agent-afk 3.51.0 → 3.51.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +2 -2
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -2116,7 +2116,7 @@ A CLAUDE.md exists at \`${r}\`. Read it and incorporate relevant context (comman
|
|
|
2116
2116
|
|
|
2117
2117
|
## Additional context from user
|
|
2118
2118
|
${a}`)}o.push({type:"text",text:s});let i=Cl(e,{skillName:"init",out:Ro(),onCancel:()=>{e.session.current.interrupt().catch(()=>{})}});try{await i.arm(),await jr(i.sink,async()=>{for await(let a of e.session.current.sendMessageStream(o))i.sink(a)})}catch(a){e.out.line(),e.out.error(`init failed: ${a instanceof Error?a.message:String(a)}`)}finally{await i.dispose()}return"continue"}};import uv from"chalk";var Lp=new Map;function dv(e,t){let n=Lp.get(e);if(n){if(n.glyph===t.glyph&&n.color===t.color&&n.inFlightVerb===t.inFlightVerb)return;throw new Error(`Trusted skill "${e}" already registered with different config`)}Lp.set(e,t),my(e)}function Il(e){return Lp.get(e)}function IN(e){return(e/1e3).toFixed(1)+"s"}function pv(e,t){let n=Il(e.skillName),r=IN(e.durationMs);if(!n){let s=`[${e.skillName} \xB7 ${r}]`;return Ao(s,t?.columns)}if(t?.isTTY!==!1){let s;if(e.claimsTotal!==void 0){let a=e.claimsTotal===e.claimsConfirmed&&e.claimsRefuted===void 0&&e.claimsInconclusive===void 0,l;if(a)l=`${e.claimsTotal} claims \xB7 all confirmed`;else{let c=`${e.claimsTotal} claims`;e.claimsConfirmed!==void 0&&(c+=` \xB7 ${e.claimsConfirmed} confirmed`),e.claimsRefuted!==void 0&&(c+=` \xB7 ${e.claimsRefuted} refuted`),e.claimsInconclusive!==void 0&&(c+=` \xB7 ${e.claimsInconclusive} inconclusive`),l=c}s=`${n.glyph} ${e.skillName} \xB7 ${l} \xB7 ${r}`}else s=`${n.glyph} ${e.skillName} \xB7 ${r}`;let i=uv.hex(n.color)(s);return Ao(i,t?.columns)}else{let s;if(e.claimsTotal!==void 0){let i=e.claimsConfirmed??0;s=`[${e.skillName} \xB7 ${i}/${e.claimsTotal} confirmed \xB7 ${r}]`}else s=`[${e.skillName} \xB7 ${r}]`;return Ao(s,t?.columns)}}function Ao(e,t){return t!==void 0&&z(e)>t?ue(e,t):e}function mv(e,t){let n=Il(e);if(!n){let s=`[${e} \xB7 running\u2026]`;return Ao(s,t?.columns)}if(t?.isTTY!==!1){let s=`${n.glyph} ${e} \xB7 ${n.inFlightVerb}`,i=uv.hex(n.color)(s);return Ao(i,t?.columns)}let o=`[${e} \xB7 ${n.inFlightVerb}]`;return Ao(o,t?.columns)}var fv={name:"/stats",summary:"Show session statistics including skill runs",async handler(e){let t=e.ledger;if(!t)return e.out.info("No skill stats available."),"continue";let n=t.summary();if(!n)return e.out.info("No skill runs recorded this session."),"continue";e.out.line(),e.out.line(m.bold("Skill runs"));for(let[r,o]of n){let s=Il(r)?.glyph??"",i=s?`${s} `:"",a=`${(o.totalDurationMs/1e3).toFixed(1)}s total`,l=`${o.runs} run${o.runs!==1?"s":""}`,c="";o.totalClaims!==void 0&&(c=` \xB7 ${o.totalClaims} claims`,o.totalConfirmed!==void 0&&(c+=` \xB7 ${o.totalConfirmed} confirmed`),o.totalRefuted!==void 0&&(c+=` \xB7 ${o.totalRefuted} refuted`),o.totalInconclusive!==void 0&&(c+=` \xB7 ${o.totalInconclusive} inconclusive`)),e.out.line(` ${i}${r} ${l}${c} \xB7 ${a}`)}return e.out.line(),"continue"}};function PN(e=Du){return{name:"/font-size",summary:"Get or set the terminal font size in Cursor / VS Code",usage:"/font-size [size] [editor]",hint:"Direct shortcut to the terminal_font_size tool \u2014 bypasses the LLM and the first-write permission prompt. Examples: `/font-size` (read all), `/font-size 18` (set all), `/font-size 14 cursor` (set Cursor only).",async handler(t,n){let r=n.split(/\s+/).filter(Boolean),o=new AbortController;if(r.length===0){let u=await e({action:"get"},o.signal);return u.isError?t.out.error(u.content):t.out.line(u.content),"continue"}let s=r[0],i=Number(s);if(!Number.isFinite(i))return t.out.error(`Invalid size: "${s}". Usage: /font-size [size] [editor]`),"continue";let a=r[1],l={action:"set",size:i};a!==void 0&&(l.editor=a);let c=await e(l,o.signal);return c.isError?t.out.error(c.content):t.out.success(c.content),"continue"}}}var gv=PN();import MN from"path";import{statSync as ON}from"fs";var hr;function hv(e){hr=e}var yv={name:"/allow-dir",summary:"Manage per-session directory access grants for tool handlers",usage:"/allow-dir [--rw | --revoke] [<path>]",flags:["--rw","--revoke"],async handler(e,t){if(!hr)return e.out.error("Directory grants not available in this session."),"continue";let n=t.trim();if(!n){let a=hr.getGrants();return e.out.line(" Session directory grants:"),e.out.line(` resolveBase : ${a.resolveBase??"(none)"}`),e.out.line(` readRoots : ${a.readRoots.length>0?a.readRoots.join(", "):"(none)"}`),e.out.line(` writeRoots : ${a.writeRoots.length>0?a.writeRoots.join(", "):"(none)"}`),"continue"}let r="read",o=n;if(o.startsWith("--rw ")||o==="--rw"?(r="write",o=o.slice(5).trim()):(o.startsWith("--revoke ")||o==="--revoke")&&(r="revoke",o=o.slice(9).trim()),!o)return e.out.error("Usage: /allow-dir [--rw | --revoke] <path>"),"continue";let s=MN.resolve(process.cwd(),o);if(r!=="revoke")try{ON(s)}catch{return e.out.error(`Path does not exist: ${s}`),"continue"}let i=e.stats.sessionId;if(r==="revoke"){let a=hr.getGrants();hr.revokeRoot(s,"slash",i),a.resolveBase&&s===a.resolveBase?e.out.warn(`Cannot revoke the session's initial resolveBase: ${s}`):e.out.line(`\u2713 Revoked: ${s}`)}else r==="write"?(hr.addWriteRoot(s,"slash",i),e.out.line(`\u2713 Read+write grant: ${s}`)):(hr.addReadRoot(s,"slash",i),e.out.line(`\u2713 Read-only grant: ${s}`));return"continue"}};var bv=[{group:"Navigation",rows:[["ctrl+a","Move to start of current line"],["ctrl+e","Move to end of current line"],["ctrl+b","Move one character backward (input mode) / Run turn in background (streaming mode)"],["ctrl+f","Move one character forward"],["alt+b","Move one word backward"],["alt+f","Move one word forward"],["\u2190 / \u2192","Character left / right"],["home / end","Buffer start / end"]]},{group:"Editing",rows:[["ctrl+u","Delete to start of current line"],["ctrl+k","Delete to end of current line"],["ctrl+w","Delete previous word"],["backspace","Delete previous character"],["delete","Delete next character"],["alt+backspace","Delete previous word (Option+Delete on macOS)"],["alt+delete","Delete next word (Option+Fn-Delete on macOS)"]]},{group:"History",rows:[["ctrl+p / \u2191","Previous history entry (or move up in multi-line draft)"],["ctrl+n / \u2193","Next history entry (or move down in multi-line draft)"]]},{group:"Multi-line",rows:[["shift+enter","Insert newline (no submit)"],["alt+enter","Insert newline (no submit)"],["<text>\\","Trailing \\ + Enter inserts newline (backwards-compat)"]]},{group:"Misc",rows:[["ctrl+l","Clear screen and repaint"],["ctrl+v","Paste image from clipboard"],["ctrl+x","Remove last attached image"],["ctrl+c","Interrupt running turn / exit (second press)"],["ctrl+d","EOF / exit (when buffer is empty)"],["tab","Accept autocomplete suggestion"],["enter","Submit prompt"]]}],wv={name:"/keys",summary:"Show keybinding reference",async handler(e){e.out.line(),e.out.line(m.bold(m.brand("Keybindings"))),e.out.line(ge());let n=bv.flatMap(r=>r.rows).reduce((r,[o])=>Math.max(r,o.length),0);for(let{group:r,rows:o}of bv){e.out.line(),e.out.line(m.bold(r));for(let[s,i]of o){let a=" ".repeat(Math.max(0,n-s.length));e.out.line(` ${m.warning(s)}${a} ${m.dim(i)}`)}}return e.out.line(),"continue"}};import{execFile as HN}from"node:child_process";import{promises as KN}from"node:fs";import{dirname as GN,isAbsolute as zN,join as qN,resolve as JN}from"node:path";import{promisify as VN}from"node:util";U();import{promises as Rt,existsSync as Sv,createReadStream as $N}from"node:fs";import{join as Pl}from"node:path";import{createInterface as DN}from"node:readline";var LN=36e5,FN=30*864e5;function NN(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}function jN(e){let t=e.trim().split(/\n\n+/),n=[];for(let r of t){let o=r.split(`
|
|
2119
|
-
`),s="",i="",a="",l=!1,c=!1,u=!1;for(let d of o)d.startsWith("worktree ")?s=d.slice(9).trim():d.startsWith("HEAD ")?i=d.slice(5).trim():d.startsWith("branch ")?a=d.slice(7).trim():d.trim()==="locked"?l=!0:d.trim()==="prunable"?c=!0:d.trim()==="bare"&&(u=!0);s&&n.push({path:s,head:i,branch:a,locked:l,prunable:c,isBare:u})}return n}function UN(e,t,n){if(e.locked)return"locked";let r=864e5,o=t*r,s=n*r;return e.ownerLiveness==="dead"&&!e.isDirty&&e.commitsAhead===0?"dead-owner":e.commitsAhead===0&&!e.isDirty&&e.ageMs>=LN?"empty":e.isDirty&&e.ageMs>s?"stale-dirty":!e.isDirty&&e.ageMs>o?"stale-clean":"active"}async function BN(e){if(!Sv(e))return 0;let t=0;try{let n=DN({input:$N(e),crlfDelay:1/0});for await(let r of n){let o=r.trim();if(o)try{let s=JSON.parse(o);s.taskId==="worktree-prune"&&(s.status==="success"||s.status==="error")&&t++}catch{}}}catch{}return t}var Ml=class extends Error{constructor(t){super(`Worktree sweep lock contested: ${t} \u2014 another sweep may be running.`),this.name="LockContestedError"}};async function WN(e){let t=Pl(e,"..");await Rt.mkdir(t,{recursive:!0}).catch(()=>{});let r=await(async()=>{try{return await Rt.open(e,"wx")}catch(o){if(o.code!=="EEXIST")throw o;let i=null;try{let a=await Rt.readFile(e,"utf-8");i=parseInt(a.trim(),10)}catch{}if(i!==null&&!Number.isNaN(i)){let a=!1;try{process.kill(i,0),a=!0}catch{}if(!a)return await Rt.unlink(e).catch(()=>{}),await Rt.open(e,"wx")}throw new Ml(e)}})();return await r.writeFile(String(process.pid),"utf-8"),await r.close(),async()=>{await Rt.unlink(e).catch(()=>{})}}async function Ut(e){let{execFile:t,repoRoot:n,maxAgeDaysClean:r=14,maxAgeDaysDirty:o=30,scope:s="all",telemetryPath:i}=e,a=i??Ct(),l=vf(),c={removed:[],warnings:[],dryRun:e.dryRun??!1,candidates:[]},u=e.bypassSoftLaunch?Number.POSITIVE_INFINITY:await BN(a),d=e.dryRun===!0||u<3;c.dryRun=d;let p=null;try{p=await WN(l)}catch(f){if(f instanceof Ml)return c.warnings.push(`[WARN] ${f.message}`),c;throw f}try{let f=await t("git",["-C",n,"worktree","list","--porcelain"]),g=jN(f.stdout),h=Pl(n,".afk-worktrees"),b=new Set(g.map(v=>v.path)),y=[];try{y=(await Rt.readdir(h,{withFileTypes:!0})).filter(_=>_.isDirectory()).map(_=>Pl(h,_.name))}catch{}let w=y.filter(v=>!b.has(v));if(s==="all"||s==="interactive")for(let v of w){let _=0;try{let I=await Rt.stat(v);_=Date.now()-I.birthtimeMs}catch{}if(c.candidates.push({path:v,verdict:"orphaned-dir",owner:"interactive",ageMs:_}),!d)try{await Rt.rm(v,{recursive:!0,force:!0}),c.removed.push(v)}catch(I){c.warnings.push(`[ERROR] Failed to remove orphaned dir ${v}: ${I instanceof Error?I.message:String(I)}`)}}let k=!1,E=g[0]?.path;for(let v of g){if(v.path===E||v.isBare||!v.path.startsWith(h))continue;let _;try{let N=await Rt.readFile(Pl(v.path,".afk-worktree-meta.json"),"utf-8");_=JSON.parse(N)}catch{}if(s!=="all"&&_?.owner!==s)continue;let I=_?.owner==="interactive"||_?.owner==="diagnose"?_.owner:"unknown";if(!Sv(v.path)){c.candidates.push({path:v.path,verdict:"orphaned-registration",owner:I,ageMs:0}),d||(k=!0);continue}let R=0,C=_?.createdAt;if(C)R=Date.now()-new Date(C).getTime();else try{let N=await Rt.stat(v.path);R=Date.now()-N.birthtimeMs}catch{}let M=!1,$=0;try{M=(await t("git",["-C",v.path,"status","--porcelain"])).stdout.trim().length>0}catch{M=!0}if(!M&&v.head){let N=_?.baseSha??v.head;try{let K=await t("git",["-C",n,"rev-list",`${N}..${v.head}`,"--count"]);$=parseInt(K.stdout.trim(),10)||0}catch{$=0}}let x="unknown";typeof _?.pid=="number"&&Number.isInteger(_.pid)&&_.pid>0&&R<=FN&&(x=NN(_.pid)?"alive":"dead");let A={path:v.path,head:v.head,branch:v.branch,locked:v.locked,prunable:v.prunable,meta:_,ageMs:R,isDirty:M,commitsAhead:$,ownerLiveness:x},P=UN(A,r,o);if(c.candidates.push({path:v.path,verdict:P,owner:I,ageMs:R}),!d)try{P==="empty"?(await t("git",["-C",n,"worktree","remove","--force",v.path]),v.branch&&await t("git",["-C",n,"branch","-d",v.branch]).catch(()=>{}),c.removed.push(v.path)):P==="dead-owner"?(await t("git",["-C",n,"worktree","remove","--force",v.path]),v.branch&&await t("git",["-C",n,"branch","-d",v.branch]).catch(()=>{}),c.removed.push(v.path)):P==="stale-clean"?(await t("git",["-C",n,"worktree","remove","--force",v.path]),c.removed.push(v.path)):P==="stale-dirty"&&c.warnings.push(`[WARN] stale-dirty worktree preserved (uncommitted changes): ${v.path}`)}catch(N){c.warnings.push(`[ERROR] Failed to process ${v.path} (${P}): ${N instanceof Error?N.message:String(N)}`)}}if(k&&!d)try{await t("git",["-C",n,"worktree","prune"])}catch(v){c.warnings.push(`[ERROR] git worktree prune failed: ${v instanceof Error?v.message:String(v)}`)}}finally{p&&await p()}return c}var Fp=VN(HN),kv=["interactive","diagnose","all"],Ol=new Set(["empty","stale-clean","orphaned-dir","orphaned-registration","dead-owner"]);async function vv(){let t=(await Fp("git",["rev-parse","--git-common-dir"])).stdout.trim();if(!t)throw new Error("Not in a git repository.");let n=zN(t)?t:JN(process.cwd(),t);return GN(n)}function YN(e){if(e<=0)return"-";let t=e/864e5;return t<1?`${Math.max(1,Math.round(e/36e5))}h`:`${Math.round(t)}d`}function XN(e,t){return Ol.has(e)?m.error(t):e==="stale-dirty"?m.warning(t):e==="locked"?m.dim(t):m.dim(t)}function Tv(e,t){let n=e.split(/\s+/).map(o=>o.trim()).filter(o=>o.length>0),r={scope:t,apply:!1,unknown:[]};for(let o=0;o<n.length;o++){let s=n[o];if(s==="--apply")r.apply=!0;else if(s==="--scope"&&o+1<n.length){let i=n[o+1];o++,kv.includes(i)?r.scope=i:r.unknown.push(`--scope=${i}`)}else if(s.startsWith("--scope=")){let i=s.slice(8);kv.includes(i)?r.scope=i:r.unknown.push(s)}else r.unknown.push(s)}return r}async function ZN(e){try{let t=await KN.readFile(qN(e,".afk-worktree-meta.json"),"utf-8"),n=JSON.parse(t);if(typeof n.pid=="number"&&Number.isInteger(n.pid)&&n.pid>0)return n.pid}catch{}}async function QN(e,t,n){if(t.length===0){e.info("No afk-managed worktrees found.");return}let r=process.pid;e.line(),e.line(m.bold("Worktrees")),e.line(m.dim(" "+"PATH".padEnd(45)+" "+"OWNER".padEnd(12)+" "+"AGE".padEnd(5)+" "+"VERDICT".padEnd(22)+" PRUNE?"));for(let o of t){let a=n.get(o.path)===r?m.brand("\u2192 "):" ",l=o.path.slice(-44).padEnd(45),c=o.owner.padEnd(12),u=YN(o.ageMs).padEnd(5),d=o.verdict.padEnd(22),p=Ol.has(o.verdict)?m.error("yes"):o.verdict==="stale-dirty"?m.warning("warn"):m.dim("no"),f=XN(o.verdict,d);e.line(`${a}${l} ${c} ${u} ${f} ${p}`)}e.line(),e.line(m.dim(" \u2192 this session")),e.line()}async function ej(e){let t=new Map;for(let n of e)t.set(n.path,await ZN(n.path));return t}async function tj(e,t){let n=Tv(t,"interactive");n.unknown.length>0&&e.out.warn(`Unknown args ignored: ${n.unknown.join(" ")}`);let r;try{r=await vv()}catch(i){return e.out.error(`Not in a git repository: ${i.message}`),"continue"}let o;try{let i={execFile:Fp,repoRoot:r,dryRun:!0,scope:n.scope};o=await Ut(i)}catch(i){return e.out.error(`Sweep failed: ${i.message}`),"continue"}let s=await ej(o.candidates);await QN(e.out,o.candidates,s);for(let i of o.warnings)e.out.warn(i);return"continue"}async function nj(e,t){let n=Tv(t,"interactive");n.unknown.length>0&&e.out.warn(`Unknown args ignored: ${n.unknown.join(" ")}`);let r;try{r=await vv()}catch(a){return e.out.error(`Not in a git repository: ${a.message}`),"continue"}let o;try{let a={execFile:Fp,repoRoot:r,dryRun:!n.apply,scope:n.scope};o=await Ut(a)}catch(a){return e.out.error(`Sweep failed: ${a.message}`),"continue"}let s={};for(let a of o.candidates)s[a.verdict]=(s[a.verdict]??0)+1;let i=Object.entries(s).sort(([a],[l])=>a.localeCompare(l)).map(([a,l])=>`${a}=${l}`);if(o.dryRun){let a=o.candidates.filter(l=>Ol.has(l.verdict)).length;e.out.line(),e.out.line(m.warning("\u{1F50D} Dry-run \u2014 pass --apply to actually remove.")+` Would prune ${a} worktree(s).`+(i.length>0?` [${i.join(" ")}]`:""))}else{let a=o.warnings.filter(c=>c.startsWith("[WARN]")).length,l=o.warnings.filter(c=>c.startsWith("[ERROR]")).length;e.out.line(),e.out.success(`Removed ${o.removed.length}, warned ${a}, errors ${l}`+(i.length>0?` [${i.join(" ")}]`:""))}for(let a of o.candidates){let c=o.removed.includes(a.path)?m.error("\u2717"):Ol.has(a.verdict)?m.warning("\u2022"):m.dim("\xB7");e.out.line(` ${c} [${a.verdict.padEnd(22)}] ${a.path}`)}for(let a of o.warnings)a.startsWith("[ERROR]")?e.out.error(a):e.out.warn(a);return e.out.line(),"continue"}var Ev={name:"/worktree",summary:"List or prune afk-managed git worktrees",usage:"/worktree list | /worktree prune [--apply] [--scope <interactive|diagnose|all>]",async handler(e,t){let n=t.trim();return n.length===0||n.startsWith("list")?tj(e,n.replace(/^list\s*/,"")):n.startsWith("prune")?nj(e,n.replace(/^prune\s*/,"")):(e.out.error(`Unknown /worktree subcommand. Usage:
|
|
2119
|
+
`),s="",i="",a="",l=!1,c=!1,u=!1;for(let d of o)d.startsWith("worktree ")?s=d.slice(9).trim():d.startsWith("HEAD ")?i=d.slice(5).trim():d.startsWith("branch ")?a=d.slice(7).trim():d.trim()==="locked"?l=!0:d.trim()==="prunable"?c=!0:d.trim()==="bare"&&(u=!0);s&&n.push({path:s,head:i,branch:a,locked:l,prunable:c,isBare:u})}return n}function UN(e,t,n){if(e.locked)return"locked";let r=864e5,o=t*r,s=n*r;return e.ownerLiveness==="dead"&&!e.isDirty&&e.commitsAhead===0?"dead-owner":e.commitsAhead===0&&!e.isDirty&&e.ageMs>=LN?"empty":e.isDirty&&e.ageMs>s?"stale-dirty":!e.isDirty&&e.ageMs>o?"stale-clean":"active"}async function BN(e){if(!Sv(e))return 0;let t=0;try{let n=DN({input:$N(e),crlfDelay:1/0});for await(let r of n){let o=r.trim();if(o)try{let s=JSON.parse(o);s.taskId==="worktree-prune"&&(s.status==="success"||s.status==="error")&&t++}catch{}}}catch{}return t}var Ml=class extends Error{constructor(t){super(`Worktree sweep lock contested: ${t} \u2014 another sweep may be running.`),this.name="LockContestedError"}};async function WN(e){let t=Pl(e,"..");await Rt.mkdir(t,{recursive:!0}).catch(()=>{});let r=await(async()=>{try{return await Rt.open(e,"wx")}catch(o){if(o.code!=="EEXIST")throw o;let i=null;try{let a=await Rt.readFile(e,"utf-8");i=parseInt(a.trim(),10)}catch{}if(i!==null&&!Number.isNaN(i)){let a=!1;try{process.kill(i,0),a=!0}catch{}if(!a)return await Rt.unlink(e).catch(()=>{}),await Rt.open(e,"wx")}throw new Ml(e)}})();return await r.writeFile(String(process.pid),"utf-8"),await r.close(),async()=>{await Rt.unlink(e).catch(()=>{})}}async function Ut(e){let{execFile:t,repoRoot:n,maxAgeDaysClean:r=14,maxAgeDaysDirty:o=30,scope:s="all",telemetryPath:i}=e,a=i??Ct(),l=e.lockPath??vf(),c={removed:[],warnings:[],dryRun:e.dryRun??!1,candidates:[]},u=e.bypassSoftLaunch?Number.POSITIVE_INFINITY:await BN(a),d=e.dryRun===!0||u<3;c.dryRun=d;let p=null;try{p=await WN(l)}catch(f){if(f instanceof Ml)return c.warnings.push(`[WARN] ${f.message}`),c;throw f}try{let f=await t("git",["-C",n,"worktree","list","--porcelain"]),g=jN(f.stdout),h=Pl(n,".afk-worktrees"),b=new Set(g.map(v=>v.path)),y=[];try{y=(await Rt.readdir(h,{withFileTypes:!0})).filter(_=>_.isDirectory()).map(_=>Pl(h,_.name))}catch{}let w=y.filter(v=>!b.has(v));if(s==="all"||s==="interactive")for(let v of w){let _=0;try{let I=await Rt.stat(v);_=Date.now()-I.birthtimeMs}catch{}if(c.candidates.push({path:v,verdict:"orphaned-dir",owner:"interactive",ageMs:_}),!d)try{await Rt.rm(v,{recursive:!0,force:!0}),c.removed.push(v)}catch(I){c.warnings.push(`[ERROR] Failed to remove orphaned dir ${v}: ${I instanceof Error?I.message:String(I)}`)}}let k=!1,E=g[0]?.path;for(let v of g){if(v.path===E||v.isBare||!v.path.startsWith(h))continue;let _;try{let N=await Rt.readFile(Pl(v.path,".afk-worktree-meta.json"),"utf-8");_=JSON.parse(N)}catch{}if(s!=="all"&&_?.owner!==s)continue;let I=_?.owner==="interactive"||_?.owner==="diagnose"?_.owner:"unknown";if(!Sv(v.path)){c.candidates.push({path:v.path,verdict:"orphaned-registration",owner:I,ageMs:0}),d||(k=!0);continue}let R=0,C=_?.createdAt;if(C)R=Date.now()-new Date(C).getTime();else try{let N=await Rt.stat(v.path);R=Date.now()-N.birthtimeMs}catch{}let M=!1,$=0;try{M=(await t("git",["-C",v.path,"status","--porcelain"])).stdout.trim().length>0}catch{M=!0}if(!M&&v.head){let N=_?.baseSha??v.head;try{let K=await t("git",["-C",n,"rev-list",`${N}..${v.head}`,"--count"]);$=parseInt(K.stdout.trim(),10)||0}catch{$=0}}let x="unknown";typeof _?.pid=="number"&&Number.isInteger(_.pid)&&_.pid>0&&R<=FN&&(x=NN(_.pid)?"alive":"dead");let A={path:v.path,head:v.head,branch:v.branch,locked:v.locked,prunable:v.prunable,meta:_,ageMs:R,isDirty:M,commitsAhead:$,ownerLiveness:x},P=UN(A,r,o);if(c.candidates.push({path:v.path,verdict:P,owner:I,ageMs:R}),!d)try{P==="empty"?(await t("git",["-C",n,"worktree","remove","--force",v.path]),v.branch&&await t("git",["-C",n,"branch","-d",v.branch]).catch(()=>{}),c.removed.push(v.path)):P==="dead-owner"?(await t("git",["-C",n,"worktree","remove","--force",v.path]),v.branch&&await t("git",["-C",n,"branch","-d",v.branch]).catch(()=>{}),c.removed.push(v.path)):P==="stale-clean"?(await t("git",["-C",n,"worktree","remove","--force",v.path]),c.removed.push(v.path)):P==="stale-dirty"&&c.warnings.push(`[WARN] stale-dirty worktree preserved (uncommitted changes): ${v.path}`)}catch(N){c.warnings.push(`[ERROR] Failed to process ${v.path} (${P}): ${N instanceof Error?N.message:String(N)}`)}}if(k&&!d)try{await t("git",["-C",n,"worktree","prune"])}catch(v){c.warnings.push(`[ERROR] git worktree prune failed: ${v instanceof Error?v.message:String(v)}`)}}finally{p&&await p()}return c}var Fp=VN(HN),kv=["interactive","diagnose","all"],Ol=new Set(["empty","stale-clean","orphaned-dir","orphaned-registration","dead-owner"]);async function vv(){let t=(await Fp("git",["rev-parse","--git-common-dir"])).stdout.trim();if(!t)throw new Error("Not in a git repository.");let n=zN(t)?t:JN(process.cwd(),t);return GN(n)}function YN(e){if(e<=0)return"-";let t=e/864e5;return t<1?`${Math.max(1,Math.round(e/36e5))}h`:`${Math.round(t)}d`}function XN(e,t){return Ol.has(e)?m.error(t):e==="stale-dirty"?m.warning(t):e==="locked"?m.dim(t):m.dim(t)}function Tv(e,t){let n=e.split(/\s+/).map(o=>o.trim()).filter(o=>o.length>0),r={scope:t,apply:!1,unknown:[]};for(let o=0;o<n.length;o++){let s=n[o];if(s==="--apply")r.apply=!0;else if(s==="--scope"&&o+1<n.length){let i=n[o+1];o++,kv.includes(i)?r.scope=i:r.unknown.push(`--scope=${i}`)}else if(s.startsWith("--scope=")){let i=s.slice(8);kv.includes(i)?r.scope=i:r.unknown.push(s)}else r.unknown.push(s)}return r}async function ZN(e){try{let t=await KN.readFile(qN(e,".afk-worktree-meta.json"),"utf-8"),n=JSON.parse(t);if(typeof n.pid=="number"&&Number.isInteger(n.pid)&&n.pid>0)return n.pid}catch{}}async function QN(e,t,n){if(t.length===0){e.info("No afk-managed worktrees found.");return}let r=process.pid;e.line(),e.line(m.bold("Worktrees")),e.line(m.dim(" "+"PATH".padEnd(45)+" "+"OWNER".padEnd(12)+" "+"AGE".padEnd(5)+" "+"VERDICT".padEnd(22)+" PRUNE?"));for(let o of t){let a=n.get(o.path)===r?m.brand("\u2192 "):" ",l=o.path.slice(-44).padEnd(45),c=o.owner.padEnd(12),u=YN(o.ageMs).padEnd(5),d=o.verdict.padEnd(22),p=Ol.has(o.verdict)?m.error("yes"):o.verdict==="stale-dirty"?m.warning("warn"):m.dim("no"),f=XN(o.verdict,d);e.line(`${a}${l} ${c} ${u} ${f} ${p}`)}e.line(),e.line(m.dim(" \u2192 this session")),e.line()}async function ej(e){let t=new Map;for(let n of e)t.set(n.path,await ZN(n.path));return t}async function tj(e,t){let n=Tv(t,"interactive");n.unknown.length>0&&e.out.warn(`Unknown args ignored: ${n.unknown.join(" ")}`);let r;try{r=await vv()}catch(i){return e.out.error(`Not in a git repository: ${i.message}`),"continue"}let o;try{let i={execFile:Fp,repoRoot:r,dryRun:!0,scope:n.scope};o=await Ut(i)}catch(i){return e.out.error(`Sweep failed: ${i.message}`),"continue"}let s=await ej(o.candidates);await QN(e.out,o.candidates,s);for(let i of o.warnings)e.out.warn(i);return"continue"}async function nj(e,t){let n=Tv(t,"interactive");n.unknown.length>0&&e.out.warn(`Unknown args ignored: ${n.unknown.join(" ")}`);let r;try{r=await vv()}catch(a){return e.out.error(`Not in a git repository: ${a.message}`),"continue"}let o;try{let a={execFile:Fp,repoRoot:r,dryRun:!n.apply,scope:n.scope};o=await Ut(a)}catch(a){return e.out.error(`Sweep failed: ${a.message}`),"continue"}let s={};for(let a of o.candidates)s[a.verdict]=(s[a.verdict]??0)+1;let i=Object.entries(s).sort(([a],[l])=>a.localeCompare(l)).map(([a,l])=>`${a}=${l}`);if(o.dryRun){let a=o.candidates.filter(l=>Ol.has(l.verdict)).length;e.out.line(),e.out.line(m.warning("\u{1F50D} Dry-run \u2014 pass --apply to actually remove.")+` Would prune ${a} worktree(s).`+(i.length>0?` [${i.join(" ")}]`:""))}else{let a=o.warnings.filter(c=>c.startsWith("[WARN]")).length,l=o.warnings.filter(c=>c.startsWith("[ERROR]")).length;e.out.line(),e.out.success(`Removed ${o.removed.length}, warned ${a}, errors ${l}`+(i.length>0?` [${i.join(" ")}]`:""))}for(let a of o.candidates){let c=o.removed.includes(a.path)?m.error("\u2717"):Ol.has(a.verdict)?m.warning("\u2022"):m.dim("\xB7");e.out.line(` ${c} [${a.verdict.padEnd(22)}] ${a.path}`)}for(let a of o.warnings)a.startsWith("[ERROR]")?e.out.error(a):e.out.warn(a);return e.out.line(),"continue"}var Ev={name:"/worktree",summary:"List or prune afk-managed git worktrees",usage:"/worktree list | /worktree prune [--apply] [--scope <interactive|diagnose|all>]",async handler(e,t){let n=t.trim();return n.length===0||n.startsWith("list")?tj(e,n.replace(/^list\s*/,"")):n.startsWith("prune")?nj(e,n.replace(/^prune\s*/,"")):(e.out.error(`Unknown /worktree subcommand. Usage:
|
|
2120
2120
|
/worktree list
|
|
2121
2121
|
/worktree prune [--apply] [--scope <interactive|diagnose|all>]`),"continue")}};var xv={name:"/reauth",summary:"Re-read keychain credentials and swap the running session's client",usage:"/reauth [--check]",hint:"Force the running session to pick up a new keychain token (e.g. after `claude /login` in another terminal)",async handler(e,t){if(t.trim()==="--check"){let s=ze();if(!s)return e.out.warn("No OAuth token found. Run `claude login` in a terminal to authenticate."),"continue";let i=yn(s);return e.out.success(`Active keychain account: ${i}`),e.out.info("Note: --check only inspects the keychain. The running SDK client may still hold an older token \u2014 run `/reauth` (no args) to actually swap."),"continue"}let r=ze();if(r){let s=yn(r);e.out.info(`Current keychain account: ${s}`)}e.out.info("Rebuilding session client from keychain credentials\u2026");let o;try{o=await e.session.current.reauth()}catch(s){return e.out.error(`Client refresh failed: ${s instanceof Error?s.message:String(s)}`),e.out.warn("Run `claude login` in a terminal to re-authenticate."),"continue"}return o?(o.swapped?(e.out.success(`\u2713 Client swapped. Session now authenticated as: ${o.accountId}`),e.out.info("Next turn will use the new credential. If a usage-limit pause is active, it will resume automatically within ~30s (or send a message to retry immediately).")):e.out.success(`\u2713 Client refreshed. Authenticated as: ${o.accountId} (token unchanged)`),"continue"):(ze()?e.out.warn("This session is not using OAuth (probably api-key mode) \u2014 nothing to refresh. The active credential is whatever ANTHROPIC_API_KEY held at session start."):e.out.warn("No OAuth credentials found in the keychain. Run `claude login` in a terminal to authenticate."),"continue")}};H();import{spawn as rj}from"node:child_process";import{promises as Np}from"node:fs";import*as Rv from"node:os";import*as Av from"node:path";function oj(e){return new Date(e).toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit"})}function sj(e,t){let n=[m.meta(`#${t+1}`),m.dim(oj(e.timestamp))];if(e.durationMs!==void 0&&e.durationMs>0&&n.push(m.dim(se(e.durationMs))),e.costUsd!==void 0&&e.costUsd>0&&n.push(m.dim(Le(e.costUsd))),e.inputTokens!==void 0||e.outputTokens!==void 0){let r=e.inputTokens??0,o=e.outputTokens??0;n.push(m.dim(`${Math.round((r+o)/1e3)}k tok`))}return n.join(" ")}function ij(e){if(!e.toolEvents||e.toolEvents.length===0)return"";let t=[];for(let n of e.toolEvents){let r=n.isError?m.error("\u2717"):m.dim("\u25CF"),o=m.chrome(n.toolName),s="";if(n.result){let i=n.result.trim().split(`
|
|
2122
2122
|
`)[0]??"";s=i.length>80?i.slice(0,77)+"...":i}t.push(` ${r} ${o}${s?m.dim(` ${s}`):""}`)}return t.join(`
|
|
@@ -2201,7 +2201,7 @@ _ended: ${new Date().toISOString()}_
|
|
|
2201
2201
|
`)}function aB(e){let t=[],n=(r,o)=>{o&&o.trim().length>0&&t.push({label:r,value:o.trim()})};switch(e.kind){case"done":n("done",e.whatWasDone),n("evidence",e.evidence),n("deferred",e.deferred);break;case"blocked":n("blocks",e.whatBlocks),n("unblock",e.unblockCondition),n("progress",e.alreadyDone);break;case"asking":n("question",e.question),n("resolves",e.assumption),n("after",e.followup);break;case"interrupted":n("was doing",e.whatWasInProgress),n("saved at",e.stateLocation),n("resume",e.resumeRequires);break}return t}function KT(e,t,n){let r=[];return n&&n.trim().length>0&&r.push({type:"text",text:n}),e&&r.push({type:"text",text:e}),$l(r,t),r}async function GT(e,t,n,r,o="summary",s,i,a){let l=yk(e.text,e.attachments);r.setInFlight(!0);let c="",u=!1,d=!1,p=!1,f=!1,g,h=!1,b=!1,y=[],w=new Map,k=e.text.startsWith("/")?e.text.split(/[\s:]/)[0]?.slice(1):void 0,E=r.getCompositor?r.getCompositor():null,v=()=>new xo({out:Ro(s),thinkingMode:o,...k?{activeSkillName:k}:{},onCancel:()=>{t.interrupt().catch(C=>{je()&&console.error(" "+m.error("session.interrupt() failed:"),C)})},...i?{onBackground:()=>{h=!0}}:{},...a?.history?{history:a.history}:{},...a?.autocompleteState?{autocompleteState:a.autocompleteState}:{},...a?.promptText!==void 0?{promptText:a.promptText}:{},...r.scrollRegion?{scrollRegion:r.scrollRegion}:{},...E?{compositor:E}:{}}),_=v(),I=async()=>{if(!p){p=!0;try{await _.dispose()}catch{}}},R=async()=>{await _.arm();let C=_.getCompositor();if(s&&C){let M=C;s.fn=$=>M.commitAbove($)}r.setActiveCompositor?.(C),r.setInterruptNotifier?.(M=>_.setInterrupting(M)),r.rearmStatus?.()};try{E?E.commitAbove(""):console.log(),r.setSoftStopHandler&&r.setSoftStopHandler(()=>{b=!0}),await R(),i&&r.setBackgroundHandler&&r.setBackgroundHandler(()=>{h=!0});let C=e.attachments.length===0?e.text:KT(e.text,e.attachments),M=t.sendMessageStream(C);if(await jr((x,A)=>{_.process(x,A)},async()=>{for await(let x of M){if(b){t.interrupt().catch(A=>{je()&&console.error(" "+m.error("soft-stop session.interrupt() failed:"),A)});break}if(h&&i){let A=k??e.text.slice(0,40),P=i.register(A),N=nl(P,i);rl(M,c,l,P,i,N,n,r.onTurnComplete,t.abortSignal),await I(),(s??{fn:console.log}).fn(m.dim(` \u2192 backgrounded as ${P.id}: ${P.label}`)),r.setInFlight(!1),r.rearmStatus?.();return}if(x.type==="chunk"&&x.chunk.type==="content"?(c+=x.chunk.content,u=!0):x.type==="message"&&!u&&(c=x.message.content),x.type==="chunk"&&x.chunk.type==="tool_use_detail"){let A=x.chunk,P={toolName:A.toolName,toolUseId:A.toolUseId,input:A.toolInput};w.set(A.toolUseId,P),y.push(P)}else if(x.type==="chunk"&&x.chunk.type==="tool_result"){let A=x.chunk,P=w.get(A.toolUseId);P&&(P.result=A.content,P.isError=A.isError,w.delete(A.toolUseId))}if(x.type==="paused"){await I(),(s??{fn:console.log}).fn(zf({reason:x.reason,...x.resetsAt!==void 0?{resetsAt:x.resetsAt}:{},...x.accountId!==void 0?{accountId:x.accountId}:{},...x.autoResume!==void 0?{autoResume:x.autoResume}:{}}));continue}if(x.type==="resumed"){let A=x.hotSwapped&&x.accountId?`\u25B6 Resumed on ${x.accountId}`:"\u25B6 Resumed";c="",u=!1,y.length=0,w.clear(),f=!1,g=void 0,d=!1,h=!1,_=v(),p=!1,await R(),(s??{fn:console.log}).fn(m.success(A));continue}if(x.type==="error"){await I(),Lr($r(x.error)),d=!0;continue}_.process(x),x.type==="done"&&(f=!0,g=x.metadata)}}),await I(),b){let x=s?s.fn:console.log;x(m.warning("\u23F8 Stopped \u2014 work so far kept.")+m.dim(" Use /resume or --resume to continue.")),x("")}if(f&&!b){sr(n,l,c,g,y),r.onTurnComplete&&await r.onTurnComplete(l,c).catch(()=>{}),Wa(process.stdout);let x=P=>{s?s.fn(P):console.log(P)},A=WT(c);if(A&&(x(HT(A)),x(""),r.onTerminalState))try{r.onTerminalState(A)}catch{}if(lB(g,n,x),r.onAfterTurn){let P=r.onAfterTurn();P instanceof Promise&&await P.catch(()=>{})}}}catch(C){await I(),d||Lr($r(C))}finally{await I(),s&&(s.fn=s.idleFn),r.setActiveCompositor?.(null),r.setInterruptNotifier?.(null),r.setBackgroundHandler?.(null),r.setSoftStopHandler?.(null),r.setInFlight(!1),r.rearmStatus?.()}}function lB(e,t,n=console.log){if(!e)return;let r=[];e.durationMs&&r.push(se(e.durationMs)),e.totalCostUsd!==void 0&&r.push(Le(e.totalCostUsd));let o=Number(e.usage?.input_tokens??0),s=Number(e.usage?.output_tokens??0);o+s>0&&r.push(ee(o+s)+" tok"),r.length>0&&n(m.dim(" \u25E6 "+r.join(" \xB7 ")));let i=zd(t),a=ot(t.model);if(i>=1){let l=Math.round((i-1)*a),c=Math.round(a/1e3);console.log(m.error(` context OVER ${c}k tok by ~${ee(l)} tok \u2014 model output may be silently truncated`))}else if(i>.5){let l=i>.8?m.error:m.warning;n(l(` context ${Math.round(i*100)}% used of ${ee(a)}`))}n("")}function zT(e={}){let t=e.load??Qa,n=e.onResize??(i=>Ge.subscribe(i)),r="",o,s=n(()=>{r=""});return{renderIfChanged(i){let a=i??"unbound",l=t(a),c=MS(l);return a===o&&c===r?[]:(o=a,r=c,c===""?[]:el(l))},invalidate(){r=""},dispose(){try{s()}catch{}}}}var pm={done:{glyph:"\u2713",color:m.success,label:"done"},blocked:{glyph:"\u2298",color:m.error,label:"blocked"},asking:{glyph:"?",color:m.warning,label:"asking"},interrupted:{glyph:"\u23F8",color:m.meta,label:"interrupted"}};function qT(e={}){let t=Math.max(2,e.capacity??8),n=[];return{push(r){n.push(r.kind),n.length>t&&(n=n.slice(n.length-t))},reset(){n=[]},entries(){return n},render(){if(n.length===0)return null;let r=m.dim(" ledger "),o=m.dim(" \xB7 "),s=n.map(u=>{let d=pm[u];return d.color(`${d.glyph} ${d.label}`)}),i=m.dim(` (${n.length} turn${n.length===1?"":"s"})`),a=r+s.join(o)+i,l=Math.max(20,V()-2);if(z(a)<=l)return a;let c=r+n.map(u=>pm[u].color(pm[u].glyph)).join(m.dim(" "))+i;return ue(c,l)}}}var mm=["\u25D0","\u25D1","\u25D2","\u25D3"],dc=class{stream;manager;registry;throttleMs;started=!1;lastRepaint=0;spinnerIndex=0;spinnerInterval=null;resizeUnsub=null;updateHandler=null;registryStartedHandler=null;registrySettledHandler=null;rowCount=0;onRowCountChange;constructor(t,n,r={}){this.manager=t,this.registry=n,this.stream=r.stream??process.stdout,this.throttleMs=r.throttleMs??200}setRowCountChangeHandler(t){this.onRowCountChange=t}start(){this.started||(this.started=!0,this.updateHandler=()=>this.scheduleRepaint(),this.manager.on("update",this.updateHandler),this.manager.on("complete",this.updateHandler),this.registry&&(this.registryStartedHandler=t=>{this.scheduleRepaint()},this.registrySettledHandler=t=>{this.scheduleRepaint()},this.registry.on("started",this.registryStartedHandler),this.registry.on("settled",this.registrySettledHandler)),this.resizeUnsub=Ge.subscribe(()=>this.repaint()),this.spinnerInterval=setInterval(()=>{this.spinnerIndex=(this.spinnerIndex+1)%mm.length,this.rowCount>0&&this.repaint()},Math.max(this.throttleMs,50)))}stop(){this.started&&(this.started=!1,this.updateHandler&&(this.manager.removeListener("update",this.updateHandler),this.manager.removeListener("complete",this.updateHandler),this.updateHandler=null),this.registry&&(this.registryStartedHandler&&(this.registry.off("started",this.registryStartedHandler),this.registryStartedHandler=null),this.registrySettledHandler&&(this.registry.off("settled",this.registrySettledHandler),this.registrySettledHandler=null)),this.resizeUnsub&&(this.resizeUnsub(),this.resizeUnsub=null),this.spinnerInterval&&(clearInterval(this.spinnerInterval),this.spinnerInterval=null),this.rowCount>0&&(this.clearRows(),this.rowCount=0,this.onRowCountChange?.(0)))}scheduleRepaint(){Date.now()-this.lastRepaint<this.throttleMs||this.repaint()}repaint(){if(!this.started||!this.stream.isTTY)return;this.lastRepaint=Date.now();let t=[...this.manager.running().map(s=>({kind:"turn",task:s})),...(this.registry?.list()??[]).filter(s=>s.status==="running").map(s=>({kind:"subagent",job:s}))],n=this.stream.rows??24,r=Math.max(0,Math.min(t.length,n-1));if(r!==this.rowCount&&(this.rowCount>0&&this.clearRows(),this.rowCount=r,this.onRowCountChange?.(r)),r===0)return;let o=Math.max(1,n-r);this.stream.write("\x1B[s");for(let s=0;s<r;s++){let i=t[s],a=o+s;this.stream.write(`\x1B[${a};1H`),this.stream.write("\x1B[2K"),this.stream.write(this.formatItemLine(i))}this.stream.write("\x1B[u")}clearRows(){if(!this.stream.isTTY)return;let t=this.stream.rows??24,n=Math.min(this.rowCount,t-1),r=Math.max(1,t-n);this.stream.write("\x1B[s");for(let o=0;o<n;o++)this.stream.write(`\x1B[${r+o};1H`),this.stream.write("\x1B[2K");this.stream.write("\x1B[u")}formatItemLine(t){return t.kind==="turn"?this.formatTaskLine(t.task):this.formatJobLine(t.job)}formatTaskLine(t){let n=Math.max(4,(this.stream.columns??80)-2),r=m.brand(mm[this.spinnerIndex]),o=m.dim(t.id),s=m.bold(t.label),i=[r,o,s];t.progressDescription&&i.push(m.dim(t.progressDescription));let a=[];t.stats.toolUses>0&&a.push(`${t.stats.toolUses} tool${t.stats.toolUses===1?"":"s"}`),t.stats.tokens>0&&a.push(`${ee(t.stats.tokens)} tok`);let l=Date.now()-t.startedAt;return a.push(se(l)),a.length>0&&i.push(m.dim(a.join(" \xB7 "))),ue(" "+i.join(" "),n)}formatJobLine(t){let n=Math.max(4,(this.stream.columns??80)-2),r=m.brand(mm[this.spinnerIndex]),o=m.dim(t.jobId),s=m.bold(t.label||t.jobId),i=[r,o,s],a=Date.now()-t.startedAt;return i.push(m.dim(se(a))),ue(" "+i.join(" "),n)}};function pc(e,t){let n=m.brand("afk")+m.dim(` (${e})`),r=t?m.warning(" \u25CF plan"):"";return n+r+m.dim(" \u203A ")}async function JT(e,t,n,r){let o=null,s=[];e.session.current.waitForInitialization().then(async p=>{je()&&(o=Va(p)),await jl(e.session.current),je()&&(s=zv())}).catch(()=>{});let i=await DT(),a=new uc({rl:e.rl,history:i,statusLine:e.statusLine}),l,c,u,d;try{await a.armCompositor({promptFn:()=>pc(e.stats.model,e.stats.planMode),onCancel:r,onShiftTab:()=>{let y=e.slashCtx;y.stats.planMode&&y.stats.pendingPlanExit?(y.stats.pendingPlanExit=!1,Et(y,!1,{closureSummarySkipped:!0}).catch(()=>{})):Et(y).catch(()=>{}),e.statusLine.rearm()},scrollRegion:e.statusLine,...e.preArmAnchorRow!==void 0?{anchorRow:e.preArmAnchorRow}:{}});let p=a.getCompositor();$t.install(Ka({readLine:y=>a.readLine({promptFn:()=>y}).then(w=>w.text),writer:{line:(y="")=>{let w=a.getCompositor();w?w.commitAbove(y):process.stdout.write(y+`
|
|
2202
2202
|
`)}},pendingCount:()=>$t.pendingCount(),...p?{pickFromList:y=>UT(p,y),readTextOverlay:y=>BT(p,y)}:{}})),e.replRenderer.setCompositor(a.getCompositor()),e.slashCtx.getCompositor=()=>a.getCompositor();let f=a.getCompositor();if(f){let y=w=>f.commitAbove(w);e.completionWriter.fn=y,e.completionWriter.idleFn=y}e.slashCtx.setSoftStopHandler=y=>a.setSoftStopHandler(y),e.inputSurfaceRef&&(e.inputSurfaceRef.current=a),c=zT();let g=qT();e.clearVerdictLedger=()=>g.reset(),u=new tl,HS(u),VS(u),ZS(u),YS(e.backgroundRegistry),d=new dc(u,e.backgroundRegistry),d.setRowCountChangeHandler(y=>{e.statusLine.setExtraRows(y)}),d.start();let h=50,b=[];for(u.on("complete",y=>{b.length>=h&&b.shift(),b.push(y)});;){if(o&&(e.replRenderer.writeLine(o),e.replRenderer.writeLine(""),o=null),s.length>0){for(let R of s)e.replRenderer.writeLine(R);e.replRenderer.writeLine(""),s=[]}for(;b.length>0;){let R=b.shift(),C=R.status==="succeeded"?"\u2713":"\u2717",M=[];if(R.resultText){let x=R.resultText.trim().split(`
|
|
2203
2203
|
`)[0]?.slice(0,80)??"";x&&M.push(x)}R.error&&M.push(R.error.message);let $=[R.stats.toolUses>0?`${R.stats.toolUses} tools`:"",R.stats.tokens>0?`${Math.round(R.stats.tokens/1e3)}k tok`:"",R.stats.durationMs>0?`${Math.round(R.stats.durationMs/1e3)}s`:""].filter(Boolean).join(" \xB7 ");$&&M.push($),e.replRenderer.writeLine(gn({kind:R.status==="succeeded"?"checkpoint":"diagnosis",title:`${C} ${R.id} ${R.label}`,body:M})),e.replRenderer.writeLine("")}let y=c.renderIfChanged(e.stats.sessionId);if(y.length>0){for(let R of y)e.replRenderer.writeLine(R);e.replRenderer.writeLine("")}let w=g.render();w&&e.replRenderer.writeLine(w);let k,E;if(l!==void 0){let R=l;l=void 0;let C=pc(e.stats.model,e.stats.planMode),M=cr({buffer:R.text,promptText:C,isTTY:!!process.stdout.isTTY,attachmentSummary:bo([...R.attachments])});e.replRenderer.writeLine(M),k=R.text.trim(),E=R.attachments}else{let R=await a.readLine({promptFn:()=>pc(e.stats.model,e.stats.planMode),onSigint:r,onShiftTab:()=>{let C=e.slashCtx;C.stats.planMode&&C.stats.pendingPlanExit?(C.stats.pendingPlanExit=!1,Et(C,!1,{closureSummarySkipped:!0}).catch(()=>{})):Et(C).catch(()=>{}),e.statusLine.rearm()}});k=R.text.trim(),E=R.attachments}if(!k&&E.length===0)continue;let v=!1;if(k.startsWith("/")){let R=await cS(k,e.slashCtx,E);if(R.handled){if(R.result==="exit"){e.rl.close();return}if((k==="/clear"||k.startsWith("/clear "))&&(await t.rotateOnClear(),e.replRenderer.writeLine(m.dim(` transcript: ${t.path()}`)),g.reset()),R.result!==null&&typeof R.result=="object"&&"kind"in R.result&&R.result.kind==="submit"){l={text:R.result.message,attachments:E??[]},e.statusLine.rearm();continue}e.statusLine.rearm();continue}v=!0}i.push(k);let _=k;if(v){let R=Gd(k);if(R){let C=R.name.replace(/^\//,"").split(":").pop()??"";if(C&&Wp(C)){let M={skillName:C,rawArgs:R.args,source:"plugin",capabilities:{compose:!0,subagents:!0}},$=e.session.current.sessionId,x=br($),A=Date.now();J(`[afk trace] preflight.start commandName=${C}`);let P=!1,N=await yr(M,{cwd:e.stats.cwd??process.cwd(),artifactDir:x},K=>{je()&&e.replRenderer.writeLine(m.warning(`\u26A0 preflight(${C}) failed: `)+(K instanceof Error?K.message:String(K)))});P=N!==null,J(`[afk trace] preflight.end commandName=${C} durationMs=${Date.now()-A} success=${P}`),_=Gp(N?.manifestBlock,k)}}}let I;if(e.firstTurnHook&&e.stats.totalTurns===0){let R=e.firstTurnHook;e.firstTurnHook=void 0,I=Promise.resolve().then(()=>R(k)).catch(C=>{e.completionWriter.fn(m.warning("\u26A0 ")+"first-turn hook failed: "+(C instanceof Error?C.message:String(C)))})}await GT({text:_,attachments:E},e.session.current,e.stats,{setInFlight(R){n.turnInFlight=R},async onTurnComplete(R,C){await t.appendTurn(R,C)},async onAfterTurn(){await e.contextSampler.onTurn(e.stats.totalTurns),await TS(e.slashCtx),e.statusLine.rearm()},rearmStatus:()=>e.statusLine.rearm(),onTerminalState:R=>g.push(R),setActiveCompositor:R=>{n.activeCompositor=R},setInterruptNotifier:R=>{n.notifyInterrupting=R},scrollRegion:e.statusLine,getCompositor:()=>a.getCompositor(),setBackgroundHandler:R=>a.setBackgroundHandler(R),setSoftStopHandler:R=>a.setSoftStopHandler(R)},e.options.thinkingUi,e.completionWriter,u,a.toRunTurnRefs(pc(e.stats.model,e.stats.planMode))),I!==void 0&&await I}}finally{if(u!==void 0)for(let f of u.running())u.cancel(f.id);d?.stop(),c?.dispose();let p=f=>console.log(f);e.completionWriter.fn=p,e.completionWriter.idleFn=p,await a.dispose(),e.inputSurfaceRef&&(e.inputSurfaceRef.current=null)}}import{execFile as cB}from"node:child_process";import{dirname as uB,isAbsolute as dB,resolve as pB}from"node:path";import{promisify as mB}from"node:util";var VT=mB(cB),fB=3e3,gB=new Set(["empty","orphaned-dir","orphaned-registration","dead-owner"]);async function hB(){let t=(await VT("git",["rev-parse","--git-common-dir"])).stdout.trim();if(!t)throw new Error("Not in a git repository.");let n=dB(t)?t:pB(process.cwd(),t);return uB(n)}async function YT(e){if(e?.disabled)return{ran:!1,removedCount:0,skippedReason:"disabled"};let t;try{t=await hB()}catch{return{ran:!1,removedCount:0,skippedReason:"not-in-repo"}}let n,r=new Promise(o=>{n=setTimeout(()=>o("timeout"),fB)});try{let o=Ut({execFile:VT,repoRoot:t,dryRun:!1,scope:"interactive",bypassSoftLaunch:!0}),s=await Promise.race([o,r]);if(s==="timeout")return{ran:!1,removedCount:0,skippedReason:"timeout"};let i=s;return i.warnings.some(c=>c.toLowerCase().includes("contested"))?{ran:!1,removedCount:0,skippedReason:"lock-contested"}:{ran:!0,removedCount:i.candidates.filter(c=>gB.has(c.verdict)&&i.removed.includes(c.path)).length}}catch{return{ran:!1,removedCount:0,skippedReason:"error"}}finally{n&&clearTimeout(n)}}import{promises as yB}from"node:fs";import{dirname as bB,join as wB}from"node:path";import{randomBytes as SB}from"node:crypto";var kB=["Generate a 2-4 word kebab-case slug describing this work request.","Rules:","- ASCII lowercase letters and digits only, separated by single hyphens","- 2 to 4 hyphen-separated words","- Maximum 30 characters total","- No prefix, no quotes, no punctuation other than hyphens","- Output ONLY the slug \u2014 no explanation, no preamble","Examples: fix-cleanup-race, add-telegram-allowlist, refactor-prompt-loader, debug-flaky-test"].join(`
|
|
2204
|
-
`),XT=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,fm=30,vB=1024,TB=8e3,EB="haiku";async function xB(e,t){let n=e.trim();if(n.length===0)return t.onSkip?.("empty-message"),null;if(n.startsWith("/"))return t.onSkip?.("slash-command"),null;let r=CB(n,vB),o=new AbortController,s=setTimeout(()=>o.abort(),t.timeoutMs??TB),i=t.signal?IB([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,i):a=await ec({token:t.token,model:t.model??EB,system:kB,user:r,maxTokens:32,signal:i})}catch(d){let p=d instanceof Error?d.message:String(d);return t.onSkip?.("slug-generator-error",p.slice(0,200)),null}finally{clearTimeout(s)}let l=RB(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=bB(t.worktreePath);return await AB(l,c)}function RB(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(XT.test(t)&&t.length<=fm)return t;let n=t.replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");if(n.length===0)return null;let r=n.split("-").filter(s=>s.length>0).slice(0,4);if(r.length<2)return null;let o=r[0];for(let s=1;s<r.length;s++){let i=`${o}-${r[s]}`;if(i.length>fm)break;o=i}return XT.test(o)?o:null}async function AB(e,t){if(!await _B(wB(t,e)))return e;let n=SB(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,fm-5)}-${n}`}async function _B(e){try{return await yB.access(e),!0}catch{return!1}}function CB(e,t){let n=Buffer.from(e,"utf8");if(n.length<=t)return e;let r=t;for(;r>0&&n[r]!==void 0&&(n[r]&192)===128;)r--;return n.slice(0,r).toString("utf8")}function IB(e){let t=AbortSignal.any;if(typeof t=="function")return t.call(AbortSignal,e);let n=new AbortController;for(let r of e){if(r.aborted)return n.abort(r.reason),n.signal;r.addEventListener("abort",()=>n.abort(r.reason),{once:!0})}return n.signal}async function QT(e){let t,n,r=await xB(e.message,{token:e.token,...e.model!==void 0?{model:e.model}:{},...e.timeoutMs!==void 0?{timeoutMs:e.timeoutMs}:{},worktreePath:e.handle.path,...e.signal!==void 0?{signal:e.signal}:{},...e.slugGenerator!==void 0?{slugGenerator:e.slugGenerator}:{},onSkip:(i,a)=>{t=i,n=a}});if(r===null)return{status:"skipped",reason:t??"unknown",...n!==void 0?{detail:n}:{}};let s=await(e.renameFn??hb)(e.handle,r,e.branchPrefix!==void 0?{branchPrefix:e.branchPrefix}:void 0);return s.ok?(e.session&&e.session.setCwd(s.newPath),ZT(s.newPath),{status:"renamed",oldPath:s.oldPath,newPath:s.newPath,oldBranch:s.oldBranch,newBranch:s.newBranch}):(s.partial==="branch"&&(e.session&&e.session.setCwd(e.handle.path),ZT(e.handle.path)),{status:"failed",reason:s.reason,...s.partial!==void 0?{partial:s.partial}:{}})}function ZT(e){try{process.chdir(e)}catch{}}U();import{spawn as eE}from"child_process";import{existsSync as DB,mkdirSync as LB,readFileSync as tE,unlinkSync as FB,writeFileSync as NB}from"fs";import{get as jB}from"https";import{join as nE}from"path";import{readFileSync as PB}from"fs";import{dirname as MB,join as OB}from"path";import{fileURLToPath as $B}from"url";function an(){try{return"3.51.
|
|
2204
|
+
`),XT=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,fm=30,vB=1024,TB=8e3,EB="haiku";async function xB(e,t){let n=e.trim();if(n.length===0)return t.onSkip?.("empty-message"),null;if(n.startsWith("/"))return t.onSkip?.("slash-command"),null;let r=CB(n,vB),o=new AbortController,s=setTimeout(()=>o.abort(),t.timeoutMs??TB),i=t.signal?IB([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,i):a=await ec({token:t.token,model:t.model??EB,system:kB,user:r,maxTokens:32,signal:i})}catch(d){let p=d instanceof Error?d.message:String(d);return t.onSkip?.("slug-generator-error",p.slice(0,200)),null}finally{clearTimeout(s)}let l=RB(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=bB(t.worktreePath);return await AB(l,c)}function RB(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(XT.test(t)&&t.length<=fm)return t;let n=t.replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");if(n.length===0)return null;let r=n.split("-").filter(s=>s.length>0).slice(0,4);if(r.length<2)return null;let o=r[0];for(let s=1;s<r.length;s++){let i=`${o}-${r[s]}`;if(i.length>fm)break;o=i}return XT.test(o)?o:null}async function AB(e,t){if(!await _B(wB(t,e)))return e;let n=SB(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,fm-5)}-${n}`}async function _B(e){try{return await yB.access(e),!0}catch{return!1}}function CB(e,t){let n=Buffer.from(e,"utf8");if(n.length<=t)return e;let r=t;for(;r>0&&n[r]!==void 0&&(n[r]&192)===128;)r--;return n.slice(0,r).toString("utf8")}function IB(e){let t=AbortSignal.any;if(typeof t=="function")return t.call(AbortSignal,e);let n=new AbortController;for(let r of e){if(r.aborted)return n.abort(r.reason),n.signal;r.addEventListener("abort",()=>n.abort(r.reason),{once:!0})}return n.signal}async function QT(e){let t,n,r=await xB(e.message,{token:e.token,...e.model!==void 0?{model:e.model}:{},...e.timeoutMs!==void 0?{timeoutMs:e.timeoutMs}:{},worktreePath:e.handle.path,...e.signal!==void 0?{signal:e.signal}:{},...e.slugGenerator!==void 0?{slugGenerator:e.slugGenerator}:{},onSkip:(i,a)=>{t=i,n=a}});if(r===null)return{status:"skipped",reason:t??"unknown",...n!==void 0?{detail:n}:{}};let s=await(e.renameFn??hb)(e.handle,r,e.branchPrefix!==void 0?{branchPrefix:e.branchPrefix}:void 0);return s.ok?(e.session&&e.session.setCwd(s.newPath),ZT(s.newPath),{status:"renamed",oldPath:s.oldPath,newPath:s.newPath,oldBranch:s.oldBranch,newBranch:s.newBranch}):(s.partial==="branch"&&(e.session&&e.session.setCwd(e.handle.path),ZT(e.handle.path)),{status:"failed",reason:s.reason,...s.partial!==void 0?{partial:s.partial}:{}})}function ZT(e){try{process.chdir(e)}catch{}}U();import{spawn as eE}from"child_process";import{existsSync as DB,mkdirSync as LB,readFileSync as tE,unlinkSync as FB,writeFileSync as NB}from"fs";import{get as jB}from"https";import{join as nE}from"path";import{readFileSync as PB}from"fs";import{dirname as MB,join as OB}from"path";import{fileURLToPath as $B}from"url";function an(){try{return"3.51.1"}catch{}try{let e=MB($B(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse(PB(OB(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}H();var UB=64*1024,BB=1440*60*1e3,WB="update-check.json",HB="pending-update.json";function rE(){return nE(bi(),WB)}function gm(){return nE(bi(),HB)}function oE(){let e=bi();DB(e)||LB(e,{recursive:!0})}function KB(e,t){let n=e.split(".").map(Number),r=t.split(".").map(Number),o=Math.max(n.length,r.length);for(let s=0;s<o;s++){let i=n[s]??0,a=r[s]??0;if(a>i)return!0;if(a<i)return!1}return!1}function GB(){try{let e=tE(rE(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function zB(){try{oE();let e=`
|
|
2205
2205
|
const https = require('https');
|
|
2206
2206
|
const fs = require('fs');
|
|
2207
2207
|
const url = 'https://registry.npmjs.org/agent-afk/latest';
|