typebulb 0.56.0 → 0.56.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/README.md +4 -3
- package/SKILL.md +6 -5
- package/dist/agents/claude/client.js +56 -45
- package/dist/agents/codex/client.js +55 -44
- package/dist/agents/pi/client.js +212 -201
- package/dist/index.js +247 -234
- package/dist/render.js +35 -24
- package/dist/resolver/semver.d.ts +2 -0
- package/dist/resolver/semver.d.ts.map +1 -1
- package/dist/resolver/semver.js +5 -1
- package/dist/resolver/semver.js.map +1 -1
- package/dist/resolver/versionResolver.d.ts.map +1 -1
- package/dist/resolver/versionResolver.js +6 -4
- package/dist/resolver/versionResolver.js.map +1 -1
- package/dist/servers.js +25 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,7 +67,8 @@ typebulb stop --global Stop every running bulb and mirror, all projects
|
|
|
67
67
|
typebulb trust [file] Remember a bulb as trusted (no arg: list trusted bulbs)
|
|
68
68
|
typebulb untrust <file> Forget a bulb's trust (back to Restricted)
|
|
69
69
|
typebulb --no-watch <file> Disable hot reload
|
|
70
|
-
typebulb --port 3333 <file> Bind this exact port (fails if taken)
|
|
70
|
+
typebulb --port 3333 <file> Bind this exact port (fails if taken). Rarely needed: a bulb keeps its port
|
|
71
|
+
across runs, and a different port strands the open tab
|
|
71
72
|
typebulb --no-open <file> Open nothing at launch, not even inside VS Code
|
|
72
73
|
typebulb --mode <name> <file> Also load .env.<name> on top of .env / .env.local
|
|
73
74
|
typebulb --batch <name> <file> Scope tb.dir + relative tb.fs paths to <bulb-folder>/batches/<name> (batch runs)
|
|
@@ -252,7 +253,7 @@ The agent mirror turns that block into a live, sandboxed app, with a *breakout
|
|
|
252
253
|
|
|
253
254
|
`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 (Claude Code and pi; Codex has no background wake — its recipe is the bounded foreground wait above, and this loop doesn't reach it). 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. It parks until the event. Exit `2` means it gave up before any event arrived (re-arm if you still care, or move on); exit `3` means the server died.
|
|
254
255
|
|
|
255
|
-
**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. **`call` always boots a fresh `server.ts` instance** — it never attaches to the running bulb's server — so any state shared between the page and your calls must live on disk (load/save it in each export), not in `server.ts` module memory. A bulb's uncaught browser errors land in the same log as `[runtime error] …`, so the wake channel also catches your bulb breaking. For inline bulbs, the same subscription is `typebulb wait agent` on the mirror — see [Emitting an inline bulb](#emitting-an-inline-bulb).
|
|
256
|
+
**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. **`call` always boots a fresh `server.ts` instance** — it never attaches to the running bulb's server — so any state shared between the page and your calls must live on disk (load/save it in each export), not in `server.ts` module memory. A bulb's uncaught browser errors land in the same log as `[runtime error] …`, so the wake channel also catches your bulb breaking. A page that closes mid-run logs `[page] disconnected` a few seconds later, so a wait on a page-driven run's completion tag pairs with a second `wait <file> --match "[page] disconnected"`: a run whose page is gone never completes. For inline bulbs, the same subscription is `typebulb wait agent` on the mirror — see [Emitting an inline bulb](#emitting-an-inline-bulb).
|
|
256
257
|
|
|
257
258
|
**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. `send` takes its message the same way (`typebulb send <file> -`), which is also how a large or quote-heavy payload avoids the shell. `wait` and a `getState` call are constant already.
|
|
258
259
|
|
|
@@ -265,7 +266,7 @@ The agent mirror turns that block into a live, sandboxed app, with a *breakout
|
|
|
265
266
|
|
|
266
267
|
That one launch *is* the loop: the server watches the file, so every save recompiles and reloads the page (`server.ts` included) — editing the file is the iteration.
|
|
267
268
|
|
|
268
|
-
- **Don't relaunch, and don't wrap it in the `timeout` command.** A relaunch replaces the running server (one per bulb file), reclaiming the same port so the open tab reloads itself — it costs the page's in-memory state and nothing else. The `timeout` command kills the server outright, and the racing relaunch is what spawns extra windows; your harness's own tool timeout does not kill it.
|
|
269
|
+
- **Don't relaunch, and don't wrap it in the `timeout` command.** A relaunch replaces the running server (one per bulb file), reclaiming the same port so the open tab reloads itself — it costs the page's in-memory state and nothing else. The `timeout` command kills the server outright, and the racing relaunch is what spawns extra windows; your harness's own tool timeout does not kill it. When you must relaunch, relaunch plainly: never `stop` first, and never pick a new `--port`. A relaunch replaces on its own, and either move strands the open tab (a stopped server's tab keeps retrying its port for 30 minutes and greets whatever lands there next).
|
|
269
270
|
- **What needs a restart:** a `.env` change (read once at boot) and in-memory `server.ts` state (reset on each reload).
|
|
270
271
|
- **Each reload re-runs the bulb.** A save re-executes `code.tsx` from scratch, so work you start on mount repeats every edit — re-spending GPU/network, re-firing side effects, flooding the log. Put expensive or side-effecting work behind a trigger: `tb.onMessage(() => start())`, then `typebulb send <file>` when ready (also a general terminal→page channel — pass params, drive a loop).
|
|
271
272
|
- **Reading the log:** it appends across every reload, so `typebulb logs --run latest <file>` shows just the current run (no need to clear).
|
package/SKILL.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: typebulb
|
|
3
3
|
description: "Author and run Typebulb bulbs — single-file markdown apps (TypeScript/TSX) that run locally via `npx typebulb` (full power: filesystem, database, `server.ts`, `tb.ai`) or render live inline in your coding agent's session through Typebulb's agent mirror (sandboxed, client-only). A bulb can be a visual widget (chart, simulation, diagram, calculator, UI), a full-stack tool with a Node backend, or an AI app that calls models at runtime. Covers the bulb format, the `tb.*` API, trust, and the local run/inline workflow. Use when the user wants a bulb, a quick local tool (visual, backend-backed, or AI-powered), or something visual rendered inline in the conversation."
|
|
4
|
-
version: 0.56.
|
|
4
|
+
version: 0.56.2
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
> Generated from typebulb v0.56.
|
|
7
|
+
> Generated from typebulb v0.56.2. `npx typebulb agent` prints the running version alongside the path to its packaged SKILL.md: if that version is newer than this one, replace this file with that one.
|
|
8
8
|
|
|
9
9
|
# typebulb
|
|
10
10
|
|
|
@@ -75,7 +75,8 @@ typebulb stop --global Stop every running bulb and mirror, all projects
|
|
|
75
75
|
typebulb trust [file] Remember a bulb as trusted (no arg: list trusted bulbs)
|
|
76
76
|
typebulb untrust <file> Forget a bulb's trust (back to Restricted)
|
|
77
77
|
typebulb --no-watch <file> Disable hot reload
|
|
78
|
-
typebulb --port 3333 <file> Bind this exact port (fails if taken)
|
|
78
|
+
typebulb --port 3333 <file> Bind this exact port (fails if taken). Rarely needed: a bulb keeps its port
|
|
79
|
+
across runs, and a different port strands the open tab
|
|
79
80
|
typebulb --no-open <file> Open nothing at launch, not even inside VS Code
|
|
80
81
|
typebulb --mode <name> <file> Also load .env.<name> on top of .env / .env.local
|
|
81
82
|
typebulb --batch <name> <file> Scope tb.dir + relative tb.fs paths to <bulb-folder>/batches/<name> (batch runs)
|
|
@@ -260,7 +261,7 @@ The agent mirror turns that block into a live, sandboxed app, with a *breakout
|
|
|
260
261
|
|
|
261
262
|
`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 (Claude Code and pi; Codex has no background wake — its recipe is the bounded foreground wait above, and this loop doesn't reach it). 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. It parks until the event. Exit `2` means it gave up before any event arrived (re-arm if you still care, or move on); exit `3` means the server died.
|
|
262
263
|
|
|
263
|
-
**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. **`call` always boots a fresh `server.ts` instance** — it never attaches to the running bulb's server — so any state shared between the page and your calls must live on disk (load/save it in each export), not in `server.ts` module memory. A bulb's uncaught browser errors land in the same log as `[runtime error] …`, so the wake channel also catches your bulb breaking. For inline bulbs, the same subscription is `typebulb wait agent` on the mirror — see [Emitting an inline bulb](#emitting-an-inline-bulb).
|
|
264
|
+
**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. **`call` always boots a fresh `server.ts` instance** — it never attaches to the running bulb's server — so any state shared between the page and your calls must live on disk (load/save it in each export), not in `server.ts` module memory. A bulb's uncaught browser errors land in the same log as `[runtime error] …`, so the wake channel also catches your bulb breaking. A page that closes mid-run logs `[page] disconnected` a few seconds later, so a wait on a page-driven run's completion tag pairs with a second `wait <file> --match "[page] disconnected"`: a run whose page is gone never completes. For inline bulbs, the same subscription is `typebulb wait agent` on the mirror — see [Emitting an inline bulb](#emitting-an-inline-bulb).
|
|
264
265
|
|
|
265
266
|
**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. `send` takes its message the same way (`typebulb send <file> -`), which is also how a large or quote-heavy payload avoids the shell. `wait` and a `getState` call are constant already.
|
|
266
267
|
|
|
@@ -273,7 +274,7 @@ The agent mirror turns that block into a live, sandboxed app, with a *breakout
|
|
|
273
274
|
|
|
274
275
|
That one launch *is* the loop: the server watches the file, so every save recompiles and reloads the page (`server.ts` included) — editing the file is the iteration.
|
|
275
276
|
|
|
276
|
-
- **Don't relaunch, and don't wrap it in the `timeout` command.** A relaunch replaces the running server (one per bulb file), reclaiming the same port so the open tab reloads itself — it costs the page's in-memory state and nothing else. The `timeout` command kills the server outright, and the racing relaunch is what spawns extra windows; your harness's own tool timeout does not kill it.
|
|
277
|
+
- **Don't relaunch, and don't wrap it in the `timeout` command.** A relaunch replaces the running server (one per bulb file), reclaiming the same port so the open tab reloads itself — it costs the page's in-memory state and nothing else. The `timeout` command kills the server outright, and the racing relaunch is what spawns extra windows; your harness's own tool timeout does not kill it. When you must relaunch, relaunch plainly: never `stop` first, and never pick a new `--port`. A relaunch replaces on its own, and either move strands the open tab (a stopped server's tab keeps retrying its port for 30 minutes and greets whatever lands there next).
|
|
277
278
|
- **What needs a restart:** a `.env` change (read once at boot) and in-memory `server.ts` state (reset on each reload).
|
|
278
279
|
- **Each reload re-runs the bulb.** A save re-executes `code.tsx` from scratch, so work you start on mount repeats every edit — re-spending GPU/network, re-firing side effects, flooding the log. Put expensive or side-effecting work behind a trigger: `tb.onMessage(() => start())`, then `typebulb send <file>` when ready (also a general terminal→page channel — pass params, drive a loop).
|
|
279
280
|
- **Reading the log:** it appends across every reload, so `typebulb logs --run latest <file>` shows just the current run (no need to clear).
|