typebulb 0.7.1 → 0.8.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,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import*as _ from"fs/promises";import{readFileSync as On}from"fs";import*as P from"path";import{pathToFileURL as An}from"url";import{execFile as Mn,spawn as $n}from"child_process";import{promisify as Fn}from"util";import{EventEmitter as wt}from"events";var yr={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 bt(s){try{let e=s.split(`
3
- `),t=0;if(e[t]?.trim()!=="---")return null;t++;let r=[];for(;t<e.length&&e[t]?.trim()!=="---";)r.push(e[t]),t++;if(e[t]?.trim()!=="---")return null;t++;let n=wr(r);if(!n)return null;let o=new Map;for(;t<e.length;){let a=e[t]?.trim()?.match(/^\*\*(.+)\*\*$/);if(a){let l=a[1].trim();for(t++;t<e.length&&e[t]?.trim()==="";)t++;let d=e[t]?.match(/^(`{3,})(\w*)\s*$/);if(!d){t++;continue}let u=d[1];t++;let f=[];for(;t<e.length&&!e[t]?.match(new RegExp(`^${u}\\s*$`));)f.push(e[t]),t++;t++,o.set(l,f.join(`
4
- `))}else t++}return{frontmatter:n,files:o}}catch{return null}}function wr(s){let e={};for(let t of s){let r=t.indexOf(":");if(r===-1)continue;let n=t.slice(0,r).trim(),o=t.slice(r+1).trim();switch(n){case"format":e.format=o;break;case"name":e.name=vr(o);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function vr(s){return s.startsWith('"')&&s.endsWith('"')?s.slice(1,-1).replace(/\\"/g,'"'):s.startsWith("'")&&s.endsWith("'")?s.slice(1,-1):s}function xt(s){let e=t=>s.files.get(yr[t].path)||"";return{name:s.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 br(s){try{return JSON.parse(s),!0}catch{}return!!(/^\s*<[\s\S]*>/.test(s)||/^---\s*$/m.test(s)||/^\w[\w\s]*:[ \t]/m.test(s))}function Pt(s){let e=s.trim();return e?br(e)?[e]:s.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function St(s){if(!s.trim())return{};try{return JSON.parse(s)}catch{return{}}}import{transform as xr}from"sucrase";function Ve(s,e={}){let t=e.serverOnly?["typescript"]:["typescript","jsx"];try{let{code:r}=xr(s,{transforms:t,jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:r}}catch(r){return{code:"",error:String(r)}}}var oe="https://esm.sh",ie="https://cdn.jsdelivr.net/npm/",He="https://data.jsdelivr.com/v1/package/npm/";function Rt(s){let e=(s||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var m=class s{constructor(e,t,r){let n=typeof e=="string"?s.parse(e):e;this.name=n.name,this.version=X(t??n.version),this.subpath=X(r??n.subpath)}static parse(e){let t=Rt(e||"");if(!t.length)return new s({name:""});if(t[0].startsWith("@")){let n=t[0],[o,i]=Et(t[1]??""),a=X(t.slice(2).join("/"));return new s({name:`${n}/${o}`,version:i,subpath:a})}else{let[n,o]=Et(t[0]),i=X(t.slice(1).join("/"));return new s({name:n,version:o,subpath:i})}}static fromUrl(e){try{let t=new URL(e),r=new URL(oe).host,n=new URL(ie).host;if(t.host===r){let o=Rt(t.pathname.replace(/^\/v\d+\//,"/"));if(!o.length)return;let i=o[0].startsWith("@")?`${o[0]}/${o[1]??""}`:o[0];return s.parse(i)}if(t.host===n){let o=t.pathname.split("/npm/")[1];if(!o)return;let i=o.split("/")[0]||"";return s.parse(i)}return}catch{return}}static versionFromUrl(e){return s.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 s.parse(e).name}withVersion(e){return new s({name:this.name,version:X(e),subpath:this.subpath})}withPreferredVersion(e,t){let r=e||t;return r?this.withVersion(r):this}static isBare(e){if(!e||e.startsWith(".")||e.startsWith("/"))return!1;let t=e.toLowerCase();return!t.startsWith("http://")&&!t.startsWith("https://")}},X=s=>s&&s.length?s:void 0,Et=s=>{let e=s.indexOf("@");return e<0?[s,void 0]:[s.slice(0,e),X(s.slice(e+1))]};async function E(s){try{return await s()}catch{return}}var ae=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=oe,this.jsDelivrBase=ie,this.jsDelivrMeta=He,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 m(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:r="es2022",bundle:n=!1,external:o}=t,i=new URLSearchParams({target:r});return n&&i.append("bundle",""),o?.length&&i.append("external",o.join(",")),`${this.esmHost}/${e}?${i.toString()}`}async pinEsmUrl(e,t="es2022"){let r=this.buildEsmUrl(e,{target:t}),n=await E(()=>this.http.head(r));return n?.ok?n.url||r:void 0}async resolveExactVersion(e){let t=Date.now(),r=this.pinCache.get(e);if(r&&t-r.ts<this.pinMs)return r.value;let n=await this.tryResolveFromUrls([this.buildEsmUrl(e),`${this.esmHost}/${e}`]);return this.pinCache.set(e,{value:n,ts:t}),n}async tryResolveFromUrls(e){for(let t of e){let r=await E(()=>this.http.head(t)),n=this.parseVersionFromUrl(r?.url||t);if(n)return n}}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 r=await E(()=>this.http.getJson(`${this.jsDelivrMeta}${encodeURIComponent(e)}`));if(!r?.versions?.length){await this.cache.recordNegative(e);return}await this.cache.clearNegative(e);let n=r.distTags&&Object.keys(r.distTags).length?r.distTags:void 0;return await this.cache.setIndex(e,r.versions,n),r}parseVersionFromUrl(e){let t=m.fromUrl(e)?.version;return t&&/\d+\.\d+\.\d+/.test(t)?t:void 0}async fetchPackageMeta(e,t){let r=await this.cache.getMeta(e,t);if(r&&Date.now()-r.updatedAt<this.metaTtlMs){let{dependencies:u,peerDependencies:f,peerDependenciesMeta:h}=r;return{name:e,version:t,dependencies:u,peerDependencies:f,peerDependenciesMeta:h}}let n=this.packageJson(new m(`${e}@${t}`)),o=await E(()=>this.http.getJson(n));if(!o)return;let i=u=>u&&Object.keys(u).length?u:void 0,a=i(o.dependencies),l=i(o.peerDependencies),d=i(o.peerDependenciesMeta);return await this.cache.setMeta(e,t,a,l,d),{name:e,version:t,dependencies:a,peerDependencies:l,peerDependenciesMeta:d}}};var kt=s=>s.startsWith("@types/"),ce=s=>Object.keys(s?.peerDependencies||{}).filter(e=>!kt(e)),qe=s=>Object.keys(s?.dependencies||{}).filter(e=>!kt(e)),Pr=s=>ce(s).filter(e=>!s?.peerDependenciesMeta?.[e]?.optional),le=class{constructor(e){this.cdn=e}async resolve(e,t){let r=await this.fetchMeta(e),{allRoots:n,autoAddedPeers:o}=await this.expandWithPeers(r,t),i=this.computeFlags(n);return{allRoots:n,flags:i,autoAddedPeers:o}}async fetchMeta(e){return Promise.all(e.map(async({name:t,version:r})=>({name:t,version:r,meta:await this.cdn.fetchPackageMeta(t,r)})))}async expandWithPeers(e,t){let r=new Map(e.map(o=>[o.name,o])),n=[];for(let o of e)for(let i of Pr(o.meta))!r.has(i)&&!n.some(a=>a.name===i)&&n.push({name:i,requiredBy:o.name});for(let{name:o,requiredBy:i}of n)try{let a=await t(o),l=await this.cdn.fetchPackageMeta(o,a);r.set(o,{name:o,version:a,meta:l})}catch(a){console.warn(`[typebulb] Failed to resolve peer "${o}" for "${i}":`,a)}return{allRoots:[...r.values()],autoAddedPeers:n.filter(o=>r.has(o.name))}}computeFlags(e){let t=new Set(e.flatMap(o=>ce(o.meta))),r=new Map;for(let o of e)for(let i of qe(o.meta))r.set(i,(r.get(i)||0)+1);let n=new Set([...r.entries()].filter(([,o])=>o>=2).map(([o])=>o));return new Map(e.map(o=>[o.name,{isPeerRoot:t.has(o.name),hasPeers:ce(o.meta).length>0,isSharedDep:n.has(o.name)}]))}};var de=class{constructor(e,t,r){this.cache=e,this.cdn=t,this.semver=r}selectVersionFromIndex(e,t,r){return this.semver.selectBestVersion(e,{range:t,distTags:r})}async learnExactVersion(e){let t=await E(()=>this.cdn.fetchVersionsIndex(e));if(t?.versions?.length){let r=this.semver.selectBestVersion(t.versions,{distTags:t.distTags});if(r)return r}return this.cdn.resolveExactVersion(e)}async resolveExactForRoot(e,t){if(!t)return this.learnExactVersion(e);let r=await this.cache.getPinnedExact(e,t);if(r){if(this.semver.isExactVersion(r))return r;console.warn("[versionResolver] Rejecting invalid cached version for",e,":",r)}let n=await E(()=>this.cdn.fetchVersionsIndex(e));if(n?.versions?.length){let i=this.selectVersionFromIndex(n.versions,t,n.distTags);if(i){if(this.semver.isExactVersion(i))return await this.cache.setPinnedExact(e,t,i),i}else{console.warn("[versionResolver] Invalidating stale versions cache for",e,"- range",t,"not satisfied"),await this.cache.invalidateVersionsCache(e);let a=await E(()=>this.cdn.fetchVersionsIndex(e));if(a?.versions?.length){let l=this.selectVersionFromIndex(a.versions,t,a.distTags);if(l&&this.semver.isExactVersion(l))return await this.cache.setPinnedExact(e,t,l),l}}}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 r=new m(e),n=r.root(),o=t[n],i=o?await E(()=>this.cache.getPinnedExact(n,o))??await E(()=>this.resolveExactForRoot(n,o)):void 0;return{effectivePackage:i?r.withVersion(i).format():e,root:n,range:o,pinned:i}}};import{init as Sr,parse as Rr}from"es-module-lexer";var Q=class s{constructor(e,t,r,n){this.version=e,this.cdn=t,this.peer=r,this.cache=n}extractImportsSync(e){let t=new Set;for(let r of s.importPatterns){r.lastIndex=0;for(let n of e.matchAll(r))m.isBare(n[1])&&t.add(n[1])}return Array.from(t)}async extractImports(e){let t=new Set,r=n=>{m.isBare(n)&&t.add(n)};try{await Sr;let[n]=Rr(e);n.forEach(o=>r(e.slice(o.s,o.e).trim()))}catch{return this.extractImportsSync(e)}return Array.from(t)}async buildImportMap(e,t,r){let n=(await this.extractImports(e)).filter(f=>!r?.has(m.rootOf(f))),o=[...new Set(n.map(m.rootOf))],i=await Promise.all(o.map(async f=>({name:f,version:await this.resolveVersion(f,t)}))),{allRoots:a,flags:l,autoAddedPeers:d}=await this.peer.resolve(i,f=>this.resolveVersion(f,t)),u=this.buildEntries([...n,...d.map(f=>f.name)],a,l,t);return{importMap:{imports:Object.fromEntries(u)},prefetchUrls:u.map(([,f])=>f)}}async resolveVersion(e,t){let r=t[e],n=r?`${e}@${r}`:e,o=await this.version.resolveExactForRoot(e,r);if(!o){let i=await E(()=>this.cdn.pinEsmUrl(n));if(!i)throw new Error(`Cannot resolve ${n}: no matching version is published (the package or version may not exist, or the registry was unreachable).`);o=m.versionFromUrl(i),o&&r&&await E(()=>this.cache.setPinnedExact(e,r,o))}if(!o)throw new Error(`Cannot resolve ${n}: no concrete version found.`);return o}buildEntries(e,t,r,n){let o=new Map(t.map(c=>[c.name,c])),i=c=>{let p=o.get(m.rootOf(c));return new m(c).withPreferredVersion(p.version,n[p.name]).format()},a=new Set([...r.entries()].filter(([,c])=>c.isPeerRoot||c.isSharedDep).map(([c])=>c)),l=new Set(e.filter(c=>c!==m.rootOf(c)).map(m.rootOf)),d=[],u=new Set,f=new Set(e.filter(c=>c===m.rootOf(c))),h=new Set;for(let c of e){let p=m.rootOf(c),g=o.get(p),{isPeerRoot:v,hasPeers:w,isSharedDep:I}=r.get(p),W=l.has(p),$=c!==p,N=!(v||I)&&(W||!w),Y=this.singletonDepsOf(g,a),J=$&&f.has(p);J&&h.add(p);let gr=J?[...Y,p]:Y.length?Y:void 0;d.push([c,this.cdn.buildEsmUrl(i(c),{bundle:N,external:gr})]),u.add(c)}let y=new Set([...a,...h]);for(let c of y)o.has(c)&&(u.has(c)||d.push([c,this.cdn.buildEsmUrl(i(c),{})]),d.push([`${c}/`,`${this.cdn.esmHost}/${i(c)}/`]));return d}singletonDepsOf(e,t){return[...new Set([...ce(e.meta),...qe(e.meta)])].filter(r=>t.has(r))}};Q.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as Tt,satisfies as Er,maxSatisfying as Ge,major as kr,prerelease as Tr,rsort as Cr,valid as _r}from"semver";var Ce=class{cmp(e,t){return e===t?0:Tt(e,t)?1:Tt(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!Er(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let r=Ge(e,t,{includePrerelease:!0});return r===null?void 0:r}pickLatest(e){return e?.length?Cr(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let r=t?.range?.trim()||"*",n=t?.preferStable??!0,o=t?.distTags?.latest;if(o&&e.includes(o)&&this.satisfies(r,o))return o;if(n){let a=Ge(e,r,{includePrerelease:!1});if(a)return a}return Ge(e,r,{includePrerelease:!0})??void 0}majorOf(e){return kr(e)}isPrerelease(e){return Tr(e)!==null}isExactVersion(e){return _r(e)!==null}},V=new Ce;function Ct(s,e){let t=new ae(s,e),r=new le(t),n=new de(s,t,V);return{packageService:new Q(n,t,r,s),versionResolver:n,cdnClient:t,peerResolver:r}}import*as Jt from"fs/promises";import*as O from"path";var ze=[{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"}],Ke=[{name:"dom"},{name:"dom.iterable"},{name:"dom.asynciterable"}];var _t=`
2
+ import*as O from"fs/promises";import{readFileSync as Nn}from"fs";import*as S from"path";import{pathToFileURL as Ln}from"url";import{execFile as Un,spawn as Bn}from"child_process";import{promisify as Wn}from"util";import{EventEmitter as bt}from"events";var xr={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 Pt(s){try{let e=s.split(`
3
+ `),t=0;if(e[t]?.trim()!=="---")return null;t++;let r=[];for(;t<e.length&&e[t]?.trim()!=="---";)r.push(e[t]),t++;if(e[t]?.trim()!=="---")return null;t++;let n=Pr(r);if(!n)return null;let i=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 d=e[t]?.match(/^(`{3,})(\w*)\s*$/);if(!d){t++;continue}let u=d[1];t++;let p=[];for(;t<e.length&&!e[t]?.match(new RegExp(`^${u}\\s*$`));)p.push(e[t]),t++;t++,i.set(c,p.join(`
4
+ `))}else t++}return{frontmatter:n,files:i}}catch{return null}}function Pr(s){let e={};for(let t of s){let r=t.indexOf(":");if(r===-1)continue;let n=t.slice(0,r).trim(),i=t.slice(r+1).trim();switch(n){case"format":e.format=i;break;case"name":e.name=Sr(i);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function Sr(s){return s.startsWith('"')&&s.endsWith('"')?s.slice(1,-1).replace(/\\"/g,'"'):s.startsWith("'")&&s.endsWith("'")?s.slice(1,-1):s}function St(s){let e=t=>s.files.get(xr[t].path)||"";return{name:s.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 Rr(s){try{return JSON.parse(s),!0}catch{}return!!(/^\s*<[\s\S]*>/.test(s)||/^---\s*$/m.test(s)||/^\w[\w\s]*:[ \t]/m.test(s))}function Rt(s){let e=s.trim();return e?Rr(e)?[e]:s.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function Et(s){if(!s.trim())return{};try{return JSON.parse(s)}catch{return{}}}import{transform as Er}from"sucrase";function qe(s,e={}){let t=e.serverOnly?["typescript"]:["typescript","jsx"];try{let{code:r}=Er(s,{transforms:t,jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:r}}catch(r){return{code:"",error:String(r)}}}var ae="https://esm.sh",ce="https://cdn.jsdelivr.net/npm/",Ge="https://data.jsdelivr.com/v1/package/npm/";function kt(s){let e=(s||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var y=class s{constructor(e,t,r){let n=typeof e=="string"?s.parse(e):e;this.name=n.name,this.version=X(t??n.version),this.subpath=X(r??n.subpath)}static parse(e){let t=kt(e||"");if(!t.length)return new s({name:""});if(t[0].startsWith("@")){let n=t[0],[i,o]=Tt(t[1]??""),a=X(t.slice(2).join("/"));return new s({name:`${n}/${i}`,version:o,subpath:a})}else{let[n,i]=Tt(t[0]),o=X(t.slice(1).join("/"));return new s({name:n,version:i,subpath:o})}}static fromUrl(e){try{let t=new URL(e),r=new URL(ae).host,n=new URL(ce).host;if(t.host===r){let i=kt(t.pathname.replace(/^\/v\d+\//,"/"));if(!i.length)return;let o=i[0].startsWith("@")?`${i[0]}/${i[1]??""}`:i[0];return s.parse(o)}if(t.host===n){let i=t.pathname.split("/npm/")[1];if(!i)return;let o=i.split("/")[0]||"";return s.parse(o)}return}catch{return}}static versionFromUrl(e){return s.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 s.parse(e).name}withVersion(e){return new s({name:this.name,version:X(e),subpath:this.subpath})}withPreferredVersion(e,t){let r=e||t;return r?this.withVersion(r):this}static isBare(e){if(!e||e.startsWith(".")||e.startsWith("/"))return!1;let t=e.toLowerCase();return!t.startsWith("http://")&&!t.startsWith("https://")}},X=s=>s&&s.length?s:void 0,Tt=s=>{let e=s.indexOf("@");return e<0?[s,void 0]:[s.slice(0,e),X(s.slice(e+1))]};async function k(s){try{return await s()}catch{return}}var le=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=ae,this.jsDelivrBase=ce,this.jsDelivrMeta=Ge,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:r="es2022",bundle:n=!1,external:i}=t,o=new URLSearchParams({target:r});return n&&o.append("bundle",""),i?.length&&o.append("external",i.join(",")),`${this.esmHost}/${e}?${o.toString()}`}async pinEsmUrl(e,t="es2022"){let r=this.buildEsmUrl(e,{target:t}),n=await k(()=>this.http.head(r));return n?.ok?n.url||r:void 0}async resolveExactVersion(e){let t=Date.now(),r=this.pinCache.get(e);if(r&&t-r.ts<this.pinMs)return r.value;let n=await this.tryResolveFromUrls([this.buildEsmUrl(e),`${this.esmHost}/${e}`]);return this.pinCache.set(e,{value:n,ts:t}),n}async tryResolveFromUrls(e){for(let t of e){let r=await k(()=>this.http.head(t)),n=this.parseVersionFromUrl(r?.url||t);if(n)return n}}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 r=await k(()=>this.http.getJson(`${this.jsDelivrMeta}${encodeURIComponent(e)}`));if(!r?.versions?.length){await this.cache.recordNegative(e);return}await this.cache.clearNegative(e);let n=r.distTags&&Object.keys(r.distTags).length?r.distTags:void 0;return await this.cache.setIndex(e,r.versions,n),r}parseVersionFromUrl(e){let t=y.fromUrl(e)?.version;return t&&/\d+\.\d+\.\d+/.test(t)?t:void 0}async fetchPackageMeta(e,t){let r=await this.cache.getMeta(e,t);if(r&&Date.now()-r.updatedAt<this.metaTtlMs){let{dependencies:u,peerDependencies:p,peerDependenciesMeta:m}=r;return{name:e,version:t,dependencies:u,peerDependencies:p,peerDependenciesMeta:m}}let n=this.packageJson(new y(`${e}@${t}`)),i=await k(()=>this.http.getJson(n));if(!i)return;let o=u=>u&&Object.keys(u).length?u:void 0,a=o(i.dependencies),c=o(i.peerDependencies),d=o(i.peerDependenciesMeta);return await this.cache.setMeta(e,t,a,c,d),{name:e,version:t,dependencies:a,peerDependencies:c,peerDependenciesMeta:d}}};var Ct=s=>s.startsWith("@types/"),de=s=>Object.keys(s?.peerDependencies||{}).filter(e=>!Ct(e)),ze=s=>Object.keys(s?.dependencies||{}).filter(e=>!Ct(e)),kr=s=>de(s).filter(e=>!s?.peerDependenciesMeta?.[e]?.optional),pe=class{constructor(e){this.cdn=e}async resolve(e,t){let r=await this.fetchMeta(e),{allRoots:n,autoAddedPeers:i}=await this.expandWithPeers(r,t),o=this.computeFlags(n);return{allRoots:n,flags:o,autoAddedPeers:i}}async fetchMeta(e){return Promise.all(e.map(async({name:t,version:r})=>({name:t,version:r,meta:await this.cdn.fetchPackageMeta(t,r)})))}async expandWithPeers(e,t){let r=new Map(e.map(i=>[i.name,i])),n=[];for(let i of e)for(let o of kr(i.meta))!r.has(o)&&!n.some(a=>a.name===o)&&n.push({name:o,requiredBy:i.name});for(let{name:i,requiredBy:o}of n)try{let a=await t(i),c=await this.cdn.fetchPackageMeta(i,a);r.set(i,{name:i,version:a,meta:c})}catch(a){console.warn(`[typebulb] Failed to resolve peer "${i}" for "${o}":`,a)}return{allRoots:[...r.values()],autoAddedPeers:n.filter(i=>r.has(i.name))}}computeFlags(e){let t=new Set(e.flatMap(i=>de(i.meta))),r=new Map;for(let i of e)for(let o of ze(i.meta))r.set(o,(r.get(o)||0)+1);let n=new Set([...r.entries()].filter(([,i])=>i>=2).map(([i])=>i));return new Map(e.map(i=>[i.name,{isPeerRoot:t.has(i.name),hasPeers:de(i.meta).length>0,isSharedDep:n.has(i.name)}]))}};var ue=class{constructor(e,t,r){this.cache=e,this.cdn=t,this.semver=r}selectVersionFromIndex(e,t,r){return this.semver.selectBestVersion(e,{range:t,distTags:r})}async learnExactVersion(e){let t=await k(()=>this.cdn.fetchVersionsIndex(e));if(t?.versions?.length){let r=this.semver.selectBestVersion(t.versions,{distTags:t.distTags});if(r)return r}return this.cdn.resolveExactVersion(e)}async resolveExactForRoot(e,t){if(!t)return this.learnExactVersion(e);let r=await this.cache.getPinnedExact(e,t);if(r){if(this.semver.isExactVersion(r))return r;console.warn("[versionResolver] Rejecting invalid cached version for",e,":",r)}let n=await k(()=>this.cdn.fetchVersionsIndex(e));if(n?.versions?.length){let o=this.selectVersionFromIndex(n.versions,t,n.distTags);if(o){if(this.semver.isExactVersion(o))return await this.cache.setPinnedExact(e,t,o),o}else{console.warn("[versionResolver] Invalidating stale versions cache for",e,"- range",t,"not satisfied"),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 i=await this.cdn.resolveExactVersion(`${e}@${t}`);if(i&&this.semver.isExactVersion(i))return await this.cache.setPinnedExact(e,t,i),i}async effectivePackage(e,t){let r=new y(e),n=r.root(),i=t[n],o=i?await k(()=>this.cache.getPinnedExact(n,i))??await k(()=>this.resolveExactForRoot(n,i)):void 0;return{effectivePackage:o?r.withVersion(o).format():e,root:n,range:i,pinned:o}}};import{init as Tr,parse as Cr}from"es-module-lexer";var Q=class s{constructor(e,t,r,n){this.version=e,this.cdn=t,this.peer=r,this.cache=n}extractImportsSync(e){let t=new Set;for(let r of s.importPatterns){r.lastIndex=0;for(let n of e.matchAll(r))y.isBare(n[1])&&t.add(n[1])}return Array.from(t)}async extractImports(e){let t=new Set,r=n=>{y.isBare(n)&&t.add(n)};try{await Tr;let[n]=Cr(e);n.forEach(i=>r(e.slice(i.s,i.e).trim()))}catch{return this.extractImportsSync(e)}return Array.from(t)}async buildImportMap(e,t,r){let n=(await this.extractImports(e)).filter(p=>!r?.has(y.rootOf(p))),i=[...new Set(n.map(y.rootOf))],o=await Promise.all(i.map(async p=>({name:p,version:await this.resolveVersion(p,t)}))),{allRoots:a,flags:c,autoAddedPeers:d}=await this.peer.resolve(o,p=>this.resolveVersion(p,t)),u=this.buildEntries([...n,...d.map(p=>p.name)],a,c,t);return{importMap:{imports:Object.fromEntries(u)},prefetchUrls:u.map(([,p])=>p)}}async resolveVersion(e,t){let r=t[e],n=r?`${e}@${r}`:e,i=await this.version.resolveExactForRoot(e,r);if(!i){let o=await k(()=>this.cdn.pinEsmUrl(n));if(!o)throw new Error(`Cannot resolve ${n}: no matching version is published (the package or version may not exist, or the registry was unreachable).`);i=y.versionFromUrl(o),i&&r&&await k(()=>this.cache.setPinnedExact(e,r,i))}if(!i)throw new Error(`Cannot resolve ${n}: no concrete version found.`);return i}buildEntries(e,t,r,n){let i=new Map(t.map(h=>[h.name,h])),o=h=>{let l=i.get(y.rootOf(h));return new y(h).withPreferredVersion(l.version,n[l.name]).format()},a=new Set([...r.entries()].filter(([,h])=>h.isPeerRoot||h.isSharedDep).map(([h])=>h)),c=new Set(e.filter(h=>h!==y.rootOf(h)).map(y.rootOf)),d=[],u=new Set,p=new Set(e.filter(h=>h===y.rootOf(h))),m=new Set;for(let h of e){let l=y.rootOf(h),f=i.get(l),{isPeerRoot:g,hasPeers:b,isSharedDep:v}=r.get(l),I=c.has(l),J=h!==l,ie=!(g||v)&&(I||!b),F=this.singletonDepsOf(f,a),oe=J&&p.has(l);oe&&m.add(l);let Y=oe?[...F,l]:F.length?F:void 0;d.push([h,this.cdn.buildEsmUrl(o(h),{bundle:ie,external:Y})]),u.add(h)}let w=new Set([...a,...m]);for(let h of w)i.has(h)&&(u.has(h)||d.push([h,this.cdn.buildEsmUrl(o(h),{})]),d.push([`${h}/`,`${this.cdn.esmHost}/${o(h)}/`]));return d}singletonDepsOf(e,t){return[...new Set([...de(e.meta),...ze(e.meta)])].filter(r=>t.has(r))}};Q.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as _t,satisfies as _r,maxSatisfying as Ke,major as Or,prerelease as Ir,rsort as Dr,valid as Ar}from"semver";var _e=class{cmp(e,t){return e===t?0:_t(e,t)?1:_t(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!_r(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let r=Ke(e,t,{includePrerelease:!0});return r===null?void 0:r}pickLatest(e){return e?.length?Dr(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let r=t?.range?.trim()||"*",n=t?.preferStable??!0,i=t?.distTags?.latest;if(i&&e.includes(i)&&this.satisfies(r,i))return i;if(n){let a=Ke(e,r,{includePrerelease:!1});if(a)return a}return Ke(e,r,{includePrerelease:!0})??void 0}majorOf(e){return Or(e)}isPrerelease(e){return Ir(e)!==null}isExactVersion(e){return Ar(e)!==null}},V=new _e;function Ot(s,e){let t=new le(s,e),r=new pe(t),n=new ue(s,t,V);return{packageService:new Q(n,t,r,s),versionResolver:n,cdnClient:t,peerResolver:r}}import*as Ht from"fs/promises";import*as A from"path";var Ye=[{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"}],Xe=[{name:"dom"},{name:"dom.iterable"},{name:"dom.asynciterable"}];var It=`
5
5
  /**
6
6
  * Get raw data chunk from the Data tab.
7
7
  * @param index - Chunk index (0-based). Separate chunks with 2 blank lines.
@@ -12,7 +12,7 @@ import*as _ from"fs/promises";import{readFileSync as On}from"fs";import*as P fro
12
12
  * @param index - Chunk index (0-based)
13
13
  * @throws If chunk is not valid JSON/JSON-ish
14
14
  */
15
- json<T = unknown>(index: number): T;`,It=`
15
+ json<T = unknown>(index: number): T;`,Dt=`
16
16
  /**
17
17
  * Get the insight data produced by the inference layer.
18
18
  *
@@ -21,7 +21,7 @@ import*as _ from"fs/promises";import{readFileSync as On}from"fs";import*as P fro
21
21
  *
22
22
  * @returns The parsed insight JSON, or undefined if no insight is available
23
23
  */
24
- insight<T = unknown>(): T | undefined;`,Dt=`
24
+ insight<T = unknown>(): T | undefined;`,At=`
25
25
  /**
26
26
  * General-purpose AI call.
27
27
  *
@@ -38,7 +38,7 @@ import*as _ from"fs/promises";import{readFileSync as On}from"fs";import*as P fro
38
38
  model?: string;
39
39
  /** Enable/disable web search. Default: on for BYOK, always off for free model. */
40
40
  webSearch?: boolean;
41
- }): Promise<{ text: string }>;`,Ot=`
41
+ }): Promise<{ text: string }>;`,Mt=`
42
42
  /**
43
43
  * Returns AI models available to the current user.
44
44
  * Models are filtered by the user's configured API keys.
@@ -53,15 +53,17 @@ import*as _ from"fs/promises";import{readFileSync as On}from"fs";import*as P fro
53
53
  friendlyName: string;
54
54
  /** Provider display name, e.g. "Anthropic" */
55
55
  providerName: string;
56
- }>>;`,Ir="\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;",At=`
56
+ }>>;`,Mr="\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;",$t=`
57
57
  /**
58
58
  * The mode this bulb is running in.
59
59
  *
60
60
  * - \`'local'\` \u2014 Running via the typebulb CLI
61
61
  * - \`'editor'\` \u2014 Running in the typebulb.com editor
62
62
  * - \`'published'\` \u2014 Running as a published/standalone bulb on typebulb.com
63
+ * - \`'embedded'\` \u2014 Running as a bulb embedded inside another bulb (sandboxed,
64
+ * client-only: AI, filesystem, and server RPC are unavailable)
63
65
  */
64
- mode: 'local' | 'editor' | 'published';`,Mt=`
66
+ mode: 'local' | 'editor' | 'published' | 'embedded';`,Ft=`
65
67
  /**
66
68
  * Local filesystem access (CLI only).
67
69
  *
@@ -75,7 +77,7 @@ import*as _ from"fs/promises";import{readFileSync as On}from"fs";import*as P fro
75
77
  readBytes(path: string): Promise<Uint8Array>;
76
78
  /** Write text or raw bytes to a file. Creates parent directories if needed. */
77
79
  write(path: string, content: string | Uint8Array): Promise<boolean>;
78
- };`,Dr=`
80
+ };`,$r=`
79
81
  /**
80
82
  * Server-side function proxy. The built-in \`log\` prints to CLI stdout
81
83
  * (falls back to console.log on web). On the server side, this object only
@@ -83,7 +85,7 @@ import*as _ from"fs/promises";import{readFileSync as On}from"fs";import*as P fro
83
85
  */
84
86
  server: {
85
87
  log(...args: any[]): Promise<void>;
86
- };`,Or=`
88
+ };`,Fr=`
87
89
  /**
88
90
  * Async value inspector for tensor-like objects.
89
91
  *
@@ -150,7 +152,7 @@ import*as _ from"fs/promises";import{readFileSync as On}from"fs";import*as P fro
150
152
  *
151
153
  * @returns The full canonical URL
152
154
  */
153
- url(): Promise<string>;`,Ar=`
155
+ url(): Promise<string>;`,jr=`
154
156
  /**
155
157
  * Server-side function proxy.
156
158
  *
@@ -158,24 +160,30 @@ import*as _ from"fs/promises";import{readFileSync as On}from"fs";import*as P fro
158
160
  * \`tb.server.log(...)\` is a built-in that prints to CLI stdout (falls back to console.log on web).
159
161
  * User exports override built-ins of the same name.
160
162
  */
161
- server: Record<string, (...args: any[]) => Promise<any>>;`,Ye=`
163
+ server: Record<string, (...args: any[]) => Promise<any>>;`,Qe=`
162
164
  /**
163
165
  * Typebulb utilities namespace.
164
166
  * Type \`tb.\` to discover available helpers.
165
167
  */
166
- declare const tb: {${_t}${Or}${It}${Ar}${Dt}${Mt}${Ot}${Ir}${At}
168
+ declare const tb: {${It}${Fr}${Dt}${jr}${At}${Ft}${Mt}${Mr}${$t}
167
169
  };
168
- `,Xe=`
170
+ `,Ze=`
169
171
  /**
170
172
  * Typebulb utilities namespace (server-side).
171
173
  * Type \`tb.\` to discover available helpers.
172
174
  */
173
- declare const tb: {${_t}${It}${Dt}${Mt}${Dr}${Ot}${At}
175
+ declare const tb: {${It}${Dt}${At}${Ft}${$r}${Mt}${$t}
174
176
  };
175
- `;var H=class{constructor(e){this.store=e}async isNegative(e){let t=await _e(()=>this.store.get(e));return!!t&&t.until>Date.now()}async recordNegative(e){let r=((await _e(()=>this.store.get(e)))?.attempts||0)+1;await _e(()=>this.store.set(e,{until:Date.now()+Mr(r),attempts:r}))}async clearNegative(e){await _e(()=>this.store.delete(e))}};function Mr(s){return Math.min(9e5*Math.pow(2,Math.max(0,s-1)),864e5)}async function _e(s){try{return await s()}catch{return}}import Ur from"p-limit";import{resolve as $t}from"resolve.exports";var Z=class{constructor(e){this.fetchDts=e}fetchDtsText(e){return this.tryUrls([e])}async tryUrls(e){for(let t of e){let r=await this.fetchDts(t);if(r&&(this.looksLikeDts(r.dts)||/\.(d\.ts|d\.mts)(?:[?#].*)?$/i.test(r.url)||/[?&]dts(?:[&#]|$)/i.test(r.url)))return r}}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 L={maxRelativeTypeRefs:500,maxBareDeps:8,maxBareDepth:3,prefetchConcurrency:4,negativeTtlMs:1e4},pe=["index.d.ts","index.d.mts"],ue=/\.d\.(ts|mts)$/i;function Qe(s){if(ue.test(s))return!0;try{return new URL(s,"file://").search.includes("dts")}catch{return s.includes("?")&&s.includes("dts")}}function Ie(s){return[`${s}.d.ts`,`${s}.d.mts`]}async function fe(s,{retries:e=2,timeoutMs:t=15e3,init:r}={}){for(let n=0;n<=e;n++){let o=new AbortController,i=setTimeout(()=>o.abort(),t);try{let a=await fetch(s,{...r,signal:o.signal});if($r(a.status)&&n<e)continue;return a}catch{if(n<e)continue;return}finally{clearTimeout(i)}}}function $r(s){return s===408||s===429||s>=500&&s<600}var he=class extends Z{constructor(e,t){super(e),this.cdnClient=t}async loadPackageAtVersionedRoot(e,t){let r=this.cdnClient.packageJson(new m({name:e,version:t})),n=await fe(r);if(!n?.ok)return;let o;try{o=await n.json()}catch{return}if(o)return{pkg:o,baseDir:this.cdnClient.baseDir(new m({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 r of e){let n=await t(r);if(n)return n}}async resolveFromSelected(e,t){if(e.kind==="types"){let n=this.cdnClient.normalizeRelative(e.path);if(!n||n==="/"||n===".")return this.tryUntilSuccess([...pe],t);if(!ue.test(n)){let o=await this.tryUntilSuccess(this.declarationCandidatesFor(n),t);if(o)return o}return t(n)}let r=this.declarationCandidatesFor(e.path);return this.tryUntilSuccess([...pe,...r],t)}toResolutionResult(e){return{kind:ue.test(e)?"types":"probe",path:e}}resolveExportsPath(e,t){let r=t||".",n=e;try{let o=this.extractPathFromResult($t(n,r,{conditions:["types"]}));if(o)return o}catch{}try{return this.extractPathFromResult($t(n,r,{browser:!0,conditions:["import","default","module","browser","node"]}))}catch{return}}async resolve(e){try{let t=m.parse(e),{pkg:r,baseDir:n}=await this.loadPackageAtVersionedRoot(t.name,t.version)||{};if(!r||!n)return;let o={name:t.name,version:t.version},i=new m(o).format(),a=new m({...o,subpath:t.subpath}).format(),l=f=>this.fetchCandidateFrom(n,t.name,f);if(t.subpath){let f=this.cdnClient.ensureLeadingDotSlash(t.subpath),h=this.resolveExportsPath(r,f);if(h){let c=await this.resolveFromSelected(this.toResolutionResult(h),l);if(c)return{...c,resolvedPkg:a}}let y=await this.tryUntilSuccess(this.declarationCandidatesFor(f),l);if(y)return{...y,resolvedPkg:a}}let d=r.types??r.typings;if(d){let f=await this.resolveFromSelected({kind:"types",path:d},l);if(f)return{...f,resolvedPkg:i}}let u=this.resolveExportsPath(r,".");if(u){let f=await this.resolveFromSelected(this.toResolutionResult(u),l);if(f)return{...f,resolvedPkg:i}}return}catch{return}}async fetchCandidateFrom(e,t,r){let n=this.cdnClient.normalizeRelative(r),o=new URL(n,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[...pe];let t=e.replace(/\.(mjs|cjs|js|mts|cts|ts)$/i,""),r=Ie(t),n=t.endsWith("/")?t:`${t}/`;return r.push(...Ie(`${n}index`)),r}};import{gunzipSync as Fr}from"fflate";var ee=class{async fetchAndExtract(e,t){let r=this.getTarballUrl(e,t),n=await fe(r,{timeoutMs:3e4});if(!n?.ok)return new Map;let o=new Uint8Array(await n.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\//,""),r=t.indexOf("/");return r>0?t.substring(r+1):t}extractDtsFiles(e){let t=new Map;try{let r=Fr(e),n=new TextDecoder("utf-8"),o=0;for(;o<r.length-512;){let i=r.slice(o,o+512);if(i[0]===0)break;let a=i.slice(0,100),l=a.indexOf(0),d=n.decode(a.slice(0,l>0?l:100)).trim(),u=i.slice(124,136),f=n.decode(u).trim().replace(/\0/g,""),h=parseInt(f,8)||0,y=String.fromCharCode(i[156]);if(o+=512,(y==="0"||y==="\0")&&(d.endsWith(".d.ts")||d.endsWith(".d.mts"))){let c=r.slice(o,o+h);t.set(this.normalizeTarPath(d),n.decode(c))}o+=Math.ceil(h/512)*512}}catch{}return t}},jr=new ee;var me=class extends Z{constructor(e,t,r,n=new ee){super(e),this.cdnClient=t,this.cache=r,this.tarballFetcher=n}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,r){try{if(r){let o=V.majorOf(r),i=e.filter(a=>V.majorOf(a)===o);if(i.length)return i.sort((a,l)=>V.cmp(l,a))[0]}let n=t?.latest;return n&&e.includes(n)?n:e[0]}catch{return e[0]}}async fetchFromVersionedRoot(e,t){let r=new m(e),n=r.version;if(!n)return;let o;try{o=await this.tarballFetcher.fetchAndExtract(r.name,n)}catch{return}if(!o||o.size===0)return;for(let[a,l]of o.entries()){let d=this.cdnClient.file(e,a);try{await this.cache.setCachedFile(d,l)}catch{}}let i=t.subpath?[t.subpath+".d.ts",t.subpath+"/index.d.ts"]:["index.d.ts"];for(let a of i){let l=o.get(a);if(l)return{dts:l,url:this.cdnClient.file(e,a),resolvedPkg:t.subpath?new m(t).format():t.name}}}async resolve(e){let t=m.parse(e);if(t.name)for(let r of this.typesNameCandidates(t.name)){let n=`@types/${r}`,o;try{o=await this.cdnClient.fetchVersionsIndex(n)}catch{continue}if(!o?.versions?.length)continue;let i=this.selectTypesVersion(o.versions,o.distTags,t.version),a=await this.fetchFromVersionedRoot(`${n}@${i}`,t);if(a)return a}}};var ge=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,r=(n,o)=>(t.add(n[o]),null);return this.matchAll(e,/(import|export)\s+[^'"\n]*from\s*['"]([^'"\n]+)['"]/,n=>r(n,2)),this.matchAll(e,/export\s*\*\s*from\s*['"]([^'"\n]+)['"]/,n=>r(n,1)),Array.from(t)}matchAll(e,t,r){let n=[];try{let o=new RegExp(t.source,"g"),i;for(;i=o.exec(e);){let a=r(i);a!==null&&n.push(a)}}catch{}return n}isBare(e){return!(e.startsWith("./")||e.startsWith("../")||e.startsWith("file:")||e.startsWith("http://")||e.startsWith("https://"))}};var Ft="file:///node_modules",ye=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`${Ft}/${this.epochDir()}/${e}/index.d.ts`}pathFor(e,t){let r=Nr(t);return`${Ft}/${this.epochDir()}/${e}/${r}`}};function Nr(s){let e=s||"";return e.startsWith("./")?e.slice(2):e.replace(/^\/+/,"")}import{LRUCache as Lr}from"lru-cache";function Ze(s){let e=new Lr({ttl:1e4,max:500}),t=new Map;return async function(n){try{if(await s.isNegative(n))return;let o=e.get(n);if(o&&Date.now()-o<1e4)return;let i=await s.getCachedFile(n);if(i)return{dts:i,url:n};let a=t.get(n);if(a)return a;let l=(async()=>{let d=await fetch(n,{cache:"no-store"});if(!d.ok){d.status===404&&(e.set(n,Date.now()),await s.recordNegative(n));return}let u=await d.text(),f=d.url||n;return await s.clearNegative(n),await s.setCachedFile(f,u),{dts:u,url:f}})();return t.set(n,l),await l.finally(()=>t.delete(n))}catch{return}}}var De=class{constructor(e){this.inFlight=new Map,this.scanner=new ge,this.cache=e.cache,this.cdnClient=e.cdnClient,this.versionResolver=e.versionResolver,this.packageService=e.packageService,this.fetchDts=Ze(e.cache),this.typescriptProvider=new he(this.fetchDts,e.cdnClient),this.definitelyTypedProvider=new me(this.fetchDts,e.cdnClient,e.cache),this.virtualFs=new ye}withInFlight(e,t){let r=this.inFlight.get(e);if(r)return r;let n=t().finally(()=>this.inFlight.delete(e));return this.inFlight.set(e,n),n}invalidate(){this.virtualFs.bumpEpoch(),this.inFlight.clear()}capArray(e,t){return e.length<=t?e:e.slice(0,t)}pushFileIfNew(e,t,r){e.some(n=>n.path===t)||e.push({path:t,content:r})}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 r=new m(e);return r.subpath?this.fetchRootDts(r.name,t):void 0}async fetchViaProviders(e){for(let t of[this.typescriptProvider,this.definitelyTypedProvider])try{let r=await t.resolve(e);if(r?.dts)return r}catch{}}subpathsMatch(e,t){return new m(e).subpath===new m(t).subpath}async fetchRootDts(e,t){let{effectivePackage:r,root:n,pinned:o}=await this.versionResolver.effectivePackage(e,t),i=await this.cache.getCachedDts(r);if(i?.content){let l=i.url??this.cdnClient.file(o?`${n}@${o}`:n,"index.d.ts");return{dts:i.content,url:l,resolvedPkg:r}}let a;try{a=await this.fetchViaProviders(r)}catch{return}if(!(!a?.dts||!a.url)){try{await this.cache.setCachedFile(a.url,a.dts)}catch{}if(this.subpathsMatch(r,a.resolvedPkg||r)){try{await this.cache.setCachedDts(r,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,r){let n=t.pathname.startsWith(e.pathname)?t.pathname.slice(e.pathname.length):`__deps__/${encodeURIComponent(t.toString()).replace(/%/g,"_")}.d.ts`;return this.virtualFs.pathFor(r,n)}computeEntryPath(e,t){if(!e)return{mainPath:this.virtualFs.pathForMain(t),packageRootUrl:void 0};let r=new URL(e),n=this.extractPackageRootUrl(r);return{mainPath:this.toVirtualPath(n,r,t),packageRootUrl:n}}async expandRelativeRefs(e,t,r,n,o=new Set,i){if(!o.has(t)&&(o.add(t),!(o.size>L.maxRelativeTypeRefs)))try{let a=new URL(t),l=new URL("./",a);i??(i=this.extractPackageRootUrl(a));let d=this.capArray(this.scanner.collectRelativeTypeRefs(e),L.maxRelativeTypeRefs);for(let u of d)await this.tryRelativeRef(u,l,i,r,n,o)}catch{}}async tryRelativeRef(e,t,r,n,o,i){try{let a=new URL(e,t),l=a.pathname+a.search,d=Qe(l)?[l]:this.typescriptProvider.declarationCandidatesFor(l);for(let u of d){let h=new URL(u,a).toString();if(i.has(h))return;let y=await this.fetchDts(h);if(y?.dts){let c=this.toVirtualPath(r,new URL(y.url),n);this.pushFileIfNew(o,c,y.dts),await this.expandRelativeRefs(y.dts,y.url,n,o,i,r);return}}}catch{}}isDifferentPackage(e,t){return e===t?!1:new m(e).name!==new m(t).name}async prefetchBareDeps(e,t,r,n,o){try{let i=this.capArray(this.scanner.collectBareModuleRefs(e),L.maxBareDeps).filter(d=>this.isDifferentPackage(d,t));if(!i.length)return;let a=new Set([t]),l=Ur(L.prefetchConcurrency);await Promise.all(i.map(d=>l(()=>this.prefetchBareDepsRecursive(d,r,n,L.maxBareDepth,a,o).catch(()=>{}))))}catch{}}async prefetchBareDepsRecursive(e,t,r,n,o,i){if(n<=0||o.has(e))return;o.add(e);let a=await this.fetchRootDts(e,i);if(!a?.dts)return;let l=a.resolvedPkg||e,d=this.virtualFs.pathForMain(l);this.pushFileIfNew(t,d,a.dts),r.push({module:e,path:d}),a.url&&await this.expandRelativeRefs(a.dts,a.url,l,t);let u=this.capArray(this.scanner.collectBareModuleRefs(a.dts),L.maxBareDeps).filter(f=>!o.has(f));for(let f of u)await this.prefetchBareDepsRecursive(f,t,r,n-1,o,i)}async resolve(e,t,r){let n=await this.packageService.extractImports(e),o=r?[...n,...r]:n;return(await Promise.all(o.map(a=>this.resolveOne(a,t)))).filter(a=>!!a)}async resolveOne(e,t){let{effectivePackage:r}=await this.versionResolver.effectivePackage(e,t);return this.withInFlight(r,async()=>{let n=await this.fetchRootDts(e,t)??await this.trySubpathWithRootFallback(e,t);return n?this.buildDefFromContent(e,n,n.resolvedPkg||e,t):this.createStubDef(e)})}async buildDefFromContent(e,t,r,n){let{dts:o,url:i,resolvedPkg:a}=t,l=new m(a||r),d=l.version?`${l.name}@${l.version}`:l.name,{mainPath:u,packageRootUrl:f}=this.computeEntryPath(i,d),h=[{path:u,content:o}],y=[];i&&await this.expandRelativeRefs(o,i,d,h,void 0,f);let c=h.map(v=>v.content).join(`
176
- `);await this.prefetchBareDeps(c,d,h,y,n);let p=l.format(),g=e===p?[e]:[e,p];return y.push(...g.map(v=>({module:v,path:u}))),{pkg:e,mainPath:u,files:h,shims:y}}};function et(s){return new De(s)}import*as F from"fs/promises";import*as j from"path";import*as Lt from"os";import*as tt from"fs/promises";import*as jt from"crypto";function D(s){return jt.createHash("sha1").update(s).digest("hex")}async function q(s){try{return JSON.parse(await tt.readFile(s,"utf8"))}catch{return}}async function Oe(s){try{return await tt.readFile(s,"utf8")}catch{return}}var Nt=1,U=j.join(Lt.homedir(),".typebulb","cache"),we=j.join(U,"packages"),ve=j.join(U,"proxy"),Ae=j.join(U,"dts"),Br=j.join(U,"emit"),rt;function b(){return rt||(rt=Wr()),rt}function Me(s,e){return j.join(Br,D(s),e)}async function Wr(){await F.mkdir(U,{recursive:!0});let s=j.join(U,"version.json");if((await Jr(s))?.version===Nt)return;let t=await F.readdir(U).catch(()=>[]);await Promise.all(t.map(r=>F.rm(j.join(U,r),{recursive:!0,force:!0}))),await F.writeFile(s,JSON.stringify({version:Nt})+`
177
- `,"utf8")}async function Jr(s){try{let e=await F.readFile(s,"utf8");return JSON.parse(e)}catch{return}}import*as B from"fs/promises";import*as Ut from"path";async function k(s,e){await B.mkdir(Ut.dirname(s),{recursive:!0});let t=`${s}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await B.writeFile(t,e,"utf8"),await B.rename(t,s).catch(async r=>{throw await B.rm(t,{force:!0}).catch(()=>{}),r})}var te=class{constructor(e){this.filePath=e}mem;loadPromise;load(){return this.mem?Promise.resolve(this.mem):(this.loadPromise||(this.loadPromise=q(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 r=await this.load();r.set(e,t),await this.persist(r)}async delete(e){let t=await this.load();t.delete(e)&&await this.persist(t)}async persist(e){await k(this.filePath,JSON.stringify(Object.fromEntries(e)))}};var nt=O.join(we,"indexes"),Bt=O.join(we,"pinned"),Vr=O.join(we,"meta"),Hr=O.join(we,"negative.json"),re=Symbol("missing"),Fe=class{pinnedMem=new Map;indexMem=new Map;metaMem=new Map;negativeCache=new H(new te(Hr));async getPinnedExact(e,t){let r=`${e}@${t}`,n=this.pinnedMem.get(r);if(n!==void 0)return n===re?void 0:n;await b();let o=await Oe(O.join(Bt,D(r)+".txt"));return this.pinnedMem.set(r,o??re),o}async setPinnedExact(e,t,r){let n=`${e}@${t}`;this.pinnedMem.set(n,r),await b(),await k(O.join(Bt,D(n)+".txt"),r)}async getIndex(e){let t=this.indexMem.get(e);if(t!==void 0)return t===re?void 0:t;await b();let r=await q(O.join(nt,$e(e)+".json"));return this.indexMem.set(e,r??re),r}async setIndex(e,t,r){let n={versions:t,distTags:r,updatedAt:Date.now()};this.indexMem.set(e,n),await b(),await k(O.join(nt,$e(e)+".json"),JSON.stringify(n))}async invalidateVersionsCache(e){this.indexMem.delete(e),await Jt.rm(O.join(nt,$e(e)+".json"),{force:!0})}async isNegative(e){return await b(),this.negativeCache.isNegative(e)}async recordNegative(e){await b(),await this.negativeCache.recordNegative(e)}async clearNegative(e){await this.negativeCache.clearNegative(e)}async getMeta(e,t){let r=`${e}@${t}`,n=this.metaMem.get(r);if(n!==void 0)return n===re?void 0:n;await b();let o=await q(Wt(e,t));return this.metaMem.set(r,o??re),o}async setMeta(e,t,r,n,o){let i={dependencies:r,peerDependencies:n,peerDependenciesMeta:o,updatedAt:Date.now()};this.metaMem.set(`${e}@${t}`,i),await b(),await k(Wt(e,t),JSON.stringify(i))}};function Wt(s,e){return O.join(Vr,$e(s),encodeURIComponent(e)+".json")}function $e(s){return s.replace(/\//g,"__")}var qr={async getJson(s){try{let e=await fetch(s,{redirect:"follow"});return e.ok?await e.json():void 0}catch{return}},async head(s){try{let e=await fetch(s,{method:"HEAD",redirect:"follow"});return{ok:e.ok,url:e.url}}catch{return}}},Gr=new Fe,{packageService:je,versionResolver:Vt,cdnClient:Ht,peerResolver:$o}=Ct(Gr,qr);var qt=`
177
+ `;var H=class{constructor(e){this.store=e}async isNegative(e){let t=await Oe(()=>this.store.get(e));return!!t&&t.until>Date.now()}async recordNegative(e){let r=((await Oe(()=>this.store.get(e)))?.attempts||0)+1;await Oe(()=>this.store.set(e,{until:Date.now()+Nr(r),attempts:r}))}async clearNegative(e){await Oe(()=>this.store.delete(e))}};function Nr(s){return Math.min(9e5*Math.pow(2,Math.max(0,s-1)),864e5)}async function Oe(s){try{return await s()}catch{return}}import Vr from"p-limit";import{resolve as jt}from"resolve.exports";var Z=class{constructor(e){this.fetchDts=e}fetchDtsText(e){return this.tryUrls([e])}async tryUrls(e){for(let t of e){let r=await this.fetchDts(t);if(r&&(this.looksLikeDts(r.dts)||/\.(d\.ts|d\.mts)(?:[?#].*)?$/i.test(r.url)||/[?&]dts(?:[&#]|$)/i.test(r.url)))return r}}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 U={maxRelativeTypeRefs:500,maxBareDeps:8,maxBareDepth:3,prefetchConcurrency:4,negativeTtlMs:1e4},he=["index.d.ts","index.d.mts"],fe=/\.d\.(ts|mts)$/i;function et(s){if(fe.test(s))return!0;try{return new URL(s,"file://").search.includes("dts")}catch{return s.includes("?")&&s.includes("dts")}}function Ie(s){return[`${s}.d.ts`,`${s}.d.mts`]}async function me(s,{retries:e=2,timeoutMs:t=15e3,init:r}={}){for(let n=0;n<=e;n++){let i=new AbortController,o=setTimeout(()=>i.abort(),t);try{let a=await fetch(s,{...r,signal:i.signal});if(Lr(a.status)&&n<e)continue;return a}catch{if(n<e)continue;return}finally{clearTimeout(o)}}}function Lr(s){return s===408||s===429||s>=500&&s<600}var ge=class extends Z{constructor(e,t){super(e),this.cdnClient=t}async loadPackageAtVersionedRoot(e,t){let r=this.cdnClient.packageJson(new y({name:e,version:t})),n=await me(r);if(!n?.ok)return;let i;try{i=await n.json()}catch{return}if(i)return{pkg:i,baseDir:this.cdnClient.baseDir(new y({name:e,version:t??i.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 r of e){let n=await t(r);if(n)return n}}async resolveFromSelected(e,t){if(e.kind==="types"){let n=this.cdnClient.normalizeRelative(e.path);if(!n||n==="/"||n===".")return this.tryUntilSuccess([...he],t);if(!fe.test(n)){let i=await this.tryUntilSuccess(this.declarationCandidatesFor(n),t);if(i)return i}return t(n)}let r=this.declarationCandidatesFor(e.path);return this.tryUntilSuccess([...he,...r],t)}toResolutionResult(e){return{kind:fe.test(e)?"types":"probe",path:e}}resolveExportsPath(e,t){let r=t||".",n=e;try{let i=this.extractPathFromResult(jt(n,r,{conditions:["types"]}));if(i)return i}catch{}try{return this.extractPathFromResult(jt(n,r,{browser:!0,conditions:["import","default","module","browser","node"]}))}catch{return}}async resolve(e){try{let t=y.parse(e),{pkg:r,baseDir:n}=await this.loadPackageAtVersionedRoot(t.name,t.version)||{};if(!r||!n)return;let i={name:t.name,version:t.version},o=new y(i).format(),a=new y({...i,subpath:t.subpath}).format(),c=p=>this.fetchCandidateFrom(n,t.name,p);if(t.subpath){let p=this.cdnClient.ensureLeadingDotSlash(t.subpath),m=this.resolveExportsPath(r,p);if(m){let h=await this.resolveFromSelected(this.toResolutionResult(m),c);if(h)return{...h,resolvedPkg:a}}let w=await this.tryUntilSuccess(this.declarationCandidatesFor(p),c);if(w)return{...w,resolvedPkg:a}}let d=r.types??r.typings;if(d){let p=await this.resolveFromSelected({kind:"types",path:d},c);if(p)return{...p,resolvedPkg:o}}let u=this.resolveExportsPath(r,".");if(u){let p=await this.resolveFromSelected(this.toResolutionResult(u),c);if(p)return{...p,resolvedPkg:o}}return}catch{return}}async fetchCandidateFrom(e,t,r){let n=this.cdnClient.normalizeRelative(r),i=new URL(n,e).toString(),o=await this.fetchDtsText(i);return o?{dts:o.dts,url:o.url,resolvedPkg:t}:void 0}declarationCandidatesFor(e){if(!e||e==="./"||e==="/")return[...he];let t=e.replace(/\.(mjs|cjs|js|mts|cts|ts)$/i,""),r=Ie(t),n=t.endsWith("/")?t:`${t}/`;return r.push(...Ie(`${n}index`)),r}};import{gunzipSync as Ur}from"fflate";var ee=class{async fetchAndExtract(e,t){let r=this.getTarballUrl(e,t),n=await me(r,{timeoutMs:3e4});if(!n?.ok)return new Map;let i=new Uint8Array(await n.arrayBuffer());return this.extractDtsFiles(i)}getTarballUrl(e,t){return`https://registry.npmjs.org/${e.replace("/","%2F")}/-/${e.split("/").pop()}-${t}.tgz`}normalizeTarPath(e){let t=e.replace(/^package\//,""),r=t.indexOf("/");return r>0?t.substring(r+1):t}extractDtsFiles(e){let t=new Map;try{let r=Ur(e),n=new TextDecoder("utf-8"),i=0;for(;i<r.length-512;){let o=r.slice(i,i+512);if(o[0]===0)break;let a=o.slice(0,100),c=a.indexOf(0),d=n.decode(a.slice(0,c>0?c:100)).trim(),u=o.slice(124,136),p=n.decode(u).trim().replace(/\0/g,""),m=parseInt(p,8)||0,w=String.fromCharCode(o[156]);if(i+=512,(w==="0"||w==="\0")&&(d.endsWith(".d.ts")||d.endsWith(".d.mts"))){let h=r.slice(i,i+m);t.set(this.normalizeTarPath(d),n.decode(h))}i+=Math.ceil(m/512)*512}}catch{}return t}},Br=new ee;var ye=class extends Z{constructor(e,t,r,n=new ee){super(e),this.cdnClient=t,this.cache=r,this.tarballFetcher=n}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,r){try{if(r){let i=V.majorOf(r),o=e.filter(a=>V.majorOf(a)===i);if(o.length)return o.sort((a,c)=>V.cmp(c,a))[0]}let n=t?.latest;return n&&e.includes(n)?n:e[0]}catch{return e[0]}}async fetchFromVersionedRoot(e,t){let r=new y(e),n=r.version;if(!n)return;let i;try{i=await this.tarballFetcher.fetchAndExtract(r.name,n)}catch{return}if(!i||i.size===0)return;for(let[a,c]of i.entries()){let d=this.cdnClient.file(e,a);try{await this.cache.setCachedFile(d,c)}catch{}}let o=t.subpath?[t.subpath+".d.ts",t.subpath+"/index.d.ts"]:["index.d.ts"];for(let a of o){let c=i.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 r of this.typesNameCandidates(t.name)){let n=`@types/${r}`,i;try{i=await this.cdnClient.fetchVersionsIndex(n)}catch{continue}if(!i?.versions?.length)continue;let o=this.selectTypesVersion(i.versions,i.distTags,t.version),a=await this.fetchFromVersionedRoot(`${n}@${o}`,t);if(a)return a}}};var we=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,r=(n,i)=>(t.add(n[i]),null);return this.matchAll(e,/(import|export)\s+[^'"\n]*from\s*['"]([^'"\n]+)['"]/,n=>r(n,2)),this.matchAll(e,/export\s*\*\s*from\s*['"]([^'"\n]+)['"]/,n=>r(n,1)),Array.from(t)}matchAll(e,t,r){let n=[];try{let i=new RegExp(t.source,"g"),o;for(;o=i.exec(e);){let a=r(o);a!==null&&n.push(a)}}catch{}return n}isBare(e){return!(e.startsWith("./")||e.startsWith("../")||e.startsWith("file:")||e.startsWith("http://")||e.startsWith("https://"))}};var Nt="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`${Nt}/${this.epochDir()}/${e}/index.d.ts`}pathFor(e,t){let r=Wr(t);return`${Nt}/${this.epochDir()}/${e}/${r}`}};function Wr(s){let e=s||"";return e.startsWith("./")?e.slice(2):e.replace(/^\/+/,"")}import{LRUCache as Jr}from"lru-cache";function tt(s){let e=new Jr({ttl:1e4,max:500}),t=new Map;return async function(n){try{if(await s.isNegative(n))return;let i=e.get(n);if(i&&Date.now()-i<1e4)return;let o=await s.getCachedFile(n);if(o)return{dts:o,url:n};let a=t.get(n);if(a)return a;let c=(async()=>{let d=await fetch(n,{cache:"no-store"});if(!d.ok){d.status===404&&(e.set(n,Date.now()),await s.recordNegative(n));return}let u=await d.text(),p=d.url||n;return await s.clearNegative(n),await s.setCachedFile(p,u),{dts:u,url:p}})();return t.set(n,c),await c.finally(()=>t.delete(n))}catch{return}}}var De=class{constructor(e){this.inFlight=new Map,this.scanner=new we,this.cache=e.cache,this.cdnClient=e.cdnClient,this.versionResolver=e.versionResolver,this.packageService=e.packageService,this.fetchDts=tt(e.cache),this.typescriptProvider=new ge(this.fetchDts,e.cdnClient),this.definitelyTypedProvider=new ye(this.fetchDts,e.cdnClient,e.cache),this.virtualFs=new ve}withInFlight(e,t){let r=this.inFlight.get(e);if(r)return r;let n=t().finally(()=>this.inFlight.delete(e));return this.inFlight.set(e,n),n}invalidate(){this.virtualFs.bumpEpoch(),this.inFlight.clear()}capArray(e,t){return e.length<=t?e:e.slice(0,t)}pushFileIfNew(e,t,r){e.some(n=>n.path===t)||e.push({path:t,content:r})}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 r=new y(e);return r.subpath?this.fetchRootDts(r.name,t):void 0}async fetchViaProviders(e){for(let t of[this.typescriptProvider,this.definitelyTypedProvider])try{let r=await t.resolve(e);if(r?.dts)return r}catch{}}subpathsMatch(e,t){return new y(e).subpath===new y(t).subpath}async fetchRootDts(e,t){let{effectivePackage:r,root:n,pinned:i}=await this.versionResolver.effectivePackage(e,t),o=await this.cache.getCachedDts(r);if(o?.content){let c=o.url??this.cdnClient.file(i?`${n}@${i}`:n,"index.d.ts");return{dts:o.content,url:c,resolvedPkg:r}}let a;try{a=await this.fetchViaProviders(r)}catch{return}if(!(!a?.dts||!a.url)){try{await this.cache.setCachedFile(a.url,a.dts)}catch{}if(this.subpathsMatch(r,a.resolvedPkg||r)){try{await this.cache.setCachedDts(r,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,r){let n=t.pathname.startsWith(e.pathname)?t.pathname.slice(e.pathname.length):`__deps__/${encodeURIComponent(t.toString()).replace(/%/g,"_")}.d.ts`;return this.virtualFs.pathFor(r,n)}computeEntryPath(e,t){if(!e)return{mainPath:this.virtualFs.pathForMain(t),packageRootUrl:void 0};let r=new URL(e),n=this.extractPackageRootUrl(r);return{mainPath:this.toVirtualPath(n,r,t),packageRootUrl:n}}async expandRelativeRefs(e,t,r,n,i=new Set,o){if(!i.has(t)&&(i.add(t),!(i.size>U.maxRelativeTypeRefs)))try{let a=new URL(t),c=new URL("./",a);o??(o=this.extractPackageRootUrl(a));let d=this.capArray(this.scanner.collectRelativeTypeRefs(e),U.maxRelativeTypeRefs);for(let u of d)await this.tryRelativeRef(u,c,o,r,n,i)}catch{}}async tryRelativeRef(e,t,r,n,i,o){try{let a=new URL(e,t),c=a.pathname+a.search,d=et(c)?[c]:this.typescriptProvider.declarationCandidatesFor(c);for(let u of d){let m=new URL(u,a).toString();if(o.has(m))return;let w=await this.fetchDts(m);if(w?.dts){let h=this.toVirtualPath(r,new URL(w.url),n);this.pushFileIfNew(i,h,w.dts),await this.expandRelativeRefs(w.dts,w.url,n,i,o,r);return}}}catch{}}isDifferentPackage(e,t){return e===t?!1:new y(e).name!==new y(t).name}async prefetchBareDeps(e,t,r,n,i){try{let o=this.capArray(this.scanner.collectBareModuleRefs(e),U.maxBareDeps).filter(d=>this.isDifferentPackage(d,t));if(!o.length)return;let a=new Set([t]),c=Vr(U.prefetchConcurrency);await Promise.all(o.map(d=>c(()=>this.prefetchBareDepsRecursive(d,r,n,U.maxBareDepth,a,i).catch(()=>{}))))}catch{}}async prefetchBareDepsRecursive(e,t,r,n,i,o){if(n<=0||i.has(e))return;i.add(e);let a=await this.fetchRootDts(e,o);if(!a?.dts)return;let c=a.resolvedPkg||e,d=this.virtualFs.pathForMain(c);this.pushFileIfNew(t,d,a.dts),r.push({module:e,path:d}),a.url&&await this.expandRelativeRefs(a.dts,a.url,c,t);let u=this.capArray(this.scanner.collectBareModuleRefs(a.dts),U.maxBareDeps).filter(p=>!i.has(p));for(let p of u)await this.prefetchBareDepsRecursive(p,t,r,n-1,i,o)}async resolve(e,t,r){let n=await this.packageService.extractImports(e),i=r?[...n,...r]:n;return(await Promise.all(i.map(a=>this.resolveOne(a,t)))).filter(a=>!!a)}async resolveOne(e,t){let{effectivePackage:r}=await this.versionResolver.effectivePackage(e,t);return this.withInFlight(r,async()=>{let n=await this.fetchRootDts(e,t)??await this.trySubpathWithRootFallback(e,t);return n?this.buildDefFromContent(e,n,n.resolvedPkg||e,t):this.createStubDef(e)})}async buildDefFromContent(e,t,r,n){let{dts:i,url:o,resolvedPkg:a}=t,c=new y(a||r),d=c.version?`${c.name}@${c.version}`:c.name,{mainPath:u,packageRootUrl:p}=this.computeEntryPath(o,d),m=[{path:u,content:i}],w=[];o&&await this.expandRelativeRefs(i,o,d,m,void 0,p);let h=m.map(g=>g.content).join(`
178
+ `);await this.prefetchBareDeps(h,d,m,w,n);let l=c.format(),f=e===l?[e]:[e,l];return w.push(...f.map(g=>({module:g,path:u}))),{pkg:e,mainPath:u,files:m,shims:w}}};function rt(s){return new De(s)}import*as j from"fs/promises";import*as L from"path";import*as Bt from"os";import*as nt from"fs/promises";import*as Lt from"crypto";function D(s){return Lt.createHash("sha1").update(s).digest("hex")}async function q(s){try{return JSON.parse(await nt.readFile(s,"utf8"))}catch{return}}async function Ae(s){try{return await nt.readFile(s,"utf8")}catch{return}}var Ut=1,B=L.join(Bt.homedir(),".typebulb","cache"),be=L.join(B,"packages"),xe=L.join(B,"proxy"),Me=L.join(B,"dts"),Hr=L.join(B,"emit"),st;function x(){return st||(st=qr()),st}function $e(s,e){return L.join(Hr,D(s),e)}async function qr(){await j.mkdir(B,{recursive:!0});let s=L.join(B,"version.json");if((await Gr(s))?.version===Ut)return;let t=await j.readdir(B).catch(()=>[]);await Promise.all(t.map(r=>j.rm(L.join(B,r),{recursive:!0,force:!0}))),await j.writeFile(s,JSON.stringify({version:Ut})+`
179
+ `,"utf8")}async function Gr(s){try{let e=await j.readFile(s,"utf8");return JSON.parse(e)}catch{return}}import*as W from"fs/promises";import*as Wt from"path";async function T(s,e){await W.mkdir(Wt.dirname(s),{recursive:!0});let t=`${s}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await W.writeFile(t,e,"utf8"),await W.rename(t,s).catch(async r=>{throw await W.rm(t,{force:!0}).catch(()=>{}),r})}var te=class{constructor(e){this.filePath=e}mem;loadPromise;load(){return this.mem?Promise.resolve(this.mem):(this.loadPromise||(this.loadPromise=q(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 r=await this.load();r.set(e,t),await this.persist(r)}async delete(e){let t=await this.load();t.delete(e)&&await this.persist(t)}async persist(e){await T(this.filePath,JSON.stringify(Object.fromEntries(e)))}};var it=A.join(be,"indexes"),Jt=A.join(be,"pinned"),zr=A.join(be,"meta"),Kr=A.join(be,"negative.json"),re=Symbol("missing"),je=class{pinnedMem=new Map;indexMem=new Map;metaMem=new Map;negativeCache=new H(new te(Kr));async getPinnedExact(e,t){let r=`${e}@${t}`,n=this.pinnedMem.get(r);if(n!==void 0)return n===re?void 0:n;await x();let i=await Ae(A.join(Jt,D(r)+".txt"));return this.pinnedMem.set(r,i??re),i}async setPinnedExact(e,t,r){let n=`${e}@${t}`;this.pinnedMem.set(n,r),await x(),await T(A.join(Jt,D(n)+".txt"),r)}async getIndex(e){let t=this.indexMem.get(e);if(t!==void 0)return t===re?void 0:t;await x();let r=await q(A.join(it,Fe(e)+".json"));return this.indexMem.set(e,r??re),r}async setIndex(e,t,r){let n={versions:t,distTags:r,updatedAt:Date.now()};this.indexMem.set(e,n),await x(),await T(A.join(it,Fe(e)+".json"),JSON.stringify(n))}async invalidateVersionsCache(e){this.indexMem.delete(e),await Ht.rm(A.join(it,Fe(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 r=`${e}@${t}`,n=this.metaMem.get(r);if(n!==void 0)return n===re?void 0:n;await x();let i=await q(Vt(e,t));return this.metaMem.set(r,i??re),i}async setMeta(e,t,r,n,i){let o={dependencies:r,peerDependencies:n,peerDependenciesMeta:i,updatedAt:Date.now()};this.metaMem.set(`${e}@${t}`,o),await x(),await T(Vt(e,t),JSON.stringify(o))}};function Vt(s,e){return A.join(zr,Fe(s),encodeURIComponent(e)+".json")}function Fe(s){return s.replace(/\//g,"__")}var qt={async getJson(s){try{let e=await fetch(s,{redirect:"follow"});return e.ok?await e.json():void 0}catch{return}},async head(s){try{let e=await fetch(s,{method:"HEAD",redirect:"follow"});return{ok:e.ok,url:e.url}}catch{return}}};var Yr=new je,{packageService:Ne,versionResolver:Gt,cdnClient:zt,peerResolver:Wi}=Ot(Yr,qt);var Kt=`
178
180
  (() => {
181
+ // Embedded (bulb-in-a-bulb): runs inside a sandboxed iframe with no parent
182
+ // bridge, so privileged tb.* (AI, fs, server RPC) can't reach a host and would
183
+ // otherwise fail with cryptic CORS/CSP errors. Detect it and fail clearly.
184
+ const isEmbedded = window.parent !== window;
185
+ const embedErr = (name) => new Error(name + ' is not available in an embedded bulb (no host bridge).');
186
+
179
187
  // JSON parser (handles jsonish - unquoted keys)
180
188
  const parseJson = (str) => {
181
189
  try {
@@ -197,6 +205,7 @@ declare const tb: {${_t}${It}${Dt}${Mt}${Dr}${Ot}${At}
197
205
  throw new Error(err.error || 'Failed to ' + action + ' file: ' + path);
198
206
  };
199
207
  const fetchFileBytes = async (path) => {
208
+ if (isEmbedded) throw embedErr('tb.fs');
200
209
  const resp = await fetch('/__fs/read', {
201
210
  method: 'POST',
202
211
  headers: { 'Content-Type': 'application/json' },
@@ -216,6 +225,7 @@ declare const tb: {${_t}${It}${Dt}${Mt}${Dr}${Ot}${At}
216
225
  },
217
226
  readBytes: async (path) => new Uint8Array(await fetchFileBytes(path)),
218
227
  write: async (path, content) => {
228
+ if (isEmbedded) throw embedErr('tb.fs');
219
229
  const resp = await fetch('/__fs/write?path=' + encodeURIComponent(path), {
220
230
  method: 'POST',
221
231
  body: content
@@ -243,6 +253,7 @@ declare const tb: {${_t}${It}${Dt}${Mt}${Dr}${Ot}${At}
243
253
 
244
254
  // Inference not available locally
245
255
  infer: () => {
256
+ if (isEmbedded) return Promise.reject(embedErr('tb.infer()'));
246
257
  alert('This bulb uses AI inference.\\n\\nFor local bulbs, simply ask your AI assistant (e.g. Claude Code) to read your .bulb.md file and edit the data.txt and insight.json blocks directly.');
247
258
  return Promise.reject(new Error('tb.infer() is not available in the local CLI.'));
248
259
  },
@@ -252,6 +263,7 @@ declare const tb: {${_t}${It}${Dt}${Mt}${Dr}${Ot}${At}
252
263
 
253
264
  // AI - calls local server which proxies to LLM provider
254
265
  ai: async ({ messages, system, reasoning, provider, model, webSearch }) => {
266
+ if (isEmbedded) throw embedErr('tb.ai()');
255
267
  const resp = await fetch('/__ai', {
256
268
  method: 'POST',
257
269
  headers: { 'Content-Type': 'application/json' },
@@ -269,6 +281,7 @@ declare const tb: {${_t}${It}${Dt}${Mt}${Dr}${Ot}${At}
269
281
 
270
282
  // Model discovery - fetches catalog from typebulb.com, filtered by local API keys
271
283
  models: async () => {
284
+ if (isEmbedded) return [];
272
285
  const resp = await fetch('/__models');
273
286
  if (!resp.ok) return [];
274
287
  return resp.json();
@@ -283,17 +296,20 @@ declare const tb: {${_t}${It}${Dt}${Mt}${Dr}${Ot}${At}
283
296
  // URL
284
297
  url: () => Promise.resolve(location.href),
285
298
 
286
- // Proxy: rewrite CDN URLs to local server for same-origin Worker/WASM loading
299
+ // Proxy: rewrite CDN URLs to the local server's /proxy/. Relative on purpose \u2014
300
+ // it resolves against the served page on the CLI, and against the host page
301
+ // inside a srcdoc embed, where location.origin is the string "null".
287
302
  proxy: (url) => {
288
303
  if (!url) return url;
289
304
  const i = url.lastIndexOf('https://');
290
305
  const clean = i !== -1 ? url.slice(i) : url;
291
306
  if (!clean.startsWith('https://')) return url;
292
- return location.origin + '/proxy/' + clean;
307
+ return '/proxy/' + clean;
293
308
  },
294
309
 
295
310
  // Server API - call functions from **server.ts**
296
311
  api: async (name, ...args) => {
312
+ if (isEmbedded) throw embedErr('tb.server.' + name + '()');
297
313
  const resp = await fetch('/__api/' + name, {
298
314
  method: 'POST',
299
315
  headers: { 'Content-Type': 'application/json' },
@@ -312,8 +328,8 @@ declare const tb: {${_t}${It}${Dt}${Mt}${Dr}${Ot}${At}
312
328
  // Filesystem - local CLI extension
313
329
  fs,
314
330
 
315
- // Environment
316
- mode: 'local',
331
+ // Environment ('embedded' when running as a bulb-in-a-bulb)
332
+ mode: isEmbedded ? 'embedded' : 'local',
317
333
 
318
334
  // Theme accessor - delegates to the head-script engine (window.__tbTheme).
319
335
  // Get: override slot ('dark'|'light'|undefined). Set applies + persists
@@ -335,12 +351,12 @@ declare const tb: {${_t}${It}${Dt}${Mt}${Dr}${Ot}${At}
335
351
  };
336
352
  }
337
353
  })();
338
- `;function Gt(s){let{name:e,code:t,css:r,html:n,data:o,insight:i,importMap:a,watch:l}=s,d=n.trim()||'<div id="app"></div>',u=h=>h.replace(/<\/script/gi,"<\\/script"),f={imports:Kr(a.imports)};return`<!DOCTYPE html>
354
+ `;function Yt(s){let{name:e,code:t,css:r,html:n,data:i,insight:o,importMap:a,watch:c,theme:d}=s,u=n.trim()||'<div id="app"></div>',p=w=>w.replace(/<\/script/gi,"<\\/script"),m={imports:Zr(a.imports)};return`<!DOCTYPE html>
339
355
  <html>
340
356
  <head>
341
357
  <meta charset="utf-8">
342
358
  <meta name="viewport" content="width=device-width, initial-scale=1">
343
- <title>${zr(e)} - typebulb</title>
359
+ <title>${Qr(e)} - typebulb</title>
344
360
  <script>
345
361
  // Theme engine. Sets html[data-theme] before stylesheets paint (no flash) and
346
362
  // exposes the tb.theme accessor via window.__tbTheme. The override is persisted
@@ -348,16 +364,19 @@ declare const tb: {${_t}${It}${Dt}${Mt}${Dr}${Ot}${At}
348
364
  // toggles the effective theme. See Specs/Theme.md.
349
365
  (function() {
350
366
  try {
351
- var KEY = ${u(JSON.stringify("tb-theme:"+e))};
367
+ var KEY = ${p(JSON.stringify("tb-theme:"+e))};
352
368
  var doc = document.documentElement;
353
369
  var mq = window.matchMedia('(prefers-color-scheme: dark)');
354
370
  var os = function() { return mq.matches ? 'dark' : 'light'; };
371
+ // A host-forced theme (bulb-in-a-bulb) outranks the OS but not an explicit
372
+ // in-iframe override, so the user can still toggle the embed independently.
373
+ var FORCED = ${p(JSON.stringify(d??null))};
355
374
  var stored = function() {
356
375
  try { var v = localStorage.getItem(KEY); return (v === 'dark' || v === 'light') ? v : undefined; }
357
376
  catch (e) { return undefined; }
358
377
  };
359
378
  var apply = function(t) { doc.setAttribute('data-theme', t); };
360
- var effective = function() { return stored() || os(); };
379
+ var effective = function() { return stored() || FORCED || os(); };
361
380
  var set = function(v) {
362
381
  if (v === 'dark' || v === 'light') {
363
382
  try { localStorage.setItem(KEY, v); } catch (e) {}
@@ -382,7 +401,7 @@ declare const tb: {${_t}${It}${Dt}${Mt}${Dr}${Ot}${At}
382
401
  })();
383
402
  </script>
384
403
  <script type="importmap">
385
- ${JSON.stringify(f,null,2)}
404
+ ${JSON.stringify(m,null,2)}
386
405
  </script>
387
406
  <style>
388
407
  /* Reset and base styles */
@@ -396,37 +415,63 @@ ${r}
396
415
  </style>
397
416
  </head>
398
417
  <body>
399
- ${d}
418
+ ${u}
400
419
 
401
- ${o.length>0?`<script>window.__TB_DATA__ = ${u(JSON.stringify(o))};</script>`:""}
402
- ${i?`<script>window.__TB_INSIGHT__ = ${u(JSON.stringify(i))};</script>`:""}
403
- ${l?"<script>window.__TYPEBULB_WATCH__ = true;</script>":""}
420
+ ${i.length>0?`<script>window.__TB_DATA__ = ${p(JSON.stringify(i))};</script>`:""}
421
+ ${o?`<script>window.__TB_INSIGHT__ = ${p(JSON.stringify(o))};</script>`:""}
422
+ ${c?"<script>window.__TYPEBULB_WATCH__ = true;</script>":""}
404
423
 
405
424
  <script>
406
- ${qt}
425
+ ${Kt}
407
426
  </script>
408
427
 
428
+ ${Xr}
429
+
409
430
  <script type="module">
410
- ${u(t)}
431
+ ${p(t)}
411
432
  </script>
412
433
  </body>
413
- </html>`}function zr(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Kr(s){let e={};for(let[t,r]of Object.entries(s))e[t]=r.startsWith("https://")?"/proxy/"+r:r;return e}import{Hono as Xr}from"hono";import{serve as Qr}from"@hono/node-server";import{streamSSE as Zr}from"hono/streaming";import*as z from"fs/promises";import*as M from"path";var T=class extends Error{constructor(e,t="unknown",r=!1){super(e),this.code=t,this.retryable=r}},A=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=`
434
+ </html>`}var Xr=`<script>
435
+ (function () {
436
+ if (window.parent === window) return;
437
+ // Embedded: the host iframe owns sizing (auto-height below), so the document
438
+ // must not scroll itself \u2014 otherwise sub-pixel rounding (the frame landing a
439
+ // fraction shorter than content) leaves a phantom scrollbar. scrollHeight still
440
+ // reports true content, so this is invisible to auto-height. A +1px report buffer
441
+ // would seem simpler but runs away on full-bleed (height:100%) bulbs.
442
+ document.documentElement.style.overflow = 'hidden';
443
+ var post = function (m) { try { parent.postMessage(m, '*'); } catch (e) {} };
444
+ var sendHeight = function () {
445
+ post({ __typebulbEmbed: true, kind: 'height', height: Math.ceil(document.documentElement.scrollHeight) });
446
+ };
447
+ window.addEventListener('error', function (e) {
448
+ post({ __typebulbEmbed: true, kind: 'error', message: String((e && e.message) || (e && e.error) || 'Error') });
449
+ });
450
+ window.addEventListener('unhandledrejection', function (e) {
451
+ var r = e && e.reason;
452
+ var msg = r && r.message ? r.message : (r == null ? 'Unhandled rejection' : r);
453
+ post({ __typebulbEmbed: true, kind: 'error', message: String(msg) });
454
+ });
455
+ window.addEventListener('load', sendHeight);
456
+ if (window.ResizeObserver) { try { new ResizeObserver(sendHeight).observe(document.documentElement); } catch (e) {} }
457
+ })();
458
+ </script>`;function Qr(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Zr(s){let e={};for(let[t,r]of Object.entries(s))e[t]=r.startsWith("https://")?"/proxy/"+r:r;return e}import{Hono as tn}from"hono";import{serve as rn}from"@hono/node-server";import{streamSSE as nn}from"hono/streaming";import*as z from"fs/promises";import*as $ from"path";var C=class extends Error{constructor(e,t="unknown",r=!1){super(e),this.code=t,this.retryable=r}},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=`
414
459
 
415
- `){let r=e.filter(n=>n.role==="system").map(n=>n.content);return{system:r.length?r.join(t):void 0,conversationMessages:e.filter(n=>n.role!=="system")}}parseJsonError(e,t,r=!1){if(!e)return{message:`HTTP ${t}`};try{let n=JSON.parse(e);if(n.error&&typeof n.error=="object"){let o={message:n.error.message||`HTTP ${t}`,type:n.error.type};return r&&(o.code=n.error.code),o}return n.message?{message:n.message}:{message:e}}catch{return{message:e}}}checkAndThrowError(e){if("type"in e&&e.type==="error"&&"message"in e){let t=e.message,r=e.code||"unknown",n=!!e.retryable;throw new T(t,r,n)}if("error"in e&&e.error){let t=this.extractErrorMessage(e.error);throw new T(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 A{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,r,n){let{system:o,conversationMessages:i}=this.extractSystemMessages(e),a={model:t,max_tokens:this.getMaxTokens(t),messages:i,stream:n};if(r?.webSearch!==!1&&(a.tools=[{type:"web_search_20250305",name:"web_search"}]),o&&(a.system=o),this.isReasoningEnabled(r)){let l=r.reasoning;if(this.isModernModel(t)){let d={0:"low",1:"low",2:"medium",3:"high"};a.thinking={type:"adaptive"},a.output_config={effort:d[l]}}else{let d={0:0,1:2048,2:4096,3:8192};a.thinking={type:"enabled",budget_tokens:d[l]}}}return a}parseError(e,t){return this.parseJsonError(e,t)}parseNonStreamingResponse(e){if(!this.isAnthropicResponse(e))return{text:""};let t=e.content.filter(n=>n.type==="text").map(n=>n.text).join(""),r=e.content.filter(n=>n.type==="thinking").map(n=>n.thinking).join(`
460
+ `){let r=e.filter(n=>n.role==="system").map(n=>n.content);return{system:r.length?r.join(t):void 0,conversationMessages:e.filter(n=>n.role!=="system")}}parseJsonError(e,t,r=!1){if(!e)return{message:`HTTP ${t}`};try{let n=JSON.parse(e);if(n.error&&typeof n.error=="object"){let i={message:n.error.message||`HTTP ${t}`,type:n.error.type};return r&&(i.code=n.error.code),i}return n.message?{message:n.message}:{message:e}}catch{return{message:e}}}checkAndThrowError(e){if("type"in e&&e.type==="error"&&"message"in e){let t=e.message,r=e.code||"unknown",n=!!e.retryable;throw new C(t,r,n)}if("error"in e&&e.error){let t=this.extractErrorMessage(e.error);throw new C(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 Pe=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,r,n){let{system:i,conversationMessages:o}=this.extractSystemMessages(e),a={model:t,max_tokens:this.getMaxTokens(t),messages:this.withLastMessageCached(o),stream:n};if(r?.webSearch!==!1&&(a.tools=[{type:"web_search_20250305",name:"web_search"}]),i&&(a.system=[{type:"text",text:i,cache_control:{type:"ephemeral"}}]),this.isReasoningEnabled(r)){let c=r.reasoning;if(this.isModernModel(t)){let d={0:"low",1:"low",2:"medium",3:"high"};a.thinking={type:"adaptive"},a.output_config={effort:d[c]}}else{let d={0:0,1:2048,2:4096,3:8192};a.thinking={type:"enabled",budget_tokens:d[c]}}}return a}parseError(e,t){return this.parseJsonError(e,t)}parseNonStreamingResponse(e){if(!this.isAnthropicResponse(e))return{text:""};let t=e.content.filter(n=>n.type==="text").map(n=>n.text).join(""),r=e.content.filter(n=>n.type==="thinking").map(n=>n.thinking).join(`
416
461
 
417
- `);return{text:t,reasoning:r||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}}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 xe=class extends A{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,r,n){let o=this.convertMessagesToInput(e),i={model:t,input:o,stream:n};return r?.webSearch!==!1&&(i.tools=[{type:"web_search"}]),this.isReasoningEnabled(r)&&(i.reasoning={effort:this.effortMap[r.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||"",r;if(e.output&&Array.isArray(e.output))for(let n of e.output)n.type==="reasoning"&&n.summary&&(r=n.summary.map(o=>o.text).join(`
418
- `)),!t&&n.type==="message"&&n.content&&(t=n.content.filter(o=>o.type==="output_text").map(o=>o.text).join(""));return{text:t,reasoning:r}}parseProviderStreamChunk(e){if(!this.isResponsesApiEvent(e))return null;switch(e.type){case"error":return null;case"response.failed":{let n=e.response?.error,o=n?.message||"Response failed",i=n?.code==="insufficient_quota"||n?.code==="rate_limit_exceeded";throw new T(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(`
462
+ `);return{text:t,reasoning:r||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((r,n)=>n===t?{role:r.role,content:[{type:"text",text:r.content,cache_control:{type:"ephemeral"}}]}:r)}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 Se=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,r,n){let i=this.convertMessagesToInput(e),o={model:t,input:i,stream:n};return r?.webSearch!==!1&&(o.tools=[{type:"web_search"}]),this.isReasoningEnabled(r)&&(o.reasoning={effort:this.effortMap[r.reasoning],summary:"auto"}),o}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.isResponsesApiResponse(e))return{text:""};let t=e.output_text||"",r;if(e.output&&Array.isArray(e.output))for(let n of e.output)n.type==="reasoning"&&n.summary&&(r=n.summary.map(i=>i.text).join(`
463
+ `)),!t&&n.type==="message"&&n.content&&(t=n.content.filter(i=>i.type==="output_text").map(i=>i.text).join(""));return{text:t,reasoning:r}}parseProviderStreamChunk(e){if(!this.isResponsesApiEvent(e))return null;switch(e.type){case"error":return null;case"response.failed":{let n=e.response?.error,i=n?.message||"Response failed",o=n?.code==="insufficient_quota"||n?.code==="rate_limit_exceeded";throw new C(i,o?"rate_limit":"unknown",o)}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(`
419
464
 
420
- `)}isResponsesApiEvent(e){return"type"in e&&typeof e.type=="string"}isResponsesApiResponse(e){return"object"in e&&e.object==="response"}};var Pe=class extends A{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,r,n){let{system:o,conversationMessages:i}=this.extractSystemMessages(e,`
421
- `),l={contents:i.map(d=>({role:d.role==="assistant"?"model":"user",parts:[{text:d.content}]}))};return r?.webSearch!==!1&&(l.tools=[{google_search:{}}]),o&&(l.systemInstruction={role:"system",parts:[{text:o}]}),this.isReasoningEnabled(r)&&(l.generationConfig={temperature:.7+r.reasoning*.1}),l}parseError(e,t){if(!e)return{message:`HTTP ${t}`};try{let r=JSON.parse(e),n=Array.isArray(r)?r[0]?.error:r?.error;return n&&typeof n=="object"?{message:(n.message||`HTTP ${t}`).split(`
422
- `)[0],type:n.status,code:n.code?.toString()}:r.message?{message:r.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)||"",r=e.candidates?.[0]?.finishReason,n="complete";return r==="MAX_TOKENS"?n="interrupted":(r==="SAFETY"||r==="RECITATION")&&(n="failed"),{text:t,status:n}}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(r=>r.text).filter(Boolean).join("")}checkGeminiError(e){if(typeof e=="object"&&e!==null&&"error"in e){let t=e.error,r;if(typeof t=="string")r=t;else if(typeof t=="object"&&t!==null){let n=t;r=n.message||n.status||"Gemini returned an error"}else r="Gemini returned an error";throw new T(r)}if(this.isGeminiResponse(e)&&e.promptFeedback?.blockReason){let t=e.promptFeedback.blockReason;throw new T(`Prompt blocked: ${t}`)}}};var Se=class extends A{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 r={Authorization:`Bearer ${e}`,"x-api-key":e,"Content-Type":"application/json",Accept:"application/json","X-Title":"Typebulb"};return t&&(r["HTTP-Referer"]=t,r.Referer=t,r.Origin=t),r}buildPayload(e,t,r,n){let o={model:t,messages:e,stream:n};return r?.webSearch===!0&&(o.plugins=[{id:"web"}]),this.isReasoningEnabled(r)&&(o.reasoning={effort:this.effortMap[r.reasoning]}),o}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.hasChoices(e))return{text:""};let t=e.choices[0],r=t?.message?.content??t?.text??"",n=t?.message?.reasoning??e.reasoning;return{text:r,reasoning:n}}parseProviderStreamChunk(e){if(!this.hasChoices(e))return null;let t=e.choices[0];if(!t)return null;let r=t.delta||t.message;if(!r)return null;let n=r.content||void 0,o=r.reasoning||void 0;return!n&&!o?null:{text:n,reasoning:o}}hasChoices(e){return typeof e=="object"&&e!==null&&"choices"in e&&Array.isArray(e.choices)}};var Yr=new Map([["openai",new xe],["openrouter",new Se],["anthropic",new be],["gemini",new Pe]]);function G(s){let e=Yr.get(s);if(!e)throw new Error(`Unsupported protocol: ${s}`);return e}async function st(s,e){let t=G(s.protocol),r=t.getPath(e.model,e.stream),n=new URL(r,s.baseUrl).toString(),o=t.buildHeaders(s.apiKey,e.origin),i=t.buildPayload(e.messages,e.model,{reasoning:e.reasoning,webSearch:e.webSearch},e.stream);return e.modifyPayload?.(i),fetch(n,{method:"POST",headers:o,body:JSON.stringify(i),signal:e.signal})}async function ot(s,e){let t=G(e),r=await s.text().catch(()=>""),{message:n}=t.parseError(r,s.status),o=s.status,i="unknown";return o===429?i="rate_limit":o===413&&(i="context_exceeded"),{code:i,message:n,retryable:o===429}}function zt(s){let e=s.indexOf(`\r
465
+ `)}isResponsesApiEvent(e){return"type"in e&&typeof e.type=="string"}isResponsesApiResponse(e){return"object"in e&&e.object==="response"}};var Re=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,r,n){let{system:i,conversationMessages:o}=this.extractSystemMessages(e,`
466
+ `),c={contents:o.map(d=>({role:d.role==="assistant"?"model":"user",parts:[{text:d.content}]}))};return r?.webSearch!==!1&&(c.tools=[{google_search:{}}]),i&&(c.systemInstruction={role:"system",parts:[{text:i}]}),this.isReasoningEnabled(r)&&(c.generationConfig={temperature:.7+r.reasoning*.1}),c}parseError(e,t){if(!e)return{message:`HTTP ${t}`};try{let r=JSON.parse(e),n=Array.isArray(r)?r[0]?.error:r?.error;return n&&typeof n=="object"?{message:(n.message||`HTTP ${t}`).split(`
467
+ `)[0],type:n.status,code:n.code?.toString()}:r.message?{message:r.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)||"",r=e.candidates?.[0]?.finishReason,n="complete";return r==="MAX_TOKENS"?n="interrupted":(r==="SAFETY"||r==="RECITATION")&&(n="failed"),{text:t,status:n}}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(r=>r.text).filter(Boolean).join("")}checkGeminiError(e){if(typeof e=="object"&&e!==null&&"error"in e){let t=e.error,r;if(typeof t=="string")r=t;else if(typeof t=="object"&&t!==null){let n=t;r=n.message||n.status||"Gemini returned an error"}else r="Gemini returned an error";throw new C(r)}if(this.isGeminiResponse(e)&&e.promptFeedback?.blockReason){let t=e.promptFeedback.blockReason;throw new C(`Prompt blocked: ${t}`)}}};var Ee=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 r={Authorization:`Bearer ${e}`,"x-api-key":e,"Content-Type":"application/json",Accept:"application/json","X-Title":"Typebulb"};return t&&(r["HTTP-Referer"]=t,r.Referer=t,r.Origin=t),r}buildPayload(e,t,r,n){let i={model:t,messages:e,stream:n};return r?.webSearch===!0&&(i.plugins=[{id:"web"}]),this.isReasoningEnabled(r)&&(i.reasoning={effort:this.effortMap[r.reasoning]}),i}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.hasChoices(e))return{text:""};let t=e.choices[0],r=t?.message?.content??t?.text??"",n=t?.message?.reasoning??e.reasoning;return{text:r,reasoning:n}}parseProviderStreamChunk(e){if(!this.hasChoices(e))return null;let t=e.choices[0];if(!t)return null;let r=t.delta||t.message;if(!r)return null;let n=r.content||void 0,i=r.reasoning||void 0;return!n&&!i?null:{text:n,reasoning:i}}hasChoices(e){return typeof e=="object"&&e!==null&&"choices"in e&&Array.isArray(e.choices)}};var en=new Map([["openai",new Se],["openrouter",new Ee],["anthropic",new Pe],["gemini",new Re]]);function G(s){let e=en.get(s);if(!e)throw new Error(`Unsupported protocol: ${s}`);return e}async function ot(s,e){let t=G(s.protocol),r=t.getPath(e.model,e.stream),n=new URL(r,s.baseUrl).toString(),i=t.buildHeaders(s.apiKey,e.origin),o=t.buildPayload(e.messages,e.model,{reasoning:e.reasoning,webSearch:e.webSearch},e.stream);return e.modifyPayload?.(o),fetch(n,{method:"POST",headers:i,body:JSON.stringify(o),signal:e.signal})}async function at(s,e){let t=G(e),r=await s.text().catch(()=>""),{message:n}=t.parseError(r,s.status),i=s.status,o="unknown";return i===429?o="rate_limit":i===413&&(o="context_exceeded"),{code:o,message:n,retryable:i===429}}function Xt(s){let e=s.indexOf(`\r
423
468
  \r
424
469
  `),t=s.indexOf(`
425
470
 
426
- `);return e!==-1&&(t===-1||e<t)?{pos:e,len:4}:t!==-1?{pos:t,len:2}:{pos:-1,len:0}}function it(s){let t=s.split(/\r?\n/).filter(n=>n.startsWith("data:"));if(!t.length)return null;let r=t.map(n=>n.replace(/^data:\s?/,"")).join(`
427
- `).trim();if(!r)return null;if(r==="[DONE]")return"done";try{return JSON.parse(r)}catch{return null}}async function Kt(s,e,t){let r=new TextDecoder,n="",o=!1,i=t?new Promise((a,l)=>{t.aborted&&l(new Error("Aborted")),t.addEventListener("abort",()=>l(new Error("Aborted")),{once:!0})}):null;for(;;){let a=i?await Promise.race([s.read(),i]):await s.read(),{done:l,value:d}=a;if(l){if(n.trim()){let h=it(n);h!==null&&h!=="done"&&e(h)}break}o=!0,n+=r.decode(d,{stream:!0});let{pos:u,len:f}=zt(n);for(;u!==-1;){let h=n.slice(0,u);n=n.slice(u+f);let y=it(h);if(y==="done"){n="";break}y!==null&&e(y),{pos:u,len:f}=zt(n)}}return{receivedAnyData:o}}async function at(s,e){let t=e??(s.headers.get("X-Provider-Protocol")||"openai"),r=G(t);if(!s.body)throw new Error("Response body is missing");let n=s.body.getReader(),o="";return await Kt(n,i=>{let a=r.parseStreamChunk(i);a?.text&&(o+=a.text)}),o}import*as ct from"fs/promises";import*as Re from"path";var Ne=class{async get(e){let t=D(e),r=Re.join(ve,t+".bin"),n=Re.join(ve,t+".json");try{let[o,i]=await Promise.all([ct.readFile(r),ct.readFile(n,"utf8")]),a=JSON.parse(i);return{body:o,contentType:a.contentType,cacheControl:a.cacheControl}}catch{return}}async set(e,t){await b();let r=D(e),n=Re.join(ve,r+".bin"),o=Re.join(ve,r+".json"),i={url:e,contentType:t.contentType,cacheControl:t.cacheControl};await Promise.all([k(n,t.body),k(o,JSON.stringify(i))])}};async function Xt(s){let{getHtml:e,basePath:t,port:r,reloadEmitter:n,getServerExports:o,localOverride:i}=s,a=new Xr;a.use("*",async(c,p)=>{await p(),c.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),c.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")}),a.get("/",c=>c.html(e())),a.post("/__fs/read",async c=>{try{let{path:p}=await c.req.json(),g=dt(p,t),v=await z.readFile(g);return new Response(new Uint8Array(v),{headers:{"Content-Type":"application/octet-stream"}})}catch(p){let g=p instanceof Error?p.message:"Unknown error";return c.json({error:g},400)}}),a.post("/__fs/write",async c=>{try{let p=c.req.query("path");if(!p)return c.json({error:"Missing path"},400);let g=dt(p,t);return await z.mkdir(M.dirname(g),{recursive:!0}),await z.writeFile(g,Buffer.from(await c.req.arrayBuffer())),c.json({success:!0})}catch(p){let g=p instanceof Error?p.message:"Unknown error";return c.json({error:g},400)}});let l={log:console.log};a.post("/__api/:name",async c=>{try{let p=o?.(),g=c.req.param("name"),v=p?.[g]??l[g];if(!v||typeof v!="function")return c.json({error:`API function '${g}' not found`},404);let{args:w}=await c.req.json(),I=await v(...w||[]);return c.json({result:I})}catch(p){let g=p instanceof Error?p.message:"Unknown error";return c.json({error:g},500)}}),a.post("/__ai",async c=>{try{let{messages:p,system:g,reasoning:v,provider:w,model:I,webSearch:W}=await c.req.json();if(!p||!Array.isArray(p)||p.length===0)return c.json({message:"messages array is required",code:"unknown",retryable:!1},400);let $=en(w,I);if(typeof $=="string")return c.json({message:$,code:"unknown",retryable:!1},400);let Te=[...g?[{role:"system",content:g}]:[],...p.map(J=>({role:J.role,content:J.content}))],N=await st($,{model:$.model,messages:Te,stream:!0,reasoning:v??0,webSearch:W??!0});if(!N.ok){let J=await ot(N,$.protocol);return c.json(J,N.status)}let Y=await at(N,$.protocol);return Y||console.warn("[tb.ai] Empty response from provider"),c.json({text:Y})}catch(p){if(p instanceof T)return c.json({message:p.message,code:p.code,retryable:p.retryable},500);let g=p instanceof Error?p.message:"Unknown error";return c.json({message:g,code:"unknown",retryable:!1},500)}}),a.get("/__models",async c=>{try{let p=await nn();return c.json(p)}catch{return c.json([],200)}});let d=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"],u=new Ne;if(a.get("/proxy/*",async c=>{let p=new URL(c.req.url),v=(p.pathname+p.search).slice(7),w=v.lastIndexOf("https://");return w===-1?c.text("Invalid proxy URL",400):f(c,v.slice(w))}),i){let c=`/local/${i.name}/`;a.get("/local/*",async p=>{let{pathname:g}=new URL(p.req.url);if(!g.startsWith(c))return p.text("Not Found",404);let v=decodeURIComponent(g.slice(c.length));try{let w=dt(v,i.serveDir),I=await z.readFile(w);return new Response(I,{headers:{"Content-Type":sn(w)}})}catch{return p.text("Not Found",404)}})}async function f(c,p){let g;try{g=new URL(p)}catch{return c.text("Invalid URL",400)}if(g.protocol!=="https:")return c.text("HTTPS only",400);if(!d.includes(g.hostname))return c.text("Host not allowed",403);let v=await u.get(p);if(v)return new Response(v.body,{status:200,headers:lt(v.contentType,v.cacheControl)});try{let w=await fetch(p,{headers:{Accept:c.req.header("Accept")||"*/*"},redirect:"follow"});if(!w.ok)return c.text(`Upstream ${w.status}`,w.status);let I=w.headers.get("Content-Type")||void 0,W=w.headers.get("Cache-Control")||void 0;if(w.body){let[$,Te]=w.body.tee();return(async()=>{try{let N=await new Response(Te).arrayBuffer();await u.set(p,{body:Buffer.from(N),contentType:I,cacheControl:W})}catch{}})(),new Response($,{status:w.status,headers:lt(I,W)})}return new Response(null,{status:w.status,headers:lt(I,W)})}catch(w){return c.text(`Proxy fetch failed: ${w instanceof Error?w.message:w}`,502)}}n&&a.get("/__reload",c=>Zr(c,async p=>{let g=()=>{p.writeSSE({event:"reload",data:""})};for(n.on("reload",g),p.onAbort(()=>{n.removeListener("reload",g)});;)await p.sleep(3e4)}));let h=/^\/(v\d+\/|stable\/|node\/|gh\/|@[^/]+\/[^@/]+@|[^@/]+@)/;a.notFound(async c=>{if(c.req.method!=="GET")return c.text("Not Found",404);let p=new URL(c.req.url);return h.test(p.pathname)?f(c,"https://esm.sh"+p.pathname+p.search):c.text("Not Found",404)});let y=Qr({fetch:a.fetch,port:r});return{port:r,close:()=>y.close()}}var Qt={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"};function en(s,e){let t=s??process.env.TB_AI_PROVIDER,r=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(!r)return"No model specified. Set TB_AI_MODEL in your .env file or pass model in the tb.ai() call.";let n;try{n=G(t)}catch{return`Unknown provider '${t}'.`}let o=Qt[t],i=process.env[o];return i?{apiKey:i,baseUrl:n.defaultBaseUrl,protocol:t,model:r,isFreeModel:!1}:`No API key for '${t}'. Set ${o} in your .env file.`}var tn="https://api.typebulb.com/api/models",rn=1440*60*1e3,ne=null;async function nn(){if(!ne||Date.now()-ne.fetchedAt>rn){let s=await fetch(tn);if(!s.ok)return ne?Yt(ne.models):[];ne={models:await s.json(),fetchedAt:Date.now()}}return Yt(ne.models)}function Yt(s){let e=new Set(Object.entries(Qt).filter(([,t])=>!!process.env[t]).map(([t])=>t));return s.filter(t=>e.has(t.provider))}function lt(s,e){let t=new Headers;return s&&t.set("Content-Type",s),e&&t.set("Cache-Control",e),t.set("Access-Control-Allow-Origin","*"),t.set("Cross-Origin-Resource-Policy","cross-origin"),t}function sn(s){switch(M.extname(s).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 dt(s,e){let t=M.resolve(e,s),r=M.normalize(e),n=M.normalize(t);if(n!==r&&!n.startsWith(r+M.sep))throw new Error("Path traversal detected - access denied");return t}async function pt(s){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(s,()=>{let n=r.address(),o=typeof n=="object"&&n?n.port:s;r.close(()=>t(o))}),r.on("error",()=>{t(pt(s+1))})})}import on from"open";async function Zt(s){await on(s)}import er from"chokidar";var tr={persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}};function ut(s){let{bulbPath:e,emitter:t}=s,r=er.watch(e,tr);return r.on("change",()=>{t.emit("reload")}),()=>r.close()}function rr(s){let{dir:e,onChange:t,debounceMs:r=150}=s,n,o=er.watch(e,tr);return o.on("all",()=>{n&&clearTimeout(n),n=setTimeout(t,r)}),()=>{n&&clearTimeout(n),o.close()}}import*as R from"fs/promises";import*as S from"path";import*as se from"path";var an=se.join(Ae,"pkg"),cn=se.join(Ae,"files"),ln=se.join(Ae,"negative.json"),Ue=class{pkgMem=new Map;fileMem=new Map;negativeCache=new H(new te(ln));async getCachedDts(e){if(this.pkgMem.has(e))return this.pkgMem.get(e);await b();let t=await q(nr(e));return this.pkgMem.set(e,t),t}async setCachedDts(e,t,r){let n={content:t,url:r};this.pkgMem.set(e,n),await Le(async()=>{await b(),await k(nr(e),JSON.stringify(n))})}async getCachedFile(e){if(this.fileMem.has(e))return this.fileMem.get(e);await b();let t=await Oe(sr(e));return this.fileMem.set(e,t),t}async setCachedFile(e,t){this.fileMem.set(e,t),await Le(async()=>{await b(),await k(sr(e),t)})}isNegative(e){return this.negativeCache.isNegative(e)}async recordNegative(e){await Le(async()=>{await b(),await this.negativeCache.recordNegative(e)})}clearNegative(e){return Le(()=>this.negativeCache.clearNegative(e))}};async function Le(s){try{await s()}catch{}}function nr(s){return se.join(an,D(s)+".json")}function sr(s){return se.join(cn,D(s)+".txt")}var ft;function dn(){return ft||(ft=et({cache:new Ue,cdnClient:Ht,packageService:je,versionResolver:Vt})),ft}var or="file:///node_modules/";async function ir(s){let e=Me(s.emitKey,"typecheck");await b(),await R.rm(e,{recursive:!0,force:!0}),await R.mkdir(e,{recursive:!0});let t=hn(s.jsxImportSource,s.dependencies),r=await dn().resolve(s.code,s.dependencies,t),n=s.local?.name,o=n?r.filter(d=>d.pkg!==n):r,i=new Set;for(let d of o)for(let u of d.files){let f=ht(u.path);if(!f||i.has(f))continue;i.add(f);let h=S.join(e,"node_modules",f);await R.mkdir(S.dirname(h),{recursive:!0}),await R.writeFile(h,u.content,"utf8")}let a={};for(let d of o)for(let u of d.shims){let f=ht(u.path);f&&(a[u.module]=[`./node_modules/${f}`])}for(let d of o){let u=ht(d.mainPath);u&&(a[d.pkg]=[`./node_modules/${u}`])}if(s.local){delete a[s.local.name];let d=await mn(s.local,e);d?a[s.local.name]=[`./node_modules/${s.local.name}/${d}`]:console.warn(` local: '${s.local.name}' ships no type defs; check cannot type against it.`)}let l=pn(s.jsxImportSource,a);return await R.writeFile(S.join(e,"tsconfig.json"),JSON.stringify(l,null,2)+`
428
- `,"utf8"),await R.writeFile(S.join(e,"code.tsx"),s.code,"utf8"),await R.writeFile(S.join(e,"tb.d.ts"),Ye,"utf8"),{dir:e}}function pn(s,e){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"bundler",lib:un([...ze,...Ke]),jsx:"react-jsx",jsxImportSource:s??"react",strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0,baseUrl:".",paths:e},include:["code.tsx","tb.d.ts"]}}function un(s){return s.filter(e=>!e.since).map(e=>fn(e.name))}function fn(s){return s.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 hn(s,e){let t=s??("react"in e?"react":void 0);return t?[`${t}/jsx-runtime`,`${t}/jsx-dev-runtime`]:[]}function ht(s){if(!s.startsWith(or))return;let e=s.slice(or.length),t=e.indexOf("/");if(!(t<0))return e.slice(t+1)}async function mn(s,e){if(!s.typesAbs)return;let t=S.dirname(s.typesAbs),r=S.join(e,"node_modules",s.name);for(let n of await gn(t)){let o=S.join(r,S.relative(t,n));await R.mkdir(S.dirname(o),{recursive:!0}),await R.copyFile(n,o)}return S.basename(s.typesAbs)}async function gn(s){let e=[];async function t(r){let n=await R.readdir(r,{withFileTypes:!0});for(let o of n){let i=S.join(r,o.name);o.isDirectory()?await t(i):/\.d\.ts(\.map)?$/.test(o.name)&&e.push(i)}}return await t(s),e}import*as C from"fs/promises";import*as K from"path";import{existsSync as Pn}from"fs";import*as Be from"fs/promises";import*as mt from"path";import{existsSync as ar}from"fs";import{execFile as yn}from"child_process";import{promisify as wn}from"util";var vn=wn(yn);async function We(s,e){let t=s.filter(n=>!bn(n,e));if(t.length===0)return;await Be.mkdir(e,{recursive:!0});let r=mt.join(e,"package.json");ar(r)||await Be.writeFile(r,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${t.join(", ")}`),await vn("npm",["install","--no-audit","--no-fund",...t],{cwd:e,shell:!0})}function bn(s,e){return ar(mt.join(e,"node_modules",xn(s)))}function Je(s){let e=new Set,t=/\bimport\s+(?:[\s\S]*?\s+from\s+)?['"]([^./][^'"]*)['"]/g,r;for(;r=t.exec(s);){let n=r[1];if(n.startsWith("node:"))continue;let o=n.startsWith("@")?n.split("/").slice(0,2).join("/"):n.split("/")[0];e.add(o)}return[...e]}function xn(s){if(s.startsWith("@")){let t=s.indexOf("/");if(t<0)return s;let r=s.indexOf("@",t+1);return r<0?s:s.slice(0,r)}let e=s.indexOf("@");return e<0?s:s.slice(0,e)}var Sn="^22";async function cr(s){let e=Me(s.emitKey,"typecheck-server");await b(),await C.rm(e,{recursive:!0,force:!0}),await C.mkdir(e,{recursive:!0});let t=K.join(s.bulbDir,".typebulb"),r=Je(s.server);await We([`@types/node@${Sn}`,...r],t);let n=K.join(t,"node_modules"),o=K.join(e,"node_modules");return await En(n,o),await C.writeFile(K.join(e,"server.ts"),s.server,"utf8"),await C.writeFile(K.join(e,"tb.d.ts"),Xe,"utf8"),await C.writeFile(K.join(e,"tsconfig.json"),JSON.stringify(Rn(),null,2)+`
429
- `,"utf8"),{dir:e}}function Rn(){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"node",lib:["ES2023"],types:["node"],strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0},include:["server.ts","tb.d.ts"]}}async function En(s,e){if(!Pn(s)){await C.mkdir(e,{recursive:!0});return}await C.rm(e,{recursive:!0,force:!0});let t=process.platform==="win32"?"junction":"dir";await C.symlink(s,e,t)}import*as yt from"fs/promises";import{existsSync as Ee}from"fs";import*as x from"path";import{resolve as lr}from"resolve.exports";import{init as kn,parse as Tn}from"es-module-lexer";var gt=["browser","import","default"];function dr(s){let e=s.indexOf("=");if(e===-1)throw new Error(`--replace must be <name>=<path> (got '${s}')`);let t=s.slice(0,e).trim(),r=s.slice(e+1).trim();if(!t)throw new Error(`--replace missing package name (got '${s}')`);if(!r)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:x.resolve(r)}}async function pr(s){let{name:e,dir:t}=s;if(!Ee(t))throw new Error(`--replace path for '${e}' does not exist: ${t}`);let r=x.join(t,"package.json"),n;try{n=JSON.parse(await yt.readFile(r,"utf8"))}catch{throw new Error(`--replace package '${e}' has no readable package.json at ${r}`)}let o=Cn(n,e),i=x.resolve(t,o);if(!Ee(i))throw new Error(`--replace package '${e}' entry not found on disk: ${i} \u2014 did you build it (e.g. \`pnpm run build\`)?`);let a=x.dirname(i),l=`/local/${e}/${x.basename(i)}`,d=_n(n,t);return await In(e,i,a),{name:e,dir:t,entryAbs:i,serveDir:a,entryUrl:l,typesAbs:d}}function Cn(s,e){if(s.exports!==void 0){let r;try{r=lr(s,".",{browser:!0,conditions:gt})}catch(o){throw new Error(`--replace package '${e}' "exports" does not resolve a browser entry (conditions: ${gt.join(", ")}): ${o instanceof Error?o.message:o}`)}let n=ur(r);if(!n)throw new Error(`--replace package '${e}' "exports" did not resolve "." to a single file (conditions: ${gt.join(", ")}); too complex to override.`);return n}let t=s.module??s.main;if(!t)throw new Error(`--replace package '${e}' has no "exports", "module", or "main" entry to resolve.`);return t}function _n(s,e){if(s.exports!==void 0)try{let r=lr(s,".",{conditions:["types"]}),n=ur(r);if(n){let o=x.resolve(e,n);if(Ee(o))return o}}catch{}let t=s.types??s.typings;if(t){let r=x.resolve(e,t);if(Ee(r))return r}}function ur(s){if(typeof s=="string")return s;if(Array.isArray(s))return s.find(e=>typeof e=="string")}async function In(s,e,t){await kn;let r=x.normalize(t),n=new Set,o=[e];for(;o.length;){let i=o.shift();if(n.has(i))continue;n.add(i);let a;try{a=await yt.readFile(i,"utf8")}catch{continue}let l,d;try{[l,,,d]=Tn(a,i)}catch{continue}if(i===e&&!d)throw new Error(`override package '${s}' 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 u of l){if(u.d===-2)continue;let f=u.n;if(f&&!f.startsWith("node:")){if(f.startsWith("./")||f.startsWith("../")||f.startsWith("/")){let h=Dn(i,f,r);h&&!n.has(h)&&o.push(h);continue}throw new Error(`override package must ship self-contained (bundle its dependencies); ${s} externalizes '${f}'`)}}}}function Dn(s,e,t){let r=e.replace(/[?#].*$/,""),n=x.resolve(x.dirname(s),r),o=[n,n+".js",n+".mjs",x.join(n,"index.js"),x.join(n,"index.mjs")];for(let i of o)if(x.normalize(i).startsWith(t)&&Ee(i))return i}var ea=Fn(Mn),jn="0.7.1";function Nn(s){let e={subcommand:"run",file:"",port:3e3,watch:!0,open:!0,server:!1,help:!1,version:!1};s[0]==="check"&&(e.subcommand="check",s=s.slice(1));for(let t=0;t<s.length;t++){let r=s[t];if(r==="--help"||r==="-h")e.help=!0;else if(r==="--version"||r==="-V")e.version=!0;else if(r==="--no-watch")e.watch=!1;else if(r==="--no-open")e.open=!1;else if(r==="--server")e.server=!0;else if(r==="--port"||r==="-p"){let n=s[++t],o=parseInt(n,10);isNaN(o)&&(console.error(`Invalid port: ${n}`),process.exit(1)),e.port=o}else if(r==="--replace"||r.startsWith("--replace=")){let n=r.startsWith("--replace=")?r.slice(10):s[++t]??"";try{let o=dr(n);if(e.local)throw new Error(`--replace can only be used once (got '${e.local.name}' and '${o.name}')`);e.local=o}catch(o){console.error(o instanceof Error?o.message:String(o)),process.exit(1)}}else r.startsWith("-")||(e.file=r)}return e}function Ln(){console.log(`
471
+ `);return e!==-1&&(t===-1||e<t)?{pos:e,len:4}:t!==-1?{pos:t,len:2}:{pos:-1,len:0}}function ct(s){let t=s.split(/\r?\n/).filter(n=>n.startsWith("data:"));if(!t.length)return null;let r=t.map(n=>n.replace(/^data:\s?/,"")).join(`
472
+ `).trim();if(!r)return null;if(r==="[DONE]")return"done";try{return JSON.parse(r)}catch{return null}}async function Qt(s,e,t){let r=new TextDecoder,n="",i=!1,o=t?new Promise((a,c)=>{t.aborted&&c(new Error("Aborted")),t.addEventListener("abort",()=>c(new Error("Aborted")),{once:!0})}):null;for(;;){let a=o?await Promise.race([s.read(),o]):await s.read(),{done:c,value:d}=a;if(c){if(n.trim()){let m=ct(n);m!==null&&m!=="done"&&e(m)}break}i=!0,n+=r.decode(d,{stream:!0});let{pos:u,len:p}=Xt(n);for(;u!==-1;){let m=n.slice(0,u);n=n.slice(u+p);let w=ct(m);if(w==="done"){n="";break}w!==null&&e(w),{pos:u,len:p}=Xt(n)}}return{receivedAnyData:i}}async function lt(s,e){let t=e??(s.headers.get("X-Provider-Protocol")||"openai"),r=G(t);if(!s.body)throw new Error("Response body is missing");let n=s.body.getReader(),i="";return await Qt(n,o=>{let a=r.parseStreamChunk(o);a?.text&&(i+=a.text)}),i}import*as dt from"fs/promises";import*as ke from"path";var Le=class{async get(e){let t=D(e),r=ke.join(xe,t+".bin"),n=ke.join(xe,t+".json");try{let[i,o]=await Promise.all([dt.readFile(r),dt.readFile(n,"utf8")]),a=JSON.parse(o);return{body:i,contentType:a.contentType,cacheControl:a.cacheControl}}catch{return}}async set(e,t){await x();let r=D(e),n=ke.join(xe,r+".bin"),i=ke.join(xe,r+".json"),o={url:e,contentType:t.contentType,cacheControl:t.cacheControl};await Promise.all([T(n,t.body),T(i,JSON.stringify(o))])}};var tr="127.0.0.1",sn=new Set(["localhost","127.0.0.1","::1"]);function on(s){if(s)try{return new URL(s.includes("://")?s:`http://${s}`).hostname}catch{return}}function Zt(s){let e=on(s);return!!e&&sn.has(e)}function Ue(s){return s instanceof Error?s.message:"Unknown error"}async function rr(s){let{getHtml:e,basePath:t,port:r,reloadEmitter:n,getServerExports:i,localOverride:o}=s,a=new tn;a.use("*",async(l,f)=>{if(!Zt(l.req.header("host")))return l.text("Forbidden: untrusted Host",403);await f()}),a.use("*",async(l,f)=>{await f(),l.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),l.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")});let c=async(l,f)=>{let g=l.req.header("sec-fetch-site");if(g){if(g==="cross-site")return l.text("Forbidden: cross-site request",403)}else{let b=l.req.header("origin");if(b&&!Zt(b))return l.text("Forbidden: cross-origin request",403)}await f()};a.use("/__fs/*",c),a.use("/__api/*",c),a.use("/__ai",c),a.get("/",l=>l.html(e())),a.post("/__fs/read",async l=>{try{let{path:f}=await l.req.json(),g=ut(f,t),b=await z.readFile(g);return new Response(new Uint8Array(b),{headers:{"Content-Type":"application/octet-stream"}})}catch(f){let g=Ue(f);return l.json({error:g},400)}}),a.post("/__fs/write",async l=>{try{let f=l.req.query("path");if(!f)return l.json({error:"Missing path"},400);let g=ut(f,t);return await z.mkdir($.dirname(g),{recursive:!0}),await z.writeFile(g,Buffer.from(await l.req.arrayBuffer())),l.json({success:!0})}catch(f){let g=Ue(f);return l.json({error:g},400)}});let d={log:console.log};a.post("/__api/:name",async l=>{try{let f=i?.(),g=l.req.param("name"),b=f?.[g]??d[g];if(!b||typeof b!="function")return l.json({error:`API function '${g}' not found`},404);let{args:v}=await l.req.json(),I=await b(...v||[]);return l.json({result:I})}catch(f){let g=Ue(f);return l.json({error:g},500)}}),a.post("/__ai",async l=>{try{let{messages:f,system:g,reasoning:b,provider:v,model:I,webSearch:J}=await l.req.json();if(!f||!Array.isArray(f)||f.length===0)return l.json({message:"messages array is required",code:"unknown",retryable:!1},400);let N=an(v,I);if(typeof N=="string")return l.json({message:N,code:"unknown",retryable:!1},400);let ie=[...g?[{role:"system",content:g}]:[],...f.map(Y=>({role:Y.role,content:Y.content}))],F=await ot(N,{model:N.model,messages:ie,stream:!0,reasoning:b??0,webSearch:J??!0});if(!F.ok){let Y=await at(F,N.protocol);return l.json(Y,F.status)}let oe=await lt(F,N.protocol);return oe||console.warn("[tb.ai] Empty response from provider"),l.json({text:oe})}catch(f){if(f instanceof C)return l.json({message:f.message,code:f.code,retryable:f.retryable},500);let g=Ue(f);return l.json({message:g,code:"unknown",retryable:!1},500)}}),a.get("/__models",async l=>{try{let f=await dn();return l.json(f)}catch{return l.json([],200)}});let u=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"],p=new Le;if(a.get("/proxy/*",async l=>{let f=new URL(l.req.url),b=(f.pathname+f.search).slice(7),v=b.lastIndexOf("https://");return v===-1?l.text("Invalid proxy URL",400):m(l,b.slice(v))}),o){let l=`/local/${o.name}/`;a.get("/local/*",async f=>{let{pathname:g}=new URL(f.req.url);if(!g.startsWith(l))return f.text("Not Found",404);let b=decodeURIComponent(g.slice(l.length));try{let v=ut(b,o.serveDir),I=await z.readFile(v);return new Response(I,{headers:{"Content-Type":pn(v)}})}catch{return f.text("Not Found",404)}})}async function m(l,f){let g;try{g=new URL(f)}catch{return l.text("Invalid URL",400)}if(g.protocol!=="https:")return l.text("HTTPS only",400);if(!u.includes(g.hostname))return l.text("Host not allowed",403);let b=await p.get(f);if(b)return new Response(b.body,{status:200,headers:pt(b.contentType,b.cacheControl)});try{let v=await fetch(f,{headers:{Accept:l.req.header("Accept")||"*/*"},redirect:"follow"});if(!v.ok)return l.text(`Upstream ${v.status}`,v.status);let I=v.headers.get("Content-Type")||void 0,J=v.headers.get("Cache-Control")||void 0;if(v.body){let[N,ie]=v.body.tee();return(async()=>{try{let F=await new Response(ie).arrayBuffer();await p.set(f,{body:Buffer.from(F),contentType:I,cacheControl:J})}catch{}})(),new Response(N,{status:v.status,headers:pt(I,J)})}return new Response(null,{status:v.status,headers:pt(I,J)})}catch(v){return l.text(`Proxy fetch failed: ${v instanceof Error?v.message:v}`,502)}}n&&a.get("/__reload",l=>nn(l,async f=>{let g=()=>{f.writeSSE({event:"reload",data:""})};for(n.on("reload",g),f.onAbort(()=>{n.removeListener("reload",g)});;)await f.sleep(3e4)}));let w=/^\/(v\d+\/|stable\/|node\/|gh\/|@[^/]+\/[^@/]+@|[^@/]+@)/;a.notFound(async l=>{if(l.req.method!=="GET")return l.text("Not Found",404);let f=new URL(l.req.url);return w.test(f.pathname)?m(l,"https://esm.sh"+f.pathname+f.search):l.text("Not Found",404)});let h=rn({fetch:a.fetch,port:r,hostname:tr});return{port:r,close:()=>h.close()}}var nr={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"};function an(s,e){let t=s??process.env.TB_AI_PROVIDER,r=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(!r)return"No model specified. Set TB_AI_MODEL in your .env file or pass model in the tb.ai() call.";let n;try{n=G(t)}catch{return`Unknown provider '${t}'.`}let i=nr[t],o=process.env[i];return o?{apiKey:o,baseUrl:n.defaultBaseUrl,protocol:t,model:r,isFreeModel:!1}:`No API key for '${t}'. Set ${i} in your .env file.`}var cn="https://api.typebulb.com/api/models",ln=1440*60*1e3,ne=null;async function dn(){if(!ne||Date.now()-ne.fetchedAt>ln){let s=await fetch(cn);if(!s.ok)return ne?er(ne.models):[];ne={models:await s.json(),fetchedAt:Date.now()}}return er(ne.models)}function er(s){let e=new Set(Object.entries(nr).filter(([,t])=>!!process.env[t]).map(([t])=>t));return s.filter(t=>e.has(t.provider))}function pt(s,e){let t=new Headers;return s&&t.set("Content-Type",s),e&&t.set("Cache-Control",e),t.set("Access-Control-Allow-Origin","*"),t.set("Cross-Origin-Resource-Policy","cross-origin"),t}function pn(s){switch($.extname(s).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 ut(s,e){let t=$.resolve(e,s),r=$.normalize(e),n=$.normalize(t);if(n!==r&&!n.startsWith(r+$.sep))throw new Error("Path traversal detected - access denied");return t}async function ht(s){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(s,tr,()=>{let n=r.address(),i=typeof n=="object"&&n?n.port:s;r.close(()=>t(i))}),r.on("error",()=>{t(ht(s+1))})})}import un from"open";async function sr(s){await un(s)}import ir from"chokidar";var or={persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}};function ft(s){let{bulbPath:e,emitter:t}=s,r=ir.watch(e,or);return r.on("change",()=>{t.emit("reload")}),()=>r.close()}function ar(s){let{dir:e,onChange:t,debounceMs:r=150}=s,n,i=ir.watch(e,or);return i.on("all",()=>{n&&clearTimeout(n),n=setTimeout(t,r)}),()=>{n&&clearTimeout(n),i.close()}}import*as E from"fs/promises";import*as R from"path";import*as se from"path";var hn=se.join(Me,"pkg"),fn=se.join(Me,"files"),mn=se.join(Me,"negative.json"),We=class{pkgMem=new Map;fileMem=new Map;negativeCache=new H(new te(mn));async getCachedDts(e){if(this.pkgMem.has(e))return this.pkgMem.get(e);await x();let t=await q(cr(e));return this.pkgMem.set(e,t),t}async setCachedDts(e,t,r){let n={content:t,url:r};this.pkgMem.set(e,n),await Be(async()=>{await x(),await T(cr(e),JSON.stringify(n))})}async getCachedFile(e){if(this.fileMem.has(e))return this.fileMem.get(e);await x();let t=await Ae(lr(e));return this.fileMem.set(e,t),t}async setCachedFile(e,t){this.fileMem.set(e,t),await Be(async()=>{await x(),await T(lr(e),t)})}isNegative(e){return this.negativeCache.isNegative(e)}async recordNegative(e){await Be(async()=>{await x(),await this.negativeCache.recordNegative(e)})}clearNegative(e){return Be(()=>this.negativeCache.clearNegative(e))}};async function Be(s){try{await s()}catch{}}function cr(s){return se.join(hn,D(s)+".json")}function lr(s){return se.join(fn,D(s)+".txt")}var mt;function gn(){return mt||(mt=rt({cache:new We,cdnClient:zt,packageService:Ne,versionResolver:Gt})),mt}var dr="file:///node_modules/";async function pr(s){let e=$e(s.emitKey,"typecheck");await x(),await E.rm(e,{recursive:!0,force:!0}),await E.mkdir(e,{recursive:!0});let t=bn(s.jsxImportSource,s.dependencies),r=await gn().resolve(s.code,s.dependencies,t),n=s.local?.name,i=n?r.filter(d=>d.pkg!==n):r,o=new Set;for(let d of i)for(let u of d.files){let p=gt(u.path);if(!p||o.has(p))continue;o.add(p);let m=R.join(e,"node_modules",p);await E.mkdir(R.dirname(m),{recursive:!0}),await E.writeFile(m,u.content,"utf8")}let a={};for(let d of i)for(let u of d.shims){let p=gt(u.path);p&&(a[u.module]=[`./node_modules/${p}`])}for(let d of i){let u=gt(d.mainPath);u&&(a[d.pkg]=[`./node_modules/${u}`])}if(s.local){delete a[s.local.name];let d=await xn(s.local,e);d?a[s.local.name]=[`./node_modules/${s.local.name}/${d}`]:console.warn(` local: '${s.local.name}' ships no type defs; check cannot type against it.`)}let c=yn(s.jsxImportSource,a);return await E.writeFile(R.join(e,"tsconfig.json"),JSON.stringify(c,null,2)+`
473
+ `,"utf8"),await E.writeFile(R.join(e,"code.tsx"),s.code,"utf8"),await E.writeFile(R.join(e,"tb.d.ts"),Qe,"utf8"),{dir:e}}function yn(s,e){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"bundler",lib:wn([...Ye,...Xe]),jsx:"react-jsx",jsxImportSource:s??"react",strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0,baseUrl:".",paths:e},include:["code.tsx","tb.d.ts"]}}function wn(s){return s.filter(e=>!e.since).map(e=>vn(e.name))}function vn(s){return s.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 bn(s,e){let t=s??("react"in e?"react":void 0);return t?[`${t}/jsx-runtime`,`${t}/jsx-dev-runtime`]:[]}function gt(s){if(!s.startsWith(dr))return;let e=s.slice(dr.length),t=e.indexOf("/");if(!(t<0))return e.slice(t+1)}async function xn(s,e){if(!s.typesAbs)return;let t=R.dirname(s.typesAbs),r=R.join(e,"node_modules",s.name);for(let n of await Pn(t)){let i=R.join(r,R.relative(t,n));await E.mkdir(R.dirname(i),{recursive:!0}),await E.copyFile(n,i)}return R.basename(s.typesAbs)}async function Pn(s){let e=[];async function t(r){let n=await E.readdir(r,{withFileTypes:!0});for(let i of n){let o=R.join(r,i.name);i.isDirectory()?await t(o):/\.d\.ts(\.map)?$/.test(i.name)&&e.push(o)}}return await t(s),e}import*as _ from"fs/promises";import*as K from"path";import{existsSync as Cn}from"fs";import*as Je from"fs/promises";import*as yt from"path";import{existsSync as ur}from"fs";import{execFile as Sn}from"child_process";import{promisify as Rn}from"util";var En=Rn(Sn);async function Ve(s,e){let t=s.filter(n=>!kn(n,e));if(t.length===0)return;await Je.mkdir(e,{recursive:!0});let r=yt.join(e,"package.json");ur(r)||await Je.writeFile(r,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${t.join(", ")}`),await En("npm",["install","--no-audit","--no-fund",...t],{cwd:e,shell:!0})}function kn(s,e){return ur(yt.join(e,"node_modules",Tn(s)))}function He(s){let e=new Set,t=/\bimport\s+(?:[\s\S]*?\s+from\s+)?['"]([^./][^'"]*)['"]/g,r;for(;r=t.exec(s);){let n=r[1];if(n.startsWith("node:"))continue;let i=n.startsWith("@")?n.split("/").slice(0,2).join("/"):n.split("/")[0];e.add(i)}return[...e]}function Tn(s){if(s.startsWith("@")){let t=s.indexOf("/");if(t<0)return s;let r=s.indexOf("@",t+1);return r<0?s:s.slice(0,r)}let e=s.indexOf("@");return e<0?s:s.slice(0,e)}var _n="^22";async function hr(s){let e=$e(s.emitKey,"typecheck-server");await x(),await _.rm(e,{recursive:!0,force:!0}),await _.mkdir(e,{recursive:!0});let t=K.join(s.bulbDir,".typebulb"),r=He(s.server);await Ve([`@types/node@${_n}`,...r],t);let n=K.join(t,"node_modules"),i=K.join(e,"node_modules");return await In(n,i),await _.writeFile(K.join(e,"server.ts"),s.server,"utf8"),await _.writeFile(K.join(e,"tb.d.ts"),Ze,"utf8"),await _.writeFile(K.join(e,"tsconfig.json"),JSON.stringify(On(),null,2)+`
474
+ `,"utf8"),{dir:e}}function On(){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"node",lib:["ES2023"],types:["node"],strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0},include:["server.ts","tb.d.ts"]}}async function In(s,e){if(!Cn(s)){await _.mkdir(e,{recursive:!0});return}await _.rm(e,{recursive:!0,force:!0});let t=process.platform==="win32"?"junction":"dir";await _.symlink(s,e,t)}import*as vt from"fs/promises";import{existsSync as Te}from"fs";import*as P from"path";import{resolve as fr}from"resolve.exports";import{init as Dn,parse as An}from"es-module-lexer";var wt=["browser","import","default"];function mr(s){let e=s.indexOf("=");if(e===-1)throw new Error(`--replace must be <name>=<path> (got '${s}')`);let t=s.slice(0,e).trim(),r=s.slice(e+1).trim();if(!t)throw new Error(`--replace missing package name (got '${s}')`);if(!r)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(r)}}async function gr(s){let{name:e,dir:t}=s;if(!Te(t))throw new Error(`--replace path for '${e}' does not exist: ${t}`);let r=P.join(t,"package.json"),n;try{n=JSON.parse(await vt.readFile(r,"utf8"))}catch{throw new Error(`--replace package '${e}' has no readable package.json at ${r}`)}let i=Mn(n,e),o=P.resolve(t,i);if(!Te(o))throw new Error(`--replace package '${e}' entry not found on disk: ${o} \u2014 did you build it (e.g. \`pnpm run build\`)?`);let a=P.dirname(o),c=`/local/${e}/${P.basename(o)}`,d=$n(n,t);return await Fn(e,o,a),{name:e,dir:t,entryAbs:o,serveDir:a,entryUrl:c,typesAbs:d}}function Mn(s,e){if(s.exports!==void 0){let r;try{r=fr(s,".",{browser:!0,conditions:wt})}catch(i){throw new Error(`--replace package '${e}' "exports" does not resolve a browser entry (conditions: ${wt.join(", ")}): ${i instanceof Error?i.message:i}`)}let n=yr(r);if(!n)throw new Error(`--replace package '${e}' "exports" did not resolve "." to a single file (conditions: ${wt.join(", ")}); too complex to override.`);return n}let t=s.module??s.main;if(!t)throw new Error(`--replace package '${e}' has no "exports", "module", or "main" entry to resolve.`);return t}function $n(s,e){if(s.exports!==void 0)try{let r=fr(s,".",{conditions:["types"]}),n=yr(r);if(n){let i=P.resolve(e,n);if(Te(i))return i}}catch{}let t=s.types??s.typings;if(t){let r=P.resolve(e,t);if(Te(r))return r}}function yr(s){if(typeof s=="string")return s;if(Array.isArray(s))return s.find(e=>typeof e=="string")}async function Fn(s,e,t){await Dn;let r=P.normalize(t),n=new Set,i=[e];for(;i.length;){let o=i.shift();if(n.has(o))continue;n.add(o);let a;try{a=await vt.readFile(o,"utf8")}catch{continue}let c,d;try{[c,,,d]=An(a,o)}catch{continue}if(o===e&&!d)throw new Error(`override package '${s}' 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 u of c){if(u.d===-2)continue;let p=u.n;if(p&&!p.startsWith("node:")){if(p.startsWith("./")||p.startsWith("../")||p.startsWith("/")){let m=jn(o,p,r);m&&!n.has(m)&&i.push(m);continue}throw new Error(`override package must ship self-contained (bundle its dependencies); ${s} externalizes '${p}'`)}}}}function jn(s,e,t){let r=e.replace(/[?#].*$/,""),n=P.resolve(P.dirname(s),r),i=[n,n+".js",n+".mjs",P.join(n,"index.js"),P.join(n,"index.mjs")];for(let o of i)if(P.normalize(o).startsWith(t)&&Te(o))return o}var ca=Wn(Un),Jn="0.8.0";function Vn(s){let e={subcommand:"run",file:"",port:3e3,watch:!0,open:!0,server:!1,help:!1,version:!1};s[0]==="check"&&(e.subcommand="check",s=s.slice(1));for(let t=0;t<s.length;t++){let r=s[t];if(r==="--help"||r==="-h")e.help=!0;else if(r==="--version"||r==="-V")e.version=!0;else if(r==="--no-watch")e.watch=!1;else if(r==="--no-open")e.open=!1;else if(r==="--server")e.server=!0;else if(r==="--port"||r==="-p"){let n=s[++t],i=parseInt(n,10);isNaN(i)&&(console.error(`Invalid port: ${n}`),process.exit(1)),e.port=i}else if(r==="--replace"||r.startsWith("--replace=")){let n=r.startsWith("--replace=")?r.slice(10):s[++t]??"";try{let i=mr(n);if(e.local)throw new Error(`--replace can only be used once (got '${e.local.name}' and '${i.name}')`);e.local=i}catch(i){console.error(i instanceof Error?i.message:String(i)),process.exit(1)}}else r.startsWith("-")||(e.file=r)}return e}function Hn(){console.log(`
430
475
  typebulb - Local bulb runner for Typebulb
431
476
 
432
477
  Usage:
@@ -479,12 +524,12 @@ Examples:
479
524
  typebulb my-editor.bulb.md
480
525
  typebulb --no-watch --port 8080 my-editor.bulb.md
481
526
  typebulb .
482
- `)}async function Un(s){let t=(await _.readdir(s)).find(r=>r.endsWith(".bulb.md"));return t?P.join(s,t):null}function hr(){vt([".env",".env.local"],process.cwd(),!0)}function vt(s,e,t=!1){for(let r of s){let n=P.resolve(e,r);try{let o=On(n,"utf-8");for(let i of o.split(`
483
- `)){let a=i.trim();if(!a||a.startsWith("#"))continue;let l=a.indexOf("=");if(l===-1)continue;let d=a.slice(0,l).trim(),u=a.slice(l+1).trim();(u.startsWith('"')&&u.endsWith('"')||u.startsWith("'")&&u.endsWith("'"))&&(u=u.slice(1,-1)),process.env[d]??=u}}catch{t||console.warn(` Warning: env file not found: ${r}`)}}}async function mr(s,e){let t=Ve(s,{serverOnly:!0});if(t.error)throw new Error(`Server compilation error: ${t.error}`);let r=P.join(e,".typebulb");await _.mkdir(r,{recursive:!0});let n=Je(t.code);n.length>0&&await We(n,r);let o=P.join(r,"server.mjs");return await _.writeFile(o,t.code,"utf-8"),await import(`${An(o).href}?t=${Date.now()}`)}async function ke(s){let e=await _.readFile(s,"utf-8"),t=bt(e);if(!t)throw new Error("Invalid .bulb.md file format");let r=xt(t);return{bulb:r,config:St(r.config)}}async function fr(s,e,t){let{bulb:r,config:n}=await ke(s),o=Pt(r.data),i=Ve(r.code,{jsxImportSource:n.jsxImportSource});i.error&&console.error("Compilation error:",i.error);let{importMap:a}=await je.buildImportMap(i.code,n.dependencies??{},t?new Set([t.name]):void 0);t&&(a.imports[t.name]=t.entryUrl);let l=Gt({name:r.name,code:i.code,css:r.css,html:r.html,data:o,insight:r.insight,importMap:a,watch:e}),d=P.dirname(s);n.env?.length&&vt(n.env,d);let u=null;return r.server&&(u=await mr(r.server,d)),{html:l,bulb:r,serverExports:u}}async function Bn(s,e){let{bulb:t,config:r}=await ke(s);!t.code&&!t.server&&(console.error("Bulb has neither **code.tsx** nor **server.ts**; nothing to check."),process.exit(1));let n=[];if(t.code){let{dir:i}=await ir({code:t.code,dependencies:r.dependencies??{},jsxImportSource:r.jsxImportSource,emitKey:s,local:e});n.push({role:"client",dir:i})}if(t.server){let{dir:i}=await cr({server:t.server,bulbDir:P.dirname(s),emitKey:s});n.push({role:"server",dir:i})}let o=!1;for(let{role:i,dir:a}of n){let{stdout:l,exitCode:d}=await Wn(a);for(let u of l.split(/\r?\n/))u.trim()&&console.log(`${i} ${u}`);d!==0&&(o=!0)}o&&process.exit(1)}function Wn(s){return new Promise(e=>{let t=$n("npx",["tsc","--noEmit"],{cwd:s,shell:!0}),r="";t.stdout?.on("data",n=>{r+=n.toString()}),t.stderr?.on("data",n=>{r+=n.toString()}),t.on("close",n=>e({stdout:r,exitCode:n??1}))})}async function Jn(s,e){hr();let t=async()=>{let{bulb:r,config:n}=await ke(s),o=P.dirname(s);n.env?.length&&vt(n.env,o),await mr(r.server,o)};if(console.log(`Running ${P.basename(s)}...`),await t(),e){console.log(`Watching for changes...
484
- `);let r=new wt;r.on("reload",async()=>{try{console.log("Re-running..."),await t()}catch(n){console.error("Error:",n)}}),ut({bulbPath:s,emitter:r})}}async function Vn(){let s=Nn(process.argv.slice(2));s.version&&(console.log(`typebulb ${jn}`),process.exit(0)),s.help&&(Ln(),process.exit(0));let e;if(!s.file||s.file==="."){let c=await Un(process.cwd());c||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=c}else e=P.resolve(s.file);try{await _.access(e)}catch{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 t;if(s.local){let c;try{c=await ke(e)}catch{}c&&!(s.local.name in(c.config.dependencies??{}))&&(console.error(`--replace: '${s.local.name}' is not a dependency in this bulb's config.json; nothing to replace.`),process.exit(1)),c&&(!c.bulb.code||s.server)&&console.warn("warning: --replace has no effect in server mode (the override is client-only).");try{t=await pr(s.local)}catch(p){console.error(p instanceof Error?p.message:String(p)),process.exit(1)}console.log(`replace: ${t.name} \u2192 ${P.relative(process.cwd(),t.dir)||"."}`)}if(s.subcommand==="check"){await Bn(e,t);return}try{let{bulb:c}=await ke(e);if(c.server&&(!c.code||s.server)){await Jn(e,s.watch);return}}catch{}let r=process.cwd(),n=s.watch?new wt:void 0;hr(),console.log(`Loading ${P.basename(e)}...`);let{html:o,bulb:i,serverExports:a}=await fr(e,s.watch,t),l=await pt(s.port),d=await Xt({getHtml:()=>o,basePath:r,port:l,reloadEmitter:n,getServerExports:()=>a,localOverride:t?{name:t.name,serveDir:t.serveDir}:void 0}),u=`http://localhost:${l}`;console.log(`
485
- ${i.name}`),console.log(` ${u}
527
+ `)}async function qn(s){let t=(await O.readdir(s)).find(r=>r.endsWith(".bulb.md"));return t?S.join(s,t):null}function vr(){xt([".env",".env.local"],process.cwd(),!0)}function xt(s,e,t=!1){for(let r of s){let n=S.resolve(e,r);try{let i=Nn(n,"utf-8");for(let o of i.split(`
528
+ `)){let a=o.trim();if(!a||a.startsWith("#"))continue;let c=a.indexOf("=");if(c===-1)continue;let d=a.slice(0,c).trim(),u=a.slice(c+1).trim();(u.startsWith('"')&&u.endsWith('"')||u.startsWith("'")&&u.endsWith("'"))&&(u=u.slice(1,-1)),process.env[d]??=u}}catch{t||console.warn(` Warning: env file not found: ${r}`)}}}async function br(s,e){let t=qe(s,{serverOnly:!0});if(t.error)throw new Error(`Server compilation error: ${t.error}`);let r=S.join(e,".typebulb");await O.mkdir(r,{recursive:!0});let n=He(t.code);n.length>0&&await Ve(n,r);let i=S.join(r,"server.mjs");return await O.writeFile(i,t.code,"utf-8"),await import(`${Ln(i).href}?t=${Date.now()}`)}async function Ce(s){let e=await O.readFile(s,"utf-8"),t=Pt(e);if(!t)throw new Error("Invalid .bulb.md file format");let r=St(t);return{bulb:r,config:Et(r.config)}}async function wr(s,e,t){let{bulb:r,config:n}=await Ce(s),i=Rt(r.data),o=qe(r.code,{jsxImportSource:n.jsxImportSource});o.error&&console.error("Compilation error:",o.error);let{importMap:a}=await Ne.buildImportMap(o.code,n.dependencies??{},t?new Set([t.name]):void 0);t&&(a.imports[t.name]=t.entryUrl);let c=Yt({name:r.name,code:o.code,css:r.css,html:r.html,data:i,insight:r.insight,importMap:a,watch:e}),d=S.dirname(s);n.env?.length&&xt(n.env,d);let u=null;return r.server&&(u=await br(r.server,d)),{html:c,bulb:r,serverExports:u}}async function Gn(s,e){let{bulb:t,config:r}=await Ce(s);!t.code&&!t.server&&(console.error("Bulb has neither **code.tsx** nor **server.ts**; nothing to check."),process.exit(1));let n=[];if(t.code){let{dir:o}=await pr({code:t.code,dependencies:r.dependencies??{},jsxImportSource:r.jsxImportSource,emitKey:s,local:e});n.push({role:"client",dir:o})}if(t.server){let{dir:o}=await hr({server:t.server,bulbDir:S.dirname(s),emitKey:s});n.push({role:"server",dir:o})}let i=!1;for(let{role:o,dir:a}of n){let{stdout:c,exitCode:d}=await zn(a);for(let u of c.split(/\r?\n/))u.trim()&&console.log(`${o} ${u}`);d!==0&&(i=!0)}i&&process.exit(1)}function zn(s){return new Promise(e=>{let t=Bn("npx",["tsc","--noEmit"],{cwd:s,shell:!0}),r="";t.stdout?.on("data",n=>{r+=n.toString()}),t.stderr?.on("data",n=>{r+=n.toString()}),t.on("close",n=>e({stdout:r,exitCode:n??1}))})}async function Kn(s,e){vr();let t=async()=>{let{bulb:r,config:n}=await Ce(s),i=S.dirname(s);n.env?.length&&xt(n.env,i),await br(r.server,i)};if(console.log(`Running ${S.basename(s)}...`),await t(),e){console.log(`Watching for changes...
529
+ `);let r=new bt;r.on("reload",async()=>{try{console.log("Re-running..."),await t()}catch(n){console.error("Error:",n)}}),ft({bulbPath:s,emitter:r})}}async function Yn(){let s=Vn(process.argv.slice(2));s.version&&(console.log(`typebulb ${Jn}`),process.exit(0)),s.help&&(Hn(),process.exit(0));let e;if(!s.file||s.file==="."){let h=await qn(process.cwd());h||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=h}else e=S.resolve(s.file);try{await O.access(e)}catch{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 t;if(s.local){let h;try{h=await Ce(e)}catch{}h&&!(s.local.name in(h.config.dependencies??{}))&&(console.error(`--replace: '${s.local.name}' is not a dependency in this bulb's config.json; nothing to replace.`),process.exit(1)),h&&(!h.bulb.code||s.server)&&console.warn("warning: --replace has no effect in server mode (the override is client-only).");try{t=await gr(s.local)}catch(l){console.error(l instanceof Error?l.message:String(l)),process.exit(1)}console.log(`replace: ${t.name} \u2192 ${S.relative(process.cwd(),t.dir)||"."}`)}if(s.subcommand==="check"){await Gn(e,t);return}try{let{bulb:h}=await Ce(e);if(h.server&&(!h.code||s.server)){await Kn(e,s.watch);return}}catch{}let r=process.cwd(),n=s.watch?new bt:void 0;vr(),console.log(`Loading ${S.basename(e)}...`);let{html:i,bulb:o,serverExports:a}=await wr(e,s.watch,t),c=await ht(s.port),d=await rr({getHtml:()=>i,basePath:r,port:c,reloadEmitter:n,getServerExports:()=>a,localOverride:t?{name:t.name,serveDir:t.serveDir}:void 0}),u=`http://localhost:${c}`;console.log(`
530
+ ${o.name}`),console.log(` ${u}
486
531
  `),s.watch&&console.log(` Watching for changes...
487
- `);let f,h;if(s.watch&&n){let c=new wt;if(c.on("reload",async()=>{try{console.log("Recompiling...");let p=await fr(e,!0,t);o=p.html,a=p.serverExports,n.emit("reload"),console.log(`Done. Browser reloading...
488
- `)}catch(p){console.error("Compile error:",p)}}),f=ut({bulbPath:e,emitter:c}),t){let{name:p,serveDir:g}=t;h=rr({dir:g,onChange:()=>{console.log(`Local package '${p}' changed. Browser reloading...
489
- `),n.emit("reload")}})}}s.open&&await Zt(u);let y=async()=>{console.log(`
490
- Shutting down...`),d.close(),f?.(),h?.();let c=P.join(P.dirname(e),".typebulb","server.mjs");await _.rm(c,{force:!0}).catch(()=>{}),process.exit(0)};process.on("SIGINT",y),process.on("SIGTERM",y)}Vn().catch(s=>{console.error("Error:",s.message),process.exit(1)});
532
+ `);let p,m;if(s.watch&&n){let h=new bt;if(h.on("reload",async()=>{try{console.log("Recompiling...");let l=await wr(e,!0,t);i=l.html,a=l.serverExports,n.emit("reload"),console.log(`Done. Browser reloading...
533
+ `)}catch(l){console.error("Compile error:",l)}}),p=ft({bulbPath:e,emitter:h}),t){let{name:l,serveDir:f}=t;m=ar({dir:f,onChange:()=>{console.log(`Local package '${l}' changed. Browser reloading...
534
+ `),n.emit("reload")}})}}s.open&&await sr(u);let w=async()=>{console.log(`
535
+ Shutting down...`),d.close(),p?.(),m?.();let h=S.join(S.dirname(e),".typebulb","server.mjs");await O.rm(h,{force:!0}).catch(()=>{}),process.exit(0)};process.on("SIGINT",w),process.on("SIGTERM",w)}Yn().catch(s=>{console.error("Error:",s.message),process.exit(1)});