@burtson-labs/bandit-stealth-cli 1.7.244 → 1.7.245
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +3 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -152,7 +152,7 @@ ${s}
|
|
|
152
152
|
`).filter(O=>O.length>0).length;return`<tool_result name="${c}">[earlier run, ${P} lines elided \u2014 summary: ${S}]</tool_result>`}t(ktt,"summarizeToolResult");function fBt(a,s={}){let c=s.tokenBudget??sBt,_=s.keepRecentToolResults??oBt,u=s.charsPerToken??cBt,y=a.reduce((ge,Te)=>ge+sV(Te.content,u),0);if(y<=c)return{compacted:a,beforeTokens:y,afterTokens:y,messagesCompacted:0};let S=[];for(let ge=0;ge<a.length;ge++)uBt(a[ge])&&S.push(ge);let P=Math.min(S.length,_),O=S.slice(0,S.length-P),L=new Set,z=y;for(let ge of O){if(z<=c)break;let Te=a[ge].content,dt=ktt(Te);z-=sV(Te,u),z+=sV(dt,u),L.add(ge)}let Z=[],q=0;for(let ge=0;ge<a.length;ge++)L.has(ge)?(Z.push({role:a[ge].role,content:ktt(a[ge].content)}),q++):Z.push(a[ge]);let ye=Z.reduce((ge,Te)=>ge+sV(Te.content,u),0);if(ye>c){let ge=new Set,Te=Z.findIndex(mt=>mt.role==="user");Z.forEach((mt,bt)=>{mt.role==="system"&&ge.add(bt)});let dt=Te+1;for(;ye>c&&dt<Z.length-2;){if(ge.has(dt)){dt++;continue}let mt=sV(Z[dt].content,u);Z.splice(dt,1),ye-=mt,q++}}return{compacted:Z,beforeTokens:y,afterTokens:ye,messagesCompacted:q}}t(fBt,"compactToolMessages")});var xtt=Nt(oV=>{"use strict";Object.defineProperty(oV,"__esModule",{value:!0});oV.ToolUseLoop=void 0;oV.createToolUseLoop=pBt;var Wk=cEe(),_Bt=uEe();function dBt(a){let s=a.params??{},c=[s.content,s.replace,s.find,s.text].filter(_=>typeof _=="string"&&_.length>0).reduce((_,u)=>_+u.length,0);return Math.ceil(c/4)}t(dBt,"estimateToolCallOutputTokens");var use=class{static{t(this,"ToolUseLoop")}constructor(s,c,_={}){this.registry=s,this.ctx=c,this.defaultOptions=_,this.maxIterations=_.maxIterations??10,this.defaultEmit=_.emitEvent??(()=>{}),this.defaultBeforeToolExecute=_.beforeToolExecute??(()=>({allow:!0}))}async run(s,c,_,u){return this.runWithMessages([{role:"user",content:s}],c,_,u)}async runWithMessages(s,c,_,u){let y={...this.defaultOptions,...u},S=y.emitEvent??this.defaultEmit,P=y.maxIterations??this.maxIterations,O=y.beforeToolExecute??this.defaultBeforeToolExecute,L=y.signal,z=Math.max(1,y.maxParallelTools??8),Z=Math.max(1,y.maxTotalTools??60),q=y.outputBudgetTokens??1/0,ye=y.outputBudgetRatio??.6,ge=0,Te=t((wf,Ry,Am="")=>({finalResponse:Am||"[cancelled]",iterations:Ry,messages:wf,hitLimit:!1,cancelled:!0}),"buildCancelledResult"),dt=y.nativeTools??!1,mt=dt?"":this.registry.buildSystemPromptBlock(),bt=_?mt?`${_}
|
|
153
153
|
|
|
154
154
|
${mt}`:_:mt,Wt=dt?this.registry.buildNativeToolsSchema():void 0,Tt=[];bt&&Tt.push({role:"system",content:bt});let Bt="",Et=0;for(let wf of s)wf.role==="user"&&typeof wf.content=="string"&&wf.content.trim()&&(Bt&&Et++,Bt=wf.content);let Kt=-1,bn=4;for(let wf of s)wf.role!=="system"&&Tt.push(wf);let mr=0,xn=!1,Xr=0,_a=0,fi=0,Nr=2,ga=2,xa=!1,ur,Ms=[],Wa=2,jo=!1,En=[],no=3,gl=0,xu=3,Yo=!1,Xi=-1,qf=0,_s=!1,ds=3,Pi=2,Nc=!1,To=!1;{let wf=s.filter(Ry=>Ry.role==="user").map(Ry=>Ry.content).join(`
|
|
155
|
-
`).toLowerCase();Nc=/\b(update|edit|change|fix|modify|refactor|rewrite|replace|add)\b/.test(wf)||/[\w\-./]+\.(?:ts|tsx|js|jsx|py|rb|go|rs|java|kt|cs|swift|php|cpp|c|h|md|json|ya?ml|html|css)\b/.test(wf),To=/\b(evaluate|review|analy[sz]e|audit|inspect|investigate|explain|summari[sz]e|describe|tell\s+me|find\s+out|self[-\s]?eval(?:uat(?:e|ion))?)\b/i.test(wf)||/\b(what(?:'s|\s+is|\s+are)|how\s+does|why\s+does|where\s+does)\b/i.test(wf)||/\blook(?:ing)?\s+at\b/i.test(wf)}let vt=0,Dr=!1,Lr=!1,ps=!1,au=!1,Im=!1,ch=!1,ug=[/in (?:my|a|the) previous response/i,/already provided (?:the|an?) (?:implementation|refactored|improved|updated)/i,/you can find (?:the |this )?(?:refactored|improved|updated) (?:code|implementation)/i,/here (?:is|'s) the (?:refactored|improved|updated|revised) (?:code|implementation|file)/i,/(?:i have|i've) (?:refactored|rewritten|updated|improved)/i,/(?:refactored|updated) (?:the )?(?:code|implementation) above/i,/i'll finalize the task here/i,/i've also marked (?:the tasks|these steps) as complet/i,/i apologi[sz]e for the (?:malformed|invalid)/i,/(?:ensure|escape) (?:all )?(?:quotes|newlines|characters).*(?:properly )?escap/i,/in my next tool call/i,/let me know (?:which|what) (?:task|action) (?:i should |to )?resume/i,/please (?:let me know|tell me).*(?:specific action|which task|what.*like me to)/i,/here (?:is|'s) the (?:final|resulting|updated|modified) (?:state|version|content|output) of/i,/(?:comments?|changes?|edits?|annotations?|updates?) (?:have )?been (?:added|made|applied|written|included)/i,/you can verify (?:these|the|your) (?:changes?|edits?|updates?)/i,/check(?:ing)? the files? (?:directly )?in your editor/i,/running (?:a )?build to (?:see|verify|check)/i];for(;;){if(L?.aborted)return S("tool_loop:cancelled",{iteration:mr,stage:"pre_iteration"}),Te(Tt,mr);let wf=Bt?`## ORIGINAL USER GOAL \u2014 answer THIS, not whatever feels salient in recent reads:
|
|
155
|
+
`).toLowerCase();Nc=/\b(update|edit|change|fix|modify|refactor|rewrite|replace|add)\b/.test(wf)||/[\w\-./]+\.(?:ts|tsx|js|jsx|py|rb|go|rs|java|kt|cs|swift|php|cpp|c|h|md|json|ya?ml|html|css)\b/.test(wf),To=/\b(evaluate|review|analy[sz]e|audit|inspect|investigate|explain|summari[sz]e|describe|tell\s+me|find\s+out|self[-\s]?eval(?:uat(?:e|ion))?)\b/i.test(wf)||/\b(what(?:'s|\s+is|\s+are)|how\s+does|why\s+does|where\s+does)\b/i.test(wf)||/\blook(?:ing)?\s+at\b/i.test(wf)}let vt=0,Dr=!1,Lr=!1,ps=!1,au=!1,Im=!1,ch=!1,ug=[/in (?:my|a|the) previous response/i,/already provided (?:the|an?) (?:implementation|refactored|improved|updated)/i,/you can find (?:the |this )?(?:refactored|improved|updated) (?:code|implementation)/i,/here (?:is|'s) the (?:refactored|improved|updated|revised) (?:code|implementation|file)/i,/(?:i have|i've) (?:refactored|rewritten|updated|improved)/i,/(?:refactored|updated) (?:the )?(?:code|implementation) above/i,/i'll finalize the task here/i,/i've also marked (?:the tasks|these steps) as complet/i,/i apologi[sz]e for the (?:malformed|invalid)/i,/(?:ensure|escape) (?:all )?(?:quotes|newlines|characters).*(?:properly )?escap/i,/in my next tool call/i,/let me know (?:which|what) (?:task|action) (?:i should |to )?resume/i,/please (?:let me know|tell me).*(?:specific action|which task|what.*like me to)/i,/here (?:is|'s) the (?:final|resulting|updated|modified) (?:state|version|content|output) of/i,/(?:comments?|changes?|edits?|annotations?|updates?) (?:have )?been (?:added|made|applied|written|included)/i,/you can verify (?:these|the|your) (?:changes?|edits?|updates?)/i,/check(?:ing)? the files? (?:directly )?in your editor/i,/running (?:a )?build to (?:see|verify|check)/i,/(?:i have|i've)\s+(?:successfully\s+)?(?:eliminated|resolved|removed|cleaned|cleared|deleted|wiped|converted|wrapped|implemented|completed|finished)/i,/(?:the project|the codebase|the file|the code) is now (?:in a (?:healthy|clean|working|fixed) state|fixed|complete|done|ready)/i,/(?:verified|confirmed) (?:via|with|by running)\s+(?:the\s+)?(?:linter|tests?|build|tsc|eslint)/i,/(?:critical errors?|lint(?:ing)? errors?|warnings?|issues?) (?:dropped|went|reduced) (?:from\s+)?\d+\+?\s*(?:to|→)\s*\d+/i,/successfully\s+(?:fixed|resolved|removed|eliminated|cleaned|converted|implemented|verified|completed|applied|updated|patched)/i];for(;;){if(L?.aborted)return S("tool_loop:cancelled",{iteration:mr,stage:"pre_iteration"}),Te(Tt,mr);let wf=Bt?`## ORIGINAL USER GOAL \u2014 answer THIS, not whatever feels salient in recent reads:
|
|
156
156
|
|
|
157
157
|
"${Bt.trim()}"
|
|
158
158
|
|
|
@@ -180,7 +180,7 @@ No more tool calls. Close the turn.`}));let Db=y.messageTokenBudget,r2=!1;if(Db!
|
|
|
180
180
|
Rules:
|
|
181
181
|
- Use what you have gathered to answer the goal above.
|
|
182
182
|
- Do not pivot to a related topic that happens to be salient in recent tool results.${Cf}
|
|
183
|
-
- If the available tools cannot finish the goal, own that honestly in your final answer \u2014 do NOT redirect to an easier question.`})}}let tn=Tt.reduce((la,bi)=>la+(bi.content?.length??0),0),Ib=Tt.filter(la=>la.role==="system").reduce((la,bi)=>la+(bi.content?.length??0),0),G6=Date.now();S("tool_loop:llm_start",{iteration:mr,messageCount:Tt.length,promptCharsTotal:tn,systemPromptChars:Ib,thinkOverride:ur});let _i=ur!==void 0?{think:ur}:void 0;ur=void 0;let sc=await this.streamAndAggregate(c,Tt,S,mr,Wt,L,_i);if(S("tool_loop:llm_response",{iteration:mr,response:sc.slice(0,2e3),responseLength:sc.length,hasToolCallMarkup:sc.includes("<tool_call>")||/```\s*tool_call\b/.test(sc),endsWithFenceClose:/```\s*$/.test(sc.trimEnd()),llmDurationMs:Date.now()-G6}),L?.aborted)return S("tool_loop:cancelled",{iteration:mr,stage:"post_stream"}),Te(Tt,mr,sc);if(!xn&&/<tool_result\b[\s\S]*?<\/tool_result\s*>|<tool_result\b[^<]*$/i.test(sc)&&fi<ga){fi++,S("tool_loop:fake_tool_result_detected",{iteration:mr,preview:sc.slice(0,200)});let la=sc.replace(/<tool_result\b[\s\S]*?<\/tool_result\s*>/gi,"").replace(/<tool_result\b[^<]*$/i,"").trim();Tt.push({role:"assistant",content:la}),Tt.push({role:"user",content:'You emitted a `<tool_result>` envelope in your response. Those envelopes are SYSTEM output \u2014 they appear BETWEEN your turns, never inside your own message. If you meant to invoke a tool, emit a single `<tool_call>{"name":"...","params":{...}}</tool_call>` and wait for the real result. If the task is complete, give a plain-prose final answer with no XML envelopes. Retry now.'});continue}let Li=/```bandit-(?:tl|run|subagent)\b[\s\S]*?```/gi,Gi=/```bandit-(?:tl|run|subagent)\b[\s\S]*$/i,Rs=Li.test(sc)||Gi.test(sc),za=/<tool_call\b/i.test(sc);if(!xn&&Rs&&!za&&fi<ga){fi++,S("tool_loop:fake_tool_result_detected",{iteration:mr,preview:sc.slice(0,200),shape:"bandit-tl"});let la=sc.replace(/```bandit-(?:tl|run|subagent)\b[\s\S]*?```/gi,"").replace(/```bandit-(?:tl|run|subagent)\b[\s\S]*$/i,"").trim();Tt.push({role:"assistant",content:la}),Tt.push({role:"user",content:'You emitted `\u200A```bandit-tl` (or `bandit-run` / `bandit-subagent`) fenced JSON in your response. Those fences are emitted by the EXTENSION HOST to log real tool execution \u2014 you CANNOT produce them. They show up in your context because the host logged actual tool calls, not because you can fabricate them. To actually run a tool, emit `<tool_call>{"name":"...","params":{...}}</tool_call>` and wait for the real result.
|
|
183
|
+
- If the available tools cannot finish the goal, own that honestly in your final answer \u2014 do NOT redirect to an easier question.`})}}let tn=Tt.reduce((la,bi)=>la+(bi.content?.length??0),0),Ib=Tt.filter(la=>la.role==="system").reduce((la,bi)=>la+(bi.content?.length??0),0),G6=Date.now();S("tool_loop:llm_start",{iteration:mr,messageCount:Tt.length,promptCharsTotal:tn,systemPromptChars:Ib,thinkOverride:ur});let _i=ur!==void 0?{think:ur}:void 0;ur=void 0;let sc=await this.streamAndAggregate(c,Tt,S,mr,Wt,L,_i);if(S("tool_loop:llm_response",{iteration:mr,response:sc.slice(0,2e3),responseLength:sc.length,hasToolCallMarkup:sc.includes("<tool_call>")||/```\s*tool_call\b/.test(sc),endsWithFenceClose:/```\s*$/.test(sc.trimEnd()),llmDurationMs:Date.now()-G6}),L?.aborted)return S("tool_loop:cancelled",{iteration:mr,stage:"post_stream"}),Te(Tt,mr,sc);if(!xn&&/<tool_result\b[\s\S]*?<\/tool_result\s*>|<tool_result\b[^<]*$/i.test(sc)&&fi<ga){fi++,S("tool_loop:fake_tool_result_detected",{iteration:mr,preview:sc.slice(0,200)});let la=sc.replace(/<tool_result\b[\s\S]*?<\/tool_result\s*>/gi,"").replace(/<tool_result\b[^<]*$/i,"").trim();Tt.push({role:"assistant",content:la}),Tt.push({role:"user",content:'You emitted a `<tool_result>` envelope in your response. Those envelopes are SYSTEM output \u2014 they appear BETWEEN your turns, never inside your own message. If you meant to invoke a tool, emit a single `<tool_call>{"name":"...","params":{...}}</tool_call>` and wait for the real result. If the task is complete, give a plain-prose final answer with no XML envelopes. Retry now.'});continue}let Li=/```bandit-(?:tl|run|subagent)\b[\s\S]*?```/gi,Gi=/```bandit-(?:tl|run|subagent)\b[\s\S]*$/i,Rs=Li.test(sc)||Gi.test(sc),za=/<tool_call\b/i.test(sc);if(!xn&&Rs&&!za&&fi<ga){fi++,S("tool_loop:fake_tool_result_detected",{iteration:mr,preview:sc.slice(0,200),shape:"bandit-tl"});let la=sc.replace(/```bandit-(?:tl|run|subagent)\b[\s\S]*?```/gi,"").replace(/```bandit-(?:tl|run|subagent)\b[\s\S]*$/i,"").trim();Tt.push({role:"assistant",content:la}),Tt.push({role:"user",content:'You emitted `\u200A```bandit-tl` (or `bandit-run` / `bandit-subagent`) fenced JSON in your response. Those fences are emitted by the EXTENSION HOST to log real tool execution \u2014 you CANNOT produce them. They show up in your context because the host logged actual tool calls, not because you can fabricate them. To actually run a tool, emit `<tool_call>{"name":"...","params":{...}}</tool_call>` and wait for the real result. Your fake fences mean NO work has happened this turn. You have TWO options for your retry, and ONLY two: (a) Emit a real `<tool_call>{"name":"...","params":{...}}</tool_call>` envelope NOW to actually do the work, then wait for the real result. (b) Honestly state "I have not [action] yet" and STOP. Do NOT claim completion. You MUST NOT claim you have fixed / eliminated / resolved / removed / cleaned / verified anything. No "successfully [verb]" phrasing. No numbered lists of "Step 1: I did X" actions. No "the project is now in a healthy state." Until a real `<tool_call>` lands on disk and returns a real tool-result, nothing has changed. Lying about completion is the worst failure mode. Retry now.'});continue}Tt.push({role:"assistant",content:sc});let Gs=sc.replace(/<think\b[\s\S]*?<\/think\s*>/gi,"").replace(/<think\b[\s\S]*$/i,"").replace(/```bandit-reasoning\b[\s\S]*?```/gi,"").replace(/```bandit-reasoning\b[\s\S]*$/i,"").trim(),$s=!Gs&&sc.trim().length>0,kl=/\b(use|uses|used|using|call|calls|called|calling|invoke|invokes|invoked|invoking|execute|executes|executed|executing|run|runs|running|ran|search|searches|searched|searching|look|looks|looked|looking|read|reads|reading|check|checks|checked|checking|find|finds|finding|found|list|lists|listed|listing|fetch|fetches|fetched|fetching|grep|greps|grepped|grepping|explore|explores|explored|exploring|locate|locates|located|locating)\b/i,ha=/\b(we (?:will|need to|should)|we'?ll|we'?re going to|i'?ll|i will|let me|let'?s|going to|i'?m going to|i need to)\b/i,y_=/```[a-zA-Z0-9_-]*\s*\n/.test(Gs),co=Gs.match(/(?:[.!?]\s+)([^.!?]*)$/),Ss=(co?co[1]:Gs).slice(-200),Jf=!(0,Wk.hasToolCalls)(sc)&&!y_&&Gs.length>0&&Gs.length<240&&ha.test(Ss)&&kl.test(Ss);if((!sc.trim()||$s||Jf)&&!xn&&Xr<2){Xr++,S("tool_loop:empty_retry",{iteration:mr,attempt:Xr,reasoningOnly:$s,narratedButNoAction:Jf});let la=Jf?`You announced your next step in prose ("we will search\u2026" / "let me check\u2026" / "use X to find Y") but did NOT emit a \`<tool_call>\` envelope. Announcing intent is not enough \u2014 you must actually invoke the tool. Emit the call now in this exact format, OUTSIDE of any reasoning block, with NO commentary and NO markdown fence:
|
|
184
184
|
|
|
185
185
|
<tool_call>{"name":"<tool>","params":{"<key>":"<value>"}}</tool_call>
|
|
186
186
|
|
|
@@ -1367,7 +1367,7 @@ ${(()=>{let Z=`Bandit insights \u2014 ${new Date(s).toISOString().slice(0,10)}`,
|
|
|
1367
1367
|
<h1>You're signed in.</h1>
|
|
1368
1368
|
<p>Bandit picked up your session. You can close this tab and return to your terminal.</p>
|
|
1369
1369
|
</div>
|
|
1370
|
-
</body></html>`;t(eTr,"startLoopbackListener");t(tTr,"openBrowser");t(rTr,"buildDefaultDeviceLabel");t(nTr,"runOAuthSignIn")});var Wue=Nt((pOr,iTr)=>{iTr.exports={name:"@burtson-labs/bandit-stealth-cli",version:"1.7.
|
|
1370
|
+
</body></html>`;t(eTr,"startLoopbackListener");t(tTr,"openBrowser");t(rTr,"buildDefaultDeviceLabel");t(nTr,"runOAuthSignIn")});var Wue=Nt((pOr,iTr)=>{iTr.exports={name:"@burtson-labs/bandit-stealth-cli",version:"1.7.245",description:"Bandit \u2014 a local-first AI coding agent for your terminal. Same runtime as the Bandit Stealth VS Code / Cursor extension.",keywords:["ai","agent","cli","coding-agent","llm","ollama","local-first","bandit","burtson-labs","terminal","repl","developer-tools"],homepage:"https://burtson.ai",bugs:{email:"team@burtson.ai"},license:"MIT",author:{name:"Burtson Labs",email:"team@burtson.ai",url:"https://burtson.ai"},bin:{bandit:"./dist/cli.js"},main:"dist/cli.js",files:["dist/cli.js","README.md","LICENSE"],engines:{node:">=20"},publishConfig:{access:"public"},scripts:{typecheck:"tsc -p tsconfig.json --noEmit",build:"node build.mjs","build:publish":"node build.mjs --publish",dev:"node build.mjs --watch",start:"node dist/cli.js",smoke:"node build.mjs && node dist/__smoke__/smoke.js",integration:"node build.mjs && node dist/__integration__/ollama.js",eval:"node build.mjs && node dist/__eval__/eval.js",benchmark:"node build.mjs && node dist/__eval__/benchmark.js","gen-logo":"node scripts/gen-logo.mjs","preview-banner":"node scripts/preview-banner.mjs",clean:"rm -rf dist",prepack:"node scripts/prepack.mjs",postpack:"node scripts/postpack.mjs",prepublishOnly:"pnpm run clean && pnpm run typecheck && pnpm run build:publish"},dependencies:{"pdf-parse":"^2.4.5"},devDependencies:{"@burtson-labs/agent-core":"workspace:*","@burtson-labs/host-kit":"workspace:*","@burtson-labs/stealth-core-runtime":"workspace:*","@types/node":"^20.11.0","@types/pdf-parse":"^1.1.5","@types/pngjs":"^6.0.5",esbuild:"^0.28.0",pngjs:"^7.0.0",typescript:"^5.4.0"}}});var jTr={};module.exports=Iet(jTr);var Dm=Su(require("fs")),Vue=Su(require("os")),tm=Su(require("path")),O9=Su(require("readline")),Zue=Su(require("child_process")),rm=Su(uZ()),S0=Su(wOe());var z6=Su(require("fs")),COe=Su(require("os")),lT=Su(require("path")),CZ=Su(require("child_process"));function v1(a){return a==="~"?COe.homedir():a.startsWith("~/")?lT.join(COe.homedir(),a.slice(2)):a}t(v1,"expandHome");var x9=16*1024,wZ=32*1024,h_t=1e4,j1r=3e4,POe=200,EOe=new Set(["node_modules",".git","dist","build","out",".next",".turbo","coverage","target","__pycache__",".venv","venv"]);function L1r(a){let s=t(_=>{let u=_.match(/^(.*?)\{([^}]+)\}(.*)$/);if(!u)return[_];let[,y,S,P]=u;return S.split(",").map(O=>`${y}${O.trim()}${P}`)},"braceExpand"),c=a.match(/^([^*{}]+?)\/\*\*\/(.+)$/);if(c){let[,_,u]=c;return{includes:s(u),subDir:_}}return{includes:s(a),subDir:""}}t(L1r,"expandGlobForGrep");var _M=class{constructor(s,c,_={}){this.workspaceRoot=s;this.languageAdapters=c;this.options=_;this._readFiles=new Set;this.customRepoRoots=_.customRepoRoots&&_.customRepoRoots.length>0?_.customRepoRoots:void 0}static{t(this,"CliToolExecutionContext")}markFileRead(s){this._readFiles.add(v1(s))}hasFileBeenRead(s){return this._readFiles.has(v1(s))}async readFile(s){return z6.promises.readFile(v1(s),"utf-8")}async writeFile(s,c){let _=v1(s);if(this.options.approveWrite&&!await this.options.approveWrite(_,c))throw new Error(`Write to ${_} rejected by user`);await z6.promises.mkdir(lT.dirname(_),{recursive:!0}),await z6.promises.writeFile(_,c,"utf-8")}async deleteFile(s){let c=lT.resolve(v1(s)),_=lT.resolve(this.workspaceRoot);if(!c.startsWith(_+lT.sep)&&c!==_)throw new Error(`Refusing to delete outside workspace: ${s}`);await z6.promises.unlink(c)}async listFiles(s,c){let _=v1(c??this.workspaceRoot),u=$1r(s),y=[];return await y_t(_,_,u,y),y.slice(0,POe).sort()}async listDirectoryEntries(s){let c=v1(s),_=await z6.promises.readdir(c,{withFileTypes:!0}),u=[];for(let y of _){if(y.name.startsWith("."))continue;let S=y.isDirectory();if(y.isSymbolicLink())try{S=(await z6.promises.stat(lT.join(c,y.name))).isDirectory()}catch{S=!1}u.push(S?`${y.name}/`:y.name)}return u.sort()}async searchCode(s,c,_){let u=v1(c??this.workspaceRoot);return this.runRipgrep(s,u,_).catch(()=>this.runGrep(s,u,_))}async runCommand(s,c,_){let u=c.map(v1),y=_?v1(_):this.workspaceRoot,S={...process.env};if((s.split(/[\\/]/).pop()??s)==="gh")for(let O of["GITHUB_TOKEN","GH_TOKEN"]){let L=S[O];typeof L=="string"&&L.trim()===""&&delete S[O]}return new Promise(O=>{let L="",z="",Z=CZ.spawn(s,u,{cwd:y,shell:process.platform==="win32",env:S}),q=setTimeout(()=>{Z.kill("SIGTERM"),O({stdout:L.slice(0,wZ),stderr:z+`
|
|
1371
1371
|
[process timed out]`,exitCode:124})},j1r),ye=process.stdout.isTTY===!0,ge=t((Te,dt)=>{if(!ye)return;(dt?process.stderr:process.stdout).write("\r\x1B[2K\x1B[2m"+Te+"\x1B[0m")},"writeLive");Z.stdout?.on("data",Te=>{let dt=Te.toString();L+=dt,ge(dt,!1),L.length>wZ&&Z.kill("SIGTERM")}),Z.stderr?.on("data",Te=>{let dt=Te.toString();z+=dt,ge(dt,!0)}),Z.on("close",Te=>{clearTimeout(q);let dt=L.slice(0,wZ);if(Te===0&&/Operation cancelled/i.test(dt)&&/(create-vite|create-react-app|create-next|create-svelte|create-astro|create-remix|@clack)/i.test(`${s} ${u.join(" ")} ${dt}`)){let bt=[s,...u].join(" ");O({stdout:dt,stderr:`Interactive scaffolder detected \u2014 \`${s}\` aborted with "Operation cancelled" because Bandit captures stdout/stderr (no TTY on stdin) and modern scaffolders refuse to start without one. Tell the user to run this directly in their shell: \`!${bt}\`. The \`!\`-prefix runs through their terminal with real stdin, so the scaffolder's prompts work. After they finish, you can pick up from the resulting filesystem state. Do NOT retry the same command \u2014 it will loop forever.`,exitCode:1});return}O({stdout:dt,stderr:z.slice(0,4*1024),exitCode:Te??0})}),Z.on("error",Te=>{if(clearTimeout(q),Te.code==="ENOENT"){O({stdout:"",stderr:`spawn ${s} ENOENT \u2014 '${s}' not found on PATH. Verify the tool is installed (\`which ${s}\` in a fresh terminal). If you use nvm/asdf/volta, your shim PATH may not be inherited; relaunching this CLI from the same terminal session that has \`${s}\` on PATH usually fixes it.`,exitCode:127});return}O({stdout:"",stderr:Te.message,exitCode:1})})})}async watchCommand(s,c,_,u){let y=c.map(v1),S=_?v1(_):this.workspaceRoot;return new Promise(P=>{let O="",L="",z=!1,Z=!1,q=CZ.spawn(s,y,{cwd:S,shell:process.platform==="win32",env:{...process.env}}),ye=t(mt=>{Z||(Z=!0,P({stdout:O.slice(0,wZ),stderr:L.slice(0,4*1024),exitCode:mt,endedEarly:z}))},"finish"),ge=setTimeout(()=>{try{q.kill("SIGTERM")}catch{}let mt=setTimeout(()=>{try{q.kill("SIGKILL")}catch{}ye(null)},1e3);q.once("close",bt=>{clearTimeout(mt),ye(typeof bt=="number"?bt:null)})},u),Te=process.stdout.isTTY===!0,dt=t((mt,bt)=>{if(!Te)return;(bt?process.stderr:process.stdout).write("\r\x1B[2K\x1B[2m"+mt+"\x1B[0m")},"writeLive");q.stdout?.on("data",mt=>{let bt=mt.toString();if(O+=bt,dt(bt,!1),O.length>wZ)try{q.kill("SIGTERM")}catch{}}),q.stderr?.on("data",mt=>{let bt=mt.toString();L+=bt,dt(bt,!0)}),q.on("close",mt=>{Z||(clearTimeout(ge),z=!0,ye(typeof mt=="number"?mt:null))}),q.on("error",mt=>{Z||(clearTimeout(ge),z=!0,L+=mt.message,ye(1))})})}runRipgrep(s,c,_){return new Promise((u,y)=>{let S=["--color=never","--line-number","--max-count=25","--max-filesize=1M",...[...EOe].map(z=>["--glob",`!${z}`]).flat()];_&&S.push("--glob",_),S.push(s,c);let P="",O=CZ.spawn("rg",S,{shell:!1}),L=setTimeout(()=>{O.kill("SIGTERM"),u(P.slice(0,x9))},h_t);O.stdout?.on("data",z=>{P+=z.toString(),P.length>x9&&O.kill("SIGTERM")}),O.on("close",z=>{clearTimeout(L),z!=null&&z>=2&&P.length===0?y(new Error(`rg exited with code ${z}`)):u(P.slice(0,x9))}),O.on("error",y)})}runGrep(s,c,_){return new Promise((u,y)=>{let S=[...EOe].map(ge=>["--exclude-dir",ge]).flat(),P=_?L1r(_):{includes:[],subDir:""},O=P.includes.flatMap(ge=>["--include",ge]),L=P.subDir?`${c}/${P.subDir}`:c,z=["-rn","-E","--color=never",...S,...O,s,L],Z="",q=CZ.spawn("grep",z,{shell:!1}),ye=setTimeout(()=>{q.kill("SIGTERM"),u(Z.slice(0,x9))},h_t);q.stdout?.on("data",ge=>{Z+=ge.toString(),Z.length>x9&&q.kill("SIGTERM")}),q.on("close",ge=>{clearTimeout(ye),ge!=null&&ge>=2&&Z.length===0?y(new Error(`grep exited with code ${ge}`)):u(Z.slice(0,x9))}),q.on("error",y)})}};function $1r(a){let s=B1r(a);return c=>s.test(c.replace(/\\/g,"/"))}t($1r,"compileGlob");function B1r(a){let s="^";for(let c=0;c<a.length;c++){let _=a[c];if(_==="*")a[c+1]==="*"?(s+=".*",c++,a[c+1]==="/"&&c++):s+="[^/]*";else if(_==="?")s+="[^/]";else if(_==="{"){let u=a.indexOf("}",c);if(u===-1){s+="\\{";continue}let y=a.slice(c+1,u).split(",").map(z1r).join("|");s+=`(?:${y})`,c=u}else/[.+^$()|\\]/.test(_)?s+="\\"+_:s+=_}return s+="$",new RegExp(s)}t(B1r,"globToRegex");function z1r(a){return a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}t(z1r,"escapeRegex");async function y_t(a,s,c,_){if(_.length>=POe)return;let u;try{u=await z6.promises.readdir(a,{withFileTypes:!0})}catch{return}for(let y of u){if(_.length>=POe)return;if(EOe.has(y.name))continue;let S=lT.join(a,y.name),P=lT.relative(s,S);y.isDirectory()?await y_t(S,s,c,_):y.isFile()&&c(P)&&_.push(S)}}t(y_t,"walk");var b_t=Su(require("child_process")),yE=Su(require("fs")),S_t=Su(require("os")),DOe=Su(require("path")),T_t=Su(require("crypto"));function IOe(){let a=T_t.randomBytes(4).toString("hex");return DOe.join(S_t.tmpdir(),`bandit-paste-${Date.now()}-${a}.png`)}t(IOe,"freshTempPath");function xue(a,s,c={}){try{let _=b_t.spawnSync(a,s,{...c,encoding:void 0});return{stdout:Buffer.isBuffer(_.stdout)?_.stdout:Buffer.from(_.stdout??""),code:_.status}}catch{return{stdout:Buffer.alloc(0),code:null}}}t(xue,"tryExec");async function wue(){return process.platform==="darwin"?U1r():process.platform==="linux"?q1r():process.platform==="win32"?J1r():null}t(wue,"readClipboardImage");function U1r(){let a=IOe(),s=`set pngData to (the clipboard as \xABclass PNGf\xBB)
|
|
1372
1372
|
set outFile to (open for access (POSIX file "${a}") with write permission)
|
|
1373
1373
|
write pngData to outFile
|
package/package.json
CHANGED