@burtson-labs/bandit-stealth-cli 1.7.363 → 1.7.364
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 +2 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -228,7 +228,7 @@ Replace name/params with the right values for your task. Or, if the task is alre
|
|
|
228
228
|
<tool_call>{"name":"<tool>","params":{"<key>":"<value>"}}</tool_call>
|
|
229
229
|
|
|
230
230
|
No prose around it, no markdown fence, just the bare tag. If the task is answerable without a tool, write a complete final answer instead. Do not stop after only thinking.`:'Your previous response was empty. Either emit a `<tool_call>{"name":"<tool>","params":{...}}</tool_call>` to invoke a tool, OR produce a complete final answer using what you have. Do not respond with an empty message.';Sn.push({role:"user",content:Pt});continue}let il=Oh||!wc.trim();if(!aa&&il&&no>=1&&!er){er=!0,no=0,qs=!1,v("tool_loop:thinking_off_recovery",{iteration:cn,reason:"reasoning_only_cap_exhausted"}),Sn.push({role:"user",content:"Switching to non-thinking mode for this attempt because reasoning-only retries exhausted. Emit either a tool_call or a complete final answer. No more reasoning preamble."});continue}if(!aa&&il&&er&&!Pu){Pu=!0,no=0,qs=!1,hc='<tool_call>{"name":"',v("tool_loop:prefill_recovery",{iteration:cn,prefix:hc}),Sn.push({role:"assistant",content:hc});continue}if(no=0,!aa&&(0,_1.looksLikeAttemptedToolCall)(wc)&&!(0,_1.hasToolCalls)(wc)&&co<mo){co++,v("tool_loop:parse_retry",{iteration:cn,attempt:co});let Pt=co===1;Sn.push({role:"user",content:Pt?'Your previous tool_call was not valid JSON \u2014 I could not parse it. Common cause: unescaped `"` characters inside a string value (for example `["", "", ""]` inside a `content` string). Retry the tool call with properly escaped JSON: every `"` inside a string value must be written as `\\"`, and every newline as `\\n`. If the content is very long, consider `replace_range` for a line-numbered block or breaking the change into smaller edits.':"Your tool_call still did not parse. Do NOT retry with the same shape or the same escaping failure. Switch tactics: (a) call `replace_range` for a large block whose line numbers you just read, (b) call `write_file` for a new file, or (c) split the change into multiple small `apply_edit` calls that each target just one method or block (e.g. 3-5 lines of `find`, 5-10 lines of `replace`) instead of rewriting the whole class. Pick the smallest scope that accomplishes the next step. If you cannot produce a valid tool call, respond with a plain-prose final answer acknowledging you could not complete the edit."});continue}if(!aa&&!(0,_1.hasToolCalls)(wc)){let Pt=wc.toLowerCase().replace(/\s+/g," ").trim(),Jt=Pa[Pa.length-1],En=!!Jt&&(()=>{let di=Jt.length<Pt.length?Jt:Pt,Ga=Jt.length<Pt.length?Pt:Jt,ms=0;for(;ms<di.length&&di[ms]===Ga[ms];)ms++;return ms/di.length>.6})(),Cr=(Pt.match(/wait,? i see/g)??[]).length,Lr=(Pt.match(/actually,? i'?ll/g)??[]).length,ni=Cr>=3&&Lr>=3,Or=wc.includes("[stream aborted: self-contradicting prose loop detected]");if(!gr&&(En||ni||Or)){gr=!0,v("tool_loop:prose_loop_nudge",{iteration:cn,responsePreview:wc.slice(0,200),reason:Or?"stream_abort":ni?"self_contradict":"cross_iteration_similarity"}),Sn.push({role:"user",content:'STOP deliberating. Your last response either repeated itself, contradicted itself (e.g. "Wait, I see X / Actually I\'ll try X"), or was aborted mid-stream as a loop. Do NOT continue speculating about what files might exist. Take exactly one of these actions now: (a) invoke a tool (`list_files`, `read_file`, `search_code`, etc.) to answer the question with real data, OR (b) give up and tell the user plainly that you could not complete the task and why. Do not write more than two sentences of prose before either calling a tool or terminating.'}),Pa.length=0;continue}Pa.push(Pt),Pa.length>ca&&Pa.shift()}else Pa.length=0;if(!aa&&!(0,_1.hasToolCalls)(wc)&&!Kc){let Pt=/```json\s*\n([\s\S]*?)```/i,Jt=wc.match(Pt);if(Jt)try{let En=JSON.parse(Jt[1].trim());if(Array.isArray(En)&&En.length>0&&En.every(Cr=>Cr&&typeof Cr=="object"&&typeof Cr.content=="string")){Kc=!0,v("tool_loop:json_todo_auto_promoted",{iteration:cn,itemCount:En.length});let Cr=this.registry.get("todo_write");if(Cr){let Lr={name:"todo_write",params:{items:JSON.stringify(En)},raw:`<tool_call>{"name":"todo_write","params":{"items":${JSON.stringify(JSON.stringify(En))}}}</tool_call>`};v("tool_loop:tool_execute",{name:"todo_write",params:Lr.params,rawSnippet:Lr.raw.slice(0,400)});try{let ni=await Cr.execute(Lr.params,this.ctx);v("tool_loop:tool_result",{name:"todo_write",isError:ni.isError,outputLength:ni.output.length,outputSnippet:(0,_1.applySecretRedactionIfEnabled)(ni.output.slice(0,280)),outputFull:(0,_1.applySecretRedactionIfEnabled)(ni.output.slice(0,65536))}),Sn.push({role:"user",content:(0,_1.buildToolResultsMessage)([{name:"todo_write",output:ni.output,isError:ni.isError}])})}catch(ni){let Or=ni instanceof Error?ni.message:String(ni);v("tool_loop:tool_error",{name:"todo_write",error:Or}),Sn.push({role:"user",content:(0,_1.buildToolResultsMessage)([{name:"todo_write",output:`Error: ${Or}`,isError:!0}])})}Sn.push({role:"user",content:'Note: I detected a JSON todo list in your response and auto-promoted it to a todo_write call. Next time, emit `<tool_call>{"name":"todo_write","params":{"items":"..."}}</tool_call>` directly instead of pasting JSON as a code block \u2014 pasted JSON does not update your plan, only the tool call does.'}),cn++;continue}}}catch{}}if(aa||!(0,_1.hasToolCalls)(wc)){(0,_1.hasFabricatedToolResult)(wc)&&v("tool_loop:hallucinated_tool_result",{iteration:cn,responsePreview:wc.slice(0,300)});let Pt=(0,_1.stripToolCallMarkup)(wc).trim();if(!aa&&!Hs&&Ur===0&&kg.some(Or=>Or.test(Pt))){Hs=!0,v("tool_loop:false_completion_nudge",{iteration:cn,responsePreview:Pt.slice(0,200)}),Sn.push({role:"user",content:'Your response either claims work is done OR apologizes and asks what to do next \u2014 but I see NO successful `write_file`, `apply_edit`, `replace_range`, or `apply_patch` tool call in this turn, so nothing on disk has changed. Do NOT ask the user which task to resume, do NOT promise to escape JSON "in your next tool call", and do NOT defer. Either (a) emit a real edit tool call NOW with the actual change \u2014 use `replace_range` for a large block whose line numbers you just read, `apply_edit` for a small exact replacement, or `write_file` for a new file \u2014 or (b) respond honestly that you could not complete the task and briefly explain why. Retry the tool call yourself; the user cannot help you escape JSON.'});continue}if(!aa&&!Hs&&Ur>0){let ni=/[`"']?([\w./\\-]+\.(?:cs|ts|tsx|js|jsx|mjs|cjs|py|rb|go|rs|java|kt|swift|cpp|cc|c|h|hpp|md|json|ya?ml|html|css|scss|sql|toml|sh|bash))[`"']?/gi,Or=new Set,di;for(;(di=ni.exec(Pt))!==null;){let Ga=di[1].split(/[/\\]/),ms=Ga[Ga.length-1].toLowerCase();Or.add(ms)}if(Or.size>Ur){Hs=!0,v("tool_loop:partial_completion_nudge",{iteration:cn,editToolsInvoked:Ur,claimedFiles:Or.size,responsePreview:Pt.slice(0,200)}),Sn.push({role:"user",content:`Your response describes edits to ${Or.size} files (${[...Or].slice(0,8).join(", ")}${Or.size>8?", \u2026":""}), but only ${Ur} successful edit${Ur===1?"":"s"} actually fired this turn. The remaining ${Or.size-Ur} file(s) were NOT modified \u2014 nothing landed on disk for them. Either (a) emit the missing \`apply_edit\` / \`replace_range\` / \`write_file\` tool calls now to actually do the work, OR (b) revise your response to honestly describe ONLY the edits that successfully applied. Do not summarize work that did not happen.`});continue}}let Jt=/\b(refactor|refactoring|break\s+(?:out|up|apart|into)|split\s+(?:out|up|into|apart)|extract|extracting|migrate|migrating|move\s+(?:out\s+of|from|into)|reorganize|reorganizing|restructure|restructuring|consolidate|consolidating)\b/i;if(!aa&&!xo&&Ur>0&&ha.size>0&&Yt&&Jt.test(Yt)){let ni=[...ha].filter(Or=>!la.has(Or));if(ni.length===ha.size){xo=!0,v("tool_loop:subject_not_modified_nudge",{iteration:cn,readNotWritten:ni.slice(0,4),writtenCount:la.size});let Or=ni.slice(0,3).join(", "),di=la.size;Sn.push({role:"user",content:`The user's goal contains a refactor verb (refactor/break out/split/extract/move) which implies the SOURCE file(s) should be modified, not just supplemented with new siblings. You read ${Or}${ni.length>3?" and others":""} for context, then wrote ${di} NEW file(s), but you NEVER modified the file(s) you read. The refactor is incomplete: the source file still contains the old monolithic code. Emit the missing apply_edit/replace_range/write_file call on the source file now \u2014 it should import from the new files and drop the inlined code that's been extracted. If the refactor is genuinely a "scaffold only, leave source untouched" task, say so explicitly and explain why the source doesn't need to change.`});continue}}if(!aa&&!Ja&&Ur===0&&vu){let ni=/```[a-zA-Z0-9_-]*\n([\s\S]*?)```/g,di=0,Ga;for(;(Ga=ni.exec(Pt))!==null;){let ms=Ga[1].split(`
|
|
231
|
-
`).filter(ao=>ao.trim().length>0).length;ms>di&&(di=ms)}if(di>=8){Ja=!0,v("tool_loop:code_fence_nudge",{iteration:cn,fenceLines:di,responsePreview:Pt.slice(0,200)}),Sn.push({role:"user",content:"You produced a substantial code block in your reply but never emitted a `write_file`, `apply_edit`, `replace_range`, or `apply_patch` tool call \u2014 so the change is NOT on disk. Do not ask the user to paste your code into a file themselves. Take exactly one of these actions now: (a) call `replace_range`, `apply_edit`, or `write_file` with the real change to the correct file, OR (b) say plainly that you could not locate the target file and explain what you searched for. Do not wrap up with another prose + code-fence response."});continue}}if(!aa&&!os&&!Hs&&Pt){let ni=Pt.replace(/```bandit-reasoning\b[\s\S]*?```/gi,"").replace(/```bandit-reasoning\b[\s\S]*$/i,"").replace(/<think\b[\s\S]*?<\/think\s*>/gi,"").replace(/<think\b[\s\S]*$/i,"").trim();if(ni&&ni.length<=600){let Or=ni.slice(0,240).toLowerCase(),di=/^(?:next,?\s+|now,?\s+|then,?\s+)?(?:let me|let us|let'?s|i(?:'ll| will| am going to| 'm going to| 'm about to| should))\s+(?:dig|continue|explore|investigate|check|look|read|inspect|analyze|examine|review|verify|find|search|trace|walk|drill|keep|move on)/,Ga=new RegExp("^(?:next,?\\s+|now,?\\s+|then,?\\s+)?(?:i(?:'m| am)\\s+on it|i(?:'m| am)\\s+(?:currently\\s+|now\\s+)?\\w+ing|i(?:'ve| have)\\s+(?:already\\s+)?(?:started|begun|kicked off)|i(?:'ll| will)\\s+(?:keep|continue)\\b)");if(di.test(Or)||Ga.test(Or)){os=!0,v("tool_loop:announce_intent_nudge",{iteration:cn,responsePreview:ni.slice(0,240)}),Sn.push({role:"user",content:'Your response announces an action ("Let me X", "I\'ll Y next") but emits NO tool call \u2014 so the loop will exit and the user only sees your announcement, not the result. Take the action now: emit the `read_file`, `search_code`, `list_files`, `run_command`, or other tool call you just described. If you have nothing more to investigate, write a complete final answer instead \u2014 do not announce future work without doing it.'});continue}}}if(!aa&&!kl&&!Hs&&Pt&&this.registry.get("ask_user")){let ni=Pt.replace(/```bandit-reasoning\b[\s\S]*?```/gi,"").replace(/```bandit-reasoning\b[\s\S]*$/i,"").replace(/<think\b[\s\S]*?<\/think\s*>/gi,"").replace(/<think\b[\s\S]*$/i,"").trim(),Or=ni.slice(-320).toLowerCase(),di=/(shall i|should i|do you want me to|would you like me to|want me to (?:proceed|continue|go ahead)|which (?:option|approach|one)|proceed with the|go ahead with|or were you looking|or do you want|let me know (?:if|which|whether))/;if(/\?\s*$/.test(ni)&&di.test(Or)){kl=!0,v("tool_loop:ask_user_nudge",{iteration:cn,responsePreview:ni.slice(-240)}),Sn.push({role:"user",content:'You asked the user to choose or approve, but you did it in prose and the loop is exiting \u2014 they get a passive question, not an interactive prompt. Call the `ask_user` tool now: pose the question with 2\u20134 concrete options (put the recommended one first and append " (Recommended)"). Do not ask for a decision in plain prose when ask_user is available.'});continue}}if(m.isSubagent&&cn===0&&!yp&&!os&&!Hs&&!aa){yp=!0,v("tool_loop:subagent_first_iter_no_tool_call",{iteration:cn,responsePreview:Pt.slice(0,240)}),Sn.push({role:"user",content:'Your first response had reasoning but emitted NO tool call \u2014 that is a hard stall for a subagent (you exist to gather information; reasoning alone produces zero output). For your next response, emit a tool call. The minimum viable starting move for ANY exploration goal is:\n\n<tool_call>{"name":"list_files","params":{"path":"."}}</tool_call>\n\nCopy that exact envelope as the very first thing you emit (you may keep the reasoning block before it if your model needs to think first, but the tool_call envelope MUST appear in this turn). Substitute a different tool only if it\'s obviously better for the goal \u2014 `read_file` for "what does file X look like", `search_code` for "where is symbol Y", `run_command` for shell output. Do NOT respond with reasoning only again. The next message you send must contain a real <tool_call> envelope.'});continue}let En=wc.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();if(!(0,_1.stripToolCallMarkup)(En).trim()){let Or=(wc.match(/<think\b[\s\S]*?<\/think\s*>/gi)?.pop()??wc.match(/```bandit-reasoning\b[\s\S]*?```/gi)?.pop()??wc).replace(/<\/?think[^>]*>/gi,"").replace(/```bandit-reasoning\s*\n?|```/g,"").trim(),Ga=(Or.match(/[^.!?]+[.!?]/g)??[Or]).slice(-2).join(" ").trim().slice(-280);return{finalResponse:`[Bandit stalled after reasoning without emitting a tool call \u2014 the model thought through the next step but never committed to an action. Last reasoning: "${Ga}${Ga.length===280?"\u2026":""}"
|
|
231
|
+
`).filter(ao=>ao.trim().length>0).length;ms>di&&(di=ms)}if(di>=8){Ja=!0,v("tool_loop:code_fence_nudge",{iteration:cn,fenceLines:di,responsePreview:Pt.slice(0,200)}),Sn.push({role:"user",content:"You produced a substantial code block in your reply but never emitted a `write_file`, `apply_edit`, `replace_range`, or `apply_patch` tool call \u2014 so the change is NOT on disk. Do not ask the user to paste your code into a file themselves. Take exactly one of these actions now: (a) call `replace_range`, `apply_edit`, or `write_file` with the real change to the correct file, OR (b) say plainly that you could not locate the target file and explain what you searched for. Do not wrap up with another prose + code-fence response."});continue}}if(!aa&&!os&&!Hs&&Pt){let ni=Pt.replace(/```bandit-reasoning\b[\s\S]*?```/gi,"").replace(/```bandit-reasoning\b[\s\S]*$/i,"").replace(/<think\b[\s\S]*?<\/think\s*>/gi,"").replace(/<think\b[\s\S]*$/i,"").trim();if(ni&&ni.length<=600){let Or=ni.slice(0,240).toLowerCase(),di=/^(?:next,?\s+|now,?\s+|then,?\s+)?(?:let me|let us|let'?s|i(?:'ll| will| am going to| 'm going to| 'm about to| should))\s+(?:dig|continue|explore|investigate|check|look|read|inspect|analyze|examine|review|verify|find|search|trace|walk|drill|keep|move on)/,Ga=new RegExp("^(?:next,?\\s+|now,?\\s+|then,?\\s+)?(?:i(?:'m| am)\\s+on it|i(?:'m| am)\\s+(?:currently\\s+|now\\s+)?\\w+ing\\s+(?:on|with|to|in|the|a|an|that|this|it|my|our|your|some|all|more|through|over|out)\\b|i(?:'ve| have)\\s+(?:already\\s+)?(?:started|begun|kicked off)|i(?:'ll| will)\\s+(?:keep|continue)\\b)");if(di.test(Or)||Ga.test(Or)){os=!0,v("tool_loop:announce_intent_nudge",{iteration:cn,responsePreview:ni.slice(0,240)}),Sn.push({role:"user",content:'Your response announces an action ("Let me X", "I\'ll Y next") but emits NO tool call \u2014 so the loop will exit and the user only sees your announcement, not the result. Take the action now: emit the `read_file`, `search_code`, `list_files`, `run_command`, or other tool call you just described. If you have nothing more to investigate, write a complete final answer instead \u2014 do not announce future work without doing it.'});continue}}}if(!aa&&!kl&&!Hs&&Pt&&this.registry.get("ask_user")){let ni=Pt.replace(/```bandit-reasoning\b[\s\S]*?```/gi,"").replace(/```bandit-reasoning\b[\s\S]*$/i,"").replace(/<think\b[\s\S]*?<\/think\s*>/gi,"").replace(/<think\b[\s\S]*$/i,"").trim(),Or=ni.slice(-320).toLowerCase(),di=/(shall i|should i|do you want me to|would you like me to|want me to (?:proceed|continue|go ahead)|which (?:option|approach|one)|proceed with the|go ahead with|or were you looking|or do you want|let me know (?:if|which|whether))/;if(/\?\s*$/.test(ni)&&di.test(Or)){kl=!0,v("tool_loop:ask_user_nudge",{iteration:cn,responsePreview:ni.slice(-240)}),Sn.push({role:"user",content:'You asked the user to choose or approve, but you did it in prose and the loop is exiting \u2014 they get a passive question, not an interactive prompt. Call the `ask_user` tool now: pose the question with 2\u20134 concrete options (put the recommended one first and append " (Recommended)"). Do not ask for a decision in plain prose when ask_user is available.'});continue}}if(m.isSubagent&&cn===0&&!yp&&!os&&!Hs&&!aa){yp=!0,v("tool_loop:subagent_first_iter_no_tool_call",{iteration:cn,responsePreview:Pt.slice(0,240)}),Sn.push({role:"user",content:'Your first response had reasoning but emitted NO tool call \u2014 that is a hard stall for a subagent (you exist to gather information; reasoning alone produces zero output). For your next response, emit a tool call. The minimum viable starting move for ANY exploration goal is:\n\n<tool_call>{"name":"list_files","params":{"path":"."}}</tool_call>\n\nCopy that exact envelope as the very first thing you emit (you may keep the reasoning block before it if your model needs to think first, but the tool_call envelope MUST appear in this turn). Substitute a different tool only if it\'s obviously better for the goal \u2014 `read_file` for "what does file X look like", `search_code` for "where is symbol Y", `run_command` for shell output. Do NOT respond with reasoning only again. The next message you send must contain a real <tool_call> envelope.'});continue}let En=wc.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();if(!(0,_1.stripToolCallMarkup)(En).trim()){let Or=(wc.match(/<think\b[\s\S]*?<\/think\s*>/gi)?.pop()??wc.match(/```bandit-reasoning\b[\s\S]*?```/gi)?.pop()??wc).replace(/<\/?think[^>]*>/gi,"").replace(/```bandit-reasoning\s*\n?|```/g,"").trim(),Ga=(Or.match(/[^.!?]+[.!?]/g)??[Or]).slice(-2).join(" ").trim().slice(-280);return{finalResponse:`[Bandit stalled after reasoning without emitting a tool call \u2014 the model thought through the next step but never committed to an action. Last reasoning: "${Ga}${Ga.length===280?"\u2026":""}"
|
|
232
232
|
|
|
233
233
|
Try: re-prompt with the same request (often resolves on the next turn), or run the planned command yourself.]`,iterations:cn,messages:Sn,hitLimit:aa}}let Lr=En;if(Lr.endsWith(":")&&Lr.length<600){let ni=Lr.match(/(?:[.!?]\s+)([^.!?]*)$/),Or=(ni?ni[1]:Lr).slice(-200);if(or.test(Or))return{finalResponse:`${Pt}
|
|
234
234
|
|
|
@@ -1785,7 +1785,7 @@ ${(()=>{let q=`Bandit insights \u2014 ${new Date(i).toISOString().slice(0,10)}`,
|
|
|
1785
1785
|
<h1>You're signed in.</h1>
|
|
1786
1786
|
<p>Bandit picked up your session. You can close this tab and return to your terminal.</p>
|
|
1787
1787
|
</div>
|
|
1788
|
-
</body></html>`;t(DUn,"startLoopbackListener");t(PUn,"openBrowser");t(NUn,"buildDefaultDeviceLabel");t(OUn,"runOAuthSignIn")});var Pbe=Lt((Hdr,RUn)=>{RUn.exports={name:"@burtson-labs/bandit-stealth-cli",version:"1.7.
|
|
1788
|
+
</body></html>`;t(DUn,"startLoopbackListener");t(PUn,"openBrowser");t(NUn,"buildDefaultDeviceLabel");t(OUn,"runOAuthSignIn")});var Pbe=Lt((Hdr,RUn)=>{RUn.exports={name:"@burtson-labs/bandit-stealth-cli",version:"1.7.364",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:{url:"https://github.com/Burtson-Labs/bandit-agent-framework/issues",email:"team@burtson.ai"},license:"Apache-2.0",author:{name:"Burtson Labs",email:"team@burtson.ai",url:"https://burtson.ai"},repository:{type:"git",url:"git+https://github.com/Burtson-Labs/bandit-agent-framework.git",directory:"apps/bandit-cli"},type:"module",bin:{bandit:"./dist/cli.js"},main:"dist/cli.js",files:["dist/cli.js","README.md","LICENSE"],engines:{node:">=20"},publishConfig:{access:"public"},scripts:{test:"vitest run",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","@types/react":"^19.2.2",esbuild:"^0.28.0",ink:"^7.0.4","ink-text-input":"^6.0.0",pngjs:"^7.0.0",react:"^19.2.0",typescript:"^5.4.0",vitest:"^4.0.10"}}});var MUe={};Kre(MUe,{resolveEditor:()=>BUe,spawnEditorOnFile:()=>HUn});import{spawnSync as JUn,spawn as qUn}from"child_process";import*as kIt from"path";function BUe(r=process.env){let i=(r.VISUAL??"").trim();if(i.length>0){let{cmd:u,args:l}=wIt(i);return{label:`$VISUAL (${u})`,cmd:u,args:l}}let o=(r.EDITOR??"").trim();if(o.length>0){let{cmd:u,args:l}=wIt(o);return{label:`$EDITOR (${u})`,cmd:u,args:l}}return r.TERM_PROGRAM==="vscode"&&xIt("code",r)?{label:"code --wait (VS Code tab)",cmd:"code",args:["--wait"]}:process.platform==="win32"?{label:"notepad",cmd:"notepad.exe",args:[]}:xIt("nano",r)?{label:"nano",cmd:"nano",args:[]}:null}async function HUn(r,i){let o=kIt.resolve(i);return new Promise(u=>{let l=qUn(r.cmd,[...r.args,o],{stdio:"inherit",shell:!1});l.on("exit",(m,v)=>{u({exitCode:typeof m=="number"?m:v?130:1})}),l.on("error",()=>u({exitCode:1}))})}function wIt(r){let i=r.split(/\s+/).filter(Boolean);return{cmd:i[0]??"",args:i.slice(1)}}function xIt(r,i){let o=process.platform==="win32"?"where":"which";return JUn(o,[r],{stdio:"ignore",env:i}).status===0}var Obe=I3(()=>{"use strict";t(BUe,"resolveEditor");t(HUn,"spawnEditorOnFile");t(wIt,"splitEditorEnv");t(xIt,"commandExists")});var PIt={};Kre(PIt,{PLAN_FILE:()=>IIt,STAGING_DIR:()=>FK,loadPlan:()=>DIt,runWizard:()=>GUn});import*as XJ from"fs";import*as XR from"path";async function DIt(r){let i=XR.join(r,FK,IIt),o;try{o=await XJ.promises.readFile(i,"utf-8")}catch{return null}try{let u=JSON.parse(o);return u.version!==1||!Array.isArray(u.entries)||u.entries.length===0?null:u}catch{return null}}async function GUn(r){let i=await DIt(r.cwd);if(!i)return process.stdout.write(W.red("No migration plan found. ")+W.dim(`Run ${W.cyan("/memory migrate")} first to generate one, then ${W.cyan("/memory migrate apply")} to launch this wizard.
|
|
1789
1789
|
`)),{applied:0,skipped:0,edited:0,quit:!0,originalBackup:""};let o=BUe();if(!o)return process.stdout.write(W.red("No editor available. ")+W.dim("Set $EDITOR (e.g. ")+W.cyan("EDITOR=code")+W.dim(") or ")+W.cyan("EDITOR=nano")+W.dim(" and rerun ")+W.cyan("/memory migrate apply")+W.dim(". ")+W.dim("You can also edit the files under ")+W.cyan(FK)+W.dim(` directly with any editor before running apply \u2014 the wizard reads them as-is.
|
|
1790
1790
|
`)),{applied:0,skipped:0,edited:0,quit:!0,originalBackup:""};let u="\u2550".repeat(60);process.stdout.write(`
|
|
1791
1791
|
`+W.accent(u)+`
|
package/package.json
CHANGED