@burtson-labs/bandit-stealth-cli 1.7.440 → 1.7.441
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
|
@@ -1540,7 +1540,7 @@ Content-Type: ${o}\r
|
|
|
1540
1540
|
`}<style data-${T4t}>body{word-wrap:break-word;-webkit-text-size-adjust:100%}img,video,canvas,svg{max-width:100%;height:auto}table{display:block;max-width:100%;overflow-x:auto}pre{max-width:100%;overflow-x:auto}</style>`,l=/<head[^>]*>/i.exec(r);if(l){let _=l.index+l[0].length;return`${r.slice(0,_)}
|
|
1541
1541
|
${o}${r.slice(_)}`}let u=/<html[^>]*>/i.exec(r);if(u){let _=u.index+u[0].length;return`${r.slice(0,_)}
|
|
1542
1542
|
<head>${o}</head>${r.slice(_)}`}return`${o}
|
|
1543
|
-
${r}`}t(Cqe,"ensureMobileFriendlyHtml");async function _Vn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=r.contentType??Sqe(r.filename),u=typeof r.content=="string"&&/html/.test(l)?Cqe(r.content):r.content,_=typeof u=="string"?new TextEncoder().encode(u):u,h=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),{body:C,contentType:I}=k4t("File",r.filename,l,_),N=r.scope==="team"?"?scope=team":"",B=Math.max(1,r.maxAttempts??3),J=r.retryDelayMs??300,j=new Error("artifact upload failed");for(let ne=1;ne<=B;ne++){let re;try{re=await i(`${o}/api/artifact${N}`,{method:"POST",headers:{authorization:`Bearer ${h}`,"content-type":I},body:C})}catch(Pe){if(j=new Error(`artifact upload failed: ${Pe instanceof Error?Pe.message:String(Pe)}`),ne<B){await w4t(J*ne);continue}throw j}if(re.ok){let Pe=await re.json();if(!Pe.url)throw new Error("artifact upload succeeded but no URL was returned");return{url:Pe.url,key:Pe.key??"",size:Pe.size??_.byteLength}}let se="";try{se=(await re.json())?.message??""}catch{}if(j=new Error(`artifact upload failed: HTTP ${re.status}${se?` \u2014 ${se}`:""}`),re.status>=500&&ne<B){await w4t(J*ne);continue}throw j}throw j}t(_Vn,"publishArtifact");function w4t(r){return r>0?new Promise(i=>setTimeout(i,r)):Promise.resolve()}t(w4t,"sleep");function wM(r){let i=/[?&]a=([^&#]+)/.exec(r);if(i)try{return decodeURIComponent(i[1])}catch{return i[1]}let o="/api/artifact/",l=r.indexOf(o);return(l>=0?r.slice(l+o.length):r).split("/").map(_=>{try{return decodeURIComponent(_)}catch{return _}}).join("/")}t(wM,"artifactKeyFromUrl");async function mVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),u=await i(`${o}/api/artifact/mine`,{headers:{authorization:`Bearer ${l}`}});if(!u.ok)throw new Error(`could not list artifacts: HTTP ${u.status}`);return(await u.json()).artifacts??[]}t(mVn,"listArtifacts");async function gVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),u=wM(r.keyOrUrl).split("/").map(encodeURIComponent).join("/"),_=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),h=await i(`${o}/api/artifact/${u}`,{method:"DELETE",headers:{authorization:`Bearer ${_}`}});if(!h.ok)throw h.status===404?new Error(`no artifact found for "${r.keyOrUrl}" (or it isn't yours)`):new Error(`could not delete artifact: HTTP ${h.status}`)}t(gVn,"deleteArtifact");async function hVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/share`,{method:"POST",headers:{authorization:`Bearer ${u}`,"content-type":"application/json"},body:JSON.stringify({key:l,expiryMinutes:r.expiryMinutes})});if(!_.ok){let C="";try{C=(await _.json())?.message??""}catch{}throw new Error(`could not create share link: HTTP ${_.status}${C?` \u2014 ${C}`:""}`)}let h=await _.json();if(!h.url)throw new Error("share link created but no URL was returned");return{url:h.url,token:h.token??"",expiresAt:h.expiresAt??""}}t(hVn,"createShareLink");async function yVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/scope`,{method:"POST",headers:{authorization:`Bearer ${u}`,"content-type":"application/json"},body:JSON.stringify({key:l,scope:r.scope})});if(!_.ok){let C="";try{C=(await _.json())?.message??""}catch{}throw new Error(`could not change scope: HTTP ${_.status}${C?` \u2014 ${C}`:""}`)}let h=await _.json();return{key:h.key??l,url:h.url??"",scope:h.scope??r.scope}}t(yVn,"setArtifactScope");async function vVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/restore`,{method:"POST",headers:{authorization:`Bearer ${u}`,"content-type":"application/json"},body:JSON.stringify({key:l})});if(!_.ok){let h="";try{h=(await _.json())?.message??""}catch{}throw new Error(`could not restore artifact: HTTP ${_.status}${h?` \u2014 ${h}`:""}`)}}t(vVn,"restoreArtifact");async function AVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/archive`,{method:"POST",headers:{authorization:`Bearer ${u}`,"content-type":"application/json"},body:JSON.stringify({key:l})});if(!_.ok){let h="";try{h=(await _.json())?.message??""}catch{}throw new Error(`could not archive artifact: HTTP ${_.status}${h?` \u2014 ${h}`:""}`)}}t(AVn,"archiveArtifact");async function bVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=l.split("/").map(encodeURIComponent).join("/"),_=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),h=await i(`${o}/api/artifact/${u}`,{headers:{authorization:`Bearer ${_}`}});if(!h.ok){let N="";try{N=(await h.json())?.message??""}catch{}throw new Error(`could not fetch artifact: HTTP ${h.status}${N?` \u2014 ${N}`:""}`)}let C=h.headers.get("content-type")??"application/octet-stream",I=await h.text();return{key:l,contentType:C,content:I}}t(bVn,"getArtifact");async function SVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=l.split("/").map(encodeURIComponent).join("/"),_=r.filename??(l.split("/").pop()||"artifact"),h=r.contentType??Sqe(_),C=typeof r.content=="string"&&/html/.test(h)?Cqe(r.content):r.content,I=typeof C=="string"?new TextEncoder().encode(C):C,N=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),{body:B,contentType:J}=k4t("File",_,h,I),j=await i(`${o}/api/artifact/${u}`,{method:"PUT",headers:{authorization:`Bearer ${N}`,"content-type":J},body:B});if(!j.ok){let re="";try{re=(await j.json())?.message??""}catch{}throw new Error(`could not update artifact: HTTP ${j.status}${re?` \u2014 ${re}`:""}`)}let ne=await j.json();return{url:ne.url??r.keyOrUrl,key:ne.key??l,size:ne.size??I.byteLength}}t(SVn,"updateArtifact");async function CVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/share/email`,{method:"POST",headers:{authorization:`Bearer ${u}`,"content-type":"application/json"},body:JSON.stringify({key:l,to:r.to,expiryMinutes:r.expiryMinutes,message:r.message})});if(!_.ok){let C="";try{C=(await _.json())?.message??""}catch{}throw new Error(`could not email share link: HTTP ${_.status}${C?` \u2014 ${C}`:""}`)}let h=await _.json();if(!h.url)throw new Error("share link created but no URL was returned");return{url:h.url,token:h.token??"",expiresAt:h.expiresAt??"",emailed:h.emailed??!1}}t(CVn,"emailShareLink");async function EVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),u=await i(`${o}/api/artifact/share/${encodeURIComponent(r.shareToken)}`,{method:"DELETE",headers:{authorization:`Bearer ${l}`}});if(!u.ok)throw u.status===404?new Error("no matching share link (or it isn't yours)"):new Error(`could not revoke share link: HTTP ${u.status}`)}t(EVn,"revokeShareLink");async function TVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/shares?key=${encodeURIComponent(l)}`,{headers:{authorization:`Bearer ${u}`}});if(!_.ok)throw new Error(`could not list share links: HTTP ${_.status}`);return(await _.json()).shares??[]}t(TVn,"listShareLinks");async function wVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=r.scope==="team"?"?scope=team":"",u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/mine${l}`,{method:"DELETE",headers:{authorization:`Bearer ${u}`}});if(!_.ok)throw new Error(`could not clear artifacts: HTTP ${_.status}`);return(await _.json()).deleted??0}t(wVn,"clearArtifacts")});var vCe=Dt(RL=>{"use strict";var kVn=RL&&RL.__createBinding||(Object.create?(function(r,i,o,l){l===void 0&&(l=o);var u=Object.getOwnPropertyDescriptor(i,o);(!u||("get"in u?!i.__esModule:u.writable||u.configurable))&&(u={enumerable:!0,get:t(function(){return i[o]},"get")}),Object.defineProperty(r,l,u)}):(function(r,i,o,l){l===void 0&&(l=o),r[l]=i[o]})),xVn=RL&&RL.__setModuleDefault||(Object.create?(function(r,i){Object.defineProperty(r,"default",{enumerable:!0,value:i})}):function(r,i){r.default=i}),x4t=RL&&RL.__importStar||(function(){var r=t(function(i){return r=Object.getOwnPropertyNames||function(o){var l=[];for(var u in o)Object.prototype.hasOwnProperty.call(o,u)&&(l[l.length]=u);return l},r(i)},"ownKeys");return function(i){if(i&&i.__esModule)return i;var o={};if(i!=null)for(var l=r(i),u=0;u<l.length;u++)l[u]!=="default"&&kVn(o,i,l[u]);return xVn(o,i),o}})();Object.defineProperty(RL,"__esModule",{value:!0});RL.inlineHtmlImages=OVn;var IVn=x4t(ja("fs")),Eqe=x4t(ja("path")),DVn={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".bmp":"image/bmp",".ico":"image/x-icon",".avif":"image/avif"};function PVn(r){return DVn[Eqe.extname(r).toLowerCase()]??"application/octet-stream"}t(PVn,"mimeFromPath");async function NVn(r,i,o){if(!r||r.startsWith("data:"))return null;try{let l,u;if(/^https?:\/\//i.test(r)){let _=new AbortController,h=setTimeout(()=>_.abort(),i.timeoutMs),C;try{C=await i.fetchImpl(r,{signal:_.signal,redirect:"follow"})}finally{clearTimeout(h)}if(!C.ok||(u=(C.headers.get("content-type")??"").split(";")[0].trim(),!/^image\//i.test(u)))return null;l=Buffer.from(await C.arrayBuffer())}else{let _=Eqe.isAbsolute(r)?r:Eqe.join(i.baseDir,r);if(l=await IVn.promises.readFile(_),u=PVn(_),!u.startsWith("image/"))return null}return l.byteLength>i.maxImageBytes||l.byteLength>o?null:`data:${u};base64,${l.toString("base64")}`}catch{return null}}t(NVn,"resolveOne");async function OVn(r,i={}){let o={baseDir:i.baseDir??process.cwd(),fetchImpl:i.fetchImpl??fetch,maxImageBytes:i.maxImageBytes??4194304,timeoutMs:i.timeoutMs??15e3},l=i.maxTotalBytes??20*1024*1024,u=/<img\b[^>]*?\bsrc\s*=\s*(["'])(.*?)\1/gi,_=[...r.matchAll(u)];if(_.length===0)return{html:r,inlined:0,skipped:0};let h=0,C=0,I=0,N=[];for(let j of _){let ne=j[0],re=j[1],se=j[2],Pe=await NVn(se,o,l-h);if(Pe==null){se&&!se.startsWith("data:")&&I++;continue}h+=Math.ceil((Pe.length-13)*.75);let Qe=ne.replace(`=${re}${se}${re}`,`=${re}${Pe}${re}`);N.push({index:j.index??0,length:ne.length,text:Qe}),C++}if(N.length===0)return{html:r,inlined:0,skipped:I};let B="",J=0;for(let j of N)B+=r.slice(J,j.index)+j.text,J=j.index+j.length;return B+=r.slice(J),{html:B,inlined:C,skipped:I}}t(OVn,"inlineHtmlImages")});var D4t=Dt(ML=>{"use strict";var RVn=ML&&ML.__createBinding||(Object.create?(function(r,i,o,l){l===void 0&&(l=o);var u=Object.getOwnPropertyDescriptor(i,o);(!u||("get"in u?!i.__esModule:u.writable||u.configurable))&&(u={enumerable:!0,get:t(function(){return i[o]},"get")}),Object.defineProperty(r,l,u)}):(function(r,i,o,l){l===void 0&&(l=o),r[l]=i[o]})),MVn=ML&&ML.__setModuleDefault||(Object.create?(function(r,i){Object.defineProperty(r,"default",{enumerable:!0,value:i})}):function(r,i){r.default=i}),I4t=ML&&ML.__importStar||(function(){var r=t(function(i){return r=Object.getOwnPropertyNames||function(o){var l=[];for(var u in o)Object.prototype.hasOwnProperty.call(o,u)&&(l[l.length]=u);return l},r(i)},"ownKeys");return function(i){if(i&&i.__esModule)return i;var o={};if(i!=null)for(var l=r(i),u=0;u<l.length;u++)l[u]!=="default"&&RVn(o,i,l[u]);return MVn(o,i),o}})();Object.defineProperty(ML,"__esModule",{value:!0});ML.buildPublishArtifactTool=LVn;var BVn=I4t(ja("fs")),FY=I4t(ja("path")),Tqe=OL(),FVn=vCe();function LVn(r){return{name:"publish_artifact",description:'Publish a file from the workspace as a shareable Bandit Artifact and return a public URL anyone can open. Use this when the user asks to "publish", "share", or "make an artifact" of a file \u2014 write the file first, then call this with its path. Cloud feature.',parameters:[{name:"path",description:'Workspace-relative (or absolute) path to the file to publish, e.g. "README.md".',required:!0},{name:"scope",description:'Visibility: "private" (default, only the user) or "team" (shared with their team). The link works for anyone either way.',required:!1}],async execute(i,o){let l=(i.path??"").trim();if(!l)return{output:"Error: the `path` parameter is required.",isError:!0};let u=o.workspaceRoot??process.cwd(),_=FY.isAbsolute(l)?l:FY.join(u,l),h;try{h=await BVn.promises.readFile(_)}catch{return{output:`Error: can't read "${l}". Write the file first, then publish it.`,isError:!0}}try{let C=(i.scope??"").trim().toLowerCase()==="team"?"team":void 0,I=(0,Tqe.guessContentType)(FY.basename(_)),N=new Uint8Array(h),B="";if(I==="text/html"){let Pe=await(0,FVn.inlineHtmlImages)(h.toString("utf8"),{baseDir:FY.dirname(_)});N=new Uint8Array(Buffer.from(Pe.html,"utf8")),Pe.inlined&&(B=` Inlined ${Pe.inlined} image(s).`),Pe.skipped&&(B+=` (${Pe.skipped} image(s) couldn't be inlined \u2014 unreachable, not an image, or too large.)`)}let J=await(0,Tqe.publishArtifact)({s3ApiBaseUrl:r.s3ApiBaseUrl,authBaseUrl:r.authBaseUrl,token:r.token,scope:C,content:N,filename:FY.basename(_),contentType:I}),j=FY.basename(_),ne=(0,Tqe.artifactKeyFromUrl)(J.url),re=r.webBaseUrl?`${r.webBaseUrl.replace(/\/$/,"")}/artifacts?a=${encodeURIComponent(ne)}`:null,se=re?` The user can open and manage it here (signs them in if needed): ${re}`:"";return{output:`Published "${j}"${C==="team"?" to the team":" (private)"}.`+B+se+` To create an external link anyone can open without signing in, call share_artifact with url "${J.url}".`}}catch(C){return{output:`Error publishing artifact: ${C instanceof Error?C.message:String(C)}`,isError:!0}}}}}t(LVn,"buildPublishArtifactTool")});var P4t=Dt(wqe=>{"use strict";Object.defineProperty(wqe,"__esModule",{value:!0});wqe.buildShareArtifactTool=UVn;var jVn=OL();function $Vn(r){if(!r)return;let i=/^(\d+)\s*(d|h|m)?$/i.exec(r.trim());if(!i)return;let o=parseInt(i[1],10),l=(i[2]??"m").toLowerCase();return l==="d"?o*24*60:l==="h"?o*60:o}t($Vn,"parseExpiryMinutes");function UVn(r){return{name:"share_artifact",description:'Create an EXTERNAL share link for an artifact you already published \u2014 a URL anyone can open without a Bandit account. Use when the user asks to "share externally", "send this to someone outside", or "make a link for a client". Pass the artifact URL returned by publish_artifact (or its key). The link auto-expires and can be revoked later. Cloud feature.',parameters:[{name:"url",description:"The artifact URL from publish_artifact (or its object key). This must be an artifact you own.",required:!0},{name:"expires",description:'Optional lifetime like "1d", "7d" (default), or "30d" (max). Prefer the shortest window that fits.',required:!1}],async execute(i){let o=(i.url??"").trim();if(!o)return{output:"Error: the `url` parameter is required (the artifact URL or key).",isError:!0};try{let l=await(0,jVn.createShareLink)({s3ApiBaseUrl:r.s3ApiBaseUrl,authBaseUrl:r.authBaseUrl,token:r.token,keyOrUrl:o,expiryMinutes:$Vn(i.expires),fetchImpl:r.fetchImpl}),u=(l.expiresAt||"").replace("T"," ").slice(0,16);return{output:`External share link${u?` (expires ${u} UTC)`:""} \u2014 anyone with it can view:
|
|
1543
|
+
${r}`}t(Cqe,"ensureMobileFriendlyHtml");async function _Vn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=r.contentType??Sqe(r.filename),u=typeof r.content=="string"&&/html/.test(l)?Cqe(r.content):r.content,_=typeof u=="string"?new TextEncoder().encode(u):u,h=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),{body:C,contentType:I}=k4t("File",r.filename,l,_),N=r.scope==="team"?"?scope=team":"",B=Math.max(1,r.maxAttempts??3),J=r.retryDelayMs??300,j=new Error("artifact upload failed");for(let ne=1;ne<=B;ne++){let re;try{re=await i(`${o}/api/artifact${N}`,{method:"POST",headers:{authorization:`Bearer ${h}`,"content-type":I},body:C})}catch(Pe){if(j=new Error(`artifact upload failed: ${Pe instanceof Error?Pe.message:String(Pe)}`),ne<B){await w4t(J*ne);continue}throw j}if(re.ok){let Pe=await re.json();if(!Pe.url)throw new Error("artifact upload succeeded but no URL was returned");return{url:Pe.url,key:Pe.key??"",size:Pe.size??_.byteLength}}let se="";try{se=(await re.json())?.message??""}catch{}if(j=new Error(`artifact upload failed: HTTP ${re.status}${se?` \u2014 ${se}`:""}`),re.status>=500&&ne<B){await w4t(J*ne);continue}throw j}throw j}t(_Vn,"publishArtifact");function w4t(r){return r>0?new Promise(i=>setTimeout(i,r)):Promise.resolve()}t(w4t,"sleep");function wM(r){let i=t(h=>h.split("/").map(C=>{try{return decodeURIComponent(C)}catch{return C}}).join("/"),"decodeSegs"),o=/[?&]a=([^&#]+)/.exec(r);if(o)try{return decodeURIComponent(o[1])}catch{return o[1]}let l="/api/artifact/",u=r.indexOf(l);if(u>=0)return i(r.slice(u+l.length).replace(/[?#].*$/,""));let _=/^[a-z][a-z0-9+.-]*:\/\/[^/]+\/(.+)$/i.exec(r);return i(_?_[1].replace(/[?#].*$/,""):r)}t(wM,"artifactKeyFromUrl");async function mVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),u=await i(`${o}/api/artifact/mine`,{headers:{authorization:`Bearer ${l}`}});if(!u.ok)throw new Error(`could not list artifacts: HTTP ${u.status}`);return(await u.json()).artifacts??[]}t(mVn,"listArtifacts");async function gVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),u=wM(r.keyOrUrl).split("/").map(encodeURIComponent).join("/"),_=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),h=await i(`${o}/api/artifact/${u}`,{method:"DELETE",headers:{authorization:`Bearer ${_}`}});if(!h.ok)throw h.status===404?new Error(`no artifact found for "${r.keyOrUrl}" (or it isn't yours)`):new Error(`could not delete artifact: HTTP ${h.status}`)}t(gVn,"deleteArtifact");async function hVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/share`,{method:"POST",headers:{authorization:`Bearer ${u}`,"content-type":"application/json"},body:JSON.stringify({key:l,expiryMinutes:r.expiryMinutes})});if(!_.ok){let C="";try{C=(await _.json())?.message??""}catch{}throw new Error(`could not create share link: HTTP ${_.status}${C?` \u2014 ${C}`:""}`)}let h=await _.json();if(!h.url)throw new Error("share link created but no URL was returned");return{url:h.url,token:h.token??"",expiresAt:h.expiresAt??""}}t(hVn,"createShareLink");async function yVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/scope`,{method:"POST",headers:{authorization:`Bearer ${u}`,"content-type":"application/json"},body:JSON.stringify({key:l,scope:r.scope})});if(!_.ok){let C="";try{C=(await _.json())?.message??""}catch{}throw new Error(`could not change scope: HTTP ${_.status}${C?` \u2014 ${C}`:""}`)}let h=await _.json();return{key:h.key??l,url:h.url??"",scope:h.scope??r.scope}}t(yVn,"setArtifactScope");async function vVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/restore`,{method:"POST",headers:{authorization:`Bearer ${u}`,"content-type":"application/json"},body:JSON.stringify({key:l})});if(!_.ok){let h="";try{h=(await _.json())?.message??""}catch{}throw new Error(`could not restore artifact: HTTP ${_.status}${h?` \u2014 ${h}`:""}`)}}t(vVn,"restoreArtifact");async function AVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/archive`,{method:"POST",headers:{authorization:`Bearer ${u}`,"content-type":"application/json"},body:JSON.stringify({key:l})});if(!_.ok){let h="";try{h=(await _.json())?.message??""}catch{}throw new Error(`could not archive artifact: HTTP ${_.status}${h?` \u2014 ${h}`:""}`)}}t(AVn,"archiveArtifact");async function bVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=l.split("/").map(encodeURIComponent).join("/"),_=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),h=await i(`${o}/api/artifact/${u}`,{headers:{authorization:`Bearer ${_}`}});if(!h.ok){let N="";try{N=(await h.json())?.message??""}catch{}throw new Error(`could not fetch artifact: HTTP ${h.status}${N?` \u2014 ${N}`:""}`)}let C=h.headers.get("content-type")??"application/octet-stream",I=await h.text();return{key:l,contentType:C,content:I}}t(bVn,"getArtifact");async function SVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=l.split("/").map(encodeURIComponent).join("/"),_=r.filename??(l.split("/").pop()||"artifact"),h=r.contentType??Sqe(_),C=typeof r.content=="string"&&/html/.test(h)?Cqe(r.content):r.content,I=typeof C=="string"?new TextEncoder().encode(C):C,N=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),{body:B,contentType:J}=k4t("File",_,h,I),j=await i(`${o}/api/artifact/${u}`,{method:"PUT",headers:{authorization:`Bearer ${N}`,"content-type":J},body:B});if(!j.ok){let re="";try{re=(await j.json())?.message??""}catch{}throw new Error(`could not update artifact: HTTP ${j.status}${re?` \u2014 ${re}`:""}`)}let ne=await j.json();return{url:ne.url??r.keyOrUrl,key:ne.key??l,size:ne.size??I.byteLength}}t(SVn,"updateArtifact");async function CVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/share/email`,{method:"POST",headers:{authorization:`Bearer ${u}`,"content-type":"application/json"},body:JSON.stringify({key:l,to:r.to,expiryMinutes:r.expiryMinutes,message:r.message})});if(!_.ok){let C="";try{C=(await _.json())?.message??""}catch{}throw new Error(`could not email share link: HTTP ${_.status}${C?` \u2014 ${C}`:""}`)}let h=await _.json();if(!h.url)throw new Error("share link created but no URL was returned");return{url:h.url,token:h.token??"",expiresAt:h.expiresAt??"",emailed:h.emailed??!1}}t(CVn,"emailShareLink");async function EVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),u=await i(`${o}/api/artifact/share/${encodeURIComponent(r.shareToken)}`,{method:"DELETE",headers:{authorization:`Bearer ${l}`}});if(!u.ok)throw u.status===404?new Error("no matching share link (or it isn't yours)"):new Error(`could not revoke share link: HTTP ${u.status}`)}t(EVn,"revokeShareLink");async function TVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=wM(r.keyOrUrl),u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/shares?key=${encodeURIComponent(l)}`,{headers:{authorization:`Bearer ${u}`}});if(!_.ok)throw new Error(`could not list share links: HTTP ${_.status}`);return(await _.json()).shares??[]}t(TVn,"listShareLinks");async function wVn(r){let i=r.fetchImpl??fetch,o=r.s3ApiBaseUrl.replace(/\/$/,""),l=r.scope==="team"?"?scope=team":"",u=await xx(r.token,{authBaseUrl:r.authBaseUrl,fetchImpl:i}),_=await i(`${o}/api/artifact/mine${l}`,{method:"DELETE",headers:{authorization:`Bearer ${u}`}});if(!_.ok)throw new Error(`could not clear artifacts: HTTP ${_.status}`);return(await _.json()).deleted??0}t(wVn,"clearArtifacts")});var vCe=Dt(RL=>{"use strict";var kVn=RL&&RL.__createBinding||(Object.create?(function(r,i,o,l){l===void 0&&(l=o);var u=Object.getOwnPropertyDescriptor(i,o);(!u||("get"in u?!i.__esModule:u.writable||u.configurable))&&(u={enumerable:!0,get:t(function(){return i[o]},"get")}),Object.defineProperty(r,l,u)}):(function(r,i,o,l){l===void 0&&(l=o),r[l]=i[o]})),xVn=RL&&RL.__setModuleDefault||(Object.create?(function(r,i){Object.defineProperty(r,"default",{enumerable:!0,value:i})}):function(r,i){r.default=i}),x4t=RL&&RL.__importStar||(function(){var r=t(function(i){return r=Object.getOwnPropertyNames||function(o){var l=[];for(var u in o)Object.prototype.hasOwnProperty.call(o,u)&&(l[l.length]=u);return l},r(i)},"ownKeys");return function(i){if(i&&i.__esModule)return i;var o={};if(i!=null)for(var l=r(i),u=0;u<l.length;u++)l[u]!=="default"&&kVn(o,i,l[u]);return xVn(o,i),o}})();Object.defineProperty(RL,"__esModule",{value:!0});RL.inlineHtmlImages=OVn;var IVn=x4t(ja("fs")),Eqe=x4t(ja("path")),DVn={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".bmp":"image/bmp",".ico":"image/x-icon",".avif":"image/avif"};function PVn(r){return DVn[Eqe.extname(r).toLowerCase()]??"application/octet-stream"}t(PVn,"mimeFromPath");async function NVn(r,i,o){if(!r||r.startsWith("data:"))return null;try{let l,u;if(/^https?:\/\//i.test(r)){let _=new AbortController,h=setTimeout(()=>_.abort(),i.timeoutMs),C;try{C=await i.fetchImpl(r,{signal:_.signal,redirect:"follow"})}finally{clearTimeout(h)}if(!C.ok||(u=(C.headers.get("content-type")??"").split(";")[0].trim(),!/^image\//i.test(u)))return null;l=Buffer.from(await C.arrayBuffer())}else{let _=Eqe.isAbsolute(r)?r:Eqe.join(i.baseDir,r);if(l=await IVn.promises.readFile(_),u=PVn(_),!u.startsWith("image/"))return null}return l.byteLength>i.maxImageBytes||l.byteLength>o?null:`data:${u};base64,${l.toString("base64")}`}catch{return null}}t(NVn,"resolveOne");async function OVn(r,i={}){let o={baseDir:i.baseDir??process.cwd(),fetchImpl:i.fetchImpl??fetch,maxImageBytes:i.maxImageBytes??4194304,timeoutMs:i.timeoutMs??15e3},l=i.maxTotalBytes??20*1024*1024,u=/<img\b[^>]*?\bsrc\s*=\s*(["'])(.*?)\1/gi,_=[...r.matchAll(u)];if(_.length===0)return{html:r,inlined:0,skipped:0};let h=0,C=0,I=0,N=[];for(let j of _){let ne=j[0],re=j[1],se=j[2],Pe=await NVn(se,o,l-h);if(Pe==null){se&&!se.startsWith("data:")&&I++;continue}h+=Math.ceil((Pe.length-13)*.75);let Qe=ne.replace(`=${re}${se}${re}`,`=${re}${Pe}${re}`);N.push({index:j.index??0,length:ne.length,text:Qe}),C++}if(N.length===0)return{html:r,inlined:0,skipped:I};let B="",J=0;for(let j of N)B+=r.slice(J,j.index)+j.text,J=j.index+j.length;return B+=r.slice(J),{html:B,inlined:C,skipped:I}}t(OVn,"inlineHtmlImages")});var D4t=Dt(ML=>{"use strict";var RVn=ML&&ML.__createBinding||(Object.create?(function(r,i,o,l){l===void 0&&(l=o);var u=Object.getOwnPropertyDescriptor(i,o);(!u||("get"in u?!i.__esModule:u.writable||u.configurable))&&(u={enumerable:!0,get:t(function(){return i[o]},"get")}),Object.defineProperty(r,l,u)}):(function(r,i,o,l){l===void 0&&(l=o),r[l]=i[o]})),MVn=ML&&ML.__setModuleDefault||(Object.create?(function(r,i){Object.defineProperty(r,"default",{enumerable:!0,value:i})}):function(r,i){r.default=i}),I4t=ML&&ML.__importStar||(function(){var r=t(function(i){return r=Object.getOwnPropertyNames||function(o){var l=[];for(var u in o)Object.prototype.hasOwnProperty.call(o,u)&&(l[l.length]=u);return l},r(i)},"ownKeys");return function(i){if(i&&i.__esModule)return i;var o={};if(i!=null)for(var l=r(i),u=0;u<l.length;u++)l[u]!=="default"&&RVn(o,i,l[u]);return MVn(o,i),o}})();Object.defineProperty(ML,"__esModule",{value:!0});ML.buildPublishArtifactTool=LVn;var BVn=I4t(ja("fs")),FY=I4t(ja("path")),Tqe=OL(),FVn=vCe();function LVn(r){return{name:"publish_artifact",description:'Publish a file from the workspace as a shareable Bandit Artifact and return a public URL anyone can open. Use this when the user asks to "publish", "share", or "make an artifact" of a file \u2014 write the file first, then call this with its path. Cloud feature.',parameters:[{name:"path",description:'Workspace-relative (or absolute) path to the file to publish, e.g. "README.md".',required:!0},{name:"scope",description:'Visibility: "private" (default, only the user) or "team" (shared with their team). The link works for anyone either way.',required:!1}],async execute(i,o){let l=(i.path??"").trim();if(!l)return{output:"Error: the `path` parameter is required.",isError:!0};let u=o.workspaceRoot??process.cwd(),_=FY.isAbsolute(l)?l:FY.join(u,l),h;try{h=await BVn.promises.readFile(_)}catch{return{output:`Error: can't read "${l}". Write the file first, then publish it.`,isError:!0}}try{let C=(i.scope??"").trim().toLowerCase()==="team"?"team":void 0,I=(0,Tqe.guessContentType)(FY.basename(_)),N=new Uint8Array(h),B="";if(I==="text/html"){let Pe=await(0,FVn.inlineHtmlImages)(h.toString("utf8"),{baseDir:FY.dirname(_)});N=new Uint8Array(Buffer.from(Pe.html,"utf8")),Pe.inlined&&(B=` Inlined ${Pe.inlined} image(s).`),Pe.skipped&&(B+=` (${Pe.skipped} image(s) couldn't be inlined \u2014 unreachable, not an image, or too large.)`)}let J=await(0,Tqe.publishArtifact)({s3ApiBaseUrl:r.s3ApiBaseUrl,authBaseUrl:r.authBaseUrl,token:r.token,scope:C,content:N,filename:FY.basename(_),contentType:I}),j=FY.basename(_),ne=(0,Tqe.artifactKeyFromUrl)(J.url),re=r.webBaseUrl?`${r.webBaseUrl.replace(/\/$/,"")}/artifacts?a=${encodeURIComponent(ne)}`:null,se=re?` The user can open and manage it here (signs them in if needed): ${re}`:"";return{output:`Published "${j}"${C==="team"?" to the team":" (private)"}.`+B+se+` To create an external link anyone can open without signing in, call share_artifact with url "${J.url}".`}}catch(C){return{output:`Error publishing artifact: ${C instanceof Error?C.message:String(C)}`,isError:!0}}}}}t(LVn,"buildPublishArtifactTool")});var P4t=Dt(wqe=>{"use strict";Object.defineProperty(wqe,"__esModule",{value:!0});wqe.buildShareArtifactTool=UVn;var jVn=OL();function $Vn(r){if(!r)return;let i=/^(\d+)\s*(d|h|m)?$/i.exec(r.trim());if(!i)return;let o=parseInt(i[1],10),l=(i[2]??"m").toLowerCase();return l==="d"?o*24*60:l==="h"?o*60:o}t($Vn,"parseExpiryMinutes");function UVn(r){return{name:"share_artifact",description:'Create an EXTERNAL share link for an artifact you already published \u2014 a URL anyone can open without a Bandit account. Use when the user asks to "share externally", "send this to someone outside", or "make a link for a client". Pass the artifact URL returned by publish_artifact (or its key). The link auto-expires and can be revoked later. Cloud feature.',parameters:[{name:"url",description:"The artifact URL from publish_artifact (or its object key). This must be an artifact you own.",required:!0},{name:"expires",description:'Optional lifetime like "1d", "7d" (default), or "30d" (max). Prefer the shortest window that fits.',required:!1}],async execute(i){let o=(i.url??"").trim();if(!o)return{output:"Error: the `url` parameter is required (the artifact URL or key).",isError:!0};try{let l=await(0,jVn.createShareLink)({s3ApiBaseUrl:r.s3ApiBaseUrl,authBaseUrl:r.authBaseUrl,token:r.token,keyOrUrl:o,expiryMinutes:$Vn(i.expires),fetchImpl:r.fetchImpl}),u=(l.expiresAt||"").replace("T"," ").slice(0,16);return{output:`External share link${u?` (expires ${u} UTC)`:""} \u2014 anyone with it can view:
|
|
1544
1544
|
${l.url}
|
|
1545
1545
|
Revoke it later with this token: ${l.token}`}}catch(l){return{output:`Error creating share link: ${l instanceof Error?l.message:String(l)}`,isError:!0}}}}}t(UVn,"buildShareArtifactTool")});var N4t=Dt(kqe=>{"use strict";Object.defineProperty(kqe,"__esModule",{value:!0});kqe.buildListArtifactsTool=qVn;var zVn=OL();function QVn(r){return r<1024?`${r} B`:r<1024*1024?`${(r/1024).toFixed(1)} KB`:`${(r/1024/1024).toFixed(1)} MB`}t(QVn,"humanSize");function qVn(r){return{name:"list_artifacts",description:`List the user's published Bandit Artifacts (their private ones and their team's shared ones), newest first, with each artifact's name, scope, size, and URL. Use this to answer "what have I published?" or to find an artifact's URL before sharing or deleting it. Cloud feature.`,parameters:[{name:"scope",description:`Optional filter: "private" (only yours), "team" (your team's shared), or omit for both.`,required:!1}],async execute(i){try{let o=await(0,zVn.listArtifacts)({s3ApiBaseUrl:r.s3ApiBaseUrl,authBaseUrl:r.authBaseUrl,token:r.token,fetchImpl:r.fetchImpl}),l=(i.scope??"").trim().toLowerCase(),u=l==="private"?o.filter(h=>h.scope!=="team"):l==="team"?o.filter(h=>h.scope==="team"):o;if(u.length===0)return{output:"No artifacts found. Publish one with publish_artifact."};let _=u.map(h=>{let C=h.key.split("/").pop()??h.key,I=(h.lastModified||"").replace("T"," ").slice(0,16);return`- ${C} [${h.scope==="team"?"team":"private"}] ${QVn(h.size)} ${I} \u2014 ${h.url}`});return{output:`${u.length} artifact(s):
|
|
1546
1546
|
${_.join(`
|
|
@@ -2095,7 +2095,7 @@ Upgrade it with:
|
|
|
2095
2095
|
`)),l}async function sce(r,i){let o=ORt(r);if(o===null)return process.stdout.write(z.dim("No graph run to resume. Start one with: ")+z.cyan("BANDIT_GRAPH=1 bandit graph demo")+z.dim(" or ")+z.cyan('bandit graph plan "\u2026" --run')+`
|
|
2096
2096
|
`),null;if(!o.ok)return process.stdout.write(z.red(`Can't resume: ${o.error}
|
|
2097
2097
|
`)),null;let{spec:l,checkpoint:u,nodePrompts:_}=o.file,h=l.nodes.filter(I=>!_[I.id]).map(I=>I.id);if(h.length>0)return process.stdout.write(z.red(`Can't resume: run file has no prompts for: ${h.join(", ")}
|
|
2098
|
-
`)),null;let C=qCe(_,i);return q$({cwd:r,spec:l,executors:C,nodePrompts:_,resumeFrom:u})}var Q$,h6,QY=Gi(()=>{"use strict";Q$=Eo(JC(),1);sv();h6=["read_file","list_files","ls","search_code","find_directory","glob","web_fetch","web_search","read_pdf","read_memory","list_artifacts","fetch_image"];t(zCe,"graphRunPath");t(NRt,"saveRunFile");t(ORt,"loadRunFile");t(qCe,"executorsFromPrompts");t(q$,"runSpecLive");t(sce,"resumeSpecLive")});var oce=Dt((WEr,_Xn)=>{_Xn.exports={name:"@burtson-labs/bandit-stealth-cli",version:"1.7.
|
|
2098
|
+
`)),null;let C=qCe(_,i);return q$({cwd:r,spec:l,executors:C,nodePrompts:_,resumeFrom:u})}var Q$,h6,QY=Gi(()=>{"use strict";Q$=Eo(JC(),1);sv();h6=["read_file","list_files","ls","search_code","find_directory","glob","web_fetch","web_search","read_pdf","read_memory","list_artifacts","fetch_image"];t(zCe,"graphRunPath");t(NRt,"saveRunFile");t(ORt,"loadRunFile");t(qCe,"executorsFromPrompts");t(q$,"runSpecLive");t(sce,"resumeSpecLive")});var oce=Dt((WEr,_Xn)=>{_Xn.exports={name:"@burtson-labs/bandit-stealth-cli",version:"1.7.441",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"}}});import*as HJ from"child_process";import*as N1 from"fs";import*as Ow from"path";function mXn(r){let i=process.env.HOME||"";return i&&r.startsWith(i)?`~${r.slice(i.length)}`:r}function gXn(){return new Promise(r=>{let i=HJ.spawn("npm",["view",JCe,"version"],{shell:!1,stdio:["ignore","pipe","pipe"]}),o="";i.stdout?.on("data",u=>{o+=u.toString()});let l=setTimeout(()=>{i.kill("SIGTERM"),r(null)},8e3);i.on("close",u=>{clearTimeout(l),r(u===0?o.trim():null)}),i.on("error",()=>{clearTimeout(l),r(null)})})}function yXn(r){return(r??"").trim().split(/\s+/).filter(Boolean).some(i=>hXn.has(i.toLowerCase()))}function vXn(r,i){let o=[...r].map(h=>h.role).lastIndexOf("user");if(o===-1)return null;let l=r[o],u=typeof l.content=="string"?l.content:"",_=i&&i.trim()?i.trim():u;return _?{prompt:_,trimmedConversation:r.slice(0,o)}:null}function AXn(r,i){let o=t(N=>N.replace(/[^0-9.]/g,"").split(".").map(B=>parseInt(B,10)||0),"parse"),[l,u,_]=o(r),[h,C,I]=o(i);return l!==h?l<h?-1:1:u!==C?u<C?-1:1:_!==I?_<I?-1:1:0}function SXn(r){return qY.find(i=>i.name===r)}function CXn(){let r=qY.map(i=>` ${z.cyan("/"+i.name.padEnd(14))} ${z.dim(i.description)}`);return[z.bold("All slash commands:"),...r,"",z.dim("Tip: prefix any file with @ to pin it, or run /help permissions for the permission model.")].join(`
|
|
2099
2099
|
`)}function EXn(){return[z.bold("Permission choices"),"",` ${z.accent("allow once")} ${z.dim("Run only this call.")}`,` ${z.accent("allow turn")} ${z.dim("Allow calls like this until the agent finishes the current turn.")}`,` ${z.dim(" ")}${z.dim("Best pick when the model is making a batch of similar edits.")}`,` ${z.accent("allow session")} ${z.dim("Allow them until you exit Bandit.")}`,` ${z.accent("always allow")} ${z.dim("Save the rule to .bandit/settings.json so it survives restarts.")}`,` ${z.accent("deny")} ${z.dim("Block the call. Bandit should not retry it.")}`,` ${z.accent("deny + note")} ${z.dim("Block it and tell Bandit what to do instead.")}`,"",z.dim(" The card shows the exact rule each choice stores, under the highlighted"),z.dim(" option. For shell commands the rule covers a command shape \u2014 approving"),z.dim(" `git status` grants `git status \u2026`, not every command."),"",z.bold("Permission modes")+z.dim(" \u2014 /auto to change"),` ${z.accent("ask")} ${z.dim("Every non-allowlisted call prompts. Default.")}`,` ${z.accent("auto")} ${z.dim("Routine work runs unprompted: reading, editing files in this")}`,` ${z.dim(" ")}${z.dim("project, running builds and tests. Everything else still asks.")}`,` ${z.accent("dangerous")} ${z.dim("Nothing prompts. CI and sandboxes only; not settable from /auto.")}`,"",z.bold("What auto mode never does without asking"),z.dim(" Deleting files \xB7 writing outside the project \xB7 force-push and history"),z.dim(" rewrites \xB7 global installs and publishes \xB7 touching credential files \xB7"),z.dim(" sending data off the machine \xB7 mutating a connected service."),z.dim(" That floor holds even if a saved allow rule would cover the call."),"",z.dim(" /permissions review what ran unattended and which grants are active"),z.dim(" /doctor explain the current setup and next best actions")].join(`
|
|
2100
2100
|
`)}function TXn(){let r=[z.bold("Bandit commands"),z.dim("Use /help all for the full list, /help permissions for approval choices."),""],i=new Set;for(let l of bXn){let u=l.names.map(_=>SXn(_)).filter(_=>!!_);if(u.length!==0){r.push(z.bold(l.title));for(let _ of u)i.add(_.name),r.push(` ${z.cyan("/"+_.name.padEnd(14))} ${z.dim(_.description)}`);r.push("")}}let o=qY.filter(l=>!i.has(l.name)&&l.name!=="quit");return o.length>0&&(r.push(z.dim(`Also available: ${o.map(l=>"/"+l.name).join(", ")}`)),r.push("")),r.push(z.dim("Fast path: /doctor \u2192 /connect or /init \u2192 ask for the change \u2192 /review \u2192 /test \u2192 /commit")),r.join(`
|
|
2101
2101
|
`)}function wXn(r){let i=[],o=r.accomplishments,l=Math.max(1,Math.round((Date.now()-(r.firstSeenAt??Date.now()))/864e5)),u=r.ai?.storyline&&r.ai.storyline.length>0?r.ai.storyline:r.localStory;if(u.length>0){let N=Math.min(process.stdout.columns||80,100),B=Math.max(40,N-4);i.push(z.bold("Your story")+z.dim(` \xB7 ${r.ai?.storyline?.length?r.ai.modelLabel:"local synthesis"}`)),i.push("");for(let J of u){let j=J.replace(/\s+/g," ").trim().split(" "),ne="";for(let re of j)ne.length===0?ne=re:ne.length+1+re.length<=B?ne+=" "+re:(i.push(" "+ne),ne=re);ne&&i.push(" "+ne),i.push("")}}if(i.push(z.bold("How you use Bandit")),i.push(""),i.push(` ${z.dim("sessions ")} ${z.accent(String(r.sessions.length))} ${z.dim("over "+l+" day"+(l===1?"":"s"))}`),i.push(` ${z.dim("prompts ")} ${z.accent(String(r.totalPrompts))} ${z.dim("~"+(r.totalApproxTokens>=1e3?(r.totalApproxTokens/1e3).toFixed(1)+"K":r.totalApproxTokens)+" tokens")}`),(r.streak.current>0||r.streak.longest>0)&&i.push(` ${z.dim("streak ")} ${z.accent(r.streak.current+" day"+(r.streak.current===1?"":"s"))} ${z.dim("(longest "+r.streak.longest+")")}`),r.peakDay&&i.push(` ${z.dim("peak day ")} ${z.accent(r.peakDay.date)} ${z.dim(r.peakDay.prompts+" prompts")}`),i.push(""),i.push(z.bold("What got done")),i.push(` ${z.dim("files touched ")} ${z.accent(String(o.filesTouched))} ${z.dim("("+o.filesWritten+" written, "+o.editsApplied+" edited)")}`),o.gitOperations>0&&i.push(` ${z.dim("git ops ")} ${z.accent(String(o.gitOperations))} ${z.dim("("+o.commitsMade+" commits)")}`),o.testsRun>0&&i.push(` ${z.dim("tests run ")} ${z.accent(String(o.testsRun))}`),o.subagentsSpawned>0&&i.push(` ${z.dim("subagents ")} ${z.accent(String(o.subagentsSpawned))}`),o.languages.length>0){let N=o.languages.slice(0,5).map(B=>`${B.label} ${z.dim("("+B.count+")")}`).join(z.dim(", "));i.push(` ${z.dim("languages ")} ${N}`)}if(r.work.themes.length>0){i.push(""),i.push(z.bold("Bigger arcs"));for(let N of r.work.themes.slice(0,4)){let B=[`${N.turns} turn${N.turns===1?"":"s"}`,N.filesTouched>0?`${N.filesTouched} files`:"",N.testsRun>0?`${N.testsRun} tests`:"",N.externalActions>0?`${N.externalActions} external`:"",N.subagentsSpawned>0?`${N.subagentsSpawned} subagents`:""].filter(Boolean).join(", ");i.push(` ${z.cyan(N.title)} ${z.dim(B?"\u2014 "+B:"")}`),N.outcomes.length>0&&i.push(z.dim(` ${N.outcomes[0]}`)),N.sampleTitles.length>0&&i.push(z.dim(` ${N.sampleTitles[0]}`))}}if(r.work.highlights.length>0){i.push(""),i.push(z.bold("Largest work highlights"));for(let N of r.work.highlights.slice(0,5))i.push(` ${z.cyan(N.date)} ${z.accent(N.area)} ${z.dim("\xB7 "+N.category)}`),i.push(z.dim(` ${N.title}`)),i.push(z.dim(` ${N.summary}`)),N.outcome&&i.push(z.dim(` ${N.outcome}`))}if(o.topFiles.length>0){i.push(""),i.push(z.bold("Most-touched files"));for(let N of o.topFiles.slice(0,5))i.push(` ${z.cyan(N.path)} ${z.dim("\xD7"+N.touches)}`)}let _=[...r.toolStats.entries()].map(([N,B])=>({name:N,calls:B.calls,errors:B.errors,rate:B.calls>0?B.errors/B.calls:0})).sort((N,B)=>B.calls-N.calls).slice(0,6);if(_.length>0){i.push(""),i.push(z.bold("Top tools"));for(let N of _){let B=Math.round(N.rate*100),J=N.calls>=5&&B>=25?" "+z.yellow("\u26A0 "+B+"% error rate"):"";i.push(` ${z.cyan(N.name.padEnd(16))} ${z.accent(String(N.calls).padStart(4))} ${z.dim("calls")}${J}`)}}let h=[...r.errorClusters.entries()].flatMap(([N,B])=>B.map(J=>({tool:N,error:J.error,count:J.count}))).sort((N,B)=>B.count-N.count);if(h.length>0){let N=h[0],B=N.error.replace(/\s+/g," ").slice(0,70);i.push(""),i.push(z.bold("Top friction")),i.push(` ${z.cyan(N.tool)} ${z.dim("\xD7"+N.count)} ${z.dim(B+(N.error.length>70?"\u2026":""))}`)}let C=r.sentiment;if(C.satisfied+C.happy+C.excited+C.frustrated+C.unsatisfied>0){let N=[];C.excited>0&&N.push(z.green("excited ")+z.bold(String(C.excited))),C.happy>0&&N.push(z.green("happy ")+z.bold(String(C.happy))),C.satisfied>0&&N.push(z.green("satisfied ")+z.bold(String(C.satisfied)));let B=[];if(C.unsatisfied>0&&B.push(z.yellow("unsatisfied ")+z.bold(String(C.unsatisfied))),C.frustrated>0&&B.push(z.red("frustrated ")+z.bold(String(C.frustrated))),i.push(""),i.push(z.bold("How you felt")),N.length>0&&i.push(` ${N.join(z.dim(" \xB7 "))}`),B.length>0&&i.push(` ${B.join(z.dim(" \xB7 "))}`),C.notable.length>0){i.push(z.dim(" Frustration moments:"));for(let J of C.notable.slice(0,3))i.push(z.dim(' "')+z.dim(J)+z.dim('"'))}}return i.push(""),i.push(z.dim(" Full report (HTML + AI summary): ")+z.cyan("/insights")),i.join(`
|
package/package.json
CHANGED