typebulb 0.14.1 → 0.14.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.
Files changed (3) hide show
  1. package/README.md +99 -94
  2. package/dist/index.js +2 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -25,14 +25,60 @@ A `.bulb.md` file bundles code, styles, data, and config in one file.
25
25
  - **Package resolution** — Client dependencies are automatically resolved by generating import maps (same resolver as typebulb.com). Server dependencies are automatically installed via npm.
26
26
  - **Replace dependency** — `--replace <name>=<path>` replaces a declared dependency with a local *built* package folder (browser-ready ESM, no external bare imports) instead of a CDN, for testing an unpublished build. Supplies both runtime bytes and types; applies to `run` and `check`. Under `--watch` the folder is watched and the browser reloads on rebuild (`--no-watch` freezes it). Dev-only; nothing is written to the bulb.
27
27
  - **Local caching** — Resolver metadata and CDN package bytes are cached under `~/.typebulb/cache/`, so repeat runs don't re-hit the network and warm runs work offline.
28
- - **AI calls** — `tb.ai()` for general-purpose AI (chatbots, agents, experiments). `tb.models()` lists available models. Set API keys in `.env` (see below). Requires `--trust`.
28
+ - **`tb.ai()`** a bulb's own code calling AI providers at runtime (chatbots, agents, experiments). `tb.models()` lists available models. Set API keys in `.env` (see below). Requires `--trust`.
29
29
  - **Restricted by default** — A plain `npx typebulb my-app.bulb.md` runs with no filesystem or `server.ts` (like typebulb.com); `--trust` grants those for a run. Trust is **remembered**: `typebulb trust <file>` elevates a bulb once so later plain runs are trusted, `untrust` revokes it, and `--no-trust` forces a Restricted run.
30
30
  - **Predict trust** — `typebulb predict <file>` reports the capability a bulb will likely need (fs / AI / `server.ts`) without running it, so you can decide on `--trust` up front rather than after a mid-run permission failure.
31
31
  - **Agent mirror** — a browser view of your project's Claude Code sessions that renders embedded bulbs, KaTeX, and mermaid live inline, plus runs/stops local bulbs (see [Claude](#claude)). `typebulb agent:claude` opens it. `typebulb agent` (no target) is the first command an agent runs: it brings up the mirror without opening a browser, prints its link, and points at the authoring skill. `typebulb skill` prints this whole README as an Agent Skill the agent can read and save.
32
32
 
33
- ## Quick Start
33
+ ## Usage
34
+
35
+ ```
36
+ typebulb [file.bulb.md] Run a bulb (defaults to .bulb.md in cwd)
37
+ typebulb agent:claude Open the agent mirror of your project's Claude Code sessions
38
+ typebulb agent An agent's first command — brings up the agent mirror,
39
+ prints its URL + the authoring-skill paths; always exits 0
40
+ typebulb skill Print this README as an Agent Skill on stdout
41
+ typebulb call <file> <fn> […] Invoke one server.ts export headlessly: prints its return as JSON to stdout, logs/errors to stderr (needs --trust)
42
+ typebulb check [file.bulb.md] Type-check a bulb without running it
43
+ typebulb predict [file] Report the capability a bulb probably needs, without running it
44
+ typebulb models List AI models for tb.ai, filtered by your .env API keys
45
+ typebulb logs [file|pid] Print a running bulb's captured console (no arg: list running servers; -f follow, -n N tail)
46
+ typebulb wait [file|agent] Block until the target server logs a new line, print it, exit — an agent's wake-up
47
+ (--match <substr> filters; --timeout <sec>, default 1800, exit 2)
48
+ typebulb stop [file|pid] Stop a running bulb (no arg: list this project's running servers)
49
+ typebulb stop --bulbs Stop this project's bulbs; the agent mirror keeps running
50
+ typebulb stop --agent Stop this project's agent mirror; its bulbs keep running
51
+ typebulb stop --global Stop every running bulb and mirror, all projects (housekeeping)
52
+ typebulb trust [file] Remember a bulb as trusted (no arg: list trusted bulbs)
53
+ typebulb untrust <file> Forget a bulb's trust (back to Restricted)
54
+ typebulb --no-watch <file> Disable hot reload
55
+ typebulb --port 3333 <file> Custom port
56
+ typebulb --no-open <file> Don't auto-open browser
57
+ typebulb --mode <name> <file> Also load .env.<name> on top of .env / .env.local
58
+ typebulb --trust <file> Grant filesystem + AI + server.ts for this run (default: Restricted)
59
+ typebulb --no-trust <file> Force Restricted even if the bulb is remembered-trusted
60
+ typebulb --server <file> Run server.ts only, no web server (needs --trust)
61
+ typebulb --replace <name>=<path> Replace a dependency with a local build
62
+ typebulb --help Show help
63
+ typebulb --version Show version
64
+ ```
65
+
66
+ ## Bulb Format
67
+
68
+ A bulb is a single **markdown** file — the minimum viable structure for a small app. Its named **blocks** hold the code, plus optional styles, data, and config. Every block except `code.tsx` is optional. Mechanically, each block is a `**name**` header on its own line followed by a fenced code block, and the file opens with YAML frontmatter (`format: typebulb/v1`, `name:`).
69
+
70
+ | Block | Purpose |
71
+ |-------|---------|
72
+ | `**code.tsx**` | **Required.** App logic and UI (TypeScript/TSX). |
73
+ | `**index.html**` | The mount container. Include it — nearly every bulb does (e.g. `<div id="root"></div>`). Only pure console apps omit it. |
74
+ | `**styles.css**` | CSS. |
75
+ | `**config.json**` | `dependencies` and a `description`. |
76
+ | `**data.txt**` | Read-only data your code processes via `tb.data(n)` (raw string) / `tb.json(n)` (parsed) — JSON, CSV, XML, YAML, or plain text. Multiple chunks are separated by **two blank lines**. |
77
+ | `**infer.md**` / `**insight.json**` | Runtime one-shot LLM call via `tb.infer()` — a typebulb.com feature; not supported locally. |
78
+ | `**notes.md**` | Persistent context for the AI assistant, carried across conversations and clones. Not run. |
79
+ | `**server.ts**` | Node.js code; its exports become `tb.server.<name>()` in the browser. Plain Node — no `tb`; log with `console.log`. **Local only.** |
34
80
 
35
- A bulb is a markdown file with named code blocks:
81
+ ### Example
36
82
 
37
83
  ````markdown
38
84
  ---
@@ -114,96 +160,6 @@ Or install globally:
114
160
  npm install -g typebulb
115
161
  ```
116
162
 
117
- ## Usage
118
-
119
- ```
120
- typebulb [file.bulb.md] Run a bulb (defaults to .bulb.md in cwd)
121
- typebulb agent:claude Open the agent mirror of your project's Claude Code sessions
122
- typebulb agent An agent's first command — brings up the agent mirror,
123
- prints its URL + the authoring-skill paths; always exits 0
124
- typebulb skill Print this README as an Agent Skill on stdout
125
- typebulb call <file> <fn> […] Invoke one server.ts export headlessly: prints its return as JSON to stdout, logs/errors to stderr (needs --trust)
126
- typebulb check [file.bulb.md] Type-check a bulb without running it
127
- typebulb predict [file] Report the capability a bulb probably needs, without running it
128
- typebulb models List AI models for tb.ai, filtered by your .env API keys
129
- typebulb logs [file|pid] Print a running bulb's captured console (no arg: list running servers; -f follow, -n N tail)
130
- typebulb wait [file|agent] Block until the target server logs a new line, print it, exit — an agent's wake-up
131
- (--match <substr> filters; --timeout <sec>, default 1800, exit 2)
132
- typebulb stop [file|pid] Stop a running bulb (no arg: list this project's running servers)
133
- typebulb stop --bulbs Stop this project's bulbs; the agent mirror keeps running
134
- typebulb stop --agent Stop this project's agent mirror; its bulbs keep running
135
- typebulb stop --global Stop every running bulb and mirror, all projects (housekeeping)
136
- typebulb trust [file] Remember a bulb as trusted (no arg: list trusted bulbs)
137
- typebulb untrust <file> Forget a bulb's trust (back to Restricted)
138
- typebulb --no-watch <file> Disable hot reload
139
- typebulb --port 3333 <file> Custom port
140
- typebulb --no-open <file> Don't auto-open browser
141
- typebulb --mode <name> <file> Also load .env.<name> on top of .env / .env.local
142
- typebulb --trust <file> Grant filesystem + AI + server.ts for this run (default: Restricted)
143
- typebulb --no-trust <file> Force Restricted even if the bulb is remembered-trusted
144
- typebulb --server <file> Run server.ts only, no web server (needs --trust)
145
- typebulb --replace <name>=<path> Replace a dependency with a local build
146
- typebulb --help Show help
147
- typebulb --version Show version
148
- ```
149
-
150
- ## AI API Setup
151
-
152
- Bulbs can call AI providers via `tb.ai()`. Add API keys to your `.env` file:
153
-
154
- | Provider name | API key env var |
155
- |---------------|-----------------|
156
- | `anthropic` | `ANTHROPIC_API_KEY` |
157
- | `openai` | `OPENAI_API_KEY` |
158
- | `gemini` | `GOOGLE_API_KEY` |
159
- | `openrouter` | `OPENROUTER_API_KEY` |
160
-
161
- Set your default provider and model:
162
-
163
- ```
164
- TB_AI_PROVIDER=anthropic
165
- TB_AI_MODEL=claude-haiku-4-5-20251001
166
- ```
167
-
168
- Both can be overridden per-call: `tb.ai({ provider: "gemini", model: "gemini-3.1-flash-lite", ... })`.
169
-
170
- Run `typebulb models` to list the available model ids instead of guessing one.
171
-
172
- ### Reasoning
173
-
174
- `tb.ai()` accepts an optional `reasoning` parameter (0–3) that hints at how much extended thinking the model should use:
175
-
176
- | Level | Label | Effect |
177
- |-------|-------|--------|
178
- | 0 | Min | No extended reasoning (default) |
179
- | 1 | Low | Light reasoning |
180
- | 2 | Med | Moderate reasoning |
181
- | 3 | Max | Maximum reasoning |
182
-
183
- ```typescript
184
- const { text } = await tb.ai({
185
- messages: [{ role: "user", content: "Explain quantum tunneling" }],
186
- reasoning: 2,
187
- });
188
- ```
189
-
190
- Provider support varies — the level is mapped to provider-specific parameters (e.g. Anthropic's adaptive thinking, OpenAI's reasoning effort).
191
-
192
- ## Blocks
193
-
194
- A bulb is a single **markdown** file — the minimum viable structure for a small app. Its named **blocks** hold the code, plus optional styles, data, and config. Every block except `code.tsx` is optional. Mechanically, each block is a `**name**` header on its own line followed by a fenced code block, and the file opens with YAML frontmatter (`format: typebulb/v1`, `name:`).
195
-
196
- | Block | Purpose |
197
- |-------|---------|
198
- | `**code.tsx**` | **Required.** App logic and UI (TypeScript/TSX). |
199
- | `**index.html**` | The mount container. Include it — nearly every bulb does (e.g. `<div id="root"></div>`). Only pure console apps omit it. |
200
- | `**styles.css**` | CSS. |
201
- | `**config.json**` | `dependencies` and a `description`. |
202
- | `**data.txt**` | Read-only data your code processes via `tb.data(n)` (raw string) / `tb.json(n)` (parsed) — JSON, CSV, XML, YAML, or plain text. Multiple chunks are separated by **two blank lines**. |
203
- | `**infer.md**` / `**insight.json**` | Runtime one-shot LLM call via `tb.infer()` — a typebulb.com feature; not supported locally. |
204
- | `**notes.md**` | Persistent context for the AI assistant, carried across conversations and clones. Not run. |
205
- | `**server.ts**` | Node.js code; its exports become `tb.server.<name>()` in the browser. Plain Node — no `tb`; log with `console.log`. **Local only.** |
206
-
207
163
  ## The `tb.*` API, by target
208
164
 
209
165
  `tb` is a pre-declared global your code can use without importing. What each call does, and where it works:
@@ -273,6 +229,14 @@ The host owns a bulb's **width**; you own its **height**.
273
229
  .wrap { margin: 0 auto; padding: 24px 16px; } /* not: margin: 24px auto */
274
230
  ```
275
231
 
232
+ ## Wake-on-event
233
+
234
+ `typebulb wait` turns a background task into a subscription. It blocks until the target server logs a new line (`--match <substr>` filters), prints it, and exits — and since an agent harness re-invokes the agent when a background task finishes, the exit *is* the wake-up. It resumes where your last `wait` or `call` on that target left off, so an event that lands while you're acting — or before the wait attaches — still fires it immediately; arm order doesn't matter. Exit `2` is the timeout (default 30 min): nothing happened, re-arm or stand down. Exit `3` means the server died.
235
+
236
+ **The turn-based loop** (a game, an approval flow): a bulb whose `server.ts` does `console.log` on each user action is the event channel. Per turn — act via `typebulb call`, arm `wait <file> --match <tag>` in the background, end your turn; on wake, read state with `typebulb call <file> <getState>` (never parse it from the log line) and repeat. A bulb's uncaught browser errors land in the same log as `[runtime error] …`, so the wake channel also catches your bulb breaking. For embeds, the same subscription is `typebulb wait claude` on the mirror — see [Emitting an embedded bulb](#emitting-an-embedded-bulb).
237
+
238
+ **Keep every loop command argument-stable.** A harness that permission-matches exact command strings prompts the user on *every* event if varying data (a move, a payload) rides the command line. Keep it off: write the args to a fixed file and pipe them — `cat <bulb-folder>/args.json | typebulb call <file> <fn> --args -` — so each of the loop's commands is one constant string, approved once. `wait` and a `getState` call are constant already.
239
+
276
240
  ## Tips for Agents
277
241
 
278
242
  - **`config.json` `description`** is the bulb's SEO meta description — keep it to one or two plain sentences (~150–160 chars), or it gets truncated.
@@ -280,7 +244,6 @@ The host owns a bulb's **width**; you own its **height**.
280
244
  - **Self-testing a local bulb** — To confirm a bulb works, run it, instrument with `tb.server.log(...)` (prints to the server's stdout, captured in the log — and works **even on a Restricted bulb**), and read it back with `typebulb logs`. That's the loop to verify behaviour without asking the user to copy-paste console output. `tb.fs.write(...)` is handy for dumping large outputs.
281
245
  - **A bulb's working files live in a folder named after the bulb.** Whether written by `server.ts` or `tb.fs.write`, favor a sibling folder matching the bulb's slug.
282
246
  - **Testing a `server.ts` export directly** — `typebulb call <file> <fn> [arg…]` boots `server.ts`, invokes one export, and prints its return as JSON to stdout (logs/errors to stderr, so `… | jq` works). Args after `<fn>` are JSON-or-string; `--args '<json-array>'` (or `--args -` for stdin) escapes tricky quoting. Needs `--trust`.
283
- - **Waking on a user's action** — a bulb whose `server.ts` does `console.log` on an event (a chess move, a form submit) is a wake-up channel: `typebulb wait <file> --match <tag>` exits when the line lands. `wait` resumes where your last `wait` or `call` on that target left off, so an event that lands while you're acting (or before the wait attaches) still fires it immediately — arm order doesn't matter. On wake, read state with `typebulb call <file> <getState>` (never parse it from the log line), act, re-arm. Uncaught browser errors land in the same log as `[runtime error] …`.
284
247
  - **Mount to the container your `index.html` declares.** The corpus convention is `<div id="root"></div>` with `createRoot(document.getElementById("root")!)`.
285
248
  - **All imports at the top of `code.tsx`.** Bare imports (`react`, `d3`, `three`, …) auto-resolve from a CDN — no install step. Declare them in `config.json` `dependencies` anyway: that's what lets `npx typebulb check` fetch type defs (without it you get errors like `TS2875: react/jsx-runtime`) and pins versions.
286
249
  - **Theme-aware styling.** Style off CSS variables / `currentColor` so the bulb reads correctly in both light and dark; the host sets the theme.
@@ -345,6 +308,48 @@ Which must be declared in the dependencies section:
345
308
 
346
309
  Typebulb has a package resolver that will load and cache these packages from `esm.sh` when the bulb runs.
347
310
 
311
+ ## `tb.ai()`
312
+
313
+ Trusted bulbs can call AI providers **from their own code** at runtime, billed to your API keys. Don't confuse this with the agent loop ([Wake-on-event](#wake-on-event)): there Claude drives a bulb from the chat session and *is* the intelligence — no provider, no key, and the bulb stays plain. `tb.ai()` is for bulbs that are themselves AI apps (chatbots, agents, experiments). Add API keys to your `.env` file:
314
+
315
+ | Provider name | API key env var |
316
+ |---------------|-----------------|
317
+ | `anthropic` | `ANTHROPIC_API_KEY` |
318
+ | `openai` | `OPENAI_API_KEY` |
319
+ | `gemini` | `GOOGLE_API_KEY` |
320
+ | `openrouter` | `OPENROUTER_API_KEY` |
321
+
322
+ Set your default provider and model:
323
+
324
+ ```
325
+ TB_AI_PROVIDER=anthropic
326
+ TB_AI_MODEL=claude-haiku-4-5-20251001
327
+ ```
328
+
329
+ Both can be overridden per-call: `tb.ai({ provider: "gemini", model: "gemini-3.1-flash-lite", ... })`.
330
+
331
+ Run `typebulb models` to list the available model ids instead of guessing one.
332
+
333
+ ### Reasoning
334
+
335
+ `tb.ai()` accepts an optional `reasoning` parameter (0–3) that hints at how much extended thinking the model should use:
336
+
337
+ | Level | Label | Effect |
338
+ |-------|-------|--------|
339
+ | 0 | Min | No extended reasoning (default) |
340
+ | 1 | Low | Light reasoning |
341
+ | 2 | Med | Moderate reasoning |
342
+ | 3 | High | Heavy reasoning |
343
+
344
+ ```typescript
345
+ const { text } = await tb.ai({
346
+ messages: [{ role: "user", content: "Explain quantum tunneling" }],
347
+ reasoning: 2,
348
+ });
349
+ ```
350
+
351
+ Provider support varies — the level is mapped to provider-specific parameters (e.g. Anthropic's adaptive thinking, OpenAI's reasoning effort).
352
+
348
353
  ## License
349
354
 
350
355
  MIT
package/dist/index.js CHANGED
@@ -254,7 +254,7 @@ AI API:
254
254
  TB_AI_MODEL=claude-haiku-4-5-20251001
255
255
  Both can be overridden per-call: tb.ai({ provider: "openai", model: "gpt-5.4-mini", ... })
256
256
  Don't guess a model id \u2014 run 'typebulb models' to list the exact ids your keys cover.
257
- Optional reasoning depth (0=min, 1=low, 2=med, 3=max):
257
+ Optional reasoning depth (0=min, 1=low, 2=med, 3=high):
258
258
  tb.ai({ ..., reasoning: 2 })
259
259
 
260
260
  Examples:
@@ -1084,6 +1084,6 @@ ${Aw}
1084
1084
  Shutting down...`),p.close(),y?.(),t(),await Tr(process.pid),process.exit(0)};process.on("SIGINT",k),process.on("SIGTERM",k)}import*as Id from"path";import{EventEmitter as xv}from"events";async function _d(r,e,t,s,n){let i=fe(t),o=!1,a=async()=>{let{bulb:c,config:l}=await ne(r);o||(Le(i,r,c.server),o=!0),await vr(c.server,n,s,l.dependencies)};if(console.log(`Running ${Id.basename(r)}...`),await a(),e){console.log(`Watching for changes...
1085
1085
  `);let c=new xv;c.on("reload",async()=>{try{console.log("Re-running..."),await a()}catch(l){console.error("Error:",l)}}),wn({bulbPath:r,emitter:c})}}import{Console as Ev}from"node:console";ye();Sr();async function Ld(r,e,t,s,n){Cv();try{let p=M(r),g=(await B()).find(h=>M(h.file)===p);g&&sn(g.pid,ue(g.pid).offset)}catch{}let i=fe(t),{bulb:o,config:a}=await ne(r);o.server||An("This bulb has no **server.ts** block; nothing to call."),Le(i,r,o.server);let c;try{c=await vr(o.server,n,s,a.dependencies)}catch(p){An(p instanceof Error?p.message:String(p))}let l=gn(c,e.fn);if(!l){let p=[...Object.keys(c).filter(g=>typeof c[g]=="function"),...Object.keys(ea)];An(`Function '${e.fn}' not found. Available: ${p.length?p.join(", "):"(none)"}.`)}let f=await Av(e),u;try{u=await l(...f)}catch(p){An(p instanceof Error?p.stack??p.message:String(p))}let d=Ov(u);d!==void 0&&await Rv(d+`
1086
1086
  `),process.exit(0)}async function Av(r){if(r.hasArgsFlag){let e=r.argsJson??"";return e==="-"&&(e=await Iv()),Pv(e)}return Tv(r.positional)}function Tv(r){return r.map(e=>{try{return JSON.parse(e)}catch{return e}})}function Pv(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 Ov(r){if(r!==void 0)return JSON.stringify(r,Nv,2)}function Nv(r,e){return typeof e=="bigint"?e.toString():e}function An(r){process.stderr.write(r+`
1087
- `),process.exit(1)}function Cv(){let r=new Ev(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 Rv(r){return new Promise((e,t)=>{process.stdout.write(r,s=>s?t(s):e())})}async function Iv(){let r=[];for await(let e of process.stdin)r.push(e);return Buffer.concat(r).toString("utf-8")}var $d="0.14.1";function Md(r,e){r||(console.error(`This bulb runs server-side Node code (server.ts), which --trust must authorize:
1087
+ `),process.exit(1)}function Cv(){let r=new Ev(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 Rv(r){return new Promise((e,t)=>{process.stdout.write(r,s=>s?t(s):e())})}async function Iv(){let r=[];for await(let e of process.stdin)r.push(e);return Buffer.concat(r).toString("utf-8")}var $d="0.14.2";function Md(r,e){r||(console.error(`This bulb runs server-side Node code (server.ts), which --trust must authorize:
1088
1088
  ${e}`),process.exit(1))}async function _v(){let r=Ea(process.argv.slice(2));if(r.version&&(console.log(`typebulb ${$d}`),process.exit(0)),r.help&&(Aa(),process.exit(0)),r.subcommand==="logs"){await jf(r.file||void 0,{follow:r.follow,lines:r.lines});return}if(r.subcommand==="wait"){await Uf(r.file||void 0,{match:r.match,timeoutSec:r.timeoutSec??1800});return}if(r.subcommand==="stop"){r.stopScope?await Kf(r.stopScope):await Jf(r.file||void 0);return}if(r.subcommand==="skill"){await Bf($d);return}if(r.subcommand==="models"){await Mf(r.mode);return}if(r.subcommand==="agent"){if(!r.agentTarget){await If();return}lf(r.agentTarget)||(console.error(`Unknown agent '${r.agentTarget}'. Known: ${xr().join(", ")}.`),process.exit(1));let l=await Wo(process.cwd(),r.agentTarget);if(l){console.log(`Mirror '${r.agentTarget}' is already running for this project:
1089
1089
  ${l.url}`),r.open&&await wt(l.url);return}await Rd(r);return}if(r.subcommand==="trust"||r.subcommand==="untrust"){await wf(r.file||void 0,r.subcommand==="trust");return}let e;if(!r.file||r.file==="."){let l=await nf(process.cwd());l||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=l}else e=we.resolve(r.file);await Dd.access(e).then(()=>!0,()=>!1)||(xr().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 s=r.file&&r.file!=="."?r.file:we.relative(process.cwd(),e)||we.basename(e),n=`npx typebulb --trust ${s.includes(" ")?`"${s}"`:s}`;if(r.subcommand==="predict"){await bf(e,n);return}let i=!r.noTrust&&We(e);i&&!r.trust&&console.log("trust: granted from memory (run `typebulb untrust` to revoke)"),r.trust=r.noTrust?!1:r.trust||i;let o;try{o=await ne(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 ka(r.local)}catch(l){console.error(l instanceof Error?l.message:String(l)),process.exit(1)}console.log(`replace: ${a.name} \u2192 ${we.relative(process.cwd(),a.dir)||"."}`)}if(r.subcommand==="check"){await yf(e,a);return}let c=we.dirname(e);if(r.subcommand==="call"){Md(r.trust,n),await Ld(e,{fn:r.fn,positional:r.callArgs,argsJson:r.argsJson,hasArgsFlag:r.hasArgsFlag},r.mode,a,c);return}if(o&&o.bulb.server&&(!o.bulb.code||r.server)){Md(r.trust,n),await _d(e,r.watch,r.mode,a,c);return}await ed(e,r,n,a,c)}_v().catch(r=>{console.error("Error:",r.message),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typebulb",
3
- "version": "0.14.1",
3
+ "version": "0.14.2",
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": {