@ebowwa/coder 0.1.10 → 0.1.11

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 (2) hide show
  1. package/dist/cli.js +55 -36
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{A as Gz,P as Az,S as bz,T as Nz,Y as Fz,Z as Tz,a as rz,ba as xz,t as n,u as p,w as i,y as Hz}from"./index-wn2m4wma.js";async function m(z,W){let X=Bun.spawn(["git",...z],{cwd:W,stdout:"pipe",stderr:"pipe"}),Y=await new Response(X.stdout).text(),$=await new Response(X.stderr).text(),Q=await X.exited;return{stdout:Y.trim(),stderr:$.trim(),exitCode:Q}}async function jz(z){let{exitCode:W}=await m(["rev-parse","--git-dir"],z);return W===0}async function Mz(z){let{stdout:W,exitCode:X}=await m(["rev-parse","--abbrev-ref","HEAD"],z);if(X!==0)return"HEAD";return W||"HEAD"}async function wz(z){let{stdout:W,exitCode:X}=await m(["rev-list","--left-right","--count","@{upstream}...HEAD"],z);if(X!==0||!W)return{ahead:0,behind:0};let Y=W.split(/\s+/);if(Y.length>=2&&Y[0]!==void 0&&Y[1]!==void 0)return{ahead:parseInt(Y[0],10)||0,behind:parseInt(Y[1],10)||0};return{ahead:0,behind:0}}async function Pz(z){let{stdout:W,exitCode:X}=await m(["status","--porcelain"],z);if(X!==0||!W)return{staged:[],unstaged:[],untracked:[],conflicted:[]};let Y=[],$=[],Q=[],K=[],J=W.split(`
4
- `);for(let U of J){if(!U)continue;let R=U[0],E=U[1],O=U.substring(3);if(O.includes(" -> ")){let H=O.split(" -> ");O=H[1]??H[0]??O}if(R==="U"||E==="U"||R==="A"&&E==="A"||R==="D"&&E==="D"||R==="A"&&E==="U"||R==="U"&&E==="A"||R==="D"&&E==="U"||R==="U"&&E==="D"){K.push(O);continue}if(R==="?"&&E==="?"){Q.push(O);continue}if(R!==" "&&R!=="?"&&R!=="!")Y.push(O);if(E!==" "&&E!=="?"&&E!=="!"){if(!Y.includes(O))$.push(O)}}return{staged:Y,unstaged:$,untracked:Q,conflicted:K}}async function k(z){try{if(!await jz(z))return null;let[X,Y,$]=await Promise.all([Mz(z),wz(z),Pz(z)]);return{branch:X,ahead:Y.ahead,behind:Y.behind,staged:$.staged,unstaged:$.unstaged,untracked:$.untracked,conflicted:$.conflicted}}catch(W){return console.error("Error getting git status:",W),null}}import{randomUUID as Dz}from"crypto";import{execSync as d}from"child_process";var h=process.env.CLAUDE_CHECKPOINTS_DIR||`${process.env.HOME}/.claude/checkpoints`;function vz(z){let W=0;for(let X=0;X<z.length;X++){let Y=z.charCodeAt(X);W=(W<<5)-W+Y,W=W&W}return Math.abs(W).toString(16)}function yz(z){try{d("git rev-parse --is-inside-work-tree",{cwd:z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let W=d("git rev-parse --abbrev-ref HEAD",{cwd:z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),X=0,Y=0;try{let U=d("git rev-list --left-right --count @{upstream}...HEAD 2>/dev/null || echo '0 0'",{cwd:z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(/\s+/);Y=parseInt(U[0]||"0",10),X=parseInt(U[1]||"0",10)}catch{}let $=d("git status --porcelain",{cwd:z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),Q=[],K=[],J=[];for(let U of $.split(`
5
- `)){if(!U.trim())continue;let R=U[0],E=U[1],O=U.slice(3);if(R==="?"&&E==="?")J.push(O);else if(R!==" "&&R!=="?")Q.push(O);else if(E!==" ")K.push(O)}return{branch:W,ahead:X,behind:Y,staged:Q,unstaged:K,untracked:J}}catch(W){return}}async function Sz(z,W){let X=[];for(let Y of W)try{let $=`${z}/${Y}`,Q=Bun.file($);if(await Q.exists()){let K=await Q.text();X.push({path:Y,content:K,hash:vz(K)})}}catch{}return X}async function Iz(z,W){let X=0,Y=0;for(let $ of W)try{let Q=`${z}/${$.path}`;await Bun.write(Q,$.content),X++}catch{Y++}return{restored:X,failed:Y}}async function r(){if(!await Bun.file(h).exists())await Bun.write(h+"/.gitkeep","")}function o(z){return`${h}/${z}.json`}async function S(z){let W=new Map;try{let X=o(z),Y=Bun.file(X);if(await Y.exists()){let $=await Y.text(),Q=JSON.parse($);for(let K of Q)W.set(K.id,K)}}catch(X){}return W}async function fz(z,W){await r();let X=o(z),Y=Array.from(W.values());await Bun.write(X,JSON.stringify(Y,null,2))}async function t(z,W,X={}){let Y=await S(z),$=X.workingDirectory||process.cwd(),Q=yz($),K=[];if(X.trackFiles!==!1&&Q){let U=[...Q.staged,...Q.unstaged,...Q.untracked];K=await Sz($,U)}let J={id:Dz().slice(0,8),sessionId:z,timestamp:Date.now(),label:X.label||`Checkpoint ${Y.size+1}`,description:X.description,messages:JSON.parse(JSON.stringify(W)),files:K,gitState:Q,metadata:{model:X.model,workingDirectory:$,totalCost:X.totalCost||0,messageCount:W.length,fileCount:K.length}};return Y.set(J.id,J),await fz(z,Y),J}async function g(z,W){return(await S(z)).get(W)||null}async function I(z,W={}){let X=W.workingDirectory||z.metadata.workingDirectory||process.cwd(),Y=0,$=0;if(W.restoreFiles!==!1&&z.files.length>0){let Q=await Iz(X,z.files);Y=Q.restored,$=Q.failed}return{messages:W.restoreMessages!==!1?z.messages:[],filesRestored:Y,filesFailed:$}}async function e(z){let W=await S(z);return Array.from(W.values()).sort((X,Y)=>Y.timestamp-X.timestamp)}function v(z,W=!1){let X=new Date(z.timestamp),Y=X.toLocaleTimeString(),$=X.toLocaleDateString(),Q=`\x1B[33m${z.id}\x1B[0m `;if(Q+=`\x1B[1m${z.label}\x1B[0m `,Q+=`\x1B[90m(${$} ${Y})\x1B[0m`,z.files.length>0)Q+=` \x1B[32m[${z.files.length} files]\x1B[0m`;if(z.gitState)Q+=` \x1B[34m(${z.gitState.branch})\x1B[0m`;if(W){if(Q+=`
3
+ import{A as Gz,P as Az,S as bz,T as Nz,Y as Fz,Z as Tz,a as rz,ba as qz,t as n,u as p,w as i,y as Hz}from"./index-wn2m4wma.js";async function m(z,W){let X=Bun.spawn(["git",...z],{cwd:W,stdout:"pipe",stderr:"pipe"}),Y=await new Response(X.stdout).text(),$=await new Response(X.stderr).text(),Q=await X.exited;return{stdout:Y.trim(),stderr:$.trim(),exitCode:Q}}async function jz(z){let{exitCode:W}=await m(["rev-parse","--git-dir"],z);return W===0}async function Mz(z){let{stdout:W,exitCode:X}=await m(["rev-parse","--abbrev-ref","HEAD"],z);if(X!==0)return"HEAD";return W||"HEAD"}async function wz(z){let{stdout:W,exitCode:X}=await m(["rev-list","--left-right","--count","@{upstream}...HEAD"],z);if(X!==0||!W)return{ahead:0,behind:0};let Y=W.split(/\s+/);if(Y.length>=2&&Y[0]!==void 0&&Y[1]!==void 0)return{ahead:parseInt(Y[0],10)||0,behind:parseInt(Y[1],10)||0};return{ahead:0,behind:0}}async function Pz(z){let{stdout:W,exitCode:X}=await m(["status","--porcelain"],z);if(X!==0||!W)return{staged:[],unstaged:[],untracked:[],conflicted:[]};let Y=[],$=[],Q=[],L=[],J=W.split(`
4
+ `);for(let K of J){if(!K)continue;let R=K[0],E=K[1],O=K.substring(3);if(O.includes(" -> ")){let _=O.split(" -> ");O=_[1]??_[0]??O}if(R==="U"||E==="U"||R==="A"&&E==="A"||R==="D"&&E==="D"||R==="A"&&E==="U"||R==="U"&&E==="A"||R==="D"&&E==="U"||R==="U"&&E==="D"){L.push(O);continue}if(R==="?"&&E==="?"){Q.push(O);continue}if(R!==" "&&R!=="?"&&R!=="!")Y.push(O);if(E!==" "&&E!=="?"&&E!=="!"){if(!Y.includes(O))$.push(O)}}return{staged:Y,unstaged:$,untracked:Q,conflicted:L}}async function k(z){try{if(!await jz(z))return null;let[X,Y,$]=await Promise.all([Mz(z),wz(z),Pz(z)]);return{branch:X,ahead:Y.ahead,behind:Y.behind,staged:$.staged,unstaged:$.unstaged,untracked:$.untracked,conflicted:$.conflicted}}catch(W){return console.error("Error getting git status:",W),null}}import{randomUUID as Dz}from"crypto";import{execSync as d}from"child_process";var h=process.env.CLAUDE_CHECKPOINTS_DIR||`${process.env.HOME}/.claude/checkpoints`;function vz(z){let W=0;for(let X=0;X<z.length;X++){let Y=z.charCodeAt(X);W=(W<<5)-W+Y,W=W&W}return Math.abs(W).toString(16)}function yz(z){try{d("git rev-parse --is-inside-work-tree",{cwd:z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let W=d("git rev-parse --abbrev-ref HEAD",{cwd:z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),X=0,Y=0;try{let K=d("git rev-list --left-right --count @{upstream}...HEAD 2>/dev/null || echo '0 0'",{cwd:z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(/\s+/);Y=parseInt(K[0]||"0",10),X=parseInt(K[1]||"0",10)}catch{}let $=d("git status --porcelain",{cwd:z,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),Q=[],L=[],J=[];for(let K of $.split(`
5
+ `)){if(!K.trim())continue;let R=K[0],E=K[1],O=K.slice(3);if(R==="?"&&E==="?")J.push(O);else if(R!==" "&&R!=="?")Q.push(O);else if(E!==" ")L.push(O)}return{branch:W,ahead:X,behind:Y,staged:Q,unstaged:L,untracked:J}}catch(W){return}}async function Sz(z,W){let X=[];for(let Y of W)try{let $=`${z}/${Y}`,Q=Bun.file($);if(await Q.exists()){let L=await Q.text();X.push({path:Y,content:L,hash:vz(L)})}}catch{}return X}async function Iz(z,W){let X=0,Y=0;for(let $ of W)try{let Q=`${z}/${$.path}`;await Bun.write(Q,$.content),X++}catch{Y++}return{restored:X,failed:Y}}async function r(){if(!await Bun.file(h).exists())await Bun.write(h+"/.gitkeep","")}function o(z){return`${h}/${z}.json`}async function S(z){let W=new Map;try{let X=o(z),Y=Bun.file(X);if(await Y.exists()){let $=await Y.text(),Q=JSON.parse($);for(let L of Q)W.set(L.id,L)}}catch(X){}return W}async function fz(z,W){await r();let X=o(z),Y=Array.from(W.values());await Bun.write(X,JSON.stringify(Y,null,2))}async function t(z,W,X={}){let Y=await S(z),$=X.workingDirectory||process.cwd(),Q=yz($),L=[];if(X.trackFiles!==!1&&Q){let K=[...Q.staged,...Q.unstaged,...Q.untracked];L=await Sz($,K)}let J={id:Dz().slice(0,8),sessionId:z,timestamp:Date.now(),label:X.label||`Checkpoint ${Y.size+1}`,description:X.description,messages:JSON.parse(JSON.stringify(W)),files:L,gitState:Q,metadata:{model:X.model,workingDirectory:$,totalCost:X.totalCost||0,messageCount:W.length,fileCount:L.length}};return Y.set(J.id,J),await fz(z,Y),J}async function g(z,W){return(await S(z)).get(W)||null}async function I(z,W={}){let X=W.workingDirectory||z.metadata.workingDirectory||process.cwd(),Y=0,$=0;if(W.restoreFiles!==!1&&z.files.length>0){let Q=await Iz(X,z.files);Y=Q.restored,$=Q.failed}return{messages:W.restoreMessages!==!1?z.messages:[],filesRestored:Y,filesFailed:$}}async function e(z){let W=await S(z);return Array.from(W.values()).sort((X,Y)=>Y.timestamp-X.timestamp)}function v(z,W=!1){let X=new Date(z.timestamp),Y=X.toLocaleTimeString(),$=X.toLocaleDateString(),Q=`\x1B[33m${z.id}\x1B[0m `;if(Q+=`\x1B[1m${z.label}\x1B[0m `,Q+=`\x1B[90m(${$} ${Y})\x1B[0m`,z.files.length>0)Q+=` \x1B[32m[${z.files.length} files]\x1B[0m`;if(z.gitState)Q+=` \x1B[34m(${z.gitState.branch})\x1B[0m`;if(W){if(Q+=`
6
6
  Messages: ${z.metadata.messageCount}`,Q+=`
7
7
  Files: ${z.metadata.fileCount}`,Q+=`
8
- Cost: $${z.metadata.totalCost.toFixed(4)}`,z.gitState){let K=z.gitState.staged.length+z.gitState.unstaged.length+z.gitState.untracked.length;Q+=`
9
- Git changes: ${K}`}if(z.description)Q+=`
8
+ Cost: $${z.metadata.totalCost.toFixed(4)}`,z.gitState){let L=z.gitState.staged.length+z.gitState.unstaged.length+z.gitState.untracked.length;Q+=`
9
+ Git changes: ${L}`}if(z.description)Q+=`
10
10
  ${z.description}`}return Q}function s(z){if(z.length===0){console.log("\x1B[90mNo checkpoints saved.\x1B[0m"),console.log("\x1B[90mUse /checkpoint <label> to create one.\x1B[0m");return}console.log(`
11
- \x1B[1mCheckpoints (${z.length}):\x1B[0m`),console.log("\x1B[90m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m");for(let W of z)console.log(v(W));console.log("\x1B[90m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m"),console.log("\x1B[90m/restore <id> - Restore checkpoint (files + chat)\x1B[0m"),console.log("\x1B[90m/restore-chat <id> - Restore chat only (no files)\x1B[0m"),console.log("\x1B[90m/checkpoint <label> - Create new checkpoint\x1B[0m")}function zz(z){let W=[];if(z.files.length>0)W.push(`${z.files.length} files`);if(W.push(`${z.metadata.messageCount} msgs`),z.gitState){let X=z.gitState.staged.length+z.gitState.unstaged.length+z.gitState.untracked.length;if(X>0)W.push(`${X} changes`)}return W.join(" | ")}var Wz=(z)=>`${h}/${z}-nav.json`;async function u(z){try{let W=Bun.file(Wz(z));if(await W.exists())return JSON.parse(await W.text())}catch{}return{sessionId:z,checkpointIds:[],currentIndex:-1,undoneIds:[]}}async function c(z){await r(),await Bun.write(Wz(z.sessionId),JSON.stringify(z,null,2))}async function Xz(z,W){let X=await u(z);if(X.currentIndex<X.checkpointIds.length-1)X.checkpointIds=X.checkpointIds.slice(0,X.currentIndex+1);X.checkpointIds.push(W),X.currentIndex=X.checkpointIds.length-1,X.undoneIds=[],await c(X)}async function Yz(z){let W=await u(z),X=await S(z);if(W.currentIndex<=0)return{checkpoint:null,canRedo:!1};let Y=W.checkpointIds[W.currentIndex];if(Y)W.undoneIds.push(Y);W.currentIndex--;let $=W.checkpointIds[W.currentIndex];return await c(W),{checkpoint:$?X.get($)||null:null,canRedo:W.undoneIds.length>0}}async function Zz(z){let W=await u(z),X=await S(z);if(W.undoneIds.length===0)return{checkpoint:null,canRedo:!1};let Y=W.undoneIds.pop();return W.currentIndex++,await c(W),{checkpoint:X.get(Y)||null,canRedo:W.undoneIds.length>0}}async function $z(z){let W=await u(z);return{total:W.checkpointIds.length,current:W.currentIndex+1,canUndo:W.currentIndex>0,canRedo:W.undoneIds.length>0,currentId:W.checkpointIds[W.currentIndex]}}import{readFile as Cz,access as mz}from"fs/promises";import{join as Qz}from"path";var kz={globalPath:`${process.env.HOME}/.claude/CLAUDE.md`,projectPath:".claude/CLAUDE.md",rootPath:"CLAUDE.md"};async function dz(z){try{return await mz(z),!0}catch{return!1}}async function a(z){try{if(await dz(z))return(await Cz(z,"utf-8")).trim()}catch(W){}return null}async function hz(z=process.cwd(),W={}){let X={...kz,...W},Y=[],$=null,Q=null,K=X.globalPath;if($=await a(K),$)Y.push(K);let J=Qz(z,X.projectPath),U=Qz(z,X.rootPath);if(Q=await a(J),Q)Y.push(J);else if(Q=await a(U),Q)Y.push(U);let R=[];if($)R.push(`# Global Instructions
11
+ \x1B[1mCheckpoints (${z.length}):\x1B[0m`),console.log("\x1B[90m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m");for(let W of z)console.log(v(W));console.log("\x1B[90m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m"),console.log("\x1B[90m/restore <id> - Restore checkpoint (files + chat)\x1B[0m"),console.log("\x1B[90m/restore-chat <id> - Restore chat only (no files)\x1B[0m"),console.log("\x1B[90m/checkpoint <label> - Create new checkpoint\x1B[0m")}function zz(z){let W=[];if(z.files.length>0)W.push(`${z.files.length} files`);if(W.push(`${z.metadata.messageCount} msgs`),z.gitState){let X=z.gitState.staged.length+z.gitState.unstaged.length+z.gitState.untracked.length;if(X>0)W.push(`${X} changes`)}return W.join(" | ")}var Wz=(z)=>`${h}/${z}-nav.json`;async function u(z){try{let W=Bun.file(Wz(z));if(await W.exists())return JSON.parse(await W.text())}catch{}return{sessionId:z,checkpointIds:[],currentIndex:-1,undoneIds:[]}}async function c(z){await r(),await Bun.write(Wz(z.sessionId),JSON.stringify(z,null,2))}async function Xz(z,W){let X=await u(z);if(X.currentIndex<X.checkpointIds.length-1)X.checkpointIds=X.checkpointIds.slice(0,X.currentIndex+1);X.checkpointIds.push(W),X.currentIndex=X.checkpointIds.length-1,X.undoneIds=[],await c(X)}async function Yz(z){let W=await u(z),X=await S(z);if(W.currentIndex<=0)return{checkpoint:null,canRedo:!1};let Y=W.checkpointIds[W.currentIndex];if(Y)W.undoneIds.push(Y);W.currentIndex--;let $=W.checkpointIds[W.currentIndex];return await c(W),{checkpoint:$?X.get($)||null:null,canRedo:W.undoneIds.length>0}}async function Zz(z){let W=await u(z),X=await S(z);if(W.undoneIds.length===0)return{checkpoint:null,canRedo:!1};let Y=W.undoneIds.pop();return W.currentIndex++,await c(W),{checkpoint:X.get(Y)||null,canRedo:W.undoneIds.length>0}}async function $z(z){let W=await u(z);return{total:W.checkpointIds.length,current:W.currentIndex+1,canUndo:W.currentIndex>0,canRedo:W.undoneIds.length>0,currentId:W.checkpointIds[W.currentIndex]}}import{readFile as Cz,access as mz}from"fs/promises";import{join as Qz}from"path";var kz={globalPath:`${process.env.HOME}/.claude/CLAUDE.md`,projectPath:".claude/CLAUDE.md",rootPath:"CLAUDE.md"};async function dz(z){try{return await mz(z),!0}catch{return!1}}async function a(z){try{if(await dz(z))return(await Cz(z,"utf-8")).trim()}catch(W){}return null}async function hz(z=process.cwd(),W={}){let X={...kz,...W},Y=[],$=null,Q=null,L=X.globalPath;if($=await a(L),$)Y.push(L);let J=Qz(z,X.projectPath),K=Qz(z,X.rootPath);if(Q=await a(J),Q)Y.push(J);else if(Q=await a(K),Q)Y.push(K);let R=[];if($)R.push(`# Global Instructions
12
12
 
13
13
  ${$}`);if(Q)R.push(`# Project Instructions
14
14
 
@@ -22,7 +22,7 @@ ${Q}`);return{global:$,project:Q,merged:R.join(`
22
22
  ${X.length>0?`Loaded from: ${X.join(", ")}`:""}
23
23
 
24
24
  ${W}
25
- `}import{readFile as uz,access as lz}from"fs/promises";import{join as f}from"path";var Bz=process.env.HOME||"",Vz=f(Bz,".claude"),w={main:f(Bz,".claude.json"),settings:f(Vz,"settings.json"),keybindings:f(Vz,"keybindings.json"),projectSettings:(z)=>f(z,".claude","settings.json")};async function pz(z){try{return await lz(z),!0}catch{return!1}}async function l(z,W){try{if(await pz(z)){let X=await uz(z,"utf-8");return{config:JSON.parse(X),loaded:!0}}}catch(X){}return{config:W,loaded:!1}}async function gz(){return l(w.main,{})}async function cz(){return l(w.settings,{})}async function az(){return l(w.keybindings,{bindings:[]})}async function nz(z){return l(w.projectSettings(z),{})}function iz(z,W){return z.projects?.[W]}async function Uz(z=process.cwd()){let W=[],{config:X,loaded:Y}=await gz();if(Y)W.push(w.main);let{config:$,loaded:Q}=await cz();if(Q)W.push(w.settings);let{config:K,loaded:J}=await az();if(J)W.push(w.keybindings);let{config:U,loaded:R}=await nz(z);if(R)W.push(w.projectSettings(z));return{main:X,settings:$,keybindings:K,projectSettings:U,sources:W}}function Kz(z,W){return{hooks:{...z.hooks,...W.hooks},permissions:{...z.permissions,...W.permissions}}}function Lz(z,W){let X={};if(z.mcpServers)Object.assign(X,z.mcpServers);let Y=iz(z,W);if(Y?.mcpServers)Object.assign(X,Y.mcpServers);return X}function Rz(z){let W={};if(!z.hooks)return W;for(let[X,Y]of Object.entries(z.hooks)){let $=[],Q=X;for(let K of Y)for(let J of K.hooks)$.push({event:Q,command:J.type==="command"?J.command||"":"",timeout:J.timeout||60000,enabled:!0,_matcher:K.matcher,_prompt:J.type==="prompt"?J.prompt:void 0});if($.length>0)W[Q]=$}return W}function Ez(z){return z.permissions?.defaultMode||"default"}function Oz(z){return new Set(z.permissions?.allowedTools||[])}function _z(z){return new Set(z.permissions?.disallowedTools||[])}async function oz(z){try{let X=await Bun.file(z).text(),Y=JSON.parse(X);if("servers"in Y&&typeof Y.servers==="object"&&Y.servers!==null)return Y.servers;if("type"in Y){let $={};return $.default=Y,$}return Y}catch(W){let X=W instanceof Error?W.message:String(W);throw Error(`Failed to load MCP config from ${z}: ${X}`)}}function tz(z){let W=[];for(let[X,Y]of z)for(let $ of Y.tools)W.push({name:`mcp__${X}__${$.name}`,description:$.description,input_schema:$.inputSchema,handler:async(Q,K)=>{if(!Y.connected)return{content:`Error: MCP server "${X}" is not connected`,is_error:!0};return Y.callTool($.name,Q)}});return W}function ez(){let z=process.argv.slice(2),W={model:"claude-sonnet-4-6",permissionMode:"default",maxTokens:4096};for(let X=0;X<z.length;X++)switch(z[X]){case"--model":case"-m":W.model=z[++X]??"claude-sonnet-4-6";break;case"--permission-mode":case"-p":W.permissionMode=z[++X]??"default";break;case"--max-tokens":W.maxTokens=parseInt(z[++X]??"4096",10);break;case"--system-prompt":W.systemPrompt=z[++X];break;case"--append-system-prompt":W.appendSystemPrompt=z[++X];break;case"--config":W.configFile=z[++X];break;case"--mcp-config":W.mcpConfig=z[++X];break;case"--resume":W.resumeSession=z[++X];break;case"--sessions":W.listSessions=!0;break;case"--teammate-mode":W.teammateMode=!0;break;case"--agent-id":W.agentId=z[++X];break;case"--agent-name":W.agentName=z[++X];break;case"--team-name":W.teamName=z[++X];break;case"--agent-color":W.agentColor=z[++X];break;case"--interleaved":W.interleaved=!0;break;case"--no-interleaved":W.interleaved=!1;break;case"--extended-thinking":case"-e":W.extendedThinking=!0;break;case"--effort":W.effort=z[++X]??"medium";break;case"--query":case"-q":W.query=z[++X];break;case"--loop":case"-l":W.loop=!0;break;case"--max-iterations":W.maxIterations=parseInt(z[++X]??"10",10);break;case"--help":case"-h":sz(),process.exit(0)}return W}function sz(){console.log(`
25
+ `}import{readFile as uz,access as lz}from"fs/promises";import{join as f}from"path";var Bz=process.env.HOME||"",Vz=f(Bz,".claude"),w={main:f(Bz,".claude.json"),settings:f(Vz,"settings.json"),keybindings:f(Vz,"keybindings.json"),projectSettings:(z)=>f(z,".claude","settings.json")};async function pz(z){try{return await lz(z),!0}catch{return!1}}async function l(z,W){try{if(await pz(z)){let X=await uz(z,"utf-8");return{config:JSON.parse(X),loaded:!0}}}catch(X){}return{config:W,loaded:!1}}async function gz(){return l(w.main,{})}async function cz(){return l(w.settings,{})}async function az(){return l(w.keybindings,{bindings:[]})}async function nz(z){return l(w.projectSettings(z),{})}function iz(z,W){return z.projects?.[W]}async function Uz(z=process.cwd()){let W=[],{config:X,loaded:Y}=await gz();if(Y)W.push(w.main);let{config:$,loaded:Q}=await cz();if(Q)W.push(w.settings);let{config:L,loaded:J}=await az();if(J)W.push(w.keybindings);let{config:K,loaded:R}=await nz(z);if(R)W.push(w.projectSettings(z));return{main:X,settings:$,keybindings:L,projectSettings:K,sources:W}}function Kz(z,W){return{hooks:{...z.hooks,...W.hooks},permissions:{...z.permissions,...W.permissions}}}function Lz(z,W){let X={};if(z.mcpServers)Object.assign(X,z.mcpServers);let Y=iz(z,W);if(Y?.mcpServers)Object.assign(X,Y.mcpServers);return X}function Rz(z){let W={};if(!z.hooks)return W;for(let[X,Y]of Object.entries(z.hooks)){let $=[],Q=X;for(let L of Y)for(let J of L.hooks)$.push({event:Q,command:J.type==="command"?J.command||"":"",timeout:J.timeout||60000,enabled:!0,_matcher:L.matcher,_prompt:J.type==="prompt"?J.prompt:void 0});if($.length>0)W[Q]=$}return W}function Ez(z){return z.permissions?.defaultMode||"default"}function Oz(z){return new Set(z.permissions?.allowedTools||[])}function _z(z){return new Set(z.permissions?.disallowedTools||[])}async function oz(z){try{let X=await Bun.file(z).text(),Y=JSON.parse(X);if("servers"in Y&&typeof Y.servers==="object"&&Y.servers!==null)return Y.servers;if("type"in Y){let $={};return $.default=Y,$}return Y}catch(W){let X=W instanceof Error?W.message:String(W);throw Error(`Failed to load MCP config from ${z}: ${X}`)}}function tz(z){let W=[];for(let[X,Y]of z)for(let $ of Y.tools)W.push({name:`mcp__${X}__${$.name}`,description:$.description,input_schema:$.inputSchema,handler:async(Q,L)=>{if(!Y.connected)return{content:`Error: MCP server "${X}" is not connected`,is_error:!0};return Y.callTool($.name,Q)}});return W}function ez(){let z=process.argv.slice(2),W={model:"claude-sonnet-4-6",permissionMode:"default",maxTokens:4096};for(let X=0;X<z.length;X++)switch(z[X]){case"--model":case"-m":W.model=z[++X]??"claude-sonnet-4-6";break;case"--permission-mode":case"-p":W.permissionMode=z[++X]??"default";break;case"--max-tokens":W.maxTokens=parseInt(z[++X]??"4096",10);break;case"--system-prompt":W.systemPrompt=z[++X];break;case"--append-system-prompt":W.appendSystemPrompt=z[++X];break;case"--config":W.configFile=z[++X];break;case"--mcp-config":W.mcpConfig=z[++X];break;case"--resume":W.resumeSession=z[++X];break;case"--sessions":W.listSessions=!0;break;case"--teammate-mode":W.teammateMode=!0;break;case"--agent-id":W.agentId=z[++X];break;case"--agent-name":W.agentName=z[++X];break;case"--team-name":W.teamName=z[++X];break;case"--agent-color":W.agentColor=z[++X];break;case"--interleaved":W.interleaved=!0;break;case"--no-interleaved":W.interleaved=!1;break;case"--extended-thinking":case"-e":W.extendedThinking=!0;break;case"--effort":W.effort=z[++X]??"medium";break;case"--query":case"-q":W.query=z[++X];break;case"--loop":case"-l":W.loop=!0;break;case"--max-iterations":W.maxIterations=parseInt(z[++X]??"100",10);break;case"--no-autonomous":W.noAutonomous=!0;break;case"--help":case"-h":sz(),process.exit(0)}return W}function sz(){console.log(`
26
26
  Coder v0.1.0
27
27
  A reimplementation of Claude Code CLI
28
28
 
@@ -41,8 +41,9 @@ Extended Thinking:
41
41
  --no-interleaved Disable interleaved thinking
42
42
 
43
43
  Autonomous Loop:
44
- -l, --loop Enable autonomous loop mode
45
- --max-iterations <n> Max iterations in loop mode (default: 10)
44
+ -l, --loop Enable autonomous loop mode (runs until TASKS_COMPLETE)
45
+ --max-iterations <n> Max iterations (default: 100, use 0 for unlimited)
46
+ --no-autonomous Disable autonomous discovery (just continue original task)
46
47
 
47
48
  Other:
48
49
  --system-prompt <prompt> Override system prompt
@@ -63,23 +64,24 @@ EXAMPLES:
63
64
  coder "What files are in this directory?"
64
65
  coder -m claude-opus-4-6 "Explain this codebase"
65
66
  coder --permission-mode acceptEdits "Add a test"
66
- coder --loop "Fix all TypeScript errors" # Autonomous loop
67
- coder --loop --max-iterations 20 "Big task" # More iterations
67
+ coder --loop "Fix all issues" # Autonomous: finds & fixes work
68
+ coder --loop --max-iterations 0 "Go crazy" # Unlimited iterations
69
+ coder --loop --no-autonomous "Just this" # No discovery, just continue
68
70
  coder --sessions
69
71
  coder --resume abc123-def456
70
- `)}async function zW(){let z=ez(),W=new Hz;if(await W.init(),z.listSessions){let B=await W.listSessions(20);Gz(B),process.exit(0)}let X=process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_API_KEY||process.env.ANTHROPIC_AUTH_TOKEN||process.env.Z_AI_API_KEY;if(!X)console.error("Error: ANTHROPIC_API_KEY, CLAUDE_API_KEY, ANTHROPIC_AUTH_TOKEN, or Z_AI_API_KEY environment variable required"),process.exit(1);console.log("\x1B[90mLoading configuration...\x1B[0m");let Y;try{Y=await Uz(process.cwd())}catch(B){let b=B instanceof Error?B.message:String(B);console.error(`\x1B[33mWarning: Failed to load config: ${b}\x1B[0m`),Y={main:{},settings:{},keybindings:{bindings:[]},projectSettings:{},sources:[]}}let $=Kz(Y.settings,Y.projectSettings);if(Y.sources.length>0)console.log(`\x1B[90m Config sources: ${Y.sources.length} files\x1B[0m`);if(z.permissionMode==="default"){let B=Ez($);if(B!=="default")z.permissionMode=B,console.log(`\x1B[90m Permission mode: ${B} (from config)\x1B[0m`)}let Q=Oz($),K=_z($),J=new Nz,U=new Fz,R=new xz,E=Rz($);for(let[B,b]of Object.entries(E))for(let G of b)J.register(B,G);if(Object.keys(E).length>0)console.log(`\x1B[90m Hooks registered: ${Object.keys(E).length} events\x1B[0m`);let O=process.cwd()+"/.claude/skills";U.loadFromDirectory(O,"project");let A=new Map,_=Lz(Y.main,process.cwd());if(z.mcpConfig)try{console.log(`\x1B[90mLoading MCP config from ${z.mcpConfig}...\x1B[0m`),_=await oz(z.mcpConfig)}catch(B){let b=B instanceof Error?B.message:String(B);console.error(`\x1B[33mWarning: Failed to load MCP config file: ${b}\x1B[0m`)}if(Object.keys(_).length>0){let b=Object.entries(_).filter(([G,M])=>!M.disabled).length;if(b>0){console.log(`\x1B[90m Connecting to ${b} MCP server(s)...\x1B[0m`);let G=await bz(_,(M)=>{console.log(`\x1B[90m ${M}\x1B[0m`)});for(let[M,y]of G)A.set(M,y);if(A.size>0)console.log(`\x1B[32m Connected to ${A.size} MCP server(s)\x1B[0m`);else console.log("\x1B[33m Warning: No MCP servers connected successfully\x1B[0m")}else if(Object.keys(_).length>0)console.log(`\x1B[90m MCP config loaded but all ${Object.keys(_).length} server(s) are disabled\x1B[0m`)}let N=[...Az,...tz(A)],F=await k(process.cwd()),q=z.systemPrompt||await YW(F);if(z.appendSystemPrompt)q+=`
71
-
72
- ${z.appendSystemPrompt}`;if(z.teammateMode&&z.teamName)q+=`
73
-
74
- You are running as a teammate agent in the "${z.teamName}" team.`,q+=`
75
- Agent ID: ${z.agentId}`,q+=`
76
- Agent Name: ${z.agentName}`;let L=[],T;if(z.resumeSession){let B=await W.resumeSession(z.resumeSession);if(!B)console.error(`Error: Session not found: ${z.resumeSession}`),process.exit(1);L=B.messages,T=z.resumeSession,z.model=B.metadata.model,z.agentName=B.metadata.agentName,z.agentColor=B.metadata.agentColor,z.teamName=B.metadata.teamName,console.log(`\x1B[90mResumed session: ${z.resumeSession}\x1B[0m`),console.log(`\x1B[90mModel: ${z.model} | Messages: ${L.length}\x1B[0m
77
- `)}else T=await W.createSession({model:z.model,workingDirectory:process.cwd(),agentName:z.agentName,agentColor:z.agentColor,teamName:z.teamName});let x=z.query,j=process.argv[2];if(!x&&process.argv.length>2&&j&&!j.startsWith("-"))x=process.argv.slice(2).join(" ");if(!x)console.log("Coder v0.1.0"),console.log(`Session: ${T}`),console.log(`Type your message or /help for commands.
78
- `),await WW(X,z,q,N,J,U,W,L,T,A);else await XW(X,z,q,N,x,W,T)}async function WW(z,W,X,Y,$,Q,K,J,U,R){let E=process.stdin.isTTY,O=process.env.CLAUDE_FORCE_INTERACTIVE==="true";if(!E&&!O){console.error("Error: Interactive mode requires a TTY. Use -q for single query mode."),console.error(" Or set CLAUDE_FORCE_INTERACTIVE=true for testing.");return}let A=!0,H=0,_=await k(process.cwd()),N=rz("readline").createInterface({input:process.stdin,output:process.stdout,terminal:!0,historySize:1000,removeHistoryDuplicates:!0});process.on("SIGINT",()=>{console.log(`
79
- \x1B[90mGoodbye!\x1B[0m`),N.close(),process.exit(0)});let F=(L)=>{return new Promise((T,x)=>{if(N.closed){x(Error("Readline closed"));return}N.question(L,(j)=>{T(j)})})},q=async(L)=>{if(console.log(`
80
- \x1B[36m\u2501\u2501\u2501 Permission Required \u2501\u2501\u2501\x1B[0m`),console.log(`Tool: \x1B[1m${L.toolName}\x1B[0m`),console.log(`Risk: \x1B[32m${L.riskLevel.toUpperCase()}\x1B[0m`),console.log(`Action: ${L.description}`),L.file)console.log(`File: ${L.file}`);else if(L.command)console.log(`Command: ${L.command}`);else if(L.toolInput.file_path)console.log(`File: ${L.toolInput.file_path}`);else if(L.toolInput.command)console.log(`Command: ${L.toolInput.command}`);while(!0)try{switch((await F(`
81
- Allow? [y]es / [n]o / [a]lways / [d]eny always: `)).trim().toLowerCase()){case"y":case"yes":case"":return{decision:"allow"};case"n":case"no":return{decision:"deny",reason:"User denied"};case"a":case"always":return{decision:"allowAlways"};case"d":case"deny":return{decision:"denyAlways",reason:"User denied always"};default:console.log("Please enter y, n, a, or d")}}catch{return{decision:"deny",reason:"Input error"}}};while(A)try{let L=await F(`
82
- \x1B[1;36mYou:\x1B[0m `);if(!L.trim())continue;if(L.startsWith("/")){let b=L.slice(1).split(" ")[0]??"",G=L.slice(b.length+2);switch(b){case"exit":case"quit":case"q":A=!1,console.log("\x1B[90mGoodbye!\x1B[0m");continue;case"help":case"?":console.log(`
72
+ `)}async function zW(){let z=ez(),W=new Hz;if(await W.init(),z.listSessions){let B=await W.listSessions(20);Gz(B),process.exit(0)}let X=process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_API_KEY||process.env.ANTHROPIC_AUTH_TOKEN||process.env.Z_AI_API_KEY;if(!X)console.error("Error: ANTHROPIC_API_KEY, CLAUDE_API_KEY, ANTHROPIC_AUTH_TOKEN, or Z_AI_API_KEY environment variable required"),process.exit(1);console.log("\x1B[90mLoading configuration...\x1B[0m");let Y;try{Y=await Uz(process.cwd())}catch(B){let F=B instanceof Error?B.message:String(B);console.error(`\x1B[33mWarning: Failed to load config: ${F}\x1B[0m`),Y={main:{},settings:{},keybindings:{bindings:[]},projectSettings:{},sources:[]}}let $=Kz(Y.settings,Y.projectSettings);if(Y.sources.length>0)console.log(`\x1B[90m Config sources: ${Y.sources.length} files\x1B[0m`);if(z.permissionMode==="default"){let B=Ez($);if(B!=="default")z.permissionMode=B,console.log(`\x1B[90m Permission mode: ${B} (from config)\x1B[0m`)}let Q=Oz($),L=_z($),J=new Nz,K=new Fz,R=new qz,E=Rz($);for(let[B,F]of Object.entries(E))for(let G of F)J.register(B,G);if(Object.keys(E).length>0)console.log(`\x1B[90m Hooks registered: ${Object.keys(E).length} events\x1B[0m`);let O=process.cwd()+"/.claude/skills";K.loadFromDirectory(O,"project");let T=new Map,q=Lz(Y.main,process.cwd());if(z.mcpConfig)try{console.log(`\x1B[90mLoading MCP config from ${z.mcpConfig}...\x1B[0m`),q=await oz(z.mcpConfig)}catch(B){let F=B instanceof Error?B.message:String(B);console.error(`\x1B[33mWarning: Failed to load MCP config file: ${F}\x1B[0m`)}if(Object.keys(q).length>0){let F=Object.entries(q).filter(([G,M])=>!M.disabled).length;if(F>0){console.log(`\x1B[90m Connecting to ${F} MCP server(s)...\x1B[0m`);let G=await bz(q,(M)=>{console.log(`\x1B[90m ${M}\x1B[0m`)});for(let[M,y]of G)T.set(M,y);if(T.size>0)console.log(`\x1B[32m Connected to ${T.size} MCP server(s)\x1B[0m`);else console.log("\x1B[33m Warning: No MCP servers connected successfully\x1B[0m")}else if(Object.keys(q).length>0)console.log(`\x1B[90m MCP config loaded but all ${Object.keys(q).length} server(s) are disabled\x1B[0m`)}let x=[...Az,...tz(T)],A=await k(process.cwd()),b=z.systemPrompt||await YW(A);if(z.appendSystemPrompt)b+=`
73
+
74
+ ${z.appendSystemPrompt}`;if(z.teammateMode&&z.teamName)b+=`
75
+
76
+ You are running as a teammate agent in the "${z.teamName}" team.`,b+=`
77
+ Agent ID: ${z.agentId}`,b+=`
78
+ Agent Name: ${z.agentName}`;let U=[],N;if(z.resumeSession){let B=await W.resumeSession(z.resumeSession);if(!B)console.error(`Error: Session not found: ${z.resumeSession}`),process.exit(1);U=B.messages,N=z.resumeSession,z.model=B.metadata.model,z.agentName=B.metadata.agentName,z.agentColor=B.metadata.agentColor,z.teamName=B.metadata.teamName,console.log(`\x1B[90mResumed session: ${z.resumeSession}\x1B[0m`),console.log(`\x1B[90mModel: ${z.model} | Messages: ${U.length}\x1B[0m
79
+ `)}else N=await W.createSession({model:z.model,workingDirectory:process.cwd(),agentName:z.agentName,agentColor:z.agentColor,teamName:z.teamName});let H=z.query,j=process.argv[2];if(!H&&process.argv.length>2&&j&&!j.startsWith("-"))H=process.argv.slice(2).join(" ");if(!H)console.log("Coder v0.1.0"),console.log(`Session: ${N}`),console.log(`Type your message or /help for commands.
80
+ `),await WW(X,z,b,x,J,K,W,U,N,T);else await XW(X,z,b,x,H,W,N)}async function WW(z,W,X,Y,$,Q,L,J,K,R){let E=process.stdin.isTTY,O=process.env.CLAUDE_FORCE_INTERACTIVE==="true";if(!E&&!O){console.error("Error: Interactive mode requires a TTY. Use -q for single query mode."),console.error(" Or set CLAUDE_FORCE_INTERACTIVE=true for testing.");return}let T=!0,_=0,q=await k(process.cwd()),x=rz("readline").createInterface({input:process.stdin,output:process.stdout,terminal:!0,historySize:1000,removeHistoryDuplicates:!0});process.on("SIGINT",()=>{console.log(`
81
+ \x1B[90mGoodbye!\x1B[0m`),x.close(),process.exit(0)});let A=(U)=>{return new Promise((N,H)=>{if(x.closed){H(Error("Readline closed"));return}x.question(U,(j)=>{N(j)})})},b=async(U)=>{if(console.log(`
82
+ \x1B[36m\u2501\u2501\u2501 Permission Required \u2501\u2501\u2501\x1B[0m`),console.log(`Tool: \x1B[1m${U.toolName}\x1B[0m`),console.log(`Risk: \x1B[32m${U.riskLevel.toUpperCase()}\x1B[0m`),console.log(`Action: ${U.description}`),U.file)console.log(`File: ${U.file}`);else if(U.command)console.log(`Command: ${U.command}`);else if(U.toolInput.file_path)console.log(`File: ${U.toolInput.file_path}`);else if(U.toolInput.command)console.log(`Command: ${U.toolInput.command}`);while(!0)try{switch((await A(`
83
+ Allow? [y]es / [n]o / [a]lways / [d]eny always: `)).trim().toLowerCase()){case"y":case"yes":case"":return{decision:"allow"};case"n":case"no":return{decision:"deny",reason:"User denied"};case"a":case"always":return{decision:"allowAlways"};case"d":case"deny":return{decision:"denyAlways",reason:"User denied always"};default:console.log("Please enter y, n, a, or d")}}catch{return{decision:"deny",reason:"Input error"}}};while(T)try{let U=await A(`
84
+ \x1B[1;36mYou:\x1B[0m `);if(!U.trim())continue;if(U.startsWith("/")){let F=U.slice(1).split(" ")[0]??"",G=U.slice(F.length+2);switch(F){case"exit":case"quit":case"q":T=!1,console.log("\x1B[90mGoodbye!\x1B[0m");continue;case"help":case"?":console.log(`
83
85
  \x1B[1mCommands:\x1B[0m
84
86
  /help, /? Show this help
85
87
  /exit, /quit, /q Exit the session
@@ -103,20 +105,37 @@ Allow? [y]es / [n]o / [a]lways / [d]eny always: `)).trim().toLowerCase()){case"y
103
105
 
104
106
  \x1B[1mExport:\x1B[0m
105
107
  /export [format] Export session (jsonl/json/md)
106
- `);continue;case"clear":J.length=0,console.log("\x1B[90mConversation cleared.\x1B[0m");continue;case"compact":console.log("\x1B[90mForcing context compaction...\x1B[0m");continue;case"model":if(G)W.model=G,console.log(`\x1B[90mSwitched to model: ${G}\x1B[0m`);else console.log(`Current model: \x1B[1m${W.model}\x1B[0m`);continue;case"tools":console.log("\x1B[1mAvailable tools:\x1B[0m");for(let Z of Y){let V=Z.description.split(".")[0]??Z.description;console.log(` \x1B[33m${Z.name}\x1B[0m: ${V}`)}continue;case"mcp":if(R.size===0)console.log("\x1B[90mNo MCP servers connected.\x1B[0m"),console.log("\x1B[90mUse --mcp-config to specify a config file.\x1B[0m");else{console.log("\x1B[1mConnected MCP Servers:\x1B[0m");for(let[Z,V]of R){let P=V.connected?"\x1B[32m\u25CF\x1B[0m":"\x1B[31m\u25CB\x1B[0m";console.log(` ${P} \x1B[1m${Z}\x1B[0m (${V.tools.length} tools)`);for(let D of V.tools)console.log(` \x1B[33m${D.name}\x1B[0m: ${D.description.slice(0,50)}...`)}}continue;case"skills":let M=Q.getAll();if(M.length===0)console.log("\x1B[90mNo skills loaded.\x1B[0m");else{console.log("\x1B[1mAvailable skills:\x1B[0m");for(let Z of M){let V=Z.description??Z.prompt.slice(0,50);console.log(` \x1B[33m/${Z.name}\x1B[0m: ${V}...`)}}continue;case"cost":console.log(`Total cost: \x1B[1m${p(H)}\x1B[0m`);continue;case"status":case"session":console.log("\x1B[1mSession Status:\x1B[0m"),console.log(` ID: ${U}`),console.log(` Model: ${W.model}`),console.log(` Messages: ${J.length}`),console.log(` Total cost: ${p(H)}`),console.log(` Permission mode: ${W.permissionMode}`);continue;case"export":try{let Z=G||"markdown",V=await K.exportSession(U,Z);console.log(`\x1B[90mSession exported to: ${V}\x1B[0m`)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mExport failed: ${V}\x1B[0m`)}continue;case"checkpoint":case"cp":if(!G){console.log("\x1B[31mUsage: /checkpoint <label>\x1B[0m"),console.log("\x1B[90mExample: /checkpoint before-refactor\x1B[0m"),console.log("\x1B[90mCreates checkpoint with chat history + file snapshots\x1B[0m");continue}try{let Z=await t(U,J,{label:G,model:W.model,workingDirectory:process.cwd(),totalCost:H,trackFiles:!0});await Xz(U,Z.id);let V=zz(Z);if(console.log(`\x1B[32m\u2713 Checkpoint saved:\x1B[0m ${v(Z)}`),V)console.log(`\x1B[90m ${V}\x1B[0m`)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mFailed to create checkpoint: ${V}\x1B[0m`)}continue;case"checkpoints":case"cps":try{let Z=await e(U);s(Z)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mFailed to list checkpoints: ${V}\x1B[0m`)}continue;case"restore":case"rollback":case"rewind":if(!G){console.log("\x1B[31mUsage: /${command} <checkpoint-id>\x1B[0m"),console.log("\x1B[90mUse /checkpoints to see available checkpoints\x1B[0m");continue}try{let Z=G.trim(),V=await g(U,Z);if(!V){console.log(`\x1B[31mCheckpoint not found: ${Z}\x1B[0m`),console.log("\x1B[90mUse /checkpoints to see available checkpoints\x1B[0m");continue}console.log(`
107
- \x1B[1mRestoring checkpoint:\x1B[0m ${v(V)}`);let P=V.files.length>0,D=!1;if(P){console.log(`\x1B[33m${V.files.length} file(s) saved in checkpoint:\x1B[0m`);for(let qz of V.files.slice(0,5))console.log(` - ${qz.path}`);if(V.files.length>5)console.log(` ... and ${V.files.length-5} more`);D=(await F(`
108
- \x1B[36mRestore files too? [Y/n]: \x1B[0m`)).trim().toLowerCase()!=="n"}let C=await I(V,{restoreFiles:D,restoreMessages:!0,workingDirectory:process.cwd()});if(J.length=0,J.push(...C.messages),H=V.metadata.totalCost,console.log(`
109
- \x1B[32m\u2713 Checkpoint restored:\x1B[0m`),console.log(` Messages: ${J.length}`),D&&P){if(console.log(` Files restored: ${C.filesRestored}`),C.filesFailed>0)console.log(` \x1B[33mFiles failed: ${C.filesFailed}\x1B[0m`)}console.log(` Cost reset to: $${H.toFixed(4)}`)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mFailed to restore checkpoint: ${V}\x1B[0m`)}continue;case"restore-chat":if(!G){console.log("\x1B[31mUsage: /restore-chat <checkpoint-id>\x1B[0m"),console.log("\x1B[90mRestores chat only, no files\x1B[0m");continue}try{let Z=G.trim(),V=await g(U,Z);if(!V){console.log(`\x1B[31mCheckpoint not found: ${Z}\x1B[0m`);continue}let P=await I(V,{restoreFiles:!1,restoreMessages:!0});J.length=0,J.push(...P.messages),H=V.metadata.totalCost,console.log(`\x1B[32m\u2713 Chat restored:\x1B[0m ${J.length} messages (no files changed)`)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mFailed to restore chat: ${V}\x1B[0m`)}continue;case"undo":try{let Z=await Yz(U);if(!Z.checkpoint){console.log("\x1B[33mNothing to undo\x1B[0m");continue}let V=await I(Z.checkpoint,{restoreFiles:!0,restoreMessages:!0,workingDirectory:process.cwd()});if(J.length=0,J.push(...V.messages),H=Z.checkpoint.metadata.totalCost,console.log(`\x1B[32m\u2713 Undone to:\x1B[0m ${v(Z.checkpoint)}`),console.log(`\x1B[90mMessages: ${J.length} | Files: ${V.filesRestored}\x1B[0m`),Z.canRedo)console.log("\x1B[90mUse /redo to go forward\x1B[0m")}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mUndo failed: ${V}\x1B[0m`)}continue;case"redo":try{let Z=await Zz(U);if(!Z.checkpoint){console.log("\x1B[33mNothing to redo\x1B[0m");continue}let V=await I(Z.checkpoint,{restoreFiles:!0,restoreMessages:!0,workingDirectory:process.cwd()});if(J.length=0,J.push(...V.messages),H=Z.checkpoint.metadata.totalCost,console.log(`\x1B[32m\u2713 Redone to:\x1B[0m ${v(Z.checkpoint)}`),console.log(`\x1B[90mMessages: ${J.length} | Files: ${V.filesRestored}\x1B[0m`),Z.canRedo)console.log("\x1B[90mUse /redo to go forward again\x1B[0m")}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mRedo failed: ${V}\x1B[0m`)}continue;case"checkpoint-status":case"cps-status":try{let Z=await $z(U);if(console.log("\x1B[1mCheckpoint Navigation:\x1B[0m"),console.log(` Position: ${Z.current}/${Z.total}`),console.log(` Can undo: ${Z.canUndo?"\x1B[32myes\x1B[0m":"\x1B[31mno\x1B[0m"}`),console.log(` Can redo: ${Z.canRedo?"\x1B[32myes\x1B[0m":"\x1B[31mno\x1B[0m"}`),Z.currentId)console.log(` Current: ${Z.currentId}`)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mFailed to get status: ${V}\x1B[0m`)}continue;default:let y=Q.get(b);if(y){console.log(`\x1B[90mLoading skill: ${y.name}\x1B[0m`),X+=`
108
+ `);continue;case"clear":J.length=0,console.log("\x1B[90mConversation cleared.\x1B[0m");continue;case"compact":console.log("\x1B[90mForcing context compaction...\x1B[0m");continue;case"model":if(G)W.model=G,console.log(`\x1B[90mSwitched to model: ${G}\x1B[0m`);else console.log(`Current model: \x1B[1m${W.model}\x1B[0m`);continue;case"tools":console.log("\x1B[1mAvailable tools:\x1B[0m");for(let Z of Y){let V=Z.description.split(".")[0]??Z.description;console.log(` \x1B[33m${Z.name}\x1B[0m: ${V}`)}continue;case"mcp":if(R.size===0)console.log("\x1B[90mNo MCP servers connected.\x1B[0m"),console.log("\x1B[90mUse --mcp-config to specify a config file.\x1B[0m");else{console.log("\x1B[1mConnected MCP Servers:\x1B[0m");for(let[Z,V]of R){let P=V.connected?"\x1B[32m\u25CF\x1B[0m":"\x1B[31m\u25CB\x1B[0m";console.log(` ${P} \x1B[1m${Z}\x1B[0m (${V.tools.length} tools)`);for(let D of V.tools)console.log(` \x1B[33m${D.name}\x1B[0m: ${D.description.slice(0,50)}...`)}}continue;case"skills":let M=Q.getAll();if(M.length===0)console.log("\x1B[90mNo skills loaded.\x1B[0m");else{console.log("\x1B[1mAvailable skills:\x1B[0m");for(let Z of M){let V=Z.description??Z.prompt.slice(0,50);console.log(` \x1B[33m/${Z.name}\x1B[0m: ${V}...`)}}continue;case"cost":console.log(`Total cost: \x1B[1m${p(_)}\x1B[0m`);continue;case"status":case"session":console.log("\x1B[1mSession Status:\x1B[0m"),console.log(` ID: ${K}`),console.log(` Model: ${W.model}`),console.log(` Messages: ${J.length}`),console.log(` Total cost: ${p(_)}`),console.log(` Permission mode: ${W.permissionMode}`);continue;case"export":try{let Z=G||"markdown",V=await L.exportSession(K,Z);console.log(`\x1B[90mSession exported to: ${V}\x1B[0m`)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mExport failed: ${V}\x1B[0m`)}continue;case"checkpoint":case"cp":if(!G){console.log("\x1B[31mUsage: /checkpoint <label>\x1B[0m"),console.log("\x1B[90mExample: /checkpoint before-refactor\x1B[0m"),console.log("\x1B[90mCreates checkpoint with chat history + file snapshots\x1B[0m");continue}try{let Z=await t(K,J,{label:G,model:W.model,workingDirectory:process.cwd(),totalCost:_,trackFiles:!0});await Xz(K,Z.id);let V=zz(Z);if(console.log(`\x1B[32m\u2713 Checkpoint saved:\x1B[0m ${v(Z)}`),V)console.log(`\x1B[90m ${V}\x1B[0m`)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mFailed to create checkpoint: ${V}\x1B[0m`)}continue;case"checkpoints":case"cps":try{let Z=await e(K);s(Z)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mFailed to list checkpoints: ${V}\x1B[0m`)}continue;case"restore":case"rollback":case"rewind":if(!G){console.log("\x1B[31mUsage: /${command} <checkpoint-id>\x1B[0m"),console.log("\x1B[90mUse /checkpoints to see available checkpoints\x1B[0m");continue}try{let Z=G.trim(),V=await g(K,Z);if(!V){console.log(`\x1B[31mCheckpoint not found: ${Z}\x1B[0m`),console.log("\x1B[90mUse /checkpoints to see available checkpoints\x1B[0m");continue}console.log(`
109
+ \x1B[1mRestoring checkpoint:\x1B[0m ${v(V)}`);let P=V.files.length>0,D=!1;if(P){console.log(`\x1B[33m${V.files.length} file(s) saved in checkpoint:\x1B[0m`);for(let xz of V.files.slice(0,5))console.log(` - ${xz.path}`);if(V.files.length>5)console.log(` ... and ${V.files.length-5} more`);D=(await A(`
110
+ \x1B[36mRestore files too? [Y/n]: \x1B[0m`)).trim().toLowerCase()!=="n"}let C=await I(V,{restoreFiles:D,restoreMessages:!0,workingDirectory:process.cwd()});if(J.length=0,J.push(...C.messages),_=V.metadata.totalCost,console.log(`
111
+ \x1B[32m\u2713 Checkpoint restored:\x1B[0m`),console.log(` Messages: ${J.length}`),D&&P){if(console.log(` Files restored: ${C.filesRestored}`),C.filesFailed>0)console.log(` \x1B[33mFiles failed: ${C.filesFailed}\x1B[0m`)}console.log(` Cost reset to: $${_.toFixed(4)}`)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mFailed to restore checkpoint: ${V}\x1B[0m`)}continue;case"restore-chat":if(!G){console.log("\x1B[31mUsage: /restore-chat <checkpoint-id>\x1B[0m"),console.log("\x1B[90mRestores chat only, no files\x1B[0m");continue}try{let Z=G.trim(),V=await g(K,Z);if(!V){console.log(`\x1B[31mCheckpoint not found: ${Z}\x1B[0m`);continue}let P=await I(V,{restoreFiles:!1,restoreMessages:!0});J.length=0,J.push(...P.messages),_=V.metadata.totalCost,console.log(`\x1B[32m\u2713 Chat restored:\x1B[0m ${J.length} messages (no files changed)`)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mFailed to restore chat: ${V}\x1B[0m`)}continue;case"undo":try{let Z=await Yz(K);if(!Z.checkpoint){console.log("\x1B[33mNothing to undo\x1B[0m");continue}let V=await I(Z.checkpoint,{restoreFiles:!0,restoreMessages:!0,workingDirectory:process.cwd()});if(J.length=0,J.push(...V.messages),_=Z.checkpoint.metadata.totalCost,console.log(`\x1B[32m\u2713 Undone to:\x1B[0m ${v(Z.checkpoint)}`),console.log(`\x1B[90mMessages: ${J.length} | Files: ${V.filesRestored}\x1B[0m`),Z.canRedo)console.log("\x1B[90mUse /redo to go forward\x1B[0m")}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mUndo failed: ${V}\x1B[0m`)}continue;case"redo":try{let Z=await Zz(K);if(!Z.checkpoint){console.log("\x1B[33mNothing to redo\x1B[0m");continue}let V=await I(Z.checkpoint,{restoreFiles:!0,restoreMessages:!0,workingDirectory:process.cwd()});if(J.length=0,J.push(...V.messages),_=Z.checkpoint.metadata.totalCost,console.log(`\x1B[32m\u2713 Redone to:\x1B[0m ${v(Z.checkpoint)}`),console.log(`\x1B[90mMessages: ${J.length} | Files: ${V.filesRestored}\x1B[0m`),Z.canRedo)console.log("\x1B[90mUse /redo to go forward again\x1B[0m")}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mRedo failed: ${V}\x1B[0m`)}continue;case"checkpoint-status":case"cps-status":try{let Z=await $z(K);if(console.log("\x1B[1mCheckpoint Navigation:\x1B[0m"),console.log(` Position: ${Z.current}/${Z.total}`),console.log(` Can undo: ${Z.canUndo?"\x1B[32myes\x1B[0m":"\x1B[31mno\x1B[0m"}`),console.log(` Can redo: ${Z.canRedo?"\x1B[32myes\x1B[0m":"\x1B[31mno\x1B[0m"}`),Z.currentId)console.log(` Current: ${Z.currentId}`)}catch(Z){let V=Z instanceof Error?Z.message:String(Z);console.error(`\x1B[31mFailed to get status: ${V}\x1B[0m`)}continue;default:let y=Q.get(F);if(y){console.log(`\x1B[90mLoading skill: ${y.name}\x1B[0m`),X+=`
110
112
 
111
- `+Tz(y);continue}console.log(`\x1B[31mUnknown command: /${b}\x1B[0m`),console.log("\x1B[90mType /help for available commands.\x1B[0m");continue}}J.push({role:"user",content:[{type:"text",text:L}]}),await K.saveMessage(J[J.length-1]),process.stdout.write(`
112
- \x1B[1;35mClaude:\x1B[0m `);let T=W.extendedThinking?{enabled:!0,effort:W.effort??"medium",interleaved:W.interleaved??!0}:void 0,x=await n(J,{apiKey:z,model:W.model,maxTokens:W.maxTokens,systemPrompt:X,tools:Y,permissionMode:W.permissionMode,workingDirectory:process.cwd(),gitStatus:_,extendedThinking:T,onText:(B)=>{process.stdout.write(B)},onThinking:(B)=>{process.stdout.write(`\x1B[90m${B}\x1B[0m`)},onToolUse:(B)=>{process.stdout.write(`
113
+ `+Tz(y);continue}console.log(`\x1B[31mUnknown command: /${F}\x1B[0m`),console.log("\x1B[90mType /help for available commands.\x1B[0m");continue}}J.push({role:"user",content:[{type:"text",text:U}]}),await L.saveMessage(J[J.length-1]),process.stdout.write(`
114
+ \x1B[1;35mClaude:\x1B[0m `);let N=W.extendedThinking?{enabled:!0,effort:W.effort??"medium",interleaved:W.interleaved??!0}:void 0,H=await n(J,{apiKey:z,model:W.model,maxTokens:W.maxTokens,systemPrompt:X,tools:Y,permissionMode:W.permissionMode,workingDirectory:process.cwd(),gitStatus:q,extendedThinking:N,onText:(B)=>{process.stdout.write(B)},onThinking:(B)=>{process.stdout.write(`\x1B[90m${B}\x1B[0m`)},onToolUse:(B)=>{process.stdout.write(`
113
115
  \x1B[90m[Trying: ${B.name}]\x1B[0m `)},onToolResult:(B)=>{if(B.result.is_error)process.stdout.write("\x1B[31m[Error]\x1B[0m ")},onMetrics:async(B)=>{console.log(`
114
- \x1B[90m${i(B)}\x1B[0m`),await K.saveMetrics(B)},onPermissionRequest:async(B)=>{return await q({toolName:B.toolName,toolInput:B.toolInput,riskLevel:B.riskLevel,description:B.description,file:B.file,command:B.command})}}),j=x.messages[x.messages.length-1];if(j&&j.role==="assistant")await K.saveMessage(j);J.length=0,J.push(...x.messages),H+=x.totalCost}catch(L){if(L instanceof Error&&L.message==="Readline closed")break;let T=L instanceof Error?L.message:String(L);console.error(`
115
- \x1B[31mError: ${T}\x1B[0m`)}N.close()}async function XW(z,W,X,Y,$,Q,K){let J=[{role:"user",content:[{type:"text",text:$}]}];await Q.saveMessage(J[0]);let U=await k(process.cwd()),R=W.extendedThinking?{enabled:!0,effort:W.effort??"medium",interleaved:W.interleaved??!0}:void 0,E=W.loop??!1,O=W.maxIterations??10,A=0,H=0;try{while(!0){if(A++,E)console.log(`
116
- \x1B[36m\u2501\u2501\u2501 Iteration ${A}/${O} \u2501\u2501\u2501\x1B[0m`);let _=await n(J,{apiKey:z,model:W.model,maxTokens:W.maxTokens,systemPrompt:X,tools:Y,permissionMode:W.permissionMode,workingDirectory:process.cwd(),gitStatus:U,extendedThinking:R,onText:(F)=>{process.stdout.write(F)},onThinking:(F)=>{process.stdout.write(`\x1B[90m${F}\x1B[0m`)},onMetrics:async(F)=>{console.log(`
117
- \x1B[90m${i(F)}\x1B[0m`),await Q.saveMetrics(F)}}),N=_.messages[_.messages.length-1];if(N&&N.role==="assistant")await Q.saveMessage(N);if(H+=_.totalCost,J.length=0,J.push(..._.messages),E&&A<O)J.push({role:"user",content:[{type:"text",text:"Continue working on the task. If complete, summarize what was done."}]});else break}if(E)console.log(`
118
- \x1B[32m\u2713 Completed ${A} iteration(s)\x1B[0m`);console.log(`
119
- \x1B[90mSession: ${K}\x1B[0m`),console.log(`\x1B[90mTotal cost: ${p(H)}\x1B[0m`)}catch(_){let N=_ instanceof Error?_.message:String(_);console.error(`Error: ${N}`),process.exit(1)}}async function YW(z){let W=`You are Claude Code, an AI coding assistant created by Anthropic.
116
+ \x1B[90m${i(B)}\x1B[0m`),await L.saveMetrics(B)},onPermissionRequest:async(B)=>{return await b({toolName:B.toolName,toolInput:B.toolInput,riskLevel:B.riskLevel,description:B.description,file:B.file,command:B.command})}}),j=H.messages[H.messages.length-1];if(j&&j.role==="assistant")await L.saveMessage(j);J.length=0,J.push(...H.messages),_+=H.totalCost}catch(U){if(U instanceof Error&&U.message==="Readline closed")break;let N=U instanceof Error?U.message:String(U);console.error(`
117
+ \x1B[31mError: ${N}\x1B[0m`)}x.close()}async function XW(z,W,X,Y,$,Q,L){let J=[{role:"user",content:[{type:"text",text:$}]}];await Q.saveMessage(J[0]);let K=await k(process.cwd()),R=W.extendedThinking?{enabled:!0,effort:W.effort??"medium",interleaved:W.interleaved??!0}:void 0,E=W.loop??!1,O=W.maxIterations??100,T=W.noAutonomous??!1,_=0,q=0,x=!1;try{while(!0){if(_++,O>0&&_>O){console.log(`
118
+ \x1B[33m\u26A0 Max iterations (${O}) reached\x1B[0m`);break}if(E){let U=O>0?`/${O}`:"";console.log(`
119
+ \x1B[36m\u2501\u2501\u2501 Iteration ${_}${U} \u2501\u2501\u2501\x1B[0m`)}let A=await n(J,{apiKey:z,model:W.model,maxTokens:W.maxTokens,systemPrompt:X,tools:Y,permissionMode:W.permissionMode,workingDirectory:process.cwd(),gitStatus:K,extendedThinking:R,onText:(U)=>{process.stdout.write(U)},onThinking:(U)=>{process.stdout.write(`\x1B[90m${U}\x1B[0m`)},onMetrics:async(U)=>{console.log(`
120
+ \x1B[90m${i(U)}\x1B[0m`),await Q.saveMetrics(U)}}),b=A.messages[A.messages.length-1];if(b&&b.role==="assistant")await Q.saveMessage(b);if(q+=A.totalCost,J.length=0,J.push(...A.messages),E&&!x){let U=[...J].reverse().find((H)=>H.role==="assistant");if(U){let H=U.content;if((Array.isArray(H)?H.filter((B)=>B.type==="text").map((B)=>B.text).join(" "):String(H)).includes("TASKS_COMPLETE")){console.log(`
121
+ \x1B[32m\u2713 Model signaled TASKS_COMPLETE - all work done\x1B[0m`),x=!0;break}}let N=T?"Continue working on the original task. If fully complete, respond with 'TASKS_COMPLETE'.":`Autonomous check #${_}: Scan for additional productive work in this codebase.
122
+
123
+ Look for:
124
+ - TODOs, FIXMEs, or incomplete code
125
+ - Failing or missing tests
126
+ - Outdated documentation
127
+ - Dependencies that could be updated
128
+ - Code quality improvements (typos, dead code, etc.)
129
+ - Security issues or vulnerabilities
130
+ - Performance optimizations
131
+ - Missing error handling
132
+
133
+ Use your tools (Glob, Grep, Read, Bash) to actively search. Do not guess or hallucinate - investigate.
134
+
135
+ If you find productive work, do it. If nothing productive remains, respond with exactly: TASKS_COMPLETE`;J.push({role:"user",content:[{type:"text",text:N}]})}else break}if(E)if(x)console.log(`
136
+ \x1B[32m\u2713 Autonomous loop completed after ${_} iteration(s)\x1B[0m`);else console.log(`
137
+ \x1B[33m\u2713 Loop ended after ${_} iteration(s)\x1B[0m`);console.log(`
138
+ \x1B[90mSession: ${L}\x1B[0m`),console.log(`\x1B[90mTotal cost: ${p(q)}\x1B[0m`)}catch(A){let b=A instanceof Error?A.message:String(A);console.error(`Error: ${b}`),process.exit(1)}}async function YW(z){let W=`You are Claude Code, an AI coding assistant created by Anthropic.
120
139
 
121
140
  You help users with software engineering tasks:
122
141
  - Reading, writing, and editing code
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ebowwa/coder",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "AI coding assistant CLI with extended thinking and teammate mode",
5
5
  "author": "ebowwa",
6
6
  "license": "MIT",