typebulb 0.41.2 → 0.43.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 +11 -4
- package/dist/agents/claude/client.js +183 -34
- package/dist/agents/claude/styles.css +7 -4
- package/dist/agents/pi/client.js +243 -94
- package/dist/agents/pi/matchu-patchu.ts +1 -1
- package/dist/agents/pi/styles.css +7 -4
- package/dist/format/index.d.ts +1 -0
- package/dist/format/index.d.ts.map +1 -1
- package/dist/format/index.js +1 -0
- package/dist/format/index.js.map +1 -1
- package/dist/format/slug.d.ts +4 -0
- package/dist/format/slug.d.ts.map +1 -0
- package/dist/format/slug.js +7 -0
- package/dist/format/slug.js.map +1 -0
- package/dist/index.js +442 -285
- package/dist/render.js +285 -136
- package/dist/servers.js +274 -125
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -44,6 +44,8 @@ typebulb call <file> <fn> […] Invoke one server.ts export headlessly: prints
|
|
|
44
44
|
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
45
|
With --wait, a handler's non-undefined return prints on stdout (JSON; a bare string raw)
|
|
46
46
|
typebulb send <file> tb:snapshot Print the live page's rendered outline (roles, names, visible text)
|
|
47
|
+
typebulb send <file> tb:click … Click a control by role+name ('tb:click button "Pass"'); the reply is a fresh snapshot
|
|
48
|
+
typebulb send <file> tb:set … Set a form control ('tb:set combobox "level" = hard'), firing input+change
|
|
47
49
|
typebulb get <file> <kind> Print one block's content (data, insight, code, …) to stdout
|
|
48
50
|
typebulb put <file> <k>=<src> Write a file's (or stdin's) content into a block, surgically
|
|
49
51
|
typebulb pull <url|file> Fetch a bulb from typebulb.com into typebulbs/u/<user>/<slug>.bulb.md
|
|
@@ -51,6 +53,7 @@ typebulb push <file> Upload a local bulb to typebulb.com as you (needs
|
|
|
51
53
|
typebulb check [file.bulb.md] Type-check a bulb without running it
|
|
52
54
|
typebulb predict [file] Report the capability a bulb probably needs, without running it
|
|
53
55
|
typebulb models List AI models for tb.ai, filtered by your .env API keys
|
|
56
|
+
typebulb slug <name> Print the slug a title derives to — the filename to save the bulb as
|
|
54
57
|
typebulb logs [file|agent] Print a running bulb's (or `agent` mirror's) captured console (no arg: list running servers; -f follow, -n N tail, --run latest|N for one reload's output, --clear to empty it)
|
|
55
58
|
typebulb wait [file|agent] Block until the target logs a matching line, print it, exit — an agent's wake-up
|
|
56
59
|
(run it backgrounded; --match <substr> filters; exit 2 = gave up)
|
|
@@ -88,6 +91,11 @@ A bulb is a single **markdown** file — the minimum viable structure for a smal
|
|
|
88
91
|
| `**notes.md**` | Persistent context for the AI assistant, carried across conversations and clones. Not run. |
|
|
89
92
|
| `**server.ts**` | Node.js code; its exports become `tb.server.<name>()` in the browser. Mostly plain Node — log with `console.log` — but `tb.fs` and `tb.ai`/`tb.ai.stream`/`tb.models` are callable here too (under `--trust`). **Local only.** |
|
|
90
93
|
|
|
94
|
+
### Frontmatter and config
|
|
95
|
+
|
|
96
|
+
- **`name:`** (frontmatter) is the bulb's title — a few words, not a sentence — and the file takes its slug: `<slug>.bulb.md`, in the project's **`typebulbs/`** folder. The slug is derived, not chosen: `Counter` → `counter.bulb.md` is obvious, `Rock & Roll` → `rock-and-roll` is not, so run `npx typebulb slug "<name>"` rather than guess. Once pushed, that name is the bulb's URL.
|
|
97
|
+
- **`description`** (in `config.json`) is the bulb's search-result blurb — what makes someone open it. Keep it short; it truncates past ~160 chars.
|
|
98
|
+
|
|
91
99
|
### Example
|
|
92
100
|
|
|
93
101
|
````markdown
|
|
@@ -261,8 +269,9 @@ That one launch *is* the loop: the server watches the file, so every save recomp
|
|
|
261
269
|
|
|
262
270
|
- **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.
|
|
263
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`.)
|
|
264
|
-
- **
|
|
265
|
-
- **
|
|
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). Adding the handler later is itself the edit that destroys the state.
|
|
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.
|
|
266
275
|
|
|
267
276
|
### Emitting a server-only bulb
|
|
268
277
|
|
|
@@ -286,8 +295,6 @@ The host owns a bulb's **width**; you own its **height**.
|
|
|
286
295
|
|
|
287
296
|
## Tips for Agents
|
|
288
297
|
|
|
289
|
-
- **`config.json` `description`** is the bulb's search-result blurb — what makes someone open it, kept short (it truncates past ~160 chars).
|
|
290
|
-
- **The frontmatter `name:` is the bulb's title** — a few words, not a sentence — and the filename should be its slug (`name: Counter` → `counter.bulb.md`), saved in the project's **`typebulbs/`** folder.
|
|
291
298
|
- **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.
|
|
292
299
|
- **Images & media: an `assets/` subfolder of the bulb's folder** (`birds.bulb.md` → `birds/assets/robin.png`) — `<img src="assets/robin.png">` just works (always that relative form, never `/assets/…`), every tier except embedded.
|
|
293
300
|
- **Batch runs: scope with `--batch`, don't hand-roll plumbing** — `--batch pilot` on a run or `call` lands `tb.dir` and relative `tb.fs` paths in `<bulb-folder>/batches/pilot/`; the bulb's code stays batch-unaware, an unscoped run sees `batches/` as an ordinary subfolder, and the agent mirror lists a bulb's batches on its launcher row (play opens the newest).
|