typebulb 0.10.6 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import*as zn from"fs/promises";import*as q from"path";import*as ir from"fs/promises";import{existsSync as ae,readFileSync as Gn}from"fs";import*as P from"path";import{pathToFileURL as Kn}from"url";import{resolve as Pt}from"resolve.exports";import{init as ar,parse as cr}from"es-module-lexer";function lr(r,e){let t=P.join(r,"package.json");try{return JSON.parse(Gn(t,"utf8"))}catch{throw new Error(`--replace package '${e}' has no readable package.json at ${t}`)}}var St=["browser","import","default"],or=["node","import","default"];function dr(r){let e=r.indexOf("=");if(e===-1)throw new Error(`--replace must be <name>=<path> (got '${r}')`);let t=r.slice(0,e).trim(),n=r.slice(e+1).trim();if(!t)throw new Error(`--replace missing package name (got '${r}')`);if(!n)throw new Error(`--replace missing path for '${t}'`);if(t.startsWith("@"))throw new Error(`--replace does not support scoped names yet; '${t}' is scoped`);return{name:t,dir:P.resolve(n)}}async function Je(r){let{name:e,dir:t}=r;if(!ae(t))throw new Error(`--replace path for '${e}' does not exist: ${t}`);let n=lr(t,e),s=Yn(n,e),o=P.resolve(t,s);if(!ae(o))throw new Error(`--replace package '${e}' entry not found on disk: ${o} \u2014 did you build it (e.g. \`pnpm run build\`)?`);let i=P.dirname(o),a=`/local/${e}/${P.basename(o)}`,c=Xn(n,t);return await Qn(e,o,i),{name:e,dir:t,entryAbs:o,serveDir:i,entryUrl:a,typesAbs:c}}function Yn(r,e){if(r.exports!==void 0){let n;try{n=Pt(r,".",{browser:!0,conditions:St})}catch(o){throw new Error(`--replace package '${e}' "exports" does not resolve a browser entry (conditions: ${St.join(", ")}): ${o instanceof Error?o.message:o}`)}let s=Rt(n);if(!s)throw new Error(`--replace package '${e}' "exports" did not resolve "." to a single file (conditions: ${St.join(", ")}); too complex to override.`);return s}let t=r.module??r.main;if(!t)throw new Error(`--replace package '${e}' has no "exports", "module", or "main" entry to resolve.`);return t}function Xn(r,e){if(r.exports!==void 0)try{let n=Pt(r,".",{conditions:["types"]}),s=Rt(n);if(s){let o=P.resolve(e,s);if(ae(o))return o}}catch{}let t=r.types??r.typings;if(t){let n=P.resolve(e,t);if(ae(n))return n}}function Rt(r){if(typeof r=="string")return r;if(Array.isArray(r))return r.find(e=>typeof e=="string")}async function Qn(r,e,t){await ar;let n=P.normalize(t),s=new Set,o=[e];for(;o.length;){let i=o.shift();if(s.has(i))continue;s.add(i);let a;try{a=await ir.readFile(i,"utf8")}catch{continue}let c,l;try{[c,,,l]=cr(a,i)}catch{continue}if(i===e&&!l)throw new Error(`override package '${r}' entry is not an ES module (no import/export syntax); CommonJS or non-module entries aren't supported (esm.sh would have to transform it).`);for(let p of c){if(p.d===-2)continue;let d=p.n;if(d&&!d.startsWith("node:")){if(d.startsWith("./")||d.startsWith("../")||d.startsWith("/")){let m=Zn(i,d,n);m&&!s.has(m)&&o.push(m);continue}throw new Error(`override package must ship self-contained (bundle its dependencies); ${r} externalizes '${d}'`)}}}}function Zn(r,e,t){let n=e.replace(/[?#].*$/,""),s=P.resolve(P.dirname(r),n),o=[s,s+".js",s+".mjs",P.join(s,"index.js"),P.join(s,"index.mjs")];for(let i of o)if(P.normalize(i).startsWith(t)&&ae(i))return i}function es(r,e,t){let n=lr(r,e),s;if(n.exports!==void 0)try{s=Rt(Pt(n,t,{conditions:or}))}catch(i){throw new Error(`--replace package '${e}' "exports" does not resolve a node entry for '${t}' (conditions: ${or.join(", ")}): ${i instanceof Error?i.message:i}`)}else t==="."&&(s=n.main??n.module);if(!s)throw new Error(`--replace package '${e}' has no node export for '${t}'.`);let o=P.resolve(r,s);if(!ae(o))throw new Error(`--replace package '${e}' built file not found: ${o} \u2014 did you build it (e.g. \`pnpm run build\`)?`);return Kn(o).href}async function ur(r,e){await ar;let t;try{[t]=cr(r)}catch{return r}let n="",s=0;for(let o of t){if(o.d!==-1)continue;let i=o.n;if(!i||i!==e.name&&!i.startsWith(e.name+"/"))continue;let a=i===e.name?".":"."+i.slice(e.name.length),c=es(e.dir,e.name,a);n+=r.slice(s,o.s)+c,s=o.e}return n+r.slice(s)}function pr(r){let e={subcommand:"run",file:"",port:3e3,watch:!0,open:!0,server:!1,trust:!1,noTrust:!1,follow:!1,help:!1,version:!1},t=["check","predict","logs","stop","trust","untrust","skill","models"],n=r[0];if(n==="agent"||n?.startsWith("agent:")){e.subcommand="agent";let s=n.indexOf(":");if(s!==-1){let o=n.slice(s+1);o&&(e.agentTarget=o)}r=r.slice(1)}else n&&t.includes(n)&&(e.subcommand=n,r=r.slice(1));for(let s=0;s<r.length;s++){let o=r[s];if(o==="--help"||o==="-h")e.help=!0;else if(o==="--version"||o==="-V")e.version=!0;else if(o==="--no-watch")e.watch=!1;else if(o==="--no-open")e.open=!1;else if(o==="--server")e.server=!0;else if(o==="--trust")e.trust=!0;else if(o==="--no-trust")e.noTrust=!0;else if(o==="--mode"){let i=r[++s];(!i||i.startsWith("-"))&&(console.error("Missing value for --mode (e.g. --mode staging)"),process.exit(1)),e.mode=i}else if(o==="--follow"||o==="-f")e.follow=!0;else if(o==="--lines"||o==="-n"){let i=parseInt(r[++s],10);(isNaN(i)||i<0)&&(console.error(`Invalid --lines value: ${r[s]}`),process.exit(1)),e.lines=i}else if(o==="--port"||o==="-p"){let i=r[++s],a=parseInt(i,10);isNaN(a)&&(console.error(`Invalid port: ${i}`),process.exit(1)),e.port=a}else if(o==="--replace"||o.startsWith("--replace=")){let i=o.startsWith("--replace=")?o.slice(10):r[++s]??"";try{let a=dr(i);if(e.local)throw new Error(`--replace can only be used once (got '${e.local.name}' and '${a.name}')`);e.local=a}catch(a){console.error(a instanceof Error?a.message:String(a)),process.exit(1)}}else o==="-"?e.file="-":o.startsWith("-")||(e.file=o)}return e}function fr(){console.log(`
2
+ var Hs=Object.defineProperty;var j=(r,e)=>()=>(r&&(e=r(r=0)),e);var qs=(r,e)=>{for(var t in e)Hs(r,t,{get:e[t],enumerable:!0})};function at(r){try{let e=r.split(`
3
+ `),t=0;if(e[t]?.trim()!=="---")return null;t++;let n=[];for(;t<e.length&&e[t]?.trim()!=="---";)n.push(e[t]),t++;if(e[t]?.trim()!=="---")return null;t++;let s=to(n);if(!s)return null;let o=new Map;for(;t<e.length;){let a=e[t]?.trim()?.match(/^\*\*(.+)\*\*$/);if(a){let c=a[1].trim();for(t++;t<e.length&&e[t]?.trim()==="";)t++;let l=e[t]?.match(/^(`{3,})(\w*)\s*$/);if(!l){t++;continue}let d=l[1];t++;let u=[];for(;t<e.length&&!e[t]?.match(new RegExp(`^${d}\\s*$`));)u.push(e[t]),t++;t++,o.set(c,u.join(`
4
+ `))}else t++}return{frontmatter:s,files:o}}catch{return null}}function to(r){let e={};for(let t of r){let n=t.indexOf(":");if(n===-1)continue;let s=t.slice(0,n).trim(),o=t.slice(n+1).trim();switch(s){case"format":e.format=o;break;case"name":e.name=ro(o);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function ro(r){return r.startsWith('"')&&r.endsWith('"')?r.slice(1,-1).replace(/\\"/g,'"'):r.startsWith("'")&&r.endsWith("'")?r.slice(1,-1):r}function ct(r){let e=t=>r.files.get(eo[t].path)||"";return{name:r.frontmatter.name,code:e("code"),css:e("css"),html:e("html"),config:e("config"),notes:e("notes"),data:e("data"),infer:e("infer"),insight:e("insight"),server:e("server")}}function no(r){try{return JSON.parse(r),!0}catch{}return!!(/^\s*<[\s\S]*>/.test(r)||/^---\s*$/m.test(r)||/^\w[\w\s]*:[ \t]/m.test(r))}function Jr(r){let e=r.trim();return e?no(e)?[e]:r.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function Vr(r){if(!r.trim())return{};try{return JSON.parse(r)}catch{return{}}}var eo,zt=j(()=>{eo={code:{path:"code.tsx",language:"typescript"},css:{path:"styles.css",language:"css"},html:{path:"index.html",language:"html"},config:{path:"config.json",language:"json"},notes:{path:"notes.md",language:"markdown"},data:{path:"data.txt",language:"text"},infer:{path:"infer.md",language:"markdown"},insight:{path:"insight.json",language:"json"},server:{path:"server.ts",language:"typescript"}}});import{join as dr,resolve as Wo}from"path";import{homedir as Jo}from"os";function Et(){let r=process.env.TYPEBULB_SERVERS_DIR;return r?dr(r,".."):dr(Jo(),".typebulb")}function le(){return process.env.TYPEBULB_SERVERS_DIR||dr(Et(),"servers")}function W(r){let e=Wo(r);return(process.platform==="win32"?e.toLowerCase():e).replace(/\\/g,"/")}function xn(r,e){let t=W(r),n=W(e);return t.startsWith(n.endsWith("/")?n:n+"/")?!t.includes("/node_modules/"):!1}var ze=j(()=>{});import{readFileSync as Vo,writeFileSync as Ho,mkdirSync as qo}from"fs";import{join as zo}from"path";function Sn(){return zo(Et(),"trust.json")}function ur(){try{let r=JSON.parse(Vo(Sn(),"utf8"));return new Set(Array.isArray(r)?r:[])}catch{return new Set}}function Go(r){qo(Et(),{recursive:!0}),Ho(Sn(),JSON.stringify([...r]))}function de(r){return ur().has(W(r))}function Se(r,e){let t=ur(),n=W(r);(e?t.has(n):!t.has(n))||(e?t.add(n):t.delete(n),Go(t))}function pr(){return[...ur()]}var Ge=j(()=>{ze()});function ke(r){if(r.server.trim())return"server-side code (server.ts)";let e=r.code;if(/\btb\s*\.\s*fs\b/.test(e)||e.includes("/__fs"))return"the filesystem";if(/\btb\s*\.\s*ai\b/.test(e)||e.includes("/__ai"))return"AI (your API keys)";if(/\btb\s*\.\s*server\s*\.\s*(?!log\b)\w/.test(e)||e.includes("/__api"))return"server-side code (server.ts)"}var _t=j(()=>{});import{spawn as Dn}from"child_process";import{readdir as pi,readFile as Mn,writeFile as Nn,unlink as Ye,mkdir as fi}from"fs/promises";import{mkdirSync as mi,writeFileSync as Fn,appendFileSync as hi,readFileSync as jn}from"fs";import*as J from"path";import{fileURLToPath as gi}from"url";function hr(r){return J.join(le(),`${r}.json`)}function Xe(r){return J.join(le(),`${r}.log`)}function Ct(r){let e=Xe(r);try{mi(le(),{recursive:!0}),Fn(e,"")}catch{return()=>{}}let t=process.stdout.write.bind(process.stdout),n=process.stderr.write.bind(process.stderr),s=0,o=!1,i=a=>{if(!o)try{let c=typeof a=="string"?Buffer.from(a,"utf8"):Buffer.from(a);if(hi(e,c),s+=c.length,s>2*Bn){let l=jn(e),d=l.subarray(Math.max(0,l.length-Bn));Fn(e,d),s=d.length}}catch{o=!0}};return process.stdout.write=((a,...c)=>(i(a),t(a,...c))),process.stderr.write=((a,...c)=>(i(a),n(a,...c))),()=>{process.stdout.write=t,process.stderr.write=n}}function Re(r,e=0){try{let t=jn(Xe(r)),n=e>=0&&e<=t.length?e:0;return{text:t.subarray(n).toString("utf8"),offset:t.length}}catch{return{text:"",offset:0}}}function yi(r){try{return process.kill(r,0),!0}catch(e){return e.code==="EPERM"}}async function At(r){await fi(le(),{recursive:!0}),await Nn(hr(r.pid),JSON.stringify(r))}async function Ln(r,e){let t=hr(r);try{let n=JSON.parse(await Mn(t,"utf8"));if(n.denied===e)return;n.denied=e,await Nn(t,JSON.stringify(n))}catch{}}async function Qe(r){await Ye(hr(r)).catch(()=>{}),await Ye(Xe(r)).catch(()=>{})}async function M(r){let e;try{e=await pi(le())}catch{return[]}let t=[];return await Promise.all(e.map(async s=>{if(!s.endsWith(".json"))return;let o=J.join(le(),s),i;try{i=JSON.parse(await Mn(o,"utf8"))}catch{await Ye(o).catch(()=>{});return}i&&typeof i.pid=="number"&&yi(i.pid)?t.push(i):(await Ye(o).catch(()=>{}),i?.pid&&await Ye(Xe(i.pid)).catch(()=>{}))})),(r?t.filter(s=>s.agent==null&&xn(s.file,r)):t).sort((s,o)=>s.startedAt-o.startedAt)}async function Ze(r){try{process.kill(r,"SIGTERM")}catch{}await Qe(r)}function wi(){return J.join(J.dirname(gi(import.meta.url)),"index.js")}function vi(r,e={}){return{command:process.execPath,args:[wi(),...e.trust?["--trust"]:[],r,...e.open===!1?["--no-open"]:[]]}}async function It(r,e={}){let t=e.cwd??process.cwd(),n=J.resolve(t,r),s=(await M()).find(l=>l.file===n);if(s)return s;let{command:o,args:i}=vi(r,e);(process.platform==="win32"?Dn("cmd",["/c","start","","/b",o,...i],{cwd:t,stdio:"ignore",windowsHide:!0}):Dn(o,i,{cwd:t,detached:!0,stdio:"ignore"})).unref();let c=Date.now()+2e4;for(;Date.now()<c;){await bi(150);let l=(await M()).find(d=>d.file===n);if(l)return l}throw new Error(`Launched ${J.basename(r)} but it did not register within 20s.`)}var Bn,bi,ue=j(()=>{ze();Bn=1e6;bi=r=>new Promise(e=>setTimeout(e,r))});function Lt(r){let e=/^---[^\n]*\n([\s\S]*?)\n---/.exec(r),t=e?/^\s*name:\s*(.+?)\s*$/m.exec(e[1]):null;return t?t[1].replace(/^["']|["']$/g,""):void 0}function Er(r){return(Lt(r)??"bulb").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"bulb"}var kr=j(()=>{});import{readdirSync as Wi,readFileSync as Ji,statSync as Vi}from"fs";import{join as ps,basename as Hi}from"path";function fs(r,e,t){if(e>8)return t;let n;try{n=Wi(r,{withFileTypes:!0})}catch{return t}for(let s of n)if(s.isDirectory()){if(s.name.startsWith(".")||s.name==="node_modules")continue;fs(ps(r,s.name),e+1,t)}else s.isFile()&&s.name.endsWith(".bulb.md")&&t.push(ps(r,s.name));return t}function Rr(r){return fs(r,0,[]).map(e=>{let t=0;try{t=Vi(e).mtimeMs}catch{}let n;try{n=Lt(Ji(e,"utf8").slice(0,1024))}catch{}return{path:e,name:n??Hi(e).replace(/\.bulb\.md$/,""),mtime:t}})}var ms=j(()=>{kr()});import{readFile as qi}from"fs/promises";async function Tr(r){try{let e=at(await qi(r,"utf-8"));return e?ke(ct(e)):void 0}catch{return}}var hs=j(()=>{zt();_t()});import{spawn as zi}from"child_process";import{basename as Gi}from"path";function Ki(){return process.env.TYPEBULB_EDITOR||"code"}function Xi(r,e,t){return t==null?[e]:Yi.test(Gi(r))?["-g",`${e}:${t}`]:[`+${t}`,e]}function Qi(r,e){let t=Ki();return{command:t,args:Xi(t,r,e)}}function _r(r,e){let{command:t,args:n}=Qi(r,e),s=zi(t,n,{shell:!0,detached:!0,stdio:"ignore"});s.on("error",o=>console.error("[typebulb] editor launch failed:",o?.message??o)),s.unref()}var Yi,gs=j(()=>{Yi=/^(code|code-insiders|codium|vscodium|cursor|windsurf)(\.cmd|\.exe)?$/i});var ys=j(()=>{ue();ms();hs();kr();gs();Ge()});var Ms={};qs(Ms,{attach:()=>xa,breakout:()=>Pa,info:()=>ga,launchBulb:()=>Ta,listBreakouts:()=>Ea,listBulbFiles:()=>Ra,listSessions:()=>va,openFile:()=>Sa,poll:()=>ya,predictTrustOf:()=>_a,readBulbLog:()=>Aa,setBulbTrust:()=>Ca,stopBreakout:()=>ka});import{existsSync as Ie,openSync as Ss,readSync as Ps,closeSync as Es,statSync as fe,readdirSync as Cr,watchFile as Zi,unwatchFile as bs,mkdirSync as ks,writeFileSync as Rs,readFileSync as Ar,unlinkSync as ea}from"fs";import{join as C}from"path";import{homedir as ta}from"os";function Ts(r){return r?.message??String(r)}function ra(r){return r.replace(/[^a-zA-Z0-9]/g,"-")}function _s(r){let e=Ir(r);if(!Ie(e))return[];let t;try{t=Cr(e)}catch{return[]}let n=[];for(let s of t){if(!s.endsWith(".jsonl"))continue;let o=C(e,s);try{let i=fe(o);i.isFile()&&n.push({sessionId:s.slice(0,-6),file:o,mtime:i.mtimeMs})}catch{}}return n}function Wt(r){return C(r,oa)}function As(r,e){return C(Wt(r),`${e}.lock`)}function aa(r,e){try{let t=As(r,e);if(Date.now()-fe(t).mtimeMs>=Cs)return!1;try{if(parseInt(Ar(t,"utf8").trim(),10)===process.pid)return!1}catch{}return!0}catch{return!1}}function Is(r,e){if(e)try{ks(Wt(r),{recursive:!0}),Rs(As(r,e),String(process.pid))}catch(t){console.error("[lock] claim failed:",Ts(t))}}function ca(r){let e=Wt(r);if(!Ie(e))return;let t;try{t=Cr(e)}catch{return}let n=Date.now();for(let s of t){if(!s.endsWith(".lock"))continue;let o=C(e,s);try{let i=fe(o);n-i.mtimeMs>ia&&ea(o)}catch{}}}function ws(r){return typeof r=="string"?r:Array.isArray(r)?r.map(e=>typeof e=="string"?e:e?.text??e?.content??JSON.stringify(e)).join(`
5
+ `):r==null?"":JSON.stringify(r)}function $s(r){try{return fe(r),!1}catch(e){return e.code==="ENOENT"}}function Os(){let r=D;if(r.file&&!$s(r.file)){Is(r.cwd,r.sessionId);return}let e=la(r);e&&Ds(e)}function la(r){if(!r.everAttached)return da(r.cwd)??ua(r.cwd,()=>!0)}function da(r){let e=Wt(r);if(!Ie(e))return;let t;try{t=Cr(e)}catch{return}let n;for(let o of t)if(o.endsWith(".lock"))try{let i=fe(C(e,o));if(Date.now()-i.mtimeMs>=Cs||parseInt(Ar(C(e,o),"utf8").trim(),10)!==process.pid)continue;(!n||i.mtimeMs>n.mtime)&&(n={sessionId:o.slice(0,-5),mtime:i.mtimeMs})}catch{}if(!n)return;let s=C(Ir(r),`${n.sessionId}.jsonl`);if(!$s(s))return{sessionId:n.sessionId,file:s,mtime:n.mtime}}function ua(r,e){return _s(r).sort((t,n)=>n.mtime-t.mtime).find(t=>!aa(r,t.sessionId)&&e(t))}function Ds(r){let e=D;if(e.file)try{bs(e.file)}catch{}e.file=r.file,e.sessionId=r.sessionId,e.everAttached=!0,e.partial="",e.offset=0,e.totals={in:0,out:0,cached:0,cacheCreate:0},e.entries=new Map,e.chainLastUuid=void 0,e.buffer.push({type:"cleared"}),e.buffer.push({type:"session",sessionId:r.sessionId}),Is(e.cwd,r.sessionId),vs();try{bs(r.file)}catch{}Zi(r.file,{interval:200},()=>vs())}function vs(){let r=D;if(!r.file)return;let e;try{e=fe(r.file).size}catch{return}if(e<=r.offset)return;let t;try{t=Ss(r.file,"r")}catch{return}try{let c=e-r.offset,l=Buffer.alloc(c),d=0;for(;d<c;){let u=Ps(t,l,d,c-d,r.offset+d);if(!u)break;d+=u}r.offset+=d,r.partial+=l.subarray(0,d).toString("utf8")}finally{Es(t)}let n,s;for(;(s=r.partial.indexOf(`
6
+ `))>=0;){let c=r.partial.slice(0,s);if(r.partial=r.partial.slice(s+1),!c.trim())continue;let l;try{l=JSON.parse(c)}catch{continue}l&&l.uuid&&(r.entries.set(l.uuid,l),l.isSidechain||(n=l.uuid))}if(!n)return;let o=[],i=r.entries.get(n),a=!1;for(;i;){if(o.push(i),i.uuid===r.chainLastUuid){a=!0;break}i=i.parentUuid?r.entries.get(i.parentUuid):void 0}if(a)for(let c=o.length-2;c>=0;c--)xs(o[c]);else{r.chainLastUuid!==void 0&&(r.buffer.push({type:"cleared"}),r.buffer.push({type:"session",sessionId:r.sessionId}),r.totals={in:0,out:0,cached:0,cacheCreate:0});for(let c=o.length-1;c>=0;c--)xs(o[c])}r.chainLastUuid=n}function Fs(r){let e=r.trim();return!!e&&pa.some(t=>t.test(e))}function ma(r){return r.replace(fa,"")}function Ut(r){let e=ma(r).trim();return e&&!Fs(e)?e:""}function Bs(r){return r?.type==="text"&&typeof r.text=="string"?Ut(r.text):""}function xs(r){try{ha(r)}catch(e){console.error("[claude-bulb] skipped malformed entry:",Ts(e))}}function ha(r){if(r.isSidechain)return;let e=D;if(r.type==="user"){let t=r.message?.content;if(typeof t=="string"){let n=Ut(t);n&&e.buffer.push({type:"user",text:n})}else if(Array.isArray(t))for(let n of t)if(n?.type==="tool_result")e.buffer.push({type:"tool_result",id:n.tool_use_id??"",content:ws(n.content),isError:!!n.is_error});else{let s=Bs(n);s&&e.buffer.push({type:"user",text:s})}}else if(r.type==="attachment"&&r.attachment?.type==="queued_command"){let t=Ut(ws(r.attachment.prompt));t&&e.buffer.push({type:"user",text:t})}else if(r.type==="assistant"){let t=r.message?.content,n=Array.isArray(t)?t:[],s=n.filter(c=>c.type==="text").map(c=>c.text??"").filter(c=>!Fs(c)).join(""),o=n.filter(c=>c.type==="thinking").map(c=>c.thinking??"").join(`
7
+ `),i=n.filter(c=>c.type==="tool_use").map(c=>({id:c.id??"",name:c.name??"",input:c.input??{}}));if(s||o||i.length){let c=Date.parse(r.timestamp??""),l=!isNaN(c)&&c>=e.sessionStartMs;e.buffer.push({type:"assistant",text:s,thinking:o,tools:i,live:l})}let a=r.message?.usage??r.usage;a&&(e.totals.in+=a.input_tokens??0,e.totals.out+=a.output_tokens??0,e.totals.cached+=a.cache_read_input_tokens??0,e.totals.cacheCreate+=a.cache_creation_input_tokens??0,e.buffer.push({type:"usage",...e.totals}))}}async function ga(){return{cwd:D.cwd,pid:process.pid}}async function ya(r){let e=D;return Os(),{events:e.buffer.slice(r),cursor:e.buffer.length,working:ba(e)}}function ba(r){let e;for(let o of r.entries.values())(o.type==="user"||o.type==="assistant")&&(e=o);if(!e)return!1;if(e.type==="user")return!0;let n=(Array.isArray(e.message?.content)?e.message.content:[]).filter(o=>o.type==="tool_use").map(o=>o.id);if(n.length===0)return!1;let s=new Set;for(let o of r.entries.values()){let i=o.message?.content;if(Array.isArray(i))for(let a of i)a.type==="tool_result"&&a.tool_use_id&&s.add(a.tool_use_id)}return n.some(o=>o&&!s.has(o))}function wa(r){let e;try{e=Ss(r,"r")}catch{return""}try{let n=65536;try{n=fe(r).size}catch{}let s=(l,d)=>{if(d<=0)return"";let u=Buffer.alloc(d),f=Ps(e,u,0,d,l);return u.subarray(0,f).toString("utf8")},o=(l,d,u)=>{let f="";for(let h of l.split(`
8
+ `)){if(!h.includes(`"${d}"`))continue;let g;try{g=JSON.parse(h)}catch{continue}let x=g?.[u];g?.type===d&&typeof x=="string"&&x&&(f=x)}return f},i=s(0,Math.min(65536,n)),a=n>65536?s(n-65536,65536):"",c=o(a,"custom-title","customTitle")||o(i,"custom-title","customTitle")||o(a,"ai-title","aiTitle")||o(i,"ai-title","aiTitle");if(c)return c.replace(/\s+/g," ").trim().slice(0,200);for(let l of i.split(`
9
+ `)){if(!l.trim())continue;let d;try{d=JSON.parse(l)}catch{continue}if(!d||d.isSidechain||d.type!=="user")continue;let u=d.message?.content,f="";typeof u=="string"?f=Ut(u):Array.isArray(u)&&(f=u.map(Bs).filter(Boolean).join(" "));let h=f.replace(/\s+/g," ").trim();if(h)return(h.replace(/^Continuing from a prior session\. Here is the summary of our work so far:\s*/i,"").trim()||h).slice(0,200)}return""}finally{Es(e)}}async function va(){return _s(D.cwd).sort((r,e)=>e.mtime-r.mtime).map(({sessionId:r,file:e,mtime:t})=>({sessionId:r,mtime:t,preview:wa(e)}))}async function xa(r){let e=D,t=C(Ir(e.cwd),`${r}.jsonl`);return Ie(t)?t===e.file?{ok:!0}:(Ds({sessionId:r,file:t}),{ok:!0}):{ok:!1,error:"session not found"}}async function Sa(r,e){return _r(r,e),{ok:!0}}async function Pa(r){let e=D.cwd,t=C(e,"typebulbs");ks(t,{recursive:!0});let n=Er(r),s=`${n}.bulb.md`;for(let c=2;Ie(C(t,s))&&Ar(C(t,s),"utf8")!==r;c++)s=`${n}-${c}.bulb.md`;let o=C(t,s);Ie(o)||Rs(o,r);let i=C("typebulbs",s),a=await It(i,{cwd:e,open:!0});return{ok:!0,file:i,pid:a.pid,url:a.url}}async function Ea(){return M(D.cwd)}async function ka(r){return await Ze(r),{ok:!0}}async function Ra(){return Rr(D.cwd).map(r=>({...r,trusted:de(r.path)}))}async function Ta(r,e){let t=D.cwd;e!=null&&Se(r,e);let n=await It(r,{cwd:t,open:!0,trust:e});return{ok:!0,file:n.file,pid:n.pid,url:n.url,trust:!!n.trust}}async function _a(r){return{cap:await Tr(r)}}async function Ca(r,e){return Se(r,e),{ok:!0}}async function Aa(r,e){return Re(r,e)}var na,sa,Ir,oa,Cs,ia,D,pa,fa,Ns=j(()=>{ys();na=".claude-bulb",sa=C(ta(),".claude","projects"),Ir=r=>C(sa,ra(r));oa=`${na}/locks`,Cs=5e3,ia=6e4;D={cwd:process.cwd(),sessionId:"",sessionStartMs:Date.now(),buffer:[],partial:"",offset:0,totals:{in:0,out:0,cached:0,cacheCreate:0},everAttached:!1,entries:new Map};pa=[/\[Request interrupted by user\b/i,/\[Tool use was interrupted\]/i,/Claude Code returned an error/i,/\[ede_diagnostic\]/i,/^No response requested\.?$/i,/^<task-notification\b/i,/^<system-reminder\b/i];fa=/<ide_[a-z_]+>[\s\S]*?<\/ide_[a-z_]+>/gi;ca(D.cwd);Os()});import*as Vs from"fs/promises";import*as Q from"path";import*as Dr from"fs/promises";import{existsSync as he,readFileSync as zs}from"fs";import*as P from"path";import{pathToFileURL as Gs}from"url";import{resolve as Ht}from"resolve.exports";import{init as Fr,parse as Br}from"es-module-lexer";function Mr(r,e){let t=P.join(r,"package.json");try{return JSON.parse(zs(t,"utf8"))}catch{throw new Error(`--replace package '${e}' has no readable package.json at ${t}`)}}var Vt=["browser","import","default"],Or=["node","import","default"];function Nr(r){let e=r.indexOf("=");if(e===-1)throw new Error(`--replace must be <name>=<path> (got '${r}')`);let t=r.slice(0,e).trim(),n=r.slice(e+1).trim();if(!t)throw new Error(`--replace missing package name (got '${r}')`);if(!n)throw new Error(`--replace missing path for '${t}'`);if(t.startsWith("@"))throw new Error(`--replace does not support scoped names yet; '${t}' is scoped`);return{name:t,dir:P.resolve(n)}}async function jr(r){let{name:e,dir:t}=r;if(!he(t))throw new Error(`--replace path for '${e}' does not exist: ${t}`);let n=Mr(t,e),s=Ks(n,e),o=P.resolve(t,s);if(!he(o))throw new Error(`--replace package '${e}' entry not found on disk: ${o} \u2014 did you build it (e.g. \`pnpm run build\`)?`);let i=P.dirname(o),a=`/local/${e}/${P.basename(o)}`,c=Ys(n,t);return await Xs(e,o,i),{name:e,dir:t,entryAbs:o,serveDir:i,entryUrl:a,typesAbs:c}}function Ks(r,e){if(r.exports!==void 0){let n;try{n=Ht(r,".",{browser:!0,conditions:Vt})}catch(o){throw new Error(`--replace package '${e}' "exports" does not resolve a browser entry (conditions: ${Vt.join(", ")}): ${o instanceof Error?o.message:o}`)}let s=qt(n);if(!s)throw new Error(`--replace package '${e}' "exports" did not resolve "." to a single file (conditions: ${Vt.join(", ")}); too complex to override.`);return s}let t=r.module??r.main;if(!t)throw new Error(`--replace package '${e}' has no "exports", "module", or "main" entry to resolve.`);return t}function Ys(r,e){if(r.exports!==void 0)try{let n=Ht(r,".",{conditions:["types"]}),s=qt(n);if(s){let o=P.resolve(e,s);if(he(o))return o}}catch{}let t=r.types??r.typings;if(t){let n=P.resolve(e,t);if(he(n))return n}}function qt(r){if(typeof r=="string")return r;if(Array.isArray(r))return r.find(e=>typeof e=="string")}async function Xs(r,e,t){await Fr;let n=P.normalize(t),s=new Set,o=[e];for(;o.length;){let i=o.shift();if(s.has(i))continue;s.add(i);let a;try{a=await Dr.readFile(i,"utf8")}catch{continue}let c,l;try{[c,,,l]=Br(a,i)}catch{continue}if(i===e&&!l)throw new Error(`override package '${r}' entry is not an ES module (no import/export syntax); CommonJS or non-module entries aren't supported (esm.sh would have to transform it).`);for(let d of c){if(d.d===-2)continue;let u=d.n;if(u&&!u.startsWith("node:")){if(u.startsWith("./")||u.startsWith("../")||u.startsWith("/")){let f=Qs(i,u,n);f&&!s.has(f)&&o.push(f);continue}throw new Error(`override package must ship self-contained (bundle its dependencies); ${r} externalizes '${u}'`)}}}}function Qs(r,e,t){let n=e.replace(/[?#].*$/,""),s=P.resolve(P.dirname(r),n),o=[s,s+".js",s+".mjs",P.join(s,"index.js"),P.join(s,"index.mjs")];for(let i of o)if(P.normalize(i).startsWith(t)&&he(i))return i}function Zs(r,e,t){let n=Mr(r,e),s;if(n.exports!==void 0)try{s=qt(Ht(n,t,{conditions:Or}))}catch(i){throw new Error(`--replace package '${e}' "exports" does not resolve a node entry for '${t}' (conditions: ${Or.join(", ")}): ${i instanceof Error?i.message:i}`)}else t==="."&&(s=n.main??n.module);if(!s)throw new Error(`--replace package '${e}' has no node export for '${t}'.`);let o=P.resolve(r,s);if(!he(o))throw new Error(`--replace package '${e}' built file not found: ${o} \u2014 did you build it (e.g. \`pnpm run build\`)?`);return Gs(o).href}async function Lr(r,e){await Fr;let t;try{[t]=Br(r)}catch{return r}let n="",s=0;for(let o of t){if(o.d!==-1)continue;let i=o.n;if(!i||i!==e.name&&!i.startsWith(e.name+"/"))continue;let a=i===e.name?".":"."+i.slice(e.name.length),c=Zs(e.dir,e.name,a);n+=r.slice(s,o.s)+c,s=o.e}return n+r.slice(s)}function Ur(r){let e={subcommand:"run",file:"",port:3e3,watch:!0,open:!0,server:!1,trust:!1,noTrust:!1,follow:!1,help:!1,version:!1},t=["check","predict","logs","stop","trust","untrust","skill","models"],n=r[0];if(n==="agent"||n?.startsWith("agent:")){e.subcommand="agent";let s=n.indexOf(":");if(s!==-1){let o=n.slice(s+1);o&&(e.agentTarget=o)}r=r.slice(1)}else n&&t.includes(n)&&(e.subcommand=n,r=r.slice(1));for(let s=0;s<r.length;s++){let o=r[s];if(o==="--help"||o==="-h")e.help=!0;else if(o==="--version"||o==="-V")e.version=!0;else if(o==="--no-watch")e.watch=!1;else if(o==="--no-open")e.open=!1;else if(o==="--server")e.server=!0;else if(o==="--trust")e.trust=!0;else if(o==="--no-trust")e.noTrust=!0;else if(o==="--mode"){let i=r[++s];(!i||i.startsWith("-"))&&(console.error("Missing value for --mode (e.g. --mode staging)"),process.exit(1)),e.mode=i}else if(o==="--follow"||o==="-f")e.follow=!0;else if(o==="--lines"||o==="-n"){let i=parseInt(r[++s],10);(isNaN(i)||i<0)&&(console.error(`Invalid --lines value: ${r[s]}`),process.exit(1)),e.lines=i}else if(o==="--port"||o==="-p"){let i=r[++s],a=parseInt(i,10);isNaN(a)&&(console.error(`Invalid port: ${i}`),process.exit(1)),e.port=a}else if(o==="--replace"||o.startsWith("--replace=")){let i=o.startsWith("--replace=")?o.slice(10):r[++s]??"";try{let a=Nr(i);if(e.local)throw new Error(`--replace can only be used once (got '${e.local.name}' and '${a.name}')`);e.local=a}catch(a){console.error(a instanceof Error?a.message:String(a)),process.exit(1)}}else o.startsWith("-")||(e.file=o)}return e}function Wr(){console.log(`
3
10
  typebulb - Local bulb runner for Typebulb
4
11
 
5
12
  Usage:
@@ -11,8 +18,7 @@ Usage:
11
18
  Code session; 'agent:<name>' selects which agent).
12
19
  typebulb skill Print this README as an Agent Skill (stdout), for the
13
20
  agent to read and copy into its own skills folder.
14
- typebulb check [file.bulb.md] Type-check a bulb without running it ('-' reads the
15
- bulb from stdin \u2014 validate an embed before emitting it).
21
+ typebulb check [file.bulb.md] Type-check a bulb without running it
16
22
  typebulb predict [file] Report the capability a bulb probably needs
17
23
  (fs / AI / server.ts) without running it.
18
24
  typebulb models List AI models for tb.ai, filtered by the API
@@ -88,9 +94,7 @@ Examples:
88
94
  typebulb my-editor.bulb.md
89
95
  typebulb --no-watch --port 8080 my-editor.bulb.md
90
96
  typebulb .
91
- `)}import*as X from"fs/promises";import*as st from"path";import{pathToFileURL as Us}from"url";var ts={code:{path:"code.tsx",language:"typescript"},css:{path:"styles.css",language:"css"},html:{path:"index.html",language:"html"},config:{path:"config.json",language:"json"},notes:{path:"notes.md",language:"markdown"},data:{path:"data.txt",language:"text"},infer:{path:"infer.md",language:"markdown"},insight:{path:"insight.json",language:"json"},server:{path:"server.ts",language:"typescript"}};function mr(r){try{let e=r.split(`
92
- `),t=0;if(e[t]?.trim()!=="---")return null;t++;let n=[];for(;t<e.length&&e[t]?.trim()!=="---";)n.push(e[t]),t++;if(e[t]?.trim()!=="---")return null;t++;let s=rs(n);if(!s)return null;let o=new Map;for(;t<e.length;){let a=e[t]?.trim()?.match(/^\*\*(.+)\*\*$/);if(a){let c=a[1].trim();for(t++;t<e.length&&e[t]?.trim()==="";)t++;let l=e[t]?.match(/^(`{3,})(\w*)\s*$/);if(!l){t++;continue}let p=l[1];t++;let d=[];for(;t<e.length&&!e[t]?.match(new RegExp(`^${p}\\s*$`));)d.push(e[t]),t++;t++,o.set(c,d.join(`
93
- `))}else t++}return{frontmatter:s,files:o}}catch{return null}}function rs(r){let e={};for(let t of r){let n=t.indexOf(":");if(n===-1)continue;let s=t.slice(0,n).trim(),o=t.slice(n+1).trim();switch(s){case"format":e.format=o;break;case"name":e.name=ns(o);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function ns(r){return r.startsWith('"')&&r.endsWith('"')?r.slice(1,-1).replace(/\\"/g,'"'):r.startsWith("'")&&r.endsWith("'")?r.slice(1,-1):r}function hr(r){let e=t=>r.files.get(ts[t].path)||"";return{name:r.frontmatter.name,code:e("code"),css:e("css"),html:e("html"),config:e("config"),notes:e("notes"),data:e("data"),infer:e("infer"),insight:e("insight"),server:e("server")}}function ss(r){try{return JSON.parse(r),!0}catch{}return!!(/^\s*<[\s\S]*>/.test(r)||/^---\s*$/m.test(r)||/^\w[\w\s]*:[ \t]/m.test(r))}function gr(r){let e=r.trim();return e?ss(e)?[e]:r.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function br(r){if(!r.trim())return{};try{return JSON.parse(r)}catch{return{}}}import{transform as os}from"sucrase";function Et(r,e={}){let t=e.serverOnly?["typescript"]:["typescript","jsx"];try{let{code:n}=os(r,{transforms:t,jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:n}}catch(n){return{code:"",error:String(n)}}}var we="https://esm.sh",xe="https://cdn.jsdelivr.net/npm/",kt="https://data.jsdelivr.com/v1/package/npm/";function yr(r){let e=(r||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var y=class r{constructor(e,t,n){let s=typeof e=="string"?r.parse(e):e;this.name=s.name,this.version=ce(t??s.version),this.subpath=ce(n??s.subpath)}static parse(e){let t=yr(e||"");if(!t.length)return new r({name:""});if(t[0].startsWith("@")){let s=t[0],[o,i]=vr(t[1]??""),a=ce(t.slice(2).join("/"));return new r({name:`${s}/${o}`,version:i,subpath:a})}else{let[s,o]=vr(t[0]),i=ce(t.slice(1).join("/"));return new r({name:s,version:o,subpath:i})}}static fromUrl(e){try{let t=new URL(e),n=new URL(we).host,s=new URL(xe).host;if(t.host===n){let o=yr(t.pathname.replace(/^\/v\d+\//,"/"));if(!o.length)return;let i=o[0].startsWith("@")?`${o[0]}/${o[1]??""}`:o[0];return r.parse(i)}if(t.host===s){let o=t.pathname.split("/npm/")[1];if(!o)return;let i=o.split("/")[0]||"";return r.parse(i)}return}catch{return}}static versionFromUrl(e){return r.fromUrl(e)?.version}format(){let e=this.version?`${this.name}@${this.version}`:this.name;return this.subpath?`${e}/${this.subpath}`:e}root(){return this.name}static rootOf(e){return r.parse(e).name}withVersion(e){return new r({name:this.name,version:ce(e),subpath:this.subpath})}withPreferredVersion(e,t){let n=e||t;return n?this.withVersion(n):this}static isBare(e){if(!e||e.startsWith(".")||e.startsWith("/"))return!1;let t=e.toLowerCase();return!t.startsWith("http://")&&!t.startsWith("https://")}},ce=r=>r&&r.length?r:void 0,vr=r=>{let e=r.indexOf("@");return e<0?[r,void 0]:[r.slice(0,e),ce(r.slice(e+1))]};async function k(r){try{return await r()}catch{return}}var Se=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=we,this.jsDelivrBase=xe,this.jsDelivrMeta=kt,this.pinMs=1e4,this.versionsIndexMs=1440*60*1e3,this.metaTtlMs=10080*60*1e3,this.pinCache=new Map}normalizeRelative(e){let t=e||"";return t.startsWith("./")?t.slice(2):t.replace(/^\/+/,"")}ensureLeadingDotSlash(e){return e.startsWith("./")?e:`./${e}`}baseDir(e){let t=typeof e=="string"?new y(e):e;return`${this.jsDelivrBase}${t.name}${t.version?`@${t.version}`:""}/`}file(e,t){return new URL(this.normalizeRelative(t),this.baseDir(e)).toString()}packageJson(e){return this.file(e,"package.json")}buildEsmUrl(e,t={}){let{target:n="es2022",bundle:s=!1,external:o}=t,i=new URLSearchParams({target:n});return s&&i.append("bundle",""),o?.length&&i.append("external",o.join(",")),`${this.esmHost}/${e}?${i.toString()}`}async pinEsmUrl(e,t="es2022"){let n=this.buildEsmUrl(e,{target:t}),s=await k(()=>this.http.head(n));return s?.ok?s.url||n:void 0}async resolveExactVersion(e){let t=Date.now(),n=this.pinCache.get(e);if(n&&t-n.ts<this.pinMs)return n.value;let s=await this.tryResolveFromUrls([this.buildEsmUrl(e),`${this.esmHost}/${e}`]);return this.pinCache.set(e,{value:s,ts:t}),s}async tryResolveFromUrls(e){for(let t of e){let n=await k(()=>this.http.head(t)),s=this.parseVersionFromUrl(n?.url||t);if(s)return s}}async fetchVersionsIndex(e){if(await this.cache.isNegative(e))return;let t=await this.cache.getIndex(e);if(t&&Date.now()-t.updatedAt<this.versionsIndexMs)return{versions:t.versions,distTags:t.distTags};let n=await k(()=>this.http.getJson(`${this.jsDelivrMeta}${encodeURIComponent(e)}`));if(!n?.versions?.length){await this.cache.recordNegative(e);return}await this.cache.clearNegative(e);let s=n.distTags&&Object.keys(n.distTags).length?n.distTags:void 0;return await this.cache.setIndex(e,n.versions,s),n}parseVersionFromUrl(e){let t=y.fromUrl(e)?.version;return t&&/\d+\.\d+\.\d+/.test(t)?t:void 0}async fetchPackageMeta(e,t){let n=await this.cache.getMeta(e,t);if(n&&Date.now()-n.updatedAt<this.metaTtlMs){let{dependencies:p,peerDependencies:d,peerDependenciesMeta:m}=n;return{name:e,version:t,dependencies:p,peerDependencies:d,peerDependenciesMeta:m}}let s=this.packageJson(new y(`${e}@${t}`)),o=await k(()=>this.http.getJson(s));if(!o)return;let i=p=>p&&Object.keys(p).length?p:void 0,a=i(o.dependencies),c=i(o.peerDependencies),l=i(o.peerDependenciesMeta);return await this.cache.setMeta(e,t,a,c,l),{name:e,version:t,dependencies:a,peerDependencies:c,peerDependenciesMeta:l}}};var wr=r=>r.startsWith("@types/"),Pe=r=>Object.keys(r?.peerDependencies||{}).filter(e=>!wr(e)),Tt=r=>Object.keys(r?.dependencies||{}).filter(e=>!wr(e)),is=r=>Pe(r).filter(e=>!r?.peerDependenciesMeta?.[e]?.optional),Re=class{constructor(e){this.cdn=e}async resolve(e,t){let n=await this.fetchMeta(e),{allRoots:s,autoAddedPeers:o}=await this.expandWithPeers(n,t),i=this.computeFlags(s);return{allRoots:s,flags:i,autoAddedPeers:o}}async fetchMeta(e){return Promise.all(e.map(async({name:t,version:n})=>({name:t,version:n,meta:await this.cdn.fetchPackageMeta(t,n)})))}async expandWithPeers(e,t){let n=new Map(e.map(o=>[o.name,o])),s=[];for(let o of e)for(let i of is(o.meta))!n.has(i)&&!s.some(a=>a.name===i)&&s.push({name:i,requiredBy:o.name});for(let{name:o,requiredBy:i}of s)try{let a=await t(o),c=await this.cdn.fetchPackageMeta(o,a);n.set(o,{name:o,version:a,meta:c})}catch(a){console.warn(`[typebulb] Failed to resolve peer "${o}" for "${i}":`,a)}return{allRoots:[...n.values()],autoAddedPeers:s.filter(o=>n.has(o.name))}}computeFlags(e){let t=new Set(e.flatMap(o=>Pe(o.meta))),n=new Map;for(let o of e)for(let i of Tt(o.meta))n.set(i,(n.get(i)||0)+1);let s=new Set([...n.entries()].filter(([,o])=>o>=2).map(([o])=>o));return new Map(e.map(o=>[o.name,{isPeerRoot:t.has(o.name),hasPeers:Pe(o.meta).length>0,isSharedDep:s.has(o.name)}]))}};var Ee=class{constructor(e,t,n){this.cache=e,this.cdn=t,this.semver=n}selectVersionFromIndex(e,t,n){return this.semver.selectBestVersion(e,{range:t,distTags:n})}async learnExactVersion(e){let t=await k(()=>this.cdn.fetchVersionsIndex(e));if(t?.versions?.length){let n=this.semver.selectBestVersion(t.versions,{distTags:t.distTags});if(n)return n}return this.cdn.resolveExactVersion(e)}async resolveExactForRoot(e,t){if(!t)return this.learnExactVersion(e);let n=await this.cache.getPinnedExact(e,t);if(n){if(this.semver.isExactVersion(n))return n;console.debug("[typebulb] cached version for",e,"is not exact (",n,"); re-resolving from registry")}let s=await k(()=>this.cdn.fetchVersionsIndex(e));if(s?.versions?.length){let i=this.selectVersionFromIndex(s.versions,t,s.distTags);if(i){if(this.semver.isExactVersion(i))return await this.cache.setPinnedExact(e,t,i),i}else{console.debug("[typebulb] refreshing version cache for",e,"(",t,"not in cached set \u2014 likely a new release)"),await this.cache.invalidateVersionsCache(e);let a=await k(()=>this.cdn.fetchVersionsIndex(e));if(a?.versions?.length){let c=this.selectVersionFromIndex(a.versions,t,a.distTags);if(c&&this.semver.isExactVersion(c))return await this.cache.setPinnedExact(e,t,c),c}}}let o=await this.cdn.resolveExactVersion(`${e}@${t}`);if(o&&this.semver.isExactVersion(o))return await this.cache.setPinnedExact(e,t,o),o}async effectivePackage(e,t){let n=new y(e),s=n.root(),o=t[s],i=o?await k(()=>this.cache.getPinnedExact(s,o))??await k(()=>this.resolveExactForRoot(s,o)):void 0;return{effectivePackage:i?n.withVersion(i).format():e,root:s,range:o,pinned:i}}};import{init as as,parse as cs}from"es-module-lexer";var le=class r{constructor(e,t,n,s){this.version=e,this.cdn=t,this.peer=n,this.cache=s}extractImportsSync(e){let t=new Set;for(let n of r.importPatterns){n.lastIndex=0;for(let s of e.matchAll(n))y.isBare(s[1])&&t.add(s[1])}return Array.from(t)}async extractImports(e){let t=new Set,n=s=>{y.isBare(s)&&t.add(s)};try{await as;let[s]=cs(e);s.forEach(o=>n(e.slice(o.s,o.e).trim()))}catch{return this.extractImportsSync(e)}return Array.from(t)}async buildImportMap(e,t,n){let s=(await this.extractImports(e)).filter(d=>!n?.has(y.rootOf(d))),o=[...new Set(s.map(y.rootOf))],i=await Promise.all(o.map(async d=>({name:d,version:await this.resolveVersion(d,t)}))),{allRoots:a,flags:c,autoAddedPeers:l}=await this.peer.resolve(i,d=>this.resolveVersion(d,t)),p=this.buildEntries([...s,...l.map(d=>d.name)],a,c,t);return{importMap:{imports:Object.fromEntries(p)},prefetchUrls:p.map(([,d])=>d)}}async resolveVersion(e,t){let n=t[e],s=n?`${e}@${n}`:e,o=await this.version.resolveExactForRoot(e,n);if(!o){let i=await k(()=>this.cdn.pinEsmUrl(s));if(!i)throw new Error(`Cannot resolve ${s}: no matching version is published (the package or version may not exist, or the registry was unreachable).`);o=y.versionFromUrl(i),o&&n&&await k(()=>this.cache.setPinnedExact(e,n,o))}if(!o)throw new Error(`Cannot resolve ${s}: no concrete version found.`);return o}buildEntries(e,t,n,s){let o=new Map(t.map(g=>[g.name,g])),i=g=>{let S=o.get(y.rootOf(g));return new y(g).withPreferredVersion(S.version,s[S.name]).format()},a=new Set([...n.entries()].filter(([,g])=>g.isPeerRoot||g.isSharedDep).map(([g])=>g)),c=new Set(e.filter(g=>g!==y.rootOf(g)).map(y.rootOf)),l=[],p=new Set,d=new Set(e.filter(g=>g===y.rootOf(g))),m=new Set;for(let g of e){let S=y.rootOf(g),B=o.get(S),{isPeerRoot:N,hasPeers:_,isSharedDep:u}=n.get(S),f=c.has(S),b=g!==S,v=!(N||u)&&(f||!_),T=this.singletonDepsOf(B,a),z=b&&d.has(S);z&&m.add(S);let F=z?[...T,S]:T.length?T:void 0;l.push([g,this.cdn.buildEsmUrl(i(g),{bundle:v,external:F})]),p.add(g)}let h=new Set([...a,...m]);for(let g of h)o.has(g)&&(p.has(g)||l.push([g,this.cdn.buildEsmUrl(i(g),{})]),l.push([`${g}/`,`${this.cdn.esmHost}/${i(g)}/`]));return l}singletonDepsOf(e,t){return[...new Set([...Pe(e.meta),...Tt(e.meta)])].filter(n=>t.has(n))}};le.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as xr,satisfies as ls,maxSatisfying as _t,major as ds,prerelease as us,rsort as ps,valid as fs}from"semver";var Ve=class{cmp(e,t){return e===t?0:xr(e,t)?1:xr(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!ls(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let n=_t(e,t,{includePrerelease:!0});return n===null?void 0:n}pickLatest(e){return e?.length?ps(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let n=t?.range?.trim()||"*",s=t?.preferStable??!0,o=t?.distTags?.latest;if(o&&e.includes(o)&&this.satisfies(n,o))return o;if(s){let a=_t(e,n,{includePrerelease:!1});if(a)return a}return _t(e,n,{includePrerelease:!0})??void 0}majorOf(e){return ds(e)}isPrerelease(e){return us(e)!==null}isExactVersion(e){return fs(e)!==null}},Q=new Ve;function Sr(r,e){let t=new Se(r,e),n=new Re(t),s=new Ee(r,t,Q);return{packageService:new le(s,t,n,r),versionResolver:s,cdnClient:t,peerResolver:n}}import*as Br from"fs/promises";import*as $ from"path";var Ct=[{name:"es5"},{name:"es2015.core"},{name:"es2015.collection"},{name:"es2015.promise"},{name:"es2015.iterable"},{name:"es2015.symbol"},{name:"es2015.symbol.wellknown"},{name:"es2015.generator"},{name:"es2015.proxy"},{name:"es2015.reflect"},{name:"es2016.array.include"},{name:"es2016.intl"},{name:"es2017.object"},{name:"es2017.string"},{name:"es2017.sharedmemory"},{name:"es2017.typedarrays"},{name:"es2017.date"},{name:"es2017.intl"},{name:"es2018.asynciterable"},{name:"es2018.asyncgenerator"},{name:"es2018.promise"},{name:"es2018.regexp"},{name:"es2018.intl"},{name:"es2019.array"},{name:"es2019.object"},{name:"es2019.string"},{name:"es2019.symbol"},{name:"es2019.intl"},{name:"es2020.bigint"},{name:"es2020.promise"},{name:"es2020.string"},{name:"es2020.sharedmemory"},{name:"es2020.date"},{name:"es2020.number"},{name:"es2020.symbol.wellknown"},{name:"es2020.intl"},{name:"es2021.promise"},{name:"es2021.string"},{name:"es2021.weakref"},{name:"es2021.intl"},{name:"es2022.array"},{name:"es2022.object"},{name:"es2022.error"},{name:"es2022.string"},{name:"es2022.regexp"},{name:"es2022.intl"},{name:"es2023.array"},{name:"es2023.collection"},{name:"es2023.intl",since:"5.5"},{name:"es2024.arraybuffer",since:"5.5"},{name:"es2024.collection",since:"5.5"},{name:"es2024.object",since:"5.5"},{name:"es2024.promise",since:"5.5"},{name:"es2024.regexp",since:"5.5"},{name:"es2024.sharedmemory",since:"5.5"},{name:"es2024.string",since:"5.5"},{name:"esnext.array",since:"5.5"},{name:"esnext.collection"},{name:"esnext.decorators"},{name:"esnext.disposable"},{name:"esnext.error",since:"5.5"},{name:"esnext.float16",since:"5.5"},{name:"esnext.iterator",since:"5.5"},{name:"esnext.object"},{name:"esnext.promise"},{name:"esnext.sharedmemory",since:"5.5"},{name:"esnext.intl"}],Ot=[{name:"dom"},{name:"dom.iterable"},{name:"dom.asynciterable"}];var Pr=`
97
+ `)}zt();import*as ne from"fs/promises";import*as Pt from"path";import{pathToFileURL as Uo}from"url";import{transform as so}from"sucrase";function Gt(r,e={}){let t=e.serverOnly?["typescript"]:["typescript","jsx"];try{let{code:n}=so(r,{transforms:t,jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:n}}catch(n){return{code:"",error:String(n)}}}var $e="https://esm.sh",Oe="https://cdn.jsdelivr.net/npm/",Kt="https://data.jsdelivr.com/v1/package/npm/";function Hr(r){let e=(r||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var b=class r{constructor(e,t,n){let s=typeof e=="string"?r.parse(e):e;this.name=s.name,this.version=ge(t??s.version),this.subpath=ge(n??s.subpath)}static parse(e){let t=Hr(e||"");if(!t.length)return new r({name:""});if(t[0].startsWith("@")){let s=t[0],[o,i]=qr(t[1]??""),a=ge(t.slice(2).join("/"));return new r({name:`${s}/${o}`,version:i,subpath:a})}else{let[s,o]=qr(t[0]),i=ge(t.slice(1).join("/"));return new r({name:s,version:o,subpath:i})}}static fromUrl(e){try{let t=new URL(e),n=new URL($e).host,s=new URL(Oe).host;if(t.host===n){let o=Hr(t.pathname.replace(/^\/v\d+\//,"/"));if(!o.length)return;let i=o[0].startsWith("@")?`${o[0]}/${o[1]??""}`:o[0];return r.parse(i)}if(t.host===s){let o=t.pathname.split("/npm/")[1];if(!o)return;let i=o.split("/")[0]||"";return r.parse(i)}return}catch{return}}static versionFromUrl(e){return r.fromUrl(e)?.version}format(){let e=this.version?`${this.name}@${this.version}`:this.name;return this.subpath?`${e}/${this.subpath}`:e}root(){return this.name}static rootOf(e){return r.parse(e).name}withVersion(e){return new r({name:this.name,version:ge(e),subpath:this.subpath})}withPreferredVersion(e,t){let n=e||t;return n?this.withVersion(n):this}static isBare(e){if(!e||e.startsWith(".")||e.startsWith("/"))return!1;let t=e.toLowerCase();return!t.startsWith("http://")&&!t.startsWith("https://")}},ge=r=>r&&r.length?r:void 0,qr=r=>{let e=r.indexOf("@");return e<0?[r,void 0]:[r.slice(0,e),ge(r.slice(e+1))]};async function A(r){try{return await r()}catch{return}}var De=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=$e,this.jsDelivrBase=Oe,this.jsDelivrMeta=Kt,this.pinMs=1e4,this.versionsIndexMs=1440*60*1e3,this.metaTtlMs=10080*60*1e3,this.pinCache=new Map}normalizeRelative(e){let t=e||"";return t.startsWith("./")?t.slice(2):t.replace(/^\/+/,"")}ensureLeadingDotSlash(e){return e.startsWith("./")?e:`./${e}`}baseDir(e){let t=typeof e=="string"?new b(e):e;return`${this.jsDelivrBase}${t.name}${t.version?`@${t.version}`:""}/`}file(e,t){return new URL(this.normalizeRelative(t),this.baseDir(e)).toString()}packageJson(e){return this.file(e,"package.json")}buildEsmUrl(e,t={}){let{target:n="es2022",bundle:s=!1,external:o}=t,i=new URLSearchParams({target:n});return s&&i.append("bundle",""),o?.length&&i.append("external",o.join(",")),`${this.esmHost}/${e}?${i.toString()}`}async pinEsmUrl(e,t="es2022"){let n=this.buildEsmUrl(e,{target:t}),s=await A(()=>this.http.head(n));return s?.ok?s.url||n:void 0}async resolveExactVersion(e){let t=Date.now(),n=this.pinCache.get(e);if(n&&t-n.ts<this.pinMs)return n.value;let s=await this.tryResolveFromUrls([this.buildEsmUrl(e),`${this.esmHost}/${e}`]);return this.pinCache.set(e,{value:s,ts:t}),s}async tryResolveFromUrls(e){for(let t of e){let n=await A(()=>this.http.head(t)),s=this.parseVersionFromUrl(n?.url||t);if(s)return s}}async fetchVersionsIndex(e){if(await this.cache.isNegative(e))return;let t=await this.cache.getIndex(e);if(t&&Date.now()-t.updatedAt<this.versionsIndexMs)return{versions:t.versions,distTags:t.distTags};let n=await A(()=>this.http.getJson(`${this.jsDelivrMeta}${encodeURIComponent(e)}`));if(!n?.versions?.length){await this.cache.recordNegative(e);return}await this.cache.clearNegative(e);let s=n.distTags&&Object.keys(n.distTags).length?n.distTags:void 0;return await this.cache.setIndex(e,n.versions,s),n}parseVersionFromUrl(e){let t=b.fromUrl(e)?.version;return t&&/\d+\.\d+\.\d+/.test(t)?t:void 0}async fetchPackageMeta(e,t){let n=await this.cache.getMeta(e,t);if(n&&Date.now()-n.updatedAt<this.metaTtlMs){let{dependencies:d,peerDependencies:u,peerDependenciesMeta:f}=n;return{name:e,version:t,dependencies:d,peerDependencies:u,peerDependenciesMeta:f}}let s=this.packageJson(new b(`${e}@${t}`)),o=await A(()=>this.http.getJson(s));if(!o)return;let i=d=>d&&Object.keys(d).length?d:void 0,a=i(o.dependencies),c=i(o.peerDependencies),l=i(o.peerDependenciesMeta);return await this.cache.setMeta(e,t,a,c,l),{name:e,version:t,dependencies:a,peerDependencies:c,peerDependenciesMeta:l}}};var zr=r=>r.startsWith("@types/"),Fe=r=>Object.keys(r?.peerDependencies||{}).filter(e=>!zr(e)),Yt=r=>Object.keys(r?.dependencies||{}).filter(e=>!zr(e)),oo=r=>Fe(r).filter(e=>!r?.peerDependenciesMeta?.[e]?.optional),Be=class{constructor(e){this.cdn=e}async resolve(e,t){let n=await this.fetchMeta(e),{allRoots:s,autoAddedPeers:o}=await this.expandWithPeers(n,t),i=this.computeFlags(s);return{allRoots:s,flags:i,autoAddedPeers:o}}async fetchMeta(e){return Promise.all(e.map(async({name:t,version:n})=>({name:t,version:n,meta:await this.cdn.fetchPackageMeta(t,n)})))}async expandWithPeers(e,t){let n=new Map(e.map(o=>[o.name,o])),s=[];for(let o of e)for(let i of oo(o.meta))!n.has(i)&&!s.some(a=>a.name===i)&&s.push({name:i,requiredBy:o.name});for(let{name:o,requiredBy:i}of s)try{let a=await t(o),c=await this.cdn.fetchPackageMeta(o,a);n.set(o,{name:o,version:a,meta:c})}catch(a){console.warn(`[typebulb] Failed to resolve peer "${o}" for "${i}":`,a)}return{allRoots:[...n.values()],autoAddedPeers:s.filter(o=>n.has(o.name))}}computeFlags(e){let t=new Set(e.flatMap(o=>Fe(o.meta))),n=new Map;for(let o of e)for(let i of Yt(o.meta))n.set(i,(n.get(i)||0)+1);let s=new Set([...n.entries()].filter(([,o])=>o>=2).map(([o])=>o));return new Map(e.map(o=>[o.name,{isPeerRoot:t.has(o.name),hasPeers:Fe(o.meta).length>0,isSharedDep:s.has(o.name)}]))}};var Me=class{constructor(e,t,n){this.cache=e,this.cdn=t,this.semver=n}selectVersionFromIndex(e,t,n){return this.semver.selectBestVersion(e,{range:t,distTags:n})}async learnExactVersion(e){let t=await A(()=>this.cdn.fetchVersionsIndex(e));if(t?.versions?.length){let n=this.semver.selectBestVersion(t.versions,{distTags:t.distTags});if(n)return n}return this.cdn.resolveExactVersion(e)}async resolveExactForRoot(e,t){if(!t)return this.learnExactVersion(e);let n=await this.cache.getPinnedExact(e,t);if(n){if(this.semver.isExactVersion(n))return n;console.debug("[typebulb] cached version for",e,"is not exact (",n,"); re-resolving from registry")}let s=await A(()=>this.cdn.fetchVersionsIndex(e));if(s?.versions?.length){let i=this.selectVersionFromIndex(s.versions,t,s.distTags);if(i){if(this.semver.isExactVersion(i))return await this.cache.setPinnedExact(e,t,i),i}else{console.debug("[typebulb] refreshing version cache for",e,"(",t,"not in cached set \u2014 likely a new release)"),await this.cache.invalidateVersionsCache(e);let a=await A(()=>this.cdn.fetchVersionsIndex(e));if(a?.versions?.length){let c=this.selectVersionFromIndex(a.versions,t,a.distTags);if(c&&this.semver.isExactVersion(c))return await this.cache.setPinnedExact(e,t,c),c}}}let o=await this.cdn.resolveExactVersion(`${e}@${t}`);if(o&&this.semver.isExactVersion(o))return await this.cache.setPinnedExact(e,t,o),o}async effectivePackage(e,t){let n=new b(e),s=n.root(),o=t[s],i=o?await A(()=>this.cache.getPinnedExact(s,o))??await A(()=>this.resolveExactForRoot(s,o)):void 0;return{effectivePackage:i?n.withVersion(i).format():e,root:s,range:o,pinned:i}}};import{init as io,parse as ao}from"es-module-lexer";var ye=class r{constructor(e,t,n,s){this.version=e,this.cdn=t,this.peer=n,this.cache=s}extractImportsSync(e){let t=new Set;for(let n of r.importPatterns){n.lastIndex=0;for(let s of e.matchAll(n))b.isBare(s[1])&&t.add(s[1])}return Array.from(t)}async extractImports(e){let t=new Set,n=s=>{b.isBare(s)&&t.add(s)};try{await io;let[s]=ao(e);s.forEach(o=>n(e.slice(o.s,o.e).trim()))}catch{return this.extractImportsSync(e)}return Array.from(t)}async buildImportMap(e,t,n){let s=(await this.extractImports(e)).filter(u=>!n?.has(b.rootOf(u))),o=[...new Set(s.map(b.rootOf))],i=await Promise.all(o.map(async u=>({name:u,version:await this.resolveVersion(u,t)}))),{allRoots:a,flags:c,autoAddedPeers:l}=await this.peer.resolve(i,u=>this.resolveVersion(u,t)),d=this.buildEntries([...s,...l.map(u=>u.name)],a,c,t);return{importMap:{imports:Object.fromEntries(d)},prefetchUrls:d.map(([,u])=>u)}}async resolveVersion(e,t){let n=t[e],s=n?`${e}@${n}`:e,o=await this.version.resolveExactForRoot(e,n);if(!o){let i=await A(()=>this.cdn.pinEsmUrl(s));if(!i)throw new Error(`Cannot resolve ${s}: no matching version is published (the package or version may not exist, or the registry was unreachable).`);o=b.versionFromUrl(i),o&&n&&await A(()=>this.cache.setPinnedExact(e,n,o))}if(!o)throw new Error(`Cannot resolve ${s}: no concrete version found.`);return o}buildEntries(e,t,n,s){let o=new Map(t.map(g=>[g.name,g])),i=g=>{let x=o.get(b.rootOf(g));return new b(g).withPreferredVersion(x.version,s[x.name]).format()},a=new Set([...n.entries()].filter(([,g])=>g.isPeerRoot||g.isSharedDep).map(([g])=>g)),c=new Set(e.filter(g=>g!==b.rootOf(g)).map(b.rootOf)),l=[],d=new Set,u=new Set(e.filter(g=>g===b.rootOf(g))),f=new Set;for(let g of e){let x=b.rootOf(g),$=o.get(x),{isPeerRoot:O,hasPeers:E,isSharedDep:R}=n.get(x),p=c.has(x),m=g!==x,v=!(O||R)&&(p||!E),w=this.singletonDepsOf($,a),T=m&&u.has(x);T&&f.add(x);let z=T?[...w,x]:w.length?w:void 0;l.push([g,this.cdn.buildEsmUrl(i(g),{bundle:v,external:z})]),d.add(g)}let h=new Set([...a,...f]);for(let g of h)o.has(g)&&(d.has(g)||l.push([g,this.cdn.buildEsmUrl(i(g),{})]),l.push([`${g}/`,`${this.cdn.esmHost}/${i(g)}/`]));return l}singletonDepsOf(e,t){return[...new Set([...Fe(e.meta),...Yt(e.meta)])].filter(n=>t.has(n))}};ye.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as Gr,satisfies as co,maxSatisfying as Xt,major as lo,prerelease as uo,rsort as po,valid as fo}from"semver";var lt=class{cmp(e,t){return e===t?0:Gr(e,t)?1:Gr(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!co(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let n=Xt(e,t,{includePrerelease:!0});return n===null?void 0:n}pickLatest(e){return e?.length?po(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let n=t?.range?.trim()||"*",s=t?.preferStable??!0,o=t?.distTags?.latest;if(o&&e.includes(o)&&this.satisfies(n,o))return o;if(s){let a=Xt(e,n,{includePrerelease:!1});if(a)return a}return Xt(e,n,{includePrerelease:!0})??void 0}majorOf(e){return lo(e)}isPrerelease(e){return uo(e)!==null}isExactVersion(e){return fo(e)!==null}},ie=new lt;function Kr(r,e){let t=new De(r,e),n=new Be(t),s=new Me(r,t,ie);return{packageService:new ye(s,t,n,r),versionResolver:s,cdnClient:t,peerResolver:n}}import*as un from"fs/promises";import*as U from"path";var Qt=[{name:"es5"},{name:"es2015.core"},{name:"es2015.collection"},{name:"es2015.promise"},{name:"es2015.iterable"},{name:"es2015.symbol"},{name:"es2015.symbol.wellknown"},{name:"es2015.generator"},{name:"es2015.proxy"},{name:"es2015.reflect"},{name:"es2016.array.include"},{name:"es2016.intl"},{name:"es2017.object"},{name:"es2017.string"},{name:"es2017.sharedmemory"},{name:"es2017.typedarrays"},{name:"es2017.date"},{name:"es2017.intl"},{name:"es2018.asynciterable"},{name:"es2018.asyncgenerator"},{name:"es2018.promise"},{name:"es2018.regexp"},{name:"es2018.intl"},{name:"es2019.array"},{name:"es2019.object"},{name:"es2019.string"},{name:"es2019.symbol"},{name:"es2019.intl"},{name:"es2020.bigint"},{name:"es2020.promise"},{name:"es2020.string"},{name:"es2020.sharedmemory"},{name:"es2020.date"},{name:"es2020.number"},{name:"es2020.symbol.wellknown"},{name:"es2020.intl"},{name:"es2021.promise"},{name:"es2021.string"},{name:"es2021.weakref"},{name:"es2021.intl"},{name:"es2022.array"},{name:"es2022.object"},{name:"es2022.error"},{name:"es2022.string"},{name:"es2022.regexp"},{name:"es2022.intl"},{name:"es2023.array"},{name:"es2023.collection"},{name:"es2023.intl",since:"5.5"},{name:"es2024.arraybuffer",since:"5.5"},{name:"es2024.collection",since:"5.5"},{name:"es2024.object",since:"5.5"},{name:"es2024.promise",since:"5.5"},{name:"es2024.regexp",since:"5.5"},{name:"es2024.sharedmemory",since:"5.5"},{name:"es2024.string",since:"5.5"},{name:"esnext.array",since:"5.5"},{name:"esnext.collection"},{name:"esnext.decorators"},{name:"esnext.disposable"},{name:"esnext.error",since:"5.5"},{name:"esnext.float16",since:"5.5"},{name:"esnext.iterator",since:"5.5"},{name:"esnext.object"},{name:"esnext.promise"},{name:"esnext.sharedmemory",since:"5.5"},{name:"esnext.intl"}],Zt=[{name:"dom"},{name:"dom.iterable"},{name:"dom.asynciterable"}];var Yr=`
94
98
  /**
95
99
  * Get raw data chunk from the Data tab.
96
100
  * @param index - Chunk index (0-based). Separate chunks with 2 blank lines.
@@ -101,7 +105,7 @@ Examples:
101
105
  * @param index - Chunk index (0-based)
102
106
  * @throws If chunk is not valid JSON/JSON-ish
103
107
  */
104
- json<T = unknown>(index: number): T;`,Rr=`
108
+ json<T = unknown>(index: number): T;`,Xr=`
105
109
  /**
106
110
  * Get the insight data produced by the inference layer.
107
111
  *
@@ -110,7 +114,7 @@ Examples:
110
114
  *
111
115
  * @returns The parsed insight JSON, or undefined if no insight is available
112
116
  */
113
- insight<T = unknown>(): T | undefined;`,Er=`
117
+ insight<T = unknown>(): T | undefined;`,Qr=`
114
118
  /**
115
119
  * General-purpose AI call.
116
120
  *
@@ -127,7 +131,7 @@ Examples:
127
131
  model?: string;
128
132
  /** Enable/disable web search. Default: on for BYOK, always off for free model. */
129
133
  webSearch?: boolean;
130
- }): Promise<{ text: string }>;`,kr=`
134
+ }): Promise<{ text: string }>;`,Zr=`
131
135
  /**
132
136
  * Returns AI models available to the current user.
133
137
  * Models are filtered by the user's configured API keys.
@@ -142,7 +146,7 @@ Examples:
142
146
  friendlyName: string;
143
147
  /** Provider display name, e.g. "Anthropic" */
144
148
  providerName: string;
145
- }>>;`,ms="\n /**\n * The bulb's theme override (`<html data-theme>`).\n *\n * - Get: the current override \u2014 `'dark'` | `'light'`, or `undefined` when\n * following the OS preference.\n * - Set `'dark'`/`'light'` to force and persist it (per-bulb); set\n * `undefined` to clear the override and follow the OS again.\n *\n * Drives `<html data-theme>`, so render off `html[data-theme=\"\u2026\"]` selectors\n * (or observe the attribute) rather than reading `tb.theme`.\n */\n theme: 'light' | 'dark' | undefined;",Tr=`
149
+ }>>;`,mo="\n /**\n * The bulb's theme override (`<html data-theme>`).\n *\n * - Get: the current override \u2014 `'dark'` | `'light'`, or `undefined` when\n * following the OS preference.\n * - Set `'dark'`/`'light'` to force and persist it (per-bulb); set\n * `undefined` to clear the override and follow the OS again.\n *\n * Drives `<html data-theme>`, so render off `html[data-theme=\"\u2026\"]` selectors\n * (or observe the attribute) rather than reading `tb.theme`.\n */\n theme: 'light' | 'dark' | undefined;",en=`
146
150
  /**
147
151
  * The mode this bulb is running in.
148
152
  *
@@ -152,7 +156,7 @@ Examples:
152
156
  * - \`'embedded'\` \u2014 Running as a bulb embedded inside another bulb (sandboxed,
153
157
  * client-only: AI, filesystem, and server RPC are unavailable)
154
158
  */
155
- mode: 'local' | 'editor' | 'published' | 'embedded';`,_r=`
159
+ mode: 'local' | 'editor' | 'published' | 'embedded';`,tn=`
156
160
  /**
157
161
  * Local filesystem access (CLI only).
158
162
  *
@@ -166,7 +170,7 @@ Examples:
166
170
  readBytes(path: string): Promise<Uint8Array>;
167
171
  /** Write text or raw bytes to a file. Creates parent directories if needed. */
168
172
  write(path: string, content: string | Uint8Array): Promise<boolean>;
169
- };`,hs=`
173
+ };`,ho=`
170
174
  /**
171
175
  * Server-side function proxy. The built-in \`log\` prints to CLI stdout
172
176
  * (falls back to console.log on web). On the server side, this object only
@@ -174,7 +178,7 @@ Examples:
174
178
  */
175
179
  server: {
176
180
  log(...args: any[]): Promise<void>;
177
- };`,gs=`
181
+ };`,go=`
178
182
  /**
179
183
  * Async value inspector for tensor-like objects.
180
184
  *
@@ -241,7 +245,7 @@ Examples:
241
245
  *
242
246
  * @returns The full canonical URL
243
247
  */
244
- url(): Promise<string>;`,bs=`
248
+ url(): Promise<string>;`,yo=`
245
249
  /**
246
250
  * Server-side function proxy.
247
251
  *
@@ -249,23 +253,23 @@ Examples:
249
253
  * \`tb.server.log(...)\` is a built-in that prints to CLI stdout (falls back to console.log on web).
250
254
  * User exports override built-ins of the same name.
251
255
  */
252
- server: Record<string, (...args: any[]) => Promise<any>>;`,At=`
256
+ server: Record<string, (...args: any[]) => Promise<any>>;`,er=`
253
257
  /**
254
258
  * Typebulb utilities namespace.
255
259
  * Type \`tb.\` to discover available helpers.
256
260
  */
257
- declare const tb: {${Pr}${gs}${Rr}${bs}${Er}${_r}${kr}${ms}${Tr}
261
+ declare const tb: {${Yr}${go}${Xr}${yo}${Qr}${tn}${Zr}${mo}${en}
258
262
  };
259
- `,It=`
263
+ `,tr=`
260
264
  /**
261
265
  * Typebulb utilities namespace (server-side).
262
266
  * Type \`tb.\` to discover available helpers.
263
267
  */
264
- declare const tb: {${Pr}${Rr}${Er}${_r}${hs}${kr}${Tr}
268
+ declare const tb: {${Yr}${Xr}${Qr}${tn}${ho}${Zr}${en}
265
269
  };
266
- `;var Z=class{constructor(e){this.store=e}async isNegative(e){let t=await He(()=>this.store.get(e));return!!t&&t.until>Date.now()}async recordNegative(e){let n=((await He(()=>this.store.get(e)))?.attempts||0)+1;await He(()=>this.store.set(e,{until:Date.now()+ys(n),attempts:n}))}async clearNegative(e){await He(()=>this.store.delete(e))}};function ys(r){return Math.min(9e5*Math.pow(2,Math.max(0,r-1)),864e5)}async function He(r){try{return await r()}catch{return}}import Rs from"p-limit";import{resolve as Cr}from"resolve.exports";var de=class{constructor(e){this.fetchDts=e}fetchDtsText(e){return this.tryUrls([e])}async tryUrls(e){for(let t of e){let n=await this.fetchDts(t);if(n&&(this.looksLikeDts(n.dts)||/\.(d\.ts|d\.mts)(?:[?#].*)?$/i.test(n.url)||/[?&]dts(?:[&#]|$)/i.test(n.url)))return n}}looksLikeDts(e){return/^\s*export\s*\{\s*\}\s*;?\s*$/m.test(e)?!0:/declare\s+(module|namespace|class|interface|function|const|var|let)/.test(e)||/interface\s+\w+/.test(e)||/type\s+\w+\s*=/.test(e)}};var G={maxRelativeTypeRefs:500,maxBareDeps:8,maxBareDepth:3,prefetchConcurrency:4,negativeTtlMs:1e4},ke=["index.d.ts","index.d.mts"],Te=/\.d\.(ts|mts)$/i;function $t(r){if(Te.test(r))return!0;try{return new URL(r,"file://").search.includes("dts")}catch{return r.includes("?")&&r.includes("dts")}}function qe(r){return[`${r}.d.ts`,`${r}.d.mts`]}async function _e(r,{retries:e=2,timeoutMs:t=15e3,init:n}={}){for(let s=0;s<=e;s++){let o=new AbortController,i=setTimeout(()=>o.abort(),t);try{let a=await fetch(r,{...n,signal:o.signal});if(vs(a.status)&&s<e)continue;return a}catch{if(s<e)continue;return}finally{clearTimeout(i)}}}function vs(r){return r===408||r===429||r>=500&&r<600}var Ce=class extends de{constructor(e,t){super(e),this.cdnClient=t}async loadPackageAtVersionedRoot(e,t){let n=this.cdnClient.packageJson(new y({name:e,version:t})),s=await _e(n);if(!s?.ok)return;let o;try{o=await s.json()}catch{return}if(o)return{pkg:o,baseDir:this.cdnClient.baseDir(new y({name:e,version:t??o.version})),version:t}}extractPathFromResult(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.find(t=>typeof t=="string")}async tryUntilSuccess(e,t){for(let n of e){let s=await t(n);if(s)return s}}async resolveFromSelected(e,t){if(e.kind==="types"){let s=this.cdnClient.normalizeRelative(e.path);if(!s||s==="/"||s===".")return this.tryUntilSuccess([...ke],t);if(!Te.test(s)){let o=await this.tryUntilSuccess(this.declarationCandidatesFor(s),t);if(o)return o}return t(s)}let n=this.declarationCandidatesFor(e.path);return this.tryUntilSuccess([...ke,...n],t)}toResolutionResult(e){return{kind:Te.test(e)?"types":"probe",path:e}}resolveExportsPath(e,t){let n=t||".",s=e;try{let o=this.extractPathFromResult(Cr(s,n,{conditions:["types"]}));if(o)return o}catch{}try{return this.extractPathFromResult(Cr(s,n,{browser:!0,conditions:["import","default","module","browser","node"]}))}catch{return}}async resolve(e){try{let t=y.parse(e),{pkg:n,baseDir:s}=await this.loadPackageAtVersionedRoot(t.name,t.version)||{};if(!n||!s)return;let o={name:t.name,version:t.version},i=new y(o).format(),a=new y({...o,subpath:t.subpath}).format(),c=d=>this.fetchCandidateFrom(s,t.name,d);if(t.subpath){let d=this.cdnClient.ensureLeadingDotSlash(t.subpath),m=this.resolveExportsPath(n,d);if(m){let g=await this.resolveFromSelected(this.toResolutionResult(m),c);if(g)return{...g,resolvedPkg:a}}let h=await this.tryUntilSuccess(this.declarationCandidatesFor(d),c);if(h)return{...h,resolvedPkg:a}}let l=n.types??n.typings;if(l){let d=await this.resolveFromSelected({kind:"types",path:l},c);if(d)return{...d,resolvedPkg:i}}let p=this.resolveExportsPath(n,".");if(p){let d=await this.resolveFromSelected(this.toResolutionResult(p),c);if(d)return{...d,resolvedPkg:i}}return}catch{return}}async fetchCandidateFrom(e,t,n){let s=this.cdnClient.normalizeRelative(n),o=new URL(s,e).toString(),i=await this.fetchDtsText(o);return i?{dts:i.dts,url:i.url,resolvedPkg:t}:void 0}declarationCandidatesFor(e){if(!e||e==="./"||e==="/")return[...ke];let t=e.replace(/\.(mjs|cjs|js|mts|cts|ts)$/i,""),n=qe(t),s=t.endsWith("/")?t:`${t}/`;return n.push(...qe(`${s}index`)),n}};import{gunzipSync as ws}from"fflate";var ue=class{async fetchAndExtract(e,t){let n=this.getTarballUrl(e,t),s=await _e(n,{timeoutMs:3e4});if(!s?.ok)return new Map;let o=new Uint8Array(await s.arrayBuffer());return this.extractDtsFiles(o)}getTarballUrl(e,t){return`https://registry.npmjs.org/${e.replace("/","%2F")}/-/${e.split("/").pop()}-${t}.tgz`}normalizeTarPath(e){let t=e.replace(/^package\//,""),n=t.indexOf("/");return n>0?t.substring(n+1):t}extractDtsFiles(e){let t=new Map;try{let n=ws(e),s=new TextDecoder("utf-8"),o=0;for(;o<n.length-512;){let i=n.slice(o,o+512);if(i[0]===0)break;let a=i.slice(0,100),c=a.indexOf(0),l=s.decode(a.slice(0,c>0?c:100)).trim(),p=i.slice(124,136),d=s.decode(p).trim().replace(/\0/g,""),m=parseInt(d,8)||0,h=String.fromCharCode(i[156]);if(o+=512,(h==="0"||h==="\0")&&(l.endsWith(".d.ts")||l.endsWith(".d.mts"))){let g=n.slice(o,o+m);t.set(this.normalizeTarPath(l),s.decode(g))}o+=Math.ceil(m/512)*512}}catch{}return t}},xs=new ue;var Oe=class extends de{constructor(e,t,n,s=new ue){super(e),this.cdnClient=t,this.cache=n,this.tarballFetcher=s}typesNameCandidates(e){let t=e.startsWith("@")?e.slice(1).replace("/","__"):e;return t.includes(".")?[t,t.split(".").join("-"),t.split(".").join("")]:[t]}selectTypesVersion(e,t,n){try{if(n){let o=Q.majorOf(n),i=e.filter(a=>Q.majorOf(a)===o);if(i.length)return i.sort((a,c)=>Q.cmp(c,a))[0]}let s=t?.latest;return s&&e.includes(s)?s:e[0]}catch{return e[0]}}async fetchFromVersionedRoot(e,t){let n=new y(e),s=n.version;if(!s)return;let o;try{o=await this.tarballFetcher.fetchAndExtract(n.name,s)}catch{return}if(!o||o.size===0)return;for(let[a,c]of o.entries()){let l=this.cdnClient.file(e,a);try{await this.cache.setCachedFile(l,c)}catch{}}let i=t.subpath?[t.subpath+".d.ts",t.subpath+"/index.d.ts"]:["index.d.ts"];for(let a of i){let c=o.get(a);if(c)return{dts:c,url:this.cdnClient.file(e,a),resolvedPkg:t.subpath?new y(t).format():t.name}}}async resolve(e){let t=y.parse(e);if(t.name)for(let n of this.typesNameCandidates(t.name)){let s=`@types/${n}`,o;try{o=await this.cdnClient.fetchVersionsIndex(s)}catch{continue}if(!o?.versions?.length)continue;let i=this.selectTypesVersion(o.versions,o.distTags,t.version),a=await this.fetchFromVersionedRoot(`${s}@${i}`,t);if(a)return a}}};var Ae=class{collectRelativeTypeRefs(e){return this.collectRefs(e).filter(t=>t.startsWith("./")||t.startsWith("../"))}collectBareModuleRefs(e){return this.collectRefs(e).filter(t=>this.isBare(t))}collectRefs(e){let t=new Set,n=(s,o)=>(t.add(s[o]),null);return this.matchAll(e,/(import|export)\s+[^'"\n]*from\s*['"]([^'"\n]+)['"]/,s=>n(s,2)),this.matchAll(e,/export\s*\*\s*from\s*['"]([^'"\n]+)['"]/,s=>n(s,1)),Array.from(t)}matchAll(e,t,n){let s=[];try{let o=new RegExp(t.source,"g"),i;for(;i=o.exec(e);){let a=n(i);a!==null&&s.push(a)}}catch{}return s}isBare(e){return!(e.startsWith("./")||e.startsWith("../")||e.startsWith("file:")||e.startsWith("http://")||e.startsWith("https://"))}};var Or="file:///node_modules",Ie=class{constructor(){this.epoch=0,this.listeners=new Set}getEpoch(){return this.epoch}bumpEpoch(){this.epoch+=1;for(let e of this.listeners)try{e(this.epoch)}catch{}return this.epoch}onEpochChange(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}epochDir(){return`__tsepoch_${this.epoch}`}pathForMain(e){return`${Or}/${this.epochDir()}/${e}/index.d.ts`}pathFor(e,t){let n=Ss(t);return`${Or}/${this.epochDir()}/${e}/${n}`}};function Ss(r){let e=r||"";return e.startsWith("./")?e.slice(2):e.replace(/^\/+/,"")}import{LRUCache as Ps}from"lru-cache";function Dt(r){let e=new Ps({ttl:1e4,max:500}),t=new Map;return async function(s){try{if(await r.isNegative(s))return;let o=e.get(s);if(o&&Date.now()-o<1e4)return;let i=await r.getCachedFile(s);if(i)return{dts:i,url:s};let a=t.get(s);if(a)return a;let c=(async()=>{let l=await fetch(s,{cache:"no-store"});if(!l.ok){l.status===404&&(e.set(s,Date.now()),await r.recordNegative(s));return}let p=await l.text(),d=l.url||s;return await r.clearNegative(s),await r.setCachedFile(d,p),{dts:p,url:d}})();return t.set(s,c),await c.finally(()=>t.delete(s))}catch{return}}}var ze=class{constructor(e){this.inFlight=new Map,this.scanner=new Ae,this.cache=e.cache,this.cdnClient=e.cdnClient,this.versionResolver=e.versionResolver,this.packageService=e.packageService,this.fetchDts=Dt(e.cache),this.typescriptProvider=new Ce(this.fetchDts,e.cdnClient),this.definitelyTypedProvider=new Oe(this.fetchDts,e.cdnClient,e.cache),this.virtualFs=new Ie}withInFlight(e,t){let n=this.inFlight.get(e);if(n)return n;let s=t().finally(()=>this.inFlight.delete(e));return this.inFlight.set(e,s),s}invalidate(){this.virtualFs.bumpEpoch(),this.inFlight.clear()}capArray(e,t){return e.length<=t?e:e.slice(0,t)}pushFileIfNew(e,t,n){e.some(s=>s.path===t)||e.push({path:t,content:n})}createStubDef(e){let t=this.virtualFs.pathForMain(e);return{pkg:e,mainPath:t,files:[{path:t,content:"export const _shim: any; export default _shim;"}],shims:[{module:e,path:t}]}}async trySubpathWithRootFallback(e,t){let n=new y(e);return n.subpath?this.fetchRootDts(n.name,t):void 0}async fetchViaProviders(e){for(let t of[this.typescriptProvider,this.definitelyTypedProvider])try{let n=await t.resolve(e);if(n?.dts)return n}catch{}}subpathsMatch(e,t){return new y(e).subpath===new y(t).subpath}async fetchRootDts(e,t){let{effectivePackage:n,root:s,pinned:o}=await this.versionResolver.effectivePackage(e,t),i=await this.cache.getCachedDts(n);if(i?.content){let c=i.url??this.cdnClient.file(o?`${s}@${o}`:s,"index.d.ts");return{dts:i.content,url:c,resolvedPkg:n}}let a;try{a=await this.fetchViaProviders(n)}catch{return}if(!(!a?.dts||!a.url)){try{await this.cache.setCachedFile(a.url,a.dts)}catch{}if(this.subpathsMatch(n,a.resolvedPkg||n)){try{await this.cache.setCachedDts(n,a.dts,a.url)}catch{}return a}}}extractPackageRootUrl(e){let t=e.pathname.match(/^(.+@[^/]+\/)/);return t?new URL(t[1],e.origin):new URL("./",e)}toVirtualPath(e,t,n){let s=t.pathname.startsWith(e.pathname)?t.pathname.slice(e.pathname.length):`__deps__/${encodeURIComponent(t.toString()).replace(/%/g,"_")}.d.ts`;return this.virtualFs.pathFor(n,s)}computeEntryPath(e,t){if(!e)return{mainPath:this.virtualFs.pathForMain(t),packageRootUrl:void 0};let n=new URL(e),s=this.extractPackageRootUrl(n);return{mainPath:this.toVirtualPath(s,n,t),packageRootUrl:s}}async expandRelativeRefs(e,t,n,s,o=new Set,i){if(!o.has(t)&&(o.add(t),!(o.size>G.maxRelativeTypeRefs)))try{let a=new URL(t),c=new URL("./",a);i??(i=this.extractPackageRootUrl(a));let l=this.capArray(this.scanner.collectRelativeTypeRefs(e),G.maxRelativeTypeRefs);for(let p of l)await this.tryRelativeRef(p,c,i,n,s,o)}catch{}}async tryRelativeRef(e,t,n,s,o,i){try{let a=new URL(e,t),c=a.pathname+a.search,l=$t(c)?[c]:this.typescriptProvider.declarationCandidatesFor(c);for(let p of l){let m=new URL(p,a).toString();if(i.has(m))return;let h=await this.fetchDts(m);if(h?.dts){let g=this.toVirtualPath(n,new URL(h.url),s);this.pushFileIfNew(o,g,h.dts),await this.expandRelativeRefs(h.dts,h.url,s,o,i,n);return}}}catch{}}isDifferentPackage(e,t){return e===t?!1:new y(e).name!==new y(t).name}ambientlyDeclares(e,t){for(let n of e.matchAll(/declare\s+module\s+['"]([^'"]+)['"]/g)){let s=n[1];if(s===t||s.endsWith("/*")&&t.startsWith(s.slice(0,-1)))return!0}return!1}markFileAmbient(e,t){let n=e.find(s=>s.path===t);n&&(n.ambient=!0)}async prefetchBareDeps(e,t,n,s,o){try{let i=this.capArray(this.scanner.collectBareModuleRefs(e),G.maxBareDeps).filter(l=>this.isDifferentPackage(l,t));if(!i.length)return;let a=new Set([t]),c=Rs(G.prefetchConcurrency);await Promise.all(i.map(l=>c(()=>this.prefetchBareDepsRecursive(l,n,s,G.maxBareDepth,a,o).catch(()=>{}))))}catch{}}async prefetchBareDepsRecursive(e,t,n,s,o,i){if(s<=0||o.has(e))return;o.add(e);let a=await this.fetchRootDts(e,i);if(!a?.dts)return;let c=a.resolvedPkg||e,l=this.virtualFs.pathForMain(c);this.pushFileIfNew(t,l,a.dts),this.ambientlyDeclares(a.dts,e)?this.markFileAmbient(t,l):n.push({module:e,path:l}),a.url&&await this.expandRelativeRefs(a.dts,a.url,c,t);let p=this.capArray(this.scanner.collectBareModuleRefs(a.dts),G.maxBareDeps).filter(d=>!o.has(d));for(let d of p)await this.prefetchBareDepsRecursive(d,t,n,s-1,o,i)}async resolve(e,t,n){let s=await this.packageService.extractImports(e),o=n?[...s,...n]:s;return(await Promise.all(o.map(a=>this.resolveOne(a,t)))).filter(a=>!!a)}async resolveOne(e,t){let{effectivePackage:n}=await this.versionResolver.effectivePackage(e,t);return this.withInFlight(n,async()=>{let s=await this.fetchRootDts(e,t)??await this.trySubpathWithRootFallback(e,t);return s?this.buildDefFromContent(e,s,s.resolvedPkg||e,t):this.createStubDef(e)})}async buildDefFromContent(e,t,n,s){let{dts:o,url:i,resolvedPkg:a}=t,c=new y(a||n),l=c.version?`${c.name}@${c.version}`:c.name,{mainPath:p,packageRootUrl:d}=this.computeEntryPath(i,l),m=[{path:p,content:o}],h=[];i&&await this.expandRelativeRefs(o,i,l,m,void 0,d);let g=m.map(_=>_.content).join(`
267
- `);await this.prefetchBareDeps(g,l,m,h,s);let S=c.format(),B=e===S?[e]:[e,S],N=B.some(_=>this.ambientlyDeclares(o,_));return N?this.markFileAmbient(m,p):h.push(...B.map(_=>({module:_,path:p}))),{pkg:e,mainPath:p,files:m,shims:h,ambient:N}}};function Mt(r){return new ze(r)}import*as L from"fs/promises";import*as U from"path";import*as $r from"os";import*as jt from"fs/promises";import*as Ar from"crypto";function I(r){return Ar.createHash("sha1").update(r).digest("hex")}async function ee(r){try{return JSON.parse(await jt.readFile(r,"utf8"))}catch{return}}async function Ge(r){try{return await jt.readFile(r,"utf8")}catch{return}}var Ir=1,K=U.join($r.homedir(),".typebulb","cache"),$e=U.join(K,"packages"),De=U.join(K,"proxy"),Ke=U.join(K,"dts"),Es=U.join(K,"emit"),Bt;function x(){return Bt||(Bt=ks()),Bt}function Ye(r,e){return U.join(Es,I(r),e)}async function ks(){await L.mkdir(K,{recursive:!0});let r=U.join(K,"version.json");if((await Ts(r))?.version===Ir)return;let t=await L.readdir(K).catch(()=>[]);await Promise.all(t.map(n=>L.rm(U.join(K,n),{recursive:!0,force:!0}))),await L.writeFile(r,JSON.stringify({version:Ir})+`
268
- `,"utf8")}async function Ts(r){try{let e=await L.readFile(r,"utf8");return JSON.parse(e)}catch{return}}import*as Y from"fs/promises";import*as Dr from"path";async function C(r,e){await Y.mkdir(Dr.dirname(r),{recursive:!0});let t=`${r}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await Y.writeFile(t,e,"utf8"),await Y.rename(t,r).catch(async n=>{throw await Y.rm(t,{force:!0}).catch(()=>{}),n})}var pe=class{constructor(e){this.filePath=e}mem;loadPromise;load(){return this.mem?Promise.resolve(this.mem):(this.loadPromise||(this.loadPromise=ee(this.filePath).then(e=>(this.mem=new Map(Object.entries(e??{})),this.mem))),this.loadPromise)}async get(e){return(await this.load()).get(e)}async set(e,t){let n=await this.load();n.set(e,t),await this.persist(n)}async delete(e){let t=await this.load();t.delete(e)&&await this.persist(t)}async persist(e){await C(this.filePath,JSON.stringify(Object.fromEntries(e)))}};var Ft=$.join($e,"indexes"),Mr=$.join($e,"pinned"),_s=$.join($e,"meta"),Cs=$.join($e,"negative.json"),fe=Symbol("missing"),Qe=class{pinnedMem=new Map;indexMem=new Map;metaMem=new Map;negativeCache=new Z(new pe(Cs));async getPinnedExact(e,t){let n=`${e}@${t}`,s=this.pinnedMem.get(n);if(s!==void 0)return s===fe?void 0:s;await x();let o=await Ge($.join(Mr,I(n)+".txt"));return this.pinnedMem.set(n,o??fe),o}async setPinnedExact(e,t,n){let s=`${e}@${t}`;this.pinnedMem.set(s,n),await x(),await C($.join(Mr,I(s)+".txt"),n)}async getIndex(e){let t=this.indexMem.get(e);if(t!==void 0)return t===fe?void 0:t;await x();let n=await ee($.join(Ft,Xe(e)+".json"));return this.indexMem.set(e,n??fe),n}async setIndex(e,t,n){let s={versions:t,distTags:n,updatedAt:Date.now()};this.indexMem.set(e,s),await x(),await C($.join(Ft,Xe(e)+".json"),JSON.stringify(s))}async invalidateVersionsCache(e){this.indexMem.delete(e),await Br.rm($.join(Ft,Xe(e)+".json"),{force:!0})}async isNegative(e){return await x(),this.negativeCache.isNegative(e)}async recordNegative(e){await x(),await this.negativeCache.recordNegative(e)}async clearNegative(e){await this.negativeCache.clearNegative(e)}async getMeta(e,t){let n=`${e}@${t}`,s=this.metaMem.get(n);if(s!==void 0)return s===fe?void 0:s;await x();let o=await ee(jr(e,t));return this.metaMem.set(n,o??fe),o}async setMeta(e,t,n,s,o){let i={dependencies:n,peerDependencies:s,peerDependenciesMeta:o,updatedAt:Date.now()};this.metaMem.set(`${e}@${t}`,i),await x(),await C(jr(e,t),JSON.stringify(i))}};function jr(r,e){return $.join(_s,Xe(r),encodeURIComponent(e)+".json")}function Xe(r){return r.replace(/\//g,"__")}var Fr={async getJson(r){try{let e=await fetch(r,{redirect:"follow"});return e.ok?await e.json():void 0}catch{return}},async head(r){try{let e=await fetch(r,{method:"HEAD",redirect:"follow"});return{ok:e.ok,url:e.url}}catch{return}}};var Os=new Qe,{packageService:Ze,versionResolver:Lr,cdnClient:Nr,peerResolver:La}=Sr(Os,Fr);var Ur=`
270
+ `;var ae=class{constructor(e){this.store=e}async isNegative(e){let t=await dt(()=>this.store.get(e));return!!t&&t.until>Date.now()}async recordNegative(e){let n=((await dt(()=>this.store.get(e)))?.attempts||0)+1;await dt(()=>this.store.set(e,{until:Date.now()+bo(n),attempts:n}))}async clearNegative(e){await dt(()=>this.store.delete(e))}};function bo(r){return Math.min(9e5*Math.pow(2,Math.max(0,r-1)),864e5)}async function dt(r){try{return await r()}catch{return}}import Eo from"p-limit";import{resolve as rn}from"resolve.exports";var be=class{constructor(e){this.fetchDts=e}fetchDtsText(e){return this.tryUrls([e])}async tryUrls(e){for(let t of e){let n=await this.fetchDts(t);if(n&&(this.looksLikeDts(n.dts)||/\.(d\.ts|d\.mts)(?:[?#].*)?$/i.test(n.url)||/[?&]dts(?:[&#]|$)/i.test(n.url)))return n}}looksLikeDts(e){return/^\s*export\s*\{\s*\}\s*;?\s*$/m.test(e)?!0:/declare\s+(module|namespace|class|interface|function|const|var|let)/.test(e)||/interface\s+\w+/.test(e)||/type\s+\w+\s*=/.test(e)}};var ee={maxRelativeTypeRefs:500,maxBareDeps:8,maxBareDepth:3,prefetchConcurrency:4,negativeTtlMs:1e4},Ne=["index.d.ts","index.d.mts"],je=/\.d\.(ts|mts)$/i;function rr(r){if(je.test(r))return!0;try{return new URL(r,"file://").search.includes("dts")}catch{return r.includes("?")&&r.includes("dts")}}function ut(r){return[`${r}.d.ts`,`${r}.d.mts`]}async function Le(r,{retries:e=2,timeoutMs:t=15e3,init:n}={}){for(let s=0;s<=e;s++){let o=new AbortController,i=setTimeout(()=>o.abort(),t);try{let a=await fetch(r,{...n,signal:o.signal});if(wo(a.status)&&s<e)continue;return a}catch{if(s<e)continue;return}finally{clearTimeout(i)}}}function wo(r){return r===408||r===429||r>=500&&r<600}var Ue=class extends be{constructor(e,t){super(e),this.cdnClient=t}async loadPackageAtVersionedRoot(e,t){let n=this.cdnClient.packageJson(new b({name:e,version:t})),s=await Le(n);if(!s?.ok)return;let o;try{o=await s.json()}catch{return}if(o)return{pkg:o,baseDir:this.cdnClient.baseDir(new b({name:e,version:t??o.version})),version:t}}extractPathFromResult(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.find(t=>typeof t=="string")}async tryUntilSuccess(e,t){for(let n of e){let s=await t(n);if(s)return s}}async resolveFromSelected(e,t){if(e.kind==="types"){let s=this.cdnClient.normalizeRelative(e.path);if(!s||s==="/"||s===".")return this.tryUntilSuccess([...Ne],t);if(!je.test(s)){let o=await this.tryUntilSuccess(this.declarationCandidatesFor(s),t);if(o)return o}return t(s)}let n=this.declarationCandidatesFor(e.path);return this.tryUntilSuccess([...Ne,...n],t)}toResolutionResult(e){return{kind:je.test(e)?"types":"probe",path:e}}resolveExportsPath(e,t){let n=t||".",s=e;try{let o=this.extractPathFromResult(rn(s,n,{conditions:["types"]}));if(o)return o}catch{}try{return this.extractPathFromResult(rn(s,n,{browser:!0,conditions:["import","default","module","browser","node"]}))}catch{return}}async resolve(e){try{let t=b.parse(e),{pkg:n,baseDir:s}=await this.loadPackageAtVersionedRoot(t.name,t.version)||{};if(!n||!s)return;let o={name:t.name,version:t.version},i=new b(o).format(),a=new b({...o,subpath:t.subpath}).format(),c=u=>this.fetchCandidateFrom(s,t.name,u);if(t.subpath){let u=this.cdnClient.ensureLeadingDotSlash(t.subpath),f=this.resolveExportsPath(n,u);if(f){let g=await this.resolveFromSelected(this.toResolutionResult(f),c);if(g)return{...g,resolvedPkg:a}}let h=await this.tryUntilSuccess(this.declarationCandidatesFor(u),c);if(h)return{...h,resolvedPkg:a}}let l=n.types??n.typings;if(l){let u=await this.resolveFromSelected({kind:"types",path:l},c);if(u)return{...u,resolvedPkg:i}}let d=this.resolveExportsPath(n,".");if(d){let u=await this.resolveFromSelected(this.toResolutionResult(d),c);if(u)return{...u,resolvedPkg:i}}return}catch{return}}async fetchCandidateFrom(e,t,n){let s=this.cdnClient.normalizeRelative(n),o=new URL(s,e).toString(),i=await this.fetchDtsText(o);return i?{dts:i.dts,url:i.url,resolvedPkg:t}:void 0}declarationCandidatesFor(e){if(!e||e==="./"||e==="/")return[...Ne];let t=e.replace(/\.(mjs|cjs|js|mts|cts|ts)$/i,""),n=ut(t),s=t.endsWith("/")?t:`${t}/`;return n.push(...ut(`${s}index`)),n}};import{gunzipSync as vo}from"fflate";var we=class{async fetchAndExtract(e,t){let n=this.getTarballUrl(e,t),s=await Le(n,{timeoutMs:3e4});if(!s?.ok)return new Map;let o=new Uint8Array(await s.arrayBuffer());return this.extractDtsFiles(o)}getTarballUrl(e,t){return`https://registry.npmjs.org/${e.replace("/","%2F")}/-/${e.split("/").pop()}-${t}.tgz`}normalizeTarPath(e){let t=e.replace(/^package\//,""),n=t.indexOf("/");return n>0?t.substring(n+1):t}extractDtsFiles(e){let t=new Map;try{let n=vo(e),s=new TextDecoder("utf-8"),o=0;for(;o<n.length-512;){let i=n.slice(o,o+512);if(i[0]===0)break;let a=i.slice(0,100),c=a.indexOf(0),l=s.decode(a.slice(0,c>0?c:100)).trim(),d=i.slice(124,136),u=s.decode(d).trim().replace(/\0/g,""),f=parseInt(u,8)||0,h=String.fromCharCode(i[156]);if(o+=512,(h==="0"||h==="\0")&&(l.endsWith(".d.ts")||l.endsWith(".d.mts"))){let g=n.slice(o,o+f);t.set(this.normalizeTarPath(l),s.decode(g))}o+=Math.ceil(f/512)*512}}catch{}return t}},xo=new we;var We=class extends be{constructor(e,t,n,s=new we){super(e),this.cdnClient=t,this.cache=n,this.tarballFetcher=s}typesNameCandidates(e){let t=e.startsWith("@")?e.slice(1).replace("/","__"):e;return t.includes(".")?[t,t.split(".").join("-"),t.split(".").join("")]:[t]}selectTypesVersion(e,t,n){try{if(n){let o=ie.majorOf(n),i=e.filter(a=>ie.majorOf(a)===o);if(i.length)return i.sort((a,c)=>ie.cmp(c,a))[0]}let s=t?.latest;return s&&e.includes(s)?s:e[0]}catch{return e[0]}}async fetchFromVersionedRoot(e,t){let n=new b(e),s=n.version;if(!s)return;let o;try{o=await this.tarballFetcher.fetchAndExtract(n.name,s)}catch{return}if(!o||o.size===0)return;for(let[a,c]of o.entries()){let l=this.cdnClient.file(e,a);try{await this.cache.setCachedFile(l,c)}catch{}}let i=t.subpath?[t.subpath+".d.ts",t.subpath+"/index.d.ts"]:["index.d.ts"];for(let a of i){let c=o.get(a);if(c)return{dts:c,url:this.cdnClient.file(e,a),resolvedPkg:t.subpath?new b(t).format():t.name}}}async resolve(e){let t=b.parse(e);if(t.name)for(let n of this.typesNameCandidates(t.name)){let s=`@types/${n}`,o;try{o=await this.cdnClient.fetchVersionsIndex(s)}catch{continue}if(!o?.versions?.length)continue;let i=this.selectTypesVersion(o.versions,o.distTags,t.version),a=await this.fetchFromVersionedRoot(`${s}@${i}`,t);if(a)return a}}};var Je=class{collectRelativeTypeRefs(e){return this.collectRefs(e).filter(t=>t.startsWith("./")||t.startsWith("../"))}collectBareModuleRefs(e){return this.collectRefs(e).filter(t=>this.isBare(t))}collectRefs(e){let t=new Set,n=(s,o)=>(t.add(s[o]),null);return this.matchAll(e,/(import|export)\s+[^'"\n]*from\s*['"]([^'"\n]+)['"]/,s=>n(s,2)),this.matchAll(e,/export\s*\*\s*from\s*['"]([^'"\n]+)['"]/,s=>n(s,1)),Array.from(t)}matchAll(e,t,n){let s=[];try{let o=new RegExp(t.source,"g"),i;for(;i=o.exec(e);){let a=n(i);a!==null&&s.push(a)}}catch{}return s}isBare(e){return!(e.startsWith("./")||e.startsWith("../")||e.startsWith("file:")||e.startsWith("http://")||e.startsWith("https://"))}};var nn="file:///node_modules",Ve=class{constructor(){this.epoch=0,this.listeners=new Set}getEpoch(){return this.epoch}bumpEpoch(){this.epoch+=1;for(let e of this.listeners)try{e(this.epoch)}catch{}return this.epoch}onEpochChange(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}epochDir(){return`__tsepoch_${this.epoch}`}pathForMain(e){return`${nn}/${this.epochDir()}/${e}/index.d.ts`}pathFor(e,t){let n=So(t);return`${nn}/${this.epochDir()}/${e}/${n}`}};function So(r){let e=r||"";return e.startsWith("./")?e.slice(2):e.replace(/^\/+/,"")}import{LRUCache as Po}from"lru-cache";function nr(r){let e=new Po({ttl:1e4,max:500}),t=new Map;return async function(s){try{if(await r.isNegative(s))return;let o=e.get(s);if(o&&Date.now()-o<1e4)return;let i=await r.getCachedFile(s);if(i)return{dts:i,url:s};let a=t.get(s);if(a)return a;let c=(async()=>{let l=await fetch(s,{cache:"no-store"});if(!l.ok){l.status===404&&(e.set(s,Date.now()),await r.recordNegative(s));return}let d=await l.text(),u=l.url||s;return await r.clearNegative(s),await r.setCachedFile(u,d),{dts:d,url:u}})();return t.set(s,c),await c.finally(()=>t.delete(s))}catch{return}}}var pt=class{constructor(e){this.inFlight=new Map,this.scanner=new Je,this.cache=e.cache,this.cdnClient=e.cdnClient,this.versionResolver=e.versionResolver,this.packageService=e.packageService,this.fetchDts=nr(e.cache),this.typescriptProvider=new Ue(this.fetchDts,e.cdnClient),this.definitelyTypedProvider=new We(this.fetchDts,e.cdnClient,e.cache),this.virtualFs=new Ve}withInFlight(e,t){let n=this.inFlight.get(e);if(n)return n;let s=t().finally(()=>this.inFlight.delete(e));return this.inFlight.set(e,s),s}invalidate(){this.virtualFs.bumpEpoch(),this.inFlight.clear()}capArray(e,t){return e.length<=t?e:e.slice(0,t)}pushFileIfNew(e,t,n){e.some(s=>s.path===t)||e.push({path:t,content:n})}createStubDef(e){let t=this.virtualFs.pathForMain(e);return{pkg:e,mainPath:t,files:[{path:t,content:"export const _shim: any; export default _shim;"}],shims:[{module:e,path:t}]}}async trySubpathWithRootFallback(e,t){let n=new b(e);return n.subpath?this.fetchRootDts(n.name,t):void 0}async fetchViaProviders(e){for(let t of[this.typescriptProvider,this.definitelyTypedProvider])try{let n=await t.resolve(e);if(n?.dts)return n}catch{}}subpathsMatch(e,t){return new b(e).subpath===new b(t).subpath}async fetchRootDts(e,t){let{effectivePackage:n,root:s,pinned:o}=await this.versionResolver.effectivePackage(e,t),i=await this.cache.getCachedDts(n);if(i?.content){let c=i.url??this.cdnClient.file(o?`${s}@${o}`:s,"index.d.ts");return{dts:i.content,url:c,resolvedPkg:n}}let a;try{a=await this.fetchViaProviders(n)}catch{return}if(!(!a?.dts||!a.url)){try{await this.cache.setCachedFile(a.url,a.dts)}catch{}if(this.subpathsMatch(n,a.resolvedPkg||n)){try{await this.cache.setCachedDts(n,a.dts,a.url)}catch{}return a}}}extractPackageRootUrl(e){let t=e.pathname.match(/^(.+@[^/]+\/)/);return t?new URL(t[1],e.origin):new URL("./",e)}toVirtualPath(e,t,n){let s=t.pathname.startsWith(e.pathname)?t.pathname.slice(e.pathname.length):`__deps__/${encodeURIComponent(t.toString()).replace(/%/g,"_")}.d.ts`;return this.virtualFs.pathFor(n,s)}computeEntryPath(e,t){if(!e)return{mainPath:this.virtualFs.pathForMain(t),packageRootUrl:void 0};let n=new URL(e),s=this.extractPackageRootUrl(n);return{mainPath:this.toVirtualPath(s,n,t),packageRootUrl:s}}async expandRelativeRefs(e,t,n,s,o=new Set,i){if(!o.has(t)&&(o.add(t),!(o.size>ee.maxRelativeTypeRefs)))try{let a=new URL(t),c=new URL("./",a);i??(i=this.extractPackageRootUrl(a));let l=this.capArray(this.scanner.collectRelativeTypeRefs(e),ee.maxRelativeTypeRefs);for(let d of l)await this.tryRelativeRef(d,c,i,n,s,o)}catch{}}async tryRelativeRef(e,t,n,s,o,i){try{let a=new URL(e,t),c=a.pathname+a.search,l=rr(c)?[c]:this.typescriptProvider.declarationCandidatesFor(c);for(let d of l){let f=new URL(d,a).toString();if(i.has(f))return;let h=await this.fetchDts(f);if(h?.dts){let g=this.toVirtualPath(n,new URL(h.url),s);this.pushFileIfNew(o,g,h.dts),await this.expandRelativeRefs(h.dts,h.url,s,o,i,n);return}}}catch{}}isDifferentPackage(e,t){return e===t?!1:new b(e).name!==new b(t).name}ambientlyDeclares(e,t){for(let n of e.matchAll(/declare\s+module\s+['"]([^'"]+)['"]/g)){let s=n[1];if(s===t||s.endsWith("/*")&&t.startsWith(s.slice(0,-1)))return!0}return!1}markFileAmbient(e,t){let n=e.find(s=>s.path===t);n&&(n.ambient=!0)}async prefetchBareDeps(e,t,n,s,o){try{let i=this.capArray(this.scanner.collectBareModuleRefs(e),ee.maxBareDeps).filter(l=>this.isDifferentPackage(l,t));if(!i.length)return;let a=new Set([t]),c=Eo(ee.prefetchConcurrency);await Promise.all(i.map(l=>c(()=>this.prefetchBareDepsRecursive(l,n,s,ee.maxBareDepth,a,o).catch(()=>{}))))}catch{}}async prefetchBareDepsRecursive(e,t,n,s,o,i){if(s<=0||o.has(e))return;o.add(e);let a=await this.fetchRootDts(e,i);if(!a?.dts)return;let c=a.resolvedPkg||e,l=this.virtualFs.pathForMain(c);this.pushFileIfNew(t,l,a.dts),this.ambientlyDeclares(a.dts,e)?this.markFileAmbient(t,l):n.push({module:e,path:l}),a.url&&await this.expandRelativeRefs(a.dts,a.url,c,t);let d=this.capArray(this.scanner.collectBareModuleRefs(a.dts),ee.maxBareDeps).filter(u=>!o.has(u));for(let u of d)await this.prefetchBareDepsRecursive(u,t,n,s-1,o,i)}async resolve(e,t,n){let s=await this.packageService.extractImports(e),o=n?[...s,...n]:s;return(await Promise.all(o.map(a=>this.resolveOne(a,t)))).filter(a=>!!a)}async resolveOne(e,t){let{effectivePackage:n}=await this.versionResolver.effectivePackage(e,t);return this.withInFlight(n,async()=>{let s=await this.fetchRootDts(e,t)??await this.trySubpathWithRootFallback(e,t);return s?this.buildDefFromContent(e,s,s.resolvedPkg||e,t):this.createStubDef(e)})}async buildDefFromContent(e,t,n,s){let{dts:o,url:i,resolvedPkg:a}=t,c=new b(a||n),l=c.version?`${c.name}@${c.version}`:c.name,{mainPath:d,packageRootUrl:u}=this.computeEntryPath(i,l),f=[{path:d,content:o}],h=[];i&&await this.expandRelativeRefs(o,i,l,f,void 0,u);let g=f.map(E=>E.content).join(`
271
+ `);await this.prefetchBareDeps(g,l,f,h,s);let x=c.format(),$=e===x?[e]:[e,x],O=$.some(E=>this.ambientlyDeclares(o,E));return O?this.markFileAmbient(f,d):h.push(...$.map(E=>({module:E,path:d}))),{pkg:e,mainPath:d,files:f,shims:h,ambient:O}}};function sr(r){return new pt(r)}import*as q from"fs/promises";import*as G from"path";import*as an from"os";import*as or from"fs/promises";import*as sn from"crypto";function L(r){return sn.createHash("sha1").update(r).digest("hex")}async function ce(r){try{return JSON.parse(await or.readFile(r,"utf8"))}catch{return}}async function ft(r){try{return await or.readFile(r,"utf8")}catch{return}}var on=1,te=G.join(an.homedir(),".typebulb","cache"),He=G.join(te,"packages"),qe=G.join(te,"proxy"),mt=G.join(te,"dts"),ko=G.join(te,"emit"),ir;function S(){return ir||(ir=Ro()),ir}function ht(r,e){return G.join(ko,L(r),e)}async function Ro(){await q.mkdir(te,{recursive:!0});let r=G.join(te,"version.json");if((await To(r))?.version===on)return;let t=await q.readdir(te).catch(()=>[]);await Promise.all(t.map(n=>q.rm(G.join(te,n),{recursive:!0,force:!0}))),await q.writeFile(r,JSON.stringify({version:on})+`
272
+ `,"utf8")}async function To(r){try{let e=await q.readFile(r,"utf8");return JSON.parse(e)}catch{return}}import*as re from"fs/promises";import*as cn from"path";async function F(r,e){await re.mkdir(cn.dirname(r),{recursive:!0});let t=`${r}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await re.writeFile(t,e,"utf8"),await re.rename(t,r).catch(async n=>{throw await re.rm(t,{force:!0}).catch(()=>{}),n})}var ve=class{constructor(e){this.filePath=e}mem;loadPromise;load(){return this.mem?Promise.resolve(this.mem):(this.loadPromise||(this.loadPromise=ce(this.filePath).then(e=>(this.mem=new Map(Object.entries(e??{})),this.mem))),this.loadPromise)}async get(e){return(await this.load()).get(e)}async set(e,t){let n=await this.load();n.set(e,t),await this.persist(n)}async delete(e){let t=await this.load();t.delete(e)&&await this.persist(t)}async persist(e){await F(this.filePath,JSON.stringify(Object.fromEntries(e)))}};var ar=U.join(He,"indexes"),ln=U.join(He,"pinned"),_o=U.join(He,"meta"),Co=U.join(He,"negative.json"),xe=Symbol("missing"),yt=class{pinnedMem=new Map;indexMem=new Map;metaMem=new Map;negativeCache=new ae(new ve(Co));async getPinnedExact(e,t){let n=`${e}@${t}`,s=this.pinnedMem.get(n);if(s!==void 0)return s===xe?void 0:s;await S();let o=await ft(U.join(ln,L(n)+".txt"));return this.pinnedMem.set(n,o??xe),o}async setPinnedExact(e,t,n){let s=`${e}@${t}`;this.pinnedMem.set(s,n),await S(),await F(U.join(ln,L(s)+".txt"),n)}async getIndex(e){let t=this.indexMem.get(e);if(t!==void 0)return t===xe?void 0:t;await S();let n=await ce(U.join(ar,gt(e)+".json"));return this.indexMem.set(e,n??xe),n}async setIndex(e,t,n){let s={versions:t,distTags:n,updatedAt:Date.now()};this.indexMem.set(e,s),await S(),await F(U.join(ar,gt(e)+".json"),JSON.stringify(s))}async invalidateVersionsCache(e){this.indexMem.delete(e),await un.rm(U.join(ar,gt(e)+".json"),{force:!0})}async isNegative(e){return await S(),this.negativeCache.isNegative(e)}async recordNegative(e){await S(),await this.negativeCache.recordNegative(e)}async clearNegative(e){await this.negativeCache.clearNegative(e)}async getMeta(e,t){let n=`${e}@${t}`,s=this.metaMem.get(n);if(s!==void 0)return s===xe?void 0:s;await S();let o=await ce(dn(e,t));return this.metaMem.set(n,o??xe),o}async setMeta(e,t,n,s,o){let i={dependencies:n,peerDependencies:s,peerDependenciesMeta:o,updatedAt:Date.now()};this.metaMem.set(`${e}@${t}`,i),await S(),await F(dn(e,t),JSON.stringify(i))}};function dn(r,e){return U.join(_o,gt(r),encodeURIComponent(e)+".json")}function gt(r){return r.replace(/\//g,"__")}var pn={async getJson(r){try{let e=await fetch(r,{redirect:"follow"});return e.ok?await e.json():void 0}catch{return}},async head(r){try{let e=await fetch(r,{method:"HEAD",redirect:"follow"});return{ok:e.ok,url:e.url}}catch{return}}};var Ao=new yt,{packageService:bt,versionResolver:fn,cdnClient:mn,peerResolver:Bl}=Kr(Ao,pn);var hn=`
269
273
  (() => {
270
274
  // Embedded (bulb-in-a-bulb): runs inside a sandboxed iframe with no parent
271
275
  // bridge, so privileged tb.* (AI, fs, server RPC) can't reach a host and would
@@ -475,12 +479,12 @@ declare const tb: {${Pr}${Rr}${Er}${_r}${hs}${kr}${Tr}
475
479
  };
476
480
  }
477
481
  })();
478
- `;function Wr(r){let{name:e,code:t,css:n,html:s,data:o,insight:i,importMap:a,watch:c,theme:l}=r,p=s.trim()||'<div id="app"></div>',d=h=>h.replace(/<\/script/gi,"<\\/script"),m={imports:$s(a.imports)};return`<!DOCTYPE html>
482
+ `;function gn(r){let{name:e,code:t,css:n,html:s,data:o,insight:i,importMap:a,watch:c,theme:l}=r,d=s.trim()||'<div id="app"></div>',u=h=>h.replace(/<\/script/gi,"<\\/script"),f={imports:Oo(a.imports)};return`<!DOCTYPE html>
479
483
  <html>
480
484
  <head>
481
485
  <meta charset="utf-8">
482
486
  <meta name="viewport" content="width=device-width, initial-scale=1">
483
- <title>${Is(e)} - typebulb</title>
487
+ <title>${$o(e)} - typebulb</title>
484
488
  <script>
485
489
  // Theme engine. Sets html[data-theme] before stylesheets paint (no flash) and
486
490
  // exposes the tb.theme accessor via window.__tbTheme. The override is persisted
@@ -488,13 +492,13 @@ declare const tb: {${Pr}${Rr}${Er}${_r}${hs}${kr}${Tr}
488
492
  // toggles the effective theme. See Specs/Theme.md.
489
493
  (function() {
490
494
  try {
491
- var KEY = ${d(JSON.stringify("tb-theme:"+e))};
495
+ var KEY = ${u(JSON.stringify("tb-theme:"+e))};
492
496
  var doc = document.documentElement;
493
497
  var mq = window.matchMedia('(prefers-color-scheme: dark)');
494
498
  var os = function() { return mq.matches ? 'dark' : 'light'; };
495
499
  // A host-forced theme (bulb-in-a-bulb) outranks the OS but not an explicit
496
500
  // in-iframe override, so the user can still toggle the embed independently.
497
- var FORCED = ${d(JSON.stringify(l??null))};
501
+ var FORCED = ${u(JSON.stringify(l??null))};
498
502
  var stored = function() {
499
503
  try { var v = localStorage.getItem(KEY); return (v === 'dark' || v === 'light') ? v : undefined; }
500
504
  catch (e) { return undefined; }
@@ -525,7 +529,7 @@ declare const tb: {${Pr}${Rr}${Er}${_r}${hs}${kr}${Tr}
525
529
  })();
526
530
  </script>
527
531
  <script type="importmap">
528
- ${JSON.stringify(m,null,2)}
532
+ ${JSON.stringify(f,null,2)}
529
533
  </script>
530
534
  <style>
531
535
  /* Reset and base styles */
@@ -539,23 +543,23 @@ ${n}
539
543
  </style>
540
544
  </head>
541
545
  <body>
542
- ${p}
546
+ ${d}
543
547
 
544
- ${o.length>0?`<script>window.__TB_DATA__ = ${d(JSON.stringify(o))};</script>`:""}
545
- ${i?`<script>window.__TB_INSIGHT__ = ${d(JSON.stringify(i))};</script>`:""}
548
+ ${o.length>0?`<script>window.__TB_DATA__ = ${u(JSON.stringify(o))};</script>`:""}
549
+ ${i?`<script>window.__TB_INSIGHT__ = ${u(JSON.stringify(i))};</script>`:""}
546
550
  ${c?"<script>window.__TYPEBULB_WATCH__ = true;</script>":""}
547
551
 
548
552
  <script>
549
- ${Ur}
553
+ ${hn}
550
554
  </script>
551
555
 
552
- ${As}
556
+ ${Io}
553
557
 
554
558
  <script type="module">
555
- ${d(t)}
559
+ ${u(t)}
556
560
  </script>
557
561
  </body>
558
- </html>`}var As=`<script>
562
+ </html>`}var Io=`<script>
559
563
  (function () {
560
564
  if (window.parent === window) return;
561
565
  var de = document.documentElement;
@@ -626,50 +630,152 @@ ${d(t)}
626
630
  }
627
631
  });
628
632
  })();
629
- </script>`;function Is(r){return r.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function $s(r){let e={};for(let[t,n]of Object.entries(r))e[t]=n.startsWith("https://")?"/proxy/"+n:n;return e}import*as tt from"fs/promises";import*as et from"path";import{existsSync as Jr,readFileSync as Ds}from"fs";import{execFile as Ms}from"child_process";import{promisify as js}from"util";import{satisfies as Bs}from"semver";var Fs=js(Ms);async function rt(r,e,t){let s=r.map(i=>Ls(i,t)).filter(i=>!Ns(i,e));if(s.length===0)return;await tt.mkdir(e,{recursive:!0});let o=et.join(e,"package.json");Jr(o)||await tt.writeFile(o,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${s.join(", ")}`),await Fs("npm",["install","--no-audit","--no-fund",...s],{cwd:e,shell:!0})}function Ls(r,e){if(!e||Hr(r))return r;let t=e[r];return t?`${r}@${t}`:r}function Ns(r,e){let t=et.join(e,"node_modules",Vr(r));if(!Jr(t))return!1;let n=Hr(r);if(!n)return!0;try{let s=JSON.parse(Ds(et.join(t,"package.json"),"utf-8")).version;return Bs(s,n)}catch{return!1}}function nt(r){let e=new Set,t=/\bimport\s+(?:[\s\S]*?\s+from\s+)?['"]([^./][^'"]*)['"]/g,n;for(;n=t.exec(r);){let s=n[1];if(s.includes(":"))continue;let o=s.startsWith("@")?s.split("/").slice(0,2).join("/"):s.split("/")[0];e.add(o)}return[...e]}function Vr(r){if(r.startsWith("@")){let t=r.indexOf("/");if(t<0)return r;let n=r.indexOf("@",t+1);return n<0?r:r.slice(0,n)}let e=r.indexOf("@");return e<0?r:r.slice(0,e)}function Hr(r){let e=Vr(r);return r.length>e.length?r.slice(e.length+1):""}async function qr(r){let t=(await X.readdir(r)).find(n=>n.endsWith(".bulb.md"));return t?st.join(r,t):null}function Lt(r){let e=mr(r);if(!e)throw new Error("Invalid .bulb.md file format");let t=hr(e);return{bulb:t,config:br(t.config)}}async function W(r){return Lt(await X.readFile(r,"utf-8"))}async function Nt(r,e,t,n){let s=Et(r,{serverOnly:!0});if(s.error)throw new Error(`Server compilation error: ${s.error}`);let o=s.code;t&&(o=await ur(o,t));let i=st.join(e,".typebulb");await X.mkdir(i,{recursive:!0});let a=nt(o);a.length>0&&await rt(a,i,n);let c=st.join(i,"server.mjs");return await X.writeFile(c,o,"utf-8"),await import(`${Us(c).href}?t=${Date.now()}`)}async function Ut(r,e,t,n,s){let{bulb:o,config:i}=await W(r),a=gr(o.data),c=Et(o.code,{jsxImportSource:i.jsxImportSource});c.error&&console.error("Compilation error:",c.error);let{importMap:l}=await Ze.buildImportMap(c.code,i.dependencies??{},n?new Set([n.name]):void 0);n&&(l.imports[n.name]=n.entryUrl);let p=Wr({name:o.name,code:c.code,css:o.css,html:o.html,data:a,insight:o.insight,importMap:l,watch:e}),d=null;return o.server&&t&&(d=await Nt(o.server,s,n,i.dependencies)),{html:p,bulb:o,serverExports:d}}import{readFileSync as Vs,writeFileSync as Hs,mkdirSync as qs}from"fs";import{join as zs}from"path";import{join as Wt,resolve as Ws}from"path";import{homedir as Js}from"os";function ot(){let r=process.env.TYPEBULB_SERVERS_DIR;return r?Wt(r,".."):Wt(Js(),".typebulb")}function te(){return process.env.TYPEBULB_SERVERS_DIR||Wt(ot(),"servers")}function D(r){let e=Ws(r);return(process.platform==="win32"?e.toLowerCase():e).replace(/\\/g,"/")}function zr(r,e){let t=D(r),n=D(e);return t.startsWith(n.endsWith("/")?n:n+"/")?!t.includes("/node_modules/"):!1}function Gr(){return zs(ot(),"trust.json")}function Jt(){try{let r=JSON.parse(Vs(Gr(),"utf8"));return new Set(Array.isArray(r)?r:[])}catch{return new Set}}function Gs(r){qs(ot(),{recursive:!0}),Hs(Gr(),JSON.stringify([...r]))}function it(r){return Jt().has(D(r))}function Kr(r,e){let t=Jt(),n=D(r);(e?t.has(n):!t.has(n))||(e?t.add(n):t.delete(n),Gs(t))}function Yr(){return[...Jt()]}import Ks from"open";async function at(r){await Ks(r)}import*as J from"path";import{fileURLToPath as Ys}from"url";var ct={claude:{file:"claude.bulb.md",srcEnv:"TYPEBULB_CLAUDE_SRC",viewer:!0}};function me(r){let e=ct[r];if(!e)return;let t=e.srcEnv?process.env[e.srcEnv]:void 0;return t?J.resolve(t):J.join(J.dirname(Ys(import.meta.url)),"..","bulbs",e.file)}function lt(r){let e=J.basename(r).toLowerCase();for(let[t,n]of Object.entries(ct))if(n.viewer&&n.file.toLowerCase()===e)return t}function Vt(){return Object.entries(ct).filter(([,r])=>r.viewer).map(([r])=>r)}function Xr(r){let e=J.basename(r).toLowerCase();return Object.values(ct).some(t=>t.file.toLowerCase()===e)}import*as nn from"path";import{spawn as po}from"child_process";import*as E from"fs/promises";import*as R from"path";import*as he from"path";var Xs=he.join(Ke,"pkg"),Qs=he.join(Ke,"files"),Zs=he.join(Ke,"negative.json"),ut=class{pkgMem=new Map;fileMem=new Map;negativeCache=new Z(new pe(Zs));async getCachedDts(e){if(this.pkgMem.has(e))return this.pkgMem.get(e);await x();let t=await ee(Qr(e));return this.pkgMem.set(e,t),t}async setCachedDts(e,t,n){let s={content:t,url:n};this.pkgMem.set(e,s),await dt(async()=>{await x(),await C(Qr(e),JSON.stringify(s))})}async getCachedFile(e){if(this.fileMem.has(e))return this.fileMem.get(e);await x();let t=await Ge(Zr(e));return this.fileMem.set(e,t),t}async setCachedFile(e,t){this.fileMem.set(e,t),await dt(async()=>{await x(),await C(Zr(e),t)})}isNegative(e){return this.negativeCache.isNegative(e)}async recordNegative(e){await dt(async()=>{await x(),await this.negativeCache.recordNegative(e)})}clearNegative(e){return dt(()=>this.negativeCache.clearNegative(e))}};async function dt(r){try{await r()}catch{}}function Qr(r){return he.join(Xs,I(r)+".json")}function Zr(r){return he.join(Qs,I(r)+".txt")}var Ht;function eo(){return Ht||(Ht=Mt({cache:new ut,cdnClient:Nr,packageService:Ze,versionResolver:Lr})),Ht}var en="file:///node_modules/";async function tn(r){let e=Ye(r.emitKey,"typecheck");await x(),await E.rm(e,{recursive:!0,force:!0}),await E.mkdir(e,{recursive:!0});let t=so(r.jsxImportSource,r.dependencies),n=await eo().resolve(r.code,r.dependencies,t),s=r.local?.name,o=s?n.filter(p=>p.pkg!==s):n,i=new Set;for(let p of o)for(let d of p.files){let m=pt(d.path);if(!m||i.has(m))continue;i.add(m);let h=R.join(e,"node_modules",m);await E.mkdir(R.dirname(h),{recursive:!0}),await E.writeFile(h,d.content,"utf8")}let a={};for(let p of o)for(let d of p.shims){let m=pt(d.path);m&&(a[d.module]=[`./node_modules/${m}`])}for(let p of o){if(p.ambient)continue;let d=pt(p.mainPath);d&&(a[p.pkg]=[`./node_modules/${d}`])}let c=new Set;for(let p of o)for(let d of p.files){if(!d.ambient)continue;let m=pt(d.path);m&&c.add(`node_modules/${m}`)}if(r.local){delete a[r.local.name];let p=await oo(r.local,e);p?a[r.local.name]=[`./node_modules/${r.local.name}/${p}`]:console.warn(` local: '${r.local.name}' ships no type defs; check cannot type against it.`)}let l=to(r.jsxImportSource,a,[...c]);return await E.writeFile(R.join(e,"tsconfig.json"),JSON.stringify(l,null,2)+`
630
- `,"utf8"),await E.writeFile(R.join(e,"code.tsx"),r.code,"utf8"),await E.writeFile(R.join(e,"tb.d.ts"),At,"utf8"),{dir:e}}function to(r,e,t=[]){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"bundler",lib:ro([...Ct,...Ot]),jsx:"react-jsx",jsxImportSource:r??"react",strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0,baseUrl:".",paths:e},include:["code.tsx","tb.d.ts",...t]}}function ro(r){return r.filter(e=>!e.since).map(e=>no(e.name))}function no(r){return r.split(".").map(e=>/^es\d+$/i.test(e)?e.toUpperCase():e==="dom"?"DOM":e==="esnext"?"ESNext":e.charAt(0).toUpperCase()+e.slice(1)).join(".")}function so(r,e){let t=r??("react"in e?"react":void 0);return t?[`${t}/jsx-runtime`,`${t}/jsx-dev-runtime`]:[]}function pt(r){if(!r.startsWith(en))return;let e=r.slice(en.length),t=e.indexOf("/");if(!(t<0))return e.slice(t+1)}async function oo(r,e){if(!r.typesAbs)return;let t=R.dirname(r.typesAbs),n=R.join(e,"node_modules",r.name);for(let s of await io(t)){let o=R.join(n,R.relative(t,s));await E.mkdir(R.dirname(o),{recursive:!0}),await E.copyFile(s,o)}return R.basename(r.typesAbs)}async function io(r){let e=[];async function t(n){let s=await E.readdir(n,{withFileTypes:!0});for(let o of s){let i=R.join(n,o.name);o.isDirectory()?await t(i):/\.d\.ts(\.map)?$/.test(o.name)&&e.push(i)}}return await t(r),e}import*as O from"fs/promises";import*as V from"path";import{existsSync as ao}from"fs";var co="^22";async function rn(r){let e=Ye(r.emitKey,"typecheck-server");await x(),await O.rm(e,{recursive:!0,force:!0}),await O.mkdir(e,{recursive:!0});let t=V.join(r.bulbDir,".typebulb"),n=nt(r.server).filter(i=>i!==r.local?.name);await rt([`@types/node@${co}`,...n],t,r.dependencies);let s=V.join(t,"node_modules"),o=V.join(e,"node_modules");return await uo(s,o),await O.writeFile(V.join(e,"server.ts"),r.server,"utf8"),await O.writeFile(V.join(e,"tb.d.ts"),It,"utf8"),await O.writeFile(V.join(e,"tsconfig.json"),JSON.stringify(lo(r.local),null,2)+`
631
- `,"utf8"),{dir:e}}function lo(r){let e={target:"es2023",module:"esnext",moduleResolution:"bundler",lib:["ES2023"],types:["node"],strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0};if(r?.typesAbs){let t=o=>o.replace(/\\/g,"/"),n=t(V.dirname(r.typesAbs)),s=t(r.typesAbs).replace(/\.d\.ts$/,"");e.baseUrl=".",e.paths={[r.name]:[s],[`${r.name}/*`]:[`${n}/*`]}}return{compilerOptions:e,include:["server.ts","tb.d.ts"]}}async function uo(r,e){if(!ao(r)){await O.mkdir(e,{recursive:!0});return}await O.rm(e,{recursive:!0,force:!0});let t=process.platform==="win32"?"junction":"dir";await O.symlink(r,e,t)}async function sn(r,e){await an(await W(r),{emitKey:r,bulbDir:nn.dirname(r),local:e})}async function on(r){let e=await fo(),t,n;try{t=Lt(e),n=r?await Je(r):void 0}catch(s){console.error(s instanceof Error?s.message:String(s)),process.exit(1)}await an(t,{emitKey:"<stdin>",bulbDir:process.cwd(),local:n})}async function an({bulb:r,config:e},{emitKey:t,bulbDir:n,local:s}){!r.code&&!r.server&&(console.error("Bulb has neither **code.tsx** nor **server.ts**; nothing to check."),process.exit(1));let o=[];if(r.code){let{dir:a}=await tn({code:r.code,dependencies:e.dependencies??{},jsxImportSource:e.jsxImportSource,emitKey:t,local:s});o.push({role:"client",dir:a})}if(r.server){let{dir:a}=await rn({server:r.server,bulbDir:n,emitKey:t,local:s?{name:s.name,typesAbs:s.typesAbs}:void 0,dependencies:e.dependencies});o.push({role:"server",dir:a})}let i=!1;for(let{role:a,dir:c}of o){let{stdout:l,exitCode:p}=await mo(c);for(let d of l.split(/\r?\n/))d.trim()&&console.log(`${a} ${d}`);p!==0&&(i=!0)}i&&process.exit(1)}async function fo(){let r=[];for await(let e of process.stdin)r.push(e);return Buffer.concat(r).toString("utf-8")}function mo(r){return new Promise(e=>{let t=po("npx",["tsc","--noEmit"],{cwd:r,shell:!0}),n="";t.stdout?.on("data",s=>{n+=s.toString()}),t.stderr?.on("data",s=>{n+=s.toString()}),t.on("close",s=>e({stdout:n,exitCode:s??1}))})}function ft(r){if(r.server.trim())return"server-side code (server.ts)";let e=r.code;if(/\btb\s*\.\s*fs\b/.test(e)||e.includes("/__fs"))return"the filesystem";if(/\btb\s*\.\s*ai\b/.test(e)||e.includes("/__ai"))return"AI (your API keys)";if(/\btb\s*\.\s*server\s*\.\s*(?!log\b)\w/.test(e)||e.includes("/__api"))return"server-side code (server.ts)"}async function cn(r,e){let{bulb:t}=await W(r),n=ft(t);if(it(r)){console.log("remembered-trusted \u2014 runs with filesystem / AI / server.ts automatically (`typebulb untrust` to revoke)."),n&&console.log(` (it uses ${n})`);return}n?(console.log(`This bulb appears to use ${n}; it runs Restricted unless you grant trust:`),console.log(` ${e}`)):console.log("No privileged capability detected \u2014 runs Restricted by default. (A clean scan is a hint, not a guarantee.)")}import*as Me from"path";async function ln(r,e){if(!r){e||(console.error("Usage: typebulb untrust <file.bulb.md>"),process.exit(1));let n=Yr();if(!n.length){console.log("No bulbs are remembered as trusted.");return}console.log("Trusted bulbs (run with fs/AI/server.ts without --trust):");for(let s of n)console.log(` ${s}`);return}let t=Me.resolve(r);t.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1)),Kr(t,e),console.log(e?`Trusted ${Me.basename(t)} \u2014 runs with fs / AI / server.ts (no --trust needed).`:`Untrusted ${Me.basename(t)} \u2014 runs Restricted.`),console.log(` ${t}`)}import{readdir as ho,readFile as pn,writeFile as fn,unlink as je,mkdir as go}from"fs/promises";import{mkdirSync as bo,writeFileSync as dn,appendFileSync as yo,readFileSync as mn}from"fs";import*as re from"path";var un=1e6;function qt(r){return re.join(te(),`${r}.json`)}function mt(r){return re.join(te(),`${r}.log`)}function hn(r){let e=mt(r);try{bo(te(),{recursive:!0}),dn(e,"")}catch{return()=>{}}let t=process.stdout.write.bind(process.stdout),n=process.stderr.write.bind(process.stderr),s=0,o=!1,i=a=>{if(!o)try{let c=typeof a=="string"?Buffer.from(a,"utf8"):Buffer.from(a);if(yo(e,c),s+=c.length,s>2*un){let l=mn(e),p=l.subarray(Math.max(0,l.length-un));dn(e,p),s=p.length}}catch{o=!0}};return process.stdout.write=((a,...c)=>(i(a),t(a,...c))),process.stderr.write=((a,...c)=>(i(a),n(a,...c))),()=>{process.stdout.write=t,process.stderr.write=n}}function zt(r,e=0){try{let t=mn(mt(r)),n=e>=0&&e<=t.length?e:0;return{text:t.subarray(n).toString("utf8"),offset:t.length}}catch{return{text:"",offset:0}}}function vo(r){try{return process.kill(r,0),!0}catch(e){return e.code==="EPERM"}}async function gn(r){await go(te(),{recursive:!0}),await fn(qt(r.pid),JSON.stringify(r))}async function bn(r,e){let t=qt(r);try{let n=JSON.parse(await pn(t,"utf8"));if(n.denied===e)return;n.denied=e,await fn(t,JSON.stringify(n))}catch{}}async function Gt(r){await je(qt(r)).catch(()=>{}),await je(mt(r)).catch(()=>{})}async function ne(r){let e;try{e=await ho(te())}catch{return[]}let t=[];return await Promise.all(e.map(async s=>{if(!s.endsWith(".json"))return;let o=re.join(te(),s),i;try{i=JSON.parse(await pn(o,"utf8"))}catch{await je(o).catch(()=>{});return}i&&typeof i.pid=="number"&&vo(i.pid)?t.push(i):(await je(o).catch(()=>{}),i?.pid&&await je(mt(i.pid)).catch(()=>{}))})),(r?t.filter(s=>zr(s.file,r)&&!Xr(s.file)):t).sort((s,o)=>s.startedAt-o.startedAt)}async function yn(r){try{process.kill(r,"SIGTERM")}catch{}await Gt(r)}async function Kt(r,e){let t=D(r);return(await ne()).find(n=>n.cwd!=null&&D(n.cwd)===t&&(e?lt(n.file)===e:lt(n.file)!=null))}async function vn(){let r=await Kt(process.cwd()),e=r?lt(r.file):void 0,t=e?"output a bulb block; it renders live here":"start the viewer yourself \u2014 `npx typebulb agent:claude --no-open` \u2014 share the localhost link it prints, then output a bulb block",n=[e?`You ran \`typebulb agent\`. Viewer '${e}' is up at ${r?.url}.`:"You ran `typebulb agent`. No viewer is running.",`- To show a bulb inline in this chat: ${t}.`,"- To make a bulb to keep and iterate on: write a .bulb.md and run `npx typebulb my-bulb.bulb.md`.","Working with bulbs? Run `npx typebulb skill` for the full authoring guide \u2014 save it to your skills folder if the user wants bulbs on hand across sessions."];process.stdout.write(n.join(`
633
+ </script>`;function $o(r){return r.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Oo(r){let e={};for(let[t,n]of Object.entries(r))e[t]=n.startsWith("https://")?"/proxy/"+n:n;return e}import*as vt from"fs/promises";import*as wt from"path";import{existsSync as yn,readFileSync as Do}from"fs";import{execFile as Fo}from"child_process";import{promisify as Bo}from"util";import{satisfies as Mo}from"semver";var No=Bo(Fo);async function xt(r,e,t){let s=r.map(i=>jo(i,t)).filter(i=>!Lo(i,e));if(s.length===0)return;await vt.mkdir(e,{recursive:!0});let o=wt.join(e,"package.json");yn(o)||await vt.writeFile(o,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${s.join(", ")}`),await No("npm",["install","--no-audit","--no-fund",...s],{cwd:e,shell:!0})}function jo(r,e){if(!e||wn(r))return r;let t=e[r];return t?`${r}@${t}`:r}function Lo(r,e){let t=wt.join(e,"node_modules",bn(r));if(!yn(t))return!1;let n=wn(r);if(!n)return!0;try{let s=JSON.parse(Do(wt.join(t,"package.json"),"utf-8")).version;return Mo(s,n)}catch{return!1}}function St(r){let e=new Set,t=/\bimport\s+(?:[\s\S]*?\s+from\s+)?['"]([^./][^'"]*)['"]/g,n;for(;n=t.exec(r);){let s=n[1];if(s.includes(":"))continue;let o=s.startsWith("@")?s.split("/").slice(0,2).join("/"):s.split("/")[0];e.add(o)}return[...e]}function bn(r){if(r.startsWith("@")){let t=r.indexOf("/");if(t<0)return r;let n=r.indexOf("@",t+1);return n<0?r:r.slice(0,n)}let e=r.indexOf("@");return e<0?r:r.slice(0,e)}function wn(r){let e=bn(r);return r.length>e.length?r.slice(e.length+1):""}async function vn(r){let t=(await ne.readdir(r)).find(n=>n.endsWith(".bulb.md"));return t?Pt.join(r,t):null}async function K(r){let e=await ne.readFile(r,"utf-8"),t=at(e);if(!t)throw new Error("Invalid .bulb.md file format");let n=ct(t);return{bulb:n,config:Vr(n.config)}}async function cr(r,e,t,n){let s=Gt(r,{serverOnly:!0});if(s.error)throw new Error(`Server compilation error: ${s.error}`);let o=s.code;t&&(o=await Lr(o,t));let i=Pt.join(e,".typebulb");await ne.mkdir(i,{recursive:!0});let a=St(o);a.length>0&&await xt(a,i,n);let c=Pt.join(i,"server.mjs");return await ne.writeFile(c,o,"utf-8"),await import(`${Uo(c).href}?t=${Date.now()}`)}async function lr(r,e,t,n,s){let{bulb:o,config:i}=await K(r),a=Jr(o.data),c=Gt(o.code,{jsxImportSource:i.jsxImportSource});c.error&&console.error("Compilation error:",c.error);let{importMap:l}=await bt.buildImportMap(c.code,i.dependencies??{},n?new Set([n.name]):void 0);n&&(l.imports[n.name]=n.entryUrl);let d=gn({name:o.name,code:c.code,css:o.css,html:o.html,data:a,insight:o.insight,importMap:l,watch:e}),u=null;return o.server&&t&&(u=await cr(o.server,s,n,i.dependencies)),{html:d,bulb:o,serverExports:u}}Ge();import Ko from"open";async function Pe(r){await Ko(r)}var Pn=new Set(["claude"]);function En(r){return Pn.has(r)}function fr(){return[...Pn]}import*as An from"path";import{spawn as di}from"child_process";import*as _ from"fs/promises";import*as k from"path";import*as Ee from"path";var Yo=Ee.join(mt,"pkg"),Xo=Ee.join(mt,"files"),Qo=Ee.join(mt,"negative.json"),Rt=class{pkgMem=new Map;fileMem=new Map;negativeCache=new ae(new ve(Qo));async getCachedDts(e){if(this.pkgMem.has(e))return this.pkgMem.get(e);await S();let t=await ce(kn(e));return this.pkgMem.set(e,t),t}async setCachedDts(e,t,n){let s={content:t,url:n};this.pkgMem.set(e,s),await kt(async()=>{await S(),await F(kn(e),JSON.stringify(s))})}async getCachedFile(e){if(this.fileMem.has(e))return this.fileMem.get(e);await S();let t=await ft(Rn(e));return this.fileMem.set(e,t),t}async setCachedFile(e,t){this.fileMem.set(e,t),await kt(async()=>{await S(),await F(Rn(e),t)})}isNegative(e){return this.negativeCache.isNegative(e)}async recordNegative(e){await kt(async()=>{await S(),await this.negativeCache.recordNegative(e)})}clearNegative(e){return kt(()=>this.negativeCache.clearNegative(e))}};async function kt(r){try{await r()}catch{}}function kn(r){return Ee.join(Yo,L(r)+".json")}function Rn(r){return Ee.join(Xo,L(r)+".txt")}var mr;function Zo(){return mr||(mr=sr({cache:new Rt,cdnClient:mn,packageService:bt,versionResolver:fn})),mr}var Tn="file:///node_modules/";async function _n(r){let e=ht(r.emitKey,"typecheck");await S(),await _.rm(e,{recursive:!0,force:!0}),await _.mkdir(e,{recursive:!0});let t=ni(r.jsxImportSource,r.dependencies),n=await Zo().resolve(r.code,r.dependencies,t),s=r.local?.name,o=s?n.filter(d=>d.pkg!==s):n,i=new Set;for(let d of o)for(let u of d.files){let f=Tt(u.path);if(!f||i.has(f))continue;i.add(f);let h=k.join(e,"node_modules",f);await _.mkdir(k.dirname(h),{recursive:!0}),await _.writeFile(h,u.content,"utf8")}let a={};for(let d of o)for(let u of d.shims){let f=Tt(u.path);f&&(a[u.module]=[`./node_modules/${f}`])}for(let d of o){if(d.ambient)continue;let u=Tt(d.mainPath);u&&(a[d.pkg]=[`./node_modules/${u}`])}let c=new Set;for(let d of o)for(let u of d.files){if(!u.ambient)continue;let f=Tt(u.path);f&&c.add(`node_modules/${f}`)}if(r.local){delete a[r.local.name];let d=await si(r.local,e);d?a[r.local.name]=[`./node_modules/${r.local.name}/${d}`]:console.warn(` local: '${r.local.name}' ships no type defs; check cannot type against it.`)}let l=ei(r.jsxImportSource,a,[...c]);return await _.writeFile(k.join(e,"tsconfig.json"),JSON.stringify(l,null,2)+`
634
+ `,"utf8"),await _.writeFile(k.join(e,"code.tsx"),r.code,"utf8"),await _.writeFile(k.join(e,"tb.d.ts"),er,"utf8"),{dir:e}}function ei(r,e,t=[]){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"bundler",lib:ti([...Qt,...Zt]),jsx:"react-jsx",jsxImportSource:r??"react",strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0,baseUrl:".",paths:e},include:["code.tsx","tb.d.ts",...t]}}function ti(r){return r.filter(e=>!e.since).map(e=>ri(e.name))}function ri(r){return r.split(".").map(e=>/^es\d+$/i.test(e)?e.toUpperCase():e==="dom"?"DOM":e==="esnext"?"ESNext":e.charAt(0).toUpperCase()+e.slice(1)).join(".")}function ni(r,e){let t=r??("react"in e?"react":void 0);return t?[`${t}/jsx-runtime`,`${t}/jsx-dev-runtime`]:[]}function Tt(r){if(!r.startsWith(Tn))return;let e=r.slice(Tn.length),t=e.indexOf("/");if(!(t<0))return e.slice(t+1)}async function si(r,e){if(!r.typesAbs)return;let t=k.dirname(r.typesAbs),n=k.join(e,"node_modules",r.name);for(let s of await oi(t)){let o=k.join(n,k.relative(t,s));await _.mkdir(k.dirname(o),{recursive:!0}),await _.copyFile(s,o)}return k.basename(r.typesAbs)}async function oi(r){let e=[];async function t(n){let s=await _.readdir(n,{withFileTypes:!0});for(let o of s){let i=k.join(n,o.name);o.isDirectory()?await t(i):/\.d\.ts(\.map)?$/.test(o.name)&&e.push(i)}}return await t(r),e}import*as B from"fs/promises";import*as Y from"path";import{existsSync as ii}from"fs";var ai="^22";async function Cn(r){let e=ht(r.emitKey,"typecheck-server");await S(),await B.rm(e,{recursive:!0,force:!0}),await B.mkdir(e,{recursive:!0});let t=Y.join(r.bulbDir,".typebulb"),n=St(r.server).filter(i=>i!==r.local?.name);await xt([`@types/node@${ai}`,...n],t,r.dependencies);let s=Y.join(t,"node_modules"),o=Y.join(e,"node_modules");return await li(s,o),await B.writeFile(Y.join(e,"server.ts"),r.server,"utf8"),await B.writeFile(Y.join(e,"tb.d.ts"),tr,"utf8"),await B.writeFile(Y.join(e,"tsconfig.json"),JSON.stringify(ci(r.local),null,2)+`
635
+ `,"utf8"),{dir:e}}function ci(r){let e={target:"es2023",module:"esnext",moduleResolution:"bundler",lib:["ES2023"],types:["node"],strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0};if(r?.typesAbs){let t=o=>o.replace(/\\/g,"/"),n=t(Y.dirname(r.typesAbs)),s=t(r.typesAbs).replace(/\.d\.ts$/,"");e.baseUrl=".",e.paths={[r.name]:[s],[`${r.name}/*`]:[`${n}/*`]}}return{compilerOptions:e,include:["server.ts","tb.d.ts"]}}async function li(r,e){if(!ii(r)){await B.mkdir(e,{recursive:!0});return}await B.rm(e,{recursive:!0,force:!0});let t=process.platform==="win32"?"junction":"dir";await B.symlink(r,e,t)}async function In(r,e){let{bulb:t,config:n}=await K(r);!t.code&&!t.server&&(console.error("Bulb has neither **code.tsx** nor **server.ts**; nothing to check."),process.exit(1));let s=[];if(t.code){let{dir:i}=await _n({code:t.code,dependencies:n.dependencies??{},jsxImportSource:n.jsxImportSource,emitKey:r,local:e});s.push({role:"client",dir:i})}if(t.server){let{dir:i}=await Cn({server:t.server,bulbDir:An.dirname(r),emitKey:r,local:e?{name:e.name,typesAbs:e.typesAbs}:void 0,dependencies:n.dependencies});s.push({role:"server",dir:i})}let o=!1;for(let{role:i,dir:a}of s){let{stdout:c,exitCode:l}=await ui(a);for(let d of c.split(/\r?\n/))d.trim()&&console.log(`${i} ${d}`);l!==0&&(o=!0)}o&&process.exit(1)}function ui(r){return new Promise(e=>{let t=di("npx",["tsc","--noEmit"],{cwd:r,shell:!0}),n="";t.stdout?.on("data",s=>{n+=s.toString()}),t.stderr?.on("data",s=>{n+=s.toString()}),t.on("close",s=>e({stdout:n,exitCode:s??1}))})}_t();Ge();async function $n(r,e){let{bulb:t}=await K(r),n=ke(t);if(de(r)){console.log("remembered-trusted \u2014 runs with filesystem / AI / server.ts automatically (`typebulb untrust` to revoke)."),n&&console.log(` (it uses ${n})`);return}n?(console.log(`This bulb appears to use ${n}; it runs Restricted unless you grant trust:`),console.log(` ${e}`)):console.log("No privileged capability detected \u2014 runs Restricted by default. (A clean scan is a hint, not a guarantee.)")}Ge();import*as Ke from"path";async function On(r,e){if(!r){e||(console.error("Usage: typebulb untrust <file.bulb.md>"),process.exit(1));let n=pr();if(!n.length){console.log("No bulbs are remembered as trusted.");return}console.log("Trusted bulbs (run with fs/AI/server.ts without --trust):");for(let s of n)console.log(` ${s}`);return}let t=Ke.resolve(r);t.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1)),Se(t,e),console.log(e?`Trusted ${Ke.basename(t)} \u2014 runs with fs / AI / server.ts (no --trust needed).`:`Untrusted ${Ke.basename(t)} \u2014 runs Restricted.`),console.log(` ${t}`)}ze();ue();async function gr(r,e){let t=W(r);return(await M()).find(n=>n.cwd!=null&&W(n.cwd)===t&&(e?n.agent===e:n.agent!=null))}async function Un(){let r=await gr(process.cwd()),e=r?.agent,t=e?"output a bulb block; it renders live here":"start the viewer yourself \u2014 `npx typebulb agent:claude --no-open` \u2014 share the localhost link it prints, then output a bulb block",n=[e?`You ran \`typebulb agent\`. Viewer '${e}' is up at ${r?.url}.`:"You ran `typebulb agent`. No viewer is running.",`- To show a bulb inline in this chat: ${t}.`,"- To make a bulb to keep and iterate on: write a .bulb.md and run `npx typebulb my-bulb.bulb.md`.","Working with bulbs? Run `npx typebulb skill` for the full authoring guide \u2014 save it to your skills folder if the user wants bulbs on hand across sessions."];process.stdout.write(n.join(`
632
636
  `)+`
633
- `)}import{readFileSync as wo,existsSync as xo}from"fs";import*as H from"path";function So(r){return[...r?[`.env.${r}.local`,`.env.${r}`]:[],".env.local",".env"]}function ge(r,e=process.cwd()){let t={},n=[];for(let s of So(r)){let o;try{o=wo(H.resolve(e,s),"utf-8")}catch{continue}n.push(s);for(let[i,a]of Po(o))process.env[i]===void 0&&(process.env[i]=a,t[i]=s)}return{mode:r,sources:t,loaded:n}}function*Po(r){for(let e of r.split(`
634
- `)){let t=e.trim();if(!t||t.startsWith("#"))continue;let n=t.indexOf("=");if(n===-1)continue;let s=t.slice(0,n).trim(),o=t.slice(n+1).trim();(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),yield[s,o]}}function Ro(r){let e=new Set,t=/process\.env\.([A-Za-z_$][\w$]*)|process\.env\[\s*['"]([^'"]+)['"]\s*\]/g;for(let n;n=t.exec(r);)e.add(n[1]??n[2]);return[...e]}function ht(r,e,t){let{sources:n,mode:s,loaded:o}=r,i=process.cwd(),a=H.dirname(e),c=`(mode: ${s??"none"})`,l=t?Ro(t):[],p=l.filter(h=>n[h]).map(h=>`${h} \u2190 ${n[h]}`);p.length?console.log(`env: ${p.join(", ")} ${c}`):o.length&&console.log(`env: loaded ${o.join(", ")} ${c}`),s&&!o.some(h=>h===`.env.${s}`||h===`.env.${s}.local`)&&console.log(`env: mode=${s} \u2014 no .env.${s} found; using .env`);let d=H.resolve(a)!==H.resolve(i);if(d)for(let h of[".env.local",".env"])xo(H.join(a,h))&&console.log(`env: ${H.join(a,h)} present but not loaded (cwd is ${i})`);let m=l.filter(h=>process.env[h]===void 0);if(m.length){let h=d?` \u2014 try running from ${a}`:"";console.log(`env: server.ts reads ${m.join(", ")} but ${m.length>1?"they are":"it's"} unset${h}`)}}var ye={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"},Eo="https://api.typebulb.com/api/models",ko=1440*60*1e3,be=null;async function gt(){if(!be||Date.now()-be.fetchedAt>ko){let r=await fetch(Eo);if(!r.ok)return be?wn(be.models):[];be={models:await r.json(),fetchedAt:Date.now()}}return wn(be.models)}function wn(r){let e=new Set(Object.entries(ye).filter(([,t])=>!!process.env[t]).map(([t])=>t));return r.filter(t=>e.has(t.provider))}function xn(){return Object.values(ye).some(r=>!!process.env[r])}function Sn(r,e,t){let n=Math.max(...r.map(i=>i.name.length)),s=Math.max(...r.map(i=>i.friendlyName.length)),o=["Models available to tb.ai (filtered by your .env keys):",""];for(let i of r)o.push(` ${i.name.padEnd(n)} ${i.friendlyName.padEnd(s)} (${i.provider})`);return o.push("","Pass an id as the `model` in tb.ai({ provider, model })."),e&&t&&o.push(`Default (from .env): ${e} / ${t}`),o.join(`
635
- `)}async function Pn(r){if(ge(r),!xn()){console.log("No AI provider keys found in this directory's .env. Set one of these to use tb.ai:");for(let[t,n]of Object.entries(ye))console.log(` ${n.padEnd(20)} (${t})`);console.log("Then re-run `typebulb models`.");return}let e=await gt();if(e.length===0){console.log("Couldn't fetch the model catalog (offline?). tb.ai still works with any valid provider/model id for your keys.");return}console.log(Sn(e,process.env.TB_AI_PROVIDER,process.env.TB_AI_MODEL))}import*as En from"fs/promises";import*as bt from"path";import{fileURLToPath as Co}from"url";function To(r){return`---
637
+ `)}import{readFileSync as xi,existsSync as Si}from"fs";import*as X from"path";function Pi(r){return[...r?[`.env.${r}.local`,`.env.${r}`]:[],".env.local",".env"]}function se(r,e=process.cwd()){let t={},n=[];for(let s of Pi(r)){let o;try{o=xi(X.resolve(e,s),"utf-8")}catch{continue}n.push(s);for(let[i,a]of Ei(o))process.env[i]===void 0&&(process.env[i]=a,t[i]=s)}return{mode:r,sources:t,loaded:n}}function*Ei(r){for(let e of r.split(`
638
+ `)){let t=e.trim();if(!t||t.startsWith("#"))continue;let n=t.indexOf("=");if(n===-1)continue;let s=t.slice(0,n).trim(),o=t.slice(n+1).trim();(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),yield[s,o]}}function ki(r){let e=new Set,t=/process\.env\.([A-Za-z_$][\w$]*)|process\.env\[\s*['"]([^'"]+)['"]\s*\]/g;for(let n;n=t.exec(r);)e.add(n[1]??n[2]);return[...e]}function Te(r,e,t){let{sources:n,mode:s,loaded:o}=r,i=process.cwd(),a=X.dirname(e),c=`(mode: ${s??"none"})`,l=t?ki(t):[],d=l.filter(h=>n[h]).map(h=>`${h} \u2190 ${n[h]}`);d.length?console.log(`env: ${d.join(", ")} ${c}`):o.length&&console.log(`env: loaded ${o.join(", ")} ${c}`),s&&!o.some(h=>h===`.env.${s}`||h===`.env.${s}.local`)&&console.log(`env: mode=${s} \u2014 no .env.${s} found; using .env`);let u=X.resolve(a)!==X.resolve(i);if(u)for(let h of[".env.local",".env"])Si(X.join(a,h))&&console.log(`env: ${X.join(a,h)} present but not loaded (cwd is ${i})`);let f=l.filter(h=>process.env[h]===void 0);if(f.length){let h=u?` \u2014 try running from ${a}`:"";console.log(`env: server.ts reads ${f.join(", ")} but ${f.length>1?"they are":"it's"} unset${h}`)}}var Ce={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"},Ri="https://api.typebulb.com/api/models",Ti=1440*60*1e3,_e=null;async function $t(){if(!_e||Date.now()-_e.fetchedAt>Ti){let r=await fetch(Ri);if(!r.ok)return _e?Wn(_e.models):[];_e={models:await r.json(),fetchedAt:Date.now()}}return Wn(_e.models)}function Wn(r){let e=new Set(Object.entries(Ce).filter(([,t])=>!!process.env[t]).map(([t])=>t));return r.filter(t=>e.has(t.provider))}function Jn(){return Object.values(Ce).some(r=>!!process.env[r])}function Vn(r,e,t){let n=Math.max(...r.map(i=>i.name.length)),s=Math.max(...r.map(i=>i.friendlyName.length)),o=["Models available to tb.ai (filtered by your .env keys):",""];for(let i of r)o.push(` ${i.name.padEnd(n)} ${i.friendlyName.padEnd(s)} (${i.provider})`);return o.push("","Pass an id as the `model` in tb.ai({ provider, model })."),e&&t&&o.push(`Default (from .env): ${e} / ${t}`),o.join(`
639
+ `)}async function Hn(r){if(se(r),!Jn()){console.log("No AI provider keys found in this directory's .env. Set one of these to use tb.ai:");for(let[t,n]of Object.entries(Ce))console.log(` ${n.padEnd(20)} (${t})`);console.log("Then re-run `typebulb models`.");return}let e=await $t();if(e.length===0){console.log("Couldn't fetch the model catalog (offline?). tb.ai still works with any valid provider/model id for your keys.");return}console.log(Vn(e,process.env.TB_AI_PROVIDER,process.env.TB_AI_MODEL))}import*as zn from"fs/promises";import*as Ot from"path";import{fileURLToPath as Ai}from"url";function _i(r){return`---
636
640
  name: typebulb
637
641
  description: Author and run Typebulb bulbs \u2014 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 a Claude Code session through Typebulb's agent viewer (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/embed 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.
638
642
  version: ${r}
639
- ---`}function _o(r){return`> Generated from typebulb v${r}. If \`npx typebulb --version\` reports a newer version, re-run \`npx typebulb skill\` to refresh this file.`}function Rn(r,e){return`${To(e)}
643
+ ---`}function Ci(r){return`> Generated from typebulb v${r}. If \`npx typebulb --version\` reports a newer version, re-run \`npx typebulb skill\` to refresh this file.`}function qn(r,e){return`${_i(e)}
640
644
 
641
- ${_o(e)}
645
+ ${Ci(e)}
642
646
 
643
647
  ${r.trim()}
644
- `}async function kn(r){let e=bt.join(bt.dirname(Co(import.meta.url)),"..","README.md"),t;try{t=await En.readFile(e,"utf8")}catch{console.error(`Could not read the bundled README (expected at ${e}).`),process.exit(1)}process.stdout.write(Rn(t,r))}import*as Tn from"path";function Oo(r,e){return/^\d+$/.test(e)?r.find(t=>t.pid===parseInt(e,10)):r.find(t=>D(t.file)===D(e))}function _n(r,e){for(let t of r)e(` ${t.url} pid ${t.pid} ${t.trust?"trusted":"restricted"} ${t.file}`)}function Cn(r,e){if(!r.length){console.log("No running bulb servers.");return}console.log("Running bulb servers:"),_n(r,t=>console.log(t)),console.log(`
645
- `+e)}function On(r,e,t){let n=Oo(r,e);if(n)return n;console.error(`No running server for '${e}'.`),r.length?(console.error(`Running servers (try \`typebulb ${t} <file|pid>\`):`),_n(r,s=>console.error(s))):console.error("No bulb servers are running."),process.exit(1)}async function An(r,e){if(!r){Cn(await ne(process.cwd()),"Run `typebulb logs <file|pid>` to print one server's console.");return}let t=On(await ne(),me(r)??r,"logs"),n=zt(t.pid),s=n.text;if(e.lines&&e.lines>0){let o=s.split(`
648
+ `}async function Gn(r){let e=Ot.join(Ot.dirname(Ai(import.meta.url)),"..","README.md"),t;try{t=await zn.readFile(e,"utf8")}catch{console.error(`Could not read the bundled README (expected at ${e}).`),process.exit(1)}process.stdout.write(qn(t,r))}ze();ue();import*as Kn from"path";function Ii(r,e){return/^\d+$/.test(e)?r.find(t=>t.pid===parseInt(e,10)):r.find(t=>t.agent===e)??r.find(t=>W(t.file)===W(e))}function Yn(r,e){for(let t of r)e(` ${t.url} pid ${t.pid} ${t.trust?"trusted":"restricted"} ${t.file}`)}function Xn(r,e){if(!r.length){console.log("No running bulb servers.");return}console.log("Running bulb servers:"),Yn(r,t=>console.log(t)),console.log(`
649
+ `+e)}function Qn(r,e,t){let n=Ii(r,e);if(n)return n;console.error(`No running server for '${e}'.`),r.length?(console.error(`Running servers (try \`typebulb ${t} <file|pid>\`):`),Yn(r,s=>console.error(s))):console.error("No bulb servers are running."),process.exit(1)}async function Zn(r,e){if(!r){Xn(await M(process.cwd()),"Run `typebulb logs <file|pid>` to print one server's console.");return}let t=Qn(await M(),r,"logs"),n=Re(t.pid),s=n.text;if(e.lines&&e.lines>0){let o=s.split(`
646
650
  `);o.length&&o[o.length-1]===""&&o.pop(),s=o.slice(-e.lines).join(`
647
651
  `)}if(process.stdout.write(s),s&&!s.endsWith(`
648
652
  `)&&process.stdout.write(`
649
- `),e.follow){let o=n.offset,i=setInterval(()=>{let c=zt(t.pid,o);o=c.offset,c.text&&process.stdout.write(c.text)},500),a=()=>{clearInterval(i),process.exit(0)};process.on("SIGINT",a),process.on("SIGTERM",a),await new Promise(()=>{})}}async function In(r){if(!r){Cn(await ne(process.cwd()),"Run `typebulb stop <file|pid>` to stop one.");return}let e=On(await ne(),me(r)??r,"stop");await yn(e.pid),console.log(`Stopped ${Tn.basename(e.file)} (pid ${e.pid}, ${e.url}).`)}import*as Wn from"fs/promises";import*as ve from"path";import{EventEmitter as Un}from"events";import{Hono as Io}from"hono";import{serve as $o}from"@hono/node-server";import{streamSSE as Do}from"hono/streaming";import*as oe from"fs/promises";import*as j from"path";var A=class extends Error{constructor(e,t="unknown",n=!1){super(e),this.code=t,this.retryable=n}},M=class{getPath(e,t){return this.path}parseStreamChunk(e){return this.checkAndThrowError(e),this.parseProviderStreamChunk(e)}isReasoningEnabled(e){return e?.reasoning!==void 0&&e.reasoning>0}extractSystemMessages(e,t=`
653
+ `),e.follow){let o=n.offset,i=setInterval(()=>{let c=Re(t.pid,o);o=c.offset,c.text&&process.stdout.write(c.text)},500),a=()=>{clearInterval(i),process.exit(0)};process.on("SIGINT",a),process.on("SIGTERM",a),await new Promise(()=>{})}}async function es(r){if(!r){Xn(await M(process.cwd()),"Run `typebulb stop <file|pid>` to stop one.");return}let e=Qn(await M(),r,"stop");await Ze(e.pid),console.log(`Stopped ${e.agent??Kn.basename(e.file)} (pid ${e.pid}, ${e.url}).`)}import*as ls from"fs/promises";import*as Ae from"path";import{EventEmitter as cs}from"events";_t();import{Hono as Oi}from"hono";import{serve as Di}from"@hono/node-server";import{streamSSE as Fi}from"hono/streaming";import*as oe from"fs/promises";import*as H from"path";var N=class extends Error{constructor(e,t="unknown",n=!1){super(e),this.code=t,this.retryable=n}},V=class{getPath(e,t){return this.path}parseStreamChunk(e){return this.checkAndThrowError(e),this.parseProviderStreamChunk(e)}isReasoningEnabled(e){return e?.reasoning!==void 0&&e.reasoning>0}extractSystemMessages(e,t=`
650
654
 
651
- `){let n=e.filter(s=>s.role==="system").map(s=>s.content);return{system:n.length?n.join(t):void 0,conversationMessages:e.filter(s=>s.role!=="system")}}parseJsonError(e,t,n=!1){if(!e)return{message:`HTTP ${t}`};try{let s=JSON.parse(e);if(s.error&&typeof s.error=="object"){let o={message:s.error.message||`HTTP ${t}`,type:s.error.type};return n&&(o.code=s.error.code),o}return s.message?{message:s.message}:{message:e}}catch{return{message:e}}}checkAndThrowError(e){if("type"in e&&e.type==="error"&&"message"in e){let t=e.message,n=e.code||"unknown",s=!!e.retryable;throw new A(t,n,s)}if("error"in e&&e.error){let t=this.extractErrorMessage(e.error);throw new A(t)}}extractErrorMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);return t.error?.message||t.message||e}catch{return e}return typeof e=="object"&&e!==null?e.message||JSON.stringify(e):`${this.providerName} returned an error`}};var Be=class extends M{constructor(){super(...arguments),this.providerName="Anthropic",this.defaultBaseUrl="https://api.anthropic.com",this.path="/v1/messages"}buildHeaders(e){return{"x-api-key":e,"anthropic-version":"2023-06-01","Content-Type":"application/json",Accept:"application/json"}}buildPayload(e,t,n,s){let{system:o,conversationMessages:i}=this.extractSystemMessages(e),a={model:t,max_tokens:this.getMaxTokens(t),messages:this.withLastMessageCached(i),stream:s};if(n?.webSearch!==!1&&(a.tools=[{type:"web_search_20250305",name:"web_search"}]),o&&(a.system=[{type:"text",text:o,cache_control:{type:"ephemeral"}}]),this.isReasoningEnabled(n)){let c=n.reasoning;if(this.isModernModel(t)){let l={0:"low",1:"low",2:"medium",3:"high"};a.thinking={type:"adaptive"},a.output_config={effort:l[c]}}else{let l={0:0,1:2048,2:4096,3:8192};a.thinking={type:"enabled",budget_tokens:l[c]}}}return a}parseError(e,t){return this.parseJsonError(e,t)}parseNonStreamingResponse(e){if(!this.isAnthropicResponse(e))return{text:""};let t=e.content.filter(s=>s.type==="text").map(s=>s.text).join(""),n=e.content.filter(s=>s.type==="thinking").map(s=>s.thinking).join(`
655
+ `){let n=e.filter(s=>s.role==="system").map(s=>s.content);return{system:n.length?n.join(t):void 0,conversationMessages:e.filter(s=>s.role!=="system")}}parseJsonError(e,t,n=!1){if(!e)return{message:`HTTP ${t}`};try{let s=JSON.parse(e);if(s.error&&typeof s.error=="object"){let o={message:s.error.message||`HTTP ${t}`,type:s.error.type};return n&&(o.code=s.error.code),o}return s.message?{message:s.message}:{message:e}}catch{return{message:e}}}checkAndThrowError(e){if("type"in e&&e.type==="error"&&"message"in e){let t=e.message,n=e.code||"unknown",s=!!e.retryable;throw new N(t,n,s)}if("error"in e&&e.error){let t=this.extractErrorMessage(e.error);throw new N(t)}}extractErrorMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);return t.error?.message||t.message||e}catch{return e}return typeof e=="object"&&e!==null?e.message||JSON.stringify(e):`${this.providerName} returned an error`}};var et=class extends V{constructor(){super(...arguments),this.providerName="Anthropic",this.defaultBaseUrl="https://api.anthropic.com",this.path="/v1/messages"}buildHeaders(e){return{"x-api-key":e,"anthropic-version":"2023-06-01","Content-Type":"application/json",Accept:"application/json"}}buildPayload(e,t,n,s){let{system:o,conversationMessages:i}=this.extractSystemMessages(e),a={model:t,max_tokens:this.getMaxTokens(t),messages:this.withLastMessageCached(i),stream:s};if(n?.webSearch!==!1&&(a.tools=[{type:"web_search_20250305",name:"web_search"}]),o&&(a.system=[{type:"text",text:o,cache_control:{type:"ephemeral"}}]),this.isReasoningEnabled(n)){let c=n.reasoning;if(this.isModernModel(t)){let l={0:"low",1:"low",2:"medium",3:"high"};a.thinking={type:"adaptive"},a.output_config={effort:l[c]}}else{let l={0:0,1:2048,2:4096,3:8192};a.thinking={type:"enabled",budget_tokens:l[c]}}}return a}parseError(e,t){return this.parseJsonError(e,t)}parseNonStreamingResponse(e){if(!this.isAnthropicResponse(e))return{text:""};let t=e.content.filter(s=>s.type==="text").map(s=>s.text).join(""),n=e.content.filter(s=>s.type==="thinking").map(s=>s.thinking).join(`
652
656
 
653
- `);return{text:t,reasoning:n||void 0}}parseProviderStreamChunk(e){if(!("type"in e))return null;switch(e.type){case"content_block_delta":return e.delta.type==="text_delta"?{text:e.delta.text||""}:e.delta.type==="thinking_delta"?{reasoning:e.delta.thinking||""}:null;case"message_start":case"content_block_start":case"content_block_stop":case"message_delta":case"message_stop":case"ping":return null;default:return null}}withLastMessageCached(e){let t=e.length-1;return e.map((n,s)=>s===t?{role:n.role,content:[{type:"text",text:n.content,cache_control:{type:"ephemeral"}}]}:n)}isAnthropicResponse(e){return"content"in e&&Array.isArray(e.content)&&"type"in e&&e.type==="message"}isModernModel(e){let t=e.match(/^claude-\w+-(\d+)-(\d+)/);return!!t&&(+t[1]>4||+t[1]==4&&+t[2]>=6)}getMaxTokens(e){return this.isModernModel(e)?64e3:32e3}};var Fe=class extends M{constructor(){super(...arguments),this.providerName="OpenAI",this.defaultBaseUrl="https://api.openai.com",this.path="/v1/responses",this.effortMap={0:"minimal",1:"low",2:"medium",3:"high"}}buildHeaders(e){return{Authorization:`Bearer ${e}`,"Content-Type":"application/json",Accept:"application/json"}}buildPayload(e,t,n,s){let o=this.convertMessagesToInput(e),i={model:t,input:o,stream:s};return n?.webSearch!==!1&&(i.tools=[{type:"web_search"}]),this.isReasoningEnabled(n)&&(i.reasoning={effort:this.effortMap[n.reasoning],summary:"auto"}),i}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.isResponsesApiResponse(e))return{text:""};let t=e.output_text||"",n;if(e.output&&Array.isArray(e.output))for(let s of e.output)s.type==="reasoning"&&s.summary&&(n=s.summary.map(o=>o.text).join(`
654
- `)),!t&&s.type==="message"&&s.content&&(t=s.content.filter(o=>o.type==="output_text").map(o=>o.text).join(""));return{text:t,reasoning:n}}parseProviderStreamChunk(e){if(!this.isResponsesApiEvent(e))return null;switch(e.type){case"error":return null;case"response.failed":{let s=e.response?.error,o=s?.message||"Response failed",i=s?.code==="insufficient_quota"||s?.code==="rate_limit_exceeded";throw new A(o,i?"rate_limit":"unknown",i)}case"response.output_text.delta":return{text:e.delta};case"response.reasoning_summary_text.delta":return{reasoning:e.delta};case"response.created":case"response.in_progress":case"response.output_item.added":case"response.output_item.done":case"response.content_part.added":case"response.content_part.done":case"response.output_text.done":case"response.output_text.annotation.added":case"response.reasoning_summary_text.done":case"response.completed":case"response.web_search_call.in_progress":case"response.web_search_call.searching":case"response.web_search_call.completed":return null;default:return null}}convertMessagesToInput(e){return e.map(t=>t.role==="system"?`System: ${t.content}`:t.role==="user"?`User: ${t.content}`:t.role==="assistant"?`Assistant: ${t.content}`:t.content).join(`
657
+ `);return{text:t,reasoning:n||void 0}}parseProviderStreamChunk(e){if(!("type"in e))return null;switch(e.type){case"content_block_delta":return e.delta.type==="text_delta"?{text:e.delta.text||""}:e.delta.type==="thinking_delta"?{reasoning:e.delta.thinking||""}:null;case"message_start":case"content_block_start":case"content_block_stop":case"message_delta":case"message_stop":case"ping":return null;default:return null}}withLastMessageCached(e){let t=e.length-1;return e.map((n,s)=>s===t?{role:n.role,content:[{type:"text",text:n.content,cache_control:{type:"ephemeral"}}]}:n)}isAnthropicResponse(e){return"content"in e&&Array.isArray(e.content)&&"type"in e&&e.type==="message"}isModernModel(e){let t=e.match(/^claude-\w+-(\d+)-(\d+)/);return!!t&&(+t[1]>4||+t[1]==4&&+t[2]>=6)}getMaxTokens(e){return this.isModernModel(e)?64e3:32e3}};var tt=class extends V{constructor(){super(...arguments),this.providerName="OpenAI",this.defaultBaseUrl="https://api.openai.com",this.path="/v1/responses",this.effortMap={0:"minimal",1:"low",2:"medium",3:"high"}}buildHeaders(e){return{Authorization:`Bearer ${e}`,"Content-Type":"application/json",Accept:"application/json"}}buildPayload(e,t,n,s){let o=this.convertMessagesToInput(e),i={model:t,input:o,stream:s};return n?.webSearch!==!1&&(i.tools=[{type:"web_search"}]),this.isReasoningEnabled(n)&&(i.reasoning={effort:this.effortMap[n.reasoning],summary:"auto"}),i}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.isResponsesApiResponse(e))return{text:""};let t=e.output_text||"",n;if(e.output&&Array.isArray(e.output))for(let s of e.output)s.type==="reasoning"&&s.summary&&(n=s.summary.map(o=>o.text).join(`
658
+ `)),!t&&s.type==="message"&&s.content&&(t=s.content.filter(o=>o.type==="output_text").map(o=>o.text).join(""));return{text:t,reasoning:n}}parseProviderStreamChunk(e){if(!this.isResponsesApiEvent(e))return null;switch(e.type){case"error":return null;case"response.failed":{let s=e.response?.error,o=s?.message||"Response failed",i=s?.code==="insufficient_quota"||s?.code==="rate_limit_exceeded";throw new N(o,i?"rate_limit":"unknown",i)}case"response.output_text.delta":return{text:e.delta};case"response.reasoning_summary_text.delta":return{reasoning:e.delta};case"response.created":case"response.in_progress":case"response.output_item.added":case"response.output_item.done":case"response.content_part.added":case"response.content_part.done":case"response.output_text.done":case"response.output_text.annotation.added":case"response.reasoning_summary_text.done":case"response.completed":case"response.web_search_call.in_progress":case"response.web_search_call.searching":case"response.web_search_call.completed":return null;default:return null}}convertMessagesToInput(e){return e.map(t=>t.role==="system"?`System: ${t.content}`:t.role==="user"?`User: ${t.content}`:t.role==="assistant"?`Assistant: ${t.content}`:t.content).join(`
655
659
 
656
- `)}isResponsesApiEvent(e){return"type"in e&&typeof e.type=="string"}isResponsesApiResponse(e){return"object"in e&&e.object==="response"}};var Le=class extends M{constructor(){super(...arguments),this.providerName="Gemini",this.defaultBaseUrl="https://generativelanguage.googleapis.com",this.path="/v1beta/models"}getPath(e,t){return`/v1beta/models/${e}:${t?"streamGenerateContent":"generateContent"}${t?"?alt=sse":""}`}buildHeaders(e){return{"Content-Type":"application/json","x-goog-api-key":e}}buildPayload(e,t,n,s){let{system:o,conversationMessages:i}=this.extractSystemMessages(e,`
660
+ `)}isResponsesApiEvent(e){return"type"in e&&typeof e.type=="string"}isResponsesApiResponse(e){return"object"in e&&e.object==="response"}};var rt=class extends V{constructor(){super(...arguments),this.providerName="Gemini",this.defaultBaseUrl="https://generativelanguage.googleapis.com",this.path="/v1beta/models"}getPath(e,t){return`/v1beta/models/${e}:${t?"streamGenerateContent":"generateContent"}${t?"?alt=sse":""}`}buildHeaders(e){return{"Content-Type":"application/json","x-goog-api-key":e}}buildPayload(e,t,n,s){let{system:o,conversationMessages:i}=this.extractSystemMessages(e,`
657
661
  `),c={contents:i.map(l=>({role:l.role==="assistant"?"model":"user",parts:[{text:l.content}]}))};return n?.webSearch!==!1&&(c.tools=[{google_search:{}}]),o&&(c.systemInstruction={role:"system",parts:[{text:o}]}),this.isReasoningEnabled(n)&&(c.generationConfig={temperature:.7+n.reasoning*.1}),c}parseError(e,t){if(!e)return{message:`HTTP ${t}`};try{let n=JSON.parse(e),s=Array.isArray(n)?n[0]?.error:n?.error;return s&&typeof s=="object"?{message:(s.message||`HTTP ${t}`).split(`
658
- `)[0],type:s.status,code:s.code?.toString()}:n.message?{message:n.message}:{message:e}}catch{return{message:e}}}parseNonStreamingResponse(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return{text:"",status:"failed",error:"Invalid response format"};let t=this.extractText(e)||"",n=e.candidates?.[0]?.finishReason,s="complete";return n==="MAX_TOKENS"?s="interrupted":(n==="SAFETY"||n==="RECITATION")&&(s="failed"),{text:t,status:s}}parseProviderStreamChunk(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return null;let t=this.extractText(e);return t?{text:t}:null}isGeminiResponse(e){return typeof e=="object"&&e!==null&&"candidates"in e&&Array.isArray(e.candidates)}extractText(e){let t=e.candidates?.[0];if(t?.content?.parts)return t.content.parts.map(n=>n.text).filter(Boolean).join("")}checkGeminiError(e){if(typeof e=="object"&&e!==null&&"error"in e){let t=e.error,n;if(typeof t=="string")n=t;else if(typeof t=="object"&&t!==null){let s=t;n=s.message||s.status||"Gemini returned an error"}else n="Gemini returned an error";throw new A(n)}if(this.isGeminiResponse(e)&&e.promptFeedback?.blockReason){let t=e.promptFeedback.blockReason;throw new A(`Prompt blocked: ${t}`)}}};var Ne=class extends M{constructor(){super(...arguments),this.providerName="OpenRouter",this.defaultBaseUrl="https://openrouter.ai/api",this.path="/api/v1/chat/completions",this.effortMap={0:"low",1:"low",2:"medium",3:"high"}}buildHeaders(e,t){let n={Authorization:`Bearer ${e}`,"x-api-key":e,"Content-Type":"application/json",Accept:"application/json","X-Title":"Typebulb"};return t&&(n["HTTP-Referer"]=t,n.Referer=t,n.Origin=t),n}buildPayload(e,t,n,s){let o={model:t,messages:e,stream:s};return n?.webSearch===!0&&(o.plugins=[{id:"web"}]),this.isReasoningEnabled(n)&&(o.reasoning={effort:this.effortMap[n.reasoning]}),o}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.hasChoices(e))return{text:""};let t=e.choices[0],n=t?.message?.content??t?.text??"",s=t?.message?.reasoning??e.reasoning;return{text:n,reasoning:s}}parseProviderStreamChunk(e){if(!this.hasChoices(e))return null;let t=e.choices[0];if(!t)return null;let n=t.delta||t.message;if(!n)return null;let s=n.content||void 0,o=n.reasoning||void 0;return!s&&!o?null:{text:s,reasoning:o}}hasChoices(e){return typeof e=="object"&&e!==null&&"choices"in e&&Array.isArray(e.choices)}};var Ao=new Map([["openai",new Fe],["openrouter",new Ne],["anthropic",new Be],["gemini",new Le]]);function se(r){let e=Ao.get(r);if(!e)throw new Error(`Unsupported protocol: ${r}`);return e}async function Yt(r,e){let t=se(r.protocol),n=t.getPath(e.model,e.stream),s=new URL(n,r.baseUrl).toString(),o=t.buildHeaders(r.apiKey,e.origin),i=t.buildPayload(e.messages,e.model,{reasoning:e.reasoning,webSearch:e.webSearch},e.stream);return e.modifyPayload?.(i),fetch(s,{method:"POST",headers:o,body:JSON.stringify(i),signal:e.signal})}async function Xt(r,e){let t=se(e),n=await r.text().catch(()=>""),{message:s}=t.parseError(n,r.status),o=r.status,i="unknown";return o===429?i="rate_limit":o===413&&(i="context_exceeded"),{code:i,message:s,retryable:o===429}}function $n(r){let e=r.indexOf(`\r
662
+ `)[0],type:s.status,code:s.code?.toString()}:n.message?{message:n.message}:{message:e}}catch{return{message:e}}}parseNonStreamingResponse(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return{text:"",status:"failed",error:"Invalid response format"};let t=this.extractText(e)||"",n=e.candidates?.[0]?.finishReason,s="complete";return n==="MAX_TOKENS"?s="interrupted":(n==="SAFETY"||n==="RECITATION")&&(s="failed"),{text:t,status:s}}parseProviderStreamChunk(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return null;let t=this.extractText(e);return t?{text:t}:null}isGeminiResponse(e){return typeof e=="object"&&e!==null&&"candidates"in e&&Array.isArray(e.candidates)}extractText(e){let t=e.candidates?.[0];if(t?.content?.parts)return t.content.parts.map(n=>n.text).filter(Boolean).join("")}checkGeminiError(e){if(typeof e=="object"&&e!==null&&"error"in e){let t=e.error,n;if(typeof t=="string")n=t;else if(typeof t=="object"&&t!==null){let s=t;n=s.message||s.status||"Gemini returned an error"}else n="Gemini returned an error";throw new N(n)}if(this.isGeminiResponse(e)&&e.promptFeedback?.blockReason){let t=e.promptFeedback.blockReason;throw new N(`Prompt blocked: ${t}`)}}};var nt=class extends V{constructor(){super(...arguments),this.providerName="OpenRouter",this.defaultBaseUrl="https://openrouter.ai/api",this.path="/api/v1/chat/completions",this.effortMap={0:"low",1:"low",2:"medium",3:"high"}}buildHeaders(e,t){let n={Authorization:`Bearer ${e}`,"x-api-key":e,"Content-Type":"application/json",Accept:"application/json","X-Title":"Typebulb"};return t&&(n["HTTP-Referer"]=t,n.Referer=t,n.Origin=t),n}buildPayload(e,t,n,s){let o={model:t,messages:e,stream:s};return n?.webSearch===!0&&(o.plugins=[{id:"web"}]),this.isReasoningEnabled(n)&&(o.reasoning={effort:this.effortMap[n.reasoning]}),o}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.hasChoices(e))return{text:""};let t=e.choices[0],n=t?.message?.content??t?.text??"",s=t?.message?.reasoning??e.reasoning;return{text:n,reasoning:s}}parseProviderStreamChunk(e){if(!this.hasChoices(e))return null;let t=e.choices[0];if(!t)return null;let n=t.delta||t.message;if(!n)return null;let s=n.content||void 0,o=n.reasoning||void 0;return!s&&!o?null:{text:s,reasoning:o}}hasChoices(e){return typeof e=="object"&&e!==null&&"choices"in e&&Array.isArray(e.choices)}};var $i=new Map([["openai",new tt],["openrouter",new nt],["anthropic",new et],["gemini",new rt]]);function pe(r){let e=$i.get(r);if(!e)throw new Error(`Unsupported protocol: ${r}`);return e}async function yr(r,e){let t=pe(r.protocol),n=t.getPath(e.model,e.stream),s=new URL(n,r.baseUrl).toString(),o=t.buildHeaders(r.apiKey,e.origin),i=t.buildPayload(e.messages,e.model,{reasoning:e.reasoning,webSearch:e.webSearch},e.stream);return e.modifyPayload?.(i),fetch(s,{method:"POST",headers:o,body:JSON.stringify(i),signal:e.signal})}async function br(r,e){let t=pe(e),n=await r.text().catch(()=>""),{message:s}=t.parseError(n,r.status),o=r.status,i="unknown";return o===429?i="rate_limit":o===413&&(i="context_exceeded"),{code:i,message:s,retryable:o===429}}function ts(r){let e=r.indexOf(`\r
659
663
  \r
660
664
  `),t=r.indexOf(`
661
665
 
662
- `);return e!==-1&&(t===-1||e<t)?{pos:e,len:4}:t!==-1?{pos:t,len:2}:{pos:-1,len:0}}function Qt(r){let t=r.split(/\r?\n/).filter(s=>s.startsWith("data:"));if(!t.length)return null;let n=t.map(s=>s.replace(/^data:\s?/,"")).join(`
663
- `).trim();if(!n)return null;if(n==="[DONE]")return"done";try{return JSON.parse(n)}catch{return null}}async function Dn(r,e,t){let n=new TextDecoder,s="",o=!1,i=t?new Promise((a,c)=>{t.aborted&&c(new Error("Aborted")),t.addEventListener("abort",()=>c(new Error("Aborted")),{once:!0})}):null;for(;;){let a=i?await Promise.race([r.read(),i]):await r.read(),{done:c,value:l}=a;if(c){if(s.trim()){let m=Qt(s);m!==null&&m!=="done"&&e(m)}break}o=!0,s+=n.decode(l,{stream:!0});let{pos:p,len:d}=$n(s);for(;p!==-1;){let m=s.slice(0,p);s=s.slice(p+d);let h=Qt(m);if(h==="done"){s="";break}h!==null&&e(h),{pos:p,len:d}=$n(s)}}return{receivedAnyData:o}}async function Zt(r,e){let t=e??(r.headers.get("X-Provider-Protocol")||"openai"),n=se(t);if(!r.body)throw new Error("Response body is missing");let s=r.body.getReader(),o="";return await Dn(s,i=>{let a=n.parseStreamChunk(i);a?.text&&(o+=a.text)}),o}import*as er from"fs/promises";import*as Ue from"path";var yt=class{async get(e){let t=I(e),n=Ue.join(De,t+".bin"),s=Ue.join(De,t+".json");try{let[o,i]=await Promise.all([er.readFile(n),er.readFile(s,"utf8")]),a=JSON.parse(i);return{body:o,contentType:a.contentType,cacheControl:a.cacheControl}}catch{return}}async set(e,t){await x();let n=I(e),s=Ue.join(De,n+".bin"),o=Ue.join(De,n+".json"),i={url:e,contentType:t.contentType,cacheControl:t.cacheControl};await Promise.all([C(s,t.body),C(o,JSON.stringify(i))])}};var jn="127.0.0.1",Mo=new Set(["localhost","127.0.0.1","::1"]);function jo(r){if(r)try{return new URL(r.includes("://")?r:`http://${r}`).hostname}catch{return}}function Mn(r){let e=jo(r);return!!e&&Mo.has(e)}function vt(r){return r instanceof Error?r.message:"Unknown error"}async function Bn(r){let{getHtml:e,basePath:t,port:n,reloadEmitter:s,getServerExports:o,localOverride:i,trusted:a=!1,trustHint:c}=r,l=new Io;l.use("*",async(u,f)=>{if(!Mn(u.req.header("host")))return u.text("Forbidden: untrusted Host",403);await f()}),l.use("*",async(u,f)=>{await f(),u.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),u.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")});let p=["/__fs/*","/__api/*","/__ai"],d=async(u,f)=>{if(!a){let b=new URL(u.req.url).pathname,w=b.startsWith("/__fs")?"the filesystem":b==="/__ai"?"AI (your API keys)":"server-side code (server.ts)";bn(process.pid,w);let v=c?`
664
- ${c}`:"";return u.text(`Forbidden: this capability requires --trust.${v}`,403)}await f()},m=async(u,f)=>{let b=u.req.header("sec-fetch-site");if(b){if(b==="cross-site")return u.text("Forbidden: cross-site request",403)}else{let w=u.req.header("origin");if(w&&!Mn(w))return u.text("Forbidden: cross-origin request",403)}await f()};for(let u of p)l.use(u,d),l.use(u,m);l.use("/__log",m),l.post("/__log",async u=>{try{let{args:f}=await u.req.json();console.log(...f||[])}catch{}return u.json({ok:!0})}),l.get("/",u=>u.html(e())),l.post("/__fs/read",async u=>{try{let{path:f}=await u.req.json(),b=rr(f,t),w=await oe.readFile(b);return new Response(new Uint8Array(w),{headers:{"Content-Type":"application/octet-stream"}})}catch(f){let b=vt(f);return u.json({error:b},400)}}),l.post("/__fs/write",async u=>{try{let f=u.req.query("path");if(!f)return u.json({error:"Missing path"},400);let b=rr(f,t);return await oe.mkdir(j.dirname(b),{recursive:!0}),await oe.writeFile(b,Buffer.from(await u.req.arrayBuffer())),u.json({success:!0})}catch(f){let b=vt(f);return u.json({error:b},400)}});let h={log:console.log};l.post("/__api/:name",async u=>{try{let f=o?.(),b=u.req.param("name"),w=f?.[b]??h[b];if(!w||typeof w!="function")return u.json({error:`API function '${b}' not found`},404);let{args:v}=await u.req.json(),T=await w(...v||[]);return u.json({result:T})}catch(f){let b=vt(f);return u.json({error:b},500)}}),l.post("/__ai",async u=>{try{let{messages:f,system:b,reasoning:w,provider:v,model:T,webSearch:z}=await u.req.json();if(!f||!Array.isArray(f)||f.length===0)return u.json({message:"messages array is required",code:"unknown",retryable:!1},400);let F=Bo(v,T);if(typeof F=="string")return u.json({message:F,code:"unknown",retryable:!1},400);let xt=[...b?[{role:"system",content:b}]:[],...f.map(We=>({role:We.role,content:We.content}))],ie=await Yt(F,{model:F.model,messages:xt,stream:!0,reasoning:w??0,webSearch:z??!0});if(!ie.ok){let We=await Xt(ie,F.protocol);return u.json(We,ie.status)}let sr=await Zt(ie,F.protocol);return sr||console.warn("[tb.ai] Empty response from provider"),u.json({text:sr})}catch(f){if(f instanceof A)return u.json({message:f.message,code:f.code,retryable:f.retryable},500);let b=vt(f);return u.json({message:b,code:"unknown",retryable:!1},500)}}),l.get("/__models",async u=>{try{let f=await gt();return u.json(f)}catch{return u.json([],200)}});let g=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"],S=new yt;if(l.get("/proxy/*",async u=>{let f=new URL(u.req.url),w=(f.pathname+f.search).slice(7),v=w.lastIndexOf("https://");return v===-1?u.text("Invalid proxy URL",400):B(u,w.slice(v))}),i){let u=`/local/${i.name}/`;l.get("/local/*",async f=>{let{pathname:b}=new URL(f.req.url);if(!b.startsWith(u))return f.text("Not Found",404);let w=decodeURIComponent(b.slice(u.length));try{let v=rr(w,i.serveDir),T=await oe.readFile(v);return new Response(T,{headers:{"Content-Type":Fo(v)}})}catch{return f.text("Not Found",404)}})}async function B(u,f){let b;try{b=new URL(f)}catch{return u.text("Invalid URL",400)}if(b.protocol!=="https:")return u.text("HTTPS only",400);if(!g.includes(b.hostname))return u.text("Host not allowed",403);let w=await S.get(f);if(w)return new Response(w.body,{status:200,headers:tr(w.contentType,w.cacheControl)});try{let v=await fetch(f,{headers:{Accept:u.req.header("Accept")||"*/*"},redirect:"follow"});if(!v.ok)return u.text(`Upstream ${v.status}`,v.status);let T=v.headers.get("Content-Type")||void 0,z=v.headers.get("Cache-Control")||void 0;if(v.body){let[F,xt]=v.body.tee();return(async()=>{try{let ie=await new Response(xt).arrayBuffer();await S.set(f,{body:Buffer.from(ie),contentType:T,cacheControl:z})}catch{}})(),new Response(F,{status:v.status,headers:tr(T,z)})}return new Response(null,{status:v.status,headers:tr(T,z)})}catch(v){return u.text(`Proxy fetch failed: ${v instanceof Error?v.message:v}`,502)}}s&&l.get("/__reload",u=>Do(u,async f=>{let b=()=>{f.writeSSE({event:"reload",data:""})};for(s.on("reload",b),f.onAbort(()=>{s.removeListener("reload",b)});;)await f.sleep(3e4)}));let N=/^\/(v\d+\/|stable\/|node\/|gh\/|@[^/]+\/[^@/]+@|[^@/]+@)/;l.notFound(async u=>{if(u.req.method!=="GET")return u.text("Not Found",404);let f=new URL(u.req.url);return N.test(f.pathname)?B(u,"https://esm.sh"+f.pathname+f.search):u.text("Not Found",404)});let _=$o({fetch:l.fetch,port:n,hostname:jn});return{port:n,close:()=>_.close()}}function Bo(r,e){let t=r??process.env.TB_AI_PROVIDER,n=e??process.env.TB_AI_MODEL;if(!t)return"No provider specified. Set TB_AI_PROVIDER in your .env file or pass provider in the tb.ai() call.";if(!n)return"No model specified. Set TB_AI_MODEL in your .env file or pass model in the tb.ai() call.";let s;try{s=se(t)}catch{return`Unknown provider '${t}'.`}let o=ye[t],i=process.env[o];return i?{apiKey:i,baseUrl:s.defaultBaseUrl,protocol:t,model:n,isFreeModel:!1}:`No API key for '${t}'. Set ${o} in your .env file.`}function tr(r,e){let t=new Headers;return r&&t.set("Content-Type",r),e&&t.set("Cache-Control",e),t.set("Access-Control-Allow-Origin","*"),t.set("Cross-Origin-Resource-Policy","cross-origin"),t}function Fo(r){switch(j.extname(r).toLowerCase()){case".js":case".mjs":return"text/javascript";case".wasm":return"application/wasm";case".json":case".map":return"application/json";default:return"application/octet-stream"}}function rr(r,e){let t=j.resolve(e,r),n=j.normalize(e),s=j.normalize(t);if(s!==n&&!s.startsWith(n+j.sep))throw new Error("Path traversal detected - access denied");return t}async function nr(r){let e=await import("net");return new Promise(t=>{let n=e.createServer();n.listen(r,jn,()=>{let s=n.address(),o=typeof s=="object"&&s?s.port:r;n.close(()=>t(o))}),n.on("error",()=>{t(nr(r+1))})})}import Fn from"chokidar";var Ln={persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}};function wt(r){let{bulbPath:e,emitter:t}=r,n=Fn.watch(e,Ln);return n.on("change",()=>{t.emit("reload")}),()=>n.close()}function Nn(r){let{dir:e,onChange:t,debounceMs:n=150}=r,s,o=Fn.watch(e,Ln);return o.on("all",()=>{s&&clearTimeout(s),s=setTimeout(t,n)}),()=>{s&&clearTimeout(s),o.close()}}async function Jn(r,e,t,n,s){let o=process.cwd(),i=hn(process.pid),a=e.watch?new Un:void 0,c=ge(e.mode);console.log(`Loading ${ve.basename(r)}...`);let{html:l,bulb:p,serverExports:d}=await Ut(r,e.watch,e.trust,n,s);ht(c,r,p.server);let m=await nr(e.port),h=await Bn({getHtml:()=>l,basePath:o,port:m,reloadEmitter:a,getServerExports:()=>d,localOverride:n?{name:n.name,serveDir:n.serveDir}:void 0,trusted:e.trust,trustHint:t}),g=`http://localhost:${m}`,S=e.trust?void 0:ft(p);await gn({pid:process.pid,port:m,url:g,file:r,cwd:process.cwd(),startedAt:Date.now(),trust:e.trust,predicted:S}),console.log(`
665
- ${p.name}`),console.log(` ${g}`),m!==e.port&&console.log(` (port ${e.port} was busy)`),e.trust?console.log(" trust: granted (filesystem, AI, server.ts enabled)"):console.log(S?` trust: sandboxed \u2014 this bulb appears to use ${S}; re-run with --trust to enable it:
666
+ `);return e!==-1&&(t===-1||e<t)?{pos:e,len:4}:t!==-1?{pos:t,len:2}:{pos:-1,len:0}}function wr(r){let t=r.split(/\r?\n/).filter(s=>s.startsWith("data:"));if(!t.length)return null;let n=t.map(s=>s.replace(/^data:\s?/,"")).join(`
667
+ `).trim();if(!n)return null;if(n==="[DONE]")return"done";try{return JSON.parse(n)}catch{return null}}async function rs(r,e,t){let n=new TextDecoder,s="",o=!1,i=t?new Promise((a,c)=>{t.aborted&&c(new Error("Aborted")),t.addEventListener("abort",()=>c(new Error("Aborted")),{once:!0})}):null;for(;;){let a=i?await Promise.race([r.read(),i]):await r.read(),{done:c,value:l}=a;if(c){if(s.trim()){let f=wr(s);f!==null&&f!=="done"&&e(f)}break}o=!0,s+=n.decode(l,{stream:!0});let{pos:d,len:u}=ts(s);for(;d!==-1;){let f=s.slice(0,d);s=s.slice(d+u);let h=wr(f);if(h==="done"){s="";break}h!==null&&e(h),{pos:d,len:u}=ts(s)}}return{receivedAnyData:o}}async function vr(r,e){let t=e??(r.headers.get("X-Provider-Protocol")||"openai"),n=pe(t);if(!r.body)throw new Error("Response body is missing");let s=r.body.getReader(),o="";return await rs(s,i=>{let a=n.parseStreamChunk(i);a?.text&&(o+=a.text)}),o}import*as xr from"fs/promises";import*as st from"path";var Dt=class{async get(e){let t=L(e),n=st.join(qe,t+".bin"),s=st.join(qe,t+".json");try{let[o,i]=await Promise.all([xr.readFile(n),xr.readFile(s,"utf8")]),a=JSON.parse(i);return{body:o,contentType:a.contentType,cacheControl:a.cacheControl}}catch{return}}async set(e,t){await S();let n=L(e),s=st.join(qe,n+".bin"),o=st.join(qe,n+".json"),i={url:e,contentType:t.contentType,cacheControl:t.cacheControl};await Promise.all([F(s,t.body),F(o,JSON.stringify(i))])}};ue();var os="127.0.0.1",Bi=new Set(["localhost","127.0.0.1","::1"]);function Mi(r){if(r)try{return new URL(r.includes("://")?r:`http://${r}`).hostname}catch{return}}function ns(r){let e=Mi(r);return!!e&&Bi.has(e)}function Ft(r){return r instanceof Error?r.message:"Unknown error"}async function Mt(r){let{getHtml:e,basePath:t,port:n,reloadEmitter:s,getServerExports:o,localOverride:i,trusted:a=!1,trustHint:c,staticAssets:l}=r,d=new Oi;d.use("*",async(p,m)=>{if(!ns(p.req.header("host")))return p.text("Forbidden: untrusted Host",403);await m()}),d.use("*",async(p,m)=>{await m(),p.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),p.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")});let u=["/__fs/*","/__api/*","/__ai"],f=async(p,m)=>{if(!a){let y=new URL(p.req.url).pathname,v=y.startsWith("/__fs")?"the filesystem":y==="/__ai"?"AI (your API keys)":"server-side code (server.ts)";Ln(process.pid,v);let w=c?`
668
+ ${c}`:"";return p.text(`Forbidden: this capability requires --trust.${w}`,403)}await m()},h=async(p,m)=>{let y=p.req.header("sec-fetch-site");if(y){if(y==="cross-site")return p.text("Forbidden: cross-site request",403)}else{let v=p.req.header("origin");if(v&&!ns(v))return p.text("Forbidden: cross-origin request",403)}await m()};for(let p of u)d.use(p,f),d.use(p,h);d.use("/__log",h),d.post("/__log",async p=>{try{let{args:m}=await p.req.json();console.log(...m||[])}catch{}return p.json({ok:!0})}),d.get("/",p=>p.html(e())),d.post("/__fs/read",async p=>{try{let{path:m}=await p.req.json(),y=Bt(m,t),v=await oe.readFile(y);return new Response(new Uint8Array(v),{headers:{"Content-Type":"application/octet-stream"}})}catch(m){let y=Ft(m);return p.json({error:y},400)}}),d.post("/__fs/write",async p=>{try{let m=p.req.query("path");if(!m)return p.json({error:"Missing path"},400);let y=Bt(m,t);return await oe.mkdir(H.dirname(y),{recursive:!0}),await oe.writeFile(y,Buffer.from(await p.req.arrayBuffer())),p.json({success:!0})}catch(m){let y=Ft(m);return p.json({error:y},400)}});let g={log:console.log};d.post("/__api/:name",async p=>{try{let m=o?.(),y=p.req.param("name"),v=m?.[y]??g[y];if(!v||typeof v!="function")return p.json({error:`API function '${y}' not found`},404);let{args:w}=await p.req.json(),T=await v(...w||[]);return p.json({result:T})}catch(m){let y=Ft(m);return p.json({error:y},500)}}),d.post("/__ai",async p=>{try{let{messages:m,system:y,reasoning:v,provider:w,model:T,webSearch:z}=await p.req.json();if(!m||!Array.isArray(m)||m.length===0)return p.json({message:"messages array is required",code:"unknown",retryable:!1},400);let Z=Ni(w,T);if(typeof Z=="string")return p.json({message:Z,code:"unknown",retryable:!1},400);let Jt=[...y?[{role:"system",content:y}]:[],...m.map(it=>({role:it.role,content:it.content}))],me=await yr(Z,{model:Z.model,messages:Jt,stream:!0,reasoning:v??0,webSearch:z??!0});if(!me.ok){let it=await br(me,Z.protocol);return p.json(it,me.status)}let $r=await vr(me,Z.protocol);return $r||console.warn("[tb.ai] Empty response from provider"),p.json({text:$r})}catch(m){if(m instanceof N)return p.json({message:m.message,code:m.code,retryable:m.retryable},500);let y=Ft(m);return p.json({message:y,code:"unknown",retryable:!1},500)}}),d.get("/__models",async p=>{try{let m=await $t();return p.json(m)}catch{return p.json([],200)}});let x=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"],$=new Dt;if(d.get("/proxy/*",async p=>{let m=new URL(p.req.url),v=(m.pathname+m.search).slice(7),w=v.lastIndexOf("https://");return w===-1?p.text("Invalid proxy URL",400):O(p,v.slice(w))}),i){let p=`/local/${i.name}/`;d.get("/local/*",async m=>{let{pathname:y}=new URL(m.req.url);if(!y.startsWith(p))return m.text("Not Found",404);let v=decodeURIComponent(y.slice(p.length));try{let w=Bt(v,i.serveDir),T=await oe.readFile(w);return new Response(T,{headers:{"Content-Type":ss(w)}})}catch{return m.text("Not Found",404)}})}if(l){let{mount:p,dir:m}=l;d.get(`${p}*`,async y=>{let{pathname:v}=new URL(y.req.url);if(!v.startsWith(p))return y.text("Not Found",404);let w=decodeURIComponent(v.slice(p.length));try{let T=Bt(w,m),z=await oe.readFile(T);return new Response(z,{headers:{"Content-Type":ss(T)}})}catch{return y.text("Not Found",404)}})}async function O(p,m){let y;try{y=new URL(m)}catch{return p.text("Invalid URL",400)}if(y.protocol!=="https:")return p.text("HTTPS only",400);if(!x.includes(y.hostname))return p.text("Host not allowed",403);let v=await $.get(m);if(v)return new Response(v.body,{status:200,headers:Sr(v.contentType,v.cacheControl)});try{let w=await fetch(m,{headers:{Accept:p.req.header("Accept")||"*/*"},redirect:"follow"});if(!w.ok)return p.text(`Upstream ${w.status}`,w.status);let T=w.headers.get("Content-Type")||void 0,z=w.headers.get("Cache-Control")||void 0;if(w.body){let[Z,Jt]=w.body.tee();return(async()=>{try{let me=await new Response(Jt).arrayBuffer();await $.set(m,{body:Buffer.from(me),contentType:T,cacheControl:z})}catch{}})(),new Response(Z,{status:w.status,headers:Sr(T,z)})}return new Response(null,{status:w.status,headers:Sr(T,z)})}catch(w){return p.text(`Proxy fetch failed: ${w instanceof Error?w.message:w}`,502)}}s&&d.get("/__reload",p=>Fi(p,async m=>{let y=()=>{m.writeSSE({event:"reload",data:""})};for(s.on("reload",y),m.onAbort(()=>{s.removeListener("reload",y)});;)await m.sleep(3e4)}));let E=/^\/(v\d+\/|stable\/|node\/|gh\/|@[^/]+\/[^@/]+@|[^@/]+@)/;d.notFound(async p=>{if(p.req.method!=="GET")return p.text("Not Found",404);let m=new URL(p.req.url);return E.test(m.pathname)?O(p,"https://esm.sh"+m.pathname+m.search):p.text("Not Found",404)});let R=Di({fetch:d.fetch,port:n,hostname:os});return{port:n,close:()=>R.close()}}function Ni(r,e){let t=r??process.env.TB_AI_PROVIDER,n=e??process.env.TB_AI_MODEL;if(!t)return"No provider specified. Set TB_AI_PROVIDER in your .env file or pass provider in the tb.ai() call.";if(!n)return"No model specified. Set TB_AI_MODEL in your .env file or pass model in the tb.ai() call.";let s;try{s=pe(t)}catch{return`Unknown provider '${t}'.`}let o=Ce[t],i=process.env[o];return i?{apiKey:i,baseUrl:s.defaultBaseUrl,protocol:t,model:n,isFreeModel:!1}:`No API key for '${t}'. Set ${o} in your .env file.`}function Sr(r,e){let t=new Headers;return r&&t.set("Content-Type",r),e&&t.set("Cache-Control",e),t.set("Access-Control-Allow-Origin","*"),t.set("Cross-Origin-Resource-Policy","cross-origin"),t}function ss(r){switch(H.extname(r).toLowerCase()){case".js":case".mjs":return"text/javascript";case".wasm":return"application/wasm";case".json":case".map":return"application/json";default:return"application/octet-stream"}}function Bt(r,e){let t=H.resolve(e,r),n=H.normalize(e),s=H.normalize(t);if(s!==n&&!s.startsWith(n+H.sep))throw new Error("Path traversal detected - access denied");return t}async function ot(r){let e=await import("net");return new Promise(t=>{let n=e.createServer();n.listen(r,os,()=>{let s=n.address(),o=typeof s=="object"&&s?s.port:r;n.close(()=>t(o))}),n.on("error",()=>{t(ot(r+1))})})}import is from"chokidar";var as={persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}};function Nt(r){let{bulbPath:e,emitter:t}=r,n=is.watch(e,as);return n.on("change",()=>{t.emit("reload")}),()=>n.close()}function jt(r){let{dir:e,onChange:t,debounceMs:n=150}=r,s,o=is.watch(e,as);return o.on("all",()=>{s&&clearTimeout(s),s=setTimeout(t,n)}),()=>{s&&clearTimeout(s),o.close()}}ue();async function ds(r,e,t,n,s){let o=process.cwd(),i=Ct(process.pid),a=e.watch?new cs:void 0,c=se(e.mode);console.log(`Loading ${Ae.basename(r)}...`);let{html:l,bulb:d,serverExports:u}=await lr(r,e.watch,e.trust,n,s);Te(c,r,d.server);let f=await ot(e.port),h=await Mt({getHtml:()=>l,basePath:o,port:f,reloadEmitter:a,getServerExports:()=>u,localOverride:n?{name:n.name,serveDir:n.serveDir}:void 0,trusted:e.trust,trustHint:t}),g=`http://localhost:${f}`,x=e.trust?void 0:ke(d);await At({pid:process.pid,port:f,url:g,file:r,cwd:process.cwd(),startedAt:Date.now(),trust:e.trust,predicted:x}),console.log(`
669
+ ${d.name}`),console.log(` ${g}`),f!==e.port&&console.log(` (port ${e.port} was busy)`),e.trust?console.log(" trust: granted (filesystem, AI, server.ts enabled)"):console.log(x?` trust: sandboxed \u2014 this bulb appears to use ${x}; re-run with --trust to enable it:
666
670
  ${t}
667
671
  `:` trust: sandboxed \u2014 re-run with --trust to enable filesystem / AI / server.ts
668
672
  `),e.watch&&console.log(` Watching for changes...
669
- `);let B,N;if(e.watch&&a){let u=new Un;if(u.on("reload",async()=>{try{console.log("Recompiling...");let f=await Ut(r,!0,e.trust,n,s);l=f.html,d=f.serverExports,a.emit("reload"),console.log(`Done. Browser reloading...
670
- `)}catch(f){console.error("Compile error:",f)}}),B=wt({bulbPath:r,emitter:u}),n){let{name:f,serveDir:b}=n;N=Nn({dir:b,onChange:()=>{console.log(`Local package '${f}' changed. Browser reloading...
671
- `),a.emit("reload")}})}}e.open&&await at(g);let _=async()=>{console.log(`
672
- Shutting down...`),h.close(),B?.(),N?.(),i(),await Gt(process.pid);let u=ve.join(ve.dirname(r),".typebulb","server.mjs");await Wn.rm(u,{force:!0}).catch(()=>{}),process.exit(0)};process.on("SIGINT",_),process.on("SIGTERM",_)}import*as Vn from"path";import{EventEmitter as Lo}from"events";async function Hn(r,e,t,n,s){let o=ge(t),i=!1,a=async()=>{let{bulb:c,config:l}=await W(r);i||(ht(o,r,c.server),i=!0),await Nt(c.server,s,n,l.dependencies)};if(console.log(`Running ${Vn.basename(r)}...`),await a(),e){console.log(`Watching for changes...
673
- `);let c=new Lo;c.on("reload",async()=>{try{console.log("Re-running..."),await a()}catch(l){console.error("Error:",l)}}),wt({bulbPath:r,emitter:c})}}var qn="0.10.6";async function No(){let r=pr(process.argv.slice(2));if(r.version&&(console.log(`typebulb ${qn}`),process.exit(0)),r.help&&(fr(),process.exit(0)),r.subcommand==="logs"){await An(r.file||void 0,{follow:r.follow,lines:r.lines});return}if(r.subcommand==="stop"){await In(r.file||void 0);return}if(r.subcommand==="skill"){await kn(qn);return}if(r.subcommand==="models"){await Pn(r.mode);return}if(r.subcommand==="check"&&r.file==="-"){await on(r.local);return}if(r.subcommand==="agent"){if(!r.agentTarget){await vn();return}me(r.agentTarget)||(console.error(`Unknown agent '${r.agentTarget}'. Known: ${Vt().join(", ")}.`),process.exit(1));let l=await Kt(process.cwd(),r.agentTarget);if(l){console.log(`Viewer '${r.agentTarget}' is already running for this project:
674
- ${l.url}`),r.open&&await at(l.url);return}r.file=r.agentTarget,r.subcommand="run"}if(r.subcommand==="trust"||r.subcommand==="untrust"){await ln(r.file||void 0,r.subcommand==="trust");return}let e,t=!1;if(!r.file||r.file==="."){let l=await qr(process.cwd());l||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=l}else e=q.resolve(r.file);if(!await zn.access(e).then(()=>!0,()=>!1)){let l=r.agentTarget?me(r.file):void 0;l?(e=l,t=!0):Vt().includes(r.file)?(console.error(`To open the ${r.file} agent viewer, run: npx typebulb agent:${r.file}`),process.exit(1)):(console.error(`File not found: ${e}`),process.exit(1))}e.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1));let s=r.file&&r.file!=="."?r.file:q.relative(process.cwd(),e)||q.basename(e),o=`npx typebulb --trust ${s.includes(" ")?`"${s}"`:s}`;if(r.subcommand==="predict"){await cn(e,o);return}if(t)r.trust=!r.noTrust,r.trust&&console.log("trust: granted (built-in bulb)");else{let l=!r.noTrust&&it(e);l&&!r.trust&&console.log("trust: granted from memory (run `typebulb untrust` to revoke)"),r.trust=r.noTrust?!1:r.trust||l}let i;try{i=await W(e)}catch{}let a;if(r.local){i&&!(r.local.name in(i.config.dependencies??{}))&&(console.error(`--replace: '${r.local.name}' is not a dependency in this bulb's config.json; nothing to replace.`),process.exit(1)),i&&(!i.bulb.code||r.server)&&console.warn("warning: --replace has no effect in server mode (the override is client-only).");try{a=await Je(r.local)}catch(l){console.error(l instanceof Error?l.message:String(l)),process.exit(1)}console.log(`replace: ${a.name} \u2192 ${q.relative(process.cwd(),a.dir)||"."}`)}if(r.subcommand==="check"){await sn(e,a);return}let c=t?process.cwd():q.dirname(e);if(i&&i.bulb.server&&(!i.bulb.code||r.server)){r.trust||(console.error(`This bulb runs server-side Node code (server.ts), which --trust must authorize:
675
- ${o}`),process.exit(1)),await Hn(e,r.watch,r.mode,a,c);return}await Jn(e,r,o,a,c)}No().catch(r=>{console.error("Error:",r.message),process.exit(1)});
673
+ `);let $,O;if(e.watch&&a){let R=new cs;if(R.on("reload",async()=>{try{console.log("Recompiling...");let p=await lr(r,!0,e.trust,n,s);l=p.html,u=p.serverExports,a.emit("reload"),console.log(`Done. Browser reloading...
674
+ `)}catch(p){console.error("Compile error:",p)}}),$=Nt({bulbPath:r,emitter:R}),n){let{name:p,serveDir:m}=n;O=jt({dir:m,onChange:()=>{console.log(`Local package '${p}' changed. Browser reloading...
675
+ `),a.emit("reload")}})}}e.open&&await Pe(g);let E=async()=>{console.log(`
676
+ Shutting down...`),h.close(),$?.(),O?.(),i(),await Qe(process.pid);let R=Ae.join(Ae.dirname(r),".typebulb","server.mjs");await ls.rm(R,{force:!0}).catch(()=>{}),process.exit(0)};process.on("SIGINT",E),process.on("SIGTERM",E)}import{readFileSync as js,copyFileSync as Ia,existsSync as $a}from"fs";import*as I from"path";import{fileURLToPath as Oa}from"url";import{EventEmitter as Da}from"events";ue();var Pr="/agents/claude/client.js";function ji(r,e){let t=n=>n.replace(/<\/script/gi,"<\\/script");return` <script>
677
+ (function() {
678
+ try {
679
+ var KEY = ${t(JSON.stringify("tb-theme:"+r))};
680
+ var doc = document.documentElement;
681
+ var mq = window.matchMedia('(prefers-color-scheme: dark)');
682
+ var os = function() { return mq.matches ? 'dark' : 'light'; };
683
+ var FORCED = ${t(JSON.stringify(e??null))};
684
+ var stored = function() {
685
+ try { var v = localStorage.getItem(KEY); return (v === 'dark' || v === 'light') ? v : undefined; }
686
+ catch (e) { return undefined; }
687
+ };
688
+ var apply = function(t) { doc.setAttribute('data-theme', t); };
689
+ var effective = function() { return stored() || FORCED || os(); };
690
+ var set = function(v) {
691
+ if (v === 'dark' || v === 'light') {
692
+ try { localStorage.setItem(KEY, v); } catch (e) {}
693
+ apply(v);
694
+ } else {
695
+ try { localStorage.removeItem(KEY); } catch (e) {}
696
+ apply(os());
697
+ }
698
+ };
699
+ apply(effective());
700
+ var onOsChange = function() { if (!stored()) apply(os()); };
701
+ mq.addEventListener ? mq.addEventListener('change', onOsChange) : mq.addListener(onOsChange);
702
+ window.__tbTheme = { get: stored, set: set, effective: effective };
703
+ window.addEventListener('keydown', function(e) {
704
+ if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.code === 'KeyL') {
705
+ e.preventDefault();
706
+ set(effective() === 'dark' ? 'light' : 'dark');
707
+ }
708
+ });
709
+ } catch (e) {}
710
+ })();
711
+ </script>`}var Li=`
712
+ (() => {
713
+ const api = async (name, ...args) => {
714
+ const resp = await fetch('/__api/' + name, {
715
+ method: 'POST',
716
+ headers: { 'Content-Type': 'application/json' },
717
+ body: JSON.stringify({ args })
718
+ });
719
+ const data = await resp.json();
720
+ if (!resp.ok) throw new Error(data.error || 'API call failed');
721
+ return data.result;
722
+ };
723
+ const serverLog = async (...args) => {
724
+ try {
725
+ const resp = await fetch('/__log', {
726
+ method: 'POST',
727
+ headers: { 'Content-Type': 'application/json' },
728
+ body: JSON.stringify({ args })
729
+ });
730
+ if (!resp.ok) console.log(...args);
731
+ } catch { console.log(...args); }
732
+ };
733
+ globalThis.tb = Object.freeze({
734
+ server: new Proxy({}, {
735
+ get: (_, name) => name === 'log'
736
+ ? (...args) => serverLog(...args)
737
+ : (...args) => api(name, ...args)
738
+ })
739
+ });
740
+ if (window.__TYPEBULB_WATCH__) {
741
+ const es = new EventSource('/__reload');
742
+ es.addEventListener('reload', () => { console.log('[typebulb] Reloading...'); window.location.reload(); });
743
+ es.onerror = () => { es.close(); };
744
+ }
745
+ })();
746
+ `;function Ui(r){return r.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function us(r){let{name:e,styles:t,mountHtml:n,watch:s,theme:o}=r;return`<!DOCTYPE html>
747
+ <html>
748
+ <head>
749
+ <meta charset="utf-8">
750
+ <meta name="viewport" content="width=device-width, initial-scale=1">
751
+ <title>${Ui(e)} - typebulb</title>
752
+ ${ji(e,o)}
753
+ <style>
754
+ *, *::before, *::after { box-sizing: border-box; }
755
+ body { margin: 0; font-family: system-ui, -apple-system, sans-serif; }
756
+ html[data-theme="dark"] { color-scheme: dark; }
757
+ html[data-theme="light"] { color-scheme: light; }
758
+ </style>
759
+ <style>
760
+ ${t}
761
+ </style>
762
+ </head>
763
+ <body>
764
+ ${n}
765
+
766
+ ${s?"<script>window.__TYPEBULB_WATCH__ = true;</script>":""}
767
+
768
+ <script>
769
+ ${Li}
770
+ </script>
771
+
772
+ <script type="module" src="${Pr}"></script>
773
+ </body>
774
+ </html>`}async function Ls(r){let e=process.cwd(),t=Ct(process.pid),n=r.watch?new Da:void 0,s=se(r.mode),o=await Promise.resolve().then(()=>(Ns(),Ms));Te(s,I.join(e,"viewer"));let i=I.dirname(Oa(import.meta.url)),a=I.join(i,"agents","claude"),c=I.join(i,"..","agents","claude"),l=I.join(a,"styles.css"),d=I.join(a,"index.html"),u=()=>us({name:"Claude Bulb",styles:js(l,"utf8"),mountHtml:js(d,"utf8"),watch:r.watch}),f=await ot(r.port),h=await Mt({getHtml:u,basePath:e,port:f,reloadEmitter:n,getServerExports:()=>o,trusted:!0,staticAssets:{mount:`${I.posix.dirname(Pr)}/`,dir:a}}),g=`http://localhost:${f}`;await At({pid:process.pid,port:f,url:g,file:"agent:claude",cwd:e,startedAt:Date.now(),trust:!0,agent:"claude"}),console.log(`
775
+ Claude Bulb`),console.log(` ${g}`),f!==r.port&&console.log(` (port ${r.port} was busy)`),r.watch&&console.log(` Watching for changes...
776
+ `);async function x(){await(await import("esbuild")).build({entryPoints:[I.join(c,"client","index.ts")],bundle:!0,platform:"browser",format:"esm",outfile:I.join(a,"client.js")});for(let R of["styles.css","index.html"])Ia(I.join(c,R),I.join(a,R))}let $;if(r.watch&&n){let E=$a(c),R=!1;$=jt({dir:E?c:a,onChange:async()=>{if(!R){R=!0;try{E&&await x(),console.log(`Viewer rebuilt. Browser reloading...
777
+ `),n.emit("reload")}catch(p){console.error("Viewer rebuild failed:",p instanceof Error?p.message:p)}finally{R=!1}}}})}r.open&&await Pe(g);let O=async()=>{console.log(`
778
+ Shutting down...`),h.close(),$?.(),t(),await Qe(process.pid),process.exit(0)};process.on("SIGINT",O),process.on("SIGTERM",O)}import*as Us from"path";import{EventEmitter as Fa}from"events";async function Ws(r,e,t,n,s){let o=se(t),i=!1,a=async()=>{let{bulb:c,config:l}=await K(r);i||(Te(o,r,c.server),i=!0),await cr(c.server,s,n,l.dependencies)};if(console.log(`Running ${Us.basename(r)}...`),await a(),e){console.log(`Watching for changes...
779
+ `);let c=new Fa;c.on("reload",async()=>{try{console.log("Re-running..."),await a()}catch(l){console.error("Error:",l)}}),Nt({bulbPath:r,emitter:c})}}var Js="0.11.0";async function Ba(){let r=Ur(process.argv.slice(2));if(r.version&&(console.log(`typebulb ${Js}`),process.exit(0)),r.help&&(Wr(),process.exit(0)),r.subcommand==="logs"){await Zn(r.file||void 0,{follow:r.follow,lines:r.lines});return}if(r.subcommand==="stop"){await es(r.file||void 0);return}if(r.subcommand==="skill"){await Gn(Js);return}if(r.subcommand==="models"){await Hn(r.mode);return}if(r.subcommand==="agent"){if(!r.agentTarget){await Un();return}En(r.agentTarget)||(console.error(`Unknown agent '${r.agentTarget}'. Known: ${fr().join(", ")}.`),process.exit(1));let l=await gr(process.cwd(),r.agentTarget);if(l){console.log(`Viewer '${r.agentTarget}' is already running for this project:
780
+ ${l.url}`),r.open&&await Pe(l.url);return}await Ls(r);return}if(r.subcommand==="trust"||r.subcommand==="untrust"){await On(r.file||void 0,r.subcommand==="trust");return}let e;if(!r.file||r.file==="."){let l=await vn(process.cwd());l||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=l}else e=Q.resolve(r.file);await Vs.access(e).then(()=>!0,()=>!1)||(fr().includes(r.file)&&(console.error(`To open the ${r.file} agent viewer, run: npx typebulb agent:${r.file}`),process.exit(1)),console.error(`File not found: ${e}`),process.exit(1)),e.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1));let n=r.file&&r.file!=="."?r.file:Q.relative(process.cwd(),e)||Q.basename(e),s=`npx typebulb --trust ${n.includes(" ")?`"${n}"`:n}`;if(r.subcommand==="predict"){await $n(e,s);return}let o=!r.noTrust&&de(e);o&&!r.trust&&console.log("trust: granted from memory (run `typebulb untrust` to revoke)"),r.trust=r.noTrust?!1:r.trust||o;let i;try{i=await K(e)}catch{}let a;if(r.local){i&&!(r.local.name in(i.config.dependencies??{}))&&(console.error(`--replace: '${r.local.name}' is not a dependency in this bulb's config.json; nothing to replace.`),process.exit(1)),i&&(!i.bulb.code||r.server)&&console.warn("warning: --replace has no effect in server mode (the override is client-only).");try{a=await jr(r.local)}catch(l){console.error(l instanceof Error?l.message:String(l)),process.exit(1)}console.log(`replace: ${a.name} \u2192 ${Q.relative(process.cwd(),a.dir)||"."}`)}if(r.subcommand==="check"){await In(e,a);return}let c=Q.dirname(e);if(i&&i.bulb.server&&(!i.bulb.code||r.server)){r.trust||(console.error(`This bulb runs server-side Node code (server.ts), which --trust must authorize:
781
+ ${s}`),process.exit(1)),await Ws(e,r.watch,r.mode,a,c);return}await ds(e,r,s,a,c)}Ba().catch(r=>{console.error("Error:",r.message),process.exit(1)});