typebulb 0.10.0 → 0.10.2

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/servers.d.ts CHANGED
@@ -7,6 +7,8 @@ export interface BulbServer {
7
7
  url: string
8
8
  /** Absolute path to the .bulb.md being served. */
9
9
  file: string
10
+ /** The cwd the server was launched in (the project it belongs to). */
11
+ cwd?: string
10
12
  /** Epoch ms the server began listening. */
11
13
  startedAt: number
12
14
  /** Launched with --trust (filesystem / AI / server.ts enabled)? */
@@ -72,6 +74,6 @@ export declare function setBulbTrusted(file: string, trust: boolean): void
72
74
  /** Every remembered-trusted bulb path (absolute, normalized). */
73
75
  export declare function listTrustedBulbs(): string[]
74
76
 
75
- /** Open `filePath` (optionally at `line`) in the user's editor, detached. Resolves
76
- * TYPEBULB_EDITOR / VISUAL / EDITOR, defaulting to VS Code; fire-and-forget. */
77
+ /** Open `filePath` (optionally at `line`) in the user's editor, detached. Defaults to VS Code
78
+ * (`code`); override with `TYPEBULB_EDITOR`. Fire-and-forget. */
77
79
  export declare function openInEditor(filePath: string, line?: number): void
package/dist/servers.js CHANGED
@@ -1,3 +1,3 @@
1
- import{spawn as _}from"child_process";import{readdir as I,readFile as $,writeFile as xt,unlink as f,mkdir as Bt}from"fs/promises";import{mkdirSync as Ft,writeFileSync as Et,appendFileSync as jt,readFileSync as N}from"fs";import*as o from"path";import{fileURLToPath as O}from"url";import{join as y,resolve as D}from"path";import{homedir as L}from"os";function m(){let r=process.env.TYPEBULB_SERVERS_DIR;return r?y(r,".."):y(L(),".typebulb")}function l(){return process.env.TYPEBULB_SERVERS_DIR||y(m(),"servers")}function c(r){let t=D(r);return(process.platform==="win32"?t.toLowerCase():t).replace(/\\/g,"/")}function x(r,t){let e=c(r),n=c(t);return e.startsWith(n.endsWith("/")?n:n+"/")?!e.includes("/node_modules/"):!1}function R(r){return o.join(l(),`${r}.json`)}function d(r){return o.join(l(),`${r}.log`)}function k(r,t=0){try{let e=N(d(r)),n=t>=0&&t<=e.length?t:0;return{text:e.subarray(n).toString("utf8"),offset:e.length}}catch{return{text:"",offset:0}}}function A(r){try{return process.kill(r,0),!0}catch(t){return t.code==="EPERM"}}async function W(r){await f(R(r)).catch(()=>{}),await f(d(r)).catch(()=>{})}async function v(r){let t;try{t=await I(l())}catch{return[]}let e=[];return await Promise.all(t.map(async s=>{if(!s.endsWith(".json"))return;let i=o.join(l(),s),a;try{a=JSON.parse(await $(i,"utf8"))}catch{await f(i).catch(()=>{});return}a&&typeof a.pid=="number"&&A(a.pid)?e.push(a):(await f(i).catch(()=>{}),a?.pid&&await f(d(a.pid)).catch(()=>{}))})),(r?e.filter(s=>x(s.file,r)):e).sort((s,i)=>s.startedAt-i.startedAt)}async function J(r){try{process.kill(r,"SIGTERM")}catch{}await W(r)}var M=r=>new Promise(t=>setTimeout(t,r));function C(){return o.join(o.dirname(O(import.meta.url)),"index.js")}function U(r,t={}){return{command:process.execPath,args:[C(),...t.trust?["--trust"]:[],r,...t.open===!1?["--no-open"]:[]]}}async function K(r,t={}){let e=t.cwd??process.cwd(),n=o.resolve(e,r),s=(await v()).find(u=>u.file===n);if(s)return s;let{command:i,args:a}=U(r,t);_(i,a,{cwd:e,detached:!0,stdio:"ignore",windowsHide:!0}).unref();let b=Date.now()+2e4;for(;Date.now()<b;){await M(150);let u=(await v()).find(h=>h.file===n);if(u)return u}throw new Error(`Launched ${o.basename(r)} but it did not register within 20s.`)}import{readdirSync as z,readFileSync as H,statSync as G}from"fs";import{join as B,basename as q}from"path";function p(r){let t=/^---[^\n]*\n([\s\S]*?)\n---/.exec(r),e=t?/^\s*name:\s*(.+?)\s*$/m.exec(t[1]):null;return e?e[1].replace(/^["']|["']$/g,""):void 0}function Y(r){return(p(r)??"bulb").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"bulb"}function V(r){return r.replace(/^---[^\n]*\r?\n[\s\S]*?\r?\n---[^\n]*\r?\n?/,"").replace(/^\r?\n+/,"")}function P(r,t,e){if(t>8)return e;let n;try{n=z(r,{withFileTypes:!0})}catch{return e}for(let s of n)if(s.isDirectory()){if(s.name.startsWith(".")||s.name==="node_modules")continue;P(B(r,s.name),t+1,e)}else s.isFile()&&s.name.endsWith(".bulb.md")&&e.push(B(r,s.name));return e}function Q(r){return P(r,0,[]).map(t=>{let e=0;try{e=G(t).mtimeMs}catch{}let n;try{n=p(H(t,"utf8").slice(0,1024))}catch{}return{path:t,name:n??q(t).replace(/\.bulb\.md$/,""),mtime:e}})}import{readFile as rt}from"fs/promises";var X={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 F(r){try{let t=r.split(`
2
- `),e=0;if(t[e]?.trim()!=="---")return null;e++;let n=[];for(;e<t.length&&t[e]?.trim()!=="---";)n.push(t[e]),e++;if(t[e]?.trim()!=="---")return null;e++;let s=Z(n);if(!s)return null;let i=new Map;for(;e<t.length;){let g=t[e]?.trim()?.match(/^\*\*(.+)\*\*$/);if(g){let b=g[1].trim();for(e++;e<t.length&&t[e]?.trim()==="";)e++;let u=t[e]?.match(/^(`{3,})(\w*)\s*$/);if(!u){e++;continue}let h=u[1];e++;let S=[];for(;e<t.length&&!t[e]?.match(new RegExp(`^${h}\\s*$`));)S.push(t[e]),e++;e++,i.set(b,S.join(`
3
- `))}else e++}return{frontmatter:s,files:i}}catch{return null}}function Z(r){let t={};for(let e of r){let n=e.indexOf(":");if(n===-1)continue;let s=e.slice(0,n).trim(),i=e.slice(n+1).trim();switch(s){case"format":t.format=i;break;case"name":t.name=tt(i);break}}return!t.format?.startsWith("typebulb")||!t.name?null:t}function tt(r){return r.startsWith('"')&&r.endsWith('"')?r.slice(1,-1).replace(/\\"/g,'"'):r.startsWith("'")&&r.endsWith("'")?r.slice(1,-1):r}function E(r){let t=e=>r.files.get(X[e].path)||"";return{name:r.frontmatter.name,code:t("code"),css:t("css"),html:t("html"),config:t("config"),notes:t("notes"),data:t("data"),infer:t("infer"),insight:t("insight"),server:t("server")}}function j(r){if(r.server.trim())return"server-side code (server.ts)";let t=r.code;if(/\btb\s*\.\s*fs\b/.test(t)||t.includes("/__fs"))return"the filesystem";if(/\btb\s*\.\s*ai\b/.test(t)||t.includes("/__ai"))return"AI (your API keys)";if(/\btb\s*\.\s*server\s*\.\s*(?!log\b)\w/.test(t)||t.includes("/__api"))return"server-side code (server.ts)"}async function et(r){try{let t=F(await rt(r,"utf-8"));return t?j(E(t)):void 0}catch{return}}import{spawn as nt}from"child_process";import{basename as st}from"path";function it(){return process.env.TYPEBULB_EDITOR||process.env.VISUAL||process.env.EDITOR||"code"}var ot=/^(code|code-insiders|codium|vscodium|cursor|windsurf)(\.cmd|\.exe)?$/i;function at(r,t,e){return e==null?[t]:ot.test(st(r))?["-g",`${t}:${e}`]:[`+${e}`,t]}function ut(r,t){let e=it(),n=nt(e,at(e,r,t),{shell:!0,detached:!0,stdio:"ignore"});n.on("error",s=>console.error("[typebulb] editor launch failed:",s?.message??s)),n.unref()}import{readFileSync as ct,writeFileSync as lt,mkdirSync as ft}from"fs";import{join as mt}from"path";function T(){return mt(m(),"trust.json")}function w(){try{let r=JSON.parse(ct(T(),"utf8"));return new Set(Array.isArray(r)?r:[])}catch{return new Set}}function dt(r){ft(m(),{recursive:!0}),lt(T(),JSON.stringify([...r]))}function pt(r){return w().has(c(r))}function gt(r,t){let e=w(),n=c(r);(t?e.has(n):!e.has(n))||(t?e.add(n):e.delete(n),dt(e))}function bt(){return[...w()]}export{p as bulbName,pt as isBulbTrusted,K as launchBulbServer,Q as listBulbFiles,v as listBulbServers,bt as listTrustedBulbs,ut as openInEditor,et as predictBulbTrust,k as readServerLog,d as serverLogPath,gt as setBulbTrusted,Y as slugifyBulbName,J as stopBulbServer,V as stripFrontmatter};
1
+ import{spawn as P}from"child_process";import{readdir as R,readFile as $,writeFile as jt,unlink as m,mkdir as Lt}from"fs/promises";import{mkdirSync as _t,writeFileSync as Dt,appendFileSync as Nt,readFileSync as C}from"fs";import*as a from"path";import{fileURLToPath as A}from"url";import{join as y,resolve as N}from"path";import{homedir as I}from"os";function d(){let e=process.env.TYPEBULB_SERVERS_DIR;return e?y(e,".."):y(I(),".typebulb")}function l(){return process.env.TYPEBULB_SERVERS_DIR||y(d(),"servers")}function c(e){let t=N(e);return(process.platform==="win32"?t.toLowerCase():t).replace(/\\/g,"/")}function F(e,t){let r=c(e),n=c(t);return r.startsWith(n.endsWith("/")?n:n+"/")?!r.includes("/node_modules/"):!1}import*as f from"path";var O={claude:{file:"claude.bulb.md",srcEnv:"TYPEBULB_CLAUDE_SRC",viewer:!0}};function p(e){let t=f.basename(e).toLowerCase();return Object.values(O).some(r=>r.file.toLowerCase()===t)}function k(e){return a.join(l(),`${e}.json`)}function g(e){return a.join(l(),`${e}.log`)}function U(e,t=0){try{let r=C(g(e)),n=t>=0&&t<=r.length?t:0;return{text:r.subarray(n).toString("utf8"),offset:r.length}}catch{return{text:"",offset:0}}}function W(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}async function J(e){await m(k(e)).catch(()=>{}),await m(g(e)).catch(()=>{})}async function x(e){let t;try{t=await R(l())}catch{return[]}let r=[];return await Promise.all(t.map(async i=>{if(!i.endsWith(".json"))return;let s=a.join(l(),i),o;try{o=JSON.parse(await $(s,"utf8"))}catch{await m(s).catch(()=>{});return}o&&typeof o.pid=="number"&&W(o.pid)?r.push(o):(await m(s).catch(()=>{}),o?.pid&&await m(g(o.pid)).catch(()=>{}))})),(e?r.filter(i=>F(i.file,e)&&!p(i.file)):r).sort((i,s)=>i.startedAt-s.startedAt)}async function M(e){try{process.kill(e,"SIGTERM")}catch{}await J(e)}var Y=e=>new Promise(t=>setTimeout(t,e));function K(){return a.join(a.dirname(A(import.meta.url)),"index.js")}function z(e,t={}){return{command:process.execPath,args:[K(),...t.trust?["--trust"]:[],e,...t.open===!1?["--no-open"]:[]]}}async function H(e,t={}){let r=t.cwd??process.cwd(),n=a.resolve(r,e),i=(await x()).find(u=>u.file===n);if(i)return i;let{command:s,args:o}=z(e,t);(process.platform==="win32"?P("cmd",["/c","start","","/b",s,...o],{cwd:r,stdio:"ignore",windowsHide:!0}):P(s,o,{cwd:r,detached:!0,stdio:"ignore"})).unref();let v=Date.now()+2e4;for(;Date.now()<v;){await Y(150);let u=(await x()).find(w=>w.file===n);if(u)return u}throw new Error(`Launched ${a.basename(e)} but it did not register within 20s.`)}import{readdirSync as q,readFileSync as Q,statSync as X}from"fs";import{join as E,basename as Z}from"path";function b(e){let t=/^---[^\n]*\n([\s\S]*?)\n---/.exec(e),r=t?/^\s*name:\s*(.+?)\s*$/m.exec(t[1]):null;return r?r[1].replace(/^["']|["']$/g,""):void 0}function V(e){return(b(e)??"bulb").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"bulb"}function G(e){return e.replace(/^---[^\n]*\r?\n[\s\S]*?\r?\n---[^\n]*\r?\n?/,"").replace(/^\r?\n+/,"")}function j(e,t,r){if(t>8)return r;let n;try{n=q(e,{withFileTypes:!0})}catch{return r}for(let i of n)if(i.isDirectory()){if(i.name.startsWith(".")||i.name==="node_modules")continue;j(E(e,i.name),t+1,r)}else if(i.isFile()&&i.name.endsWith(".bulb.md")){if(p(i.name))continue;r.push(E(e,i.name))}return r}function tt(e){return j(e,0,[]).map(t=>{let r=0;try{r=X(t).mtimeMs}catch{}let n;try{n=b(Q(t,"utf8").slice(0,1024))}catch{}return{path:t,name:n??Z(t).replace(/\.bulb\.md$/,""),mtime:r}})}import{readFile as it}from"fs/promises";var et={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 L(e){try{let t=e.split(`
2
+ `),r=0;if(t[r]?.trim()!=="---")return null;r++;let n=[];for(;r<t.length&&t[r]?.trim()!=="---";)n.push(t[r]),r++;if(t[r]?.trim()!=="---")return null;r++;let i=rt(n);if(!i)return null;let s=new Map;for(;r<t.length;){let h=t[r]?.trim()?.match(/^\*\*(.+)\*\*$/);if(h){let v=h[1].trim();for(r++;r<t.length&&t[r]?.trim()==="";)r++;let u=t[r]?.match(/^(`{3,})(\w*)\s*$/);if(!u){r++;continue}let w=u[1];r++;let S=[];for(;r<t.length&&!t[r]?.match(new RegExp(`^${w}\\s*$`));)S.push(t[r]),r++;r++,s.set(v,S.join(`
3
+ `))}else r++}return{frontmatter:i,files:s}}catch{return null}}function rt(e){let t={};for(let r of e){let n=r.indexOf(":");if(n===-1)continue;let i=r.slice(0,n).trim(),s=r.slice(n+1).trim();switch(i){case"format":t.format=s;break;case"name":t.name=nt(s);break}}return!t.format?.startsWith("typebulb")||!t.name?null:t}function nt(e){return e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1).replace(/\\"/g,'"'):e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function T(e){let t=r=>e.files.get(et[r].path)||"";return{name:e.frontmatter.name,code:t("code"),css:t("css"),html:t("html"),config:t("config"),notes:t("notes"),data:t("data"),infer:t("infer"),insight:t("insight"),server:t("server")}}function _(e){if(e.server.trim())return"server-side code (server.ts)";let t=e.code;if(/\btb\s*\.\s*fs\b/.test(t)||t.includes("/__fs"))return"the filesystem";if(/\btb\s*\.\s*ai\b/.test(t)||t.includes("/__ai"))return"AI (your API keys)";if(/\btb\s*\.\s*server\s*\.\s*(?!log\b)\w/.test(t)||t.includes("/__api"))return"server-side code (server.ts)"}async function st(e){try{let t=L(await it(e,"utf-8"));return t?_(T(t)):void 0}catch{return}}import{spawn as ot}from"child_process";import{basename as at}from"path";function ut(){return process.env.TYPEBULB_EDITOR||"code"}var ct=/^(code|code-insiders|codium|vscodium|cursor|windsurf)(\.cmd|\.exe)?$/i;function lt(e,t,r){return r==null?[t]:ct.test(at(e))?["-g",`${t}:${r}`]:[`+${r}`,t]}function ft(e,t){let r=ut();return{command:r,args:lt(r,e,t)}}function mt(e,t){let{command:r,args:n}=ft(e,t),i=ot(r,n,{shell:!0,detached:!0,stdio:"ignore"});i.on("error",s=>console.error("[typebulb] editor launch failed:",s?.message??s)),i.unref()}import{readFileSync as dt,writeFileSync as pt,mkdirSync as gt}from"fs";import{join as bt}from"path";function D(){return bt(d(),"trust.json")}function B(){try{let e=JSON.parse(dt(D(),"utf8"));return new Set(Array.isArray(e)?e:[])}catch{return new Set}}function ht(e){gt(d(),{recursive:!0}),pt(D(),JSON.stringify([...e]))}function vt(e){return B().has(c(e))}function wt(e,t){let r=B(),n=c(e);(t?r.has(n):!r.has(n))||(t?r.add(n):r.delete(n),ht(r))}function yt(){return[...B()]}export{b as bulbName,vt as isBulbTrusted,H as launchBulbServer,tt as listBulbFiles,x as listBulbServers,yt as listTrustedBulbs,mt as openInEditor,st as predictBulbTrust,U as readServerLog,g as serverLogPath,wt as setBulbTrusted,V as slugifyBulbName,M as stopBulbServer,G as stripFrontmatter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typebulb",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "description": "Local bulb runner CLI for Typebulb",
5
5
  "license": "MIT",
6
6
  "engines": { "node": ">=18" },
@@ -23,7 +23,8 @@
23
23
  }
24
24
  },
25
25
  "files": [
26
- "dist"
26
+ "dist",
27
+ "bulbs/*.bulb.md"
27
28
  ],
28
29
  "scripts": {
29
30
  "typecheck": "tsc --build",