typebulb 0.29.2 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2280,7 +2280,7 @@ var Patcher = class {
2280
2280
 
2281
2281
  // cli/agents/pi/server/piPatcherExtension.ts
2282
2282
  var DESCRIPTION = true ? "Apply unified diffs to files \u2014 tolerant of form, strict about intent. Repairs sloppy AI-generated diffs (mangled headers, whitespace drift, missing prefixes; line numbers can be wrong or absent \u2014 hunks anchor by fuzzy-matched context lines) and applies all hunks atomically when the intent is unambiguous; fails with a precise, typed error when it isn't. Use for multi-hunk edits in one step, or when exact string-replacement editing fails on whitespace or invisible characters." : "Apply unified diffs to files.";
2283
- var BUILD_TAG = true ? "matchu-patchu-pi 0.3.1, built 2026-07-17 08:45:41" : "matchu-patchu-pi dev";
2283
+ var BUILD_TAG = true ? "matchu-patchu-pi 0.3.1, built 2026-07-17 21:12:30" : "matchu-patchu-pi dev";
2284
2284
  var errorBlocks = (errors) => {
2285
2285
  const parts = [`Patch failed with ${errors.length} error(s):`];
2286
2286
  for (const e of errors) parts.push("", e.toString());
@@ -201,7 +201,8 @@ body {
201
201
  /* ONE geometry contract for both menus — sizing policy, padding, stacking. Stating it twice is
202
202
  how every sibling discrepancy of June '26 happened (row pitch, gaps, fixed-vs-grow). max-height,
203
203
  not height: a menu hugs its content and caps at the 12 rows above — a fixed height left a
204
- 1-bulb project with a row floating atop a 400px void. Per-menu rules keep only width. */
204
+ 1-bulb project with a row floating atop a 400px void. Per-menu rules keep only width and
205
+ alignment (.pop-center / .pop-start below). */
205
206
  max-height: var(--menu-h);
206
207
  overflow: hidden;
207
208
  padding: .35rem;
@@ -217,6 +218,14 @@ body {
217
218
  border-radius: 10px;
218
219
  box-shadow: 0 8px 30px rgba(0, 0, 0, .45);
219
220
  }
221
+ /* Popover alignment — which edge of the pill the menu aligns to (floating-UI's start/center/end
222
+ vocabulary; "end", right edges flush and growing left, is the unnamed default above). Tagged on
223
+ the pill's WRAP, not each popover root: a menu with several drilled-in views (the model pill's
224
+ list/info/diag/key modes) aligns once, and a future mode can't forget. The cluster's left-side
225
+ pills (diff, model) center — end-anchored, their menus run out of room growing left. No viewport
226
+ clamping: desktop-only; revisit if a narrow window ever clips one. */
227
+ .pop-center > :is(.picker, .servers-pop) { right: auto; left: 50%; transform: translateX(-50%); }
228
+ .pop-start > :is(.picker, .servers-pop) { right: auto; left: 0; }
220
229
 
221
230
  /* ---- Shimmer — the one "working" cue. One gradient, one keyframes, composed via class, never
222
231
  re-pasted (paste-drift is how each new shimmer kept landing at its own speed). `.shimmer` sweeps
@@ -821,6 +830,9 @@ a.server-port:hover { text-decoration: underline; }
821
830
  .server-name.remote:hover { text-decoration: none; }
822
831
  .sample-link { color: var(--muted); font-size: .76rem; text-decoration: none; cursor: pointer; flex: none; }
823
832
  .sample-link:hover { color: var(--accent); text-decoration: underline; }
833
+ /* A running row's --dir batch scope (bulbsPill.ts): a muted mono token after the name — the
834
+ register of the sample-link/user slug, mono because it names a folder. */
835
+ .bulb-dir { color: var(--muted); font-size: .76rem; font-family: ui-monospace, monospace; flex: none; }
824
836
  /* The remote fold (bulbsPill.ts groupRow / fold-row): the header and the remote rows within share
825
837
  one veil step over the menu's panel bg (the picker-peek shade) as ONE contiguous band — each
826
838
  row's ::before bridges the grid row-gap up to the row above, junction corners square off, and
@@ -982,16 +994,30 @@ a.server-port:hover { text-decoration: underline; }
982
994
  .gitdiff-counts { flex: none; display: inline-flex; gap: .35rem; font-size: .72rem; font-variant-numeric: tabular-nums; }
983
995
  .gitdiff-counts .count-add { color: var(--diff-add); }
984
996
  .gitdiff-counts .count-del { color: var(--err); }
997
+ /* The pill's viewing form: the doc's identity in place of the icon+count — status letter, path,
998
+ ±counts, × (the doc itself is chrome-free). Width capped so a deep path can't crowd the cluster;
999
+ rtl clip keeps the path's tail — the filename — visible, full path in the title. */
1000
+ .pill.glyph.gitdiff-pill.viewing { max-width: min(30rem, 45vw); gap: .45rem; padding: 0 .35rem 0 .5rem; }
1001
+ /* Same text seating as the word pills (.pill's text-box note): .pill.glyph opts out of the trim
1002
+ (right for pure glyphs, low for letters), and the viewing form keeps flex for the path's
1003
+ ellipsis — so the trim rides each text item instead of the button. Flex items are block
1004
+ containers, so text-box applies; the × icon stays untrimmed (symmetric, flex-exact). */
1005
+ .gitdiff-pill.viewing :is(.gitdiff-status, .gitdiff-doc-path, .gitdiff-counts span) { text-box: trim-both cap alphabetic; }
1006
+ .gitdiff-doc-path { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: left; font-size: var(--pill-font); color: var(--accent); }
1007
+ .gitdiff-doc-path:hover { text-decoration: underline; }
1008
+ .gitdiff-close { flex: none; display: inline-flex; padding: 0 .15rem; color: var(--muted); }
1009
+ .gitdiff-close .icon { width: 10px; height: 10px; }
1010
+ .gitdiff-close:hover { color: var(--accent); }
1011
+ /* Doc open ⇒ the transcript-scoped pills hide: prose toggle, model switcher, session picker all act
1012
+ on the conversation, which isn't on screen (the token pill stays — its shimmer says the live diff
1013
+ may still grow). display only, never unmount — the model pill's superSelect must keep its mount. */
1014
+ .statusbar-actions.doc-open :is(.prose-pill, .model-wrap, .sid-wrap) { display: none; }
985
1015
 
986
1016
  /* The diff doc — takes the transcript's slot in .chat (same flex geometry as .messages). Full-bleed
987
1017
  like a code surface (no --content-max column: diff lines want the width); the body is the scroll
988
1018
  surface, its bottom padding clearing the overlaid statusbar like .messages' does. The ± markers and
989
1019
  red/green bands are the shared .udiff-* rules the tool cards use. */
990
1020
  .diff-doc { flex: 1; min-height: 0; display: flex; flex-direction: column; outline: none; }
991
- .diff-doc-head { display: flex; align-items: center; gap: .6rem; padding: .5rem 1.75rem .4rem; font-size: .8rem; border-bottom: 1px solid var(--border); }
992
- .diff-doc-path { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--accent); cursor: pointer; }
993
- .diff-doc-path:hover { text-decoration: underline; }
994
- .diff-doc-head .bulb-log-back { margin-left: auto; }
995
1021
  .diff-doc-body {
996
1022
  flex: 1; min-height: 0; overflow: auto;
997
1023
  scrollbar-gutter: stable both-edges;
@@ -1009,8 +1035,8 @@ a.server-port:hover { text-decoration: underline; }
1009
1035
  gutter ± glyphs and at file scale by the ruler. Scoped: the tool-card hunks keep 24%, where the
1010
1036
  unhighlighted band is the only signal. Del a touch stronger than add — red-leaning tokens
1011
1037
  camouflage against red tint more than anything does against green. */
1012
- .diff-doc-body .udiff-add { background: color-mix(in srgb, var(--diff-add) 10%, transparent); }
1013
- .diff-doc-body .udiff-del { background: color-mix(in srgb, var(--err) 13%, transparent); }
1038
+ .diff-doc-body .udiff-add { background: color-mix(in srgb, var(--diff-add) 15%, transparent); }
1039
+ .diff-doc-body .udiff-del { background: color-mix(in srgb, var(--err) 18%, transparent); }
1014
1040
  /* The overview ruler — VS Code's scrollbar change-marks, owned since the native scrollbar can't be
1015
1041
  painted: a thin track beside the scrollbar (17px clears Windows Chromium's classic bar — plain px
1016
1042
  on a desktop-only surface, the menus' own stance), red/green marks at each change run's fractional
package/dist/index.js CHANGED
@@ -373,7 +373,7 @@ Output only valid JSON. No explanation, no markdown fences, just the JSON object
373
373
  `)){if(!l.trim())continue;let f;try{f=JSON.parse(l)}catch{continue}if(!f||Rn(f)||f.type!=="user")continue;let u=f.message?.content,d="";typeof u=="string"?d=dt(u):Array.isArray(u)&&(d=u.map(Zc).filter(Boolean).join(" "));let p=d.replace(/\s+/g," ").trim();if(p)return(p.replace(/^Continuing from a prior session\. Here is the summary of our work so far:\s*/i,"").trim()||p).slice(0,200)}return""}finally{Zx(e)}}function d0(r){let e;try{e=t0(mm)}catch{return!1}for(let t of e)if(t.endsWith(".json"))try{let n=JSON.parse(r0(Nn(mm,t),"utf8"));if(n?.sessionId!==r)continue;return process.kill(n.pid,0),!0}catch{}return!1}var i0,dm,hm,c0,Ee,pm,mm,vr,Ri=A(()=>{Oi();zc();Qc();i0=Nn(el(),".claude","projects"),dm=r=>Nn(i0,s0(r));hm=[/\[Request interrupted by user\b/i,/\[Tool use was interrupted\]/i,/Claude Code returned an error/i,/\[ede_diagnostic\]/i,/^No response requested\.?$/i,/^<task-notification\b/i,/^<system-reminder\b/i,/^<local-command-stdout\b/i,/^<local-command-stderr\b/i];c0=/<ide_[a-z_]+>[\s\S]*?<\/ide_[a-z_]+>/gi;Ee=(r,e,t=e+"s")=>`${r} ${r===1?e:t}`,pm=r=>typeof r!="number"?"":r<1024?`${r}B`:r<1048576?`${Math.round(r/1024)}KB`:`${(r/1048576).toFixed(1)}MB`;mm=Nn(el(),".claude","sessions");vr=class extends wr{displayName="Claude Mirror";detectsSelf(){return process.env.CLAUDECODE==="1"}detectsInstalled(){return n0(Nn(el(),".claude"))}sessionsDir(e){return dm(e)}listSessionFiles(e){return _i(dm(e))}parseEntry(e){try{return JSON.parse(e)}catch{return null}}idOf(e){return e.uuid}parentOf(e){return e.parentUuid}timestampOf(e){return e.timestamp}isSidechain(e){return!!e.isSidechain}isLeafType(e){return e.type==="user"||e.type==="assistant"}isRecoveryNoise(e){return!!e.isApiErrorMessage}apply(e,t){if(Rn(e))return{events:[]};let n=[];if(e.type==="user"){let s=e.message?.content;if(typeof s=="string"){let i=dt(s);i&&n.push({type:"user",text:i})}else if(Array.isArray(s))for(let i of s)if(i?.type==="tool_result"){let o=Xc(i.content);n.push({type:"tool_result",id:i.tool_use_id??"",content:o,isError:!!i.is_error,digest:tl(e.toolUseResult,o)})}else{let o=Zc(i)||Ci(i);o&&n.push({type:"user",text:o})}return{events:n}}if(e.type==="attachment"&&e.attachment?.type==="queued_command"){let s=dt(Xc(e.attachment.prompt));return s&&n.push({type:"user",text:s}),{events:n}}if(e.type==="assistant"){let s=e.message?.content,i=Array.isArray(s)?s:[],o=i.filter(u=>u.type==="text").map(u=>u.text??"").filter(u=>!a0(u)).join(""),a=i.filter(u=>u.type==="thinking").map(u=>u.thinking??"").join(`
374
374
  `),c=i.filter(u=>u.type==="tool_use").map(u=>({id:u.id??"",name:u.name??"",input:u.input??{}}));if(o||a||c.length){let u=Date.parse(e.timestamp??""),d=!isNaN(u)&&u>=t;n.push({type:"assistant",text:o,thinking:a,tools:c,live:d})}let l=e.message?.usage??e.usage,f=l&&{in:l.input_tokens??0,out:l.output_tokens??0,cached:l.cache_read_input_tokens??0,cacheCreate:l.cache_creation_input_tokens??0};return{events:n,usage:f,model:e.message?.model}}return{events:n}}chainWorking(e){let t;for(let o of e)(o.type==="user"||o.type==="assistant")&&(t=o);if(!t)return!1;if(t.type==="user"){try{let o=t.message?.content,a=typeof o=="string"?o:Array.isArray(o)?o.filter(l=>l&&l.type==="text").map(l=>l.text??"").join(""):"";if(!(Array.isArray(o)&&o.some(l=>l&&l.type==="tool_result"))&&a.trim()&&dt(a)==="")return!1}catch{}return!0}let s=(Array.isArray(t.message?.content)?t.message.content:[]).filter(o=>o.type==="tool_use").map(o=>o.id);if(s.length===0)return!1;let i=new Set;for(let o of e){let a=o.message?.content;if(Array.isArray(a))for(let c of a)c.type==="tool_result"&&c.tool_use_id&&i.add(c.tool_use_id)}return s.some(o=>o&&!i.has(o))}sessionAlive(e){return d0(e)}readPreview(e){return f0(e)}searchText(e){if(!e||Rn(e)||e.type!=="user"&&e.type!=="assistant")return"";let t=e.message?.content,n="";if(typeof t=="string")n=dt(t);else if(Array.isArray(t)){let s=t;n=e.type==="user"?s.map(Zc).filter(Boolean).join(" "):s.filter(i=>i.type==="text"&&typeof i.text=="string").map(i=>i.text).join(" ")}return n.replace(/\s+/g," ").trim()}}});import{spawn as gm}from"child_process";import{readdir as p0,readFile as bm,writeFile as wm,unlink as rl,mkdir as m0}from"fs/promises";import{mkdirSync as vm,writeFileSync as Ni,appendFileSync as h0,readFileSync as nl}from"fs";import*as he from"path";import{fileURLToPath as g0}from"url";function sl(r){return he.join(Ke(),`${r}.json`)}function $n(r){return he.join(Ke(),`${r}.log`)}function il(r){return he.join(Ke(),`${r}.wait.json`)}function Sm(r){try{let e=JSON.parse(nl(il(r),"utf8"));return e.cursors&&typeof e.cursors=="object"?e.cursors:{}}catch{return{}}}function ol(r,e=""){let t=Sm(r)[e];return typeof t=="number"&&Number.isFinite(t)&&t>=0?t:void 0}function Ii(r,e,t=""){try{vm(Ke(),{recursive:!0});let n=Sm(r);n[t]=e,Ni(il(r),JSON.stringify({cursors:n}))}catch{}}function $i(r){let e=$n(r);try{vm(Ke(),{recursive:!0}),Ni(e,"")}catch{return()=>{}}let t=process.stdout.write.bind(process.stdout),n=process.stderr.write.bind(process.stderr),s=0,i=!1,o=a=>{if(!i)try{let c=typeof a=="string"?Buffer.from(a,"utf8"):Buffer.from(a);if(h0(e,c),s+=c.length,s>2*ym){let l=nl(e),f=l.subarray(Math.max(0,l.length-ym));Ni(e,f),s=f.length}}catch{i=!0}};return process.stdout.write=((a,...c)=>(o(a),t(a,...c))),process.stderr.write=((a,...c)=>(o(a),n(a,...c))),()=>{process.stdout.write=t,process.stderr.write=n}}function km(r){try{Ni($n(r),"")}catch{}}function Ce(r,e=0){try{let t=nl($n(r)),n=e>=0&&e<=t.length?e:0;return{text:t.subarray(n).toString("utf8"),offset:t.length}}catch{return{text:"",offset:0}}}function al(r){return`\u2500\u2500 run ${r} \u2500\u2500 ${new Date().toTimeString().slice(0,8)}`}function b0(r){let e=y0.exec(r);return e?Number(e[1]):void 0}function xm(r,e){let t=r.split(`
375
375
  `),n=[];if(t.forEach((o,a)=>{let c=b0(o);c!==void 0&&n.push({id:c,idx:a})}),!n.length)return e==="latest"?r:"";let s=e==="latest"?n[n.length-1]:n.find(o=>o.id===e);if(!s)return"";let i=n.find(o=>o.idx>s.idx);return t.slice(s.idx,i?i.idx:t.length).join(`
376
- `)}function cl(r){try{return process.kill(r,0),!0}catch(e){return e.code==="EPERM"}}async function Em(r){await m0(Ke(),{recursive:!0}),await wm(sl(r.pid),JSON.stringify(r))}async function Am(r,e){let t=sl(r);try{let n=JSON.parse(await bm(t,"utf8"));if(n.denied===e)return;n.denied=e,await wm(t,JSON.stringify(n))}catch{}}async function In(r){await rl(sl(r)).catch(()=>{}),await rl($n(r)).catch(()=>{}),await rl(il(r)).catch(()=>{})}async function Y(r){let e;try{e=await p0(Ke())}catch{return[]}let t=[];return await Promise.all(e.map(async s=>{if(!/^\d+\.json$/.test(s))return;let i=parseInt(s,10),o;try{o=JSON.parse(await bm(he.join(Ke(),s),"utf8"))}catch{await In(i);return}o&&typeof o.pid=="number"&&cl(o.pid)?t.push(o):await In(i)})),(r?t.filter(s=>s.agent==null&&um(s.file,r)):t).sort((s,i)=>s.startedAt-i.startedAt)}async function ll(r,e){let t=ee(r);return(await Y()).find(n=>n.cwd!=null&&ee(n.cwd)===t&&(e?n.agent===e:n.agent!=null))}async function jt(r){try{process.kill(r,"SIGTERM")}catch{}await In(r)}function Sr(r,e){let t=ee(e);return r.filter(n=>n.agent==null&&n.pid!==process.pid&&ee(n.file)===t)}async function ul(r){let e=Sr(await Y(),r);for(let t of e)await jt(t.pid);return e}function v0(r,e,t){(process.platform==="win32"?gm("cmd",["/c","start","","/b",r,...e],{cwd:t,stdio:"ignore",windowsHide:!0}):gm(r,e,{cwd:t,detached:!0,stdio:"ignore"})).unref()}function Tm(){return he.join(he.dirname(g0(import.meta.url)),"index.js")}function S0(r,e={}){return{command:process.execPath,args:[Tm(),...e.trust?["--trust"]:[],r,...e.open===!1?["--no-open"]:[]]}}function k0(r){return{command:process.execPath,args:[Tm(),`agent:${r}`,"--no-open"]}}async function Pm(r,e,t,n){let s=await r();if(s)return s;v0(e.command,e.args,t);let i=Date.now()+2e4;for(;Date.now()<i;){await w0(150);let o=await r();if(o)return o}throw new Error(`Launched ${n} but it did not register within 20s.`)}async function Li(r,e={}){let t=e.cwd??process.cwd(),n=he.resolve(t,r);return await ul(n),Pm(async()=>Sr(await Y(),n)[0],S0(r,e),t,he.basename(r))}async function Om(r,e=process.cwd()){return Pm(()=>ll(e,r),k0(r),e,`the ${r} mirror`)}var ym,y0,w0,Re=A(()=>{Ti();ym=1e6;y0=/^── run (\d+) ── /;w0=r=>new Promise(e=>setTimeout(e,r))});function Mi(r){let e=/^---[^\n]*\n([\s\S]*?)\n---/.exec(r),t=e?/^\s*name:\s*(.+?)\s*$/m.exec(e[1]):null;return t?t[1].replace(/^["']|["']$/g,""):void 0}function fl(r){return(Mi(r)??"bulb").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"bulb"}var dl=A(()=>{});import{readdirSync as x0,readFileSync as E0,statSync as A0}from"fs";import{join as _m,basename as T0}from"path";function Cm(r,e,t){if(e>8)return t;let n;try{n=x0(r,{withFileTypes:!0})}catch{return t}for(let s of n)if(s.isDirectory()){if(s.name.startsWith(".")||s.name==="node_modules")continue;Cm(_m(r,s.name),e+1,t)}else s.isFile()&&s.name.endsWith(".bulb.md")&&t.push(_m(r,s.name));return t}function Di(r){return Cm(r,0,[]).map(e=>{let t=0;try{t=A0(e).mtimeMs}catch{}let n,s=!1;try{let i=E0(e,"utf8");n=Mi(i.slice(0,1024));let o=de(i);s=!!o&&Qs(ar(o))}catch{}return{path:e,name:n??T0(e).replace(/\.bulb\.md$/,""),mtime:t,serverOnly:s}})}var Rm=A(()=>{Be();gn();dl()});function kr(r){if(r.server.trim())return"server-side code (server.ts)";let e=r.code;if(/\btb\s*\.\s*fs\b/.test(e)||e.includes("/__fs"))return"the filesystem";if(/\btb\s*\.\s*ai\b/.test(e)||e.includes("/__ai")||r.infer.trim()||/\btb\s*\.\s*infer\b/.test(e))return"AI (your API keys)";if(/\btb\s*\.\s*server\s*\.\s*(?!log\b)\w/.test(e)||e.includes("/__api"))return"server-side code (server.ts)"}var Bi=A(()=>{});import{readFile as P0}from"fs/promises";async function pl(r){try{let e=de(await P0(r,"utf-8"));return e?kr(ar(e)):void 0}catch{return}}var Nm=A(()=>{gn();Bi()});function ml(r){let e=de(r);if(!e)return r;let t=e.files.get("code.tsx");if(!t)return r;let n=Cp(t);if(!n.length)return r;let s=e.files.get("config.json"),i={};if(s)try{let l=JSON.parse(s);l&&typeof l=="object"&&(i=l)}catch{}let o=i.dependencies&&typeof i.dependencies=="object"?{...i.dependencies}:{},a=n.filter(l=>!(l in o));if(!a.length)return r;for(let l of a)o[l]="latest";i.dependencies=o;let c={name:e.frontmatter.name};for(let[l,f]of e.files){let u=bu(l);u&&(c[u]=f)}return c.config=JSON.stringify(i,null,2),Tu(c)}var Im=A(()=>{Be();Xs()});import{spawn as $m}from"child_process";import{basename as O0}from"path";function _0(){return process.env.TYPEBULB_EDITOR||"code"}function R0(r,e,t){return t==null?[e]:C0.test(O0(r))?["-g",`${e}:${t}`]:[`+${t}`,e]}function N0(r,e){let t=_0();return{command:t,args:R0(t,r,e)}}function hl(r,e){let{command:t,args:n}=N0(r,e),s=process.platform==="win32"?$m("cmd.exe",["/d","/s","/c",t,...n],{detached:!0,stdio:"ignore",windowsHide:!0}):$m(t,n,{detached:!0,stdio:"ignore"});s.on("error",i=>console.error("[typebulb] editor launch failed:",i?.message??i)),s.unref()}var C0,Lm=A(()=>{C0=/^(code|code-insiders|codium|vscodium|cursor|windsurf)(\.cmd|\.exe)?$/i});import{readFileSync as I0,existsSync as $0}from"fs";import*as Ft from"path";import{fileURLToPath as L0}from"url";function Mm(){let r=Ft.dirname(L0(import.meta.url));for(;!$0(Ft.join(r,"package.json"));){let e=Ft.dirname(r);if(e===r)break;r=e}return r}function qt(){return Ft.join(Mm(),"README.md")}function xr(){return Ft.join(Mm(),"description.md")}function M0(r){let e=I0(xr(),"utf8").trim().replace(/\s+/g," ");return`---
376
+ `)}function cl(r){try{return process.kill(r,0),!0}catch(e){return e.code==="EPERM"}}async function Em(r){await m0(Ke(),{recursive:!0}),await wm(sl(r.pid),JSON.stringify(r))}async function Am(r,e){let t=sl(r);try{let n=JSON.parse(await bm(t,"utf8"));if(n.denied===e)return;n.denied=e,await wm(t,JSON.stringify(n))}catch{}}async function In(r){await rl(sl(r)).catch(()=>{}),await rl($n(r)).catch(()=>{}),await rl(il(r)).catch(()=>{})}async function Y(r){let e;try{e=await p0(Ke())}catch{return[]}let t=[];return await Promise.all(e.map(async s=>{if(!/^\d+\.json$/.test(s))return;let i=parseInt(s,10),o;try{o=JSON.parse(await bm(he.join(Ke(),s),"utf8"))}catch{await In(i);return}o&&typeof o.pid=="number"&&cl(o.pid)?t.push(o):await In(i)})),(r?t.filter(s=>s.agent==null&&um(s.file,r)):t).sort((s,i)=>s.startedAt-i.startedAt)}async function ll(r,e){let t=ee(r);return(await Y()).find(n=>n.cwd!=null&&ee(n.cwd)===t&&(e?n.agent===e:n.agent!=null))}async function jt(r){try{process.kill(r,"SIGTERM")}catch{}await In(r)}function Sr(r,e){let t=ee(e);return r.filter(n=>n.agent==null&&n.pid!==process.pid&&ee(n.file)===t)}async function ul(r){let e=Sr(await Y(),r);for(let t of e)await jt(t.pid);return e}function v0(r,e,t){(process.platform==="win32"?gm("cmd",["/c","start","","/b",r,...e],{cwd:t,stdio:"ignore",windowsHide:!0}):gm(r,e,{cwd:t,detached:!0,stdio:"ignore"})).unref()}function Tm(){return he.join(he.dirname(g0(import.meta.url)),"index.js")}function S0(r,e={}){return{command:process.execPath,args:[Tm(),...e.trust?["--trust"]:[],...e.dir?["--dir",e.dir]:[],...e.mode?["--mode",e.mode]:[],r,...e.open===!1?["--no-open"]:[]]}}function k0(r){return{command:process.execPath,args:[Tm(),`agent:${r}`,"--no-open"]}}async function Pm(r,e,t,n){let s=await r();if(s)return s;v0(e.command,e.args,t);let i=Date.now()+2e4;for(;Date.now()<i;){await w0(150);let o=await r();if(o)return o}throw new Error(`Launched ${n} but it did not register within 20s.`)}async function Li(r,e={}){let t=e.cwd??process.cwd(),n=he.resolve(t,r),[s]=await ul(n),i={...e,dir:e.dir??s?.dir,mode:e.mode??s?.mode};return Pm(async()=>Sr(await Y(),n)[0],S0(r,i),t,he.basename(r))}async function Om(r,e=process.cwd()){return Pm(()=>ll(e,r),k0(r),e,`the ${r} mirror`)}var ym,y0,w0,Re=A(()=>{Ti();ym=1e6;y0=/^── run (\d+) ── /;w0=r=>new Promise(e=>setTimeout(e,r))});function Mi(r){let e=/^---[^\n]*\n([\s\S]*?)\n---/.exec(r),t=e?/^\s*name:\s*(.+?)\s*$/m.exec(e[1]):null;return t?t[1].replace(/^["']|["']$/g,""):void 0}function fl(r){return(Mi(r)??"bulb").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"bulb"}var dl=A(()=>{});import{readdirSync as x0,readFileSync as E0,statSync as A0}from"fs";import{join as _m,basename as T0}from"path";function Cm(r,e,t){if(e>8)return t;let n;try{n=x0(r,{withFileTypes:!0})}catch{return t}for(let s of n)if(s.isDirectory()){if(s.name.startsWith(".")||s.name==="node_modules")continue;Cm(_m(r,s.name),e+1,t)}else s.isFile()&&s.name.endsWith(".bulb.md")&&t.push(_m(r,s.name));return t}function Di(r){return Cm(r,0,[]).map(e=>{let t=0;try{t=A0(e).mtimeMs}catch{}let n,s=!1;try{let i=E0(e,"utf8");n=Mi(i.slice(0,1024));let o=de(i);s=!!o&&Qs(ar(o))}catch{}return{path:e,name:n??T0(e).replace(/\.bulb\.md$/,""),mtime:t,serverOnly:s}})}var Rm=A(()=>{Be();gn();dl()});function kr(r){if(r.server.trim())return"server-side code (server.ts)";let e=r.code;if(/\btb\s*\.\s*fs\b/.test(e)||e.includes("/__fs"))return"the filesystem";if(/\btb\s*\.\s*ai\b/.test(e)||e.includes("/__ai")||r.infer.trim()||/\btb\s*\.\s*infer\b/.test(e))return"AI (your API keys)";if(/\btb\s*\.\s*server\s*\.\s*(?!log\b)\w/.test(e)||e.includes("/__api"))return"server-side code (server.ts)"}var Bi=A(()=>{});import{readFile as P0}from"fs/promises";async function pl(r){try{let e=de(await P0(r,"utf-8"));return e?kr(ar(e)):void 0}catch{return}}var Nm=A(()=>{gn();Bi()});function ml(r){let e=de(r);if(!e)return r;let t=e.files.get("code.tsx");if(!t)return r;let n=Cp(t);if(!n.length)return r;let s=e.files.get("config.json"),i={};if(s)try{let l=JSON.parse(s);l&&typeof l=="object"&&(i=l)}catch{}let o=i.dependencies&&typeof i.dependencies=="object"?{...i.dependencies}:{},a=n.filter(l=>!(l in o));if(!a.length)return r;for(let l of a)o[l]="latest";i.dependencies=o;let c={name:e.frontmatter.name};for(let[l,f]of e.files){let u=bu(l);u&&(c[u]=f)}return c.config=JSON.stringify(i,null,2),Tu(c)}var Im=A(()=>{Be();Xs()});import{spawn as $m}from"child_process";import{basename as O0}from"path";function _0(){return process.env.TYPEBULB_EDITOR||"code"}function R0(r,e,t){return t==null?[e]:C0.test(O0(r))?["-g",`${e}:${t}`]:[`+${t}`,e]}function N0(r,e){let t=_0();return{command:t,args:R0(t,r,e)}}function hl(r,e){let{command:t,args:n}=N0(r,e),s=process.platform==="win32"?$m("cmd.exe",["/d","/s","/c",t,...n],{detached:!0,stdio:"ignore",windowsHide:!0}):$m(t,n,{detached:!0,stdio:"ignore"});s.on("error",i=>console.error("[typebulb] editor launch failed:",i?.message??i)),s.unref()}var C0,Lm=A(()=>{C0=/^(code|code-insiders|codium|vscodium|cursor|windsurf)(\.cmd|\.exe)?$/i});import{readFileSync as I0,existsSync as $0}from"fs";import*as Ft from"path";import{fileURLToPath as L0}from"url";function Mm(){let r=Ft.dirname(L0(import.meta.url));for(;!$0(Ft.join(r,"package.json"));){let e=Ft.dirname(r);if(e===r)break;r=e}return r}function qt(){return Ft.join(Mm(),"README.md")}function xr(){return Ft.join(Mm(),"description.md")}function M0(r){let e=I0(xr(),"utf8").trim().replace(/\s+/g," ");return`---
377
377
  name: typebulb
378
378
  description: ${JSON.stringify(e)}
379
379
  version: ${r}
@@ -1536,7 +1536,7 @@ declare const tb: {${wg}${kg}${xg}${vg}${Sg}
1536
1536
  `)+`
1537
1537
  `);let i=Fg.createInterface({input:process.stdin,output:process.stdout});try{let o=(await new Promise(c=>i.question(" Open which? [1]: ",c))).trim();if(o==="")return e[0];let a=Number(o);return Number.isInteger(a)&&a>=1&&a<=e.length?e[a-1]:e.find(c=>c===o.toLowerCase())}finally{i.close()}}function YT(r,e){let{lit:t,brand:n}=Wl(process.stdout.isTTY===!0),s=[` ${n(`typebulb v${r}`)}`," More than one agent harness is available here."," Open the mirror for the one you want:",...e.map(i=>` \u2022 ${t(`npx typebulb agent:${i}`)}`),""];process.stdout.write(s.join(`
1538
1538
  `)+`
1539
- `)}mt();Dt();async function Ug(r){ge(r);let e=await qe();if(e.length>0){console.log(om(e,process.env.TB_AI_PROVIDER,process.env.TB_AI_MODEL));return}if(!Kc()){console.log("No AI provider keys found in this directory's .env, and no local Ollama server detected."),console.log("Set one of these to use a cloud model with tb.ai:");for(let[t,n]of Object.entries(hr))console.log(` ${n.padEnd(20)} (${t})`);console.log("\u2026or start Ollama (http://localhost:11434, or set OLLAMA_HOST) for local models. Then re-run `typebulb models`.");return}console.log("Couldn't fetch the model catalog (offline?). tb.ai still works with any valid provider/model id for your keys.")}ji();import*as Jg from"fs/promises";async function Kg(r){let e=qt(),t;try{t=await Jg.readFile(e,"utf8")}catch{console.error(`Could not read the bundled README (expected at ${e}).`),process.exit(1)}process.stdout.write(Dm(t,r))}Ti();import*as Hg from"path";Re();function VT(r,e,t,n){if(/^\d+$/.test(e))return r.find(i=>i.pid===parseInt(e,10));let s=e==="agent"?r.filter(i=>i.agent!=null):r.filter(i=>i.agent===e);if(s.length){if(!t)return s[0];let i=s.filter(o=>o.cwd&&ee(o.cwd)===ee(t));return n&&i.find(o=>o.agent===n)||i[0]}return r.find(i=>ee(i.file)===ee(e))}var Hn=r=>r.agent??Hg.basename(r.file);function Wg(r,e){for(let t of r)e(` ${t.url} pid ${t.pid} ${t.trust?"trusted":"restricted"} ${t.file}`)}function Yl(r,e){if(!r.length){console.log("No running bulb servers.");return}console.log("Running bulb servers:"),Wg(r,t=>console.log(t)),console.log(`
1539
+ `)}mt();Dt();async function Ug(r){ge(r);let e=await qe();if(e.length>0){console.log(om(e,process.env.TB_AI_PROVIDER,process.env.TB_AI_MODEL));return}if(!Kc()){console.log("No AI provider keys found in this directory's .env, and no local Ollama server detected."),console.log("Set one of these to use a cloud model with tb.ai:");for(let[t,n]of Object.entries(hr))console.log(` ${n.padEnd(20)} (${t})`);console.log("\u2026or start Ollama (http://localhost:11434, or set OLLAMA_HOST) for local models. Then re-run `typebulb models`.");return}console.log("Couldn't fetch the model catalog (offline?). tb.ai still works with any valid provider/model id for your keys.")}ji();import*as Jg from"fs/promises";async function Kg(r){let e=qt(),t;try{t=await Jg.readFile(e,"utf8")}catch{console.error(`Could not read the bundled README (expected at ${e}).`),process.exit(1)}process.stdout.write(Dm(t,r))}Ti();import*as Hg from"path";Re();function VT(r,e,t,n){if(/^\d+$/.test(e))return r.find(i=>i.pid===parseInt(e,10));let s=e==="agent"?r.filter(i=>i.agent!=null):r.filter(i=>i.agent===e);if(s.length){if(!t)return s[0];let i=s.filter(o=>o.cwd&&ee(o.cwd)===ee(t));return n&&i.find(o=>o.agent===n)||i[0]}return r.find(i=>ee(i.file)===ee(e))}var Hn=r=>r.agent??Hg.basename(r.file);function Wg(r,e){for(let t of r)e(` ${t.url} pid ${t.pid} ${t.trust?"trusted":"restricted"}${t.dir?` --dir ${t.dir}`:""} ${t.file}`)}function Yl(r,e){if(!r.length){console.log("No running bulb servers.");return}console.log("Running bulb servers:"),Wg(r,t=>console.log(t)),console.log(`
1540
1540
  `+e)}function Vl(r,e,t,n,s){let i=VT(r,e,n,s);if(i)return i;console.error(`No running server for '${e}'.`),r.length?(console.error(`Running servers (try \`typebulb ${t} <file|pid>\`):`),Wg(r,o=>console.error(o))):console.error("No bulb servers are running."),process.exit(1)}async function Yg(r,e){if(!r){e.clear&&(console.error("Specify which server to clear: typebulb logs --clear <file|pid>"),process.exit(1)),Yl(await Y(process.cwd()),"Run `typebulb logs <file|pid>` to print one server's console.");return}let t=Vl(await Y(),r,"logs",process.cwd(),Kn());if(e.clear){km(t.pid),console.log(`Cleared log for ${Hn(t)} (pid ${t.pid}).`);return}let n=Ce(t.pid),s=n.text;if(e.run!==void 0&&(s=xm(s,e.run),!s&&e.run!=="latest"&&console.error(`No output for run ${e.run} (it hasn't started, or was trimmed from the log).`)),e.lines&&e.lines>0){let i=s.split(`
1541
1541
  `);i.length&&i[i.length-1]===""&&i.pop(),s=i.slice(-e.lines).join(`
1542
1542
  `)}if(process.stdout.write(s),s&&!s.endsWith(`
@@ -1850,7 +1850,7 @@ export function runInference(ctx) {
1850
1850
  ${d}`:"";return h.text(`Forbidden: this capability requires --trust.${N}`,403)}await S()},x=async(h,S)=>{let I=h.req.header("sec-fetch-site");if(I){if(I!=="same-origin")return h.text(`Forbidden: ${I} request`,403)}else{let D=h.req.header("origin");if(D&&!aP(D,h.req.header("host")))return h.text("Forbidden: cross-origin request",403)}await S()};for(let[h]of b)m.use(h,k),m.use(h,x);m.use("/__log",x),m.post("/__log",async h=>{try{let{args:S}=await h.req.json();console.log(...S||[])}catch{}return h.json({ok:!0})}),o&&(m.use("/__send",x),m.post("/__send",async h=>{let S="";try{S=await h.req.text()}catch{}let I=o.listenerCount("message");return o.emit("message",S),h.json({clients:I})})),m.get("/",h=>h.html(e())),m.post("/__fs/read",async h=>{try{let{path:S}=await h.req.json(),I=await On(S,y,t);return new Response(new Uint8Array(I),{headers:{"Content-Type":"application/octet-stream"}})}catch(S){let I=zl(S);return h.json({error:I},400)}}),m.post("/__fs/write",async h=>{try{let S=h.req.query("path");return S?(await xi(S,new Uint8Array(await h.req.arrayBuffer()),y,t),h.json({success:!0})):h.json({error:"Missing path"},400)}catch(S){let I=zl(S);return h.json({error:I},400)}}),m.post("/__api/:name",async h=>{try{let S=h.req.param("name"),I=Ao(a?.(),S);if(!I)return h.json({error:`API function '${S}' not found`},404);let{args:D}=await h.req.json();if(To(I))return xo(h,I(...D||[]));let N=await I(...D||[]);return h.json({result:N})}catch(S){let I=zl(S);return h.json({error:I},500)}}),m.post("/__ai",async h=>{try{let{messages:S,system:I,effort:D,provider:N,model:X,webSearch:fe,stream:vt}=await h.req.json();if(!S||!Array.isArray(S)||S.length===0)return h.json({message:"messages array is required",code:"unknown",retryable:!1},400);let te=Ue(N,X);if(typeof te=="string")return h.json({message:te,code:"unknown",retryable:!1},400);let z=await ut(te,{messages:S,system:I,effort:D,webSearch:fe,signal:h.req.raw.signal});if(!z.ok){let Ve=await pr(z,te.protocol);return h.json(Ve,z.status)}if(vt)return xo(h,Mt(z,te.protocol));let St=await Lt(z,te.protocol);return St||console.warn("[tb.ai] Empty response from provider"),h.json({text:St})}catch(S){return h.json(Yn(S),500)}}),m.post("/__infer",async h=>{try{let{data:S}=await h.req.json().catch(()=>({})),I=c?.();if(!I?.infer.trim())return h.json({message:"This bulb has no infer.md block.",code:"unknown",retryable:!1},400);let D=Ue();if(typeof D=="string")return h.json({message:D,code:"unknown",retryable:!1},400);let N=Array.isArray(S)?S.map(String):[],X=jc(I,N),fe=await ut(D,{messages:[{role:"user",content:X}],signal:h.req.raw.signal});if(!fe.ok){let te=await pr(fe,D.protocol);return h.json(te,fe.status)}let vt=(async function*(){let te="";for await(let Ve of Mt(fe,D.protocol))Ve.kind!=="text"||!Ve.text||(te+=Ve.text,yield{kind:"delta",text:Ve.text});let z=Fc(te);if(z.parsed===null)throw console.warn(`[tb.infer] output not valid JSON after sanitize; raw output (last 4000 chars):
1851
1851
  `+te.slice(-4e3)),new ue("LLM output is not valid JSON","parse_error",!0);z.fixesApplied.length&&console.warn("[tb.infer] sanitized output, fixes applied:",z.fixesApplied.join(", "));let St={insight:z.parsed,insightJson:z.json,data:N};yield{kind:"complete",...St,fixesApplied:z.fixesApplied,hash:qc(St)}})();return xo(h,vt)}catch(S){return h.json(Yn(S),500)}});let T=async h=>{let{hash:S}=await h.req.json().catch(()=>({}));return typeof S=="string"?Uc(S):null};m.post("/__infer-save",async h=>{try{if(!l)return h.json({message:"Save is not available for this server.",code:"unknown",retryable:!1},400);let S=await T(h);return S?(await l(S.data,S.insightJson),h.json({ok:!0})):h.json({message:"No decodable #tb= fragment to save.",code:"unknown",retryable:!1},400)}catch(S){return h.json(Yn(S),500)}}),m.get("/__infer-info",h=>{let S=c?.(),I=Lr(S?.config??"").inference,D=zs(S?.data??""),N=Ue();return typeof N=="string"?h.json({error:N,inference:I,data:D}):h.json({provider:N.protocol,model:N.model,inference:I,data:D})}),m.use("/__infer-decode",x),m.post("/__infer-decode",async h=>h.json(await T(h)??{error:"invalid fragment"})),m.get("/__infer-ui.js",h=>h.body(Zg,200,{"Content-Type":"text/javascript; charset=utf-8"})),m.get("/__models",async h=>{try{let S=await qe();return h.json(S)}catch{return h.json([],200)}}),m.get("/__has-own-keys",async h=>{try{return h.json(await vi())}catch{return h.json(!1,200)}});let P=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"],_=new ko;m.get("/proxy/*",async h=>{let S=new URL(h.req.url),D=(S.pathname+S.search).slice(7),N=D.lastIndexOf("https://");return N===-1?h.text("Invalid proxy URL",400):O(h,D.slice(N))}),f&&ty(m,`/local/${f.name}/`,f.serveDir),p&&ty(m,p.mount,p.dir);async function O(h,S){let I;try{I=new URL(S)}catch{return h.text("Invalid URL",400)}if(I.protocol!=="https:")return h.text("HTTPS only",400);if(!P.includes(I.hostname))return h.text("Host not allowed",403);let D=await _.get(S);if(D)return new Response(D.body,{status:200,headers:Ql(D.contentType,D.cacheControl)});try{let N=await fetch(S,{headers:{Accept:h.req.header("Accept")||"*/*"},redirect:"follow"});if(!N.ok)return h.text(`Upstream ${N.status}`,N.status);let X=N.headers.get("Content-Type")||void 0,fe=N.headers.get("Cache-Control")||void 0;if(N.body){let[vt,te]=N.body.tee();return(async()=>{try{let z=await new Response(te).arrayBuffer();await _.set(S,{body:Buffer.from(z),contentType:X,cacheControl:fe})}catch{}})(),new Response(vt,{status:N.status,headers:Ql(X,fe)})}return new Response(null,{status:N.status,headers:Ql(X,fe)})}catch(N){return h.text(`Proxy fetch failed: ${N instanceof Error?N.message:N}`,502)}}(i||o)&&m.get("/__reload",h=>nP(h,async S=>{let I=()=>{S.writeSSE({event:"reload",data:""})},D=N=>{S.writeSSE({event:"message",data:JSON.stringify(N)})};for(i?.on("reload",I),o?.on("message",D),S.onAbort(()=>{i?.removeListener("reload",I),o?.removeListener("message",D)});!S.aborted;)await S.sleep(3e4)})),m.notFound(async h=>{if(h.req.method!=="GET")return h.text("Not Found",404);let S=new URL(h.req.url);return ey(S.pathname,S.search)?O(h,"https://esm.sh"+S.pathname+S.search):h.text("Not Found",404)});let R=rP({fetch:m.fetch,port:s,hostname:sy});return{port:s,close:()=>R.close()}}function Ql(r,e){let t=new Headers;return r&&t.set("Content-Type",r),e&&t.set("Cache-Control",e),t.set("Access-Control-Allow-Origin","*"),t.set("Cross-Origin-Resource-Policy","cross-origin"),t}function ty(r,e,t){r.get(`${e}*`,async n=>{let{pathname:s}=new URL(n.req.url);if(!s.startsWith(e))return n.text("Not Found",404);let i=decodeURIComponent(s.slice(e.length));try{let o=ki(i,t),a=await ry.readFile(o);return new Response(a,{headers:{"Content-Type":cP(o)}})}catch{return n.text("Not Found",404)}})}function cP(r){switch(ny.extname(r).toLowerCase()){case".js":case".mjs":return"text/javascript";case".wasm":return"application/wasm";case".json":case".map":return"application/json";default:return"application/octet-stream"}}async function Xl(r){let e=await import("net");return new Promise(t=>{let n=e.createServer();n.listen(r,sy,()=>{let s=n.address(),i=typeof s=="object"&&s?s.port:r;n.close(()=>t(i))}),n.on("error",()=>{t(Xl(r+1))})})}Re();async function Po(r){let{portPreference:e,makeServerOptions:t,makeEntry:n,displayName:s,stopLog:i}=r,o=await Xl(e),a=await iy(t(o)),c=`http://localhost:${o}`;await Em(n(o,c)),console.log(`
1852
1852
  ${s}`),console.log(` ${c}`),o!==e&&console.log(` (port ${e} was busy)`);let l=[],f=async()=>{console.log(`
1853
- Shutting down...`),a.close();for(let u of l)try{await u()}catch{}i(),await In(process.pid),process.exit(0)};return process.on("SIGINT",f),process.on("SIGTERM",f),{port:o,url:c,onCleanup(u){l.push(u)}}}import lP from"chokidar";var uP={persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}};function Yt(r){let{target:e,onChange:t,events:n="change",debounceMs:s=150}=r,i,o=lP.watch(e,uP),a=()=>{i&&clearTimeout(i),i=setTimeout(t,s)};return n==="all"?o.on("all",a):o.on("change",a),()=>{i&&clearTimeout(i),o.close()}}Re();async function cy(r,e,t,n){let s=process.cwd(),i=$i(process.pid),o=e.watch?new oy:void 0,a=new oy;a.setMaxListeners(0);let c=ge(e.mode),l=await ul(r);l.length&&console.log(`Replacing the running server for this bulb (pid ${l.map(P=>P.pid).join(", ")})`);let f=1;console.log(al(f)),console.log(`Loading ${ay.basename(r)}...`);let{html:u,bulb:d,serverExports:p}=await Wc(r,e.watch,e.trust,n,e.dir);pt(c,r,d.server);let y=e.trust?void 0:kr(d),{port:m,url:b,onCleanup:k}=await Po({portPreference:e.port,displayName:d.name,stopLog:i,makeServerOptions:P=>({getHtml:()=>u,basePath:s,fsBase:Ei(r,e.dir),port:P,reloadEmitter:o,messageEmitter:a,getServerExports:()=>p,getBulbBlocks:()=>({infer:d.infer,insight:d.insight,code:d.code,config:d.config,data:d.data}),saveInferenceResult:async(_,O)=>{let R=await $r.readFile(r,"utf-8");R=Mo(R,"data",_.join(Pp)),R=Mo(R,"insight",O),await $r.writeFile(r,R)},localOverride:n?{name:n.name,serveDir:n.serveDir}:void 0,trusted:e.trust,trustHint:t}),makeEntry:(P,_)=>({pid:process.pid,port:P,url:_,file:r,cwd:process.cwd(),startedAt:Date.now(),trust:e.trust,predicted:y})});e.trust?console.log(" trust: granted (filesystem, AI, server.ts enabled)"):console.log(y?` trust: restricted \u2014 this bulb appears to use ${y}; re-run with --trust to enable it:
1853
+ Shutting down...`),a.close();for(let u of l)try{await u()}catch{}i(),await In(process.pid),process.exit(0)};return process.on("SIGINT",f),process.on("SIGTERM",f),{port:o,url:c,onCleanup(u){l.push(u)}}}import lP from"chokidar";var uP={persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}};function Yt(r){let{target:e,onChange:t,events:n="change",debounceMs:s=150}=r,i,o=lP.watch(e,uP),a=()=>{i&&clearTimeout(i),i=setTimeout(t,s)};return n==="all"?o.on("all",a):o.on("change",a),()=>{i&&clearTimeout(i),o.close()}}Re();async function cy(r,e,t,n){let s=process.cwd(),i=$i(process.pid),o=e.watch?new oy:void 0,a=new oy;a.setMaxListeners(0);let c=ge(e.mode),l=await ul(r);l.length&&console.log(`Replacing the running server for this bulb (pid ${l.map(P=>P.pid).join(", ")})`);let f=1;console.log(al(f)),console.log(`Loading ${ay.basename(r)}...`);let{html:u,bulb:d,serverExports:p}=await Wc(r,e.watch,e.trust,n,e.dir);pt(c,r,d.server);let y=e.trust?void 0:kr(d),{port:m,url:b,onCleanup:k}=await Po({portPreference:e.port,displayName:d.name,stopLog:i,makeServerOptions:P=>({getHtml:()=>u,basePath:s,fsBase:Ei(r,e.dir),port:P,reloadEmitter:o,messageEmitter:a,getServerExports:()=>p,getBulbBlocks:()=>({infer:d.infer,insight:d.insight,code:d.code,config:d.config,data:d.data}),saveInferenceResult:async(_,O)=>{let R=await $r.readFile(r,"utf-8");R=Mo(R,"data",_.join(Pp)),R=Mo(R,"insight",O),await $r.writeFile(r,R)},localOverride:n?{name:n.name,serveDir:n.serveDir}:void 0,trusted:e.trust,trustHint:t}),makeEntry:(P,_)=>({pid:process.pid,port:P,url:_,file:r,cwd:process.cwd(),startedAt:Date.now(),trust:e.trust,dir:e.dir,mode:e.mode,predicted:y})});e.trust?console.log(" trust: granted (filesystem, AI, server.ts enabled)"):console.log(y?` trust: restricted \u2014 this bulb appears to use ${y}; re-run with --trust to enable it:
1854
1854
  ${t}
1855
1855
  `:` trust: restricted \u2014 re-run with --trust to enable filesystem / AI / server.ts
1856
1856
  `),e.watch&&console.log(` Watching for changes...
@@ -1923,5 +1923,5 @@ ${dP}
1923
1923
  `);let c=0,l=Promise.resolve();Yt({target:r,onChange:()=>{let f=++c;l=l.then(async()=>{if(f===c)try{console.log("Re-running..."),await a()}catch(u){console.error("Error:",u)}})}})}}mt();import{Console as yP}from"node:console";Re();async function yy(r,e,t,n,s){kP();try{let p=Sr(await Y(),r)[0];p&&(Ii(p.pid,Ce(p.pid).offset),console.error(`note: 'call' boots a fresh server.ts instance; the running server (${p.url}) is not contacted \u2014 state shared with it must live on disk.`))}catch{}let i=ge(t),{bulb:o,config:a}=await xe(r);o.server||Vn("This bulb has no **server.ts** block; nothing to call."),pt(i,r,o.server);let c;try{c=await _n(o.server,r,n,a.dependencies,s)}catch(p){Vn(p instanceof Error?p.message:String(p))}let l=Ao(c,e.fn);if(!l){let p=[...Object.keys(c).filter(y=>typeof c[y]=="function"),...Object.keys(Eo)];Vn(`Function '${e.fn}' not found. Available: ${p.length?p.join(", "):"(none)"}.`)}let f=await bP(e);if(To(l)){try{for await(let p of l(...f))await gy(JSON.stringify(p,by)+`
1924
1924
  `)}catch(p){Vn(p instanceof Error?p.stack??p.message:String(p))}return hy(0)}let u;try{u=await l(...f)}catch(p){Vn(p instanceof Error?p.stack??p.message:String(p))}let d=SP(u);d!==void 0&&await gy(d+`
1925
1925
  `),hy(0)}function hy(r){process.exitCode=r,setTimeout(()=>process.exit(r),2e3).unref?.()}async function bP(r){if(r.hasArgsFlag){let e=r.argsJson??"";return e==="-"&&(e=await xP()),vP(e)}return wP(r.positional)}function wP(r){return r.map(e=>{try{return JSON.parse(e)}catch{return e}})}function vP(r){let e;try{e=JSON.parse(r)}catch(t){throw new Error(`--args must be a JSON array: ${t instanceof Error?t.message:String(t)}`)}if(!Array.isArray(e))throw new Error(`--args must be a JSON array, got ${e===null?"null":typeof e}`);return e}function SP(r){if(r!==void 0)return JSON.stringify(r,by,2)}function by(r,e){return typeof e=="bigint"?e.toString():e}function Vn(r){process.stderr.write(r+`
1926
- `),process.exit(1)}function kP(){let r=new yP(process.stderr,process.stderr);console.log=r.log.bind(r),console.info=r.info.bind(r),console.debug=r.debug.bind(r),console.dir=r.dir.bind(r)}function gy(r){return new Promise((e,t)=>{process.stdout.write(r,n=>n?t(n):e())})}async function xP(){let r=[];for await(let e of process.stdin)r.push(e);return Buffer.concat(r).toString("utf-8")}var eu="0.29.2";function wy(r,e){r||(console.error(`This bulb runs server-side Node code (server.ts), which --trust must authorize:
1926
+ `),process.exit(1)}function kP(){let r=new yP(process.stderr,process.stderr);console.log=r.log.bind(r),console.info=r.info.bind(r),console.debug=r.debug.bind(r),console.dir=r.dir.bind(r)}function gy(r){return new Promise((e,t)=>{process.stdout.write(r,n=>n?t(n):e())})}async function xP(){let r=[];for await(let e of process.stdin)r.push(e);return Buffer.concat(r).toString("utf-8")}var eu="0.30.0";function wy(r,e){r||(console.error(`This bulb runs server-side Node code (server.ts), which --trust must authorize:
1927
1927
  ${e}`),process.exit(1))}async function EP(){let r=gu(process.argv.slice(2));if(r.version&&(console.log(`typebulb ${eu}`),process.exit(0)),r.help&&(yu(),process.exit(0)),Dg(),r.subcommand==="logs"){await Yg(r.file||void 0,{follow:r.follow,clear:r.clear,run:r.run,lines:r.lines});return}if(r.subcommand==="wait"){await Vg(r.file||void 0,{match:r.match,timeoutSec:r.timeoutSec});return}if(r.subcommand==="stop"){r.stopScope?await zg(r.stopScope):await Gg(r.file||void 0);return}if(r.subcommand==="send"){await Xg(r.file,r.sendMessage,r.sendWaitMs??0);return}if(r.subcommand==="skill"){await Kg(eu);return}if(r.subcommand==="models"){await Ug(r.mode);return}if(r.subcommand==="pull"){await qm(r.file||void 0,{force:r.force,mode:r.mode});return}if(r.subcommand==="push"){await Km(r.file||void 0,{force:r.force,mode:r.mode});return}if(r.subcommand==="agent"){await(r.agentTarget?dy(r):qg(eu));return}if(r.subcommand==="trust"||r.subcommand==="untrust"){await Mg(r.file||void 0,r.subcommand==="trust");return}let e;if(!r.file||r.file==="."){let c=await lm(process.cwd());c||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=c}else e=Vt.resolve(r.file);await vy.access(e).then(()=>!0,()=>!1)||(Rr().includes(r.file)&&(console.error(`To open the ${r.file} agent mirror, run: npx typebulb agent:${r.file}`),process.exit(1)),console.error(`File not found: ${e}`),process.exit(1)),e.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1));let n=r.file&&r.file!=="."?r.file:Vt.relative(process.cwd(),e)||Vt.basename(e),s=`npx typebulb --trust ${n.includes(" ")?`"${n}"`:n}`;if(r.subcommand==="predict"){await Lg(e,s);return}let i=!r.noTrust&&Bt(e);i&&!r.trust&&console.error("trust: granted from memory (run `typebulb untrust` to revoke)"),r.trust=r.noTrust?!1:r.trust||i;let o;try{o=await xe(e)}catch{}let a;if(r.local){o&&!(r.local.name in(o.config.dependencies??{}))&&(console.error(`--replace: '${r.local.name}' is not a dependency in this bulb's config.json; nothing to replace.`),process.exit(1)),o&&r.subcommand!=="call"&&(!o.bulb.code||r.server)&&console.warn("warning: --replace has no effect in server mode (the override is client-only).");try{a=await pu(r.local)}catch(c){console.error(c instanceof Error?c.message:String(c)),process.exit(1)}console.error(`replace: ${a.name} \u2192 ${Vt.relative(process.cwd(),a.dir)||"."}`)}if(r.subcommand==="check"){await $g(e,a);return}if(r.subcommand==="call"){wy(r.trust,s),await yy(e,{fn:r.fn,positional:r.callArgs,argsJson:r.argsJson,hasArgsFlag:r.hasArgsFlag},r.mode,a,r.dir);return}if(o&&o.bulb.server&&(Qs(o.bulb)||r.server)){wy(r.trust,s),await my(e,r.watch,r.mode,a,r.dir);return}await cy(e,r,s,a)}EP().catch(r=>{console.error("Error:",r.message),process.exit(1)});
package/dist/servers.js CHANGED
@@ -137,7 +137,7 @@ ${t.comment}`:t.comment}this.doc.range[2]=t.offset;break}default:this.errors.pus
137
137
  `)+1;for(;t!==0;)this.onNewLine(this.offset+t),t=this.source.indexOf(`
138
138
  `,t)+1}yield*this.pop();break;default:yield*this.pop(),yield*this.step()}}*blockMap(e){let t=e.items[e.items.length-1];switch(this.type){case"newline":if(this.onKeyLine=!1,t.value){let s="end"in t.value?t.value.end:void 0;(Array.isArray(s)?s[s.length-1]:void 0)?.type==="comment"?s?.push(this.sourceToken):e.items.push({start:[this.sourceToken]})}else t.sep?t.sep.push(this.sourceToken):t.start.push(this.sourceToken);return;case"space":case"comment":if(t.value)e.items.push({start:[this.sourceToken]});else if(t.sep)t.sep.push(this.sourceToken);else{if(this.atIndentedComment(t.start,e.indent)){let r=e.items[e.items.length-2]?.value?.end;if(Array.isArray(r)){Array.prototype.push.apply(r,t.start),r.push(this.sourceToken),e.items.pop();return}}t.start.push(this.sourceToken)}return}if(this.indent>=e.indent){let s=!this.onKeyLine&&this.indent===e.indent,r=s&&(t.sep||t.explicitKey)&&this.type!=="seq-item-ind",i=[];if(r&&t.sep&&!t.value){let o=[];for(let a=0;a<t.sep.length;++a){let l=t.sep[a];switch(l.type){case"newline":o.push(a);break;case"space":break;case"comment":l.indent>e.indent&&(o.length=0);break;default:o.length=0}}o.length>=2&&(i=t.sep.splice(o[1]))}switch(this.type){case"anchor":case"tag":r||t.value?(i.push(this.sourceToken),e.items.push({start:i}),this.onKeyLine=!0):t.sep?t.sep.push(this.sourceToken):t.start.push(this.sourceToken);return;case"explicit-key-ind":!t.sep&&!t.explicitKey?(t.start.push(this.sourceToken),t.explicitKey=!0):r||t.value?(i.push(this.sourceToken),e.items.push({start:i,explicitKey:!0})):this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken],explicitKey:!0}]}),this.onKeyLine=!0;return;case"map-value-ind":if(t.explicitKey)if(t.sep)if(t.value)e.items.push({start:[],key:null,sep:[this.sourceToken]});else if(oe(t.sep,"map-value-ind"))this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:i,key:null,sep:[this.sourceToken]}]});else if(ia(t.key)&&!oe(t.sep,"newline")){let o=Te(t.start),a=t.key,l=t.sep;l.push(this.sourceToken),delete t.key,delete t.sep,this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:o,key:a,sep:l}]})}else i.length>0?t.sep=t.sep.concat(i,this.sourceToken):t.sep.push(this.sourceToken);else if(oe(t.start,"newline"))Object.assign(t,{key:null,sep:[this.sourceToken]});else{let o=Te(t.start);this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:o,key:null,sep:[this.sourceToken]}]})}else t.sep?t.value||r?e.items.push({start:i,key:null,sep:[this.sourceToken]}):oe(t.sep,"map-value-ind")?this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:[],key:null,sep:[this.sourceToken]}]}):t.sep.push(this.sourceToken):Object.assign(t,{key:null,sep:[this.sourceToken]});this.onKeyLine=!0;return;case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":{let o=this.flowScalar(this.type);r||t.value?(e.items.push({start:i,key:o,sep:[]}),this.onKeyLine=!0):t.sep?this.stack.push(o):(Object.assign(t,{key:o,sep:[]}),this.onKeyLine=!0);return}default:{let o=this.startBlockValue(e);if(o){if(o.type==="block-seq"){if(!t.explicitKey&&t.sep&&!oe(t.sep,"newline")){yield*this.pop({type:"error",offset:this.offset,message:"Unexpected block-seq-ind on same line with key",source:this.source});return}}else s&&e.items.push({start:i});this.stack.push(o);return}}}}yield*this.pop(),yield*this.step()}*blockSequence(e){let t=e.items[e.items.length-1];switch(this.type){case"newline":if(t.value){let s="end"in t.value?t.value.end:void 0;(Array.isArray(s)?s[s.length-1]:void 0)?.type==="comment"?s?.push(this.sourceToken):e.items.push({start:[this.sourceToken]})}else t.start.push(this.sourceToken);return;case"space":case"comment":if(t.value)e.items.push({start:[this.sourceToken]});else{if(this.atIndentedComment(t.start,e.indent)){let r=e.items[e.items.length-2]?.value?.end;if(Array.isArray(r)){Array.prototype.push.apply(r,t.start),r.push(this.sourceToken),e.items.pop();return}}t.start.push(this.sourceToken)}return;case"anchor":case"tag":if(t.value||this.indent<=e.indent)break;t.start.push(this.sourceToken);return;case"seq-item-ind":if(this.indent!==e.indent)break;t.value||oe(t.start,"seq-item-ind")?e.items.push({start:[this.sourceToken]}):t.start.push(this.sourceToken);return}if(this.indent>e.indent){let s=this.startBlockValue(e);if(s){this.stack.push(s);return}}yield*this.pop(),yield*this.step()}*flowCollection(e){let t=e.items[e.items.length-1];if(this.type==="flow-error-end"){let s;do yield*this.pop(),s=this.peek(1);while(s?.type==="flow-collection")}else if(e.end.length===0){switch(this.type){case"comma":case"explicit-key-ind":!t||t.sep?e.items.push({start:[this.sourceToken]}):t.start.push(this.sourceToken);return;case"map-value-ind":!t||t.value?e.items.push({start:[],key:null,sep:[this.sourceToken]}):t.sep?t.sep.push(this.sourceToken):Object.assign(t,{key:null,sep:[this.sourceToken]});return;case"space":case"comment":case"newline":case"anchor":case"tag":!t||t.value?e.items.push({start:[this.sourceToken]}):t.sep?t.sep.push(this.sourceToken):t.start.push(this.sourceToken);return;case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":{let r=this.flowScalar(this.type);!t||t.value?e.items.push({start:[],key:r,sep:[]}):t.sep?this.stack.push(r):Object.assign(t,{key:r,sep:[]});return}case"flow-map-end":case"flow-seq-end":e.end.push(this.sourceToken);return}let s=this.startBlockValue(e);s?this.stack.push(s):(yield*this.pop(),yield*this.step())}else{let s=this.peek(2);if(s.type==="block-map"&&(this.type==="map-value-ind"&&s.indent===e.indent||this.type==="newline"&&!s.items[s.items.length-1].sep))yield*this.pop(),yield*this.step();else if(this.type==="map-value-ind"&&s.type!=="flow-collection"){let r=an(s),i=Te(r);ra(e);let o=e.end.splice(1,e.end.length);o.push(this.sourceToken);let a={type:"block-map",offset:e.offset,indent:e.indent,items:[{start:i,key:e,sep:o}]};this.onKeyLine=!0,this.stack[this.stack.length-1]=a}else yield*this.lineEnd(e)}}flowScalar(e){if(this.onNewLine){let t=this.source.indexOf(`
139
139
  `)+1;for(;t!==0;)this.onNewLine(this.offset+t),t=this.source.indexOf(`
140
- `,t)+1}return{type:e,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue(e){switch(this.type){case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return this.flowScalar(this.type);case"block-scalar-header":return{type:"block-scalar",offset:this.offset,indent:this.indent,props:[this.sourceToken],source:""};case"flow-map-start":case"flow-seq-start":return{type:"flow-collection",offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case"seq-item-ind":return{type:"block-seq",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case"explicit-key-ind":{this.onKeyLine=!0;let t=an(e),s=Te(t);return s.push(this.sourceToken),{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:s,explicitKey:!0}]}}case"map-value-ind":{this.onKeyLine=!0;let t=an(e),s=Te(t);return{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:s,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment(e,t){return this.type!=="comment"||this.indent<=t?!1:e.every(s=>s.type==="newline"||s.type==="space")}*documentEnd(e){this.type!=="doc-mode"&&(e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop()))}*lineEnd(e){switch(this.type){case"comma":case"doc-start":case"doc-end":case"flow-seq-end":case"flow-map-end":case"map-value-ind":yield*this.pop(),yield*this.step();break;case"newline":this.onKeyLine=!1;default:e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop())}}};oa.Parser=rr});var fa=g(ot=>{"use strict";var aa=Ys(),hd=ze(),it=et(),md=Kn(),gd=O(),yd=sr(),la=ir();function ca(n){let e=n.prettyErrors!==!1;return{lineCounter:n.lineCounter||e&&new yd.LineCounter||null,prettyErrors:e}}function bd(n,e={}){let{lineCounter:t,prettyErrors:s}=ca(e),r=new la.Parser(t?.addNewLine),i=new aa.Composer(e),o=Array.from(i.compose(r.parse(n)));if(s&&t)for(let a of o)a.errors.forEach(it.prettifyError(n,t)),a.warnings.forEach(it.prettifyError(n,t));return o.length>0?o:Object.assign([],{empty:!0},i.streamInfo())}function ua(n,e={}){let{lineCounter:t,prettyErrors:s}=ca(e),r=new la.Parser(t?.addNewLine),i=new aa.Composer(e),o=null;for(let a of i.compose(r.parse(n),!0,n.length))if(!o)o=a;else if(o.options.logLevel!=="silent"){o.errors.push(new it.YAMLParseError(a.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}return s&&t&&(o.errors.forEach(it.prettifyError(n,t)),o.warnings.forEach(it.prettifyError(n,t))),o}function wd(n,e,t){let s;typeof e=="function"?s=e:t===void 0&&e&&typeof e=="object"&&(t=e);let r=ua(n,t);if(!r)return null;if(r.warnings.forEach(i=>md.warn(r.options.logLevel,i)),r.errors.length>0){if(r.options.logLevel!=="silent")throw r.errors[0];r.errors=[]}return r.toJS(Object.assign({reviver:s},t))}function Sd(n,e,t){let s=null;if(typeof e=="function"||Array.isArray(e)?s=e:t===void 0&&e&&(t=e),typeof t=="string"&&(t=t.length),typeof t=="number"){let r=Math.round(t);t=r<1?void 0:r>8?{indent:8}:{indent:r}}if(n===void 0){let{keepUndefined:r}=t??e??{};if(!r)return}return gd.isDocument(n)&&!s?n.toString(t):new hd.Document(n,s,t).toString(t)}ot.parse=wd;ot.parseAllDocuments=bd;ot.parseDocument=ua;ot.stringify=Sd});var pa=g(E=>{"use strict";var vd=Ys(),kd=ze(),Ad=Os(),or=et(),Nd=qe(),ae=O(),Od=ne(),Ed=L(),Td=re(),Ld=ie(),Cd=rn(),Pd=tr(),Id=sr(),xd=ir(),ln=fa(),da=Pe();E.Composer=vd.Composer;E.Document=kd.Document;E.Schema=Ad.Schema;E.YAMLError=or.YAMLError;E.YAMLParseError=or.YAMLParseError;E.YAMLWarning=or.YAMLWarning;E.Alias=Nd.Alias;E.isAlias=ae.isAlias;E.isCollection=ae.isCollection;E.isDocument=ae.isDocument;E.isMap=ae.isMap;E.isNode=ae.isNode;E.isPair=ae.isPair;E.isScalar=ae.isScalar;E.isSeq=ae.isSeq;E.Pair=Od.Pair;E.Scalar=Ed.Scalar;E.YAMLMap=Td.YAMLMap;E.YAMLSeq=Ld.YAMLSeq;E.CST=Cd;E.Lexer=Pd.Lexer;E.LineCounter=Id.LineCounter;E.Parser=xd.Parser;E.parse=ln.parse;E.parseAllDocuments=ln.parseAllDocuments;E.parseDocument=ln.parseDocument;E.stringify=ln.stringify;E.visit=da.visit;E.visitAsync=da.visitAsync});import{spawn as hr}from"child_process";import{readdir as Ma,readFile as Ra,writeFile as Fp,unlink as Sn,mkdir as jp}from"fs/promises";import{mkdirSync as Kp,writeFileSync as Jp,appendFileSync as Yp,readFileSync as Ba}from"fs";import*as _ from"path";import{fileURLToPath as Da}from"url";import{realpathSync as $a}from"fs";import{join as wn,resolve as qa}from"path";import{homedir as _a}from"os";function ft(){let n=process.env.TYPEBULB_SERVERS_DIR;return n?wn(n,".."):wn(_a(),".typebulb")}function ge(){return process.env.TYPEBULB_SERVERS_DIR||wn(ft(),"servers")}function Q(n){let e=qa(n),t=e;try{t=$a.native(e)}catch{}return(process.platform==="win32"?t.toLowerCase():t).replace(/\\/g,"/")}function pr(n,e){let t=Q(n),s=Q(e);return t.startsWith(s.endsWith("/")?s:s+"/")?!t.includes("/node_modules/"):!1}function Fa(n){return _.join(ge(),`${n}.json`)}function kn(n){return _.join(ge(),`${n}.log`)}function ja(n){return _.join(ge(),`${n}.wait.json`)}function Ua(n,e=0){try{let t=Ba(kn(n)),s=e>=0&&e<=t.length?e:0;return{text:t.subarray(s).toString("utf8"),offset:t.length}}catch{return{text:"",offset:0}}}function Ka(n){try{return process.kill(n,0),!0}catch(e){return e.code==="EPERM"}}async function vn(n){await Sn(Fa(n)).catch(()=>{}),await Sn(kn(n)).catch(()=>{}),await Sn(ja(n)).catch(()=>{})}async function An(n){let e;try{e=await Ma(ge())}catch{return[]}let t=[];return await Promise.all(e.map(async r=>{if(!/^\d+\.json$/.test(r))return;let i=parseInt(r,10),o;try{o=JSON.parse(await Ra(_.join(ge(),r),"utf8"))}catch{await vn(i);return}o&&typeof o.pid=="number"&&Ka(o.pid)?t.push(o):await vn(i)})),(n?t.filter(r=>r.agent==null&&pr(r.file,n)):t).sort((r,i)=>r.startedAt-i.startedAt)}async function mr(n){try{process.kill(n,"SIGTERM")}catch{}await vn(n)}function gr(n,e){let t=Q(e);return n.filter(s=>s.agent==null&&s.pid!==process.pid&&Q(s.file)===t)}async function Ja(n){let e=gr(await An(),n);for(let t of e)await mr(t.pid);return e}var Ya=n=>new Promise(e=>setTimeout(e,n));function Va(n,e,t){(process.platform==="win32"?hr("cmd",["/c","start","","/b",n,...e],{cwd:t,stdio:"ignore",windowsHide:!0}):hr(n,e,{cwd:t,detached:!0,stdio:"ignore"})).unref()}function Wa(){return _.join(_.dirname(Da(import.meta.url)),"index.js")}function Ga(n,e={}){return{command:process.execPath,args:[Wa(),...e.trust?["--trust"]:[],n,...e.open===!1?["--no-open"]:[]]}}async function Ha(n,e,t,s){let r=await n();if(r)return r;Va(e.command,e.args,t);let i=Date.now()+2e4;for(;Date.now()<i;){await Ya(150);let o=await n();if(o)return o}throw new Error(`Launched ${s} but it did not register within 20s.`)}async function Qa(n,e={}){let t=e.cwd??process.cwd(),s=_.resolve(t,n);return await Ja(s),Ha(async()=>gr(await An(),s)[0],Ga(n,e),t,_.basename(n))}import{readdirSync as Md,readFileSync as Rd,statSync as Bd}from"fs";import{join as ma,basename as Dd}from"path";var J={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"}},z=["code","css","html","data","infer","insight","config","notes"];function yr(n){return z.find(e=>J[e].path===n)}var br="typebulb/v1";function wr(n){return!!n?.startsWith("typebulb")}function Nn(n){return/[:\n"']/.test(n)||n.startsWith(" ")||n.endsWith(" ")?`"${n.replace(/"/g,'\\"')}"`:n}function On(n){return n.startsWith('"')&&n.endsWith('"')?n.slice(1,-1).replace(/\\"/g,'"'):n.startsWith("'")&&n.endsWith("'")?n.slice(1,-1):n}var Sr=/^\*\*(.+)\*\*$/,En=/^(`{3,})(\w*)\s*$/,za=new Set(z.map(n=>J[n].path)),vr=n=>new RegExp(`^${n}\\s*$`);function Y(n){try{let e=n.split(`
140
+ `,t)+1}return{type:e,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue(e){switch(this.type){case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return this.flowScalar(this.type);case"block-scalar-header":return{type:"block-scalar",offset:this.offset,indent:this.indent,props:[this.sourceToken],source:""};case"flow-map-start":case"flow-seq-start":return{type:"flow-collection",offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case"seq-item-ind":return{type:"block-seq",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case"explicit-key-ind":{this.onKeyLine=!0;let t=an(e),s=Te(t);return s.push(this.sourceToken),{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:s,explicitKey:!0}]}}case"map-value-ind":{this.onKeyLine=!0;let t=an(e),s=Te(t);return{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:s,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment(e,t){return this.type!=="comment"||this.indent<=t?!1:e.every(s=>s.type==="newline"||s.type==="space")}*documentEnd(e){this.type!=="doc-mode"&&(e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop()))}*lineEnd(e){switch(this.type){case"comma":case"doc-start":case"doc-end":case"flow-seq-end":case"flow-map-end":case"map-value-ind":yield*this.pop(),yield*this.step();break;case"newline":this.onKeyLine=!1;default:e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop())}}};oa.Parser=rr});var fa=g(ot=>{"use strict";var aa=Ys(),hd=ze(),it=et(),md=Kn(),gd=O(),yd=sr(),la=ir();function ca(n){let e=n.prettyErrors!==!1;return{lineCounter:n.lineCounter||e&&new yd.LineCounter||null,prettyErrors:e}}function bd(n,e={}){let{lineCounter:t,prettyErrors:s}=ca(e),r=new la.Parser(t?.addNewLine),i=new aa.Composer(e),o=Array.from(i.compose(r.parse(n)));if(s&&t)for(let a of o)a.errors.forEach(it.prettifyError(n,t)),a.warnings.forEach(it.prettifyError(n,t));return o.length>0?o:Object.assign([],{empty:!0},i.streamInfo())}function ua(n,e={}){let{lineCounter:t,prettyErrors:s}=ca(e),r=new la.Parser(t?.addNewLine),i=new aa.Composer(e),o=null;for(let a of i.compose(r.parse(n),!0,n.length))if(!o)o=a;else if(o.options.logLevel!=="silent"){o.errors.push(new it.YAMLParseError(a.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}return s&&t&&(o.errors.forEach(it.prettifyError(n,t)),o.warnings.forEach(it.prettifyError(n,t))),o}function wd(n,e,t){let s;typeof e=="function"?s=e:t===void 0&&e&&typeof e=="object"&&(t=e);let r=ua(n,t);if(!r)return null;if(r.warnings.forEach(i=>md.warn(r.options.logLevel,i)),r.errors.length>0){if(r.options.logLevel!=="silent")throw r.errors[0];r.errors=[]}return r.toJS(Object.assign({reviver:s},t))}function Sd(n,e,t){let s=null;if(typeof e=="function"||Array.isArray(e)?s=e:t===void 0&&e&&(t=e),typeof t=="string"&&(t=t.length),typeof t=="number"){let r=Math.round(t);t=r<1?void 0:r>8?{indent:8}:{indent:r}}if(n===void 0){let{keepUndefined:r}=t??e??{};if(!r)return}return gd.isDocument(n)&&!s?n.toString(t):new hd.Document(n,s,t).toString(t)}ot.parse=wd;ot.parseAllDocuments=bd;ot.parseDocument=ua;ot.stringify=Sd});var pa=g(E=>{"use strict";var vd=Ys(),kd=ze(),Ad=Os(),or=et(),Nd=qe(),ae=O(),Od=ne(),Ed=L(),Td=re(),Ld=ie(),Cd=rn(),Pd=tr(),Id=sr(),xd=ir(),ln=fa(),da=Pe();E.Composer=vd.Composer;E.Document=kd.Document;E.Schema=Ad.Schema;E.YAMLError=or.YAMLError;E.YAMLParseError=or.YAMLParseError;E.YAMLWarning=or.YAMLWarning;E.Alias=Nd.Alias;E.isAlias=ae.isAlias;E.isCollection=ae.isCollection;E.isDocument=ae.isDocument;E.isMap=ae.isMap;E.isNode=ae.isNode;E.isPair=ae.isPair;E.isScalar=ae.isScalar;E.isSeq=ae.isSeq;E.Pair=Od.Pair;E.Scalar=Ed.Scalar;E.YAMLMap=Td.YAMLMap;E.YAMLSeq=Ld.YAMLSeq;E.CST=Cd;E.Lexer=Pd.Lexer;E.LineCounter=Id.LineCounter;E.Parser=xd.Parser;E.parse=ln.parse;E.parseAllDocuments=ln.parseAllDocuments;E.parseDocument=ln.parseDocument;E.stringify=ln.stringify;E.visit=da.visit;E.visitAsync=da.visitAsync});import{spawn as hr}from"child_process";import{readdir as Ma,readFile as Ra,writeFile as Fp,unlink as Sn,mkdir as jp}from"fs/promises";import{mkdirSync as Kp,writeFileSync as Jp,appendFileSync as Yp,readFileSync as Ba}from"fs";import*as _ from"path";import{fileURLToPath as Da}from"url";import{realpathSync as $a}from"fs";import{join as wn,resolve as qa}from"path";import{homedir as _a}from"os";function ft(){let n=process.env.TYPEBULB_SERVERS_DIR;return n?wn(n,".."):wn(_a(),".typebulb")}function ge(){return process.env.TYPEBULB_SERVERS_DIR||wn(ft(),"servers")}function Q(n){let e=qa(n),t=e;try{t=$a.native(e)}catch{}return(process.platform==="win32"?t.toLowerCase():t).replace(/\\/g,"/")}function pr(n,e){let t=Q(n),s=Q(e);return t.startsWith(s.endsWith("/")?s:s+"/")?!t.includes("/node_modules/"):!1}function Fa(n){return _.join(ge(),`${n}.json`)}function kn(n){return _.join(ge(),`${n}.log`)}function ja(n){return _.join(ge(),`${n}.wait.json`)}function Ua(n,e=0){try{let t=Ba(kn(n)),s=e>=0&&e<=t.length?e:0;return{text:t.subarray(s).toString("utf8"),offset:t.length}}catch{return{text:"",offset:0}}}function Ka(n){try{return process.kill(n,0),!0}catch(e){return e.code==="EPERM"}}async function vn(n){await Sn(Fa(n)).catch(()=>{}),await Sn(kn(n)).catch(()=>{}),await Sn(ja(n)).catch(()=>{})}async function An(n){let e;try{e=await Ma(ge())}catch{return[]}let t=[];return await Promise.all(e.map(async r=>{if(!/^\d+\.json$/.test(r))return;let i=parseInt(r,10),o;try{o=JSON.parse(await Ra(_.join(ge(),r),"utf8"))}catch{await vn(i);return}o&&typeof o.pid=="number"&&Ka(o.pid)?t.push(o):await vn(i)})),(n?t.filter(r=>r.agent==null&&pr(r.file,n)):t).sort((r,i)=>r.startedAt-i.startedAt)}async function mr(n){try{process.kill(n,"SIGTERM")}catch{}await vn(n)}function gr(n,e){let t=Q(e);return n.filter(s=>s.agent==null&&s.pid!==process.pid&&Q(s.file)===t)}async function Ja(n){let e=gr(await An(),n);for(let t of e)await mr(t.pid);return e}var Ya=n=>new Promise(e=>setTimeout(e,n));function Va(n,e,t){(process.platform==="win32"?hr("cmd",["/c","start","","/b",n,...e],{cwd:t,stdio:"ignore",windowsHide:!0}):hr(n,e,{cwd:t,detached:!0,stdio:"ignore"})).unref()}function Wa(){return _.join(_.dirname(Da(import.meta.url)),"index.js")}function Ga(n,e={}){return{command:process.execPath,args:[Wa(),...e.trust?["--trust"]:[],...e.dir?["--dir",e.dir]:[],...e.mode?["--mode",e.mode]:[],n,...e.open===!1?["--no-open"]:[]]}}async function Ha(n,e,t,s){let r=await n();if(r)return r;Va(e.command,e.args,t);let i=Date.now()+2e4;for(;Date.now()<i;){await Ya(150);let o=await n();if(o)return o}throw new Error(`Launched ${s} but it did not register within 20s.`)}async function Qa(n,e={}){let t=e.cwd??process.cwd(),s=_.resolve(t,n),[r]=await Ja(s),i={...e,dir:e.dir??r?.dir,mode:e.mode??r?.mode};return Ha(async()=>gr(await An(),s)[0],Ga(n,i),t,_.basename(n))}import{readdirSync as Md,readFileSync as Rd,statSync as Bd}from"fs";import{join as ma,basename as Dd}from"path";var J={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"}},z=["code","css","html","data","infer","insight","config","notes"];function yr(n){return z.find(e=>J[e].path===n)}var br="typebulb/v1";function wr(n){return!!n?.startsWith("typebulb")}function Nn(n){return/[:\n"']/.test(n)||n.startsWith(" ")||n.endsWith(" ")?`"${n.replace(/"/g,'\\"')}"`:n}function On(n){return n.startsWith('"')&&n.endsWith('"')?n.slice(1,-1).replace(/\\"/g,'"'):n.startsWith("'")&&n.endsWith("'")?n.slice(1,-1):n}var Sr=/^\*\*(.+)\*\*$/,En=/^(`{3,})(\w*)\s*$/,za=new Set(z.map(n=>J[n].path)),vr=n=>new RegExp(`^${n}\\s*$`);function Y(n){try{let e=n.split(`
141
141
  `),t=0;if(e[t]?.trim()!=="---")return null;t++;let s=[];for(;t<e.length&&e[t]?.trim()!=="---";)s.push(e[t]),t++;if(e[t]?.trim()!=="---")return null;t++;let r=el(s);if(!r)return null;let i=new Map,o=[],a=t;for(;t<e.length;){let c=e[t]?.trim()?.match(Sr);if(c){let p=c[1].trim();for(t++;t<e.length&&e[t]?.trim()==="";)t++;let u=e[t]?.match(En);if(!u){o.push(`**${p}** has no code fence \u2014 block skipped`);continue}let f=u[1];t++;let m=[],y=vr(f);for(;t<e.length&&!e[t]?.match(y);)m.push(e[t]),t++;let d=t<e.length;t++,o.push(...Xa(p,m,d)),i.set(p,m.join(`
142
142
  `)),a=t}else t++}return{frontmatter:r,files:i,warnings:o,bodyEndLine:a}}catch{return null}}function Xa(n,e,t){let s=[];for(let r=0;r<e.length;r++){let i=e[r]?.trim().match(Sr);i&&za.has(i[1].trim())&&Za(e,r)&&s.push(i[1].trim())}return s.length?s.map(r=>`**${n}** block has an unterminated code fence \u2014 it swallowed the **${r}** block.`):t?[]:[`**${n}** block has an unterminated code fence (it runs to the end of the file).`]}function Za(n,e){let t=e+1;for(;t<n.length&&n[t]?.trim()==="";)t++;return!!n[t]?.match(En)}function el(n){let e={};for(let t of n){let s=t.indexOf(":");if(s===-1)continue;let r=t.slice(0,s).trim(),i=t.slice(s+1).trim();switch(r){case"format":e.format=i;break;case"name":e.name=On(i);break}}return!wr(e.format)||!e.name?null:e}function kr(n){let e=Object.fromEntries(z.map(t=>[t,n.files.get(J[t].path)||""]));return{name:n.frontmatter.name,...e}}function tl(n){let e=n.match(/^`{3,}/gm),t=e?Math.max(...e.map(s=>s.length)):0;return"`".repeat(Math.max(3,t+1))}function nl(n,e){let{path:t}=J[n],s=t.split(".").pop(),r=tl(e);return`**${t}**
143
143
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typebulb",
3
- "version": "0.29.2",
3
+ "version": "0.30.0",
4
4
  "description": "Typebulb CLI to run single-file markdown apps called bulbs, either as standalone web apps or embedded in agent responses.",
5
5
  "license": "MIT",
6
6
  "repository": {