typebulb 0.29.3 → 0.31.0
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 +13 -3
- package/dist/agents/claude/client.js +186 -105
- package/dist/agents/claude/styles.css +30 -7
- package/dist/agents/pi/client.js +122 -41
- package/dist/agents/pi/matchu-patchu.ts +1 -1
- package/dist/agents/pi/styles.css +30 -7
- package/dist/dts/tbTypings.d.ts +1 -1
- package/dist/dts/tbTypings.d.ts.map +1 -1
- package/dist/dts/tbTypings.js +5 -3
- package/dist/dts/tbTypings.js.map +1 -1
- package/dist/index.js +282 -213
- package/dist/render.js +100 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,7 +40,9 @@ typebulb agent An agent's first command — auto-detects the har
|
|
|
40
40
|
typebulb agent:{claude|pi} Open a named harness's mirror in the foreground — the explicit form, or to override auto-detect
|
|
41
41
|
typebulb skill Print this README as an Agent Skill on stdout
|
|
42
42
|
typebulb call <file> <fn> […] Invoke one server.ts export headlessly: prints its return as JSON to stdout, logs/errors to stderr (needs --trust)
|
|
43
|
-
typebulb send <file> [msg] Push a message into a running bulb's page (its tb.onMessage handlers); the client-side twin of call, no --trust
|
|
43
|
+
typebulb send <file> [msg] Push a message into a running bulb's page (its tb.onMessage handlers); the client-side twin of call, no --trust.
|
|
44
|
+
With --wait, a handler's non-undefined return prints on stdout (JSON; a bare string raw)
|
|
45
|
+
typebulb send <file> tb:snapshot Print the live page's rendered outline (roles, names, visible text)
|
|
44
46
|
typebulb pull <url|file> Fetch a bulb from typebulb.com into typebulbs/u/<user>/<slug>.bulb.md
|
|
45
47
|
typebulb push <file> Upload a local bulb to typebulb.com as you (needs TYPEBULB_TOKEN in .env)
|
|
46
48
|
typebulb check [file.bulb.md] Type-check a bulb without running it
|
|
@@ -185,7 +187,7 @@ everywhere.
|
|
|
185
187
|
| `tb.url()` | Get the bulb URL (the served localhost URL, locally) | |
|
|
186
188
|
| `tb.models()` | List available AI models (for dynamic model selectors); the `.env` default is flagged (`default: true`); returns `[]` when embedded (no host AI) | |
|
|
187
189
|
| `tb.hasOwnKeys()` | Whether the user's own AI keys back `tb.ai` — `false` means courtesy model only; always `false` embedded | |
|
|
188
|
-
| `tb.onMessage(cb)` | Receive a value pushed in from the terminal by `typebulb send` — inert when embedded (no sender) | |
|
|
190
|
+
| `tb.onMessage(cb)` | Receive a value pushed in from the terminal by `typebulb send`; a non-`undefined` return becomes the reply `send --wait` prints — inert when embedded (no sender) | |
|
|
189
191
|
| `tb.fs.read/readBytes/write` | Read and write local files | yes |
|
|
190
192
|
| `tb.dir` | The bulb's folder (absolute path), where relative `tb.fs` paths land | |
|
|
191
193
|
| `tb.server.<name>(...)` | Call a function exported from the `server.ts` block | yes |
|
|
@@ -249,6 +251,14 @@ That one launch *is* the loop: the server watches the file, so every save recomp
|
|
|
249
251
|
- **Reading the log:** it appends across every reload, so `typebulb logs --run latest <file>` shows just the current run (no need to clear).
|
|
250
252
|
- **When done:** Ctrl-C, or `typebulb stop <file>` — closing the terminal leaves the server running detached.
|
|
251
253
|
|
|
254
|
+
#### Interrogating the live page
|
|
255
|
+
|
|
256
|
+
`send --wait` is a round trip: the page's `tb.onMessage` handler runs and its non-`undefined` return value prints on stdout — JSON, or raw for a bare string. The delivery line stays on stderr, so the reply is what you parse.
|
|
257
|
+
|
|
258
|
+
- **Structured selftest** — a handler that returns `{ count, verdict }` beats one that logs prose: `typebulb send <file> selftest --wait` prints the object as JSON, and you assert on fields instead of parsing `logs`. At most one handler, in one page, may return a value; a slow check needs `--wait=<ms>` above the 5s default.
|
|
259
|
+
- **Rendered truth** — `typebulb send <file> tb:snapshot` prints the page's accessibility outline (roles, names, visible text) without disturbing its state. Use it when logs say ok but the screen might not, and as the first probe on a live page in a state you can't reproduce — a save would hot-reload and destroy it. (`tb:` messages are answered by the runtime, never your handlers, and imply `--wait`.)
|
|
260
|
+
- **A page must be open** — `send` reports "no page connected" until someone opens the printed link; the CLI runs no browser of its own.
|
|
261
|
+
|
|
252
262
|
### Emitting a server-only bulb
|
|
253
263
|
|
|
254
264
|
A `**server.ts**` block with no `**code.tsx**` is a headless bulb — no UI, no port, absent from the launcher. Under `--trust` its code can use `tb.fs`, and call `tb.ai`, `tb.ai.stream`, and `tb.models` against your `.env` keys.
|
|
@@ -276,7 +286,7 @@ The host owns a bulb's **width**; you own its **height**.
|
|
|
276
286
|
- **A bulb's working files land beside it automatically** — relative `tb.fs` paths resolve to the bulb's folder, in `code.tsx` and `server.ts` alike: `tb.fs.write('run.json')`, no path prefix, no mkdir.
|
|
277
287
|
- **Batch runs: scope with `--dir`, don't hand-roll plumbing** — `--dir batch2` on a run or `call` lands `tb.dir` and relative `tb.fs` paths in `<bulb-folder>/batch2/`; the bulb's code stays batch-unaware, and an unscoped run sees batches as ordinary subfolders.
|
|
278
288
|
- **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.
|
|
279
|
-
- **Self-testing client code** —
|
|
289
|
+
- **Self-testing client code** — gate checks behind `tb.onMessage(m => { if (m === 'selftest') return run() })`, trigger with `typebulb send <file> selftest --wait`, and assert on the JSON reply — see [Interrogating the live page](#interrogating-the-live-page).
|
|
280
290
|
- **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`.
|
|
281
291
|
- **Mount to the container your `index.html` declares.** The corpus convention is `<div id="root"></div>` with `createRoot(document.getElementById("root")!)`.
|
|
282
292
|
- **All imports at the top of `code.tsx`, and every bare import declared in `config.json` `dependencies`.** Bare imports (`react`, `d3`, `three`, …) resolve from a CDN — no install step — but declaring them is **required, not optional**: an import missing from `dependencies` is a lint error that fails `npx typebulb check` *and* refuses to run. Declaring is also what pins versions and lets `check` fetch type defs (without it you get errors like `TS2875: react/jsx-runtime`). So a bulb with imports must carry a `config.json` with a matching `dependencies` entry for each.
|