typebulb 0.9.5 → 0.9.7

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
@@ -23,8 +23,9 @@ export interface BulbServer {
23
23
  * (no console window); detached so it outlives the caller. `trust` passes --trust. */
24
24
  export declare function launchBulbServer(file: string, opts?: { cwd?: string; open?: boolean; trust?: boolean }): Promise<BulbServer>
25
25
 
26
- /** Every live dev server, oldest first. Dead entries are pruned on read. */
27
- export declare function listBulbServers(): Promise<BulbServer[]>
26
+ /** Every live dev server, oldest first. Dead entries are pruned on read. Pass `cwd` to scope the
27
+ * list to that project's bulbs (the machine-global default is for explicit pid/file targeting). */
28
+ export declare function listBulbServers(cwd?: string): Promise<BulbServer[]>
28
29
 
29
30
  /** Stop a server by pid (SIGTERM + deregister). Idempotent. */
30
31
  export declare function stopBulbServer(pid: number): Promise<void>
package/dist/servers.js CHANGED
@@ -1,3 +1,3 @@
1
- import{spawn as v}from"child_process";import{readdir as L,readFile as N,writeFile as pt,unlink as c,mkdir as mt}from"fs/promises";import{mkdirSync as gt,writeFileSync as bt,appendFileSync as ht,readFileSync as k}from"fs";import*as o from"path";import{join as g,resolve as _}from"path";import{homedir as E}from"os";function p(){let e=process.env.TYPEBULB_SERVERS_DIR;return e?g(e,".."):g(E(),".typebulb")}function u(){return process.env.TYPEBULB_SERVERS_DIR||g(p(),"servers")}function b(e){let t=_(e);return(process.platform==="win32"?t.toLowerCase():t).replace(/\\/g,"/")}function $(e){return o.join(u(),`${e}.json`)}function m(e){return o.join(u(),`${e}.log`)}function O(e,t=0){try{let r=k(m(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 R(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}async function A(e){await c($(e)).catch(()=>{}),await c(m(e)).catch(()=>{})}async function h(){let e;try{e=await L(u())}catch{return[]}let t=[];return await Promise.all(e.map(async r=>{if(!r.endsWith(".json"))return;let n=o.join(u(),r),s;try{s=JSON.parse(await N(n,"utf8"))}catch{await c(n).catch(()=>{});return}s&&typeof s.pid=="number"&&R(s.pid)?t.push(s):(await c(n).catch(()=>{}),s?.pid&&await c(m(s.pid)).catch(()=>{}))})),t.sort((r,n)=>r.startedAt-n.startedAt)}async function I(e){try{process.kill(e,"SIGTERM")}catch{}await A(e)}var J=e=>new Promise(t=>setTimeout(t,e));async function M(e,t={}){let r=t.cwd??process.cwd(),n=o.resolve(r,e),s=(await h()).find(a=>a.file===n);if(s)return s;let i=["typebulb",...t.trust?["--trust"]:[],e,...t.open===!1?["--no-open"]:[]];(process.platform==="win32"?v("cmd",["/c","start","","/b","npx",...i],{cwd:r,stdio:"ignore",windowsHide:!0}):v("npx",i,{cwd:r,detached:!0,stdio:"ignore"})).unref();let l=Date.now()+2e4;for(;Date.now()<l;){await J(150);let a=(await h()).find(f=>f.file===n);if(a)return a}throw new Error(`Launched ${o.basename(e)} but it did not register within 20s.`)}import{readdirSync as K,readFileSync as z,statSync as H}from"fs";import{join as S,basename as U}from"path";function d(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 W(e){return(d(e)??"bulb").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"bulb"}function C(e){return e.replace(/^---[^\n]*\r?\n[\s\S]*?\r?\n---[^\n]*\r?\n?/,"").replace(/^\r?\n+/,"")}function x(e,t,r){if(t>8)return r;let n;try{n=K(e,{withFileTypes:!0})}catch{return r}for(let s of n)if(s.isDirectory()){if(s.name.startsWith(".")||s.name==="node_modules")continue;x(S(e,s.name),t+1,r)}else s.isFile()&&s.name.endsWith(".bulb.md")&&r.push(S(e,s.name));return r}function Y(e){return x(e,0,[]).map(t=>{let r=0;try{r=H(t).mtimeMs}catch{}let n;try{n=d(z(t,"utf8").slice(0,1024))}catch{}return{path:t,name:n??U(t).replace(/\.bulb\.md$/,""),mtime:r}})}import{readFile as Q}from"fs/promises";var G={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 B(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 s=V(n);if(!s)return null;let i=new Map;for(;r<t.length;){let l=t[r]?.trim()?.match(/^\*\*(.+)\*\*$/);if(l){let a=l[1].trim();for(r++;r<t.length&&t[r]?.trim()==="";)r++;let f=t[r]?.match(/^(`{3,})(\w*)\s*$/);if(!f){r++;continue}let T=f[1];r++;let w=[];for(;r<t.length&&!t[r]?.match(new RegExp(`^${T}\\s*$`));)w.push(t[r]),r++;r++,i.set(a,w.join(`
3
- `))}else r++}return{frontmatter:s,files:i}}catch{return null}}function V(e){let t={};for(let r of e){let n=r.indexOf(":");if(n===-1)continue;let s=r.slice(0,n).trim(),i=r.slice(n+1).trim();switch(s){case"format":t.format=i;break;case"name":t.name=q(i);break}}return!t.format?.startsWith("typebulb")||!t.name?null:t}function q(e){return e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1).replace(/\\"/g,'"'):e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function F(e){let t=r=>e.files.get(G[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 P(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 X(e){try{let t=B(await Q(e,"utf-8"));return t?P(F(t)):void 0}catch{return}}import{readFileSync as Z,writeFileSync as tt,mkdirSync as et}from"fs";import{join as rt}from"path";function j(){return rt(p(),"trust.json")}function y(){try{let e=JSON.parse(Z(j(),"utf8"));return new Set(Array.isArray(e)?e:[])}catch{return new Set}}function nt(e){et(p(),{recursive:!0}),tt(j(),JSON.stringify([...e]))}function st(e){return y().has(b(e))}function it(e,t){let r=y(),n=b(e);(t?r.has(n):!r.has(n))||(t?r.add(n):r.delete(n),nt(r))}function ot(){return[...y()]}export{d as bulbName,st as isBulbTrusted,M as launchBulbServer,Y as listBulbFiles,h as listBulbServers,ot as listTrustedBulbs,X as predictBulbTrust,O as readServerLog,m as serverLogPath,it as setBulbTrusted,W as slugifyBulbName,I as stopBulbServer,C as stripFrontmatter};
1
+ import{spawn as x}from"child_process";import{readdir as N,readFile as k,writeFile as mt,unlink as f,mkdir as dt}from"fs/promises";import{mkdirSync as bt,writeFileSync as ht,appendFileSync as yt,readFileSync as $}from"fs";import*as a from"path";import{join as h,resolve as E}from"path";import{homedir as L}from"os";function d(){let e=process.env.TYPEBULB_SERVERS_DIR;return e?h(e,".."):h(L(),".typebulb")}function l(){return process.env.TYPEBULB_SERVERS_DIR||h(d(),"servers")}function c(e){let t=E(e);return(process.platform==="win32"?t.toLowerCase():t).replace(/\\/g,"/")}function S(e,t){let r=c(e),n=c(t);return r.startsWith(n.endsWith("/")?n:n+"/")?!r.includes("/node_modules/"):!1}function O(e){return a.join(l(),`${e}.json`)}function g(e){return a.join(l(),`${e}.log`)}function R(e,t=0){try{let r=$(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 A(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}async function I(e){await f(O(e)).catch(()=>{}),await f(g(e)).catch(()=>{})}async function y(e){let t;try{t=await N(l())}catch{return[]}let r=[];return await Promise.all(t.map(async s=>{if(!s.endsWith(".json"))return;let i=a.join(l(),s),o;try{o=JSON.parse(await k(i,"utf8"))}catch{await f(i).catch(()=>{});return}o&&typeof o.pid=="number"&&A(o.pid)?r.push(o):(await f(i).catch(()=>{}),o?.pid&&await f(g(o.pid)).catch(()=>{}))})),(e?r.filter(s=>S(s.file,e)):r).sort((s,i)=>s.startedAt-i.startedAt)}async function W(e){try{process.kill(e,"SIGTERM")}catch{}await I(e)}var J=e=>new Promise(t=>setTimeout(t,e));async function M(e,t={}){let r=t.cwd??process.cwd(),n=a.resolve(r,e),s=(await y()).find(u=>u.file===n);if(s)return s;let i=["typebulb",...t.trust?["--trust"]:[],e,...t.open===!1?["--no-open"]:[]];(process.platform==="win32"?x("cmd",["/c","start","","/b","npx",...i],{cwd:r,stdio:"ignore",windowsHide:!0}):x("npx",i,{cwd:r,detached:!0,stdio:"ignore"})).unref();let p=Date.now()+2e4;for(;Date.now()<p;){await J(150);let u=(await y()).find(m=>m.file===n);if(u)return u}throw new Error(`Launched ${a.basename(e)} but it did not register within 20s.`)}import{readdirSync as U,readFileSync as z,statSync as H}from"fs";import{join as B,basename as Y}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 C(e){return(b(e)??"bulb").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"bulb"}function K(e){return e.replace(/^---[^\n]*\r?\n[\s\S]*?\r?\n---[^\n]*\r?\n?/,"").replace(/^\r?\n+/,"")}function P(e,t,r){if(t>8)return r;let n;try{n=U(e,{withFileTypes:!0})}catch{return r}for(let s of n)if(s.isDirectory()){if(s.name.startsWith(".")||s.name==="node_modules")continue;P(B(e,s.name),t+1,r)}else s.isFile()&&s.name.endsWith(".bulb.md")&&r.push(B(e,s.name));return r}function G(e){return P(e,0,[]).map(t=>{let r=0;try{r=H(t).mtimeMs}catch{}let n;try{n=b(z(t,"utf8").slice(0,1024))}catch{}return{path:t,name:n??Y(t).replace(/\.bulb\.md$/,""),mtime:r}})}import{readFile as X}from"fs/promises";var V={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(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 s=q(n);if(!s)return null;let i=new Map;for(;r<t.length;){let p=t[r]?.trim()?.match(/^\*\*(.+)\*\*$/);if(p){let u=p[1].trim();for(r++;r<t.length&&t[r]?.trim()==="";)r++;let m=t[r]?.match(/^(`{3,})(\w*)\s*$/);if(!m){r++;continue}let T=m[1];r++;let v=[];for(;r<t.length&&!t[r]?.match(new RegExp(`^${T}\\s*$`));)v.push(t[r]),r++;r++,i.set(u,v.join(`
3
+ `))}else r++}return{frontmatter:s,files:i}}catch{return null}}function q(e){let t={};for(let r of e){let n=r.indexOf(":");if(n===-1)continue;let s=r.slice(0,n).trim(),i=r.slice(n+1).trim();switch(s){case"format":t.format=i;break;case"name":t.name=Q(i);break}}return!t.format?.startsWith("typebulb")||!t.name?null:t}function Q(e){return e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1).replace(/\\"/g,'"'):e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function j(e){let t=r=>e.files.get(V[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 Z(e){try{let t=F(await X(e,"utf-8"));return t?_(j(t)):void 0}catch{return}}import{readFileSync as tt,writeFileSync as et,mkdirSync as rt}from"fs";import{join as nt}from"path";function D(){return nt(d(),"trust.json")}function w(){try{let e=JSON.parse(tt(D(),"utf8"));return new Set(Array.isArray(e)?e:[])}catch{return new Set}}function st(e){rt(d(),{recursive:!0}),et(D(),JSON.stringify([...e]))}function it(e){return w().has(c(e))}function ot(e,t){let r=w(),n=c(e);(t?r.has(n):!r.has(n))||(t?r.add(n):r.delete(n),st(r))}function at(){return[...w()]}export{b as bulbName,it as isBulbTrusted,M as launchBulbServer,G as listBulbFiles,y as listBulbServers,at as listTrustedBulbs,Z as predictBulbTrust,R as readServerLog,g as serverLogPath,ot as setBulbTrusted,C as slugifyBulbName,W as stopBulbServer,K as stripFrontmatter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typebulb",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "description": "Local bulb runner CLI for Typebulb",
5
5
  "license": "MIT",
6
6
  "engines": { "node": ">=18" },