typebulb 0.9.2 → 0.9.3

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
@@ -9,15 +9,57 @@ export interface BulbServer {
9
9
  file: string
10
10
  /** Epoch ms the server began listening. */
11
11
  startedAt: number
12
+ /** Launched with --trust (filesystem / AI / server.ts enabled)? */
13
+ trust?: boolean
14
+ /** Human label of a privileged capability this untrusted server denied (set by the gate). */
15
+ denied?: string
12
16
  }
13
17
 
14
18
  /** Launch (or re-attach to) a standalone `typebulb` dev server for `file`. Idempotent
15
19
  * per file: a live server already serving it is returned, not re-spawned. Always silent
16
- * (no console window); detached so it outlives the caller. */
17
- export declare function launchBulbServer(file: string, opts?: { cwd?: string; open?: boolean }): Promise<BulbServer>
20
+ * (no console window); detached so it outlives the caller. `trust` passes --trust. */
21
+ export declare function launchBulbServer(file: string, opts?: { cwd?: string; open?: boolean; trust?: boolean }): Promise<BulbServer>
18
22
 
19
23
  /** Every live dev server, oldest first. Dead entries are pruned on read. */
20
24
  export declare function listBulbServers(): Promise<BulbServer[]>
21
25
 
22
26
  /** Stop a server by pid (SIGTERM + deregister). Idempotent. */
23
27
  export declare function stopBulbServer(pid: number): Promise<void>
28
+
29
+ /** New console bytes of a server (its `<pid>.log`) since `offset`; returns the text and
30
+ * the new offset. A trim past the cap resyncs from 0. Absent file ⇒ empty. */
31
+ export declare function readServerLog(pid: number, offset?: number): { text: string; offset: number }
32
+
33
+ /** Absolute path of a server's console log, sibling of its registry entry. */
34
+ export declare function serverLogPath(pid: number): string
35
+
36
+ export interface BulbFileInfo {
37
+ /** Absolute path to the .bulb.md. */
38
+ path: string
39
+ /** The bulb's `name:` frontmatter title, or the filename stem when unnamed. */
40
+ name: string
41
+ /** File mtime (epoch ms); 0 if it vanished mid-walk. */
42
+ mtime: number
43
+ }
44
+
45
+ /** Every `*.bulb.md` under `cwd` (dot-dirs and node_modules skipped, depth-bounded),
46
+ * each with its frontmatter name (or filename stem) and mtime. */
47
+ export declare function listBulbFiles(cwd: string): BulbFileInfo[]
48
+
49
+ /** The bulb's `name:` from its leading frontmatter, or undefined if absent. */
50
+ export declare function bulbName(source: string): string | undefined
51
+
52
+ /** A filesystem-safe slug from the bulb's name; 'bulb' when unnamed. */
53
+ export declare function slugifyBulbName(source: string): string
54
+
55
+ /** The source with its leading `---` frontmatter block stripped. */
56
+ export declare function stripFrontmatter(source: string): string
57
+
58
+ /** Is this bulb remembered as Trusted in the CLI's per-machine trust store? */
59
+ export declare function isBulbTrusted(file: string): boolean
60
+
61
+ /** Set or clear a bulb's remembered trust (written only by user/agent action, never bulb code). */
62
+ export declare function setBulbTrusted(file: string, trust: boolean): void
63
+
64
+ /** Every remembered-trusted bulb path (absolute, normalized). */
65
+ export declare function listTrustedBulbs(): string[]
package/dist/servers.js CHANGED
@@ -1 +1 @@
1
- import{spawn as l}from"child_process";import{readdir as f,readFile as w,writeFile as j,unlink as a,mkdir as R}from"fs/promises";import*as o from"path";import*as d from"os";function u(){return process.env.TYPEBULB_SERVERS_DIR||o.join(d.homedir(),".typebulb","servers")}function v(r){return o.join(u(),`${r}.json`)}function h(r){try{return process.kill(r,0),!0}catch(e){return e.code==="EPERM"}}async function S(r){await a(v(r)).catch(()=>{})}async function c(){let r;try{r=await f(u())}catch{return[]}let e=[];return await Promise.all(r.map(async t=>{if(!t.endsWith(".json"))return;let n=o.join(u(),t),i;try{i=JSON.parse(await w(n,"utf8"))}catch{await a(n).catch(()=>{});return}i&&typeof i.pid=="number"&&h(i.pid)?e.push(i):await a(n).catch(()=>{})})),e.sort((t,n)=>t.startedAt-n.startedAt)}async function y(r){try{process.kill(r,"SIGTERM")}catch{}await S(r)}var g=r=>new Promise(e=>setTimeout(e,r));async function B(r,e={}){let t=e.cwd??process.cwd(),n=o.resolve(t,r),i=(await c()).find(s=>s.file===n);if(i)return i;let p=["typebulb",r,...e.open===!1?["--no-open"]:[]];(process.platform==="win32"?l("cmd",["/c","start","","/b","npx",...p],{cwd:t,stdio:"ignore",windowsHide:!0}):l("npx",p,{cwd:t,detached:!0,stdio:"ignore"})).unref();let b=Date.now()+2e4;for(;Date.now()<b;){await g(150);let s=(await c()).find(m=>m.file===n);if(s)return s}throw new Error(`Launched ${o.basename(r)} but it did not register within 20s.`)}export{B as launchBulbServer,c as listBulbServers,y as stopBulbServer};
1
+ import{spawn as y}from"child_process";import{readdir as F,readFile as E,writeFile as tr,unlink as a,mkdir as nr}from"fs/promises";import{mkdirSync as sr,writeFileSync as or,appendFileSync as ar,readFileSync as L}from"fs";import*as s from"path";import{join as f,resolve as x}from"path";import{homedir as P}from"os";function c(){let r=process.env.TYPEBULB_SERVERS_DIR;return r?f(r,".."):f(P(),".typebulb")}function o(){return process.env.TYPEBULB_SERVERS_DIR||f(c(),"servers")}function m(r){let e=x(r);return(process.platform==="win32"?e.toLowerCase():e).replace(/\\/g,"/")}function N(r){return s.join(o(),`${r}.json`)}function l(r){return s.join(o(),`${r}.log`)}function T(r,e=0){try{let t=L(l(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 D(r){try{return process.kill(r,0),!0}catch(e){return e.code==="EPERM"}}async function j(r){await a(N(r)).catch(()=>{}),await a(l(r)).catch(()=>{})}async function d(){let r;try{r=await F(o())}catch{return[]}let e=[];return await Promise.all(r.map(async t=>{if(!t.endsWith(".json"))return;let n=s.join(o(),t),i;try{i=JSON.parse(await E(n,"utf8"))}catch{await a(n).catch(()=>{});return}i&&typeof i.pid=="number"&&D(i.pid)?e.push(i):(await a(n).catch(()=>{}),i?.pid&&await a(l(i.pid)).catch(()=>{}))})),e.sort((t,n)=>t.startedAt-n.startedAt)}async function _(r){try{process.kill(r,"SIGTERM")}catch{}await j(r)}var A=r=>new Promise(e=>setTimeout(e,r));async function O(r,e={}){let t=e.cwd??process.cwd(),n=s.resolve(t,r),i=(await d()).find(u=>u.file===n);if(i)return i;let g=["typebulb",...e.trust?["--trust"]:[],r,...e.open===!1?["--no-open"]:[]];(process.platform==="win32"?y("cmd",["/c","start","","/b","npx",...g],{cwd:t,stdio:"ignore",windowsHide:!0}):y("npx",g,{cwd:t,detached:!0,stdio:"ignore"})).unref();let h=Date.now()+2e4;for(;Date.now()<h;){await A(150);let u=(await d()).find(B=>B.file===n);if(u)return u}throw new Error(`Launched ${s.basename(r)} but it did not register within 20s.`)}import{readdirSync as $,readFileSync as k,statSync as I}from"fs";import{join as w,basename as M}from"path";function p(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 R(r){return(p(r)??"bulb").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"bulb"}function J(r){return r.replace(/^---[^\n]*\r?\n[\s\S]*?\r?\n---[^\n]*\r?\n?/,"").replace(/^\r?\n+/,"")}function S(r,e,t){if(e>8)return t;let n;try{n=$(r,{withFileTypes:!0})}catch{return t}for(let i of n)if(i.isDirectory()){if(i.name.startsWith(".")||i.name==="node_modules")continue;S(w(r,i.name),e+1,t)}else i.isFile()&&i.name.endsWith(".bulb.md")&&t.push(w(r,i.name));return t}function z(r){return S(r,0,[]).map(e=>{let t=0;try{t=I(e).mtimeMs}catch{}let n;try{n=p(k(e,"utf8").slice(0,1024))}catch{}return{path:e,name:n??M(e).replace(/\.bulb\.md$/,""),mtime:t}})}import{readFileSync as C,writeFileSync as H,mkdirSync as U}from"fs";import{join as W}from"path";function v(){return W(c(),"trust.json")}function b(){try{let r=JSON.parse(C(v(),"utf8"));return new Set(Array.isArray(r)?r:[])}catch{return new Set}}function G(r){U(c(),{recursive:!0}),H(v(),JSON.stringify([...r]))}function V(r){return b().has(m(r))}function Y(r,e){let t=b(),n=m(r);(e?t.has(n):!t.has(n))||(e?t.add(n):t.delete(n),G(t))}function q(){return[...b()]}export{p as bulbName,V as isBulbTrusted,O as launchBulbServer,z as listBulbFiles,d as listBulbServers,q as listTrustedBulbs,T as readServerLog,l as serverLogPath,Y as setBulbTrusted,R as slugifyBulbName,_ as stopBulbServer,J as stripFrontmatter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typebulb",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "description": "Local bulb runner CLI for Typebulb",
5
5
  "license": "MIT",
6
6
  "engines": { "node": ">=18" },