typebulb 0.60.7 → 0.60.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/dist/agents/claude/client.js +1 -1
- package/dist/agents/codex/client.js +1 -1
- package/dist/agents/pi/client.js +1 -1
- package/dist/index.js +218 -218
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: typebulb
|
|
3
3
|
description: "Author and run Typebulb bulbs — single-file markdown apps (TypeScript/TSX) that run locally via `npx typebulb` (full power: filesystem, database, `server.ts`, `tb.ai`) or render live inline in your coding agent's session through Typebulb's agent mirror (sandboxed, client-only). A bulb can be a visual widget (chart, simulation, diagram, calculator, UI), a full-stack tool with a Node backend, or an AI app that calls models at runtime. Covers the bulb format, the `tb.*` API, trust, and the local run/inline workflow. Use when the user wants a bulb, a quick local tool (visual, backend-backed, or AI-powered), or something visual rendered inline in the conversation."
|
|
4
|
-
version: 0.60.
|
|
4
|
+
version: 0.60.9
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
> Generated from typebulb v0.60.
|
|
7
|
+
> Generated from typebulb v0.60.9. `npx typebulb agent` prints the running version alongside the path to its packaged SKILL.md: if that version is newer than this one, replace this file with that one.
|
|
8
8
|
|
|
9
9
|
# typebulb
|
|
10
10
|
|
|
@@ -2191,7 +2191,7 @@ ${a||this.currentRow()?.pending?"New conversation \u2014 not saved yet":`Session
|
|
|
2191
2191
|
`):"Waiting for the harness to flush this turn";return Jn({class:"token-wrap"},Jn({class:["token",Vee(b)],"data-tip":T},I))}};function zSt(o,...s){return o.slice().sort((a,d)=>{for(let{key:p,desc:b}of s){let v=p(a),w=p(d);if(v!==w)return v==null?b?-1:1:w==null||v<w?b?1:-1:b?-1:1}return 0})}var i5n=()=>t2("play","btn-icon"),s5n=()=>t2("stop","btn-icon"),o5n=o=>`typebulbs/u/samples/${o}.bulb.md`,rD=o=>Gh(o.path).match(/typebulbs\/u\/([^/]+)\//)?.[1],c5n=(o,s)=>`https://typebulb.com/u/${s}/${aM(o.path)}/full`,KSt=o=>o==="HTTP 404"?"not found \u2014 check the URL (private bulbs need their owner's token)":o==="HTTP 401"||o==="HTTP 403"?"private \u2014 needs its owner's TYPEBULB_TOKEN in .env":o||"pull failed",tie=class extends n2{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;pullErrors=new Map;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?SF(a.running.url):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||d.lastRunAt!==this.files[p]?.lastRunAt);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=>Gh(p.path)),d=[...this.samples.map(p=>[o5n(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:Math.max(p.mtime,p.lastRunAt??0),trusted:p.trusted})});for(let p of this.servers){if(p.pid===this.parent.ownPid)continue;let b=Gh(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=>[Gh(d.path),d]));s=s.flatMap(d=>{let p=a.get(Gh(d.path));return p?[{...d,hitCount:p.hitCount,snippet:p.snippet}]:[]})}else{let a=this.filter.trim().toLowerCase(),d=L6t(this.filter);if(d){let p=`typebulbs/u/${d.user}/${d.slug}.bulb.md`,b=s.find(v=>("/"+Gh(v.path)).endsWith("/"+p));return b?[b]:[{path:p,name:d.slug,recent:0,remote:{slug:d.slug,name:d.slug,description:`u/${d.user}/${d.slug} on typebulb.com \u2014 play pulls it into the project`}}]}a?s=s.filter(p=>p.name.toLowerCase().includes(a)||p.path.toLowerCase().includes(a)):[...new Set(s.filter(b=>b.remote).map(b=>rD(b)))].forEach((b,v)=>{let w=T=>!!T.remote&&rD(T)===b,I=s.filter(w).length;this.openFolds.has(b)?s=s.map(T=>w(T)?{...T,recent:-.5-v}:T):s=s.filter(T=>!w(T)),s.push({path:`::${b}`,name:this.foldLabel(b),recent:-1-v,group:{user:b,count:I}})})}return zSt(s,{key:a=>!!a.running},{key:a=>a.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.pullErrors.clear(),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}'s bulbs`}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=>Gh(d.path)===Gh(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=Gh(s.path);this.launching.add(a),this.pullErrors.delete(a),this.update();try{let d=rD(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),this.pullErrors.set(a,KSt(p.error));return}await this.refreshFiles();let b=this.files.find(v=>Gh(v.path).endsWith("/"+Gh(p.file)))?.path??p.file;await this.launch(b)}catch(d){console.error("[mirror] remote pull failed",d),this.pullErrors.set(a,KSt(d?.message))}finally{this.launching.delete(a),this.update()}}async syncRow(s,a,d=!1){let p=`${Gh(s.path)}:${a}`;this.syncBusy.add(p),this.update();try{let b=a==="pull"?await tb.server.pullRemoteBulb(rD(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),this.update()}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=Gh(s);this.launching.add(p),this.update();let b;try{b=await tb.server.launchBulb(s,a)}catch(v){console.error("[mirror] launchBulb failed",v)}finally{this.launching.delete(p)}d&&b?.pid&&this.dismissedDenials.add(b.pid),b?.url&&SF(b.url),await this.refresh(),this.pinToBottom()}displayName(s){return this.files.find(d=>Gh(d.path)===Gh(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.#t(),this.#e=setInterval(()=>this.#t(),700)}closeLog(){this.#e&&(clearInterval(this.#e),this.#e=void 0),this.openLog&&(this.openLog=void 0,this.update())}async#t(){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 yt({class:"servers-wrap"});let d=this.pendingDenial();return yt({class:"servers-wrap"},Ao({class:["pill",s>0?"":"glyph",this.open?"on":""],"data-tip":"Launch a project bulb \xB7 stop a running one",ariaLabel:s>0?`Bulbs (${s} running)`:"Bulbs",onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},s>0?`${s}\u{1F4A1}`:Jn({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 yt({class:"trust-back",tabIndex:0,onMounted:d=>d.focus(),onKeyDown:d=>{d.key==="Escape"&&a(d,s.onDismiss)},onClick:d=>a(d,s.onDismiss)},yt({class:"trust-modal",onClick:d=>d.stopPropagation()},yt({class:"trust-modal-h"},s.heading),yt({class:"trust-modal-b"},s.body),yt({class:"trust-modal-warn"},s.warn),yt({class:"trust-modal-acts"},Ao({class:"trust-no",onClick:d=>a(d,s.onNo)},s.noLabel),Ao({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 yt({class:"servers-pop"},s.length===0?this.emptyState("No bulbs in this project yet."):yt({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 yt({id:"bulb-console",class:"servers-pop log-mode",tabIndex:0,onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeLog())}},yt({class:"bulb-log-head"},Jn({class:"bulb-log-name"},`console \xB7 ${s.name}`),Ao({class:"bulb-log-back",title:"Back to the bulb list",onClick:a=>{a.stopPropagation(),this.closeLog()}},"\u2190 bulbs")),i6({class:"bulb-log-body"},Jn({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=this.pullErrors.get(Gh(s.path)),w=p?!!p.trust:!!s.trusted,I=!!s.remote&&!this.searchActive&&!this.filter.trim();return yt({class:["server-row",I?"fold-row":"",a===this.highlighted?"active":"",d?"dimmed":""],onMouseEnter:()=>this.hoverRow(a,p)},p?Ao({class:"server-stop",title:"Stop this server",ariaLabel:"Stop",onClick:T=>{T.stopPropagation(),this.stop(p.pid)}},s5n()):Ao({class:["bulb-launch",this.launching.has(Gh(s.path))?"launching shimmer":""],title:s.remote?"Download from typebulb.com & launch":w?"Launch (trusted \u2014 remembered)":"Launch (restricted)",ariaLabel:"Launch",onClick:T=>{T.stopPropagation(),s.remote?this.downloadAndLaunch(s):this.launch(s.path)}},i5n()),yt({class:"bulb-name-cell"},s.remote?Jn({class:"server-name stopped remote",title:s.remote.description},s.name):Jn({class:["server-name",p?"":"stopped"],title:`Open ${s.path}`,onClick:T=>{T.stopPropagation(),tb.server.openFile(s.path)}},s.name),this.userLink(s),Zee(s.hitCount),v?Jn({class:"pull-error"},v):null),this.syncCell(s),p||w?this.trustToggle(s,w):Jn({class:"cell-empty"}),p?Dk({class:["server-logs",b?"on":""],title:"Show this server\u2019s console",onClick:T=>{T.stopPropagation(),this.showLog(p,s.name)}},"logs"):Jn({class:"cell-empty"}),p?Dk({class:"server-port",href:Yye(p.url),target:"_blank",rel:"noopener noreferrer",title:`Open ${p.url}`},`:${p.port}`):s.remote?Jn({class:"cell-empty"}):Jn({class:"bulb-time"},nte(s.recent)),ete(s.snippet,this.filter.trim()))}userLink(s){let a=rD(s);return a?Dk({class:"sample-link",href:c5n(s,a),target:"_blank",rel:"noopener noreferrer",title:"Open this bulb's page on typebulb.com"},a):null}syncCell(s){let a=rD(s);if(!a||s.remote)return Jn({class:"cell-empty"});let d=(p,b)=>{let v=`${Gh(s.path)}:${p}`,w=this.syncBusy.has(v),I=this.syncDone.has(v);return Ao({class:["sync-btn",w?"busy shimmer":"",I?"done":""],title:b,ariaLabel:p,onClick:T=>{T.stopPropagation(),w||this.syncRow(s,p)}},t2(I?"check":p,"btn-icon-sm"))};return Jn({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 yt({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)}},Jn({class:"fold-caret"},t2("caret",["caret-tri",v?"open":""])),Jn({class:"sample-group-label"},`${s.name} (${b})`))}trustToggle(s,a){return Ao({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 nie=class{#e;#t;#n;#r=!1;#i;#s;constructor(s){this.#e=s}#o(){this.#e()?.classList.add("oruler-host")}#c(s){this.#t=s;let a=this.#e();a&&(this.#o(),this.#s?.disconnect(),this.#s=new ResizeObserver(()=>this.sync()),this.#s.observe(a),this.sync())}release(){this.#s?.disconnect(),this.#s=void 0,this.#e()?.classList.remove("oruler-host"),this.#t=void 0,this.#n=void 0}sync(){this.#r||(this.#r=!0,requestAnimationFrame(()=>{this.#r=!1;let s=this.#e(),a=this.#n;if(!s||!a||!s.scrollHeight)return;this.#o();let d=s.scrollHeight-s.clientHeight;a.style.display=d>0?"":"none",a.style.top=`${s.scrollTop/s.scrollHeight*100}%`,a.style.height=`${s.clientHeight/s.scrollHeight*100}%`,this.#t?.setAttribute("aria-valuenow",String(d>0?Math.round(s.scrollTop/d*100):0))}))}view(s,a={}){return yt({class:["oruler",a.class??""],title:a.title,role:"scrollbar",ariaOrientation:"vertical",ariaLabel:a.label??"Scroll position",ariaControls:a.controls,ariaValueMin:0,ariaValueMax:100,ariaValueNow:0,onMounted:d=>this.#c(d),onPointerDown:d=>this.#u(d),onPointerMove:d=>this.#f(d),onPointerUp:d=>this.#l(d),onPointerCancel:d=>this.#l(d),onWheel:d=>this.#h(d)},yt({class:"oruler-win",onMounted:d=>{this.#n=d,this.sync()}}),s.map(d=>yt({class:["oruler-mark",d.class??""],style:{top:`${d.top*100}%`,height:`${d.height*100}%`}})))}#u(s){let a=this.#e(),d=s.currentTarget;if(!a)return;s.preventDefault();let p=this.#n?.getBoundingClientRect(),b=!!p&&s.clientY>=p.top&&s.clientY<=p.bottom;this.#i=b?s.clientY-p.top:(p?.height??0)/2,d.setPointerCapture(s.pointerId),this.#a(s,d,a)}#f(s){let a=this.#e();this.#i===void 0||!a||this.#a(s,s.currentTarget,a)}#l(s){let a=s.currentTarget;this.#i=void 0,a.hasPointerCapture(s.pointerId)&&a.releasePointerCapture(s.pointerId)}#h(s){let a=this.#e();if(!a)return;let d=s.deltaMode===1?16:s.deltaMode===2?a.clientHeight:1;a.scrollTop+=s.deltaY*d,this.sync()}#a(s,a,d){let p=s.clientY-a.getBoundingClientRect().top-(this.#i??0);d.scrollTop=p/a.clientHeight*d.scrollHeight,this.sync()}};var u5n=4e5,sEe="diff-doc-body";function a5n(o,s){let a=o.split(`
|
|
2192
2192
|
`).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 l5n(o,s,a){let d=a5n(o,s),p=o.length>u5n?"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=nEe(b.join(`
|
|
2193
2193
|
`),p),I=nEe(v.join(`
|
|
2194
|
-
`),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 rie=class extends n2{files=[];repo=!0;root="";viewing;#e=0;#t=!1;#n=()=>document.getElementById(sEe);#r=new nie(this.#n);#i=[];#s=-1;keepOpenSelector=".gitdiff-wrap";filterId="gitdiff-filter";listSelector=".gitdiff-list";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||b.binary!==w.binary});this.repo=s,this.root=a,this.files=d,p&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] gitChangedFiles failed",s)}}#o(s,a,d){this.viewing?.path!==s&&(this.#i=[]),this.viewing={path:s,status:a,text:d.text,truncated:!!d.truncated,...l5n(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.#o(s.path,s.status,a),this.#t=!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.#o(s.path,s.status,a)}catch(a){console.error("[mirror] gitDiff refresh failed",a)}}closeDoc(){this.#r.release(),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?yt({class:"gitdiff-wrap"}):yt({class:"gitdiff-wrap pop-center"},this.viewing?this.viewingPill():Ao({class:["pill","glyph","gitdiff-pill",this.open?"on":""],"data-tip":`${s} changed file${s===1?"":"s"} \u2014 view a diff`,ariaLabel:`${s} changed file${s===1?"":"s"}`,onClick:a=>{a.stopPropagation(),this.open?this.close():this.show()}},t2("diff"),Jn({class:"gitdiff-count"},String(s))),this.open?this.popup():null)}viewingPill(){let s=this.viewing,a=s.kinds.filter(p=>p==="add").length,d=s.kinds.filter(p=>p==="del").length;return Ao({class:["pill","glyph","gitdiff-pill","viewing","on"],"data-tip":`${this.files.length} changed file${this.files.length===1?"":"s"} \u2014 switch file`,onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},Jn({class:["gitdiff-status",`s-${s.status}`]},s.status),Jn({class:"gitdiff-doc-path",title:`Open ${s.path}`,onClick:p=>{p.stopPropagation(),tb.server.openFile(`${this.root}/${s.path}`)}},s.path),Jn({class:"gitdiff-counts"},Jn({class:"count-add"},`+${a}`),Jn({class:"count-del"},`\u2212${d}`)),tte(()=>this.closeDoc()))}popup(){let s=this.rows();return yt({class:"servers-pop gitdiff-pop"},s.length===0?this.emptyState("No changes in the working tree."):yt({class:"gitdiff-list",onScroll:()=>this.onListScroll()},s.map((a,d)=>this.row(a,d))),this.filterBox(this.files.length,"file"))}row(s,a){return yt({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)}},Jn({class:["gitdiff-status",`s-${s.status}`]},s.status),Jn({class:"gitdiff-path",title:s.path},s.path),s.add!==void 0||s.del!==void 0?Jn({class:"gitdiff-counts"},Jn({class:"count-add"},`+${s.add??0}`),Jn({class:"count-del"},`\u2212${s.del??0}`)):s.status==="U"?Jn({class:"gitdiff-counts"},Jn({class:"count-add"},"new")):Jn({class:"gitdiff-counts"},Jn({},s.binary?"binary":"\u2014")))}docView(){let s=this.viewing;return yt({class:"diff-doc",onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeDoc())}},yt({class:"diff-doc-scroll"},yt({class:"diff-doc-body",id:sEe,tabIndex:0,onMounted:a=>a.focus(),onScroll:()=>this.#r.sync()},s.kinds.length===0?yt({class:"diff-doc-empty"},"No changes."):yt({class:"diff-doc-code",key:`diff-code-${this.#e}`,onMounted:a=>{a.innerHTML=s.bodyHtml,this.#c(a),this.#u(a)}},""),s.truncated?yt({class:"diff-doc-trunc"},"Diff truncated \u2014 file too large to show in full."):null),s.kinds.length?this.#r.view(this.#i,{class:"diff-ruler",title:"Jump to a change",label:"Diff scroll position",controls:sEe}):null))}#c(s){if(!this.#t)return;this.#t=!1;let a=s.querySelector(".udiff-add, .udiff-del"),d=this.#n();a&&d&&(d.scrollTop=a.offsetTop-d.clientHeight/3)}#u(s){this.#s!==this.#e&&(this.#s=this.#e,requestAnimationFrame(()=>{this.#f(s),this.update(),this.#r.sync()}))}#f(s){let a=this.viewing,d=this.#n();if(!a||!d?.scrollHeight)return;let p=d.scrollHeight,b=[];for(let v=0;v<a.kinds.length;v++){let w=a.kinds[v];if(w!=="add"&&w!=="del")continue;let I=v;for(;I+1<a.kinds.length&&a.kinds[I+1]===w;)I++;let T=s.children[v],B=s.children[I];T&&B&&b.push({top:T.offsetTop/p,height:(B.offsetTop+B.offsetHeight-T.offsetTop)/p,class:w}),v=I}this.#i=b}};function f5n(o){let s=new Set(o.map(v=>v.id)),a=new Map;for(let v of o){let w=v.parentId&&s.has(v.parentId)?v.parentId:"",I=a.get(w);I?I.push(v):a.set(w,[v])}let d=[],p=new Set,b=v=>{for(let w of a.get(v)??[])p.has(w.id)||(p.add(w.id),d.push(w),b(w.id))};b("");for(let v of o)p.has(v.id)||d.push(v);return d}var iie=class extends n2{children=[];enabled=!1;viewing=null;#e=null;keepOpenSelector=".children-wrap";filterId="children-filter";listSelector=".children-list";onActivate(s){let a=this.rows()[s];a&&this.openChild(a.id)}onAttached(){setInterval(()=>{this.refresh()},3e3)}rows(){let s=this.filter.trim().toLowerCase();return s?this.children.filter(a=>[a.kind,a.label].filter(Boolean).join(" ").toLowerCase().includes(s)):this.children}get running(){return this.children.filter(s=>s.state==="running").length}async refresh(){if(this.enabled)try{let s=f5n((await tb.server.listChildren()).reverse()),a=s.length!==this.children.length||s.some((d,p)=>{let b=this.children[p];return d.id!==b?.id||d.state!==b.state||d.mtime!==b.mtime||d.tokens!==b.tokens})||s.some(d=>d.state==="running");this.children=s,this.#t(),a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] listChildren failed",s)}}syncFromPoll(s){let a=this.viewing?.id??null;return this.#e=s,this.#t(),s&&!this.viewing&&this.refresh(),(this.viewing?.id??null)!==a}reset(){this.children=[],this.refresh()}#t(){this.viewing=this.#e?this.children.find(s=>s.id===this.#e)??null:null}async openChild(s){this.close(),this.parent.messageList.stickToBottomNextRender();try{await tb.server.openChild(s),this.#e=s,this.#t(),this.update()}catch(a){console.error("[mirror] openChild failed",a)}this.refresh()}async closeChild(){this.parent.messageList.stickToBottomNextRender();try{await tb.server.closeChild(),this.#e=null,this.#t(),this.update()}catch(s){console.error("[mirror] closeChild failed",s)}}show(){this.beginOpen(),this.refresh(),this.refreshList(),this.armClose(),this.focusFilter()}view(){let s=this.children.length;return!this.enabled||s===0&&!this.viewing&&!this.open?yt({class:"children-wrap"}):yt({class:"children-wrap pop-center"},this.viewing?this.viewingPill():this.chip(s),this.open?this.popup():null)}chip(s){let a=this.running;return Ao({class:["pill","children-pill",Vee(a>0),this.open?"on":""],"data-tip":a?`${a} of ${s} agent${s===1?"":"s"} still working \u2014 open one`:`${s} agent${s===1?"":"s"} this session spawned \u2014 open one`,ariaLabel:a?`Agents (${a} of ${s} running)`:`Agents (${s})`,onClick:d=>{d.stopPropagation(),this.open?this.close():this.show()}},Jn({class:"glyph-img"},"\u{1F916}"),String(
|
|
2194
|
+
`),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 rie=class extends n2{files=[];repo=!0;root="";viewing;#e=0;#t=!1;#n=()=>document.getElementById(sEe);#r=new nie(this.#n);#i=[];#s=-1;keepOpenSelector=".gitdiff-wrap";filterId="gitdiff-filter";listSelector=".gitdiff-list";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||b.binary!==w.binary});this.repo=s,this.root=a,this.files=d,p&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] gitChangedFiles failed",s)}}#o(s,a,d){this.viewing?.path!==s&&(this.#i=[]),this.viewing={path:s,status:a,text:d.text,truncated:!!d.truncated,...l5n(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.#o(s.path,s.status,a),this.#t=!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.#o(s.path,s.status,a)}catch(a){console.error("[mirror] gitDiff refresh failed",a)}}closeDoc(){this.#r.release(),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?yt({class:"gitdiff-wrap"}):yt({class:"gitdiff-wrap pop-center"},this.viewing?this.viewingPill():Ao({class:["pill","glyph","gitdiff-pill",this.open?"on":""],"data-tip":`${s} changed file${s===1?"":"s"} \u2014 view a diff`,ariaLabel:`${s} changed file${s===1?"":"s"}`,onClick:a=>{a.stopPropagation(),this.open?this.close():this.show()}},t2("diff"),Jn({class:"gitdiff-count"},String(s))),this.open?this.popup():null)}viewingPill(){let s=this.viewing,a=s.kinds.filter(p=>p==="add").length,d=s.kinds.filter(p=>p==="del").length;return Ao({class:["pill","glyph","gitdiff-pill","viewing","on"],"data-tip":`${this.files.length} changed file${this.files.length===1?"":"s"} \u2014 switch file`,onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},Jn({class:["gitdiff-status",`s-${s.status}`]},s.status),Jn({class:"gitdiff-doc-path",title:`Open ${s.path}`,onClick:p=>{p.stopPropagation(),tb.server.openFile(`${this.root}/${s.path}`)}},s.path),Jn({class:"gitdiff-counts"},Jn({class:"count-add"},`+${a}`),Jn({class:"count-del"},`\u2212${d}`)),tte(()=>this.closeDoc()))}popup(){let s=this.rows();return yt({class:"servers-pop gitdiff-pop"},s.length===0?this.emptyState("No changes in the working tree."):yt({class:"gitdiff-list",onScroll:()=>this.onListScroll()},s.map((a,d)=>this.row(a,d))),this.filterBox(this.files.length,"file"))}row(s,a){return yt({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)}},Jn({class:["gitdiff-status",`s-${s.status}`]},s.status),Jn({class:"gitdiff-path",title:s.path},s.path),s.add!==void 0||s.del!==void 0?Jn({class:"gitdiff-counts"},Jn({class:"count-add"},`+${s.add??0}`),Jn({class:"count-del"},`\u2212${s.del??0}`)):s.status==="U"?Jn({class:"gitdiff-counts"},Jn({class:"count-add"},"new")):Jn({class:"gitdiff-counts"},Jn({},s.binary?"binary":"\u2014")))}docView(){let s=this.viewing;return yt({class:"diff-doc",onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeDoc())}},yt({class:"diff-doc-scroll"},yt({class:"diff-doc-body",id:sEe,tabIndex:0,onMounted:a=>a.focus(),onScroll:()=>this.#r.sync()},s.kinds.length===0?yt({class:"diff-doc-empty"},"No changes."):yt({class:"diff-doc-code",key:`diff-code-${this.#e}`,onMounted:a=>{a.innerHTML=s.bodyHtml,this.#c(a),this.#u(a)}},""),s.truncated?yt({class:"diff-doc-trunc"},"Diff truncated \u2014 file too large to show in full."):null),s.kinds.length?this.#r.view(this.#i,{class:"diff-ruler",title:"Jump to a change",label:"Diff scroll position",controls:sEe}):null))}#c(s){if(!this.#t)return;this.#t=!1;let a=s.querySelector(".udiff-add, .udiff-del"),d=this.#n();a&&d&&(d.scrollTop=a.offsetTop-d.clientHeight/3)}#u(s){this.#s!==this.#e&&(this.#s=this.#e,requestAnimationFrame(()=>{this.#f(s),this.update(),this.#r.sync()}))}#f(s){let a=this.viewing,d=this.#n();if(!a||!d?.scrollHeight)return;let p=d.scrollHeight,b=[];for(let v=0;v<a.kinds.length;v++){let w=a.kinds[v];if(w!=="add"&&w!=="del")continue;let I=v;for(;I+1<a.kinds.length&&a.kinds[I+1]===w;)I++;let T=s.children[v],B=s.children[I];T&&B&&b.push({top:T.offsetTop/p,height:(B.offsetTop+B.offsetHeight-T.offsetTop)/p,class:w}),v=I}this.#i=b}};function f5n(o){let s=new Set(o.map(v=>v.id)),a=new Map;for(let v of o){let w=v.parentId&&s.has(v.parentId)?v.parentId:"",I=a.get(w);I?I.push(v):a.set(w,[v])}let d=[],p=new Set,b=v=>{for(let w of a.get(v)??[])p.has(w.id)||(p.add(w.id),d.push(w),b(w.id))};b("");for(let v of o)p.has(v.id)||d.push(v);return d}var iie=class extends n2{children=[];enabled=!1;viewing=null;#e=null;keepOpenSelector=".children-wrap";filterId="children-filter";listSelector=".children-list";onActivate(s){let a=this.rows()[s];a&&this.openChild(a.id)}onAttached(){setInterval(()=>{this.refresh()},3e3)}rows(){let s=this.filter.trim().toLowerCase();return s?this.children.filter(a=>[a.kind,a.label].filter(Boolean).join(" ").toLowerCase().includes(s)):this.children}get running(){return this.children.filter(s=>s.state==="running").length}async refresh(){if(this.enabled)try{let s=f5n((await tb.server.listChildren()).reverse()),a=s.length!==this.children.length||s.some((d,p)=>{let b=this.children[p];return d.id!==b?.id||d.state!==b.state||d.mtime!==b.mtime||d.tokens!==b.tokens})||s.some(d=>d.state==="running");this.children=s,this.#t(),a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] listChildren failed",s)}}syncFromPoll(s){let a=this.viewing?.id??null;return this.#e=s,this.#t(),s&&!this.viewing&&this.refresh(),(this.viewing?.id??null)!==a}reset(){this.children=[],this.refresh()}#t(){this.viewing=this.#e?this.children.find(s=>s.id===this.#e)??null:null}async openChild(s){this.close(),this.parent.messageList.stickToBottomNextRender();try{await tb.server.openChild(s),this.#e=s,this.#t(),this.update()}catch(a){console.error("[mirror] openChild failed",a)}this.refresh()}async closeChild(){this.parent.messageList.stickToBottomNextRender();try{await tb.server.closeChild(),this.#e=null,this.#t(),this.update()}catch(s){console.error("[mirror] closeChild failed",s)}}show(){this.beginOpen(),this.refresh(),this.refreshList(),this.armClose(),this.focusFilter()}view(){let s=this.children.length;return!this.enabled||s===0&&!this.viewing&&!this.open?yt({class:"children-wrap"}):yt({class:"children-wrap pop-center"},this.viewing?this.viewingPill():this.chip(s),this.open?this.popup():null)}chip(s){let a=this.running;return Ao({class:["pill","children-pill",Vee(a>0),this.open?"on":""],"data-tip":a?`${a} of ${s} agent${s===1?"":"s"} still working \u2014 open one`:`${s} agent${s===1?"":"s"} this session spawned \u2014 open one`,ariaLabel:a?`Agents (${a} of ${s} running)`:`Agents (${s})`,onClick:d=>{d.stopPropagation(),this.open?this.close():this.show()}},Jn({class:"glyph-img"},"\u{1F916}"),String(a),Jn({class:"glyph-img"},"\u{1F916}"))}viewingPill(){let s=this.viewing,a=this.children.length;return Ao({class:["pill","glyph","children-pill","viewing","on"],"data-tip":`${a} agent${a===1?"":"s"} \u2014 switch`,onClick:d=>{d.stopPropagation(),this.open?this.close():this.show()}},Jn({class:"glyph-img"},"\u{1F916}"),Jn({class:["children-doc-label",s.state==="running"?"shimmer-text shimmer-slow":""],title:[s.kind,s.label||"no description"].filter(Boolean).join(" \u2014 ")},s.label||s.kind||"agent"),tte(()=>{this.closeChild()}))}popup(){let s=this.rows();return yt({class:"servers-pop children-pop"},s.length===0?this.emptyState("No agents in this session yet."):yt({class:"children-list",onScroll:()=>this.onListScroll()},s.map((a,d)=>this.row(a,d))),this.filterBox(this.children.length,"agent"))}row(s,a){return yt({class:["children-row",a===this.highlighted?"active":"",this.viewing?.id===s.id?"viewing":""],style:s.depth>1?{paddingLeft:`${(s.depth-1)*16+10}px`}:void 0,onMouseEnter:()=>{this.highlighted!==a&&(this.highlighted=a,this.update())},onClick:d=>{d.stopPropagation(),this.openChild(s.id)}},Jn({class:["children-dot",s.state]}),s.kind?Jn({class:"children-kind"},s.kind):null,Jn({class:["children-label",s.state==="running"?"shimmer-text shimmer-slow":""]},s.label||"(no description)"),s.model?Jn({class:"children-model"},s.model):null,s.started?Jn({class:"children-time"},D6t((s.state==="running"?Date.now():s.mtime)-s.started)):null,s.tokens?Jn({class:"children-tokens"},TF(s.tokens)):null)}};var iD=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 Ao({class:["overlay-pill","copy",this.done?"done":""],onClick:s=>{s.stopPropagation(),this.flash()}},this.done?"copied":"copy")}};var WSt=new Map,YSt=(o,s)=>s+`
|
|
2195
2195
|
|
|
2196
2196
|
---
|
|
2197
2197
|
|
|
@@ -2191,7 +2191,7 @@ ${a||this.currentRow()?.pending?"New conversation \u2014 not saved yet":`Session
|
|
|
2191
2191
|
`):"Waiting for the harness to flush this turn";return cr({class:"token-wrap"},cr({class:["token",Yee(b)],"data-tip":T},I))}};function PSt(o,...s){return o.slice().sort((a,d)=>{for(let{key:p,desc:b}of s){let v=p(a),w=p(d);if(v!==w)return v==null?b?-1:1:w==null||v<w?b?1:-1:b?-1:1}return 0})}var Jvn=()=>e2("play","btn-icon"),Uvn=()=>e2("stop","btn-icon"),zvn=o=>`typebulbs/u/samples/${o}.bulb.md`,rD=o=>Gh(o.path).match(/typebulbs\/u\/([^/]+)\//)?.[1],Kvn=(o,s)=>`https://typebulb.com/u/${s}/${aM(o.path)}/full`,jSt=o=>o==="HTTP 404"?"not found \u2014 check the URL (private bulbs need their owner's token)":o==="HTTP 401"||o==="HTTP 403"?"private \u2014 needs its owner's TYPEBULB_TOKEN in .env":o||"pull failed",Zre=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;pullErrors=new Map;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?SF(a.running.url):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||d.lastRunAt!==this.files[p]?.lastRunAt);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=>Gh(p.path)),d=[...this.samples.map(p=>[zvn(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:Math.max(p.mtime,p.lastRunAt??0),trusted:p.trusted})});for(let p of this.servers){if(p.pid===this.parent.ownPid)continue;let b=Gh(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=>[Gh(d.path),d]));s=s.flatMap(d=>{let p=a.get(Gh(d.path));return p?[{...d,hitCount:p.hitCount,snippet:p.snippet}]:[]})}else{let a=this.filter.trim().toLowerCase(),d=x6t(this.filter);if(d){let p=`typebulbs/u/${d.user}/${d.slug}.bulb.md`,b=s.find(v=>("/"+Gh(v.path)).endsWith("/"+p));return b?[b]:[{path:p,name:d.slug,recent:0,remote:{slug:d.slug,name:d.slug,description:`u/${d.user}/${d.slug} on typebulb.com \u2014 play pulls it into the project`}}]}a?s=s.filter(p=>p.name.toLowerCase().includes(a)||p.path.toLowerCase().includes(a)):[...new Set(s.filter(b=>b.remote).map(b=>rD(b)))].forEach((b,v)=>{let w=T=>!!T.remote&&rD(T)===b,I=s.filter(w).length;this.openFolds.has(b)?s=s.map(T=>w(T)?{...T,recent:-.5-v}:T):s=s.filter(T=>!w(T)),s.push({path:`::${b}`,name:this.foldLabel(b),recent:-1-v,group:{user:b,count:I}})})}return PSt(s,{key:a=>!!a.running},{key:a=>a.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.pullErrors.clear(),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}'s bulbs`}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=>Gh(d.path)===Gh(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=Gh(s.path);this.launching.add(a),this.pullErrors.delete(a),this.update();try{let d=rD(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),this.pullErrors.set(a,jSt(p.error));return}await this.refreshFiles();let b=this.files.find(v=>Gh(v.path).endsWith("/"+Gh(p.file)))?.path??p.file;await this.launch(b)}catch(d){console.error("[mirror] remote pull failed",d),this.pullErrors.set(a,jSt(d?.message))}finally{this.launching.delete(a),this.update()}}async syncRow(s,a,d=!1){let p=`${Gh(s.path)}:${a}`;this.syncBusy.add(p),this.update();try{let b=a==="pull"?await tb.server.pullRemoteBulb(rD(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),this.update()}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=Gh(s);this.launching.add(p),this.update();let b;try{b=await tb.server.launchBulb(s,a)}catch(v){console.error("[mirror] launchBulb failed",v)}finally{this.launching.delete(p)}d&&b?.pid&&this.dismissedDenials.add(b.pid),b?.url&&SF(b.url),await this.refresh(),this.pinToBottom()}displayName(s){return this.files.find(d=>Gh(d.path)===Gh(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.#t(),this.#e=setInterval(()=>this.#t(),700)}closeLog(){this.#e&&(clearInterval(this.#e),this.#e=void 0),this.openLog&&(this.openLog=void 0,this.update())}async#t(){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"},mu({class:["pill",s>0?"":"glyph",this.open?"on":""],"data-tip":"Launch a project bulb \xB7 stop a running one",ariaLabel:s>0?`Bulbs (${s} running)`:"Bulbs",onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},s>0?`${s}\u{1F4A1}`:cr({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"},mu({class:"trust-no",onClick:d=>a(d,s.onNo)},s.noLabel),mu({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 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"},cr({class:"bulb-log-name"},`console \xB7 ${s.name}`),mu({class:"bulb-log-back",title:"Back to the bulb list",onClick:a=>{a.stopPropagation(),this.closeLog()}},"\u2190 bulbs")),i6({class:"bulb-log-body"},cr({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=this.pullErrors.get(Gh(s.path)),w=p?!!p.trust:!!s.trusted,I=!!s.remote&&!this.searchActive&&!this.filter.trim();return Zt({class:["server-row",I?"fold-row":"",a===this.highlighted?"active":"",d?"dimmed":""],onMouseEnter:()=>this.hoverRow(a,p)},p?mu({class:"server-stop",title:"Stop this server",ariaLabel:"Stop",onClick:T=>{T.stopPropagation(),this.stop(p.pid)}},Uvn()):mu({class:["bulb-launch",this.launching.has(Gh(s.path))?"launching shimmer":""],title:s.remote?"Download from typebulb.com & launch":w?"Launch (trusted \u2014 remembered)":"Launch (restricted)",ariaLabel:"Launch",onClick:T=>{T.stopPropagation(),s.remote?this.downloadAndLaunch(s):this.launch(s.path)}},Jvn()),Zt({class:"bulb-name-cell"},s.remote?cr({class:"server-name stopped remote",title:s.remote.description},s.name):cr({class:["server-name",p?"":"stopped"],title:`Open ${s.path}`,onClick:T=>{T.stopPropagation(),tb.server.openFile(s.path)}},s.name),this.userLink(s),Xee(s.hitCount),v?cr({class:"pull-error"},v):null),this.syncCell(s),p||w?this.trustToggle(s,w):cr({class:"cell-empty"}),p?D7({class:["server-logs",b?"on":""],title:"Show this server\u2019s console",onClick:T=>{T.stopPropagation(),this.showLog(p,s.name)}},"logs"):cr({class:"cell-empty"}),p?D7({class:"server-port",href:Jye(p.url),target:"_blank",rel:"noopener noreferrer",title:`Open ${p.url}`},`:${p.port}`):s.remote?cr({class:"cell-empty"}):cr({class:"bulb-time"},ete(s.recent)),Vee(s.snippet,this.filter.trim()))}userLink(s){let a=rD(s);return a?D7({class:"sample-link",href:Kvn(s,a),target:"_blank",rel:"noopener noreferrer",title:"Open this bulb's page on typebulb.com"},a):null}syncCell(s){let a=rD(s);if(!a||s.remote)return cr({class:"cell-empty"});let d=(p,b)=>{let v=`${Gh(s.path)}:${p}`,w=this.syncBusy.has(v),I=this.syncDone.has(v);return mu({class:["sync-btn",w?"busy shimmer":"",I?"done":""],title:b,ariaLabel:p,onClick:T=>{T.stopPropagation(),w||this.syncRow(s,p)}},e2(I?"check":p,"btn-icon-sm"))};return cr({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)}},cr({class:"fold-caret"},e2("caret",["caret-tri",v?"open":""])),cr({class:"sample-group-label"},`${s.name} (${b})`))}trustToggle(s,a){return mu({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 eie=class{#e;#t;#n;#r=!1;#i;#s;constructor(s){this.#e=s}#o(){this.#e()?.classList.add("oruler-host")}#c(s){this.#t=s;let a=this.#e();a&&(this.#o(),this.#s?.disconnect(),this.#s=new ResizeObserver(()=>this.sync()),this.#s.observe(a),this.sync())}release(){this.#s?.disconnect(),this.#s=void 0,this.#e()?.classList.remove("oruler-host"),this.#t=void 0,this.#n=void 0}sync(){this.#r||(this.#r=!0,requestAnimationFrame(()=>{this.#r=!1;let s=this.#e(),a=this.#n;if(!s||!a||!s.scrollHeight)return;this.#o();let d=s.scrollHeight-s.clientHeight;a.style.display=d>0?"":"none",a.style.top=`${s.scrollTop/s.scrollHeight*100}%`,a.style.height=`${s.clientHeight/s.scrollHeight*100}%`,this.#t?.setAttribute("aria-valuenow",String(d>0?Math.round(s.scrollTop/d*100):0))}))}view(s,a={}){return Zt({class:["oruler",a.class??""],title:a.title,role:"scrollbar",ariaOrientation:"vertical",ariaLabel:a.label??"Scroll position",ariaControls:a.controls,ariaValueMin:0,ariaValueMax:100,ariaValueNow:0,onMounted:d=>this.#c(d),onPointerDown:d=>this.#u(d),onPointerMove:d=>this.#f(d),onPointerUp:d=>this.#l(d),onPointerCancel:d=>this.#l(d),onWheel:d=>this.#h(d)},Zt({class:"oruler-win",onMounted:d=>{this.#n=d,this.sync()}}),s.map(d=>Zt({class:["oruler-mark",d.class??""],style:{top:`${d.top*100}%`,height:`${d.height*100}%`}})))}#u(s){let a=this.#e(),d=s.currentTarget;if(!a)return;s.preventDefault();let p=this.#n?.getBoundingClientRect(),b=!!p&&s.clientY>=p.top&&s.clientY<=p.bottom;this.#i=b?s.clientY-p.top:(p?.height??0)/2,d.setPointerCapture(s.pointerId),this.#a(s,d,a)}#f(s){let a=this.#e();this.#i===void 0||!a||this.#a(s,s.currentTarget,a)}#l(s){let a=s.currentTarget;this.#i=void 0,a.hasPointerCapture(s.pointerId)&&a.releasePointerCapture(s.pointerId)}#h(s){let a=this.#e();if(!a)return;let d=s.deltaMode===1?16:s.deltaMode===2?a.clientHeight:1;a.scrollTop+=s.deltaY*d,this.sync()}#a(s,a,d){let p=s.clientY-a.getBoundingClientRect().top-(this.#i??0);d.scrollTop=p/a.clientHeight*d.scrollHeight,this.sync()}};var Wvn=4e5,eEe="diff-doc-body";function Yvn(o,s){let a=o.split(`
|
|
2192
2192
|
`).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 Xvn(o,s,a){let d=Yvn(o,s),p=o.length>Wvn?"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=Xxe(b.join(`
|
|
2193
2193
|
`),p),I=Xxe(v.join(`
|
|
2194
|
-
`),p),T=0,D=0,B=[];for(let P of d){if(P.kind==="gap"){B.push('<div class="udiff-gap">\u22EF</div>');continue}let F=P.kind==="del"?w[T++]:(P.kind==="add"||T++,I[D++]);B.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:B.join("")}}var tie=class extends v4{files=[];repo=!0;root="";viewing;#e=0;#t=!1;#n=()=>document.getElementById(eEe);#r=new eie(this.#n);#i=[];#s=-1;keepOpenSelector=".gitdiff-wrap";filterId="gitdiff-filter";listSelector=".gitdiff-list";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||b.binary!==w.binary});this.repo=s,this.root=a,this.files=d,p&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] gitChangedFiles failed",s)}}#o(s,a,d){this.viewing?.path!==s&&(this.#i=[]),this.viewing={path:s,status:a,text:d.text,truncated:!!d.truncated,...Xvn(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.#o(s.path,s.status,a),this.#t=!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.#o(s.path,s.status,a)}catch(a){console.error("[mirror] gitDiff refresh failed",a)}}closeDoc(){this.#r.release(),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 pop-center"},this.viewing?this.viewingPill():mu({class:["pill","glyph","gitdiff-pill",this.open?"on":""],"data-tip":`${s} changed file${s===1?"":"s"} \u2014 view a diff`,ariaLabel:`${s} changed file${s===1?"":"s"}`,onClick:a=>{a.stopPropagation(),this.open?this.close():this.show()}},e2("diff"),cr({class:"gitdiff-count"},String(s))),this.open?this.popup():null)}viewingPill(){let s=this.viewing,a=s.kinds.filter(p=>p==="add").length,d=s.kinds.filter(p=>p==="del").length;return mu({class:["pill","glyph","gitdiff-pill","viewing","on"],"data-tip":`${this.files.length} changed file${this.files.length===1?"":"s"} \u2014 switch file`,onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},cr({class:["gitdiff-status",`s-${s.status}`]},s.status),cr({class:"gitdiff-doc-path",title:`Open ${s.path}`,onClick:p=>{p.stopPropagation(),tb.server.openFile(`${this.root}/${s.path}`)}},s.path),cr({class:"gitdiff-counts"},cr({class:"count-add"},`+${a}`),cr({class:"count-del"},`\u2212${d}`)),Zee(()=>this.closeDoc()))}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.filterBox(this.files.length,"file"))}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)}},cr({class:["gitdiff-status",`s-${s.status}`]},s.status),cr({class:"gitdiff-path",title:s.path},s.path),s.add!==void 0||s.del!==void 0?cr({class:"gitdiff-counts"},cr({class:"count-add"},`+${s.add??0}`),cr({class:"count-del"},`\u2212${s.del??0}`)):s.status==="U"?cr({class:"gitdiff-counts"},cr({class:"count-add"},"new")):cr({class:"gitdiff-counts"},cr({},s.binary?"binary":"\u2014")))}docView(){let s=this.viewing;return Zt({class:"diff-doc",onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeDoc())}},Zt({class:"diff-doc-scroll"},Zt({class:"diff-doc-body",id:eEe,tabIndex:0,onMounted:a=>a.focus(),onScroll:()=>this.#r.sync()},s.kinds.length===0?Zt({class:"diff-doc-empty"},"No changes."):Zt({class:"diff-doc-code",key:`diff-code-${this.#e}`,onMounted:a=>{a.innerHTML=s.bodyHtml,this.#c(a),this.#u(a)}},""),s.truncated?Zt({class:"diff-doc-trunc"},"Diff truncated \u2014 file too large to show in full."):null),s.kinds.length?this.#r.view(this.#i,{class:"diff-ruler",title:"Jump to a change",label:"Diff scroll position",controls:eEe}):null))}#c(s){if(!this.#t)return;this.#t=!1;let a=s.querySelector(".udiff-add, .udiff-del"),d=this.#n();a&&d&&(d.scrollTop=a.offsetTop-d.clientHeight/3)}#u(s){this.#s!==this.#e&&(this.#s=this.#e,requestAnimationFrame(()=>{this.#f(s),this.update(),this.#r.sync()}))}#f(s){let a=this.viewing,d=this.#n();if(!a||!d?.scrollHeight)return;let p=d.scrollHeight,b=[];for(let v=0;v<a.kinds.length;v++){let w=a.kinds[v];if(w!=="add"&&w!=="del")continue;let I=v;for(;I+1<a.kinds.length&&a.kinds[I+1]===w;)I++;let T=s.children[v],D=s.children[I];T&&D&&b.push({top:T.offsetTop/p,height:(D.offsetTop+D.offsetHeight-T.offsetTop)/p,class:w}),v=I}this.#i=b}};function Vvn(o){let s=new Set(o.map(v=>v.id)),a=new Map;for(let v of o){let w=v.parentId&&s.has(v.parentId)?v.parentId:"",I=a.get(w);I?I.push(v):a.set(w,[v])}let d=[],p=new Set,b=v=>{for(let w of a.get(v)??[])p.has(w.id)||(p.add(w.id),d.push(w),b(w.id))};b("");for(let v of o)p.has(v.id)||d.push(v);return d}var nie=class extends v4{children=[];enabled=!1;viewing=null;#e=null;keepOpenSelector=".children-wrap";filterId="children-filter";listSelector=".children-list";onActivate(s){let a=this.rows()[s];a&&this.openChild(a.id)}onAttached(){setInterval(()=>{this.refresh()},3e3)}rows(){let s=this.filter.trim().toLowerCase();return s?this.children.filter(a=>[a.kind,a.label].filter(Boolean).join(" ").toLowerCase().includes(s)):this.children}get running(){return this.children.filter(s=>s.state==="running").length}async refresh(){if(this.enabled)try{let s=Vvn((await tb.server.listChildren()).reverse()),a=s.length!==this.children.length||s.some((d,p)=>{let b=this.children[p];return d.id!==b?.id||d.state!==b.state||d.mtime!==b.mtime||d.tokens!==b.tokens})||s.some(d=>d.state==="running");this.children=s,this.#t(),a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] listChildren failed",s)}}syncFromPoll(s){let a=this.viewing?.id??null;return this.#e=s,this.#t(),s&&!this.viewing&&this.refresh(),(this.viewing?.id??null)!==a}reset(){this.children=[],this.refresh()}#t(){this.viewing=this.#e?this.children.find(s=>s.id===this.#e)??null:null}async openChild(s){this.close(),this.parent.messageList.stickToBottomNextRender();try{await tb.server.openChild(s),this.#e=s,this.#t(),this.update()}catch(a){console.error("[mirror] openChild failed",a)}this.refresh()}async closeChild(){this.parent.messageList.stickToBottomNextRender();try{await tb.server.closeChild(),this.#e=null,this.#t(),this.update()}catch(s){console.error("[mirror] closeChild failed",s)}}show(){this.beginOpen(),this.refresh(),this.refreshList(),this.armClose(),this.focusFilter()}view(){let s=this.children.length;return!this.enabled||s===0&&!this.viewing&&!this.open?Zt({class:"children-wrap"}):Zt({class:"children-wrap pop-center"},this.viewing?this.viewingPill():this.chip(s),this.open?this.popup():null)}chip(s){let a=this.running;return mu({class:["pill","children-pill",Yee(a>0),this.open?"on":""],"data-tip":a?`${a} of ${s} agent${s===1?"":"s"} still working \u2014 open one`:`${s} agent${s===1?"":"s"} this session spawned \u2014 open one`,ariaLabel:a?`Agents (${a} of ${s} running)`:`Agents (${s})`,onClick:d=>{d.stopPropagation(),this.open?this.close():this.show()}},cr({class:"glyph-img"},"\u{1F916}"),String(
|
|
2194
|
+
`),p),T=0,D=0,B=[];for(let P of d){if(P.kind==="gap"){B.push('<div class="udiff-gap">\u22EF</div>');continue}let F=P.kind==="del"?w[T++]:(P.kind==="add"||T++,I[D++]);B.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:B.join("")}}var tie=class extends v4{files=[];repo=!0;root="";viewing;#e=0;#t=!1;#n=()=>document.getElementById(eEe);#r=new eie(this.#n);#i=[];#s=-1;keepOpenSelector=".gitdiff-wrap";filterId="gitdiff-filter";listSelector=".gitdiff-list";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||b.binary!==w.binary});this.repo=s,this.root=a,this.files=d,p&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] gitChangedFiles failed",s)}}#o(s,a,d){this.viewing?.path!==s&&(this.#i=[]),this.viewing={path:s,status:a,text:d.text,truncated:!!d.truncated,...Xvn(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.#o(s.path,s.status,a),this.#t=!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.#o(s.path,s.status,a)}catch(a){console.error("[mirror] gitDiff refresh failed",a)}}closeDoc(){this.#r.release(),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 pop-center"},this.viewing?this.viewingPill():mu({class:["pill","glyph","gitdiff-pill",this.open?"on":""],"data-tip":`${s} changed file${s===1?"":"s"} \u2014 view a diff`,ariaLabel:`${s} changed file${s===1?"":"s"}`,onClick:a=>{a.stopPropagation(),this.open?this.close():this.show()}},e2("diff"),cr({class:"gitdiff-count"},String(s))),this.open?this.popup():null)}viewingPill(){let s=this.viewing,a=s.kinds.filter(p=>p==="add").length,d=s.kinds.filter(p=>p==="del").length;return mu({class:["pill","glyph","gitdiff-pill","viewing","on"],"data-tip":`${this.files.length} changed file${this.files.length===1?"":"s"} \u2014 switch file`,onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},cr({class:["gitdiff-status",`s-${s.status}`]},s.status),cr({class:"gitdiff-doc-path",title:`Open ${s.path}`,onClick:p=>{p.stopPropagation(),tb.server.openFile(`${this.root}/${s.path}`)}},s.path),cr({class:"gitdiff-counts"},cr({class:"count-add"},`+${a}`),cr({class:"count-del"},`\u2212${d}`)),Zee(()=>this.closeDoc()))}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.filterBox(this.files.length,"file"))}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)}},cr({class:["gitdiff-status",`s-${s.status}`]},s.status),cr({class:"gitdiff-path",title:s.path},s.path),s.add!==void 0||s.del!==void 0?cr({class:"gitdiff-counts"},cr({class:"count-add"},`+${s.add??0}`),cr({class:"count-del"},`\u2212${s.del??0}`)):s.status==="U"?cr({class:"gitdiff-counts"},cr({class:"count-add"},"new")):cr({class:"gitdiff-counts"},cr({},s.binary?"binary":"\u2014")))}docView(){let s=this.viewing;return Zt({class:"diff-doc",onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeDoc())}},Zt({class:"diff-doc-scroll"},Zt({class:"diff-doc-body",id:eEe,tabIndex:0,onMounted:a=>a.focus(),onScroll:()=>this.#r.sync()},s.kinds.length===0?Zt({class:"diff-doc-empty"},"No changes."):Zt({class:"diff-doc-code",key:`diff-code-${this.#e}`,onMounted:a=>{a.innerHTML=s.bodyHtml,this.#c(a),this.#u(a)}},""),s.truncated?Zt({class:"diff-doc-trunc"},"Diff truncated \u2014 file too large to show in full."):null),s.kinds.length?this.#r.view(this.#i,{class:"diff-ruler",title:"Jump to a change",label:"Diff scroll position",controls:eEe}):null))}#c(s){if(!this.#t)return;this.#t=!1;let a=s.querySelector(".udiff-add, .udiff-del"),d=this.#n();a&&d&&(d.scrollTop=a.offsetTop-d.clientHeight/3)}#u(s){this.#s!==this.#e&&(this.#s=this.#e,requestAnimationFrame(()=>{this.#f(s),this.update(),this.#r.sync()}))}#f(s){let a=this.viewing,d=this.#n();if(!a||!d?.scrollHeight)return;let p=d.scrollHeight,b=[];for(let v=0;v<a.kinds.length;v++){let w=a.kinds[v];if(w!=="add"&&w!=="del")continue;let I=v;for(;I+1<a.kinds.length&&a.kinds[I+1]===w;)I++;let T=s.children[v],D=s.children[I];T&&D&&b.push({top:T.offsetTop/p,height:(D.offsetTop+D.offsetHeight-T.offsetTop)/p,class:w}),v=I}this.#i=b}};function Vvn(o){let s=new Set(o.map(v=>v.id)),a=new Map;for(let v of o){let w=v.parentId&&s.has(v.parentId)?v.parentId:"",I=a.get(w);I?I.push(v):a.set(w,[v])}let d=[],p=new Set,b=v=>{for(let w of a.get(v)??[])p.has(w.id)||(p.add(w.id),d.push(w),b(w.id))};b("");for(let v of o)p.has(v.id)||d.push(v);return d}var nie=class extends v4{children=[];enabled=!1;viewing=null;#e=null;keepOpenSelector=".children-wrap";filterId="children-filter";listSelector=".children-list";onActivate(s){let a=this.rows()[s];a&&this.openChild(a.id)}onAttached(){setInterval(()=>{this.refresh()},3e3)}rows(){let s=this.filter.trim().toLowerCase();return s?this.children.filter(a=>[a.kind,a.label].filter(Boolean).join(" ").toLowerCase().includes(s)):this.children}get running(){return this.children.filter(s=>s.state==="running").length}async refresh(){if(this.enabled)try{let s=Vvn((await tb.server.listChildren()).reverse()),a=s.length!==this.children.length||s.some((d,p)=>{let b=this.children[p];return d.id!==b?.id||d.state!==b.state||d.mtime!==b.mtime||d.tokens!==b.tokens})||s.some(d=>d.state==="running");this.children=s,this.#t(),a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] listChildren failed",s)}}syncFromPoll(s){let a=this.viewing?.id??null;return this.#e=s,this.#t(),s&&!this.viewing&&this.refresh(),(this.viewing?.id??null)!==a}reset(){this.children=[],this.refresh()}#t(){this.viewing=this.#e?this.children.find(s=>s.id===this.#e)??null:null}async openChild(s){this.close(),this.parent.messageList.stickToBottomNextRender();try{await tb.server.openChild(s),this.#e=s,this.#t(),this.update()}catch(a){console.error("[mirror] openChild failed",a)}this.refresh()}async closeChild(){this.parent.messageList.stickToBottomNextRender();try{await tb.server.closeChild(),this.#e=null,this.#t(),this.update()}catch(s){console.error("[mirror] closeChild failed",s)}}show(){this.beginOpen(),this.refresh(),this.refreshList(),this.armClose(),this.focusFilter()}view(){let s=this.children.length;return!this.enabled||s===0&&!this.viewing&&!this.open?Zt({class:"children-wrap"}):Zt({class:"children-wrap pop-center"},this.viewing?this.viewingPill():this.chip(s),this.open?this.popup():null)}chip(s){let a=this.running;return mu({class:["pill","children-pill",Yee(a>0),this.open?"on":""],"data-tip":a?`${a} of ${s} agent${s===1?"":"s"} still working \u2014 open one`:`${s} agent${s===1?"":"s"} this session spawned \u2014 open one`,ariaLabel:a?`Agents (${a} of ${s} running)`:`Agents (${s})`,onClick:d=>{d.stopPropagation(),this.open?this.close():this.show()}},cr({class:"glyph-img"},"\u{1F916}"),String(a),cr({class:"glyph-img"},"\u{1F916}"))}viewingPill(){let s=this.viewing,a=this.children.length;return mu({class:["pill","glyph","children-pill","viewing","on"],"data-tip":`${a} agent${a===1?"":"s"} \u2014 switch`,onClick:d=>{d.stopPropagation(),this.open?this.close():this.show()}},cr({class:"glyph-img"},"\u{1F916}"),cr({class:["children-doc-label",s.state==="running"?"shimmer-text shimmer-slow":""],title:[s.kind,s.label||"no description"].filter(Boolean).join(" \u2014 ")},s.label||s.kind||"agent"),Zee(()=>{this.closeChild()}))}popup(){let s=this.rows();return Zt({class:"servers-pop children-pop"},s.length===0?this.emptyState("No agents in this session yet."):Zt({class:"children-list",onScroll:()=>this.onListScroll()},s.map((a,d)=>this.row(a,d))),this.filterBox(this.children.length,"agent"))}row(s,a){return Zt({class:["children-row",a===this.highlighted?"active":"",this.viewing?.id===s.id?"viewing":""],style:s.depth>1?{paddingLeft:`${(s.depth-1)*16+10}px`}:void 0,onMouseEnter:()=>{this.highlighted!==a&&(this.highlighted=a,this.update())},onClick:d=>{d.stopPropagation(),this.openChild(s.id)}},cr({class:["children-dot",s.state]}),s.kind?cr({class:"children-kind"},s.kind):null,cr({class:["children-label",s.state==="running"?"shimmer-text shimmer-slow":""]},s.label||"(no description)"),s.model?cr({class:"children-model"},s.model):null,s.started?cr({class:"children-time"},y6t((s.state==="running"?Date.now():s.mtime)-s.started)):null,s.tokens?cr({class:"children-tokens"},TF(s.tokens)):null)}};var iD=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 mu({class:["overlay-pill","copy",this.done?"done":""],onClick:s=>{s.stopPropagation(),this.flash()}},this.done?"copied":"copy")}};var FSt=new Map,$St=(o,s)=>s+`
|
|
2195
2195
|
|
|
2196
2196
|
---
|
|
2197
2197
|
|
package/dist/agents/pi/client.js
CHANGED
|
@@ -2191,7 +2191,7 @@ ${a||this.currentRow()?.pending?"New conversation \u2014 not saved yet":`Session
|
|
|
2191
2191
|
`):"Waiting for the harness to flush this turn";return nr({class:"token-wrap"},nr({class:["token",ete(b)],"data-tip":T},I))}};function GSt(o,...s){return o.slice().sort((a,h)=>{for(let{key:p,desc:b}of s){let v=p(a),w=p(h);if(v!==w)return v==null?b?-1:1:w==null||v<w?b?1:-1:b?-1:1}return 0})}var n5n=()=>X1("play","btn-icon"),r5n=()=>X1("stop","btn-icon"),i5n=o=>`typebulbs/u/samples/${o}.bulb.md`,cD=o=>Qh(o.path).match(/typebulbs\/u\/([^/]+)\//)?.[1],s5n=(o,s)=>`https://typebulb.com/u/${s}/${dM(o.path)}/full`,JSt=o=>o==="HTTP 404"?"not found \u2014 check the URL (private bulbs need their owner's token)":o==="HTTP 401"||o==="HTTP 403"?"private \u2014 needs its owner's TYPEBULB_TOKEN in .env":o||"pull failed",nie=class extends y4{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;pullErrors=new Map;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?BF(a.running.url):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((h,p)=>h.pid!==this.servers[p]?.pid||h.denied!==this.servers[p]?.denied||h.predicted!==this.servers[p]?.predicted||h.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((h,p)=>h.path!==this.files[p]?.path||h.mtime!==this.files[p]?.mtime||h.lastRunAt!==this.files[p]?.lastRunAt);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((h,p)=>h.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(),h=s!==this.myUser||a.length!==this.mine.length||a.some((p,b)=>p.slug!==this.mine[b]?.slug);this.myUser=s,this.mine=a,h&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] my-bulbs refresh failed",s)}}merged(){let s=new Map,a=this.files.map(p=>Qh(p.path)),h=[...this.samples.map(p=>[i5n(p.slug),p]),...this.myUser?this.mine.map(p=>[`typebulbs/u/${this.myUser}/${p.slug}.bulb.md`,p]):[]];for(let[p,b]of h)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:Math.max(p.mtime,p.lastRunAt??0),trusted:p.trusted})});for(let p of this.servers){if(p.pid===this.parent.ownPid)continue;let b=Qh(p.file),v=dM(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(h=>[Qh(h.path),h]));s=s.flatMap(h=>{let p=a.get(Qh(h.path));return p?[{...h,hitCount:p.hitCount,snippet:p.snippet}]:[]})}else{let a=this.filter.trim().toLowerCase(),h=M6t(this.filter);if(h){let p=`typebulbs/u/${h.user}/${h.slug}.bulb.md`,b=s.find(v=>("/"+Qh(v.path)).endsWith("/"+p));return b?[b]:[{path:p,name:h.slug,recent:0,remote:{slug:h.slug,name:h.slug,description:`u/${h.user}/${h.slug} on typebulb.com \u2014 play pulls it into the project`}}]}a?s=s.filter(p=>p.name.toLowerCase().includes(a)||p.path.toLowerCase().includes(a)):[...new Set(s.filter(b=>b.remote).map(b=>cD(b)))].forEach((b,v)=>{let w=T=>!!T.remote&&cD(T)===b,I=s.filter(w).length;this.openFolds.has(b)?s=s.map(T=>w(T)?{...T,recent:-.5-v}:T):s=s.filter(T=>!w(T)),s.push({path:`::${b}`,name:this.foldLabel(b),recent:-1-v,group:{user:b,count:I}})})}return GSt(s,{key:a=>!!a.running},{key:a=>a.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.pullErrors.clear(),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}'s bulbs`}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(h=>Qh(h.path)===Qh(s))?.trusted){let h;try{h=(await tb.server.predictTrustOf(s)).cap}catch(p){console.error("[mirror] predictTrustOf failed",p)}if(h){this.pendingLaunch={path:s,name:this.displayName(s),cap:h},this.update();return}}await this.doLaunch(s)}async downloadAndLaunch(s){let a=Qh(s.path);this.launching.add(a),this.pullErrors.delete(a),this.update();try{let h=cD(s),p=h==="samples"?await tb.server.downloadSample(s.remote.slug):await tb.server.pullRemoteBulb(h,s.remote.slug);if(!p.ok||!p.file){console.error("[mirror] remote pull failed",p.error),this.pullErrors.set(a,JSt(p.error));return}await this.refreshFiles();let b=this.files.find(v=>Qh(v.path).endsWith("/"+Qh(p.file)))?.path??p.file;await this.launch(b)}catch(h){console.error("[mirror] remote pull failed",h),this.pullErrors.set(a,JSt(h?.message))}finally{this.launching.delete(a),this.update()}}async syncRow(s,a,h=!1){let p=`${Qh(s.path)}:${a}`;this.syncBusy.add(p),this.update();try{let b=a==="pull"?await tb.server.pullRemoteBulb(cD(s),dM(s.path),h):await tb.server.pushLocalBulb(s.path,h);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),this.update()}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,h=!1){let p=Qh(s);this.launching.add(p),this.update();let b;try{b=await tb.server.launchBulb(s,a)}catch(v){console.error("[mirror] launchBulb failed",v)}finally{this.launching.delete(p)}h&&b?.pid&&this.dismissedDenials.add(b.pid),b?.url&&BF(b.url),await this.refresh(),this.pinToBottom()}displayName(s){return this.files.find(h=>Qh(h.path)===Qh(s))?.name||dM(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(h){console.error("[mirror] toggleTrust failed",h)}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:h}=await tb.server.readBulbLog(s.pid,s.offset);if(this.openLog!==s)return;a?(s.text=(s.text+a).slice(-5e4),s.offset=h,this.update()):h!==s.offset&&(s.offset=h)}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 h=this.pendingDenial();return $t({class:"servers-wrap"},Po({class:["pill",s>0?"":"glyph",this.open?"on":""],"data-tip":"Launch a project bulb \xB7 stop a running one",ariaLabel:s>0?`Bulbs (${s} running)`:"Bulbs",onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},s>0?`${s}\u{1F4A1}`:nr({class:"glyph-img"},"\u{1F4A1}")),this.open?this.popup():null,this.pendingLaunch?this.launchModal(this.pendingLaunch):this.pendingOverwrite?this.overwriteModal(this.pendingOverwrite):h?this.denialModal(h):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=(h,p)=>{h.stopPropagation(),p(),this.open&&this.focusFilter()};return $t({class:"trust-back",tabIndex:0,onMounted:h=>h.focus(),onKeyDown:h=>{h.key==="Escape"&&a(h,s.onDismiss)},onClick:h=>a(h,s.onDismiss)},$t({class:"trust-modal",onClick:h=>h.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"},Po({class:"trust-no",onClick:h=>a(h,s.onNo)},s.noLabel),Po({class:"trust-yes",onClick:h=>a(h,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=dM(s.file)||s.file,h=!s.predicted;return this.trustModal({heading:h?`\u201C${a}\u201D reached for access it didn't declare`:`\u201C${a}\u201D wants more access`,body:h?`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:h?"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,h=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,h&&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"},nr({class:"bulb-log-name"},`console \xB7 ${s.name}`),Po({class:"bulb-log-back",title:"Back to the bulb list",onClick:a=>{a.stopPropagation(),this.closeLog()}},"\u2190 bulbs")),s6({class:"bulb-log-body"},nr({class:"bulb-log-text"},s.text||"(no output yet)")))}hoverRow(s,a){let h=a!==void 0&&a.pid===this.spotlightPid;h&&(this.spotlightPid=void 0),(this.highlighted!==s||h)&&(this.highlighted=s,this.update())}row(s,a,h=!1){if(s.group)return this.groupRow(s,a,h);let p=s.running,b=p&&this.openLog?.pid===p.pid,v=this.pullErrors.get(Qh(s.path)),w=p?!!p.trust:!!s.trusted,I=!!s.remote&&!this.searchActive&&!this.filter.trim();return $t({class:["server-row",I?"fold-row":"",a===this.highlighted?"active":"",h?"dimmed":""],onMouseEnter:()=>this.hoverRow(a,p)},p?Po({class:"server-stop",title:"Stop this server",ariaLabel:"Stop",onClick:T=>{T.stopPropagation(),this.stop(p.pid)}},r5n()):Po({class:["bulb-launch",this.launching.has(Qh(s.path))?"launching shimmer":""],title:s.remote?"Download from typebulb.com & launch":w?"Launch (trusted \u2014 remembered)":"Launch (restricted)",ariaLabel:"Launch",onClick:T=>{T.stopPropagation(),s.remote?this.downloadAndLaunch(s):this.launch(s.path)}},n5n()),$t({class:"bulb-name-cell"},s.remote?nr({class:"server-name stopped remote",title:s.remote.description},s.name):nr({class:["server-name",p?"":"stopped"],title:`Open ${s.path}`,onClick:T=>{T.stopPropagation(),tb.server.openFile(s.path)}},s.name),this.userLink(s),tte(s.hitCount),v?nr({class:"pull-error"},v):null),this.syncCell(s),p||w?this.trustToggle(s,w):nr({class:"cell-empty"}),p?Bk({class:["server-logs",b?"on":""],title:"Show this server\u2019s console",onClick:T=>{T.stopPropagation(),this.showLog(p,s.name)}},"logs"):nr({class:"cell-empty"}),p?Bk({class:"server-port",href:Yye(p.url),target:"_blank",rel:"noopener noreferrer",title:`Open ${p.url}`},`:${p.port}`):s.remote?nr({class:"cell-empty"}):nr({class:"bulb-time"},ite(s.recent)),nte(s.snippet,this.filter.trim()))}userLink(s){let a=cD(s);return a?Bk({class:"sample-link",href:s5n(s,a),target:"_blank",rel:"noopener noreferrer",title:"Open this bulb's page on typebulb.com"},a):null}syncCell(s){let a=cD(s);if(!a||s.remote)return nr({class:"cell-empty"});let h=(p,b)=>{let v=`${Qh(s.path)}:${p}`,w=this.syncBusy.has(v),I=this.syncDone.has(v);return Po({class:["sync-btn",w?"busy shimmer":"",I?"done":""],title:b,ariaLabel:p,onClick:T=>{T.stopPropagation(),w||this.syncRow(s,p)}},X1(I?"check":p,"btn-icon-sm"))};return nr({class:"sync-cell"},h("pull",`Pull \u2014 update the local file from typebulb.com/u/${a}`),a===this.myUser?h("push","Push \u2014 upload this file to typebulb.com"):null)}groupRow(s,a,h){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":"",h?"dimmed":""],title:v?"Collapse":this.foldTitle(p),onMouseEnter:()=>this.hoverRow(a),onClick:w=>{w.stopPropagation(),this.toggleFold(p)}},nr({class:"fold-caret"},X1("caret",["caret-tri",v?"open":""])),nr({class:"sample-group-label"},`${s.name} (${b})`))}trustToggle(s,a){return Po({class:["trust-toggle",a?"on":""],title:`${a?"Trusted":"Restricted"} \u2014 click to switch to ${a?"restricted":"trusted"}`+(s.running?" (stops + relaunches it)":""),onClick:h=>{h.stopPropagation(),this.toggleTrust(s)}},a?"trusted":"restricted")}};var rie=class{#e;#n;#t;#r=!1;#i;#s;constructor(s){this.#e=s}#o(){this.#e()?.classList.add("oruler-host")}#c(s){this.#n=s;let a=this.#e();a&&(this.#o(),this.#s?.disconnect(),this.#s=new ResizeObserver(()=>this.sync()),this.#s.observe(a),this.sync())}release(){this.#s?.disconnect(),this.#s=void 0,this.#e()?.classList.remove("oruler-host"),this.#n=void 0,this.#t=void 0}sync(){this.#r||(this.#r=!0,requestAnimationFrame(()=>{this.#r=!1;let s=this.#e(),a=this.#t;if(!s||!a||!s.scrollHeight)return;this.#o();let h=s.scrollHeight-s.clientHeight;a.style.display=h>0?"":"none",a.style.top=`${s.scrollTop/s.scrollHeight*100}%`,a.style.height=`${s.clientHeight/s.scrollHeight*100}%`,this.#n?.setAttribute("aria-valuenow",String(h>0?Math.round(s.scrollTop/h*100):0))}))}view(s,a={}){return $t({class:["oruler",a.class??""],title:a.title,role:"scrollbar",ariaOrientation:"vertical",ariaLabel:a.label??"Scroll position",ariaControls:a.controls,ariaValueMin:0,ariaValueMax:100,ariaValueNow:0,onMounted:h=>this.#c(h),onPointerDown:h=>this.#u(h),onPointerMove:h=>this.#f(h),onPointerUp:h=>this.#l(h),onPointerCancel:h=>this.#l(h),onWheel:h=>this.#h(h)},$t({class:"oruler-win",onMounted:h=>{this.#t=h,this.sync()}}),s.map(h=>$t({class:["oruler-mark",h.class??""],style:{top:`${h.top*100}%`,height:`${h.height*100}%`}})))}#u(s){let a=this.#e(),h=s.currentTarget;if(!a)return;s.preventDefault();let p=this.#t?.getBoundingClientRect(),b=!!p&&s.clientY>=p.top&&s.clientY<=p.bottom;this.#i=b?s.clientY-p.top:(p?.height??0)/2,h.setPointerCapture(s.pointerId),this.#a(s,h,a)}#f(s){let a=this.#e();this.#i===void 0||!a||this.#a(s,s.currentTarget,a)}#l(s){let a=s.currentTarget;this.#i=void 0,a.hasPointerCapture(s.pointerId)&&a.releasePointerCapture(s.pointerId)}#h(s){let a=this.#e();if(!a)return;let h=s.deltaMode===1?16:s.deltaMode===2?a.clientHeight:1;a.scrollTop+=s.deltaY*h,this.sync()}#a(s,a,h){let p=s.clientY-a.getBoundingClientRect().top-(this.#i??0);h.scrollTop=p/a.clientHeight*h.scrollHeight,this.sync()}};var o5n=4e5,sEe="diff-doc-body";function c5n(o,s){let a=o.split(`
|
|
2192
2192
|
`).map(v=>v.replace(/\r$/,""));if(a.length&&a[a.length-1]===""&&a.pop(),s)return a.map(v=>({kind:"add",text:v}));let h=[],p=!1,b=!1;for(let v of a){if(v.startsWith("@@")){b&&h.push({kind:"gap",text:"\u22EF"}),b=!0,p=!0;continue}if(!p){v.startsWith("Binary file")&&h.push({kind:"ctx",text:v});continue}v.startsWith("\\")||(v.startsWith("+")?h.push({kind:"add",text:v.slice(1)}):v.startsWith("-")?h.push({kind:"del",text:v.slice(1)}):h.push({kind:"ctx",text:v.slice(1)}))}return h}function u5n(o,s,a){let h=c5n(o,s),p=o.length>o5n?"txt":a.split(".").pop()??"",b=[],v=[];for(let P of h)(P.kind==="ctx"||P.kind==="del")&&b.push(P.text),(P.kind==="ctx"||P.kind==="add")&&v.push(P.text);let w=nEe(b.join(`
|
|
2193
2193
|
`),p),I=nEe(v.join(`
|
|
2194
|
-
`),p),T=0,B=0,D=[];for(let P of h){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:h.map(P=>P.kind),bodyHtml:D.join("")}}var iie=class extends y4{files=[];repo=!0;root="";viewing;#e=0;#n=!1;#t=()=>document.getElementById(sEe);#r=new rie(this.#t);#i=[];#s=-1;keepOpenSelector=".gitdiff-wrap";filterId="gitdiff-filter";listSelector=".gitdiff-list";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:h}=await tb.server.gitChangedFiles(),p=s!==this.repo||h.length!==this.files.length||h.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||b.binary!==w.binary});this.repo=s,this.root=a,this.files=h,p&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] gitChangedFiles failed",s)}}#o(s,a,h){this.viewing?.path!==s&&(this.#i=[]),this.viewing={path:s,status:a,text:h.text,truncated:!!h.truncated,...u5n(h.text,!!h.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.#o(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.#o(s.path,s.status,a)}catch(a){console.error("[mirror] gitDiff refresh failed",a)}}closeDoc(){this.#r.release(),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 pop-center"},this.viewing?this.viewingPill():Po({class:["pill","glyph","gitdiff-pill",this.open?"on":""],"data-tip":`${s} changed file${s===1?"":"s"} \u2014 view a diff`,ariaLabel:`${s} changed file${s===1?"":"s"}`,onClick:a=>{a.stopPropagation(),this.open?this.close():this.show()}},X1("diff"),nr({class:"gitdiff-count"},String(s))),this.open?this.popup():null)}viewingPill(){let s=this.viewing,a=s.kinds.filter(p=>p==="add").length,h=s.kinds.filter(p=>p==="del").length;return Po({class:["pill","glyph","gitdiff-pill","viewing","on"],"data-tip":`${this.files.length} changed file${this.files.length===1?"":"s"} \u2014 switch file`,onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},nr({class:["gitdiff-status",`s-${s.status}`]},s.status),nr({class:"gitdiff-doc-path",title:`Open ${s.path}`,onClick:p=>{p.stopPropagation(),tb.server.openFile(`${this.root}/${s.path}`)}},s.path),nr({class:"gitdiff-counts"},nr({class:"count-add"},`+${a}`),nr({class:"count-del"},`\u2212${h}`)),rte(()=>this.closeDoc()))}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,h)=>this.row(a,h))),this.filterBox(this.files.length,"file"))}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:h=>{h.stopPropagation(),this.openDiff(s)}},nr({class:["gitdiff-status",`s-${s.status}`]},s.status),nr({class:"gitdiff-path",title:s.path},s.path),s.add!==void 0||s.del!==void 0?nr({class:"gitdiff-counts"},nr({class:"count-add"},`+${s.add??0}`),nr({class:"count-del"},`\u2212${s.del??0}`)):s.status==="U"?nr({class:"gitdiff-counts"},nr({class:"count-add"},"new")):nr({class:"gitdiff-counts"},nr({},s.binary?"binary":"\u2014")))}docView(){let s=this.viewing;return $t({class:"diff-doc",onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeDoc())}},$t({class:"diff-doc-scroll"},$t({class:"diff-doc-body",id:sEe,tabIndex:0,onMounted:a=>a.focus(),onScroll:()=>this.#r.sync()},s.kinds.length===0?$t({class:"diff-doc-empty"},"No changes."):$t({class:"diff-doc-code",key:`diff-code-${this.#e}`,onMounted:a=>{a.innerHTML=s.bodyHtml,this.#c(a),this.#u(a)}},""),s.truncated?$t({class:"diff-doc-trunc"},"Diff truncated \u2014 file too large to show in full."):null),s.kinds.length?this.#r.view(this.#i,{class:"diff-ruler",title:"Jump to a change",label:"Diff scroll position",controls:sEe}):null))}#c(s){if(!this.#n)return;this.#n=!1;let a=s.querySelector(".udiff-add, .udiff-del"),h=this.#t();a&&h&&(h.scrollTop=a.offsetTop-h.clientHeight/3)}#u(s){this.#s!==this.#e&&(this.#s=this.#e,requestAnimationFrame(()=>{this.#f(s),this.update(),this.#r.sync()}))}#f(s){let a=this.viewing,h=this.#t();if(!a||!h?.scrollHeight)return;let p=h.scrollHeight,b=[];for(let v=0;v<a.kinds.length;v++){let w=a.kinds[v];if(w!=="add"&&w!=="del")continue;let I=v;for(;I+1<a.kinds.length&&a.kinds[I+1]===w;)I++;let T=s.children[v],B=s.children[I];T&&B&&b.push({top:T.offsetTop/p,height:(B.offsetTop+B.offsetHeight-T.offsetTop)/p,class:w}),v=I}this.#i=b}};function a5n(o){let s=new Set(o.map(v=>v.id)),a=new Map;for(let v of o){let w=v.parentId&&s.has(v.parentId)?v.parentId:"",I=a.get(w);I?I.push(v):a.set(w,[v])}let h=[],p=new Set,b=v=>{for(let w of a.get(v)??[])p.has(w.id)||(p.add(w.id),h.push(w),b(w.id))};b("");for(let v of o)p.has(v.id)||h.push(v);return h}var sie=class extends y4{children=[];enabled=!1;viewing=null;#e=null;keepOpenSelector=".children-wrap";filterId="children-filter";listSelector=".children-list";onActivate(s){let a=this.rows()[s];a&&this.openChild(a.id)}onAttached(){setInterval(()=>{this.refresh()},3e3)}rows(){let s=this.filter.trim().toLowerCase();return s?this.children.filter(a=>[a.kind,a.label].filter(Boolean).join(" ").toLowerCase().includes(s)):this.children}get running(){return this.children.filter(s=>s.state==="running").length}async refresh(){if(this.enabled)try{let s=a5n((await tb.server.listChildren()).reverse()),a=s.length!==this.children.length||s.some((h,p)=>{let b=this.children[p];return h.id!==b?.id||h.state!==b.state||h.mtime!==b.mtime||h.tokens!==b.tokens})||s.some(h=>h.state==="running");this.children=s,this.#n(),a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] listChildren failed",s)}}syncFromPoll(s){let a=this.viewing?.id??null;return this.#e=s,this.#n(),s&&!this.viewing&&this.refresh(),(this.viewing?.id??null)!==a}reset(){this.children=[],this.refresh()}#n(){this.viewing=this.#e?this.children.find(s=>s.id===this.#e)??null:null}async openChild(s){this.close(),this.parent.messageList.stickToBottomNextRender();try{await tb.server.openChild(s),this.#e=s,this.#n(),this.update()}catch(a){console.error("[mirror] openChild failed",a)}this.refresh()}async closeChild(){this.parent.messageList.stickToBottomNextRender();try{await tb.server.closeChild(),this.#e=null,this.#n(),this.update()}catch(s){console.error("[mirror] closeChild failed",s)}}show(){this.beginOpen(),this.refresh(),this.refreshList(),this.armClose(),this.focusFilter()}view(){let s=this.children.length;return!this.enabled||s===0&&!this.viewing&&!this.open?$t({class:"children-wrap"}):$t({class:"children-wrap pop-center"},this.viewing?this.viewingPill():this.chip(s),this.open?this.popup():null)}chip(s){let a=this.running;return Po({class:["pill","children-pill",ete(a>0),this.open?"on":""],"data-tip":a?`${a} of ${s} agent${s===1?"":"s"} still working \u2014 open one`:`${s} agent${s===1?"":"s"} this session spawned \u2014 open one`,ariaLabel:a?`Agents (${a} of ${s} running)`:`Agents (${s})`,onClick:h=>{h.stopPropagation(),this.open?this.close():this.show()}},nr({class:"glyph-img"},"\u{1F916}"),String(
|
|
2194
|
+
`),p),T=0,B=0,D=[];for(let P of h){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:h.map(P=>P.kind),bodyHtml:D.join("")}}var iie=class extends y4{files=[];repo=!0;root="";viewing;#e=0;#n=!1;#t=()=>document.getElementById(sEe);#r=new rie(this.#t);#i=[];#s=-1;keepOpenSelector=".gitdiff-wrap";filterId="gitdiff-filter";listSelector=".gitdiff-list";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:h}=await tb.server.gitChangedFiles(),p=s!==this.repo||h.length!==this.files.length||h.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||b.binary!==w.binary});this.repo=s,this.root=a,this.files=h,p&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] gitChangedFiles failed",s)}}#o(s,a,h){this.viewing?.path!==s&&(this.#i=[]),this.viewing={path:s,status:a,text:h.text,truncated:!!h.truncated,...u5n(h.text,!!h.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.#o(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.#o(s.path,s.status,a)}catch(a){console.error("[mirror] gitDiff refresh failed",a)}}closeDoc(){this.#r.release(),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 pop-center"},this.viewing?this.viewingPill():Po({class:["pill","glyph","gitdiff-pill",this.open?"on":""],"data-tip":`${s} changed file${s===1?"":"s"} \u2014 view a diff`,ariaLabel:`${s} changed file${s===1?"":"s"}`,onClick:a=>{a.stopPropagation(),this.open?this.close():this.show()}},X1("diff"),nr({class:"gitdiff-count"},String(s))),this.open?this.popup():null)}viewingPill(){let s=this.viewing,a=s.kinds.filter(p=>p==="add").length,h=s.kinds.filter(p=>p==="del").length;return Po({class:["pill","glyph","gitdiff-pill","viewing","on"],"data-tip":`${this.files.length} changed file${this.files.length===1?"":"s"} \u2014 switch file`,onClick:p=>{p.stopPropagation(),this.open?this.close():this.show()}},nr({class:["gitdiff-status",`s-${s.status}`]},s.status),nr({class:"gitdiff-doc-path",title:`Open ${s.path}`,onClick:p=>{p.stopPropagation(),tb.server.openFile(`${this.root}/${s.path}`)}},s.path),nr({class:"gitdiff-counts"},nr({class:"count-add"},`+${a}`),nr({class:"count-del"},`\u2212${h}`)),rte(()=>this.closeDoc()))}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,h)=>this.row(a,h))),this.filterBox(this.files.length,"file"))}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:h=>{h.stopPropagation(),this.openDiff(s)}},nr({class:["gitdiff-status",`s-${s.status}`]},s.status),nr({class:"gitdiff-path",title:s.path},s.path),s.add!==void 0||s.del!==void 0?nr({class:"gitdiff-counts"},nr({class:"count-add"},`+${s.add??0}`),nr({class:"count-del"},`\u2212${s.del??0}`)):s.status==="U"?nr({class:"gitdiff-counts"},nr({class:"count-add"},"new")):nr({class:"gitdiff-counts"},nr({},s.binary?"binary":"\u2014")))}docView(){let s=this.viewing;return $t({class:"diff-doc",onKeyDown:a=>{a.key==="Escape"&&(a.stopPropagation(),this.closeDoc())}},$t({class:"diff-doc-scroll"},$t({class:"diff-doc-body",id:sEe,tabIndex:0,onMounted:a=>a.focus(),onScroll:()=>this.#r.sync()},s.kinds.length===0?$t({class:"diff-doc-empty"},"No changes."):$t({class:"diff-doc-code",key:`diff-code-${this.#e}`,onMounted:a=>{a.innerHTML=s.bodyHtml,this.#c(a),this.#u(a)}},""),s.truncated?$t({class:"diff-doc-trunc"},"Diff truncated \u2014 file too large to show in full."):null),s.kinds.length?this.#r.view(this.#i,{class:"diff-ruler",title:"Jump to a change",label:"Diff scroll position",controls:sEe}):null))}#c(s){if(!this.#n)return;this.#n=!1;let a=s.querySelector(".udiff-add, .udiff-del"),h=this.#t();a&&h&&(h.scrollTop=a.offsetTop-h.clientHeight/3)}#u(s){this.#s!==this.#e&&(this.#s=this.#e,requestAnimationFrame(()=>{this.#f(s),this.update(),this.#r.sync()}))}#f(s){let a=this.viewing,h=this.#t();if(!a||!h?.scrollHeight)return;let p=h.scrollHeight,b=[];for(let v=0;v<a.kinds.length;v++){let w=a.kinds[v];if(w!=="add"&&w!=="del")continue;let I=v;for(;I+1<a.kinds.length&&a.kinds[I+1]===w;)I++;let T=s.children[v],B=s.children[I];T&&B&&b.push({top:T.offsetTop/p,height:(B.offsetTop+B.offsetHeight-T.offsetTop)/p,class:w}),v=I}this.#i=b}};function a5n(o){let s=new Set(o.map(v=>v.id)),a=new Map;for(let v of o){let w=v.parentId&&s.has(v.parentId)?v.parentId:"",I=a.get(w);I?I.push(v):a.set(w,[v])}let h=[],p=new Set,b=v=>{for(let w of a.get(v)??[])p.has(w.id)||(p.add(w.id),h.push(w),b(w.id))};b("");for(let v of o)p.has(v.id)||h.push(v);return h}var sie=class extends y4{children=[];enabled=!1;viewing=null;#e=null;keepOpenSelector=".children-wrap";filterId="children-filter";listSelector=".children-list";onActivate(s){let a=this.rows()[s];a&&this.openChild(a.id)}onAttached(){setInterval(()=>{this.refresh()},3e3)}rows(){let s=this.filter.trim().toLowerCase();return s?this.children.filter(a=>[a.kind,a.label].filter(Boolean).join(" ").toLowerCase().includes(s)):this.children}get running(){return this.children.filter(s=>s.state==="running").length}async refresh(){if(this.enabled)try{let s=a5n((await tb.server.listChildren()).reverse()),a=s.length!==this.children.length||s.some((h,p)=>{let b=this.children[p];return h.id!==b?.id||h.state!==b.state||h.mtime!==b.mtime||h.tokens!==b.tokens})||s.some(h=>h.state==="running");this.children=s,this.#n(),a&&(this.update(),this.keepBottom())}catch(s){console.error("[mirror] listChildren failed",s)}}syncFromPoll(s){let a=this.viewing?.id??null;return this.#e=s,this.#n(),s&&!this.viewing&&this.refresh(),(this.viewing?.id??null)!==a}reset(){this.children=[],this.refresh()}#n(){this.viewing=this.#e?this.children.find(s=>s.id===this.#e)??null:null}async openChild(s){this.close(),this.parent.messageList.stickToBottomNextRender();try{await tb.server.openChild(s),this.#e=s,this.#n(),this.update()}catch(a){console.error("[mirror] openChild failed",a)}this.refresh()}async closeChild(){this.parent.messageList.stickToBottomNextRender();try{await tb.server.closeChild(),this.#e=null,this.#n(),this.update()}catch(s){console.error("[mirror] closeChild failed",s)}}show(){this.beginOpen(),this.refresh(),this.refreshList(),this.armClose(),this.focusFilter()}view(){let s=this.children.length;return!this.enabled||s===0&&!this.viewing&&!this.open?$t({class:"children-wrap"}):$t({class:"children-wrap pop-center"},this.viewing?this.viewingPill():this.chip(s),this.open?this.popup():null)}chip(s){let a=this.running;return Po({class:["pill","children-pill",ete(a>0),this.open?"on":""],"data-tip":a?`${a} of ${s} agent${s===1?"":"s"} still working \u2014 open one`:`${s} agent${s===1?"":"s"} this session spawned \u2014 open one`,ariaLabel:a?`Agents (${a} of ${s} running)`:`Agents (${s})`,onClick:h=>{h.stopPropagation(),this.open?this.close():this.show()}},nr({class:"glyph-img"},"\u{1F916}"),String(a),nr({class:"glyph-img"},"\u{1F916}"))}viewingPill(){let s=this.viewing,a=this.children.length;return Po({class:["pill","glyph","children-pill","viewing","on"],"data-tip":`${a} agent${a===1?"":"s"} \u2014 switch`,onClick:h=>{h.stopPropagation(),this.open?this.close():this.show()}},nr({class:"glyph-img"},"\u{1F916}"),nr({class:["children-doc-label",s.state==="running"?"shimmer-text shimmer-slow":""],title:[s.kind,s.label||"no description"].filter(Boolean).join(" \u2014 ")},s.label||s.kind||"agent"),rte(()=>{this.closeChild()}))}popup(){let s=this.rows();return $t({class:"servers-pop children-pop"},s.length===0?this.emptyState("No agents in this session yet."):$t({class:"children-list",onScroll:()=>this.onListScroll()},s.map((a,h)=>this.row(a,h))),this.filterBox(this.children.length,"agent"))}row(s,a){return $t({class:["children-row",a===this.highlighted?"active":"",this.viewing?.id===s.id?"viewing":""],style:s.depth>1?{paddingLeft:`${(s.depth-1)*16+10}px`}:void 0,onMouseEnter:()=>{this.highlighted!==a&&(this.highlighted=a,this.update())},onClick:h=>{h.stopPropagation(),this.openChild(s.id)}},nr({class:["children-dot",s.state]}),s.kind?nr({class:"children-kind"},s.kind):null,nr({class:["children-label",s.state==="running"?"shimmer-text shimmer-slow":""]},s.label||"(no description)"),s.model?nr({class:"children-model"},s.model):null,s.started?nr({class:"children-time"},T6t((s.state==="running"?Date.now():s.mtime)-s.started)):null,s.tokens?nr({class:"children-tokens"},wC(s.tokens)):null)}};var uD=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 Po({class:["overlay-pill","copy",this.done?"done":""],onClick:s=>{s.stopPropagation(),this.flash()}},this.done?"copied":"copy")}};var USt=new Map,zSt=(o,s)=>s+`
|
|
2195
2195
|
|
|
2196
2196
|
---
|
|
2197
2197
|
|