typebulb 0.43.1 → 0.44.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 +6 -4
- package/SKILL.md +575 -0
- package/dist/agents/pi/matchu-patchu.ts +125 -42
- package/dist/index.js +247 -262
- package/dist/servers.js +70 -70
- package/package.json +3 -3
- package/description.md +0 -8
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ This document is dedicated to the typebulb CLI. At its core, it compiles and ser
|
|
|
30
30
|
- **`tb.infer()`** — one-shot runtime inference over the bulb's own blocks (`infer.md` + `data.txt` → `insight.json`), with a confirmation modal, streaming, and share/save of a good run. Requires `--trust`.
|
|
31
31
|
- **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.
|
|
32
32
|
- **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.
|
|
33
|
-
- **Agent mirror** — a browser view of your coding agent's sessions, rendering embedded bulbs, KaTeX, and mermaid live inline, plus runs/stops local bulbs. On Pi it also carries a prompt panel, so the user can drive their pi sessions from the mirror directly. `typebulb agent` brings it up, auto-detecting your harness (Claude Code or Pi) — see [Agent Harness Support](#agent-harness-support).
|
|
33
|
+
- **Agent mirror** — a browser view of your coding agent's sessions, rendering embedded bulbs, KaTeX, and mermaid live inline, plus runs/stops local bulbs. On Pi it also carries a prompt panel, so the user can drive their pi sessions from the mirror directly. `typebulb agent` brings it up, auto-detecting your harness (Claude Code or Pi) — see [Agent Harness Support](#agent-harness-support).
|
|
34
34
|
- **Proxying Claude** — the agent mirror lets you proxy Claude with a model from [OpenRouter](https://openrouter.ai). This will apply to your project only.
|
|
35
35
|
|
|
36
36
|
## Usage
|
|
@@ -39,7 +39,6 @@ This document is dedicated to the typebulb CLI. At its core, it compiles and ser
|
|
|
39
39
|
typebulb [file.bulb.md] Run a bulb (defaults to .bulb.md in cwd)
|
|
40
40
|
typebulb agent An agent's first command — auto-detects the harness, starts the mirror detached, prints its URL, exits 0
|
|
41
41
|
typebulb agent:{claude|pi} Open a named harness's mirror in the foreground — the explicit form, or to override auto-detect
|
|
42
|
-
typebulb skill Print this README as an Agent Skill on stdout
|
|
43
42
|
typebulb call <file> <fn> […] Invoke one server.ts export headlessly: prints its return as JSON to stdout, logs/errors to stderr (needs --trust)
|
|
44
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.
|
|
45
44
|
With --wait, a handler's non-undefined return prints on stdout (JSON; a bare string raw)
|
|
@@ -222,7 +221,7 @@ Start it yourself with `npx typebulb agent` (it auto-detects your harness) — d
|
|
|
222
221
|
|
|
223
222
|
One exception: if `TYPEBULB_MIRROR=1` is set in your environment, the user is prompting you from the mirror itself — it's already open in front of them, so skip `npx typebulb agent` and don't end with its link; just emit bulbs.
|
|
224
223
|
|
|
225
|
-
|
|
224
|
+
If the user asks to keep this document on hand across sessions, copy its packaged skill form — `SKILL.md`, at the path `npx typebulb agent` prints — into your skills folder (e.g. for Claude Code, `.claude/skills/typebulb/SKILL.md`).
|
|
226
225
|
|
|
227
226
|
### When agents should output local vs embedded bulbs
|
|
228
227
|
|
|
@@ -268,9 +267,10 @@ That one launch *is* the loop: the server watches the file, so every save recomp
|
|
|
268
267
|
`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.
|
|
269
268
|
|
|
270
269
|
- **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.
|
|
270
|
+
- **Slow work settles in the handler** — a handler may be async, and the reply waits for its promise: keep a done-promise, `await` it, and return the finished state, with `--wait=<ms>` sized to the work (instead of polling flags in a sleep loop, or snapshot-polling from outside). The sharp edge: settle the promise on *every* exit of the run — success, failure, supersession, in a `finally` — and start idle with an already-resolved one, or the handler hangs and reads as a broken bulb. One case stays two-step: a `tb:*` gesture that kicks off slow work replies with the immediate frame (runtime-answered), so follow it with this settle probe.
|
|
271
271
|
- **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`.)
|
|
272
272
|
- **Acting on the page** — `typebulb send <file> 'tb:click button "Pass"'` clicks the one control matching that role and name (exact, else a unique case-insensitive substring) and replies with a fresh snapshot; `tb:set combobox "strength" = hard` is the same for form controls (checkboxes and radios take `tb:click`). A disabled, readonly, or covered target is an error naming it — that silence is the bug class these verbs catch. Needs exactly one page open, and the reply is the immediate frame (slow work: follow up with `tb:snapshot`). Only what the outline names is targetable: real `<button>`s and labeled controls, not an `onClick` `<div>`.
|
|
273
|
-
- **Poking state** — for state beyond what a form control expresses (`tb:set` covers those), author a set-handler up front: a `tb.onMessage` branch that takes a data payload (JSON arrives parsed), applies it to your state — committing the change if your framework needs an explicit step — and returns the new state: `typebulb send <file> '{"set":"speed","value":2}' --wait` prints it. In React, register it in an effect so it closes over the setters (the returned unsubscribe is the cleanup).
|
|
273
|
+
- **Poking state** — for state beyond what a form control expresses (`tb:set` covers those), author a set-handler up front: a `tb.onMessage` branch that takes a data payload (JSON arrives parsed), applies it to your state — committing the change if your framework needs an explicit step — and returns the new state: `typebulb send <file> '{"set":"speed","value":2}' --wait` prints it. In React, register it in an effect so it closes over the setters (the returned unsubscribe is the cleanup).
|
|
274
274
|
- **A page must be open** — the CLI runs no browser of its own, so every client-side check waits on a real window (and `--no-open` means there isn't one). `send` says which case it is: nobody has ever connected (share the link), or a page dropped and hasn't returned (it's stale — reload it). Never open a window at the user: the server logs `[page] connected` when a page attaches, so end your turn with the link, arming `typebulb wait <file> --match "[page] connected"` in the background first — the user opening the page is your wake-up.
|
|
275
275
|
|
|
276
276
|
### Emitting a server-only bulb
|
|
@@ -301,6 +301,8 @@ The host owns a bulb's **width**; you own its **height**.
|
|
|
301
301
|
- **See what's already running** — `typebulb logs` with no argument lists every running bulb and mirror; check it before launching anything.
|
|
302
302
|
- **Self-testing a local bulb** — To confirm a bulb works, run it, instrument with `tb.log(...)`, 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.
|
|
303
303
|
- **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).
|
|
304
|
+
- **Probe handlers go in the first draft** — the selftest, readback, and set handlers you'll want later: adding one is an edit, and that hot reload destroys the very state you meant to inspect.
|
|
305
|
+
- **Read a canvas back as an image** — return a bare `canvas.toDataURL()` string from a handler; `typebulb send <file> png --wait` prints it raw, and decoding the base64 after the `data:image/png;base64,` prefix yields a PNG you can view. That's the visual-verification loop for canvas/WebGPU bulbs.
|
|
304
306
|
- **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`.
|
|
305
307
|
- **Mount to the container your `index.html` declares.** The corpus convention is `<div id="root"></div>` with `createRoot(document.getElementById("root")!)`.
|
|
306
308
|
- **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.
|