typebulb 0.28.1 → 0.28.2
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.
|
@@ -1447,7 +1447,7 @@ ${lCt(b)}`};let v=aCt(d.code,{jsxImportSource:p.ts?.jsxImportSource});if(v.error
|
|
|
1447
1447
|
`),a=[];for(let b of z1.parse(o,{})){if(b.type!=="fence"||!b.map)continue;let v=b.content.replace(fvn,"");((b.info??"").trim().toLowerCase()==="bulb"||TC(v)!=null)&&a.push({start:b.map[0],end:b.map[1],source:v})}for(let b of kke(o))a.some(v=>b.start>=v.start&&b.start<v.end)||a.push({start:b.start,end:b.end,source:b.source});a.sort((b,v)=>b.start-v.start);let d=[],p=0;for(let b of a)b.start<p||(b.start>p&&d.push({kind:"md",text:s.slice(p,b.start).join(`
|
|
1448
1448
|
`)}),d.push({kind:"bulb",source:b.source}),p=b.end);return p<s.length&&d.push({kind:"md",text:s.slice(p).join(`
|
|
1449
1449
|
`)}),d}var qre=class extends v4{sessions=[];keepOpenSelector=".sid-wrap";filterId="session-filter";listSelector="#session-list";filterNoun="title";#e=new Map;#n=!1;#t=null;#r=new Map;search(s){return tb.server.searchSessions(s)}onActivate(s){let a=this.rows()[s];a&&this.pick(a.sessionId)}filtered(){let s=this.filter.trim().toLowerCase();return s?this.sessions.filter(a=>a.preview.toLowerCase().includes(s)):this.sessions}rows(){return this.searchActive?this.results:this.filtered()}currentIndex(){let s=this.rows(),a=s.findIndex(d=>d.sessionId===this.parent.sessionId);return a<0?s.length-1:a}async loadSessions(){this.sessions=(await tb.server.listSessions()).reverse(),this.#i(),this.parent.updateTitle()}#i(){let s=this.parent.sessionId;for(let a of this.sessions)(!this.#n||a.sessionId===s)&&this.#e.set(a.sessionId,a.mtime);this.#n=!0}#s(s){if(s.sessionId===this.parent.sessionId)return!1;let a=this.#e.get(s.sessionId);return a===void 0||s.mtime>a}onAttached(){this.loadSessions().then(()=>this.update()).catch(()=>{})}currentPreview(){return this.sessions.find(s=>s.sessionId===this.parent.sessionId)?.preview?.trim()??""}async show(){this.beginOpen(),this.refreshList(this.currentIndex()),this.focusFilter();try{await this.loadSessions(),this.refreshList(this.currentIndex())}catch(s){console.error("[mirror] listSessions failed",s)}this.armClose()}async pick(s){let a=this.rows().find(d=>d.sessionId===s);a&&this.#e.set(s,a.mtime),this.close(),this.parent.messageList.stickToBottomNextRender(),await tb.server.attach(s)}view(){let s=this.parent;if(s.sessionId===null)return $t({class:"sid-wrap"});let a=s.sessionId==="",d=a?"new conversation":this.currentPreview()||"current",p=Yee(d,25),b=`${s.cwd}
|
|
1450
|
-
${a?"New conversation \u2014 not saved yet":`Session: ${s.sessionId}`}`;return $t({class:"sid-wrap"},nc({class:"pill",title:b,onClick:v=>{v.stopPropagation(),this.open?this.close():this.show()}},p),this.open?this.picker():null)}picker(){let s=this.rows();return $t({class:"picker"},$t({class:"picker-body"},s.length===0?this.emptyState("No sessions yet \u2014 start one in your terminal."):$t({id:"session-list",class:"picker-list",onScroll:()=>this.onListScroll()},s.map((a,d)=>this.pickerRow(a,d))),this.peekCard()),this.filterBox(this.sessions.length,"session"))}pickerRow(s,a){let d=s.sessionId===this.parent.sessionId,p=this.parent.busy.includes(s.sessionId);return $t({class:["picker-row",a===this.highlighted?"active":"",d?"current":""],onMouseEnter:()=>{this.highlighted!==a&&(this.highlighted=a,this.update())},onClick:()=>this.pick(s.sessionId)},$t({class:"picker-row-main"},Ir({class:"picker-dot"}),Ir({class:["picker-preview",p?"shimmer-text shimmer-slow":""]},s.preview||"(no preview)"),zee(s.hitCount),Ir({class:["picker-time",this.#s(s)?"unseen":""],onMouseEnter:()=>this.#o(s),onMouseLeave:()=>this.#c(s)},Wee(s.mtime))),Kee(s.snippet,this.filter.trim()))}#o(s){this.#t=`${s.sessionId}:${s.mtime}`,this.#u(s.sessionId,this.#t),this.update()}#c(s){this.#t===`${s.sessionId}:${s.mtime}`&&(this.#t=null,this.update())}async#u(s,a){if(this.#r.has(a))return;let d="";try{d=String((await tb.server.sessionPeek(s))?.text??"")}catch{}this.#r.set(a,d),this.#t===a&&this.update()}peekCard(){if(!this.#t)return null;let s=this.#r.get(this.#t);return s===void 0?$t({class:"picker-peek muted"},"\u2026"):s?$t({class:"picker-peek md",key:`peek:${this.#t}`,onMounted:a=>{a.innerHTML=eD.render(s)}}):$t({class:"picker-peek muted"},"(no assistant text yet)")}onClosed(){super.onClosed(),this.#t=null}};var Jre=class extends Ia{get parent(){return this.ctx.parent}view(){let s=this.parent.tokens,a=this.parent.stats,d=a?a.contextTokens??0:s.in+s.out+s.cached+s.cacheCreate,p=a?.cost??this.parent.cost,b=this.parent.working,v=[];if(d>0&&v.push(p6t(d)),a&&a.contextPercent!=null&&v.push(`${Math.round(a.contextPercent)}%`),p>0&&v.push(`$${p>=1?p.toFixed(2):p.toFixed(3)}`),!v.length&&!b)return Ir({class:"token-wrap"});let w=v.length?v.length===1&&d>0?`${v[0]} tokens`:v.join(" \xB7 "):"working\u2026";return Ir({class:"token-wrap"},Ir({class:["token",b?"busy shimmer shimmer-slow":""]},w))}};var wSt={"play_arrow.fill":'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M320-200v-560l440 280-440 280Z"/></svg>',"stop.fill":'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M240-240v-480h480v480H240Z"/></svg>',play_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m380-300 280-180-280-180v360ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',stop_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M320-320h320v-320H320v320ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',add_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M440-280h80v-160h160v-80H520v-160h-80v160H280v80h160v160Zm40 200q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',attach_file:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M720-330q0 104-73 177T470-80q-104 0-177-73t-73-177v-370q0-75 52.5-127.5T400-880q75 0 127.5 52.5T580-700v350q0 46-32 78t-78 32q-46 0-78-32t-32-78v-370h80v370q0 13 8.5 21.5T470-320q13 0 21.5-8.5T500-350v-350q-1-42-29.5-71T400-800q-42 0-71 29t-29 71v370q-1 71 49 120.5T470-160q70 0 119-49.5T640-330v-390h80v390Z"/></svg>'};var hvn={play:"play_arrow.fill",stop:"stop.fill",playCircle:"play_circle",stopCircle:"stop_circle",addCircle:"add_circle",attach:"attach_file"},dvn={caret:'<svg viewBox="0 0 16 16"><path d="M4 1.5 L13 8 L4 14.5 Z" fill="currentColor"/></svg>',push:'<svg viewBox="0 0 16 16" fill="none"><path d="M8 11 V3 M4.75 6.25 L8 3 L11.25 6.25" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 14 H13" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>',pull:'<svg viewBox="0 0 16 16" fill="none"><path d="M8 3 V11 M4.75 7.75 L8 11 L11.25 7.75" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 14 H13" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>',check:'<svg viewBox="0 0 16 16" fill="none"><path d="M3 8.5 L6.5 12 L13 4.5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>',fork:'<svg viewBox="0 0 16 16" fill="none"><path d="M4 2 V8 H12 V2 M8 8 V14" stroke="currentColor" stroke-width="1.8" stroke-linecap="square"/></svg>',diff:'<svg viewBox="4 2 8 12" fill="none"><path d="M5.25 6 H10.75 M8 3.25 V8.75" stroke="var(--diff-add)" stroke-width="1.8" stroke-linecap="round"/><path d="M5.25 12.5 H10.75" stroke="var(--err)" stroke-width="1.8" stroke-linecap="round"/></svg>'},pvn=o=>{let s=dvn[o]??wSt[hvn[o]??""]??"";return/<svg[^>]*\bfill=/.test(s)?s:s.replace("<svg ",'<svg fill="currentColor" ')},U4=(o,s="")=>Ir({class:["icon",...Array.isArray(s)?s:[s]],key:`icon-${o}`,onMounted:a=>{a.innerHTML=pvn(o)}},"");var gvn=()=>U4("play","btn-icon"),bvn=()=>U4("stop","btn-icon"),mvn=o=>`typebulbs/u/samples/${o}.bulb.md`,nD=o=>Xh(o.path).match(/typebulbs\/u\/([^/]+)\//)?.[1],wvn=(o,s)=>`https://typebulb.com/u/${s}/${aM(o.path)}/full`,Ure=class extends v4{files=[];servers=[];samples=[];mine=[];myUser;keepOpenSelector=".servers-wrap";filterId="bulb-filter";listSelector=".bulb-list";filterNoun="name";launching=new Set;dismissedDenials=new Set;pendingLaunch;openLog;#e;spotlightPid;openFolds=new Set;pendingOverwrite;syncBusy=new Set;syncDone=new Set;search(s){return tb.server.searchBulbs(s)}onActivate(s){let a=this.rows()[s];a&&(a.group?this.toggleFold(a.group.user):a.running?window.open(a.running.url,"_blank","noopener"):a.remote?this.downloadAndLaunch(a):this.launch(a.path))}onAttached(){this.refresh(),setInterval(()=>this.refreshServers(),800),setInterval(()=>this.refreshFiles(),3e3),window.addEventListener("tb-breakout",s=>this.spotlight(s.detail?.pid))}spotlight(s){this.spotlightPid=s,this.show()}refresh(){return Promise.all([this.refreshServers(),this.refreshFiles(),this.refreshSamples(),this.refreshMine()])}async refreshServers(){try{let s=await tb.server.listBreakouts(),a=s.length!==this.servers.length||s.some((d,p)=>d.pid!==this.servers[p]?.pid||d.denied!==this.servers[p]?.denied||d.predicted!==this.servers[p]?.predicted||d.trust!==this.servers[p]?.trust);this.servers=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] server list refresh failed",s)}}async refreshFiles(){try{let s=await tb.server.listBulbFiles(),a=s.length!==this.files.length||s.some((d,p)=>d.path!==this.files[p]?.path||d.mtime!==this.files[p]?.mtime);this.files=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] bulb list refresh failed",s)}}async refreshSamples(){try{let s=await tb.server.listSamples(),a=s.length!==this.samples.length||s.some((d,p)=>d.slug!==this.samples[p]?.slug);this.samples=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] samples refresh failed",s)}}async refreshMine(){try{let{user:s,bulbs:a}=await tb.server.listMyBulbs(),d=s!==this.myUser||a.length!==this.mine.length||a.some((p,b)=>p.slug!==this.mine[b]?.slug);this.myUser=s,this.mine=a,d&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] my-bulbs refresh failed",s)}}merged(){let s=new Map,a=this.files.map(p=>Xh(p.path)),d=[...this.samples.map(p=>[mvn(p.slug),p]),...this.myUser?this.mine.map(p=>[`typebulbs/u/${this.myUser}/${p.slug}.bulb.md`,p]):[]];for(let[p,b]of d)a.some(v=>v.endsWith("/"+p))||s.set(p,{path:p,name:b.name,recent:0,remote:b});this.files.forEach((p,b)=>{s.set(a[b],{path:p.path,name:p.name,recent:p.mtime,trusted:p.trusted})});for(let p of this.servers){if(p.pid===this.parent.ownPid)continue;let b=Xh(p.file),v=aM(p.file)||p.file,w=s.get(b)??{path:p.file,name:v,recent:0};w.running=p,w.recent=Math.max(w.recent,p.startedAt),s.set(b,w)}return[...s.values()]}rows(){let s=this.merged();if(this.searchActive){let a=new Map(this.results.map(d=>[Xh(d.path),d]));s=s.flatMap(d=>{let p=a.get(Xh(d.path));return p?[{...d,hitCount:p.hitCount,snippet:p.snippet}]:[]})}else{let a=this.filter.trim().toLowerCase();a?s=s.filter(d=>d.name.toLowerCase().includes(a)||d.path.toLowerCase().includes(a)):[...new Set(s.filter(p=>p.remote).map(p=>nD(p)))].forEach((p,b)=>{let v=I=>!!I.remote&&nD(I)===p,w=s.filter(v).length;this.openFolds.has(p)||(s=s.filter(I=>!v(I))),s.push({path:`::${p}`,name:this.foldLabel(p),recent:-1-b,group:{user:p,count:w}})})}return s.sort((a,d)=>a.recent-d.recent)}show(){this.beginOpen(),this.refresh(),this.refreshList(),this.armClose(),this.focusFilter()}onClosed(){super.onClosed(),this.closeLog(),this.openFolds.clear(),this.pendingOverwrite=void 0,this.spotlightPid=void 0}toggleFold(s){this.openFolds.delete(s)||this.openFolds.add(s),this.update()}foldLabel(s){return s==="samples"?"samples from typebulb.com":s===this.myUser?"your typebulb.com bulbs":`${s} on typebulb.com`}foldTitle(s){return s==="samples"?"Runnable sample bulbs from typebulb.com \u2014 click to browse":`${s===this.myUser?"Your":`${s}'s`} bulbs on typebulb.com \u2014 click to browse; play pulls one into the project`}async launch(s){if(!this.files.find(d=>Xh(d.path)===Xh(s))?.trusted){let d;try{d=(await tb.server.predictTrustOf(s)).cap}catch(p){console.error("[mirror] predictTrustOf failed",p)}if(d){this.pendingLaunch={path:s,name:this.displayName(s),cap:d},this.update();return}}await this.doLaunch(s)}async downloadAndLaunch(s){let a=Xh(s.path);this.launching.add(a),this.update();try{let d=nD(s),p=d==="samples"?await tb.server.downloadSample(s.remote.slug):await tb.server.pullRemoteBulb(d,s.remote.slug);if(!p.ok||!p.file){console.error("[mirror] remote pull failed",p.error);return}await this.refreshFiles();let b=this.files.find(v=>Xh(v.path).endsWith("/"+Xh(p.file)))?.path??p.file;await this.launch(b)}catch(d){console.error("[mirror] remote pull failed",d)}finally{this.launching.delete(a),this.update()}}async syncRow(s,a,d=!1){let p=`${Xh(s.path)}:${a}`;this.syncBusy.add(p),this.update();try{let b=a==="pull"?await tb.server.pullRemoteBulb(nD(s),aM(s.path),d):await tb.server.pushLocalBulb(s.path,d);b.ok?this.tickDone(p):b.conflict?this.pendingOverwrite={...a==="pull"?{heading:`\u201C${s.name}\u201D has local changes`,body:"Your local file differs from the typebulb.com copy. Overwrite the local file with the site's version?",yesLabel:"Overwrite local"}:{heading:`The site copy of \u201C${s.name}\u201D changed`,body:"It changed since your last sync. Overwrite the typebulb.com copy with your local file?",yesLabel:"Overwrite site copy"},onYes:()=>this.syncRow(s,a,!0)}:console.error(`[mirror] ${a} failed`,b.error)}catch(b){console.error(`[mirror] ${a} failed`,b)}finally{this.syncBusy.delete(p)}await(a==="pull"?this.refreshFiles():this.refreshMine()),this.update()}tickDone(s){this.syncDone.add(s),setTimeout(()=>{this.syncDone.delete(s),this.update()},1200)}async doLaunch(s,a,d=!1){let p=Xh(s);this.launching.add(p),this.update();let b;try{b=(await tb.server.launchBulb(s,a)).pid}catch(v){console.error("[mirror] launchBulb failed",v)}finally{this.launching.delete(p)}d&&b&&this.dismissedDenials.add(b),await this.refresh(),this.pinToBottom()}displayName(s){return this.files.find(d=>Xh(d.path)===Xh(s))?.name||aM(s)||s}launchTrusted(){let s=this.pendingLaunch;this.pendingLaunch=void 0,s&&this.doLaunch(s.path,!0)}launchRestricted(){let s=this.pendingLaunch;this.pendingLaunch=void 0,s&&this.doLaunch(s.path,void 0,!0)}cancelLaunch(){this.pendingLaunch=void 0,this.update()}async stop(s){this.openLog?.pid===s&&this.closeLog(),this.dismissedDenials.delete(s);try{await tb.server.stopBreakout(s)}catch(a){console.error("[mirror] stopBreakout failed",a)}await this.refresh()}pendingDenial(){return this.servers.find(s=>s.denied&&s.pid!==this.parent.ownPid&&!this.dismissedDenials.has(s.pid))}async elevate(s){this.dismissedDenials.add(s.pid),this.openLog?.pid===s.pid&&this.closeLog();try{await tb.server.launchBulb(s.file,!0)}catch(a){console.error("[mirror] elevate failed",a)}await this.refresh()}dismissDenial(s){this.dismissedDenials.add(s),this.update()}async toggleTrust(s){let a=!(s.running?s.running.trust:s.trusted);try{await tb.server.setBulbTrust(s.path,a),s.running&&(this.openLog?.pid===s.running.pid&&this.closeLog(),await tb.server.launchBulb(s.path,a))}catch(d){console.error("[mirror] toggleTrust failed",d)}await this.refresh()}showLog(s,a){if(this.openLog?.pid===s.pid){this.closeLog();return}this.closeLog(),this.openLog={pid:s.pid,name:a,text:"",offset:0},this.update(),setTimeout(()=>document.getElementById("bulb-console")?.focus()),this.#n(),this.#e=setInterval(()=>this.#n(),700)}closeLog(){this.#e&&(clearInterval(this.#e),this.#e=void 0),this.openLog&&(this.openLog=void 0,this.update())}async#n(){let s=this.openLog;if(s)try{let{text:a,offset:d}=await tb.server.readBulbLog(s.pid,s.offset);if(this.openLog!==s)return;a?(s.text=(s.text+a).slice(-5e4),s.offset=d,this.update()):d!==s.offset&&(s.offset=d)}catch(a){console.error("[mirror] readBulbLog failed",a)}}view(){let s=this.servers.filter(p=>p.pid!==this.parent.ownPid).length;if(!(this.files.length>0||this.samples.length>0)&&s===0)return $t({class:"servers-wrap"});let d=this.pendingDenial();return $t({class:"servers-wrap"},nc({class:["pill",s>0?"":"glyph",this.open?"on":""],title:"Launch a project bulb \xB7 stop a running one",onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},s>0?`${s}\u{1F4A1}`:Ir({class:"glyph-img"},"\u{1F4A1}")),this.open?this.popup():null,this.pendingLaunch?this.launchModal(this.pendingLaunch):this.pendingOverwrite?this.overwriteModal(this.pendingOverwrite):d?this.denialModal(d):null)}overwriteModal(s){let a=()=>{this.pendingOverwrite=void 0,this.update()};return this.trustModal({heading:s.heading,body:s.body,warn:"There is no undo \u2014 the overwritten side's changes are gone.",noLabel:"Cancel",yesLabel:s.yesLabel,onNo:a,onYes:()=>{this.pendingOverwrite=void 0,s.onYes()},onDismiss:a})}trustModal(s){let a=(d,p)=>{d.stopPropagation(),p(),this.open&&this.focusFilter()};return $t({class:"trust-back",tabIndex:0,onMounted:d=>d.focus(),onKeyDown:d=>{d.key==="Escape"&&a(d,s.onDismiss)},onClick:d=>a(d,s.onDismiss)},$t({class:"trust-modal",onClick:d=>d.stopPropagation()},$t({class:"trust-modal-h"},s.heading),$t({class:"trust-modal-b"},s.body),$t({class:"trust-modal-warn"},s.warn),$t({class:"trust-modal-acts"},nc({class:"trust-no",onClick:d=>a(d,s.onNo)},s.noLabel),nc({class:"trust-yes",onClick:d=>a(d,s.onYes)},s.yesLabel))))}launchModal(s){return this.trustModal({heading:`\u201C${s.name}\u201D will likely need access`,body:`It looks like it uses ${s.cap}, which is blocked unless you launch it Trusted. Launch Trusted to allow filesystem / AI / server.ts?`,warn:"Only trust bulbs you wrote or have read \u2014 be careful with anything off the internet.",noLabel:"Launch restricted",yesLabel:"Launch trusted",onNo:()=>this.launchRestricted(),onYes:()=>this.launchTrusted(),onDismiss:()=>this.cancelLaunch()})}denialModal(s){let a=aM(s.file)||s.file,d=!s.predicted;return this.trustModal({heading:d?`\u201C${a}\u201D reached for access it didn't declare`:`\u201C${a}\u201D wants more access`,body:d?`It tried to use ${s.denied} at runtime, though nothing in its code obviously needed it. Relaunch it Trusted to allow filesystem / AI / server.ts?`:`It tried to use ${s.denied}, blocked while it's restricted. Relaunch it Trusted to allow filesystem / AI / server.ts?`,warn:d?"Code that reaches for capabilities it never visibly uses can be hiding something \u2014 only continue if you wrote this bulb or have read it.":"Only trust bulbs you wrote or have read \u2014 be careful with anything off the internet.",noLabel:"Keep restricted",yesLabel:"Trust & relaunch",onNo:()=>this.dismissDenial(s.pid),onYes:()=>this.elevate(s),onDismiss:()=>this.dismissDenial(s.pid)})}popup(){if(this.openLog)return this.consoleView(this.openLog);let s=this.rows(),a=this.spotlightPid,d=a!==void 0&&s.some(p=>p.running?.pid===a);return $t({class:"servers-pop"},s.length===0?this.emptyState("No bulbs in this project yet."):$t({class:"bulb-list",onScroll:()=>this.onListScroll()},s.map((p,b)=>this.row(p,b,d&&p.running?.pid!==a))),this.filterBox(this.merged().filter(p=>!p.remote).length,"bulb"))}consoleView(s){return $t({id:"bulb-console",class:"servers-pop log-mode",tabIndex:0,onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeLog())}},$t({class:"bulb-log-head"},Ir({class:"bulb-log-name"},`console \xB7 ${s.name}`),nc({class:"bulb-log-back",title:"Back to the bulb list",onClick:a=>{a.stopPropagation(),this.closeLog()}},"\u2190 bulbs")),i6({class:"bulb-log-body"},Ir({class:"bulb-log-text"},s.text||"(no output yet)")))}hoverRow(s,a){let d=a!==void 0&&a.pid===this.spotlightPid;d&&(this.spotlightPid=void 0),(this.highlighted!==s||d)&&(this.highlighted=s,this.update())}row(s,a,d=!1){if(s.group)return this.groupRow(s,a,d);let p=s.running,b=p&&this.openLog?.pid===p.pid,v=p?!!p.trust:!!s.trusted;return $t({class:["server-row",a===this.highlighted?"active":"",d?"dimmed":""],onMouseEnter:()=>this.hoverRow(a,p)},p?nc({class:"server-stop",title:"Stop this server",ariaLabel:"Stop",onClick:w=>{w.stopPropagation(),this.stop(p.pid)}},bvn()):nc({class:["bulb-launch",this.launching.has(Xh(s.path))?"launching shimmer":""],title:s.remote?"Download from typebulb.com & launch":v?"Launch (trusted \u2014 remembered)":"Launch (restricted)",ariaLabel:"Launch",onClick:w=>{w.stopPropagation(),s.remote?this.downloadAndLaunch(s):this.launch(s.path)}},gvn()),$t({class:"bulb-name-cell"},s.remote?Ir({class:"server-name stopped remote",title:s.remote.description},s.name):Ir({class:["server-name",p?"":"stopped"],title:`Open ${s.path}`,onClick:w=>{w.stopPropagation(),tb.server.openFile(s.path)}},s.name),this.userLink(s),zee(s.hitCount)),this.syncCell(s),p||v?this.trustToggle(s,v):Ir({class:"cell-empty"}),p?pC({class:["server-logs",b?"on":""],title:"Show this server\u2019s console",onClick:w=>{w.stopPropagation(),this.showLog(p,s.name)}},"logs"):Ir({class:"cell-empty"}),p?pC({class:"server-port",href:p.url,target:"_blank",rel:"noopener noreferrer",title:`Open ${p.url}`},`:${p.port}`):s.remote?Ir({class:"cell-empty"}):Ir({class:"bulb-time"},Wee(s.recent)),Kee(s.snippet,this.filter.trim()))}userLink(s){let a=nD(s);return a?pC({class:"sample-link",href:wvn(s,a),target:"_blank",rel:"noopener noreferrer",title:"Open this bulb's page on typebulb.com"},a):null}syncCell(s){let a=nD(s);if(!a||s.remote)return Ir({class:"cell-empty"});let d=(p,b)=>{let v=`${Xh(s.path)}:${p}`,w=this.syncBusy.has(v),I=this.syncDone.has(v);return nc({class:["sync-btn",w?"busy shimmer":"",I?"done":""],title:b,ariaLabel:p,onClick:T=>{T.stopPropagation(),w||this.syncRow(s,p)}},U4(I?"check":p,"btn-icon-sm"))};return Ir({class:"sync-cell"},d("pull",`Pull \u2014 update the local file from typebulb.com/u/${a}`),a===this.myUser?d("push","Push \u2014 upload this file to typebulb.com"):null)}groupRow(s,a,d){let{user:p,count:b}=s.group,v=this.openFolds.has(p);return $t({class:["server-row","sample-group",a===this.highlighted?"active":"",d?"dimmed":""],title:v?"Collapse":this.foldTitle(p),onMouseEnter:()=>this.hoverRow(a),onClick:w=>{w.stopPropagation(),this.toggleFold(p)}},U4("caret",["caret-tri",v?"open":""]),Ir({class:"sample-group-label"},`${s.name} (${b})`))}trustToggle(s,a){return nc({class:["trust-toggle",a?"on":""],title:`${a?"Trusted":"Restricted"} \u2014 click to switch to ${a?"restricted":"trusted"}`+(s.running?" (stops + relaunches it)":""),onClick:d=>{d.stopPropagation(),this.toggleTrust(s)}},a?"trusted":"restricted")}};var zre=class extends Ia{get parent(){return this.ctx.parent}view(){let s=this.parent.prose;return nc({class:["pill","glyph",s?"on":""],title:s?"Trace view":"Content view",onClick:()=>{this.parent.prose=!s,this.update()}},Ir({class:"glyph-img"},"\u{1F648}"))}};var Avn=4e5;function vvn(o,s){let a=o.split(`
|
|
1450
|
+
${a?"New conversation \u2014 not saved yet":`Session: ${s.sessionId}`}`;return $t({class:"sid-wrap"},nc({class:"pill",title:b,onClick:v=>{v.stopPropagation(),this.open?this.close():this.show()}},p),this.open?this.picker():null)}picker(){let s=this.rows();return $t({class:"picker"},$t({class:"picker-body"},s.length===0?this.emptyState("No sessions yet \u2014 start one in your terminal."):$t({id:"session-list",class:"picker-list",onScroll:()=>this.onListScroll()},s.map((a,d)=>this.pickerRow(a,d))),this.peekCard()),this.filterBox(this.sessions.length,"session"))}pickerRow(s,a){let d=s.sessionId===this.parent.sessionId,p=this.parent.busy.includes(s.sessionId);return $t({class:["picker-row",a===this.highlighted?"active":"",d?"current":""],onMouseEnter:()=>{this.highlighted!==a&&(this.highlighted=a,this.update())},onClick:()=>this.pick(s.sessionId)},$t({class:"picker-row-main"},Ir({class:"picker-dot"}),Ir({class:["picker-preview",p?"shimmer-text shimmer-slow":""]},s.preview||"(no preview)"),zee(s.hitCount),Ir({class:["picker-time",this.#s(s)?"unseen":""],onMouseEnter:()=>this.#o(s),onMouseLeave:()=>this.#c(s)},Wee(s.mtime))),Kee(s.snippet,this.filter.trim()))}#o(s){this.#t=`${s.sessionId}:${s.mtime}`,this.#u(s.sessionId,this.#t),this.update()}#c(s){this.#t===`${s.sessionId}:${s.mtime}`&&(this.#t=null,this.update())}async#u(s,a){if(this.#r.has(a))return;let d="";try{d=String((await tb.server.sessionPeek(s))?.text??"")}catch{}this.#r.set(a,d),this.#t===a&&this.update()}peekCard(){if(!this.#t)return null;let s=this.#r.get(this.#t);return s===void 0?$t({class:"picker-peek muted"},"\u2026"):s?$t({class:"picker-peek md",key:`peek:${this.#t}`,onMounted:a=>{a.innerHTML=eD.render(s)}}):$t({class:"picker-peek muted"},"(no assistant text yet)")}onClosed(){super.onClosed(),this.#t=null}};var Jre=class extends Ia{get parent(){return this.ctx.parent}view(){let s=this.parent.tokens,a=this.parent.stats,d=a?a.contextTokens??0:s.in+s.out+s.cached+s.cacheCreate,p=a?.cost??this.parent.cost,b=this.parent.working,v=[];if(d>0&&v.push(p6t(d)),a&&a.contextPercent!=null&&v.push(`${Math.round(a.contextPercent)}%`),p>0&&v.push(`$${p>=1?p.toFixed(2):p.toFixed(3)}`),!v.length&&!b)return Ir({class:"token-wrap"});let w=v.length?v.length===1&&d>0?`${v[0]} tokens`:v.join(" \xB7 "):"working\u2026";return Ir({class:"token-wrap"},Ir({class:["token",b?"busy shimmer shimmer-slow":""]},w))}};var wSt={"play_arrow.fill":'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M320-200v-560l440 280-440 280Z"/></svg>',"stop.fill":'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M240-240v-480h480v480H240Z"/></svg>',play_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m380-300 280-180-280-180v360ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',stop_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M320-320h320v-320H320v320ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',add_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M440-280h80v-160h160v-80H520v-160h-80v160H280v80h160v160Zm40 200q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',attach_file:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M720-330q0 104-73 177T470-80q-104 0-177-73t-73-177v-370q0-75 52.5-127.5T400-880q75 0 127.5 52.5T580-700v350q0 46-32 78t-78 32q-46 0-78-32t-32-78v-370h80v370q0 13 8.5 21.5T470-320q13 0 21.5-8.5T500-350v-350q-1-42-29.5-71T400-800q-42 0-71 29t-29 71v370q-1 71 49 120.5T470-160q70 0 119-49.5T640-330v-390h80v390Z"/></svg>'};var hvn={play:"play_arrow.fill",stop:"stop.fill",playCircle:"play_circle",stopCircle:"stop_circle",addCircle:"add_circle",attach:"attach_file"},dvn={caret:'<svg viewBox="0 0 16 16"><path d="M4 1.5 L13 8 L4 14.5 Z" fill="currentColor"/></svg>',push:'<svg viewBox="0 0 16 16" fill="none"><path d="M8 11 V3 M4.75 6.25 L8 3 L11.25 6.25" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 14 H13" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>',pull:'<svg viewBox="0 0 16 16" fill="none"><path d="M8 3 V11 M4.75 7.75 L8 11 L11.25 7.75" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 14 H13" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>',check:'<svg viewBox="0 0 16 16" fill="none"><path d="M3 8.5 L6.5 12 L13 4.5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>',fork:'<svg viewBox="0 0 16 16" fill="none"><path d="M4 2 V8 H12 V2 M8 8 V14" stroke="currentColor" stroke-width="1.8" stroke-linecap="square"/></svg>',diff:'<svg viewBox="4 2 8 12" fill="none"><path d="M5.25 6 H10.75 M8 3.25 V8.75" stroke="var(--diff-add)" stroke-width="1.8" stroke-linecap="round"/><path d="M5.25 12.5 H10.75" stroke="var(--err)" stroke-width="1.8" stroke-linecap="round"/></svg>'},pvn=o=>{let s=dvn[o]??wSt[hvn[o]??""]??"";return/<svg[^>]*\bfill=/.test(s)?s:s.replace("<svg ",'<svg fill="currentColor" ')},U4=(o,s="")=>Ir({class:["icon",...Array.isArray(s)?s:[s]],key:`icon-${o}`,onMounted:a=>{a.innerHTML=pvn(o)}},"");var gvn=()=>U4("play","btn-icon"),bvn=()=>U4("stop","btn-icon"),mvn=o=>`typebulbs/u/samples/${o}.bulb.md`,nD=o=>Xh(o.path).match(/typebulbs\/u\/([^/]+)\//)?.[1],wvn=(o,s)=>`https://typebulb.com/u/${s}/${aM(o.path)}/full`,Ure=class extends v4{files=[];servers=[];samples=[];mine=[];myUser;keepOpenSelector=".servers-wrap";filterId="bulb-filter";listSelector=".bulb-list";filterNoun="name";launching=new Set;dismissedDenials=new Set;pendingLaunch;openLog;#e;spotlightPid;openFolds=new Set;pendingOverwrite;syncBusy=new Set;syncDone=new Set;search(s){return tb.server.searchBulbs(s)}onActivate(s){let a=this.rows()[s];a&&(a.group?this.toggleFold(a.group.user):a.running?window.open(a.running.url,"_blank","noopener"):a.remote?this.downloadAndLaunch(a):this.launch(a.path))}onAttached(){this.refresh(),setInterval(()=>this.refreshServers(),800),setInterval(()=>this.refreshFiles(),3e3),window.addEventListener("tb-breakout",s=>this.spotlight(s.detail?.pid))}spotlight(s){this.spotlightPid=s,this.show()}refresh(){return Promise.all([this.refreshServers(),this.refreshFiles(),this.refreshSamples(),this.refreshMine()])}async refreshServers(){try{let s=await tb.server.listBreakouts(),a=s.length!==this.servers.length||s.some((d,p)=>d.pid!==this.servers[p]?.pid||d.denied!==this.servers[p]?.denied||d.predicted!==this.servers[p]?.predicted||d.trust!==this.servers[p]?.trust);this.servers=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] server list refresh failed",s)}}async refreshFiles(){try{let s=await tb.server.listBulbFiles(),a=s.length!==this.files.length||s.some((d,p)=>d.path!==this.files[p]?.path||d.mtime!==this.files[p]?.mtime);this.files=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] bulb list refresh failed",s)}}async refreshSamples(){try{let s=await tb.server.listSamples(),a=s.length!==this.samples.length||s.some((d,p)=>d.slug!==this.samples[p]?.slug);this.samples=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] samples refresh failed",s)}}async refreshMine(){try{let{user:s,bulbs:a}=await tb.server.listMyBulbs(),d=s!==this.myUser||a.length!==this.mine.length||a.some((p,b)=>p.slug!==this.mine[b]?.slug);this.myUser=s,this.mine=a,d&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] my-bulbs refresh failed",s)}}merged(){let s=new Map,a=this.files.map(p=>Xh(p.path)),d=[...this.samples.map(p=>[mvn(p.slug),p]),...this.myUser?this.mine.map(p=>[`typebulbs/u/${this.myUser}/${p.slug}.bulb.md`,p]):[]];for(let[p,b]of d)a.some(v=>v.endsWith("/"+p))||s.set(p,{path:p,name:b.name,recent:0,remote:b});this.files.forEach((p,b)=>{s.set(a[b],{path:p.path,name:p.name,recent:p.mtime,trusted:p.trusted})});for(let p of this.servers){if(p.pid===this.parent.ownPid)continue;let b=Xh(p.file),v=aM(p.file)||p.file,w=s.get(b)??{path:p.file,name:v,recent:0};w.running=p,w.recent=Math.max(w.recent,p.startedAt),s.set(b,w)}return[...s.values()]}rows(){let s=this.merged();if(this.searchActive){let a=new Map(this.results.map(d=>[Xh(d.path),d]));s=s.flatMap(d=>{let p=a.get(Xh(d.path));return p?[{...d,hitCount:p.hitCount,snippet:p.snippet}]:[]})}else{let a=this.filter.trim().toLowerCase();a?s=s.filter(d=>d.name.toLowerCase().includes(a)||d.path.toLowerCase().includes(a)):[...new Set(s.filter(p=>p.remote).map(p=>nD(p)))].forEach((p,b)=>{let v=I=>!!I.remote&&nD(I)===p,w=s.filter(v).length;this.openFolds.has(p)?s=s.map(I=>v(I)?{...I,recent:-.5-b}:I):s=s.filter(I=>!v(I)),s.push({path:`::${p}`,name:this.foldLabel(p),recent:-1-b,group:{user:p,count:w}})})}return s.sort((a,d)=>a.recent-d.recent)}show(){this.beginOpen(),this.refresh(),this.refreshList(),this.armClose(),this.focusFilter()}onClosed(){super.onClosed(),this.closeLog(),this.openFolds.clear(),this.pendingOverwrite=void 0,this.spotlightPid=void 0}toggleFold(s){this.openFolds.delete(s)||this.openFolds.add(s),this.update()}foldLabel(s){return s==="samples"?"Samples from typebulb.com":s===this.myUser?"Your typebulb.com bulbs":`${s} on typebulb.com`}foldTitle(s){return s==="samples"?"Runnable sample bulbs from typebulb.com \u2014 click to browse":`${s===this.myUser?"Your":`${s}'s`} bulbs on typebulb.com \u2014 click to browse; play pulls one into the project`}async launch(s){if(!this.files.find(d=>Xh(d.path)===Xh(s))?.trusted){let d;try{d=(await tb.server.predictTrustOf(s)).cap}catch(p){console.error("[mirror] predictTrustOf failed",p)}if(d){this.pendingLaunch={path:s,name:this.displayName(s),cap:d},this.update();return}}await this.doLaunch(s)}async downloadAndLaunch(s){let a=Xh(s.path);this.launching.add(a),this.update();try{let d=nD(s),p=d==="samples"?await tb.server.downloadSample(s.remote.slug):await tb.server.pullRemoteBulb(d,s.remote.slug);if(!p.ok||!p.file){console.error("[mirror] remote pull failed",p.error);return}await this.refreshFiles();let b=this.files.find(v=>Xh(v.path).endsWith("/"+Xh(p.file)))?.path??p.file;await this.launch(b)}catch(d){console.error("[mirror] remote pull failed",d)}finally{this.launching.delete(a),this.update()}}async syncRow(s,a,d=!1){let p=`${Xh(s.path)}:${a}`;this.syncBusy.add(p),this.update();try{let b=a==="pull"?await tb.server.pullRemoteBulb(nD(s),aM(s.path),d):await tb.server.pushLocalBulb(s.path,d);b.ok?this.tickDone(p):b.conflict?this.pendingOverwrite={...a==="pull"?{heading:`\u201C${s.name}\u201D has local changes`,body:"Your local file differs from the typebulb.com copy. Overwrite the local file with the site's version?",yesLabel:"Overwrite local"}:{heading:`The site copy of \u201C${s.name}\u201D changed`,body:"It changed since your last sync. Overwrite the typebulb.com copy with your local file?",yesLabel:"Overwrite site copy"},onYes:()=>this.syncRow(s,a,!0)}:console.error(`[mirror] ${a} failed`,b.error)}catch(b){console.error(`[mirror] ${a} failed`,b)}finally{this.syncBusy.delete(p)}await(a==="pull"?this.refreshFiles():this.refreshMine()),this.update()}tickDone(s){this.syncDone.add(s),setTimeout(()=>{this.syncDone.delete(s),this.update()},1200)}async doLaunch(s,a,d=!1){let p=Xh(s);this.launching.add(p),this.update();let b;try{b=(await tb.server.launchBulb(s,a)).pid}catch(v){console.error("[mirror] launchBulb failed",v)}finally{this.launching.delete(p)}d&&b&&this.dismissedDenials.add(b),await this.refresh(),this.pinToBottom()}displayName(s){return this.files.find(d=>Xh(d.path)===Xh(s))?.name||aM(s)||s}launchTrusted(){let s=this.pendingLaunch;this.pendingLaunch=void 0,s&&this.doLaunch(s.path,!0)}launchRestricted(){let s=this.pendingLaunch;this.pendingLaunch=void 0,s&&this.doLaunch(s.path,void 0,!0)}cancelLaunch(){this.pendingLaunch=void 0,this.update()}async stop(s){this.openLog?.pid===s&&this.closeLog(),this.dismissedDenials.delete(s);try{await tb.server.stopBreakout(s)}catch(a){console.error("[mirror] stopBreakout failed",a)}await this.refresh()}pendingDenial(){return this.servers.find(s=>s.denied&&s.pid!==this.parent.ownPid&&!this.dismissedDenials.has(s.pid))}async elevate(s){this.dismissedDenials.add(s.pid),this.openLog?.pid===s.pid&&this.closeLog();try{await tb.server.launchBulb(s.file,!0)}catch(a){console.error("[mirror] elevate failed",a)}await this.refresh()}dismissDenial(s){this.dismissedDenials.add(s),this.update()}async toggleTrust(s){let a=!(s.running?s.running.trust:s.trusted);try{await tb.server.setBulbTrust(s.path,a),s.running&&(this.openLog?.pid===s.running.pid&&this.closeLog(),await tb.server.launchBulb(s.path,a))}catch(d){console.error("[mirror] toggleTrust failed",d)}await this.refresh()}showLog(s,a){if(this.openLog?.pid===s.pid){this.closeLog();return}this.closeLog(),this.openLog={pid:s.pid,name:a,text:"",offset:0},this.update(),setTimeout(()=>document.getElementById("bulb-console")?.focus()),this.#n(),this.#e=setInterval(()=>this.#n(),700)}closeLog(){this.#e&&(clearInterval(this.#e),this.#e=void 0),this.openLog&&(this.openLog=void 0,this.update())}async#n(){let s=this.openLog;if(s)try{let{text:a,offset:d}=await tb.server.readBulbLog(s.pid,s.offset);if(this.openLog!==s)return;a?(s.text=(s.text+a).slice(-5e4),s.offset=d,this.update()):d!==s.offset&&(s.offset=d)}catch(a){console.error("[mirror] readBulbLog failed",a)}}view(){let s=this.servers.filter(p=>p.pid!==this.parent.ownPid).length;if(!(this.files.length>0||this.samples.length>0)&&s===0)return $t({class:"servers-wrap"});let d=this.pendingDenial();return $t({class:"servers-wrap"},nc({class:["pill",s>0?"":"glyph",this.open?"on":""],title:"Launch a project bulb \xB7 stop a running one",onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},s>0?`${s}\u{1F4A1}`:Ir({class:"glyph-img"},"\u{1F4A1}")),this.open?this.popup():null,this.pendingLaunch?this.launchModal(this.pendingLaunch):this.pendingOverwrite?this.overwriteModal(this.pendingOverwrite):d?this.denialModal(d):null)}overwriteModal(s){let a=()=>{this.pendingOverwrite=void 0,this.update()};return this.trustModal({heading:s.heading,body:s.body,warn:"There is no undo \u2014 the overwritten side's changes are gone.",noLabel:"Cancel",yesLabel:s.yesLabel,onNo:a,onYes:()=>{this.pendingOverwrite=void 0,s.onYes()},onDismiss:a})}trustModal(s){let a=(d,p)=>{d.stopPropagation(),p(),this.open&&this.focusFilter()};return $t({class:"trust-back",tabIndex:0,onMounted:d=>d.focus(),onKeyDown:d=>{d.key==="Escape"&&a(d,s.onDismiss)},onClick:d=>a(d,s.onDismiss)},$t({class:"trust-modal",onClick:d=>d.stopPropagation()},$t({class:"trust-modal-h"},s.heading),$t({class:"trust-modal-b"},s.body),$t({class:"trust-modal-warn"},s.warn),$t({class:"trust-modal-acts"},nc({class:"trust-no",onClick:d=>a(d,s.onNo)},s.noLabel),nc({class:"trust-yes",onClick:d=>a(d,s.onYes)},s.yesLabel))))}launchModal(s){return this.trustModal({heading:`\u201C${s.name}\u201D will likely need access`,body:`It looks like it uses ${s.cap}, which is blocked unless you launch it Trusted. Launch Trusted to allow filesystem / AI / server.ts?`,warn:"Only trust bulbs you wrote or have read \u2014 be careful with anything off the internet.",noLabel:"Launch restricted",yesLabel:"Launch trusted",onNo:()=>this.launchRestricted(),onYes:()=>this.launchTrusted(),onDismiss:()=>this.cancelLaunch()})}denialModal(s){let a=aM(s.file)||s.file,d=!s.predicted;return this.trustModal({heading:d?`\u201C${a}\u201D reached for access it didn't declare`:`\u201C${a}\u201D wants more access`,body:d?`It tried to use ${s.denied} at runtime, though nothing in its code obviously needed it. Relaunch it Trusted to allow filesystem / AI / server.ts?`:`It tried to use ${s.denied}, blocked while it's restricted. Relaunch it Trusted to allow filesystem / AI / server.ts?`,warn:d?"Code that reaches for capabilities it never visibly uses can be hiding something \u2014 only continue if you wrote this bulb or have read it.":"Only trust bulbs you wrote or have read \u2014 be careful with anything off the internet.",noLabel:"Keep restricted",yesLabel:"Trust & relaunch",onNo:()=>this.dismissDenial(s.pid),onYes:()=>this.elevate(s),onDismiss:()=>this.dismissDenial(s.pid)})}popup(){if(this.openLog)return this.consoleView(this.openLog);let s=this.rows(),a=this.spotlightPid,d=a!==void 0&&s.some(p=>p.running?.pid===a);return $t({class:"servers-pop"},s.length===0?this.emptyState("No bulbs in this project yet."):$t({class:"bulb-list",onScroll:()=>this.onListScroll()},s.map((p,b)=>this.row(p,b,d&&p.running?.pid!==a))),this.filterBox(this.merged().filter(p=>!p.remote).length,"bulb"))}consoleView(s){return $t({id:"bulb-console",class:"servers-pop log-mode",tabIndex:0,onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeLog())}},$t({class:"bulb-log-head"},Ir({class:"bulb-log-name"},`console \xB7 ${s.name}`),nc({class:"bulb-log-back",title:"Back to the bulb list",onClick:a=>{a.stopPropagation(),this.closeLog()}},"\u2190 bulbs")),i6({class:"bulb-log-body"},Ir({class:"bulb-log-text"},s.text||"(no output yet)")))}hoverRow(s,a){let d=a!==void 0&&a.pid===this.spotlightPid;d&&(this.spotlightPid=void 0),(this.highlighted!==s||d)&&(this.highlighted=s,this.update())}row(s,a,d=!1){if(s.group)return this.groupRow(s,a,d);let p=s.running,b=p&&this.openLog?.pid===p.pid,v=p?!!p.trust:!!s.trusted,w=!!s.remote&&!this.searchActive&&!this.filter.trim();return $t({class:["server-row",w?"fold-row":"",a===this.highlighted?"active":"",d?"dimmed":""],onMouseEnter:()=>this.hoverRow(a,p)},p?nc({class:"server-stop",title:"Stop this server",ariaLabel:"Stop",onClick:I=>{I.stopPropagation(),this.stop(p.pid)}},bvn()):nc({class:["bulb-launch",this.launching.has(Xh(s.path))?"launching shimmer":""],title:s.remote?"Download from typebulb.com & launch":v?"Launch (trusted \u2014 remembered)":"Launch (restricted)",ariaLabel:"Launch",onClick:I=>{I.stopPropagation(),s.remote?this.downloadAndLaunch(s):this.launch(s.path)}},gvn()),$t({class:"bulb-name-cell"},s.remote?Ir({class:"server-name stopped remote",title:s.remote.description},s.name):Ir({class:["server-name",p?"":"stopped"],title:`Open ${s.path}`,onClick:I=>{I.stopPropagation(),tb.server.openFile(s.path)}},s.name),this.userLink(s),zee(s.hitCount)),this.syncCell(s),p||v?this.trustToggle(s,v):Ir({class:"cell-empty"}),p?pC({class:["server-logs",b?"on":""],title:"Show this server\u2019s console",onClick:I=>{I.stopPropagation(),this.showLog(p,s.name)}},"logs"):Ir({class:"cell-empty"}),p?pC({class:"server-port",href:p.url,target:"_blank",rel:"noopener noreferrer",title:`Open ${p.url}`},`:${p.port}`):s.remote?Ir({class:"cell-empty"}):Ir({class:"bulb-time"},Wee(s.recent)),Kee(s.snippet,this.filter.trim()))}userLink(s){let a=nD(s);return a?pC({class:"sample-link",href:wvn(s,a),target:"_blank",rel:"noopener noreferrer",title:"Open this bulb's page on typebulb.com"},a):null}syncCell(s){let a=nD(s);if(!a||s.remote)return Ir({class:"cell-empty"});let d=(p,b)=>{let v=`${Xh(s.path)}:${p}`,w=this.syncBusy.has(v),I=this.syncDone.has(v);return nc({class:["sync-btn",w?"busy shimmer":"",I?"done":""],title:b,ariaLabel:p,onClick:T=>{T.stopPropagation(),w||this.syncRow(s,p)}},U4(I?"check":p,"btn-icon-sm"))};return Ir({class:"sync-cell"},d("pull",`Pull \u2014 update the local file from typebulb.com/u/${a}`),a===this.myUser?d("push","Push \u2014 upload this file to typebulb.com"):null)}groupRow(s,a,d){let{user:p,count:b}=s.group,v=this.openFolds.has(p);return $t({class:["server-row","sample-group",v?"open":"",a===this.highlighted?"active":"",d?"dimmed":""],title:v?"Collapse":this.foldTitle(p),onMouseEnter:()=>this.hoverRow(a),onClick:w=>{w.stopPropagation(),this.toggleFold(p)}},U4("caret",["caret-tri",v?"open":""]),Ir({class:"sample-group-label"},`${s.name} (${b})`))}trustToggle(s,a){return nc({class:["trust-toggle",a?"on":""],title:`${a?"Trusted":"Restricted"} \u2014 click to switch to ${a?"restricted":"trusted"}`+(s.running?" (stops + relaunches it)":""),onClick:d=>{d.stopPropagation(),this.toggleTrust(s)}},a?"trusted":"restricted")}};var zre=class extends Ia{get parent(){return this.ctx.parent}view(){let s=this.parent.prose;return nc({class:["pill","glyph",s?"on":""],title:s?"Trace view":"Content view",onClick:()=>{this.parent.prose=!s,this.update()}},Ir({class:"glyph-img"},"\u{1F648}"))}};var Avn=4e5;function vvn(o,s){let a=o.split(`
|
|
1451
1451
|
`).map(v=>v.replace(/\r$/,""));if(a.length&&a[a.length-1]===""&&a.pop(),s)return a.map(v=>({kind:"add",text:v}));let d=[],p=!1,b=!1;for(let v of a){if(v.startsWith("@@")){b&&d.push({kind:"gap",text:"\u22EF"}),b=!0,p=!0;continue}if(!p){v.startsWith("Binary file")&&d.push({kind:"ctx",text:v});continue}v.startsWith("\\")||(v.startsWith("+")?d.push({kind:"add",text:v.slice(1)}):v.startsWith("-")?d.push({kind:"del",text:v.slice(1)}):d.push({kind:"ctx",text:v.slice(1)}))}return d}function yvn(o,s,a){let d=vvn(o,s),p=o.length>Avn?"txt":a.split(".").pop()??"",b=[],v=[];for(let P of d)(P.kind==="ctx"||P.kind==="del")&&b.push(P.text),(P.kind==="ctx"||P.kind==="add")&&v.push(P.text);let w=Gxe(b.join(`
|
|
1452
1452
|
`),p),I=Gxe(v.join(`
|
|
1453
1453
|
`),p),T=0,B=0,D=[];for(let P of d){if(P.kind==="gap"){D.push('<div class="udiff-gap">\u22EF</div>');continue}let F=P.kind==="del"?w[T++]:(P.kind==="add"||T++,I[B++]);D.push(`<div class="udiff-line${P.kind==="add"?" udiff-add":P.kind==="del"?" udiff-del":""}">${F??""}</div>`)}return{kinds:d.map(P=>P.kind),bodyHtml:D.join("")}}var Kre=class extends v4{files=[];repo=!0;root="";viewing;#e=0;#n=!1;keepOpenSelector=".gitdiff-wrap";filterId="gitdiff-filter";listSelector=".gitdiff-list";filterNoun="file";search(){return Promise.resolve([])}onActivate(s){let a=this.rows()[s];a&&this.openDiff(a)}onAttached(){this.refreshFiles(),setInterval(()=>this.refreshFiles(),3e3),setInterval(()=>{this.viewing&&this.refreshDiff()},1500)}rows(){let s=this.filter.trim().toLowerCase();return s?this.files.filter(a=>a.path.toLowerCase().includes(s)):this.files}async refreshFiles(){try{let{repo:s,root:a,files:d}=await tb.server.gitChangedFiles(),p=s!==this.repo||d.length!==this.files.length||d.some((b,v)=>{let w=this.files[v];return b.path!==w?.path||b.status!==w.status||b.add!==w.add||b.del!==w.del});this.repo=s,this.root=a,this.files=d,p&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] gitChangedFiles failed",s)}}#t(s,a,d){this.viewing={path:s,status:a,text:d.text,truncated:!!d.truncated,...yvn(d.text,!!d.untracked,s)},this.#e++,this.update()}async openDiff(s){try{let a=await tb.server.gitDiff(s.path);if(!a.ok){console.error("[mirror] gitDiff failed:",a.error);return}this.#t(s.path,s.status,a),this.#n=!0,this.close()}catch(a){console.error("[mirror] gitDiff failed",a)}}async refreshDiff(){let s=this.viewing;if(s)try{let a=await tb.server.gitDiff(s.path);if(this.viewing!==s||!a.ok||a.text===s.text)return;this.#t(s.path,s.status,a)}catch(a){console.error("[mirror] gitDiff refresh failed",a)}}closeDoc(){this.viewing=void 0,this.update()}show(){this.beginOpen(),this.refreshFiles(),this.refreshList(),this.armClose(),this.focusFilter()}view(){let s=this.files.length;return!this.repo||s===0&&!this.viewing&&!this.open?$t({class:"gitdiff-wrap"}):$t({class:"gitdiff-wrap"},nc({class:["pill","glyph","gitdiff-pill",this.viewing||this.open?"on":""],title:`${s} changed file${s===1?"":"s"} \u2014 view a diff`,onClick:a=>{a.stopPropagation(),this.open?this.close():this.show()}},U4("diff"),Ir({class:"gitdiff-count"},String(s))),this.open?this.popup():null)}popup(){let s=this.rows();return $t({class:"servers-pop gitdiff-pop"},s.length===0?this.emptyState("No changes in the working tree."):$t({class:"gitdiff-list",onScroll:()=>this.onListScroll()},s.map((a,d)=>this.row(a,d))),this.filterRow())}filterRow(){let s=this.files.length;return Uee({target:this,prop:()=>this.filter,id:this.filterId,placeholder:s?`Filter ${s} file${s===1?"":"s"}\u2026`:"Filter files\u2026",hasValue:!!this.filter,onKeyDown:a=>this.onFilterKey(a),onClear:()=>this.clearFilter()})}row(s,a){return $t({class:["gitdiff-row",a===this.highlighted?"active":"",this.viewing?.path===s.path?"viewing":""],onMouseEnter:()=>{this.highlighted!==a&&(this.highlighted=a,this.update())},onClick:d=>{d.stopPropagation(),this.openDiff(s)}},Ir({class:["gitdiff-status",`s-${s.status}`]},s.status),Ir({class:"gitdiff-path",title:s.path},s.path),s.add!==void 0||s.del!==void 0?Ir({class:"gitdiff-counts"},Ir({class:"count-add"},`+${s.add??0}`),Ir({class:"count-del"},`\u2212${s.del??0}`)):Ir({class:"gitdiff-counts"},Ir({class:"count-add"},"new")))}docView(){let s=this.viewing,a=s.kinds.filter(p=>p==="add").length,d=s.kinds.filter(p=>p==="del").length;return $t({class:"diff-doc",tabIndex:0,onMounted:p=>p.focus(),onKeyDown:p=>{p.key==="Escape"&&(p.stopPropagation(),this.closeDoc())}},$t({class:"diff-doc-head"},Ir({class:["gitdiff-status",`s-${s.status}`]},s.status),Ir({class:"diff-doc-path",title:`Open ${s.path}`,onClick:()=>tb.server.openFile(`${this.root}/${s.path}`)},s.path),Ir({class:"gitdiff-counts"},Ir({class:"count-add"},`+${a}`),Ir({class:"count-del"},`\u2212${d}`)),nc({class:"bulb-log-back",title:"Back to the conversation (Esc)",onClick:p=>{p.stopPropagation(),this.closeDoc()}},"\u2190 conversation")),$t({class:"diff-doc-scroll"},$t({class:"diff-doc-body"},s.kinds.length===0?$t({class:"diff-doc-empty"},"No changes."):$t({class:"diff-doc-code",key:`diff-code-${this.#e}`,onMounted:p=>{p.innerHTML=s.bodyHtml,this.#r(p)}},""),s.truncated?$t({class:"diff-doc-trunc"},"Diff truncated \u2014 file too large to show in full."):null),s.kinds.length?this.ruler(s.kinds):null))}#r(s){if(!this.#n)return;this.#n=!1;let a=s.querySelector(".udiff-add, .udiff-del"),d=s.closest(".diff-doc-body");a&&d&&(d.scrollTop=a.offsetTop-d.clientHeight/3)}ruler(s){let a=s.length,d=[];return s.forEach((p,b)=>{if(p!=="add"&&p!=="del")return;let v=d[d.length-1];v&&v.kind===p&&v.start+v.len===b?v.len++:d.push({kind:p,start:b,len:1})}),$t({class:"diff-ruler",title:"Jump to a change",onClick:p=>{let b=document.querySelector(".diff-doc-body"),v=p.currentTarget;if(!b)return;let w=(p.clientY-v.getBoundingClientRect().top)/v.clientHeight;b.scrollTop=w*b.scrollHeight-b.clientHeight/2}},d.map(p=>$t({class:["diff-ruler-mark",p.kind],style:{top:`${p.start/a*100}%`,height:`${p.len/a*100}%`}})))}};var Wre=class extends Ia{done=!1;#e;constructor(s){super(),this.#e=s}setText(s){this.#e=s}flash(){navigator.clipboard?.writeText(this.#e),this.done=!0,this.update(),setTimeout(()=>{this.done=!1,this.update()},600)}view(){return nc({class:["overlay-pill","copy",this.done?"done":""],onClick:s=>{s.stopPropagation(),this.flash()}},this.done?"copied":"copy")}};var Yre=class extends Ia{spread=!1;showingCode=!1;copied=!1;#e="";#n;#t;#r;#i;#s;#o;#c;#u=!1;#f=1;#h=!1;#l;#a="idle";constructor(s,a){super(),this.#n=s,this.#t=a,this.#r=vH(s);let d=yke(s);this.#i=d.length?d.join(" "):void 0}get name(){return this.#r}get key(){return this.#t}setChainPosition(s){this.#f=s}get chainPosition(){return this.#f}setMounted(s){s!==this.#u&&(this.#u=s,this.#d())}onAttached(){this.#d()}#d(){if(this.#u){if(this.#s||this.#h||this.#o)return;this.#h=!0,this.#l=new AbortController,hSt(this.#n,{signal:this.#l.signal,onError:s=>{this.#c=s,this.#p("runtime",s),this.update()},onReady:()=>this.#p(this.#i?"malformed":"ok",this.#i)}).then(s=>{this.#h=!1,this.#u&&(this.#s=s,this.update())}).catch(s=>{this.#h=!1,this.#o=s instanceof Error?s.message:String(s),this.#p("compile",this.#o),this.update()})}else{if(!this.#s&&!this.#h)return;this.#l?.abort(),this.#l=void 0,this.#s=void 0,this.#c=void 0,this.update()}}#p(s,a){let d=this.#r??this.#t,p=s==="ok"?"ok":s==="malformed"?`malformed: ${a}`:`${s} error: ${a}`;tb.server.logEmbedStatus(d,`[embed ${d} v${this.#f}] ${p}`).catch(()=>{})}dispose(){this.#l?.abort()}view(){let s=["embed","bulb-embed",this.spread?"spread":"fit",this.showingCode?"code-open":"",this.#o?"err":""],a=this.#r?`${this.#r} \u2014 `:"",d=this.#o?[`${a}could not render: ${this.#o}`]:this.#s?[this.#m(),$t({class:"bulb-frame",key:"frame",onMounted:p=>{this.#s&&p.replaceChildren(this.#s)}}),this.showingCode?this.#v():null,this.#c?$t({class:"bulb-err-strip",key:"err"},`\u26A0 ${a}${this.#c}`):null,this.#i?$t({class:"bulb-warn-strip",key:"warn"},`\u26A0 ${a}malformed: ${this.#i}`):null]:["compiling bulb\u2026"];return $t({class:"md",key:this.#t},$t({class:s},...d))}#m(){let s=this.#a==="done"?this.#e:"breakout \u2197";return $t({class:"bulb-controls",key:"controls"},this.#g("bulb-view",this.spread?"fit":"spread",this.spread?"Fit into the conversation column":"Spread to the full transcript width and height",()=>{this.spread=!this.spread,this.update()}),this.#g("bulb-toggle",this.showingCode?"run":"code",this.showingCode?"Back to the running bulb":"View this bulb's source",()=>{this.showingCode=!this.showingCode,this.update()}),this.#g(["bulb-copy",this.copied?"done":""],this.copied?"copied":"copy","Copy this bulb's full source",()=>this.#w()),nc({class:["overlay-pill","bulb-breakout",this.#a==="busy"?"launching shimmer":""],type:"button",disabled:this.#a!=="idle",title:"Save as a standalone .bulb.md and open it with typebulb",onClick:a=>{a.stopPropagation(),this.#A()}},s))}#g(s,a,d,p){let b=Array.isArray(s)?s:[s];return nc({class:["overlay-pill",...b],type:"button",title:d,onClick:v=>{v.stopPropagation(),p()}},a)}#w(){navigator.clipboard?.writeText(this.#n),this.copied=!0,this.update(),setTimeout(()=>{this.copied=!1,this.update()},1200)}async#A(){if(this.#a==="idle"){this.#a="busy",this.update();try{let{file:s,pid:a}=await tb.server.breakout(this.#n);this.#e=`launched ${s}`,window.dispatchEvent(new CustomEvent("tb-breakout",{detail:{pid:a}}))}catch(s){this.#e="breakout failed",console.error("[mirror] breakout failed",s)}this.#a="done",this.update(),setTimeout(()=>{this.#a="idle",this.update()},2500)}}#v(){return $t({class:["bulb-code","md"],key:"code",tabIndex:0,onKeyDown:s=>{if(!((s.ctrlKey||s.metaKey)&&(s.key==="a"||s.key==="A")))return;s.preventDefault();let a=getSelection();if(!a)return;let d=document.createRange();d.selectNodeContents(s.currentTarget),a.removeAllRanges(),a.addRange(d)},onMounted:s=>{s.innerHTML=eD.render(yH(this.#n))}})}};function ASt(o){return o.map((s,a)=>!!s&&o[a+1]===s)}function vSt(o){let s=[];for(let a=0;a<o.length;a++)s[a]=a>0&&o[a]&&o[a]===o[a-1]?s[a-1]+1:1;return s}var ySt=".typebulb/paste",kSt={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",bmp:"image/bmp"};var kvn=new RegExp(`@${ySt.replace(/\./g,"\\.")}/([\\w-]+(?:\\.[\\w-]+)*\\.(?:${Object.keys(kSt).join("|")}))`,"gi"),xvn=new URL("typebulb.png",import.meta.url).href,Evn=new URL("typebulb-inv.png",import.meta.url).href;function Cvn(o){return!o||typeof o!="object"?"":Gd(o.command)??Gd(o.file_path)??Gd(o.path)??Gd(o.pattern)??Gd(o.query)??Gd(o.url)??Gd(o.skill)??Gd(o.description)??""}function Ivn(o){let s=o.indexOf(`
|
|
@@ -817,16 +817,27 @@ a.server-port:hover { text-decoration: underline; }
|
|
|
817
817
|
the logs-link register — marks the category and opens the bulb's published page. A remote
|
|
818
818
|
(not-yet-downloaded) row's name is additionally muted and inert (no file to open), and its
|
|
819
819
|
time column stays empty (no mtime to show). */
|
|
820
|
-
.server-name.remote {
|
|
820
|
+
.server-name.remote { cursor: default; }
|
|
821
821
|
.server-name.remote:hover { text-decoration: none; }
|
|
822
822
|
.sample-link { color: var(--muted); font-size: .76rem; text-decoration: none; cursor: pointer; flex: none; }
|
|
823
823
|
.sample-link:hover { color: var(--accent); text-decoration: underline; }
|
|
824
|
-
/* The
|
|
825
|
-
|
|
824
|
+
/* The remote fold (bulbsPill.ts groupRow / fold-row): the header and the remote rows within share
|
|
825
|
+
one veil step over the menu's panel bg (the picker-peek shade) as ONE contiguous band — each
|
|
826
|
+
row's ::before bridges the grid row-gap up to the row above, junction corners square off, and
|
|
827
|
+
only the band's outer corners round (the header's top; the last row's bottom, via :has). The
|
|
828
|
+
accent label marks the header. Single-class selectors on purpose: .server-row:hover/.active
|
|
829
|
+
outrank them, so the highlight tints still win. */
|
|
826
830
|
.sample-group { cursor: pointer; color: var(--muted); }
|
|
827
|
-
.sample-group
|
|
831
|
+
.sample-group, .fold-row { background: linear-gradient(var(--veil), var(--veil)), var(--panel); }
|
|
832
|
+
.sample-group.open { border-radius: 6px 6px 0 0; }
|
|
833
|
+
.fold-row { position: relative; border-radius: 0; }
|
|
834
|
+
.fold-row::before {
|
|
835
|
+
content: ''; position: absolute; left: 0; right: 0; top: -.15rem; height: .15rem;
|
|
836
|
+
background: linear-gradient(var(--veil), var(--veil)), var(--panel);
|
|
837
|
+
}
|
|
838
|
+
.fold-row:not(:has(+ .fold-row)) { border-radius: 0 0 6px 6px; }
|
|
828
839
|
.sample-group .caret-tri { justify-self: center; }
|
|
829
|
-
.sample-group-label { grid-column: 2 / -1; }
|
|
840
|
+
.sample-group-label { grid-column: 2 / -1; color: var(--accent); }
|
|
830
841
|
/* The 1fr name column: name + (in full-text mode) its hit count read together, the badge
|
|
831
842
|
right-aligned at the column's end by the name's flex:1 — the session row's preview/hits layout. */
|
|
832
843
|
.bulb-name-cell { display: flex; align-items: baseline; gap: .6rem; min-width: 0; }
|
package/dist/agents/pi/client.js
CHANGED
|
@@ -1447,7 +1447,7 @@ ${cCt(b)}`};let v=oCt(d.code,{jsxImportSource:p.ts?.jsxImportSource});if(v.error
|
|
|
1447
1447
|
`),a=[];for(let b of z1.parse(o,{})){if(b.type!=="fence"||!b.map)continue;let v=b.content.replace(avn,"");((b.info??"").trim().toLowerCase()==="bulb"||_C(v)!=null)&&a.push({start:b.map[0],end:b.map[1],source:v})}for(let b of xke(o))a.some(v=>b.start>=v.start&&b.start<v.end)||a.push({start:b.start,end:b.end,source:b.source});a.sort((b,v)=>b.start-v.start);let d=[],p=0;for(let b of a)b.start<p||(b.start>p&&d.push({kind:"md",text:s.slice(p,b.start).join(`
|
|
1448
1448
|
`)}),d.push({kind:"bulb",source:b.source}),p=b.end);return p<s.length&&d.push({kind:"md",text:s.slice(p).join(`
|
|
1449
1449
|
`)}),d}var Ure=class extends M7{sessions=[];keepOpenSelector=".sid-wrap";filterId="session-filter";listSelector="#session-list";filterNoun="title";#e=new Map;#n=!1;#t=null;#r=new Map;search(s){return tb.server.searchSessions(s)}onActivate(s){let a=this.rows()[s];a&&this.pick(a.sessionId)}filtered(){let s=this.filter.trim().toLowerCase();return s?this.sessions.filter(a=>a.preview.toLowerCase().includes(s)):this.sessions}rows(){return this.searchActive?this.results:this.filtered()}currentIndex(){let s=this.rows(),a=s.findIndex(d=>d.sessionId===this.parent.sessionId);return a<0?s.length-1:a}async loadSessions(){this.sessions=(await tb.server.listSessions()).reverse(),this.#i(),this.parent.updateTitle()}#i(){let s=this.parent.sessionId;for(let a of this.sessions)(!this.#n||a.sessionId===s)&&this.#e.set(a.sessionId,a.mtime);this.#n=!0}#s(s){if(s.sessionId===this.parent.sessionId)return!1;let a=this.#e.get(s.sessionId);return a===void 0||s.mtime>a}onAttached(){this.loadSessions().then(()=>this.update()).catch(()=>{})}currentPreview(){return this.sessions.find(s=>s.sessionId===this.parent.sessionId)?.preview?.trim()??""}async show(){this.beginOpen(),this.refreshList(this.currentIndex()),this.focusFilter();try{await this.loadSessions(),this.refreshList(this.currentIndex())}catch(s){console.error("[mirror] listSessions failed",s)}this.armClose()}async pick(s){let a=this.rows().find(d=>d.sessionId===s);a&&this.#e.set(s,a.mtime),this.close(),this.parent.messageList.stickToBottomNextRender(),await tb.server.attach(s)}view(){let s=this.parent;if(s.sessionId===null)return Zt({class:"sid-wrap"});let a=s.sessionId==="",d=a?"new conversation":this.currentPreview()||"current",p=fM(d,25),b=`${s.cwd}
|
|
1450
|
-
${a?"New conversation \u2014 not saved yet":`Session: ${s.sessionId}`}`;return Zt({class:"sid-wrap"},wc({class:"pill",title:b,onClick:v=>{v.stopPropagation(),this.open?this.close():this.show()}},p),this.open?this.picker():null)}picker(){let s=this.rows();return Zt({class:"picker"},Zt({class:"picker-body"},s.length===0?this.emptyState("No sessions yet \u2014 start one in your terminal."):Zt({id:"session-list",class:"picker-list",onScroll:()=>this.onListScroll()},s.map((a,d)=>this.pickerRow(a,d))),this.peekCard()),this.filterBox(this.sessions.length,"session"))}pickerRow(s,a){let d=s.sessionId===this.parent.sessionId,p=this.parent.busy.includes(s.sessionId);return Zt({class:["picker-row",a===this.highlighted?"active":"",d?"current":""],onMouseEnter:()=>{this.highlighted!==a&&(this.highlighted=a,this.update())},onClick:()=>this.pick(s.sessionId)},Zt({class:"picker-row-main"},Fr({class:"picker-dot"}),Fr({class:["picker-preview",p?"shimmer-text shimmer-slow":""]},s.preview||"(no preview)"),Wee(s.hitCount),Fr({class:["picker-time",this.#s(s)?"unseen":""],onMouseEnter:()=>this.#o(s),onMouseLeave:()=>this.#c(s)},Xee(s.mtime))),Yee(s.snippet,this.filter.trim()))}#o(s){this.#t=`${s.sessionId}:${s.mtime}`,this.#u(s.sessionId,this.#t),this.update()}#c(s){this.#t===`${s.sessionId}:${s.mtime}`&&(this.#t=null,this.update())}async#u(s,a){if(this.#r.has(a))return;let d="";try{d=String((await tb.server.sessionPeek(s))?.text??"")}catch{}this.#r.set(a,d),this.#t===a&&this.update()}peekCard(){if(!this.#t)return null;let s=this.#r.get(this.#t);return s===void 0?Zt({class:"picker-peek muted"},"\u2026"):s?Zt({class:"picker-peek md",key:`peek:${this.#t}`,onMounted:a=>{a.innerHTML=rD.render(s)}}):Zt({class:"picker-peek muted"},"(no assistant text yet)")}onClosed(){super.onClosed(),this.#t=null}};var zre=class extends wu{get parent(){return this.ctx.parent}view(){let s=this.parent.tokens,a=this.parent.stats,d=a?a.contextTokens??0:s.in+s.out+s.cached+s.cacheCreate,p=a?.cost??this.parent.cost,b=this.parent.working,v=[];if(d>0&&v.push(Vee(d)),a&&a.contextPercent!=null&&v.push(`${Math.round(a.contextPercent)}%`),p>0&&v.push(`$${p>=1?p.toFixed(2):p.toFixed(3)}`),!v.length&&!b)return Fr({class:"token-wrap"});let w=v.length?v.length===1&&d>0?`${v[0]} tokens`:v.join(" \xB7 "):"working\u2026";return Fr({class:"token-wrap"},Fr({class:["token",b?"busy shimmer shimmer-slow":""]},w))}};var gSt={"play_arrow.fill":'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M320-200v-560l440 280-440 280Z"/></svg>',"stop.fill":'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M240-240v-480h480v480H240Z"/></svg>',play_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m380-300 280-180-280-180v360ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',stop_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M320-320h320v-320H320v320ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',add_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M440-280h80v-160h160v-80H520v-160h-80v160H280v80h160v160Zm40 200q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',attach_file:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M720-330q0 104-73 177T470-80q-104 0-177-73t-73-177v-370q0-75 52.5-127.5T400-880q75 0 127.5 52.5T580-700v350q0 46-32 78t-78 32q-46 0-78-32t-32-78v-370h80v370q0 13 8.5 21.5T470-320q13 0 21.5-8.5T500-350v-350q-1-42-29.5-71T400-800q-42 0-71 29t-29 71v370q-1 71 49 120.5T470-160q70 0 119-49.5T640-330v-390h80v390Z"/></svg>'};var lvn={play:"play_arrow.fill",stop:"stop.fill",playCircle:"play_circle",stopCircle:"stop_circle",addCircle:"add_circle",attach:"attach_file"},fvn={caret:'<svg viewBox="0 0 16 16"><path d="M4 1.5 L13 8 L4 14.5 Z" fill="currentColor"/></svg>',push:'<svg viewBox="0 0 16 16" fill="none"><path d="M8 11 V3 M4.75 6.25 L8 3 L11.25 6.25" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 14 H13" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>',pull:'<svg viewBox="0 0 16 16" fill="none"><path d="M8 3 V11 M4.75 7.75 L8 11 L11.25 7.75" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 14 H13" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>',check:'<svg viewBox="0 0 16 16" fill="none"><path d="M3 8.5 L6.5 12 L13 4.5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>',fork:'<svg viewBox="0 0 16 16" fill="none"><path d="M4 2 V8 H12 V2 M8 8 V14" stroke="currentColor" stroke-width="1.8" stroke-linecap="square"/></svg>',diff:'<svg viewBox="4 2 8 12" fill="none"><path d="M5.25 6 H10.75 M8 3.25 V8.75" stroke="var(--diff-add)" stroke-width="1.8" stroke-linecap="round"/><path d="M5.25 12.5 H10.75" stroke="var(--err)" stroke-width="1.8" stroke-linecap="round"/></svg>'},hvn=o=>{let s=fvn[o]??gSt[lvn[o]??""]??"";return/<svg[^>]*\bfill=/.test(s)?s:s.replace("<svg ",'<svg fill="currentColor" ')},np=(o,s="")=>Fr({class:["icon",...Array.isArray(s)?s:[s]],key:`icon-${o}`,onMounted:a=>{a.innerHTML=hvn(o)}},"");var dvn=()=>np("play","btn-icon"),pvn=()=>np("stop","btn-icon"),gvn=o=>`typebulbs/u/samples/${o}.bulb.md`,sD=o=>Xh(o.path).match(/typebulbs\/u\/([^/]+)\//)?.[1],bvn=(o,s)=>`https://typebulb.com/u/${s}/${hM(o.path)}/full`,Kre=class extends M7{files=[];servers=[];samples=[];mine=[];myUser;keepOpenSelector=".servers-wrap";filterId="bulb-filter";listSelector=".bulb-list";filterNoun="name";launching=new Set;dismissedDenials=new Set;pendingLaunch;openLog;#e;spotlightPid;openFolds=new Set;pendingOverwrite;syncBusy=new Set;syncDone=new Set;search(s){return tb.server.searchBulbs(s)}onActivate(s){let a=this.rows()[s];a&&(a.group?this.toggleFold(a.group.user):a.running?window.open(a.running.url,"_blank","noopener"):a.remote?this.downloadAndLaunch(a):this.launch(a.path))}onAttached(){this.refresh(),setInterval(()=>this.refreshServers(),800),setInterval(()=>this.refreshFiles(),3e3),window.addEventListener("tb-breakout",s=>this.spotlight(s.detail?.pid))}spotlight(s){this.spotlightPid=s,this.show()}refresh(){return Promise.all([this.refreshServers(),this.refreshFiles(),this.refreshSamples(),this.refreshMine()])}async refreshServers(){try{let s=await tb.server.listBreakouts(),a=s.length!==this.servers.length||s.some((d,p)=>d.pid!==this.servers[p]?.pid||d.denied!==this.servers[p]?.denied||d.predicted!==this.servers[p]?.predicted||d.trust!==this.servers[p]?.trust);this.servers=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] server list refresh failed",s)}}async refreshFiles(){try{let s=await tb.server.listBulbFiles(),a=s.length!==this.files.length||s.some((d,p)=>d.path!==this.files[p]?.path||d.mtime!==this.files[p]?.mtime);this.files=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] bulb list refresh failed",s)}}async refreshSamples(){try{let s=await tb.server.listSamples(),a=s.length!==this.samples.length||s.some((d,p)=>d.slug!==this.samples[p]?.slug);this.samples=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] samples refresh failed",s)}}async refreshMine(){try{let{user:s,bulbs:a}=await tb.server.listMyBulbs(),d=s!==this.myUser||a.length!==this.mine.length||a.some((p,b)=>p.slug!==this.mine[b]?.slug);this.myUser=s,this.mine=a,d&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] my-bulbs refresh failed",s)}}merged(){let s=new Map,a=this.files.map(p=>Xh(p.path)),d=[...this.samples.map(p=>[gvn(p.slug),p]),...this.myUser?this.mine.map(p=>[`typebulbs/u/${this.myUser}/${p.slug}.bulb.md`,p]):[]];for(let[p,b]of d)a.some(v=>v.endsWith("/"+p))||s.set(p,{path:p,name:b.name,recent:0,remote:b});this.files.forEach((p,b)=>{s.set(a[b],{path:p.path,name:p.name,recent:p.mtime,trusted:p.trusted})});for(let p of this.servers){if(p.pid===this.parent.ownPid)continue;let b=Xh(p.file),v=hM(p.file)||p.file,w=s.get(b)??{path:p.file,name:v,recent:0};w.running=p,w.recent=Math.max(w.recent,p.startedAt),s.set(b,w)}return[...s.values()]}rows(){let s=this.merged();if(this.searchActive){let a=new Map(this.results.map(d=>[Xh(d.path),d]));s=s.flatMap(d=>{let p=a.get(Xh(d.path));return p?[{...d,hitCount:p.hitCount,snippet:p.snippet}]:[]})}else{let a=this.filter.trim().toLowerCase();a?s=s.filter(d=>d.name.toLowerCase().includes(a)||d.path.toLowerCase().includes(a)):[...new Set(s.filter(p=>p.remote).map(p=>sD(p)))].forEach((p,b)=>{let v=I=>!!I.remote&&sD(I)===p,w=s.filter(v).length;this.openFolds.has(p)||(s=s.filter(I=>!v(I))),s.push({path:`::${p}`,name:this.foldLabel(p),recent:-1-b,group:{user:p,count:w}})})}return s.sort((a,d)=>a.recent-d.recent)}show(){this.beginOpen(),this.refresh(),this.refreshList(),this.armClose(),this.focusFilter()}onClosed(){super.onClosed(),this.closeLog(),this.openFolds.clear(),this.pendingOverwrite=void 0,this.spotlightPid=void 0}toggleFold(s){this.openFolds.delete(s)||this.openFolds.add(s),this.update()}foldLabel(s){return s==="samples"?"samples from typebulb.com":s===this.myUser?"your typebulb.com bulbs":`${s} on typebulb.com`}foldTitle(s){return s==="samples"?"Runnable sample bulbs from typebulb.com \u2014 click to browse":`${s===this.myUser?"Your":`${s}'s`} bulbs on typebulb.com \u2014 click to browse; play pulls one into the project`}async launch(s){if(!this.files.find(d=>Xh(d.path)===Xh(s))?.trusted){let d;try{d=(await tb.server.predictTrustOf(s)).cap}catch(p){console.error("[mirror] predictTrustOf failed",p)}if(d){this.pendingLaunch={path:s,name:this.displayName(s),cap:d},this.update();return}}await this.doLaunch(s)}async downloadAndLaunch(s){let a=Xh(s.path);this.launching.add(a),this.update();try{let d=sD(s),p=d==="samples"?await tb.server.downloadSample(s.remote.slug):await tb.server.pullRemoteBulb(d,s.remote.slug);if(!p.ok||!p.file){console.error("[mirror] remote pull failed",p.error);return}await this.refreshFiles();let b=this.files.find(v=>Xh(v.path).endsWith("/"+Xh(p.file)))?.path??p.file;await this.launch(b)}catch(d){console.error("[mirror] remote pull failed",d)}finally{this.launching.delete(a),this.update()}}async syncRow(s,a,d=!1){let p=`${Xh(s.path)}:${a}`;this.syncBusy.add(p),this.update();try{let b=a==="pull"?await tb.server.pullRemoteBulb(sD(s),hM(s.path),d):await tb.server.pushLocalBulb(s.path,d);b.ok?this.tickDone(p):b.conflict?this.pendingOverwrite={...a==="pull"?{heading:`\u201C${s.name}\u201D has local changes`,body:"Your local file differs from the typebulb.com copy. Overwrite the local file with the site's version?",yesLabel:"Overwrite local"}:{heading:`The site copy of \u201C${s.name}\u201D changed`,body:"It changed since your last sync. Overwrite the typebulb.com copy with your local file?",yesLabel:"Overwrite site copy"},onYes:()=>this.syncRow(s,a,!0)}:console.error(`[mirror] ${a} failed`,b.error)}catch(b){console.error(`[mirror] ${a} failed`,b)}finally{this.syncBusy.delete(p)}await(a==="pull"?this.refreshFiles():this.refreshMine()),this.update()}tickDone(s){this.syncDone.add(s),setTimeout(()=>{this.syncDone.delete(s),this.update()},1200)}async doLaunch(s,a,d=!1){let p=Xh(s);this.launching.add(p),this.update();let b;try{b=(await tb.server.launchBulb(s,a)).pid}catch(v){console.error("[mirror] launchBulb failed",v)}finally{this.launching.delete(p)}d&&b&&this.dismissedDenials.add(b),await this.refresh(),this.pinToBottom()}displayName(s){return this.files.find(d=>Xh(d.path)===Xh(s))?.name||hM(s)||s}launchTrusted(){let s=this.pendingLaunch;this.pendingLaunch=void 0,s&&this.doLaunch(s.path,!0)}launchRestricted(){let s=this.pendingLaunch;this.pendingLaunch=void 0,s&&this.doLaunch(s.path,void 0,!0)}cancelLaunch(){this.pendingLaunch=void 0,this.update()}async stop(s){this.openLog?.pid===s&&this.closeLog(),this.dismissedDenials.delete(s);try{await tb.server.stopBreakout(s)}catch(a){console.error("[mirror] stopBreakout failed",a)}await this.refresh()}pendingDenial(){return this.servers.find(s=>s.denied&&s.pid!==this.parent.ownPid&&!this.dismissedDenials.has(s.pid))}async elevate(s){this.dismissedDenials.add(s.pid),this.openLog?.pid===s.pid&&this.closeLog();try{await tb.server.launchBulb(s.file,!0)}catch(a){console.error("[mirror] elevate failed",a)}await this.refresh()}dismissDenial(s){this.dismissedDenials.add(s),this.update()}async toggleTrust(s){let a=!(s.running?s.running.trust:s.trusted);try{await tb.server.setBulbTrust(s.path,a),s.running&&(this.openLog?.pid===s.running.pid&&this.closeLog(),await tb.server.launchBulb(s.path,a))}catch(d){console.error("[mirror] toggleTrust failed",d)}await this.refresh()}showLog(s,a){if(this.openLog?.pid===s.pid){this.closeLog();return}this.closeLog(),this.openLog={pid:s.pid,name:a,text:"",offset:0},this.update(),setTimeout(()=>document.getElementById("bulb-console")?.focus()),this.#n(),this.#e=setInterval(()=>this.#n(),700)}closeLog(){this.#e&&(clearInterval(this.#e),this.#e=void 0),this.openLog&&(this.openLog=void 0,this.update())}async#n(){let s=this.openLog;if(s)try{let{text:a,offset:d}=await tb.server.readBulbLog(s.pid,s.offset);if(this.openLog!==s)return;a?(s.text=(s.text+a).slice(-5e4),s.offset=d,this.update()):d!==s.offset&&(s.offset=d)}catch(a){console.error("[mirror] readBulbLog failed",a)}}view(){let s=this.servers.filter(p=>p.pid!==this.parent.ownPid).length;if(!(this.files.length>0||this.samples.length>0)&&s===0)return Zt({class:"servers-wrap"});let d=this.pendingDenial();return Zt({class:"servers-wrap"},wc({class:["pill",s>0?"":"glyph",this.open?"on":""],title:"Launch a project bulb \xB7 stop a running one",onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},s>0?`${s}\u{1F4A1}`:Fr({class:"glyph-img"},"\u{1F4A1}")),this.open?this.popup():null,this.pendingLaunch?this.launchModal(this.pendingLaunch):this.pendingOverwrite?this.overwriteModal(this.pendingOverwrite):d?this.denialModal(d):null)}overwriteModal(s){let a=()=>{this.pendingOverwrite=void 0,this.update()};return this.trustModal({heading:s.heading,body:s.body,warn:"There is no undo \u2014 the overwritten side's changes are gone.",noLabel:"Cancel",yesLabel:s.yesLabel,onNo:a,onYes:()=>{this.pendingOverwrite=void 0,s.onYes()},onDismiss:a})}trustModal(s){let a=(d,p)=>{d.stopPropagation(),p(),this.open&&this.focusFilter()};return Zt({class:"trust-back",tabIndex:0,onMounted:d=>d.focus(),onKeyDown:d=>{d.key==="Escape"&&a(d,s.onDismiss)},onClick:d=>a(d,s.onDismiss)},Zt({class:"trust-modal",onClick:d=>d.stopPropagation()},Zt({class:"trust-modal-h"},s.heading),Zt({class:"trust-modal-b"},s.body),Zt({class:"trust-modal-warn"},s.warn),Zt({class:"trust-modal-acts"},wc({class:"trust-no",onClick:d=>a(d,s.onNo)},s.noLabel),wc({class:"trust-yes",onClick:d=>a(d,s.onYes)},s.yesLabel))))}launchModal(s){return this.trustModal({heading:`\u201C${s.name}\u201D will likely need access`,body:`It looks like it uses ${s.cap}, which is blocked unless you launch it Trusted. Launch Trusted to allow filesystem / AI / server.ts?`,warn:"Only trust bulbs you wrote or have read \u2014 be careful with anything off the internet.",noLabel:"Launch restricted",yesLabel:"Launch trusted",onNo:()=>this.launchRestricted(),onYes:()=>this.launchTrusted(),onDismiss:()=>this.cancelLaunch()})}denialModal(s){let a=hM(s.file)||s.file,d=!s.predicted;return this.trustModal({heading:d?`\u201C${a}\u201D reached for access it didn't declare`:`\u201C${a}\u201D wants more access`,body:d?`It tried to use ${s.denied} at runtime, though nothing in its code obviously needed it. Relaunch it Trusted to allow filesystem / AI / server.ts?`:`It tried to use ${s.denied}, blocked while it's restricted. Relaunch it Trusted to allow filesystem / AI / server.ts?`,warn:d?"Code that reaches for capabilities it never visibly uses can be hiding something \u2014 only continue if you wrote this bulb or have read it.":"Only trust bulbs you wrote or have read \u2014 be careful with anything off the internet.",noLabel:"Keep restricted",yesLabel:"Trust & relaunch",onNo:()=>this.dismissDenial(s.pid),onYes:()=>this.elevate(s),onDismiss:()=>this.dismissDenial(s.pid)})}popup(){if(this.openLog)return this.consoleView(this.openLog);let s=this.rows(),a=this.spotlightPid,d=a!==void 0&&s.some(p=>p.running?.pid===a);return Zt({class:"servers-pop"},s.length===0?this.emptyState("No bulbs in this project yet."):Zt({class:"bulb-list",onScroll:()=>this.onListScroll()},s.map((p,b)=>this.row(p,b,d&&p.running?.pid!==a))),this.filterBox(this.merged().filter(p=>!p.remote).length,"bulb"))}consoleView(s){return Zt({id:"bulb-console",class:"servers-pop log-mode",tabIndex:0,onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeLog())}},Zt({class:"bulb-log-head"},Fr({class:"bulb-log-name"},`console \xB7 ${s.name}`),wc({class:"bulb-log-back",title:"Back to the bulb list",onClick:a=>{a.stopPropagation(),this.closeLog()}},"\u2190 bulbs")),i6({class:"bulb-log-body"},Fr({class:"bulb-log-text"},s.text||"(no output yet)")))}hoverRow(s,a){let d=a!==void 0&&a.pid===this.spotlightPid;d&&(this.spotlightPid=void 0),(this.highlighted!==s||d)&&(this.highlighted=s,this.update())}row(s,a,d=!1){if(s.group)return this.groupRow(s,a,d);let p=s.running,b=p&&this.openLog?.pid===p.pid,v=p?!!p.trust:!!s.trusted;return Zt({class:["server-row",a===this.highlighted?"active":"",d?"dimmed":""],onMouseEnter:()=>this.hoverRow(a,p)},p?wc({class:"server-stop",title:"Stop this server",ariaLabel:"Stop",onClick:w=>{w.stopPropagation(),this.stop(p.pid)}},pvn()):wc({class:["bulb-launch",this.launching.has(Xh(s.path))?"launching shimmer":""],title:s.remote?"Download from typebulb.com & launch":v?"Launch (trusted \u2014 remembered)":"Launch (restricted)",ariaLabel:"Launch",onClick:w=>{w.stopPropagation(),s.remote?this.downloadAndLaunch(s):this.launch(s.path)}},dvn()),Zt({class:"bulb-name-cell"},s.remote?Fr({class:"server-name stopped remote",title:s.remote.description},s.name):Fr({class:["server-name",p?"":"stopped"],title:`Open ${s.path}`,onClick:w=>{w.stopPropagation(),tb.server.openFile(s.path)}},s.name),this.userLink(s),Wee(s.hitCount)),this.syncCell(s),p||v?this.trustToggle(s,v):Fr({class:"cell-empty"}),p?gC({class:["server-logs",b?"on":""],title:"Show this server\u2019s console",onClick:w=>{w.stopPropagation(),this.showLog(p,s.name)}},"logs"):Fr({class:"cell-empty"}),p?gC({class:"server-port",href:p.url,target:"_blank",rel:"noopener noreferrer",title:`Open ${p.url}`},`:${p.port}`):s.remote?Fr({class:"cell-empty"}):Fr({class:"bulb-time"},Xee(s.recent)),Yee(s.snippet,this.filter.trim()))}userLink(s){let a=sD(s);return a?gC({class:"sample-link",href:bvn(s,a),target:"_blank",rel:"noopener noreferrer",title:"Open this bulb's page on typebulb.com"},a):null}syncCell(s){let a=sD(s);if(!a||s.remote)return Fr({class:"cell-empty"});let d=(p,b)=>{let v=`${Xh(s.path)}:${p}`,w=this.syncBusy.has(v),I=this.syncDone.has(v);return wc({class:["sync-btn",w?"busy shimmer":"",I?"done":""],title:b,ariaLabel:p,onClick:T=>{T.stopPropagation(),w||this.syncRow(s,p)}},np(I?"check":p,"btn-icon-sm"))};return Fr({class:"sync-cell"},d("pull",`Pull \u2014 update the local file from typebulb.com/u/${a}`),a===this.myUser?d("push","Push \u2014 upload this file to typebulb.com"):null)}groupRow(s,a,d){let{user:p,count:b}=s.group,v=this.openFolds.has(p);return Zt({class:["server-row","sample-group",a===this.highlighted?"active":"",d?"dimmed":""],title:v?"Collapse":this.foldTitle(p),onMouseEnter:()=>this.hoverRow(a),onClick:w=>{w.stopPropagation(),this.toggleFold(p)}},np("caret",["caret-tri",v?"open":""]),Fr({class:"sample-group-label"},`${s.name} (${b})`))}trustToggle(s,a){return wc({class:["trust-toggle",a?"on":""],title:`${a?"Trusted":"Restricted"} \u2014 click to switch to ${a?"restricted":"trusted"}`+(s.running?" (stops + relaunches it)":""),onClick:d=>{d.stopPropagation(),this.toggleTrust(s)}},a?"trusted":"restricted")}};var Wre=class extends wu{get parent(){return this.ctx.parent}view(){let s=this.parent.prose;return wc({class:["pill","glyph",s?"on":""],title:s?"Trace view":"Content view",onClick:()=>{this.parent.prose=!s,this.update()}},Fr({class:"glyph-img"},"\u{1F648}"))}};var mvn=4e5;function wvn(o,s){let a=o.split(`
|
|
1450
|
+
${a?"New conversation \u2014 not saved yet":`Session: ${s.sessionId}`}`;return Zt({class:"sid-wrap"},wc({class:"pill",title:b,onClick:v=>{v.stopPropagation(),this.open?this.close():this.show()}},p),this.open?this.picker():null)}picker(){let s=this.rows();return Zt({class:"picker"},Zt({class:"picker-body"},s.length===0?this.emptyState("No sessions yet \u2014 start one in your terminal."):Zt({id:"session-list",class:"picker-list",onScroll:()=>this.onListScroll()},s.map((a,d)=>this.pickerRow(a,d))),this.peekCard()),this.filterBox(this.sessions.length,"session"))}pickerRow(s,a){let d=s.sessionId===this.parent.sessionId,p=this.parent.busy.includes(s.sessionId);return Zt({class:["picker-row",a===this.highlighted?"active":"",d?"current":""],onMouseEnter:()=>{this.highlighted!==a&&(this.highlighted=a,this.update())},onClick:()=>this.pick(s.sessionId)},Zt({class:"picker-row-main"},Fr({class:"picker-dot"}),Fr({class:["picker-preview",p?"shimmer-text shimmer-slow":""]},s.preview||"(no preview)"),Wee(s.hitCount),Fr({class:["picker-time",this.#s(s)?"unseen":""],onMouseEnter:()=>this.#o(s),onMouseLeave:()=>this.#c(s)},Xee(s.mtime))),Yee(s.snippet,this.filter.trim()))}#o(s){this.#t=`${s.sessionId}:${s.mtime}`,this.#u(s.sessionId,this.#t),this.update()}#c(s){this.#t===`${s.sessionId}:${s.mtime}`&&(this.#t=null,this.update())}async#u(s,a){if(this.#r.has(a))return;let d="";try{d=String((await tb.server.sessionPeek(s))?.text??"")}catch{}this.#r.set(a,d),this.#t===a&&this.update()}peekCard(){if(!this.#t)return null;let s=this.#r.get(this.#t);return s===void 0?Zt({class:"picker-peek muted"},"\u2026"):s?Zt({class:"picker-peek md",key:`peek:${this.#t}`,onMounted:a=>{a.innerHTML=rD.render(s)}}):Zt({class:"picker-peek muted"},"(no assistant text yet)")}onClosed(){super.onClosed(),this.#t=null}};var zre=class extends wu{get parent(){return this.ctx.parent}view(){let s=this.parent.tokens,a=this.parent.stats,d=a?a.contextTokens??0:s.in+s.out+s.cached+s.cacheCreate,p=a?.cost??this.parent.cost,b=this.parent.working,v=[];if(d>0&&v.push(Vee(d)),a&&a.contextPercent!=null&&v.push(`${Math.round(a.contextPercent)}%`),p>0&&v.push(`$${p>=1?p.toFixed(2):p.toFixed(3)}`),!v.length&&!b)return Fr({class:"token-wrap"});let w=v.length?v.length===1&&d>0?`${v[0]} tokens`:v.join(" \xB7 "):"working\u2026";return Fr({class:"token-wrap"},Fr({class:["token",b?"busy shimmer shimmer-slow":""]},w))}};var gSt={"play_arrow.fill":'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M320-200v-560l440 280-440 280Z"/></svg>',"stop.fill":'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M240-240v-480h480v480H240Z"/></svg>',play_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m380-300 280-180-280-180v360ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',stop_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M320-320h320v-320H320v320ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',add_circle:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M440-280h80v-160h160v-80H520v-160h-80v160H280v80h160v160Zm40 200q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',attach_file:'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M720-330q0 104-73 177T470-80q-104 0-177-73t-73-177v-370q0-75 52.5-127.5T400-880q75 0 127.5 52.5T580-700v350q0 46-32 78t-78 32q-46 0-78-32t-32-78v-370h80v370q0 13 8.5 21.5T470-320q13 0 21.5-8.5T500-350v-350q-1-42-29.5-71T400-800q-42 0-71 29t-29 71v370q-1 71 49 120.5T470-160q70 0 119-49.5T640-330v-390h80v390Z"/></svg>'};var lvn={play:"play_arrow.fill",stop:"stop.fill",playCircle:"play_circle",stopCircle:"stop_circle",addCircle:"add_circle",attach:"attach_file"},fvn={caret:'<svg viewBox="0 0 16 16"><path d="M4 1.5 L13 8 L4 14.5 Z" fill="currentColor"/></svg>',push:'<svg viewBox="0 0 16 16" fill="none"><path d="M8 11 V3 M4.75 6.25 L8 3 L11.25 6.25" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 14 H13" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>',pull:'<svg viewBox="0 0 16 16" fill="none"><path d="M8 3 V11 M4.75 7.75 L8 11 L11.25 7.75" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 14 H13" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>',check:'<svg viewBox="0 0 16 16" fill="none"><path d="M3 8.5 L6.5 12 L13 4.5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>',fork:'<svg viewBox="0 0 16 16" fill="none"><path d="M4 2 V8 H12 V2 M8 8 V14" stroke="currentColor" stroke-width="1.8" stroke-linecap="square"/></svg>',diff:'<svg viewBox="4 2 8 12" fill="none"><path d="M5.25 6 H10.75 M8 3.25 V8.75" stroke="var(--diff-add)" stroke-width="1.8" stroke-linecap="round"/><path d="M5.25 12.5 H10.75" stroke="var(--err)" stroke-width="1.8" stroke-linecap="round"/></svg>'},hvn=o=>{let s=fvn[o]??gSt[lvn[o]??""]??"";return/<svg[^>]*\bfill=/.test(s)?s:s.replace("<svg ",'<svg fill="currentColor" ')},np=(o,s="")=>Fr({class:["icon",...Array.isArray(s)?s:[s]],key:`icon-${o}`,onMounted:a=>{a.innerHTML=hvn(o)}},"");var dvn=()=>np("play","btn-icon"),pvn=()=>np("stop","btn-icon"),gvn=o=>`typebulbs/u/samples/${o}.bulb.md`,sD=o=>Xh(o.path).match(/typebulbs\/u\/([^/]+)\//)?.[1],bvn=(o,s)=>`https://typebulb.com/u/${s}/${hM(o.path)}/full`,Kre=class extends M7{files=[];servers=[];samples=[];mine=[];myUser;keepOpenSelector=".servers-wrap";filterId="bulb-filter";listSelector=".bulb-list";filterNoun="name";launching=new Set;dismissedDenials=new Set;pendingLaunch;openLog;#e;spotlightPid;openFolds=new Set;pendingOverwrite;syncBusy=new Set;syncDone=new Set;search(s){return tb.server.searchBulbs(s)}onActivate(s){let a=this.rows()[s];a&&(a.group?this.toggleFold(a.group.user):a.running?window.open(a.running.url,"_blank","noopener"):a.remote?this.downloadAndLaunch(a):this.launch(a.path))}onAttached(){this.refresh(),setInterval(()=>this.refreshServers(),800),setInterval(()=>this.refreshFiles(),3e3),window.addEventListener("tb-breakout",s=>this.spotlight(s.detail?.pid))}spotlight(s){this.spotlightPid=s,this.show()}refresh(){return Promise.all([this.refreshServers(),this.refreshFiles(),this.refreshSamples(),this.refreshMine()])}async refreshServers(){try{let s=await tb.server.listBreakouts(),a=s.length!==this.servers.length||s.some((d,p)=>d.pid!==this.servers[p]?.pid||d.denied!==this.servers[p]?.denied||d.predicted!==this.servers[p]?.predicted||d.trust!==this.servers[p]?.trust);this.servers=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] server list refresh failed",s)}}async refreshFiles(){try{let s=await tb.server.listBulbFiles(),a=s.length!==this.files.length||s.some((d,p)=>d.path!==this.files[p]?.path||d.mtime!==this.files[p]?.mtime);this.files=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] bulb list refresh failed",s)}}async refreshSamples(){try{let s=await tb.server.listSamples(),a=s.length!==this.samples.length||s.some((d,p)=>d.slug!==this.samples[p]?.slug);this.samples=s,a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] samples refresh failed",s)}}async refreshMine(){try{let{user:s,bulbs:a}=await tb.server.listMyBulbs(),d=s!==this.myUser||a.length!==this.mine.length||a.some((p,b)=>p.slug!==this.mine[b]?.slug);this.myUser=s,this.mine=a,d&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] my-bulbs refresh failed",s)}}merged(){let s=new Map,a=this.files.map(p=>Xh(p.path)),d=[...this.samples.map(p=>[gvn(p.slug),p]),...this.myUser?this.mine.map(p=>[`typebulbs/u/${this.myUser}/${p.slug}.bulb.md`,p]):[]];for(let[p,b]of d)a.some(v=>v.endsWith("/"+p))||s.set(p,{path:p,name:b.name,recent:0,remote:b});this.files.forEach((p,b)=>{s.set(a[b],{path:p.path,name:p.name,recent:p.mtime,trusted:p.trusted})});for(let p of this.servers){if(p.pid===this.parent.ownPid)continue;let b=Xh(p.file),v=hM(p.file)||p.file,w=s.get(b)??{path:p.file,name:v,recent:0};w.running=p,w.recent=Math.max(w.recent,p.startedAt),s.set(b,w)}return[...s.values()]}rows(){let s=this.merged();if(this.searchActive){let a=new Map(this.results.map(d=>[Xh(d.path),d]));s=s.flatMap(d=>{let p=a.get(Xh(d.path));return p?[{...d,hitCount:p.hitCount,snippet:p.snippet}]:[]})}else{let a=this.filter.trim().toLowerCase();a?s=s.filter(d=>d.name.toLowerCase().includes(a)||d.path.toLowerCase().includes(a)):[...new Set(s.filter(p=>p.remote).map(p=>sD(p)))].forEach((p,b)=>{let v=I=>!!I.remote&&sD(I)===p,w=s.filter(v).length;this.openFolds.has(p)?s=s.map(I=>v(I)?{...I,recent:-.5-b}:I):s=s.filter(I=>!v(I)),s.push({path:`::${p}`,name:this.foldLabel(p),recent:-1-b,group:{user:p,count:w}})})}return s.sort((a,d)=>a.recent-d.recent)}show(){this.beginOpen(),this.refresh(),this.refreshList(),this.armClose(),this.focusFilter()}onClosed(){super.onClosed(),this.closeLog(),this.openFolds.clear(),this.pendingOverwrite=void 0,this.spotlightPid=void 0}toggleFold(s){this.openFolds.delete(s)||this.openFolds.add(s),this.update()}foldLabel(s){return s==="samples"?"Samples from typebulb.com":s===this.myUser?"Your typebulb.com bulbs":`${s} on typebulb.com`}foldTitle(s){return s==="samples"?"Runnable sample bulbs from typebulb.com \u2014 click to browse":`${s===this.myUser?"Your":`${s}'s`} bulbs on typebulb.com \u2014 click to browse; play pulls one into the project`}async launch(s){if(!this.files.find(d=>Xh(d.path)===Xh(s))?.trusted){let d;try{d=(await tb.server.predictTrustOf(s)).cap}catch(p){console.error("[mirror] predictTrustOf failed",p)}if(d){this.pendingLaunch={path:s,name:this.displayName(s),cap:d},this.update();return}}await this.doLaunch(s)}async downloadAndLaunch(s){let a=Xh(s.path);this.launching.add(a),this.update();try{let d=sD(s),p=d==="samples"?await tb.server.downloadSample(s.remote.slug):await tb.server.pullRemoteBulb(d,s.remote.slug);if(!p.ok||!p.file){console.error("[mirror] remote pull failed",p.error);return}await this.refreshFiles();let b=this.files.find(v=>Xh(v.path).endsWith("/"+Xh(p.file)))?.path??p.file;await this.launch(b)}catch(d){console.error("[mirror] remote pull failed",d)}finally{this.launching.delete(a),this.update()}}async syncRow(s,a,d=!1){let p=`${Xh(s.path)}:${a}`;this.syncBusy.add(p),this.update();try{let b=a==="pull"?await tb.server.pullRemoteBulb(sD(s),hM(s.path),d):await tb.server.pushLocalBulb(s.path,d);b.ok?this.tickDone(p):b.conflict?this.pendingOverwrite={...a==="pull"?{heading:`\u201C${s.name}\u201D has local changes`,body:"Your local file differs from the typebulb.com copy. Overwrite the local file with the site's version?",yesLabel:"Overwrite local"}:{heading:`The site copy of \u201C${s.name}\u201D changed`,body:"It changed since your last sync. Overwrite the typebulb.com copy with your local file?",yesLabel:"Overwrite site copy"},onYes:()=>this.syncRow(s,a,!0)}:console.error(`[mirror] ${a} failed`,b.error)}catch(b){console.error(`[mirror] ${a} failed`,b)}finally{this.syncBusy.delete(p)}await(a==="pull"?this.refreshFiles():this.refreshMine()),this.update()}tickDone(s){this.syncDone.add(s),setTimeout(()=>{this.syncDone.delete(s),this.update()},1200)}async doLaunch(s,a,d=!1){let p=Xh(s);this.launching.add(p),this.update();let b;try{b=(await tb.server.launchBulb(s,a)).pid}catch(v){console.error("[mirror] launchBulb failed",v)}finally{this.launching.delete(p)}d&&b&&this.dismissedDenials.add(b),await this.refresh(),this.pinToBottom()}displayName(s){return this.files.find(d=>Xh(d.path)===Xh(s))?.name||hM(s)||s}launchTrusted(){let s=this.pendingLaunch;this.pendingLaunch=void 0,s&&this.doLaunch(s.path,!0)}launchRestricted(){let s=this.pendingLaunch;this.pendingLaunch=void 0,s&&this.doLaunch(s.path,void 0,!0)}cancelLaunch(){this.pendingLaunch=void 0,this.update()}async stop(s){this.openLog?.pid===s&&this.closeLog(),this.dismissedDenials.delete(s);try{await tb.server.stopBreakout(s)}catch(a){console.error("[mirror] stopBreakout failed",a)}await this.refresh()}pendingDenial(){return this.servers.find(s=>s.denied&&s.pid!==this.parent.ownPid&&!this.dismissedDenials.has(s.pid))}async elevate(s){this.dismissedDenials.add(s.pid),this.openLog?.pid===s.pid&&this.closeLog();try{await tb.server.launchBulb(s.file,!0)}catch(a){console.error("[mirror] elevate failed",a)}await this.refresh()}dismissDenial(s){this.dismissedDenials.add(s),this.update()}async toggleTrust(s){let a=!(s.running?s.running.trust:s.trusted);try{await tb.server.setBulbTrust(s.path,a),s.running&&(this.openLog?.pid===s.running.pid&&this.closeLog(),await tb.server.launchBulb(s.path,a))}catch(d){console.error("[mirror] toggleTrust failed",d)}await this.refresh()}showLog(s,a){if(this.openLog?.pid===s.pid){this.closeLog();return}this.closeLog(),this.openLog={pid:s.pid,name:a,text:"",offset:0},this.update(),setTimeout(()=>document.getElementById("bulb-console")?.focus()),this.#n(),this.#e=setInterval(()=>this.#n(),700)}closeLog(){this.#e&&(clearInterval(this.#e),this.#e=void 0),this.openLog&&(this.openLog=void 0,this.update())}async#n(){let s=this.openLog;if(s)try{let{text:a,offset:d}=await tb.server.readBulbLog(s.pid,s.offset);if(this.openLog!==s)return;a?(s.text=(s.text+a).slice(-5e4),s.offset=d,this.update()):d!==s.offset&&(s.offset=d)}catch(a){console.error("[mirror] readBulbLog failed",a)}}view(){let s=this.servers.filter(p=>p.pid!==this.parent.ownPid).length;if(!(this.files.length>0||this.samples.length>0)&&s===0)return Zt({class:"servers-wrap"});let d=this.pendingDenial();return Zt({class:"servers-wrap"},wc({class:["pill",s>0?"":"glyph",this.open?"on":""],title:"Launch a project bulb \xB7 stop a running one",onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},s>0?`${s}\u{1F4A1}`:Fr({class:"glyph-img"},"\u{1F4A1}")),this.open?this.popup():null,this.pendingLaunch?this.launchModal(this.pendingLaunch):this.pendingOverwrite?this.overwriteModal(this.pendingOverwrite):d?this.denialModal(d):null)}overwriteModal(s){let a=()=>{this.pendingOverwrite=void 0,this.update()};return this.trustModal({heading:s.heading,body:s.body,warn:"There is no undo \u2014 the overwritten side's changes are gone.",noLabel:"Cancel",yesLabel:s.yesLabel,onNo:a,onYes:()=>{this.pendingOverwrite=void 0,s.onYes()},onDismiss:a})}trustModal(s){let a=(d,p)=>{d.stopPropagation(),p(),this.open&&this.focusFilter()};return Zt({class:"trust-back",tabIndex:0,onMounted:d=>d.focus(),onKeyDown:d=>{d.key==="Escape"&&a(d,s.onDismiss)},onClick:d=>a(d,s.onDismiss)},Zt({class:"trust-modal",onClick:d=>d.stopPropagation()},Zt({class:"trust-modal-h"},s.heading),Zt({class:"trust-modal-b"},s.body),Zt({class:"trust-modal-warn"},s.warn),Zt({class:"trust-modal-acts"},wc({class:"trust-no",onClick:d=>a(d,s.onNo)},s.noLabel),wc({class:"trust-yes",onClick:d=>a(d,s.onYes)},s.yesLabel))))}launchModal(s){return this.trustModal({heading:`\u201C${s.name}\u201D will likely need access`,body:`It looks like it uses ${s.cap}, which is blocked unless you launch it Trusted. Launch Trusted to allow filesystem / AI / server.ts?`,warn:"Only trust bulbs you wrote or have read \u2014 be careful with anything off the internet.",noLabel:"Launch restricted",yesLabel:"Launch trusted",onNo:()=>this.launchRestricted(),onYes:()=>this.launchTrusted(),onDismiss:()=>this.cancelLaunch()})}denialModal(s){let a=hM(s.file)||s.file,d=!s.predicted;return this.trustModal({heading:d?`\u201C${a}\u201D reached for access it didn't declare`:`\u201C${a}\u201D wants more access`,body:d?`It tried to use ${s.denied} at runtime, though nothing in its code obviously needed it. Relaunch it Trusted to allow filesystem / AI / server.ts?`:`It tried to use ${s.denied}, blocked while it's restricted. Relaunch it Trusted to allow filesystem / AI / server.ts?`,warn:d?"Code that reaches for capabilities it never visibly uses can be hiding something \u2014 only continue if you wrote this bulb or have read it.":"Only trust bulbs you wrote or have read \u2014 be careful with anything off the internet.",noLabel:"Keep restricted",yesLabel:"Trust & relaunch",onNo:()=>this.dismissDenial(s.pid),onYes:()=>this.elevate(s),onDismiss:()=>this.dismissDenial(s.pid)})}popup(){if(this.openLog)return this.consoleView(this.openLog);let s=this.rows(),a=this.spotlightPid,d=a!==void 0&&s.some(p=>p.running?.pid===a);return Zt({class:"servers-pop"},s.length===0?this.emptyState("No bulbs in this project yet."):Zt({class:"bulb-list",onScroll:()=>this.onListScroll()},s.map((p,b)=>this.row(p,b,d&&p.running?.pid!==a))),this.filterBox(this.merged().filter(p=>!p.remote).length,"bulb"))}consoleView(s){return Zt({id:"bulb-console",class:"servers-pop log-mode",tabIndex:0,onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeLog())}},Zt({class:"bulb-log-head"},Fr({class:"bulb-log-name"},`console \xB7 ${s.name}`),wc({class:"bulb-log-back",title:"Back to the bulb list",onClick:a=>{a.stopPropagation(),this.closeLog()}},"\u2190 bulbs")),i6({class:"bulb-log-body"},Fr({class:"bulb-log-text"},s.text||"(no output yet)")))}hoverRow(s,a){let d=a!==void 0&&a.pid===this.spotlightPid;d&&(this.spotlightPid=void 0),(this.highlighted!==s||d)&&(this.highlighted=s,this.update())}row(s,a,d=!1){if(s.group)return this.groupRow(s,a,d);let p=s.running,b=p&&this.openLog?.pid===p.pid,v=p?!!p.trust:!!s.trusted,w=!!s.remote&&!this.searchActive&&!this.filter.trim();return Zt({class:["server-row",w?"fold-row":"",a===this.highlighted?"active":"",d?"dimmed":""],onMouseEnter:()=>this.hoverRow(a,p)},p?wc({class:"server-stop",title:"Stop this server",ariaLabel:"Stop",onClick:I=>{I.stopPropagation(),this.stop(p.pid)}},pvn()):wc({class:["bulb-launch",this.launching.has(Xh(s.path))?"launching shimmer":""],title:s.remote?"Download from typebulb.com & launch":v?"Launch (trusted \u2014 remembered)":"Launch (restricted)",ariaLabel:"Launch",onClick:I=>{I.stopPropagation(),s.remote?this.downloadAndLaunch(s):this.launch(s.path)}},dvn()),Zt({class:"bulb-name-cell"},s.remote?Fr({class:"server-name stopped remote",title:s.remote.description},s.name):Fr({class:["server-name",p?"":"stopped"],title:`Open ${s.path}`,onClick:I=>{I.stopPropagation(),tb.server.openFile(s.path)}},s.name),this.userLink(s),Wee(s.hitCount)),this.syncCell(s),p||v?this.trustToggle(s,v):Fr({class:"cell-empty"}),p?gC({class:["server-logs",b?"on":""],title:"Show this server\u2019s console",onClick:I=>{I.stopPropagation(),this.showLog(p,s.name)}},"logs"):Fr({class:"cell-empty"}),p?gC({class:"server-port",href:p.url,target:"_blank",rel:"noopener noreferrer",title:`Open ${p.url}`},`:${p.port}`):s.remote?Fr({class:"cell-empty"}):Fr({class:"bulb-time"},Xee(s.recent)),Yee(s.snippet,this.filter.trim()))}userLink(s){let a=sD(s);return a?gC({class:"sample-link",href:bvn(s,a),target:"_blank",rel:"noopener noreferrer",title:"Open this bulb's page on typebulb.com"},a):null}syncCell(s){let a=sD(s);if(!a||s.remote)return Fr({class:"cell-empty"});let d=(p,b)=>{let v=`${Xh(s.path)}:${p}`,w=this.syncBusy.has(v),I=this.syncDone.has(v);return wc({class:["sync-btn",w?"busy shimmer":"",I?"done":""],title:b,ariaLabel:p,onClick:T=>{T.stopPropagation(),w||this.syncRow(s,p)}},np(I?"check":p,"btn-icon-sm"))};return Fr({class:"sync-cell"},d("pull",`Pull \u2014 update the local file from typebulb.com/u/${a}`),a===this.myUser?d("push","Push \u2014 upload this file to typebulb.com"):null)}groupRow(s,a,d){let{user:p,count:b}=s.group,v=this.openFolds.has(p);return Zt({class:["server-row","sample-group",v?"open":"",a===this.highlighted?"active":"",d?"dimmed":""],title:v?"Collapse":this.foldTitle(p),onMouseEnter:()=>this.hoverRow(a),onClick:w=>{w.stopPropagation(),this.toggleFold(p)}},np("caret",["caret-tri",v?"open":""]),Fr({class:"sample-group-label"},`${s.name} (${b})`))}trustToggle(s,a){return wc({class:["trust-toggle",a?"on":""],title:`${a?"Trusted":"Restricted"} \u2014 click to switch to ${a?"restricted":"trusted"}`+(s.running?" (stops + relaunches it)":""),onClick:d=>{d.stopPropagation(),this.toggleTrust(s)}},a?"trusted":"restricted")}};var Wre=class extends wu{get parent(){return this.ctx.parent}view(){let s=this.parent.prose;return wc({class:["pill","glyph",s?"on":""],title:s?"Trace view":"Content view",onClick:()=>{this.parent.prose=!s,this.update()}},Fr({class:"glyph-img"},"\u{1F648}"))}};var mvn=4e5;function wvn(o,s){let a=o.split(`
|
|
1451
1451
|
`).map(v=>v.replace(/\r$/,""));if(a.length&&a[a.length-1]===""&&a.pop(),s)return a.map(v=>({kind:"add",text:v}));let d=[],p=!1,b=!1;for(let v of a){if(v.startsWith("@@")){b&&d.push({kind:"gap",text:"\u22EF"}),b=!0,p=!0;continue}if(!p){v.startsWith("Binary file")&&d.push({kind:"ctx",text:v});continue}v.startsWith("\\")||(v.startsWith("+")?d.push({kind:"add",text:v.slice(1)}):v.startsWith("-")?d.push({kind:"del",text:v.slice(1)}):d.push({kind:"ctx",text:v.slice(1)}))}return d}function Avn(o,s,a){let d=wvn(o,s),p=o.length>mvn?"txt":a.split(".").pop()??"",b=[],v=[];for(let P of d)(P.kind==="ctx"||P.kind==="del")&&b.push(P.text),(P.kind==="ctx"||P.kind==="add")&&v.push(P.text);let w=Gxe(b.join(`
|
|
1452
1452
|
`),p),I=Gxe(v.join(`
|
|
1453
1453
|
`),p),T=0,B=0,D=[];for(let P of d){if(P.kind==="gap"){D.push('<div class="udiff-gap">\u22EF</div>');continue}let j=P.kind==="del"?w[T++]:(P.kind==="add"||T++,I[B++]);D.push(`<div class="udiff-line${P.kind==="add"?" udiff-add":P.kind==="del"?" udiff-del":""}">${j??""}</div>`)}return{kinds:d.map(P=>P.kind),bodyHtml:D.join("")}}var Yre=class extends M7{files=[];repo=!0;root="";viewing;#e=0;#n=!1;keepOpenSelector=".gitdiff-wrap";filterId="gitdiff-filter";listSelector=".gitdiff-list";filterNoun="file";search(){return Promise.resolve([])}onActivate(s){let a=this.rows()[s];a&&this.openDiff(a)}onAttached(){this.refreshFiles(),setInterval(()=>this.refreshFiles(),3e3),setInterval(()=>{this.viewing&&this.refreshDiff()},1500)}rows(){let s=this.filter.trim().toLowerCase();return s?this.files.filter(a=>a.path.toLowerCase().includes(s)):this.files}async refreshFiles(){try{let{repo:s,root:a,files:d}=await tb.server.gitChangedFiles(),p=s!==this.repo||d.length!==this.files.length||d.some((b,v)=>{let w=this.files[v];return b.path!==w?.path||b.status!==w.status||b.add!==w.add||b.del!==w.del});this.repo=s,this.root=a,this.files=d,p&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] gitChangedFiles failed",s)}}#t(s,a,d){this.viewing={path:s,status:a,text:d.text,truncated:!!d.truncated,...Avn(d.text,!!d.untracked,s)},this.#e++,this.update()}async openDiff(s){try{let a=await tb.server.gitDiff(s.path);if(!a.ok){console.error("[mirror] gitDiff failed:",a.error);return}this.#t(s.path,s.status,a),this.#n=!0,this.close()}catch(a){console.error("[mirror] gitDiff failed",a)}}async refreshDiff(){let s=this.viewing;if(s)try{let a=await tb.server.gitDiff(s.path);if(this.viewing!==s||!a.ok||a.text===s.text)return;this.#t(s.path,s.status,a)}catch(a){console.error("[mirror] gitDiff refresh failed",a)}}closeDoc(){this.viewing=void 0,this.update()}show(){this.beginOpen(),this.refreshFiles(),this.refreshList(),this.armClose(),this.focusFilter()}view(){let s=this.files.length;return!this.repo||s===0&&!this.viewing&&!this.open?Zt({class:"gitdiff-wrap"}):Zt({class:"gitdiff-wrap"},wc({class:["pill","glyph","gitdiff-pill",this.viewing||this.open?"on":""],title:`${s} changed file${s===1?"":"s"} \u2014 view a diff`,onClick:a=>{a.stopPropagation(),this.open?this.close():this.show()}},np("diff"),Fr({class:"gitdiff-count"},String(s))),this.open?this.popup():null)}popup(){let s=this.rows();return Zt({class:"servers-pop gitdiff-pop"},s.length===0?this.emptyState("No changes in the working tree."):Zt({class:"gitdiff-list",onScroll:()=>this.onListScroll()},s.map((a,d)=>this.row(a,d))),this.filterRow())}filterRow(){let s=this.files.length;return Kee({target:this,prop:()=>this.filter,id:this.filterId,placeholder:s?`Filter ${s} file${s===1?"":"s"}\u2026`:"Filter files\u2026",hasValue:!!this.filter,onKeyDown:a=>this.onFilterKey(a),onClear:()=>this.clearFilter()})}row(s,a){return Zt({class:["gitdiff-row",a===this.highlighted?"active":"",this.viewing?.path===s.path?"viewing":""],onMouseEnter:()=>{this.highlighted!==a&&(this.highlighted=a,this.update())},onClick:d=>{d.stopPropagation(),this.openDiff(s)}},Fr({class:["gitdiff-status",`s-${s.status}`]},s.status),Fr({class:"gitdiff-path",title:s.path},s.path),s.add!==void 0||s.del!==void 0?Fr({class:"gitdiff-counts"},Fr({class:"count-add"},`+${s.add??0}`),Fr({class:"count-del"},`\u2212${s.del??0}`)):Fr({class:"gitdiff-counts"},Fr({class:"count-add"},"new")))}docView(){let s=this.viewing,a=s.kinds.filter(p=>p==="add").length,d=s.kinds.filter(p=>p==="del").length;return Zt({class:"diff-doc",tabIndex:0,onMounted:p=>p.focus(),onKeyDown:p=>{p.key==="Escape"&&(p.stopPropagation(),this.closeDoc())}},Zt({class:"diff-doc-head"},Fr({class:["gitdiff-status",`s-${s.status}`]},s.status),Fr({class:"diff-doc-path",title:`Open ${s.path}`,onClick:()=>tb.server.openFile(`${this.root}/${s.path}`)},s.path),Fr({class:"gitdiff-counts"},Fr({class:"count-add"},`+${a}`),Fr({class:"count-del"},`\u2212${d}`)),wc({class:"bulb-log-back",title:"Back to the conversation (Esc)",onClick:p=>{p.stopPropagation(),this.closeDoc()}},"\u2190 conversation")),Zt({class:"diff-doc-scroll"},Zt({class:"diff-doc-body"},s.kinds.length===0?Zt({class:"diff-doc-empty"},"No changes."):Zt({class:"diff-doc-code",key:`diff-code-${this.#e}`,onMounted:p=>{p.innerHTML=s.bodyHtml,this.#r(p)}},""),s.truncated?Zt({class:"diff-doc-trunc"},"Diff truncated \u2014 file too large to show in full."):null),s.kinds.length?this.ruler(s.kinds):null))}#r(s){if(!this.#n)return;this.#n=!1;let a=s.querySelector(".udiff-add, .udiff-del"),d=s.closest(".diff-doc-body");a&&d&&(d.scrollTop=a.offsetTop-d.clientHeight/3)}ruler(s){let a=s.length,d=[];return s.forEach((p,b)=>{if(p!=="add"&&p!=="del")return;let v=d[d.length-1];v&&v.kind===p&&v.start+v.len===b?v.len++:d.push({kind:p,start:b,len:1})}),Zt({class:"diff-ruler",title:"Jump to a change",onClick:p=>{let b=document.querySelector(".diff-doc-body"),v=p.currentTarget;if(!b)return;let w=(p.clientY-v.getBoundingClientRect().top)/v.clientHeight;b.scrollTop=w*b.scrollHeight-b.clientHeight/2}},d.map(p=>Zt({class:["diff-ruler-mark",p.kind],style:{top:`${p.start/a*100}%`,height:`${p.len/a*100}%`}})))}};var Xre=class extends wu{done=!1;#e;constructor(s){super(),this.#e=s}setText(s){this.#e=s}flash(){navigator.clipboard?.writeText(this.#e),this.done=!0,this.update(),setTimeout(()=>{this.done=!1,this.update()},600)}view(){return wc({class:["overlay-pill","copy",this.done?"done":""],onClick:s=>{s.stopPropagation(),this.flash()}},this.done?"copied":"copy")}};var Vre=class extends wu{spread=!1;showingCode=!1;copied=!1;#e="";#n;#t;#r;#i;#s;#o;#c;#u=!1;#h=1;#g=!1;#a;#l="idle";constructor(s,a){super(),this.#n=s,this.#t=a,this.#r=EH(s);let d=kke(s);this.#i=d.length?d.join(" "):void 0}get name(){return this.#r}get key(){return this.#t}setChainPosition(s){this.#h=s}get chainPosition(){return this.#h}setMounted(s){s!==this.#u&&(this.#u=s,this.#d())}onAttached(){this.#d()}#d(){if(this.#u){if(this.#s||this.#g||this.#o)return;this.#g=!0,this.#a=new AbortController,aSt(this.#n,{signal:this.#a.signal,onError:s=>{this.#c=s,this.#p("runtime",s),this.update()},onReady:()=>this.#p(this.#i?"malformed":"ok",this.#i)}).then(s=>{this.#g=!1,this.#u&&(this.#s=s,this.update())}).catch(s=>{this.#g=!1,this.#o=s instanceof Error?s.message:String(s),this.#p("compile",this.#o),this.update()})}else{if(!this.#s&&!this.#g)return;this.#a?.abort(),this.#a=void 0,this.#s=void 0,this.#c=void 0,this.update()}}#p(s,a){let d=this.#r??this.#t,p=s==="ok"?"ok":s==="malformed"?`malformed: ${a}`:`${s} error: ${a}`;tb.server.logEmbedStatus(d,`[embed ${d} v${this.#h}] ${p}`).catch(()=>{})}dispose(){this.#a?.abort()}view(){let s=["embed","bulb-embed",this.spread?"spread":"fit",this.showingCode?"code-open":"",this.#o?"err":""],a=this.#r?`${this.#r} \u2014 `:"",d=this.#o?[`${a}could not render: ${this.#o}`]:this.#s?[this.#w(),Zt({class:"bulb-frame",key:"frame",onMounted:p=>{this.#s&&p.replaceChildren(this.#s)}}),this.showingCode?this.#A():null,this.#c?Zt({class:"bulb-err-strip",key:"err"},`\u26A0 ${a}${this.#c}`):null,this.#i?Zt({class:"bulb-warn-strip",key:"warn"},`\u26A0 ${a}malformed: ${this.#i}`):null]:["compiling bulb\u2026"];return Zt({class:"md",key:this.#t},Zt({class:s},...d))}#w(){let s=this.#l==="done"?this.#e:"breakout \u2197";return Zt({class:"bulb-controls",key:"controls"},this.#b("bulb-view",this.spread?"fit":"spread",this.spread?"Fit into the conversation column":"Spread to the full transcript width and height",()=>{this.spread=!this.spread,this.update()}),this.#b("bulb-toggle",this.showingCode?"run":"code",this.showingCode?"Back to the running bulb":"View this bulb's source",()=>{this.showingCode=!this.showingCode,this.update()}),this.#b(["bulb-copy",this.copied?"done":""],this.copied?"copied":"copy","Copy this bulb's full source",()=>this.#m()),wc({class:["overlay-pill","bulb-breakout",this.#l==="busy"?"launching shimmer":""],type:"button",disabled:this.#l!=="idle",title:"Save as a standalone .bulb.md and open it with typebulb",onClick:a=>{a.stopPropagation(),this.#f()}},s))}#b(s,a,d,p){let b=Array.isArray(s)?s:[s];return wc({class:["overlay-pill",...b],type:"button",title:d,onClick:v=>{v.stopPropagation(),p()}},a)}#m(){navigator.clipboard?.writeText(this.#n),this.copied=!0,this.update(),setTimeout(()=>{this.copied=!1,this.update()},1200)}async#f(){if(this.#l==="idle"){this.#l="busy",this.update();try{let{file:s,pid:a}=await tb.server.breakout(this.#n);this.#e=`launched ${s}`,window.dispatchEvent(new CustomEvent("tb-breakout",{detail:{pid:a}}))}catch(s){this.#e="breakout failed",console.error("[mirror] breakout failed",s)}this.#l="done",this.update(),setTimeout(()=>{this.#l="idle",this.update()},2500)}}#A(){return Zt({class:["bulb-code","md"],key:"code",tabIndex:0,onKeyDown:s=>{if(!((s.ctrlKey||s.metaKey)&&(s.key==="a"||s.key==="A")))return;s.preventDefault();let a=getSelection();if(!a)return;let d=document.createRange();d.selectNodeContents(s.currentTarget),a.removeAllRanges(),a.addRange(d)},onMounted:s=>{s.innerHTML=rD.render(CH(this.#n))}})}};function bSt(o){return o.map((s,a)=>!!s&&o[a+1]===s)}function mSt(o){let s=[];for(let a=0;a<o.length;a++)s[a]=a>0&&o[a]&&o[a]===o[a-1]?s[a-1]+1:1;return s}var wSt=".typebulb/paste",ASt={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",bmp:"image/bmp"};var vvn=new RegExp(`@${wSt.replace(/\./g,"\\.")}/([\\w-]+(?:\\.[\\w-]+)*\\.(?:${Object.keys(ASt).join("|")}))`,"gi"),yvn=new URL("typebulb.png",import.meta.url).href,kvn=new URL("typebulb-inv.png",import.meta.url).href;function xvn(o){return!o||typeof o!="object"?"":qd(o.command)??qd(o.file_path)??qd(o.path)??qd(o.pattern)??qd(o.query)??qd(o.url)??qd(o.skill)??qd(o.description)??""}function Evn(o){let s=o.indexOf(`
|
|
@@ -2217,7 +2217,7 @@ var Patcher = class _Patcher {
|
|
|
2217
2217
|
|
|
2218
2218
|
// cli/agents/pi/server/piPatcherExtension.ts
|
|
2219
2219
|
var DESCRIPTION = true ? "Apply unified diffs to files \u2014 tolerant of form, strict about intent. Repairs sloppy AI-generated diffs (mangled headers, whitespace drift, missing prefixes; line numbers can be wrong or absent \u2014 hunks anchor by fuzzy-matched context lines) and applies all hunks atomically when the intent is unambiguous; fails with a precise, typed error when it isn't. Use for multi-hunk edits in one step, or when exact string-replacement editing fails on whitespace or invisible characters." : "Apply unified diffs to files.";
|
|
2220
|
-
var BUILD_TAG = true ? "matchu-patchu-pi 0.2.0, built 2026-07-16 09:
|
|
2220
|
+
var BUILD_TAG = true ? "matchu-patchu-pi 0.2.0, built 2026-07-16 09:47:20" : "matchu-patchu-pi dev";
|
|
2221
2221
|
var errorBlocks = (errors) => {
|
|
2222
2222
|
const parts = [`Patch failed with ${errors.length} error(s):`];
|
|
2223
2223
|
for (const e of errors) parts.push("", e.toString());
|
|
@@ -817,16 +817,27 @@ a.server-port:hover { text-decoration: underline; }
|
|
|
817
817
|
the logs-link register — marks the category and opens the bulb's published page. A remote
|
|
818
818
|
(not-yet-downloaded) row's name is additionally muted and inert (no file to open), and its
|
|
819
819
|
time column stays empty (no mtime to show). */
|
|
820
|
-
.server-name.remote {
|
|
820
|
+
.server-name.remote { cursor: default; }
|
|
821
821
|
.server-name.remote:hover { text-decoration: none; }
|
|
822
822
|
.sample-link { color: var(--muted); font-size: .76rem; text-decoration: none; cursor: pointer; flex: none; }
|
|
823
823
|
.sample-link:hover { color: var(--accent); text-decoration: underline; }
|
|
824
|
-
/* The
|
|
825
|
-
|
|
824
|
+
/* The remote fold (bulbsPill.ts groupRow / fold-row): the header and the remote rows within share
|
|
825
|
+
one veil step over the menu's panel bg (the picker-peek shade) as ONE contiguous band — each
|
|
826
|
+
row's ::before bridges the grid row-gap up to the row above, junction corners square off, and
|
|
827
|
+
only the band's outer corners round (the header's top; the last row's bottom, via :has). The
|
|
828
|
+
accent label marks the header. Single-class selectors on purpose: .server-row:hover/.active
|
|
829
|
+
outrank them, so the highlight tints still win. */
|
|
826
830
|
.sample-group { cursor: pointer; color: var(--muted); }
|
|
827
|
-
.sample-group
|
|
831
|
+
.sample-group, .fold-row { background: linear-gradient(var(--veil), var(--veil)), var(--panel); }
|
|
832
|
+
.sample-group.open { border-radius: 6px 6px 0 0; }
|
|
833
|
+
.fold-row { position: relative; border-radius: 0; }
|
|
834
|
+
.fold-row::before {
|
|
835
|
+
content: ''; position: absolute; left: 0; right: 0; top: -.15rem; height: .15rem;
|
|
836
|
+
background: linear-gradient(var(--veil), var(--veil)), var(--panel);
|
|
837
|
+
}
|
|
838
|
+
.fold-row:not(:has(+ .fold-row)) { border-radius: 0 0 6px 6px; }
|
|
828
839
|
.sample-group .caret-tri { justify-self: center; }
|
|
829
|
-
.sample-group-label { grid-column: 2 / -1; }
|
|
840
|
+
.sample-group-label { grid-column: 2 / -1; color: var(--accent); }
|
|
830
841
|
/* The 1fr name column: name + (in full-text mode) its hit count read together, the badge
|
|
831
842
|
right-aligned at the column's end by the name's flex:1 — the session row's preview/hits layout. */
|
|
832
843
|
.bulb-name-cell { display: flex; align-items: baseline; gap: .6rem; min-width: 0; }
|
package/dist/index.js
CHANGED
|
@@ -1915,5 +1915,5 @@ ${oP}
|
|
|
1915
1915
|
`);let a=0,c=Promise.resolve();Vt({target:r,onChange:()=>{let l=++a;c=c.then(async()=>{if(l===a)try{console.log("Re-running..."),await o()}catch(d){console.error("Error:",d)}})}})}}mt();import{Console as fP}from"node:console";Ne();async function fy(r,e,t,n){gP();try{let f=Sr(await Y(),r)[0];f&&(_i(f.pid,Re(f.pid).offset),console.error(`note: 'call' boots a fresh server.ts instance; the running server (${f.url}) is not contacted \u2014 state shared with it must live on disk.`))}catch{}let s=ge(t),{bulb:i,config:o}=await xe(r);i.server||Yn("This bulb has no **server.ts** block; nothing to call."),pt(s,r,i.server);let a;try{a=await On(i.server,r,n,o.dependencies)}catch(f){Yn(f instanceof Error?f.message:String(f))}let c=ko(a,e.fn);if(!c){let f=[...Object.keys(a).filter(p=>typeof a[p]=="function"),...Object.keys(So)];Yn(`Function '${e.fn}' not found. Available: ${f.length?f.join(", "):"(none)"}.`)}let l=await dP(e);if(xo(c)){try{for await(let f of c(...l))await uy(JSON.stringify(f,dy)+`
|
|
1916
1916
|
`)}catch(f){Yn(f instanceof Error?f.stack??f.message:String(f))}return ly(0)}let d;try{d=await c(...l)}catch(f){Yn(f instanceof Error?f.stack??f.message:String(f))}let u=hP(d);u!==void 0&&await uy(u+`
|
|
1917
1917
|
`),ly(0)}function ly(r){process.exitCode=r,setTimeout(()=>process.exit(r),2e3).unref?.()}async function dP(r){if(r.hasArgsFlag){let e=r.argsJson??"";return e==="-"&&(e=await yP()),mP(e)}return pP(r.positional)}function pP(r){return r.map(e=>{try{return JSON.parse(e)}catch{return e}})}function mP(r){let e;try{e=JSON.parse(r)}catch(t){throw new Error(`--args must be a JSON array: ${t instanceof Error?t.message:String(t)}`)}if(!Array.isArray(e))throw new Error(`--args must be a JSON array, got ${e===null?"null":typeof e}`);return e}function hP(r){if(r!==void 0)return JSON.stringify(r,dy,2)}function dy(r,e){return typeof e=="bigint"?e.toString():e}function Yn(r){process.stderr.write(r+`
|
|
1918
|
-
`),process.exit(1)}function gP(){let r=new fP(process.stderr,process.stderr);console.log=r.log.bind(r),console.info=r.info.bind(r),console.debug=r.debug.bind(r),console.dir=r.dir.bind(r)}function uy(r){return new Promise((e,t)=>{process.stdout.write(r,n=>n?t(n):e())})}async function yP(){let r=[];for await(let e of process.stdin)r.push(e);return Buffer.concat(r).toString("utf-8")}var Xl="0.28.
|
|
1918
|
+
`),process.exit(1)}function gP(){let r=new fP(process.stderr,process.stderr);console.log=r.log.bind(r),console.info=r.info.bind(r),console.debug=r.debug.bind(r),console.dir=r.dir.bind(r)}function uy(r){return new Promise((e,t)=>{process.stdout.write(r,n=>n?t(n):e())})}async function yP(){let r=[];for await(let e of process.stdin)r.push(e);return Buffer.concat(r).toString("utf-8")}var Xl="0.28.2";function py(r,e){r||(console.error(`This bulb runs server-side Node code (server.ts), which --trust must authorize:
|
|
1919
1919
|
${e}`),process.exit(1))}async function bP(){let r=pu(process.argv.slice(2));if(r.version&&(console.log(`typebulb ${Xl}`),process.exit(0)),r.help&&(mu(),process.exit(0)),Ig(),r.subcommand==="logs"){await Jg(r.file||void 0,{follow:r.follow,clear:r.clear,run:r.run,lines:r.lines});return}if(r.subcommand==="wait"){await Kg(r.file||void 0,{match:r.match,timeoutSec:r.timeoutSec});return}if(r.subcommand==="stop"){r.stopScope?await Wg(r.stopScope):await Hg(r.file||void 0);return}if(r.subcommand==="send"){await Vg(r.file,r.sendMessage,r.sendWaitMs??0);return}if(r.subcommand==="skill"){await Fg(Xl);return}if(r.subcommand==="models"){await Bg(r.mode);return}if(r.subcommand==="pull"){await Bm(r.file||void 0,{force:r.force,mode:r.mode});return}if(r.subcommand==="push"){await qm(r.file||void 0,{force:r.force,mode:r.mode});return}if(r.subcommand==="agent"){await(r.agentTarget?oy(r):Dg(Xl));return}if(r.subcommand==="trust"||r.subcommand==="untrust"){await Ng(r.file||void 0,r.subcommand==="trust");return}let e;if(!r.file||r.file==="."){let c=await om(process.cwd());c||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=c}else e=Gt.resolve(r.file);await my.access(e).then(()=>!0,()=>!1)||(Rr().includes(r.file)&&(console.error(`To open the ${r.file} agent mirror, run: npx typebulb agent:${r.file}`),process.exit(1)),console.error(`File not found: ${e}`),process.exit(1)),e.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1));let n=r.file&&r.file!=="."?r.file:Gt.relative(process.cwd(),e)||Gt.basename(e),s=`npx typebulb --trust ${n.includes(" ")?`"${n}"`:n}`;if(r.subcommand==="predict"){await Rg(e,s);return}let i=!r.noTrust&&Bt(e);i&&!r.trust&&console.error("trust: granted from memory (run `typebulb untrust` to revoke)"),r.trust=r.noTrust?!1:r.trust||i;let o;try{o=await xe(e)}catch{}let a;if(r.local){o&&!(r.local.name in(o.config.dependencies??{}))&&(console.error(`--replace: '${r.local.name}' is not a dependency in this bulb's config.json; nothing to replace.`),process.exit(1)),o&&r.subcommand!=="call"&&(!o.bulb.code||r.server)&&console.warn("warning: --replace has no effect in server mode (the override is client-only).");try{a=await fu(r.local)}catch(c){console.error(c instanceof Error?c.message:String(c)),process.exit(1)}console.error(`replace: ${a.name} \u2192 ${Gt.relative(process.cwd(),a.dir)||"."}`)}if(r.subcommand==="check"){await _g(e,a);return}if(r.subcommand==="call"){py(r.trust,s),await fy(e,{fn:r.fn,positional:r.callArgs,argsJson:r.argsJson,hasArgsFlag:r.hasArgsFlag},r.mode,a);return}if(o&&o.bulb.server&&(zs(o.bulb)||r.server)){py(r.trust,s),await cy(e,r.watch,r.mode,a);return}await ry(e,r,s,a)}bP().catch(r=>{console.error("Error:",r.message),process.exit(1)});
|
package/package.json
CHANGED