typebulb 0.57.2 → 0.58.1

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 CHANGED
@@ -192,12 +192,13 @@ everywhere.
192
192
  |-----|--------------|:-----------:|
193
193
  | `tb.data(n)` / `tb.json(n)` | Read data chunk `n` from the `data.txt` block — raw string, or parsed JSON | |
194
194
  | `tb.insight()` | Read the `insight.json` block as JSON | |
195
+ | `tb.setData(chunks)` / `tb.setInsight(v)` | Replace this run's data / insight; the URL fragment follows, the file is untouched | |
195
196
  | `tb.theme` | Get/set the light/dark override; `undefined` follows the OS | |
196
197
  | `tb.mode` | Runtime mode — `'local'` (CLI) or `'inline'` (sandboxed iframe); `'ide'`/`'published'` on typebulb.com | |
197
198
  | `tb.proxy(url)` | Rewrite a CDN URL to load through the host origin (Web Worker / WASM) | |
198
199
  | `tb.dump(...)` | Log values (incl. lazy / device-backed tensors) to the browser console | |
199
200
  | `tb.copy(text)` | Copy text to the clipboard | |
200
- | `tb.url()` | Get the bulb URL (the served localhost URL, locally) | |
201
+ | `tb.url()` | Get the bulb's canonical URL, `#tb=` fragment included (the served localhost URL, locally) | |
201
202
  | `tb.models()` | List available AI models (for dynamic model selectors); the `.env` default is flagged (`default: true`); returns `[]` when inline (no host AI) | |
202
203
  | `tb.aiAccess()` | What backs `tb.ai` — `'own' \| 'courtesy' \| 'none'` | |
203
204
  | `tb.log(...)` | Print to the CLI's stdout (read back with `typebulb logs`); falls back to the browser console when no CLI serves the page | |
@@ -507,6 +508,22 @@ the whole file; `put` replaces it blind, knowing neither its size, its format, n
507
508
  - **Put**: `typebulb put <file> <kind>=<source>` writes a file's content into that block; `<kind>=-` reads stdin. Several pairs in one command are one atomic write. It replaces the block, appends it when absent, writes nothing when the content is identical, and **removes** the block when the source is empty — the only way to clear one.
508
509
  - Only the named block changes; every other block and the frontmatter survive byte-for-byte. A running bulb hot-reloads on a `put`.
509
510
 
511
+ ## Runtime data (`tb.setData`)
512
+
513
+ A bulb that computes its own results (a scrape, a batch score, a simulation, a tournament) can swap
514
+ them in as the data it's running on, and the page URL then carries them:
515
+
516
+ ```ts
517
+ await tb.setData(JSON.stringify(results))
518
+ tb.copy(await tb.url())
519
+ ```
520
+
521
+ - `tb.data()` / `tb.json()` return the new chunks for the rest of the page, and the URL's `#tb=` fragment holds them, so reloading or opening that link restores the run. `tb.setInsight(value)` is the same for `tb.insight()`.
522
+ - **The write is the URL update.** Awaiting a setter means the address bar holds the run. Nothing comes back: `tb.url()` is how you read the link. On typebulb.com the fragment lands in fullscreen, exactly as `tb.infer()` does; an inline bulb has no URL of its own, so there the swap happens and nothing else does.
523
+ - **Runtime only, never the file.** A reload without the fragment is back on the bulb's own `data.txt`. Two gestures promote a run to source, and no `tb.*` call does: `typebulb put` from the terminal, or `tb.infer()` to raise the modal and press **Save to bulb**, which files whatever the page holds — an LLM call is not needed and the size ceiling does not apply (needs `--trust`).
524
+ - **The link has a size ceiling; the file doesn't.** Around 60KB encoded, so pass what a share needs rather than everything. Over it the run still swaps, but the fragment clears and there is no link.
525
+ - **Set only what you changed.** An unset slot stays out of the link and falls through to the bulb's own block, so a data-only run doesn't drag a copy of `insight.json` along. Both in one tick is one encode: `tb.setData(d); await tb.setInsight(i)`.
526
+
510
527
  ## Charts
511
528
 
512
529
  Mermaid's `xychart-beta` is static, unlabeled bars and lines — no tooltips, no legend, no other chart types. Anything more is a bulb. Start from this skeleton:
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.57.2
4
+ version: 0.58.1
5
5
  ---
6
6
 
7
- > Generated from typebulb v0.57.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.
7
+ > Generated from typebulb v0.58.1. `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
 
@@ -200,12 +200,13 @@ everywhere.
200
200
  |-----|--------------|:-----------:|
201
201
  | `tb.data(n)` / `tb.json(n)` | Read data chunk `n` from the `data.txt` block — raw string, or parsed JSON | |
202
202
  | `tb.insight()` | Read the `insight.json` block as JSON | |
203
+ | `tb.setData(chunks)` / `tb.setInsight(v)` | Replace this run's data / insight; the URL fragment follows, the file is untouched | |
203
204
  | `tb.theme` | Get/set the light/dark override; `undefined` follows the OS | |
204
205
  | `tb.mode` | Runtime mode — `'local'` (CLI) or `'inline'` (sandboxed iframe); `'ide'`/`'published'` on typebulb.com | |
205
206
  | `tb.proxy(url)` | Rewrite a CDN URL to load through the host origin (Web Worker / WASM) | |
206
207
  | `tb.dump(...)` | Log values (incl. lazy / device-backed tensors) to the browser console | |
207
208
  | `tb.copy(text)` | Copy text to the clipboard | |
208
- | `tb.url()` | Get the bulb URL (the served localhost URL, locally) | |
209
+ | `tb.url()` | Get the bulb's canonical URL, `#tb=` fragment included (the served localhost URL, locally) | |
209
210
  | `tb.models()` | List available AI models (for dynamic model selectors); the `.env` default is flagged (`default: true`); returns `[]` when inline (no host AI) | |
210
211
  | `tb.aiAccess()` | What backs `tb.ai` — `'own' \| 'courtesy' \| 'none'` | |
211
212
  | `tb.log(...)` | Print to the CLI's stdout (read back with `typebulb logs`); falls back to the browser console when no CLI serves the page | |
@@ -515,6 +516,22 @@ the whole file; `put` replaces it blind, knowing neither its size, its format, n
515
516
  - **Put**: `typebulb put <file> <kind>=<source>` writes a file's content into that block; `<kind>=-` reads stdin. Several pairs in one command are one atomic write. It replaces the block, appends it when absent, writes nothing when the content is identical, and **removes** the block when the source is empty — the only way to clear one.
516
517
  - Only the named block changes; every other block and the frontmatter survive byte-for-byte. A running bulb hot-reloads on a `put`.
517
518
 
519
+ ## Runtime data (`tb.setData`)
520
+
521
+ A bulb that computes its own results (a scrape, a batch score, a simulation, a tournament) can swap
522
+ them in as the data it's running on, and the page URL then carries them:
523
+
524
+ ```ts
525
+ await tb.setData(JSON.stringify(results))
526
+ tb.copy(await tb.url())
527
+ ```
528
+
529
+ - `tb.data()` / `tb.json()` return the new chunks for the rest of the page, and the URL's `#tb=` fragment holds them, so reloading or opening that link restores the run. `tb.setInsight(value)` is the same for `tb.insight()`.
530
+ - **The write is the URL update.** Awaiting a setter means the address bar holds the run. Nothing comes back: `tb.url()` is how you read the link. On typebulb.com the fragment lands in fullscreen, exactly as `tb.infer()` does; an inline bulb has no URL of its own, so there the swap happens and nothing else does.
531
+ - **Runtime only, never the file.** A reload without the fragment is back on the bulb's own `data.txt`. Two gestures promote a run to source, and no `tb.*` call does: `typebulb put` from the terminal, or `tb.infer()` to raise the modal and press **Save to bulb**, which files whatever the page holds — an LLM call is not needed and the size ceiling does not apply (needs `--trust`).
532
+ - **The link has a size ceiling; the file doesn't.** Around 60KB encoded, so pass what a share needs rather than everything. Over it the run still swaps, but the fragment clears and there is no link.
533
+ - **Set only what you changed.** An unset slot stays out of the link and falls through to the bulb's own block, so a data-only run doesn't drag a copy of `insight.json` along. Both in one tick is one encode: `tb.setData(d); await tb.setInsight(i)`.
534
+
518
535
  ## Charts
519
536
 
520
537
  Mermaid's `xychart-beta` is static, unlabeled bars and lines — no tooltips, no legend, no other chart types. Anything more is a bulb. Start from this skeleton: