kpilot 0.10.42 → 0.10.45

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.mjs +144 -133
  3. package/package.json +3 -2
package/dist/cli.mjs CHANGED
@@ -1,35 +1,40 @@
1
1
  #!/usr/bin/env node
2
- import{access as wd,appendFile as yd,chmod as En,mkdir as et,readFile as Vr,stat as Ci,writeFile as ve}from"node:fs/promises";import{createHash as Mi,randomUUID as bd}from"node:crypto";import{homedir as $i}from"node:os";import D from"node:path";import{spawn as _i}from"node:child_process";import{createInterface as Ai}from"node:readline/promises";import{emitKeypressEvents as Zr}from"node:readline";var N={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m"};function F(t,e){return process.stdout.isTTY?`${t}${e}${N.reset}`:e}var eo="\x1B[?25l",to="\x1B[?25h",jt=class{drawn=0;out;constructor(e){this.out=e}paint(e){this.clear();for(let n of e)this.out.write(`\x1B[2K\r${n}
3
- `);this.drawn=e.length}clear(){if(this.drawn===0)return;let e=this.drawn;this.drawn=0,this.out.write(`\x1B[${e}A`);for(let n=0;n<e;n+=1)this.out.write("\x1B[2K\r"),n<e-1&&this.out.write("\x1B[1B");e>1&&this.out.write(`\x1B[${e-1}A`)}};function zi(t){let e=t.findIndex(n=>n.default);return e>=0?e:0}function Vi(t,e){let n=e.trim().toLowerCase();return n?t.filter(r=>r.value.toLowerCase().includes(n)||r.label.toLowerCase().includes(n)||r.description?.toLowerCase().includes(n)||r.aliases?.some(o=>o.toLowerCase().includes(n))):t}function Yi(t,e){let n=e.trim();if(!n){let s=t.find(i=>i.default)??null;return s?s.value:null}if(/^\d+$/.test(n)){let s=t[Number(n)-1];return s?s.value:null}let r=n.toLowerCase(),o=t.find(s=>s.value.toLowerCase()===r||s.label.toLowerCase()===r||s.description?.toLowerCase()===r||s.aliases?.some(i=>i.toLowerCase()===r));return o?o.value:null}async function Qi(t){let e=t.choices;if(e.length===0)return null;console.log(`${F(N.cyan,"\u25C6")} ${t.title}`);for(let[i,a]of e.entries()){let c=`${String(i+1).padStart(2)}.`,l=a.default?F(N.green,"*"):" ",u=a.description?F(N.dim,a.description):"";console.log(` ${F(N.cyan,c)}${l} ${F(N.bold,a.label.padEnd(16))} ${u}`)}let n=e.find(i=>i.default),r=n?`Select \u203A (Enter = ${n.label}) `:"Select \u203A ",o=await t.question(r),s=Yi(e,o);return o.trim()&&s===null&&console.log(`${F(N.yellow,"!")} Unknown selection: ${o.trim()}`),s}function no(t,e,n){let r=n?F(N.green,"\u203A"):" ",o=F(N.cyan,`${String(e+1).padStart(2)}.`),s=n?F(N.bold,t.label.padEnd(16)):t.label.padEnd(16),i=t.description?F(N.dim,t.description):"";return` ${r} ${o} ${s} ${i}`}async function Xi(t){let e=t.choices;if(e.length===0)return null;let n=zi(e),r=new jt(process.stdout),o=()=>[`${F(N.cyan,"\u25C6")} ${t.title}`,F(N.dim,"\u2191/\u2193 move \xB7 Enter select \xB7 Esc cancel \xB7 1-9 jump"),...e.map((i,a)=>no(i,a,a===n))];r.paint(o()),t.pauseResume?.pause(),Zr(process.stdin);let s=process.stdin.isRaw;return process.stdin.setRawMode?.(!0),process.stdin.isPaused()&&process.stdin.resume(),process.stdout.write(eo),await new Promise(i=>{let a=!1,c=u=>{if(!a){a=!0,process.stdin.off("keypress",l);try{process.stdin.setRawMode?.(s??!1)}catch{}if(t.pauseResume?.resume(),r.clear(),process.stdout.write(to),u!==null){let m=e.find(d=>d.value===u);process.stdout.write(`${F(N.green,"\u2713")} ${m?.label??u}
4
- `)}i(u)}},l=(u,m)=>{if(!(!m||a)){if(m.ctrl&&m.name==="c"){c(null);return}if(m.name==="escape"){c(null);return}if(m.name==="return"||m.name==="enter"){c(e[n]?.value??null);return}if(m.name==="up"||m.name==="k"||m.name==="p"&&m.ctrl){n=(n-1+e.length)%e.length,r.paint(o());return}if(m.name==="down"||m.name==="j"||m.name==="n"&&m.ctrl){n=(n+1)%e.length,r.paint(o());return}if(m.name&&/^[1-9]$/.test(m.name)){let d=Number(m.name)-1;d<e.length&&(n=d,r.paint(o()))}}};process.stdin.on("keypress",l)})}async function Zi(t){let e=t.pageSize??5,n=t.initialQuery??"",r=0,o=0,s=()=>Vi(t.choices,n),i=m=>Math.max(1,Math.ceil(m.length/e)),a=m=>{o=Math.min(o,i(m)-1)},c=new jt(process.stdout),l=()=>{let m=s();a(m);let d=o*e,f=m.slice(d,d+e),w=m.length?F(N.dim,`\u2191/\u2193 move \xB7 Tab complete \xB7 Enter select \xB7 Esc cancel \xB7 ${m.length} match${m.length===1?"":"es"}`):F(N.dim,"No matches \u2014 keep typing or Esc to cancel");return[`${F(N.cyan,"\u25C6")} ${t.title}`,`${F(N.dim,"Filter")} ${F(N.bold,"/"+n)}`,w,...f.map((x,P)=>no(x,d+P,P===r))]};t.pauseResume?.pause(),Zr(process.stdin);let u=process.stdin.isRaw;return process.stdin.setRawMode?.(!0),process.stdin.isPaused()&&process.stdin.resume(),c.paint(l()),process.stdout.write(eo),await new Promise(m=>{let d=!1,f=P=>{if(!d){d=!0,process.stdin.off("keypress",x);try{process.stdin.setRawMode?.(u??!1)}catch{}if(t.pauseResume?.resume(),c.clear(),process.stdout.write(to),P!==null){let S=t.choices.find(C=>C.value===P);process.stdout.write(`${F(N.green,"\u2713")} /${P}${S&&S.description?F(N.dim,` \u2014 ${S.description}`):""}
5
- `)}else process.stdout.write(`${F(N.dim,"\xB7")} cancelled
6
- `);m(P)}},w=()=>{let S=s()[o*e+r];return S?S.value:null},x=(P,S)=>{if(!S||d)return;if(S.ctrl&&S.name==="c"||S.name==="escape")return f(null);if(S.name==="return"||S.name==="enter")return f(w());if(S.name==="tab"){let b=w();b&&(n=b,r=0,o=0,c.paint(l()));return}if(S.name==="backspace"){n=n.slice(0,-1),r=0,o=0,c.paint(l());return}if(S.name==="up"||S.name==="k"||S.name==="p"&&S.ctrl){let b=s();if(b.length===0)return;r>0?r-=1:o>0&&(o-=1,r=Math.min(e-1,Math.max(0,b.length-1-o*e))),c.paint(l());return}if(S.name==="down"||S.name==="j"||S.name==="n"&&S.ctrl){let b=s();if(b.length===0)return;r<e-1&&o*e+r+1<b.length?r+=1:o+1<i(b)&&(o+=1,r=0),c.paint(l());return}if(S.name&&/^[1-9]$/.test(S.name)){let b=Number(S.name)-1;b<s().length&&(o=Math.floor(b/e),r=b%e,c.paint(l()));return}let C=S.sequence??P;C&&C.length===1&&C.charCodeAt(0)>=32&&(n+=C,r=0,o=0,c.paint(l()))};process.stdin.on("keypress",x)})}async function Q(t){let e=!!(process.stdin.isTTY&&process.stdout.isTTY&&typeof process.stdin.setRawMode=="function");return e&&t.typeahead===!0?Zi(t):e?Xi(t):Qi(t)}var Lt="__fresh__";function ea(t,e={}){let n=e.prefer??(e.currentId?"current":"recent"),r=[];e.includeFresh&&r.push({value:Lt,label:"Start fresh",description:"Create a new empty session",aliases:["fresh","new"],default:n==="fresh"});for(let[o,s]of t.entries()){let i=s.id.slice(0,8),a=e.currentId===s.id?" \xB7 current":"",c=!1;n==="current"?c=s.id===e.currentId:n==="recent"&&(c=o===0),r.push({value:s.id,label:i,description:`${s.updatedAt} ${s.mode.padEnd(5)} ${String(s.runCount).padStart(3)} run(s) ${s.title}${a}`,aliases:[i],default:c})}if(!r.some(o=>o.default)&&r.length>0){let o=n==="fresh"?r.find(s=>s.value===Lt)??r[0]:r.find(s=>s.value!==Lt)??r[0];o&&(o.default=!0)}return r}async function $n(t){let e=await t.store.list();if(e.length===0)return t.includeFresh?{kind:"fresh"}:(console.log("[no sessions]"),{kind:"cancel"});let n=await Q({title:t.title,question:t.question,pauseResume:t.pauseResume,typeahead:!0,pageSize:8,choices:ea(e,{includeFresh:t.includeFresh,currentId:t.currentId,prefer:t.prefer})});return n?n===Lt?{kind:"fresh"}:{kind:"session",session:await t.store.load(n)}:{kind:"cancel"}}var ta=new Set(["exit","quit","q","bye",":q",":quit",":exit","/exit","/quit","/q"]);function _n(t){return ta.has(t.trim().toLowerCase())}import{emitKeypressEvents as vd}from"node:readline";var R={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",magenta:"\x1B[35m"};function M(t,e){return process.stdout.isTTY?`${t}${e}${R.reset}`:e}function oo(t){return t.replace(/\u001b\[[0-9;]*m/g,"")}function so(t){let e=0;for(let n of oo(t)){let r=n.codePointAt(0)??0;e+=r>11904?2:1}return e}function io(t,e){let n=so(t);return n>=e?t:t+" ".repeat(e-n)}var ao={read_file:{label:"READ",key:"path"},list_files:{label:"LIST",key:"path"},search_text:{label:"SEARCH",key:"query"},workspace_summary:{label:"SCAN"},git_status:{label:"STATUS"},git_diff:{label:"DIFF"},write_file:{label:"WRITE",key:"path"},replace_in_file:{label:"EDIT",key:"path"},make_directory:{label:"MKDIR",key:"path"},delete_path:{label:"DELETE",key:"path"},shell:{label:"SHELL",key:"command"},web_search:{label:"WEB",key:"query"},web_fetch:{label:"FETCH",key:"url"},browser_open:{label:"BROWSER",key:"url"},delegate_subagents:{label:"AGENTS"}};function na(t){return ao[t]?.label??t.replace(/^mcp_/,"MCP").replace(/_/g," ").toUpperCase()}function co(t){if(!t||Object.keys(t).length===0)return"";let n=t.total_lines??t.totalLines,r=t.start_line??t.startLine,o=t.end_line??t.endLine,s=t.matches??t.match_count??t.count;if(typeof n=="number")return typeof r=="number"&&typeof o=="number"?`lines ${r}-${o} of ${n}`:`${n} lines`;if(typeof s=="number")return`${s} matches`;let i=[],a=!1;for(let[l,u]of Object.entries(t)){let m=typeof u=="object"&&u!==null?JSON.stringify(u):String(u);if(m.length>24){a=!0;continue}i.push(`${l}: ${m}`)}let c=i.join(", ");return c.length>60&&(c=c.slice(0,57).trimEnd(),a=!0),a?`${c}${c?" ":""}\u2026`:c}function In(t,e){let n=ao[e]?.key??["file_path","path","cwd","command","query","url","message"].find(i=>typeof t[i]=="string"&&t[i].trim().length>0);if(n&&typeof t[n]=="string"){let i=t[n].trim();if(!i)return"";let a=n==="path"||n==="file_path"?i.split("/").pop()??i:i;return a.length>60?`${a.slice(0,57)}\u2026`:a}let r=t&&typeof t=="object"?t:{};if(Object.keys(r).length===0)return"";let s=JSON.stringify(r);return s.length>60?`${s.slice(0,57)}\u2026`:s}function lo(t){if(!t)return[];let e=t.split(/\r?\n/).filter(Boolean),n=new Map,r,o=(s,i,a)=>{let c=n.get(s)??{file:s,added:0,deleted:0};c.added+=i,c.deleted+=a,n.set(s,c)};for(let s of e){if(/^\+\+\+\s/.test(s)&&!s.includes("|")){r=s.slice(4).trim().replace(/^b\//,"");continue}let i=/^(.+?)\s+\|\s+[\d ]+(.*)$/.exec(s);if(i){let a=i[1].trim(),c=i[2]??"",l=0,u=0;for(let m of c)m==="+"&&(l+=1),m==="-"&&(u+=1);if(l===0&&u===0)continue;r=a,o(a,l,u);continue}r&&s.startsWith("+")&&!s.startsWith("+++")&&o(r,1,0),r&&s.startsWith("-")&&!s.startsWith("---")&&o(r,0,1)}return[...n.values()].sort((s,i)=>s.file.localeCompare(i.file))}function ro(t){return Number.isFinite(t)?String(t):"0"}function uo(t){let e=Math.max(0,Math.floor(t/1e3)),n=Math.floor(e/60),r=e%60;return n>0?`${n}m${r.toString().padStart(2,"0")}s`:`${r}s`}function Ue(t){if(!Number.isFinite(t)||t<1e3)return String(Math.round(t));let e=["K","M","B","T"],n=Math.min(Math.floor(Math.log10(t)/3),e.length),r=t/10**(n*3),o=r>=100?0:r>=10?1:2;return`${r.toFixed(o)}${e[n-1]}`}function ra(t){return t===void 0||!Number.isFinite(t)||t<=0?"":t>=.01?`\xB7 est $${t.toFixed(4)}`:`\xB7 est $${t.toFixed(6)}`}function Nt(t,e,n,r={}){let s=[e?M(R.dim,e):"",n?M(R.dim,`session ${n}`):""].filter(Boolean).join(M(R.dim," \xB7 "));if(r.bypass&&t!=="plan"){let a=M(R.red,"BYPASS MODE"),c=M(R.dim,"\xB7 approvals auto-granted \xB7 Shift+Tab to turn off");return`\u2500\u2500 ${a} ${c}${s?` ${s}`:""} \u2500\u2500`}if(t==="plan"){let a=M(R.yellow,"PLAN MODE"),c=M(R.dim,"\xB7 read-only \xB7 edits & mutating commands are blocked");return`\u2500\u2500 ${a} ${c}${s?` ${s}`:""} \u2500\u2500`}return`\u2500\u2500 ${M(R.green,"WRITE MODE")}${s?` ${s}`:""} \u2500\u2500`}function mo(t){return t?" \u26A0 Bypass ON \xB7 approvals auto-granted \xB7 Shift+Tab to turn off":" \u2713 Bypass OFF \xB7 approvals required \xB7 Shift+Tab to turn on"}function oa(t){let e=/ /.test(t),n=e?t.replace(/\s+/g," ").trim():t.replace(/\s+/g,""),r=e?n.split(" "):[n],o=e&&r.length>1&&r.filter(C=>C.length===1).length>=r.length*.5,s=o?n.replace(/ /g,""):n;if(!s)return`\u250C\u2500 ${M(R.dim,"thinking")} \u2500\u2510
7
- \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518`;let i=Math.min(72,Math.max(24,s.length)),a=Array.from(s),c=[],l=Math.max(1,i-2);if(e&&!o){let C="";for(let b of r){let A=C?`${C} ${b}`:b;so(A)>i-2&&C?(c.push(C),C=b):C=A}C&&c.push(C)}else for(let C=0;C<a.length;C+=l)c.push(a.slice(C,C+l).join(""));let u=process.stdout.isTTY,m=u?"\x1B[100m":"",d=u?R.reset:"",f=12,w=c.length>f?[...c.slice(0,f),M(R.dim,`\u2026 ${c.length-f} more lines`)]:c,x=`${m}\u250C\u2500 ${M(R.dim,"thinking")} ${M(R.dim,"\u2500".repeat(Math.max(0,i-10)))}\u2510${d}`,P=`${m}\u2514${M(R.dim,"\u2500".repeat(i))}\u2518${d}`,S=w.map(C=>`${m}\u2502 ${M(R.dim,io(C,i-2))} \u2502${d}`).join(`
8
- `);return`${x}
9
- ${S}
10
- ${P}`}function sa(t){let e=[];return t.elapsedMs!==void 0&&e.push(uo(t.elapsedMs)),e.push(`${Ue(t.inputTokens)}\u25B2 \xB7 ${Ue(t.outputTokens)}\u25BC`),t.cacheReadTokens&&t.cacheReadTokens>0&&e.push(M(R.green,`${Ue(t.cacheReadTokens)} cached`)),t.costUsd&&e.push(ra(t.costUsd)),t.mode==="plan"&&e.push(M(R.yellow,"plan \xB7 edits blocked")),e.join(M(R.dim," \xB7 "))}function ia(t,e=28){if(!t)return"";let n=t.split(/\r?\n/).filter(Boolean),r=n.length,s=n.slice(0,e).map(i=>i.startsWith("+")?M(R.green,i):i.startsWith("-")?M(R.red,i):i.startsWith("@@")?M(R.cyan,i):(i.startsWith("diff --git")||i.startsWith("index ")||i.startsWith("---")||i.startsWith("+++"),M(R.dim,i))).join(`
2
+ import{access as Od,appendFile as Id,chmod as $n,mkdir as et,readFile as eo,stat as Bi,writeFile as ke}from"node:fs/promises";import{createHash as Ji,randomUUID as Dd}from"node:crypto";import{homedir as Ki}from"node:os";import L from"node:path";import{spawn as Wi}from"node:child_process";import{createInterface as Gi}from"node:readline/promises";import{emitKeypressEvents as so}from"node:readline";var q={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m"};function B(t,e){return process.stdout.isTTY?`${t}${e}${q.reset}`:e}var io="\x1B[?25l",ao="\x1B[?25h",Ut=class{drawn=0;out;constructor(e){this.out=e}paint(e){this.clear();for(let n of e)this.out.write(`\x1B[2K\r${n}
3
+ `);this.drawn=e.length}clear(){if(this.drawn===0)return;let e=this.drawn;this.drawn=0,this.out.write(`\x1B[${e}A`);for(let n=0;n<e;n+=1)this.out.write("\x1B[2K\r"),n<e-1&&this.out.write("\x1B[1B");e>1&&this.out.write(`\x1B[${e-1}A`)}};function ca(t){let e=t.findIndex(n=>n.default);return e>=0?e:0}function la(t,e){let n=e.trim().toLowerCase();return n?t.filter(r=>r.value.toLowerCase().includes(n)||r.label.toLowerCase().includes(n)||r.description?.toLowerCase().includes(n)||r.aliases?.some(o=>o.toLowerCase().includes(n))):t}function ua(t,e){let n=e.trim();if(!n){let s=t.find(i=>i.default)??null;return s?s.value:null}if(/^\d+$/.test(n)){let s=t[Number(n)-1];return s?s.value:null}let r=n.toLowerCase(),o=t.find(s=>s.value.toLowerCase()===r||s.label.toLowerCase()===r||s.description?.toLowerCase()===r||s.aliases?.some(i=>i.toLowerCase()===r));return o?o.value:null}async function da(t){let e=t.choices;if(e.length===0)return null;console.log(`${B(q.cyan,"\u25C6")} ${t.title}`);for(let[i,a]of e.entries()){let c=`${String(i+1).padStart(2)}.`,l=a.default?B(q.green,"*"):" ",u=a.description?B(q.dim,a.description):"";console.log(` ${B(q.cyan,c)}${l} ${B(q.bold,a.label.padEnd(16))} ${u}`)}let n=e.find(i=>i.default),r=n?`Select \u203A (Enter = ${n.label}) `:"Select \u203A ",o=await t.question(r),s=ua(e,o);return o.trim()&&s===null&&console.log(`${B(q.yellow,"!")} Unknown selection: ${o.trim()}`),s}function co(t,e,n){let r=n?B(q.green,"\u203A"):" ",o=B(q.cyan,`${String(e+1).padStart(2)}.`),s=n?B(q.bold,t.label.padEnd(16)):t.label.padEnd(16),i=t.description?B(q.dim,t.description):"";return` ${r} ${o} ${s} ${i}`}async function ma(t){let e=t.choices;if(e.length===0)return null;let n=ca(e),r=new Ut(process.stdout),o=()=>[`${B(q.cyan,"\u25C6")} ${t.title}`,B(q.dim,"\u2191/\u2193 move \xB7 Enter select \xB7 Esc cancel \xB7 1-9 jump"),...e.map((i,a)=>co(i,a,a===n))];r.paint(o()),t.pauseResume?.pause(),so(process.stdin);let s=process.stdin.isRaw;return process.stdin.setRawMode?.(!0),process.stdin.isPaused()&&process.stdin.resume(),process.stdout.write(io),await new Promise(i=>{let a=!1,c=u=>{if(!a){a=!0,process.stdin.off("keypress",l);try{process.stdin.setRawMode?.(s??!1)}catch{}if(t.pauseResume?.resume(),r.clear(),process.stdout.write(ao),u!==null){let m=e.find(d=>d.value===u);process.stdout.write(`${B(q.green,"\u2713")} ${m?.label??u}
4
+ `)}i(u)}},l=(u,m)=>{if(!(!m||a)){if(m.ctrl&&m.name==="c"){c(null);return}if(m.name==="escape"){c(null);return}if(m.name==="return"||m.name==="enter"){c(e[n]?.value??null);return}if(m.name==="up"||m.name==="k"||m.name==="p"&&m.ctrl){n=(n-1+e.length)%e.length,r.paint(o());return}if(m.name==="down"||m.name==="j"||m.name==="n"&&m.ctrl){n=(n+1)%e.length,r.paint(o());return}if(m.name&&/^[1-9]$/.test(m.name)){let d=Number(m.name)-1;d<e.length&&(n=d,r.paint(o()))}}};process.stdin.on("keypress",l)})}async function pa(t){let e=t.pageSize??5,n=t.initialQuery??"",r=0,o=0,s=()=>la(t.choices,n),i=m=>Math.max(1,Math.ceil(m.length/e)),a=m=>{o=Math.min(o,i(m)-1)},c=new Ut(process.stdout),l=()=>{let m=s();a(m);let d=o*e,p=m.slice(d,d+e),y=m.length?B(q.dim,`\u2191/\u2193 move \xB7 Tab complete \xB7 Enter select \xB7 Esc cancel \xB7 ${m.length} match${m.length===1?"":"es"}`):B(q.dim,"No matches \u2014 keep typing or Esc to cancel");return[`${B(q.cyan,"\u25C6")} ${t.title}`,`${B(q.dim,"Filter")} ${B(q.bold,"/"+n)}`,y,...p.map((S,x)=>co(S,d+x,x===r))]};t.pauseResume?.pause(),so(process.stdin);let u=process.stdin.isRaw;return process.stdin.setRawMode?.(!0),process.stdin.isPaused()&&process.stdin.resume(),c.paint(l()),process.stdout.write(io),await new Promise(m=>{let d=!1,p=x=>{if(!d){d=!0,process.stdin.off("keypress",S);try{process.stdin.setRawMode?.(u??!1)}catch{}if(t.pauseResume?.resume(),c.clear(),process.stdout.write(ao),x!==null){let k=t.choices.find(R=>R.value===x);process.stdout.write(`${B(q.green,"\u2713")} /${x}${k&&k.description?B(q.dim,` \u2014 ${k.description}`):""}
5
+ `)}else process.stdout.write(`${B(q.dim,"\xB7")} cancelled
6
+ `);m(x)}},y=()=>{let k=s()[o*e+r];return k?k.value:null},S=(x,k)=>{if(!k||d)return;if(k.ctrl&&k.name==="c"||k.name==="escape")return p(null);if(k.name==="return"||k.name==="enter")return p(y());if(k.name==="tab"){let P=y();P&&(n=P,r=0,o=0,c.paint(l()));return}if(k.name==="backspace"){n=n.slice(0,-1),r=0,o=0,c.paint(l());return}if(k.name==="up"||k.name==="k"||k.name==="p"&&k.ctrl){let P=s();if(P.length===0)return;r>0?r-=1:o>0&&(o-=1,r=Math.min(e-1,Math.max(0,P.length-1-o*e))),c.paint(l());return}if(k.name==="down"||k.name==="j"||k.name==="n"&&k.ctrl){let P=s();if(P.length===0)return;r<e-1&&o*e+r+1<P.length?r+=1:o+1<i(P)&&(o+=1,r=0),c.paint(l());return}if(k.name&&/^[1-9]$/.test(k.name)){let P=Number(k.name)-1;P<s().length&&(o=Math.floor(P/e),r=P%e,c.paint(l()));return}let R=k.sequence??x;R&&R.length===1&&R.charCodeAt(0)>=32&&(n+=R,r=0,o=0,c.paint(l()))};process.stdin.on("keypress",S)})}async function Q(t){let e=!!(process.stdin.isTTY&&process.stdout.isTTY&&typeof process.stdin.setRawMode=="function");return e&&t.typeahead===!0?pa(t):e?ma(t):da(t)}var Nt="__fresh__";function fa(t,e={}){let n=e.prefer??(e.currentId?"current":"recent"),r=[];e.includeFresh&&r.push({value:Nt,label:"Start fresh",description:"Create a new empty session",aliases:["fresh","new"],default:n==="fresh"});for(let[o,s]of t.entries()){let i=s.id.slice(0,8),a=e.currentId===s.id?" \xB7 current":"",c=!1;n==="current"?c=s.id===e.currentId:n==="recent"&&(c=o===0),r.push({value:s.id,label:s.title,description:`${s.updatedAt} ${s.mode.padEnd(5)} ${String(s.runCount).padStart(3)} run(s)${a}`,aliases:[i],default:c})}if(!r.some(o=>o.default)&&r.length>0){let o=n==="fresh"?r.find(s=>s.value===Nt)??r[0]:r.find(s=>s.value!==Nt)??r[0];o&&(o.default=!0)}return r}async function Dn(t){let e=await t.store.list();if(e.length===0)return t.includeFresh?{kind:"fresh"}:(console.log("[no sessions]"),{kind:"cancel"});let n=await Q({title:t.title,question:t.question,pauseResume:t.pauseResume,typeahead:!0,pageSize:8,choices:fa(e,{includeFresh:t.includeFresh,currentId:t.currentId,prefer:t.prefer})});return n?n===Nt?{kind:"fresh"}:{kind:"session",session:await t.store.load(n)}:{kind:"cancel"}}var ga=new Set(["exit","quit","q","bye",":q",":quit",":exit","/exit","/quit","/q"]);function jn(t){return ga.has(t.trim().toLowerCase())}import{emitKeypressEvents as jd}from"node:readline";var C={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",magenta:"\x1B[35m"};function M(t,e){return process.stdout.isTTY?`${t}${e}${C.reset}`:e}function uo(t){return t.replace(/\u001b\[[0-9;]*m/g,"")}function mo(t){let e=0;for(let n of uo(t)){let r=n.codePointAt(0)??0;e+=r>11904?2:1}return e}function po(t,e){let n=mo(t);return n>=e?t:t+" ".repeat(e-n)}var fo={read_file:{label:"READ",key:"path"},list_files:{label:"LIST",key:"path"},search_text:{label:"SEARCH",key:"query"},workspace_summary:{label:"SCAN"},git_status:{label:"STATUS"},git_diff:{label:"DIFF"},write_file:{label:"WRITE",key:"path"},replace_in_file:{label:"EDIT",key:"path"},make_directory:{label:"MKDIR",key:"path"},delete_path:{label:"DELETE",key:"path"},shell:{label:"SHELL",key:"command"},web_search:{label:"WEB",key:"query"},web_fetch:{label:"FETCH",key:"url"},browser_open:{label:"BROWSER",key:"url"},delegate_subagents:{label:"AGENTS"}};function ha(t){return fo[t]?.label??t.replace(/^mcp_/,"MCP").replace(/_/g," ").toUpperCase()}function go(t){if(!t||Object.keys(t).length===0)return"";let n=t.total_lines??t.totalLines,r=t.start_line??t.startLine,o=t.end_line??t.endLine,s=t.matches??t.match_count??t.count,i=t.entries??t.entry_count,a=t.top_level??t.topLevel,c=t.manifests,l=t.files??t.file_count,u=t.dirs??t.directories??t.dir_count,m=t.resultCount??t.result_count;if(typeof n=="number")return typeof r=="number"&&typeof o=="number"?`lines ${r}-${o} of ${n}`:`${n} lines`;if(typeof s=="number")return`${s} match${s===1?"":"es"}`;if(typeof m=="number")return`${m} result${m===1?"":"s"}`;if(typeof i=="number")return`${i} entr${i===1?"y":"ies"}`;if(typeof a=="number"){let S=[`${a} top-level`];return typeof c=="number"&&S.push(`${c} manifest${c===1?"":"s"}`),S.join(" \xB7 ")}if(typeof l=="number"){let S=[`${l} file${l===1?"":"s"}`];return typeof u=="number"&&S.push(`${u} dir${u===1?"":"s"}`),S.join(" \xB7 ")}let d=[],p=!1;for(let[S,x]of Object.entries(t)){let k=typeof x=="object"&&x!==null?JSON.stringify(x):String(x);if(k.length>24){p=!0;continue}d.push(`${S}: ${k}`)}let y=d.join(", ");return y.length>60&&(y=y.slice(0,57).trimEnd(),p=!0),p?`${y}${y?" ":""}\u2026`:y}function Nn(t,e){let n=fo[e]?.key??["file_path","path","cwd","command","query","url","message"].find(i=>typeof t[i]=="string"&&t[i].trim().length>0);if(n&&typeof t[n]=="string"){let i=t[n].trim();if(!i)return"";let a=n==="path"||n==="file_path"?i.split("/").pop()??i:i;return a.length>60?`${a.slice(0,57)}\u2026`:a}let r=t&&typeof t=="object"?t:{};if(Object.keys(r).length===0)return"";let s=JSON.stringify(r);return s.length>60?`${s.slice(0,57)}\u2026`:s}function ho(t){if(!t)return[];let e=t.split(/\r?\n/).filter(Boolean),n=new Map,r,o=(s,i,a)=>{let c=n.get(s)??{file:s,added:0,deleted:0};c.added+=i,c.deleted+=a,n.set(s,c)};for(let s of e){if(/^\+\+\+\s/.test(s)&&!s.includes("|")){r=s.slice(4).trim().replace(/^b\//,"");continue}let i=/^(.+?)\s+\|\s+[\d ]+(.*)$/.exec(s);if(i){let a=i[1].trim(),c=i[2]??"",l=0,u=0;for(let m of c)m==="+"&&(l+=1),m==="-"&&(u+=1);if(l===0&&u===0)continue;r=a,o(a,l,u);continue}r&&s.startsWith("+")&&!s.startsWith("+++")&&o(r,1,0),r&&s.startsWith("-")&&!s.startsWith("---")&&o(r,0,1)}return[...n.values()].sort((s,i)=>s.file.localeCompare(i.file))}function lo(t){return Number.isFinite(t)?String(t):"0"}function wo(t){let e=Math.max(0,Math.floor(t/1e3)),n=Math.floor(e/60),r=e%60;return n>0?`${n}m${r.toString().padStart(2,"0")}s`:`${r}s`}function Ue(t){if(!Number.isFinite(t)||t<1e3)return String(Math.round(t));let e=["K","M","B","T"],n=Math.min(Math.floor(Math.log10(t)/3),e.length),r=t/10**(n*3),o=r>=100?0:r>=10?1:2;return`${r.toFixed(o)}${e[n-1]}`}function wa(t){return t===void 0||!Number.isFinite(t)||t<=0?"":t>=.01?`\xB7 est $${t.toFixed(4)}`:`\xB7 est $${t.toFixed(6)}`}function qt(t,e,n,r={}){let s=[e?M(C.dim,e):"",n?M(C.dim,n):""].filter(Boolean).join(M(C.dim," \xB7 "));if(r.bypass&&t!=="plan"){let a=M(C.red,"BYPASS MODE"),c=M(C.dim,"\xB7 approvals auto-granted \xB7 Shift+Tab to turn off");return`\u2500\u2500 ${a} ${c}${s?` ${s}`:""} \u2500\u2500`}if(t==="plan"){let a=M(C.yellow,"PLAN MODE"),c=M(C.dim,"\xB7 read-only \xB7 edits & mutating commands are blocked");return`\u2500\u2500 ${a} ${c}${s?` ${s}`:""} \u2500\u2500`}return`\u2500\u2500 ${M(C.green,"WRITE MODE")}${s?` ${s}`:""} \u2500\u2500`}function yo(t){return t?" \u26A0 Bypass ON \xB7 approvals auto-granted \xB7 Shift+Tab to turn off":" \u2713 Bypass OFF \xB7 approvals required \xB7 Shift+Tab to turn on"}function bo(t,e){return t.lineOpen||t.speakerShown?"":`${e} \u203A `}function ya(t){let e=/ /.test(t),n=e?t.replace(/\s+/g," ").trim():t.replace(/\s+/g,""),r=e?n.split(" "):[n],o=e&&r.length>1&&r.filter(R=>R.length===1).length>=r.length*.5,s=o?n.replace(/ /g,""):n;if(!s)return`\u250C\u2500 ${M(C.dim,"thinking")} \u2500\u2510
7
+ \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518`;let i=Math.min(72,Math.max(24,s.length)),a=Array.from(s),c=[],l=Math.max(1,i-2);if(e&&!o){let R="";for(let P of r){let _=R?`${R} ${P}`:P;mo(_)>i-2&&R?(c.push(R),R=P):R=_}R&&c.push(R)}else for(let R=0;R<a.length;R+=l)c.push(a.slice(R,R+l).join(""));let u=process.stdout.isTTY,m=u?"\x1B[100m":"",d=u?C.reset:"",p=12,y=c.length>p?[...c.slice(0,p),M(C.dim,`\u2026 ${c.length-p} more lines`)]:c,S=`${m}\u250C\u2500 ${M(C.dim,"thinking")} ${M(C.dim,"\u2500".repeat(Math.max(0,i-10)))}\u2510${d}`,x=`${m}\u2514${M(C.dim,"\u2500".repeat(i))}\u2518${d}`,k=y.map(R=>`${m}\u2502 ${M(C.dim,po(R,i-2))} \u2502${d}`).join(`
8
+ `);return`${S}
9
+ ${k}
10
+ ${x}`}function ba(t){let e=[];return t.elapsedMs!==void 0&&e.push(wo(t.elapsedMs)),e.push(`${Ue(t.inputTokens)}\u25B2 \xB7 ${Ue(t.outputTokens)}\u25BC`),t.cacheReadTokens&&t.cacheReadTokens>0&&e.push(M(C.green,`${Ue(t.cacheReadTokens)} cached`)),t.costUsd&&e.push(wa(t.costUsd)),t.mode==="plan"&&e.push(M(C.yellow,"plan \xB7 edits blocked")),e.join(M(C.dim," \xB7 "))}function va(t,e=28){if(!t)return"";let n=t.split(/\r?\n/).filter(Boolean),r=n.length,s=n.slice(0,e).map(i=>i.startsWith("+")?M(C.green,i):i.startsWith("-")?M(C.red,i):i.startsWith("@@")?M(C.cyan,i):(i.startsWith("diff --git")||i.startsWith("index ")||i.startsWith("---")||i.startsWith("+++"),M(C.dim,i))).join(`
11
11
  `);return r>e&&(s+=`
12
- ${M(R.dim,`\u2026 ${r-e} more diff lines`)}`),s}var An=["\u2722","\u2740","\u273F","\u2744","\u2748","\u2734","\u2736","\u2605","\u272E","\u272A","\u263C","\u25C6"],On=["parsing","framing","ingesting","detecting","decoding","scanning","probing","mapping","brainstorming","clustering","structuring","pivoting","planning","blueprinting","architecting","scoping","routing","filtering","reasoning","coding","calculating","compiling","building","synthesizing","processing"];function aa(t,e){let n=Math.max(3,Math.round(t.length/2)),r="";for(let o=0;o<t.length;o+=1){let s=e-o,i=R.dim;s>=0&&s<n&&(s===0?i=R.green:s<Math.ceil(n/2)?i=R.cyan:i=R.yellow),r+=M(i,t[o])}return r}var Ut=class{mode;tty;timer;frame=0;startedAt=Date.now();inputTokens=0;cacheReadTokens=0;outputTokens=0;costUsd;reasoning=[];reasoningOpen=!1;lastLineOpen=!1;nonTtyAnnounced=!1;finished=!1;sawOutput=!1;constructor(e){this.mode=e.mode,this.tty=!!process.stdout.isTTY}clearLine(){this.tty&&process.stdout.write("\r\x1B[2K")}writeLine(e){if(this.tty)process.stdout.write(`\r\x1B[2K${e}
13
- `);else{let n=oo(e);console.log(n)}this.lastLineOpen=!1}noteOutput(){this.sawOutput=!0}activity(e,n,r,o){if(this.finished)return;this.sawOutput=!0,this.clearReasoningIfOpen();let s=na(n),i=this.tty?`\x1B[7m ${s} \x1B[0m`:`[${s}]`,a=r?M(R.dim,` ${r}`):"";if(e==="start")this.writeLine(`${M(R.magenta,"\u2192")} ${i}${a}`);else if(e==="result"){let c=o===!1?M(R.red,"\u2717"):M(R.green,"\u2713");this.writeLine(`${c} ${i}${a}`)}else this.writeLine(` ${i}${a}`)}reasoningDelta(e){this.finished||(this.sawOutput=!0,this.reasoning.push(e),this.reasoningOpen=!0,this.redrawFooter())}clearReasoning(){this.clearReasoningIfOpen()}clearReasoningIfOpen(){this.reasoningOpen&&(this.reasoningOpen=!1,this.reasoning.length>0&&!this.finished&&this.writeLine(oa(this.reasoning.join("").trim())),this.reasoning=[])}addUsage(e,n,r=0){this.inputTokens+=e,this.outputTokens+=n,this.cacheReadTokens+=r}setCost(e){this.costUsd=e}finish(e){if(this.finished)return;this.finished=!0,this.stopTimer(),this.clearReasoningIfOpen(),this.tty?(this.lastLineOpen&&process.stdout.write(`
14
- `),this.writeLine("")):console.log("");let n=e?.files??[];if(e?.changed&&n.length>0){this.writeLine(M(R.bold,`Files changed (${n.length}):`));for(let o of n)this.writeLine(` ${M(R.dim,o.file.padEnd(40))} ${M(R.green,`+${ro(o.added)}`)} ${M(R.red,`\u2212${ro(o.deleted)}`)}`);if(e.diff){this.writeLine(""),this.writeLine(M(R.dim,"Diff:"));for(let o of ia(e.diff).split(`
15
- `))this.writeLine(o)}}else e&&!e.changed&&this.mode==="plan"&&this.writeLine(M(R.dim,"No files changed \xB7 plan-only run."));if(e?.planSummary){this.writeLine(M(R.bold,"Plan summary"));for(let o of e.planSummary.split(`
16
- `))this.writeLine(M(R.dim,` ${o}`))}let r=sa({elapsedMs:Date.now()-this.startedAt,inputTokens:this.inputTokens,outputTokens:this.outputTokens,costUsd:this.costUsd,cacheReadTokens:this.cacheReadTokens,mode:this.mode});this.writeLine(M(R.dim,r))}renderFrame(){if(this.finished||!this.tty)return;let e=this.frame,n=An[Math.floor(e/2)%An.length]??An[0],r=this.reasoningOpen?this.reasoning.join("").replace(/\s+/g," ").trim().slice(-60):"",o;if(!this.sawOutput)o=M(R.dim,"connecting\u2026");else if(r)o=M(R.dim,`thinking: ${r}`);else{let u=On[Math.floor(e/8)%On.length]??On[0],m=Math.floor(e/2)%Math.max(1,u.length+6);o=aa(u,m)}let s=uo(Date.now()-this.startedAt),i=` \xB7 ${Ue(this.inputTokens)}\u25B2 ${Ue(this.outputTokens)}\u25BC${this.cacheReadTokens>0?M(R.green,` ${Ue(this.cacheReadTokens)} cached`):""}`,a=`${o}${M(R.dim,`${i} \xB7 ${s}`)}`,c=Math.max(30,(process.stdout.columns??80)-4);process.stdout.write(`\r\x1B[2K${M(R.cyan,n)} ${io(a,c)}`),this.lastLineOpen=!0}redrawFooter(){!this.tty||this.finished||(this.clearLine(),this.renderFrame())}start(){this.timer||this.finished||(this.startedAt=Date.now(),this.tty?(process.stdout.write(`
17
- `),this.renderFrame(),this.timer=setInterval(()=>{this.frame+=1,this.renderFrame()},140)):this.nonTtyAnnounced||(this.nonTtyAnnounced=!0,console.log(M(R.dim,"\u25C6 working\u2026"))))}stop(){this.stopTimer(),this.tty&&(this.clearLine(),this.lastLineOpen=!1)}stopTimer(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}};function po(t){let e=new Set(["read_file","git_diff","git_status"]),n=new Set(["search_text","list_files","workspace_summary"]),r=new Set,o=0,s=0;for(let a of t)a.type==="tool_start"&&(e.has(a.call.function.name)?r.add(In(a.args,a.call.function.name)):n.has(a.call.function.name)&&(o+=1)),a.type==="tool_result"&&!a.result.ok&&(s+=1);let i=[];return i.push(`inspected ${r.size} file(s)${r.size?`: ${[...r].slice(0,6).join(", ")}${r.size>6?"\u2026":""}`:""}`),o>0&&i.push(`${o} search/list call(s)`),s>0&&i.push(`${s} tool call(s) failed`),i.push("No files were modified (plan mode)."),i.join(`
18
- `)}var fo={"anthropic/claude-opus-5":{name:"Claude Opus 5",description:"Anthropic flagship for demanding reasoning, coding, and long-horizon agentic work"},"anthropic/claude-opus-4.8":{name:"Claude Opus 4.8",description:"Anthropic flagship for complex reasoning and high-stakes coding"},"anthropic/claude-sonnet-5":{name:"Claude Sonnet 5",description:"Frontier Sonnet-class model for coding, agents, and knowledge work"},"anthropic/claude-fable-5.1":{name:"Claude Fable 5.1",description:"Agentic coding and long-range tool use with broad gains over Fable 5"},"anthropic/claude-fable-5":{name:"Claude Fable 5",description:"Lightweight Claude model tuned for agentic coding and tool calling"},"openai/gpt-6-astra":{name:"GPT-6 Astra",description:"OpenAI flagship for advanced analysis, software engineering, and agentic work"},"openai/gpt-5.6-sol":{name:"GPT-5.6 Sol",description:"OpenAI flagship for complex reasoning and coding"},"openai/gpt-5.6-terra":{name:"GPT-5.6 Terra",description:"Balanced GPT-5.6 model between flagship and everyday tiers"},"openai/gpt-5.6-luna":{name:"GPT-5.6 Luna",description:"GPT-5.6 series model for general reasoning and coding"},"openai/gpt-5.5":{name:"GPT-5.5",description:"OpenAI frontier model for complex professional workloads"},"google/gemini-3.8-flash":{name:"Gemini 3.8 Flash",description:"Google\u2019s most intelligent Flash model for software and reasoning"},"google/gemini-3.7-flash":{name:"Gemini 3.7 Flash",description:"Google Flash model balancing speed, reasoning, and coding"},"google/gemini-3.5-flash-lite":{name:"Gemini 3.5 Flash Lite",description:"Fast, low-latency Google model for everyday tasks"},"google/gemini-3.1-flash-lite":{name:"Gemini 3.1 Flash Lite",description:"Lightweight Google model for quick, cost-effective work"},"x-ai/grok-4.6":{name:"Grok 4.6",description:"xAI\u2019s smartest model for coding, knowledge work, and STEM"},"x-ai/grok-4.5":{name:"Grok 4.5",description:"xAI model for coding and knowledge-heavy tasks"},"qwen/qwen3.8-max-0902":{name:"Qwen3.8 Max",description:"2.4T-parameter Qwen model for complex coding and reasoning"},"qwen/qwen3.8-27b":{name:"Qwen3.8 27B",description:"Qwen model for general coding and agentic work"},"qwen/qwen3.8-flash":{name:"Qwen3.8 Flash",description:"Fast Qwen model for everyday agentic coding"},"qwen/qwen3.7-plus":{name:"Qwen3.7 Plus",description:"Cost-effective Qwen model with text + image input"},"qwen/qwen3.7-flash":{name:"Qwen3.7 Flash",description:"Fast Qwen model for agentic coding tasks"},"moonshotai/kimi-k3":{name:"Kimi K3",description:"2.8T-parameter multimodal reasoning model from Moonshot AI"},"z-ai/glm-5.3":{name:"GLM-5.3",description:"Large-scale Z.ai reasoning model for complex software engineering"},"z-ai/glm-5.3-flash":{name:"GLM-5.3 Flash",description:"Fast Z.ai GLM model for everyday coding"},"deepseek/deepseek-v4-pro-0813":{name:"DeepSeek V4 Pro",description:"Large mixture-of-experts model for reasoning and coding"},"deepseek/deepseek-v4-flash":{name:"DeepSeek V4 Flash",description:"Sparse MoE model balancing speed and capability"},"deepseek/deepseek-v4-flash-0731":{name:"DeepSeek V4 Flash (fast)",description:"Fast-flash DeepSeek model for quick coding turns"},"deepseek/deepseek-v4-flash-vision-exp":{name:"DeepSeek V4 Flash Vision",description:"Vision-capable DeepSeek model for image and UI work"},"stepfun/step-3.5-flash":{name:"Step 3.5 Flash",description:"StepFun fast model for everyday tasks"},"stepfun/step-3.7-flash":{name:"Step 3.7 Flash",description:"StepFun fast model for agentic coding"},"tencent/hy3":{name:"Tencent Hy3",description:"Tencent hybrid reasoning model for general work"},"minimax/minimax-m3":{name:"MiniMax M3",description:"MiniMax high-capability model for coding and long context"},"xiaomi/mimo-v2.5-pro":{name:"MiMo V2.5 Pro",description:"High-capability long-context agentic coding"},"xiaomi/mimo-v2.5":{name:"MiMo V2.5",description:"Xiaomi general-purpose model for coding and agents"},"meta/muse-spark-1.3":{name:"Muse Spark 1.3",description:"Meta reasoning model for complex agentic work"},"meta/muse-spark-1.2":{name:"Muse Spark 1.2",description:"Meta reasoning model for coding and analysis"},"meta/muse-spark-1.3-contributor":{name:"Muse Spark 1.3 (Contributor)",description:"Meta open-contributor Muse Spark model"}};function Ft(t){let e=fo[t]?.name;return e||(t.includes("/")?t.slice(t.lastIndexOf("/")+1):t).replace(/[-_]/g," ").replace(/\b\w/g,r=>r.toUpperCase())}function go(t){return fo[t]?.description??"Hosted model available through kpilot"}import{emitKeypressEvents as ca}from"node:readline";var Se={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m"},Dn="\x1B[2K";function Ee(t,e){return`${t}${e}${Se.reset}`}function Re(t){if(!t.startsWith("/"))return null;let e=t.slice(1);return e.includes(" ")||e.includes(" ")?null:e}function la(t){return[t.name,...t.aliases??[]].map(e=>e.toLowerCase())}function ho(t,e){let n=e.trim().toLowerCase();if(!n)return[...t];let r=[];for(let o of t){let s=o.name.toLowerCase(),i=-1;la(o).includes(n)?i=0:s.startsWith(n)?i=1:s.includes(n)?i=2:o.description.toLowerCase().includes(n)&&(i=3),i>=0&&r.push({entry:o,score:i})}return r.sort((o,s)=>o.score-s.score||o.entry.name.localeCompare(s.entry.name)),r.map(o=>o.entry)}var Bt=class{entries=[];attached=!1;suspended=!1;drawn=0;pending=!1;skipRender=!1;hover=0;current=[];lastQuery=null;pendingSelection=null;savedHistory=null;maxRows;tty;rl;streams;constructor(e,n,r={}){this.rl=e,this.streams=n,this.maxRows=r.maxRows??8,this.tty=!!(n.input.isTTY&&n.output.isTTY)}setEntries(e){this.entries=e,this.current=this.computeMatches(),this.schedule()}attach(){this.attached||!this.tty||(this.attached=!0,ca(this.streams.input),this.streams.input.on("keypress",this.onKeypress),this.rl.on("pause",this.onPause),this.rl.on("resume",this.onResume))}detach(){this.attached&&(this.attached=!1,this.erase(),this.restoreHistory(),this.streams.input.off("keypress",this.onKeypress),this.rl.off("pause",this.onPause),this.rl.off("resume",this.onResume))}takeSelection(){let e=this.pendingSelection;return this.pendingSelection=null,e}onPause=()=>{this.suspended=!0,this.erase()};onResume=()=>{this.suspended=!1,this.schedule()};computeMatches(){let e=Re(this.rl.line);return e===null?[]:ho(this.entries,e)}onKeypress=(e,n)=>{if(!this.suspended){if(n?.name==="return"||n?.name==="enter"||n?.ctrl&&n.name==="c"){if(n.name!=="c"){let r=this.current;r.length>0&&this.hover<r.length&&(this.pendingSelection=r[this.hover]?.name??null)}this.clearAtCursor(),this.skipRender=!0;return}if(n?.ctrl&&n.name==="l"){this.drawn=0,this.schedule();return}if(n?.name==="escape"){this.rl.write?.(null,{ctrl:!0,name:"u"}),this.erase(),this.skipRender=!0;return}if(this.current=this.computeMatches(),(n?.name==="down"||n?.ctrl&&n.name==="n")&&this.current.length>0){this.move(1);return}if((n?.name==="up"||n?.ctrl&&n.name==="p")&&this.current.length>0){this.move(-1);return}this.pendingSelection!==null&&(this.pendingSelection=null),this.schedule()}};move(e){let n=this.current.length;n!==0&&(this.hover=(this.hover+e+n)%n,this.render())}syncHistory(e){try{e&&this.savedHistory===null?(this.savedHistory=[...this.rl.history],this.rl.history.splice(0,this.rl.history.length)):e||this.restoreHistory()}catch{}}restoreHistory(){if(this.savedHistory!==null){try{this.rl.history.splice(0,0,...this.savedHistory)}catch{}this.savedHistory=null}}schedule(){!this.attached||this.suspended||!this.tty||this.pending||(this.pending=!0,setTimeout(()=>{if(this.pending=!1,this.skipRender){this.skipRender=!1,this.lastQuery=Re(this.rl.line);return}this.render()},0))}render(){if(!this.attached||this.suspended||!this.tty)return;let e=Re(this.rl.line);if(this.syncHistory(e!==null),e===null){this.erase();return}let n=ho(this.entries,e);if(this.current=n,n.length===0){this.hover=0,this.lastQuery=e,this.draw([` ${Ee(Se.dim,"No matching commands")}`]);return}e!==this.lastQuery&&(this.hover=0,this.lastQuery=e),this.hover>=n.length&&(this.hover=n.length-1);let r=Math.max(0,Math.min(this.hover,n.length-this.maxRows)),o=n.slice(r,r+this.maxRows),s=o.map((a,c)=>this.renderRow(a,r+c===this.hover));n.length-o.length>0&&s.push(` ${Ee(Se.dim,`\u2026 ${r+1}-${r+o.length} of ${n.length} \u2014 \u2191/\u2193 to move`)}`),this.draw(s)}renderRow(e,n){let r=`/${e.name}`.padEnd(14),o=n?Ee(Se.green,"\u203A"):" ",s=n?Ee(Se.bold,Ee(Se.cyan,r)):Ee(Se.cyan,r);return` ${o} ${s} ${Ee(Se.dim,e.description)}`}draw(e){if(this.erase(),e.length===0)return;let{output:n}=this.streams;n.write(`\r
19
- `);for(let r=0;r<e.length;r+=1)n.write(`${Dn}${e[r]}`),r<e.length-1&&n.write(`\r
12
+ ${M(C.dim,`\u2026 ${r-e} more diff lines`)}`),s}var Ln=["\u2722","\u2740","\u273F","\u2744","\u2748","\u2734","\u2736","\u2605","\u272E","\u272A","\u263C","\u25C6"],Un=["parsing","framing","ingesting","detecting","decoding","scanning","probing","mapping","brainstorming","clustering","structuring","pivoting","planning","blueprinting","architecting","scoping","routing","filtering","reasoning","coding","calculating","compiling","building","synthesizing","processing"];function ka(t,e){let n=Math.max(3,Math.round(t.length/2)),r="";for(let o=0;o<t.length;o+=1){let s=e-o,i=C.dim;s>=0&&s<n&&(s===0?i=C.green:s<Math.ceil(n/2)?i=C.cyan:i=C.yellow),r+=M(i,t[o])}return r}var Ft=class{mode;output;tty;timer;frame=0;startedAt=Date.now();inputTokens=0;cacheReadTokens=0;outputTokens=0;costUsd;reasoning=[];reasoningOpen=!1;lastLineOpen=!1;nonTtyAnnounced=!1;finished=!1;sawOutput=!1;constructor(e){this.mode=e.mode,this.output=e.output??process.stdout,this.tty=e.tty??!!process.stdout.isTTY}clearLine(){this.tty&&this.output.write("\r\x1B[2K")}writeLine(e){if(this.tty)this.output.write(`\r\x1B[2K${e}
13
+ `);else{let n=uo(e);this.output.write(`${n}
14
+ `)}this.lastLineOpen=!1}noteOutput(){this.sawOutput=!0}activity(e,n,r,o){if(this.finished)return;this.sawOutput=!0,this.clearReasoningIfOpen();let s=ha(n),i=this.tty?`\x1B[7m ${s} \x1B[0m`:`[${s}]`,a=r?M(C.dim,` ${r}`):"";if(e==="start")this.writeLine(`${M(C.magenta,"\u2192")} ${i}${a}`);else if(e==="result"){let c=o===!1?M(C.red,"\u2717"):M(C.green,"\u2713");this.writeLine(`${c} ${i}${a}`)}else this.writeLine(` ${i}${a}`)}reasoningDelta(e,n=!0){this.finished||(this.sawOutput=!0,this.reasoning.push(e),this.reasoningOpen=!0,n&&this.redrawFooter())}clearReasoning(){this.clearReasoningIfOpen()}clearReasoningIfOpen(){this.reasoningOpen&&(this.reasoningOpen=!1,this.reasoning.length>0&&!this.finished&&this.writeLine(ya(this.reasoning.join("").trim())),this.reasoning=[])}addUsage(e,n,r=0){this.inputTokens+=e,this.outputTokens+=n,this.cacheReadTokens+=r}setCost(e){this.costUsd=e}finish(e){if(this.finished)return;this.finished=!0,this.stopTimer(),this.clearReasoningIfOpen(),this.tty?(this.lastLineOpen&&process.stdout.write(`
15
+ `),this.writeLine("")):console.log("");let n=e?.files??[];if(e?.changed&&n.length>0){this.writeLine(M(C.bold,`Files changed (${n.length}):`));for(let o of n)this.writeLine(` ${M(C.dim,o.file.padEnd(40))} ${M(C.green,`+${lo(o.added)}`)} ${M(C.red,`\u2212${lo(o.deleted)}`)}`);if(e.diff){this.writeLine(""),this.writeLine(M(C.dim,"Diff:"));for(let o of va(e.diff).split(`
16
+ `))this.writeLine(o)}}else e&&!e.changed&&this.mode==="plan"&&this.writeLine(M(C.dim,"No files changed \xB7 plan-only run."));if(e?.planSummary){this.writeLine(M(C.bold,"Plan summary"));for(let o of e.planSummary.split(`
17
+ `))this.writeLine(M(C.dim,` ${o}`))}let r=ba({elapsedMs:Date.now()-this.startedAt,inputTokens:this.inputTokens,outputTokens:this.outputTokens,costUsd:this.costUsd,cacheReadTokens:this.cacheReadTokens,mode:this.mode});this.writeLine(M(C.dim,r))}renderFrame(){if(this.finished||!this.tty)return;let e=this.frame,n=Ln[Math.floor(e/2)%Ln.length]??Ln[0],r=this.reasoningOpen?this.reasoning.join("").replace(/\s+/g," ").trim().slice(-60):"",o;if(!this.sawOutput)o=M(C.dim,"connecting\u2026");else if(r)o=M(C.dim,`thinking: ${r}`);else{let u=Un[Math.floor(e/8)%Un.length]??Un[0],m=Math.floor(e/2)%Math.max(1,u.length+6);o=ka(u,m)}let s=wo(Date.now()-this.startedAt),i=` \xB7 ${Ue(this.inputTokens)}\u25B2 ${Ue(this.outputTokens)}\u25BC${this.cacheReadTokens>0?M(C.green,` ${Ue(this.cacheReadTokens)} cached`):""}`,a=`${o}${M(C.dim,`${i} \xB7 ${s}`)}`,c=Math.max(30,(this.output.columns??80)-4);this.output.write(`\r\x1B[2K${M(C.cyan,n)} ${po(a,c)}`),this.lastLineOpen=!0}redrawFooter(){!this.tty||this.finished||(this.clearLine(),this.renderFrame())}start(){this.timer||this.finished||(this.startedAt=Date.now(),this.tty?(process.stdout.write(`
18
+ `),this.renderFrame(),this.timer=setInterval(()=>{this.frame+=1,this.renderFrame()},140)):this.nonTtyAnnounced||(this.nonTtyAnnounced=!0,this.output.write(`${M(C.dim,"\u25C6 working\u2026")}
19
+ `)))}stop(){this.stopTimer(),this.tty&&(this.clearLine(),this.lastLineOpen=!1)}dispose(){this.finished=!0,this.stop(),this.reasoningOpen=!1,this.reasoning=[]}stopTimer(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}};function vo(t){let e=new Set(["read_file","git_diff","git_status"]),n=new Set(["search_text","list_files","workspace_summary"]),r=new Set,o=0,s=0;for(let a of t)a.type==="tool_start"&&(e.has(a.call.function.name)?r.add(Nn(a.args,a.call.function.name)):n.has(a.call.function.name)&&(o+=1)),a.type==="tool_result"&&!a.result.ok&&(s+=1);let i=[];return i.push(`inspected ${r.size} file(s)${r.size?`: ${[...r].slice(0,6).join(", ")}${r.size>6?"\u2026":""}`:""}`),o>0&&i.push(`${o} search/list call(s)`),s>0&&i.push(`${s} tool call(s) failed`),i.push("No files were modified (plan mode)."),i.join(`
20
+ `)}var ko={"anthropic/claude-opus-5":{name:"Claude Opus 5",description:"Anthropic flagship for demanding reasoning, coding, and long-horizon agentic work"},"anthropic/claude-opus-4.8":{name:"Claude Opus 4.8",description:"Anthropic flagship for complex reasoning and high-stakes coding"},"anthropic/claude-sonnet-5":{name:"Claude Sonnet 5",description:"Frontier Sonnet-class model for coding, agents, and knowledge work"},"anthropic/claude-fable-5.1":{name:"Claude Fable 5.1",description:"Agentic coding and long-range tool use with broad gains over Fable 5"},"anthropic/claude-fable-5":{name:"Claude Fable 5",description:"Lightweight Claude model tuned for agentic coding and tool calling"},"openai/gpt-6-astra":{name:"GPT-6 Astra",description:"OpenAI flagship for advanced analysis, software engineering, and agentic work"},"openai/gpt-5.6-sol":{name:"GPT-5.6 Sol",description:"OpenAI flagship for complex reasoning and coding"},"openai/gpt-5.6-terra":{name:"GPT-5.6 Terra",description:"Balanced GPT-5.6 model between flagship and everyday tiers"},"openai/gpt-5.6-luna":{name:"GPT-5.6 Luna",description:"GPT-5.6 series model for general reasoning and coding"},"openai/gpt-5.5":{name:"GPT-5.5",description:"OpenAI frontier model for complex professional workloads"},"google/gemini-3.8-flash":{name:"Gemini 3.8 Flash",description:"Google\u2019s most intelligent Flash model for software and reasoning"},"google/gemini-3.7-flash":{name:"Gemini 3.7 Flash",description:"Google Flash model balancing speed, reasoning, and coding"},"google/gemini-3.5-flash-lite":{name:"Gemini 3.5 Flash Lite",description:"Fast, low-latency Google model for everyday tasks"},"google/gemini-3.1-flash-lite":{name:"Gemini 3.1 Flash Lite",description:"Lightweight Google model for quick, cost-effective work"},"x-ai/grok-4.6":{name:"Grok 4.6",description:"xAI\u2019s smartest model for coding, knowledge work, and STEM"},"x-ai/grok-4.5":{name:"Grok 4.5",description:"xAI model for coding and knowledge-heavy tasks"},"qwen/qwen3.8-max-0902":{name:"Qwen3.8 Max",description:"2.4T-parameter Qwen model for complex coding and reasoning"},"qwen/qwen3.8-27b":{name:"Qwen3.8 27B",description:"Qwen model for general coding and agentic work"},"qwen/qwen3.8-flash":{name:"Qwen3.8 Flash",description:"Fast Qwen model for everyday agentic coding"},"qwen/qwen3.7-plus":{name:"Qwen3.7 Plus",description:"Cost-effective Qwen model with text + image input"},"qwen/qwen3.7-flash":{name:"Qwen3.7 Flash",description:"Fast Qwen model for agentic coding tasks"},"moonshotai/kimi-k3":{name:"Kimi K3",description:"2.8T-parameter multimodal reasoning model from Moonshot AI"},"z-ai/glm-5.3":{name:"GLM-5.3",description:"Large-scale Z.ai reasoning model for complex software engineering"},"z-ai/glm-5.3-flash":{name:"GLM-5.3 Flash",description:"Fast Z.ai GLM model for everyday coding"},"deepseek/deepseek-v4-pro-0813":{name:"DeepSeek V4 Pro",description:"Large mixture-of-experts model for reasoning and coding"},"deepseek/deepseek-v4-flash":{name:"DeepSeek V4 Flash",description:"Sparse MoE model balancing speed and capability"},"deepseek/deepseek-v4-flash-0731":{name:"DeepSeek V4 Flash (fast)",description:"Fast-flash DeepSeek model for quick coding turns"},"deepseek/deepseek-v4-flash-vision-exp":{name:"DeepSeek V4 Flash Vision",description:"Vision-capable DeepSeek model for image and UI work"},"stepfun/step-3.5-flash":{name:"Step 3.5 Flash",description:"StepFun fast model for everyday tasks"},"stepfun/step-3.7-flash":{name:"Step 3.7 Flash",description:"StepFun fast model for agentic coding"},"tencent/hy3":{name:"Tencent Hy3",description:"Tencent hybrid reasoning model for general work"},"minimax/minimax-m3":{name:"MiniMax M3",description:"MiniMax high-capability model for coding and long context"},"xiaomi/mimo-v2.5-pro":{name:"MiMo V2.5 Pro",description:"High-capability long-context agentic coding"},"xiaomi/mimo-v2.5":{name:"MiMo V2.5",description:"Xiaomi general-purpose model for coding and agents"},"meta/muse-spark-1.3":{name:"Muse Spark 1.3",description:"Meta reasoning model for complex agentic work"},"meta/muse-spark-1.2":{name:"Muse Spark 1.2",description:"Meta reasoning model for coding and analysis"},"meta/muse-spark-1.3-contributor":{name:"Muse Spark 1.3 (Contributor)",description:"Meta open-contributor Muse Spark model"}};function Bt(t){let e=ko[t]?.name;return e||(t.includes("/")?t.slice(t.lastIndexOf("/")+1):t).replace(/[-_]/g," ").replace(/\b\w/g,r=>r.toUpperCase())}function xo(t){return ko[t]?.description??"Hosted model available through kpilot"}import{emitKeypressEvents as xa}from"node:readline";var Se={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m"},Fn="\x1B[2K";function Pe(t,e){return`${t}${e}${Se.reset}`}function Ee(t){if(!t.startsWith("/"))return null;let e=t.slice(1);return e.includes(" ")||e.includes(" ")?null:e}function Sa(t){return[t.name,...t.aliases??[]].map(e=>e.toLowerCase())}function So(t,e){let n=e.trim().toLowerCase();if(!n)return[...t];let r=[];for(let o of t){let s=o.name.toLowerCase(),i=-1;Sa(o).includes(n)?i=0:s.startsWith(n)?i=1:s.includes(n)?i=2:o.description.toLowerCase().includes(n)&&(i=3),i>=0&&r.push({entry:o,score:i})}return r.sort((o,s)=>o.score-s.score||o.entry.name.localeCompare(s.entry.name)),r.map(o=>o.entry)}var Jt=class{entries=[];attached=!1;suspended=!1;drawn=0;pending=!1;skipRender=!1;hover=0;current=[];lastQuery=null;pendingSelection=null;savedHistory=null;maxRows;tty;rl;streams;constructor(e,n,r={}){this.rl=e,this.streams=n,this.maxRows=r.maxRows??8,this.tty=!!(n.input.isTTY&&n.output.isTTY)}setEntries(e){this.entries=e,this.current=this.computeMatches(),this.schedule()}attach(){this.attached||!this.tty||(this.attached=!0,xa(this.streams.input),this.streams.input.on("keypress",this.onKeypress),this.rl.on("pause",this.onPause),this.rl.on("resume",this.onResume))}detach(){this.attached&&(this.attached=!1,this.erase(),this.restoreHistory(),this.streams.input.off("keypress",this.onKeypress),this.rl.off("pause",this.onPause),this.rl.off("resume",this.onResume))}takeSelection(){let e=this.pendingSelection;return this.pendingSelection=null,e}onPause=()=>{this.suspended=!0,this.erase()};onResume=()=>{this.suspended=!1,this.schedule()};computeMatches(){let e=Ee(this.rl.line);return e===null?[]:So(this.entries,e)}onKeypress=(e,n)=>{if(!this.suspended){if(n?.name==="return"||n?.name==="enter"||n?.ctrl&&n.name==="c"){if(n.name!=="c"){let r=this.current;r.length>0&&this.hover<r.length&&(this.pendingSelection=r[this.hover]?.name??null)}this.clearAtCursor(),this.skipRender=!0;return}if(n?.ctrl&&n.name==="l"){this.drawn=0,this.schedule();return}if(n?.name==="escape"){this.rl.write?.(null,{ctrl:!0,name:"u"}),this.erase(),this.skipRender=!0;return}if(this.current=this.computeMatches(),(n?.name==="down"||n?.ctrl&&n.name==="n")&&this.current.length>0){this.move(1);return}if((n?.name==="up"||n?.ctrl&&n.name==="p")&&this.current.length>0){this.move(-1);return}this.pendingSelection!==null&&(this.pendingSelection=null),this.schedule()}};move(e){let n=this.current.length;n!==0&&(this.hover=(this.hover+e+n)%n,this.render())}syncHistory(e){try{e&&this.savedHistory===null?(this.savedHistory=[...this.rl.history],this.rl.history.splice(0,this.rl.history.length)):e||this.restoreHistory()}catch{}}restoreHistory(){if(this.savedHistory!==null){try{this.rl.history.splice(0,0,...this.savedHistory)}catch{}this.savedHistory=null}}schedule(){!this.attached||this.suspended||!this.tty||this.pending||(this.pending=!0,setTimeout(()=>{if(this.pending=!1,this.skipRender){this.skipRender=!1,this.lastQuery=Ee(this.rl.line);return}this.render()},0))}render(){if(!this.attached||this.suspended||!this.tty)return;let e=Ee(this.rl.line);if(this.syncHistory(e!==null),e===null){this.erase();return}let n=So(this.entries,e);if(this.current=n,n.length===0){this.hover=0,this.lastQuery=e,this.draw([` ${Pe(Se.dim,"No matching commands")}`]);return}e!==this.lastQuery&&(this.hover=0,this.lastQuery=e),this.hover>=n.length&&(this.hover=n.length-1);let r=Math.max(0,Math.min(this.hover,n.length-this.maxRows)),o=n.slice(r,r+this.maxRows),s=o.map((a,c)=>this.renderRow(a,r+c===this.hover));n.length-o.length>0&&s.push(` ${Pe(Se.dim,`\u2026 ${r+1}-${r+o.length} of ${n.length} \u2014 \u2191/\u2193 to move`)}`),this.draw(s)}renderRow(e,n){let r=`/${e.name}`.padEnd(14),o=n?Pe(Se.green,"\u203A"):" ",s=n?Pe(Se.bold,Pe(Se.cyan,r)):Pe(Se.cyan,r);return` ${o} ${s} ${Pe(Se.dim,e.description)}`}draw(e){if(this.erase(),e.length===0)return;let{output:n}=this.streams;n.write(`\r
21
+ `);for(let r=0;r<e.length;r+=1)n.write(`${Fn}${e[r]}`),r<e.length-1&&n.write(`\r
20
22
  `);n.write(`\x1B[${e.length}A\r`),this.drawn=e.length}erase(){let e=this.drawn;if(this.drawn=0,e===0)return;let{output:n}=this.streams;n.write(`\r
21
- `);for(let r=0;r<e;r+=1)n.write(Dn),r<e-1&&n.write(`\r
22
- `);n.write(`\x1B[${e}A\r`)}clearAtCursor(){let e=this.drawn;if(this.drawn=0,e===0)return;let{output:n}=this.streams;for(let r=0;r<e;r+=1)n.write(Dn),r<e-1&&n.write(`\r
23
- `);e>1&&n.write(`\x1B[${e-1}A\r`)}};import{readFile as ua,stat as da}from"node:fs/promises";import wo from"node:path";var yo="\x1B[?2004h",bo="\x1B[?2004l",ma=200,pa=5e3,fa=5*1024*1024,ga={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp"};function ha(t){if(t.length===0)return null;let n=t.replace(/\r\n|\r/g,`
23
+ `);for(let r=0;r<e;r+=1)n.write(Fn),r<e-1&&n.write(`\r
24
+ `);n.write(`\x1B[${e}A\r`)}clearAtCursor(){let e=this.drawn;if(this.drawn=0,e===0)return;let{output:n}=this.streams;for(let r=0;r<e;r+=1)n.write(Fn),r<e-1&&n.write(`\r
25
+ `);e>1&&n.write(`\x1B[${e-1}A\r`)}};import{readFile as Ta,stat as Pa}from"node:fs/promises";import To from"node:path";var Po="\x1B[?2004h",Eo="\x1B[?2004l",Ea=200,Ra=5e3,Ca=5*1024*1024,Ma={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp"};function $a(t){if(t.length===0)return null;let n=t.replace(/\r\n|\r/g,`
24
26
  `).replace(/\n+$/,"").split(`
25
- `).length;if(n>1)return`[pasted ${n} lines]`;let r=[...t].length;return r>ma?`[pasted ${r} chars]`:null}var qt=class{entries=[];pasted=!1;record(e,n){let r=n??ha(e);return r?(this.entries.push({token:r,text:e}),r):e}markPasted(){this.pasted=!0}get isEmpty(){return!this.pasted&&this.entries.length===0}expand(e){let n=e,r=!1;for(let s of this.entries)n.includes(s.token)&&(n=n.replace(s.token,()=>s.text),r=!0);let o=this.pasted||r;return this.reset(),{text:n,pasted:o}}reset(){this.entries=[],this.pasted=!1}};async function vo(t){let e=t.trim();if(!e||/[\r\n]/.test(e))return{text:t};if(/^data:image\//i.test(e))return{text:e,label:"[pasted image]"};let n=wo.extname(e).toLowerCase(),r=ga[n];if(!r)return{text:t};try{let o=await da(e);if(!o.isFile()||o.size>fa)return{text:t};let s=await ua(e);return{text:`data:${r};base64,${s.toString("base64")}`,label:`[pasted image ${wo.basename(e)}]`}}catch{return{text:t}}}var Jt=class{rl;input;store;options;attached=!1;pasting=!1;buffer="";suspended=[];restoreTimer;constructor(e,n,r,o={}){this.rl=e,this.input=n,this.store=r,this.options=o}attach(){this.attached||(this.attached=!0,this.input.on("keypress",this.onKeypress))}detach(){this.attached&&(this.attached=!1,this.restore(),this.input.off("keypress",this.onKeypress))}onKeypress=(e,n)=>{if(n){if(n.name==="paste-start"){this.beginPaste();return}if(n.name==="paste-end"){this.endPaste();return}this.pasting&&(this.buffer+=n.sequence??e??"")}};beginPaste(){if(!this.pasting){this.pasting=!0,this.buffer="",this.suspended=this.input.listeners("keypress").filter(e=>e!==this.onKeypress);for(let e of this.suspended)this.input.off("keypress",e);this.restoreTimer=setTimeout(()=>this.restore(),pa)}}restore(){this.restoreTimer&&(clearTimeout(this.restoreTimer),this.restoreTimer=void 0);for(let e of this.suspended)this.input.on("keypress",e);this.suspended=[]}async endPaste(){if(!this.pasting)return;let e=this.buffer;this.pasting=!1,this.buffer="",this.restore();let n=this.options.prepare?await this.options.prepare(e):{text:e};this.store.markPasted();let r=this.store.record(n.text,n.label);this.options.placeholder&&this.rl.line===this.options.placeholder&&this.rl.write(null,{ctrl:!0,name:"u"}),this.rl.write(r),this.options.onInsert?.(r)}};var wa=["--yolo","--bypass-permissions","--yes-always","--dangerously-skip-permissions","--auto-accept","--force"];function So(t){return wa.includes(t)}var ko=new Set(["bypass","bypass-permissions","yolo","auto-accept","autoaccept","accept","accept-edits","auto","skip","all"]),xo=new Set(["ask","default","manual","normal","prompt","confirm"]);function To(t){let e=t.trim().toLowerCase();if(ko.has(e))return!0;if(xo.has(e))return!1;let n=[...ko,...xo].join(", ");throw new Error(`--permission-mode must be one of: ${n}.`)}var Te={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",yellow:"\x1B[33m",cyan:"\x1B[36m"};function Ne(t,e,n){return n?`${t}${e}${Te.reset}`:e}function Po(){return process.stdout.isTTY===!0}var jn=`${Ne(Te.cyan,"\u276F",!0)} `,Ln="Ask your question...",ya=2;function Un(t=process.stdout.columns,e=Po()){return Ne(Te.dim,"\u2500".repeat(Math.max(20,Eo(t)-1)),e)}function Eo(t=process.stdout.columns){return typeof t=="number"&&Number.isFinite(t)&&t>0?t:80}function ba(t){return t.replace(/\u001b\[[0-9;]*m/g,"").length}function Ro(t,e=Po()){let n=t.bypass?"type / for commands \xB7 Shift+Tab bypass is ON":"type / for commands \xB7 Shift+Tab bypass",r=t.exitArmed?"Press Ctrl+C again to exit":"Ctrl+C twice to exit",o=" ";return[Ne(Te.dim,o+n,e),Ne(t.exitArmed?Te.yellow:Te.dim,o+r,e)]}var Kt=class{output;rl;active=!1;footer=[];noteText=null;noteTimer;placeholder=null;placeholderPending=!1;constructor(e,n){this.output=e,this.rl=n}get tty(){return this.output.isTTY===!0}columns(){return Eo(this.output.columns)}column(){return(ya+this.rl.cursor)%this.columns()+1}suppressed(){return Re(this.rl.line)!==null}belowLines(){let e=[Un(this.columns(),this.tty),...this.footer];return this.noteText&&e.push(this.noteText),e}paint(){if(!this.active||!this.tty||this.suppressed())return;let e=this.belowLines();this.output.write(`
27
+ `).length;if(n>1)return`[pasted ${n} lines]`;let r=[...t].length;return r>Ea?`[pasted ${r} chars]`:null}var Kt=class{entries=[];pasted=!1;record(e,n){let r=n??$a(e);return r?(this.entries.push({token:r,text:e}),r):e}markPasted(){this.pasted=!0}get isEmpty(){return!this.pasted&&this.entries.length===0}expand(e){let n=e,r=!1;for(let s of this.entries)n.includes(s.token)&&(n=n.replace(s.token,()=>s.text),r=!0);let o=this.pasted||r;return this.reset(),{text:n,pasted:o}}reset(){this.entries=[],this.pasted=!1}};async function Ro(t){let e=t.trim();if(!e||/[\r\n]/.test(e))return{text:t};if(/^data:image\//i.test(e))return{text:e,label:"[pasted image]"};let n=To.extname(e).toLowerCase(),r=Ma[n];if(!r)return{text:t};try{let o=await Pa(e);if(!o.isFile()||o.size>Ca)return{text:t};let s=await Ta(e);return{text:`data:${r};base64,${s.toString("base64")}`,label:`[pasted image ${To.basename(e)}]`}}catch{return{text:t}}}var Wt=class{rl;input;store;options;attached=!1;pasting=!1;buffer="";suspended=[];restoreTimer;constructor(e,n,r,o={}){this.rl=e,this.input=n,this.store=r,this.options=o}attach(){this.attached||(this.attached=!0,this.input.on("keypress",this.onKeypress))}detach(){this.attached&&(this.attached=!1,this.restore(),this.input.off("keypress",this.onKeypress))}onKeypress=(e,n)=>{if(n){if(n.name==="paste-start"){this.beginPaste();return}if(n.name==="paste-end"){this.endPaste();return}this.pasting&&(this.buffer+=n.sequence??e??"")}};beginPaste(){if(!this.pasting){this.pasting=!0,this.buffer="",this.suspended=this.input.listeners("keypress").filter(e=>e!==this.onKeypress);for(let e of this.suspended)this.input.off("keypress",e);this.restoreTimer=setTimeout(()=>this.restore(),Ra)}}restore(){this.restoreTimer&&(clearTimeout(this.restoreTimer),this.restoreTimer=void 0);for(let e of this.suspended)this.input.on("keypress",e);this.suspended=[]}async endPaste(){if(!this.pasting)return;let e=this.buffer;this.pasting=!1,this.buffer="",this.restore();let n=this.options.prepare?await this.options.prepare(e):{text:e};this.store.markPasted();let r=this.store.record(n.text,n.label);this.options.placeholder&&this.rl.line===this.options.placeholder&&this.rl.write(null,{ctrl:!0,name:"u"}),this.rl.write(r),this.options.onInsert?.(r)}};var _a=["--yolo","--bypass-permissions","--yes-always","--dangerously-skip-permissions","--auto-accept","--force"];function $o(t){return _a.includes(t)}var Co=new Set(["bypass","bypass-permissions","yolo","auto-accept","autoaccept","accept","accept-edits","auto","skip","all"]),Mo=new Set(["ask","default","manual","normal","prompt","confirm"]);function _o(t){let e=t.trim().toLowerCase();if(Co.has(e))return!0;if(Mo.has(e))return!1;let n=[...Co,...Mo].join(", ");throw new Error(`--permission-mode must be one of: ${n}.`)}var me={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",yellow:"\x1B[33m",cyan:"\x1B[36m"},Aa=`${me.bold}${me.cyan}`;function Re(t,e,n){return n?`${t}${e}${me.reset}`:e}function qn(){return process.stdout.isTTY===!0}var Ht=`${Re(me.cyan,"\u276F",!0)} `,Bn="Ask your question...",Ao=2;function Jn(t=process.stdout.columns,e=qn()){return Re(me.dim,"\u2500".repeat(Math.max(20,zt(t)-1)),e)}function zt(t=process.stdout.columns){return typeof t=="number"&&Number.isFinite(t)&&t>0?t:80}function Kn(t){return t.replace(/\u001b\[[0-9;]*m/g,"").length}function Oo(t,e=process.stdout.columns){return t?1+Math.max(1,Math.ceil(Kn(t)/zt(e))):1}function Io(t){return`\x1B[${t+1}A\r\x1B[0J`}function Do(t,e={}){let n=zt(e.columns),r=e.color??qn(),o=Math.max(1,Math.ceil((Ao+Kn(t))/n));return`\x1B[${(e.rowsAbove??0)+o}A\r\x1B[0J${Ht}${Re(Aa,t,r)}
28
+ `}function jo(t,e=qn()){let n=t.bypass?"type / for commands \xB7 Shift+Tab bypass is ON":"type / for commands \xB7 Shift+Tab bypass",r=t.exitArmed?"Press Ctrl+C again to exit":"Ctrl+C twice to exit",o=" ";return[Re(me.dim,o+n,e),Re(t.exitArmed?me.yellow:me.dim,o+r,e)]}var Gt=class{output;rl;active=!1;footer=[];noteText=null;noteTimer;placeholder=null;placeholderPending=!1;constructor(e,n){this.output=e,this.rl=n}get tty(){return this.output.isTTY===!0}columns(){return zt(this.output.columns)}column(){return(Ao+this.rl.cursor)%this.columns()+1}suppressed(){return Ee(this.rl.line)!==null}belowLines(){let e=[Jn(this.columns(),this.tty),...this.footer];return this.noteText&&e.push(this.noteText),e}paint(){if(!this.active||!this.tty||this.suppressed())return;let e=this.belowLines();e.length!==0&&this.output.write(`
26
29
  \x1B[0J${e.join(`
27
- `)}\x1B[${e.length}A\x1B[${this.column()}G`)}setFooter(e){this.footer=e.filter(n=>n.length>0),this.paint()}note(e){!this.active||!this.tty||this.suppressed()||(this.noteText=Ne(Te.dim,` ${e}`,this.tty),this.paint(),this.noteTimer&&clearTimeout(this.noteTimer),this.noteTimer=setTimeout(()=>{this.noteText=null,this.paint()},2500),this.noteTimer.unref?.())}showPlaceholder(e){this.placeholder=e,this.placeholderPending=!0,!(!this.active||!this.tty||this.suppressed())&&this.drawPlaceholder()}drawPlaceholder(){this.placeholder!==null&&this.output.write(`${Ne(Te.dim,this.placeholder,!0)}\x1B[${ba(this.placeholder)}D`)}syncPlaceholder(){if(!(!this.placeholderPending||this.placeholder===null||!this.tty)){if(this.rl.line.length>0){this.placeholderPending=!1,this.output.write(`\r\x1B[2K${jn}${this.rl.line}\x1B[${this.column()}G`);return}this.drawPlaceholder()}}clearPlaceholder(){this.placeholder=null,this.placeholderPending=!1}rewind(){!this.active||!this.tty||this.suppressed()||this.output.write("\x1B[1A\x1B[2K\r")}clear(){try{this.rl.write(null,{ctrl:!0,name:"u"})}catch{}}begin(){this.active=!0,this.paint()}end(){this.active=!1,this.noteText=null,this.noteTimer&&(clearTimeout(this.noteTimer),this.noteTimer=void 0)}};import{emitKeypressEvents as va}from"node:readline";var ka=1e4;function Fn(){let t=new Error("Stopped by user");return t.name="AbortError",t}var Nn=class{active=null;installed=!1;stopped=null;stream;constructor(e=process.stdin){this.stream=e}install(){this.installed||!this.stream.isTTY||(this.installed=!0,va(this.stream),this.stream.on("keypress",this.onKeypress))}onKeypress=(e,n)=>{this.handleKey(n)};handleKey(e){return!e||e.name!=="escape"?!1:this.stop("Esc")}noteStop(e){this.stopped={reason:e,at:Date.now()}}get stopReason(){return!this.stopped||Date.now()-this.stopped.at>ka?null:this.stopped.reason}stop(e){let n=this.active;return!n||n.signal.aborted?!1:(this.stopped={reason:e,at:Date.now()},n.abort(Fn()),!0)}get running(){return this.active!==null&&!this.active.signal.aborted}begin(e){this.install(),this.active=e,this.stopped=null;let n=this.stream.isRaw;try{this.stream.setRawMode?.(!0),this.stream.isPaused?.()&&this.stream.resume?.()}catch{}let r=!1;return()=>{if(!r){r=!0,this.active===e&&(this.active=null);try{this.stream.setRawMode?.(n??!1)}catch{}}}}},st=new Nn;function Bn(t){let e=new Set;for(let n of t.split(/\r?\n/))if(n.startsWith("+++ b/"))e.add(n.slice(6));else if(n.startsWith("diff --git ")){let r=/diff --git a\/(.+) b\/(.+)/.exec(n.trim());r?.[1]&&e.add(r[1])}return[...e]}function Co(t){return`'${t.replace(/'/g,"'\\''")}'`}import Ea from"node:path";import{mkdir as $o,readdir as Kn,rename as xa,rm as qn,stat as _o}from"node:fs/promises";import Ce from"node:path";var E=".kpilot",Ao=".konsolepilot";async function Mo(t){try{return await _o(t),!0}catch{return!1}}async function Oo(t){try{return(await _o(t)).isDirectory()}catch{return!1}}async function Jn(t){return await Oo(t)?(await Kn(t)).length===0:!1}async function Sa(t,e){if(await Mo(t)&&!await Mo(e)){await $o(Ce.dirname(e),{recursive:!0});try{await xa(t,e)}catch(n){throw(n&&typeof n=="object"&&"code"in n?String(n.code):"")==="EXDEV"?new Error(`Cannot migrate ${t} to ${e} across filesystems. Move .konsolepilot into .kpilot manually.`):n}}}async function Wt(t){let e=Ce.resolve(t),n=Ce.join(e,Ao),r=Ce.join(e,E);if(await $o(r,{recursive:!0}),!await Oo(n))return{migrated:!1};let o=await Kn(n);for(let s of o)await Sa(Ce.join(n,s),Ce.join(r,s));if(await Jn(n))await qn(n,{recursive:!0,force:!0});else{let s=await Kn(n);for(let i of s){let a=Ce.join(n,i);await Jn(a)&&await qn(a,{recursive:!0,force:!0})}await Jn(n)&&await qn(n,{recursive:!0,force:!0})}return{migrated:!0}}function Ta(t,e="value"){if(typeof t!="object"||t===null||Array.isArray(t))throw new Error(`${e} must be a JSON object.`);return t}function U(t,e,n={}){let r=t[e];if(typeof r!="string")throw new Error(`"${e}" must be a string.`);if(!n.allowEmpty&&r.trim().length===0)throw new Error(`"${e}" cannot be empty.`);if(n.maximumLength&&r.length>n.maximumLength)throw new Error(`"${e}" exceeds ${n.maximumLength} characters.`);return r}function X(t,e){let n=t[e];if(n!==void 0){if(typeof n!="string")throw new Error(`"${e}" must be a string.`);return n}}function Me(t,e,n){let r=t[e];if(r===void 0)return n;if(typeof r!="boolean")throw new Error(`"${e}" must be a boolean.`);return r}function te(t,e,n,r,o){let s=t[e];if(s===void 0)return n;if(typeof s!="number"||!Number.isInteger(s))throw new Error(`"${e}" must be an integer.`);if(s<r||s>o)throw new Error(`"${e}" must be between ${r} and ${o}.`);return s}function Io(t,e="JSON"){let n;try{n=JSON.parse(t)}catch(r){let o=r instanceof Error?r.message:String(r);throw new Error(`${e} is invalid: ${o}`)}return Ta(n,e)}function Pa(t){try{return JSON.parse(t&&t.trim()?t:"{}"),!0}catch{return!1}}function me(t){let e=new Set,n=[];for(let o of t){if(o.role==="assistant"&&o.tool_calls?.length){let s=[],i=[];for(let a of o.tool_calls){if(Pa(a.function.arguments)){s.push(a);continue}e.add(a.id),i.push(a.function.name||"unknown_tool")}if(s.length===0){let a=i.length?`[Dropped invalid tool call(s): ${i.join(", ")}. Prefer replace_in_file or write_file with content_b64.]`:"[Dropped invalid tool call.]";n.push({role:"assistant",content:[o.content?.trim(),a].filter(Boolean).join(`
30
+ `)}\x1B[${e.length}A\x1B[${this.column()}G`)}setFooter(e){this.footer=e.filter(n=>n.length>0),this.paint()}note(e){!this.active||!this.tty||this.suppressed()||(this.noteText=Re(me.dim,` ${e}`,this.tty),this.paint(),this.noteTimer&&clearTimeout(this.noteTimer),this.noteTimer=setTimeout(()=>{this.noteText=null,this.paint()},2500),this.noteTimer.unref?.())}showPlaceholder(e){this.placeholder=e,this.placeholderPending=!0,!(!this.active||!this.tty||this.suppressed())&&this.drawPlaceholder()}drawPlaceholder(){this.placeholder!==null&&this.output.write(`${Re(me.dim,this.placeholder,!0)}\x1B[${Kn(this.placeholder)}D`)}syncPlaceholder(){if(!(!this.placeholderPending||this.placeholder===null||!this.tty)){if(this.rl.line.length>0){this.placeholderPending=!1,this.output.write(`\r\x1B[2K${Ht}${this.rl.line}\x1B[${this.column()}G`);return}this.drawPlaceholder()}}clearPlaceholder(){this.placeholder=null,this.placeholderPending=!1}rewind(){!this.active||!this.tty||this.suppressed()||this.output.write("\x1B[1A\x1B[2K\r")}clear(){try{this.rl.write(null,{ctrl:!0,name:"u"})}catch{}}begin(){this.active=!0,this.paint()}end(){this.active=!1,this.noteText=null,this.noteTimer&&(clearTimeout(this.noteTimer),this.noteTimer=void 0)}};import{emitKeypressEvents as Oa}from"node:readline";var Ia=1e4;function Gn(){let t=new Error("Stopped by user");return t.name="AbortError",t}var Wn=class{active=null;stopped=null;stream;constructor(e=process.stdin){this.stream=e}install(){if(!this.stream.isTTY)return;Oa(this.stream),(this.stream.listeners?.("keypress")??[]).includes(this.onKeypress)||this.stream.on("keypress",this.onKeypress)}onKeypress=(e,n)=>{this.handleKey(n)};handleKey(e){if(!e)return!1;let n=e.name==="escape"||e.sequence==="\x1B",r=e.ctrl===!0&&(e.name==="c"||e.sequence==="");return!n&&!r?!1:this.stop(n?"Esc":"Ctrl+C")}noteStop(e){this.stopped={reason:e,at:Date.now()}}get stopReason(){return!this.stopped||Date.now()-this.stopped.at>Ia?null:this.stopped.reason}stop(e){let n=this.active;return!n||n.signal.aborted?!1:(this.stopped={reason:e,at:Date.now()},n.abort(Gn()),!0)}get running(){return this.active!==null&&!this.active.signal.aborted}begin(e){this.install(),this.active=e,this.stopped=null;let n=this.stream.isRaw;try{this.stream.setRawMode?.(!0),this.stream.resume?.()}catch{}let r=!1;return()=>{if(!r){r=!0,this.active===e&&(this.active=null);try{this.stream.setRawMode?.(n??!1)}catch{}}}}},ct=new Wn;function Hn(t){let e=new Set;for(let n of t.split(/\r?\n/))if(n.startsWith("+++ b/"))e.add(n.slice(6));else if(n.startsWith("diff --git ")){let r=/diff --git a\/(.+) b\/(.+)/.exec(n.trim());r?.[1]&&e.add(r[1])}return[...e]}function Lo(t){return`'${t.replace(/'/g,"'\\''")}'`}import Na from"node:path";import{mkdir as No,readdir as Yn,rename as Da,rm as zn,stat as Fo}from"node:fs/promises";import Ce from"node:path";var E=".kpilot",qo=".konsolepilot";async function Uo(t){try{return await Fo(t),!0}catch{return!1}}async function Bo(t){try{return(await Fo(t)).isDirectory()}catch{return!1}}async function Vn(t){return await Bo(t)?(await Yn(t)).length===0:!1}async function ja(t,e){if(await Uo(t)&&!await Uo(e)){await No(Ce.dirname(e),{recursive:!0});try{await Da(t,e)}catch(n){throw(n&&typeof n=="object"&&"code"in n?String(n.code):"")==="EXDEV"?new Error(`Cannot migrate ${t} to ${e} across filesystems. Move .konsolepilot into .kpilot manually.`):n}}}async function Vt(t){let e=Ce.resolve(t),n=Ce.join(e,qo),r=Ce.join(e,E);if(await No(r,{recursive:!0}),!await Bo(n))return{migrated:!1};let o=await Yn(n);for(let s of o)await ja(Ce.join(n,s),Ce.join(r,s));if(await Vn(n))await zn(n,{recursive:!0,force:!0});else{let s=await Yn(n);for(let i of s){let a=Ce.join(n,i);await Vn(a)&&await zn(a,{recursive:!0,force:!0})}await Vn(n)&&await zn(n,{recursive:!0,force:!0})}return{migrated:!0}}function La(t,e="value"){if(typeof t!="object"||t===null||Array.isArray(t))throw new Error(`${e} must be a JSON object.`);return t}function F(t,e,n={}){let r=t[e];if(typeof r!="string")throw new Error(`"${e}" must be a string.`);if(!n.allowEmpty&&r.trim().length===0)throw new Error(`"${e}" cannot be empty.`);if(n.maximumLength&&r.length>n.maximumLength)throw new Error(`"${e}" exceeds ${n.maximumLength} characters.`);return r}function X(t,e){let n=t[e];if(n!==void 0){if(typeof n!="string")throw new Error(`"${e}" must be a string.`);return n}}function Me(t,e,n){let r=t[e];if(r===void 0)return n;if(typeof r!="boolean")throw new Error(`"${e}" must be a boolean.`);return r}function ne(t,e,n,r,o){let s=t[e];if(s===void 0)return n;if(typeof s!="number"||!Number.isInteger(s))throw new Error(`"${e}" must be an integer.`);if(s<r||s>o)throw new Error(`"${e}" must be between ${r} and ${o}.`);return s}function Jo(t,e="JSON"){let n;try{n=JSON.parse(t)}catch(r){let o=r instanceof Error?r.message:String(r);throw new Error(`${e} is invalid: ${o}`)}return La(n,e)}function Ua(t){try{return JSON.parse(t&&t.trim()?t:"{}"),!0}catch{return!1}}function pe(t){let e=new Set,n=[];for(let o of t){if(o.role==="assistant"&&o.tool_calls?.length){let s=[],i=[];for(let a of o.tool_calls){if(Ua(a.function.arguments)){s.push(a);continue}e.add(a.id),i.push(a.function.name||"unknown_tool")}if(s.length===0){let a=i.length?`[Dropped invalid tool call(s): ${i.join(", ")}. Prefer replace_in_file or write_file with content_b64.]`:"[Dropped invalid tool call.]";n.push({role:"assistant",content:[o.content?.trim(),a].filter(Boolean).join(`
28
31
 
29
- `)||a});continue}n.push({role:"assistant",content:o.content,tool_calls:s});continue}o.role==="tool"&&e.has(o.tool_call_id)||n.push(o)}let r=new Set;for(let o of n)if(o.role==="assistant"&&o.tool_calls)for(let s of o.tool_calls)r.add(s.id);return n.filter(o=>o.role!=="tool"||r.has(o.tool_call_id))}function Ra(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"plan"}function Ca(t=new Date){return t.toISOString().slice(0,16).replace(/[:T]/g,"").replace(/-/g,"")}function Do(t,e,n=new Date){return Ea.join(t,E,"plans",`${Ra(e)}-${Ca(n)}.md`)}import{readFile as Ma,stat as $a}from"node:fs/promises";import _a from"node:path";var Aa=[".kpilot/logbook/project.md",".kpilot/logbook/learnings.md",".kpilot/instructions.md","KPILOT.md","AGENTS.md","KONSOLEPILOT.md",".kpilot/understanding.md",".kpilot/learnings.md"],Oa=8e3,Ia=50,Da={"AGENTS.md":1500,"KPILOT.md":2e3,"KONSOLEPILOT.md":2e3};async function ja(t){try{return await $a(t),!0}catch{return!1}}async function La(t){let e=[],n=0;for(let r of Aa){let o=_a.join(t,r);if(!await ja(o))continue;let s=await Ma(o,"utf8"),i=Oa-n;if(i<=0)break;let a=Da[r]??i,c=s.slice(0,Math.min(i,a));e.push(`## ${r}
32
+ `)||a});continue}n.push({role:"assistant",content:o.content,tool_calls:s});continue}o.role==="tool"&&e.has(o.tool_call_id)||n.push(o)}let r=new Set;for(let o of n)if(o.role==="assistant"&&o.tool_calls)for(let s of o.tool_calls)r.add(s.id);return n.filter(o=>o.role!=="tool"||r.has(o.tool_call_id))}function Fa(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"plan"}function qa(t=new Date){return t.toISOString().slice(0,16).replace(/[:T]/g,"").replace(/-/g,"")}function Ko(t,e,n=new Date){return Na.join(t,E,"plans",`${Fa(e)}-${qa(n)}.md`)}function Wo(t){let n=(t.split(/\r?\n/).find(r=>r.trim())??"").replace(/^\s*(?:title|name|session)\s*[:\-–—]\s*/i,"").replace(/[`"“”'‘’*_#]+/g,"").replace(/\s+/g," ").trim().replace(/[.,;:!?\-–—]+$/,"").trim();return Ba(n)}function Ba(t){if(!t)return"";let e=t.split(" ").slice(0,8).join(" ");if(e.length<=60)return e;let n=e.slice(0,60),r=n.lastIndexOf(" ");return`${(r>60/2?n.slice(0,r):n).trim()}\u2026`}function Ja(t){let n=(t.split(/\r?\n/).find(r=>r.trim())??"").replace(/`{1,3}[^`]*`{1,3}/g," ").replace(/\[([^\]]+)\]\([^)]*\)/g,"$1").replace(/\s+/g," ").trim();return Wo(n)||"New session"}async function Go(t,e,n={}){let r=Ja(e);try{let o=await t.complete({messages:[{role:"system",content:"You name coding sessions. Reply with a title of at most 6 words describing what the request is for. No quotes, no trailing punctuation, no explanation."},{role:"user",content:`Request:
33
+
34
+ ${e.slice(0,1500)}`}],tools:[]},{signal:n.signal});return Wo(o.message.content??"")||r}catch{return r}}import{readFile as Ka,stat as Wa}from"node:fs/promises";import Ga from"node:path";var Ha=[".kpilot/logbook/project.md",".kpilot/logbook/learnings.md",".kpilot/instructions.md","KPILOT.md","AGENTS.md","KONSOLEPILOT.md",".kpilot/understanding.md",".kpilot/learnings.md"],za=8e3,Va=50,Ya={"AGENTS.md":1500,"KPILOT.md":2e3,"KONSOLEPILOT.md":2e3};async function Qa(t){try{return await Wa(t),!0}catch{return!1}}async function Xa(t){let e=[],n=0;for(let r of Ha){let o=Ga.join(t,r);if(!await Qa(o))continue;let s=await Ka(o,"utf8"),i=za-n;if(i<=0)break;let a=Ya[r]??i,c=s.slice(0,Math.min(i,a));e.push(`## ${r}
30
35
  ${c}`),n+=c.length}return e.join(`
31
36
 
32
- `)}function Ua(t){return`You are kpilot, a precise local coding agent operating inside one repository.
37
+ `)}function Za(t){return`You are kpilot, a precise local coding agent operating inside one repository.
33
38
 
34
39
  ${t.mode==="plan"?`You are in PLAN mode \u2014 read-only. Inspect and reason; do not change files or run mutating commands.
35
40
  Produce a concrete, actionable implementation plan for the request:
@@ -84,116 +89,123 @@ ${t.projectInstructions}
84
89
  `:""}
85
90
  ${t.preferenceContext?`Learned coding preferences:
86
91
  ${t.preferenceContext}
87
- `:""}`}var at=class extends Error{constructor(e){super(typeof e=="string"&&e.trim()?`Agent run cancelled: ${e}`:"Agent run cancelled."),this.name="AgentCancelledError"}};function Gt(t){if(t?.aborted)throw new at(t.reason)}function Na(t){let e=t instanceof Error?t.message:String(t);return/parse tool call arguments as JSON|json\.exception\.parse_error|tool call arguments/i.test(e)}var Fa=`Your previous tool call failed because the tool-argument JSON was invalid (usually unescaped quotes/newlines in a raw "content" string).
92
+ `:""}`}var lt=class extends Error{constructor(e){super(typeof e=="string"&&e.trim()?`Agent run cancelled: ${e}`:"Agent run cancelled."),this.name="AgentCancelledError"}};function Yt(t){if(t?.aborted)throw new lt(t.reason)}function ec(t){let e=t instanceof Error?t.message:String(t);return/parse tool call arguments as JSON|json\.exception\.parse_error|tool call arguments/i.test(e)}var tc=`Your previous tool call failed because the tool-argument JSON was invalid (usually unescaped quotes/newlines in a raw "content" string).
88
93
 
89
94
  Retry with ONE of these safer approaches:
90
95
  1. For .env / markdown / plain config: write_file with content set to the raw text (escape newlines as \\n in JSON), OR
91
96
  2. replace_in_file with a short exact old_string and new_string, OR
92
97
  3. For TypeScript/JS with nested quotes only: write_file using content_b64 (real base64 of the UTF-8 file) \u2014 never invent placeholder base64.
93
98
 
94
- Do not keep retrying the same broken content_b64.`,Ba=`Stop. write_file for that path already succeeded earlier in this turn (or was refused as a repeat).
99
+ Do not keep retrying the same broken content_b64.`,nc=`Stop. write_file for that path already succeeded earlier in this turn (or was refused as a repeat).
95
100
  Do NOT call write_file again for the same path. Do NOT invent base64.
96
- If needed, call read_file once to verify, then finish with a short confirmation and no more tools.`;function jo(t){return typeof t.path=="string"?t.path:""}function qa(t){let e=t instanceof Error?t.message:String(t);return/exceeds the available context size|context.?length|context.?window|too many tokens|maximum context/i.test(e)}function Ja(t){let e=t instanceof Error?t.message:String(t),n=/request \((\d+) tokens\) exceeds the available context size \((\d+) tokens\)/i.exec(e);return n?{requestTokens:Number(n[1]),availableTokens:Number(n[2])}:null}function Wn(t){return t?Math.max(1,Math.ceil(t.length/3.5)):0}function Gn(t){return t.role==="assistant"?{role:"assistant",content:t.content,...t.tool_calls?{tool_calls:t.tool_calls.map(e=>({id:e.id,type:e.type,function:{name:e.function.name,arguments:e.function.arguments}}))}:{}}:t.role==="tool"?{role:"tool",tool_call_id:t.tool_call_id,content:t.content}:{role:t.role,content:t.content}}function Fo(t){if(t.role==="assistant"){let e=t.tool_calls?.map(n=>n.function.arguments).join(`
101
+ If needed, call read_file once to verify, then finish with a short confirmation and no more tools.`;function Ho(t){return typeof t.path=="string"?t.path:""}function rc(t){let e=t instanceof Error?t.message:String(t);return/exceeds the available context size|context.?length|context.?window|too many tokens|maximum context/i.test(e)}function oc(t){let e=t instanceof Error?t.message:String(t),n=/request \((\d+) tokens\) exceeds the available context size \((\d+) tokens\)/i.exec(e);return n?{requestTokens:Number(n[1]),availableTokens:Number(n[2])}:null}function Qn(t){return t?Math.max(1,Math.ceil(t.length/3.5)):0}function Xn(t){return t.role==="assistant"?{role:"assistant",content:t.content,...t.tool_calls?{tool_calls:t.tool_calls.map(e=>({id:e.id,type:e.type,function:{name:e.function.name,arguments:e.function.arguments}}))}:{}}:t.role==="tool"?{role:"tool",tool_call_id:t.tool_call_id,content:t.content}:{role:t.role,content:t.content}}function Qo(t){if(t.role==="assistant"){let e=t.tool_calls?.map(n=>n.function.arguments).join(`
97
102
  `)??"";return`${t.content??""}
98
- ${e}`}return t.content??""}function Ht(t){let e=0;for(let n of t)e+=Wn(Fo(n))+8;return e}function it(t,e,n){return t.length<=e?t:`${t.slice(0,Math.max(0,e))}
99
- \u2026[${n}]`}function Bo(t,e){return t.map(n=>n.role==="system"?{role:"system",content:it(n.content,e.systemChars,"system truncated for hub context")}:n.role==="tool"?{role:"tool",tool_call_id:n.tool_call_id,content:it(n.content,e.toolChars,"tool output truncated for hub context")}:n.role==="assistant"&&n.tool_calls?.length?{role:"assistant",content:n.content,tool_calls:n.tool_calls.map(r=>({...r,function:{...r.function,arguments:it(r.function.arguments,e.argumentChars,"args truncated")}}))}:n.role==="user"&&n.content.length>e.systemChars?{role:"user",content:it(n.content,e.systemChars,"user truncated for hub context")}:Gn(n))}function Ka(t){if(t.length<=2)return t;let e=t[0]?.role==="system"?1:0,n=-1;for(let s=t.length-1;s>=e;s-=1)if(t[s]?.role==="user"){n=s;break}if(n<=e)return t;let r=t[e];if(!r)return t;let o=e+1;if(r.role==="assistant"&&r.tool_calls?.length){let s=new Set(r.tool_calls.map(a=>a.id)),i=e+1;for(;i<n&&t[i]?.role==="tool"&&s.has(t[i].tool_call_id);)i+=1;o=i}return o>n?t:[...t.slice(0,e),...t.slice(o)]}function Lo(t,e){let n=t.map(Gn),r=800,o=2e3;for(let s=0;s<8&&Ht(n)>e;s+=1)r=Math.max(240,Math.floor(r*.6)),o=Math.max(600,Math.floor(o*.7)),n=Bo(n,{toolChars:r,systemChars:o,argumentChars:Math.max(200,r)});return n}function Wa(t){return/^(Context reset:|Hub context full|Your previous tool call failed|Stop\. write_file|Tool JSON parse failed)/i.test(t.trim())}function Uo(t){for(let e=t.length-1;e>=0;e-=1){let n=t[e];if(n?.role==="user"&&!Wa(n.content))return n.content}}function Ga(t,e=6){let n=t.filter(r=>r.role==="tool").slice(-e);return n.length===0?"":n.map((r,o)=>{let s=it(r.content,240,"truncated");return`${o+1}. ${s}`}).join(`
100
- `)}function No(t,e){let n=Math.max(1,e.aggressiveness??1),r=(e.reserveOutputTokens??384)*n,o=Wn(e.toolsJson??""),i=e.contextWindowTokens-r-o-96;i<400&&(i=400);let a=n>=2?600:e.contextWindowTokens<=8192?1200:2500,c=n>=2?2200:e.contextWindowTokens<=8192?4e3:8e3,l=Bo(t.map(Gn),{toolChars:a,systemChars:c,argumentChars:Math.min(2e3,a*2)}),u=0;for(;Ht(l)>i&&u<40;){u+=1;let m=Ka(l);if(m.length===l.length){l=Lo(l,i);break}l=m}return Ht(l)>i&&(l=Lo(l,i)),me(l)}var Fe=class{gateway;runtime;permissions;conversation;constructor(e){this.gateway=e.gateway,this.runtime=e.runtime,this.permissions=e.permissions,this.conversation=e.initialMessages?me(e.initialMessages):[]}reset(){this.conversation=[]}restore(e){this.conversation=me(e)}get messages(){return this.conversation}async refreshSystemMessage(e){let n=await La(e.rootDir),r=(e.contextWindowTokens??Number.POSITIVE_INFINITY)<=8192,o=e.preferenceContext,s=n;r&&(s&&s.length>3500&&(s=`${s.slice(0,3500)}
103
+ ${e}`}return t.content??""}function Qt(t){let e=0;for(let n of t)e+=Qn(Qo(n))+8;return e}function Ne(t,e,n){return t.length<=e?t:`${t.slice(0,Math.max(0,e))}
104
+ \u2026[${n}]`}function Xo(t,e){return t.map(n=>n.role==="system"?{role:"system",content:Ne(n.content,e.systemChars,"system truncated for hub context")}:n.role==="tool"?{role:"tool",tool_call_id:n.tool_call_id,content:Ne(n.content,e.toolChars,"tool output truncated for hub context")}:n.role==="assistant"&&n.tool_calls?.length?{role:"assistant",content:n.content,tool_calls:n.tool_calls.map(r=>({...r,function:{...r.function,arguments:Ne(r.function.arguments,e.argumentChars,"args truncated")}}))}:n.role==="user"&&n.content.length>e.systemChars?{role:"user",content:Ne(n.content,e.systemChars,"user truncated for hub context")}:Xn(n))}function sc(t){if(t.length<=2)return t;let e=t[0]?.role==="system"?1:0,n=-1;for(let s=t.length-1;s>=e;s-=1)if(t[s]?.role==="user"){n=s;break}if(n<=e)return t;let r=t[e];if(!r)return t;let o=e+1;if(r.role==="assistant"&&r.tool_calls?.length){let s=new Set(r.tool_calls.map(a=>a.id)),i=e+1;for(;i<n&&t[i]?.role==="tool"&&s.has(t[i].tool_call_id);)i+=1;o=i}return o>n?t:[...t.slice(0,e),...t.slice(o)]}function zo(t,e){let n=t.map(Xn),r=800,o=2e3;for(let s=0;s<8&&Qt(n)>e;s+=1)r=Math.max(240,Math.floor(r*.6)),o=Math.max(600,Math.floor(o*.7)),n=Xo(n,{toolChars:r,systemChars:o,argumentChars:Math.max(200,r)});return n}var Zo="Continue from where you stopped. Check the current state first and do not redo work that is already finished.";function Zn(t){return/^(Context reset:|Hub context full|Your previous tool call failed|Stop\. write_file|Tool JSON parse failed|Continue from where you stopped|Write the project's Logbook entry|The verification command)/i.test(t.trim())}function Vo(t){for(let e=t.length-1;e>=0;e-=1){let n=t[e];if(n?.role==="user"&&!Zn(n.content))return n.content}}function ic(t){let e=[];for(let n=t.length-1;n>=0;n-=1){let r=t[n];if(r?.role!=="user")break;Zn(r.content)||e.unshift(r.content)}return e}function ac(t,e){if(t.length===0)return"";let n=t.map((r,o)=>`${o+1}. ${Ne(r.replace(/\s+/g," ").trim(),300,"\u2026")}`).join(`
105
+ `);return e?[`Unfinished request(s) from this session that were never answered (oldest first):
106
+ ${n}`,'The user asked you to resume. Complete the oldest unfinished request first, then any that follow, opening with a short line such as "Now let me complete the previous answer\u2026".'].join(`
107
+
108
+ `):[`Earlier request(s) in this session that were interrupted before you answered them (oldest first):
109
+ ${n}`,'Answer the current request below first. Then complete the unfinished request(s) above, opening that part with a short line such as "Now let me complete the previous answer\u2026". If the current request is a follow-up to or part of an earlier one, treat them as a single task instead.'].join(`
110
+
111
+ `)}function cc(t,e=6){let n=t.filter(r=>r.role==="tool").slice(-e);return n.length===0?"":n.map((r,o)=>{let s=Ne(r.content,240,"truncated");return`${o+1}. ${s}`}).join(`
112
+ `)}function Yo(t,e){let n=Math.max(1,e.aggressiveness??1),r=(e.reserveOutputTokens??384)*n,o=Qn(e.toolsJson??""),i=e.contextWindowTokens-r-o-96;i<400&&(i=400);let a=n>=2?600:e.contextWindowTokens<=8192?1200:2500,c=n>=2?2200:e.contextWindowTokens<=8192?4e3:8e3,l=Xo(t.map(Xn),{toolChars:a,systemChars:c,argumentChars:Math.min(2e3,a*2)}),u=0;for(;Qt(l)>i&&u<40;){u+=1;let m=sc(l);if(m.length===l.length){l=zo(l,i);break}l=m}return Qt(l)>i&&(l=zo(l,i)),pe(l)}var Fe=class{gateway;runtime;permissions;conversation;constructor(e){this.gateway=e.gateway,this.runtime=e.runtime,this.permissions=e.permissions,this.conversation=e.initialMessages?pe(e.initialMessages):[]}reset(){this.conversation=[]}restore(e){this.conversation=pe(e)}get messages(){return this.conversation}async refreshSystemMessage(e){let n=await Xa(e.rootDir),r=(e.contextWindowTokens??Number.POSITIVE_INFINITY)<=8192,o=e.preferenceContext,s=n;r&&(s&&s.length>3500&&(s=`${s.slice(0,3500)}
101
113
  \u2026[project instructions truncated for hub context]`),o&&o.length>600&&(o=`${o.slice(0,600)}
102
- \u2026[preferences truncated for hub context]`));let i={role:"system",content:Ua({rootDir:e.rootDir,mode:e.mode,projectInstructions:s,preferenceContext:o})};this.conversation[0]?.role==="system"?this.conversation[0]=i:this.conversation.unshift(i)}toolResultCharCap(e){return e===void 0?4e3:e<=8192?1200:e<=16384?2e3:4e3}async run(e){if(!e.prompt.trim())throw new Error("Prompt cannot be empty.");if(e.maxSteps!==void 0&&e.maxSteps<1)throw new Error("maxSteps must be at least 1.");let n=e.maxSteps??Ia;Gt(e.signal),this.conversation=me(this.conversation),await this.refreshSystemMessage(e),Gt(e.signal),this.conversation.push({role:"user",content:[e.volatileContext?.trim(),e.prompt].filter(Boolean).join(`
114
+ \u2026[preferences truncated for hub context]`));let i={role:"system",content:Za({rootDir:e.rootDir,mode:e.mode,projectInstructions:s,preferenceContext:o})};this.conversation[0]?.role==="system"?this.conversation[0]=i:this.conversation.unshift(i)}toolResultCharCap(e){return e===void 0?4e3:e<=8192?1200:e<=16384?2e3:4e3}async run(e){if(!e.prompt.trim())throw new Error("Prompt cannot be empty.");if(e.maxSteps!==void 0&&e.maxSteps<1)throw new Error("maxSteps must be at least 1.");let n=e.maxSteps??Va;Yt(e.signal),this.conversation=pe(this.conversation);let r=ic(this.conversation);await this.refreshSystemMessage(e),Yt(e.signal),this.conversation.push({role:"user",content:[e.volatileContext?.trim(),ac(r,Zn(e.prompt)),e.prompt].filter(Boolean).join(`
103
115
 
104
- `)});let r={inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0},o=new Set(["read_file","list_files","search_text","git_status","git_diff","workspace_summary"]),s=new Map,i=new Set(["write_file","replace_in_file","make_directory","delete_path","shell"]),a=0,c=0,l=e.contextWindowTokens,u=new Map,m=new Map,d=0,f=0,w=!1,x=this.runtime.definitions(),P=JSON.stringify(x),S=async b=>{c+=1;let A=Uo(this.conversation)??e.prompt,O=Ga(this.conversation);this.conversation=[],await this.refreshSystemMessage({...e,contextWindowTokens:l}),this.conversation.push({role:"user",content:A}),O&&this.conversation.push({role:"user",content:`Context reset: hub window was full. Continue without redoing finished work.
116
+ `)});let o={inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0},s=new Set(["read_file","list_files","search_text","git_status","git_diff","workspace_summary"]),i=new Map,a=new Set(["write_file","replace_in_file","make_directory","delete_path","shell"]),c=0,l=0,u=e.contextWindowTokens,m=new Map,d=new Map,p=0,y=0,S=!1,x=this.runtime.definitions(),k=JSON.stringify(x),R=async _=>{l+=1;let I=Vo(this.conversation)??e.prompt,j=cc(this.conversation);this.conversation=[],await this.refreshSystemMessage({...e,contextWindowTokens:u}),this.conversation.push({role:"user",content:I}),j&&this.conversation.push({role:"user",content:`Context reset: hub window was full. Continue without redoing finished work.
105
117
  Recent tool results:
106
- ${O}`}),l&&(this.conversation=No(this.conversation,{contextWindowTokens:l,toolsJson:P,aggressiveness:2})),await e.onEvent?.({type:"assistant_text",text:`${b} Context reset (${c}/2)\u2026
107
- `})};for(let b=1;b<=n;b+=1){Gt(e.signal),await e.onEvent?.({type:"step",current:b,maximum:n});let A=!1,O;if(e.maxTotalTokens){let T=r.inputTokens+r.outputTokens+Ht(this.conversation)+Wn(P);if(T>e.maxTotalTokens)throw new Error(`Per-run token budget exceeded (projected ${T}/${e.maxTotalTokens}).`)}try{this.conversation=me(this.conversation);let h=l?No(this.conversation,{contextWindowTokens:l,toolsJson:P,aggressiveness:1}):this.conversation;O=await this.gateway.complete({messages:h,tools:x},{signal:e.signal,onTextDelta:async T=>{A=!0,await e.onEvent?.({type:"assistant_delta",delta:T})},onReasoningDelta:async T=>{A=!0,await e.onEvent?.({type:"reasoning_delta",delta:T})}})}catch(h){if(Na(h)&&a<2){a+=1,this.conversation=me(this.conversation),await e.onEvent?.({type:"assistant_text",text:`Tool JSON parse failed; cleaned history and guiding a safer retry (${a}/2).
108
- `}),this.conversation.push({role:"user",content:Fa});continue}if(qa(h)&&c<2){let T=Ja(h);T&&(l=T.availableTokens),await S("Hub context full."),b-=1;continue}throw h}let L=O.message,B=O.usage?.inputTokens??0,y=O.usage?.outputTokens??0,p=O.usage?.cacheReadTokens??0,g=O.usage?.cacheWriteTokens??0;if(r.inputTokens+=B,r.outputTokens+=y,r.cacheReadTokens+=p,r.cacheWriteTokens+=g,await e.onEvent?.({type:"usage",model:O.model,inputTokens:B,outputTokens:y,...p?{cacheReadTokens:p}:{},...g?{cacheWriteTokens:g}:{}}),this.conversation.push(L),e.maxTotalTokens&&r.inputTokens+r.outputTokens>e.maxTotalTokens)throw new Error(`Per-run token budget exceeded (${r.inputTokens+r.outputTokens}/${e.maxTotalTokens}).`);!A&&L.content?.trim()&&await e.onEvent?.({type:"assistant_text",text:L.content});let k=L.tool_calls??[];if(k.length===0)return{answer:L.content?.trim()||"[The model returned no text.]",messages:[...this.conversation],steps:b,usage:r};for(let h of k){Gt(e.signal);let T;try{T=Io(h.function.arguments||"{}",`Arguments for ${h.function.name}`)}catch(Y){let ot=Y instanceof Error?Y.message:String(Y),xe={role:"tool",tool_call_id:h.id,content:JSON.stringify({ok:!1,output:`${ot}. For .env/plain text use write_file with content; for TS/JS with nested quotes use content_b64 or prefer replace_in_file.`})};this.conversation.push(xe);continue}if(h.function.name==="write_file"){let Y=jo(T),ot=(m.get(Y)??0)+1;if(m.set(Y,ot),(u.get(Y)??0)>=1&&ot>=2){let Xr={ok:!0,output:`Refusing repeated write_file to ${Y||"(missing path)"}: already succeeded earlier this turn. Stop retrying. Use read_file once only if needed, then finish.`};await e.onEvent?.({type:"tool_start",call:h,args:T}),await e.onEvent?.({type:"tool_result",call:h,result:Xr}),this.conversation.push({role:"tool",tool_call_id:h.id,content:JSON.stringify(Xr)}),d<2&&(d+=1,this.conversation.push({role:"user",content:Ba}));continue}}await e.onEvent?.({type:"tool_start",call:h,args:T});let G=await this.permissions.authorize(h.function.name,T,e.mode,e.approvalHandler,{bypassPermissions:e.bypassPermissions});if(await e.onEvent?.({type:"permission",request:G,approved:G.approved}),!G.approved){this.conversation.push({role:"tool",tool_call_id:h.id,content:JSON.stringify({ok:!1,output:`Permission denied: ${G.reason}`,permission:G.category})});continue}let V=`${h.function.name}:${h.function.arguments}`;if(o.has(h.function.name)&&s.has(V)){let Y=s.get(V);if(this.conversation.some(xe=>xe.role==="tool"&&xe.tool_call_id===Y)){let xe={ok:!0,output:"Unchanged: this is an identical repeat of an earlier call whose result is already above. Use it directly."};await e.onEvent?.({type:"tool_result",call:h,result:xe}),this.conversation.push({role:"tool",tool_call_id:h.id,content:JSON.stringify(xe)});continue}}let ae=await this.runtime.execute(h.function.name,T,{rootDir:e.rootDir,mode:e.mode,signal:e.signal,...e.onEvent?{onOutput:Y=>{e.onEvent?.({type:"tool_output",call:h,chunk:Y})}}:{}});if(o.has(h.function.name)&&ae.ok&&s.set(V,h.id),ae.ok&&i.has(h.function.name)&&s.clear(),await e.onEvent?.({type:"tool_result",call:h,result:ae}),ae.ok){if(f=0,h.function.name==="write_file"){let Y=jo(T);u.set(Y,(u.get(Y)??0)+1)}}else f+=1;if(f>=12)throw new Error(`Agent stopped after ${f} consecutive tool failures.`);f>=6&&!w&&(w=!0,this.conversation.push({role:"user",content:"Six consecutive tool calls have failed. Stop retrying, explain what is blocking you, and report what you have so far."}));let de=JSON.stringify(ae),ke=this.toolResultCharCap(l),Hi=de.length<=ke?de:`${de.slice(0,ke)}
109
- \u2026[truncated ${de.length-ke} chars to fit local hub context]`;this.conversation.push({role:"tool",tool_call_id:h.id,content:Hi})}}let C=e.maxSteps===void 0?"internal step backstop":`${e.maxSteps}-step`;throw new Error(`Agent stopped after reaching the ${C} safety limit.`)}async compact(e){let n=this.conversation.length,r=this.conversation.find(l=>l.role==="system"),o=Uo(this.conversation)??"Continue the current task.",s=this.conversation.filter(l=>l.role!=="system").map(l=>Fo(l)).join(`
118
+ ${j}`}),u&&(this.conversation=Yo(this.conversation,{contextWindowTokens:u,toolsJson:k,aggressiveness:2})),await e.onEvent?.({type:"assistant_text",text:`${_} Context reset (${l}/2)\u2026
119
+ `})};for(let _=1;_<=n;_+=1){Yt(e.signal),await e.onEvent?.({type:"step",current:_,maximum:n});let I=!1,j;if(e.maxTotalTokens){let O=o.inputTokens+o.outputTokens+Qt(this.conversation)+Qn(k);if(O>e.maxTotalTokens)throw new Error(`Per-run token budget exceeded (projected ${O}/${e.maxTotalTokens}).`)}try{this.conversation=pe(this.conversation);let v=u?Yo(this.conversation,{contextWindowTokens:u,toolsJson:k,aggressiveness:1}):this.conversation;j=await this.gateway.complete({messages:v,tools:x},{signal:e.signal,onTextDelta:async O=>{I=!0,await e.onEvent?.({type:"assistant_delta",delta:O})},onReasoningDelta:async O=>{I=!0,await e.onEvent?.({type:"reasoning_delta",delta:O})}})}catch(v){if(ec(v)&&c<2){c+=1,this.conversation=pe(this.conversation),await e.onEvent?.({type:"assistant_text",text:`Tool JSON parse failed; cleaned history and guiding a safer retry (${c}/2).
120
+ `}),this.conversation.push({role:"user",content:tc});continue}if(rc(v)&&l<2){let O=oc(v);O&&(u=O.availableTokens),await R("Hub context full."),_-=1;continue}throw v}let N=j.message,h=j.usage?.inputTokens??0,f=j.usage?.outputTokens??0,w=j.usage?.cacheReadTokens??0,g=j.usage?.cacheWriteTokens??0;if(o.inputTokens+=h,o.outputTokens+=f,o.cacheReadTokens+=w,o.cacheWriteTokens+=g,await e.onEvent?.({type:"usage",model:j.model,inputTokens:h,outputTokens:f,...w?{cacheReadTokens:w}:{},...g?{cacheWriteTokens:g}:{}}),this.conversation.push(N),e.maxTotalTokens&&o.inputTokens+o.outputTokens>e.maxTotalTokens)throw new Error(`Per-run token budget exceeded (${o.inputTokens+o.outputTokens}/${e.maxTotalTokens}).`);!I&&N.content?.trim()&&await e.onEvent?.({type:"assistant_text",text:N.content});let b=N.tool_calls??[];if(b.length===0)return{answer:N.content?.trim()||"[The model returned no text.]",messages:[...this.conversation],steps:_,usage:o};for(let v of b){Yt(e.signal);let O;try{O=Jo(v.function.arguments||"{}",`Arguments for ${v.function.name}`)}catch(Y){let at=Y instanceof Error?Y.message:String(Y),xe={role:"tool",tool_call_id:v.id,content:JSON.stringify({ok:!1,output:`${at}. For .env/plain text use write_file with content; for TS/JS with nested quotes use content_b64 or prefer replace_in_file.`})};this.conversation.push(xe);continue}if(v.function.name==="write_file"){let Y=Ho(O),at=(d.get(Y)??0)+1;if(d.set(Y,at),(m.get(Y)??0)>=1&&at>=2){let oo={ok:!0,output:`Refusing repeated write_file to ${Y||"(missing path)"}: already succeeded earlier this turn. Stop retrying. Use read_file once only if needed, then finish.`};await e.onEvent?.({type:"tool_start",call:v,args:O}),await e.onEvent?.({type:"tool_result",call:v,result:oo}),this.conversation.push({role:"tool",tool_call_id:v.id,content:JSON.stringify(oo)}),p<2&&(p+=1,this.conversation.push({role:"user",content:nc}));continue}}await e.onEvent?.({type:"tool_start",call:v,args:O});let H=await this.permissions.authorize(v.function.name,O,e.mode,e.approvalHandler,{bypassPermissions:e.bypassPermissions});if(await e.onEvent?.({type:"permission",request:H,approved:H.approved}),!H.approved){this.conversation.push({role:"tool",tool_call_id:v.id,content:JSON.stringify({ok:!1,output:`Permission denied: ${H.reason}`,permission:H.category})});continue}let ce=`${v.function.name}:${v.function.arguments}`;if(s.has(v.function.name)&&i.has(ce)){let Y=i.get(ce);if(this.conversation.some(xe=>xe.role==="tool"&&xe.tool_call_id===Y)){let xe={ok:!0,output:"Unchanged: this is an identical repeat of an earlier call whose result is already above. Use it directly."};await e.onEvent?.({type:"tool_result",call:v,result:xe}),this.conversation.push({role:"tool",tool_call_id:v.id,content:JSON.stringify(xe)});continue}}let te=await this.runtime.execute(v.function.name,O,{rootDir:e.rootDir,mode:e.mode,signal:e.signal,...e.onEvent?{onOutput:Y=>{e.onEvent?.({type:"tool_output",call:v,chunk:Y})}}:{}});if(s.has(v.function.name)&&te.ok&&i.set(ce,v.id),te.ok&&a.has(v.function.name)&&i.clear(),await e.onEvent?.({type:"tool_result",call:v,result:te}),te.ok){if(y=0,v.function.name==="write_file"){let Y=Ho(O);m.set(Y,(m.get(Y)??0)+1)}}else y+=1;if(y>=12)throw new Error(`Agent stopped after ${y} consecutive tool failures.`);y>=6&&!S&&(S=!0,this.conversation.push({role:"user",content:"Six consecutive tool calls have failed. Stop retrying, explain what is blocking you, and report what you have so far."}));let ye=JSON.stringify(te),In=this.toolResultCharCap(u),aa=ye.length<=In?ye:`${ye.slice(0,In)}
121
+ \u2026[truncated ${ye.length-In} chars to fit local hub context]`;this.conversation.push({role:"tool",tool_call_id:v.id,content:aa})}}let P=e.maxSteps===void 0?"internal step backstop":`${e.maxSteps}-step`;throw new Error(`Agent stopped after reaching the ${P} safety limit.`)}async compact(e){let n=this.conversation.length,r=this.conversation.find(l=>l.role==="system"),o=Vo(this.conversation)??"Continue the current task.",s=this.conversation.filter(l=>l.role!=="system").map(l=>Qo(l)).join(`
110
122
 
111
123
  `).slice(-24e3);if(!s.trim())return{before:n,after:n};let a=((await this.gateway.complete({messages:[{role:"system",content:"You compress coding-agent transcripts. Produce a dense brief that preserves the task, key decisions, files changed, exact commands with their outcomes, and remaining work. Plain prose, no preamble, at most 400 words."},{role:"user",content:s}],tools:[]},{signal:e})).message.content??"").trim().slice(0,4e3);if(!a)return{before:n,after:n};let c=[];return r&&c.push({role:"system",content:r.content}),c.push({role:"user",content:`Conversation summary so far (context was compacted):
112
- ${a}`}),c.push({role:"user",content:o}),this.conversation=me(c),{before:n,after:this.conversation.length}}};import{mkdir as Ha,readFile as za,rename as Va,stat as Ya,writeFile as Qa}from"node:fs/promises";import{randomUUID as qo}from"node:crypto";import zn from"node:path";async function Xa(t){try{return await Ya(t),!0}catch{return!1}}async function Hn(t,e){await Ha(zn.dirname(t),{recursive:!0});let n=`${t}.${qo()}.tmp`;await Qa(n,`${JSON.stringify(e,null,2)}
113
- `,"utf8"),await Va(n,t)}function Za(t,e){let n;try{n=JSON.parse(t)}catch(o){throw new Error(`Invalid memory JSON in ${e}: ${o instanceof Error?o.message:String(o)}`)}if(typeof n!="object"||n===null||Array.isArray(n))throw new Error("Memory document must be an object.");let r=n;if(r.schemaVersion!==1||!Array.isArray(r.entries))throw new Error("Unsupported memory document schema.");return r}var zt=class{rootDir;filePath;constructor(e){this.rootDir=zn.resolve(e),this.filePath=zn.join(this.rootDir,E,"memory.json")}async readDocument(){return await Xa(this.filePath)?Za(await za(this.filePath,"utf8"),this.filePath):{schemaVersion:1,entries:[]}}async list(){return[...(await this.readDocument()).entries].sort((n,r)=>r.updatedAt.localeCompare(n.updatedAt))}async add(e,n="user"){let r=e.trim();if(!r)throw new Error("Memory text cannot be empty.");if(r.length>4e3)throw new Error("A memory entry cannot exceed 4,000 characters.");let o=await this.readDocument(),s=o.entries.find(c=>c.text.toLowerCase()===r.toLowerCase());if(s)return s;let i=new Date().toISOString(),a={id:qo(),text:r,createdAt:i,updatedAt:i,source:n};return o.entries.push(a),await Hn(this.filePath,o),a}async remove(e){let n=await this.readDocument(),r=n.entries.filter(s=>s.id.startsWith(e));if(r.length===0)throw new Error(`Memory entry not found: ${e}`);if(r.length>1)throw new Error(`Memory entry prefix is ambiguous: ${e}`);let o=r[0];return n.entries=n.entries.filter(s=>s.id!==o.id),await Hn(this.filePath,n),o}async clear(){let n=(await this.readDocument()).entries.length;return await Hn(this.filePath,{schemaVersion:1,entries:[]}),n}async renderForPrompt(e=12e3){let n=await this.list(),r=[],o=0;for(let s of n){let i=`- ${s.text}`;if(o+i.length+1>e)break;r.push(i),o+=i.length+1}return r.join(`
114
- `)}};import{mkdir as ec,readFile as tc,rename as nc,stat as rc,writeFile as oc}from"node:fs/promises";import{randomUUID as Jo}from"node:crypto";import Ko from"node:path";async function sc(t){try{return await rc(t),!0}catch{return!1}}async function ic(t){try{return JSON.parse(await tc(t,"utf8"))}catch{return{schemaVersion:1,todos:[]}}}async function Vt(t,e){await ec(Ko.dirname(t),{recursive:!0});let n=`${t}.${Jo()}.tmp`;await oc(n,`${JSON.stringify(e,null,2)}
115
- `,"utf8"),await nc(n,t)}var Yt=class{rootDir;filePath;constructor(e){this.rootDir=e,this.filePath=Ko.join(e,E,"todos.json")}async list(){return await sc(this.filePath)?(await ic(this.filePath)).todos??[]:[]}async open(){return(await this.list()).filter(e=>!e.completed)}async add(e){let n=e.trim();if(!n)throw new Error("Todo text is required.");let r=await this.list(),o={id:Jo(),text:n,completed:!1,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return r.push(o),await Vt(this.filePath,{schemaVersion:1,todos:r}),o}async complete(e){let n=await this.list(),r=s=>s.id.startsWith(e),o=n.find(r);if(!o)throw new Error(`No todo matches "${e}".`);return o.completed=!0,o.updatedAt=new Date().toISOString(),await Vt(this.filePath,{schemaVersion:1,todos:n}),o}async remove(e){let n=await this.list(),r=i=>i.id.startsWith(e),o=n.findIndex(r);if(o===-1)throw new Error(`No todo matches "${e}".`);let[s]=n.splice(o,1);return await Vt(this.filePath,{schemaVersion:1,todos:n}),s}async clear(){let n=(await this.list()).length;return await Vt(this.filePath,{schemaVersion:1,todos:[]}),n}async renderForPrompt(){let e=await this.open();return e.length===0?"":`Open project todos (track with /todo, mark done with /todo done <id>):
124
+ ${a}`}),c.push({role:"user",content:o}),this.conversation=pe(c),{before:n,after:this.conversation.length}}};import{mkdir as lc,readFile as uc,rename as dc,stat as mc,writeFile as pc}from"node:fs/promises";import{randomUUID as es}from"node:crypto";import tr from"node:path";async function fc(t){try{return await mc(t),!0}catch{return!1}}async function er(t,e){await lc(tr.dirname(t),{recursive:!0});let n=`${t}.${es()}.tmp`;await pc(n,`${JSON.stringify(e,null,2)}
125
+ `,"utf8"),await dc(n,t)}function gc(t,e){let n;try{n=JSON.parse(t)}catch(o){throw new Error(`Invalid memory JSON in ${e}: ${o instanceof Error?o.message:String(o)}`)}if(typeof n!="object"||n===null||Array.isArray(n))throw new Error("Memory document must be an object.");let r=n;if(r.schemaVersion!==1||!Array.isArray(r.entries))throw new Error("Unsupported memory document schema.");return r}var Xt=class{rootDir;filePath;constructor(e){this.rootDir=tr.resolve(e),this.filePath=tr.join(this.rootDir,E,"memory.json")}async readDocument(){return await fc(this.filePath)?gc(await uc(this.filePath,"utf8"),this.filePath):{schemaVersion:1,entries:[]}}async list(){return[...(await this.readDocument()).entries].sort((n,r)=>r.updatedAt.localeCompare(n.updatedAt))}async add(e,n="user"){let r=e.trim();if(!r)throw new Error("Memory text cannot be empty.");if(r.length>4e3)throw new Error("A memory entry cannot exceed 4,000 characters.");let o=await this.readDocument(),s=o.entries.find(c=>c.text.toLowerCase()===r.toLowerCase());if(s)return s;let i=new Date().toISOString(),a={id:es(),text:r,createdAt:i,updatedAt:i,source:n};return o.entries.push(a),await er(this.filePath,o),a}async remove(e){let n=await this.readDocument(),r=n.entries.filter(s=>s.id.startsWith(e));if(r.length===0)throw new Error(`Memory entry not found: ${e}`);if(r.length>1)throw new Error(`Memory entry prefix is ambiguous: ${e}`);let o=r[0];return n.entries=n.entries.filter(s=>s.id!==o.id),await er(this.filePath,n),o}async clear(){let n=(await this.readDocument()).entries.length;return await er(this.filePath,{schemaVersion:1,entries:[]}),n}async renderForPrompt(e=12e3){let n=await this.list(),r=[],o=0;for(let s of n){let i=`- ${s.text}`;if(o+i.length+1>e)break;r.push(i),o+=i.length+1}return r.join(`
126
+ `)}};import{mkdir as hc,readFile as wc,rename as yc,stat as bc,writeFile as vc}from"node:fs/promises";import{randomUUID as ts}from"node:crypto";import ns from"node:path";async function kc(t){try{return await bc(t),!0}catch{return!1}}async function xc(t){try{return JSON.parse(await wc(t,"utf8"))}catch{return{schemaVersion:1,todos:[]}}}async function Zt(t,e){await hc(ns.dirname(t),{recursive:!0});let n=`${t}.${ts()}.tmp`;await vc(n,`${JSON.stringify(e,null,2)}
127
+ `,"utf8"),await yc(n,t)}var en=class{rootDir;filePath;constructor(e){this.rootDir=e,this.filePath=ns.join(e,E,"todos.json")}async list(){return await kc(this.filePath)?(await xc(this.filePath)).todos??[]:[]}async open(){return(await this.list()).filter(e=>!e.completed)}async add(e){let n=e.trim();if(!n)throw new Error("Todo text is required.");let r=await this.list(),o={id:ts(),text:n,completed:!1,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return r.push(o),await Zt(this.filePath,{schemaVersion:1,todos:r}),o}async complete(e){let n=await this.list(),r=s=>s.id.startsWith(e),o=n.find(r);if(!o)throw new Error(`No todo matches "${e}".`);return o.completed=!0,o.updatedAt=new Date().toISOString(),await Zt(this.filePath,{schemaVersion:1,todos:n}),o}async remove(e){let n=await this.list(),r=i=>i.id.startsWith(e),o=n.findIndex(r);if(o===-1)throw new Error(`No todo matches "${e}".`);let[s]=n.splice(o,1);return await Zt(this.filePath,{schemaVersion:1,todos:n}),s}async clear(){let n=(await this.list()).length;return await Zt(this.filePath,{schemaVersion:1,todos:[]}),n}async renderForPrompt(){let e=await this.open();return e.length===0?"":`Open project todos (track with /todo, mark done with /todo done <id>):
116
128
  `+e.map(n=>`- [ ] ${n.text} (${n.id.slice(0,8)})`).join(`
117
- `)}};import{mkdir as ac,readFile as Wo,readdir as cc,rename as lc,rm as uc,stat as dc,writeFile as mc}from"node:fs/promises";import{randomUUID as Go}from"node:crypto";import Qt from"node:path";async function pc(t){try{return await dc(t),!0}catch{return!1}}async function fc(t,e){await ac(Qt.dirname(t),{recursive:!0});let n=`${t}.${Go()}.tmp`;await mc(n,`${JSON.stringify(e,null,2)}
118
- `,"utf8"),await lc(n,t)}var Xt=class{rootDir;constructor(e){this.rootDir=e}dir(e){return Qt.join(this.rootDir,E,"checkpoints",e)}file(e,n){return Qt.join(this.dir(e),`${n}.json`)}async save(e,n,r){let o=Go(),s={id:o,label:(r??"").trim()||`checkpoint ${new Date().toISOString()}`,createdAt:new Date().toISOString(),sessionId:e,messages:n};return await fc(this.file(e,o),s),s}async list(e){let n=this.dir(e);if(!await pc(n))return[];let r=(await cc(n)).filter(s=>s.endsWith(".json")),o=[];for(let s of r)try{let i=JSON.parse(await Wo(Qt.join(n,s),"utf8"));o.push({id:i.id,label:i.label,createdAt:i.createdAt,sessionId:i.sessionId})}catch{}return o.sort((s,i)=>s.createdAt.localeCompare(i.createdAt))}async load(e,n){let o=(await this.list(e)).find(s=>s.id.startsWith(n));if(!o)throw new Error(`No checkpoint matches "${n}".`);return JSON.parse(await Wo(this.file(e,o.id),"utf8"))}async remove(e,n){let o=(await this.list(e)).find(s=>s.id.startsWith(n));if(!o)throw new Error(`No checkpoint matches "${n}".`);await uc(this.file(e,o.id),{force:!0})}};function Pe(t){return t.replace(/\/+$/,"")}function Vn(t){let e=typeof t=="string"&&t.trim()?`: ${t}`:"",n=new Error(`Model request cancelled${e}`);return n.name="AbortError",n}function gc(t,e){let n=new AbortController,r=setTimeout(()=>n.abort("request timeout"),t),o=()=>n.abort(e?.reason);return e?.aborted?n.abort(e.reason):e?.addEventListener("abort",o,{once:!0}),{signal:n.signal,cleanup:()=>{clearTimeout(r),e?.removeEventListener("abort",o)}}}async function pe(t,e,n,r){let o=gc(r,n.signal);try{let s=await fetch(t,{...e,signal:o.signal}),i=await s.text(),a={};if(i)try{a=JSON.parse(i)}catch{throw new Error(`Model endpoint returned non-JSON data (HTTP ${s.status}): ${i.slice(0,500)}`)}if(!s.ok){let c=a?.error?.message??a?.message??a?.detail??`HTTP ${s.status}`;throw new Error(`Model request failed: ${c}`)}return a}catch(s){throw n.signal?.aborted?Vn(n.signal.reason):s}finally{o.cleanup()}}async function fe(t,e){t.content&&await e.onTextDelta?.(t.content)}function Be(t){let e=[],n=o=>{typeof o=="string"&&o.trim()&&e.push(o)};for(let o of t?.content??[])(o?.type==="thinking"||o?.type==="redacted_thinking")&&n(o.thinking);for(let o of t?.message?.content??[])if(typeof o=="string")n(o);else if(o?.type==="text"){let s=typeof o.text=="string"?o.text:JSON.stringify(o.text??"");n(s.replace(/\s*\(reasoning:\s*([\s\S]*?)\)\s*$/,"$1"))}else if(o?.type==="reasoning"){let s=typeof o.summary=="string"?o.summary:Array.isArray(o.summary)?o.summary.map(i=>typeof i?.text=="string"?i.text:"").join(""):"";n(s)}for(let o of t?.candidates?.[0]?.content?.parts??[])typeof o?.thought=="string"&&n(o.thought);let r=t?.usage;if(r){let o=typeof r.reasoning_tokens=="number"?`${r.reasoning_tokens} reasoning tokens`:"";o&&e.push(o)}return e.join(`
119
- `)}async function ge(t,e){if(!e.onReasoningDelta)return;let n=Be(t);n&&await e.onReasoningDelta(n)}function Ho(t){return t.map(e=>({type:"function",name:e.function.name,description:e.function.description,parameters:e.function.parameters,strict:e.function.strict}))}function zo(t){let e=[];for(let n of t){if(n.role==="system"||n.role==="user"){e.push({role:n.role,content:n.content});continue}if(n.role==="assistant"){n.content&&e.push({role:"assistant",content:n.content});for(let r of n.tool_calls??[])e.push({type:"function_call",call_id:r.id,name:r.function.name,arguments:r.function.arguments});continue}e.push({type:"function_call_output",call_id:n.tool_call_id,output:n.content})}return e}function Vo(t){let e=[],n=[];for(let o of t?.output??[])if(o?.type==="message")for(let s of o.content??[])s?.type==="output_text"&&typeof s.text=="string"&&e.push(s.text);else o?.type==="function_call"&&typeof o.name=="string"&&n.push({id:o.call_id??o.id??`tool_call_${n.length+1}`,type:"function",function:{name:o.name,arguments:typeof o.arguments=="string"?o.arguments:JSON.stringify(o.arguments??{})}});return{message:{role:"assistant",content:e.length?e.join(""):null,...n.length?{tool_calls:n}:{}},model:t?.model,usage:{inputTokens:t?.usage?.input_tokens,outputTokens:t?.usage?.output_tokens}}}function hc(t){return t.map(e=>e.role==="tool"?`tool(${e.tool_call_id}): ${e.content}`:e.role==="assistant"&&e.tool_calls?.length?`assistant: ${e.content??""}
129
+ `)}};import{mkdir as Sc,readFile as rs,readdir as Tc,rename as Pc,rm as Ec,stat as Rc,writeFile as Cc}from"node:fs/promises";import{randomUUID as os}from"node:crypto";import tn from"node:path";async function Mc(t){try{return await Rc(t),!0}catch{return!1}}async function $c(t,e){await Sc(tn.dirname(t),{recursive:!0});let n=`${t}.${os()}.tmp`;await Cc(n,`${JSON.stringify(e,null,2)}
130
+ `,"utf8"),await Pc(n,t)}var nn=class{rootDir;constructor(e){this.rootDir=e}dir(e){return tn.join(this.rootDir,E,"checkpoints",e)}file(e,n){return tn.join(this.dir(e),`${n}.json`)}async save(e,n,r){let o=os(),s={id:o,label:(r??"").trim()||`checkpoint ${new Date().toISOString()}`,createdAt:new Date().toISOString(),sessionId:e,messages:n};return await $c(this.file(e,o),s),s}async list(e){let n=this.dir(e);if(!await Mc(n))return[];let r=(await Tc(n)).filter(s=>s.endsWith(".json")),o=[];for(let s of r)try{let i=JSON.parse(await rs(tn.join(n,s),"utf8"));o.push({id:i.id,label:i.label,createdAt:i.createdAt,sessionId:i.sessionId})}catch{}return o.sort((s,i)=>s.createdAt.localeCompare(i.createdAt))}async load(e,n){let o=(await this.list(e)).find(s=>s.id.startsWith(n));if(!o)throw new Error(`No checkpoint matches "${n}".`);return JSON.parse(await rs(this.file(e,o.id),"utf8"))}async remove(e,n){let o=(await this.list(e)).find(s=>s.id.startsWith(n));if(!o)throw new Error(`No checkpoint matches "${n}".`);await Ec(this.file(e,o.id),{force:!0})}};function Te(t){return t.replace(/\/+$/,"")}function nr(t){let e=typeof t=="string"&&t.trim()?`: ${t}`:"",n=new Error(`Model request cancelled${e}`);return n.name="AbortError",n}function _c(t,e){let n=new AbortController,r=setTimeout(()=>n.abort("request timeout"),t),o=()=>n.abort(e?.reason);return e?.aborted?n.abort(e.reason):e?.addEventListener("abort",o,{once:!0}),{signal:n.signal,cleanup:()=>{clearTimeout(r),e?.removeEventListener("abort",o)}}}async function fe(t,e,n,r){let o=_c(r,n.signal);try{let s=await fetch(t,{...e,signal:o.signal}),i=await s.text(),a={};if(i)try{a=JSON.parse(i)}catch{throw new Error(`Model endpoint returned non-JSON data (HTTP ${s.status}): ${i.slice(0,500)}`)}if(!s.ok){let c=a?.error?.message??a?.message??a?.detail??`HTTP ${s.status}`;throw new Error(`Model request failed: ${c}`)}return a}catch(s){throw n.signal?.aborted?nr(n.signal.reason):s}finally{o.cleanup()}}async function ge(t,e){t.content&&await e.onTextDelta?.(t.content)}function qe(t){let e=[],n=o=>{typeof o=="string"&&o.trim()&&e.push(o)};for(let o of t?.content??[])(o?.type==="thinking"||o?.type==="redacted_thinking")&&n(o.thinking);for(let o of t?.message?.content??[])if(typeof o=="string")n(o);else if(o?.type==="text"){let s=typeof o.text=="string"?o.text:JSON.stringify(o.text??"");n(s.replace(/\s*\(reasoning:\s*([\s\S]*?)\)\s*$/,"$1"))}else if(o?.type==="reasoning"){let s=typeof o.summary=="string"?o.summary:Array.isArray(o.summary)?o.summary.map(i=>typeof i?.text=="string"?i.text:"").join(""):"";n(s)}for(let o of t?.candidates?.[0]?.content?.parts??[])typeof o?.thought=="string"&&n(o.thought);let r=t?.usage;if(r){let o=typeof r.reasoning_tokens=="number"?`${r.reasoning_tokens} reasoning tokens`:"";o&&e.push(o)}return e.join(`
131
+ `)}async function he(t,e){if(!e.onReasoningDelta)return;let n=qe(t);n&&await e.onReasoningDelta(n)}function ss(t){return t.map(e=>({type:"function",name:e.function.name,description:e.function.description,parameters:e.function.parameters,strict:e.function.strict}))}function is(t){let e=[];for(let n of t){if(n.role==="system"||n.role==="user"){e.push({role:n.role,content:n.content});continue}if(n.role==="assistant"){n.content&&e.push({role:"assistant",content:n.content});for(let r of n.tool_calls??[])e.push({type:"function_call",call_id:r.id,name:r.function.name,arguments:r.function.arguments});continue}e.push({type:"function_call_output",call_id:n.tool_call_id,output:n.content})}return e}function as(t){let e=[],n=[];for(let o of t?.output??[])if(o?.type==="message")for(let s of o.content??[])s?.type==="output_text"&&typeof s.text=="string"&&e.push(s.text);else o?.type==="function_call"&&typeof o.name=="string"&&n.push({id:o.call_id??o.id??`tool_call_${n.length+1}`,type:"function",function:{name:o.name,arguments:typeof o.arguments=="string"?o.arguments:JSON.stringify(o.arguments??{})}});return{message:{role:"assistant",content:e.length?e.join(""):null,...n.length?{tool_calls:n}:{}},model:t?.model,usage:{inputTokens:t?.usage?.input_tokens,outputTokens:t?.usage?.output_tokens}}}function Ac(t){return t.map(e=>e.role==="tool"?`tool(${e.tool_call_id}): ${e.content}`:e.role==="assistant"&&e.tool_calls?.length?`assistant: ${e.content??""}
120
132
  tool calls: ${JSON.stringify(e.tool_calls)}`:`${e.role}: ${e.content??""}`).join(`
121
133
 
122
- `)}function Yn(t,e){let n=e.map(r=>({name:r.function.name,description:r.function.description,parameters:r.function.parameters}));return["You are acting as a read-only model backend for kpilot.","Answer the latest user request directly. Do not modify files or run commands.","The following tool definitions are informational only; this bridge does not permit tool execution.",JSON.stringify(n),"",hc(t)].join(`
123
- `)}var $e=class{options;constructor(e){if(!e.model.trim())throw new Error("A model name is required.");this.options={...e,baseUrl:Pe(e.baseUrl),model:e.model,timeoutMs:e.timeoutMs??12e4}}async complete(e,n={}){let r=this.options.accessToken??this.options.apiKey,o=await pe(`${this.options.baseUrl}/responses`,{method:"POST",headers:{"content-type":"application/json",...r?{authorization:`Bearer ${r}`}:{},...this.options.headers},body:JSON.stringify({model:this.options.model,input:zo(e.messages),tools:Ho(e.tools),tool_choice:"auto",...this.options.maxOutputTokens===void 0?{}:{max_output_tokens:this.options.maxOutputTokens}})},n,this.options.timeoutMs),s=Vo(o);return await ge(o,n),await fe(s.message,n),s}};function wc(t){let e=t.filter(s=>s.role==="system").map(s=>s.content).join(`
134
+ `)}function rr(t,e){let n=e.map(r=>({name:r.function.name,description:r.function.description,parameters:r.function.parameters}));return["You are acting as a read-only model backend for kpilot.","Answer the latest user request directly. Do not modify files or run commands.","The following tool definitions are informational only; this bridge does not permit tool execution.",JSON.stringify(n),"",Ac(t)].join(`
135
+ `)}var $e=class{options;constructor(e){if(!e.model.trim())throw new Error("A model name is required.");this.options={...e,baseUrl:Te(e.baseUrl),model:e.model,timeoutMs:e.timeoutMs??12e4}}async complete(e,n={}){let r=this.options.accessToken??this.options.apiKey,o=await fe(`${this.options.baseUrl}/responses`,{method:"POST",headers:{"content-type":"application/json",...r?{authorization:`Bearer ${r}`}:{},...this.options.headers},body:JSON.stringify({model:this.options.model,input:is(e.messages),tools:ss(e.tools),tool_choice:"auto",...this.options.maxOutputTokens===void 0?{}:{max_output_tokens:this.options.maxOutputTokens}})},n,this.options.timeoutMs),s=as(o);return await he(o,n),await ge(s.message,n),s}};function Oc(t){let e=t.filter(s=>s.role==="system").map(s=>s.content).join(`
124
136
 
125
- `),n=[],r=new Map;for(let s of t)if(s.role!=="system")if(s.role==="user")n.push({role:"user",content:s.content});else if(s.role==="assistant"){let i=[];s.content&&i.push({type:"text",text:s.content});for(let a of s.tool_calls??[]){r.set(a.id,a.function.name);let c={};try{c=JSON.parse(a.function.arguments)}catch{c={raw:a.function.arguments}}i.push({type:"tool_use",id:a.id,name:a.function.name,input:c})}n.push({role:"assistant",content:i})}else{let i=n[n.length-1],a={type:"tool_result",tool_use_id:s.tool_call_id,content:s.content};i?.role==="user"&&Array.isArray(i.content)?i.content.push(a):n.push({role:"user",content:[a]})}let o=e?[{type:"text",text:e,cache_control:{type:"ephemeral"}}]:void 0;return{...o?{system:o}:{},messages:n}}var ct=class{options;constructor(e){if(!e.apiKey)throw new Error("Anthropic API key is required.");if(!e.model.trim())throw new Error("A model name is required.");this.options={...e,baseUrl:Pe(e.baseUrl??"https://api.anthropic.com"),model:e.model,maxTokens:e.maxOutputTokens??e.maxTokens??16384,anthropicVersion:e.anthropicVersion??"2023-06-01",timeoutMs:e.timeoutMs??12e4}}async complete(e,n={}){let r=wc(e.messages),o=await pe(`${this.options.baseUrl}/v1/messages`,{method:"POST",headers:{"content-type":"application/json","x-api-key":this.options.apiKey,"anthropic-version":this.options.anthropicVersion},body:JSON.stringify({model:this.options.model,max_tokens:this.options.maxTokens,...r,tools:e.tools.map((c,l,u)=>({name:c.function.name,description:c.function.description,input_schema:c.function.parameters,...l===u.length-1?{cache_control:{type:"ephemeral"}}:{}}))})},n,this.options.timeoutMs),s=[],i=[];for(let c of o?.content??[])c?.type==="text"&&typeof c.text=="string"&&s.push(c.text),c?.type==="tool_use"&&typeof c.name=="string"&&i.push({id:c.id??`tool_call_${i.length+1}`,type:"function",function:{name:c.name,arguments:JSON.stringify(c.input??{})}});let a={role:"assistant",content:s.length?s.join(""):null,...i.length?{tool_calls:i}:{}};return await ge(o,n),await fe(a,n),{message:a,model:o?.model,usage:{inputTokens:o?.usage?.input_tokens,outputTokens:o?.usage?.output_tokens,...o?.usage?.cache_read_input_tokens===void 0&&o?.usage?.cache_creation_input_tokens===void 0?{}:{...o.usage.cache_read_input_tokens===void 0?{}:{cacheReadTokens:o.usage.cache_read_input_tokens},...o.usage.cache_creation_input_tokens===void 0?{}:{cacheWriteTokens:o.usage.cache_creation_input_tokens}}}}}};function yc(t){let e=t.filter(o=>o.role==="system").map(o=>o.content).join(`
137
+ `),n=[],r=new Map;for(let s of t)if(s.role!=="system")if(s.role==="user")n.push({role:"user",content:s.content});else if(s.role==="assistant"){let i=[];s.content&&i.push({type:"text",text:s.content});for(let a of s.tool_calls??[]){r.set(a.id,a.function.name);let c={};try{c=JSON.parse(a.function.arguments)}catch{c={raw:a.function.arguments}}i.push({type:"tool_use",id:a.id,name:a.function.name,input:c})}n.push({role:"assistant",content:i})}else{let i=n[n.length-1],a={type:"tool_result",tool_use_id:s.tool_call_id,content:s.content};i?.role==="user"&&Array.isArray(i.content)?i.content.push(a):n.push({role:"user",content:[a]})}let o=e?[{type:"text",text:e,cache_control:{type:"ephemeral"}}]:void 0;return{...o?{system:o}:{},messages:n}}var ut=class{options;constructor(e){if(!e.apiKey)throw new Error("Anthropic API key is required.");if(!e.model.trim())throw new Error("A model name is required.");this.options={...e,baseUrl:Te(e.baseUrl??"https://api.anthropic.com"),model:e.model,maxTokens:e.maxOutputTokens??e.maxTokens??16384,anthropicVersion:e.anthropicVersion??"2023-06-01",timeoutMs:e.timeoutMs??12e4}}async complete(e,n={}){let r=Oc(e.messages),o=await fe(`${this.options.baseUrl}/v1/messages`,{method:"POST",headers:{"content-type":"application/json","x-api-key":this.options.apiKey,"anthropic-version":this.options.anthropicVersion},body:JSON.stringify({model:this.options.model,max_tokens:this.options.maxTokens,...r,tools:e.tools.map((c,l,u)=>({name:c.function.name,description:c.function.description,input_schema:c.function.parameters,...l===u.length-1?{cache_control:{type:"ephemeral"}}:{}}))})},n,this.options.timeoutMs),s=[],i=[];for(let c of o?.content??[])c?.type==="text"&&typeof c.text=="string"&&s.push(c.text),c?.type==="tool_use"&&typeof c.name=="string"&&i.push({id:c.id??`tool_call_${i.length+1}`,type:"function",function:{name:c.name,arguments:JSON.stringify(c.input??{})}});let a={role:"assistant",content:s.length?s.join(""):null,...i.length?{tool_calls:i}:{}};return await he(o,n),await ge(a,n),{message:a,model:o?.model,usage:{inputTokens:o?.usage?.input_tokens,outputTokens:o?.usage?.output_tokens,...o?.usage?.cache_read_input_tokens===void 0&&o?.usage?.cache_creation_input_tokens===void 0?{}:{...o.usage.cache_read_input_tokens===void 0?{}:{cacheReadTokens:o.usage.cache_read_input_tokens},...o.usage.cache_creation_input_tokens===void 0?{}:{cacheWriteTokens:o.usage.cache_creation_input_tokens}}}}}};function Ic(t){let e=t.filter(o=>o.role==="system").map(o=>o.content).join(`
126
138
 
127
- `),n=[],r=new Map;for(let o of t)if(o.role!=="system")if(o.role==="user")n.push({role:"user",parts:[{text:o.content}]});else if(o.role==="assistant"){let s=[];o.content&&s.push({text:o.content});for(let i of o.tool_calls??[]){r.set(i.id,i.function.name);let a={};try{a=JSON.parse(i.function.arguments)}catch{a={raw:i.function.arguments}}s.push({functionCall:{name:i.function.name,args:a}})}n.push({role:"model",parts:s})}else{let s=r.get(o.tool_call_id)??o.tool_call_id,i={output:o.content};try{i=JSON.parse(o.content)}catch{}n.push({role:"user",parts:[{functionResponse:{name:s,response:i}}]})}return{...e?{systemInstruction:{parts:[{text:e}]}}:{},contents:n}}var qe=class{options;constructor(e){if(!e.model.trim())throw new Error("A model name is required.");if(!e.apiKey&&!e.accessToken)throw new Error("Gemini API key or Google access token is required.");if(e.vertex&&(!e.project||!e.location))throw new Error("Vertex AI requires project and location.");this.options={...e,baseUrl:Pe(e.baseUrl??(e.vertex?`https://${e.location}-aiplatform.googleapis.com/v1`:"https://generativelanguage.googleapis.com/v1beta")),model:e.model,vertex:e.vertex??!1,timeoutMs:e.timeoutMs??12e4}}endpoint(){if(this.options.vertex)return`${this.options.baseUrl}/projects/${encodeURIComponent(this.options.project)}/locations/${encodeURIComponent(this.options.location)}/publishers/google/models/${encodeURIComponent(this.options.model)}:generateContent`;let e=this.options.apiKey?`?key=${encodeURIComponent(this.options.apiKey)}`:"";return`${this.options.baseUrl}/models/${encodeURIComponent(this.options.model)}:generateContent${e}`}async complete(e,n={}){let r=yc(e.messages),o=await pe(this.endpoint(),{method:"POST",headers:{"content-type":"application/json",...this.options.accessToken?{authorization:`Bearer ${this.options.accessToken}`}:{}},body:JSON.stringify({...r,tools:e.tools.length?[{functionDeclarations:e.tools.map(l=>({name:l.function.name,description:l.function.description,parameters:l.function.parameters}))}]:void 0,toolConfig:e.tools.length?{functionCallingConfig:{mode:"AUTO"}}:void 0,...this.options.maxOutputTokens===void 0?{}:{generationConfig:{maxOutputTokens:this.options.maxOutputTokens}}})},n,this.options.timeoutMs),s=o?.candidates?.[0]?.content?.parts??[],i=[],a=[];for(let l of s)typeof l?.text=="string"&&i.push(l.text),l?.functionCall?.name&&a.push({id:l.functionCall.id??`tool_call_${a.length+1}`,type:"function",function:{name:l.functionCall.name,arguments:JSON.stringify(l.functionCall.args??{})}});let c={role:"assistant",content:i.length?i.join(""):null,...a.length?{tool_calls:a}:{}};return await ge(o,n),await fe(c,n),{message:c,model:this.options.model,usage:{inputTokens:o?.usageMetadata?.promptTokenCount,outputTokens:o?.usageMetadata?.candidatesTokenCount}}}};var lt=class{options;constructor(e){if(!e.apiKey)throw new Error("Cohere API key is required.");if(!e.model.trim())throw new Error("A model name is required.");this.options={...e,baseUrl:Pe(e.baseUrl??"https://api.cohere.com"),model:e.model,timeoutMs:e.timeoutMs??12e4}}async complete(e,n={}){let r=await pe(`${this.options.baseUrl}/v2/chat`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${this.options.apiKey}`,"x-client-name":"kpilot"},body:JSON.stringify({model:this.options.model,messages:e.messages.map(c=>c.role==="tool"?{role:"tool",tool_call_id:c.tool_call_id,content:c.content}:c.role==="assistant"?{role:"assistant",content:c.content??"",tool_calls:c.tool_calls}:{role:c.role,content:c.content}),tools:e.tools.map(c=>({type:"function",function:{name:c.function.name,description:c.function.description,parameters:c.function.parameters}})),...this.options.maxOutputTokens===void 0?{}:{max_tokens:this.options.maxOutputTokens}})},n,this.options.timeoutMs),o=[];for(let c of r?.message?.content??[])typeof c?.text=="string"?o.push(c.text):typeof c=="string"&&o.push(c);let i=(r?.message?.tool_calls??r?.tool_calls??[]).map((c,l)=>({id:c.id??`tool_call_${l+1}`,type:"function",function:{name:c.function?.name??c.name,arguments:typeof c.function?.arguments=="string"?c.function.arguments:JSON.stringify(c.function?.arguments??c.parameters??{})}})).filter(c=>!!c.function.name),a={role:"assistant",content:o.length?o.join(""):null,...i.length?{tool_calls:i}:{}};return await ge(r,n),await fe(a,n),{message:a,model:this.options.model,usage:{inputTokens:r?.usage?.tokens?.input_tokens??r?.usage?.billed_units?.input_tokens,outputTokens:r?.usage?.tokens?.output_tokens??r?.usage?.billed_units?.output_tokens}}}};import{createHash as bc,createHmac as Qo}from"node:crypto";function Yo(t){return bc("sha256").update(t).digest("hex")}function Zt(t,e){return Qo("sha256",t).update(e).digest()}function vc(t){let e=t.toISOString().replace(/[:-]|\.\d{3}/g,"");return{timestamp:e,day:e.slice(0,8)}}function kc(t,e,n,r=new Date){let{timestamp:o,day:s}=vc(r),a={"content-type":"application/json",host:e.host,"x-amz-date":o,...t.sessionToken?{"x-amz-security-token":t.sessionToken}:{}},c=Object.keys(a).sort(),l=c.map(C=>`${C}:${a[C].trim()}
128
- `).join(""),u=["POST",e.pathname,"",l,c.join(";"),Yo(n)].join(`
129
- `),m=`${s}/${t.region}/bedrock/aws4_request`,d=["AWS4-HMAC-SHA256",o,m,Yo(u)].join(`
130
- `),f=Zt(`AWS4${t.secretAccessKey}`,s),w=Zt(f,t.region),x=Zt(w,"bedrock"),P=Zt(x,"aws4_request"),S=Qo("sha256",P).update(d).digest("hex");return{"content-type":a["content-type"],"x-amz-date":o,...t.sessionToken?{"x-amz-security-token":t.sessionToken}:{},authorization:`AWS4-HMAC-SHA256 Credential=${t.accessKeyId}/${m}, SignedHeaders=${c.join(";")}, Signature=${S}`}}function xc(t){let e=t.filter(r=>r.role==="system").map(r=>r.content).join(`
139
+ `),n=[],r=new Map;for(let o of t)if(o.role!=="system")if(o.role==="user")n.push({role:"user",parts:[{text:o.content}]});else if(o.role==="assistant"){let s=[];o.content&&s.push({text:o.content});for(let i of o.tool_calls??[]){r.set(i.id,i.function.name);let a={};try{a=JSON.parse(i.function.arguments)}catch{a={raw:i.function.arguments}}s.push({functionCall:{name:i.function.name,args:a}})}n.push({role:"model",parts:s})}else{let s=r.get(o.tool_call_id)??o.tool_call_id,i={output:o.content};try{i=JSON.parse(o.content)}catch{}n.push({role:"user",parts:[{functionResponse:{name:s,response:i}}]})}return{...e?{systemInstruction:{parts:[{text:e}]}}:{},contents:n}}var Be=class{options;constructor(e){if(!e.model.trim())throw new Error("A model name is required.");if(!e.apiKey&&!e.accessToken)throw new Error("Gemini API key or Google access token is required.");if(e.vertex&&(!e.project||!e.location))throw new Error("Vertex AI requires project and location.");this.options={...e,baseUrl:Te(e.baseUrl??(e.vertex?`https://${e.location}-aiplatform.googleapis.com/v1`:"https://generativelanguage.googleapis.com/v1beta")),model:e.model,vertex:e.vertex??!1,timeoutMs:e.timeoutMs??12e4}}endpoint(){if(this.options.vertex)return`${this.options.baseUrl}/projects/${encodeURIComponent(this.options.project)}/locations/${encodeURIComponent(this.options.location)}/publishers/google/models/${encodeURIComponent(this.options.model)}:generateContent`;let e=this.options.apiKey?`?key=${encodeURIComponent(this.options.apiKey)}`:"";return`${this.options.baseUrl}/models/${encodeURIComponent(this.options.model)}:generateContent${e}`}async complete(e,n={}){let r=Ic(e.messages),o=await fe(this.endpoint(),{method:"POST",headers:{"content-type":"application/json",...this.options.accessToken?{authorization:`Bearer ${this.options.accessToken}`}:{}},body:JSON.stringify({...r,tools:e.tools.length?[{functionDeclarations:e.tools.map(l=>({name:l.function.name,description:l.function.description,parameters:l.function.parameters}))}]:void 0,toolConfig:e.tools.length?{functionCallingConfig:{mode:"AUTO"}}:void 0,...this.options.maxOutputTokens===void 0?{}:{generationConfig:{maxOutputTokens:this.options.maxOutputTokens}}})},n,this.options.timeoutMs),s=o?.candidates?.[0]?.content?.parts??[],i=[],a=[];for(let l of s)typeof l?.text=="string"&&i.push(l.text),l?.functionCall?.name&&a.push({id:l.functionCall.id??`tool_call_${a.length+1}`,type:"function",function:{name:l.functionCall.name,arguments:JSON.stringify(l.functionCall.args??{})}});let c={role:"assistant",content:i.length?i.join(""):null,...a.length?{tool_calls:a}:{}};return await he(o,n),await ge(c,n),{message:c,model:this.options.model,usage:{inputTokens:o?.usageMetadata?.promptTokenCount,outputTokens:o?.usageMetadata?.candidatesTokenCount}}}};var dt=class{options;constructor(e){if(!e.apiKey)throw new Error("Cohere API key is required.");if(!e.model.trim())throw new Error("A model name is required.");this.options={...e,baseUrl:Te(e.baseUrl??"https://api.cohere.com"),model:e.model,timeoutMs:e.timeoutMs??12e4}}async complete(e,n={}){let r=await fe(`${this.options.baseUrl}/v2/chat`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${this.options.apiKey}`,"x-client-name":"kpilot"},body:JSON.stringify({model:this.options.model,messages:e.messages.map(c=>c.role==="tool"?{role:"tool",tool_call_id:c.tool_call_id,content:c.content}:c.role==="assistant"?{role:"assistant",content:c.content??"",tool_calls:c.tool_calls}:{role:c.role,content:c.content}),tools:e.tools.map(c=>({type:"function",function:{name:c.function.name,description:c.function.description,parameters:c.function.parameters}})),...this.options.maxOutputTokens===void 0?{}:{max_tokens:this.options.maxOutputTokens}})},n,this.options.timeoutMs),o=[];for(let c of r?.message?.content??[])typeof c?.text=="string"?o.push(c.text):typeof c=="string"&&o.push(c);let i=(r?.message?.tool_calls??r?.tool_calls??[]).map((c,l)=>({id:c.id??`tool_call_${l+1}`,type:"function",function:{name:c.function?.name??c.name,arguments:typeof c.function?.arguments=="string"?c.function.arguments:JSON.stringify(c.function?.arguments??c.parameters??{})}})).filter(c=>!!c.function.name),a={role:"assistant",content:o.length?o.join(""):null,...i.length?{tool_calls:i}:{}};return await he(r,n),await ge(a,n),{message:a,model:this.options.model,usage:{inputTokens:r?.usage?.tokens?.input_tokens??r?.usage?.billed_units?.input_tokens,outputTokens:r?.usage?.tokens?.output_tokens??r?.usage?.billed_units?.output_tokens}}}};import{createHash as Dc,createHmac as ls}from"node:crypto";function cs(t){return Dc("sha256").update(t).digest("hex")}function rn(t,e){return ls("sha256",t).update(e).digest()}function jc(t){let e=t.toISOString().replace(/[:-]|\.\d{3}/g,"");return{timestamp:e,day:e.slice(0,8)}}function Lc(t,e,n,r=new Date){let{timestamp:o,day:s}=jc(r),a={"content-type":"application/json",host:e.host,"x-amz-date":o,...t.sessionToken?{"x-amz-security-token":t.sessionToken}:{}},c=Object.keys(a).sort(),l=c.map(R=>`${R}:${a[R].trim()}
140
+ `).join(""),u=["POST",e.pathname,"",l,c.join(";"),cs(n)].join(`
141
+ `),m=`${s}/${t.region}/bedrock/aws4_request`,d=["AWS4-HMAC-SHA256",o,m,cs(u)].join(`
142
+ `),p=rn(`AWS4${t.secretAccessKey}`,s),y=rn(p,t.region),S=rn(y,"bedrock"),x=rn(S,"aws4_request"),k=ls("sha256",x).update(d).digest("hex");return{"content-type":a["content-type"],"x-amz-date":o,...t.sessionToken?{"x-amz-security-token":t.sessionToken}:{},authorization:`AWS4-HMAC-SHA256 Credential=${t.accessKeyId}/${m}, SignedHeaders=${c.join(";")}, Signature=${k}`}}function Uc(t){let e=t.filter(r=>r.role==="system").map(r=>r.content).join(`
131
143
 
132
- `),n=[];for(let r of t)if(r.role!=="system")if(r.role==="user")n.push({role:"user",content:[{text:r.content}]});else if(r.role==="assistant"){let o=[];r.content&&o.push({text:r.content});for(let s of r.tool_calls??[]){let i={};try{i=JSON.parse(s.function.arguments)}catch{i={raw:s.function.arguments}}o.push({toolUse:{toolUseId:s.id,name:s.function.name,input:i}})}n.push({role:"assistant",content:o})}else{let o;try{o={json:JSON.parse(r.content)}}catch{o={text:r.content}}n.push({role:"user",content:[{toolResult:{toolUseId:r.tool_call_id,content:[o]}}]})}return{...e?{system:[{text:e}]}:{},messages:n}}var ut=class{options;constructor(e){if(!e.model.trim())throw new Error("A Bedrock model ID is required.");if(!e.region)throw new Error("AWS region is required.");if(!e.accessKeyId||!e.secretAccessKey)throw new Error("AWS credentials are required.");this.options={...e,model:e.model,region:e.region,accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey,baseUrl:e.baseUrl??`https://bedrock-runtime.${e.region}.amazonaws.com`,timeoutMs:e.timeoutMs??12e4}}async complete(e,n={}){let r=xc(e.messages),o=JSON.stringify({...r,toolConfig:e.tools.length?{tools:e.tools.map(m=>({toolSpec:{name:m.function.name,description:m.function.description,inputSchema:{json:m.function.parameters}}})),toolChoice:{auto:{}}}:void 0,...this.options.maxOutputTokens===void 0?{}:{inferenceConfig:{maxTokens:this.options.maxOutputTokens}}}),s=new URL(`${this.options.baseUrl.replace(/\/+$/,"")}/model/${encodeURIComponent(this.options.model)}/converse`),i=await pe(s.toString(),{method:"POST",headers:kc(this.options,s,o),body:o},n,this.options.timeoutMs),a=i?.output?.message?.content??[],c=[],l=[];for(let m of a)typeof m?.text=="string"&&c.push(m.text),m?.toolUse?.name&&l.push({id:m.toolUse.toolUseId??`tool_call_${l.length+1}`,type:"function",function:{name:m.toolUse.name,arguments:JSON.stringify(m.toolUse.input??{})}});let u={role:"assistant",content:c.length?c.join(""):null,...l.length?{tool_calls:l}:{}};return await ge(i,n),await fe(u,n),{message:u,model:this.options.model,usage:{inputTokens:i?.usage?.inputTokens,outputTokens:i?.usage?.outputTokens}}}};import{spawn as Sc}from"node:child_process";async function Xo(t,e,n,r){return await new Promise((o,s)=>{let i=Sc(t,e,{cwd:n.rootDir,env:{...process.env,...n.environment},stdio:["ignore","pipe","pipe"]}),a="",c="",l=setTimeout(()=>i.kill("SIGTERM"),n.timeoutMs??3e5),u=()=>{i.kill("SIGTERM")};r.signal?.addEventListener("abort",u,{once:!0}),i.stdout?.on("data",m=>{a+=String(m)}),i.stderr?.on("data",m=>{c+=String(m)}),i.on("error",m=>{clearTimeout(l),r.signal?.removeEventListener("abort",u),s(m)}),i.on("close",m=>{clearTimeout(l),r.signal?.removeEventListener("abort",u),r.signal?.aborted?s(Vn(r.signal.reason)):m!==0?s(new Error(`${t} exited with code ${m}: ${c.trim()||a.trim()}`)):o({stdout:a,stderr:c})})})}function Tc(t){let e=t.split(/\r?\n/).filter(Boolean),n=[];for(let r of e)try{let o=JSON.parse(r),s=[o?.item?.text,o?.item?.content,o?.message?.content,o?.message,o?.text,o?.output_text,o?.content];for(let i of s)typeof i=="string"&&i.trim()&&n.push(i.trim())}catch{}return n.at(-1)??t.trim()}var dt=class{options;constructor(e){this.options=e}async complete(e,n={}){let r=Yn(e.messages,e.tools),o=["bash","powershell","list_bash","list_powershell","read_bash","read_powershell","stop_bash","stop_powershell","write_bash","write_powershell","apply_patch","create","edit","list_agents","read_agent","task","write_agent","ask_user","skill","web_fetch"].join(","),s=["-p",r,"-s","--no-ask-user","--allow-tool=read",`--excluded-tools=${o}`,"--disable-builtin-mcps","--no-custom-instructions","--no-experimental","--no-remote","--no-remote-export","--no-auto-update"];this.options.model&&s.push("--model",this.options.model);let{stdout:i}=await Xo(this.options.command||"copilot",s,this.options,n),a=i.trim();if(!a)throw new Error("GitHub Copilot CLI returned no response. Run `copilot login` and verify the subscription.");return await n.onTextDelta?.(a),{message:{role:"assistant",content:a},model:this.options.model}}},mt=class{options;constructor(e){this.options=e}async complete(e,n={}){let r=Yn(e.messages,e.tools),o=["exec","--json","--sandbox","read-only","--skip-git-repo-check"];this.options.model&&o.push("--model",this.options.model),o.push(r);let{stdout:s}=await Xo(this.options.command||"codex",o,this.options,n),i=Tc(s);if(!i)throw new Error("Codex CLI returned no response. Run `codex login` and sign in with ChatGPT.");return await n.onTextDelta?.(i),{message:{role:"assistant",content:i},model:this.options.model}}};var pt=class{baseUrl;options;constructor(e){if(this.options=e,!e.accessToken)throw new Error("kpilot needs an account to continue. Run `kpilot login`.");this.baseUrl=e.baseUrl.replace(/\/+$/,"")}async complete(e,n={}){let r=new AbortController,o=setTimeout(()=>r.abort("request timeout"),this.options.timeoutMs??18e4),s=()=>r.abort(n.signal?.reason);n.signal?.aborted?r.abort(n.signal.reason):n.signal?.addEventListener("abort",s,{once:!0});let i=await this.options.getAccessToken?.()??this.options.accessToken;try{let a=await fetch(`${this.baseUrl}/v1/ai/responses`,{method:"POST",signal:r.signal,headers:{authorization:`Bearer ${i}`,"content-type":"application/json",...this.options.headers},body:JSON.stringify({route:this.options.route??"auto",...this.options.model?{model:this.options.model}:{},messages:e.messages,tools:e.tools})}),c=await a.text(),l;try{l=c?JSON.parse(c):{}}catch{throw new Error(`kpilot endpoint returned a non-JSON response (HTTP ${a.status}). If this persists, re-run \`kpilot login\`.`)}if(!a.ok){let u=typeof l.message=="string"?l.message:typeof l.error?.message=="string"?l.error.message:`kpilot endpoint returned HTTP ${a.status}.`,m=typeof l.detail=="string"?l.detail:void 0,d=l.attempts??l.error?.attempts,f=Array.isArray(d)&&d.length>0?d.map(w=>`${w.model??"?"}: ${w.error??"unknown error"}`).join(" | "):void 0;throw new Error([u,m&&m!==u?m:void 0,f].filter(w=>!!(w&&w.trim())).join(" "))}if(l.message?.content&&n.onTextDelta&&await n.onTextDelta(l.message.content),n.onReasoningDelta){let u=Be(l);u&&await n.onReasoningDelta(u)}return l}finally{clearTimeout(o),n.signal?.removeEventListener("abort",s)}}};import{spawn as Pc}from"node:child_process";function Zo(t){if(!t||t.message?.role!=="assistant")throw new Error("External agent response must contain an assistant message.");return t}var ft=class{options;constructor(e){if(this.options=e,!e.command&&!e.endpoint)throw new Error("Bring-your-own-agent requires either command or endpoint.")}async complete(e,n={}){return this.options.endpoint?await this.completeHttp(e,n):await this.completeCommand(e,n)}async completeHttp(e,n){let r=await fetch(this.options.endpoint,{method:"POST",signal:n.signal,headers:{"content-type":"application/json",...this.options.accessToken?{authorization:`Bearer ${this.options.accessToken}`}:{}},body:JSON.stringify({protocol:"kpilot-agent-v1",request:e})}),o=await r.text(),s;try{s=JSON.parse(o)}catch{throw new Error(`External agent returned non-JSON data (HTTP ${r.status}).`)}if(!r.ok)throw new Error(s.message??`External agent returned HTTP ${r.status}.`);let i=Zo(s);if(n.onReasoningDelta){let a=Be(s);a&&await n.onReasoningDelta(a)}return i.message.content&&n.onTextDelta&&await n.onTextDelta(i.message.content),i}async completeCommand(e,n){return await new Promise((r,o)=>{let s=Pc(this.options.command,this.options.args??[],{cwd:this.options.rootDir??process.cwd(),env:process.env,stdio:["pipe","pipe","pipe"]}),i=setTimeout(()=>s.kill("SIGTERM"),this.options.timeoutMs??18e4),a="",c="",l=()=>{s.kill("SIGTERM")};n.signal?.addEventListener("abort",l,{once:!0}),s.stdout?.on("data",u=>{a+=String(u)}),s.stderr?.on("data",u=>{c+=String(u)}),s.once("error",o),s.once("close",async u=>{if(clearTimeout(i),n.signal?.removeEventListener("abort",l),n.signal?.aborted)return o(n.signal.reason??new Error("External agent cancelled."));if(u!==0)return o(new Error(`External agent exited with code ${u}: ${c.trim().slice(0,1e3)}`));try{let m=Zo(JSON.parse(a.trim()));if(n.onReasoningDelta){let d=Be(m);d&&await n.onReasoningDelta(d)}m.message.content&&n.onTextDelta&&await n.onTextDelta(m.message.content),r(m)}catch(m){o(m)}}),s.stdin?.end(`${JSON.stringify({protocol:"kpilot-agent-v1",request:e})}
133
- `)})}};import{spawn as Ec}from"node:child_process";var es=[{id:"openai-compatible",name:"OpenAI-compatible Chat Completions",protocol:"POST /v1/chat/completions",auth:["none","api-key","bearer-token"],nativeTools:!0,streaming:!0},{id:"openai-responses",name:"OpenAI Responses API",protocol:"POST /v1/responses",auth:["api-key","bearer-token"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://api.openai.com/v1"},{id:"anthropic",name:"Anthropic Claude API",protocol:"POST /v1/messages",auth:["api-key"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://api.anthropic.com"},{id:"gemini",name:"Google Gemini Developer API",protocol:"models.generateContent",auth:["api-key"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta"},{id:"xai",name:"xAI Inference API",protocol:"POST /v1/responses",auth:["api-key"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://api.x.ai/v1"},{id:"mistral",name:"Mistral AI API",protocol:"POST /v1/chat/completions",auth:["api-key"],nativeTools:!0,streaming:!0,defaultBaseUrl:"https://api.mistral.ai/v1"},{id:"cohere",name:"Cohere v2 Chat API",protocol:"POST /v2/chat",auth:["api-key"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://api.cohere.com"},{id:"aws-bedrock",name:"Amazon Bedrock Converse API",protocol:"Converse",auth:["aws-sigv4"],nativeTools:!0,streaming:"buffered-fallback"},{id:"google-vertex",name:"Google Vertex AI",protocol:"publishers/google/models:generateContent",auth:["bearer-token"],nativeTools:!0,streaming:"buffered-fallback"},{id:"azure-openai",name:"Azure OpenAI v1 Responses API",protocol:"POST /openai/v1/responses",auth:["api-key","bearer-token"],nativeTools:!0,streaming:"buffered-fallback"},{id:"github-copilot",name:"GitHub Copilot subscription bridge",protocol:"Official Copilot CLI",auth:["github-subscription"],nativeTools:"bridge-limited",streaming:!1,notes:"Uses copilot login or COPILOT_GITHUB_TOKEN/GH_TOKEN/GITHUB_TOKEN. Model calls are read-only text bridges so kpilot governance remains authoritative."},{id:"chatgpt-codex",name:"ChatGPT subscription through Codex CLI",protocol:"Official Codex CLI",auth:["chatgpt-subscription"],nativeTools:"bridge-limited",streaming:!1,notes:"Uses the official Codex CLI signed in with ChatGPT. It does not treat a ChatGPT subscription as an API key."},{id:"kpilot-hosted",name:"kpilot",protocol:"POST /v1/ai/responses",auth:["kpilot-account"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://api.konsolepilot.ai",notes:"Automatically routes prompts to a preferred kpilot capability unless a route or model is selected."},{id:"external-agent",name:"Bring-your-own agent",protocol:"kpilot Agent Protocol v1 over HTTP or stdio",auth:["none","bearer-token","external"],nativeTools:!0,streaming:"buffered-fallback",notes:"Runs an operator-provided agent executable or HTTP service."}];function Je(t){let e=es.find(n=>n.id===t);if(!e)throw new Error(`Unknown model provider: ${t}`);return e}async function Rc(t,e){return t.length?await new Promise((n,r)=>{let o=Ec(t[0],t.slice(1),{cwd:e,env:process.env,stdio:["ignore","pipe","pipe"]}),s="",i="";o.stdout?.on("data",a=>{s+=String(a)}),o.stderr?.on("data",a=>{i+=String(a)}),o.on("error",r),o.on("close",a=>{a===0?n(s.trim()):r(new Error(`${t.join(" ")} exited with code ${a}: ${i.trim()}`))})}):""}async function Cc(t){if(t.accessToken)return t.accessToken;if(t.credentialCommand?.length)return await Rc(t.credentialCommand,t.rootDir)}function oe(t,e){if(!t)throw new Error(e);return t}async function en(t){let e=t.provider??"openai-compatible",n=Je(e),r=t.model||(e==="github-copilot"||e==="chatgpt-codex"||e==="kpilot-hosted"||e==="external-agent"?"auto":"");if(!r)throw new Error(`A model is required for provider ${e}.`);let o=await Cc(t),s;switch(e){case"openai-compatible":s=new gt({baseUrl:t.baseUrl??"https://api.openai.com/v1",model:r,apiKey:t.apiKey??o,headers:t.headers,providerBody:t.providerBody,streaming:t.streaming,timeoutMs:t.timeoutMs,retries:t.retries,maxOutputTokens:t.maxOutputTokens,...t.sessionId?{sessionId:t.sessionId}:{}});break;case"openai-responses":s=new $e({baseUrl:t.baseUrl??n.defaultBaseUrl,model:r,apiKey:t.apiKey,accessToken:o,headers:t.headers,timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"anthropic":s=new ct({baseUrl:t.baseUrl,model:r,apiKey:oe(t.apiKey,"ANTHROPIC_API_KEY is required."),timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"gemini":s=new qe({baseUrl:t.baseUrl,model:r,apiKey:t.apiKey,accessToken:o,timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"xai":s=new $e({baseUrl:t.baseUrl??n.defaultBaseUrl,model:r,apiKey:oe(t.apiKey,"XAI_API_KEY is required."),timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"mistral":s=new gt({baseUrl:t.baseUrl??n.defaultBaseUrl,model:r,apiKey:oe(t.apiKey,"MISTRAL_API_KEY is required."),headers:t.headers,streaming:t.streaming,timeoutMs:t.timeoutMs,retries:t.retries,maxOutputTokens:t.maxOutputTokens});break;case"cohere":s=new lt({baseUrl:t.baseUrl,model:r,apiKey:oe(t.apiKey,"COHERE_API_KEY is required."),timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"aws-bedrock":s=new ut({baseUrl:t.baseUrl,model:r,region:oe(t.region,"AWS region is required."),accessKeyId:oe(t.awsAccessKeyId,"AWS_ACCESS_KEY_ID is required."),secretAccessKey:oe(t.awsSecretAccessKey,"AWS_SECRET_ACCESS_KEY is required."),sessionToken:t.awsSessionToken,timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"google-vertex":s=new qe({baseUrl:t.baseUrl,model:r,accessToken:oe(o,"Google OAuth access token is required."),project:oe(t.project,"Google Cloud project is required."),location:oe(t.location,"Vertex AI location is required."),vertex:!0,timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"azure-openai":{let i=oe(t.baseUrl,"Azure OpenAI base URL ending in /openai/v1 is required."),a=t.apiKey?{"api-key":t.apiKey,...t.headers}:t.headers;s=new $e({baseUrl:i,model:r,accessToken:o,headers:a,timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break}case"kpilot-hosted":s=new pt({baseUrl:t.baseUrl??n.defaultBaseUrl,accessToken:oe(o??t.accessToken,"kpilot account access token is required."),route:t.route??(r==="auto"?"auto":void 0),model:r==="auto"?void 0:r,timeoutMs:t.timeoutMs,headers:t.headers,getAccessToken:t.getAccessToken});break;case"external-agent":s=new ft({command:t.command,args:t.commandArgs,endpoint:t.endpoint??t.baseUrl,accessToken:o??t.accessToken??t.apiKey,rootDir:t.rootDir,timeoutMs:t.timeoutMs});break;case"github-copilot":s=new dt({command:t.command??"copilot",model:r==="default"?void 0:r,rootDir:t.rootDir??process.cwd(),timeoutMs:t.timeoutMs});break;case"chatgpt-codex":s=new mt({command:t.command??"codex",model:r==="default"?void 0:r,rootDir:t.rootDir??process.cwd(),timeoutMs:t.timeoutMs});break}return{gateway:s,provider:n,resolvedConfig:{...t,provider:e,model:r}}}function ts(t){let e=t?.prompt_tokens_details?.cached_tokens,n=t?.prompt_tokens_details?.cache_write_tokens;return{...typeof e=="number"&&e>=0?{read:e}:{},...typeof n=="number"&&n>=0?{write:n}:{}}}function Mc(t){return t.replace(/\/+$/,"")}function ns(t,e){return e?.aborted?Promise.reject(ht(e.reason)):new Promise((n,r)=>{let s=setTimeout(()=>{e?.removeEventListener("abort",i),n()},t),i=()=>{clearTimeout(s),e?.removeEventListener("abort",i),r(ht(e?.reason))};e?.addEventListener("abort",i,{once:!0})})}function ht(t){let e=typeof t=="string"&&t.trim()?`: ${t}`:"",n=new Error(`Model request cancelled${e}`);return n.name="AbortError",n}function $c(t){return me(t).map(e=>e.role==="assistant"?{role:"assistant",content:e.content,...e.tool_calls?{tool_calls:e.tool_calls}:{}}:e.role==="tool"?{role:"tool",tool_call_id:e.tool_call_id,content:e.content}:{role:e.role,content:e.content})}function _c(t){let e=t.toLowerCase();return!!(e.includes("claude")||e.startsWith("anthropic/")||/(^|\/)gemini/.test(e)||/qwen[^/]*(?:max|plus)/.test(e)||/qwen3-coder-(?:plus|flash)/.test(e))}function rs(t){return[{type:"text",text:t,cache_control:{type:"ephemeral"}}]}function Ac(t){if(t.length===0)return t;let e=t.map(o=>({...o})),n=e[0];n.role==="system"&&typeof n.content=="string"&&(n.content=rs(n.content));let r=e[e.length-1];return r.role==="user"&&typeof r.content=="string"&&(r.content=rs(r.content)),e}function Oc(t){let e=t.choices?.[0]?.message;if(!e)throw new Error(t.error?.message??"The model response did not contain an assistant message.");let n=e.tool_calls?.map((r,o)=>{if(!r.function?.name)throw new Error(`Tool call ${o+1} is missing a function name.`);return{id:r.id??`tool_call_${o+1}`,type:"function",function:{name:r.function.name,arguments:r.function.arguments??"{}"}}});return{role:"assistant",content:typeof e.content=="string"?e.content:null,...n?.length?{tool_calls:n}:{}}}function os(t,e){let n=new AbortController,r=setTimeout(()=>n.abort("request timeout"),t),o=()=>n.abort(e?.reason);return e?.aborted?n.abort(e.reason):e?.addEventListener("abort",o,{once:!0}),{controller:n,cleanup:()=>{clearTimeout(r),e?.removeEventListener("abort",o)}}}function ss(t,e){if(t instanceof Error&&t.name==="AbortError")return t;let n=t instanceof Error?t.message:String(t);return/fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENOTFOUND|network/i.test(n)?new Error(`Model hub unreachable at ${e} (${n}). Check that llama-server/Cockpit is still running.`):t instanceof Error?t:new Error(n)}function Ic(t){return!/unreachable|fetch failed|ECONNREFUSED|ECONNRESET|ENOTFOUND/i.test(t.message)}var gt=class{options;isOpenRouter;constructor(e){if(!e.model.trim())throw new Error("A model name is required.");this.options={...e,baseUrl:Mc(e.baseUrl),model:e.model,timeoutMs:e.timeoutMs??12e4,retries:e.retries??2,streaming:e.streaming??!0},this.isOpenRouter=e.openrouter??/openrouter\.ai/i.test(this.options.baseUrl)}async complete(e,n={}){return this.options.streaming&&n.onTextDelta?await this.completeStreaming(e,n):await this.completeBuffered(e,n)}requestBody(e,n){let r=$c(e.messages);return this.isOpenRouter&&_c(this.options.model)&&(r=Ac(r)),{model:this.options.model,messages:r,tools:e.tools,tool_choice:"auto",...this.options.sessionId?{session_id:this.options.sessionId,prompt_cache_key:this.options.sessionId}:{},...this.options.maxOutputTokens===void 0?{}:{max_tokens:this.options.maxOutputTokens},...n?{stream:!0,stream_options:{include_usage:!0}}:{},...this.options.providerBody&&Object.keys(this.options.providerBody).length>0?{provider:this.options.providerBody}:{}}}requestHeaders(){return{"content-type":"application/json",...this.options.apiKey?{authorization:`Bearer ${this.options.apiKey}`}:{},...this.options.headers}}async completeBuffered(e,n){let r,o=Math.ceil(JSON.stringify(e.messages).length/4),s=this.options.maxRetryPromptTokens??32e3,i=o>s?0:this.options.retries;for(let a=0;a<=i;a+=1){let c=os(this.options.timeoutMs,n.signal);try{let l=await fetch(`${this.options.baseUrl}/chat/completions`,{method:"POST",signal:c.controller.signal,headers:this.requestHeaders(),body:JSON.stringify(this.requestBody(e,!1))}),u=await l.text(),m;try{m=JSON.parse(u)}catch{throw new Error(`Model endpoint returned non-JSON data (HTTP ${l.status}): ${u.slice(0,500)}`)}if(!l.ok){let w=m.error?.message??`HTTP ${l.status}`;if((l.status===408||l.status===409||l.status===429||l.status>=500)&&a<i){await ns(500*2**a,n.signal);continue}throw new Error(`Model request failed: ${w}`)}let d=m.choices?.[0]?.message?.reasoning_content;d&&n.onReasoningDelta&&await n.onReasoningDelta(d);let f=ts(m.usage);return{message:Oc(m),model:m.model,usage:{inputTokens:m.usage?.prompt_tokens,outputTokens:m.usage?.completion_tokens,...f.read===void 0?{}:{cacheReadTokens:f.read},...f.write===void 0?{}:{cacheWriteTokens:f.write}}}}catch(l){if(r=n.signal?.aborted?ht(n.signal.reason):ss(l,this.options.baseUrl),r.name==="AbortError")break;if(a<i&&Ic(r)){await ns(500*2**a,n.signal);continue}break}finally{c.cleanup()}}throw r??new Error("Model request failed for an unknown reason.")}async completeStreaming(e,n){let r=os(this.options.timeoutMs,n.signal);try{let o=await fetch(`${this.options.baseUrl}/chat/completions`,{method:"POST",signal:r.controller.signal,headers:this.requestHeaders(),body:JSON.stringify(this.requestBody(e,!0))});if(!o.ok){let b=await o.text(),A=`HTTP ${o.status}`;try{A=JSON.parse(b).error?.message??A}catch{b&&(A=b.slice(0,500))}throw new Error(`Model request failed: ${A}`)}if(!o.body)throw new Error("Model endpoint returned no streaming response body.");let s=o.body.getReader(),i=new TextDecoder,a="",c="",l="",u,m,d,f,w,x=new Map,P=async b=>{let A=b.trim();if(!A||A.startsWith(":")||!A.startsWith("data:"))return!1;let O=A.slice(5).trim();if(O==="[DONE]")return!0;let L;try{L=JSON.parse(O)}catch{throw new Error(`Invalid streaming JSON chunk: ${O.slice(0,300)}`)}if(L.error?.message)throw new Error(`Model request failed: ${L.error.message}`);u=L.model??u,m=L.usage?.prompt_tokens??m,d=L.usage?.completion_tokens??d;let B=ts(L.usage);f=B.read??f,w=B.write??w;let y=L.choices?.[0]?.delta;typeof y?.content=="string"&&y.content&&(c+=y.content,await n.onTextDelta?.(y.content)),typeof y?.reasoning_content=="string"&&y.reasoning_content&&(l+=y.reasoning_content,await n.onReasoningDelta?.(y.reasoning_content));for(let p of y?.tool_calls??[]){let g=p.index??x.size,k=x.get(g)??{id:p.id??`tool_call_${g+1}`,type:"function",function:{name:"",arguments:""}};p.id&&(k.id=p.id),p.function?.name&&(k.function.name+=p.function.name),p.function?.arguments&&(k.function.arguments+=p.function.arguments),x.set(g,k)}return!1},S=!1;for(;!S;){if(n.signal?.aborted)throw ht(n.signal.reason);let b=await s.read();a+=i.decode(b.value??new Uint8Array,{stream:!b.done});let A=a.split(/\r?\n/);a=A.pop()??"";for(let O of A)if(await P(O)){S=!0;break}if(b.done){a.trim()&&await P(a);break}}let C=[...x.entries()].sort(([b],[A])=>b-A).map(([,b],A)=>{if(!b.function.name)throw new Error(`Streaming tool call ${A+1} is missing a function name.`);return b});return{message:{role:"assistant",content:c||null,...C.length?{tool_calls:C}:{}},model:u,usage:{inputTokens:m,outputTokens:d,...f===void 0?{}:{cacheReadTokens:f},...w===void 0?{}:{cacheWriteTokens:w}}}}catch(o){throw n.signal?.aborted?ht(n.signal.reason):ss(o,this.options.baseUrl)}finally{r.cleanup()}}};var _e=["fast","balanced","complex","reasoning","large-context","vision","security"];function wt(t){return _e.includes(t)}var Dc=[{route:"vision",score:8,words:["image","screenshot","diagram","visual","ui mockup","photo","video","multimodal"]},{route:"security",score:7,words:["security","security audit","vulnerability","vulnerabilities","threat model","penetration test","xss","csrf","sql injection","authentication bypass","authorization bypass","cryptography","secret leak","owasp"]},{route:"reasoning",score:6,words:["prove","root cause","deep analysis","formal","algorithm","optimize","concurrency","race condition","distributed","debug complex"]},{route:"complex",score:5,words:["architecture","migration","repository-wide","large refactor","multi-service","implement feature","production-ready","redesign","framework upgrade"]},{route:"balanced",score:3,words:["fix","refactor","test","review","implement","bug","api","database","typescript"]},{route:"fast",score:2,words:["rename","explain","summarize","format","typo","comment","small change","documentation"]}];function Qn(t,e={}){return e.hasImages?{route:"vision",confidence:.99,reason:"The request includes image input."}:(e.estimatedContextTokens??0)>=18e4||t.length>=8e4?{route:"large-context",confidence:.96,reason:"The request requires an unusually large context window."}:null}function tn(t,e={}){let n=Qn(t,e);if(n)return n;let r=t.toLowerCase(),o=new Map;for(let l of Dc)for(let u of l.words)r.includes(u)&&o.set(l.route,(o.get(l.route)??0)+l.score);t.length>12e3&&o.set("large-context",(o.get("large-context")??0)+5),t.length>3e3&&o.set("complex",(o.get("complex")??0)+2),/\b(one[- ]?liner|quick|simple|minor)\b/.test(r)&&o.set("fast",(o.get("fast")??0)+3);let s=[...o.entries()].sort((l,u)=>u[1]-l[1]),i=s[0];if(!i)return{route:"balanced",confidence:.55,reason:"No specialist signal was strong enough; using the balanced coding model."};let a=s[1]?.[1]??0,c=Math.min(.98,.58+Math.max(0,i[1]-a)*.05);return{route:i[0],confidence:c,reason:`Prompt signals matched the ${i[0]} route.`}}import{spawn as Nc}from"node:child_process";var is="2025-11-25",as=new Set([is,"2025-06-18","2025-03-26"]);function ne(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`${e} must be an object.`);return t}function nn(t){return t.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/^_+|_+$/g,"")||"unnamed"}function Fc(t,e=200){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function cs(t){if(!t)return"[MCP tool returned no result]";let e=ne(t,"MCP tool result"),n=e.content;if(!Array.isArray(n))return JSON.stringify(t,null,2);let r=[];for(let o of n){if(!o||typeof o!="object"||Array.isArray(o))continue;let s=o;s.type==="text"&&typeof s.text=="string"?r.push(s.text):r.push(JSON.stringify(s))}return e.structuredContent!==void 0&&r.push(JSON.stringify(e.structuredContent,null,2)),r.join(`
134
- `)||JSON.stringify(t,null,2)}var Xn=class{name;config;child;nextId=1;buffer="";pending=new Map;initialized=!1;serverInfo={};constructor(e,n){if(!n.command.trim())throw new Error(`MCP server ${e} requires a command.`);this.name=nn(e),this.config={...n,args:n.args??[],timeoutMs:n.timeoutMs??3e4,enabled:n.enabled??!0}}async connect(e){if(this.initialized)return;if(!this.config.enabled)throw new Error(`MCP server ${this.name} is disabled.`);this.child=Nc(this.config.command,this.config.args,{cwd:this.config.cwd,env:{...process.env,...this.config.env},stdio:["pipe","pipe","pipe"]}),this.child.stdout.setEncoding("utf8"),this.child.stderr.setEncoding("utf8"),this.child.stdout.on("data",o=>this.consume(o)),this.child.stderr.on("data",o=>{}),this.child.once("error",o=>this.failAll(o)),this.child.once("close",o=>{this.initialized=!1,this.failAll(new Error(`MCP server ${this.name} exited with code ${o??1}.`))});let n=ne(await this.request("initialize",{protocolVersion:is,capabilities:{},clientInfo:{name:"kpilot",title:"kpilot",version:"0.10.42",description:"Local-first AI coding agent"}},e),"MCP initialize result"),r=typeof n.protocolVersion=="string"?n.protocolVersion:"";if(!as.has(r))throw await this.close(),new Error(`MCP server ${this.name} negotiated unsupported protocol version ${r||"[missing]"}.`);this.serverInfo=ne(n.serverInfo,"MCP serverInfo"),this.notify("notifications/initialized",{}),this.initialized=!0}consume(e){this.buffer+=e;let n=this.buffer.split(/\r?\n/);this.buffer=n.pop()??"";for(let r of n){if(!r.trim())continue;let o;try{o=JSON.parse(r)}catch{this.failAll(new Error(`MCP server ${this.name} emitted invalid JSON on stdout.`));continue}if(o.id!==void 0&&(o.result!==void 0||o.error)){let s=this.pending.get(o.id);if(!s)continue;clearTimeout(s.timeout),this.pending.delete(o.id),o.error?s.reject(new Error(`MCP ${this.name}: ${o.error.message??`error ${o.error.code??"unknown"}`}`)):s.resolve(o.result??null)}else o.id!==void 0&&o.method&&this.write({jsonrpc:"2.0",id:o.id,error:{code:-32601,message:`Client method not supported: ${o.method}`}})}}write(e){if(!this.child?.stdin?.writable)throw new Error(`MCP server ${this.name} is not connected.`);this.child.stdin.write(`${JSON.stringify(e)}
135
- `)}notify(e,n){this.write({jsonrpc:"2.0",method:e,params:n})}async request(e,n,r){if(r?.aborted)throw new Error(`MCP request cancelled: ${String(r.reason??"")}`);let o=this.nextId++;return await new Promise((s,i)=>{let a=setTimeout(()=>{this.pending.delete(o),this.notify("notifications/cancelled",{requestId:o,reason:"timeout"}),i(new Error(`MCP ${this.name} request timed out: ${e}`))},this.config.timeoutMs),c=()=>{clearTimeout(a),this.pending.delete(o);try{this.notify("notifications/cancelled",{requestId:o,reason:"user cancellation"})}catch{}i(new Error(`MCP request cancelled: ${e}`))};r?.addEventListener("abort",c,{once:!0}),this.pending.set(o,{resolve:l=>{r?.removeEventListener("abort",c),s(l)},reject:l=>{r?.removeEventListener("abort",c),i(l)},timeout:a});try{this.write({jsonrpc:"2.0",id:o,method:e,params:n})}catch(l){clearTimeout(a),this.pending.delete(o),i(l instanceof Error?l:new Error(String(l)))}})}async listTools(e){await this.connect(e);let n=[],r;do{let o=ne(await this.request("tools/list",r?{cursor:r}:{},e),"MCP tools/list result"),s=o.tools;if(!Array.isArray(s))throw new Error(`MCP server ${this.name} returned an invalid tool list.`);for(let i of s){let a=ne(i,"MCP tool");if(typeof a.name!="string")throw new Error(`MCP server ${this.name} returned a tool without a name.`);n.push({name:a.name,title:typeof a.title=="string"?a.title:void 0,description:typeof a.description=="string"?a.description:void 0,inputSchema:ne(a.inputSchema,`MCP inputSchema for ${a.name}`)})}r=typeof o.nextCursor=="string"?o.nextCursor:void 0}while(r);return n}async callTool(e,n,r){await this.connect(r);let o=await this.request("tools/call",{name:e,arguments:n},r);return{ok:ne(o,"MCP tools/call result").isError!==!0,output:cs(o),metadata:{server:this.name,tool:e}}}info(){return{name:this.name,serverInfo:this.serverInfo,connected:this.initialized}}failAll(e){for(let n of this.pending.values())clearTimeout(n.timeout),n.reject(e);this.pending.clear()}async close(){if(!this.child)return;let e=this.child;this.child=void 0,this.initialized=!1,await new Promise(n=>{let r=!1,o=()=>{r||(r=!0,clearTimeout(s),clearTimeout(i),clearTimeout(a),n())};e.once("close",o),e.stdin?.end();let s=setTimeout(()=>e.kill("SIGTERM"),300),i=setTimeout(()=>e.kill("SIGKILL"),900),a=setTimeout(o,1200)})}},Zn=class{name;config;url;nextId=1;pending=new Map;initialized=!1;serverInfo={};constructor(e,n){if(!n.url?.trim())throw new Error(`MCP server ${e} requires url for ${n.transport??"http"} transport.`);let r=new URL(n.url);if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`MCP server ${e} http transport requires an http(s) url; got ${r.protocol}`);this.name=nn(e),this.config={...n,timeoutMs:n.timeoutMs??3e4},this.url=r.href}headers(){return{"Content-Type":"application/json",Accept:"application/json, text/event-stream","MCP-Protocol-Version":"2025-06-18",...this.config.token?{Authorization:`Bearer ${this.config.token}`}:{},...this.config.headers}}async connect(e){if(this.initialized)return;if(this.config.enabled===!1)throw new Error(`MCP server ${this.name} is disabled.`);let n=ne(await this.request("initialize",{protocolVersion:"2025-06-18",capabilities:{},clientInfo:{name:"kpilot",title:"kpilot",version:"0.10.42",description:"Local-first AI coding agent"}},e),"MCP initialize result"),r=typeof n.protocolVersion=="string"?n.protocolVersion:"";if(!as.has(r))throw new Error(`MCP server ${this.name} negotiated unsupported protocol version ${r||"[missing]"}.`);this.serverInfo=ne(n.serverInfo,"MCP serverInfo"),this.notify("notifications/initialized",{}),this.initialized=!0}async request(e,n,r){if(r?.aborted)throw new Error(`MCP request cancelled: ${String(r.reason??"")}`);let o=this.nextId++;return await new Promise((s,i)=>{let a=setTimeout(()=>{this.pending.delete(o),this.notify("notifications/cancelled",{requestId:o,reason:"timeout"}),i(new Error(`MCP ${this.name} request timed out: ${e}`))},this.config.timeoutMs),c=()=>{clearTimeout(a),this.pending.delete(o);try{this.notify("notifications/cancelled",{requestId:o,reason:"user cancellation"})}catch{}i(new Error(`MCP request cancelled: ${e}`))};r?.addEventListener("abort",c,{once:!0});let l=u=>{r?.removeEventListener("abort",c),u()};this.pending.set(o,{resolve:u=>l(()=>s(u)),reject:u=>l(()=>i(u)),timer:a}),this.postBody({jsonrpc:"2.0",id:o,method:e,params:n}).then(u=>this.consumeResponse(u)).catch(u=>{let m=this.pending.get(o);m&&(clearTimeout(m.timer),this.pending.delete(o),l(()=>i(u instanceof Error?u:new Error(String(u)))))})})}notify(e,n){return this.postBody({jsonrpc:"2.0",method:e,params:n}).then(r=>{r?.body?.cancel().catch(()=>{})}).catch(()=>{})}async postBody(e){return await fetch(this.url,{method:"POST",headers:this.headers(),body:JSON.stringify(e),signal:AbortSignal.timeout(this.config.timeoutMs)})}async consumeResponse(e){let n=e.headers.get("content-type")??"";n.includes("text/event-stream")?await this.consumeSse(e):n.includes("application/json")?await this.consumeJson(e):await e.body?.cancel().catch(()=>{})}async consumeSse(e){if(!e.body)return;let n=e.body.getReader(),r=new TextDecoder,o="";for(;;){let{done:s,value:i}=await n.read();if(s)break;o+=r.decode(i,{stream:!0});let a=o.indexOf(`
144
+ `),n=[];for(let r of t)if(r.role!=="system")if(r.role==="user")n.push({role:"user",content:[{text:r.content}]});else if(r.role==="assistant"){let o=[];r.content&&o.push({text:r.content});for(let s of r.tool_calls??[]){let i={};try{i=JSON.parse(s.function.arguments)}catch{i={raw:s.function.arguments}}o.push({toolUse:{toolUseId:s.id,name:s.function.name,input:i}})}n.push({role:"assistant",content:o})}else{let o;try{o={json:JSON.parse(r.content)}}catch{o={text:r.content}}n.push({role:"user",content:[{toolResult:{toolUseId:r.tool_call_id,content:[o]}}]})}return{...e?{system:[{text:e}]}:{},messages:n}}var mt=class{options;constructor(e){if(!e.model.trim())throw new Error("A Bedrock model ID is required.");if(!e.region)throw new Error("AWS region is required.");if(!e.accessKeyId||!e.secretAccessKey)throw new Error("AWS credentials are required.");this.options={...e,model:e.model,region:e.region,accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey,baseUrl:e.baseUrl??`https://bedrock-runtime.${e.region}.amazonaws.com`,timeoutMs:e.timeoutMs??12e4}}async complete(e,n={}){let r=Uc(e.messages),o=JSON.stringify({...r,toolConfig:e.tools.length?{tools:e.tools.map(m=>({toolSpec:{name:m.function.name,description:m.function.description,inputSchema:{json:m.function.parameters}}})),toolChoice:{auto:{}}}:void 0,...this.options.maxOutputTokens===void 0?{}:{inferenceConfig:{maxTokens:this.options.maxOutputTokens}}}),s=new URL(`${this.options.baseUrl.replace(/\/+$/,"")}/model/${encodeURIComponent(this.options.model)}/converse`),i=await fe(s.toString(),{method:"POST",headers:Lc(this.options,s,o),body:o},n,this.options.timeoutMs),a=i?.output?.message?.content??[],c=[],l=[];for(let m of a)typeof m?.text=="string"&&c.push(m.text),m?.toolUse?.name&&l.push({id:m.toolUse.toolUseId??`tool_call_${l.length+1}`,type:"function",function:{name:m.toolUse.name,arguments:JSON.stringify(m.toolUse.input??{})}});let u={role:"assistant",content:c.length?c.join(""):null,...l.length?{tool_calls:l}:{}};return await he(i,n),await ge(u,n),{message:u,model:this.options.model,usage:{inputTokens:i?.usage?.inputTokens,outputTokens:i?.usage?.outputTokens}}}};import{spawn as Nc}from"node:child_process";async function us(t,e,n,r){return await new Promise((o,s)=>{let i=Nc(t,e,{cwd:n.rootDir,env:{...process.env,...n.environment},stdio:["ignore","pipe","pipe"]}),a="",c="",l=setTimeout(()=>i.kill("SIGTERM"),n.timeoutMs??3e5),u=()=>{i.kill("SIGTERM")};r.signal?.addEventListener("abort",u,{once:!0}),i.stdout?.on("data",m=>{a+=String(m)}),i.stderr?.on("data",m=>{c+=String(m)}),i.on("error",m=>{clearTimeout(l),r.signal?.removeEventListener("abort",u),s(m)}),i.on("close",m=>{clearTimeout(l),r.signal?.removeEventListener("abort",u),r.signal?.aborted?s(nr(r.signal.reason)):m!==0?s(new Error(`${t} exited with code ${m}: ${c.trim()||a.trim()}`)):o({stdout:a,stderr:c})})})}function Fc(t){let e=t.split(/\r?\n/).filter(Boolean),n=[];for(let r of e)try{let o=JSON.parse(r),s=[o?.item?.text,o?.item?.content,o?.message?.content,o?.message,o?.text,o?.output_text,o?.content];for(let i of s)typeof i=="string"&&i.trim()&&n.push(i.trim())}catch{}return n.at(-1)??t.trim()}var pt=class{options;constructor(e){this.options=e}async complete(e,n={}){let r=rr(e.messages,e.tools),o=["bash","powershell","list_bash","list_powershell","read_bash","read_powershell","stop_bash","stop_powershell","write_bash","write_powershell","apply_patch","create","edit","list_agents","read_agent","task","write_agent","ask_user","skill","web_fetch"].join(","),s=["-p",r,"-s","--no-ask-user","--allow-tool=read",`--excluded-tools=${o}`,"--disable-builtin-mcps","--no-custom-instructions","--no-experimental","--no-remote","--no-remote-export","--no-auto-update"];this.options.model&&s.push("--model",this.options.model);let{stdout:i}=await us(this.options.command||"copilot",s,this.options,n),a=i.trim();if(!a)throw new Error("GitHub Copilot CLI returned no response. Run `copilot login` and verify the subscription.");return await n.onTextDelta?.(a),{message:{role:"assistant",content:a},model:this.options.model}}},ft=class{options;constructor(e){this.options=e}async complete(e,n={}){let r=rr(e.messages,e.tools),o=["exec","--json","--sandbox","read-only","--skip-git-repo-check"];this.options.model&&o.push("--model",this.options.model),o.push(r);let{stdout:s}=await us(this.options.command||"codex",o,this.options,n),i=Fc(s);if(!i)throw new Error("Codex CLI returned no response. Run `codex login` and sign in with ChatGPT.");return await n.onTextDelta?.(i),{message:{role:"assistant",content:i},model:this.options.model}}};var gt=class{baseUrl;options;constructor(e){if(this.options=e,!e.accessToken)throw new Error("kpilot needs an account to continue. Run `kpilot login`.");this.baseUrl=e.baseUrl.replace(/\/+$/,"")}async complete(e,n={}){let r=new AbortController,o=setTimeout(()=>r.abort("request timeout"),this.options.timeoutMs??18e4),s=()=>r.abort(n.signal?.reason);n.signal?.aborted?r.abort(n.signal.reason):n.signal?.addEventListener("abort",s,{once:!0});let i=await this.options.getAccessToken?.()??this.options.accessToken;try{let a=await fetch(`${this.baseUrl}/v1/ai/responses`,{method:"POST",signal:r.signal,headers:{authorization:`Bearer ${i}`,"content-type":"application/json",...this.options.headers},body:JSON.stringify({route:this.options.route??"auto",...this.options.model?{model:this.options.model}:{},messages:e.messages,tools:e.tools})}),c=await a.text(),l;try{l=c?JSON.parse(c):{}}catch{throw new Error(`kpilot endpoint returned a non-JSON response (HTTP ${a.status}). If this persists, re-run \`kpilot login\`.`)}if(!a.ok){let u=typeof l.message=="string"?l.message:typeof l.error?.message=="string"?l.error.message:`kpilot endpoint returned HTTP ${a.status}.`,m=typeof l.detail=="string"?l.detail:void 0,d=l.attempts??l.error?.attempts,p=Array.isArray(d)&&d.length>0?d.map(y=>`${y.model??"?"}: ${y.error??"unknown error"}`).join(" | "):void 0;throw new Error([u,m&&m!==u?m:void 0,p].filter(y=>!!(y&&y.trim())).join(" "))}if(l.message?.content&&n.onTextDelta&&await n.onTextDelta(l.message.content),n.onReasoningDelta){let u=qe(l);u&&await n.onReasoningDelta(u)}return l}finally{clearTimeout(o),n.signal?.removeEventListener("abort",s)}}};import{spawn as qc}from"node:child_process";function ds(t){if(!t||t.message?.role!=="assistant")throw new Error("External agent response must contain an assistant message.");return t}var ht=class{options;constructor(e){if(this.options=e,!e.command&&!e.endpoint)throw new Error("Bring-your-own-agent requires either command or endpoint.")}async complete(e,n={}){return this.options.endpoint?await this.completeHttp(e,n):await this.completeCommand(e,n)}async completeHttp(e,n){let r=await fetch(this.options.endpoint,{method:"POST",signal:n.signal,headers:{"content-type":"application/json",...this.options.accessToken?{authorization:`Bearer ${this.options.accessToken}`}:{}},body:JSON.stringify({protocol:"kpilot-agent-v1",request:e})}),o=await r.text(),s;try{s=JSON.parse(o)}catch{throw new Error(`External agent returned non-JSON data (HTTP ${r.status}).`)}if(!r.ok)throw new Error(s.message??`External agent returned HTTP ${r.status}.`);let i=ds(s);if(n.onReasoningDelta){let a=qe(s);a&&await n.onReasoningDelta(a)}return i.message.content&&n.onTextDelta&&await n.onTextDelta(i.message.content),i}async completeCommand(e,n){return await new Promise((r,o)=>{let s=qc(this.options.command,this.options.args??[],{cwd:this.options.rootDir??process.cwd(),env:process.env,stdio:["pipe","pipe","pipe"]}),i=setTimeout(()=>s.kill("SIGTERM"),this.options.timeoutMs??18e4),a="",c="",l=()=>{s.kill("SIGTERM")};n.signal?.addEventListener("abort",l,{once:!0}),s.stdout?.on("data",u=>{a+=String(u)}),s.stderr?.on("data",u=>{c+=String(u)}),s.once("error",o),s.once("close",async u=>{if(clearTimeout(i),n.signal?.removeEventListener("abort",l),n.signal?.aborted)return o(n.signal.reason??new Error("External agent cancelled."));if(u!==0)return o(new Error(`External agent exited with code ${u}: ${c.trim().slice(0,1e3)}`));try{let m=ds(JSON.parse(a.trim()));if(n.onReasoningDelta){let d=qe(m);d&&await n.onReasoningDelta(d)}m.message.content&&n.onTextDelta&&await n.onTextDelta(m.message.content),r(m)}catch(m){o(m)}}),s.stdin?.end(`${JSON.stringify({protocol:"kpilot-agent-v1",request:e})}
145
+ `)})}};import{spawn as Bc}from"node:child_process";var ms=[{id:"openai-compatible",name:"OpenAI-compatible Chat Completions",protocol:"POST /v1/chat/completions",auth:["none","api-key","bearer-token"],nativeTools:!0,streaming:!0},{id:"openai-responses",name:"OpenAI Responses API",protocol:"POST /v1/responses",auth:["api-key","bearer-token"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://api.openai.com/v1"},{id:"anthropic",name:"Anthropic Claude API",protocol:"POST /v1/messages",auth:["api-key"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://api.anthropic.com"},{id:"gemini",name:"Google Gemini Developer API",protocol:"models.generateContent",auth:["api-key"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta"},{id:"xai",name:"xAI Inference API",protocol:"POST /v1/responses",auth:["api-key"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://api.x.ai/v1"},{id:"mistral",name:"Mistral AI API",protocol:"POST /v1/chat/completions",auth:["api-key"],nativeTools:!0,streaming:!0,defaultBaseUrl:"https://api.mistral.ai/v1"},{id:"cohere",name:"Cohere v2 Chat API",protocol:"POST /v2/chat",auth:["api-key"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://api.cohere.com"},{id:"aws-bedrock",name:"Amazon Bedrock Converse API",protocol:"Converse",auth:["aws-sigv4"],nativeTools:!0,streaming:"buffered-fallback"},{id:"google-vertex",name:"Google Vertex AI",protocol:"publishers/google/models:generateContent",auth:["bearer-token"],nativeTools:!0,streaming:"buffered-fallback"},{id:"azure-openai",name:"Azure OpenAI v1 Responses API",protocol:"POST /openai/v1/responses",auth:["api-key","bearer-token"],nativeTools:!0,streaming:"buffered-fallback"},{id:"github-copilot",name:"GitHub Copilot subscription bridge",protocol:"Official Copilot CLI",auth:["github-subscription"],nativeTools:"bridge-limited",streaming:!1,notes:"Uses copilot login or COPILOT_GITHUB_TOKEN/GH_TOKEN/GITHUB_TOKEN. Model calls are read-only text bridges so kpilot governance remains authoritative."},{id:"chatgpt-codex",name:"ChatGPT subscription through Codex CLI",protocol:"Official Codex CLI",auth:["chatgpt-subscription"],nativeTools:"bridge-limited",streaming:!1,notes:"Uses the official Codex CLI signed in with ChatGPT. It does not treat a ChatGPT subscription as an API key."},{id:"kpilot-hosted",name:"kpilot",protocol:"POST /v1/ai/responses",auth:["kpilot-account"],nativeTools:!0,streaming:"buffered-fallback",defaultBaseUrl:"https://api.konsolepilot.ai",notes:"Automatically routes prompts to a preferred kpilot capability unless a route or model is selected."},{id:"external-agent",name:"Bring-your-own agent",protocol:"kpilot Agent Protocol v1 over HTTP or stdio",auth:["none","bearer-token","external"],nativeTools:!0,streaming:"buffered-fallback",notes:"Runs an operator-provided agent executable or HTTP service."}];function Je(t){let e=ms.find(n=>n.id===t);if(!e)throw new Error(`Unknown model provider: ${t}`);return e}async function Jc(t,e){return t.length?await new Promise((n,r)=>{let o=Bc(t[0],t.slice(1),{cwd:e,env:process.env,stdio:["ignore","pipe","pipe"]}),s="",i="";o.stdout?.on("data",a=>{s+=String(a)}),o.stderr?.on("data",a=>{i+=String(a)}),o.on("error",r),o.on("close",a=>{a===0?n(s.trim()):r(new Error(`${t.join(" ")} exited with code ${a}: ${i.trim()}`))})}):""}async function Kc(t){if(t.accessToken)return t.accessToken;if(t.credentialCommand?.length)return await Jc(t.credentialCommand,t.rootDir)}function se(t,e){if(!t)throw new Error(e);return t}async function on(t){let e=t.provider??"openai-compatible",n=Je(e),r=t.model||(e==="github-copilot"||e==="chatgpt-codex"||e==="kpilot-hosted"||e==="external-agent"?"auto":"");if(!r)throw new Error(`A model is required for provider ${e}.`);let o=await Kc(t),s;switch(e){case"openai-compatible":s=new wt({baseUrl:t.baseUrl??"https://api.openai.com/v1",model:r,apiKey:t.apiKey??o,headers:t.headers,providerBody:t.providerBody,streaming:t.streaming,timeoutMs:t.timeoutMs,retries:t.retries,maxOutputTokens:t.maxOutputTokens,...t.sessionId?{sessionId:t.sessionId}:{}});break;case"openai-responses":s=new $e({baseUrl:t.baseUrl??n.defaultBaseUrl,model:r,apiKey:t.apiKey,accessToken:o,headers:t.headers,timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"anthropic":s=new ut({baseUrl:t.baseUrl,model:r,apiKey:se(t.apiKey,"ANTHROPIC_API_KEY is required."),timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"gemini":s=new Be({baseUrl:t.baseUrl,model:r,apiKey:t.apiKey,accessToken:o,timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"xai":s=new $e({baseUrl:t.baseUrl??n.defaultBaseUrl,model:r,apiKey:se(t.apiKey,"XAI_API_KEY is required."),timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"mistral":s=new wt({baseUrl:t.baseUrl??n.defaultBaseUrl,model:r,apiKey:se(t.apiKey,"MISTRAL_API_KEY is required."),headers:t.headers,streaming:t.streaming,timeoutMs:t.timeoutMs,retries:t.retries,maxOutputTokens:t.maxOutputTokens});break;case"cohere":s=new dt({baseUrl:t.baseUrl,model:r,apiKey:se(t.apiKey,"COHERE_API_KEY is required."),timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"aws-bedrock":s=new mt({baseUrl:t.baseUrl,model:r,region:se(t.region,"AWS region is required."),accessKeyId:se(t.awsAccessKeyId,"AWS_ACCESS_KEY_ID is required."),secretAccessKey:se(t.awsSecretAccessKey,"AWS_SECRET_ACCESS_KEY is required."),sessionToken:t.awsSessionToken,timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"google-vertex":s=new Be({baseUrl:t.baseUrl,model:r,accessToken:se(o,"Google OAuth access token is required."),project:se(t.project,"Google Cloud project is required."),location:se(t.location,"Vertex AI location is required."),vertex:!0,timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break;case"azure-openai":{let i=se(t.baseUrl,"Azure OpenAI base URL ending in /openai/v1 is required."),a=t.apiKey?{"api-key":t.apiKey,...t.headers}:t.headers;s=new $e({baseUrl:i,model:r,accessToken:o,headers:a,timeoutMs:t.timeoutMs,maxOutputTokens:t.maxOutputTokens});break}case"kpilot-hosted":s=new gt({baseUrl:t.baseUrl??n.defaultBaseUrl,accessToken:se(o??t.accessToken,"kpilot account access token is required."),route:t.route??(r==="auto"?"auto":void 0),model:r==="auto"?void 0:r,timeoutMs:t.timeoutMs,headers:t.headers,getAccessToken:t.getAccessToken});break;case"external-agent":s=new ht({command:t.command,args:t.commandArgs,endpoint:t.endpoint??t.baseUrl,accessToken:o??t.accessToken??t.apiKey,rootDir:t.rootDir,timeoutMs:t.timeoutMs});break;case"github-copilot":s=new pt({command:t.command??"copilot",model:r==="default"?void 0:r,rootDir:t.rootDir??process.cwd(),timeoutMs:t.timeoutMs});break;case"chatgpt-codex":s=new ft({command:t.command??"codex",model:r==="default"?void 0:r,rootDir:t.rootDir??process.cwd(),timeoutMs:t.timeoutMs});break}return{gateway:s,provider:n,resolvedConfig:{...t,provider:e,model:r}}}function ps(t){let e=t?.prompt_tokens_details?.cached_tokens,n=t?.prompt_tokens_details?.cache_write_tokens;return{...typeof e=="number"&&e>=0?{read:e}:{},...typeof n=="number"&&n>=0?{write:n}:{}}}function Wc(t){return t.replace(/\/+$/,"")}function fs(t,e){return e?.aborted?Promise.reject(yt(e.reason)):new Promise((n,r)=>{let s=setTimeout(()=>{e?.removeEventListener("abort",i),n()},t),i=()=>{clearTimeout(s),e?.removeEventListener("abort",i),r(yt(e?.reason))};e?.addEventListener("abort",i,{once:!0})})}function yt(t){let e=typeof t=="string"&&t.trim()?`: ${t}`:"",n=new Error(`Model request cancelled${e}`);return n.name="AbortError",n}function Gc(t){return pe(t).map(e=>e.role==="assistant"?{role:"assistant",content:e.content,...e.tool_calls?{tool_calls:e.tool_calls}:{}}:e.role==="tool"?{role:"tool",tool_call_id:e.tool_call_id,content:e.content}:{role:e.role,content:e.content})}function Hc(t){let e=t.toLowerCase();return!!(e.includes("claude")||e.startsWith("anthropic/")||/(^|\/)gemini/.test(e)||/qwen[^/]*(?:max|plus)/.test(e)||/qwen3-coder-(?:plus|flash)/.test(e))}function gs(t){return[{type:"text",text:t,cache_control:{type:"ephemeral"}}]}function zc(t){if(t.length===0)return t;let e=t.map(o=>({...o})),n=e[0];n.role==="system"&&typeof n.content=="string"&&(n.content=gs(n.content));let r=e[e.length-1];return r.role==="user"&&typeof r.content=="string"&&(r.content=gs(r.content)),e}function Vc(t){let e=t.choices?.[0]?.message;if(!e)throw new Error(t.error?.message??"The model response did not contain an assistant message.");let n=e.tool_calls?.map((r,o)=>{if(!r.function?.name)throw new Error(`Tool call ${o+1} is missing a function name.`);return{id:r.id??`tool_call_${o+1}`,type:"function",function:{name:r.function.name,arguments:r.function.arguments??"{}"}}});return{role:"assistant",content:typeof e.content=="string"?e.content:null,...n?.length?{tool_calls:n}:{}}}function hs(t,e){let n=new AbortController,r=setTimeout(()=>n.abort("request timeout"),t),o=()=>n.abort(e?.reason);return e?.aborted?n.abort(e.reason):e?.addEventListener("abort",o,{once:!0}),{controller:n,cleanup:()=>{clearTimeout(r),e?.removeEventListener("abort",o)}}}function ws(t,e){if(t instanceof Error&&t.name==="AbortError")return t;let n=t instanceof Error?t.message:String(t);return/fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENOTFOUND|network/i.test(n)?new Error(`Model hub unreachable at ${e} (${n}). Check that llama-server/Cockpit is still running.`):t instanceof Error?t:new Error(n)}function Yc(t){return!/unreachable|fetch failed|ECONNREFUSED|ECONNRESET|ENOTFOUND/i.test(t.message)}var wt=class{options;isOpenRouter;constructor(e){if(!e.model.trim())throw new Error("A model name is required.");this.options={...e,baseUrl:Wc(e.baseUrl),model:e.model,timeoutMs:e.timeoutMs??12e4,retries:e.retries??2,streaming:e.streaming??!0},this.isOpenRouter=e.openrouter??/openrouter\.ai/i.test(this.options.baseUrl)}async complete(e,n={}){return this.options.streaming&&n.onTextDelta?await this.completeStreaming(e,n):await this.completeBuffered(e,n)}requestBody(e,n){let r=Gc(e.messages);return this.isOpenRouter&&Hc(this.options.model)&&(r=zc(r)),{model:this.options.model,messages:r,tools:e.tools,tool_choice:"auto",...this.options.sessionId?{session_id:this.options.sessionId,prompt_cache_key:this.options.sessionId}:{},...this.options.maxOutputTokens===void 0?{}:{max_tokens:this.options.maxOutputTokens},...n?{stream:!0,stream_options:{include_usage:!0}}:{},...this.options.providerBody&&Object.keys(this.options.providerBody).length>0?{provider:this.options.providerBody}:{}}}requestHeaders(){return{"content-type":"application/json",...this.options.apiKey?{authorization:`Bearer ${this.options.apiKey}`}:{},...this.options.headers}}async completeBuffered(e,n){let r,o=Math.ceil(JSON.stringify(e.messages).length/4),s=this.options.maxRetryPromptTokens??32e3,i=o>s?0:this.options.retries;for(let a=0;a<=i;a+=1){let c=hs(this.options.timeoutMs,n.signal);try{let l=await fetch(`${this.options.baseUrl}/chat/completions`,{method:"POST",signal:c.controller.signal,headers:this.requestHeaders(),body:JSON.stringify(this.requestBody(e,!1))}),u=await l.text(),m;try{m=JSON.parse(u)}catch{throw new Error(`Model endpoint returned non-JSON data (HTTP ${l.status}): ${u.slice(0,500)}`)}if(!l.ok){let y=m.error?.message??`HTTP ${l.status}`;if((l.status===408||l.status===409||l.status===429||l.status>=500)&&a<i){await fs(500*2**a,n.signal);continue}throw new Error(`Model request failed: ${y}`)}let d=m.choices?.[0]?.message?.reasoning_content;d&&n.onReasoningDelta&&await n.onReasoningDelta(d);let p=ps(m.usage);return{message:Vc(m),model:m.model,usage:{inputTokens:m.usage?.prompt_tokens,outputTokens:m.usage?.completion_tokens,...p.read===void 0?{}:{cacheReadTokens:p.read},...p.write===void 0?{}:{cacheWriteTokens:p.write}}}}catch(l){if(r=n.signal?.aborted?yt(n.signal.reason):ws(l,this.options.baseUrl),r.name==="AbortError")break;if(a<i&&Yc(r)){await fs(500*2**a,n.signal);continue}break}finally{c.cleanup()}}throw r??new Error("Model request failed for an unknown reason.")}async completeStreaming(e,n){let r=hs(this.options.timeoutMs,n.signal);try{let o=await fetch(`${this.options.baseUrl}/chat/completions`,{method:"POST",signal:r.controller.signal,headers:this.requestHeaders(),body:JSON.stringify(this.requestBody(e,!0))});if(!o.ok){let P=await o.text(),_=`HTTP ${o.status}`;try{_=JSON.parse(P).error?.message??_}catch{P&&(_=P.slice(0,500))}throw new Error(`Model request failed: ${_}`)}if(!o.body)throw new Error("Model endpoint returned no streaming response body.");let s=o.body.getReader(),i=new TextDecoder,a="",c="",l="",u,m,d,p,y,S=new Map,x=async P=>{let _=P.trim();if(!_||_.startsWith(":")||!_.startsWith("data:"))return!1;let I=_.slice(5).trim();if(I==="[DONE]")return!0;let j;try{j=JSON.parse(I)}catch{throw new Error(`Invalid streaming JSON chunk: ${I.slice(0,300)}`)}if(j.error?.message)throw new Error(`Model request failed: ${j.error.message}`);u=j.model??u,m=j.usage?.prompt_tokens??m,d=j.usage?.completion_tokens??d;let N=ps(j.usage);p=N.read??p,y=N.write??y;let h=j.choices?.[0]?.delta;typeof h?.content=="string"&&h.content&&(c+=h.content,await n.onTextDelta?.(h.content)),typeof h?.reasoning_content=="string"&&h.reasoning_content&&(l+=h.reasoning_content,await n.onReasoningDelta?.(h.reasoning_content));for(let f of h?.tool_calls??[]){let w=f.index??S.size,g=S.get(w)??{id:f.id??`tool_call_${w+1}`,type:"function",function:{name:"",arguments:""}};f.id&&(g.id=f.id),f.function?.name&&(g.function.name+=f.function.name),f.function?.arguments&&(g.function.arguments+=f.function.arguments),S.set(w,g)}return!1},k=!1;for(;!k;){if(n.signal?.aborted)throw yt(n.signal.reason);let P=await s.read();a+=i.decode(P.value??new Uint8Array,{stream:!P.done});let _=a.split(/\r?\n/);a=_.pop()??"";for(let I of _)if(await x(I)){k=!0;break}if(P.done){a.trim()&&await x(a);break}}let R=[...S.entries()].sort(([P],[_])=>P-_).map(([,P],_)=>{if(!P.function.name)throw new Error(`Streaming tool call ${_+1} is missing a function name.`);return P});return{message:{role:"assistant",content:c||null,...R.length?{tool_calls:R}:{}},model:u,usage:{inputTokens:m,outputTokens:d,...p===void 0?{}:{cacheReadTokens:p},...y===void 0?{}:{cacheWriteTokens:y}}}}catch(o){throw n.signal?.aborted?yt(n.signal.reason):ws(o,this.options.baseUrl)}finally{r.cleanup()}}};var _e=["fast","balanced","complex","reasoning","large-context","vision","security"];function bt(t){return _e.includes(t)}var Qc=[{route:"vision",score:8,words:["image","screenshot","diagram","visual","ui mockup","photo","video","multimodal"]},{route:"security",score:7,words:["security","security audit","vulnerability","vulnerabilities","threat model","penetration test","xss","csrf","sql injection","authentication bypass","authorization bypass","cryptography","secret leak","owasp"]},{route:"reasoning",score:6,words:["prove","root cause","deep analysis","formal","algorithm","optimize","concurrency","race condition","distributed","debug complex"]},{route:"complex",score:5,words:["architecture","migration","repository-wide","large refactor","multi-service","implement feature","production-ready","redesign","framework upgrade"]},{route:"balanced",score:3,words:["fix","refactor","test","review","implement","bug","api","database","typescript"]},{route:"fast",score:2,words:["rename","explain","summarize","format","typo","comment","small change","documentation"]}];function or(t,e={}){return e.hasImages?{route:"vision",confidence:.99,reason:"The request includes image input."}:(e.estimatedContextTokens??0)>=18e4||t.length>=8e4?{route:"large-context",confidence:.96,reason:"The request requires an unusually large context window."}:null}function sn(t,e={}){let n=or(t,e);if(n)return n;let r=t.toLowerCase(),o=new Map;for(let l of Qc)for(let u of l.words)r.includes(u)&&o.set(l.route,(o.get(l.route)??0)+l.score);t.length>12e3&&o.set("large-context",(o.get("large-context")??0)+5),t.length>3e3&&o.set("complex",(o.get("complex")??0)+2),/\b(one[- ]?liner|quick|simple|minor)\b/.test(r)&&o.set("fast",(o.get("fast")??0)+3);let s=[...o.entries()].sort((l,u)=>u[1]-l[1]),i=s[0];if(!i)return{route:"balanced",confidence:.55,reason:"No specialist signal was strong enough; using the balanced coding model."};let a=s[1]?.[1]??0,c=Math.min(.98,.58+Math.max(0,i[1]-a)*.05);return{route:i[0],confidence:c,reason:`Prompt signals matched the ${i[0]} route.`}}import{spawn as tl}from"node:child_process";var ys="2025-11-25",bs=new Set([ys,"2025-06-18","2025-03-26"]);function re(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`${e} must be an object.`);return t}function an(t){return t.replace(/[^a-zA-Z0-9_-]/g,"_").replace(/^_+|_+$/g,"")||"unnamed"}function nl(t,e=200){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function vs(t){if(!t)return"[MCP tool returned no result]";let e=re(t,"MCP tool result"),n=e.content;if(!Array.isArray(n))return JSON.stringify(t,null,2);let r=[];for(let o of n){if(!o||typeof o!="object"||Array.isArray(o))continue;let s=o;s.type==="text"&&typeof s.text=="string"?r.push(s.text):r.push(JSON.stringify(s))}return e.structuredContent!==void 0&&r.push(JSON.stringify(e.structuredContent,null,2)),r.join(`
146
+ `)||JSON.stringify(t,null,2)}var sr=class{name;config;child;nextId=1;buffer="";pending=new Map;initialized=!1;serverInfo={};constructor(e,n){if(!n.command.trim())throw new Error(`MCP server ${e} requires a command.`);this.name=an(e),this.config={...n,args:n.args??[],timeoutMs:n.timeoutMs??3e4,enabled:n.enabled??!0}}async connect(e){if(this.initialized)return;if(!this.config.enabled)throw new Error(`MCP server ${this.name} is disabled.`);this.child=tl(this.config.command,this.config.args,{cwd:this.config.cwd,env:{...process.env,...this.config.env},stdio:["pipe","pipe","pipe"]}),this.child.stdout.setEncoding("utf8"),this.child.stderr.setEncoding("utf8"),this.child.stdout.on("data",o=>this.consume(o)),this.child.stderr.on("data",o=>{}),this.child.once("error",o=>this.failAll(o)),this.child.once("close",o=>{this.initialized=!1,this.failAll(new Error(`MCP server ${this.name} exited with code ${o??1}.`))});let n=re(await this.request("initialize",{protocolVersion:ys,capabilities:{},clientInfo:{name:"kpilot",title:"kpilot",version:"0.10.45",description:"Local-first AI coding agent"}},e),"MCP initialize result"),r=typeof n.protocolVersion=="string"?n.protocolVersion:"";if(!bs.has(r))throw await this.close(),new Error(`MCP server ${this.name} negotiated unsupported protocol version ${r||"[missing]"}.`);this.serverInfo=re(n.serverInfo,"MCP serverInfo"),this.notify("notifications/initialized",{}),this.initialized=!0}consume(e){this.buffer+=e;let n=this.buffer.split(/\r?\n/);this.buffer=n.pop()??"";for(let r of n){if(!r.trim())continue;let o;try{o=JSON.parse(r)}catch{this.failAll(new Error(`MCP server ${this.name} emitted invalid JSON on stdout.`));continue}if(o.id!==void 0&&(o.result!==void 0||o.error)){let s=this.pending.get(o.id);if(!s)continue;clearTimeout(s.timeout),this.pending.delete(o.id),o.error?s.reject(new Error(`MCP ${this.name}: ${o.error.message??`error ${o.error.code??"unknown"}`}`)):s.resolve(o.result??null)}else o.id!==void 0&&o.method&&this.write({jsonrpc:"2.0",id:o.id,error:{code:-32601,message:`Client method not supported: ${o.method}`}})}}write(e){if(!this.child?.stdin?.writable)throw new Error(`MCP server ${this.name} is not connected.`);this.child.stdin.write(`${JSON.stringify(e)}
147
+ `)}notify(e,n){this.write({jsonrpc:"2.0",method:e,params:n})}async request(e,n,r){if(r?.aborted)throw new Error(`MCP request cancelled: ${String(r.reason??"")}`);let o=this.nextId++;return await new Promise((s,i)=>{let a=setTimeout(()=>{this.pending.delete(o),this.notify("notifications/cancelled",{requestId:o,reason:"timeout"}),i(new Error(`MCP ${this.name} request timed out: ${e}`))},this.config.timeoutMs),c=()=>{clearTimeout(a),this.pending.delete(o);try{this.notify("notifications/cancelled",{requestId:o,reason:"user cancellation"})}catch{}i(new Error(`MCP request cancelled: ${e}`))};r?.addEventListener("abort",c,{once:!0}),this.pending.set(o,{resolve:l=>{r?.removeEventListener("abort",c),s(l)},reject:l=>{r?.removeEventListener("abort",c),i(l)},timeout:a});try{this.write({jsonrpc:"2.0",id:o,method:e,params:n})}catch(l){clearTimeout(a),this.pending.delete(o),i(l instanceof Error?l:new Error(String(l)))}})}async listTools(e){await this.connect(e);let n=[],r;do{let o=re(await this.request("tools/list",r?{cursor:r}:{},e),"MCP tools/list result"),s=o.tools;if(!Array.isArray(s))throw new Error(`MCP server ${this.name} returned an invalid tool list.`);for(let i of s){let a=re(i,"MCP tool");if(typeof a.name!="string")throw new Error(`MCP server ${this.name} returned a tool without a name.`);n.push({name:a.name,title:typeof a.title=="string"?a.title:void 0,description:typeof a.description=="string"?a.description:void 0,inputSchema:re(a.inputSchema,`MCP inputSchema for ${a.name}`)})}r=typeof o.nextCursor=="string"?o.nextCursor:void 0}while(r);return n}async callTool(e,n,r){await this.connect(r);let o=await this.request("tools/call",{name:e,arguments:n},r);return{ok:re(o,"MCP tools/call result").isError!==!0,output:vs(o),metadata:{server:this.name,tool:e}}}info(){return{name:this.name,serverInfo:this.serverInfo,connected:this.initialized}}failAll(e){for(let n of this.pending.values())clearTimeout(n.timeout),n.reject(e);this.pending.clear()}async close(){if(!this.child)return;let e=this.child;this.child=void 0,this.initialized=!1,await new Promise(n=>{let r=!1,o=()=>{r||(r=!0,clearTimeout(s),clearTimeout(i),clearTimeout(a),n())};e.once("close",o),e.stdin?.end();let s=setTimeout(()=>e.kill("SIGTERM"),300),i=setTimeout(()=>e.kill("SIGKILL"),900),a=setTimeout(o,1200)})}},ir=class{name;config;url;nextId=1;pending=new Map;initialized=!1;serverInfo={};constructor(e,n){if(!n.url?.trim())throw new Error(`MCP server ${e} requires url for ${n.transport??"http"} transport.`);let r=new URL(n.url);if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`MCP server ${e} http transport requires an http(s) url; got ${r.protocol}`);this.name=an(e),this.config={...n,timeoutMs:n.timeoutMs??3e4},this.url=r.href}headers(){return{"Content-Type":"application/json",Accept:"application/json, text/event-stream","MCP-Protocol-Version":"2025-06-18",...this.config.token?{Authorization:`Bearer ${this.config.token}`}:{},...this.config.headers}}async connect(e){if(this.initialized)return;if(this.config.enabled===!1)throw new Error(`MCP server ${this.name} is disabled.`);let n=re(await this.request("initialize",{protocolVersion:"2025-06-18",capabilities:{},clientInfo:{name:"kpilot",title:"kpilot",version:"0.10.45",description:"Local-first AI coding agent"}},e),"MCP initialize result"),r=typeof n.protocolVersion=="string"?n.protocolVersion:"";if(!bs.has(r))throw new Error(`MCP server ${this.name} negotiated unsupported protocol version ${r||"[missing]"}.`);this.serverInfo=re(n.serverInfo,"MCP serverInfo"),this.notify("notifications/initialized",{}),this.initialized=!0}async request(e,n,r){if(r?.aborted)throw new Error(`MCP request cancelled: ${String(r.reason??"")}`);let o=this.nextId++;return await new Promise((s,i)=>{let a=setTimeout(()=>{this.pending.delete(o),this.notify("notifications/cancelled",{requestId:o,reason:"timeout"}),i(new Error(`MCP ${this.name} request timed out: ${e}`))},this.config.timeoutMs),c=()=>{clearTimeout(a),this.pending.delete(o);try{this.notify("notifications/cancelled",{requestId:o,reason:"user cancellation"})}catch{}i(new Error(`MCP request cancelled: ${e}`))};r?.addEventListener("abort",c,{once:!0});let l=u=>{r?.removeEventListener("abort",c),u()};this.pending.set(o,{resolve:u=>l(()=>s(u)),reject:u=>l(()=>i(u)),timer:a}),this.postBody({jsonrpc:"2.0",id:o,method:e,params:n}).then(u=>this.consumeResponse(u)).catch(u=>{let m=this.pending.get(o);m&&(clearTimeout(m.timer),this.pending.delete(o),l(()=>i(u instanceof Error?u:new Error(String(u)))))})})}notify(e,n){return this.postBody({jsonrpc:"2.0",method:e,params:n}).then(r=>{r?.body?.cancel().catch(()=>{})}).catch(()=>{})}async postBody(e){return await fetch(this.url,{method:"POST",headers:this.headers(),body:JSON.stringify(e),signal:AbortSignal.timeout(this.config.timeoutMs)})}async consumeResponse(e){let n=e.headers.get("content-type")??"";n.includes("text/event-stream")?await this.consumeSse(e):n.includes("application/json")?await this.consumeJson(e):await e.body?.cancel().catch(()=>{})}async consumeSse(e){if(!e.body)return;let n=e.body.getReader(),r=new TextDecoder,o="";for(;;){let{done:s,value:i}=await n.read();if(s)break;o+=r.decode(i,{stream:!0});let a=o.indexOf(`
136
148
  `);for(;a!==-1;){let c=o.slice(0,a).trim();if(o=o.slice(a+1),c.startsWith("data:")){let l=c.slice(5).trim();l&&this.routeMessage(this.safelyParse(l))}a=o.indexOf(`
137
- `)}}}async consumeJson(e){let n=await e.text();n.trim()&&this.routeMessage(this.safelyParse(n))}safelyParse(e){try{return JSON.parse(e)}catch{return null}}routeMessage(e){if(!e||e.id===void 0||typeof e.id!="number"||!("result"in e)&&!e.error)return;let n=this.pending.get(e.id);n&&(clearTimeout(n.timer),this.pending.delete(e.id),e.error?n.reject(new Error(`MCP ${this.name}: ${e.error.message??`error ${e.error.code??"unknown"}`}`)):n.resolve(e.result??null))}async listTools(e){await this.connect(e);let n=[],r;do{let o=ne(await this.request("tools/list",r?{cursor:r}:{},e),"MCP tools/list result"),s=o.tools;if(!Array.isArray(s))throw new Error(`MCP server ${this.name} returned an invalid tool list.`);for(let i of s){let a=ne(i,"MCP tool");if(typeof a.name!="string")throw new Error(`MCP server ${this.name} returned a tool without a name.`);n.push({name:a.name,title:typeof a.title=="string"?a.title:void 0,description:typeof a.description=="string"?a.description:void 0,inputSchema:ne(a.inputSchema,`MCP inputSchema for ${a.name}`)})}r=typeof o.nextCursor=="string"?o.nextCursor:void 0}while(r);return n}async callTool(e,n,r){await this.connect(r);let o=await this.request("tools/call",{name:e,arguments:n},r);return{ok:ne(o,"MCP tools/call result").isError!==!0,output:cs(o),metadata:{server:this.name,tool:e}}}info(){return{name:this.name,serverInfo:this.serverInfo,connected:this.initialized}}async close(){this.initialized=!1;for(let e of this.pending.values())clearTimeout(e.timer),e.reject(new Error("MCP client closed."));this.pending.clear()}},Ae=class t{tools=new Map;clients;constructor(e){this.clients=e}static async connect(e,n){let r=Object.entries(e).filter(([,s])=>s.enabled!==!1).map(([s,i])=>(i.transport??"stdio")==="stdio"?new Xn(s,i):new Zn(s,i)),o=new t(r);for(let s of r){let i=await s.listTools(n);for(let a of i){let c=`mcp_${nn(s.name)}_${nn(a.name)}`;if(o.tools.has(c))throw new Error(`Duplicate MCP tool name: ${c}`);o.tools.set(c,{client:s,remoteName:a.name,definition:{type:"function",function:{name:c,description:`[MCP:${s.name}] ${Fc(a.description??a.title??a.name)}`,parameters:a.inputSchema}}})}}return o}definitions(){return[...this.tools.values()].map(e=>e.definition)}async execute(e,n,r){let o=this.tools.get(e);return o?await o.client.callTool(o.remoteName,n,r.signal):{ok:!1,output:`Unknown MCP tool: ${e}`}}list(){return[...this.tools.entries()].map(([e,n])=>({exposedName:e,server:n.client.name,remoteName:n.remoteName,description:n.definition.function.description}))}async close(){await Promise.all(this.clients.map(e=>e.close()))}};var Bc="2025-11-25",qc=["2025-11-25","2025-06-18","2025-03-26"];function Jc(t){return t.map(e=>({name:e.function.name,description:e.function.description,inputSchema:e.function.parameters??{type:"object",properties:{}}}))}function ls(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`${e} must be an object.`);return t}var rn=class{name;version;rootDir;mode;runtime;initialized=!1;constructor(e,n){this.runtime=e,this.name=n.name??"kpilot",this.version=n.version??"0.0.0",this.rootDir=n.rootDir,this.mode=n.mode??"write"}async dispatch(e){let n=e.id,r=e.method;if(!(typeof n=="number"||typeof n=="string"))return r==="notifications/initialized"&&(this.initialized=!0),null;let s=ls(e.params??{},`${r} params`);try{let i=await this.handleMethod(String(r??""),s);return r==="initialize"&&(this.initialized=!0),{jsonrpc:"2.0",id:n,result:i}}catch(i){let a=i instanceof Error?i.message:String(i);return{jsonrpc:"2.0",id:n,error:{code:r==="tools/call"?-32603:-32601,message:a}}}}async handleMethod(e,n){switch(e){case"initialize":{let r=typeof n.protocolVersion=="string"?n.protocolVersion:"";return{protocolVersion:qc.includes(r)?r:Bc,capabilities:{tools:{listChanged:!1}},serverInfo:{name:this.name,version:this.version}}}case"ping":return{};case"tools/list":{let r=Jc(this.runtime.definitions());return typeof n.cursor=="string"?{tools:[],nextCursor:void 0}:{tools:r}}case"tools/call":{let r=typeof n.name=="string"?n.name:"";if(!r)throw new Error("tools/call requires a name.");let o=ls(n.arguments??{},"tools/call arguments"),s={rootDir:this.rootDir,mode:this.mode},i=await this.runtime.execute(r,o,s);return{content:[{type:"text",text:i.output??""}],isError:i.ok!==!0}}default:throw new Error(`Method not found: ${e}`)}}};function us(t){if(!t.trim())return null;try{let e=JSON.parse(t);return e&&typeof e=="object"&&!Array.isArray(e)?e:null}catch{return null}}async function ms(t){await new Promise((e,n)=>{let r="";process.stdin.setEncoding("utf8");let o=(s,i=!1)=>{r+=s;let a=r.indexOf(`
138
- `);for(;a!==-1;){let c=r.slice(0,a);r=r.slice(a+1);let l=us(c);l&&ds(t,l),a=r.indexOf(`
139
- `)}if(i&&r.trim()){let c=us(r.trim());c&&ds(t,c),r=""}};process.stdin.on("data",s=>o(s)),process.stdin.on("end",()=>{o("",!0),e()}),process.stdin.on("error",n)})}async function ds(t,e){let n=await t.dispatch(e);n&&process.stdout.write(`${JSON.stringify(n)}
140
- `)}var ce={filesystem:{read:"allow",write:"ask",delete:"ask"},shell:{readOnly:"allow",mutating:"ask",destructive:"deny"},git:{read:"allow",write:"ask"},network:{search:"ask",fetch:"ask"},mcp:{call:"ask"},subagents:{delegate:"allow"}},Kc=[/\brm\s+-[^\n]*r[^\n]*f\b/i,/\bmkfs(?:\.|\s)/i,/\bdd\s+[^\n]*\bof=/i,/\bshutdown\b/i,/\breboot\b/i,/\bpoweroff\b/i,/\bhalt\b/i,/\bgit\s+reset\s+--hard\b/i,/\bgit\s+clean\s+-[^\n]*f/i,/\bDROP\s+(?:DATABASE|SCHEMA|TABLE)\b/i,/\bTRUNCATE\s+TABLE\b/i,/\bcurl\b[^\n|]*\|\s*(?:sudo\s+)?(?:sh|bash|zsh)\b/i,/\bwget\b[^\n|]*\|\s*(?:sudo\s+)?(?:sh|bash|zsh)\b/i,/\|\s*(?:sudo\s+)?(?:sh|bash|zsh|pwsh|powershell)(?:\s|$)/i,/\bchmod\s+-R\b/i,/\bchown\s+-R\b/i],Wc=[/^pwd(?:\s|$)/i,/^ls(?:\s|$)/i,/^find(?:\s|$)/i,/^rg(?:\s|$)/i,/^grep(?:\s|$)/i,/^cat(?:\s|$)/i,/^head(?:\s|$)/i,/^tail(?:\s|$)/i,/^sed\s+-n(?:\s|$)/i,/^wc(?:\s|$)/i,/^file(?:\s|$)/i,/^stat(?:\s|$)/i,/^cd(?:\s|$)/i,/^git\s+(?:status|diff|log|show|branch|rev-parse|ls-files)(?:\s|$)/i,/^(?:node|npm|pnpm|yarn|bun)\s+--version(?:\s|$)/i,/^which(?:\s|$)/i,/^whereis(?:\s|$)/i,/^echo(?:\s|$)/i];function Gc(t){let e=t.trim();if(Kc.some(r=>r.test(e)))return"destructive";if(/(?:^|[^<])>{1,2}|\btee(?:\s|$)|\bsed\s+-i(?:\s|$)/i.test(e))return"mutating";let n=e.split(/&&|\|\||\||;|\n/).map(r=>r.trim()).filter(Boolean);return n.length>0&&n.every(r=>Wc.some(o=>o.test(r)))?"readOnly":"mutating"}function Z(t,e,n,r,o){return{tool:t,category:e,decision:n,reason:r,summary:o}}function yt(t){let e=X(t,"path")??X(t,"cwd")??".";return e.length>100?`${e.slice(0,97)}...`:e}function ps(t,e){let n=X(t,"query")??X(t,"url")??e;return n.length>100?`${n.slice(0,97)}...`:n}var Ke=class{policy;constructor(e=ce){this.policy=e}inspect(e,n,r){switch(e){case"list_files":case"read_file":case"search_text":case"workspace_summary":return Z(e,"filesystem.read",this.policy.filesystem.read,"Reads project files only.",yt(n));case"write_file":case"replace_in_file":case"make_directory":return r==="plan"?Z(e,"filesystem.write","deny","Plan mode cannot change files.",yt(n)):Z(e,"filesystem.write",this.policy.filesystem.write,"Changes a project file.",yt(n));case"delete_path":return r==="plan"?Z(e,"filesystem.delete","deny","Plan mode cannot delete files.",yt(n)):Z(e,"filesystem.delete",this.policy.filesystem.delete,"Deletes a path inside the project.",yt(n));case"git_status":case"git_diff":return Z(e,"git.read",this.policy.git.read,"Reads repository state.",".git");case"web_search":return Z(e,"network.search",this.policy.network.search,"Queries the public web (DuckDuckGo first; Brave if keyed and free search fails).",ps(n,"web search"));case"web_fetch":return Z(e,"network.fetch",this.policy.network.fetch,"Fetches a public http(s) URL and returns extracted text.",ps(n,"web fetch"));case"delegate_subagents":return Z(e,"subagents.delegate",this.policy.subagents.delegate,"Runs read-only specialist agents in parallel.","read-only repository analysis");case(e.startsWith("mcp_")?e:""):return r==="plan"?Z(e,"mcp.call","deny","MCP tools are denied in plan mode because their side effects are not knowable locally.",e):Z(e,"mcp.call",this.policy.mcp.call,"Invokes an external MCP tool whose side effects depend on its server.",e);case"shell":{let o=U(n,"command",{maximumLength:2e4}),s=Gc(o);return r==="plan"&&s!=="readOnly"?Z(e,`shell.${s}`,"deny","Plan mode permits only read-only shell commands.",o):Z(e,`shell.${s}`,this.policy.shell[s],`Command classified as ${s}.`,o)}default:return Z(e,"unknown","deny","Unknown tools are denied by default.",e)}}async authorize(e,n,r,o,s={}){let i=this.inspect(e,n,r);if(i.decision==="allow")return{...i,approved:!0};if(s.bypassPermissions&&r!=="plan"&&i.category!=="unknown")return{...i,decision:"allow",reason:`${i.reason} Auto-approved (bypass).`,approved:!0};if(i.decision==="deny")return{...i,approved:!1};let a=await o(i);return{...i,approved:a}}};import{mkdir as Hc,readFile as zc,rename as Vc,stat as Yc,writeFile as Qc}from"node:fs/promises";import{randomUUID as tr}from"node:crypto";import er from"node:path";async function Xc(t){try{return await Yc(t),!0}catch{return!1}}async function fs(t,e){await Hc(er.dirname(t),{recursive:!0});let n=`${t}.${tr()}.tmp`;await Qc(n,`${JSON.stringify(e,null,2)}
141
- `,"utf8"),await Vc(n,t)}function Zc(){return{schemaVersion:1,rules:[],feedback:[]}}function el(t){let e;try{e=JSON.parse(t)}catch(r){throw new Error(`Invalid preferences JSON: ${r instanceof Error?r.message:String(r)}`)}if(typeof e!="object"||e===null||Array.isArray(e))throw new Error("Preferences document must be an object.");let n=e;if(n.schemaVersion!==1||!Array.isArray(n.rules)||!Array.isArray(n.feedback))throw new Error("Unsupported preferences document schema.");return n}function tl(t){return t.split(/\r?\n/).filter(e=>e.startsWith("+")&&!e.startsWith("+++")).map(e=>e.slice(1))}function nl(t){return t.split(/\r?\n/).filter(e=>e.startsWith("+++ b/")).map(e=>e.slice(6))}function rl(t){let e=tl(t),n=nl(t),r=[];if(e.length===0)return r;let o=e.filter(d=>/(?:^|[=(,:\s])'[^']*'/.test(d)).length,s=e.filter(d=>/(?:^|[=(,:\s])"[^"]*"/.test(d)).length;o+s>=6&&(o>=s*2?r.push({text:"Use single quotes for string literals where the language permits.",confidence:.62,source:"heuristic:quotes"}):s>=o*2&&r.push({text:"Use double quotes for string literals where the language permits.",confidence:.62,source:"heuristic:quotes"}));let i=e.filter(d=>/;\s*$/.test(d.trim())).length,a=e.filter(d=>/^(?:\s*)(?:const|let|var|return|throw|import|export|[A-Za-z_$][\w$]*\s*=)/.test(d)).length;a>=8&&i>=a*.7&&r.push({text:"Terminate applicable statements with semicolons.",confidence:.58,source:"heuristic:semicolon"});let c=n.filter(d=>/\.(?:test|spec)\.[cm]?[jt]sx?$/.test(d)),l=c.filter(d=>/\.test\./.test(d)).length,u=c.filter(d=>/\.spec\./.test(d)).length;return c.length>=2&&l>u?r.push({text:"Name test files with the .test.* convention.",confidence:.68,source:"heuristic:test-name"}):c.length>=2&&u>l&&r.push({text:"Name test files with the .spec.* convention.",confidence:.68,source:"heuristic:test-name"}),n.some(d=>d.endsWith("pnpm-lock.yaml"))?r.push({text:"Use pnpm as the package manager for this project.",confidence:.9,source:"heuristic:package-manager"}):n.some(d=>d.endsWith("yarn.lock"))?r.push({text:"Use Yarn as the package manager for this project.",confidence:.9,source:"heuristic:package-manager"}):n.some(d=>d.endsWith("package-lock.json"))&&r.push({text:"Use npm as the package manager for this project.",confidence:.9,source:"heuristic:package-manager"}),e.filter(d=>/^\s*import\s+type\b/.test(d)).length>=3&&r.push({text:"Use TypeScript type-only imports when imports are used only as types.",confidence:.65,source:"heuristic:type-imports"}),r}function ol(t){return t.trim().replace(/\s+/g," ")}function gs(t,e){let n=ol(e.text),r=t.rules.find(i=>i.polarity===e.polarity&&i.text.toLowerCase()===n.toLowerCase()),o=new Date().toISOString();if(r)return r.evidenceCount+=1,r.confidence=Math.min(.99,Number((r.confidence+(1-r.confidence)*e.confidence*.35).toFixed(3))),r.updatedAt=o,r.sources.includes(e.source)||r.sources.push(e.source),r;let s={id:tr(),text:n,polarity:e.polarity,confidence:e.confidence,evidenceCount:1,createdAt:o,updatedAt:o,sources:[e.source]};return t.rules.push(s),s}var on=class{rootDir;filePath;constructor(e){this.rootDir=er.resolve(e),this.filePath=er.join(this.rootDir,E,"preferences.json")}async readDocument(){return await Xc(this.filePath)?el(await zc(this.filePath,"utf8")):Zc()}async listRules(){return[...(await this.readDocument()).rules].sort((n,r)=>r.confidence-n.confidence||r.updatedAt.localeCompare(n.updatedAt))}async listFeedback(){return[...(await this.readDocument()).feedback].sort((n,r)=>r.createdAt.localeCompare(n.createdAt))}async learn(e){if(!e.task.trim())throw new Error("Feedback must reference a non-empty task.");let n=await this.readDocument(),r=[],o=`feedback:${e.outcome}`;e.note?.trim()&&r.push(gs(n,{text:e.note,polarity:e.outcome==="rejected"?"avoid":"prefer",confidence:e.outcome==="edited"?.92:.88,source:`${o}:note`}));let s=e.outcome==="edited"?e.finalDiff:e.outcome==="accepted"?e.proposedDiff:void 0;if(s?.trim())for(let a of rl(s))r.push(gs(n,{text:a.text,polarity:"prefer",confidence:e.outcome==="edited"?Math.min(.95,a.confidence+.12):a.confidence,source:`${o}:${a.source}`}));let i={id:tr(),outcome:e.outcome,task:e.task.trim(),note:e.note?.trim()||void 0,sessionId:e.sessionId,proposedDiff:e.proposedDiff,finalDiff:e.finalDiff,createdAt:new Date().toISOString(),learnedRuleIds:[...new Set(r.map(a=>a.id))]};return n.feedback.push(i),n.feedback.length>500&&(n.feedback=n.feedback.slice(-500)),await fs(this.filePath,n),{feedback:i,learned:[...new Map(r.map(a=>[a.id,a])).values()]}}async removeRule(e){let n=await this.readDocument(),r=n.rules.filter(s=>s.id.startsWith(e));if(r.length===0)throw new Error(`Preference rule not found: ${e}`);if(r.length>1)throw new Error(`Preference rule prefix is ambiguous: ${e}`);let o=r[0];return n.rules=n.rules.filter(s=>s.id!==o.id),await fs(this.filePath,n),o}async renderForPrompt(e=.55,n=12e3){let r=(await this.listRules()).filter(i=>i.confidence>=e),o=[],s=0;for(let i of r){let c=`- ${i.polarity==="prefer"?"Prefer":"Avoid"}: ${i.text} (confidence ${Math.round(i.confidence*100)}%)`;if(s+c.length+1>n)break;o.push(c),s+=c.length+1}return o.join(`
142
- `)}};import{mkdir as sl,readFile as hs,readdir as il,rename as al,rm as cl,stat as ll,writeFile as ul}from"node:fs/promises";import{randomUUID as bs}from"node:crypto";import We from"node:path";function nr(t){let e=t.trim();if(!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/.test(e))throw new Error("Session ID may contain only letters, numbers, underscores, and hyphens.");return e}async function ws(t){try{return await ll(t),!0}catch{return!1}}async function dl(t,e){await sl(We.dirname(t),{recursive:!0});let n=`${t}.${process.pid??"tmp"}.${bs()}.tmp`;await ul(n,`${JSON.stringify(e,null,2)}
143
- `,"utf8"),await al(n,t)}function ys(t,e){let n;try{n=JSON.parse(t)}catch(o){throw new Error(`Invalid session JSON in ${e}: ${o instanceof Error?o.message:String(o)}`)}if(typeof n!="object"||n===null||Array.isArray(n))throw new Error(`Session file ${e} does not contain an object.`);let r=n;if(r.schemaVersion!==1||typeof r.id!="string"||typeof r.title!="string")throw new Error(`Session file ${e} has an unsupported schema.`);if(!Array.isArray(r.messages)||!Array.isArray(r.runs))throw new Error(`Session file ${e} is missing messages or runs.`);return r}var sn=class{rootDir;directory;constructor(e){this.rootDir=We.resolve(e),this.directory=We.join(this.rootDir,E,"sessions")}filePath(e){return We.join(this.directory,`${nr(e)}.json`)}async create(e){let n=new Date().toISOString(),o={schemaVersion:1,id:bs(),title:e.title?.trim()||`Session ${n.slice(0,16).replace("T"," ")}`,rootDir:this.rootDir,createdAt:n,updatedAt:n,mode:e.mode,model:e.model,messages:[],runs:[]};return await this.save(o),o}async save(e){if(nr(e.id),We.resolve(e.rootDir)!==this.rootDir)throw new Error("Session belongs to a different project root.");e.updatedAt=new Date().toISOString(),await dl(this.filePath(e.id),e)}async load(e){let n=await this.resolveId(e),r=this.filePath(n);return ys(await hs(r,"utf8"),r)}async resolveId(e){let n=nr(e),r=this.filePath(n);if(await ws(r))return n;let s=(await this.list()).filter(i=>i.id.startsWith(n));if(s.length===0)throw new Error(`Session not found: ${e}`);if(s.length>1)throw new Error(`Session prefix is ambiguous: ${e}`);return s[0].id}async list(){if(!await ws(this.directory))return[];let e=await il(this.directory,{withFileTypes:!0}),n=[];for(let r of e){if(!r.isFile()||!r.name.endsWith(".json"))continue;let o=We.join(this.directory,r.name);try{let s=ys(await hs(o,"utf8"),o);n.push({id:s.id,title:s.title,updatedAt:s.updatedAt,mode:s.mode,model:s.model,messageCount:s.messages.length,runCount:s.runs.length})}catch{}}return n.sort((r,o)=>o.updatedAt.localeCompare(r.updatedAt))}async delete(e){let n=await this.resolveId(e);await cl(this.filePath(n),{force:!1})}};import{readFile as ml,readdir as pl,stat as fl}from"node:fs/promises";import{homedir as gl}from"node:os";import bt from"node:path";async function vs(t){try{return await fl(t),!0}catch{return!1}}function hl(t){if(!t.startsWith(`---
149
+ `)}}}async consumeJson(e){let n=await e.text();n.trim()&&this.routeMessage(this.safelyParse(n))}safelyParse(e){try{return JSON.parse(e)}catch{return null}}routeMessage(e){if(!e||e.id===void 0||typeof e.id!="number"||!("result"in e)&&!e.error)return;let n=this.pending.get(e.id);n&&(clearTimeout(n.timer),this.pending.delete(e.id),e.error?n.reject(new Error(`MCP ${this.name}: ${e.error.message??`error ${e.error.code??"unknown"}`}`)):n.resolve(e.result??null))}async listTools(e){await this.connect(e);let n=[],r;do{let o=re(await this.request("tools/list",r?{cursor:r}:{},e),"MCP tools/list result"),s=o.tools;if(!Array.isArray(s))throw new Error(`MCP server ${this.name} returned an invalid tool list.`);for(let i of s){let a=re(i,"MCP tool");if(typeof a.name!="string")throw new Error(`MCP server ${this.name} returned a tool without a name.`);n.push({name:a.name,title:typeof a.title=="string"?a.title:void 0,description:typeof a.description=="string"?a.description:void 0,inputSchema:re(a.inputSchema,`MCP inputSchema for ${a.name}`)})}r=typeof o.nextCursor=="string"?o.nextCursor:void 0}while(r);return n}async callTool(e,n,r){await this.connect(r);let o=await this.request("tools/call",{name:e,arguments:n},r);return{ok:re(o,"MCP tools/call result").isError!==!0,output:vs(o),metadata:{server:this.name,tool:e}}}info(){return{name:this.name,serverInfo:this.serverInfo,connected:this.initialized}}async close(){this.initialized=!1;for(let e of this.pending.values())clearTimeout(e.timer),e.reject(new Error("MCP client closed."));this.pending.clear()}},Ae=class t{tools=new Map;clients;constructor(e){this.clients=e}static async connect(e,n){let r=Object.entries(e).filter(([,s])=>s.enabled!==!1).map(([s,i])=>(i.transport??"stdio")==="stdio"?new sr(s,i):new ir(s,i)),o=new t(r);for(let s of r){let i=await s.listTools(n);for(let a of i){let c=`mcp_${an(s.name)}_${an(a.name)}`;if(o.tools.has(c))throw new Error(`Duplicate MCP tool name: ${c}`);o.tools.set(c,{client:s,remoteName:a.name,definition:{type:"function",function:{name:c,description:`[MCP:${s.name}] ${nl(a.description??a.title??a.name)}`,parameters:a.inputSchema}}})}}return o}definitions(){return[...this.tools.values()].map(e=>e.definition)}async execute(e,n,r){let o=this.tools.get(e);return o?await o.client.callTool(o.remoteName,n,r.signal):{ok:!1,output:`Unknown MCP tool: ${e}`}}list(){return[...this.tools.entries()].map(([e,n])=>({exposedName:e,server:n.client.name,remoteName:n.remoteName,description:n.definition.function.description}))}async close(){await Promise.all(this.clients.map(e=>e.close()))}};var rl="2025-11-25",ol=["2025-11-25","2025-06-18","2025-03-26"];function sl(t){return t.map(e=>({name:e.function.name,description:e.function.description,inputSchema:e.function.parameters??{type:"object",properties:{}}}))}function ks(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`${e} must be an object.`);return t}var cn=class{name;version;rootDir;mode;runtime;initialized=!1;constructor(e,n){this.runtime=e,this.name=n.name??"kpilot",this.version=n.version??"0.0.0",this.rootDir=n.rootDir,this.mode=n.mode??"write"}async dispatch(e){let n=e.id,r=e.method;if(!(typeof n=="number"||typeof n=="string"))return r==="notifications/initialized"&&(this.initialized=!0),null;let s=ks(e.params??{},`${r} params`);try{let i=await this.handleMethod(String(r??""),s);return r==="initialize"&&(this.initialized=!0),{jsonrpc:"2.0",id:n,result:i}}catch(i){let a=i instanceof Error?i.message:String(i);return{jsonrpc:"2.0",id:n,error:{code:r==="tools/call"?-32603:-32601,message:a}}}}async handleMethod(e,n){switch(e){case"initialize":{let r=typeof n.protocolVersion=="string"?n.protocolVersion:"";return{protocolVersion:ol.includes(r)?r:rl,capabilities:{tools:{listChanged:!1}},serverInfo:{name:this.name,version:this.version}}}case"ping":return{};case"tools/list":{let r=sl(this.runtime.definitions());return typeof n.cursor=="string"?{tools:[],nextCursor:void 0}:{tools:r}}case"tools/call":{let r=typeof n.name=="string"?n.name:"";if(!r)throw new Error("tools/call requires a name.");let o=ks(n.arguments??{},"tools/call arguments"),s={rootDir:this.rootDir,mode:this.mode},i=await this.runtime.execute(r,o,s);return{content:[{type:"text",text:i.output??""}],isError:i.ok!==!0}}default:throw new Error(`Method not found: ${e}`)}}};function xs(t){if(!t.trim())return null;try{let e=JSON.parse(t);return e&&typeof e=="object"&&!Array.isArray(e)?e:null}catch{return null}}async function Ts(t){await new Promise((e,n)=>{let r="";process.stdin.setEncoding("utf8");let o=(s,i=!1)=>{r+=s;let a=r.indexOf(`
150
+ `);for(;a!==-1;){let c=r.slice(0,a);r=r.slice(a+1);let l=xs(c);l&&Ss(t,l),a=r.indexOf(`
151
+ `)}if(i&&r.trim()){let c=xs(r.trim());c&&Ss(t,c),r=""}};process.stdin.on("data",s=>o(s)),process.stdin.on("end",()=>{o("",!0),e()}),process.stdin.on("error",n)})}async function Ss(t,e){let n=await t.dispatch(e);n&&process.stdout.write(`${JSON.stringify(n)}
152
+ `)}var le={filesystem:{read:"allow",write:"ask",delete:"ask"},shell:{readOnly:"allow",mutating:"ask",destructive:"deny"},git:{read:"allow",write:"ask"},network:{search:"ask",fetch:"ask"},mcp:{call:"ask"},subagents:{delegate:"allow"}},il=[/\brm\s+-[^\n]*r[^\n]*f\b/i,/\bmkfs(?:\.|\s)/i,/\bdd\s+[^\n]*\bof=/i,/\bshutdown\b/i,/\breboot\b/i,/\bpoweroff\b/i,/\bhalt\b/i,/\bgit\s+reset\s+--hard\b/i,/\bgit\s+clean\s+-[^\n]*f/i,/\bDROP\s+(?:DATABASE|SCHEMA|TABLE)\b/i,/\bTRUNCATE\s+TABLE\b/i,/\bcurl\b[^\n|]*\|\s*(?:sudo\s+)?(?:sh|bash|zsh)\b/i,/\bwget\b[^\n|]*\|\s*(?:sudo\s+)?(?:sh|bash|zsh)\b/i,/\|\s*(?:sudo\s+)?(?:sh|bash|zsh|pwsh|powershell)(?:\s|$)/i,/\bchmod\s+-R\b/i,/\bchown\s+-R\b/i],al=[/^pwd(?:\s|$)/i,/^ls(?:\s|$)/i,/^find(?:\s|$)/i,/^rg(?:\s|$)/i,/^grep(?:\s|$)/i,/^cat(?:\s|$)/i,/^head(?:\s|$)/i,/^tail(?:\s|$)/i,/^sed\s+-n(?:\s|$)/i,/^wc(?:\s|$)/i,/^file(?:\s|$)/i,/^stat(?:\s|$)/i,/^cd(?:\s|$)/i,/^git\s+(?:status|diff|log|show|branch|rev-parse|ls-files)(?:\s|$)/i,/^(?:node|npm|pnpm|yarn|bun)\s+--version(?:\s|$)/i,/^which(?:\s|$)/i,/^whereis(?:\s|$)/i,/^echo(?:\s|$)/i];function cl(t){let e=t.trim();if(il.some(r=>r.test(e)))return"destructive";if(/(?:^|[^<])>{1,2}|\btee(?:\s|$)|\bsed\s+-i(?:\s|$)/i.test(e))return"mutating";let n=e.split(/&&|\|\||\||;|\n/).map(r=>r.trim()).filter(Boolean);return n.length>0&&n.every(r=>al.some(o=>o.test(r)))?"readOnly":"mutating"}function Z(t,e,n,r,o){return{tool:t,category:e,decision:n,reason:r,summary:o}}function vt(t){let e=X(t,"path")??X(t,"cwd")??".";return e.length>100?`${e.slice(0,97)}...`:e}function Ps(t,e){let n=X(t,"query")??X(t,"url")??e;return n.length>100?`${n.slice(0,97)}...`:n}var Ke=class{policy;constructor(e=le){this.policy=e}inspect(e,n,r){switch(e){case"list_files":case"read_file":case"search_text":case"workspace_summary":return Z(e,"filesystem.read",this.policy.filesystem.read,"Reads project files only.",vt(n));case"write_file":case"replace_in_file":case"make_directory":return r==="plan"?Z(e,"filesystem.write","deny","Plan mode cannot change files.",vt(n)):Z(e,"filesystem.write",this.policy.filesystem.write,"Changes a project file.",vt(n));case"delete_path":return r==="plan"?Z(e,"filesystem.delete","deny","Plan mode cannot delete files.",vt(n)):Z(e,"filesystem.delete",this.policy.filesystem.delete,"Deletes a path inside the project.",vt(n));case"git_status":case"git_diff":return Z(e,"git.read",this.policy.git.read,"Reads repository state.",".git");case"web_search":return Z(e,"network.search",this.policy.network.search,"Queries the public web (DuckDuckGo first; Brave if keyed and free search fails).",Ps(n,"web search"));case"web_fetch":return Z(e,"network.fetch",this.policy.network.fetch,"Fetches a public http(s) URL and returns extracted text.",Ps(n,"web fetch"));case"delegate_subagents":return Z(e,"subagents.delegate",this.policy.subagents.delegate,"Runs read-only specialist agents in parallel.","read-only repository analysis");case(e.startsWith("mcp_")?e:""):return r==="plan"?Z(e,"mcp.call","deny","MCP tools are denied in plan mode because their side effects are not knowable locally.",e):Z(e,"mcp.call",this.policy.mcp.call,"Invokes an external MCP tool whose side effects depend on its server.",e);case"shell":{let o=F(n,"command",{maximumLength:2e4}),s=cl(o);return r==="plan"&&s!=="readOnly"?Z(e,`shell.${s}`,"deny","Plan mode permits only read-only shell commands.",o):Z(e,`shell.${s}`,this.policy.shell[s],`Command classified as ${s}.`,o)}default:return Z(e,"unknown","deny","Unknown tools are denied by default.",e)}}async authorize(e,n,r,o,s={}){let i=this.inspect(e,n,r);if(i.decision==="allow")return{...i,approved:!0};if(s.bypassPermissions&&r!=="plan"&&i.category!=="unknown")return{...i,decision:"allow",reason:`${i.reason} Auto-approved (bypass).`,approved:!0};if(i.decision==="deny")return{...i,approved:!1};let a=await o(i);return{...i,approved:a}}};import{mkdir as ll,readFile as ul,rename as dl,stat as ml,writeFile as pl}from"node:fs/promises";import{randomUUID as cr}from"node:crypto";import ar from"node:path";async function fl(t){try{return await ml(t),!0}catch{return!1}}async function Es(t,e){await ll(ar.dirname(t),{recursive:!0});let n=`${t}.${cr()}.tmp`;await pl(n,`${JSON.stringify(e,null,2)}
153
+ `,"utf8"),await dl(n,t)}function gl(){return{schemaVersion:1,rules:[],feedback:[]}}function hl(t){let e;try{e=JSON.parse(t)}catch(r){throw new Error(`Invalid preferences JSON: ${r instanceof Error?r.message:String(r)}`)}if(typeof e!="object"||e===null||Array.isArray(e))throw new Error("Preferences document must be an object.");let n=e;if(n.schemaVersion!==1||!Array.isArray(n.rules)||!Array.isArray(n.feedback))throw new Error("Unsupported preferences document schema.");return n}function wl(t){return t.split(/\r?\n/).filter(e=>e.startsWith("+")&&!e.startsWith("+++")).map(e=>e.slice(1))}function yl(t){return t.split(/\r?\n/).filter(e=>e.startsWith("+++ b/")).map(e=>e.slice(6))}function bl(t){let e=wl(t),n=yl(t),r=[];if(e.length===0)return r;let o=e.filter(d=>/(?:^|[=(,:\s])'[^']*'/.test(d)).length,s=e.filter(d=>/(?:^|[=(,:\s])"[^"]*"/.test(d)).length;o+s>=6&&(o>=s*2?r.push({text:"Use single quotes for string literals where the language permits.",confidence:.62,source:"heuristic:quotes"}):s>=o*2&&r.push({text:"Use double quotes for string literals where the language permits.",confidence:.62,source:"heuristic:quotes"}));let i=e.filter(d=>/;\s*$/.test(d.trim())).length,a=e.filter(d=>/^(?:\s*)(?:const|let|var|return|throw|import|export|[A-Za-z_$][\w$]*\s*=)/.test(d)).length;a>=8&&i>=a*.7&&r.push({text:"Terminate applicable statements with semicolons.",confidence:.58,source:"heuristic:semicolon"});let c=n.filter(d=>/\.(?:test|spec)\.[cm]?[jt]sx?$/.test(d)),l=c.filter(d=>/\.test\./.test(d)).length,u=c.filter(d=>/\.spec\./.test(d)).length;return c.length>=2&&l>u?r.push({text:"Name test files with the .test.* convention.",confidence:.68,source:"heuristic:test-name"}):c.length>=2&&u>l&&r.push({text:"Name test files with the .spec.* convention.",confidence:.68,source:"heuristic:test-name"}),n.some(d=>d.endsWith("pnpm-lock.yaml"))?r.push({text:"Use pnpm as the package manager for this project.",confidence:.9,source:"heuristic:package-manager"}):n.some(d=>d.endsWith("yarn.lock"))?r.push({text:"Use Yarn as the package manager for this project.",confidence:.9,source:"heuristic:package-manager"}):n.some(d=>d.endsWith("package-lock.json"))&&r.push({text:"Use npm as the package manager for this project.",confidence:.9,source:"heuristic:package-manager"}),e.filter(d=>/^\s*import\s+type\b/.test(d)).length>=3&&r.push({text:"Use TypeScript type-only imports when imports are used only as types.",confidence:.65,source:"heuristic:type-imports"}),r}function vl(t){return t.trim().replace(/\s+/g," ")}function Rs(t,e){let n=vl(e.text),r=t.rules.find(i=>i.polarity===e.polarity&&i.text.toLowerCase()===n.toLowerCase()),o=new Date().toISOString();if(r)return r.evidenceCount+=1,r.confidence=Math.min(.99,Number((r.confidence+(1-r.confidence)*e.confidence*.35).toFixed(3))),r.updatedAt=o,r.sources.includes(e.source)||r.sources.push(e.source),r;let s={id:cr(),text:n,polarity:e.polarity,confidence:e.confidence,evidenceCount:1,createdAt:o,updatedAt:o,sources:[e.source]};return t.rules.push(s),s}var ln=class{rootDir;filePath;constructor(e){this.rootDir=ar.resolve(e),this.filePath=ar.join(this.rootDir,E,"preferences.json")}async readDocument(){return await fl(this.filePath)?hl(await ul(this.filePath,"utf8")):gl()}async listRules(){return[...(await this.readDocument()).rules].sort((n,r)=>r.confidence-n.confidence||r.updatedAt.localeCompare(n.updatedAt))}async listFeedback(){return[...(await this.readDocument()).feedback].sort((n,r)=>r.createdAt.localeCompare(n.createdAt))}async learn(e){if(!e.task.trim())throw new Error("Feedback must reference a non-empty task.");let n=await this.readDocument(),r=[],o=`feedback:${e.outcome}`;e.note?.trim()&&r.push(Rs(n,{text:e.note,polarity:e.outcome==="rejected"?"avoid":"prefer",confidence:e.outcome==="edited"?.92:.88,source:`${o}:note`}));let s=e.outcome==="edited"?e.finalDiff:e.outcome==="accepted"?e.proposedDiff:void 0;if(s?.trim())for(let a of bl(s))r.push(Rs(n,{text:a.text,polarity:"prefer",confidence:e.outcome==="edited"?Math.min(.95,a.confidence+.12):a.confidence,source:`${o}:${a.source}`}));let i={id:cr(),outcome:e.outcome,task:e.task.trim(),note:e.note?.trim()||void 0,sessionId:e.sessionId,proposedDiff:e.proposedDiff,finalDiff:e.finalDiff,createdAt:new Date().toISOString(),learnedRuleIds:[...new Set(r.map(a=>a.id))]};return n.feedback.push(i),n.feedback.length>500&&(n.feedback=n.feedback.slice(-500)),await Es(this.filePath,n),{feedback:i,learned:[...new Map(r.map(a=>[a.id,a])).values()]}}async removeRule(e){let n=await this.readDocument(),r=n.rules.filter(s=>s.id.startsWith(e));if(r.length===0)throw new Error(`Preference rule not found: ${e}`);if(r.length>1)throw new Error(`Preference rule prefix is ambiguous: ${e}`);let o=r[0];return n.rules=n.rules.filter(s=>s.id!==o.id),await Es(this.filePath,n),o}async renderForPrompt(e=.55,n=12e3){let r=(await this.listRules()).filter(i=>i.confidence>=e),o=[],s=0;for(let i of r){let c=`- ${i.polarity==="prefer"?"Prefer":"Avoid"}: ${i.text} (confidence ${Math.round(i.confidence*100)}%)`;if(s+c.length+1>n)break;o.push(c),s+=c.length+1}return o.join(`
154
+ `)}};import{mkdir as kl,readFile as Cs,readdir as xl,rename as Sl,rm as Tl,stat as Pl,writeFile as El}from"node:fs/promises";import{randomUUID as As}from"node:crypto";import We from"node:path";function Ms(t){let e=t.trim();if(!Os.test(e))throw new Error("Session ID may contain only letters, numbers, underscores, and hyphens.");return e}var Os=/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/;async function $s(t){try{return await Pl(t),!0}catch{return!1}}async function Rl(t,e){await kl(We.dirname(t),{recursive:!0});let n=`${t}.${process.pid??"tmp"}.${As()}.tmp`;await El(n,`${JSON.stringify(e,null,2)}
155
+ `,"utf8"),await Sl(n,t)}function _s(t,e){let n;try{n=JSON.parse(t)}catch(o){throw new Error(`Invalid session JSON in ${e}: ${o instanceof Error?o.message:String(o)}`)}if(typeof n!="object"||n===null||Array.isArray(n))throw new Error(`Session file ${e} does not contain an object.`);let r=n;if(r.schemaVersion!==1||typeof r.id!="string"||typeof r.title!="string")throw new Error(`Session file ${e} has an unsupported schema.`);if(!Array.isArray(r.messages)||!Array.isArray(r.runs))throw new Error(`Session file ${e} is missing messages or runs.`);return r}var un=class{rootDir;directory;constructor(e){this.rootDir=We.resolve(e),this.directory=We.join(this.rootDir,E,"sessions")}filePath(e){return We.join(this.directory,`${Ms(e)}.json`)}async create(e){let n=new Date().toISOString(),r=As(),o=e.title?.trim(),s={schemaVersion:1,id:r,title:o||`Session ${n.slice(0,16).replace("T"," ")}`,titleSource:o?"user":"auto",rootDir:this.rootDir,createdAt:n,updatedAt:n,mode:e.mode,model:e.model,messages:[],runs:[]};return await this.save(s),s}async save(e){if(Ms(e.id),We.resolve(e.rootDir)!==this.rootDir)throw new Error("Session belongs to a different project root.");e.updatedAt=new Date().toISOString(),await Rl(this.filePath(e.id),e)}async load(e){let n=await this.resolveId(e),r=this.filePath(n);return _s(await Cs(r,"utf8"),r)}async resolveId(e){let n=e.trim();if(!n)throw new Error("A session id or name is required.");if(Os.test(n)&&await $s(this.filePath(n)))return n;let r=await this.list(),o=r.filter(i=>i.id.startsWith(n)),s=o.length>0?o:r.filter(i=>i.title.toLowerCase()===n.toLowerCase());if(s.length===0)throw new Error(`Session not found: ${e}`);if(s.length>1)throw new Error(`Session reference is ambiguous: ${e}`);return s[0].id}async list(){if(!await $s(this.directory))return[];let e=await xl(this.directory,{withFileTypes:!0}),n=[];for(let r of e){if(!r.isFile()||!r.name.endsWith(".json"))continue;let o=We.join(this.directory,r.name);try{let s=_s(await Cs(o,"utf8"),o);n.push({id:s.id,title:s.title,updatedAt:s.updatedAt,mode:s.mode,model:s.model,messageCount:s.messages.length,runCount:s.runs.length})}catch{}}return n.sort((r,o)=>o.updatedAt.localeCompare(r.updatedAt))}async delete(e){let n=await this.resolveId(e);await Tl(this.filePath(n),{force:!1})}};import{readFile as Cl,readdir as Ml,stat as $l}from"node:fs/promises";import{homedir as _l}from"node:os";import kt from"node:path";async function Is(t){try{return await $l(t),!0}catch{return!1}}function Al(t){if(!t.startsWith(`---
144
156
  `))return{metadata:{},body:t.trim()};let e=t.indexOf(`
145
157
  ---
146
- `,4);if(e<0)return{metadata:{},body:t.trim()};let n={};for(let r of t.slice(4,e).split(/\r?\n/)){let o=r.indexOf(":");if(o<1)continue;let s=r.slice(0,o).trim().toLowerCase(),i=r.slice(o+1).trim().replace(/^['"]|['"]$/g,"");s&&(n[s]=i)}return{metadata:n,body:t.slice(e+5).trim()}}function xs(t){let e=t.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9_-]{0,63}$/.test(e))throw new Error(`Invalid skill name: ${t}`);return e}async function ks(t,e){if(!await vs(t))return[];let n=await pl(t,{withFileTypes:!0}),r=[];for(let o of n){let s,i=o.name;if(o.isDirectory()?s=bt.join(t,o.name,"SKILL.md"):o.isFile()&&o.name.endsWith(".md")&&(s=bt.join(t,o.name),i=o.name.slice(0,-3)),!s||!await vs(s))continue;let a=hl(await ml(s,"utf8")),c=xs(a.metadata.name||i);a.body&&r.push({name:c,description:a.metadata.description||`Reusable ${c} workflow`,instructions:a.body,source:e,filePath:s})}return r}var an=class{rootDir;projectDirectory;globalDirectory;constructor(e,n=bt.join(gl(),".config","kpilot","skills")){this.rootDir=bt.resolve(e),this.projectDirectory=bt.join(this.rootDir,E,"skills"),this.globalDirectory=n}async list(){let[e,n]=await Promise.all([ks(this.globalDirectory,"global"),ks(this.projectDirectory,"project")]),r=new Map;for(let o of e)r.set(o.name,o);for(let o of n)r.set(o.name,o);return[...r.values()].sort((o,s)=>o.name.localeCompare(s.name))}async get(e){let n=xs(e),r=(await this.list()).find(o=>o.name===n);if(!r)throw new Error(`Skill not found: ${e}`);return r}async renderInvocation(e,n=""){let r=await this.get(e);return`Apply the reusable skill "${r.name}".
158
+ `,4);if(e<0)return{metadata:{},body:t.trim()};let n={};for(let r of t.slice(4,e).split(/\r?\n/)){let o=r.indexOf(":");if(o<1)continue;let s=r.slice(0,o).trim().toLowerCase(),i=r.slice(o+1).trim().replace(/^['"]|['"]$/g,"");s&&(n[s]=i)}return{metadata:n,body:t.slice(e+5).trim()}}function js(t){let e=t.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9_-]{0,63}$/.test(e))throw new Error(`Invalid skill name: ${t}`);return e}async function Ds(t,e){if(!await Is(t))return[];let n=await Ml(t,{withFileTypes:!0}),r=[];for(let o of n){let s,i=o.name;if(o.isDirectory()?s=kt.join(t,o.name,"SKILL.md"):o.isFile()&&o.name.endsWith(".md")&&(s=kt.join(t,o.name),i=o.name.slice(0,-3)),!s||!await Is(s))continue;let a=Al(await Cl(s,"utf8")),c=js(a.metadata.name||i);a.body&&r.push({name:c,description:a.metadata.description||`Reusable ${c} workflow`,instructions:a.body,source:e,filePath:s})}return r}var dn=class{rootDir;projectDirectory;globalDirectory;constructor(e,n=kt.join(_l(),".config","kpilot","skills")){this.rootDir=kt.resolve(e),this.projectDirectory=kt.join(this.rootDir,E,"skills"),this.globalDirectory=n}async list(){let[e,n]=await Promise.all([Ds(this.globalDirectory,"global"),Ds(this.projectDirectory,"project")]),r=new Map;for(let o of e)r.set(o.name,o);for(let o of n)r.set(o.name,o);return[...r.values()].sort((o,s)=>o.name.localeCompare(s.name))}async get(e){let n=js(e),r=(await this.list()).find(o=>o.name===n);if(!r)throw new Error(`Skill not found: ${e}`);return r}async renderInvocation(e,n=""){let r=await this.get(e);return`Apply the reusable skill "${r.name}".
147
159
 
148
160
  Skill instructions:
149
161
  ${r.instructions}
150
162
 
151
163
  Invocation arguments:
152
- ${n.trim()||"[none]"}`}};var vt=class{runtimes;owners=new Map;tools;constructor(e){this.runtimes=e.filter(n=>!!n),this.tools=[];for(let n of this.runtimes)for(let r of n.definitions()){let o=r.function.name;if(this.owners.has(o))throw new Error(`Duplicate tool definition: ${o}`);this.owners.set(o,n),this.tools.push(r)}}definitions(){return[...this.tools]}async execute(e,n,r){let o=this.owners.get(e);return o?await o.execute(e,n,r):{ok:!1,output:`Unknown tool: ${e}`}}};import{mkdir as br,open as Zl,readFile as dn,readdir as eu,realpath as wr,rm as tu,stat as De,writeFile as vr}from"node:fs/promises";import K from"node:path";import{spawn as Js}from"node:child_process";import{spawn as wl}from"node:child_process";import{realpath as Ss}from"node:fs/promises";import cn from"node:path";var yl=new Set(["PATH","HOME","USER","LOGNAME","SHELL","LANG","LC_ALL","LC_CTYPE","TERM","COLORTERM","TMPDIR","TMP","TEMP","XDG_CACHE_HOME","XDG_CONFIG_HOME","XDG_DATA_HOME","CI"]);function bl(t){return process.platform==="win32"?Promise.resolve(!1):new Promise(e=>{let n=wl("/bin/sh",["-lc",`command -v "${t}" >/dev/null 2>&1`],{stdio:"ignore"});n.once("error",()=>e(!1)),n.once("close",r=>e(r===0))})}function vl(t){let e=new Set([...yl,...t]),n={};for(let[r,o]of Object.entries(process.env))(e.has(r)||r.startsWith("npm_")||r.startsWith("PNPM_"))&&(n[r]=o);return n.KPILOT_SANDBOX="1",n}var ln=class{rootDir;config;constructor(e,n={}){if(this.rootDir=cn.resolve(e),this.config={mode:n.mode??"portable",allowNetwork:n.allowNetwork??!1,passEnvironment:n.passEnvironment??[],...n.maxTimeoutMs===void 0?{}:{maxTimeoutMs:n.maxTimeoutMs}},this.config.maxTimeoutMs!==void 0&&(this.config.maxTimeoutMs<100||this.config.maxTimeoutMs>6e5))throw new Error("sandbox.maxTimeoutMs must be between 100 and 600000.")}async backend(){if(this.config.mode==="none")return"none";if(this.config.mode==="portable")return"portable";let e=process.platform==="linux"&&await bl("bwrap");if(this.config.mode==="bwrap"&&!e)throw new Error("sandbox.mode is bwrap, but bubblewrap is unavailable.");return e?"bwrap":"portable"}async prepareShell(e,n,r){let o=cn.resolve(n),[s,i]=await Promise.all([Ss(this.rootDir).catch(()=>this.rootDir),Ss(o).catch(()=>o)]),a=cn.relative(s,i);if(a.startsWith("..")||cn.isAbsolute(a))throw new Error("Sandbox cwd escapes the repository root.");let c=this.config.maxTimeoutMs===void 0?r:Math.min(r,this.config.maxTimeoutMs),l=await this.backend(),u=l==="none"?process.env:vl(this.config.passEnvironment);if(process.platform==="win32")return{command:"cmd.exe",args:["/d","/s","/c",e],cwd:o,env:u,timeoutMs:c,backend:l};if(l!=="bwrap")return{command:"/bin/sh",args:["-lc",e],cwd:o,env:u,timeoutMs:c,backend:l};let m=["--die-with-parent","--new-session","--unshare-pid","--ro-bind","/","/","--bind",this.rootDir,this.rootDir,"--tmpfs","/tmp","--proc","/proc","--dev","/dev","--chdir",o];return this.config.allowNetwork||m.push("--unshare-net"),m.push("/bin/sh","-lc",e),{command:"bwrap",args:m,cwd:o,env:u,timeoutMs:c,backend:l}}async describe(){let e=await this.backend(),n=e==="bwrap"?this.config.allowNetwork?"allowed":"isolated":e==="none"?"unrestricted":"not OS-isolated",r=this.config.maxTimeoutMs===void 0?"unlimited":`${this.config.maxTimeoutMs}ms`;return`${e} (network ${n}, timeout cap ${r})`}};import{lookup as kl}from"node:dns/promises";import{isIP as sr}from"node:net";var xl="https://api.search.brave.com/res/v1/web/search",Es="https://html.duckduckgo.com/html/",Sl="https://api.tavily.com/search",Tl="https://api.exa.ai/search",Pl="https://google.serper.dev/search",El=5,Rl=10,Oe=2e4,Cl=1e6,Ml=5e4,$l=2e5,rr=5;function ar(t=process.env){return t.BRAVE_API_KEY?.trim()||t.BRAVE_SEARCH_API_KEY?.trim()||void 0}function _l(t=process.env){let e=ar(t);if(!e)throw new Error("Brave Search requires BRAVE_API_KEY (or BRAVE_SEARCH_API_KEY). Get a key at https://brave.com/search/api/");return e}function cr(t=process.env){return t.TAVILY_API_KEY?.trim()||void 0}function Al(t=process.env){let e=cr(t);if(!e)throw new Error("Tavily search requires TAVILY_API_KEY. Get a key at https://tavily.com/");return e}function lr(t=process.env){return t.EXA_API_KEY?.trim()||void 0}function Ol(t=process.env){let e=lr(t);if(!e)throw new Error("Exa search requires EXA_API_KEY. Get a key at https://exa.ai/");return e}function ur(t=process.env){return t.SERPER_API_KEY?.trim()||void 0}function Il(t=process.env){let e=ur(t);if(!e)throw new Error("Serper search requires SERPER_API_KEY. Get a key at https://serper.dev/");return e}function dr(t=process.env){let e=t.SEARXNG_BASE_URL?.trim();return e?e.replace(/\/+$/,""):void 0}function Ge(t){return Math.min(Math.max(t??El,1),Rl)}function Rs(t){return t.replace(/&nbsp;/gi," ").replace(/&amp;/gi,"&").replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/&quot;/gi,'"').replace(/&#39;/gi,"'").replace(/&#x27;/gi,"'").replace(/&#(\d+);/g,(e,n)=>String.fromCharCode(Number(n)))}function Ts(t){return Rs(t.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim())}function Dl(t){try{let e=new URL(t,Es);if(e.hostname.endsWith("duckduckgo.com")&&e.pathname==="/l/"){let n=e.searchParams.get("uddg");if(n)return decodeURIComponent(n)}return e.href}catch{return t}}function jl(t,e){let n=[],r=new Set,o=/<a[^>]*class="[^"]*result__a[^"]*"[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>([\s\S]*?)(?=<a[^>]*class="[^"]*result__a|$)/gi,s;for(;(s=o.exec(t))!==null&&n.length<e;){let i=Dl(Rs(s[1]??"")).trim();if(!i||!/^https?:\/\//i.test(i)||r.has(i))continue;let a=Ts(s[2]??"")||i,l=(s[3]??"").match(/class="[^"]*result__snippet[^"]*"[^>]*>([\s\S]*?)<\/(?:a|td|div)/i),u=l?Ts(l[1]??""):"";r.add(i),n.push({title:a,url:i,description:u})}return n}function Ll(t){let e=t.trim().toLowerCase().replace(/\.$/,"");return!!(!e||e==="localhost"||e.endsWith(".localhost")||e.endsWith(".local")||e==="metadata.google.internal"||e==="metadata")}function ir(t){let e=sr(t);if(e===4){let n=t.split(".").map(Number);if(n.length!==4||n.some(s=>!Number.isInteger(s)||s<0||s>255))return!0;let[r,o]=n;return r===0||r===10||r===127||r===255||r===169&&o===254||r===172&&o>=16&&o<=31||r===192&&o===168||r===100&&o>=64&&o<=127}if(e===6){let n=t.toLowerCase();if(n==="::"||n==="::1"||n.startsWith("fc")||n.startsWith("fd")||n.startsWith("fe80"))return!0;if(n.startsWith("::ffff:")){let r=n.slice(7);if(sr(r)===4)return ir(r)}return!1}return!0}async function mr(t){let e;try{e=new URL(t)}catch{throw new Error(`Invalid URL: ${t}`)}if(e.protocol!=="http:"&&e.protocol!=="https:")throw new Error(`Only http(s) URLs are allowed; got ${e.protocol}`);if(e.username||e.password)throw new Error("URLs with embedded credentials are not allowed.");let n=e.hostname;if(Ll(n))throw new Error(`Blocked hostname: ${n}`);if(sr(n)){if(ir(n))throw new Error(`Blocked IP address: ${n}`);return e}let o;try{o=await kl(n,{all:!0,verbatim:!0})}catch(s){throw new Error(`DNS lookup failed for ${n}: ${s instanceof Error?s.message:String(s)}`)}if(o.length===0)throw new Error(`DNS lookup returned no addresses for ${n}`);for(let s of o)if(ir(s.address))throw new Error(`Hostname ${n} resolves to blocked address ${s.address}`);return e}function kt(t){return t.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi," ").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi," ").replace(/<noscript\b[^>]*>[\s\S]*?<\/noscript>/gi," ").replace(/<(?:br|\/p|\/div|\/h[1-6]|\/li|\/tr)\b[^>]*>/gi,`
164
+ ${n.trim()||"[none]"}`}};var xt=class{runtimes;owners=new Map;tools;constructor(e){this.runtimes=e.filter(n=>!!n),this.tools=[];for(let n of this.runtimes)for(let r of n.definitions()){let o=r.function.name;if(this.owners.has(o))throw new Error(`Duplicate tool definition: ${o}`);this.owners.set(o,n),this.tools.push(r)}}definitions(){return[...this.tools]}async execute(e,n,r){let o=this.owners.get(e);return o?await o.execute(e,n,r):{ok:!1,output:`Unknown tool: ${e}`}}};import{mkdir as Pr,open as gu,readFile as gn,readdir as hu,realpath as Sr,rm as wu,stat as De,writeFile as Er}from"node:fs/promises";import W from"node:path";import{spawn as ri}from"node:child_process";import{spawn as Ol}from"node:child_process";import{realpath as Ls}from"node:fs/promises";import mn from"node:path";var Il=new Set(["PATH","HOME","USER","LOGNAME","SHELL","LANG","LC_ALL","LC_CTYPE","TERM","COLORTERM","TMPDIR","TMP","TEMP","XDG_CACHE_HOME","XDG_CONFIG_HOME","XDG_DATA_HOME","CI"]);function Dl(t){return process.platform==="win32"?Promise.resolve(!1):new Promise(e=>{let n=Ol("/bin/sh",["-lc",`command -v "${t}" >/dev/null 2>&1`],{stdio:"ignore"});n.once("error",()=>e(!1)),n.once("close",r=>e(r===0))})}function jl(t){let e=new Set([...Il,...t]),n={};for(let[r,o]of Object.entries(process.env))(e.has(r)||r.startsWith("npm_")||r.startsWith("PNPM_"))&&(n[r]=o);return n.KPILOT_SANDBOX="1",n}var pn=class{rootDir;config;constructor(e,n={}){if(this.rootDir=mn.resolve(e),this.config={mode:n.mode??"portable",allowNetwork:n.allowNetwork??!1,passEnvironment:n.passEnvironment??[],...n.maxTimeoutMs===void 0?{}:{maxTimeoutMs:n.maxTimeoutMs}},this.config.maxTimeoutMs!==void 0&&(this.config.maxTimeoutMs<100||this.config.maxTimeoutMs>6e5))throw new Error("sandbox.maxTimeoutMs must be between 100 and 600000.")}async backend(){if(this.config.mode==="none")return"none";if(this.config.mode==="portable")return"portable";let e=process.platform==="linux"&&await Dl("bwrap");if(this.config.mode==="bwrap"&&!e)throw new Error("sandbox.mode is bwrap, but bubblewrap is unavailable.");return e?"bwrap":"portable"}async prepareShell(e,n,r){let o=mn.resolve(n),[s,i]=await Promise.all([Ls(this.rootDir).catch(()=>this.rootDir),Ls(o).catch(()=>o)]),a=mn.relative(s,i);if(a.startsWith("..")||mn.isAbsolute(a))throw new Error("Sandbox cwd escapes the repository root.");let c=this.config.maxTimeoutMs===void 0?r:Math.min(r,this.config.maxTimeoutMs),l=await this.backend(),u=l==="none"?process.env:jl(this.config.passEnvironment);if(process.platform==="win32")return{command:"cmd.exe",args:["/d","/s","/c",e],cwd:o,env:u,timeoutMs:c,backend:l};if(l!=="bwrap")return{command:"/bin/sh",args:["-lc",e],cwd:o,env:u,timeoutMs:c,backend:l};let m=["--die-with-parent","--new-session","--unshare-pid","--ro-bind","/","/","--bind",this.rootDir,this.rootDir,"--tmpfs","/tmp","--proc","/proc","--dev","/dev","--chdir",o];return this.config.allowNetwork||m.push("--unshare-net"),m.push("/bin/sh","-lc",e),{command:"bwrap",args:m,cwd:o,env:u,timeoutMs:c,backend:l}}async describe(){let e=await this.backend(),n=e==="bwrap"?this.config.allowNetwork?"allowed":"isolated":e==="none"?"unrestricted":"not OS-isolated",r=this.config.maxTimeoutMs===void 0?"unlimited":`${this.config.maxTimeoutMs}ms`;return`${e} (network ${n}, timeout cap ${r})`}};import{lookup as Ll}from"node:dns/promises";import{isIP as dr}from"node:net";var Ul="https://api.search.brave.com/res/v1/web/search",Fs="https://html.duckduckgo.com/html/",Nl="https://api.tavily.com/search",Fl="https://api.exa.ai/search",ql="https://google.serper.dev/search",Bl=5,Jl=10,Oe=2e4,Kl=1e6,Wl=5e4,Gl=2e5,lr=5;function pr(t=process.env){return t.BRAVE_API_KEY?.trim()||t.BRAVE_SEARCH_API_KEY?.trim()||void 0}function Hl(t=process.env){let e=pr(t);if(!e)throw new Error("Brave Search requires BRAVE_API_KEY (or BRAVE_SEARCH_API_KEY). Get a key at https://brave.com/search/api/");return e}function fr(t=process.env){return t.TAVILY_API_KEY?.trim()||void 0}function zl(t=process.env){let e=fr(t);if(!e)throw new Error("Tavily search requires TAVILY_API_KEY. Get a key at https://tavily.com/");return e}function gr(t=process.env){return t.EXA_API_KEY?.trim()||void 0}function Vl(t=process.env){let e=gr(t);if(!e)throw new Error("Exa search requires EXA_API_KEY. Get a key at https://exa.ai/");return e}function hr(t=process.env){return t.SERPER_API_KEY?.trim()||void 0}function Yl(t=process.env){let e=hr(t);if(!e)throw new Error("Serper search requires SERPER_API_KEY. Get a key at https://serper.dev/");return e}function wr(t=process.env){let e=t.SEARXNG_BASE_URL?.trim();return e?e.replace(/\/+$/,""):void 0}function Ge(t){return Math.min(Math.max(t??Bl,1),Jl)}function qs(t){return t.replace(/&nbsp;/gi," ").replace(/&amp;/gi,"&").replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/&quot;/gi,'"').replace(/&#39;/gi,"'").replace(/&#x27;/gi,"'").replace(/&#(\d+);/g,(e,n)=>String.fromCharCode(Number(n)))}function Us(t){return qs(t.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim())}function Ql(t){try{let e=new URL(t,Fs);if(e.hostname.endsWith("duckduckgo.com")&&e.pathname==="/l/"){let n=e.searchParams.get("uddg");if(n)return decodeURIComponent(n)}return e.href}catch{return t}}function Xl(t,e){let n=[],r=new Set,o=/<a[^>]*class="[^"]*result__a[^"]*"[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>([\s\S]*?)(?=<a[^>]*class="[^"]*result__a|$)/gi,s;for(;(s=o.exec(t))!==null&&n.length<e;){let i=Ql(qs(s[1]??"")).trim();if(!i||!/^https?:\/\//i.test(i)||r.has(i))continue;let a=Us(s[2]??"")||i,l=(s[3]??"").match(/class="[^"]*result__snippet[^"]*"[^>]*>([\s\S]*?)<\/(?:a|td|div)/i),u=l?Us(l[1]??""):"";r.add(i),n.push({title:a,url:i,description:u})}return n}function Zl(t){let e=t.trim().toLowerCase().replace(/\.$/,"");return!!(!e||e==="localhost"||e.endsWith(".localhost")||e.endsWith(".local")||e==="metadata.google.internal"||e==="metadata")}function mr(t){let e=dr(t);if(e===4){let n=t.split(".").map(Number);if(n.length!==4||n.some(s=>!Number.isInteger(s)||s<0||s>255))return!0;let[r,o]=n;return r===0||r===10||r===127||r===255||r===169&&o===254||r===172&&o>=16&&o<=31||r===192&&o===168||r===100&&o>=64&&o<=127}if(e===6){let n=t.toLowerCase();if(n==="::"||n==="::1"||n.startsWith("fc")||n.startsWith("fd")||n.startsWith("fe80"))return!0;if(n.startsWith("::ffff:")){let r=n.slice(7);if(dr(r)===4)return mr(r)}return!1}return!0}async function yr(t){let e;try{e=new URL(t)}catch{throw new Error(`Invalid URL: ${t}`)}if(e.protocol!=="http:"&&e.protocol!=="https:")throw new Error(`Only http(s) URLs are allowed; got ${e.protocol}`);if(e.username||e.password)throw new Error("URLs with embedded credentials are not allowed.");let n=e.hostname;if(Zl(n))throw new Error(`Blocked hostname: ${n}`);if(dr(n)){if(mr(n))throw new Error(`Blocked IP address: ${n}`);return e}let o;try{o=await Ll(n,{all:!0,verbatim:!0})}catch(s){throw new Error(`DNS lookup failed for ${n}: ${s instanceof Error?s.message:String(s)}`)}if(o.length===0)throw new Error(`DNS lookup returned no addresses for ${n}`);for(let s of o)if(mr(s.address))throw new Error(`Hostname ${n} resolves to blocked address ${s.address}`);return e}function St(t){return t.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi," ").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi," ").replace(/<noscript\b[^>]*>[\s\S]*?<\/noscript>/gi," ").replace(/<(?:br|\/p|\/div|\/h[1-6]|\/li|\/tr)\b[^>]*>/gi,`
153
165
  `).replace(/<[^>]+>/g," ").replace(/&nbsp;/gi," ").replace(/&amp;/gi,"&").replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/&quot;/gi,'"').replace(/&#39;/gi,"'").replace(/\r/g,"").replace(/[ \t]+\n/g,`
154
166
  `).replace(/\n{3,}/g,`
155
167
 
156
- `).replace(/[ \t]{2,}/g," ").trim()}async function Ul(t,e){if(!t.body){let s=await t.arrayBuffer(),i=Buffer.from(s);if(i.byteLength>e)throw new Error(`Response body exceeds ${e} byte limit.`);return i}let n=t.body.getReader(),r=[],o=0;for(;;){let{done:s,value:i}=await n.read();if(s)break;let a=Buffer.from(i??new Uint8Array);if(o+=a.byteLength,o>e)throw await n.cancel().catch(()=>{}),new Error(`Response body exceeds ${e} byte limit.`);r.push(a)}return Buffer.concat(r,o)}async function Nl(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.fetchImpl??fetch,o=new URLSearchParams({q:e}),s=await r(Es,{method:"POST",headers:{Accept:"text/html","Content-Type":"application/x-www-form-urlencoded","User-Agent":"kpilot/web_search"},body:o.toString(),signal:t.signal??AbortSignal.timeout(Oe)});if(!s.ok){let c=(await s.text().catch(()=>"")).slice(0,300);throw new Error(`DuckDuckGo search returned HTTP ${s.status}${c?`: ${c}`:""}`)}let i=await s.text(),a=jl(i,n);return{query:e,count:a.length,results:a,provider:"duckduckgo"}}async function Fl(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.apiKey??_l(),o=new URL(xl);o.searchParams.set("q",e),o.searchParams.set("count",String(n));let i=await(t.fetchImpl??fetch)(o,{method:"GET",headers:{Accept:"application/json","Accept-Encoding":"gzip","X-Subscription-Token":r},signal:t.signal??AbortSignal.timeout(Oe)});if(!i.ok){let l=(await i.text().catch(()=>"")).slice(0,300);throw new Error(`Brave Search API returned HTTP ${i.status}${l?`: ${l}`:""}`)}let c=((await i.json()).web?.results??[]).filter(l=>typeof l?.url=="string"&&l.url.trim()).slice(0,n).map(l=>({title:String(l.title??"").trim()||l.url.trim(),url:l.url.trim(),description:String(l.description??"").trim()}));return{query:e,count:c.length,results:c,provider:"brave"}}async function Bl(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.apiKey??Al(),s=await(t.fetchImpl??fetch)(Sl,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":"kpilot/web_search"},body:JSON.stringify({api_key:r,query:e,max_results:n,include_answer:!1,include_raw_content:!1}),signal:t.signal??AbortSignal.timeout(Oe)});if(!s.ok){let c=(await s.text().catch(()=>"")).slice(0,300);throw new Error(`Tavily search returned HTTP ${s.status}${c?`: ${c}`:""}`)}let a=((await s.json()).results??[]).filter(c=>typeof c?.url=="string"&&/^https?:\/\//i.test(c.url)).slice(0,n).map(c=>({title:String(c.title??"").trim()||c.url.trim(),url:c.url.trim(),description:String(c.content??"").trim()}));return{query:e,count:a.length,results:a,provider:"tavily"}}async function ql(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.apiKey??Ol(),s=await(t.fetchImpl??fetch)(Tl,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":r,"User-Agent":"kpilot/web_search"},body:JSON.stringify({query:e,numResults:n,contents:{text:!1}}),signal:t.signal??AbortSignal.timeout(Oe)});if(!s.ok){let c=(await s.text().catch(()=>"")).slice(0,300);throw new Error(`Exa search returned HTTP ${s.status}${c?`: ${c}`:""}`)}let a=((await s.json()).results??[]).filter(c=>typeof c?.url=="string"&&/^https?:\/\//i.test(c.url)).slice(0,n).map(c=>({title:String(c.title??"").trim()||c.url.trim(),url:c.url.trim(),description:String(c.text??"").trim().slice(0,300)}));return{query:e,count:a.length,results:a,provider:"exa"}}async function Jl(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.apiKey??Il(),s=await(t.fetchImpl??fetch)(Pl,{method:"POST",headers:{"Content-Type":"application/json","X-API-KEY":r,"User-Agent":"kpilot/web_search"},body:JSON.stringify({q:e,num:n}),signal:t.signal??AbortSignal.timeout(Oe)});if(!s.ok){let c=(await s.text().catch(()=>"")).slice(0,300);throw new Error(`Serper search returned HTTP ${s.status}${c?`: ${c}`:""}`)}let a=((await s.json()).organic??[]).filter(c=>typeof c?.link=="string"&&/^https?:\/\//i.test(c.link)).slice(0,n).map(c=>({title:String(c.title??"").trim()||c.link.trim(),url:c.link.trim(),description:String(c.snippet??"").trim()}));return{query:e,count:a.length,results:a,provider:"serper"}}async function Kl(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.baseUrl??dr();if(!r)throw new Error("SearXNG search requires SEARXNG_BASE_URL.");let o=new URL(`${r}/search`);o.searchParams.set("q",e),o.searchParams.set("format","json"),o.searchParams.set("safesearch","0");let i=await(t.fetchImpl??fetch)(o,{method:"GET",headers:{Accept:"application/json","User-Agent":"kpilot/web_search"},signal:t.signal??AbortSignal.timeout(Oe)});if(!i.ok){let l=(await i.text().catch(()=>"")).slice(0,300);throw new Error(`SearXNG search returned HTTP ${i.status}${l?`: ${l}`:""}`)}let c=((await i.json()).results??[]).filter(l=>typeof l?.url=="string"&&/^https?:\/\//i.test(l.url)).slice(0,n).map(l=>({title:String(l.title??"").trim()||l.url.trim(),url:l.url.trim(),description:String(l.content??"").trim()}));return{query:e,count:c.length,results:c,provider:"searxng"}}function or(t,e){let{query:n,count:r,signal:o,fetchImpl:s,env:i}=e;switch(t){case"duckduckgo":return Nl({query:n,count:r,signal:o,fetchImpl:s});case"tavily":return Bl({query:n,count:r,signal:o,fetchImpl:s,apiKey:cr(i)});case"exa":return ql({query:n,count:r,signal:o,fetchImpl:s,apiKey:lr(i)});case"serper":return Jl({query:n,count:r,signal:o,fetchImpl:s,apiKey:ur(i)});case"searxng":return Kl({query:n,count:r,signal:o,fetchImpl:s,baseUrl:dr(i)});case"brave":return Fl({query:n,count:r,signal:o,fetchImpl:e.braveFetchImpl??s,apiKey:ar(i)})}}function Ps(t,e){switch(t){case"duckduckgo":return!0;case"tavily":return!!cr(e);case"exa":return!!lr(e);case"serper":return!!ur(e);case"searxng":return!!dr(e);case"brave":return!!ar(e)}}var Wl=["tavily","exa","serper","searxng","brave"];async function Cs(t){let e=t.env??process.env,n=t.fetchImpl??fetch,r={query:t.query,count:t.count,signal:t.signal,fetchImpl:n,env:e,braveFetchImpl:t.braveFetchImpl};if(t.provider){if(!Ps(t.provider,e))throw new Error(`Web search provider "${t.provider}" is not configured. Set the required key or enabling variable.`);return await or(t.provider,r)}let o;try{let s=await or("duckduckgo",r);if(s.results.length>0)return s;o=new Error("DuckDuckGo search returned no results.")}catch(s){o=s instanceof Error?s:new Error(String(s))}for(let s of Wl)if(Ps(s,e))try{let i=await or(s,r);if(i.results.length>0)return{...i,fallbackReason:o?.message};o=new Error(`${s} search returned no results.`)}catch(i){o=i instanceof Error?i:new Error(String(i))}throw o??new Error("Web search failed.")}async function Ms(t){let e=Math.min(Math.max(t.maxChars??Ml,1),$l),n=t.fetchImpl??fetch,r=t.assertPublicUrlFn??mr,o=await r(t.url),s,i=0;for(;i<=rr;){if(s=await n(o,{method:"GET",redirect:"manual",headers:{Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,text/plain;q=0.8,*/*;q=0.5","User-Agent":"kpilot/web_fetch"},signal:t.signal??AbortSignal.timeout(Oe)}),s.status>=300&&s.status<400){let d=s.headers.get("location");if(!d)throw new Error(`Redirect without Location header from ${o.href}`);o=await r(new URL(d,o).href),i+=1;continue}break}if(!s)throw new Error("Failed to fetch URL.");if(i>rr)throw new Error(`Too many redirects (max ${rr}).`);if(!s.ok)throw new Error(`HTTP ${s.status} fetching ${o.href}`);let a=s.headers.get("content-type")??void 0,c=await Ul(s,Cl),l=new TextDecoder().decode(c),u=a&&/html|xml|sgml/i.test(a)||/html/i.test(l.slice(0,512))?kt(l):l.trim(),m=u.length>e;return{url:t.url,finalUrl:o.href,status:s.status,contentType:a,text:m?u.slice(0,e):u,truncated:m}}import{spawn as gr,spawnSync as Gl}from"node:child_process";import{mkdir as _s,writeFile as Hl}from"node:fs/promises";import{tmpdir as zl}from"node:os";import Ie from"node:path";var xt="Chromium is not installed. Install it (e.g. `brew install --cask chromium` on macOS, `sudo apt install chromium-browser` on Debian/Ubuntu, or point KPILOT_CHROME_PATH at a browser binary), or use web_fetch for static pages.",Vl=["google-chrome-stable","google-chrome","chromium-browser","chromium","microsoft-edge","microsoft-edge-stable"],Yl=["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Chromium.app/Contents/MacOS/Chromium","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"],He;function pr(t){try{let e=Gl(t,["--version"],{timeout:3e3,stdio:"ignore"});return e.error===void 0&&e.status===0}catch{return!1}}function St(t=process.env){if(He!==void 0)return He||void 0;let e=t.KPILOT_CHROME_PATH?.trim();if(e&&pr(e))return He=e,e;for(let n of Vl)if(pr(n))return He=n,n;for(let n of Yl)if(pr(n))return He=n,n;He=null}function $s(t){return new Promise(e=>{setTimeout(()=>e(),t)})}var As=1280,Os=1200,fr=class t{child;ws;sessionId="";nextId=1;pending=new Map;closed=!1;constructor(e,n){this.child=e,this.ws=n,this.ws.addEventListener("message",r=>this.handleMessage(String(r?.data??""))),this.ws.addEventListener("close",()=>this.failAll(new Error("Browser connection closed.")))}static async launch(e){let n=Ie.join(zl(),`kpilot-browser-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,7)}`),r=gr(e,["--headless=new","--no-sandbox","--disable-gpu","--disable-dev-shm-usage","--disable-extensions",`--user-data-dir=${n}`,"--remote-debugging-port=0"],{stdio:["ignore","ignore","pipe"]}),o=await new Promise((a,c)=>{let l="",u=setTimeout(()=>{r.kill("SIGKILL"),c(new Error("Timed out waiting for the browser to expose a DevTools endpoint."))},15e3);r.stderr.setEncoding("utf8"),r.stderr.on("data",m=>{l+=m;let d=l.match(/DevTools listening on (ws:\/\/\S+)/i);d?.[1]&&(clearTimeout(u),a(d[1]))}),r.once("error",m=>{clearTimeout(u),c(m)}),r.once("exit",m=>{clearTimeout(u),c(new Error(`Browser exited before starting (code ${m??1}).`))})}),s=new WebSocket(o);await new Promise((a,c)=>{s.addEventListener("open",()=>a()),s.addEventListener("error",()=>c(new Error("Failed to open the DevTools WebSocket.")))});let i=new t(r,s);return await i.attachPageTarget(),i}async attachPageTarget(){let e=await this.send("Target.createTarget",{url:"about:blank"}),n=String(e.targetId??"");if(!n)throw new Error("Browser did not create a page target.");let r=await this.send("Target.attachToTarget",{targetId:n,flatten:!0});if(this.sessionId=String(r.sessionId??""),!this.sessionId)throw new Error("Browser did not attach a page session.")}send(e,n={},r=15e3){let o=this.nextId++,s={id:o,method:e,params:n};return this.sessionId&&(s.sessionId=this.sessionId),this.ws.send(JSON.stringify(s)),new Promise((i,a)=>{let c=setTimeout(()=>{this.pending.delete(o),a(new Error(`CDP ${e} timed out.`))},r);this.pending.set(o,{resolve:i,reject:a,timer:c})})}handleMessage(e){let n;try{n=JSON.parse(e)}catch{return}let r=n.id;if(r===void 0)return;let o=this.pending.get(r);if(o)if(clearTimeout(o.timer),this.pending.delete(r),n.error&&typeof n.error=="object"){let s=n.error;o.reject(new Error(String(s.message??"CDP error")))}else o.resolve(n.result??{})}async evaluate(e){return await this.send("Runtime.evaluate",{expression:e,returnByValue:!0,awaitPromise:!0})}failAll(e){for(let n of this.pending.values())clearTimeout(n.timer),n.reject(e);this.pending.clear()}async navigate(e,n,r){await this.send("Page.navigate",{url:e});let o=r==="domcontentloaded"?["interactive","complete"]:["complete"],s=Date.now()+Math.min(n,3e4);for(;Date.now()<s;){let i=await this.evaluate("document.readyState"),a=String(i.result?.value??"");if(o.includes(a))break;await $s(120)}r==="networkidle2"&&await $s(700)}async readPage(e){let n=await this.evaluate("JSON.stringify({title:document.title,url:location.href,text:(()=>{const c=document.body?document.body.cloneNode(true):null;if(!c)return '';c.querySelectorAll('script,style,noscript,svg,canvas,iframe,template').forEach(function(n){n.remove()});return (c.innerText||c.textContent||'').replace(/\\s+/g,' ').trim();})()})"),r={};try{r=JSON.parse(String(n.result?.value??"{}"))}catch{r={}}let o=String(r.text??""),s=o.length>e;return{url:String(r.url??""),title:String(r.title??""),text:s?o.slice(0,e):o,truncated:s}}async screenshot(e,n){let r=As,o=Os;if(e){let u=(await this.send("Page.getLayoutMetrics")).cssContentSize?.height;o=Math.max(o,Math.ceil(Number(u)||o)),await this.send("Emulation.setDeviceMetricsOverride",{width:r,height:o,deviceScaleFactor:1,mobile:!1})}let s=await this.send("Page.captureScreenshot",{format:"png"}),i=String(s.data??"");if(!i)throw new Error("Browser returned an empty screenshot.");let a=Ie.join(n,".kpilot","run");await _s(a,{recursive:!0});let c=Ie.join(".kpilot","run",`browser-${Date.now().toString(36)}.png`);return await Hl(Ie.join(n,c),Buffer.from(i,"base64")),c}async click(e){let r=(await this.evaluate(`(()=>{const el=document.querySelector(${JSON.stringify(e)});if(!el)return {ok:false,why:'no matching element'};const r=el.getBoundingClientRect();try{el.click();}catch(e){}return {ok:true,tag:(el.tagName||'').toLowerCase(),x:Math.round(r.left+r.width/2),y:Math.round(r.top+r.height/2)};})()`)).result?.value??{};if(!r.ok)return`Click failed: ${String(r.why??"unknown")}`;let o=Number(r.x??0),s=Number(r.y??0);return await this.send("Input.dispatchMouseEvent",{type:"mousePressed",x:o,y:s,button:"left",clickCount:1}),await this.send("Input.dispatchMouseEvent",{type:"mouseReleased",x:o,y:s,button:"left",clickCount:1}),`Clicked <${String(r.tag)}>@${e} at (${o}, ${s}).`}async typeText(e,n){let o=(await this.evaluate(`(()=>{const el=document.querySelector(${JSON.stringify(e)});if(!el)return {ok:false,why:'no matching element'};el.focus();return {ok:true,tag:(el.tagName||'').toLowerCase()};})()`)).result?.value??{};return o.ok?(await this.send("Input.insertText",{text:n}),`Typed ${n.length} characters into <${String(o.tag)}>@${e}.`):`Type failed: ${String(o.why??"unknown")}`}async evaluateExpression(e){let n=await this.evaluate(e);if(n.exceptionDetails){let o=n.exceptionDetails,s=o?.exception?.description??o?.text??"evaluation error";return`Evaluation error: ${String(s)}`}let r=n.result?.value;if(r===void 0)return"undefined";if(typeof r=="string")return r;try{return JSON.stringify(r)}catch{return String(r)}}async close(){if(!this.closed){this.closed=!0;try{this.ws.close()}catch{}if(this.failAll(new Error("Browser closed.")),this.child)try{this.child.kill("SIGTERM")}catch{}}}},ze;async function Tt(){if(ze)return ze;let t=St();if(!t)throw new Error(xt);return ze=await fr.launch(t),ze}async function Is(){await ze?.close(),ze=void 0}async function hr(t){let n=(await mr(t.url)).href,r=Math.min(Math.max(t.maxChars??5e4,1),2e5),o=t.waitUntil??"load",s=t.waitMs??15e3;try{let i=await Tt();await i.navigate(n,s,o);let a=await i.readPage(r);return{mode:"cdp",...a,title:a.title||n}}catch{let a=await Ql(n);return{mode:"static",url:n,title:String(a.title??""),text:a.text.slice(0,r),truncated:a.text.length>r}}}async function Ds(t){let e=t.fullPage===!0;t.url&&await hr({url:t.url,waitUntil:"load",waitMs:15e3,maxChars:4e3});try{return{path:await(await Tt()).screenshot(e,t.rootDir),mode:"cdp"}}catch{if(t.url){let n=await Xl(t.url,e,t.rootDir);if(n)return{path:n,mode:"static"}}throw new Error("Unable to capture a screenshot without a browser. "+xt)}}async function js(t){return await(await Tt()).click(t)}async function Ls(t,e){return await(await Tt()).typeText(t,e)}async function Us(t){return await(await Tt()).evaluateExpression(t)}async function Ql(t){let e=St();if(!e)throw new Error(xt);let n=await new Promise((o,s)=>{let i=gr(e,["--headless=new","--no-sandbox","--disable-gpu","--dump-dom",t],{stdio:["ignore","pipe","pipe"]}),a="",c="",l=setTimeout(()=>i.kill("SIGKILL"),2e4);i.stdout.setEncoding("utf8"),i.stdout.on("data",u=>{a.length<1e6&&(a+=u)}),i.stderr.setEncoding("utf8"),i.stderr.on("data",u=>{c+=u}),i.once("error",u=>{clearTimeout(l),s(u)}),i.once("exit",u=>{clearTimeout(l),u!==0&&!a?s(new Error(c.trim()||`Browser exited with code ${u??1}.`)):o(a)})}),r=n.match(/<title[^>]*>([\s\S]*?)<\/title>/i);return{title:kt(r?.[1]??""),text:kt(n)}}async function Xl(t,e,n){let r=St();if(!r)return null;let o=Ie.join(n,".kpilot","run");await _s(o,{recursive:!0});let s=Ie.join(".kpilot","run",`browser-${Date.now().toString(36)}.png`),i=Ie.join(n,s),a=["--headless=new","--no-sandbox","--disable-gpu"];return e&&a.push(`--window-size=${As},${Os*3}`),a.push(`--screenshot=${i}`,t),await new Promise(l=>{let u=gr(r,a,{stdio:["ignore","ignore","ignore"]}),m=setTimeout(()=>u.kill("SIGKILL"),2e4);u.once("error",()=>{clearTimeout(m),l(!1)}),u.once("exit",d=>{clearTimeout(m),l(d===0)})})?s:null}var nu=new Set([".git","node_modules","dist","build",".next",".turbo","coverage",".cache",".idea"]),kr=1e6,xr=2e5,ru=/(?:✓\s*)?Ready in\b|Local:\s+https?:\/\/|Network:\s+https?:\/\/|listening on (?:port\s+)?\d+\b|started server on\b|VITE .+ ready in\b/i,Ns=/ERR_PNPM_|ELIFECYCLE|EADDRINUSE|ECONNREFUSED|Error:\s|Command failed|exit code [1-9]\d*|Failed to compile|Module not found|Cannot find module|ENOENT|pnpm approve-builds|IGNORED_BUILDS/i,ou=/\b(?:pnpm|npm|yarn|bun)(?:\s+run)?\s+dev\b|\bnext\s+dev\b|\bvite(?:\s|$)|(?:^|[;&|]\s*)(?:nodemon|tsx\s+watch|node\s+--watch)\b|\bdocker\s+compose\s+up\b(?![^\n]*\s-d\b)/i;function Pt(t,e=xr){if(t.length<=e)return t;let n=t.length-e;return`${t.slice(0,e)}
168
+ `).replace(/[ \t]{2,}/g," ").trim()}async function eu(t,e){if(!t.body){let s=await t.arrayBuffer(),i=Buffer.from(s);if(i.byteLength>e)throw new Error(`Response body exceeds ${e} byte limit.`);return i}let n=t.body.getReader(),r=[],o=0;for(;;){let{done:s,value:i}=await n.read();if(s)break;let a=Buffer.from(i??new Uint8Array);if(o+=a.byteLength,o>e)throw await n.cancel().catch(()=>{}),new Error(`Response body exceeds ${e} byte limit.`);r.push(a)}return Buffer.concat(r,o)}async function tu(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.fetchImpl??fetch,o=new URLSearchParams({q:e}),s=await r(Fs,{method:"POST",headers:{Accept:"text/html","Content-Type":"application/x-www-form-urlencoded","User-Agent":"kpilot/web_search"},body:o.toString(),signal:t.signal??AbortSignal.timeout(Oe)});if(!s.ok){let c=(await s.text().catch(()=>"")).slice(0,300);throw new Error(`DuckDuckGo search returned HTTP ${s.status}${c?`: ${c}`:""}`)}let i=await s.text(),a=Xl(i,n);return{query:e,count:a.length,results:a,provider:"duckduckgo"}}async function nu(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.apiKey??Hl(),o=new URL(Ul);o.searchParams.set("q",e),o.searchParams.set("count",String(n));let i=await(t.fetchImpl??fetch)(o,{method:"GET",headers:{Accept:"application/json","Accept-Encoding":"gzip","X-Subscription-Token":r},signal:t.signal??AbortSignal.timeout(Oe)});if(!i.ok){let l=(await i.text().catch(()=>"")).slice(0,300);throw new Error(`Brave Search API returned HTTP ${i.status}${l?`: ${l}`:""}`)}let c=((await i.json()).web?.results??[]).filter(l=>typeof l?.url=="string"&&l.url.trim()).slice(0,n).map(l=>({title:String(l.title??"").trim()||l.url.trim(),url:l.url.trim(),description:String(l.description??"").trim()}));return{query:e,count:c.length,results:c,provider:"brave"}}async function ru(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.apiKey??zl(),s=await(t.fetchImpl??fetch)(Nl,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":"kpilot/web_search"},body:JSON.stringify({api_key:r,query:e,max_results:n,include_answer:!1,include_raw_content:!1}),signal:t.signal??AbortSignal.timeout(Oe)});if(!s.ok){let c=(await s.text().catch(()=>"")).slice(0,300);throw new Error(`Tavily search returned HTTP ${s.status}${c?`: ${c}`:""}`)}let a=((await s.json()).results??[]).filter(c=>typeof c?.url=="string"&&/^https?:\/\//i.test(c.url)).slice(0,n).map(c=>({title:String(c.title??"").trim()||c.url.trim(),url:c.url.trim(),description:String(c.content??"").trim()}));return{query:e,count:a.length,results:a,provider:"tavily"}}async function ou(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.apiKey??Vl(),s=await(t.fetchImpl??fetch)(Fl,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":r,"User-Agent":"kpilot/web_search"},body:JSON.stringify({query:e,numResults:n,contents:{text:!1}}),signal:t.signal??AbortSignal.timeout(Oe)});if(!s.ok){let c=(await s.text().catch(()=>"")).slice(0,300);throw new Error(`Exa search returned HTTP ${s.status}${c?`: ${c}`:""}`)}let a=((await s.json()).results??[]).filter(c=>typeof c?.url=="string"&&/^https?:\/\//i.test(c.url)).slice(0,n).map(c=>({title:String(c.title??"").trim()||c.url.trim(),url:c.url.trim(),description:String(c.text??"").trim().slice(0,300)}));return{query:e,count:a.length,results:a,provider:"exa"}}async function su(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.apiKey??Yl(),s=await(t.fetchImpl??fetch)(ql,{method:"POST",headers:{"Content-Type":"application/json","X-API-KEY":r,"User-Agent":"kpilot/web_search"},body:JSON.stringify({q:e,num:n}),signal:t.signal??AbortSignal.timeout(Oe)});if(!s.ok){let c=(await s.text().catch(()=>"")).slice(0,300);throw new Error(`Serper search returned HTTP ${s.status}${c?`: ${c}`:""}`)}let a=((await s.json()).organic??[]).filter(c=>typeof c?.link=="string"&&/^https?:\/\//i.test(c.link)).slice(0,n).map(c=>({title:String(c.title??"").trim()||c.link.trim(),url:c.link.trim(),description:String(c.snippet??"").trim()}));return{query:e,count:a.length,results:a,provider:"serper"}}async function iu(t){let e=t.query.trim();if(!e)throw new Error("query is required.");let n=Ge(t.count),r=t.baseUrl??wr();if(!r)throw new Error("SearXNG search requires SEARXNG_BASE_URL.");let o=new URL(`${r}/search`);o.searchParams.set("q",e),o.searchParams.set("format","json"),o.searchParams.set("safesearch","0");let i=await(t.fetchImpl??fetch)(o,{method:"GET",headers:{Accept:"application/json","User-Agent":"kpilot/web_search"},signal:t.signal??AbortSignal.timeout(Oe)});if(!i.ok){let l=(await i.text().catch(()=>"")).slice(0,300);throw new Error(`SearXNG search returned HTTP ${i.status}${l?`: ${l}`:""}`)}let c=((await i.json()).results??[]).filter(l=>typeof l?.url=="string"&&/^https?:\/\//i.test(l.url)).slice(0,n).map(l=>({title:String(l.title??"").trim()||l.url.trim(),url:l.url.trim(),description:String(l.content??"").trim()}));return{query:e,count:c.length,results:c,provider:"searxng"}}function ur(t,e){let{query:n,count:r,signal:o,fetchImpl:s,env:i}=e;switch(t){case"duckduckgo":return tu({query:n,count:r,signal:o,fetchImpl:s});case"tavily":return ru({query:n,count:r,signal:o,fetchImpl:s,apiKey:fr(i)});case"exa":return ou({query:n,count:r,signal:o,fetchImpl:s,apiKey:gr(i)});case"serper":return su({query:n,count:r,signal:o,fetchImpl:s,apiKey:hr(i)});case"searxng":return iu({query:n,count:r,signal:o,fetchImpl:s,baseUrl:wr(i)});case"brave":return nu({query:n,count:r,signal:o,fetchImpl:e.braveFetchImpl??s,apiKey:pr(i)})}}function Ns(t,e){switch(t){case"duckduckgo":return!0;case"tavily":return!!fr(e);case"exa":return!!gr(e);case"serper":return!!hr(e);case"searxng":return!!wr(e);case"brave":return!!pr(e)}}var au=["tavily","exa","serper","searxng","brave"];async function Bs(t){let e=t.env??process.env,n=t.fetchImpl??fetch,r={query:t.query,count:t.count,signal:t.signal,fetchImpl:n,env:e,braveFetchImpl:t.braveFetchImpl};if(t.provider){if(!Ns(t.provider,e))throw new Error(`Web search provider "${t.provider}" is not configured. Set the required key or enabling variable.`);return await ur(t.provider,r)}let o;try{let s=await ur("duckduckgo",r);if(s.results.length>0)return s;o=new Error("DuckDuckGo search returned no results.")}catch(s){o=s instanceof Error?s:new Error(String(s))}for(let s of au)if(Ns(s,e))try{let i=await ur(s,r);if(i.results.length>0)return{...i,fallbackReason:o?.message};o=new Error(`${s} search returned no results.`)}catch(i){o=i instanceof Error?i:new Error(String(i))}throw o??new Error("Web search failed.")}async function Js(t){let e=Math.min(Math.max(t.maxChars??Wl,1),Gl),n=t.fetchImpl??fetch,r=t.assertPublicUrlFn??yr,o=await r(t.url),s,i=0;for(;i<=lr;){if(s=await n(o,{method:"GET",redirect:"manual",headers:{Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,text/plain;q=0.8,*/*;q=0.5","User-Agent":"kpilot/web_fetch"},signal:t.signal??AbortSignal.timeout(Oe)}),s.status>=300&&s.status<400){let d=s.headers.get("location");if(!d)throw new Error(`Redirect without Location header from ${o.href}`);o=await r(new URL(d,o).href),i+=1;continue}break}if(!s)throw new Error("Failed to fetch URL.");if(i>lr)throw new Error(`Too many redirects (max ${lr}).`);if(!s.ok)throw new Error(`HTTP ${s.status} fetching ${o.href}`);let a=s.headers.get("content-type")??void 0,c=await eu(s,Kl),l=new TextDecoder().decode(c),u=a&&/html|xml|sgml/i.test(a)||/html/i.test(l.slice(0,512))?St(l):l.trim(),m=u.length>e;return{url:t.url,finalUrl:o.href,status:s.status,contentType:a,text:m?u.slice(0,e):u,truncated:m}}import{spawn as kr,spawnSync as cu}from"node:child_process";import{mkdir as Ws,writeFile as lu}from"node:fs/promises";import{tmpdir as uu}from"node:os";import Ie from"node:path";var Tt="Chromium is not installed. Install it (e.g. `brew install --cask chromium` on macOS, `sudo apt install chromium-browser` on Debian/Ubuntu, or point KPILOT_CHROME_PATH at a browser binary), or use web_fetch for static pages.",du=["google-chrome-stable","google-chrome","chromium-browser","chromium","microsoft-edge","microsoft-edge-stable"],mu=["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Chromium.app/Contents/MacOS/Chromium","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"],He;function br(t){try{let e=cu(t,["--version"],{timeout:3e3,stdio:"ignore"});return e.error===void 0&&e.status===0}catch{return!1}}function Pt(t=process.env){if(He!==void 0)return He||void 0;let e=t.KPILOT_CHROME_PATH?.trim();if(e&&br(e))return He=e,e;for(let n of du)if(br(n))return He=n,n;for(let n of mu)if(br(n))return He=n,n;He=null}function Ks(t){return new Promise(e=>{setTimeout(()=>e(),t)})}var Gs=1280,Hs=1200,vr=class t{child;ws;sessionId="";nextId=1;pending=new Map;closed=!1;constructor(e,n){this.child=e,this.ws=n,this.ws.addEventListener("message",r=>this.handleMessage(String(r?.data??""))),this.ws.addEventListener("close",()=>this.failAll(new Error("Browser connection closed.")))}static async launch(e){let n=Ie.join(uu(),`kpilot-browser-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,7)}`),r=kr(e,["--headless=new","--no-sandbox","--disable-gpu","--disable-dev-shm-usage","--disable-extensions",`--user-data-dir=${n}`,"--remote-debugging-port=0"],{stdio:["ignore","ignore","pipe"]}),o=await new Promise((a,c)=>{let l="",u=setTimeout(()=>{r.kill("SIGKILL"),c(new Error("Timed out waiting for the browser to expose a DevTools endpoint."))},15e3);r.stderr.setEncoding("utf8"),r.stderr.on("data",m=>{l+=m;let d=l.match(/DevTools listening on (ws:\/\/\S+)/i);d?.[1]&&(clearTimeout(u),a(d[1]))}),r.once("error",m=>{clearTimeout(u),c(m)}),r.once("exit",m=>{clearTimeout(u),c(new Error(`Browser exited before starting (code ${m??1}).`))})}),s=new WebSocket(o);await new Promise((a,c)=>{s.addEventListener("open",()=>a()),s.addEventListener("error",()=>c(new Error("Failed to open the DevTools WebSocket.")))});let i=new t(r,s);return await i.attachPageTarget(),i}async attachPageTarget(){let e=await this.send("Target.createTarget",{url:"about:blank"}),n=String(e.targetId??"");if(!n)throw new Error("Browser did not create a page target.");let r=await this.send("Target.attachToTarget",{targetId:n,flatten:!0});if(this.sessionId=String(r.sessionId??""),!this.sessionId)throw new Error("Browser did not attach a page session.")}send(e,n={},r=15e3){let o=this.nextId++,s={id:o,method:e,params:n};return this.sessionId&&(s.sessionId=this.sessionId),this.ws.send(JSON.stringify(s)),new Promise((i,a)=>{let c=setTimeout(()=>{this.pending.delete(o),a(new Error(`CDP ${e} timed out.`))},r);this.pending.set(o,{resolve:i,reject:a,timer:c})})}handleMessage(e){let n;try{n=JSON.parse(e)}catch{return}let r=n.id;if(r===void 0)return;let o=this.pending.get(r);if(o)if(clearTimeout(o.timer),this.pending.delete(r),n.error&&typeof n.error=="object"){let s=n.error;o.reject(new Error(String(s.message??"CDP error")))}else o.resolve(n.result??{})}async evaluate(e){return await this.send("Runtime.evaluate",{expression:e,returnByValue:!0,awaitPromise:!0})}failAll(e){for(let n of this.pending.values())clearTimeout(n.timer),n.reject(e);this.pending.clear()}async navigate(e,n,r){await this.send("Page.navigate",{url:e});let o=r==="domcontentloaded"?["interactive","complete"]:["complete"],s=Date.now()+Math.min(n,3e4);for(;Date.now()<s;){let i=await this.evaluate("document.readyState"),a=String(i.result?.value??"");if(o.includes(a))break;await Ks(120)}r==="networkidle2"&&await Ks(700)}async readPage(e){let n=await this.evaluate("JSON.stringify({title:document.title,url:location.href,text:(()=>{const c=document.body?document.body.cloneNode(true):null;if(!c)return '';c.querySelectorAll('script,style,noscript,svg,canvas,iframe,template').forEach(function(n){n.remove()});return (c.innerText||c.textContent||'').replace(/\\s+/g,' ').trim();})()})"),r={};try{r=JSON.parse(String(n.result?.value??"{}"))}catch{r={}}let o=String(r.text??""),s=o.length>e;return{url:String(r.url??""),title:String(r.title??""),text:s?o.slice(0,e):o,truncated:s}}async screenshot(e,n){let r=Gs,o=Hs;if(e){let u=(await this.send("Page.getLayoutMetrics")).cssContentSize?.height;o=Math.max(o,Math.ceil(Number(u)||o)),await this.send("Emulation.setDeviceMetricsOverride",{width:r,height:o,deviceScaleFactor:1,mobile:!1})}let s=await this.send("Page.captureScreenshot",{format:"png"}),i=String(s.data??"");if(!i)throw new Error("Browser returned an empty screenshot.");let a=Ie.join(n,".kpilot","run");await Ws(a,{recursive:!0});let c=Ie.join(".kpilot","run",`browser-${Date.now().toString(36)}.png`);return await lu(Ie.join(n,c),Buffer.from(i,"base64")),c}async click(e){let r=(await this.evaluate(`(()=>{const el=document.querySelector(${JSON.stringify(e)});if(!el)return {ok:false,why:'no matching element'};const r=el.getBoundingClientRect();try{el.click();}catch(e){}return {ok:true,tag:(el.tagName||'').toLowerCase(),x:Math.round(r.left+r.width/2),y:Math.round(r.top+r.height/2)};})()`)).result?.value??{};if(!r.ok)return`Click failed: ${String(r.why??"unknown")}`;let o=Number(r.x??0),s=Number(r.y??0);return await this.send("Input.dispatchMouseEvent",{type:"mousePressed",x:o,y:s,button:"left",clickCount:1}),await this.send("Input.dispatchMouseEvent",{type:"mouseReleased",x:o,y:s,button:"left",clickCount:1}),`Clicked <${String(r.tag)}>@${e} at (${o}, ${s}).`}async typeText(e,n){let o=(await this.evaluate(`(()=>{const el=document.querySelector(${JSON.stringify(e)});if(!el)return {ok:false,why:'no matching element'};el.focus();return {ok:true,tag:(el.tagName||'').toLowerCase()};})()`)).result?.value??{};return o.ok?(await this.send("Input.insertText",{text:n}),`Typed ${n.length} characters into <${String(o.tag)}>@${e}.`):`Type failed: ${String(o.why??"unknown")}`}async evaluateExpression(e){let n=await this.evaluate(e);if(n.exceptionDetails){let o=n.exceptionDetails,s=o?.exception?.description??o?.text??"evaluation error";return`Evaluation error: ${String(s)}`}let r=n.result?.value;if(r===void 0)return"undefined";if(typeof r=="string")return r;try{return JSON.stringify(r)}catch{return String(r)}}async close(){if(!this.closed){this.closed=!0;try{this.ws.close()}catch{}if(this.failAll(new Error("Browser closed.")),this.child)try{this.child.kill("SIGTERM")}catch{}}}},ze;async function Et(){if(ze)return ze;let t=Pt();if(!t)throw new Error(Tt);return ze=await vr.launch(t),ze}async function zs(){await ze?.close(),ze=void 0}async function xr(t){let n=(await yr(t.url)).href,r=Math.min(Math.max(t.maxChars??5e4,1),2e5),o=t.waitUntil??"load",s=t.waitMs??15e3;try{let i=await Et();await i.navigate(n,s,o);let a=await i.readPage(r);return{mode:"cdp",...a,title:a.title||n}}catch{let a=await pu(n);return{mode:"static",url:n,title:String(a.title??""),text:a.text.slice(0,r),truncated:a.text.length>r}}}async function Vs(t){let e=t.fullPage===!0;t.url&&await xr({url:t.url,waitUntil:"load",waitMs:15e3,maxChars:4e3});try{return{path:await(await Et()).screenshot(e,t.rootDir),mode:"cdp"}}catch{if(t.url){let n=await fu(t.url,e,t.rootDir);if(n)return{path:n,mode:"static"}}throw new Error("Unable to capture a screenshot without a browser. "+Tt)}}async function Ys(t){return await(await Et()).click(t)}async function Qs(t,e){return await(await Et()).typeText(t,e)}async function Xs(t){return await(await Et()).evaluateExpression(t)}async function pu(t){let e=Pt();if(!e)throw new Error(Tt);let n=await new Promise((o,s)=>{let i=kr(e,["--headless=new","--no-sandbox","--disable-gpu","--dump-dom",t],{stdio:["ignore","pipe","pipe"]}),a="",c="",l=setTimeout(()=>i.kill("SIGKILL"),2e4);i.stdout.setEncoding("utf8"),i.stdout.on("data",u=>{a.length<1e6&&(a+=u)}),i.stderr.setEncoding("utf8"),i.stderr.on("data",u=>{c+=u}),i.once("error",u=>{clearTimeout(l),s(u)}),i.once("exit",u=>{clearTimeout(l),u!==0&&!a?s(new Error(c.trim()||`Browser exited with code ${u??1}.`)):o(a)})}),r=n.match(/<title[^>]*>([\s\S]*?)<\/title>/i);return{title:St(r?.[1]??""),text:St(n)}}async function fu(t,e,n){let r=Pt();if(!r)return null;let o=Ie.join(n,".kpilot","run");await Ws(o,{recursive:!0});let s=Ie.join(".kpilot","run",`browser-${Date.now().toString(36)}.png`),i=Ie.join(n,s),a=["--headless=new","--no-sandbox","--disable-gpu"];return e&&a.push(`--window-size=${Gs},${Hs*3}`),a.push(`--screenshot=${i}`,t),await new Promise(l=>{let u=kr(r,a,{stdio:["ignore","ignore","ignore"]}),m=setTimeout(()=>u.kill("SIGKILL"),2e4);u.once("error",()=>{clearTimeout(m),l(!1)}),u.once("exit",d=>{clearTimeout(m),l(d===0)})})?s:null}var yu=new Set([".git","node_modules","dist","build",".next",".turbo","coverage",".cache",".idea"]),Rr=1e6,Cr=2e5,bu=/(?:✓\s*)?Ready in\b|Local:\s+https?:\/\/|Network:\s+https?:\/\/|listening on (?:port\s+)?\d+\b|started server on\b|VITE .+ ready in\b/i,Zs=/ERR_PNPM_|ELIFECYCLE|EADDRINUSE|ECONNREFUSED|Error:\s|Command failed|exit code [1-9]\d*|Failed to compile|Module not found|Cannot find module|ENOENT|pnpm approve-builds|IGNORED_BUILDS/i,vu=/\b(?:pnpm|npm|yarn|bun)(?:\s+run)?\s+dev\b|\bnext\s+dev\b|\bvite(?:\s|$)|(?:^|[;&|]\s*)(?:nodemon|tsx\s+watch|node\s+--watch)\b|\bdocker\s+compose\s+up\b(?![^\n]*\s-d\b)/i;function Rt(t,e=Cr){if(t.length<=e)return t;let n=t.length-e;return`${t.slice(0,e)}
157
169
 
158
- [output truncated: ${n} characters omitted]`}function Sr(t,e){let n=t;for(let[r,o]of Object.entries(e))!o||o.length<8||!/(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL)/i.test(r)||(n=n.split(o).join(`[REDACTED:${r}]`));return n}async function un(t,e,n){let r=n.timeoutMs??3e4,o=n.env??process.env;return await new Promise((s,i)=>{let a=Js(t,e,{cwd:n.cwd,env:o,shell:n.shell??!1,stdio:["ignore","pipe","pipe"]}),c="",l="",u=!1,m=!1;a.stdout?.setEncoding("utf8"),a.stderr?.setEncoding("utf8");let d="",f=P=>{if(!n.onOutput)return;d+=P;let S=d.split(/\r?\n/);d=S.pop()??"";for(let C of S)n.onOutput(C)};a.stdout?.on("data",P=>{c.length<xr*2&&(c+=P),f(P)}),a.stderr?.on("data",P=>{l.length<xr*2&&(l+=P),f(P)});let w=()=>{m=!0,a.kill("SIGTERM"),setTimeout(()=>a.kill("SIGKILL"),1e3)};n.signal?.aborted?w():n.signal?.addEventListener("abort",w,{once:!0});let x=setTimeout(()=>{u=!0,a.kill("SIGTERM"),setTimeout(()=>a.kill("SIGKILL"),1e3)},r);a.once("error",P=>{clearTimeout(x),n.signal?.removeEventListener("abort",w),i(P)}),a.once("close",P=>{clearTimeout(x),n.signal?.removeEventListener("abort",w),s({code:P??1,stdout:Pt(Sr(c,o)),stderr:Pt(Sr(l,o)),timedOut:u,cancelled:m})})})}function yr(t,e){let n=K.relative(t,e);return n===""||!n.startsWith("..")&&!K.isAbsolute(n)}async function su(t){let e=t;for(;;)try{return await De(e),e}catch{let n=K.dirname(e);if(n===e)throw new Error(`No existing ancestor found for ${t}`);e=n}}var Tr=class{rootDir;canonicalRoot;constructor(e){this.rootDir=K.resolve(e)}async root(){this.canonicalRoot??=await wr(this.rootDir);let e=this.canonicalRoot;if(!e)throw new Error("Unable to resolve the project root.");return e}async resolve(e,n={}){if(e.includes("\0"))throw new Error("Paths cannot contain null bytes.");let r=await this.root(),o=K.resolve(r,e||".");if(!yr(r,o))throw new Error(`Path escapes the project root: ${e}`);if(n.mustExist){let a=await wr(o);if(!yr(r,a))throw new Error(`Resolved path escapes the project root: ${e}`);return a}let s=await su(o),i=await wr(s);if(!yr(r,i))throw new Error(`Path crosses a symlink outside the project root: ${e}`);return o}};function J(t,e,n,r=[]){return{type:"function",function:{name:t,description:e,parameters:{type:"object",properties:n,required:r,additionalProperties:!1}}}}var Fs=[J("workspace_summary","Return a concise repository overview, top-level files, detected manifests, and Git status.",{}),J("list_files","List files and directories under a project-relative path. Common generated directories are ignored.",{path:{type:"string",description:"Project-relative directory. Defaults to the project root."},max_depth:{type:"integer",minimum:0,maximum:8,description:"Maximum recursive depth."},max_entries:{type:"integer",minimum:1,maximum:2e3,description:"Maximum returned entries."}}),J("read_file","Read a UTF-8 text file with optional 1-based line boundaries.",{path:{type:"string",description:"Project-relative file path."},start_line:{type:"integer",minimum:1},end_line:{type:"integer",minimum:1}},["path"]),J("search_text","Search text across project files using ripgrep when available, with a built-in fallback.",{query:{type:"string",description:"Literal or regex search query."},path:{type:"string",description:"Project-relative search path. Defaults to root."},regex:{type:"boolean",description:"Interpret query as a regular expression."},max_results:{type:"integer",minimum:1,maximum:500}},["query"]),J("write_file","Create or replace a UTF-8 file. Prefer content (raw text) for .env, markdown, JSON, and other plain config. Use content_b64 only for multi-line source code with nested quotes that break JSON. Prefer replace_in_file for small edits.",{path:{type:"string",description:"Project-relative file path."},content:{type:"string",description:"Raw UTF-8 content. Preferred for .env and plain text."},content_b64:{type:"string",description:"Standard base64 of UTF-8 bytes. Only for code with nested quotes; never invent placeholder base64."},overwrite:{type:"boolean",description:"Allow replacing an existing file. Defaults to true."}},["path"]),J("replace_in_file","Replace an exact string in a UTF-8 file. Prefer this over write_file for small edits \u2014 safer and easier for tool JSON.",{path:{type:"string"},old_string:{type:"string"},new_string:{type:"string"},expected_occurrences:{type:"integer",minimum:1,maximum:1e3}},["path","old_string","new_string"]),J("make_directory","Create a directory recursively inside the project.",{path:{type:"string"}},["path"]),J("delete_path","Delete a file, or a directory only when recursive is explicitly true.",{path:{type:"string"},recursive:{type:"boolean"}},["path"]),J("shell","Run a shell command from a project-relative working directory. For long-lived processes (pnpm/npm/yarn/bun dev, next dev, vite, watchers), set background=true (or rely on auto-detect) so the server keeps running; the tool returns pid + log path after a ready line or wait_ms.",{command:{type:"string"},cwd:{type:"string",description:"Project-relative working directory."},timeout_ms:{type:"integer",minimum:100,maximum:36e5,description:"Foreground only: kill the command after this many ms (default 30000). When the sandbox sets a timeout cap, the lower of the two applies."},background:{type:"boolean",description:"Detach and keep running. Use for dev servers and watchers. Auto-enabled for common `*dev` / vite / next dev commands."},ready_pattern:{type:"string",description:"Optional regex (case-insensitive) matched against the background log before returning."},wait_ms:{type:"integer",minimum:500,maximum:36e5,description:"Background only: how long to wait for ready_pattern (default 45000)."}},["command"]),J("git_status","Show concise Git working-tree status.",{}),J("git_diff","Show the current Git diff, optionally staged and optionally limited to a path.",{staged:{type:"boolean"},path:{type:"string"}}),J("web_search","Search the public web. Auto mode tries free DuckDuckGo first, then the first configured API provider (TAVILY_API_KEY -> EXA_API_KEY -> SERPER_API_KEY -> SEARXNG_BASE_URL -> BRAVE_API_KEY). Set `provider` to force one. Returns titles, URLs, and descriptions.",{query:{type:"string",description:"Search query."},count:{type:"integer",minimum:1,maximum:10,description:"Number of results to return (default 5)."},provider:{type:"string",enum:["duckduckgo","brave","tavily","exa","serper","searxng"],description:"Optional provider to use; omit for auto. Requires the matching API key."}},["query"]),J("web_fetch","Fetch a public http(s) URL and return extracted text. Blocks private/link-local hosts (SSRF protection). Prefer web_search first when the URL is unknown.",{url:{type:"string",description:"Absolute http(s) URL to fetch."},max_chars:{type:"integer",minimum:1,maximum:2e5,description:"Maximum characters of extracted text to return (default 50000)."}},["url"])],iu=[J("browser_open","Open a URL in a real (headless Chromium) browser and return the JavaScript-rendered page text. Use when web_fetch returns empty or a page requires JS. Requires a Chromium browser (KPILOT_CHROME_PATH or system Chrome/Chromium/Edge).",{url:{type:"string",description:"Absolute http(s) URL to open."},wait_until:{type:"string",enum:["load","domcontentloaded","networkidle2"],description:"When to consider the page loaded (default load). networkidle2 waits ~0.7s extra for async JS."},wait_ms:{type:"integer",minimum:1e3,maximum:6e4,description:"Maximum wait for page load (default 15000)."},max_chars:{type:"integer",minimum:1,maximum:2e5,description:"Maximum extracted text characters (default 50000)."}},["url"]),J("browser_screenshot","Capture a PNG screenshot of the current browser session page (or a given URL) into .kpilot/run/ and return its relative path.",{url:{type:"string",description:"Optional URL to open before screenshot; omit to capture the current page."},full_page:{type:"boolean",description:"Capture the full page height instead of the viewport."}}),J("browser_click","Click an element in the current browser session by CSS selector.",{selector:{type:"string",description:"CSS selector of the element to click."}},["selector"]),J("browser_type","Type text into a focused-able element in the current browser session (input/textarea) by CSS selector.",{selector:{type:"string",description:"CSS selector of the input element."},text:{type:"string",description:"Text to type."}},["selector","text"]),J("browser_evaluate","Evaluate a JavaScript expression in the current browser session page and return its JSON-serializable result.",{expression:{type:"string",description:"JavaScript expression that yields a JSON-serializable value."}},["expression"]),J("browser_close","Close the browser session and release the Chromium process.",{})];async function Bs(t){try{return await De(t),!0}catch{return!1}}async function Pr(t,e,n,r){let o=[];async function s(i,a){if(o.length>=r)return;let c=await eu(i,{withFileTypes:!0});c.sort((l,u)=>l.name.localeCompare(u.name));for(let l of c){if(o.length>=r)break;if(nu.has(l.name))continue;let u=K.join(i,l.name),m=K.relative(e,u)||".";o.push(`${l.isDirectory()?"d":l.isSymbolicLink()?"l":"f"} ${m}`),l.isDirectory()&&a<n&&await s(u,a+1)}}return await s(t,0),o.length>=r&&o.push(`[truncated at ${r} entries]`),o}async function au(t,e,n,r,o){let s=r?new RegExp(n,"i"):void 0,i=await Pr(t,e,8,5e3),a=[];for(let c of i){if(!c.startsWith("f "))continue;let l=c.slice(2),u=K.join(e,l);if((await De(u)).size>kr)continue;let d;try{d=await dn(u,"utf8")}catch{continue}if(d.includes("\0"))continue;let f=d.split(/\r?\n/);for(let w=0;w<f.length;w+=1){let x=f[w]??"";if((s?s.test(x):x.toLowerCase().includes(n.toLowerCase()))&&a.push(`${l}:${w+1}:${x}`),a.length>=o)return a}}return a}function cu(t){let e=[`exit_code: ${t.code}`,`timed_out: ${t.timedOut}`,`cancelled: ${t.cancelled}`];return t.stdout&&e.push(`stdout:
170
+ [output truncated: ${n} characters omitted]`}function Mr(t,e){let n=t;for(let[r,o]of Object.entries(e))!o||o.length<8||!/(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL)/i.test(r)||(n=n.split(o).join(`[REDACTED:${r}]`));return n}async function fn(t,e,n){let r=n.timeoutMs??3e4,o=n.env??process.env;return await new Promise((s,i)=>{let a=ri(t,e,{cwd:n.cwd,env:o,shell:n.shell??!1,stdio:["ignore","pipe","pipe"]}),c="",l="",u=!1,m=!1;a.stdout?.setEncoding("utf8"),a.stderr?.setEncoding("utf8");let d="",p=x=>{if(!n.onOutput)return;d+=x;let k=d.split(/\r?\n/);d=k.pop()??"";for(let R of k)n.onOutput(R)};a.stdout?.on("data",x=>{c.length<Cr*2&&(c+=x),p(x)}),a.stderr?.on("data",x=>{l.length<Cr*2&&(l+=x),p(x)});let y=()=>{m=!0,a.kill("SIGTERM"),setTimeout(()=>a.kill("SIGKILL"),1e3)};n.signal?.aborted?y():n.signal?.addEventListener("abort",y,{once:!0});let S=setTimeout(()=>{u=!0,a.kill("SIGTERM"),setTimeout(()=>a.kill("SIGKILL"),1e3)},r);a.once("error",x=>{clearTimeout(S),n.signal?.removeEventListener("abort",y),i(x)}),a.once("close",x=>{clearTimeout(S),n.signal?.removeEventListener("abort",y),s({code:x??1,stdout:Rt(Mr(c,o)),stderr:Rt(Mr(l,o)),timedOut:u,cancelled:m})})})}function Tr(t,e){let n=W.relative(t,e);return n===""||!n.startsWith("..")&&!W.isAbsolute(n)}async function ku(t){let e=t;for(;;)try{return await De(e),e}catch{let n=W.dirname(e);if(n===e)throw new Error(`No existing ancestor found for ${t}`);e=n}}var $r=class{rootDir;canonicalRoot;constructor(e){this.rootDir=W.resolve(e)}async root(){this.canonicalRoot??=await Sr(this.rootDir);let e=this.canonicalRoot;if(!e)throw new Error("Unable to resolve the project root.");return e}async resolve(e,n={}){if(e.includes("\0"))throw new Error("Paths cannot contain null bytes.");let r=await this.root(),o=W.resolve(r,e||".");if(!Tr(r,o))throw new Error(`Path escapes the project root: ${e}`);if(n.mustExist){let a=await Sr(o);if(!Tr(r,a))throw new Error(`Resolved path escapes the project root: ${e}`);return a}let s=await ku(o),i=await Sr(s);if(!Tr(r,i))throw new Error(`Path crosses a symlink outside the project root: ${e}`);return o}};function K(t,e,n,r=[]){return{type:"function",function:{name:t,description:e,parameters:{type:"object",properties:n,required:r,additionalProperties:!1}}}}var ei=[K("workspace_summary","Return a concise repository overview, top-level files, detected manifests, and Git status.",{}),K("list_files","List files and directories under a project-relative path. Common generated directories are ignored.",{path:{type:"string",description:"Project-relative directory. Defaults to the project root."},max_depth:{type:"integer",minimum:0,maximum:8,description:"Maximum recursive depth."},max_entries:{type:"integer",minimum:1,maximum:2e3,description:"Maximum returned entries."}}),K("read_file","Read a UTF-8 text file with optional 1-based line boundaries.",{path:{type:"string",description:"Project-relative file path."},start_line:{type:"integer",minimum:1},end_line:{type:"integer",minimum:1}},["path"]),K("search_text","Search text across project files using ripgrep when available, with a built-in fallback.",{query:{type:"string",description:"Literal or regex search query."},path:{type:"string",description:"Project-relative search path. Defaults to root."},regex:{type:"boolean",description:"Interpret query as a regular expression."},max_results:{type:"integer",minimum:1,maximum:500}},["query"]),K("write_file","Create or replace a UTF-8 file. Prefer content (raw text) for .env, markdown, JSON, and other plain config. Use content_b64 only for multi-line source code with nested quotes that break JSON. Prefer replace_in_file for small edits.",{path:{type:"string",description:"Project-relative file path."},content:{type:"string",description:"Raw UTF-8 content. Preferred for .env and plain text."},content_b64:{type:"string",description:"Standard base64 of UTF-8 bytes. Only for code with nested quotes; never invent placeholder base64."},overwrite:{type:"boolean",description:"Allow replacing an existing file. Defaults to true."}},["path"]),K("replace_in_file","Replace an exact string in a UTF-8 file. Prefer this over write_file for small edits \u2014 safer and easier for tool JSON.",{path:{type:"string"},old_string:{type:"string"},new_string:{type:"string"},expected_occurrences:{type:"integer",minimum:1,maximum:1e3}},["path","old_string","new_string"]),K("make_directory","Create a directory recursively inside the project.",{path:{type:"string"}},["path"]),K("delete_path","Delete a file, or a directory only when recursive is explicitly true.",{path:{type:"string"},recursive:{type:"boolean"}},["path"]),K("shell","Run a shell command from a project-relative working directory. For long-lived processes (pnpm/npm/yarn/bun dev, next dev, vite, watchers), set background=true (or rely on auto-detect) so the server keeps running; the tool returns pid + log path after a ready line or wait_ms.",{command:{type:"string"},cwd:{type:"string",description:"Project-relative working directory."},timeout_ms:{type:"integer",minimum:100,maximum:36e5,description:"Foreground only: kill the command after this many ms (default 30000). When the sandbox sets a timeout cap, the lower of the two applies."},background:{type:"boolean",description:"Detach and keep running. Use for dev servers and watchers. Auto-enabled for common `*dev` / vite / next dev commands."},ready_pattern:{type:"string",description:"Optional regex (case-insensitive) matched against the background log before returning."},wait_ms:{type:"integer",minimum:500,maximum:36e5,description:"Background only: how long to wait for ready_pattern (default 45000)."}},["command"]),K("git_status","Show concise Git working-tree status.",{}),K("git_diff","Show the current Git diff, optionally staged and optionally limited to a path.",{staged:{type:"boolean"},path:{type:"string"}}),K("web_search","Search the public web. Auto mode tries free DuckDuckGo first, then the first configured API provider (TAVILY_API_KEY -> EXA_API_KEY -> SERPER_API_KEY -> SEARXNG_BASE_URL -> BRAVE_API_KEY). Set `provider` to force one. Returns titles, URLs, and descriptions.",{query:{type:"string",description:"Search query."},count:{type:"integer",minimum:1,maximum:10,description:"Number of results to return (default 5)."},provider:{type:"string",enum:["duckduckgo","brave","tavily","exa","serper","searxng"],description:"Optional provider to use; omit for auto. Requires the matching API key."}},["query"]),K("web_fetch","Fetch a public http(s) URL and return extracted text. Blocks private/link-local hosts (SSRF protection). Prefer web_search first when the URL is unknown.",{url:{type:"string",description:"Absolute http(s) URL to fetch."},max_chars:{type:"integer",minimum:1,maximum:2e5,description:"Maximum characters of extracted text to return (default 50000)."}},["url"])],xu=[K("browser_open","Open a URL in a real (headless Chromium) browser and return the JavaScript-rendered page text. Use when web_fetch returns empty or a page requires JS. Requires a Chromium browser (KPILOT_CHROME_PATH or system Chrome/Chromium/Edge).",{url:{type:"string",description:"Absolute http(s) URL to open."},wait_until:{type:"string",enum:["load","domcontentloaded","networkidle2"],description:"When to consider the page loaded (default load). networkidle2 waits ~0.7s extra for async JS."},wait_ms:{type:"integer",minimum:1e3,maximum:6e4,description:"Maximum wait for page load (default 15000)."},max_chars:{type:"integer",minimum:1,maximum:2e5,description:"Maximum extracted text characters (default 50000)."}},["url"]),K("browser_screenshot","Capture a PNG screenshot of the current browser session page (or a given URL) into .kpilot/run/ and return its relative path.",{url:{type:"string",description:"Optional URL to open before screenshot; omit to capture the current page."},full_page:{type:"boolean",description:"Capture the full page height instead of the viewport."}}),K("browser_click","Click an element in the current browser session by CSS selector.",{selector:{type:"string",description:"CSS selector of the element to click."}},["selector"]),K("browser_type","Type text into a focused-able element in the current browser session (input/textarea) by CSS selector.",{selector:{type:"string",description:"CSS selector of the input element."},text:{type:"string",description:"Text to type."}},["selector","text"]),K("browser_evaluate","Evaluate a JavaScript expression in the current browser session page and return its JSON-serializable result.",{expression:{type:"string",description:"JavaScript expression that yields a JSON-serializable value."}},["expression"]),K("browser_close","Close the browser session and release the Chromium process.",{})];async function ti(t){try{return await De(t),!0}catch{return!1}}async function _r(t,e,n,r){let o=[];async function s(i,a){if(o.length>=r)return;let c=await hu(i,{withFileTypes:!0});c.sort((l,u)=>l.name.localeCompare(u.name));for(let l of c){if(o.length>=r)break;if(yu.has(l.name))continue;let u=W.join(i,l.name),m=W.relative(e,u)||".";o.push(`${l.isDirectory()?"d":l.isSymbolicLink()?"l":"f"} ${m}`),l.isDirectory()&&a<n&&await s(u,a+1)}}return await s(t,0),o.length>=r&&o.push(`[truncated at ${r} entries]`),o}async function Su(t,e,n,r,o){let s=r?new RegExp(n,"i"):void 0,i=await _r(t,e,8,5e3),a=[];for(let c of i){if(!c.startsWith("f "))continue;let l=c.slice(2),u=W.join(e,l);if((await De(u)).size>Rr)continue;let d;try{d=await gn(u,"utf8")}catch{continue}if(d.includes("\0"))continue;let p=d.split(/\r?\n/);for(let y=0;y<p.length;y+=1){let S=p[y]??"";if((s?s.test(S):S.toLowerCase().includes(n.toLowerCase()))&&a.push(`${l}:${y+1}:${S}`),a.length>=o)return a}}return a}function Tu(t){let e=[`exit_code: ${t.code}`,`timed_out: ${t.timedOut}`,`cancelled: ${t.cancelled}`];return t.stdout&&e.push(`stdout:
159
171
  ${t.stdout}`),t.stderr&&e.push(`stderr:
160
172
  ${t.stderr}`),e.join(`
161
- `)}function lu(t){return ou.test(t.trim())}function uu(t){return new Promise(e=>{setTimeout(()=>e(),t)})}async function Er(t,e=4e3){try{let n=await dn(t,"utf8");return n.length<=e?n:n.slice(-e)}catch{return""}}async function du(t){let e=Date.now()+t.waitMs;for(;Date.now()<e;){if(t.signal?.aborted)return{ready:!1,failed:!1,exitedEarly:!1};let n=await Er(t.logPath,8e4);if(Ns.test(n)&&!t.pattern.test(n))return{ready:!1,failed:!0,exitedEarly:!1};if(t.pattern.test(n))return{ready:!0,failed:!1,exitedEarly:!1};try{process.kill(t.pid,0)}catch{return{ready:!1,failed:!1,exitedEarly:!0}}await uu(250)}try{process.kill(t.pid,0);let n=await Er(t.logPath,8e4);return Ns.test(n)?{ready:!1,failed:!0,exitedEarly:!1}:{ready:!1,failed:!1,exitedEarly:!1}}catch{return{ready:!1,failed:!1,exitedEarly:!0}}}function mu(t){let e=t.match(/https?:\/\/(?:localhost|127\.0\.0\.1):\d+\b/gi)??[];return[...new Set(e.map(n=>n.replace(/\/$/,"")))]}async function qs(t){for(let e of t.slice(0,3))try{let n=new AbortController,r=setTimeout(()=>n.abort(),1500);try{return await fetch(e,{signal:n.signal,redirect:"manual"}),{url:e,ok:!0}}finally{clearTimeout(r)}}catch(n){let r=n instanceof Error?n.message:String(n);if(/abort|timeout/i.test(r)||/ECONNREFUSED|fetch failed|ENOTFOUND/i.test(r))continue}}async function pu(t){let e=K.join(t.rootDir,E,"run");await br(e,{recursive:!0});let n=`bg-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,r=K.join(E,"run",`${n}.log`),o=K.join(E,"run",`${n}.json`),s=K.join(t.rootDir,r),i=K.join(t.rootDir,o),a=await Zl(s,"a"),c;try{c=Js(t.command,t.args,{cwd:t.cwd,env:t.env,detached:!0,stdio:["ignore",a.fd,a.fd]})}finally{await a.close()}if(c.pid==null)return{ok:!1,output:"Failed to start background process (no pid)."};let l=c.pid;c.unref();let u={id:n,pid:l,command:t.originalCommand,cwd:t.cwd,log:r,backend:t.backend,startedAt:new Date().toISOString()};await vr(i,`${JSON.stringify(u,null,2)}
162
- `,"utf8");let m=null;c.once("exit",A=>{m=A});let d=t.readyPattern?new RegExp(t.readyPattern,"i"):ru,f=await du({logPath:s,pid:l,pattern:d,waitMs:t.waitMs,signal:t.signal}),w=Sr(await Er(s),t.env),x=mu(w),P=f.ready?await qs(x):void 0;!f.ready&&!f.failed&&!f.exitedEarly&&x.length>0&&(P=await qs(x));let S=(()=>{try{return process.kill(l,0),m===null}catch{return!1}})(),C=!!(S&&(f.ready||P?.ok)&&!f.failed&&m===null),b=()=>{try{process.kill(-l,"SIGTERM")}catch{try{process.kill(l,"SIGTERM")}catch{}}};return f.exitedEarly||m!==null||!S?{ok:!1,output:[`Background process is NOT running (pid=${l}, id=${n}). Do not tell the user the server is up.`,`command: ${t.originalCommand}`,`log: ${r}`,`meta: ${o}`,`sandbox: ${t.backend}`,w?`--- log ---
163
- ${Pt(w)}`:"[empty log]"].join(`
164
- `),metadata:{background:!0,pid:l,id:n,log:r,ready:!1}}:f.failed||!C?(b(),{ok:!1,output:[`Background process started (pid=${l}) but is NOT ready. Do not tell the user the server is up.`,`command: ${t.originalCommand}`,f.failed?"ready: no (failure detected in log \u2014 install/build/runtime error)":`ready: no (no server startup line after ${t.waitMs}ms; http probe ${P?.ok?"ok":"failed/skipped"})`,`log: ${r}`,`meta: ${o}`,`sandbox: ${t.backend}`,"Process was stopped. Fix the error in the log (e.g. pnpm approve-builds / install), then retry.",w?`--- log (tail) ---
165
- ${Pt(w)}`:"[empty log so far]"].join(`
166
- `),metadata:{background:!0,pid:l,id:n,log:r,ready:!1,failed:f.failed}}):{ok:!0,output:[`Started background process pid=${l} id=${n}`,`command: ${t.originalCommand}`,f.ready?"ready: yes (matched startup pattern in log)":`ready: yes (HTTP probe succeeded at ${P?.url})`,P?.url?`url: ${P.url}`:x[0]?`url: ${x[0]} (from log)`:void 0,`log: ${r}`,`meta: ${o}`,`sandbox: ${t.backend}`,"Process keeps running after this tool returns.",w?`--- log (tail) ---
167
- ${Pt(w)}`:"[empty log so far]"].filter(Boolean).join(`
168
- `),metadata:{background:!0,pid:l,id:n,log:r,ready:!0,url:P?.url??x[0]}}}function fu(t){let e=t.replace(/\s+/g,"");if(!e)throw new Error("content_b64 is empty.");if(e==="QWxhZGRpbjpvcGVuIHNlc2FtZQ==")throw new Error("content_b64 is a placeholder example, not your file bytes. For .env and plain text, call write_file with content (raw string), not content_b64.");if(!/^[A-Za-z0-9+/]+={0,2}$/.test(e)||e.length%4!==0)throw new Error("content_b64 is not valid base64. For .env/config/markdown use write_file with content instead.");let n=Buffer.from(e,"base64"),r=n.toString("base64").replace(/=+$/,""),o=e.replace(/=+$/,"");if(r!==o)throw new Error("content_b64 failed base64 round-trip. For .env/config/markdown use write_file with content instead.");let s=n.toString("utf8");if(s.includes("\uFFFD"))throw new Error("content_b64 does not decode to valid UTF-8 text.");return s}var ye=class{rootDir;guard;sandbox;browserEnabled;browserClosed=!1;constructor(e,n={}){this.rootDir=K.resolve(e),this.guard=new Tr(this.rootDir),this.sandbox=new ln(this.rootDir,n.sandbox);let r=n.browser??"auto";this.browserEnabled=r==="on"?!0:r==="off"?!1:St()!==void 0}definitions(){return this.browserEnabled?[...Fs,...iu]:Fs}async execute(e,n,r){if(K.resolve(r.rootDir)!==this.rootDir)throw new Error("Tool runtime root does not match the agent root.");try{switch(e){case"workspace_summary":return await this.workspaceSummary();case"list_files":return await this.listFiles(n);case"read_file":return await this.readFile(n);case"search_text":return await this.searchText(n);case"write_file":return await this.writeFile(n);case"replace_in_file":return await this.replaceInFile(n);case"make_directory":return await this.makeDirectory(n);case"delete_path":return await this.deletePath(n);case"shell":return await this.shell(n,r.signal,r.onOutput);case"git_status":return await this.gitStatus(r.signal);case"git_diff":return await this.gitDiff(n,r.signal);case"web_search":return await this.webSearch(n,r.signal);case"web_fetch":return await this.webFetch(n,r.signal);case"browser_open":return await this.browserOpen(n);case"browser_screenshot":return await this.browserScreenshot(n);case"browser_click":return await this.browserClick(n);case"browser_type":return await this.browserType(n);case"browser_evaluate":return await this.browserEvaluate(n);case"browser_close":return await this.browserClose();default:return{ok:!1,output:`Unknown tool: ${e}`}}}catch(o){return{ok:!1,output:o instanceof Error?o.message:String(o)}}}async workspaceSummary(){let e=await Pr(this.rootDir,this.rootDir,1,80),n=["package.json","pnpm-workspace.yaml","pyproject.toml","Cargo.toml","go.mod","composer.json","Gemfile","pom.xml","build.gradle"],r=[];for(let u of n)await Bs(K.join(this.rootDir,u))&&r.push(u);let o=await this.gitStatus(),s=(o.output||"").split(/\r?\n/),i=40,a=s.length<=i?o.output:`${s.slice(0,i).join(`
173
+ `)}function Pu(t){return vu.test(t.trim())}function Eu(t){return new Promise(e=>{setTimeout(()=>e(),t)})}async function Ar(t,e=4e3){try{let n=await gn(t,"utf8");return n.length<=e?n:n.slice(-e)}catch{return""}}async function Ru(t){let e=Date.now()+t.waitMs;for(;Date.now()<e;){if(t.signal?.aborted)return{ready:!1,failed:!1,exitedEarly:!1};let n=await Ar(t.logPath,8e4);if(Zs.test(n)&&!t.pattern.test(n))return{ready:!1,failed:!0,exitedEarly:!1};if(t.pattern.test(n))return{ready:!0,failed:!1,exitedEarly:!1};try{process.kill(t.pid,0)}catch{return{ready:!1,failed:!1,exitedEarly:!0}}await Eu(250)}try{process.kill(t.pid,0);let n=await Ar(t.logPath,8e4);return Zs.test(n)?{ready:!1,failed:!0,exitedEarly:!1}:{ready:!1,failed:!1,exitedEarly:!1}}catch{return{ready:!1,failed:!1,exitedEarly:!0}}}function Cu(t){let e=t.match(/https?:\/\/(?:localhost|127\.0\.0\.1):\d+\b/gi)??[];return[...new Set(e.map(n=>n.replace(/\/$/,"")))]}async function ni(t){for(let e of t.slice(0,3))try{let n=new AbortController,r=setTimeout(()=>n.abort(),1500);try{return await fetch(e,{signal:n.signal,redirect:"manual"}),{url:e,ok:!0}}finally{clearTimeout(r)}}catch(n){let r=n instanceof Error?n.message:String(n);if(/abort|timeout/i.test(r)||/ECONNREFUSED|fetch failed|ENOTFOUND/i.test(r))continue}}async function Mu(t){let e=W.join(t.rootDir,E,"run");await Pr(e,{recursive:!0});let n=`bg-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,r=W.join(E,"run",`${n}.log`),o=W.join(E,"run",`${n}.json`),s=W.join(t.rootDir,r),i=W.join(t.rootDir,o),a=await gu(s,"a"),c;try{c=ri(t.command,t.args,{cwd:t.cwd,env:t.env,detached:!0,stdio:["ignore",a.fd,a.fd]})}finally{await a.close()}if(c.pid==null)return{ok:!1,output:"Failed to start background process (no pid)."};let l=c.pid;c.unref();let u={id:n,pid:l,command:t.originalCommand,cwd:t.cwd,log:r,backend:t.backend,startedAt:new Date().toISOString()};await Er(i,`${JSON.stringify(u,null,2)}
174
+ `,"utf8");let m=null;c.once("exit",_=>{m=_});let d=t.readyPattern?new RegExp(t.readyPattern,"i"):bu,p=await Ru({logPath:s,pid:l,pattern:d,waitMs:t.waitMs,signal:t.signal}),y=Mr(await Ar(s),t.env),S=Cu(y),x=p.ready?await ni(S):void 0;!p.ready&&!p.failed&&!p.exitedEarly&&S.length>0&&(x=await ni(S));let k=(()=>{try{return process.kill(l,0),m===null}catch{return!1}})(),R=!!(k&&(p.ready||x?.ok)&&!p.failed&&m===null),P=()=>{try{process.kill(-l,"SIGTERM")}catch{try{process.kill(l,"SIGTERM")}catch{}}};return p.exitedEarly||m!==null||!k?{ok:!1,output:[`Background process is NOT running (pid=${l}, id=${n}). Do not tell the user the server is up.`,`command: ${t.originalCommand}`,`log: ${r}`,`meta: ${o}`,`sandbox: ${t.backend}`,y?`--- log ---
175
+ ${Rt(y)}`:"[empty log]"].join(`
176
+ `),metadata:{background:!0,pid:l,id:n,log:r,ready:!1}}:p.failed||!R?(P(),{ok:!1,output:[`Background process started (pid=${l}) but is NOT ready. Do not tell the user the server is up.`,`command: ${t.originalCommand}`,p.failed?"ready: no (failure detected in log \u2014 install/build/runtime error)":`ready: no (no server startup line after ${t.waitMs}ms; http probe ${x?.ok?"ok":"failed/skipped"})`,`log: ${r}`,`meta: ${o}`,`sandbox: ${t.backend}`,"Process was stopped. Fix the error in the log (e.g. pnpm approve-builds / install), then retry.",y?`--- log (tail) ---
177
+ ${Rt(y)}`:"[empty log so far]"].join(`
178
+ `),metadata:{background:!0,pid:l,id:n,log:r,ready:!1,failed:p.failed}}):{ok:!0,output:[`Started background process pid=${l} id=${n}`,`command: ${t.originalCommand}`,p.ready?"ready: yes (matched startup pattern in log)":`ready: yes (HTTP probe succeeded at ${x?.url})`,x?.url?`url: ${x.url}`:S[0]?`url: ${S[0]} (from log)`:void 0,`log: ${r}`,`meta: ${o}`,`sandbox: ${t.backend}`,"Process keeps running after this tool returns.",y?`--- log (tail) ---
179
+ ${Rt(y)}`:"[empty log so far]"].filter(Boolean).join(`
180
+ `),metadata:{background:!0,pid:l,id:n,log:r,ready:!0,url:x?.url??S[0]}}}function $u(t){let e=t.replace(/\s+/g,"");if(!e)throw new Error("content_b64 is empty.");if(e==="QWxhZGRpbjpvcGVuIHNlc2FtZQ==")throw new Error("content_b64 is a placeholder example, not your file bytes. For .env and plain text, call write_file with content (raw string), not content_b64.");if(!/^[A-Za-z0-9+/]+={0,2}$/.test(e)||e.length%4!==0)throw new Error("content_b64 is not valid base64. For .env/config/markdown use write_file with content instead.");let n=Buffer.from(e,"base64"),r=n.toString("base64").replace(/=+$/,""),o=e.replace(/=+$/,"");if(r!==o)throw new Error("content_b64 failed base64 round-trip. For .env/config/markdown use write_file with content instead.");let s=n.toString("utf8");if(s.includes("\uFFFD"))throw new Error("content_b64 does not decode to valid UTF-8 text.");return s}var be=class{rootDir;guard;sandbox;browserEnabled;browserClosed=!1;constructor(e,n={}){this.rootDir=W.resolve(e),this.guard=new $r(this.rootDir),this.sandbox=new pn(this.rootDir,n.sandbox);let r=n.browser??"auto";this.browserEnabled=r==="on"?!0:r==="off"?!1:Pt()!==void 0}definitions(){return this.browserEnabled?[...ei,...xu]:ei}async execute(e,n,r){if(W.resolve(r.rootDir)!==this.rootDir)throw new Error("Tool runtime root does not match the agent root.");try{switch(e){case"workspace_summary":return await this.workspaceSummary();case"list_files":return await this.listFiles(n);case"read_file":return await this.readFile(n);case"search_text":return await this.searchText(n);case"write_file":return await this.writeFile(n);case"replace_in_file":return await this.replaceInFile(n);case"make_directory":return await this.makeDirectory(n);case"delete_path":return await this.deletePath(n);case"shell":return await this.shell(n,r.signal,r.onOutput);case"git_status":return await this.gitStatus(r.signal);case"git_diff":return await this.gitDiff(n,r.signal);case"web_search":return await this.webSearch(n,r.signal);case"web_fetch":return await this.webFetch(n,r.signal);case"browser_open":return await this.browserOpen(n);case"browser_screenshot":return await this.browserScreenshot(n);case"browser_click":return await this.browserClick(n);case"browser_type":return await this.browserType(n);case"browser_evaluate":return await this.browserEvaluate(n);case"browser_close":return await this.browserClose();default:return{ok:!1,output:`Unknown tool: ${e}`}}}catch(o){return{ok:!1,output:o instanceof Error?o.message:String(o)}}}async workspaceSummary(){let e=await _r(this.rootDir,this.rootDir,1,80),n=["package.json","pnpm-workspace.yaml","pyproject.toml","Cargo.toml","go.mod","composer.json","Gemfile","pom.xml","build.gradle"],r=[];for(let u of n)await ti(W.join(this.rootDir,u))&&r.push(u);let o=await this.gitStatus(),s=(o.output||"").split(/\r?\n/),i=40,a=s.length<=i?o.output:`${s.slice(0,i).join(`
169
181
  `)}
170
182
  \u2026[${s.length-i} more git status lines omitted]`,c=[`root: ${this.rootDir}`,`manifests: ${r.length?r.join(", "):"none detected"}`,"top_level:",...e,"git_status:",a].join(`
171
183
  `),l=3e3;return{ok:!0,output:c.length<=l?c:`${c.slice(0,l)}
172
- \u2026[workspace_summary truncated ${c.length-l} chars for hub context]`}}async listFiles(e){let n=X(e,"path")??".",r=te(e,"max_depth",3,0,8),o=te(e,"max_entries",500,1,2e3),s=await this.guard.resolve(n,{mustExist:!0});if(!(await De(s)).isDirectory())throw new Error(`${n} is not a directory.`);return{ok:!0,output:(await Pr(s,this.rootDir,r,o)).join(`
173
- `)||"[empty directory]"}}async readFile(e){let n=U(e,"path"),r=te(e,"start_line",1,1,1e7),o=te(e,"end_line",r+119,r,1e7),s=await this.guard.resolve(n,{mustExist:!0}),i=await De(s);if(!i.isFile())throw new Error(`${n} is not a file.`);if(i.size>kr)throw new Error(`File exceeds ${kr} bytes.`);let a=await dn(s,"utf8");if(a.includes("\0"))throw new Error("Binary files are not supported by read_file.");let c=a.split(/\r?\n/);return{ok:!0,output:c.slice(r-1,o).map((m,d)=>`${String(r+d).padStart(6," ")} | ${m}`).join(`
174
- `),metadata:{total_lines:c.length,start_line:r,end_line:Math.min(o,c.length)}}}async searchText(e){let n=U(e,"query",{maximumLength:2e3}),r=X(e,"path")??".",o=Me(e,"regex",!1),s=te(e,"max_results",100,1,500),i=await this.guard.resolve(r,{mustExist:!0}),a=["--line-number","--no-heading","--color","never","--hidden","--glob","!/.git/**","--glob","!/node_modules/**","--glob","!/dist/**"];o||a.push("--fixed-strings"),a.push("--max-count",String(s),"--",n,i);try{let l=await un("rg",a,{cwd:this.rootDir,timeoutMs:15e3});if(l.code===0||l.code===1)return{ok:!0,output:l.stdout.split(/\r?\n/).filter(Boolean).slice(0,s).map(m=>m.replace(`${this.rootDir}${K.sep}`,"")).join(`
175
- `)||"[no matches]"}}catch{}return{ok:!0,output:(await au(i,this.rootDir,n,o,s)).join(`
176
- `)||"[no matches]"}}async writeFile(e){let n=U(e,"path"),r=X(e,"content_b64"),o;if(r!==void 0){if(o=fu(r),o.length===0)throw new Error("content_b64 decoded to an empty file. For .env use write_file with content.")}else if(Object.prototype.hasOwnProperty.call(e,"content"))o=U(e,"content",{allowEmpty:!0});else throw new Error("write_file requires content or content_b64.");let s=Me(e,"overwrite",!0),i=await this.guard.resolve(n);if(!s&&await Bs(i))throw new Error(`${n} already exists.`);await br(K.dirname(i),{recursive:!0}),await vr(i,o,"utf8");let a=/\.(env|md|txt|json|ya?ml|toml|ini)$/i.test(n)||n===".env"?" File written successfully \u2014 do not rewrite with content_b64; use read_file only if you need to verify.":" File written successfully \u2014 do not repeat write_file for this path unless the content must change.";return{ok:!0,output:`Wrote ${o.length} characters to ${n}.${a}`}}async replaceInFile(e){let n=U(e,"path"),r=U(e,"old_string",{allowEmpty:!1}),o=U(e,"new_string",{allowEmpty:!0}),s=te(e,"expected_occurrences",1,1,1e3),i=await this.guard.resolve(n,{mustExist:!0}),a=await dn(i,"utf8"),c=a.split(r).length-1;if(c!==s)throw new Error(`Expected ${s} occurrence(s), found ${c}; file was not changed.`);let l=a.split(r).join(o);return await vr(i,l,"utf8"),{ok:!0,output:`Replaced ${c} occurrence(s) in ${n}.`}}async makeDirectory(e){let n=U(e,"path"),r=await this.guard.resolve(n);return await br(r,{recursive:!0}),{ok:!0,output:`Created directory ${n}.`}}async deletePath(e){let n=U(e,"path");if(n==="."||n==="")throw new Error("Deleting the project root is forbidden.");let r=Me(e,"recursive",!1),o=await this.guard.resolve(n,{mustExist:!0});if((await De(o)).isDirectory()&&!r)throw new Error("Directory deletion requires recursive=true.");return await tu(o,{recursive:r,force:!1}),{ok:!0,output:`Deleted ${n}.`}}async shell(e,n,r){let o=U(e,"command",{maximumLength:2e4}),s=X(e,"cwd")??".",i=te(e,"timeout_ms",3e4,100,36e5),a=e.background===void 0?lu(o):Me(e,"background",!1),c=te(e,"wait_ms",45e3,500,36e5),l=X(e,"ready_pattern");if(l)try{new RegExp(l,"i")}catch{throw new Error(`Invalid ready_pattern regex: ${l}`)}let u=await this.guard.resolve(s,{mustExist:!0});if(!(await De(u)).isDirectory())throw new Error(`${s} is not a directory.`);let d=await this.sandbox.prepareShell(o,u,i);if(a)return await pu({command:d.command,args:d.args,cwd:d.cwd,env:d.env,rootDir:this.rootDir,originalCommand:o,backend:d.backend,readyPattern:l,waitMs:c,signal:n});let f=await un(d.command,d.args,{cwd:d.cwd,timeoutMs:d.timeoutMs,env:d.env,signal:n,...r?{onOutput:r}:{}});return{ok:f.code===0&&!f.timedOut&&!f.cancelled,output:`${cu(f)}
177
- sandbox: ${d.backend}`,metadata:{sandbox:d.backend}}}async gitStatus(e){try{let n=await un("git",["status","--short","--branch"],{cwd:this.rootDir,timeoutMs:1e4,signal:e});return{ok:n.code===0,output:n.stdout||n.stderr||"[clean working tree]"}}catch(n){return{ok:!1,output:n instanceof Error?n.message:String(n)}}}async gitDiff(e,n){let r=Me(e,"staged",!1),o=X(e,"path"),s=["diff"];r&&s.push("--cached"),o&&(await this.guard.resolve(o),s.push("--",o));let i=await un("git",s,{cwd:this.rootDir,timeoutMs:15e3,signal:n});return{ok:i.code===0,output:i.stdout||i.stderr||"[no diff]"}}async webSearch(e,n){let r=U(e,"query",{maximumLength:500}),o=te(e,"count",5,1,10),s=X(e,"provider"),i=await Cs({query:r,count:o,provider:s,signal:n});return{ok:!0,output:JSON.stringify(i,null,2),metadata:{provider:i.provider,resultCount:i.count,...i.fallbackReason?{fallbackReason:i.fallbackReason}:{}}}}async webFetch(e,n){let r=U(e,"url",{maximumLength:2e3}),o=te(e,"max_chars",5e4,1,2e5),s=await Ms({url:r,maxChars:o,signal:n});return{ok:!0,output:`${[`url: ${s.url}`,`final_url: ${s.finalUrl}`,`status: ${s.status}`,s.contentType?`content_type: ${s.contentType}`:void 0,s.truncated?"truncated: true":void 0].filter(Boolean).join(`
184
+ \u2026[workspace_summary truncated ${c.length-l} chars for hub context]`,metadata:{top_level:e.length,manifests:r.length}}}async listFiles(e){let n=X(e,"path")??".",r=ne(e,"max_depth",3,0,8),o=ne(e,"max_entries",500,1,2e3),s=await this.guard.resolve(n,{mustExist:!0});if(!(await De(s)).isDirectory())throw new Error(`${n} is not a directory.`);let a=await _r(s,this.rootDir,r,o);return{ok:!0,output:a.join(`
185
+ `)||"[empty directory]",metadata:{entries:a.length}}}async readFile(e){let n=F(e,"path"),r=ne(e,"start_line",1,1,1e7),o=ne(e,"end_line",r+119,r,1e7),s=await this.guard.resolve(n,{mustExist:!0}),i=await De(s);if(!i.isFile())throw new Error(`${n} is not a file.`);if(i.size>Rr)throw new Error(`File exceeds ${Rr} bytes.`);let a=await gn(s,"utf8");if(a.includes("\0"))throw new Error("Binary files are not supported by read_file.");let c=a.split(/\r?\n/);return{ok:!0,output:c.slice(r-1,o).map((m,d)=>`${String(r+d).padStart(6," ")} | ${m}`).join(`
186
+ `),metadata:{total_lines:c.length,start_line:r,end_line:Math.min(o,c.length)}}}async searchText(e){let n=F(e,"query",{maximumLength:2e3}),r=X(e,"path")??".",o=Me(e,"regex",!1),s=ne(e,"max_results",100,1,500),i=await this.guard.resolve(r,{mustExist:!0}),a=["--line-number","--no-heading","--color","never","--hidden","--glob","!/.git/**","--glob","!/node_modules/**","--glob","!/dist/**"];o||a.push("--fixed-strings"),a.push("--max-count",String(s),"--",n,i);try{let l=await fn("rg",a,{cwd:this.rootDir,timeoutMs:15e3});if(l.code===0||l.code===1){let u=l.stdout.split(/\r?\n/).filter(Boolean).slice(0,s).map(m=>m.replace(`${this.rootDir}${W.sep}`,""));return{ok:!0,output:u.join(`
187
+ `)||"[no matches]",metadata:{matches:u.length}}}}catch{}let c=await Su(i,this.rootDir,n,o,s);return{ok:!0,output:c.join(`
188
+ `)||"[no matches]",metadata:{matches:c.length}}}async writeFile(e){let n=F(e,"path"),r=X(e,"content_b64"),o;if(r!==void 0){if(o=$u(r),o.length===0)throw new Error("content_b64 decoded to an empty file. For .env use write_file with content.")}else if(Object.prototype.hasOwnProperty.call(e,"content"))o=F(e,"content",{allowEmpty:!0});else throw new Error("write_file requires content or content_b64.");let s=Me(e,"overwrite",!0),i=await this.guard.resolve(n);if(!s&&await ti(i))throw new Error(`${n} already exists.`);await Pr(W.dirname(i),{recursive:!0}),await Er(i,o,"utf8");let a=/\.(env|md|txt|json|ya?ml|toml|ini)$/i.test(n)||n===".env"?" File written successfully \u2014 do not rewrite with content_b64; use read_file only if you need to verify.":" File written successfully \u2014 do not repeat write_file for this path unless the content must change.";return{ok:!0,output:`Wrote ${o.length} characters to ${n}.${a}`}}async replaceInFile(e){let n=F(e,"path"),r=F(e,"old_string",{allowEmpty:!1}),o=F(e,"new_string",{allowEmpty:!0}),s=ne(e,"expected_occurrences",1,1,1e3),i=await this.guard.resolve(n,{mustExist:!0}),a=await gn(i,"utf8"),c=a.split(r).length-1;if(c!==s)throw new Error(`Expected ${s} occurrence(s), found ${c}; file was not changed.`);let l=a.split(r).join(o);return await Er(i,l,"utf8"),{ok:!0,output:`Replaced ${c} occurrence(s) in ${n}.`}}async makeDirectory(e){let n=F(e,"path"),r=await this.guard.resolve(n);return await Pr(r,{recursive:!0}),{ok:!0,output:`Created directory ${n}.`}}async deletePath(e){let n=F(e,"path");if(n==="."||n==="")throw new Error("Deleting the project root is forbidden.");let r=Me(e,"recursive",!1),o=await this.guard.resolve(n,{mustExist:!0});if((await De(o)).isDirectory()&&!r)throw new Error("Directory deletion requires recursive=true.");return await wu(o,{recursive:r,force:!1}),{ok:!0,output:`Deleted ${n}.`}}async shell(e,n,r){let o=F(e,"command",{maximumLength:2e4}),s=X(e,"cwd")??".",i=ne(e,"timeout_ms",3e4,100,36e5),a=e.background===void 0?Pu(o):Me(e,"background",!1),c=ne(e,"wait_ms",45e3,500,36e5),l=X(e,"ready_pattern");if(l)try{new RegExp(l,"i")}catch{throw new Error(`Invalid ready_pattern regex: ${l}`)}let u=await this.guard.resolve(s,{mustExist:!0});if(!(await De(u)).isDirectory())throw new Error(`${s} is not a directory.`);let d=await this.sandbox.prepareShell(o,u,i);if(a)return await Mu({command:d.command,args:d.args,cwd:d.cwd,env:d.env,rootDir:this.rootDir,originalCommand:o,backend:d.backend,readyPattern:l,waitMs:c,signal:n});let p=await fn(d.command,d.args,{cwd:d.cwd,timeoutMs:d.timeoutMs,env:d.env,signal:n,...r?{onOutput:r}:{}});return{ok:p.code===0&&!p.timedOut&&!p.cancelled,output:`${Tu(p)}
189
+ sandbox: ${d.backend}`,metadata:{sandbox:d.backend}}}async gitStatus(e){try{let n=await fn("git",["status","--short","--branch"],{cwd:this.rootDir,timeoutMs:1e4,signal:e});return{ok:n.code===0,output:n.stdout||n.stderr||"[clean working tree]"}}catch(n){return{ok:!1,output:n instanceof Error?n.message:String(n)}}}async gitDiff(e,n){let r=Me(e,"staged",!1),o=X(e,"path"),s=["diff"];r&&s.push("--cached"),o&&(await this.guard.resolve(o),s.push("--",o));let i=await fn("git",s,{cwd:this.rootDir,timeoutMs:15e3,signal:n});return{ok:i.code===0,output:i.stdout||i.stderr||"[no diff]"}}async webSearch(e,n){let r=F(e,"query",{maximumLength:500}),o=ne(e,"count",5,1,10),s=X(e,"provider"),i=await Bs({query:r,count:o,provider:s,signal:n});return{ok:!0,output:JSON.stringify(i,null,2),metadata:{provider:i.provider,resultCount:i.count,...i.fallbackReason?{fallbackReason:i.fallbackReason}:{}}}}async webFetch(e,n){let r=F(e,"url",{maximumLength:2e3}),o=ne(e,"max_chars",5e4,1,2e5),s=await Js({url:r,maxChars:o,signal:n});return{ok:!0,output:`${[`url: ${s.url}`,`final_url: ${s.finalUrl}`,`status: ${s.status}`,s.contentType?`content_type: ${s.contentType}`:void 0,s.truncated?"truncated: true":void 0].filter(Boolean).join(`
178
190
  `)}
179
191
 
180
- ${s.text}`,metadata:{status:s.status,finalUrl:s.finalUrl,truncated:s.truncated}}}browserToolsAvailable(){return this.browserEnabled}async browserOpen(e){if(!this.browserToolsAvailable())return this.browserUnavailable();let n=U(e,"url",{maximumLength:2e3}),r=X(e,"wait_until"),o=te(e,"wait_ms",15e3,1e3,6e4),s=te(e,"max_chars",5e4,1,2e5),i=await hr({url:n,waitUntil:r,waitMs:o,maxChars:s});return{ok:!0,output:`${[`mode: ${i.mode}`,`url: ${i.url}`,i.title?`title: ${i.title}`:void 0,i.truncated?"truncated: true":void 0].filter(Boolean).join(`
192
+ ${s.text}`,metadata:{status:s.status,finalUrl:s.finalUrl,truncated:s.truncated}}}browserToolsAvailable(){return this.browserEnabled}async browserOpen(e){if(!this.browserToolsAvailable())return this.browserUnavailable();let n=F(e,"url",{maximumLength:2e3}),r=X(e,"wait_until"),o=ne(e,"wait_ms",15e3,1e3,6e4),s=ne(e,"max_chars",5e4,1,2e5),i=await xr({url:n,waitUntil:r,waitMs:o,maxChars:s});return{ok:!0,output:`${[`mode: ${i.mode}`,`url: ${i.url}`,i.title?`title: ${i.title}`:void 0,i.truncated?"truncated: true":void 0].filter(Boolean).join(`
181
193
  `)}
182
194
 
183
- ${i.text}`,metadata:{mode:i.mode,url:i.url,truncated:i.truncated}}}async browserScreenshot(e){if(!this.browserToolsAvailable())return this.browserUnavailable();let n=X(e,"url"),r=Me(e,"full_page",!1),o=await Ds({url:n,fullPage:r,rootDir:this.rootDir});return{ok:!0,output:`Screenshot saved to ${o.path}`,metadata:{path:o.path,mode:o.mode}}}async browserClick(e){if(!this.browserToolsAvailable())return this.browserUnavailable();let n=U(e,"selector",{maximumLength:2e3});return{ok:!0,output:await js(n)}}async browserType(e){if(!this.browserToolsAvailable())return this.browserUnavailable();let n=U(e,"selector",{maximumLength:2e3}),r=U(e,"text",{maximumLength:2e4});return{ok:!0,output:await Ls(n,r)}}async browserEvaluate(e){if(!this.browserToolsAvailable())return this.browserUnavailable();let n=U(e,"expression",{maximumLength:1e4});return{ok:!0,output:await Us(n)}}async browserClose(){return await Is(),this.browserClosed=!0,{ok:!0,output:"Browser session closed."}}browserUnavailable(){return{ok:!1,output:"Browser tools are disabled (no Chromium detected, or tools.browser is off). "+xt}}};var Gs={explorer:"Map the relevant code paths, dependencies, and architecture. Do not edit files. Return exact file references and concise findings.",reviewer:"Review for correctness, regressions, maintainability, and missing validation. Do not edit files. Report findings by severity.",tester:"Identify the relevant tests, likely failure modes, and the smallest useful validation plan. You may run read-only discovery commands but must not edit files.",security:"Inspect trust boundaries, input validation, secret handling, command execution, and authorization. Do not edit files. Report exploitable risks first."};function Ks(t,e){let n=t[e];if(!(n==null||n==="")){if(typeof n!="string"||!n.trim())throw new Error(`"${e}" must be a non-empty string when provided.`);return n.trim()}}function gu(){return{type:"function",function:{name:"delegate_subagents",description:["Run up to four read-only specialist coding subagents in parallel, then return their independent findings.","Optionally set route and/or model on each task so that specialist can use a different capability tier than the primary agent.",`Supported routes: ${_e.join(", ")}.`,"Omit route and model to reuse the primary model."].join(" "),parameters:{type:"object",properties:{tasks:{type:"array",minItems:1,maxItems:4,items:{type:"object",properties:{role:{type:"string",enum:["explorer","reviewer","tester","security"]},task:{type:"string"},route:{type:"string",enum:[..._e],description:"Optional capability tier for this subagent (fast, balanced, complex, \u2026)."},model:{type:"string",description:"Optional explicit preferred model id for this subagent."}},required:["role","task"],additionalProperties:!1}}},required:["tasks"],additionalProperties:!1}}}}function hu(t,e){let n=t.tasks;if(!Array.isArray(n)||n.length===0)throw new Error('"tasks" must be a non-empty array.');if(n.length>e)throw new Error(`At most ${e} subagents may run at once.`);return n.map((r,o)=>{if(!r||typeof r!="object"||Array.isArray(r))throw new Error(`tasks[${o}] must be an object.`);let s=r,i=U(s,"role");if(!(i in Gs))throw new Error(`Unsupported subagent role: ${i}`);let a=Ks(s,"route");if(a&&!wt(a))throw new Error(`tasks[${o}].route must be one of ${_e.join(", ")}.`);let c=Ks(s,"model");return{role:i,task:U(s,"task",{maximumLength:1e4}),...a?{route:a}:{},...c?{model:c}:{}}})}var wu=12,Ws=4e3,mn=class{options;constructor(e){if(this.options={...e,maxParallel:e.maxParallel??4},this.options.maxParallel<1||this.options.maxParallel>4)throw new Error("maxParallel must be between 1 and 4.")}definitions(){return[gu()]}async gatewayFor(e){let n={...e.route?{route:e.route}:{},...e.model?{model:e.model}:{}};if(!n.route&&!n.model)return{gateway:this.options.gateway,selection:n};if(!this.options.resolveGateway)throw new Error("This session cannot resolve per-task subagent routes/models. Omit route and model, or use a provider that supports resolution.");return{gateway:await this.options.resolveGateway(n),selection:n}}async execute(e,n,r){if(e!=="delegate_subagents")return{ok:!1,output:`Unknown subagent tool: ${e}`};if(r.signal?.aborted)return{ok:!1,output:"Subagent delegation cancelled."};let o=hu(n,this.options.maxParallel),s=await Promise.all(o.map(async i=>{let a=new ye(this.options.rootDir,this.options.localRuntimeOptions),c=new Ke({...ce,filesystem:{read:"allow",write:"deny",delete:"deny"},shell:{readOnly:"allow",mutating:"deny",destructive:"deny"},git:{read:"allow",write:"deny"},network:{search:"deny",fetch:"deny"}});try{let{gateway:l,selection:u}=await this.gatewayFor(i),d=await new Fe({gateway:l,runtime:a,permissions:c}).run({prompt:`${Gs[i.role]}
195
+ ${i.text}`,metadata:{mode:i.mode,url:i.url,truncated:i.truncated}}}async browserScreenshot(e){if(!this.browserToolsAvailable())return this.browserUnavailable();let n=X(e,"url"),r=Me(e,"full_page",!1),o=await Vs({url:n,fullPage:r,rootDir:this.rootDir});return{ok:!0,output:`Screenshot saved to ${o.path}`,metadata:{path:o.path,mode:o.mode}}}async browserClick(e){if(!this.browserToolsAvailable())return this.browserUnavailable();let n=F(e,"selector",{maximumLength:2e3});return{ok:!0,output:await Ys(n)}}async browserType(e){if(!this.browserToolsAvailable())return this.browserUnavailable();let n=F(e,"selector",{maximumLength:2e3}),r=F(e,"text",{maximumLength:2e4});return{ok:!0,output:await Qs(n,r)}}async browserEvaluate(e){if(!this.browserToolsAvailable())return this.browserUnavailable();let n=F(e,"expression",{maximumLength:1e4});return{ok:!0,output:await Xs(n)}}async browserClose(){return await zs(),this.browserClosed=!0,{ok:!0,output:"Browser session closed."}}browserUnavailable(){return{ok:!1,output:"Browser tools are disabled (no Chromium detected, or tools.browser is off). "+Tt}}};var ii={explorer:"Map the relevant code paths, dependencies, and architecture. Do not edit files. Return exact file references and concise findings.",reviewer:"Review for correctness, regressions, maintainability, and missing validation. Do not edit files. Report findings by severity.",tester:"Identify the relevant tests, likely failure modes, and the smallest useful validation plan. You may run read-only discovery commands but must not edit files.",security:"Inspect trust boundaries, input validation, secret handling, command execution, and authorization. Do not edit files. Report exploitable risks first."};function oi(t,e){let n=t[e];if(!(n==null||n==="")){if(typeof n!="string"||!n.trim())throw new Error(`"${e}" must be a non-empty string when provided.`);return n.trim()}}function _u(){return{type:"function",function:{name:"delegate_subagents",description:["Run up to four read-only specialist coding subagents in parallel, then return their independent findings.","Optionally set route and/or model on each task so that specialist can use a different capability tier than the primary agent.",`Supported routes: ${_e.join(", ")}.`,"Omit route and model to reuse the primary model."].join(" "),parameters:{type:"object",properties:{tasks:{type:"array",minItems:1,maxItems:4,items:{type:"object",properties:{role:{type:"string",enum:["explorer","reviewer","tester","security"]},task:{type:"string"},route:{type:"string",enum:[..._e],description:"Optional capability tier for this subagent (fast, balanced, complex, \u2026)."},model:{type:"string",description:"Optional explicit preferred model id for this subagent."}},required:["role","task"],additionalProperties:!1}}},required:["tasks"],additionalProperties:!1}}}}function Au(t,e){let n=t.tasks;if(!Array.isArray(n)||n.length===0)throw new Error('"tasks" must be a non-empty array.');if(n.length>e)throw new Error(`At most ${e} subagents may run at once.`);return n.map((r,o)=>{if(!r||typeof r!="object"||Array.isArray(r))throw new Error(`tasks[${o}] must be an object.`);let s=r,i=F(s,"role");if(!(i in ii))throw new Error(`Unsupported subagent role: ${i}`);let a=oi(s,"route");if(a&&!bt(a))throw new Error(`tasks[${o}].route must be one of ${_e.join(", ")}.`);let c=oi(s,"model");return{role:i,task:F(s,"task",{maximumLength:1e4}),...a?{route:a}:{},...c?{model:c}:{}}})}var Ou=12,si=4e3,hn=class{options;constructor(e){if(this.options={...e,maxParallel:e.maxParallel??4},this.options.maxParallel<1||this.options.maxParallel>4)throw new Error("maxParallel must be between 1 and 4.")}definitions(){return[_u()]}async gatewayFor(e){let n={...e.route?{route:e.route}:{},...e.model?{model:e.model}:{}};if(!n.route&&!n.model)return{gateway:this.options.gateway,selection:n};if(!this.options.resolveGateway)throw new Error("This session cannot resolve per-task subagent routes/models. Omit route and model, or use a provider that supports resolution.");return{gateway:await this.options.resolveGateway(n),selection:n}}async execute(e,n,r){if(e!=="delegate_subagents")return{ok:!1,output:`Unknown subagent tool: ${e}`};if(r.signal?.aborted)return{ok:!1,output:"Subagent delegation cancelled."};let o=Au(n,this.options.maxParallel),s=await Promise.all(o.map(async i=>{let a=new be(this.options.rootDir,this.options.localRuntimeOptions),c=new Ke({...le,filesystem:{read:"allow",write:"deny",delete:"deny"},shell:{readOnly:"allow",mutating:"deny",destructive:"deny"},git:{read:"allow",write:"deny"},network:{search:"deny",fetch:"deny"}});try{let{gateway:l,selection:u}=await this.gatewayFor(i),d=await new Fe({gateway:l,runtime:a,permissions:c}).run({prompt:`${ii[i.role]}
184
196
 
185
197
  Assigned task:
186
- ${i.task}`,mode:"plan",rootDir:this.options.rootDir,maxSteps:this.options.maxSteps??wu,approvalHandler:async()=>!1,signal:r.signal}),f=d.answer.length>Ws?`${d.answer.slice(0,Ws)}
187
- \u2026[subagent answer truncated]`:d.answer;return{role:i.role,task:i.task,ok:!0,answer:f,steps:d.steps,route:u.route,model:u.model}}catch(l){return{role:i.role,task:i.task,ok:!1,answer:l instanceof Error?l.message:String(l),steps:0,route:i.route,model:i.model}}}));return{ok:s.every(i=>i.ok),output:s.map((i,a)=>{let c=[i.route?`route=${i.route}`:void 0,i.model?`model=${i.model}`:void 0].filter(Boolean).join(", ");return[`## Subagent ${a+1}: ${i.role}${c?` (${c})`:""}`,`Task: ${i.task}`,`Status: ${i.ok?"completed":"failed"}`,i.answer].join(`
198
+ ${i.task}`,mode:"plan",rootDir:this.options.rootDir,maxSteps:this.options.maxSteps??Ou,approvalHandler:async()=>!1,signal:r.signal}),p=d.answer.length>si?`${d.answer.slice(0,si)}
199
+ \u2026[subagent answer truncated]`:d.answer;return{role:i.role,task:i.task,ok:!0,answer:p,steps:d.steps,route:u.route,model:u.model}}catch(l){return{role:i.role,task:i.task,ok:!1,answer:l instanceof Error?l.message:String(l),steps:0,route:i.route,model:i.model}}}));return{ok:s.every(i=>i.ok),output:s.map((i,a)=>{let c=[i.route?`route=${i.route}`:void 0,i.model?`model=${i.model}`:void 0].filter(Boolean).join(", ");return[`## Subagent ${a+1}: ${i.role}${c?` (${c})`:""}`,`Task: ${i.task}`,`Status: ${i.ok?"completed":"failed"}`,i.answer].join(`
188
200
  `)}).join(`
189
201
 
190
- `),metadata:{count:s.length,successful:s.filter(i=>i.ok).length,tasks:s.map(i=>({role:i.role,ok:i.ok,...i.route?{route:i.route}:{},...i.model?{model:i.model}:{}}))}}}};import{mkdir as yu,realpath as Et,rm as bu,stat as vu}from"node:fs/promises";import be from"node:path";import{spawn as ku}from"node:child_process";function Rt(t,e){return new Promise((n,r)=>{let o=ku("git",e,{cwd:t,stdio:["ignore","pipe","pipe"]}),s="",i="";o.stdout.setEncoding("utf8"),o.stderr.setEncoding("utf8"),o.stdout.on("data",a=>{s+=a}),o.stderr.on("data",a=>{i+=a}),o.once("error",r),o.once("close",a=>n({code:a??1,stdout:s,stderr:i}))})}function Hs(t){let e=t.trim();if(!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/.test(e))throw new Error("Worktree name must use 1\u201364 letters, numbers, dots, underscores, or hyphens.");return e}async function zs(t){try{return await vu(t),!0}catch{return!1}}var Ct=class{rootDir;storageDir;constructor(e){this.rootDir=be.resolve(e),this.storageDir=be.join(be.dirname(this.rootDir),`.${be.basename(this.rootDir)}-kpilot-worktrees`)}async assertRepository(){let e=await Rt(this.rootDir,["rev-parse","--show-toplevel"]);if(e.code!==0)throw new Error(e.stderr.trim()||"Not a Git repository.");let n=be.resolve(e.stdout.trim()),r=await Et(this.rootDir);if(n!==r)throw new Error(`Use the repository root as --cwd: ${n}`)}pathFor(e){return be.join(this.storageDir,Hs(e))}async create(e,n={}){await this.assertRepository();let r=Hs(e),o=this.pathFor(r);if(await zs(o))throw new Error(`Worktree path already exists: ${o}`);await yu(this.storageDir,{recursive:!0});let s=n.branch?.trim()||`kpilot/${r}`,i=n.base?.trim()||"HEAD",a=await Rt(this.rootDir,["worktree","add","-b",s,o,i]);if(a.code!==0)throw new Error(a.stderr.trim()||a.stdout.trim()||"Unable to create worktree.");let c=await this.list(),l=await Et(o).catch(()=>o),u=c.find(m=>m.path===l||m.path===o);if(!u)throw new Error("Git created the worktree, but it could not be discovered afterward.");return u}async list(){await this.assertRepository();let e=await Rt(this.rootDir,["worktree","list","--porcelain"]);if(e.code!==0)throw new Error(e.stderr.trim()||"Unable to list worktrees.");let n=await Et(this.storageDir).catch(()=>this.storageDir),r=[],o;for(let s of e.stdout.split(/\r?\n/))if(s.startsWith("worktree ")){o&&r.push(o);let i=s.slice(9),a=await Et(i).catch(()=>i),c=be.relative(n,a),l=c!==""&&!c.startsWith("..")&&!be.isAbsolute(c);o={path:a,bare:!1,detached:!1,managed:l,name:l?c.split(be.sep)[0]:void 0}}else{if(!o||!s)continue;s.startsWith("HEAD ")?o.head=s.slice(5):s.startsWith("branch ")?o.branch=s.slice(7).replace(/^refs\/heads\//,""):s==="bare"?o.bare=!0:s==="detached"?o.detached=!0:s.startsWith("locked")?o.locked=s.slice(6).trim()||"locked":s.startsWith("prunable")&&(o.prunable=s.slice(8).trim()||"prunable")}return o&&r.push(o),r}async remove(e,n=!1){await this.assertRepository();let r=this.pathFor(e),o=await Et(r).catch(()=>r);if(!(await this.list()).find(l=>l.managed&&l.path===o))throw new Error(`Managed worktree not found: ${e}`);let a=["worktree","remove"];n&&a.push("--force"),a.push(r);let c=await Rt(this.rootDir,a);if(c.code!==0)throw new Error(c.stderr.trim()||c.stdout.trim()||"Unable to remove worktree.");await zs(r)&&await bu(r,{recursive:!0,force:!0})}async prune(){await this.assertRepository();let e=await Rt(this.rootDir,["worktree","prune"]);if(e.code!==0)throw new Error(e.stderr.trim()||"Unable to prune worktrees.")}};import{appendFile as xu,mkdir as Vs,readFile as Su,rm as Ys,stat as Xs}from"node:fs/promises";import{createHash as Tu,randomUUID as Pu}from"node:crypto";import{hostname as Eu,userInfo as Ru}from"node:os";import pn from"node:path";function Rr(t){if(Array.isArray(t))return`[${t.map(Rr).join(",")}]`;if(t&&typeof t=="object"){let e=t;return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${Rr(e[n])}`).join(",")}}`}return JSON.stringify(t)}function Qs(t){return Tu("sha256").update(Rr(t)).digest("hex")}async function Cu(t){try{return await Xs(t),!0}catch{return!1}}function Mu(){try{return Ru().username||"unknown"}catch{return"unknown"}}var fn=class{rootDir;filePath;lockPath;constructor(e){this.rootDir=pn.resolve(e),this.filePath=pn.join(this.rootDir,E,"audit","audit.jsonl"),this.lockPath=pn.join(this.rootDir,E,"audit",".append-lock")}async parseAll(){if(!await Cu(this.filePath))return[];let e=await Su(this.filePath,"utf8"),n=[];for(let[r,o]of e.split(/\r?\n/).entries()){if(!o.trim())continue;let s;try{s=JSON.parse(o)}catch(i){throw new Error(`Invalid audit JSON at line ${r+1}: ${i instanceof Error?i.message:String(i)}`)}if(!s||typeof s!="object"||Array.isArray(s))throw new Error(`Invalid audit record at line ${r+1}.`);n.push(s)}return n}async acquireLock(e=5e3){await Vs(pn.dirname(this.lockPath),{recursive:!0});let n=Date.now();for(;;)try{return await Vs(this.lockPath),async()=>{await Ys(this.lockPath,{recursive:!0,force:!0})}}catch(r){if(r.code!=="EEXIST")throw r;try{let s=await Xs(this.lockPath);if(Date.now()-s.mtimeMs>3e4){await Ys(this.lockPath,{recursive:!0,force:!0});continue}}catch{continue}if(Date.now()-n>=e)throw new Error("Timed out waiting for the audit append lock.");await new Promise(s=>setTimeout(s,25))}}async append(e){if(!e.action.trim())throw new Error("Audit action cannot be empty.");let n=await this.acquireLock();try{let o=(await this.parseAll()).at(-1)?.hash??"GENESIS",s={schemaVersion:1,id:Pu(),timestamp:new Date().toISOString(),actor:e.actor?.trim()||Mu(),host:Eu(),action:e.action.trim(),outcome:e.outcome,...e.category?{category:e.category}:{},...e.sessionId?{sessionId:e.sessionId}:{},...e.details?{details:e.details}:{},previousHash:o},i={...s,hash:Qs(s)};return await xu(this.filePath,`${JSON.stringify(i)}
191
- `,{encoding:"utf8",mode:384}),i}finally{await n()}}async list(e=50){if(!Number.isInteger(e)||e<1||e>1e3)throw new Error("Audit limit must be between 1 and 1000.");return(await this.parseAll()).slice(-e).reverse()}async verify(){let e;try{e=await this.parseAll()}catch(r){return{valid:!1,records:0,firstInvalidLine:1,reason:r instanceof Error?r.message:String(r),headHash:"GENESIS"}}let n="GENESIS";for(let[r,o]of e.entries()){if(o.schemaVersion!==1)return{valid:!1,records:e.length,firstInvalidLine:r+1,reason:"Unsupported audit schema.",headHash:n};if(o.previousHash!==n)return{valid:!1,records:e.length,firstInvalidLine:r+1,reason:"Previous hash mismatch.",headHash:n};let{hash:s,...i}=o,a=Qs(i);if(s!==a)return{valid:!1,records:e.length,firstInvalidLine:r+1,reason:"Record hash mismatch.",headHash:n};n=s}return{valid:!0,records:e.length,headHash:n}}};import{appendFile as $u,mkdir as _u,readFile as Au,stat as Ou}from"node:fs/promises";import{randomUUID as Iu}from"node:crypto";import Cr from"node:path";async function Du(t){try{return await Ou(t),!0}catch{return!1}}function gn(t,e){if(t!==void 0){if(!Number.isInteger(t)||t<0)throw new Error(`${e} must be a non-negative integer.`);return t}}function ju(t){let e={dailyInputTokens:gn(t.dailyInputTokens,"dailyInputTokens"),dailyOutputTokens:gn(t.dailyOutputTokens,"dailyOutputTokens"),dailyTotalTokens:gn(t.dailyTotalTokens,"dailyTotalTokens"),perRunTotalTokens:gn(t.perRunTotalTokens,"perRunTotalTokens"),dailyEstimatedCostUsd:t.dailyEstimatedCostUsd,warnAtPercent:t.warnAtPercent??80};if(e.dailyEstimatedCostUsd!==void 0&&(!Number.isFinite(e.dailyEstimatedCostUsd)||e.dailyEstimatedCostUsd<0))throw new Error("dailyEstimatedCostUsd must be a non-negative number.");if(!Number.isFinite(e.warnAtPercent)||e.warnAtPercent<1||e.warnAtPercent>100)throw new Error("warnAtPercent must be between 1 and 100.");return e}var hn=class{rootDir;filePath;constructor(e){this.rootDir=Cr.resolve(e),this.filePath=Cr.join(this.rootDir,E,"usage","usage.jsonl")}async records(){return await Du(this.filePath)?(await Au(this.filePath,"utf8")).split(/\r?\n/).filter(Boolean).map((n,r)=>{try{return JSON.parse(n)}catch(o){throw new Error(`Invalid usage JSON at line ${r+1}: ${o instanceof Error?o.message:String(o)}`)}}):[]}async record(e){let n=Math.max(0,Math.trunc(e.inputTokens??0)),r=Math.max(0,Math.trunc(e.outputTokens??0)),o=Math.max(0,Math.trunc(e.cacheReadTokens??0)),s=Math.max(0,Math.trunc(e.cacheWriteTokens??0)),i=e.price?.cacheReadPerMillionUsd??e.price?.inputPerMillionUsd??0,a=e.price?.cacheWritePerMillionUsd??e.price?.inputPerMillionUsd??0,c=n/1e6*(e.price?.inputPerMillionUsd??0)+o/1e6*i+s/1e6*a+r/1e6*(e.price?.outputPerMillionUsd??0),l={schemaVersion:1,id:Iu(),timestamp:new Date().toISOString(),...e.sessionId?{sessionId:e.sessionId}:{},model:e.model,inputTokens:n,outputTokens:r,...o>0?{cacheReadTokens:o}:{},...s>0?{cacheWriteTokens:s}:{},totalTokens:n+r+o+s,estimatedCostUsd:Number(c.toFixed(8))};return await _u(Cr.dirname(this.filePath),{recursive:!0}),await $u(this.filePath,`${JSON.stringify(l)}
192
- `,{encoding:"utf8",mode:384}),l}async summarize(e=new Date().toISOString().slice(0,10)){return(await this.records()).filter(r=>r.timestamp.slice(0,10)===e).reduce((r,o)=>({date:e,inputTokens:r.inputTokens+o.inputTokens,outputTokens:r.outputTokens+o.outputTokens,cacheReadTokens:r.cacheReadTokens+(o.cacheReadTokens??0),cacheWriteTokens:r.cacheWriteTokens+(o.cacheWriteTokens??0),totalTokens:r.totalTokens+o.totalTokens,estimatedCostUsd:Number((r.estimatedCostUsd+o.estimatedCostUsd).toFixed(8)),runs:r.runs+1}),{date:e,inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0,totalTokens:0,estimatedCostUsd:0,runs:0})}async list(e=50){if(!Number.isInteger(e)||e<1||e>1e3)throw new Error("Usage limit must be between 1 and 1000.");return(await this.records()).slice(-e).reverse()}async check(e,n=0){let r=ju(e),o=await this.summarize(),s=[],i=[],a=[["daily input tokens",o.inputTokens,r.dailyInputTokens],["daily output tokens",o.outputTokens,r.dailyOutputTokens],["daily total tokens",o.totalTokens+n,r.dailyTotalTokens],["daily estimated cost",o.estimatedCostUsd,r.dailyEstimatedCostUsd]];for(let[c,l,u]of a)u===void 0||u===0||(l>=u?s.push(`${c} limit reached (${l}/${u}).`):l/u*100>=r.warnAtPercent&&i.push(`${c} is at ${Math.round(l/u*100)}% (${l}/${u}).`));return r.perRunTotalTokens&&n>r.perRunTotalTokens&&s.push(`per-run token limit exceeded (${n}/${r.perRunTotalTokens}).`),{allowed:s.length===0,warnings:i,violations:s,summary:o}}};import{chmod as Lu,mkdir as Uu,readFile as Nu,rename as Fu,rm as Bu,writeFile as qu}from"node:fs/promises";import{homedir as Ju,hostname as Ku}from"node:os";import Mr from"node:path";var Mt=class extends Error{status;code;constructor(e,n,r){super(e),this.name="ControlPlaneError",this.status=n,this.code=r}};function Wu(t){let e=new URL(t);if(e.protocol!=="https:"&&e.hostname!=="localhost"&&e.hostname!=="127.0.0.1")throw new Error("Control-plane URL must use HTTPS outside localhost.");return t.replace(/\/+$/,"")}var le=class{baseUrl;userAgent;constructor(e="https://api.konsolepilot.ai",n="kpilot CLI"){this.baseUrl=Wu(e),this.userAgent=n}async request(e,n={}){let r=await fetch(`${this.baseUrl}${e}`,{method:n.method??(n.body===void 0?"GET":"POST"),headers:{accept:"application/json","content-type":"application/json","user-agent":this.userAgent,...n.accessToken?{authorization:`Bearer ${n.accessToken}`}:{}},...n.body===void 0?{}:{body:JSON.stringify(n.body)},...n.signal?{signal:n.signal}:{}}),o=await r.text(),s={};if(o)try{s=JSON.parse(o)}catch{s={message:o}}if(!r.ok)throw new Mt(s.message??`Control plane returned HTTP ${r.status}.`,r.status,s.code);return s}createDeviceCode(e={}){return this.request("/v1/device/code",{body:{client_name:"kpilot CLI",device_name:e.deviceName??Ku(),platform:e.platform??process.platform},signal:e.signal})}async pollDeviceToken(e,n={}){let r=Date.now(),o=n.expiresInSeconds??600,s=Math.max(1,n.intervalSeconds??5),i=0;for(;(Date.now()-r)/1e3<o;){if(n.signal?.aborted)throw n.signal.reason??new Error("Login cancelled.");i+=1;try{return await this.request("/v1/device/token",{body:{device_code:e},signal:n.signal})}catch(a){if(!(a instanceof Mt))throw a;if(a.code==="authorization_pending")n.onPending?.(i);else if(a.code==="slow_down")s+=2;else throw a}await new Promise((a,c)=>{let l=setTimeout(()=>a(),s*1e3);n.signal?.addEventListener("abort",()=>{clearTimeout(l),c(n.signal?.reason??new Error("Login cancelled."))},{once:!0})})}throw new Error("Device authorization expired. Run `kpilot login` again.")}profile(e){return this.request("/v1/me",{accessToken:e})}refresh(e){return this.request("/v1/auth/refresh",{body:{refresh_token:e}})}logout(e){return this.request("/v1/auth/logout",{body:{refresh_token:e}})}catalog(e){return this.request("/v1/ai/models",{accessToken:e})}ingestUsage(e,n){return this.request("/v1/usage/events",{body:{events:n},accessToken:e})}checkBudget(e,n=0){return this.request("/v1/usage/preflight",{body:{projectedTokens:n},accessToken:e})}},se=class{filePath;constructor(e=Mr.join(Ju(),".config","kpilot","cloud-auth.json")){this.filePath=Mr.resolve(e)}async load(){try{let e=JSON.parse(await Nu(this.filePath,"utf8"));if(!e.accessToken||!e.refreshToken||!e.controlPlaneUrl)throw new Error("Cloud credential file is incomplete.");return e}catch(e){if(e?.code==="ENOENT")return;throw e}}async save(e){await Uu(Mr.dirname(this.filePath),{recursive:!0,mode:448});let n=`${this.filePath}.${process.pid??"tmp"}.tmp`;await qu(n,`${JSON.stringify(e,null,2)}
193
- `,{encoding:"utf8",mode:384}),await Fu(n,this.filePath),await Lu(this.filePath,384)}async clear(){try{await Bu(this.filePath,{force:!0})}catch(e){if(e?.code!=="ENOENT")throw e}}async validAccessToken(e){let n=await this.load();if(!n)return;let r=e??new le(n.controlPlaneUrl);if(new Date(n.expiresAt).getTime()>Date.now()+3e4)return{tokens:n,client:r};try{let o=await r.refresh(n.refreshToken);return await this.save(o),{tokens:o,client:r}}catch(o){throw o instanceof Mt&&o.status>=400&&o.status<500?(await this.clear(),new Error("Your kpilot session has expired or was revoked. Run `kpilot login` to sign in again.")):o}}};import{lstat as Gu,mkdir as Zs,readFile as $r,readdir as Hu,stat as oi,writeFile as ei}from"node:fs/promises";import{createCipheriv as zu,createDecipheriv as Vu,randomBytes as ti,scryptSync as Yu}from"node:crypto";import ee from"node:path";var Qu=[`${E}/instructions.md`,`${E}/memory.json`,`${E}/preferences.json`,`${E}/team-policy.json`,`${E}/skills`];async function wn(t){try{return await oi(t),!0}catch{return!1}}async function _r(t,e,n){let r=ee.join(t,e);if(!await wn(r))return;let o=await Hu(r,{withFileTypes:!0});for(let s of o){let i=ee.posix.join(e.replaceAll("\\","/"),s.name);if(s.isDirectory())await _r(t,i,n);else if(s.isFile()){let a=await $r(ee.join(t,i));n.push({path:i,contentBase64:a.toString("base64")})}}}function Xu(t){let e=t.replaceAll("\\","/");if(e.startsWith(".konsolepilot/")&&(e=`${E}/${e.slice(14)}`),!e.startsWith(`${E}/`)||e.includes("../")||ee.isAbsolute(e))throw new Error(`Unsafe bundle path: ${t}`);return e}async function Zu(t,e){let n=e.split("/").filter(Boolean),r=t;for(let o of n.slice(0,-1)){if(r=ee.join(r,o),!await wn(r))continue;if((await Gu(r)).isSymbolicLink())throw new Error(`Refusing to import through symbolic link: ${ee.relative(t,r)}`)}}function ni(t){return Buffer.from(JSON.stringify({schemaVersion:t.schemaVersion,format:t.format,createdAt:t.createdAt,projectName:t.projectName,includeSessions:t.includeSessions,algorithm:t.encryption.algorithm,kdf:t.encryption.kdf,salt:t.encryption.salt,iv:t.encryption.iv}),"utf8")}function ri(t,e){if(t.length<12)throw new Error("Sync passphrase must contain at least 12 characters.");return Yu(t,e,32,{N:32768,r:8,p:1,maxmem:64*1024*1024})}var yn=class{rootDir;constructor(e){this.rootDir=ee.resolve(e)}async exportBundle(e,n,r=!1){let o=[];for(let w of Qu){let x=ee.join(this.rootDir,w);if(!await wn(x))continue;(await oi(x)).isDirectory()?await _r(this.rootDir,w,o):o.push({path:w,contentBase64:(await $r(x)).toString("base64")})}r&&await _r(this.rootDir,`${E}/sessions`,o),o.sort((w,x)=>w.path.localeCompare(x.path));let s={schemaVersion:1,files:o},i=ti(16),a=ti(12),c=ri(n,i),l={schemaVersion:1,format:"kpilot-encrypted-sync",createdAt:new Date().toISOString(),projectName:ee.basename(this.rootDir),includeSessions:r,encryption:{algorithm:"aes-256-gcm",kdf:"scrypt",salt:i.toString("base64"),iv:a.toString("base64"),tag:""}},u=zu("aes-256-gcm",c,a);u.setAAD(ni(l));let m=Buffer.concat([u.update(JSON.stringify(s),"utf8"),u.final()]),d={...l,encryption:{...l.encryption,tag:u.getAuthTag().toString("base64")},ciphertext:m.toString("base64")},f=ee.resolve(e);return await Zs(ee.dirname(f),{recursive:!0}),await ei(f,`${JSON.stringify(d,null,2)}
194
- `,{encoding:"utf8",mode:384}),d}async inspectBundle(e){let n=await this.readEnvelope(e),{ciphertext:r,...o}=n;return o}async importBundle(e,n,r=!1){let o=await this.readEnvelope(e),s=Buffer.from(o.encryption.salt,"base64"),i=Buffer.from(o.encryption.iv,"base64"),a=Buffer.from(o.encryption.tag,"base64"),c=ri(n,s),l;try{let f=Vu("aes-256-gcm",c,i);f.setAuthTag(a);let{ciphertext:w,...x}=o;f.setAAD(ni(x)),l=Buffer.concat([f.update(Buffer.from(o.ciphertext,"base64")),f.final()])}catch{throw new Error("Unable to decrypt sync bundle. The passphrase is incorrect or the bundle was modified.")}let u;try{u=JSON.parse(l.toString("utf8"))}catch{throw new Error("Decrypted sync bundle payload is invalid JSON.")}if(u.schemaVersion!==1||!Array.isArray(u.files))throw new Error("Unsupported sync payload schema.");let m=[],d=[];for(let f of u.files){let w=Xu(f.path),x=ee.join(this.rootDir,w);if(await Zu(this.rootDir,w),!r&&await wn(x)){d.push(w);continue}await Zs(ee.dirname(x),{recursive:!0}),await ei(x,Buffer.from(f.contentBase64,"base64"),{mode:384}),m.push(w)}return{imported:m,skipped:d}}async readEnvelope(e){let n;try{n=JSON.parse(await $r(ee.resolve(e),"utf8"))}catch(o){throw new Error(`Invalid sync bundle: ${o instanceof Error?o.message:String(o)}`)}if(!n||typeof n!="object"||Array.isArray(n))throw new Error("Sync bundle must be a JSON object.");let r=n;if(r.schemaVersion!==1||r.format!=="kpilot-encrypted-sync")throw new Error("Unsupported sync bundle format.");if(r.encryption?.algorithm!=="aes-256-gcm"||r.encryption?.kdf!=="scrypt")throw new Error("Unsupported sync bundle encryption.");return r}};import{mkdir as si,readFile as ed,stat as td,writeFile as ii}from"node:fs/promises";import bn from"node:path";async function ai(t){try{return await td(t),!0}catch{return!1}}function ci(t){let e=[],n=[];t.schemaVersion!==1&&e.push("schemaVersion must be 1."),t.maximumSteps!==void 0&&(!Number.isInteger(t.maximumSteps)||t.maximumSteps<1||t.maximumSteps>50)&&e.push("maximumSteps must be an integer between 1 and 50."),t.allowedModels&&((!Array.isArray(t.allowedModels)||t.allowedModels.some(o=>typeof o!="string"||!o.trim()))&&e.push("allowedModels must contain non-empty strings."),t.allowedModels.length===0&&n.push("allowedModels is empty; no model can run.")),t.allowedMcpServers?.some(o=>typeof o!="string"||!o.trim())&&e.push("allowedMcpServers must contain non-empty strings.");let r=new Set(["allow","ask","deny"]);for(let[o,s]of Object.entries(t.permissions??{}))for(let[i,a]of Object.entries(s??{}))r.has(a)||e.push(`permissions.${o}.${i} must be allow, ask, or deny.`);return{valid:e.length===0,errors:e,warnings:n}}var je=class{rootDir;filePath;constructor(e){this.rootDir=bn.resolve(e),this.filePath=bn.join(this.rootDir,E,"team-policy.json")}async load(){if(!await ai(this.filePath))return;let e;try{e=JSON.parse(await ed(this.filePath,"utf8"))}catch(o){throw new Error(`Invalid team policy JSON: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Team policy must be a JSON object.");let n=e,r=ci(n);if(!r.valid)throw new Error(`Invalid team policy: ${r.errors.join(" ")}`);return n}async initialize(e,n=[]){if(await ai(this.filePath))throw new Error(`${E}/team-policy.json already exists.`);let r={schemaVersion:1,...e?.trim()?{organization:e.trim()}:{},allowedModels:[...new Set(n.map(o=>o.trim()).filter(Boolean))],allowWriteMode:!0,requireSandbox:!0,requireNetworkIsolation:!0,allowedMcpServers:[],permissions:{}};return await si(bn.dirname(this.filePath),{recursive:!0}),await ii(this.filePath,`${JSON.stringify(r,null,2)}
195
- `,"utf8"),r}async save(e){let n=ci(e);if(!n.valid)throw new Error(`Invalid team policy: ${n.errors.join(" ")}`);await si(bn.dirname(this.filePath),{recursive:!0}),await ii(this.filePath,`${JSON.stringify(e,null,2)}
196
- `,"utf8")}};function ui(t){let e=t.policy;if(e){if(t.mode==="write"&&e.allowWriteMode===!1)throw new Error("Team policy denies WRITE mode.");if(e.allowedModels&&!e.allowedModels.includes(t.model))throw new Error(`Model "${t.model}" is not allowed by team policy.`);if(e.maximumSteps!==void 0&&t.maxSteps!==void 0&&t.maxSteps>e.maximumSteps)throw new Error(`Requested max steps (${t.maxSteps}) exceeds team policy (${e.maximumSteps}).`);if(e.requireSandbox&&t.sandboxMode==="none")throw new Error("Team policy requires a command sandbox.");if(e.requireNetworkIsolation&&t.allowNetwork)throw new Error("Team policy requires sandbox network isolation.")}}var li={allow:0,ask:1,deny:2};function vn(t,e){return e&&li[e]>li[t]?e:t}function di(t,e){return e?{...t,search:vn(t.search,"deny"),fetch:vn(t.fetch,"deny")}:t}import{mkdir as xn,readFile as Ve,readdir as nd,rename as rd,writeFile as Or,chmod as od,unlink as fi,stat as gi}from"node:fs/promises";import H from"node:path";var kn=".kpilot",sd="logbook",id="project.md",ad="learnings.md",cd="meta.json",ld=220,ud=12e3,mi=3,Ar={project:H.join(kn,"understanding.md"),learnings:H.join(kn,"learnings.md"),meta:H.join(kn,"meta.json")},Sn=`Write the project's Logbook entry (.kpilot/logbook/project.md). Keep the tool chain tiny for small-context models (~8k context).
202
+ `),metadata:{count:s.length,successful:s.filter(i=>i.ok).length,tasks:s.map(i=>({role:i.role,ok:i.ok,...i.route?{route:i.route}:{},...i.model?{model:i.model}:{}}))}}}};import{mkdir as Iu,realpath as Ct,rm as Du,stat as ju}from"node:fs/promises";import ve from"node:path";import{spawn as Lu}from"node:child_process";function Mt(t,e){return new Promise((n,r)=>{let o=Lu("git",e,{cwd:t,stdio:["ignore","pipe","pipe"]}),s="",i="";o.stdout.setEncoding("utf8"),o.stderr.setEncoding("utf8"),o.stdout.on("data",a=>{s+=a}),o.stderr.on("data",a=>{i+=a}),o.once("error",r),o.once("close",a=>n({code:a??1,stdout:s,stderr:i}))})}function ai(t){let e=t.trim();if(!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/.test(e))throw new Error("Worktree name must use 1\u201364 letters, numbers, dots, underscores, or hyphens.");return e}async function ci(t){try{return await ju(t),!0}catch{return!1}}var $t=class{rootDir;storageDir;constructor(e){this.rootDir=ve.resolve(e),this.storageDir=ve.join(ve.dirname(this.rootDir),`.${ve.basename(this.rootDir)}-kpilot-worktrees`)}async assertRepository(){let e=await Mt(this.rootDir,["rev-parse","--show-toplevel"]);if(e.code!==0)throw new Error(e.stderr.trim()||"Not a Git repository.");let n=ve.resolve(e.stdout.trim()),r=await Ct(this.rootDir);if(n!==r)throw new Error(`Use the repository root as --cwd: ${n}`)}pathFor(e){return ve.join(this.storageDir,ai(e))}async create(e,n={}){await this.assertRepository();let r=ai(e),o=this.pathFor(r);if(await ci(o))throw new Error(`Worktree path already exists: ${o}`);await Iu(this.storageDir,{recursive:!0});let s=n.branch?.trim()||`kpilot/${r}`,i=n.base?.trim()||"HEAD",a=await Mt(this.rootDir,["worktree","add","-b",s,o,i]);if(a.code!==0)throw new Error(a.stderr.trim()||a.stdout.trim()||"Unable to create worktree.");let c=await this.list(),l=await Ct(o).catch(()=>o),u=c.find(m=>m.path===l||m.path===o);if(!u)throw new Error("Git created the worktree, but it could not be discovered afterward.");return u}async list(){await this.assertRepository();let e=await Mt(this.rootDir,["worktree","list","--porcelain"]);if(e.code!==0)throw new Error(e.stderr.trim()||"Unable to list worktrees.");let n=await Ct(this.storageDir).catch(()=>this.storageDir),r=[],o;for(let s of e.stdout.split(/\r?\n/))if(s.startsWith("worktree ")){o&&r.push(o);let i=s.slice(9),a=await Ct(i).catch(()=>i),c=ve.relative(n,a),l=c!==""&&!c.startsWith("..")&&!ve.isAbsolute(c);o={path:a,bare:!1,detached:!1,managed:l,name:l?c.split(ve.sep)[0]:void 0}}else{if(!o||!s)continue;s.startsWith("HEAD ")?o.head=s.slice(5):s.startsWith("branch ")?o.branch=s.slice(7).replace(/^refs\/heads\//,""):s==="bare"?o.bare=!0:s==="detached"?o.detached=!0:s.startsWith("locked")?o.locked=s.slice(6).trim()||"locked":s.startsWith("prunable")&&(o.prunable=s.slice(8).trim()||"prunable")}return o&&r.push(o),r}async remove(e,n=!1){await this.assertRepository();let r=this.pathFor(e),o=await Ct(r).catch(()=>r);if(!(await this.list()).find(l=>l.managed&&l.path===o))throw new Error(`Managed worktree not found: ${e}`);let a=["worktree","remove"];n&&a.push("--force"),a.push(r);let c=await Mt(this.rootDir,a);if(c.code!==0)throw new Error(c.stderr.trim()||c.stdout.trim()||"Unable to remove worktree.");await ci(r)&&await Du(r,{recursive:!0,force:!0})}async prune(){await this.assertRepository();let e=await Mt(this.rootDir,["worktree","prune"]);if(e.code!==0)throw new Error(e.stderr.trim()||"Unable to prune worktrees.")}};import{appendFile as Uu,mkdir as li,readFile as Nu,rm as ui,stat as mi}from"node:fs/promises";import{createHash as Fu,randomUUID as qu}from"node:crypto";import{hostname as Bu,userInfo as Ju}from"node:os";import wn from"node:path";function Or(t){if(Array.isArray(t))return`[${t.map(Or).join(",")}]`;if(t&&typeof t=="object"){let e=t;return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${Or(e[n])}`).join(",")}}`}return JSON.stringify(t)}function di(t){return Fu("sha256").update(Or(t)).digest("hex")}async function Ku(t){try{return await mi(t),!0}catch{return!1}}function Wu(){try{return Ju().username||"unknown"}catch{return"unknown"}}var yn=class{rootDir;filePath;lockPath;constructor(e){this.rootDir=wn.resolve(e),this.filePath=wn.join(this.rootDir,E,"audit","audit.jsonl"),this.lockPath=wn.join(this.rootDir,E,"audit",".append-lock")}async parseAll(){if(!await Ku(this.filePath))return[];let e=await Nu(this.filePath,"utf8"),n=[];for(let[r,o]of e.split(/\r?\n/).entries()){if(!o.trim())continue;let s;try{s=JSON.parse(o)}catch(i){throw new Error(`Invalid audit JSON at line ${r+1}: ${i instanceof Error?i.message:String(i)}`)}if(!s||typeof s!="object"||Array.isArray(s))throw new Error(`Invalid audit record at line ${r+1}.`);n.push(s)}return n}async acquireLock(e=5e3){await li(wn.dirname(this.lockPath),{recursive:!0});let n=Date.now();for(;;)try{return await li(this.lockPath),async()=>{await ui(this.lockPath,{recursive:!0,force:!0})}}catch(r){if(r.code!=="EEXIST")throw r;try{let s=await mi(this.lockPath);if(Date.now()-s.mtimeMs>3e4){await ui(this.lockPath,{recursive:!0,force:!0});continue}}catch{continue}if(Date.now()-n>=e)throw new Error("Timed out waiting for the audit append lock.");await new Promise(s=>setTimeout(s,25))}}async append(e){if(!e.action.trim())throw new Error("Audit action cannot be empty.");let n=await this.acquireLock();try{let o=(await this.parseAll()).at(-1)?.hash??"GENESIS",s={schemaVersion:1,id:qu(),timestamp:new Date().toISOString(),actor:e.actor?.trim()||Wu(),host:Bu(),action:e.action.trim(),outcome:e.outcome,...e.category?{category:e.category}:{},...e.sessionId?{sessionId:e.sessionId}:{},...e.details?{details:e.details}:{},previousHash:o},i={...s,hash:di(s)};return await Uu(this.filePath,`${JSON.stringify(i)}
203
+ `,{encoding:"utf8",mode:384}),i}finally{await n()}}async list(e=50){if(!Number.isInteger(e)||e<1||e>1e3)throw new Error("Audit limit must be between 1 and 1000.");return(await this.parseAll()).slice(-e).reverse()}async verify(){let e;try{e=await this.parseAll()}catch(r){return{valid:!1,records:0,firstInvalidLine:1,reason:r instanceof Error?r.message:String(r),headHash:"GENESIS"}}let n="GENESIS";for(let[r,o]of e.entries()){if(o.schemaVersion!==1)return{valid:!1,records:e.length,firstInvalidLine:r+1,reason:"Unsupported audit schema.",headHash:n};if(o.previousHash!==n)return{valid:!1,records:e.length,firstInvalidLine:r+1,reason:"Previous hash mismatch.",headHash:n};let{hash:s,...i}=o,a=di(i);if(s!==a)return{valid:!1,records:e.length,firstInvalidLine:r+1,reason:"Record hash mismatch.",headHash:n};n=s}return{valid:!0,records:e.length,headHash:n}}};import{appendFile as Gu,mkdir as Hu,readFile as zu,stat as Vu}from"node:fs/promises";import{randomUUID as Yu}from"node:crypto";import Ir from"node:path";async function Qu(t){try{return await Vu(t),!0}catch{return!1}}function bn(t,e){if(t!==void 0){if(!Number.isInteger(t)||t<0)throw new Error(`${e} must be a non-negative integer.`);return t}}function Xu(t){let e={dailyInputTokens:bn(t.dailyInputTokens,"dailyInputTokens"),dailyOutputTokens:bn(t.dailyOutputTokens,"dailyOutputTokens"),dailyTotalTokens:bn(t.dailyTotalTokens,"dailyTotalTokens"),perRunTotalTokens:bn(t.perRunTotalTokens,"perRunTotalTokens"),dailyEstimatedCostUsd:t.dailyEstimatedCostUsd,warnAtPercent:t.warnAtPercent??80};if(e.dailyEstimatedCostUsd!==void 0&&(!Number.isFinite(e.dailyEstimatedCostUsd)||e.dailyEstimatedCostUsd<0))throw new Error("dailyEstimatedCostUsd must be a non-negative number.");if(!Number.isFinite(e.warnAtPercent)||e.warnAtPercent<1||e.warnAtPercent>100)throw new Error("warnAtPercent must be between 1 and 100.");return e}var vn=class{rootDir;filePath;constructor(e){this.rootDir=Ir.resolve(e),this.filePath=Ir.join(this.rootDir,E,"usage","usage.jsonl")}async records(){return await Qu(this.filePath)?(await zu(this.filePath,"utf8")).split(/\r?\n/).filter(Boolean).map((n,r)=>{try{return JSON.parse(n)}catch(o){throw new Error(`Invalid usage JSON at line ${r+1}: ${o instanceof Error?o.message:String(o)}`)}}):[]}async record(e){let n=Math.max(0,Math.trunc(e.inputTokens??0)),r=Math.max(0,Math.trunc(e.outputTokens??0)),o=Math.max(0,Math.trunc(e.cacheReadTokens??0)),s=Math.max(0,Math.trunc(e.cacheWriteTokens??0)),i=e.price?.cacheReadPerMillionUsd??e.price?.inputPerMillionUsd??0,a=e.price?.cacheWritePerMillionUsd??e.price?.inputPerMillionUsd??0,c=n/1e6*(e.price?.inputPerMillionUsd??0)+o/1e6*i+s/1e6*a+r/1e6*(e.price?.outputPerMillionUsd??0),l={schemaVersion:1,id:Yu(),timestamp:new Date().toISOString(),...e.sessionId?{sessionId:e.sessionId}:{},model:e.model,inputTokens:n,outputTokens:r,...o>0?{cacheReadTokens:o}:{},...s>0?{cacheWriteTokens:s}:{},totalTokens:n+r+o+s,estimatedCostUsd:Number(c.toFixed(8))};return await Hu(Ir.dirname(this.filePath),{recursive:!0}),await Gu(this.filePath,`${JSON.stringify(l)}
204
+ `,{encoding:"utf8",mode:384}),l}async summarize(e=new Date().toISOString().slice(0,10)){return(await this.records()).filter(r=>r.timestamp.slice(0,10)===e).reduce((r,o)=>({date:e,inputTokens:r.inputTokens+o.inputTokens,outputTokens:r.outputTokens+o.outputTokens,cacheReadTokens:r.cacheReadTokens+(o.cacheReadTokens??0),cacheWriteTokens:r.cacheWriteTokens+(o.cacheWriteTokens??0),totalTokens:r.totalTokens+o.totalTokens,estimatedCostUsd:Number((r.estimatedCostUsd+o.estimatedCostUsd).toFixed(8)),runs:r.runs+1}),{date:e,inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0,totalTokens:0,estimatedCostUsd:0,runs:0})}async list(e=50){if(!Number.isInteger(e)||e<1||e>1e3)throw new Error("Usage limit must be between 1 and 1000.");return(await this.records()).slice(-e).reverse()}async check(e,n=0){let r=Xu(e),o=await this.summarize(),s=[],i=[],a=[["daily input tokens",o.inputTokens,r.dailyInputTokens],["daily output tokens",o.outputTokens,r.dailyOutputTokens],["daily total tokens",o.totalTokens+n,r.dailyTotalTokens],["daily estimated cost",o.estimatedCostUsd,r.dailyEstimatedCostUsd]];for(let[c,l,u]of a)u===void 0||u===0||(l>=u?s.push(`${c} limit reached (${l}/${u}).`):l/u*100>=r.warnAtPercent&&i.push(`${c} is at ${Math.round(l/u*100)}% (${l}/${u}).`));return r.perRunTotalTokens&&n>r.perRunTotalTokens&&s.push(`per-run token limit exceeded (${n}/${r.perRunTotalTokens}).`),{allowed:s.length===0,warnings:i,violations:s,summary:o}}};import{chmod as Zu,mkdir as ed,readFile as td,rename as nd,rm as rd,writeFile as od}from"node:fs/promises";import{homedir as sd,hostname as id}from"node:os";import Dr from"node:path";var _t=class extends Error{status;code;constructor(e,n,r){super(e),this.name="ControlPlaneError",this.status=n,this.code=r}};function ad(t){let e=new URL(t);if(e.protocol!=="https:"&&e.hostname!=="localhost"&&e.hostname!=="127.0.0.1")throw new Error("Control-plane URL must use HTTPS outside localhost.");return t.replace(/\/+$/,"")}var ue=class{baseUrl;userAgent;constructor(e="https://api.konsolepilot.ai",n="kpilot CLI"){this.baseUrl=ad(e),this.userAgent=n}async request(e,n={}){let r=await fetch(`${this.baseUrl}${e}`,{method:n.method??(n.body===void 0?"GET":"POST"),headers:{accept:"application/json","content-type":"application/json","user-agent":this.userAgent,...n.accessToken?{authorization:`Bearer ${n.accessToken}`}:{}},...n.body===void 0?{}:{body:JSON.stringify(n.body)},...n.signal?{signal:n.signal}:{}}),o=await r.text(),s={};if(o)try{s=JSON.parse(o)}catch{s={message:o}}if(!r.ok)throw new _t(s.message??`Control plane returned HTTP ${r.status}.`,r.status,s.code);return s}createDeviceCode(e={}){return this.request("/v1/device/code",{body:{client_name:"kpilot CLI",device_name:e.deviceName??id(),platform:e.platform??process.platform},signal:e.signal})}async pollDeviceToken(e,n={}){let r=Date.now(),o=n.expiresInSeconds??600,s=Math.max(1,n.intervalSeconds??5),i=0;for(;(Date.now()-r)/1e3<o;){if(n.signal?.aborted)throw n.signal.reason??new Error("Login cancelled.");i+=1;try{return await this.request("/v1/device/token",{body:{device_code:e},signal:n.signal})}catch(a){if(!(a instanceof _t))throw a;if(a.code==="authorization_pending")n.onPending?.(i);else if(a.code==="slow_down")s+=2;else throw a}await new Promise((a,c)=>{let l=setTimeout(()=>a(),s*1e3);n.signal?.addEventListener("abort",()=>{clearTimeout(l),c(n.signal?.reason??new Error("Login cancelled."))},{once:!0})})}throw new Error("Device authorization expired. Run `kpilot login` again.")}profile(e){return this.request("/v1/me",{accessToken:e})}refresh(e){return this.request("/v1/auth/refresh",{body:{refresh_token:e}})}logout(e){return this.request("/v1/auth/logout",{body:{refresh_token:e}})}catalog(e){return this.request("/v1/ai/models",{accessToken:e})}ingestUsage(e,n){return this.request("/v1/usage/events",{body:{events:n},accessToken:e})}checkBudget(e,n=0){return this.request("/v1/usage/preflight",{body:{projectedTokens:n},accessToken:e})}},ie=class{filePath;constructor(e=Dr.join(sd(),".config","kpilot","cloud-auth.json")){this.filePath=Dr.resolve(e)}async load(){try{let e=JSON.parse(await td(this.filePath,"utf8"));if(!e.accessToken||!e.refreshToken||!e.controlPlaneUrl)throw new Error("Cloud credential file is incomplete.");return e}catch(e){if(e?.code==="ENOENT")return;throw e}}async save(e){await ed(Dr.dirname(this.filePath),{recursive:!0,mode:448});let n=`${this.filePath}.${process.pid??"tmp"}.tmp`;await od(n,`${JSON.stringify(e,null,2)}
205
+ `,{encoding:"utf8",mode:384}),await nd(n,this.filePath),await Zu(this.filePath,384)}async clear(){try{await rd(this.filePath,{force:!0})}catch(e){if(e?.code!=="ENOENT")throw e}}async validAccessToken(e){let n=await this.load();if(!n)return;let r=e??new ue(n.controlPlaneUrl);if(new Date(n.expiresAt).getTime()>Date.now()+3e4)return{tokens:n,client:r};try{let o=await r.refresh(n.refreshToken);return await this.save(o),{tokens:o,client:r}}catch(o){throw o instanceof _t&&o.status>=400&&o.status<500?(await this.clear(),new Error("Your kpilot session has expired or was revoked. Run `kpilot login` to sign in again.")):o}}};import{lstat as cd,mkdir as pi,readFile as jr,readdir as ld,stat as yi,writeFile as fi}from"node:fs/promises";import{createCipheriv as ud,createDecipheriv as dd,randomBytes as gi,scryptSync as md}from"node:crypto";import ee from"node:path";var pd=[`${E}/instructions.md`,`${E}/memory.json`,`${E}/preferences.json`,`${E}/team-policy.json`,`${E}/skills`];async function kn(t){try{return await yi(t),!0}catch{return!1}}async function Lr(t,e,n){let r=ee.join(t,e);if(!await kn(r))return;let o=await ld(r,{withFileTypes:!0});for(let s of o){let i=ee.posix.join(e.replaceAll("\\","/"),s.name);if(s.isDirectory())await Lr(t,i,n);else if(s.isFile()){let a=await jr(ee.join(t,i));n.push({path:i,contentBase64:a.toString("base64")})}}}function fd(t){let e=t.replaceAll("\\","/");if(e.startsWith(".konsolepilot/")&&(e=`${E}/${e.slice(14)}`),!e.startsWith(`${E}/`)||e.includes("../")||ee.isAbsolute(e))throw new Error(`Unsafe bundle path: ${t}`);return e}async function gd(t,e){let n=e.split("/").filter(Boolean),r=t;for(let o of n.slice(0,-1)){if(r=ee.join(r,o),!await kn(r))continue;if((await cd(r)).isSymbolicLink())throw new Error(`Refusing to import through symbolic link: ${ee.relative(t,r)}`)}}function hi(t){return Buffer.from(JSON.stringify({schemaVersion:t.schemaVersion,format:t.format,createdAt:t.createdAt,projectName:t.projectName,includeSessions:t.includeSessions,algorithm:t.encryption.algorithm,kdf:t.encryption.kdf,salt:t.encryption.salt,iv:t.encryption.iv}),"utf8")}function wi(t,e){if(t.length<12)throw new Error("Sync passphrase must contain at least 12 characters.");return md(t,e,32,{N:32768,r:8,p:1,maxmem:64*1024*1024})}var xn=class{rootDir;constructor(e){this.rootDir=ee.resolve(e)}async exportBundle(e,n,r=!1){let o=[];for(let y of pd){let S=ee.join(this.rootDir,y);if(!await kn(S))continue;(await yi(S)).isDirectory()?await Lr(this.rootDir,y,o):o.push({path:y,contentBase64:(await jr(S)).toString("base64")})}r&&await Lr(this.rootDir,`${E}/sessions`,o),o.sort((y,S)=>y.path.localeCompare(S.path));let s={schemaVersion:1,files:o},i=gi(16),a=gi(12),c=wi(n,i),l={schemaVersion:1,format:"kpilot-encrypted-sync",createdAt:new Date().toISOString(),projectName:ee.basename(this.rootDir),includeSessions:r,encryption:{algorithm:"aes-256-gcm",kdf:"scrypt",salt:i.toString("base64"),iv:a.toString("base64"),tag:""}},u=ud("aes-256-gcm",c,a);u.setAAD(hi(l));let m=Buffer.concat([u.update(JSON.stringify(s),"utf8"),u.final()]),d={...l,encryption:{...l.encryption,tag:u.getAuthTag().toString("base64")},ciphertext:m.toString("base64")},p=ee.resolve(e);return await pi(ee.dirname(p),{recursive:!0}),await fi(p,`${JSON.stringify(d,null,2)}
206
+ `,{encoding:"utf8",mode:384}),d}async inspectBundle(e){let n=await this.readEnvelope(e),{ciphertext:r,...o}=n;return o}async importBundle(e,n,r=!1){let o=await this.readEnvelope(e),s=Buffer.from(o.encryption.salt,"base64"),i=Buffer.from(o.encryption.iv,"base64"),a=Buffer.from(o.encryption.tag,"base64"),c=wi(n,s),l;try{let p=dd("aes-256-gcm",c,i);p.setAuthTag(a);let{ciphertext:y,...S}=o;p.setAAD(hi(S)),l=Buffer.concat([p.update(Buffer.from(o.ciphertext,"base64")),p.final()])}catch{throw new Error("Unable to decrypt sync bundle. The passphrase is incorrect or the bundle was modified.")}let u;try{u=JSON.parse(l.toString("utf8"))}catch{throw new Error("Decrypted sync bundle payload is invalid JSON.")}if(u.schemaVersion!==1||!Array.isArray(u.files))throw new Error("Unsupported sync payload schema.");let m=[],d=[];for(let p of u.files){let y=fd(p.path),S=ee.join(this.rootDir,y);if(await gd(this.rootDir,y),!r&&await kn(S)){d.push(y);continue}await pi(ee.dirname(S),{recursive:!0}),await fi(S,Buffer.from(p.contentBase64,"base64"),{mode:384}),m.push(y)}return{imported:m,skipped:d}}async readEnvelope(e){let n;try{n=JSON.parse(await jr(ee.resolve(e),"utf8"))}catch(o){throw new Error(`Invalid sync bundle: ${o instanceof Error?o.message:String(o)}`)}if(!n||typeof n!="object"||Array.isArray(n))throw new Error("Sync bundle must be a JSON object.");let r=n;if(r.schemaVersion!==1||r.format!=="kpilot-encrypted-sync")throw new Error("Unsupported sync bundle format.");if(r.encryption?.algorithm!=="aes-256-gcm"||r.encryption?.kdf!=="scrypt")throw new Error("Unsupported sync bundle encryption.");return r}};import{mkdir as bi,readFile as hd,stat as wd,writeFile as vi}from"node:fs/promises";import Sn from"node:path";async function ki(t){try{return await wd(t),!0}catch{return!1}}function xi(t){let e=[],n=[];t.schemaVersion!==1&&e.push("schemaVersion must be 1."),t.maximumSteps!==void 0&&(!Number.isInteger(t.maximumSteps)||t.maximumSteps<1||t.maximumSteps>50)&&e.push("maximumSteps must be an integer between 1 and 50."),t.allowedModels&&((!Array.isArray(t.allowedModels)||t.allowedModels.some(o=>typeof o!="string"||!o.trim()))&&e.push("allowedModels must contain non-empty strings."),t.allowedModels.length===0&&n.push("allowedModels is empty; no model can run.")),t.allowedMcpServers?.some(o=>typeof o!="string"||!o.trim())&&e.push("allowedMcpServers must contain non-empty strings.");let r=new Set(["allow","ask","deny"]);for(let[o,s]of Object.entries(t.permissions??{}))for(let[i,a]of Object.entries(s??{}))r.has(a)||e.push(`permissions.${o}.${i} must be allow, ask, or deny.`);return{valid:e.length===0,errors:e,warnings:n}}var je=class{rootDir;filePath;constructor(e){this.rootDir=Sn.resolve(e),this.filePath=Sn.join(this.rootDir,E,"team-policy.json")}async load(){if(!await ki(this.filePath))return;let e;try{e=JSON.parse(await hd(this.filePath,"utf8"))}catch(o){throw new Error(`Invalid team policy JSON: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Team policy must be a JSON object.");let n=e,r=xi(n);if(!r.valid)throw new Error(`Invalid team policy: ${r.errors.join(" ")}`);return n}async initialize(e,n=[]){if(await ki(this.filePath))throw new Error(`${E}/team-policy.json already exists.`);let r={schemaVersion:1,...e?.trim()?{organization:e.trim()}:{},allowedModels:[...new Set(n.map(o=>o.trim()).filter(Boolean))],allowWriteMode:!0,requireSandbox:!0,requireNetworkIsolation:!0,allowedMcpServers:[],permissions:{}};return await bi(Sn.dirname(this.filePath),{recursive:!0}),await vi(this.filePath,`${JSON.stringify(r,null,2)}
207
+ `,"utf8"),r}async save(e){let n=xi(e);if(!n.valid)throw new Error(`Invalid team policy: ${n.errors.join(" ")}`);await bi(Sn.dirname(this.filePath),{recursive:!0}),await vi(this.filePath,`${JSON.stringify(e,null,2)}
208
+ `,"utf8")}};function Ti(t){let e=t.policy;if(e){if(t.mode==="write"&&e.allowWriteMode===!1)throw new Error("Team policy denies WRITE mode.");if(e.allowedModels&&!e.allowedModels.includes(t.model))throw new Error(`Model "${t.model}" is not allowed by team policy.`);if(e.maximumSteps!==void 0&&t.maxSteps!==void 0&&t.maxSteps>e.maximumSteps)throw new Error(`Requested max steps (${t.maxSteps}) exceeds team policy (${e.maximumSteps}).`);if(e.requireSandbox&&t.sandboxMode==="none")throw new Error("Team policy requires a command sandbox.");if(e.requireNetworkIsolation&&t.allowNetwork)throw new Error("Team policy requires sandbox network isolation.")}}var Si={allow:0,ask:1,deny:2};function Tn(t,e){return e&&Si[e]>Si[t]?e:t}function Pi(t,e){return e?{...t,search:Tn(t.search,"deny"),fetch:Tn(t.fetch,"deny")}:t}import{mkdir as En,readFile as Ve,readdir as yd,rename as bd,writeFile as Nr,chmod as vd,unlink as Ci,stat as Mi}from"node:fs/promises";import z from"node:path";var Pn=".kpilot",kd="logbook",xd="project.md",Sd="learnings.md",Td="meta.json",Pd=220,Ed=12e3,Ei=3,Ur={project:z.join(Pn,"understanding.md"),learnings:z.join(Pn,"learnings.md"),meta:z.join(Pn,"meta.json")},Rn=`Write the project's Logbook entry (.kpilot/logbook/project.md). Keep the tool chain tiny for small-context models (~8k context).
197
209
 
198
210
  Allowed steps only:
199
211
  1. workspace_summary once
@@ -203,8 +215,8 @@ Allowed steps only:
203
215
  5. write_file .kpilot/logbook/project.md using content_b64 (preferred) or a short content string
204
216
 
205
217
  Do NOT list deep trees or read more files. Brief: purpose, stack, layout, run/test commands, gotchas. Max ~60 lines of markdown.
206
- When done, one short confirmation sentence.`;async function Ir(t){let e=H.resolve(t),n=await nd(e).catch(()=>[]),r=[];for(let l of n.slice(0,60))if(!(l===".git"||l==="node_modules"||l==="dist"))try{let u=await gi(H.join(e,l));r.push(`${u.isDirectory()?"dir":"file"} ${l}`)}catch{r.push(`file ${l}`)}let s=["package.json","pnpm-workspace.yaml","package-lock.json","yarn.lock","Cargo.toml","go.mod","pyproject.toml","composer.json"].filter(l=>n.includes(l)),i="";try{i=(await Ve(H.join(e,"README.md"),"utf8")).split(/\r?\n/).slice(0,50).join(`
207
- `).trim()}catch{}let a="";try{let l=JSON.parse(await Ve(H.join(e,"package.json"),"utf8")),u=l.scripts?Object.keys(l.scripts).slice(0,12).map(m=>`- \`${m}\`: \`${l.scripts[m]}\``).join(`
218
+ When done, one short confirmation sentence.`;async function Fr(t){let e=z.resolve(t),n=await yd(e).catch(()=>[]),r=[];for(let l of n.slice(0,60))if(!(l===".git"||l==="node_modules"||l==="dist"))try{let u=await Mi(z.join(e,l));r.push(`${u.isDirectory()?"dir":"file"} ${l}`)}catch{r.push(`file ${l}`)}let s=["package.json","pnpm-workspace.yaml","package-lock.json","yarn.lock","Cargo.toml","go.mod","pyproject.toml","composer.json"].filter(l=>n.includes(l)),i="";try{i=(await Ve(z.join(e,"README.md"),"utf8")).split(/\r?\n/).slice(0,50).join(`
219
+ `).trim()}catch{}let a="";try{let l=JSON.parse(await Ve(z.join(e,"package.json"),"utf8")),u=l.scripts?Object.keys(l.scripts).slice(0,12).map(m=>`- \`${m}\`: \`${l.scripts[m]}\``).join(`
208
220
  `):"_none_";a=[l.name?`- name: \`${l.name}\``:"",l.description?`- description: ${l.description}`:"",l.packageManager?`- packageManager: \`${l.packageManager}\``:"","- scripts:",u].filter(Boolean).join(`
209
221
  `)}catch{}let c=`# Project Logbook
210
222
 
@@ -235,18 +247,18 @@ See \`package.json\` scripts above (or README). Prefer the repo's documented pac
235
247
  - Keep secrets out of git (\`.env\`).
236
248
  - Prefer small, permission-gated edits.
237
249
  - This lite entry may be incomplete on large monorepos \u2014 re-run \`/logbook\` with more context when possible.
238
- `;return pd(e,c)}function Dr(t){let e=t instanceof Error?t.message:String(t);return/exceeds the available context size|context.?length|context.?window|too many tokens|maximum context/i.test(e)}function dd(t){return H.join(H.resolve(t),kn)}function Le(t){return H.join(dd(t),sd)}function Ye(t){return H.join(Le(t),id)}async function hi(t,e=7){try{let n=await gi(Ye(t));return Date.now()-n.mtimeMs>e*24*60*60*1e3}catch{return!1}}function jr(t){return H.join(Le(t),ad)}function Tn(t){return H.join(Le(t),cd)}async function pi(t){try{return await Ve(t),!0}catch{return!1}}async function Qe(t){let e=H.resolve(t),n=Le(e);await xn(n,{recursive:!0,mode:493});let r=[[H.join(e,Ar.project),Ye(e)],[H.join(e,Ar.learnings),jr(e)],[H.join(e,Ar.meta),Tn(e)]];for(let[o,s]of r)if(await pi(o)){if(await pi(s)){try{await fi(o)}catch{}continue}try{await rd(o,s)}catch{}}}async function md(t){try{return JSON.parse(await Ve(t,"utf8"))}catch{return{}}}async function $t(t){await Qe(t);let e=await md(Tn(t)),n=typeof e.projectCapturedAt=="string"?e.projectCapturedAt:typeof e.understoodAt=="string"?e.understoodAt:void 0;return{schemaVersion:1,updatedAt:typeof e.updatedAt=="string"?e.updatedAt:new Date(0).toISOString(),declined:e.declined===!0,projectCapturedAt:n,learningEnabled:e.learningEnabled===!0,learningOffered:e.learningOffered===!0,lastLearnedAt:typeof e.lastLearnedAt=="string"?e.lastLearnedAt:void 0}}async function _t(t,e){await Qe(t);let n=await $t(t),r={schemaVersion:1,updatedAt:new Date().toISOString()};(e.declined!==void 0?e.declined:n.declined)&&(r.declined=!0);let s=e.projectCapturedAt!==void 0?e.projectCapturedAt:n.projectCapturedAt;s&&(r.projectCapturedAt=s),(e.learningEnabled!==void 0?e.learningEnabled:n.learningEnabled)&&(r.learningEnabled=!0),(e.learningOffered!==void 0?e.learningOffered:n.learningOffered)&&(r.learningOffered=!0);let c=e.lastLearnedAt!==void 0?e.lastLearnedAt:n.lastLearnedAt;c&&(r.lastLearnedAt=c);let l=Le(t);await xn(l,{recursive:!0,mode:448});let u=Tn(t);await Or(u,`${JSON.stringify(r,null,2)}
239
- `,{encoding:"utf8",mode:384}),await od(u,384)}async function Xe(t){await Qe(t);try{return(await Ve(Ye(t),"utf8")).trim().length>0}catch{return!1}}async function pd(t,e){await Qe(t);let n=Le(t);await xn(n,{recursive:!0,mode:493});let r=Ye(t),o=e.trim().endsWith(`
250
+ `;return Md(e,c)}function qr(t){let e=t instanceof Error?t.message:String(t);return/exceeds the available context size|context.?length|context.?window|too many tokens|maximum context/i.test(e)}function Rd(t){return z.join(z.resolve(t),Pn)}function Le(t){return z.join(Rd(t),kd)}function Ye(t){return z.join(Le(t),xd)}async function $i(t,e=7){try{let n=await Mi(Ye(t));return Date.now()-n.mtimeMs>e*24*60*60*1e3}catch{return!1}}function Br(t){return z.join(Le(t),Sd)}function Cn(t){return z.join(Le(t),Td)}async function Ri(t){try{return await Ve(t),!0}catch{return!1}}async function Qe(t){let e=z.resolve(t),n=Le(e);await En(n,{recursive:!0,mode:493});let r=[[z.join(e,Ur.project),Ye(e)],[z.join(e,Ur.learnings),Br(e)],[z.join(e,Ur.meta),Cn(e)]];for(let[o,s]of r)if(await Ri(o)){if(await Ri(s)){try{await Ci(o)}catch{}continue}try{await bd(o,s)}catch{}}}async function Cd(t){try{return JSON.parse(await Ve(t,"utf8"))}catch{return{}}}async function At(t){await Qe(t);let e=await Cd(Cn(t)),n=typeof e.projectCapturedAt=="string"?e.projectCapturedAt:typeof e.understoodAt=="string"?e.understoodAt:void 0;return{schemaVersion:1,updatedAt:typeof e.updatedAt=="string"?e.updatedAt:new Date(0).toISOString(),declined:e.declined===!0,projectCapturedAt:n,learningEnabled:e.learningEnabled===!0,learningOffered:e.learningOffered===!0,lastLearnedAt:typeof e.lastLearnedAt=="string"?e.lastLearnedAt:void 0}}async function Ot(t,e){await Qe(t);let n=await At(t),r={schemaVersion:1,updatedAt:new Date().toISOString()};(e.declined!==void 0?e.declined:n.declined)&&(r.declined=!0);let s=e.projectCapturedAt!==void 0?e.projectCapturedAt:n.projectCapturedAt;s&&(r.projectCapturedAt=s),(e.learningEnabled!==void 0?e.learningEnabled:n.learningEnabled)&&(r.learningEnabled=!0),(e.learningOffered!==void 0?e.learningOffered:n.learningOffered)&&(r.learningOffered=!0);let c=e.lastLearnedAt!==void 0?e.lastLearnedAt:n.lastLearnedAt;c&&(r.lastLearnedAt=c);let l=Le(t);await En(l,{recursive:!0,mode:448});let u=Cn(t);await Nr(u,`${JSON.stringify(r,null,2)}
251
+ `,{encoding:"utf8",mode:384}),await vd(u,384)}async function Xe(t){await Qe(t);try{return(await Ve(Ye(t),"utf8")).trim().length>0}catch{return!1}}async function Md(t,e){await Qe(t);let n=Le(t);await En(n,{recursive:!0,mode:493});let r=Ye(t),o=e.trim().endsWith(`
240
252
  `)?e.trimStart():`${e.trim()}
241
- `;return await Or(r,o,{encoding:"utf8",mode:420}),await _t(t,{projectCapturedAt:new Date().toISOString(),declined:!1}),r}async function Lr(t){await _t(t,{declined:!0})}async function Ur(t){let e=await $t(t);if(!e.declined&&!e.projectCapturedAt&&!e.learningEnabled&&!e.learningOffered&&!e.lastLearnedAt){try{await fi(Tn(t))}catch{}return}await _t(t,{declined:!1})}async function wi(t){return await Xe(t)?!1:!(await $t(t)).declined}async function At(t){return(await $t(t)).learningEnabled===!0}async function yi(t){let e=await Xe(t),n=await At(t);return e&&!n?"":e?"Logbook: learning on \xB7 /learn off":"Logbook: no project entry \xB7 /logbook to capture"}async function Ot(t,e){await _t(t,{learningEnabled:e,learningOffered:!0})}async function bi(t){let e=await $t(t);return!(e.learningEnabled||e.learningOffered)}function Nr(t){return t.replace(/\s+/g," ").trim().replace(/^[-*•]\s*/,"").slice(0,ld)}function fd(t){let e=[];for(let n of t.split(/\r?\n/)){let r=/^\s*[-*]\s+(.+)$/.exec(n);if(!r?.[1])continue;let o=Nr(r[1]);o&&e.push(o)}return e}async function vi(t){await Qe(t);try{let e=await Ve(jr(t),"utf8");return fd(e)}catch{return[]}}async function Fr(t,e=8e3){let n=await vi(t);if(!n.length)return"";let r=[],o=0;for(let s of n){let i=`- ${s}`;if(o+i.length+1>e)break;r.push(i),o+=i.length+1}return r.join(`
242
- `)}async function gd(t,e){await Qe(t);let n=e.map(Nr).filter(Boolean);if(!n.length)return[];let r=await vi(t),o=new Set(r.map(l=>l.toLowerCase())),s=[];for(let l of n){let u=l.toLowerCase();o.has(u)||(o.add(u),r.push(l),s.push(l))}if(!s.length)return[];let i=r,a=`${i.map(l=>`- ${l}`).join(`
253
+ `;return await Nr(r,o,{encoding:"utf8",mode:420}),await Ot(t,{projectCapturedAt:new Date().toISOString(),declined:!1}),r}async function Jr(t){await Ot(t,{declined:!0})}async function Kr(t){let e=await At(t);if(!e.declined&&!e.projectCapturedAt&&!e.learningEnabled&&!e.learningOffered&&!e.lastLearnedAt){try{await Ci(Cn(t))}catch{}return}await Ot(t,{declined:!1})}async function _i(t){return await Xe(t)?!1:!(await At(t)).declined}async function It(t){return(await At(t)).learningEnabled===!0}async function Ai(t){let e=await Xe(t),n=await It(t);return e&&!n?"":e?"Logbook: learning on \xB7 /learn off":"Logbook: no project entry \xB7 /logbook to capture"}async function Dt(t,e){await Ot(t,{learningEnabled:e,learningOffered:!0})}async function Oi(t){let e=await At(t);return!(e.learningEnabled||e.learningOffered)}function Wr(t){return t.replace(/\s+/g," ").trim().replace(/^[-*•]\s*/,"").slice(0,Pd)}function $d(t){let e=[];for(let n of t.split(/\r?\n/)){let r=/^\s*[-*]\s+(.+)$/.exec(n);if(!r?.[1])continue;let o=Wr(r[1]);o&&e.push(o)}return e}async function Ii(t){await Qe(t);try{let e=await Ve(Br(t),"utf8");return $d(e)}catch{return[]}}async function Gr(t,e=8e3){let n=await Ii(t);if(!n.length)return"";let r=[],o=0;for(let s of n){let i=`- ${s}`;if(o+i.length+1>e)break;r.push(i),o+=i.length+1}return r.join(`
254
+ `)}async function _d(t,e){await Qe(t);let n=e.map(Wr).filter(Boolean);if(!n.length)return[];let r=await Ii(t),o=new Set(r.map(l=>l.toLowerCase())),s=[];for(let l of n){let u=l.toLowerCase();o.has(u)||(o.add(u),r.push(l),s.push(l))}if(!s.length)return[];let i=r,a=`${i.map(l=>`- ${l}`).join(`
243
255
  `)}
244
- `;for(;a.length>ud&&i.length>1;)i=i.slice(1),a=`${i.map(l=>`- ${l}`).join(`
256
+ `;for(;a.length>Ed&&i.length>1;)i=i.slice(1),a=`${i.map(l=>`- ${l}`).join(`
245
257
  `)}
246
- `;let c=Le(t);return await xn(c,{recursive:!0,mode:493}),await Or(jr(t),`# Logbook learnings
258
+ `;let c=Le(t);return await En(c,{recursive:!0,mode:493}),await Nr(Br(t),`# Logbook learnings
247
259
 
248
- ${a}`,{encoding:"utf8",mode:420}),await _t(t,{lastLearnedAt:new Date().toISOString()}),s}function hd(t){let e=[],n=t.prompt.trim();if(!n||n===Sn)return[];let r=s=>{if(!s)return;let i=Nr(s);!i||i.length<8||e.some(a=>a.toLowerCase()===i.toLowerCase())||e.length>=mi||e.push(i)},o=[/\b(?:please\s+)?remember(?:\s+that)?\s+(.+)$/im,/\b(?:from now on|going forward)[,:]?\s+(.+)$/im,/\balways\s+(.+)$/im,/\bnever\s+(.+)$/im,/\b(?:prefer|use)\s+(.+?)(?:\s+instead\b|\s+for\b|\.|$)/im,/\bdon'?t\s+(.+)$/im,/\bdo not\s+(.+)$/im,/\bnote that\s+(.+)$/im,/\bin this (?:repo|project|codebase)[,:]?\s+(.+)$/im];for(let s of o){let i=s.exec(n);i?.[1]&&r(i[1])}if(t.changed&&t.diffAfter){let s=t.diffAfter;/\bpnpm-lock\.yaml\b/.test(s)||/\bpnpm-workspace\.yaml\b/.test(s)?r("Use pnpm for installs and scripts in this repository."):/\bpackage-lock\.json\b/.test(s)?r("Use npm for installs and scripts in this repository."):/\byarn\.lock\b/.test(s)?r("Use yarn for installs and scripts in this repository."):/\bbun\.lockb?\b/.test(s)&&r("Use bun for installs and scripts in this repository."),/\.spec\.(ts|tsx|js|jsx)\b/.test(s)&&!/\.test\.(ts|tsx|js|jsx)\b/.test(s)?r("Tests in this repository often use *.spec.* filenames."):/\.test\.(ts|tsx|js|jsx)\b/.test(s)&&!/\.spec\.(ts|tsx|js|jsx)\b/.test(s)&&r("Tests in this repository often use *.test.* filenames.")}return e.slice(0,mi)}async function ki(t){if(!await At(t.rootDir))return[];if(t.prompt.trim()===Sn)return[];let e=hd(t);return e.length?gd(t.rootDir,e):[]}function xi(t){let e=t.replace(/\\/g,"/");return e===".kpilot"||e.startsWith(".kpilot/")||e.includes("/.kpilot/")}var z="0.10.42",Br=[26,0,0];function kd(){let t=process.version.replace(/^v/,"").split(".").slice(0,3).map(Number);if(!Br.every((n,r)=>{for(let o=0;o<r;o+=1)if((t[o]??0)!==Br[o])return!0;return(t[r]??0)>=n})&&process.env.KPILOT_ALLOW_UNSUPPORTED_NODE!=="1")throw new Error(`kpilot requires Node.js ${Br.join(".")} or newer; detected ${process.version}.`)}var I={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",magenta:"\x1B[35m"},Dt=[{name:"help",usage:"/help",description:"Show slash commands"},{name:"mode",usage:"/mode plan|write",description:"Change mode without deleting history",choices:[{value:"plan",label:"plan",description:"Inspect and reason only"},{value:"write",label:"write",description:"Allow file and command changes"}]},{name:"status",usage:"/status",description:"Show Git status"},{name:"diff",usage:"/diff",description:"Show Git diff"},{name:"clear",usage:"/clear",description:"Clear current conversation history"},{name:"undo",usage:"/undo",description:"Revert file changes from the last run"},{name:"compact",usage:"/compact",description:"Summarize history to free context"},{name:"cost",usage:"/cost",description:"Show this session\u2019s token usage and estimated cost"},{name:"context",usage:"/context",description:"Show conversation size and context fill"},{name:"checkpoint",usage:"/checkpoint [save|restore|list] [id]",description:"Snapshot or restore conversation state"},{name:"save",usage:"/save",description:"Persist the current session"},{name:"sessions",usage:"/sessions",description:"Switch session (selectable list)"},{name:"resume",usage:"/resume [id]",description:"Switch session by id or picker"},{name:"new",usage:"/new [title]",description:"Start a new session"},{name:"logbook",usage:"/logbook [skip]",description:"Build or refresh .kpilot/logbook/project.md",aliases:["understand"],choices:[{value:"capture",label:"capture",description:"Inspect repo and write project.md",default:!0},{value:"skip",label:"skip",description:"Do not auto-offer Logbook again"}]},{name:"learn",usage:"/learn [on|off|status]",description:"Continuous Logbook learning",choices:[{value:"status",label:"status",description:"Show learning state and facts",default:!0},{value:"on",label:"on",description:"Enable continuous learning"},{value:"off",label:"off",description:"Disable continuous learning"}]},{name:"memory",usage:"/memory",description:"List project memory"},{name:"todo",usage:"/todo [add|done|remove|clear] [text|id]",description:"Track project todos"},{name:"remember",usage:"/remember <text>",description:"Add persistent project memory",needsArgs:!0,argPrompt:"Memory text \u203A "},{name:"forget",usage:"/forget <id>",description:"Remove a memory entry",needsArgs:!0,argPrompt:"Memory id \u203A "},{name:"skills",usage:"/skills",description:"List reusable skills"},{name:"skill",usage:"/skill <name> [args]",description:"Run a skill",needsArgs:!0,argPrompt:"Skill name [args] \u203A "},{name:"preferences",usage:"/preferences",description:"List learned preferences"},{name:"feedback",usage:"/feedback <outcome> [note]",description:"Record accepted, rejected, or edited feedback",choices:[{value:"accepted",label:"accepted",description:"Mark last run accepted"},{value:"rejected",label:"rejected",description:"Mark last run rejected"},{value:"edited",label:"edited",description:"Mark last run edited"}]},{name:"models",usage:"/models",description:"Show active models and select one",aliases:["model"]},{name:"agent",usage:"/agent",description:"Show external agent configuration"},{name:"mcp",usage:"/mcp",description:"List connected MCP tools"},{name:"worktrees",usage:"/worktrees",description:"List Git worktrees"},{name:"policy",usage:"/policy",description:"Show team policy"},{name:"usage",usage:"/usage",description:"Show usage summary"},{name:"audit",usage:"/audit",description:"Verify audit chain"},{name:"admin",usage:"/admin",description:"Show admin/control-plane status"},{name:"exit",usage:"/exit",description:"End session (also: exit, quit)",aliases:["quit"]}],Oi=new Set(Dt.flatMap(t=>[t.name,...t.aliases??[]]));function xd(t){if(!t.startsWith("/")||t==="/")return!1;let[e="",...n]=t.slice(1).split(/\s+/);return!e||n.length>0?!1:!Oi.has(e)}function j(t,e){return process.stdout.isTTY?`${t}${e}${I.reset}`:e}function ue(t){if(!Number.isFinite(t)||t<1e3)return String(Math.round(t));let e=["K","M","B","T"],n=Math.min(Math.floor(Math.log10(t)/3),e.length),r=t/10**(n*3),o=r>=100?0:r>=10?1:2;return`${r.toFixed(o)}${e[n-1]}`}function Ii(t){if(t)return{pause:()=>{t.closed||t.pause()},resume:()=>{t.closed||t.resume()}}}function Sd(){console.log(j(I.bold,"Slash commands")),console.log(j(I.dim,"Type / to list commands as you type \u2014 \u2191/\u2193 to move, Enter to run."));for(let t of Dt)console.log(` ${j(I.cyan,t.usage.padEnd(28))} ${t.description}`);console.log(` ${j(I.cyan,"/<skill-name> [args]".padEnd(28))} Run a skill directly`)}function Si(t=[]){let e=t.map(n=>({name:n,usage:`/${n}`,description:`Run skill \u201C${n}\u201D`}));return[...Dt.map(n=>({name:n.name,usage:n.usage,description:n.description,aliases:n.aliases})),...e]}async function Td(t){let e=(t.skillNames??[]).map(s=>({name:s,usage:`/${s}`,description:`Run skill \u201C${s}\u201D`})),n=[...Dt,...e],r=await Q({title:"Select a command:",question:t.question,pauseResume:t.pauseResume,typeahead:!0,initialQuery:t.initialQuery??"",choices:n.map(s=>({value:s.name,label:s.usage,description:s.description,aliases:s.aliases}))});if(!r)return null;let o=n.find(s=>s.name===r);if(!o)return null;if(o.choices&&o.choices.length>0){let s=await Q({title:`${o.usage} \u2014 choose an action:`,question:t.question,pauseResume:t.pauseResume,choices:o.choices});if(!s)return $("Cancelled."),null;if(o.name==="logbook"&&s==="capture")return"/logbook";if(o.name==="feedback"){let i=(await t.question("Optional note \u203A ")).trim();return i?`/feedback ${s} ${i}`:`/feedback ${s}`}return`/${o.name} ${s}`}if(o.needsArgs){let s=(await t.question(o.argPrompt??"Args \u203A ")).trim();return s?`/${o.name} ${s}`:($("Cancelled."),null)}return`/${o.name}`}function $(t){console.log(`${j(I.cyan,"\u25C6")} ${t}`)}function v(t){console.log(`${j(I.green,"\u2713")} ${t}`)}function _(t){console.log(`${j(I.yellow,"!")} ${t}`)}function q(t){console.error(`${j(I.red,"\u2717")} ${t}`)}function Pd(){return D.join($i(),".config","kpilot","installed-version")}function Ed(t,e){let n=s=>s.split(".").map(i=>Number(i)||0),r=n(t),o=n(e);for(let s=0;s<3;s+=1)if((r[s]??0)!==(o[s]??0))return(r[s]??0)<(o[s]??0)?-1:1;return 0}async function Rd(){if(process.env.KPILOT_SILENT_VERSION_NOTICE==="1")return;let t=Pd(),e;try{e=(await Vr(t,"utf8")).trim()||void 0}catch{e=void 0}if(e!==z){if(e){let n=Ed(e,z)<0?"Updated":"Changed";$(`kpilot CLI ${n}: ${e} \u2192 ${z}`)}else $(`kpilot CLI installed: ${z}`);try{await et(D.dirname(t),{recursive:!0}),await ve(t,`${z}
249
- `,{mode:384})}catch{}}}function Cd(){return`${j(I.bold,`kpilot ${z}`)} \u2014 governed engineering agent
260
+ ${a}`,{encoding:"utf8",mode:420}),await Ot(t,{lastLearnedAt:new Date().toISOString()}),s}function Ad(t){let e=[],n=t.prompt.trim();if(!n||n===Rn)return[];let r=s=>{if(!s)return;let i=Wr(s);!i||i.length<8||e.some(a=>a.toLowerCase()===i.toLowerCase())||e.length>=Ei||e.push(i)},o=[/\b(?:please\s+)?remember(?:\s+that)?\s+(.+)$/im,/\b(?:from now on|going forward)[,:]?\s+(.+)$/im,/\balways\s+(.+)$/im,/\bnever\s+(.+)$/im,/\b(?:prefer|use)\s+(.+?)(?:\s+instead\b|\s+for\b|\.|$)/im,/\bdon'?t\s+(.+)$/im,/\bdo not\s+(.+)$/im,/\bnote that\s+(.+)$/im,/\bin this (?:repo|project|codebase)[,:]?\s+(.+)$/im];for(let s of o){let i=s.exec(n);i?.[1]&&r(i[1])}if(t.changed&&t.diffAfter){let s=t.diffAfter;/\bpnpm-lock\.yaml\b/.test(s)||/\bpnpm-workspace\.yaml\b/.test(s)?r("Use pnpm for installs and scripts in this repository."):/\bpackage-lock\.json\b/.test(s)?r("Use npm for installs and scripts in this repository."):/\byarn\.lock\b/.test(s)?r("Use yarn for installs and scripts in this repository."):/\bbun\.lockb?\b/.test(s)&&r("Use bun for installs and scripts in this repository."),/\.spec\.(ts|tsx|js|jsx)\b/.test(s)&&!/\.test\.(ts|tsx|js|jsx)\b/.test(s)?r("Tests in this repository often use *.spec.* filenames."):/\.test\.(ts|tsx|js|jsx)\b/.test(s)&&!/\.spec\.(ts|tsx|js|jsx)\b/.test(s)&&r("Tests in this repository often use *.test.* filenames.")}return e.slice(0,Ei)}async function Di(t){if(!await It(t.rootDir))return[];if(t.prompt.trim()===Rn)return[];let e=Ad(t);return e.length?_d(t.rootDir,e):[]}function ji(t){let e=t.replace(/\\/g,"/");return e===".kpilot"||e.startsWith(".kpilot/")||e.includes("/.kpilot/")}var V="0.10.45",Hr=[26,0,0];function Ld(){let t=process.version.replace(/^v/,"").split(".").slice(0,3).map(Number);if(!Hr.every((n,r)=>{for(let o=0;o<r;o+=1)if((t[o]??0)!==Hr[o])return!0;return(t[r]??0)>=n})&&process.env.KPILOT_ALLOW_UNSUPPORTED_NODE!=="1")throw new Error(`kpilot requires Node.js ${Hr.join(".")} or newer; detected ${process.version}.`)}var D={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",magenta:"\x1B[35m"},Lt=[{name:"help",usage:"/help",description:"Show slash commands"},{name:"mode",usage:"/mode plan|write",description:"Change mode without deleting history",choices:[{value:"plan",label:"plan",description:"Inspect and reason only"},{value:"write",label:"write",description:"Allow file and command changes"}]},{name:"status",usage:"/status",description:"Show Git status"},{name:"diff",usage:"/diff",description:"Show Git diff"},{name:"clear",usage:"/clear",description:"Clear current conversation history"},{name:"undo",usage:"/undo",description:"Revert file changes from the last run"},{name:"compact",usage:"/compact",description:"Summarize history to free context"},{name:"cost",usage:"/cost",description:"Show this session\u2019s token usage and estimated cost"},{name:"context",usage:"/context",description:"Show conversation size and context fill"},{name:"checkpoint",usage:"/checkpoint [save|restore|list] [id]",description:"Snapshot or restore conversation state"},{name:"save",usage:"/save",description:"Persist the current session"},{name:"sessions",usage:"/sessions",description:"Switch session (selectable list)"},{name:"resume",usage:"/resume [id]",description:"Switch session by id or picker"},{name:"new",usage:"/new [title]",description:"Start a new session"},{name:"logbook",usage:"/logbook [skip]",description:"Build or refresh .kpilot/logbook/project.md",aliases:["understand"],choices:[{value:"capture",label:"capture",description:"Inspect repo and write project.md",default:!0},{value:"skip",label:"skip",description:"Do not auto-offer Logbook again"}]},{name:"learn",usage:"/learn [on|off|status]",description:"Continuous Logbook learning",choices:[{value:"status",label:"status",description:"Show learning state and facts",default:!0},{value:"on",label:"on",description:"Enable continuous learning"},{value:"off",label:"off",description:"Disable continuous learning"}]},{name:"memory",usage:"/memory",description:"List project memory"},{name:"todo",usage:"/todo [add|done|remove|clear] [text|id]",description:"Track project todos"},{name:"remember",usage:"/remember <text>",description:"Add persistent project memory",needsArgs:!0,argPrompt:"Memory text \u203A "},{name:"forget",usage:"/forget <id>",description:"Remove a memory entry",needsArgs:!0,argPrompt:"Memory id \u203A "},{name:"skills",usage:"/skills",description:"List reusable skills"},{name:"skill",usage:"/skill <name> [args]",description:"Run a skill",needsArgs:!0,argPrompt:"Skill name [args] \u203A "},{name:"preferences",usage:"/preferences",description:"List learned preferences"},{name:"feedback",usage:"/feedback <outcome> [note]",description:"Record accepted, rejected, or edited feedback",choices:[{value:"accepted",label:"accepted",description:"Mark last run accepted"},{value:"rejected",label:"rejected",description:"Mark last run rejected"},{value:"edited",label:"edited",description:"Mark last run edited"}]},{name:"models",usage:"/models",description:"Show active models and select one",aliases:["model"]},{name:"agent",usage:"/agent",description:"Show external agent configuration"},{name:"mcp",usage:"/mcp",description:"List connected MCP tools"},{name:"worktrees",usage:"/worktrees",description:"List Git worktrees"},{name:"policy",usage:"/policy",description:"Show team policy"},{name:"usage",usage:"/usage",description:"Show usage summary"},{name:"audit",usage:"/audit",description:"Verify audit chain"},{name:"admin",usage:"/admin",description:"Show admin/control-plane status"},{name:"exit",usage:"/exit",description:"End session (also: exit, quit)",aliases:["quit"]}],Hi=new Set(Lt.flatMap(t=>[t.name,...t.aliases??[]]));function Ud(t){if(!t.startsWith("/")||t==="/")return!1;let[e="",...n]=t.slice(1).split(/\s+/);return!e||n.length>0?!1:!Hi.has(e)}function U(t,e){return process.stdout.isTTY?`${t}${e}${D.reset}`:e}function de(t){if(!Number.isFinite(t)||t<1e3)return String(Math.round(t));let e=["K","M","B","T"],n=Math.min(Math.floor(Math.log10(t)/3),e.length),r=t/10**(n*3),o=r>=100?0:r>=10?1:2;return`${r.toFixed(o)}${e[n-1]}`}function zi(t){if(t)return{pause:()=>{t.closed||t.pause()},resume:()=>{t.closed||t.resume()}}}function Nd(){console.log(U(D.bold,"Slash commands")),console.log(U(D.dim,"Type / to list commands as you type \u2014 \u2191/\u2193 to move, Enter to run."));for(let t of Lt)console.log(` ${U(D.cyan,t.usage.padEnd(28))} ${t.description}`);console.log(` ${U(D.cyan,"/<skill-name> [args]".padEnd(28))} Run a skill directly`)}function Li(t=[]){let e=t.map(n=>({name:n,usage:`/${n}`,description:`Run skill \u201C${n}\u201D`}));return[...Lt.map(n=>({name:n.name,usage:n.usage,description:n.description,aliases:n.aliases})),...e]}async function Fd(t){let e=(t.skillNames??[]).map(s=>({name:s,usage:`/${s}`,description:`Run skill \u201C${s}\u201D`})),n=[...Lt,...e],r=await Q({title:"Select a command:",question:t.question,pauseResume:t.pauseResume,typeahead:!0,initialQuery:t.initialQuery??"",choices:n.map(s=>({value:s.name,label:s.usage,description:s.description,aliases:s.aliases}))});if(!r)return null;let o=n.find(s=>s.name===r);if(!o)return null;if(o.choices&&o.choices.length>0){let s=await Q({title:`${o.usage} \u2014 choose an action:`,question:t.question,pauseResume:t.pauseResume,choices:o.choices});if(!s)return $("Cancelled."),null;if(o.name==="logbook"&&s==="capture")return"/logbook";if(o.name==="feedback"){let i=(await t.question("Optional note \u203A ")).trim();return i?`/feedback ${s} ${i}`:`/feedback ${s}`}return`/${o.name} ${s}`}if(o.needsArgs){let s=(await t.question(o.argPrompt??"Args \u203A ")).trim();return s?`/${o.name} ${s}`:($("Cancelled."),null)}return`/${o.name}`}function $(t){console.log(`${U(D.cyan,"\u25C6")} ${t}`)}function T(t){console.log(`${U(D.green,"\u2713")} ${t}`)}function A(t){console.log(`${U(D.yellow,"!")} ${t}`)}function J(t){console.error(`${U(D.red,"\u2717")} ${t}`)}function qd(){return L.join(Ki(),".config","kpilot","installed-version")}function Bd(t,e){let n=s=>s.split(".").map(i=>Number(i)||0),r=n(t),o=n(e);for(let s=0;s<3;s+=1)if((r[s]??0)!==(o[s]??0))return(r[s]??0)<(o[s]??0)?-1:1;return 0}async function Jd(){if(process.env.KPILOT_SILENT_VERSION_NOTICE==="1")return;let t=qd(),e;try{e=(await eo(t,"utf8")).trim()||void 0}catch{e=void 0}if(e!==V){if(e){let n=Bd(e,V)<0?"Updated":"Changed";$(`kpilot CLI ${n}: ${e} \u2192 ${V}`)}else $(`kpilot CLI installed: ${V}`);try{await et(L.dirname(t),{recursive:!0}),await ke(t,`${V}
261
+ `,{mode:384})}catch{}}}function Kd(){return`${U(D.bold,`kpilot ${V}`)} \u2014 governed engineering agent
250
262
 
251
263
  All requests go through kpilot \u2014 sign in once, and kpilot handles the rest.
252
264
 
@@ -308,35 +320,35 @@ Interactive additions:
308
320
  /skills, /skill <name> [arguments], /<skill-name> [arguments]
309
321
  /preferences, /feedback <accepted|rejected|edited> [note]
310
322
  /models, /agent, /mcp, /worktrees, /policy, /usage, /audit, /admin
311
- `}function ie(t,e,n){let r=t[e+1];if(!r||r.startsWith("--"))throw new Error(`${n} requires a value.`);return[r,e+1]}function Md(t){let e={command:"run",prompt:"",args:[],cwd:process.cwd(),yes:!1,bypassPermissions:!1,debug:!1,force:!1,passphraseEnv:"KPILOT_SYNC_PASSPHRASE",includeSessions:!1,overwrite:!1,limit:50,noCloudSync:!1,noBrowser:!1},n=[],r=!1,o=["run","chat","init","doctor","login","logout","whoami","models","agents","sessions","memory","skills","preferences","feedback","mcp","worktrees","policy","usage","audit","sync","admin","help","version"];for(let s=0;s<t.length;s+=1){let i=t[s]??"";if(i==="--"){n.push(...t.slice(s+1));break}if(i==="-h"||i==="--help"){e.command="help",r=!0;continue}if(i==="-V"||i==="--version"){e.command="version",r=!0;continue}if(i.startsWith("--")&&!i.includes("=")){let a=i.slice(2);if(o.includes(a)){e.command=a,r=!0;continue}}if(i==="--yes"||i==="-y"){e.yes=!0;continue}if(So(i)){e.bypassPermissions=!0,i==="--force"&&(e.force=!0);continue}if(i==="--permission-mode"){let[a,c]=ie(t,s,i);e.bypassPermissions=To(a),s=c;continue}if(i==="--debug"){e.debug=!0;continue}if(i==="--include-sessions"){e.includeSessions=!0;continue}if(i==="--overwrite"){e.overwrite=!0;continue}if(i==="--no-cloud-sync"){e.noCloudSync=!0;continue}if(i==="--no-browser"){e.noBrowser=!0;continue}if(i==="--cwd"){let[a,c]=ie(t,s,i);e.cwd=D.resolve(a),s=c;continue}if(i==="--mode"){let[a,c]=ie(t,s,i);if(a!=="plan"&&a!=="write")throw new Error("--mode must be plan or write.");e.mode=a,s=c;continue}if(i==="--session"){let[a,c]=ie(t,s,i);e.session=a,s=c;continue}if(i==="--title"){let[a,c]=ie(t,s,i);e.title=a,s=c;continue}if(i==="--note"){let[a,c]=ie(t,s,i);e.note=a,s=c;continue}if(i==="--model"){let[a,c]=ie(t,s,i);e.model=a,s=c;continue}if(i==="--passphrase-env"){let[a,c]=ie(t,s,i);e.passphraseEnv=a,s=c;continue}if(i==="--control-plane-url"){let[a,c]=ie(t,s,i);e.controlPlaneUrl=a,s=c;continue}if(i==="--organization"){let[a,c]=ie(t,s,i);e.organization=a,s=c;continue}if(i==="--limit"){let[a,c]=ie(t,s,i),l=Number(a);if(!Number.isInteger(l)||l<1||l>1e3)throw new Error("--limit must be between 1 and 1000.");e.limit=l,s=c;continue}if(i==="--max-steps"){let[a,c]=ie(t,s,i),l=Number(a);if(!Number.isInteger(l)||l<1||l>50)throw new Error("--max-steps must be an integer between 1 and 50.");e.maxSteps=l,s=c;continue}if(i.startsWith("-")){let a=i.replace(/^--?/,"");throw o.includes(a)?new Error(`Unknown option: ${i}. Use \`kpilot ${a}\` or \`kpilot --${a}\`.`):new Error(`Unknown option: ${i}`)}if(!r&&o.includes(i)){e.command=i,r=!0;continue}n.push(i)}return e.args=n,e.prompt=e.command==="run"?n.join(" ").trim():"",e.command==="run"&&!e.prompt&&(e.command="chat"),e}async function tt(t){try{return await Ci(t),!0}catch{return!1}}async function Jr(t){if(!await tt(t))return{};let e=await Vr(t,"utf8");try{return JSON.parse(e)}catch(n){throw new Error(`Invalid JSON in ${t}: ${n instanceof Error?n.message:String(n)}`)}}function $d(t,e){return{model:{...t.model,...e.model},agent:{...t.agent,...e.agent},sandbox:{...t.sandbox,...e.sandbox},subagents:{...t.subagents,...e.subagents},mcp:{...t.mcp,...e.mcp,servers:{...t.mcp?.servers,...e.mcp?.servers}},preferences:{...t.preferences,...e.preferences},usage:{...t.usage,...e.usage,budget:{...t.usage?.budget,...e.usage?.budget},pricing:{...t.usage?.pricing,...e.usage?.pricing}},permissions:{filesystem:{...t.permissions?.filesystem,...e.permissions?.filesystem},shell:{...t.permissions?.shell,...e.permissions?.shell},git:{...t.permissions?.git,...e.permissions?.git},network:{...t.permissions?.network,...e.permissions?.network},mcp:{...t.permissions?.mcp,...e.permissions?.mcp},subagents:{...t.permissions?.subagents,...e.permissions?.subagents}}}}async function we(t){await Wt(t);let e=D.join($i(),".config","kpilot","config.json"),n=D.join(t,E,"config.json");return $d(await Jr(e),await Jr(n))}function _d(t,e){let n={filesystem:{...ce.filesystem,...t?.filesystem},shell:{...ce.shell,...t?.shell},git:{...ce.git,...t?.git},network:{...ce.network,...t?.network},mcp:{...ce.mcp,...t?.mcp},subagents:{...ce.subagents,...t?.subagents}};for(let r of["filesystem","shell","git","network","mcp","subagents"]){let o=e?.permissions?.[r]??{},s=n[r];for(let[i,a]of Object.entries(o))i in s&&(s[i]=vn(s[i],a))}return e?.requireNetworkIsolation&&(n.network=di(n.network,!0)),n}function Cn(t,e){let n=["dailyInputTokens","dailyOutputTokens","dailyTotalTokens","perRunTotalTokens","dailyEstimatedCostUsd"],r={};for(let o of n){let s=[t?.[o],e?.[o]].filter(i=>typeof i=="number"&&i>0);s.length&&(r[o]=Math.min(...s))}return r.warnAtPercent=Math.min(t?.warnAtPercent??80,e?.warnAtPercent??80),r}function nt(t,e,n){let r=e.model?.provider==="external-agent"?"external-agent":"kpilot-hosted";Je(r);let o=e.preferences?.minimumConfidence??.55;if(o<0||o>1)throw new Error("preferences.minimumConfidence must be between 0 and 1.");let s=t.mode??e.agent?.mode??"write",i=t.maxSteps??e.agent?.maxSteps,a=t.model??process.env.KPILOT_MODEL??e.model?.model??"auto";ui({policy:n,mode:s,model:a,maxSteps:i,sandboxMode:e.sandbox?.mode??"portable",allowNetwork:e.sandbox?.allowNetwork??!1});let c={provider:r,model:a,baseUrl:e.model?.baseUrl,streaming:e.model?.streaming??!0,timeoutMs:e.model?.timeoutMs,retries:e.model?.retries,headers:e.model?.headers,region:e.model?.region,project:e.model?.project,location:e.model?.location,credentialCommand:e.model?.credentialCommand,command:e.model?.command,commandArgs:e.model?.commandArgs,endpoint:e.model?.endpoint,route:e.model?.route,rootDir:t.cwd};return{mode:s,maxSteps:i,provider:r,baseUrl:c.baseUrl??"",model:a,apiKeyEnv:"",apiKey:void 0,accessTokenEnv:"",accessToken:void 0,modelConfig:c,minimumPreferenceConfidence:o,streaming:c.streaming??!0,usageBudget:Cn(e.usage?.budget,n?.usage),modelPrice:void 0,policy:n,showModel:e.ui?.showModel===!0,verifyCommand:e.agent?.verifyCommand?.trim()||void 0,autoCompactTokens:e.agent?.autoCompactTokens}}function re(t){return{sessions:new sn(t),memory:new zt(t),todos:new Yt(t),checkpoints:new Xt(t),skills:new an(t),preferences:new on(t),audit:new fn(t),usage:new hn(t),policy:new je(t)}}async function W(t){if(!(await Ci(t)).isDirectory())throw new Error(`${t} is not a directory.`);await wd(t),await Wt(t)}async function Ad(t,e){let n=D.join(t,".gitignore"),r=await tt(n)?await Vr(n,"utf8"):"",o=new Set(r.split(/\r?\n/).filter(Boolean)),s=e.filter(a=>!o.has(a));if(s.length===0)return;let i=r&&!r.endsWith(`
323
+ `}function ae(t,e,n){let r=t[e+1];if(!r||r.startsWith("--"))throw new Error(`${n} requires a value.`);return[r,e+1]}function Wd(t){let e={command:"run",prompt:"",args:[],cwd:process.cwd(),yes:!1,bypassPermissions:!1,debug:!1,force:!1,passphraseEnv:"KPILOT_SYNC_PASSPHRASE",includeSessions:!1,overwrite:!1,limit:50,noCloudSync:!1,noBrowser:!1},n=[],r=!1,o=["run","chat","init","doctor","login","logout","whoami","models","agents","sessions","memory","skills","preferences","feedback","mcp","worktrees","policy","usage","audit","sync","admin","help","version"];for(let s=0;s<t.length;s+=1){let i=t[s]??"";if(i==="--"){n.push(...t.slice(s+1));break}if(i==="-h"||i==="--help"){e.command="help",r=!0;continue}if(i==="-V"||i==="--version"){e.command="version",r=!0;continue}if(i.startsWith("--")&&!i.includes("=")){let a=i.slice(2);if(o.includes(a)){e.command=a,r=!0;continue}}if(i==="--yes"||i==="-y"){e.yes=!0;continue}if($o(i)){e.bypassPermissions=!0,i==="--force"&&(e.force=!0);continue}if(i==="--permission-mode"){let[a,c]=ae(t,s,i);e.bypassPermissions=_o(a),s=c;continue}if(i==="--debug"){e.debug=!0;continue}if(i==="--include-sessions"){e.includeSessions=!0;continue}if(i==="--overwrite"){e.overwrite=!0;continue}if(i==="--no-cloud-sync"){e.noCloudSync=!0;continue}if(i==="--no-browser"){e.noBrowser=!0;continue}if(i==="--cwd"){let[a,c]=ae(t,s,i);e.cwd=L.resolve(a),s=c;continue}if(i==="--mode"){let[a,c]=ae(t,s,i);if(a!=="plan"&&a!=="write")throw new Error("--mode must be plan or write.");e.mode=a,s=c;continue}if(i==="--session"){let[a,c]=ae(t,s,i);e.session=a,s=c;continue}if(i==="--title"){let[a,c]=ae(t,s,i);e.title=a,s=c;continue}if(i==="--note"){let[a,c]=ae(t,s,i);e.note=a,s=c;continue}if(i==="--model"){let[a,c]=ae(t,s,i);e.model=a,s=c;continue}if(i==="--passphrase-env"){let[a,c]=ae(t,s,i);e.passphraseEnv=a,s=c;continue}if(i==="--control-plane-url"){let[a,c]=ae(t,s,i);e.controlPlaneUrl=a,s=c;continue}if(i==="--organization"){let[a,c]=ae(t,s,i);e.organization=a,s=c;continue}if(i==="--limit"){let[a,c]=ae(t,s,i),l=Number(a);if(!Number.isInteger(l)||l<1||l>1e3)throw new Error("--limit must be between 1 and 1000.");e.limit=l,s=c;continue}if(i==="--max-steps"){let[a,c]=ae(t,s,i),l=Number(a);if(!Number.isInteger(l)||l<1||l>50)throw new Error("--max-steps must be an integer between 1 and 50.");e.maxSteps=l,s=c;continue}if(i.startsWith("-")){let a=i.replace(/^--?/,"");throw o.includes(a)?new Error(`Unknown option: ${i}. Use \`kpilot ${a}\` or \`kpilot --${a}\`.`):new Error(`Unknown option: ${i}`)}if(!r&&o.includes(i)){e.command=i,r=!0;continue}n.push(i)}return e.args=n,e.prompt=e.command==="run"?n.join(" ").trim():"",e.command==="run"&&!e.prompt&&(e.command="chat"),e}async function tt(t){try{return await Bi(t),!0}catch{return!1}}async function Vr(t){if(!await tt(t))return{};let e=await eo(t,"utf8");try{return JSON.parse(e)}catch(n){throw new Error(`Invalid JSON in ${t}: ${n instanceof Error?n.message:String(n)}`)}}function Gd(t,e){return{model:{...t.model,...e.model},agent:{...t.agent,...e.agent},sandbox:{...t.sandbox,...e.sandbox},subagents:{...t.subagents,...e.subagents},mcp:{...t.mcp,...e.mcp,servers:{...t.mcp?.servers,...e.mcp?.servers}},preferences:{...t.preferences,...e.preferences},usage:{...t.usage,...e.usage,budget:{...t.usage?.budget,...e.usage?.budget},pricing:{...t.usage?.pricing,...e.usage?.pricing}},permissions:{filesystem:{...t.permissions?.filesystem,...e.permissions?.filesystem},shell:{...t.permissions?.shell,...e.permissions?.shell},git:{...t.permissions?.git,...e.permissions?.git},network:{...t.permissions?.network,...e.permissions?.network},mcp:{...t.permissions?.mcp,...e.permissions?.mcp},subagents:{...t.permissions?.subagents,...e.permissions?.subagents}}}}async function we(t){await Vt(t);let e=L.join(Ki(),".config","kpilot","config.json"),n=L.join(t,E,"config.json");return Gd(await Vr(e),await Vr(n))}function Hd(t,e){let n={filesystem:{...le.filesystem,...t?.filesystem},shell:{...le.shell,...t?.shell},git:{...le.git,...t?.git},network:{...le.network,...t?.network},mcp:{...le.mcp,...t?.mcp},subagents:{...le.subagents,...t?.subagents}};for(let r of["filesystem","shell","git","network","mcp","subagents"]){let o=e?.permissions?.[r]??{},s=n[r];for(let[i,a]of Object.entries(o))i in s&&(s[i]=Tn(s[i],a))}return e?.requireNetworkIsolation&&(n.network=Pi(n.network,!0)),n}function An(t,e){let n=["dailyInputTokens","dailyOutputTokens","dailyTotalTokens","perRunTotalTokens","dailyEstimatedCostUsd"],r={};for(let o of n){let s=[t?.[o],e?.[o]].filter(i=>typeof i=="number"&&i>0);s.length&&(r[o]=Math.min(...s))}return r.warnAtPercent=Math.min(t?.warnAtPercent??80,e?.warnAtPercent??80),r}function nt(t,e,n){let r=e.model?.provider==="external-agent"?"external-agent":"kpilot-hosted";Je(r);let o=e.preferences?.minimumConfidence??.55;if(o<0||o>1)throw new Error("preferences.minimumConfidence must be between 0 and 1.");let s=t.mode??e.agent?.mode??"write",i=t.maxSteps??e.agent?.maxSteps,a=t.model??process.env.KPILOT_MODEL??e.model?.model??"auto";Ti({policy:n,mode:s,model:a,maxSteps:i,sandboxMode:e.sandbox?.mode??"portable",allowNetwork:e.sandbox?.allowNetwork??!1});let c={provider:r,model:a,baseUrl:e.model?.baseUrl,streaming:e.model?.streaming??!0,timeoutMs:e.model?.timeoutMs,retries:e.model?.retries,headers:e.model?.headers,region:e.model?.region,project:e.model?.project,location:e.model?.location,credentialCommand:e.model?.credentialCommand,command:e.model?.command,commandArgs:e.model?.commandArgs,endpoint:e.model?.endpoint,route:e.model?.route,rootDir:t.cwd};return{mode:s,maxSteps:i,provider:r,baseUrl:c.baseUrl??"",model:a,apiKeyEnv:"",apiKey:void 0,accessTokenEnv:"",accessToken:void 0,modelConfig:c,minimumPreferenceConfidence:o,streaming:c.streaming??!0,usageBudget:An(e.usage?.budget,n?.usage),modelPrice:void 0,policy:n,showModel:e.ui?.showModel===!0,verifyCommand:e.agent?.verifyCommand?.trim()||void 0,autoCompactTokens:e.agent?.autoCompactTokens}}function oe(t){return{sessions:new un(t),memory:new Xt(t),todos:new en(t),checkpoints:new nn(t),skills:new dn(t),preferences:new ln(t),audit:new yn(t),usage:new vn(t),policy:new je(t)}}async function G(t){if(!(await Bi(t)).isDirectory())throw new Error(`${t} is not a directory.`);await Od(t),await Vt(t)}async function zd(t,e){let n=L.join(t,".gitignore"),r=await tt(n)?await eo(n,"utf8"):"",o=new Set(r.split(/\r?\n/).filter(Boolean)),s=e.filter(a=>!o.has(a));if(s.length===0)return;let i=r&&!r.endsWith(`
312
324
  `)?`
313
- `:"";await tt(n)?await yd(n,`${i}${s.join(`
325
+ `:"";await tt(n)?await Id(n,`${i}${s.join(`
314
326
  `)}
315
- `,"utf8"):await ve(n,`${s.join(`
327
+ `,"utf8"):await ke(n,`${s.join(`
316
328
  `)}
317
- `,"utf8"),v(`Updated .gitignore with ${s.length} kpilot runtime path(s).`)}async function Od(t){await W(t);let e=D.join(t,E),n=D.join(e,"config.json"),r=D.join(e,"instructions.md"),o=D.join(e,"skills","review","SKILL.md");await et(D.dirname(o),{recursive:!0}),await tt(n)?_(`${D.relative(t,n)} already exists; left unchanged.`):(await ve(n,`${JSON.stringify({model:{provider:"kpilot-hosted",baseUrl:"https://api.konsolepilot.ai",model:"auto",route:"auto",streaming:!0},agent:{mode:"write"},sandbox:{mode:"portable",allowNetwork:!1,passEnvironment:[]},subagents:{enabled:!0,maxParallel:4},mcp:{servers:{}},preferences:{minimumConfidence:.55},usage:{pricing:{}},permissions:ce},null,2)}
318
- `,{encoding:"utf8",mode:384}),await En(n,384),v(`Created ${D.relative(t,n)}.`)),await tt(r)?_(`${D.relative(t,r)} already exists; left unchanged.`):(await ve(r,`# Project instructions
329
+ `,"utf8"),T(`Updated .gitignore with ${s.length} kpilot runtime path(s).`)}async function Vd(t){await G(t);let e=L.join(t,E),n=L.join(e,"config.json"),r=L.join(e,"instructions.md"),o=L.join(e,"skills","review","SKILL.md");await et(L.dirname(o),{recursive:!0}),await tt(n)?A(`${L.relative(t,n)} already exists; left unchanged.`):(await ke(n,`${JSON.stringify({model:{provider:"kpilot-hosted",baseUrl:"https://api.konsolepilot.ai",model:"auto",route:"auto",streaming:!0},agent:{mode:"write"},sandbox:{mode:"portable",allowNetwork:!1,passEnvironment:[]},subagents:{enabled:!0,maxParallel:4},mcp:{servers:{}},preferences:{minimumConfidence:.55},usage:{pricing:{}},permissions:le},null,2)}
330
+ `,{encoding:"utf8",mode:384}),await $n(n,384),T(`Created ${L.relative(t,n)}.`)),await tt(r)?A(`${L.relative(t,r)} already exists; left unchanged.`):(await ke(r,`# Project instructions
319
331
 
320
332
  - Follow the repository's existing architecture and naming conventions.
321
333
  - Do not introduce placeholder implementations.
322
334
  - Run relevant tests after code changes.
323
- `,"utf8"),v(`Created ${D.relative(t,r)}.`)),await tt(o)||(await ve(o,`---
335
+ `,"utf8"),T(`Created ${L.relative(t,r)}.`)),await tt(o)||(await ke(o,`---
324
336
  name: review
325
337
  description: Inspect a change for correctness, safety, and missing validation.
326
338
  ---
327
339
  Inspect the relevant implementation and its diff. Prioritize correctness defects, security problems, regressions, missing tests, and inaccurate claims. Report findings by severity with exact file references. Do not modify files unless the invocation explicitly requests fixes.
328
- `,"utf8"),v(`Created ${D.relative(t,o)}.`)),await Ad(t,[`${E}/sessions/`,`${E}/memory.json`,`${E}/preferences.json`,`${E}/todos.json`,`${E}/checkpoints/`,`${E}/audit/`,`${E}/usage/`,`${E}/run/`,`${E}/cache/`,`${E}/logbook/meta.json`]),$(`kpilot ${z} initialized. Connect your account with \`kpilot login\`; bring your own agent via \`kpilot agents\`.`),$("Log in with `kpilot login` and kpilot handles the rest."),$("On first chat, kpilot can inspect the repo and save a Logbook entry under `.kpilot/logbook/project.md`.")}async function Id(t){let e=t.args[0]??"routes";if(e==="routes"||e==="list"||e==="show"){let n=await Kr();if(!n.length){console.log("No kpilot capabilities are configured for this account yet.");return}console.log(j(I.bold,"kpilot capabilities"));for(let r of n){let o=r.isDefault?"default":r.routeKeys.length?`routes: ${r.routeKeys.join(", ")}`:"available";console.log(`${r.model.padEnd(52)} ${r.provider} ${j(I.dim,o)}`)}console.log("For help, contact your kpilot administrator.");return}if(e==="route"){let n=t.args.slice(1).join(" ").trim();if(!n)throw new Error("Usage: kpilot models route <prompt>");let r=tn(n),s=(await Kr()).find(i=>i.routeKeys.includes(r.route))?.model??null;console.log(JSON.stringify({...r,selected:s},null,2));return}throw new Error("Usage: kpilot models [routes|route] [prompt]")}async function Kr(){let e=await new se().validAccessToken();if(!e)throw new Error("kpilot needs an account. Run `kpilot login`.");let n=await e.client.catalog(e.tokens.accessToken),r=new Map;for(let[o,s]of Object.entries(n.routeCandidates??{}))for(let i of s){let a=r.get(i.model)??{provider:i.provider,isDefault:i.isDefault,routeKeys:[]};a.routeKeys.includes(o)||a.routeKeys.push(o),i.isDefault&&(a.isDefault=!0),r.set(i.model,a)}return[...r.entries()].map(([o,s])=>({model:o,provider:s.provider,isDefault:s.isDefault,routeKeys:s.routeKeys}))}async function Di(t){await W(t.cwd);let e=D.join(t.cwd,E,"config.json"),n=await Jr(e),r=t.args[0]??"show";if(r==="show"){if(n.model?.provider!=="external-agent"){console.log("[no project external agent configured]");return}console.log(JSON.stringify({provider:n.model.provider,command:n.model.command,commandArgs:n.model.commandArgs,endpoint:n.model.endpoint,timeoutMs:n.model.timeoutMs},null,2));return}if(r==="use-http"){let o=t.args[1];if(!o)throw new Error("Usage: kpilot agents use-http <http-or-https-endpoint>");let s=new URL(o);if(!["http:","https:"].includes(s.protocol))throw new Error("External-agent endpoint must use HTTP or HTTPS.");let i=n.model??{},{command:a,commandArgs:c,endpoint:l,...u}=i;n.model={...u,provider:"external-agent",model:"external-agent",endpoint:s.toString()},await et(D.dirname(e),{recursive:!0}),await ve(e,`${JSON.stringify(n,null,2)}
329
- `,{encoding:"utf8",mode:384}),await En(e,384),v(`Configured project external agent endpoint ${s.toString()}.`);return}if(r==="use-command"){let o=t.args[1];if(!o)throw new Error("Usage: kpilot agents use-command <executable> [args...]");let s=n.model??{},{command:i,commandArgs:a,endpoint:c,...l}=s;n.model={...l,provider:"external-agent",model:"external-agent",command:o,commandArgs:t.args.slice(2)},await et(D.dirname(e),{recursive:!0}),await ve(e,`${JSON.stringify(n,null,2)}
330
- `,{encoding:"utf8",mode:384}),await En(e,384),v(`Configured project external agent command ${o}.`);return}if(r==="clear"){n.model={provider:"kpilot-hosted",baseUrl:"https://api.konsolepilot.ai",model:"auto",route:"auto",streaming:!0},await et(D.dirname(e),{recursive:!0}),await ve(e,`${JSON.stringify(n,null,2)}
331
- `,{encoding:"utf8",mode:384}),await En(e,384),v("Removed the project external agent and restored kpilot automatic routing.");return}throw new Error("Usage: kpilot agents [show|use-http|use-command|clear] [endpoint-or-command] [args...]")}async function qr(t){return await new Promise(e=>{let n=process.platform==="win32"?"where":"sh",r=process.platform==="win32"?[t]:["-lc",`command -v "${t}" >/dev/null 2>&1`],o=_i(n,r,{stdio:"ignore"});o.once("error",()=>e(!1)),o.once("close",s=>e(s===0))})}async function Dd(t){await W(t.cwd);let e=await we(t.cwd),n=re(t.cwd),r=await n.policy.load(),o=nt(t,e,r),s=0,i=Number(process.version.slice(1).split(".")[0]);console.log(j(I.bold,`kpilot doctor \u2014 ${t.cwd}`)),i>=26?v(`Node.js ${process.version}`):(q(`Node.js ${process.version}; Node.js 26 or newer is required.`),s+=1),await qr("git")?v("Git is available."):_("Git is unavailable; status, diff, and feedback evidence will be limited."),await qr("rg")?v("ripgrep is available."):_("ripgrep is unavailable; search_text will use the slower built-in fallback.");let a=o.model&&o.model!=="auto"?`kpilot capability: ${o.model}`:"kpilot automatic routing (kpilot chooses for you).";v(a);let c=Je(o.provider);v(`Authenticated: ${c.name} (${c.id}).`),o.provider==="kpilot-hosted"?await new se().load()?v("Your kpilot account is connected."):(q("kpilot needs an account. Run `kpilot login`."),s+=1):o.provider==="external-agent"&&(o.modelConfig.endpoint?v(`External agent endpoint configured: ${o.modelConfig.endpoint}`):o.modelConfig.command&&await qr(o.modelConfig.command)?v(`External agent command is available: ${o.modelConfig.command}`):(q("External agent requires a reachable endpoint or available command."),s+=1)),v(`${(await n.sessions.list()).length} persistent session(s) readable.`),v(`${(await n.memory.list()).length} project memory entr${(await n.memory.list()).length===1?"y":"ies"} readable.`),v(`${(await n.skills.list()).length} reusable skill(s) discovered.`),v(`${(await n.preferences.listRules()).length} learned preference rule(s) readable.`),r?v(`Team policy loaded${r.organization?` for ${r.organization}`:""}.`):$("Team policy: not configured.");let l=await n.usage.check(o.usageBudget);l.allowed?v(`Usage budget available: ${ue(l.summary.totalTokens)} token(s) used today.`):(q(`Usage budget blocked: ${l.violations.join(" ")}`),s+=1);let u=await n.audit.verify();u.valid?v(`Audit chain valid: ${u.records} record(s).`):(q(`Audit chain invalid: ${u.reason??"unknown failure"}`),s+=1);let m=new ye(t.cwd,{sandbox:e.sandbox});try{v(`Sandbox: ${await m.sandbox.describe()}.`)}catch(w){q(w instanceof Error?w.message:String(w)),s+=1}let d=Object.entries(e.mcp?.servers??{}).filter(([w,x])=>x.enabled!==!1&&(!r?.allowedMcpServers||r.allowedMcpServers.includes(w)));if(d.length===0)$("MCP: no enabled servers configured.");else try{let w=await Ae.connect(Object.fromEntries(d));v(`MCP: ${d.length} server(s), ${w.list().length} tool(s) available.`),await w.close()}catch(w){q(`MCP: ${w instanceof Error?w.message:String(w)}`),s+=1}o.baseUrl&&$(`Endpoint: ${o.baseUrl}`);let f=o.maxSteps===void 0?"unlimited":String(o.maxSteps);return $(`Mode: ${o.mode}; max steps: ${f}; streaming: ${o.streaming?"on":"off"}`),s===0?0:1}var Wr;function he(){Wr?.stop(),Wr=void 0}function jd(t){return t?`kpilot (${t})`:"kpilot"}function Mn(t){return j(I.green,jd(t))}function Ze(t){t.lineOpen&&(process.stdout.write(`
332
- `),t.lineOpen=!1)}function Ti(t,e,n,r){let o=Mn(n);return s=>{if((s.type==="assistant_delta"||s.type==="assistant_text"||s.type==="tool_start"||s.type==="tool_output"||s.type==="permission"||s.type==="cancelled")&&(he(),e.thinking=void 0),s.type==="reasoning_delta"){r?.reasoningDelta(s.delta);return}if(s.type==="assistant_delta")r?.noteOutput(),e.lineOpen||(r?.clearReasoning(),he(),process.stdout.isTTY||process.stdout.write(`
333
- `),process.stdout.write(`${o} \u203A `),e.lineOpen=!0),e.streamed=!0,process.stdout.write(s.delta);else if(s.type==="tool_start")Ze(e),e.toolOutputLines=0,r?.clearReasoning(),r?.activity("start",s.call.function.name,In(s.args,s.call.function.name)),r?.start();else if(s.type==="tool_output"){let i=s.chunk.replace(/\s+$/,"");i&&e.toolOutputLines<20&&(Ze(e),process.stdout.write(`${j(I.dim,` \u2502 ${i.slice(0,160)}`)}
334
- `),e.toolOutputLines+=1,e.toolOutputLines===20&&process.stdout.write(`${j(I.dim," \u2502 \u2026 (output continues; full result on completion)")}
335
- `))}else if(s.type==="tool_result"){Ze(e);let i=s.result.ok?co(s.result.metadata):"";r?.activity("result",s.call.function.name,i,s.result.ok),(t||!s.result.ok)&&console.log(j(I.dim,s.result.output))}else s.type==="usage"?(e.inputTokens+=s.inputTokens,e.outputTokens+=s.outputTokens,e.cacheReadTokens+=s.cacheReadTokens??0,e.cacheWriteTokens+=s.cacheWriteTokens??0,r?.addUsage(s.inputTokens,s.outputTokens,s.cacheReadTokens??0)):s.type==="cancelled"&&(Ze(e),r?.finish(),_(s.reason))}}async function Yr(t){let e=new AbortController,n=()=>{st.noteStop("Ctrl+C"),e.abort(Fn())};process.once("SIGINT",n);let r=st.begin(e);try{return await t(e.signal)}finally{process.removeListener("SIGINT",n),r()}}function Ld(t){return`Approve ${t.category}?
340
+ `,"utf8"),T(`Created ${L.relative(t,o)}.`)),await zd(t,[`${E}/sessions/`,`${E}/memory.json`,`${E}/preferences.json`,`${E}/todos.json`,`${E}/checkpoints/`,`${E}/audit/`,`${E}/usage/`,`${E}/run/`,`${E}/cache/`,`${E}/logbook/meta.json`]),$(`kpilot ${V} initialized. Connect your account with \`kpilot login\`; bring your own agent via \`kpilot agents\`.`),$("Log in with `kpilot login` and kpilot handles the rest."),$("On first chat, kpilot can inspect the repo and save a Logbook entry under `.kpilot/logbook/project.md`.")}async function Yd(t){let e=t.args[0]??"routes";if(e==="routes"||e==="list"||e==="show"){let n=await Yr();if(!n.length){console.log("No kpilot capabilities are configured for this account yet.");return}console.log(U(D.bold,"kpilot capabilities"));for(let r of n){let o=r.isDefault?"default":r.routeKeys.length?`routes: ${r.routeKeys.join(", ")}`:"available";console.log(`${r.model.padEnd(52)} ${r.provider} ${U(D.dim,o)}`)}console.log("For help, contact your kpilot administrator.");return}if(e==="route"){let n=t.args.slice(1).join(" ").trim();if(!n)throw new Error("Usage: kpilot models route <prompt>");let r=sn(n),s=(await Yr()).find(i=>i.routeKeys.includes(r.route))?.model??null;console.log(JSON.stringify({...r,selected:s},null,2));return}throw new Error("Usage: kpilot models [routes|route] [prompt]")}async function Yr(){let e=await new ie().validAccessToken();if(!e)throw new Error("kpilot needs an account. Run `kpilot login`.");let n=await e.client.catalog(e.tokens.accessToken),r=new Map;for(let[o,s]of Object.entries(n.routeCandidates??{}))for(let i of s){let a=r.get(i.model)??{provider:i.provider,isDefault:i.isDefault,routeKeys:[]};a.routeKeys.includes(o)||a.routeKeys.push(o),i.isDefault&&(a.isDefault=!0),r.set(i.model,a)}return[...r.entries()].map(([o,s])=>({model:o,provider:s.provider,isDefault:s.isDefault,routeKeys:s.routeKeys}))}async function Vi(t){await G(t.cwd);let e=L.join(t.cwd,E,"config.json"),n=await Vr(e),r=t.args[0]??"show";if(r==="show"){if(n.model?.provider!=="external-agent"){console.log("[no project external agent configured]");return}console.log(JSON.stringify({provider:n.model.provider,command:n.model.command,commandArgs:n.model.commandArgs,endpoint:n.model.endpoint,timeoutMs:n.model.timeoutMs},null,2));return}if(r==="use-http"){let o=t.args[1];if(!o)throw new Error("Usage: kpilot agents use-http <http-or-https-endpoint>");let s=new URL(o);if(!["http:","https:"].includes(s.protocol))throw new Error("External-agent endpoint must use HTTP or HTTPS.");let i=n.model??{},{command:a,commandArgs:c,endpoint:l,...u}=i;n.model={...u,provider:"external-agent",model:"external-agent",endpoint:s.toString()},await et(L.dirname(e),{recursive:!0}),await ke(e,`${JSON.stringify(n,null,2)}
341
+ `,{encoding:"utf8",mode:384}),await $n(e,384),T(`Configured project external agent endpoint ${s.toString()}.`);return}if(r==="use-command"){let o=t.args[1];if(!o)throw new Error("Usage: kpilot agents use-command <executable> [args...]");let s=n.model??{},{command:i,commandArgs:a,endpoint:c,...l}=s;n.model={...l,provider:"external-agent",model:"external-agent",command:o,commandArgs:t.args.slice(2)},await et(L.dirname(e),{recursive:!0}),await ke(e,`${JSON.stringify(n,null,2)}
342
+ `,{encoding:"utf8",mode:384}),await $n(e,384),T(`Configured project external agent command ${o}.`);return}if(r==="clear"){n.model={provider:"kpilot-hosted",baseUrl:"https://api.konsolepilot.ai",model:"auto",route:"auto",streaming:!0},await et(L.dirname(e),{recursive:!0}),await ke(e,`${JSON.stringify(n,null,2)}
343
+ `,{encoding:"utf8",mode:384}),await $n(e,384),T("Removed the project external agent and restored kpilot automatic routing.");return}throw new Error("Usage: kpilot agents [show|use-http|use-command|clear] [endpoint-or-command] [args...]")}async function zr(t){return await new Promise(e=>{let n=process.platform==="win32"?"where":"sh",r=process.platform==="win32"?[t]:["-lc",`command -v "${t}" >/dev/null 2>&1`],o=Wi(n,r,{stdio:"ignore"});o.once("error",()=>e(!1)),o.once("close",s=>e(s===0))})}async function Qd(t){await G(t.cwd);let e=await we(t.cwd),n=oe(t.cwd),r=await n.policy.load(),o=nt(t,e,r),s=0,i=Number(process.version.slice(1).split(".")[0]);console.log(U(D.bold,`kpilot doctor \u2014 ${t.cwd}`)),i>=26?T(`Node.js ${process.version}`):(J(`Node.js ${process.version}; Node.js 26 or newer is required.`),s+=1),await zr("git")?T("Git is available."):A("Git is unavailable; status, diff, and feedback evidence will be limited."),await zr("rg")?T("ripgrep is available."):A("ripgrep is unavailable; search_text will use the slower built-in fallback.");let a=o.model&&o.model!=="auto"?`kpilot capability: ${o.model}`:"kpilot automatic routing (kpilot chooses for you).";T(a);let c=Je(o.provider);T(`Authenticated: ${c.name} (${c.id}).`),o.provider==="kpilot-hosted"?await new ie().load()?T("Your kpilot account is connected."):(J("kpilot needs an account. Run `kpilot login`."),s+=1):o.provider==="external-agent"&&(o.modelConfig.endpoint?T(`External agent endpoint configured: ${o.modelConfig.endpoint}`):o.modelConfig.command&&await zr(o.modelConfig.command)?T(`External agent command is available: ${o.modelConfig.command}`):(J("External agent requires a reachable endpoint or available command."),s+=1)),T(`${(await n.sessions.list()).length} persistent session(s) readable.`),T(`${(await n.memory.list()).length} project memory entr${(await n.memory.list()).length===1?"y":"ies"} readable.`),T(`${(await n.skills.list()).length} reusable skill(s) discovered.`),T(`${(await n.preferences.listRules()).length} learned preference rule(s) readable.`),r?T(`Team policy loaded${r.organization?` for ${r.organization}`:""}.`):$("Team policy: not configured.");let l=await n.usage.check(o.usageBudget);l.allowed?T(`Usage budget available: ${de(l.summary.totalTokens)} token(s) used today.`):(J(`Usage budget blocked: ${l.violations.join(" ")}`),s+=1);let u=await n.audit.verify();u.valid?T(`Audit chain valid: ${u.records} record(s).`):(J(`Audit chain invalid: ${u.reason??"unknown failure"}`),s+=1);let m=new be(t.cwd,{sandbox:e.sandbox});try{T(`Sandbox: ${await m.sandbox.describe()}.`)}catch(y){J(y instanceof Error?y.message:String(y)),s+=1}let d=Object.entries(e.mcp?.servers??{}).filter(([y,S])=>S.enabled!==!1&&(!r?.allowedMcpServers||r.allowedMcpServers.includes(y)));if(d.length===0)$("MCP: no enabled servers configured.");else try{let y=await Ae.connect(Object.fromEntries(d));T(`MCP: ${d.length} server(s), ${y.list().length} tool(s) available.`),await y.close()}catch(y){J(`MCP: ${y instanceof Error?y.message:String(y)}`),s+=1}o.baseUrl&&$(`Endpoint: ${o.baseUrl}`);let p=o.maxSteps===void 0?"unlimited":String(o.maxSteps);return $(`Mode: ${o.mode}; max steps: ${p}; streaming: ${o.streaming?"on":"off"}`),s===0?0:1}var rt;function ot(){rt?.stop(),rt=void 0}function st(){rt?.dispose(),rt=void 0}function Xd(t){return t?`kpilot (${t})`:"kpilot"}function On(t){return U(D.green,Xd(t))}function Ze(t){t.lineOpen&&(process.stdout.write(`
344
+ `),t.lineOpen=!1)}function Ui(t,e,n,r){let o=On(n);return s=>{if((s.type==="assistant_delta"||s.type==="assistant_text"||s.type==="tool_start"||s.type==="tool_output"||s.type==="permission"||s.type==="cancelled")&&(ot(),e.thinking=void 0),s.type==="reasoning_delta"){r?.reasoningDelta(s.delta,!e.lineOpen);return}if(s.type==="assistant_delta"){if(r?.noteOutput(),!e.lineOpen){r?.clearReasoning(),ot(),process.stdout.isTTY||process.stdout.write(`
345
+ `);let i=bo(e,o);i&&(process.stdout.write(i),e.speakerShown=!0),e.lineOpen=!0}e.streamed=!0,process.stdout.write(s.delta)}else if(s.type==="tool_start")Ze(e),e.toolOutputLines=0,r?.clearReasoning(),r?.activity("start",s.call.function.name,Nn(s.args,s.call.function.name)),r?.start(),e.thinking=r,rt=r;else if(s.type==="tool_output"){let i=s.chunk.replace(/\s+$/,"");i&&e.toolOutputLines<20&&(Ze(e),process.stdout.write(`${U(D.dim,` \u2502 ${i.slice(0,160)}`)}
346
+ `),e.toolOutputLines+=1,e.toolOutputLines===20&&process.stdout.write(`${U(D.dim," \u2502 \u2026 (output continues; full result on completion)")}
347
+ `))}else if(s.type==="tool_result"){Ze(e);let i=s.result.ok?go(s.result.metadata):"";r?.activity("result",s.call.function.name,i,s.result.ok),(t||!s.result.ok)&&console.log(U(D.dim,s.result.output))}else s.type==="usage"?(e.inputTokens+=s.inputTokens,e.outputTokens+=s.outputTokens,e.cacheReadTokens+=s.cacheReadTokens??0,e.cacheWriteTokens+=s.cacheWriteTokens??0,r?.addUsage(s.inputTokens,s.outputTokens,s.cacheReadTokens??0)):s.type==="cancelled"&&(Ze(e),r?.dispose(),A(s.reason))}}async function to(t){let e=new AbortController,n=()=>{ct.noteStop("Ctrl+C"),e.abort(Gn())};process.once("SIGINT",n);let r=ct.begin(e);try{return await t(e.signal)}finally{process.removeListener("SIGINT",n),r()}}function Zd(t){return`Approve ${t.category}?
336
348
  ${t.summary}
337
- ${t.reason}`}function ji(t,e,n){let r=new Set;return async o=>{if(t.yes||r.has(o.category))return!0;if(!e||!process.stdin.isTTY)return!1;he(),console.log(""),console.log(Ld(o));let s=await Q({title:"Permission action:",question:e,pauseResume:n,choices:[{value:"yes",label:"yes",description:"Allow this action once",aliases:["y"],default:!0},{value:"no",label:"no",description:"Deny this action",aliases:["n"]},{value:"always",label:"always",description:"Allow this category for the rest of the session",aliases:["a"]}]});return s==="always"?(r.add(o.category),!0):s==="yes"}}function Ud(t){return async e=>e.category==="filesystem.read"||e.category==="git.read"||e.category==="filesystem.write"&&xi(e.summary)?!0:t(e)}async function Li(t){$("Inspecting the repository and writing `.kpilot/logbook/project.md`\u2026");let e=t.cli.mode,n=t.created.settings.mode;t.cli.mode="write",t.created.settings.mode="write";let r=D.relative(t.cli.cwd,Ye(t.cli.cwd))||".kpilot/logbook/project.md";try{try{let o=await Yr(s=>Qr({cli:t.cli,created:t.created,services:t.services,session:t.session,prompt:Sn,approvalHandler:Ud(t.approvalHandler),signal:s}));o.streamed||console.log(`
338
- ${Mn(t.created.settings.showModel?t.created.settings.model:void 0)} \u203A ${o.answer}`)}catch(o){if(await Xe(t.cli.cwd)){let s=o instanceof Error?o.message:String(o);_(`Model call failed after Logbook write (${s}). Using the saved entry.`)}else{if(rt(o))throw o;if(Dr(o))_("Hub context is too small for a full agent Logbook pass; writing a lite entry from repo metadata\u2026"),await Ir(t.cli.cwd);else throw o}}return await Xe(t.cli.cwd)?(v(`Logbook project entry saved to ${r}`),$("Later turns will load this Logbook entry instead of rediscovering the repo from scratch. Refresh with /logbook"),!0):(_("Onboarding finished but `.kpilot/logbook/project.md` was not found. Ask the agent to write it, or run /logbook again."),!1)}catch(o){if(rt(o))return _("Logbook onboarding stopped."),!1;let s=o instanceof Error?o.message:String(o);if(Dr(o)||/fetch failed|unreachable/i.test(s))try{return _(`Agent Logbook pass failed (${s}). Falling back to lite capture\u2026`),await Ir(t.cli.cwd),v(`Logbook lite entry saved to ${r}`),$("Re-run /logbook later if you want a richer brief with a larger-context model."),!0}catch(i){return q(`Logbook capture failed: ${s}`),_(`Lite fallback also failed: ${i instanceof Error?i.message:String(i)}`),!1}return q(`Logbook capture failed: ${s}`),$("You can retry with /logbook, or continue chatting without a Logbook entry."),!1}finally{t.cli.mode=e,t.created.settings.mode=n}}async function Nd(t){try{if(await Xe(t.cli.cwd)){await hi(t.cli.cwd)&&_("Logbook entry is over a week old; run /logbook to refresh it if the project has changed."),await It(t);return}if(!await wi(t.cli.cwd)){await It(t);return}if(!process.stdin.isTTY)return;console.log(""),$("This repository has no Logbook project entry yet.");let e=await Q({title:"Save a Logbook entry under .kpilot/logbook/project.md for later sessions?",question:t.question,pauseResume:t.pauseResume,choices:[{value:"yes",label:"yes",description:"Inspect the repo and write project.md",aliases:["y"],default:!0},{value:"no",label:"no",description:"Skip for now (can run /logbook later)",aliases:["n"]},{value:"skip",label:"skip",description:"Do not auto-offer again"}]});if(e==="no"||e==="skip"){await Lr(t.cli.cwd),$("Skipped. You can run /logbook later."),await It(t);return}if(e!=="yes"){$("Skipped. You can run /logbook later."),await It(t);return}await Ur(t.cli.cwd),await Li(t),await It(t)}catch(e){let n=e instanceof Error?e.message:String(e);_(`Logbook onboarding interrupted: ${n}`),$("Continuing into chat. Retry later with /logbook.")}}async function It(t){if(!await bi(t.cli.cwd)){await At(t.cli.cwd)&&$("Logbook learning is on (.kpilot/logbook/learnings.md). Toggle with /learn off");return}if(!process.stdin.isTTY)return;if(console.log(""),$("Optional: keep learning durable project facts from chats to speed up later work."),await Q({title:"Enable continuous Logbook learning (.kpilot/logbook/learnings.md)?",question:t.question,pauseResume:t.pauseResume,choices:[{value:"yes",label:"yes",description:"Append durable facts from chats",aliases:["y"]},{value:"no",label:"no",description:"Leave learning off",aliases:["n"],default:!0}]})==="yes"){await Ot(t.cli.cwd,!0),v("Logbook learning enabled. Facts from chats will append to .kpilot/logbook/learnings.md");return}await Ot(t.cli.cwd,!1),$("Logbook learning left off. Enable later with /learn on")}async function Fd(t,e,n){if(!t.route&&!t.model)return n;if(e.provider!=="kpilot-hosted")throw new Error(`Provider ${e.provider} cannot resolve per-task subagent routes in hosted-only mode.`);let{gateway:r}=await en({...e.modelConfig,route:t.route??"auto",model:t.model??"auto"});return r}function Gr(t){let e=process.env.KPILOT_BROWSER?.trim().toLowerCase()||t.tools?.browser||"auto";return e==="on"?"on":e==="off"?"off":"auto"}async function Hr(t,e,n){let r=await new je(t.cwd).load(),o=nt(t,e,r);if(n&&(o.modelConfig.sessionId=n.id),!o.model)throw new Error("No capability configured. Use kpilot automatic routing.");if(o.provider==="kpilot-hosted"){await Xd(t);let f=new se,w=await f.load();if(!w)throw new Error("kpilot needs an account to continue. Run `kpilot login`.");let x=new le(t.controlPlaneUrl??w.controlPlaneUrl,`kpilot/${z}`),P=await f.validAccessToken(x);if(!P)throw new Error("kpilot needs an active account session. Run `kpilot login`.");o.modelConfig.accessToken=P.tokens.accessToken,o.modelConfig.baseUrl=t.controlPlaneUrl??P.tokens.controlPlaneUrl,o.baseUrl=o.modelConfig.baseUrl,o.modelConfig.getAccessToken=async()=>{let S=await f.validAccessToken(x);return S?(o.modelConfig.accessToken=S.tokens.accessToken,S.tokens.accessToken):o.modelConfig.accessToken}}let s=new ye(t.cwd,{sandbox:e.sandbox,browser:Gr(e)}),i=new Ke(_d(e.permissions,r)),{gateway:a}=await en(o.modelConfig),c=e.mcp?.servers??{},l=r?.allowedMcpServers?Object.fromEntries(Object.entries(c).filter(([f])=>r.allowedMcpServers.includes(f))):c,u=Object.values(l).some(f=>f.enabled!==!1)?await Ae.connect(l):void 0,m=e.subagents?.enabled===!1?void 0:new mn({rootDir:t.cwd,gateway:a,resolveGateway:f=>Fd(f,o,a),localRuntimeOptions:{sandbox:e.sandbox,browser:Gr(e)},maxParallel:e.subagents?.maxParallel,maxSteps:e.subagents?.maxSteps}),d=new vt([s,u,m]);return{agent:new Fe({gateway:a,runtime:d,permissions:i,initialMessages:n?.messages}),runtime:d,localRuntime:s,mcpRuntime:u,settings:o,close:async()=>{await u?.close()}}}async function Bd(t,e,n){return t.session?await e.load(t.session):await e.create({title:t.title,mode:n.mode,model:n.model})}function Ui(t){let e=process.env.KPILOT_CONTEXT_WINDOW?.trim();if(e&&/^\d+$/.test(e)){let n=Number(e);if(n>=1024&&n<=1e6)return n}}function Pi(t,e=12e4){if(t)return t.length<=e?t:`${t.slice(0,e)}
339
- [truncated ${t.length-e} characters]`}async function Rn(t,e,n,r){let o=await t.execute("git_diff",{},{rootDir:e,mode:n,signal:r});return o.ok?o.output:void 0}async function Ei(t,e,n){let r=await t.execute("shell",{command:`git checkout -- ${n.map(Co).join(" ")}`},{rootDir:e,mode:"write",signal:void 0});return{ok:r.ok,output:r.output}}async function qd(t,e,n,r){let o=r?await Fr(r):"",s=await t.memory.renderForPrompt(),i=await t.todos.renderForPrompt(),a=new Set(s.split(`
349
+ ${t.reason}`}function Yi(t,e,n){let r=new Set;return async o=>{if(t.yes||r.has(o.category))return!0;if(!e||!process.stdin.isTTY)return!1;ot(),console.log(""),console.log(Zd(o));let s=await Q({title:"Permission action:",question:e,pauseResume:n,choices:[{value:"yes",label:"yes",description:"Allow this action once",aliases:["y"],default:!0},{value:"no",label:"no",description:"Deny this action",aliases:["n"]},{value:"always",label:"always",description:"Allow this category for the rest of the session",aliases:["a"]}]});return s==="always"?(r.add(o.category),!0):s==="yes"}}function em(t){return async e=>e.category==="filesystem.read"||e.category==="git.read"||e.category==="filesystem.write"&&ji(e.summary)?!0:t(e)}async function Qi(t){$("Inspecting the repository and writing `.kpilot/logbook/project.md`\u2026");let e=t.cli.mode,n=t.created.settings.mode;t.cli.mode="write",t.created.settings.mode="write";let r=L.relative(t.cli.cwd,Ye(t.cli.cwd))||".kpilot/logbook/project.md";try{try{let o=await to(s=>no({cli:t.cli,created:t.created,services:t.services,session:t.session,prompt:Rn,approvalHandler:em(t.approvalHandler),skipSessionNaming:!0,signal:s}));o.streamed||console.log(`
350
+ ${On(t.created.settings.showModel?t.created.settings.model:void 0)} \u203A ${o.answer}`)}catch(o){if(await Xe(t.cli.cwd)){let s=o instanceof Error?o.message:String(o);A(`Model call failed after Logbook write (${s}). Using the saved entry.`)}else{if(it(o))throw o;if(qr(o))A("Hub context is too small for a full agent Logbook pass; writing a lite entry from repo metadata\u2026"),await Fr(t.cli.cwd);else throw o}}return await Xe(t.cli.cwd)?(T(`Logbook project entry saved to ${r}`),$("Later turns will load this Logbook entry instead of rediscovering the repo from scratch. Refresh with /logbook"),!0):(A("Onboarding finished but `.kpilot/logbook/project.md` was not found. Ask the agent to write it, or run /logbook again."),!1)}catch(o){if(it(o))return A("Logbook onboarding stopped."),!1;let s=o instanceof Error?o.message:String(o);if(qr(o)||/fetch failed|unreachable/i.test(s))try{return A(`Agent Logbook pass failed (${s}). Falling back to lite capture\u2026`),await Fr(t.cli.cwd),T(`Logbook lite entry saved to ${r}`),$("Re-run /logbook later if you want a richer brief with a larger-context model."),!0}catch(i){return J(`Logbook capture failed: ${s}`),A(`Lite fallback also failed: ${i instanceof Error?i.message:String(i)}`),!1}return J(`Logbook capture failed: ${s}`),$("You can retry with /logbook, or continue chatting without a Logbook entry."),!1}finally{t.cli.mode=e,t.created.settings.mode=n}}async function tm(t){try{if(await Xe(t.cli.cwd)){await $i(t.cli.cwd)&&A("Logbook entry is over a week old; run /logbook to refresh it if the project has changed."),await jt(t);return}if(!await _i(t.cli.cwd)){await jt(t);return}if(!process.stdin.isTTY)return;console.log(""),$("This repository has no Logbook project entry yet.");let e=await Q({title:"Save a Logbook entry under .kpilot/logbook/project.md for later sessions?",question:t.question,pauseResume:t.pauseResume,choices:[{value:"yes",label:"yes",description:"Inspect the repo and write project.md",aliases:["y"],default:!0},{value:"no",label:"no",description:"Skip for now (can run /logbook later)",aliases:["n"]},{value:"skip",label:"skip",description:"Do not auto-offer again"}]});if(e==="no"||e==="skip"){await Jr(t.cli.cwd),$("Skipped. You can run /logbook later."),await jt(t);return}if(e!=="yes"){$("Skipped. You can run /logbook later."),await jt(t);return}await Kr(t.cli.cwd),await Qi(t),await jt(t)}catch(e){let n=e instanceof Error?e.message:String(e);A(`Logbook onboarding interrupted: ${n}`),$("Continuing into chat. Retry later with /logbook.")}}async function jt(t){if(!await Oi(t.cli.cwd)){await It(t.cli.cwd)&&$("Logbook learning is on (.kpilot/logbook/learnings.md). Toggle with /learn off");return}if(!process.stdin.isTTY)return;if(console.log(""),$("Optional: keep learning durable project facts from chats to speed up later work."),await Q({title:"Enable continuous Logbook learning (.kpilot/logbook/learnings.md)?",question:t.question,pauseResume:t.pauseResume,choices:[{value:"yes",label:"yes",description:"Append durable facts from chats",aliases:["y"]},{value:"no",label:"no",description:"Leave learning off",aliases:["n"],default:!0}]})==="yes"){await Dt(t.cli.cwd,!0),T("Logbook learning enabled. Facts from chats will append to .kpilot/logbook/learnings.md");return}await Dt(t.cli.cwd,!1),$("Logbook learning left off. Enable later with /learn on")}async function nm(t,e,n){if(!t.route&&!t.model)return n;if(e.provider!=="kpilot-hosted")throw new Error(`Provider ${e.provider} cannot resolve per-task subagent routes in hosted-only mode.`);let{gateway:r}=await on({...e.modelConfig,route:t.route??"auto",model:t.model??"auto"});return r}function Qr(t){let e=process.env.KPILOT_BROWSER?.trim().toLowerCase()||t.tools?.browser||"auto";return e==="on"?"on":e==="off"?"off":"auto"}async function Xr(t,e,n){let r=await new je(t.cwd).load(),o=nt(t,e,r);if(n&&(o.modelConfig.sessionId=n.id),!o.model)throw new Error("No capability configured. Use kpilot automatic routing.");if(o.provider==="kpilot-hosted"){await pm(t);let p=new ie,y=await p.load();if(!y)throw new Error("kpilot needs an account to continue. Run `kpilot login`.");let S=new ue(t.controlPlaneUrl??y.controlPlaneUrl,`kpilot/${V}`),x=await p.validAccessToken(S);if(!x)throw new Error("kpilot needs an active account session. Run `kpilot login`.");o.modelConfig.accessToken=x.tokens.accessToken,o.modelConfig.baseUrl=t.controlPlaneUrl??x.tokens.controlPlaneUrl,o.baseUrl=o.modelConfig.baseUrl,o.modelConfig.getAccessToken=async()=>{let k=await p.validAccessToken(S);return k?(o.modelConfig.accessToken=k.tokens.accessToken,k.tokens.accessToken):o.modelConfig.accessToken}}let s=new be(t.cwd,{sandbox:e.sandbox,browser:Qr(e)}),i=new Ke(Hd(e.permissions,r)),{gateway:a}=await on(o.modelConfig),c=e.mcp?.servers??{},l=r?.allowedMcpServers?Object.fromEntries(Object.entries(c).filter(([p])=>r.allowedMcpServers.includes(p))):c,u=Object.values(l).some(p=>p.enabled!==!1)?await Ae.connect(l):void 0,m=e.subagents?.enabled===!1?void 0:new hn({rootDir:t.cwd,gateway:a,resolveGateway:p=>nm(p,o,a),localRuntimeOptions:{sandbox:e.sandbox,browser:Qr(e)},maxParallel:e.subagents?.maxParallel,maxSteps:e.subagents?.maxSteps}),d=new xt([s,u,m]);return{agent:new Fe({gateway:a,runtime:d,permissions:i,initialMessages:n?.messages}),runtime:d,localRuntime:s,mcpRuntime:u,settings:o,close:async()=>{await u?.close()}}}async function rm(t,e,n){return t.session?await e.load(t.session):await e.create({title:t.title,mode:n.mode,model:n.model})}function Xi(t){let e=process.env.KPILOT_CONTEXT_WINDOW?.trim();if(e&&/^\d+$/.test(e)){let n=Number(e);if(n>=1024&&n<=1e6)return n}}function Ni(t,e=12e4){if(t)return t.length<=e?t:`${t.slice(0,e)}
351
+ [truncated ${t.length-e} characters]`}async function _n(t,e,n,r){let o=await t.execute("git_diff",{},{rootDir:e,mode:n,signal:r});return o.ok?o.output:void 0}async function Fi(t,e,n){let r=await t.execute("shell",{command:`git checkout -- ${n.map(Lo).join(" ")}`},{rootDir:e,mode:"write",signal:void 0});return{ok:r.ok,output:r.output}}async function om(t,e,n,r){let o=r?await Gr(r):"",s=await t.memory.renderForPrompt(),i=await t.todos.renderForPrompt(),a=new Set(s.split(`
340
352
  `).map(u=>u.replace(/^[-*]\s*/,"").trim().toLowerCase()).filter(Boolean)),c=o.split(`
341
353
  `).filter(u=>{let m=u.replace(/^[-*]\s*/,"").trim().toLowerCase();return!m||!a.has(m)}).join(`
342
354
  `).trim();return{memoryContext:[s,c?`Logbook learnings (.kpilot/logbook):
@@ -344,26 +356,25 @@ ${c}`:"",i].filter(Boolean).join(`
344
356
 
345
357
  `),preferenceContext:await t.preferences.renderForPrompt(e.minimumPreferenceConfidence),skillContext:n?`${n.description}
346
358
 
347
- ${n.instructions}`:void 0}}async function Jd(t,e,n){try{let r=await t.execute("git_status",{},{rootDir:e,mode:n});if(!r.ok)return"";let o=r.output.split(/\r?\n/).filter(c=>c.trim()),i=(o.find(c=>c.startsWith("##"))??"").replace(/^##\s*/,"").split("...")[0]?.trim()||"(unknown)",a=o.filter(c=>!c.startsWith("##")).length;return`Git: branch ${i}, ${a} uncommitted change(s).`}catch{return""}}async function Qr(t){let e={streamed:!1,lineOpen:!1,inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0,toolOutputLines:0},n=new Date().toISOString(),r=[],o=new Ut({mode:t.created.settings.mode});e.thinking=o,Wr=o,o.start();try{await tm(t.cli);let s=Mi("sha256").update(t.prompt).digest("hex"),i=await t.services.usage.check(t.created.settings.usageBudget);for(let p of i.warnings)he(),_(`Usage budget: ${p}`);if(!i.allowed)throw he(),await t.services.audit.append({action:"agent.run",outcome:"denied",category:"usage",sessionId:t.session.id,details:{violations:i.violations}}),new Error(`Usage budget prevents this run: ${i.violations.join(" ")}`);await t.services.audit.append({action:"agent.run",outcome:"info",category:"agent",sessionId:t.session.id,details:{mode:t.created.settings.mode,model:t.created.settings.model,promptHash:s,promptLength:t.prompt.length}});let a=await Rn(t.created.localRuntime,t.cli.cwd,t.created.settings.mode,t.signal);t.onDiffBefore?.(a);let c=t.created.settings.autoCompactTokens;if(c&&t.created.agent.messages.length>2){let p=Math.ceil(t.created.agent.messages.reduce((g,k)=>{let h=typeof k.content=="string"?k.content.length:0,T=k.role==="assistant"?(k.tool_calls??[]).reduce((G,V)=>G+V.function.arguments.length,0):0;return g+h+T},0)/4);if(p>c){$(`Context ~${ue(p)} tokens; auto-compacting history\u2026`);try{await t.created.agent.compact(t.signal)}catch{_("Auto-compaction failed; continuing with full history.")}}}let l=await qd(t.services,t.created.settings,t.skill,t.cli.cwd),u=await Jd(t.created.localRuntime,t.cli.cwd,t.created.settings.mode),m=t.created.agent.messages.filter(p=>p.role==="user").length===0,d="";if(m){let p=await t.created.localRuntime.execute("workspace_summary",{},{rootDir:t.cli.cwd,mode:t.created.settings.mode});p.ok&&(d=`Workspace summary:
348
- ${p.output.slice(0,1500)}`)}let f=[u,l.memoryContext,l.skillContext,d].filter(Boolean).join(`
359
+ ${n.instructions}`:void 0}}async function sm(t,e,n){try{let r=await t.execute("git_status",{},{rootDir:e,mode:n});if(!r.ok)return"";let o=r.output.split(/\r?\n/).filter(c=>c.trim()),i=(o.find(c=>c.startsWith("##"))??"").replace(/^##\s*/,"").split("...")[0]?.trim()||"(unknown)",a=o.filter(c=>!c.startsWith("##")).length;return`Git: branch ${i}, ${a} uncommitted change(s).`}catch{return""}}async function no(t){let e={streamed:!1,lineOpen:!1,speakerShown:!1,inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0,toolOutputLines:0},n=new Date().toISOString(),r=[],o=new Ft({mode:t.created.settings.mode});e.thinking=o,rt=o,o.start();try{await hm(t.cli);let s=Ji("sha256").update(t.prompt).digest("hex"),i=await t.services.usage.check(t.created.settings.usageBudget);for(let g of i.warnings)ot(),A(`Usage budget: ${g}`);if(!i.allowed)throw ot(),await t.services.audit.append({action:"agent.run",outcome:"denied",category:"usage",sessionId:t.session.id,details:{violations:i.violations}}),new Error(`Usage budget prevents this run: ${i.violations.join(" ")}`);await t.services.audit.append({action:"agent.run",outcome:"info",category:"agent",sessionId:t.session.id,details:{mode:t.created.settings.mode,model:t.created.settings.model,promptHash:s,promptLength:t.prompt.length}});let a=await _n(t.created.localRuntime,t.cli.cwd,t.created.settings.mode,t.signal);t.onDiffBefore?.(a);let c=t.created.settings.autoCompactTokens;if(c&&t.created.agent.messages.length>2){let g=Math.ceil(t.created.agent.messages.reduce((b,v)=>{let O=typeof v.content=="string"?v.content.length:0,H=v.role==="assistant"?(v.tool_calls??[]).reduce((ce,te)=>ce+te.function.arguments.length,0):0;return b+O+H},0)/4);if(g>c){$(`Context ~${de(g)} tokens; auto-compacting history\u2026`);try{await t.created.agent.compact(t.signal)}catch{A("Auto-compaction failed; continuing with full history.")}}}let l=await om(t.services,t.created.settings,t.skill,t.cli.cwd),u=await sm(t.created.localRuntime,t.cli.cwd,t.created.settings.mode),m=t.created.agent.messages.filter(g=>g.role==="user").length===0,d="";if(m){let g=await t.created.localRuntime.execute("workspace_summary",{},{rootDir:t.cli.cwd,mode:t.created.settings.mode});g.ok&&(d=`Workspace summary:
360
+ ${g.output.slice(0,1500)}`)}let p=[u,l.memoryContext,l.skillContext,d].filter(Boolean).join(`
349
361
 
350
- `),w;try{let p=Ui(t.created.settings.provider);w=await t.created.agent.run({prompt:t.prompt,mode:t.created.settings.mode,rootDir:t.cli.cwd,maxSteps:t.created.settings.maxSteps,maxTotalTokens:t.created.settings.usageBudget.perRunTotalTokens,contextWindowTokens:p,approvalHandler:t.approvalHandler,bypassPermissions:t.bypassPermissions===!0,preferenceContext:l.preferenceContext,volatileContext:f,onEvent:g=>{r.push(g),Ti(t.cli.debug,e,t.created.settings.showModel?t.created.settings.model:void 0,o)(g)},signal:t.signal})}catch(p){if(he(),Ze(e),e.inputTokens||e.outputTokens){let g=await t.services.usage.record({model:t.created.settings.model,sessionId:t.session.id,inputTokens:e.inputTokens,outputTokens:e.outputTokens,price:t.created.settings.modelPrice});await Ri({cli:t.cli,provider:t.created.settings.provider,record:g,success:!1,durationMs:Date.now()-new Date(n).getTime()})}throw t.session.messages=[...t.created.agent.messages],await t.services.sessions.save(t.session),await t.services.audit.append({action:"agent.run",outcome:rt(p)?"cancelled":"failure",category:"agent",sessionId:t.session.id,details:{model:t.created.settings.model,inputTokens:e.inputTokens,outputTokens:e.outputTokens,error:p instanceof Error?p.message.slice(0,500):String(p).slice(0,500)}}),p}Ze(e);let x=await Rn(t.created.localRuntime,t.cli.cwd,t.created.settings.mode,t.signal),P=a!==x,S=0,C=0,b=t.created.settings.verifyCommand;if(P&&b&&t.created.settings.mode==="write"){$(`Verifying: ${b}`);let p=await t.created.localRuntime.execute("shell",{command:b},{rootDir:t.cli.cwd,mode:"write",signal:t.signal});if(p.ok)v("Verification passed.");else{_("Verification failed; asking the model to fix it."),console.log(j(I.dim,p.output.slice(-2e3)));try{let g=await t.created.agent.run({prompt:`The verification command \`${b}\` failed after your changes. Fix the cause, then confirm. Output:
362
+ `),S=!t.skipSessionNaming&&t.session.titleSource==="auto"&&!t.cli.title?Go(t.created.agent.gateway,t.prompt):void 0,x;try{let g=Xi(t.created.settings.provider);x=await t.created.agent.run({prompt:t.prompt,mode:t.created.settings.mode,rootDir:t.cli.cwd,maxSteps:t.created.settings.maxSteps,maxTotalTokens:t.created.settings.usageBudget.perRunTotalTokens,contextWindowTokens:g,approvalHandler:t.approvalHandler,bypassPermissions:t.bypassPermissions===!0,preferenceContext:l.preferenceContext,volatileContext:p,onEvent:b=>{r.push(b),Ui(t.cli.debug,e,t.created.settings.showModel?t.created.settings.model:void 0,o)(b)},signal:t.signal})}catch(g){if(st(),Ze(e),e.inputTokens||e.outputTokens){let b=await t.services.usage.record({model:t.created.settings.model,sessionId:t.session.id,inputTokens:e.inputTokens,outputTokens:e.outputTokens,price:t.created.settings.modelPrice});await qi({cli:t.cli,provider:t.created.settings.provider,record:b,success:!1,durationMs:Date.now()-new Date(n).getTime()})}throw t.session.messages=[...t.created.agent.messages],await t.services.sessions.save(t.session),await t.services.audit.append({action:"agent.run",outcome:it(g)?"cancelled":"failure",category:"agent",sessionId:t.session.id,details:{model:t.created.settings.model,inputTokens:e.inputTokens,outputTokens:e.outputTokens,error:g instanceof Error?g.message.slice(0,500):String(g).slice(0,500)}}),g}Ze(e);let k=await _n(t.created.localRuntime,t.cli.cwd,t.created.settings.mode,t.signal),R=a!==k,P=0,_=0,I=t.created.settings.verifyCommand;if(R&&I&&t.created.settings.mode==="write"){$(`Verifying: ${I}`);let g=await t.created.localRuntime.execute("shell",{command:I},{rootDir:t.cli.cwd,mode:"write",signal:t.signal});if(g.ok)T("Verification passed.");else{A("Verification failed; asking the model to fix it."),console.log(U(D.dim,g.output.slice(-2e3)));try{let b=await t.created.agent.run({prompt:`The verification command \`${I}\` failed after your changes. Fix the cause, then confirm. Output:
351
363
 
352
- ${p.output.slice(-4e3)}`,mode:"write",rootDir:t.cli.cwd,maxSteps:t.created.settings.maxSteps,approvalHandler:t.approvalHandler,onEvent:h=>{r.push(h),Ti(t.cli.debug,e,t.created.settings.showModel?t.created.settings.model:void 0,o)(h)},signal:t.signal});S+=g.usage.inputTokens,C+=g.usage.outputTokens,(await t.created.localRuntime.execute("shell",{command:b},{rootDir:t.cli.cwd,mode:"write",signal:t.signal})).ok?v("Verification passed after fix."):_("Verification still failing after one fix attempt.")}catch(g){if(rt(g))throw g;_(`Verification fix attempt failed: ${g instanceof Error?g.message:String(g)}`)}}}let A=w.usage.inputTokens+S,O=w.usage.outputTokens+C,L=await t.services.usage.record({model:t.created.settings.model,sessionId:t.session.id,inputTokens:A,outputTokens:O,cacheReadTokens:w.usage.cacheReadTokens,cacheWriteTokens:w.usage.cacheWriteTokens,price:t.created.settings.modelPrice});await Ri({cli:t.cli,provider:t.created.settings.provider,record:L,success:!0,durationMs:Date.now()-new Date(n).getTime()}),o.setCost(L.estimatedCostUsd);let B=lo(x),y=t.created.settings.mode==="plan"?po(r):void 0;o.finish({files:B,changed:P,planSummary:y,diff:P?x:void 0}),t.session.mode=t.created.settings.mode,t.session.model=t.created.settings.model,t.session.messages=[...w.messages],t.session.runs.push({id:bd(),prompt:t.prompt,answer:w.answer,startedAt:n,completedAt:new Date().toISOString(),steps:w.steps,usage:{inputTokens:A,outputTokens:O,estimatedCostUsd:L.estimatedCostUsd},diffBefore:Pi(a),diffAfter:Pi(x)}),t.session.runs.length>100&&(t.session.runs=t.session.runs.slice(-100)),t.session.runs.length===1&&!t.cli.title&&(t.session.title=t.prompt.length>72?`${t.prompt.slice(0,69)}...`:t.prompt),await t.services.sessions.save(t.session),await t.services.audit.append({action:"agent.run",outcome:"success",category:"agent",sessionId:t.session.id,details:{model:t.created.settings.model,steps:w.steps,inputTokens:A,outputTokens:O,estimatedCostUsd:L.estimatedCostUsd,changed:P}});try{let p=await ki({rootDir:t.cli.cwd,prompt:t.prompt,answer:w.answer,diffAfter:x,changed:a!==x});p.length&&$(`Learned ${p.length} Logbook fact(s) \u2192 .kpilot/logbook/learnings.md`)}catch(p){t.cli.debug&&_(`Logbook learning failed: ${p instanceof Error?p.message:String(p)}`)}return{answer:w.answer,streamed:e.streamed,tokensUsed:w.usage.inputTokens+w.usage.outputTokens}}finally{he(),e.thinking=void 0}}function Kd(t){if(t.length===0){console.log("[no sessions]");return}for(let e of t)console.log(`${e.id.slice(0,8)} ${e.updatedAt} ${e.mode.padEnd(5)} ${String(e.runCount).padStart(3)} run(s) ${e.title}`)}function Ni(t){if(t.length===0){console.log("[no project memory]");return}for(let e of t)console.log(`${e.id.slice(0,8)} ${e.text}`)}function Fi(t){if(t.length===0){console.log("[no skills]");return}for(let e of t)console.log(`${e.name.padEnd(20)} ${e.source.padEnd(7)} ${e.description}`)}function rt(t){return t instanceof at||t instanceof Error&&(t.name==="AbortError"||/cancelled/i.test(t.message))}var Pn=2500,Wd=150,Gd=`${I.dim} filter ${I.reset}`,Hd="\x1B[?25l",zd="\x1B[?25h";async function Vd(t,e,n,r={}){let{placeholder:o,store:s}=r,i=new Kt(process.stdout,t),a=!!(process.stdout.isTTY&&process.stdin.isTTY);for(;;){let c=new AbortController,l=0,u,m,d=!1,f=b=>{t.setPrompt(b?Gd:e),t.prompt(!0)},w=()=>{d||(d=!0,i.clearPlaceholder(),f(!0),a&&process.stdout.write(Hd))},x=(b=!0)=>{d&&(d=!1,b?f(!1):t.setPrompt(e),a&&process.stdout.write(zd),o&&t.line.length===0&&i.showPlaceholder(o))},P=()=>{Re(t.line)!==null?w():x()},S=b=>{i.setFooter(Ro({bypass:r.bypass?.()??!1,exitArmed:b}))},C=()=>{let b=Date.now();if(!(b-l<Wd)){if(l=b,n.armedAt>0&&b-n.armedAt<=Pn){c.abort(Object.assign(new Error("exit"),{name:"kpilotExit"}));return}n.armedAt=b,i.clear(),x(),o&&i.showPlaceholder(o),setTimeout(()=>S(!0),0),m&&clearTimeout(m),m=setTimeout(()=>{n.armedAt=0,S(!1)},Pn),m.unref?.()}};process.on("SIGINT",C),t.on("SIGINT",C);try{let b=t.question(e,{signal:c.signal});if(i.begin(),S(n.armedAt>0),o&&i.showPlaceholder(o),a){vd(process.stdin);let B=(y,p)=>{if(p){if(p.name==="tab"&&p.shift){let g=r.onShiftTab?.();setTimeout(()=>{S(n.armedAt>0),g&&i.note(g)},0);return}p.name==="return"||p.name==="enter"||p.ctrl&&(p.name==="c"||p.name==="d")||(P(),d||i.syncPlaceholder(),setTimeout(()=>i.paint(),0))}};process.stdin.on("keypress",B),u=()=>process.stdin.off("keypress",B)}let A=await b;x(!1);let O=(A??"").trim();if(!O){i.rewind();continue}return n.armedAt=0,m&&clearTimeout(m),s?s.expand(O):{text:O,pasted:!1}}catch{let b=c.signal.reason;if(b instanceof Error&&(b.name==="kpilotExit"||b.message==="exit"))return process.stdout.write(`
353
- `),null;let A=Date.now();if(n.armedAt>0&&A-n.armedAt<=Pn)return process.stdout.write(`
354
- `),null;n.armedAt=A,i.clear(),x(),o&&i.showPlaceholder(o),setTimeout(()=>S(!0),0),m&&clearTimeout(m),m=setTimeout(()=>{n.armedAt=0,S(!1)},Pn),m.unref?.();continue}finally{i.end(),i.clearPlaceholder(),x(!1),m&&clearTimeout(m),u?.(),process.removeListener("SIGINT",C),t.removeListener("SIGINT",C)}}}async function Yd(t,e,n,r={}){let o=await yi(e),s=Un();process.stdout.write(`${s}
355
- `),o&&process.stdout.write(`${j(I.dim,o)}
356
- `),r.store?.reset();let i=await Vd(t,jn,n,{placeholder:Ln,store:r.store,onShiftTab:r.onShiftTab,bypass:r.bypass});return i===null?(process.stdout.write(`
357
- \x1B[0J`),null):(process.stdout.write(`\x1B[0J${s}
358
- `),i)}function Bi(t){return t.controlPlaneUrl??process.env.KPILOT_CONTROL_PLANE_URL??"https://api.konsolepilot.ai"}async function Qd(t){let e=process.platform,n=e==="darwin"?"open":e==="win32"?"cmd":"xdg-open",r=e==="darwin"?[t]:e==="win32"?["/c","start","",t]:[t];return await new Promise(o=>{let s=_i(n,r,{stdio:"ignore",detached:!0});s.unref(),s.once("error",()=>o(!1)),s.once("spawn",()=>o(!0))})}async function Xd(t){let e=new se,n=await e.load(),r=new le(t.controlPlaneUrl??n?.controlPlaneUrl??Bi(t),`kpilot/${z}`);if(n?await e.validAccessToken(r):void 0)return;if(!process.stdin.isTTY)throw new Error("kpilot needs an account to continue. Run `kpilot login`.");if($("kpilot needs your account to continue. Starting sign-in\u2026"),await qi(t),!await e.load())throw new Error("kpilot needs an account to continue. Run `kpilot login`.")}async function qi(t){let e=new le(Bi(t),`kpilot/${z}`),n=new se,r=await n.load();if(r&&!t.force)throw new Error(`Already signed in as ${r.user.email}. Run \`kpilot logout\` first, or use --force.`);let o=await e.createDeviceCode(),s=o.verification_uri_complete||`${o.verification_uri}?code=${encodeURIComponent(o.user_code)}`,i=t.noBrowser||process.env.KPILOT_NO_BROWSER==="1",a=!1;i||(a=await Qd(s)),a?(console.log(`
359
- Opened ${s}`),console.log(`Confirm code ${j(I.bold,o.user_code)} in your browser if prompted.
364
+ ${g.output.slice(-4e3)}`,mode:"write",rootDir:t.cli.cwd,maxSteps:t.created.settings.maxSteps,approvalHandler:t.approvalHandler,onEvent:O=>{r.push(O),Ui(t.cli.debug,e,t.created.settings.showModel?t.created.settings.model:void 0,o)(O)},signal:t.signal});P+=b.usage.inputTokens,_+=b.usage.outputTokens,(await t.created.localRuntime.execute("shell",{command:I},{rootDir:t.cli.cwd,mode:"write",signal:t.signal})).ok?T("Verification passed after fix."):A("Verification still failing after one fix attempt.")}catch(b){if(it(b))throw b;A(`Verification fix attempt failed: ${b instanceof Error?b.message:String(b)}`)}}}let j=x.usage.inputTokens+P,N=x.usage.outputTokens+_,h=await t.services.usage.record({model:t.created.settings.model,sessionId:t.session.id,inputTokens:j,outputTokens:N,cacheReadTokens:x.usage.cacheReadTokens,cacheWriteTokens:x.usage.cacheWriteTokens,price:t.created.settings.modelPrice});await qi({cli:t.cli,provider:t.created.settings.provider,record:h,success:!0,durationMs:Date.now()-new Date(n).getTime()}),o.setCost(h.estimatedCostUsd);let f=ho(k),w=t.created.settings.mode==="plan"?vo(r):void 0;o.finish({files:f,changed:R,planSummary:w,diff:R?k:void 0}),t.session.mode=t.created.settings.mode,t.session.model=t.created.settings.model,t.session.messages=[...x.messages],t.session.runs.push({id:Dd(),prompt:t.prompt,answer:x.answer,startedAt:n,completedAt:new Date().toISOString(),steps:x.steps,usage:{inputTokens:j,outputTokens:N,estimatedCostUsd:h.estimatedCostUsd},diffBefore:Ni(a),diffAfter:Ni(k)}),t.session.runs.length>100&&(t.session.runs=t.session.runs.slice(-100)),S&&(t.session.title=await S,t.session.titleSource="generated"),await t.services.sessions.save(t.session),await t.services.audit.append({action:"agent.run",outcome:"success",category:"agent",sessionId:t.session.id,details:{model:t.created.settings.model,steps:x.steps,inputTokens:j,outputTokens:N,estimatedCostUsd:h.estimatedCostUsd,changed:R}});try{let g=await Di({rootDir:t.cli.cwd,prompt:t.prompt,answer:x.answer,diffAfter:k,changed:a!==k});g.length&&$(`Learned ${g.length} Logbook fact(s) \u2192 .kpilot/logbook/learnings.md`)}catch(g){t.cli.debug&&A(`Logbook learning failed: ${g instanceof Error?g.message:String(g)}`)}return{answer:x.answer,streamed:e.streamed,tokensUsed:x.usage.inputTokens+x.usage.outputTokens}}finally{st(),e.thinking=void 0}}function im(t){if(t.length===0){console.log("[no sessions]");return}for(let e of t){let n=`${e.updatedAt} ${e.mode.padEnd(5)} ${String(e.runCount).padStart(3)} run(s)`;console.log(`${e.title} ${U(D.dim,n)}`)}}function Zi(t){if(t.length===0){console.log("[no project memory]");return}for(let e of t)console.log(`${e.id.slice(0,8)} ${e.text}`)}function ea(t){if(t.length===0){console.log("[no skills]");return}for(let e of t)console.log(`${e.name.padEnd(20)} ${e.source.padEnd(7)} ${e.description}`)}function it(t){return t instanceof lt||t instanceof Error&&(t.name==="AbortError"||/cancelled/i.test(t.message))}var Mn=2500,am=150,cm=`${D.dim} filter ${D.reset}`,lm="\x1B[?25l",ro="\x1B[?25h";async function um(t,e,n,r={}){let{placeholder:o,store:s}=r,i=new Gt(process.stdout,t),a=!!(process.stdout.isTTY&&process.stdin.isTTY);for(;;){let c=new AbortController,l=0,u,m,d=!1,p=P=>{t.setPrompt(P?cm:e),t.prompt(!0)},y=()=>{d||(d=!0,i.clearPlaceholder(),p(!0),a&&process.stdout.write(lm))},S=(P=!0)=>{d&&(d=!1,P?p(!1):t.setPrompt(e),a&&process.stdout.write(ro),o&&t.line.length===0&&i.showPlaceholder(o))},x=()=>{Ee(t.line)!==null?y():S()},k=P=>{i.setFooter(jo({bypass:r.bypass?.()??!1,exitArmed:P}))},R=()=>{let P=Date.now();if(!(P-l<am)){if(l=P,n.armedAt>0&&P-n.armedAt<=Mn){c.abort(Object.assign(new Error("exit"),{name:"kpilotExit"}));return}n.armedAt=P,i.clear(),S(),o&&i.showPlaceholder(o),setTimeout(()=>k(!0),0),m&&clearTimeout(m),m=setTimeout(()=>{n.armedAt=0,k(!1)},Mn),m.unref?.()}};process.on("SIGINT",R),t.on("SIGINT",R);try{let P=t.question(e,{signal:c.signal});if(i.begin(),k(n.armedAt>0),o&&i.showPlaceholder(o),a){jd(process.stdin);let N=(h,f)=>{if(f){if(f.name==="tab"&&f.shift){let w=r.onShiftTab?.();setTimeout(()=>{k(n.armedAt>0),w&&i.note(w)},0);return}f.name==="return"||f.name==="enter"||f.ctrl&&(f.name==="c"||f.name==="d")||(x(),d||i.syncPlaceholder(),setTimeout(()=>i.paint(),0))}};process.stdin.on("keypress",N),u=()=>process.stdin.off("keypress",N)}let _=await P;S(!1);let I=(_??"").trim();if(!I){i.rewind();continue}return n.armedAt=0,m&&clearTimeout(m),{...s?s.expand(I):{text:I,pasted:!1},display:_??""}}catch{let P=c.signal.reason;if(P instanceof Error&&(P.name==="kpilotExit"||P.message==="exit"))return process.stdout.write(`
365
+ `),null;let _=Date.now();if(n.armedAt>0&&_-n.armedAt<=Mn)return process.stdout.write(`
366
+ `),null;n.armedAt=_,i.clear(),S(),o&&i.showPlaceholder(o),setTimeout(()=>k(!0),0),m&&clearTimeout(m),m=setTimeout(()=>{n.armedAt=0,k(!1)},Mn),m.unref?.();continue}finally{i.end(),i.clearPlaceholder(),S(!1),m&&clearTimeout(m),u?.(),process.removeListener("SIGINT",R),t.removeListener("SIGINT",R)}}}async function dm(t,e,n,r={}){let o=await Ai(e),s=Jn();process.stdout.write(`${s}
367
+ `),o&&process.stdout.write(`${U(D.dim,o)}
368
+ `);let i=Oo(o);r.store?.reset();let a=await um(t,Ht,n,{placeholder:Bn,store:r.store,onShiftTab:r.onShiftTab,bypass:r.bypass});return a===null?(process.stdout.write(`${Io(i)}
369
+ `),null):(process.stdout.write(Do(a.display,{rowsAbove:i,columns:process.stdout.columns})),a)}function ta(t){return t.controlPlaneUrl??process.env.KPILOT_CONTROL_PLANE_URL??"https://api.konsolepilot.ai"}async function mm(t){let e=process.platform,n=e==="darwin"?"open":e==="win32"?"cmd":"xdg-open",r=e==="darwin"?[t]:e==="win32"?["/c","start","",t]:[t];return await new Promise(o=>{let s=Wi(n,r,{stdio:"ignore",detached:!0});s.unref(),s.once("error",()=>o(!1)),s.once("spawn",()=>o(!0))})}async function pm(t){let e=new ie,n=await e.load(),r=new ue(t.controlPlaneUrl??n?.controlPlaneUrl??ta(t),`kpilot/${V}`);if(n?await e.validAccessToken(r):void 0)return;if(!process.stdin.isTTY)throw new Error("kpilot needs an account to continue. Run `kpilot login`.");if($("kpilot needs your account to continue. Starting sign-in\u2026"),await na(t),!await e.load())throw new Error("kpilot needs an account to continue. Run `kpilot login`.")}async function na(t){let e=new ue(ta(t),`kpilot/${V}`),n=new ie,r=await n.load();if(r&&!t.force)throw new Error(`Already signed in as ${r.user.email}. Run \`kpilot logout\` first, or use --force.`);let o=await e.createDeviceCode(),s=o.verification_uri_complete||`${o.verification_uri}?code=${encodeURIComponent(o.user_code)}`,i=t.noBrowser||process.env.KPILOT_NO_BROWSER==="1",a=!1;i||(a=await mm(s)),a?(console.log(`
370
+ Opened ${s}`),console.log(`Confirm code ${U(D.bold,o.user_code)} in your browser if prompted.
360
371
  `),$("Approve the device in your browser. Press Ctrl+C to cancel.")):(console.log(`
361
- Open: ${s}`),console.log(`Code: ${j(I.bold,o.user_code)}
362
- `),$("Waiting for authorization in your browser. Press Ctrl+C to cancel."));let c=new AbortController,l=()=>c.abort(new Error("Login cancelled."));process.once("SIGINT",l);try{let u=await e.pollDeviceToken(o.device_code,{intervalSeconds:o.interval,expiresInSeconds:o.expires_in,signal:c.signal});await n.save(u),v(`Signed in as ${u.user.email} \xB7 ${u.organization.name}`)}finally{process.removeListener("SIGINT",l)}}async function Zd(t){let e=new se,n=await e.load();if(!n){console.log("Not signed in. Run `kpilot login`.");return}let r=new le(t.controlPlaneUrl??n.controlPlaneUrl,`kpilot/${z}`),o=await e.validAccessToken(r);if(!o)throw new Error("Not signed in.");let s=await o.client.profile(o.tokens.accessToken);console.log(`${s.user.name} <${s.user.email}>`),console.log(`Organization: ${s.organization.name} (${s.organization.slug})`),s.device&&console.log(`Device: ${s.device.name}`),console.log(`Control plane: ${o.tokens.controlPlaneUrl}`)}async function em(t){let e=new se,n=await e.load();if(!n){console.log("Already signed out.");return}await new le(t.controlPlaneUrl??n.controlPlaneUrl,`kpilot/${z}`).logout(n.refreshToken).catch(()=>{}),await e.clear(),v("Signed out and removed local cloud credentials.")}async function tm(t){if(!(t.noCloudSync||process.env.KPILOT_DISABLE_CLOUD_SYNC==="1"))try{let e=new se,n=await e.load();if(!n)return;let r=new le(t.controlPlaneUrl??n.controlPlaneUrl,`kpilot/${z}`),o=await e.validAccessToken(r);if(!o)return;let s=await o.client.checkBudget(o.tokens.accessToken,0);for(let i of s.warnings)_(`Cloud budget: ${i}`);if(!s.allowed)throw new Error(`Cloud budget prevents this run: ${s.violations.join(" ")}`)}catch(e){if(e instanceof Error&&e.message.startsWith("Cloud budget prevents"))throw e;t.debug&&_(`Cloud budget check unavailable: ${e instanceof Error?e.message:String(e)}`)}}async function Ri(t){if(t.provider!=="kpilot-hosted"&&!(t.cli.noCloudSync||process.env.KPILOT_DISABLE_CLOUD_SYNC==="1"))try{let e=new se,n=await e.load();if(!n)return;let r=new le(t.cli.controlPlaneUrl??n.controlPlaneUrl,`kpilot/${z}`),o=await e.validAccessToken(r);if(!o)return;let s=Mi("sha256").update(D.resolve(t.cli.cwd)).digest("hex").slice(0,32);await o.client.ingestUsage(o.tokens.accessToken,[{eventId:t.record.id,occurredAt:t.record.timestamp,projectFingerprint:s,...t.record.sessionId?{sessionId:t.record.sessionId}:{},provider:t.provider,model:t.record.model,inputTokens:t.record.inputTokens,outputTokens:t.record.outputTokens,estimatedCostUsd:t.record.estimatedCostUsd,durationMs:Math.max(0,Math.trunc(t.durationMs)),success:t.success}])}catch(e){t.cli.debug&&_(`Cloud usage sync failed: ${e instanceof Error?e.message:String(e)}`)}}async function nm(t){if(!t.prompt)throw new Error("Provide a prompt, or use `kpilot`.");await W(t.cwd);let e=await we(t.cwd),n=re(t.cwd),r=nt(t,e,await n.policy.load()),o=await Bd(t,n.sessions,r);t.mode||(t.mode=o.mode);let s=await Hr(t,e,o),i=process.stdin.isTTY?Ai({input:process.stdin,output:process.stdout}):void 0;try{console.log(Nt(s.settings.mode,s.settings.showModel?s.settings.model:void 0,o.id.slice(0,8),{bypass:t.bypassPermissions}));try{let a=await Yr(c=>Qr({cli:t,created:s,services:n,session:o,prompt:t.prompt,approvalHandler:ji(t,i?l=>i.question(l):void 0,Ii(i)),bypassPermissions:t.bypassPermissions,signal:c}));a.streamed||console.log(`${Mn(s.settings.showModel?s.settings.model:void 0)} \u203A ${a.answer}`),$(`Resume with: kpilot chat --session ${o.id.slice(0,8)}`)}catch(a){if(!rt(a))throw a;o.messages=[...s.agent.messages],await n.sessions.save(o),he();let c=st.stopReason;_(c==="Esc"?"Stopped with Esc.":"Stopped."),$(`Nothing else was run. Resume with: kpilot chat --session ${o.id.slice(0,8)}`),process.exitCode=130}}finally{i?.close(),await s.close()}}function Ji(t){let e=t?.trim().toLowerCase();if(e==="accept")return"accepted";if(e==="reject")return"rejected";if(e==="edit")return"edited";if(e==="accepted"||e==="rejected"||e==="edited")return e;throw new Error("Feedback outcome must be accepted, rejected, or edited.")}async function Ki(t){let e=t.session.runs.at(-1);if(!e)throw new Error("The selected session has no completed run to evaluate.");let n=t.outcome==="edited"?await Rn(t.runtime,t.rootDir,t.mode):e.diffAfter,r=await t.services.preferences.learn({outcome:t.outcome,task:e.prompt,note:t.note,sessionId:t.session.id,proposedDiff:e.diffAfter,finalDiff:n});if(v(`Recorded ${t.outcome} feedback for session ${t.session.id.slice(0,8)}.`),r.learned.length===0)$("No durable rule was inferred. Add a concrete note to teach an explicit preference.");else for(let o of r.learned)$(`${o.polarity}: ${o.text} (${Math.round(o.confidence*100)}%)`)}async function rm(t){await W(t.cwd);let e=re(t.cwd).sessions,n=t.args[0]??"list";if(n==="list"){Kd(await e.list());return}let r=t.args[1]??t.session;if(!r)throw new Error(`sessions ${n} requires a session ID.`);if(n==="show"){let o=await e.load(r);console.log(JSON.stringify(o,null,2));return}if(n==="delete"){await e.delete(r),v(`Deleted session ${r}.`);return}throw new Error(`Unknown sessions action: ${n}`)}async function om(t){await W(t.cwd);let e=re(t.cwd).memory,n=t.args[0]??"list";if(n==="list"){Ni(await e.list());return}if(n==="add"){let r=await e.add(t.args.slice(1).join(" "));v(`Remembered ${r.id.slice(0,8)}: ${r.text}`);return}if(n==="remove"){let r=t.args[1];if(!r)throw new Error("memory remove requires an entry ID.");let o=await e.remove(r);v(`Removed memory: ${o.text}`);return}if(n==="clear"){let r=await e.clear();v(`Removed ${r} memory entr${r===1?"y":"ies"}.`);return}throw new Error(`Unknown memory action: ${n}`)}async function sm(t){await W(t.cwd);let e=re(t.cwd).skills,n=t.args[0]??"list";if(n==="list"){Fi(await e.list());return}if(n==="show"){let r=t.args[1];if(!r)throw new Error("skills show requires a skill name.");let o=await e.get(r);console.log(`${o.name} (${o.source})
372
+ Open: ${s}`),console.log(`Code: ${U(D.bold,o.user_code)}
373
+ `),$("Waiting for authorization in your browser. Press Ctrl+C to cancel."));let c=new AbortController,l=()=>c.abort(new Error("Login cancelled."));process.once("SIGINT",l);try{let u=await e.pollDeviceToken(o.device_code,{intervalSeconds:o.interval,expiresInSeconds:o.expires_in,signal:c.signal});await n.save(u),T(`Signed in as ${u.user.email} \xB7 ${u.organization.name}`)}finally{process.removeListener("SIGINT",l)}}async function fm(t){let e=new ie,n=await e.load();if(!n){console.log("Not signed in. Run `kpilot login`.");return}let r=new ue(t.controlPlaneUrl??n.controlPlaneUrl,`kpilot/${V}`),o=await e.validAccessToken(r);if(!o)throw new Error("Not signed in.");let s=await o.client.profile(o.tokens.accessToken);console.log(`${s.user.name} <${s.user.email}>`),console.log(`Organization: ${s.organization.name} (${s.organization.slug})`),s.device&&console.log(`Device: ${s.device.name}`),console.log(`Control plane: ${o.tokens.controlPlaneUrl}`)}async function gm(t){let e=new ie,n=await e.load();if(!n){console.log("Already signed out.");return}await new ue(t.controlPlaneUrl??n.controlPlaneUrl,`kpilot/${V}`).logout(n.refreshToken).catch(()=>{}),await e.clear(),T("Signed out and removed local cloud credentials.")}async function hm(t){if(!(t.noCloudSync||process.env.KPILOT_DISABLE_CLOUD_SYNC==="1"))try{let e=new ie,n=await e.load();if(!n)return;let r=new ue(t.controlPlaneUrl??n.controlPlaneUrl,`kpilot/${V}`),o=await e.validAccessToken(r);if(!o)return;let s=await o.client.checkBudget(o.tokens.accessToken,0);for(let i of s.warnings)A(`Cloud budget: ${i}`);if(!s.allowed)throw new Error(`Cloud budget prevents this run: ${s.violations.join(" ")}`)}catch(e){if(e instanceof Error&&e.message.startsWith("Cloud budget prevents"))throw e;t.debug&&A(`Cloud budget check unavailable: ${e instanceof Error?e.message:String(e)}`)}}async function qi(t){if(t.provider!=="kpilot-hosted"&&!(t.cli.noCloudSync||process.env.KPILOT_DISABLE_CLOUD_SYNC==="1"))try{let e=new ie,n=await e.load();if(!n)return;let r=new ue(t.cli.controlPlaneUrl??n.controlPlaneUrl,`kpilot/${V}`),o=await e.validAccessToken(r);if(!o)return;let s=Ji("sha256").update(L.resolve(t.cli.cwd)).digest("hex").slice(0,32);await o.client.ingestUsage(o.tokens.accessToken,[{eventId:t.record.id,occurredAt:t.record.timestamp,projectFingerprint:s,...t.record.sessionId?{sessionId:t.record.sessionId}:{},provider:t.provider,model:t.record.model,inputTokens:t.record.inputTokens,outputTokens:t.record.outputTokens,estimatedCostUsd:t.record.estimatedCostUsd,durationMs:Math.max(0,Math.trunc(t.durationMs)),success:t.success}])}catch(e){t.cli.debug&&A(`Cloud usage sync failed: ${e instanceof Error?e.message:String(e)}`)}}async function wm(t){if(!t.prompt)throw new Error("Provide a prompt, or use `kpilot`.");await G(t.cwd);let e=await we(t.cwd),n=oe(t.cwd),r=nt(t,e,await n.policy.load()),o=await rm(t,n.sessions,r);t.mode||(t.mode=o.mode);let s=await Xr(t,e,o),i=process.stdin.isTTY?Gi({input:process.stdin,output:process.stdout}):void 0;try{console.log(qt(s.settings.mode,s.settings.showModel?s.settings.model:void 0,o.title,{bypass:t.bypassPermissions}));try{let a=await to(c=>no({cli:t,created:s,services:n,session:o,prompt:t.prompt,approvalHandler:Yi(t,i?l=>i.question(l):void 0,zi(i)),bypassPermissions:t.bypassPermissions,signal:c}));a.streamed||console.log(`${On(s.settings.showModel?s.settings.model:void 0)} \u203A ${a.answer}`),$(`Resume with: kpilot chat --session ${o.id.slice(0,8)} \xB7 ${o.title}`)}catch(a){if(!it(a))throw a;o.messages=[...s.agent.messages],await n.sessions.save(o),st();let c=ct.stopReason;A(c==="Esc"?"Stopped with Esc.":"Stopped."),$(`Nothing else was run. Resume with: kpilot chat --session ${o.id.slice(0,8)} \xB7 ${o.title}`),process.exitCode=130}}finally{i?.close(),await s.close()}}function ra(t){let e=t?.trim().toLowerCase();if(e==="accept")return"accepted";if(e==="reject")return"rejected";if(e==="edit")return"edited";if(e==="accepted"||e==="rejected"||e==="edited")return e;throw new Error("Feedback outcome must be accepted, rejected, or edited.")}async function oa(t){let e=t.session.runs.at(-1);if(!e)throw new Error("The selected session has no completed run to evaluate.");let n=t.outcome==="edited"?await _n(t.runtime,t.rootDir,t.mode):e.diffAfter,r=await t.services.preferences.learn({outcome:t.outcome,task:e.prompt,note:t.note,sessionId:t.session.id,proposedDiff:e.diffAfter,finalDiff:n});if(T(`Recorded ${t.outcome} feedback for ${t.session.title}.`),r.learned.length===0)$("No durable rule was inferred. Add a concrete note to teach an explicit preference.");else for(let o of r.learned)$(`${o.polarity}: ${o.text} (${Math.round(o.confidence*100)}%)`)}async function ym(t){await G(t.cwd);let e=oe(t.cwd).sessions,n=t.args[0]??"list";if(n==="list"){im(await e.list());return}let r=t.args[1]??t.session;if(!r)throw new Error(`sessions ${n} requires a session ID.`);if(n==="show"){let o=await e.load(r);console.log(JSON.stringify(o,null,2));return}if(n==="delete"){await e.delete(r),T(`Deleted session ${r}.`);return}throw new Error(`Unknown sessions action: ${n}`)}async function bm(t){await G(t.cwd);let e=oe(t.cwd).memory,n=t.args[0]??"list";if(n==="list"){Zi(await e.list());return}if(n==="add"){let r=await e.add(t.args.slice(1).join(" "));T(`Remembered ${r.id.slice(0,8)}: ${r.text}`);return}if(n==="remove"){let r=t.args[1];if(!r)throw new Error("memory remove requires an entry ID.");let o=await e.remove(r);T(`Removed memory: ${o.text}`);return}if(n==="clear"){let r=await e.clear();T(`Removed ${r} memory entr${r===1?"y":"ies"}.`);return}throw new Error(`Unknown memory action: ${n}`)}async function vm(t){await G(t.cwd);let e=oe(t.cwd).skills,n=t.args[0]??"list";if(n==="list"){ea(await e.list());return}if(n==="show"){let r=t.args[1];if(!r)throw new Error("skills show requires a skill name.");let o=await e.get(r);console.log(`${o.name} (${o.source})
363
374
  ${o.description}
364
375
 
365
376
  ${o.instructions}
366
377
 
367
- ${o.filePath}`);return}throw new Error(`Unknown skills action: ${n}`)}async function im(t){await W(t.cwd);let e=re(t.cwd).preferences,n=t.args[0]??"list";if(n==="list"){let r=await e.listRules();r.length===0&&console.log("[no learned preferences]");for(let o of r)console.log(`${o.id.slice(0,8)} ${String(Math.round(o.confidence*100)).padStart(3)}% ${o.polarity.padEnd(6)} ${o.text}`);return}if(n==="remove"){let r=t.args[1];if(!r)throw new Error("preferences remove requires a rule ID.");let o=await e.removeRule(r);v(`Removed preference: ${o.text}`);return}throw new Error(`Unknown preferences action: ${n}`)}async function am(t){await W(t.cwd);let e=await we(t.cwd),n=re(t.cwd),r=await n.policy.load(),o=nt(t,e,r),s=await n.sessions.list(),i=t.session??s[0]?.id;if(!i)throw new Error("No session exists. Pass --session after completing an agent run.");let a=await n.sessions.load(i),c=new ye(t.cwd,{sandbox:e.sandbox});await Ki({outcome:Ji(t.args[0]),note:t.note??(t.args.slice(1).join(" ").trim()||void 0),session:a,services:n,runtime:c,mode:o.mode,rootDir:t.cwd})}async function cm(t){if(t.args[0]==="serve"){await lm(t);return}await W(t.cwd);let e=await we(t.cwd),n=await new je(t.cwd).load(),r=e.mcp?.servers??{},o=Object.entries(r).filter(([i,a])=>a.enabled!==!1&&(!n?.allowedMcpServers||n.allowedMcpServers.includes(i)));if(o.length===0){console.log("[no enabled MCP servers]");return}let s=await Ae.connect(Object.fromEntries(o));try{let i=s.list();i.length===0&&console.log("[MCP servers exposed no tools]");for(let a of i)console.log(`${a.exposedName.padEnd(38)} ${a.server.padEnd(16)} ${a.description}`)}finally{await s.close()}}async function lm(t){await W(t.cwd);let e=await we(t.cwd),n=await new je(t.cwd).load(),r=new ye(t.cwd,{sandbox:e.sandbox,browser:Gr(e)}),o=e.mcp?.servers??{},s=n?.allowedMcpServers?Object.fromEntries(Object.entries(o).filter(([l])=>n.allowedMcpServers.includes(l))):o,i=Object.values(s).some(l=>l.enabled!==!1)?await Ae.connect(s):void 0,a=new vt([r,i]);$(`Serving kpilot MCP server on stdio (${a.definitions().length} tools).`);let c=new rn(a,{name:"kpilot",version:z,rootDir:t.cwd,mode:t.mode??"write"});try{await ms(c)}finally{await i?.close()}}function Wi(t){for(let e of t){let n=e.managed?e.name??"[managed]":"[external]",r=e.branch??(e.detached?"[detached]":"[no branch]");console.log(`${n.padEnd(18)} ${r.padEnd(32)} ${e.path}`)}}async function um(t){await W(t.cwd);let e=new Ct(t.cwd),n=t.args[0]??"list";if(n==="list"){Wi(await e.list());return}if(n==="create"){let r=t.args[1];if(!r)throw new Error("worktrees create requires a name.");let o=await e.create(r,{base:t.args[2],branch:t.args[3]});v(`Created worktree ${o.name??r} on ${o.branch??"[detached]"}.`),console.log(o.path);return}if(n==="remove"){let r=t.args[1];if(!r)throw new Error("worktrees remove requires a name.");await e.remove(r,t.force),v(`Removed worktree ${r}.`);return}if(n==="prune"){await e.prune(),v("Pruned stale Git worktree metadata.");return}throw new Error(`Unknown worktrees action: ${n}`)}async function dm(t){await W(t.cwd);let e=re(t.cwd),n=t.args[0]??"show";if(n==="show"){let r=await e.policy.load();console.log(r?JSON.stringify(r,null,2):"[no team policy]");return}if(n==="init"){let r=await we(t.cwd),o=t.model??process.env.KPILOT_MODEL??r.model?.model,s=await e.policy.initialize(t.organization,o?[o]:[]);await e.audit.append({action:"policy.init",outcome:"success",category:"administration",details:{organization:s.organization??"",allowedModels:s.allowedModels??[]}}),v(`Created ${D.relative(t.cwd,e.policy.filePath)}.`),o||_("No model was configured, so allowedModels is empty. Add approved model names before running the agent.");return}if(n==="validate"){if(!await e.policy.load())throw new Error("No team policy exists. Run `kpilot policy init`.");v("Team policy is valid.");return}throw new Error(`Unknown policy action: ${n}`)}function zr(t){console.log(`date: ${t.date}`),console.log(`runs: ${t.runs}`),console.log(`input tokens: ${ue(t.inputTokens)}`),console.log(`output tokens: ${ue(t.outputTokens)}`),console.log(`total tokens: ${ue(t.totalTokens)}`),console.log(`estimated cost: $${t.estimatedCostUsd.toFixed(6)}`)}async function mm(t){await W(t.cwd);let e=await we(t.cwd),n=re(t.cwd),r=await n.policy.load(),o=Cn(e.usage?.budget,r?.usage),s=t.args[0]??"summary";if(s==="summary"){zr(await n.usage.summarize(t.args[1]));return}if(s==="list"){let i=await n.usage.list(t.limit);i.length===0&&console.log("[no usage records]");for(let a of i)console.log(`${a.timestamp} ${a.model.padEnd(24)} ${ue(a.totalTokens).padStart(8)} tokens $${a.estimatedCostUsd.toFixed(6)} ${a.sessionId?.slice(0,8)??"-"}`);return}if(s==="check"){let i=await n.usage.check(o);zr(i.summary);for(let a of i.warnings)_(a);if(!i.allowed)throw new Error(i.violations.join(" "));v("Usage budget allows another run.");return}throw new Error(`Unknown usage action: ${s}`)}async function pm(t){await W(t.cwd);let e=re(t.cwd).audit,n=t.args[0]??"list";if(n==="list"){let r=await e.list(t.limit);r.length===0&&console.log("[no audit records]");for(let o of r)console.log(`${o.timestamp} ${o.outcome.padEnd(9)} ${o.action.padEnd(24)} ${o.actor}@${o.host} ${o.sessionId?.slice(0,8)??"-"}`);return}if(n==="verify"){let r=await e.verify();if(!r.valid)throw new Error(`Audit verification failed at line ${r.firstInvalidLine??"?"}: ${r.reason??"unknown reason"}`);v(`Audit chain is valid: ${r.records} record(s), head ${r.headHash.slice(0,16)}.`);return}throw new Error(`Unknown audit action: ${n}`)}async function fm(t){await W(t.cwd);let e=t.args[0],n=t.args[1];if(!e||!n)throw new Error("sync requires an action and bundle path.");let r=new yn(t.cwd),o=re(t.cwd).audit;if(e==="inspect"){console.log(JSON.stringify(await r.inspectBundle(n),null,2));return}let s=process.env[t.passphraseEnv];if(!s)throw new Error(`${t.passphraseEnv} is not set.`);if(e==="export"){let i=await r.exportBundle(n,s,t.includeSessions);await o.append({action:"sync.export",outcome:"success",category:"synchronization",details:{destination:D.resolve(n),includeSessions:i.includeSessions}}),v(`Encrypted sync bundle written to ${D.resolve(n)}.`);return}if(e==="import"){let i=await r.importBundle(n,s,t.overwrite);await o.append({action:"sync.import",outcome:"success",category:"synchronization",details:{source:D.resolve(n),imported:i.imported.length,skipped:i.skipped.length,overwrite:t.overwrite}}),v(`Imported ${i.imported.length} file(s); skipped ${i.skipped.length}.`);for(let a of i.skipped.slice(0,10))_(`Skipped existing file: ${a}`);return}throw new Error(`Unknown sync action: ${e}`)}async function Gi(t){await W(t.cwd);let e=t.args[0]??"status";if(e!=="status")throw new Error(`Unknown admin action: ${e}`);let n=await we(t.cwd),r=re(t.cwd),o=await r.policy.load(),s=await r.usage.check(Cn(n.usage?.budget,o?.usage)),i=await r.audit.verify();if(console.log(j(I.bold,"kpilot administration status")),console.log(`project: ${t.cwd}`),console.log(`policy: ${o?`enabled${o.organization?` (${o.organization})`:""}`:"not configured"}`),console.log(`usage: ${s.allowed?"allowed":"blocked"}; ${ue(s.summary.totalTokens)} token(s) today`),console.log(`audit: ${i.valid?"valid":"invalid"}; ${i.records} record(s)`),console.log(`sessions: ${(await r.sessions.list()).length}`),console.log(`skills: ${(await r.skills.list()).length}`),console.log(`preferences: ${(await r.preferences.listRules()).length}`),s.warnings.length)for(let a of s.warnings)_(a);if(!s.allowed)for(let a of s.violations)q(a);i.valid||q(i.reason??"Audit chain invalid.")}async function gm(t){if(t.cli.session)return await t.store.load(t.cli.session);if(t.cli.yes)return await t.store.create({title:t.cli.title,mode:t.settings.mode,model:t.settings.model});if((await t.store.list()).length===0)return await t.store.create({title:t.cli.title,mode:t.settings.mode,model:t.settings.model});let n=await $n({store:t.store,question:t.question,pauseResume:t.pauseResume,title:"Re-open a session, or start fresh?",includeFresh:!0,prefer:"recent"});return n.kind==="cancel"?null:n.kind==="session"?n.session:await t.store.create({title:t.cli.title,mode:t.settings.mode,model:t.settings.model})}async function hm(t){if(!process.stdin.isTTY)throw new Error("Interactive chat requires a TTY.");await W(t.cwd);let e=await we(t.cwd),n=re(t.cwd),r=nt(t,e,await n.policy.load()),o=Ai({input:process.stdin,output:process.stdout}),s=x=>o.question(x),i=Ii(o),a=new qt,c=new Jt(o,process.stdin,a,{prepare:vo,placeholder:Ln});c.attach();let l=new Bt(o,{input:process.stdin,output:process.stdout});l.setEntries(Si()),l.attach();let u={bypass:t.bypassPermissions},m=()=>(u.bypass=!u.bypass,mo(u.bypass));process.stdout.isTTY&&process.stdout.write(yo);let d,f,w=!1;try{let x=await gm({cli:t,store:n.sessions,settings:r,question:s,pauseResume:i});if(!x){$("Cancelled.");return}d=x,t.session=d.id,t.mode||(t.mode=d.mode),f=await Hr(t,e,d),w=!0;let P=ji(t,s,i);console.log(Nt(f.settings.mode,f.settings.showModel?f.settings.model:void 0,d.id.slice(0,8),{bypass:u.bypass})),console.log(j(I.dim,`${t.cwd} \xB7 session ${d.id.slice(0,8)}`));let S=async()=>{await f.close();let O=await we(t.cwd);r=nt(t,O,await n.policy.load()),f=await Hr(t,O,d)},C=async O=>{d.messages=[...f.agent.messages],await n.sessions.save(d),d=O,t.session=d.id,t.mode=d.mode,await S(),v(`Switched to ${d.id.slice(0,8)} \xB7 ${d.title}`)},b=async(O,L)=>{let B,y=Date.now();try{let p=f.settings.mode==="plan",g=await Yr(k=>Qr({cli:t,created:f,services:n,session:d,prompt:O,approvalHandler:P,bypassPermissions:u.bypass,skill:L,signal:k,onDiffBefore:h=>{B=h}}));if(g.streamed||(he(),console.log(`${Mn(f.settings.showModel?f.settings.model:void 0)} \u203A ${g.answer}`)),g.tokensUsed>0&&console.log(j(I.dim,`saved \xB7 session ${d.id.slice(0,8)}`)),p&&g.answer.trim()&&process.stdin.isTTY){let k=Do(t.cwd,O);await et(D.dirname(k),{recursive:!0}),await ve(k,`${g.answer.trim()}
368
- `,"utf8");let h=D.relative(t.cwd,k);$(`Plan saved to ${h}`),await Q({title:"Proceed to implement this plan in write mode?",question:s,pauseResume:i,choices:[{value:"yes",label:"yes",description:"Switch to write mode and implement",default:!0},{value:"no",label:"no",description:"Stay in plan mode"}]})==="yes"&&(t.mode="write",d.mode="write",await n.sessions.save(d),await S(),v("Switched to WRITE mode. Implementing the plan\u2026"),await b(`Implement the plan in ${h}. Follow it step by step and verify your changes.`))}}catch(p){if(!rt(p))throw p;d.messages=[...f.agent.messages],await n.sessions.save(d),he();let g=st.stopReason,k=Math.max(1,Math.round((Date.now()-y)/1e3));_(g==="Esc"?`Stopped with Esc after ${k}s. Partial conversation saved.`:`Stopped after ${k}s. Partial conversation saved.`);let h=await Rn(f.localRuntime,t.cwd,f.settings.mode),T=h!==B,G=!B||!B.trim(),V=T?Bn(h??""):[];if(!process.stdin.isTTY)return;let ae=[{value:"prompt",label:"Back to the prompt",description:"Nothing else runs \u2014 tell me what to change",default:!0},{value:"continue",label:"Continue where it stopped",description:"Resume without redoing finished work"}];G&&V.length>0&&ae.push({value:"undo",label:"Undo this run's changes",description:`Revert ${V.length} file(s) to the last commit`}),f.settings.mode==="write"&&ae.push({value:"plan",label:"Switch to plan mode",description:"Rethink and propose a plan before editing"});let de=await Q({title:"What would you like to do instead?",question:s,pauseResume:i,choices:ae});if(de==="undo"){let ke=await Ei(f.runtime,t.cwd,V);ke.ok?v(`Reverted ${V.length} file(s) to the last commit.`):q(`Undo failed: ${ke.output.slice(0,300)}`);return}if(de==="plan"){t.mode="plan",d.mode="plan",await n.sessions.save(d),await S(),v("Switched to PLAN mode. Describe what you want instead.");return}de==="continue"&&await b("Continue from where you stopped. Check the current state first and do not redo work that is already finished.")}};await Nd({cli:t,created:f,services:n,session:d,approvalHandler:P,question:s,pauseResume:i});let A={armedAt:0};for(;;){let O=await n.skills.list().catch(()=>[]);l.setEntries(Si(O.map(p=>p.name)));let L=await Yd(o,t.cwd,A,{store:a,onShiftTab:m,bypass:()=>u.bypass});if(L===null)break;let B=L.pasted,y=L.text;if(y){if(!B&&_n(y))break;if(!B&&(y==="/"||xd(y))){let p=y,g=l.takeSelection();if(g)y=`/${g}`;else{let k=await n.skills.list().catch(()=>[]);if(!(p!=="/"&&k.some(T=>T.name===p.slice(1)))){let T=await Td({question:s,pauseResume:i,skillNames:k.map(G=>G.name),initialQuery:p==="/"?"":p.slice(1)});if(!T)continue;y=T}}}if(!B&&_n(y))break;if(y==="/help"){Sd();continue}if(y==="/learn"||y.startsWith("/learn ")){let p=y.slice(6).trim().toLowerCase();if(!p){let h=await Q({title:"/learn \u2014 choose an action:",question:s,pauseResume:i,choices:[{value:"status",label:"status",description:"Show learning state and facts",default:!0},{value:"on",label:"on",description:"Enable continuous learning"},{value:"off",label:"off",description:"Disable continuous learning"}]});if(!h)continue;p=h}if(p==="on"||p==="enable"){await Ot(t.cwd,!0),v("Logbook learning on. New durable facts append to .kpilot/logbook/learnings.md after chats.");continue}if(p==="off"||p==="disable"){await Ot(t.cwd,!1),v("Logbook learning off for this project.");continue}let g=await At(t.cwd),k=await Fr(t.cwd);console.log(g?"Logbook learning: on":"Logbook learning: off"),console.log(k?`Learnings:
369
- ${k}`:"Learnings: (none yet)");continue}if(y==="/logbook"||y.startsWith("/logbook ")||y==="/understand"||y.startsWith("/understand ")){let g=(y.startsWith("/logbook")?y.slice(8):y.slice(11)).trim().toLowerCase();if(!g&&y==="/logbook"){let k=await Q({title:"/logbook \u2014 choose an action:",question:s,pauseResume:i,choices:[{value:"capture",label:"capture",description:"Inspect repo and write project.md",default:!0},{value:"skip",label:"skip",description:"Do not auto-offer Logbook again"}]});if(!k)continue;g=k==="capture"?"":k}if(g==="skip"){await Lr(t.cwd),v("Will not auto-offer Logbook capture again. Run /logbook to build it later.");continue}await Ur(t.cwd),await Li({cli:t,created:f,services:n,session:d,approvalHandler:P});continue}if(y==="/save"){d.messages=[...f.agent.messages],await n.sessions.save(d),v(`Saved session ${d.id.slice(0,8)}.`);continue}if(y==="/undo"){let p=d.runs.at(-1);if(!p){_("No completed run to undo.");continue}let g=Bn(p.diffAfter??"");if(g.length===0){_("Last run did not change any tracked files.");continue}let k=await Ei(f.runtime,t.cwd,g);k.ok?(v(`Undid ${g.length} file(s) from the last run.`),$(g.join(" "))):q(`Undo failed: ${k.output.slice(0,300)}`);continue}if(y==="/clear"){f.agent.reset(),d.messages=[],await n.sessions.save(d),v("Conversation history cleared; run history remains available for feedback.");continue}if(y==="/compact"){try{let p=await f.agent.compact();d.messages=[...f.agent.messages],await n.sessions.save(d),p.after<p.before?v(`Compacted context: ${p.before} \u2192 ${p.after} messages.`):$("Nothing to compact yet.")}catch(p){q(`Compaction failed: ${p instanceof Error?p.message:String(p)}`)}continue}if(y==="/cost"){let p=d.runs,g=p.reduce((k,h)=>({inputTokens:k.inputTokens+(h.usage?.inputTokens??0),outputTokens:k.outputTokens+(h.usage?.outputTokens??0),costUsd:k.costUsd+(h.usage?.estimatedCostUsd??0)}),{inputTokens:0,outputTokens:0,costUsd:0});console.log(j(I.bold,"Session cost")),console.log(` runs: ${p.length}`),console.log(` input: ${ue(g.inputTokens)} tokens`),console.log(` output: ${ue(g.outputTokens)} tokens`),console.log(` est: $${g.costUsd.toFixed(6)}`),$("Automatic routing picks the cheapest capable model; prompt caching reuses earlier context.");continue}if(y==="/context"){let p=[...f.agent.messages],g=p.reduce((G,V)=>{let ae=typeof V.content=="string"?V.content:"",de=V.role==="assistant"?(V.tool_calls??[]).map(ke=>ke.function.arguments).join(""):"";return G+ae.length+de.length},0),k=Math.ceil(g/4),h=Ui(f.settings.provider),T=h?Math.round(k/h*100):void 0;console.log(j(I.bold,"Conversation context")),console.log(` messages: ${p.length}`),console.log(` approx: ~${ue(k)} tokens`),h&&T!==void 0&&console.log(` window: ${ue(h)} (${Math.min(100,T)}% used)`),T!==void 0&&T>=80?_("Context is nearly full \u2014 run /compact to summarize history."):$("Use /compact to summarize history when it grows large.");continue}if(y==="/checkpoint"||y.startsWith("/checkpoint ")){let p=y.slice(11).trim(),[g="list",...k]=p?p.split(/\s+/):["list"];try{if(g==="save"||g==="s"){let h=await n.checkpoints.save(d.id,[...f.agent.messages],k.join(" "));v(`Checkpoint ${h.id.slice(0,8)} saved (${h.messages.length} messages).`)}else if(g==="restore"||g==="r"){let h=k[0];if(!h){_("Usage: /checkpoint restore <id>");continue}let T=await n.checkpoints.load(d.id,h);f.agent.restore(T.messages),d.messages=[...f.agent.messages],await n.sessions.save(d),v(`Restored checkpoint ${T.id.slice(0,8)} (${T.messages.length} messages).`)}else if(g==="remove"||g==="rm"){let h=k[0];if(!h){_("Usage: /checkpoint remove <id>");continue}await n.checkpoints.remove(d.id,h),v(`Removed checkpoint ${h}.`)}else{let h=await n.checkpoints.list(d.id);h.length===0&&console.log("[no checkpoints]");for(let T of h)console.log(`${T.id.slice(0,8)} ${T.createdAt} ${T.label}`)}}catch(h){q(h instanceof Error?h.message:String(h))}continue}if(y==="/mode"||y.startsWith("/mode ")){let p=y==="/mode"?"":y.slice(6).trim();if(!p){let g=await Q({title:"/mode \u2014 choose write or plan:",question:s,pauseResume:i,choices:[{value:"write",label:"write",description:"Allow file and command changes",default:!0},{value:"plan",label:"plan",description:"Inspect and reason only"}]});if(!g)continue;p=g}if(p!=="plan"&&p!=="write"){_("Mode must be plan or write.");continue}t.mode=p,d.mode=p,await n.sessions.save(d),await S(),v(`Switched to ${p.toUpperCase()} mode.`),console.log(Nt(f.settings.mode,f.settings.showModel?f.settings.model:void 0,d.id.slice(0,8),{bypass:u.bypass}));continue}if(y==="/status"||y==="/diff"){let p=y==="/status"?"git_status":"git_diff",g=await f.runtime.execute(p,{},{rootDir:t.cwd,mode:f.settings.mode});console.log(g.output);continue}if(y==="/sessions"||y==="/resume"||y.startsWith("/resume ")){let p=y.startsWith("/resume ")?y.slice(8).trim():"";if(p){await C(await n.sessions.load(p));continue}let g=await $n({store:n.sessions,question:s,pauseResume:i,title:"Switch session (Esc to stay):",currentId:d.id,prefer:"current"});if(g.kind!=="session"){g.kind==="cancel"&&$("Staying on the current session.");continue}if(g.session.id===d.id){$(`Already on ${d.id.slice(0,8)} \xB7 ${d.title}`);continue}await C(g.session);continue}if(y==="/new"||y.startsWith("/new ")){let p=y.slice(4).trim()||void 0;d=await n.sessions.create({title:p,mode:f.settings.mode,model:f.settings.model}),t.session=d.id,await S(),v(`Started session ${d.id.slice(0,8)} \xB7 ${d.title}`);continue}if(y==="/memory"){Ni(await n.memory.list());continue}if(y==="/todo"||y.startsWith("/todo ")){let p=y.slice(5).trim();if(!p){let T=await n.todos.list();if(T.length===0)console.log("[no todos]");else for(let G of T)console.log(`${G.completed?j(I.green,"\u2713"):j(I.cyan,"\xB7")} ${G.id.slice(0,8)} ${G.text}`);continue}let[g="",...k]=p.split(/\s+/),h=k.join(" ").trim();try{if(g==="add"||g==="a"){let T=await n.todos.add(h);v(`Todo ${T.id.slice(0,8)}: ${T.text}`)}else if(g==="done"||g==="complete"||g==="d"){let T=await n.todos.complete(h);v(`Completed ${T.id.slice(0,8)}: ${T.text}`)}else if(g==="remove"||g==="rm"){let T=await n.todos.remove(h);$(`Removed ${T.id.slice(0,8)}: ${T.text}`)}else if(g==="clear"){let T=await n.todos.clear();v(`Cleared ${T} todo(s).`)}else _(`Unknown todo action "${g}". Usage: /todo [add|done|remove|clear] [text|id]`)}catch(T){q(T instanceof Error?T.message:String(T))}continue}if(y.startsWith("/remember ")){let p=await n.memory.add(y.slice(10));v(`Remembered ${p.id.slice(0,8)}: ${p.text}`);continue}if(y.startsWith("/forget ")){let p=await n.memory.remove(y.slice(8).trim());v(`Removed memory: ${p.text}`);continue}if(y==="/skills"){Fi(await n.skills.list());continue}if(y.startsWith("/skill ")){let p=y.slice(7).trim(),[g="",...k]=p.split(/\s+/),h=await n.skills.get(g);await b(k.join(" ")||`Run the ${g} skill for the current repository.`,h);continue}if(y==="/preferences"){let p=await n.preferences.listRules();p.length===0&&console.log("[no learned preferences]");for(let g of p)console.log(`${g.id.slice(0,8)} ${Math.round(g.confidence*100)}% ${g.polarity}: ${g.text}`);continue}if(y==="/feedback"||y.startsWith("/feedback ")){let p=y.slice(9).trim();if(!p){let h=await Q({title:"/feedback \u2014 choose an outcome:",question:s,pauseResume:i,choices:[{value:"accepted",label:"accepted",description:"Mark last run accepted"},{value:"rejected",label:"rejected",description:"Mark last run rejected"},{value:"edited",label:"edited",description:"Mark last run edited"}]});if(!h)continue;let T=(await o.question("Optional note \u203A ")).trim();p=T?`${h} ${T}`:h}let[g="",...k]=p.split(/\s+/);await Ki({outcome:Ji(g),note:k.join(" ")||void 0,session:d,services:n,runtime:f.localRuntime,mode:f.settings.mode,rootDir:t.cwd});continue}if(y==="/models"||y==="/model"){let p=await Kr();if(p.length===0){_("No kpilot capabilities are configured for this account yet.");continue}let g=f.settings.model&&f.settings.model!=="auto"?f.settings.model:"auto",k=await Q({title:"/models \u2014 select a kpilot capability:",question:s,pauseResume:i,typeahead:!0,pageSize:8,choices:[{value:"auto",label:"auto",description:"kpilot chooses automatically (recommended)",default:g==="auto"},...p.map(h=>({value:h.model,label:Ft(h.model),description:go(h.model),default:h.model===g}))]});if(k==null)continue;if(k===g){v(`Already using ${k==="auto"?"auto":Ft(k)}.`);continue}t.model=k==="auto"?void 0:k,d.messages=[...f.agent.messages],await S(),v(`Switched to ${k==="auto"?"auto":Ft(k)}. Run a prompt to use it.`);continue}if(y==="/agent"){await Di({...t,args:["show"]});continue}if(y==="/mcp"){let p=f.mcpRuntime?.list()??[];p.length===0&&console.log("[no connected MCP tools]");for(let g of p)console.log(`${g.exposedName.padEnd(38)} ${g.description}`);continue}if(y==="/worktrees"){Wi(await new Ct(t.cwd).list());continue}if(y==="/policy"){let p=await n.policy.load();console.log(p?JSON.stringify(p,null,2):"[no team policy]");continue}if(y==="/usage"){let p=await n.policy.load(),g=await n.usage.check(Cn(e.usage?.budget,p?.usage));zr(g.summary);for(let k of g.warnings)_(k);for(let k of g.violations)q(k);continue}if(y==="/audit"){let p=await n.audit.verify();p.valid?v(`Audit chain valid: ${p.records} record(s).`):q(`Audit chain invalid: ${p.reason??"unknown reason"}`);continue}if(y==="/admin"){await Gi({...t,args:["status"]});continue}if(!B&&y.startsWith("/")){let[p="",...g]=y.slice(1).split(/\s+/);if(!Oi.has(p)){try{let h=await n.skills.get(p);await b(g.join(" ")||`Run the ${p} skill for the current repository.`,h)}catch(h){_(h instanceof Error?h.message:String(h))}continue}let k=Dt.find(h=>h.name===p||(h.aliases??[]).includes(p));_(`Unknown arguments for /${p}.${k?` Usage: ${k.usage}`:""} Run /help to list commands.`);continue}try{await b(y)}catch(p){q(p instanceof Error?p.message:String(p))}}}}finally{l.detach(),c.detach(),process.stdout.isTTY&&process.stdout.write(bo),w&&(d.messages=[...f.agent.messages],await n.sessions.save(d),await f.close()),o.close()}}async function wm(){kd();let t=process.argv.slice(2);if(t.includes("-V")||t.includes("--version")||t[0]==="version"){console.log(z);return}await Rd();let e=Md(t);if(e.command==="help"){console.log(Cd());return}if(e.command==="version"){console.log(z);return}if(e.command==="init"){await Od(e.cwd);return}if(e.command==="doctor"){process.exitCode=await Dd(e);return}if(e.command==="login"){await qi(e);return}if(e.command==="whoami"){await Zd(e);return}if(e.command==="logout"){await em(e);return}if(e.command==="models"){await Id(e);return}if(e.command==="agents"){await Di(e);return}if(e.command==="sessions"){await rm(e);return}if(e.command==="memory"){await om(e);return}if(e.command==="skills"){await sm(e);return}if(e.command==="preferences"){await im(e);return}if(e.command==="feedback"){await am(e);return}if(e.command==="mcp"){await cm(e);return}if(e.command==="worktrees"){await um(e);return}if(e.command==="policy"){await dm(e);return}if(e.command==="usage"){await mm(e);return}if(e.command==="audit"){await pm(e);return}if(e.command==="sync"){await fm(e);return}if(e.command==="admin"){await Gi(e);return}if(e.command==="chat"){await hm(e);return}await nm(e)}wm().catch(t=>{q(t instanceof Error?t.message:String(t)),process.exitCode=1});
378
+ ${o.filePath}`);return}throw new Error(`Unknown skills action: ${n}`)}async function km(t){await G(t.cwd);let e=oe(t.cwd).preferences,n=t.args[0]??"list";if(n==="list"){let r=await e.listRules();r.length===0&&console.log("[no learned preferences]");for(let o of r)console.log(`${o.id.slice(0,8)} ${String(Math.round(o.confidence*100)).padStart(3)}% ${o.polarity.padEnd(6)} ${o.text}`);return}if(n==="remove"){let r=t.args[1];if(!r)throw new Error("preferences remove requires a rule ID.");let o=await e.removeRule(r);T(`Removed preference: ${o.text}`);return}throw new Error(`Unknown preferences action: ${n}`)}async function xm(t){await G(t.cwd);let e=await we(t.cwd),n=oe(t.cwd),r=await n.policy.load(),o=nt(t,e,r),s=await n.sessions.list(),i=t.session??s[0]?.id;if(!i)throw new Error("No session exists. Pass --session after completing an agent run.");let a=await n.sessions.load(i),c=new be(t.cwd,{sandbox:e.sandbox});await oa({outcome:ra(t.args[0]),note:t.note??(t.args.slice(1).join(" ").trim()||void 0),session:a,services:n,runtime:c,mode:o.mode,rootDir:t.cwd})}async function Sm(t){if(t.args[0]==="serve"){await Tm(t);return}await G(t.cwd);let e=await we(t.cwd),n=await new je(t.cwd).load(),r=e.mcp?.servers??{},o=Object.entries(r).filter(([i,a])=>a.enabled!==!1&&(!n?.allowedMcpServers||n.allowedMcpServers.includes(i)));if(o.length===0){console.log("[no enabled MCP servers]");return}let s=await Ae.connect(Object.fromEntries(o));try{let i=s.list();i.length===0&&console.log("[MCP servers exposed no tools]");for(let a of i)console.log(`${a.exposedName.padEnd(38)} ${a.server.padEnd(16)} ${a.description}`)}finally{await s.close()}}async function Tm(t){await G(t.cwd);let e=await we(t.cwd),n=await new je(t.cwd).load(),r=new be(t.cwd,{sandbox:e.sandbox,browser:Qr(e)}),o=e.mcp?.servers??{},s=n?.allowedMcpServers?Object.fromEntries(Object.entries(o).filter(([l])=>n.allowedMcpServers.includes(l))):o,i=Object.values(s).some(l=>l.enabled!==!1)?await Ae.connect(s):void 0,a=new xt([r,i]);$(`Serving kpilot MCP server on stdio (${a.definitions().length} tools).`);let c=new cn(a,{name:"kpilot",version:V,rootDir:t.cwd,mode:t.mode??"write"});try{await Ts(c)}finally{await i?.close()}}function sa(t){for(let e of t){let n=e.managed?e.name??"[managed]":"[external]",r=e.branch??(e.detached?"[detached]":"[no branch]");console.log(`${n.padEnd(18)} ${r.padEnd(32)} ${e.path}`)}}async function Pm(t){await G(t.cwd);let e=new $t(t.cwd),n=t.args[0]??"list";if(n==="list"){sa(await e.list());return}if(n==="create"){let r=t.args[1];if(!r)throw new Error("worktrees create requires a name.");let o=await e.create(r,{base:t.args[2],branch:t.args[3]});T(`Created worktree ${o.name??r} on ${o.branch??"[detached]"}.`),console.log(o.path);return}if(n==="remove"){let r=t.args[1];if(!r)throw new Error("worktrees remove requires a name.");await e.remove(r,t.force),T(`Removed worktree ${r}.`);return}if(n==="prune"){await e.prune(),T("Pruned stale Git worktree metadata.");return}throw new Error(`Unknown worktrees action: ${n}`)}async function Em(t){await G(t.cwd);let e=oe(t.cwd),n=t.args[0]??"show";if(n==="show"){let r=await e.policy.load();console.log(r?JSON.stringify(r,null,2):"[no team policy]");return}if(n==="init"){let r=await we(t.cwd),o=t.model??process.env.KPILOT_MODEL??r.model?.model,s=await e.policy.initialize(t.organization,o?[o]:[]);await e.audit.append({action:"policy.init",outcome:"success",category:"administration",details:{organization:s.organization??"",allowedModels:s.allowedModels??[]}}),T(`Created ${L.relative(t.cwd,e.policy.filePath)}.`),o||A("No model was configured, so allowedModels is empty. Add approved model names before running the agent.");return}if(n==="validate"){if(!await e.policy.load())throw new Error("No team policy exists. Run `kpilot policy init`.");T("Team policy is valid.");return}throw new Error(`Unknown policy action: ${n}`)}function Zr(t){console.log(`date: ${t.date}`),console.log(`runs: ${t.runs}`),console.log(`input tokens: ${de(t.inputTokens)}`),console.log(`output tokens: ${de(t.outputTokens)}`),console.log(`total tokens: ${de(t.totalTokens)}`),console.log(`estimated cost: $${t.estimatedCostUsd.toFixed(6)}`)}async function Rm(t){await G(t.cwd);let e=await we(t.cwd),n=oe(t.cwd),r=await n.policy.load(),o=An(e.usage?.budget,r?.usage),s=t.args[0]??"summary";if(s==="summary"){Zr(await n.usage.summarize(t.args[1]));return}if(s==="list"){let i=await n.usage.list(t.limit);i.length===0&&console.log("[no usage records]");for(let a of i)console.log(`${a.timestamp} ${a.model.padEnd(24)} ${de(a.totalTokens).padStart(8)} tokens $${a.estimatedCostUsd.toFixed(6)} ${a.sessionId?.slice(0,8)??"-"}`);return}if(s==="check"){let i=await n.usage.check(o);Zr(i.summary);for(let a of i.warnings)A(a);if(!i.allowed)throw new Error(i.violations.join(" "));T("Usage budget allows another run.");return}throw new Error(`Unknown usage action: ${s}`)}async function Cm(t){await G(t.cwd);let e=oe(t.cwd).audit,n=t.args[0]??"list";if(n==="list"){let r=await e.list(t.limit);r.length===0&&console.log("[no audit records]");for(let o of r)console.log(`${o.timestamp} ${o.outcome.padEnd(9)} ${o.action.padEnd(24)} ${o.actor}@${o.host} ${o.sessionId?.slice(0,8)??"-"}`);return}if(n==="verify"){let r=await e.verify();if(!r.valid)throw new Error(`Audit verification failed at line ${r.firstInvalidLine??"?"}: ${r.reason??"unknown reason"}`);T(`Audit chain is valid: ${r.records} record(s), head ${r.headHash.slice(0,16)}.`);return}throw new Error(`Unknown audit action: ${n}`)}async function Mm(t){await G(t.cwd);let e=t.args[0],n=t.args[1];if(!e||!n)throw new Error("sync requires an action and bundle path.");let r=new xn(t.cwd),o=oe(t.cwd).audit;if(e==="inspect"){console.log(JSON.stringify(await r.inspectBundle(n),null,2));return}let s=process.env[t.passphraseEnv];if(!s)throw new Error(`${t.passphraseEnv} is not set.`);if(e==="export"){let i=await r.exportBundle(n,s,t.includeSessions);await o.append({action:"sync.export",outcome:"success",category:"synchronization",details:{destination:L.resolve(n),includeSessions:i.includeSessions}}),T(`Encrypted sync bundle written to ${L.resolve(n)}.`);return}if(e==="import"){let i=await r.importBundle(n,s,t.overwrite);await o.append({action:"sync.import",outcome:"success",category:"synchronization",details:{source:L.resolve(n),imported:i.imported.length,skipped:i.skipped.length,overwrite:t.overwrite}}),T(`Imported ${i.imported.length} file(s); skipped ${i.skipped.length}.`);for(let a of i.skipped.slice(0,10))A(`Skipped existing file: ${a}`);return}throw new Error(`Unknown sync action: ${e}`)}async function ia(t){await G(t.cwd);let e=t.args[0]??"status";if(e!=="status")throw new Error(`Unknown admin action: ${e}`);let n=await we(t.cwd),r=oe(t.cwd),o=await r.policy.load(),s=await r.usage.check(An(n.usage?.budget,o?.usage)),i=await r.audit.verify();if(console.log(U(D.bold,"kpilot administration status")),console.log(`project: ${t.cwd}`),console.log(`policy: ${o?`enabled${o.organization?` (${o.organization})`:""}`:"not configured"}`),console.log(`usage: ${s.allowed?"allowed":"blocked"}; ${de(s.summary.totalTokens)} token(s) today`),console.log(`audit: ${i.valid?"valid":"invalid"}; ${i.records} record(s)`),console.log(`sessions: ${(await r.sessions.list()).length}`),console.log(`skills: ${(await r.skills.list()).length}`),console.log(`preferences: ${(await r.preferences.listRules()).length}`),s.warnings.length)for(let a of s.warnings)A(a);if(!s.allowed)for(let a of s.violations)J(a);i.valid||J(i.reason??"Audit chain invalid.")}async function $m(t){if(t.cli.session)return await t.store.load(t.cli.session);if(t.cli.yes)return await t.store.create({title:t.cli.title,mode:t.settings.mode,model:t.settings.model});if((await t.store.list()).length===0)return await t.store.create({title:t.cli.title,mode:t.settings.mode,model:t.settings.model});let n=await Dn({store:t.store,question:t.question,pauseResume:t.pauseResume,title:"Re-open a session, or start fresh?",includeFresh:!0,prefer:"recent"});return n.kind==="cancel"?null:n.kind==="session"?n.session:await t.store.create({title:t.cli.title,mode:t.settings.mode,model:t.settings.model})}async function _m(t){if(!process.stdin.isTTY)throw new Error("Interactive chat requires a TTY.");await G(t.cwd);let e=await we(t.cwd),n=oe(t.cwd),r=nt(t,e,await n.policy.load()),o=Gi({input:process.stdin,output:process.stdout}),s=S=>o.question(S),i=zi(o),a=new Kt,c=new Wt(o,process.stdin,a,{prepare:Ro,placeholder:Bn});c.attach();let l=new Jt(o,{input:process.stdin,output:process.stdout});l.setEntries(Li()),l.attach();let u={bypass:t.bypassPermissions},m=()=>(u.bypass=!u.bypass,yo(u.bypass));process.stdout.isTTY&&process.stdout.write(Po);let d,p,y=!1;try{let S=await $m({cli:t,store:n.sessions,settings:r,question:s,pauseResume:i});if(!S){$("Cancelled.");return}d=S,t.session=d.id,t.mode||(t.mode=d.mode),p=await Xr(t,e,d),y=!0;let x=Yi(t,s,i);console.log(qt(p.settings.mode,p.settings.showModel?p.settings.model:void 0,d.title,{bypass:u.bypass})),console.log(U(D.dim,`${t.cwd} \xB7 ${d.title}`));let k=async()=>{await p.close();let I=await we(t.cwd);r=nt(t,I,await n.policy.load()),p=await Xr(t,I,d)},R=async I=>{d.messages=[...p.agent.messages],await n.sessions.save(d),d=I,t.session=d.id,t.mode=d.mode,await k(),T(`Switched to ${d.title}`)},P=async(I,j)=>{let N,h=Date.now();try{let f=p.settings.mode==="plan",w=await to(g=>no({cli:t,created:p,services:n,session:d,prompt:I,approvalHandler:x,bypassPermissions:u.bypass,skill:j,signal:g,onDiffBefore:b=>{N=b}}));if(w.streamed||(ot(),console.log(`${On(p.settings.showModel?p.settings.model:void 0)} \u203A ${w.answer}`)),w.tokensUsed>0&&console.log(U(D.dim,`saved \xB7 ${d.title}`)),f&&w.answer.trim()&&process.stdin.isTTY){let g=Ko(t.cwd,I);await et(L.dirname(g),{recursive:!0}),await ke(g,`${w.answer.trim()}
379
+ `,"utf8");let b=L.relative(t.cwd,g);$(`Plan saved to ${b}`),await Q({title:"Proceed to implement this plan in write mode?",question:s,pauseResume:i,choices:[{value:"yes",label:"yes",description:"Switch to write mode and implement",default:!0},{value:"no",label:"no",description:"Stay in plan mode"}]})==="yes"&&(t.mode="write",d.mode="write",await n.sessions.save(d),await k(),T("Switched to WRITE mode. Implementing the plan\u2026"),await P(`Implement the plan in ${b}. Follow it step by step and verify your changes.`))}}catch(f){if(!it(f))throw f;d.messages=[...p.agent.messages],await n.sessions.save(d),st();let w=ct.stopReason,g=Math.max(1,Math.round((Date.now()-h)/1e3));A(w==="Esc"?`Stopped with Esc after ${g}s. Your request is kept and will be answered next.`:`Stopped after ${g}s. Your request is kept and will be answered next.`);let b=await _n(p.localRuntime,t.cwd,p.settings.mode),v=b!==N,O=!N||!N.trim(),H=v?Hn(b??""):[];if(!process.stdin.isTTY)return;let ce=[{value:"prompt",label:"Back to the prompt",description:"Nothing else runs \u2014 tell me what to change",default:!0},{value:"continue",label:"Continue where it stopped",description:"Resume without redoing finished work"}];O&&H.length>0&&ce.push({value:"undo",label:"Undo this run's changes",description:`Revert ${H.length} file(s) to the last commit`}),p.settings.mode==="write"&&ce.push({value:"plan",label:"Switch to plan mode",description:"Rethink and propose a plan before editing"});let te=await Q({title:"What would you like to do instead?",question:s,pauseResume:i,choices:ce});if(te==="undo"){let ye=await Fi(p.runtime,t.cwd,H);ye.ok?T(`Reverted ${H.length} file(s) to the last commit.`):J(`Undo failed: ${ye.output.slice(0,300)}`);return}if(te==="plan"){t.mode="plan",d.mode="plan",await n.sessions.save(d),await k(),T("Switched to PLAN mode. Describe what you want instead.");return}te==="continue"&&await P(Zo)}};await tm({cli:t,created:p,services:n,session:d,approvalHandler:x,question:s,pauseResume:i});let _={armedAt:0};for(;;){let I=await n.skills.list().catch(()=>[]);l.setEntries(Li(I.map(f=>f.name)));let j=await dm(o,t.cwd,_,{store:a,onShiftTab:m,bypass:()=>u.bypass});if(j===null)break;let N=j.pasted,h=j.text;if(h){if(!N&&jn(h))break;if(!N&&(h==="/"||Ud(h))){let f=h,w=l.takeSelection();if(w)h=`/${w}`;else{let g=await n.skills.list().catch(()=>[]);if(!(f!=="/"&&g.some(v=>v.name===f.slice(1)))){let v=await Fd({question:s,pauseResume:i,skillNames:g.map(O=>O.name),initialQuery:f==="/"?"":f.slice(1)});if(!v)continue;h=v}}}if(!N&&jn(h))break;if(h==="/help"){Nd();continue}if(h==="/learn"||h.startsWith("/learn ")){let f=h.slice(6).trim().toLowerCase();if(!f){let b=await Q({title:"/learn \u2014 choose an action:",question:s,pauseResume:i,choices:[{value:"status",label:"status",description:"Show learning state and facts",default:!0},{value:"on",label:"on",description:"Enable continuous learning"},{value:"off",label:"off",description:"Disable continuous learning"}]});if(!b)continue;f=b}if(f==="on"||f==="enable"){await Dt(t.cwd,!0),T("Logbook learning on. New durable facts append to .kpilot/logbook/learnings.md after chats.");continue}if(f==="off"||f==="disable"){await Dt(t.cwd,!1),T("Logbook learning off for this project.");continue}let w=await It(t.cwd),g=await Gr(t.cwd);console.log(w?"Logbook learning: on":"Logbook learning: off"),console.log(g?`Learnings:
380
+ ${g}`:"Learnings: (none yet)");continue}if(h==="/logbook"||h.startsWith("/logbook ")||h==="/understand"||h.startsWith("/understand ")){let w=(h.startsWith("/logbook")?h.slice(8):h.slice(11)).trim().toLowerCase();if(!w&&h==="/logbook"){let g=await Q({title:"/logbook \u2014 choose an action:",question:s,pauseResume:i,choices:[{value:"capture",label:"capture",description:"Inspect repo and write project.md",default:!0},{value:"skip",label:"skip",description:"Do not auto-offer Logbook again"}]});if(!g)continue;w=g==="capture"?"":g}if(w==="skip"){await Jr(t.cwd),T("Will not auto-offer Logbook capture again. Run /logbook to build it later.");continue}await Kr(t.cwd),await Qi({cli:t,created:p,services:n,session:d,approvalHandler:x});continue}if(h==="/save"){d.messages=[...p.agent.messages],await n.sessions.save(d),T(`Saved ${d.title}.`);continue}if(h==="/undo"){let f=d.runs.at(-1);if(!f){A("No completed run to undo.");continue}let w=Hn(f.diffAfter??"");if(w.length===0){A("Last run did not change any tracked files.");continue}let g=await Fi(p.runtime,t.cwd,w);g.ok?(T(`Undid ${w.length} file(s) from the last run.`),$(w.join(" "))):J(`Undo failed: ${g.output.slice(0,300)}`);continue}if(h==="/clear"){p.agent.reset(),d.messages=[],await n.sessions.save(d),T("Conversation history cleared; run history remains available for feedback.");continue}if(h==="/compact"){try{let f=await p.agent.compact();d.messages=[...p.agent.messages],await n.sessions.save(d),f.after<f.before?T(`Compacted context: ${f.before} \u2192 ${f.after} messages.`):$("Nothing to compact yet.")}catch(f){J(`Compaction failed: ${f instanceof Error?f.message:String(f)}`)}continue}if(h==="/cost"){let f=d.runs,w=f.reduce((g,b)=>({inputTokens:g.inputTokens+(b.usage?.inputTokens??0),outputTokens:g.outputTokens+(b.usage?.outputTokens??0),costUsd:g.costUsd+(b.usage?.estimatedCostUsd??0)}),{inputTokens:0,outputTokens:0,costUsd:0});console.log(U(D.bold,"Session cost")),console.log(` runs: ${f.length}`),console.log(` input: ${de(w.inputTokens)} tokens`),console.log(` output: ${de(w.outputTokens)} tokens`),console.log(` est: $${w.costUsd.toFixed(6)}`),$("Automatic routing picks the cheapest capable model; prompt caching reuses earlier context.");continue}if(h==="/context"){let f=[...p.agent.messages],w=f.reduce((O,H)=>{let ce=typeof H.content=="string"?H.content:"",te=H.role==="assistant"?(H.tool_calls??[]).map(ye=>ye.function.arguments).join(""):"";return O+ce.length+te.length},0),g=Math.ceil(w/4),b=Xi(p.settings.provider),v=b?Math.round(g/b*100):void 0;console.log(U(D.bold,"Conversation context")),console.log(` messages: ${f.length}`),console.log(` approx: ~${de(g)} tokens`),b&&v!==void 0&&console.log(` window: ${de(b)} (${Math.min(100,v)}% used)`),v!==void 0&&v>=80?A("Context is nearly full \u2014 run /compact to summarize history."):$("Use /compact to summarize history when it grows large.");continue}if(h==="/checkpoint"||h.startsWith("/checkpoint ")){let f=h.slice(11).trim(),[w="list",...g]=f?f.split(/\s+/):["list"];try{if(w==="save"||w==="s"){let b=await n.checkpoints.save(d.id,[...p.agent.messages],g.join(" "));T(`Checkpoint ${b.id.slice(0,8)} saved (${b.messages.length} messages).`)}else if(w==="restore"||w==="r"){let b=g[0];if(!b){A("Usage: /checkpoint restore <id>");continue}let v=await n.checkpoints.load(d.id,b);p.agent.restore(v.messages),d.messages=[...p.agent.messages],await n.sessions.save(d),T(`Restored checkpoint ${v.id.slice(0,8)} (${v.messages.length} messages).`)}else if(w==="remove"||w==="rm"){let b=g[0];if(!b){A("Usage: /checkpoint remove <id>");continue}await n.checkpoints.remove(d.id,b),T(`Removed checkpoint ${b}.`)}else{let b=await n.checkpoints.list(d.id);b.length===0&&console.log("[no checkpoints]");for(let v of b)console.log(`${v.id.slice(0,8)} ${v.createdAt} ${v.label}`)}}catch(b){J(b instanceof Error?b.message:String(b))}continue}if(h==="/mode"||h.startsWith("/mode ")){let f=h==="/mode"?"":h.slice(6).trim();if(!f){let w=await Q({title:"/mode \u2014 choose write or plan:",question:s,pauseResume:i,choices:[{value:"write",label:"write",description:"Allow file and command changes",default:!0},{value:"plan",label:"plan",description:"Inspect and reason only"}]});if(!w)continue;f=w}if(f!=="plan"&&f!=="write"){A("Mode must be plan or write.");continue}t.mode=f,d.mode=f,await n.sessions.save(d),await k(),T(`Switched to ${f.toUpperCase()} mode.`),console.log(qt(p.settings.mode,p.settings.showModel?p.settings.model:void 0,d.title,{bypass:u.bypass}));continue}if(h==="/status"||h==="/diff"){let f=h==="/status"?"git_status":"git_diff",w=await p.runtime.execute(f,{},{rootDir:t.cwd,mode:p.settings.mode});console.log(w.output);continue}if(h==="/sessions"||h==="/resume"||h.startsWith("/resume ")){let f=h.startsWith("/resume ")?h.slice(8).trim():"";if(f){await R(await n.sessions.load(f));continue}let w=await Dn({store:n.sessions,question:s,pauseResume:i,title:"Switch session (Esc to stay):",currentId:d.id,prefer:"current"});if(w.kind!=="session"){w.kind==="cancel"&&$("Staying on the current session.");continue}if(w.session.id===d.id){$(`Already on ${d.title}`);continue}await R(w.session);continue}if(h==="/new"||h.startsWith("/new ")){let f=h.slice(4).trim()||void 0;d=await n.sessions.create({title:f,mode:p.settings.mode,model:p.settings.model}),t.session=d.id,await k(),T(`Started ${d.title}`);continue}if(h==="/memory"){Zi(await n.memory.list());continue}if(h==="/todo"||h.startsWith("/todo ")){let f=h.slice(5).trim();if(!f){let v=await n.todos.list();if(v.length===0)console.log("[no todos]");else for(let O of v)console.log(`${O.completed?U(D.green,"\u2713"):U(D.cyan,"\xB7")} ${O.id.slice(0,8)} ${O.text}`);continue}let[w="",...g]=f.split(/\s+/),b=g.join(" ").trim();try{if(w==="add"||w==="a"){let v=await n.todos.add(b);T(`Todo ${v.id.slice(0,8)}: ${v.text}`)}else if(w==="done"||w==="complete"||w==="d"){let v=await n.todos.complete(b);T(`Completed ${v.id.slice(0,8)}: ${v.text}`)}else if(w==="remove"||w==="rm"){let v=await n.todos.remove(b);$(`Removed ${v.id.slice(0,8)}: ${v.text}`)}else if(w==="clear"){let v=await n.todos.clear();T(`Cleared ${v} todo(s).`)}else A(`Unknown todo action "${w}". Usage: /todo [add|done|remove|clear] [text|id]`)}catch(v){J(v instanceof Error?v.message:String(v))}continue}if(h.startsWith("/remember ")){let f=await n.memory.add(h.slice(10));T(`Remembered ${f.id.slice(0,8)}: ${f.text}`);continue}if(h.startsWith("/forget ")){let f=await n.memory.remove(h.slice(8).trim());T(`Removed memory: ${f.text}`);continue}if(h==="/skills"){ea(await n.skills.list());continue}if(h.startsWith("/skill ")){let f=h.slice(7).trim(),[w="",...g]=f.split(/\s+/),b=await n.skills.get(w);await P(g.join(" ")||`Run the ${w} skill for the current repository.`,b);continue}if(h==="/preferences"){let f=await n.preferences.listRules();f.length===0&&console.log("[no learned preferences]");for(let w of f)console.log(`${w.id.slice(0,8)} ${Math.round(w.confidence*100)}% ${w.polarity}: ${w.text}`);continue}if(h==="/feedback"||h.startsWith("/feedback ")){let f=h.slice(9).trim();if(!f){let b=await Q({title:"/feedback \u2014 choose an outcome:",question:s,pauseResume:i,choices:[{value:"accepted",label:"accepted",description:"Mark last run accepted"},{value:"rejected",label:"rejected",description:"Mark last run rejected"},{value:"edited",label:"edited",description:"Mark last run edited"}]});if(!b)continue;let v=(await o.question("Optional note \u203A ")).trim();f=v?`${b} ${v}`:b}let[w="",...g]=f.split(/\s+/);await oa({outcome:ra(w),note:g.join(" ")||void 0,session:d,services:n,runtime:p.localRuntime,mode:p.settings.mode,rootDir:t.cwd});continue}if(h==="/models"||h==="/model"){let f=await Yr();if(f.length===0){A("No kpilot capabilities are configured for this account yet.");continue}let w=p.settings.model&&p.settings.model!=="auto"?p.settings.model:"auto",g=await Q({title:"/models \u2014 select a kpilot capability:",question:s,pauseResume:i,typeahead:!0,pageSize:8,choices:[{value:"auto",label:"auto",description:"kpilot chooses automatically (recommended)",default:w==="auto"},...f.map(b=>({value:b.model,label:Bt(b.model),description:xo(b.model),default:b.model===w}))]});if(g==null)continue;if(g===w){T(`Already using ${g==="auto"?"auto":Bt(g)}.`);continue}t.model=g==="auto"?void 0:g,d.messages=[...p.agent.messages],await k(),T(`Switched to ${g==="auto"?"auto":Bt(g)}. Run a prompt to use it.`);continue}if(h==="/agent"){await Vi({...t,args:["show"]});continue}if(h==="/mcp"){let f=p.mcpRuntime?.list()??[];f.length===0&&console.log("[no connected MCP tools]");for(let w of f)console.log(`${w.exposedName.padEnd(38)} ${w.description}`);continue}if(h==="/worktrees"){sa(await new $t(t.cwd).list());continue}if(h==="/policy"){let f=await n.policy.load();console.log(f?JSON.stringify(f,null,2):"[no team policy]");continue}if(h==="/usage"){let f=await n.policy.load(),w=await n.usage.check(An(e.usage?.budget,f?.usage));Zr(w.summary);for(let g of w.warnings)A(g);for(let g of w.violations)J(g);continue}if(h==="/audit"){let f=await n.audit.verify();f.valid?T(`Audit chain valid: ${f.records} record(s).`):J(`Audit chain invalid: ${f.reason??"unknown reason"}`);continue}if(h==="/admin"){await ia({...t,args:["status"]});continue}if(!N&&h.startsWith("/")){let[f="",...w]=h.slice(1).split(/\s+/);if(!Hi.has(f)){try{let b=await n.skills.get(f);await P(w.join(" ")||`Run the ${f} skill for the current repository.`,b)}catch(b){A(b instanceof Error?b.message:String(b))}continue}let g=Lt.find(b=>b.name===f||(b.aliases??[]).includes(f));A(`Unknown arguments for /${f}.${g?` Usage: ${g.usage}`:""} Run /help to list commands.`);continue}try{await P(h)}catch(f){J(f instanceof Error?f.message:String(f))}}}}finally{l.detach(),c.detach(),st(),process.stdout.isTTY&&process.stdout.write(`${Eo}${ro}`),y&&(d.messages=[...p.agent.messages],await n.sessions.save(d),await p.close()),o.close()}}async function Am(){Ld();let t=process.argv.slice(2);if(t.includes("-V")||t.includes("--version")||t[0]==="version"){console.log(V);return}await Jd();let e=Wd(t);if(e.command==="help"){console.log(Kd());return}if(e.command==="version"){console.log(V);return}if(e.command==="init"){await Vd(e.cwd);return}if(e.command==="doctor"){process.exitCode=await Qd(e);return}if(e.command==="login"){await na(e);return}if(e.command==="whoami"){await fm(e);return}if(e.command==="logout"){await gm(e);return}if(e.command==="models"){await Yd(e);return}if(e.command==="agents"){await Vi(e);return}if(e.command==="sessions"){await ym(e);return}if(e.command==="memory"){await bm(e);return}if(e.command==="skills"){await vm(e);return}if(e.command==="preferences"){await km(e);return}if(e.command==="feedback"){await xm(e);return}if(e.command==="mcp"){await Sm(e);return}if(e.command==="worktrees"){await Pm(e);return}if(e.command==="policy"){await Em(e);return}if(e.command==="usage"){await Rm(e);return}if(e.command==="audit"){await Cm(e);return}if(e.command==="sync"){await Mm(e);return}if(e.command==="admin"){await ia(e);return}if(e.command==="chat"){await _m(e);return}await wm(e)}Am().catch(t=>{st(),process.stdout.isTTY&&process.stdout.write(ro),J(t instanceof Error?t.message:String(t)),process.exitCode=1});