typebulb 0.8.0 → 0.9.1

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 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=`
2
+ import*as M from"fs/promises";import{readFileSync as Hn}from"fs";import*as S from"path";import{pathToFileURL as Jn}from"url";import{execFile as Vn,spawn as qn}from"child_process";import{promisify as Gn}from"util";import{EventEmitter as Rt}from"events";var Tr={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 Tt(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=_r(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 l=e[t]?.match(/^(`{3,})(\w*)\s*$/);if(!l){t++;continue}let d=l[1];t++;let p=[];for(;t<e.length&&!e[t]?.match(new RegExp(`^${d}\\s*$`));)p.push(e[t]),t++;t++,i.set(c,p.join(`
4
+ `))}else t++}return{frontmatter:n,files:i}}catch{return null}}function _r(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=Cr(i);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function Cr(s){return s.startsWith('"')&&s.endsWith('"')?s.slice(1,-1).replace(/\\"/g,'"'):s.startsWith("'")&&s.endsWith("'")?s.slice(1,-1):s}function _t(s){let e=t=>s.files.get(Tr[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 Ir(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 Ct(s){let e=s.trim();return e?Ir(e)?[e]:s.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function It(s){if(!s.trim())return{};try{return JSON.parse(s)}catch{return{}}}import{transform as Or}from"sucrase";function Ye(s,e={}){let t=e.serverOnly?["typescript"]:["typescript","jsx"];try{let{code:r}=Or(s,{transforms:t,jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:r}}catch(r){return{code:"",error:String(r)}}}var ce="https://esm.sh",le="https://cdn.jsdelivr.net/npm/",Xe="https://data.jsdelivr.com/v1/package/npm/";function Ot(s){let e=(s||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var g=class s{constructor(e,t,r){let n=typeof e=="string"?s.parse(e):e;this.name=n.name,this.version=ee(t??n.version),this.subpath=ee(r??n.subpath)}static parse(e){let t=Ot(e||"");if(!t.length)return new s({name:""});if(t[0].startsWith("@")){let n=t[0],[i,o]=Dt(t[1]??""),a=ee(t.slice(2).join("/"));return new s({name:`${n}/${i}`,version:o,subpath:a})}else{let[n,i]=Dt(t[0]),o=ee(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(ce).host,n=new URL(le).host;if(t.host===r){let i=Ot(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:ee(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://")}},ee=s=>s&&s.length?s:void 0,Dt=s=>{let e=s.indexOf("@");return e<0?[s,void 0]:[s.slice(0,e),ee(s.slice(e+1))]};async function C(s){try{return await s()}catch{return}}var de=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=ce,this.jsDelivrBase=le,this.jsDelivrMeta=Xe,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 g(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 C(()=>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 C(()=>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 C(()=>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=g.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:d,peerDependencies:p,peerDependenciesMeta:h}=r;return{name:e,version:t,dependencies:d,peerDependencies:p,peerDependenciesMeta:h}}let n=this.packageJson(new g(`${e}@${t}`)),i=await C(()=>this.http.getJson(n));if(!i)return;let o=d=>d&&Object.keys(d).length?d:void 0,a=o(i.dependencies),c=o(i.peerDependencies),l=o(i.peerDependenciesMeta);return await this.cache.setMeta(e,t,a,c,l),{name:e,version:t,dependencies:a,peerDependencies:c,peerDependenciesMeta:l}}};var At=s=>s.startsWith("@types/"),pe=s=>Object.keys(s?.peerDependencies||{}).filter(e=>!At(e)),Qe=s=>Object.keys(s?.dependencies||{}).filter(e=>!At(e)),Dr=s=>pe(s).filter(e=>!s?.peerDependenciesMeta?.[e]?.optional),ue=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 Dr(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=>pe(i.meta))),r=new Map;for(let i of e)for(let o of Qe(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:pe(i.meta).length>0,isSharedDep:n.has(i.name)}]))}};var he=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 C(()=>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 C(()=>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 C(()=>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 g(e),n=r.root(),i=t[n],o=i?await C(()=>this.cache.getPinnedExact(n,i))??await C(()=>this.resolveExactForRoot(n,i)):void 0;return{effectivePackage:o?r.withVersion(o).format():e,root:n,range:i,pinned:o}}};import{init as Ar,parse as Mr}from"es-module-lexer";var te=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))g.isBare(n[1])&&t.add(n[1])}return Array.from(t)}async extractImports(e){let t=new Set,r=n=>{g.isBare(n)&&t.add(n)};try{await Ar;let[n]=Mr(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(g.rootOf(p))),i=[...new Set(n.map(g.rootOf))],o=await Promise.all(i.map(async p=>({name:p,version:await this.resolveVersion(p,t)}))),{allRoots:a,flags:c,autoAddedPeers:l}=await this.peer.resolve(o,p=>this.resolveVersion(p,t)),d=this.buildEntries([...n,...l.map(p=>p.name)],a,c,t);return{importMap:{imports:Object.fromEntries(d)},prefetchUrls:d.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 C(()=>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=g.versionFromUrl(o),i&&r&&await C(()=>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(f=>[f.name,f])),o=f=>{let R=i.get(g.rootOf(f));return new g(f).withPreferredVersion(R.version,n[R.name]).format()},a=new Set([...r.entries()].filter(([,f])=>f.isPeerRoot||f.isSharedDep).map(([f])=>f)),c=new Set(e.filter(f=>f!==g.rootOf(f)).map(g.rootOf)),l=[],d=new Set,p=new Set(e.filter(f=>f===g.rootOf(f))),h=new Set;for(let f of e){let R=g.rootOf(f),v=i.get(R),{isPeerRoot:k,hasPeers:$,isSharedDep:u}=r.get(R),m=c.has(R),y=f!==R,b=!(k||u)&&(m||!$),I=this.singletonDepsOf(v,a),H=y&&p.has(R);H&&h.add(R);let B=H?[...I,R]:I.length?I:void 0;l.push([f,this.cdn.buildEsmUrl(o(f),{bundle:b,external:B})]),d.add(f)}let w=new Set([...a,...h]);for(let f of w)i.has(f)&&(d.has(f)||l.push([f,this.cdn.buildEsmUrl(o(f),{})]),l.push([`${f}/`,`${this.cdn.esmHost}/${o(f)}/`]));return l}singletonDepsOf(e,t){return[...new Set([...pe(e.meta),...Qe(e.meta)])].filter(r=>t.has(r))}};te.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as Mt,satisfies as $r,maxSatisfying as Ze,major as Fr,prerelease as jr,rsort as Nr,valid as Lr}from"semver";var Oe=class{cmp(e,t){return e===t?0:Mt(e,t)?1:Mt(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=Ze(e,t,{includePrerelease:!0});return r===null?void 0:r}pickLatest(e){return e?.length?Nr(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=Ze(e,r,{includePrerelease:!1});if(a)return a}return Ze(e,r,{includePrerelease:!0})??void 0}majorOf(e){return Fr(e)}isPrerelease(e){return jr(e)!==null}isExactVersion(e){return Lr(e)!==null}},G=new Oe;function $t(s,e){let t=new de(s,e),r=new ue(t),n=new he(s,t,G);return{packageService:new te(n,t,r,s),versionResolver:n,cdnClient:t,peerResolver:r}}import*as Yt from"fs/promises";import*as j from"path";var et=[{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"}],tt=[{name:"dom"},{name:"dom.iterable"},{name:"dom.asynciterable"}];var Ft=`
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 O from"fs/promises";import{readFileSync as Nn}from"fs";import*as S 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;`,Dt=`
15
+ json<T = unknown>(index: number): T;`,jt=`
16
16
  /**
17
17
  * Get the insight data produced by the inference layer.
18
18
  *
@@ -21,7 +21,7 @@ import*as O from"fs/promises";import{readFileSync as Nn}from"fs";import*as S 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;`,At=`
24
+ insight<T = unknown>(): T | undefined;`,Nt=`
25
25
  /**
26
26
  * General-purpose AI call.
27
27
  *
@@ -38,7 +38,7 @@ import*as O from"fs/promises";import{readFileSync as Nn}from"fs";import*as S 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 }>;`,Mt=`
41
+ }): Promise<{ text: string }>;`,Lt=`
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,7 +53,7 @@ import*as O from"fs/promises";import{readFileSync as Nn}from"fs";import*as S fro
53
53
  friendlyName: string;
54
54
  /** Provider display name, e.g. "Anthropic" */
55
55
  providerName: string;
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=`
56
+ }>>;`,Br="\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;",Bt=`
57
57
  /**
58
58
  * The mode this bulb is running in.
59
59
  *
@@ -63,7 +63,7 @@ import*as O from"fs/promises";import{readFileSync as Nn}from"fs";import*as S fro
63
63
  * - \`'embedded'\` \u2014 Running as a bulb embedded inside another bulb (sandboxed,
64
64
  * client-only: AI, filesystem, and server RPC are unavailable)
65
65
  */
66
- mode: 'local' | 'editor' | 'published' | 'embedded';`,Ft=`
66
+ mode: 'local' | 'editor' | 'published' | 'embedded';`,Ut=`
67
67
  /**
68
68
  * Local filesystem access (CLI only).
69
69
  *
@@ -77,7 +77,7 @@ import*as O from"fs/promises";import{readFileSync as Nn}from"fs";import*as S fro
77
77
  readBytes(path: string): Promise<Uint8Array>;
78
78
  /** Write text or raw bytes to a file. Creates parent directories if needed. */
79
79
  write(path: string, content: string | Uint8Array): Promise<boolean>;
80
- };`,$r=`
80
+ };`,Ur=`
81
81
  /**
82
82
  * Server-side function proxy. The built-in \`log\` prints to CLI stdout
83
83
  * (falls back to console.log on web). On the server side, this object only
@@ -85,7 +85,7 @@ import*as O from"fs/promises";import{readFileSync as Nn}from"fs";import*as S fro
85
85
  */
86
86
  server: {
87
87
  log(...args: any[]): Promise<void>;
88
- };`,Fr=`
88
+ };`,Wr=`
89
89
  /**
90
90
  * Async value inspector for tensor-like objects.
91
91
  *
@@ -152,7 +152,7 @@ import*as O from"fs/promises";import{readFileSync as Nn}from"fs";import*as S fro
152
152
  *
153
153
  * @returns The full canonical URL
154
154
  */
155
- url(): Promise<string>;`,jr=`
155
+ url(): Promise<string>;`,Hr=`
156
156
  /**
157
157
  * Server-side function proxy.
158
158
  *
@@ -160,29 +160,38 @@ import*as O from"fs/promises";import{readFileSync as Nn}from"fs";import*as S fro
160
160
  * \`tb.server.log(...)\` is a built-in that prints to CLI stdout (falls back to console.log on web).
161
161
  * User exports override built-ins of the same name.
162
162
  */
163
- server: Record<string, (...args: any[]) => Promise<any>>;`,Qe=`
163
+ server: Record<string, (...args: any[]) => Promise<any>>;`,rt=`
164
164
  /**
165
165
  * Typebulb utilities namespace.
166
166
  * Type \`tb.\` to discover available helpers.
167
167
  */
168
- declare const tb: {${It}${Fr}${Dt}${jr}${At}${Ft}${Mt}${Mr}${$t}
168
+ declare const tb: {${Ft}${Wr}${jt}${Hr}${Nt}${Ut}${Lt}${Br}${Bt}
169
169
  };
170
- `,Ze=`
170
+ `,nt=`
171
171
  /**
172
172
  * Typebulb utilities namespace (server-side).
173
173
  * Type \`tb.\` to discover available helpers.
174
174
  */
175
- declare const tb: {${It}${Dt}${At}${Ft}${$r}${Mt}${$t}
175
+ declare const tb: {${Ft}${jt}${Nt}${Ut}${Ur}${Lt}${Bt}
176
176
  };
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=`
177
+ `;var z=class{constructor(e){this.store=e}async isNegative(e){let t=await De(()=>this.store.get(e));return!!t&&t.until>Date.now()}async recordNegative(e){let r=((await De(()=>this.store.get(e)))?.attempts||0)+1;await De(()=>this.store.set(e,{until:Date.now()+Jr(r),attempts:r}))}async clearNegative(e){await De(()=>this.store.delete(e))}};function Jr(s){return Math.min(9e5*Math.pow(2,Math.max(0,s-1)),864e5)}async function De(s){try{return await s()}catch{return}}import Yr from"p-limit";import{resolve as Wt}from"resolve.exports";var re=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 J={maxRelativeTypeRefs:500,maxBareDeps:8,maxBareDepth:3,prefetchConcurrency:4,negativeTtlMs:1e4},me=["index.d.ts","index.d.mts"],fe=/\.d\.(ts|mts)$/i;function st(s){if(fe.test(s))return!0;try{return new URL(s,"file://").search.includes("dts")}catch{return s.includes("?")&&s.includes("dts")}}function Ae(s){return[`${s}.d.ts`,`${s}.d.mts`]}async function ge(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(Vr(a.status)&&n<e)continue;return a}catch{if(n<e)continue;return}finally{clearTimeout(o)}}}function Vr(s){return s===408||s===429||s>=500&&s<600}var ye=class extends re{constructor(e,t){super(e),this.cdnClient=t}async loadPackageAtVersionedRoot(e,t){let r=this.cdnClient.packageJson(new g({name:e,version:t})),n=await ge(r);if(!n?.ok)return;let i;try{i=await n.json()}catch{return}if(i)return{pkg:i,baseDir:this.cdnClient.baseDir(new g({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([...me],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([...me,...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(Wt(n,r,{conditions:["types"]}));if(i)return i}catch{}try{return this.extractPathFromResult(Wt(n,r,{browser:!0,conditions:["import","default","module","browser","node"]}))}catch{return}}async resolve(e){try{let t=g.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 g(i).format(),a=new g({...i,subpath:t.subpath}).format(),c=p=>this.fetchCandidateFrom(n,t.name,p);if(t.subpath){let p=this.cdnClient.ensureLeadingDotSlash(t.subpath),h=this.resolveExportsPath(r,p);if(h){let f=await this.resolveFromSelected(this.toResolutionResult(h),c);if(f)return{...f,resolvedPkg:a}}let w=await this.tryUntilSuccess(this.declarationCandidatesFor(p),c);if(w)return{...w,resolvedPkg:a}}let l=r.types??r.typings;if(l){let p=await this.resolveFromSelected({kind:"types",path:l},c);if(p)return{...p,resolvedPkg:o}}let d=this.resolveExportsPath(r,".");if(d){let p=await this.resolveFromSelected(this.toResolutionResult(d),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[...me];let t=e.replace(/\.(mjs|cjs|js|mts|cts|ts)$/i,""),r=Ae(t),n=t.endsWith("/")?t:`${t}/`;return r.push(...Ae(`${n}index`)),r}};import{gunzipSync as qr}from"fflate";var ne=class{async fetchAndExtract(e,t){let r=this.getTarballUrl(e,t),n=await ge(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=qr(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),l=n.decode(a.slice(0,c>0?c:100)).trim(),d=o.slice(124,136),p=n.decode(d).trim().replace(/\0/g,""),h=parseInt(p,8)||0,w=String.fromCharCode(o[156]);if(i+=512,(w==="0"||w==="\0")&&(l.endsWith(".d.ts")||l.endsWith(".d.mts"))){let f=r.slice(i,i+h);t.set(this.normalizeTarPath(l),n.decode(f))}i+=Math.ceil(h/512)*512}}catch{}return t}},Gr=new ne;var we=class extends re{constructor(e,t,r,n=new ne){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=G.majorOf(r),o=e.filter(a=>G.majorOf(a)===i);if(o.length)return o.sort((a,c)=>G.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 g(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 l=this.cdnClient.file(e,a);try{await this.cache.setCachedFile(l,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 g(t).format():t.name}}}async resolve(e){let t=g.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 be=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 Ht="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`${Ht}/${this.epochDir()}/${e}/index.d.ts`}pathFor(e,t){let r=zr(t);return`${Ht}/${this.epochDir()}/${e}/${r}`}};function zr(s){let e=s||"";return e.startsWith("./")?e.slice(2):e.replace(/^\/+/,"")}import{LRUCache as Kr}from"lru-cache";function it(s){let e=new Kr({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 l=await fetch(n,{cache:"no-store"});if(!l.ok){l.status===404&&(e.set(n,Date.now()),await s.recordNegative(n));return}let d=await l.text(),p=l.url||n;return await s.clearNegative(n),await s.setCachedFile(p,d),{dts:d,url:p}})();return t.set(n,c),await c.finally(()=>t.delete(n))}catch{return}}}var Me=class{constructor(e){this.inFlight=new Map,this.scanner=new be,this.cache=e.cache,this.cdnClient=e.cdnClient,this.versionResolver=e.versionResolver,this.packageService=e.packageService,this.fetchDts=it(e.cache),this.typescriptProvider=new ye(this.fetchDts,e.cdnClient),this.definitelyTypedProvider=new we(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 g(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 g(e).subpath===new g(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>J.maxRelativeTypeRefs)))try{let a=new URL(t),c=new URL("./",a);o??(o=this.extractPackageRootUrl(a));let l=this.capArray(this.scanner.collectRelativeTypeRefs(e),J.maxRelativeTypeRefs);for(let d of l)await this.tryRelativeRef(d,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,l=st(c)?[c]:this.typescriptProvider.declarationCandidatesFor(c);for(let d of l){let h=new URL(d,a).toString();if(o.has(h))return;let w=await this.fetchDts(h);if(w?.dts){let f=this.toVirtualPath(r,new URL(w.url),n);this.pushFileIfNew(i,f,w.dts),await this.expandRelativeRefs(w.dts,w.url,n,i,o,r);return}}}catch{}}isDifferentPackage(e,t){return e===t?!1:new g(e).name!==new g(t).name}ambientlyDeclares(e,t){for(let r of e.matchAll(/declare\s+module\s+['"]([^'"]+)['"]/g)){let n=r[1];if(n===t||n.endsWith("/*")&&t.startsWith(n.slice(0,-1)))return!0}return!1}markFileAmbient(e,t){let r=e.find(n=>n.path===t);r&&(r.ambient=!0)}async prefetchBareDeps(e,t,r,n,i){try{let o=this.capArray(this.scanner.collectBareModuleRefs(e),J.maxBareDeps).filter(l=>this.isDifferentPackage(l,t));if(!o.length)return;let a=new Set([t]),c=Yr(J.prefetchConcurrency);await Promise.all(o.map(l=>c(()=>this.prefetchBareDepsRecursive(l,r,n,J.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,l=this.virtualFs.pathForMain(c);this.pushFileIfNew(t,l,a.dts),this.ambientlyDeclares(a.dts,e)?this.markFileAmbient(t,l):r.push({module:e,path:l}),a.url&&await this.expandRelativeRefs(a.dts,a.url,c,t);let d=this.capArray(this.scanner.collectBareModuleRefs(a.dts),J.maxBareDeps).filter(p=>!i.has(p));for(let p of d)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 g(a||r),l=c.version?`${c.name}@${c.version}`:c.name,{mainPath:d,packageRootUrl:p}=this.computeEntryPath(o,l),h=[{path:d,content:i}],w=[];o&&await this.expandRelativeRefs(i,o,l,h,void 0,p);let f=h.map($=>$.content).join(`
178
+ `);await this.prefetchBareDeps(f,l,h,w,n);let R=c.format(),v=e===R?[e]:[e,R],k=v.some($=>this.ambientlyDeclares(i,$));return k?this.markFileAmbient(h,d):w.push(...v.map($=>({module:$,path:d}))),{pkg:e,mainPath:d,files:h,shims:w,ambient:k}}};function ot(s){return new Me(s)}import*as U from"fs/promises";import*as W from"path";import*as qt from"os";import*as at from"fs/promises";import*as Jt from"crypto";function F(s){return Jt.createHash("sha1").update(s).digest("hex")}async function K(s){try{return JSON.parse(await at.readFile(s,"utf8"))}catch{return}}async function $e(s){try{return await at.readFile(s,"utf8")}catch{return}}var Vt=1,V=W.join(qt.homedir(),".typebulb","cache"),xe=W.join(V,"packages"),Pe=W.join(V,"proxy"),Fe=W.join(V,"dts"),Xr=W.join(V,"emit"),ct;function P(){return ct||(ct=Qr()),ct}function je(s,e){return W.join(Xr,F(s),e)}async function Qr(){await U.mkdir(V,{recursive:!0});let s=W.join(V,"version.json");if((await Zr(s))?.version===Vt)return;let t=await U.readdir(V).catch(()=>[]);await Promise.all(t.map(r=>U.rm(W.join(V,r),{recursive:!0,force:!0}))),await U.writeFile(s,JSON.stringify({version:Vt})+`
179
+ `,"utf8")}async function Zr(s){try{let e=await U.readFile(s,"utf8");return JSON.parse(e)}catch{return}}import*as q from"fs/promises";import*as Gt from"path";async function O(s,e){await q.mkdir(Gt.dirname(s),{recursive:!0});let t=`${s}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await q.writeFile(t,e,"utf8"),await q.rename(t,s).catch(async r=>{throw await q.rm(t,{force:!0}).catch(()=>{}),r})}var se=class{constructor(e){this.filePath=e}mem;loadPromise;load(){return this.mem?Promise.resolve(this.mem):(this.loadPromise||(this.loadPromise=K(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 O(this.filePath,JSON.stringify(Object.fromEntries(e)))}};var lt=j.join(xe,"indexes"),zt=j.join(xe,"pinned"),en=j.join(xe,"meta"),tn=j.join(xe,"negative.json"),ie=Symbol("missing"),Le=class{pinnedMem=new Map;indexMem=new Map;metaMem=new Map;negativeCache=new z(new se(tn));async getPinnedExact(e,t){let r=`${e}@${t}`,n=this.pinnedMem.get(r);if(n!==void 0)return n===ie?void 0:n;await P();let i=await $e(j.join(zt,F(r)+".txt"));return this.pinnedMem.set(r,i??ie),i}async setPinnedExact(e,t,r){let n=`${e}@${t}`;this.pinnedMem.set(n,r),await P(),await O(j.join(zt,F(n)+".txt"),r)}async getIndex(e){let t=this.indexMem.get(e);if(t!==void 0)return t===ie?void 0:t;await P();let r=await K(j.join(lt,Ne(e)+".json"));return this.indexMem.set(e,r??ie),r}async setIndex(e,t,r){let n={versions:t,distTags:r,updatedAt:Date.now()};this.indexMem.set(e,n),await P(),await O(j.join(lt,Ne(e)+".json"),JSON.stringify(n))}async invalidateVersionsCache(e){this.indexMem.delete(e),await Yt.rm(j.join(lt,Ne(e)+".json"),{force:!0})}async isNegative(e){return await P(),this.negativeCache.isNegative(e)}async recordNegative(e){await P(),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===ie?void 0:n;await P();let i=await K(Kt(e,t));return this.metaMem.set(r,i??ie),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 P(),await O(Kt(e,t),JSON.stringify(o))}};function Kt(s,e){return j.join(en,Ne(s),encodeURIComponent(e)+".json")}function Ne(s){return s.replace(/\//g,"__")}var Xt={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 rn=new Le,{packageService:Be,versionResolver:Qt,cdnClient:Zt,peerResolver:Gi}=$t(rn,Xt);var er=`
180
180
  (() => {
181
181
  // Embedded (bulb-in-a-bulb): runs inside a sandboxed iframe with no parent
182
182
  // bridge, so privileged tb.* (AI, fs, server RPC) can't reach a host and would
183
183
  // otherwise fail with cryptic CORS/CSP errors. Detect it and fail clearly.
184
+ //
185
+ // The same sandboxed-iframe path also backs the CLI's default (untrusted) launch
186
+ // (Specs/Typebulb-CLI-Trust.md), where the right message names \`--trust\` rather
187
+ // than "no host bridge". The host injects window.__TB_EMBED_ERR__ to override the
188
+ // text; absent it, the nested-bulb wording applies.
184
189
  const isEmbedded = window.parent !== window;
185
- const embedErr = (name) => new Error(name + ' is not available in an embedded bulb (no host bridge).');
190
+ const embedErr = (name) => new Error(
191
+ typeof window.__TB_EMBED_ERR__ === 'function'
192
+ ? window.__TB_EMBED_ERR__(name)
193
+ : name + ' is not available in an embedded bulb (no host bridge).'
194
+ );
186
195
 
187
196
  // JSON parser (handles jsonish - unquoted keys)
188
197
  const parseJson = (str) => {
@@ -351,12 +360,12 @@ declare const tb: {${It}${Dt}${At}${Ft}${$r}${Mt}${$t}
351
360
  };
352
361
  }
353
362
  })();
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>
363
+ `;function tr(s){let{name:e,code:t,css:r,html:n,data:i,insight:o,importMap:a,watch:c,theme:l,trustHint:d}=s,p=n.trim()||'<div id="app"></div>',h=f=>f.replace(/<\/script/gi,"<\\/script"),w={imports:sn(a.imports)};return`<!DOCTYPE html>
355
364
  <html>
356
365
  <head>
357
366
  <meta charset="utf-8">
358
367
  <meta name="viewport" content="width=device-width, initial-scale=1">
359
- <title>${Qr(e)} - typebulb</title>
368
+ <title>${dt(e)} - typebulb</title>
360
369
  <script>
361
370
  // Theme engine. Sets html[data-theme] before stylesheets paint (no flash) and
362
371
  // exposes the tb.theme accessor via window.__tbTheme. The override is persisted
@@ -364,13 +373,13 @@ declare const tb: {${It}${Dt}${At}${Ft}${$r}${Mt}${$t}
364
373
  // toggles the effective theme. See Specs/Theme.md.
365
374
  (function() {
366
375
  try {
367
- var KEY = ${p(JSON.stringify("tb-theme:"+e))};
376
+ var KEY = ${h(JSON.stringify("tb-theme:"+e))};
368
377
  var doc = document.documentElement;
369
378
  var mq = window.matchMedia('(prefers-color-scheme: dark)');
370
379
  var os = function() { return mq.matches ? 'dark' : 'light'; };
371
380
  // A host-forced theme (bulb-in-a-bulb) outranks the OS but not an explicit
372
381
  // in-iframe override, so the user can still toggle the embed independently.
373
- var FORCED = ${p(JSON.stringify(d??null))};
382
+ var FORCED = ${h(JSON.stringify(l??null))};
374
383
  var stored = function() {
375
384
  try { var v = localStorage.getItem(KEY); return (v === 'dark' || v === 'light') ? v : undefined; }
376
385
  catch (e) { return undefined; }
@@ -401,7 +410,7 @@ declare const tb: {${It}${Dt}${At}${Ft}${$r}${Mt}${$t}
401
410
  })();
402
411
  </script>
403
412
  <script type="importmap">
404
- ${JSON.stringify(m,null,2)}
413
+ ${JSON.stringify(w,null,2)}
405
414
  </script>
406
415
  <style>
407
416
  /* Reset and base styles */
@@ -415,23 +424,24 @@ ${r}
415
424
  </style>
416
425
  </head>
417
426
  <body>
418
- ${u}
427
+ ${p}
419
428
 
420
- ${i.length>0?`<script>window.__TB_DATA__ = ${p(JSON.stringify(i))};</script>`:""}
421
- ${o?`<script>window.__TB_INSIGHT__ = ${p(JSON.stringify(o))};</script>`:""}
429
+ ${i.length>0?`<script>window.__TB_DATA__ = ${h(JSON.stringify(i))};</script>`:""}
430
+ ${o?`<script>window.__TB_INSIGHT__ = ${h(JSON.stringify(o))};</script>`:""}
422
431
  ${c?"<script>window.__TYPEBULB_WATCH__ = true;</script>":""}
432
+ ${d?`<script>window.__TB_EMBED_ERR__ = function (name) { return name + ' is blocked in sandboxed mode. Re-run with --trust to allow it:\\n ' + ${h(JSON.stringify(d))}; };</script>`:""}
423
433
 
424
434
  <script>
425
- ${Kt}
435
+ ${er}
426
436
  </script>
427
437
 
428
- ${Xr}
438
+ ${nn}
429
439
 
430
440
  <script type="module">
431
- ${p(t)}
441
+ ${h(t)}
432
442
  </script>
433
443
  </body>
434
- </html>`}var Xr=`<script>
444
+ </html>`}var nn=`<script>
435
445
  (function () {
436
446
  if (window.parent === window) return;
437
447
  // Embedded: the host iframe owns sizing (auto-height below), so the document
@@ -455,23 +465,76 @@ ${p(t)}
455
465
  window.addEventListener('load', sendHeight);
456
466
  if (window.ResizeObserver) { try { new ResizeObserver(sendHeight).observe(document.documentElement); } catch (e) {} }
457
467
  })();
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=`
468
+ </script>`;function rr(s){let{bulbHtml:e,name:t,watch:r}=s;return`<!DOCTYPE html>
469
+ <html>
470
+ <head>
471
+ <meta charset="utf-8">
472
+ <meta name="viewport" content="width=device-width, initial-scale=1">
473
+ <title>${dt(t)} - typebulb</title>
474
+ <style>
475
+ *, *::before, *::after { box-sizing: border-box; }
476
+ body { margin: 0; }
477
+ /* The frame paints its own themed background and fills the viewport, so the
478
+ host backdrop shows only at sub-pixel edges / behind the denial bar.
479
+ color-scheme: light dark lets that backdrop and the scrollbar follow the OS
480
+ with no script \u2014 the bulb's own theme engine (template head) is unaffected. */
481
+ html { color-scheme: light dark; }
482
+ /* The frame auto-grows to content (height messages below); min-height keeps a
483
+ short bulb filling the viewport so it reads as a page, not a widget. */
484
+ #tb-frame { display: block; width: 100%; min-height: 100dvh; border: 0; }
485
+ #tb-deny {
486
+ position: fixed; left: 0; right: 0; bottom: 0; z-index: 2147483647;
487
+ margin: 0; padding: 10px 14px; font: 13px/1.5 system-ui, -apple-system, sans-serif;
488
+ white-space: pre-wrap; background: #7f1d1d; color: #fff;
489
+ border-top: 1px solid #b91c1c; display: none;
490
+ }
491
+ </style>
492
+ </head>
493
+ <body>
494
+ <iframe id="tb-frame" sandbox="allow-scripts" srcdoc="${dt(e)}"></iframe>
495
+ <pre id="tb-deny"></pre>
496
+ <script>
497
+ (function () {
498
+ var frame = document.getElementById('tb-frame');
499
+ var deny = document.getElementById('tb-deny');
500
+ // Authenticate by window identity, not origin (opaque-origin frames post
501
+ // from 'null'). Treat the payload as untrusted: clamp height, render error
502
+ // text only (never HTML).
503
+ window.addEventListener('message', function (e) {
504
+ if (e.source !== frame.contentWindow) return;
505
+ var d = e.data;
506
+ if (!d || d.__typebulbEmbed !== true) return;
507
+ if (d.kind === 'height' && typeof d.height === 'number' && Number.isFinite(d.height)) {
508
+ frame.style.height = Math.max(0, Math.min(100000, Math.ceil(d.height))) + 'px';
509
+ } else if (d.kind === 'error') {
510
+ deny.textContent = '\u26A0 ' + String(d.message == null ? 'error' : d.message);
511
+ deny.style.display = 'block';
512
+ }
513
+ });
514
+ ${r?`var es = new EventSource('/__reload');
515
+ es.addEventListener('reload', function () { location.reload(); });
516
+ es.onerror = function () { es.close(); };`:""}
517
+ })();
518
+ </script>
519
+ </body>
520
+ </html>`}function dt(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function sn(s){let e={};for(let[t,r]of Object.entries(s))e[t]=r.startsWith("https://")?"/proxy/"+r:r;return e}import{Hono as an}from"hono";import{serve as cn}from"@hono/node-server";import{streamSSE as ln}from"hono/streaming";import*as X from"fs/promises";import*as L from"path";var D=class extends Error{constructor(e,t="unknown",r=!1){super(e),this.code=t,this.retryable=r}},N=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=`
459
521
 
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(`
522
+ `){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 D(t,r,n)}if("error"in e&&e.error){let t=this.extractErrorMessage(e.error);throw new D(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 Se=class extends N{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 l={0:"low",1:"low",2:"medium",3:"high"};a.thinking={type:"adaptive"},a.output_config={effort:l[c]}}else{let l={0:0,1:2048,2:4096,3:8192};a.thinking={type:"enabled",budget_tokens:l[c]}}}return a}parseError(e,t){return this.parseJsonError(e,t)}parseNonStreamingResponse(e){if(!this.isAnthropicResponse(e))return{text:""};let t=e.content.filter(n=>n.type==="text").map(n=>n.text).join(""),r=e.content.filter(n=>n.type==="thinking").map(n=>n.thinking).join(`
461
523
 
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(`
524
+ `);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 Re=class extends N{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(`
525
+ `)),!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 D(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(`
464
526
 
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
527
+ `)}isResponsesApiEvent(e){return"type"in e&&typeof e.type=="string"}isResponsesApiResponse(e){return"object"in e&&e.object==="response"}};var Ee=class extends N{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,`
528
+ `),c={contents:o.map(l=>({role:l.role==="assistant"?"model":"user",parts:[{text:l.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(`
529
+ `)[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 D(r)}if(this.isGeminiResponse(e)&&e.promptFeedback?.blockReason){let t=e.promptFeedback.blockReason;throw new D(`Prompt blocked: ${t}`)}}};var ke=class extends N{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 on=new Map([["openai",new Re],["openrouter",new ke],["anthropic",new Se],["gemini",new Ee]]);function Y(s){let e=on.get(s);if(!e)throw new Error(`Unsupported protocol: ${s}`);return e}async function pt(s,e){let t=Y(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 ut(s,e){let t=Y(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 nr(s){let e=s.indexOf(`\r
468
530
  \r
469
531
  `),t=s.indexOf(`
470
532
 
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(`
533
+ `);return e!==-1&&(t===-1||e<t)?{pos:e,len:4}:t!==-1?{pos:t,len:2}:{pos:-1,len:0}}function ht(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(`
534
+ `).trim();if(!r)return null;if(r==="[DONE]")return"done";try{return JSON.parse(r)}catch{return null}}async function sr(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:l}=a;if(c){if(n.trim()){let h=ht(n);h!==null&&h!=="done"&&e(h)}break}i=!0,n+=r.decode(l,{stream:!0});let{pos:d,len:p}=nr(n);for(;d!==-1;){let h=n.slice(0,d);n=n.slice(d+p);let w=ht(h);if(w==="done"){n="";break}w!==null&&e(w),{pos:d,len:p}=nr(n)}}return{receivedAnyData:i}}async function mt(s,e){let t=e??(s.headers.get("X-Provider-Protocol")||"openai"),r=Y(t);if(!s.body)throw new Error("Response body is missing");let n=s.body.getReader(),i="";return await sr(n,o=>{let a=r.parseStreamChunk(o);a?.text&&(i+=a.text)}),i}import*as ft from"fs/promises";import*as Te from"path";var Ue=class{async get(e){let t=F(e),r=Te.join(Pe,t+".bin"),n=Te.join(Pe,t+".json");try{let[i,o]=await Promise.all([ft.readFile(r),ft.readFile(n,"utf8")]),a=JSON.parse(o);return{body:i,contentType:a.contentType,cacheControl:a.cacheControl}}catch{return}}async set(e,t){await P();let r=F(e),n=Te.join(Pe,r+".bin"),i=Te.join(Pe,r+".json"),o={url:e,contentType:t.contentType,cacheControl:t.cacheControl};await Promise.all([O(n,t.body),O(i,JSON.stringify(o))])}};var ar="127.0.0.1",dn=new Set(["localhost","127.0.0.1","::1"]);function pn(s){if(s)try{return new URL(s.includes("://")?s:`http://${s}`).hostname}catch{return}}function ir(s){let e=pn(s);return!!e&&dn.has(e)}function We(s){return s instanceof Error?s.message:"Unknown error"}async function cr(s){let{getHtml:e,basePath:t,port:r,reloadEmitter:n,getServerExports:i,localOverride:o,trusted:a=!1,trustHint:c}=s,l=new an;l.use("*",async(u,m)=>{if(!ir(u.req.header("host")))return u.text("Forbidden: untrusted Host",403);await m()}),l.use("*",async(u,m)=>{await m(),u.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),u.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")});let d=["/__fs/*","/__api/*","/__ai"],p=async(u,m)=>{if(!a){let y=c?`
535
+ ${c}`:"";return u.text(`Forbidden: this capability requires --trust.${y}`,403)}await m()},h=async(u,m)=>{let y=u.req.header("sec-fetch-site");if(y){if(y==="cross-site")return u.text("Forbidden: cross-site request",403)}else{let x=u.req.header("origin");if(x&&!ir(x))return u.text("Forbidden: cross-origin request",403)}await m()};for(let u of d)l.use(u,p),l.use(u,h);l.get("/",u=>u.html(e())),l.post("/__fs/read",async u=>{try{let{path:m}=await u.req.json(),y=yt(m,t),x=await X.readFile(y);return new Response(new Uint8Array(x),{headers:{"Content-Type":"application/octet-stream"}})}catch(m){let y=We(m);return u.json({error:y},400)}}),l.post("/__fs/write",async u=>{try{let m=u.req.query("path");if(!m)return u.json({error:"Missing path"},400);let y=yt(m,t);return await X.mkdir(L.dirname(y),{recursive:!0}),await X.writeFile(y,Buffer.from(await u.req.arrayBuffer())),u.json({success:!0})}catch(m){let y=We(m);return u.json({error:y},400)}});let w={log:console.log};l.post("/__api/:name",async u=>{try{let m=i?.(),y=u.req.param("name"),x=m?.[y]??w[y];if(!x||typeof x!="function")return u.json({error:`API function '${y}' not found`},404);let{args:b}=await u.req.json(),I=await x(...b||[]);return u.json({result:I})}catch(m){let y=We(m);return u.json({error:y},500)}}),l.post("/__ai",async u=>{try{let{messages:m,system:y,reasoning:x,provider:b,model:I,webSearch:H}=await u.req.json();if(!m||!Array.isArray(m)||m.length===0)return u.json({message:"messages array is required",code:"unknown",retryable:!1},400);let B=un(b,I);if(typeof B=="string")return u.json({message:B,code:"unknown",retryable:!1},400);let Ke=[...y?[{role:"system",content:y}]:[],...m.map(Ie=>({role:Ie.role,content:Ie.content}))],Z=await pt(B,{model:B.model,messages:Ke,stream:!0,reasoning:x??0,webSearch:H??!0});if(!Z.ok){let Ie=await ut(Z,B.protocol);return u.json(Ie,Z.status)}let kt=await mt(Z,B.protocol);return kt||console.warn("[tb.ai] Empty response from provider"),u.json({text:kt})}catch(m){if(m instanceof D)return u.json({message:m.message,code:m.code,retryable:m.retryable},500);let y=We(m);return u.json({message:y,code:"unknown",retryable:!1},500)}}),l.get("/__models",async u=>{try{let m=await fn();return u.json(m)}catch{return u.json([],200)}});let f=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"],R=new Ue;if(l.get("/proxy/*",async u=>{let m=new URL(u.req.url),x=(m.pathname+m.search).slice(7),b=x.lastIndexOf("https://");return b===-1?u.text("Invalid proxy URL",400):v(u,x.slice(b))}),o){let u=`/local/${o.name}/`;l.get("/local/*",async m=>{let{pathname:y}=new URL(m.req.url);if(!y.startsWith(u))return m.text("Not Found",404);let x=decodeURIComponent(y.slice(u.length));try{let b=yt(x,o.serveDir),I=await X.readFile(b);return new Response(I,{headers:{"Content-Type":gn(b)}})}catch{return m.text("Not Found",404)}})}async function v(u,m){let y;try{y=new URL(m)}catch{return u.text("Invalid URL",400)}if(y.protocol!=="https:")return u.text("HTTPS only",400);if(!f.includes(y.hostname))return u.text("Host not allowed",403);let x=await R.get(m);if(x)return new Response(x.body,{status:200,headers:gt(x.contentType,x.cacheControl)});try{let b=await fetch(m,{headers:{Accept:u.req.header("Accept")||"*/*"},redirect:"follow"});if(!b.ok)return u.text(`Upstream ${b.status}`,b.status);let I=b.headers.get("Content-Type")||void 0,H=b.headers.get("Cache-Control")||void 0;if(b.body){let[B,Ke]=b.body.tee();return(async()=>{try{let Z=await new Response(Ke).arrayBuffer();await R.set(m,{body:Buffer.from(Z),contentType:I,cacheControl:H})}catch{}})(),new Response(B,{status:b.status,headers:gt(I,H)})}return new Response(null,{status:b.status,headers:gt(I,H)})}catch(b){return u.text(`Proxy fetch failed: ${b instanceof Error?b.message:b}`,502)}}n&&l.get("/__reload",u=>ln(u,async m=>{let y=()=>{m.writeSSE({event:"reload",data:""})};for(n.on("reload",y),m.onAbort(()=>{n.removeListener("reload",y)});;)await m.sleep(3e4)}));let k=/^\/(v\d+\/|stable\/|node\/|gh\/|@[^/]+\/[^@/]+@|[^@/]+@)/;l.notFound(async u=>{if(u.req.method!=="GET")return u.text("Not Found",404);let m=new URL(u.req.url);return k.test(m.pathname)?v(u,"https://esm.sh"+m.pathname+m.search):u.text("Not Found",404)});let $=cn({fetch:l.fetch,port:r,hostname:ar});return{port:r,close:()=>$.close()}}var lr={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"};function un(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=Y(t)}catch{return`Unknown provider '${t}'.`}let i=lr[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 hn="https://api.typebulb.com/api/models",mn=1440*60*1e3,oe=null;async function fn(){if(!oe||Date.now()-oe.fetchedAt>mn){let s=await fetch(hn);if(!s.ok)return oe?or(oe.models):[];oe={models:await s.json(),fetchedAt:Date.now()}}return or(oe.models)}function or(s){let e=new Set(Object.entries(lr).filter(([,t])=>!!process.env[t]).map(([t])=>t));return s.filter(t=>e.has(t.provider))}function gt(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 gn(s){switch(L.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 yt(s,e){let t=L.resolve(e,s),r=L.normalize(e),n=L.normalize(t);if(n!==r&&!n.startsWith(r+L.sep))throw new Error("Path traversal detected - access denied");return t}async function wt(s){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(s,ar,()=>{let n=r.address(),i=typeof n=="object"&&n?n.port:s;r.close(()=>t(i))}),r.on("error",()=>{t(wt(s+1))})})}import yn from"open";async function dr(s){await yn(s)}import pr from"chokidar";var ur={persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}};function bt(s){let{bulbPath:e,emitter:t}=s,r=pr.watch(e,ur);return r.on("change",()=>{t.emit("reload")}),()=>r.close()}function hr(s){let{dir:e,onChange:t,debounceMs:r=150}=s,n,i=pr.watch(e,ur);return i.on("all",()=>{n&&clearTimeout(n),n=setTimeout(t,r)}),()=>{n&&clearTimeout(n),i.close()}}import*as _ from"fs/promises";import*as T from"path";import*as ae from"path";var wn=ae.join(Fe,"pkg"),bn=ae.join(Fe,"files"),vn=ae.join(Fe,"negative.json"),Je=class{pkgMem=new Map;fileMem=new Map;negativeCache=new z(new se(vn));async getCachedDts(e){if(this.pkgMem.has(e))return this.pkgMem.get(e);await P();let t=await K(mr(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 He(async()=>{await P(),await O(mr(e),JSON.stringify(n))})}async getCachedFile(e){if(this.fileMem.has(e))return this.fileMem.get(e);await P();let t=await $e(fr(e));return this.fileMem.set(e,t),t}async setCachedFile(e,t){this.fileMem.set(e,t),await He(async()=>{await P(),await O(fr(e),t)})}isNegative(e){return this.negativeCache.isNegative(e)}async recordNegative(e){await He(async()=>{await P(),await this.negativeCache.recordNegative(e)})}clearNegative(e){return He(()=>this.negativeCache.clearNegative(e))}};async function He(s){try{await s()}catch{}}function mr(s){return ae.join(wn,F(s)+".json")}function fr(s){return ae.join(bn,F(s)+".txt")}var vt;function xn(){return vt||(vt=ot({cache:new Je,cdnClient:Zt,packageService:Be,versionResolver:Qt})),vt}var gr="file:///node_modules/";async function yr(s){let e=je(s.emitKey,"typecheck");await P(),await _.rm(e,{recursive:!0,force:!0}),await _.mkdir(e,{recursive:!0});let t=En(s.jsxImportSource,s.dependencies),r=await xn().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 p of d.files){let h=Ve(p.path);if(!h||o.has(h))continue;o.add(h);let w=T.join(e,"node_modules",h);await _.mkdir(T.dirname(w),{recursive:!0}),await _.writeFile(w,p.content,"utf8")}let a={};for(let d of i)for(let p of d.shims){let h=Ve(p.path);h&&(a[p.module]=[`./node_modules/${h}`])}for(let d of i){if(d.ambient)continue;let p=Ve(d.mainPath);p&&(a[d.pkg]=[`./node_modules/${p}`])}let c=new Set;for(let d of i)for(let p of d.files){if(!p.ambient)continue;let h=Ve(p.path);h&&c.add(`node_modules/${h}`)}if(s.local){delete a[s.local.name];let d=await kn(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,[...c]);return await _.writeFile(T.join(e,"tsconfig.json"),JSON.stringify(l,null,2)+`
536
+ `,"utf8"),await _.writeFile(T.join(e,"code.tsx"),s.code,"utf8"),await _.writeFile(T.join(e,"tb.d.ts"),rt,"utf8"),{dir:e}}function Pn(s,e,t=[]){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"bundler",lib:Sn([...et,...tt]),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",...t]}}function Sn(s){return s.filter(e=>!e.since).map(e=>Rn(e.name))}function Rn(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 En(s,e){let t=s??("react"in e?"react":void 0);return t?[`${t}/jsx-runtime`,`${t}/jsx-dev-runtime`]:[]}function Ve(s){if(!s.startsWith(gr))return;let e=s.slice(gr.length),t=e.indexOf("/");if(!(t<0))return e.slice(t+1)}async function kn(s,e){if(!s.typesAbs)return;let t=T.dirname(s.typesAbs),r=T.join(e,"node_modules",s.name);for(let n of await Tn(t)){let i=T.join(r,T.relative(t,n));await _.mkdir(T.dirname(i),{recursive:!0}),await _.copyFile(n,i)}return T.basename(s.typesAbs)}async function Tn(s){let e=[];async function t(r){let n=await _.readdir(r,{withFileTypes:!0});for(let i of n){let o=T.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 A from"fs/promises";import*as Q from"path";import{existsSync as An}from"fs";import*as qe from"fs/promises";import*as xt from"path";import{existsSync as wr}from"fs";import{execFile as _n}from"child_process";import{promisify as Cn}from"util";var In=Cn(_n);async function Ge(s,e){let t=s.filter(n=>!On(n,e));if(t.length===0)return;await qe.mkdir(e,{recursive:!0});let r=xt.join(e,"package.json");wr(r)||await qe.writeFile(r,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${t.join(", ")}`),await In("npm",["install","--no-audit","--no-fund",...t],{cwd:e,shell:!0})}function On(s,e){return wr(xt.join(e,"node_modules",Dn(s)))}function ze(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 Dn(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 Mn="^22";async function br(s){let e=je(s.emitKey,"typecheck-server");await P(),await A.rm(e,{recursive:!0,force:!0}),await A.mkdir(e,{recursive:!0});let t=Q.join(s.bulbDir,".typebulb"),r=ze(s.server);await Ge([`@types/node@${Mn}`,...r],t);let n=Q.join(t,"node_modules"),i=Q.join(e,"node_modules");return await Fn(n,i),await A.writeFile(Q.join(e,"server.ts"),s.server,"utf8"),await A.writeFile(Q.join(e,"tb.d.ts"),nt,"utf8"),await A.writeFile(Q.join(e,"tsconfig.json"),JSON.stringify($n(),null,2)+`
537
+ `,"utf8"),{dir:e}}function $n(){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 Fn(s,e){if(!An(s)){await A.mkdir(e,{recursive:!0});return}await A.rm(e,{recursive:!0,force:!0});let t=process.platform==="win32"?"junction":"dir";await A.symlink(s,e,t)}import*as St from"fs/promises";import{existsSync as _e}from"fs";import*as E from"path";import{resolve as vr}from"resolve.exports";import{init as jn,parse as Nn}from"es-module-lexer";var Pt=["browser","import","default"];function xr(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:E.resolve(r)}}async function Pr(s){let{name:e,dir:t}=s;if(!_e(t))throw new Error(`--replace path for '${e}' does not exist: ${t}`);let r=E.join(t,"package.json"),n;try{n=JSON.parse(await St.readFile(r,"utf8"))}catch{throw new Error(`--replace package '${e}' has no readable package.json at ${r}`)}let i=Ln(n,e),o=E.resolve(t,i);if(!_e(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=E.dirname(o),c=`/local/${e}/${E.basename(o)}`,l=Bn(n,t);return await Un(e,o,a),{name:e,dir:t,entryAbs:o,serveDir:a,entryUrl:c,typesAbs:l}}function Ln(s,e){if(s.exports!==void 0){let r;try{r=vr(s,".",{browser:!0,conditions:Pt})}catch(i){throw new Error(`--replace package '${e}' "exports" does not resolve a browser entry (conditions: ${Pt.join(", ")}): ${i instanceof Error?i.message:i}`)}let n=Sr(r);if(!n)throw new Error(`--replace package '${e}' "exports" did not resolve "." to a single file (conditions: ${Pt.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 Bn(s,e){if(s.exports!==void 0)try{let r=vr(s,".",{conditions:["types"]}),n=Sr(r);if(n){let i=E.resolve(e,n);if(_e(i))return i}}catch{}let t=s.types??s.typings;if(t){let r=E.resolve(e,t);if(_e(r))return r}}function Sr(s){if(typeof s=="string")return s;if(Array.isArray(s))return s.find(e=>typeof e=="string")}async function Un(s,e,t){await jn;let r=E.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 St.readFile(o,"utf8")}catch{continue}let c,l;try{[c,,,l]=Nn(a,o)}catch{continue}if(o===e&&!l)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 d of c){if(d.d===-2)continue;let p=d.n;if(p&&!p.startsWith("node:")){if(p.startsWith("./")||p.startsWith("../")||p.startsWith("/")){let h=Wn(o,p,r);h&&!n.has(h)&&i.push(h);continue}throw new Error(`override package must ship self-contained (bundle its dependencies); ${s} externalizes '${p}'`)}}}}function Wn(s,e,t){let r=e.replace(/[?#].*$/,""),n=E.resolve(E.dirname(s),r),i=[n,n+".js",n+".mjs",E.join(n,"index.js"),E.join(n,"index.mjs")];for(let o of i)if(E.normalize(o).startsWith(t)&&_e(o))return o}var ha=Gn(Vn),zn="0.9.1";function Kn(s){let e={subcommand:"run",file:"",port:3e3,watch:!0,open:!0,server:!1,trust:!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==="--trust")e.trust=!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=xr(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 Yn(){console.log(`
475
538
  typebulb - Local bulb runner for Typebulb
476
539
 
477
540
  Usage:
@@ -482,7 +545,11 @@ Options:
482
545
  --no-watch Disable hot reload (watch is on by default)
483
546
  -p, --port <port> Use a specific port (default: 3000)
484
547
  --no-open Don't auto-open browser
485
- --server Run server.ts only, no web server
548
+ --trust Grant privileged capabilities (filesystem, AI,
549
+ and server.ts). Without it a bulb runs sandboxed:
550
+ tb.fs / tb.ai / tb.server are blocked and the page
551
+ shows the exact --trust command to unlock them.
552
+ --server Run server.ts only, no web server (needs --trust)
486
553
  --replace <name>=<path> Replace a declared dependency with a local built
487
554
  package folder instead of a CDN (dev only).
488
555
  Applies to both run and check. Watched for
@@ -524,12 +591,13 @@ Examples:
524
591
  typebulb my-editor.bulb.md
525
592
  typebulb --no-watch --port 8080 my-editor.bulb.md
526
593
  typebulb .
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}
594
+ `)}async function Xn(s){let t=(await M.readdir(s)).find(r=>r.endsWith(".bulb.md"));return t?S.join(s,t):null}function Er(){Et([".env",".env.local"],process.cwd(),!0)}function Et(s,e,t=!1){for(let r of s){let n=S.resolve(e,r);try{let i=Hn(n,"utf-8");for(let o of i.split(`
595
+ `)){let a=o.trim();if(!a||a.startsWith("#"))continue;let c=a.indexOf("=");if(c===-1)continue;let l=a.slice(0,c).trim(),d=a.slice(c+1).trim();(d.startsWith('"')&&d.endsWith('"')||d.startsWith("'")&&d.endsWith("'"))&&(d=d.slice(1,-1)),process.env[l]??=d}}catch{t||console.warn(` Warning: env file not found: ${r}`)}}}async function kr(s,e){let t=Ye(s,{serverOnly:!0});if(t.error)throw new Error(`Server compilation error: ${t.error}`);let r=S.join(e,".typebulb");await M.mkdir(r,{recursive:!0});let n=ze(t.code);n.length>0&&await Ge(n,r);let i=S.join(r,"server.mjs");return await M.writeFile(i,t.code,"utf-8"),await import(`${Jn(i).href}?t=${Date.now()}`)}async function Ce(s){let e=await M.readFile(s,"utf-8"),t=Tt(e);if(!t)throw new Error("Invalid .bulb.md file format");let r=_t(t);return{bulb:r,config:It(r.config)}}async function Rr(s,e,t,r,n){let{bulb:i,config:o}=await Ce(s),a=Ct(i.data),c=Ye(i.code,{jsxImportSource:o.jsxImportSource});c.error&&console.error("Compilation error:",c.error);let{importMap:l}=await Be.buildImportMap(c.code,o.dependencies??{},n?new Set([n.name]):void 0);n&&(l.imports[n.name]=n.entryUrl);let d=tr({name:i.name,code:c.code,css:i.css,html:i.html,data:a,insight:i.insight,importMap:l,watch:t?e:!1,trustHint:t?void 0:r}),p=t?d:rr({bulbHtml:d,name:i.name,watch:e}),h=S.dirname(s);o.env?.length&&Et(o.env,h);let w=null;return i.server&&t&&(w=await kr(i.server,h)),{html:p,bulb:i,serverExports:w}}async function Qn(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 yr({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 br({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:l}=await Zn(a);for(let d of c.split(/\r?\n/))d.trim()&&console.log(`${o} ${d}`);l!==0&&(i=!0)}i&&process.exit(1)}function Zn(s){return new Promise(e=>{let t=qn("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 es(s,e){Er();let t=async()=>{let{bulb:r,config:n}=await Ce(s),i=S.dirname(s);n.env?.length&&Et(n.env,i),await kr(r.server,i)};if(console.log(`Running ${S.basename(s)}...`),await t(),e){console.log(`Watching for changes...
596
+ `);let r=new Rt;r.on("reload",async()=>{try{console.log("Re-running..."),await t()}catch(n){console.error("Error:",n)}}),bt({bulbPath:s,emitter:r})}}async function ts(){let s=Kn(process.argv.slice(2));s.version&&(console.log(`typebulb ${zn}`),process.exit(0)),s.help&&(Yn(),process.exit(0));let e;if(!s.file||s.file==="."){let v=await Xn(process.cwd());v||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=v}else e=S.resolve(s.file);try{await M.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=s.file&&s.file!=="."?s.file:S.relative(process.cwd(),e)||S.basename(e),r=`npx typebulb --trust ${t.includes(" ")?`"${t}"`:t}`,n;if(s.local){let v;try{v=await Ce(e)}catch{}v&&!(s.local.name in(v.config.dependencies??{}))&&(console.error(`--replace: '${s.local.name}' is not a dependency in this bulb's config.json; nothing to replace.`),process.exit(1)),v&&(!v.bulb.code||s.server)&&console.warn("warning: --replace has no effect in server mode (the override is client-only).");try{n=await Pr(s.local)}catch(k){console.error(k instanceof Error?k.message:String(k)),process.exit(1)}console.log(`replace: ${n.name} \u2192 ${S.relative(process.cwd(),n.dir)||"."}`)}if(s.subcommand==="check"){await Qn(e,n);return}try{let{bulb:v}=await Ce(e);if(v.server&&(!v.code||s.server)){s.trust||(console.error(`This bulb runs server-side Node code (server.ts), which --trust must authorize:
597
+ ${r}`),process.exit(1)),await es(e,s.watch);return}}catch{}let i=process.cwd(),o=s.watch?new Rt:void 0;Er(),console.log(`Loading ${S.basename(e)}...`);let{html:a,bulb:c,serverExports:l}=await Rr(e,s.watch,s.trust,r,n),d=await wt(s.port),p=await cr({getHtml:()=>a,basePath:i,port:d,reloadEmitter:o,getServerExports:()=>l,localOverride:n?{name:n.name,serveDir:n.serveDir}:void 0,trusted:s.trust,trustHint:r}),h=`http://localhost:${d}`;console.log(`
598
+ ${c.name}`),console.log(` ${h}`),console.log(s.trust?" trust: granted (filesystem, AI, server.ts enabled)":` trust: sandboxed \u2014 re-run with --trust to enable filesystem / AI / server.ts
531
599
  `),s.watch&&console.log(` Watching for changes...
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)});
600
+ `);let w,f;if(s.watch&&o){let v=new Rt;if(v.on("reload",async()=>{try{console.log("Recompiling...");let k=await Rr(e,!0,s.trust,r,n);a=k.html,l=k.serverExports,o.emit("reload"),console.log(`Done. Browser reloading...
601
+ `)}catch(k){console.error("Compile error:",k)}}),w=bt({bulbPath:e,emitter:v}),n){let{name:k,serveDir:$}=n;f=hr({dir:$,onChange:()=>{console.log(`Local package '${k}' changed. Browser reloading...
602
+ `),o.emit("reload")}})}}s.open&&await dr(h);let R=async()=>{console.log(`
603
+ Shutting down...`),p.close(),w?.(),f?.();let v=S.join(S.dirname(e),".typebulb","server.mjs");await M.rm(v,{force:!0}).catch(()=>{}),process.exit(0)};process.on("SIGINT",R),process.on("SIGTERM",R)}ts().catch(s=>{console.error("Error:",s.message),process.exit(1)});