typebulb 0.58.0 → 0.58.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 CHANGED
@@ -192,13 +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 and get back a link carrying it; the file is untouched | |
195
+ | `tb.setData(chunks)` / `tb.setInsight(v)` | Replace this run's data / insight; the URL fragment follows, the file is untouched | |
196
196
  | `tb.theme` | Get/set the light/dark override; `undefined` follows the OS | |
197
197
  | `tb.mode` | Runtime mode — `'local'` (CLI) or `'inline'` (sandboxed iframe); `'ide'`/`'published'` on typebulb.com | |
198
198
  | `tb.proxy(url)` | Rewrite a CDN URL to load through the host origin (Web Worker / WASM) | |
199
199
  | `tb.dump(...)` | Log values (incl. lazy / device-backed tensors) to the browser console | |
200
200
  | `tb.copy(text)` | Copy text to the clipboard | |
201
- | `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) | |
202
202
  | `tb.models()` | List available AI models (for dynamic model selectors); the `.env` default is flagged (`default: true`); returns `[]` when inline (no host AI) | |
203
203
  | `tb.aiAccess()` | What backs `tb.ai` — `'own' \| 'courtesy' \| 'none'` | |
204
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 | |
@@ -511,17 +511,18 @@ the whole file; `put` replaces it blind, knowing neither its size, its format, n
511
511
  ## Runtime data (`tb.setData`)
512
512
 
513
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 get back a link that carries them:
514
+ them in as the data it's running on, and the page URL then carries them:
515
515
 
516
516
  ```ts
517
- const url = await tb.setData(JSON.stringify(results))
518
- if (url) tb.copy(url)
517
+ await tb.setData(JSON.stringify(results))
518
+ tb.copy(await tb.url())
519
519
  ```
520
520
 
521
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.
522
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`).
523
- - **The link has a size ceiling; the file doesn't.** Around 60KB encoded, so pass what a share needs rather than everything. `undefined` back means it didn't fit (also what an inline bulb gets — no address bar).
524
- - **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 and one link: `tb.setData(d); const url = await tb.setInsight(i)`.
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)`.
525
526
 
526
527
  ## Charts
527
528
 
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.58.0
4
+ version: 0.58.2
5
5
  ---
6
6
 
7
- > Generated from typebulb v0.58.0. `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.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
 
@@ -200,13 +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 and get back a link carrying it; the file is untouched | |
203
+ | `tb.setData(chunks)` / `tb.setInsight(v)` | Replace this run's data / insight; the URL fragment follows, the file is untouched | |
204
204
  | `tb.theme` | Get/set the light/dark override; `undefined` follows the OS | |
205
205
  | `tb.mode` | Runtime mode — `'local'` (CLI) or `'inline'` (sandboxed iframe); `'ide'`/`'published'` on typebulb.com | |
206
206
  | `tb.proxy(url)` | Rewrite a CDN URL to load through the host origin (Web Worker / WASM) | |
207
207
  | `tb.dump(...)` | Log values (incl. lazy / device-backed tensors) to the browser console | |
208
208
  | `tb.copy(text)` | Copy text to the clipboard | |
209
- | `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) | |
210
210
  | `tb.models()` | List available AI models (for dynamic model selectors); the `.env` default is flagged (`default: true`); returns `[]` when inline (no host AI) | |
211
211
  | `tb.aiAccess()` | What backs `tb.ai` — `'own' \| 'courtesy' \| 'none'` | |
212
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 | |
@@ -519,17 +519,18 @@ the whole file; `put` replaces it blind, knowing neither its size, its format, n
519
519
  ## Runtime data (`tb.setData`)
520
520
 
521
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 get back a link that carries them:
522
+ them in as the data it's running on, and the page URL then carries them:
523
523
 
524
524
  ```ts
525
- const url = await tb.setData(JSON.stringify(results))
526
- if (url) tb.copy(url)
525
+ await tb.setData(JSON.stringify(results))
526
+ tb.copy(await tb.url())
527
527
  ```
528
528
 
529
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.
530
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`).
531
- - **The link has a size ceiling; the file doesn't.** Around 60KB encoded, so pass what a share needs rather than everything. `undefined` back means it didn't fit (also what an inline bulb gets — no address bar).
532
- - **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 and one link: `tb.setData(d); const url = await tb.setInsight(i)`.
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)`.
533
534
 
534
535
  ## Charts
535
536
 
@@ -1109,8 +1109,8 @@ ${V9t}
1109
1109
  // tb.setData / tb.setInsight (TB-State.md), on the engine both hosts share. The globals and the
1110
1110
  // transport are all this host owns: encoding round-trips to the server because the page carries
1111
1111
  // no fflate on purpose, and the fragment write is the address bar the setters exist to fill.
1112
- // Resolves the shareable URL, or undefined when there is no address bar to put it in (inline) or
1113
- // the state is too large to encode \u2014 the one failure an author must handle.
1112
+ // Resolves once that write has landed, and hands back nothing: the link is then tb.url() like
1113
+ // any other. An inline bulb has no address bar, so its swap is page-local and never encodes.
1114
1114
  window.__tbState.init({
1115
1115
  applyData: (chunks) => { window.__TB_DATA__ = chunks; },
1116
1116
  applyInsight: (json) => { window.__TB_INSIGHT__ = json; },
@@ -1128,7 +1128,6 @@ ${V9t}
1128
1128
  // earlier fragment, or the address bar keeps addressing a run the page is no longer
1129
1129
  // showing \u2014 and a reload would silently revert to it.
1130
1130
  history.replaceState(null, '', location.pathname + location.search + hash);
1131
- return hash ? location.href : undefined;
1132
1131
  });
1133
1132
  }
1134
1133
  });
@@ -1325,8 +1324,8 @@ ${V9t}
1325
1324
  if (inferRunning) return Promise.reject(new Error('Inference already in progress'));
1326
1325
  inferRunning = true;
1327
1326
  // Data to preview: the explicit arg, else undefined \u2014 the modal then seeds from the SOURCE
1328
- // chunks (/__infer-info), the local Data tab, exactly as .com's IDE modal reseeds from the
1329
- // Data tab rather than post-run runtime state.
1327
+ // chunks the page currently holds, else the SOURCE chunks from /__infer-info \u2014 the same
1328
+ // precedence .com's modal seeds by (TB-Inference.md, "Data seed").
1330
1329
  let data = opts.data;
1331
1330
  if (data !== undefined && !Array.isArray(data)) data = [data];
1332
1331
  return new Promise((resolve, reject) => {
@@ -1109,8 +1109,8 @@ ${q9t}
1109
1109
  // tb.setData / tb.setInsight (TB-State.md), on the engine both hosts share. The globals and the
1110
1110
  // transport are all this host owns: encoding round-trips to the server because the page carries
1111
1111
  // no fflate on purpose, and the fragment write is the address bar the setters exist to fill.
1112
- // Resolves the shareable URL, or undefined when there is no address bar to put it in (inline) or
1113
- // the state is too large to encode \u2014 the one failure an author must handle.
1112
+ // Resolves once that write has landed, and hands back nothing: the link is then tb.url() like
1113
+ // any other. An inline bulb has no address bar, so its swap is page-local and never encodes.
1114
1114
  window.__tbState.init({
1115
1115
  applyData: (chunks) => { window.__TB_DATA__ = chunks; },
1116
1116
  applyInsight: (json) => { window.__TB_INSIGHT__ = json; },
@@ -1128,7 +1128,6 @@ ${q9t}
1128
1128
  // earlier fragment, or the address bar keeps addressing a run the page is no longer
1129
1129
  // showing \u2014 and a reload would silently revert to it.
1130
1130
  history.replaceState(null, '', location.pathname + location.search + hash);
1131
- return hash ? location.href : undefined;
1132
1131
  });
1133
1132
  }
1134
1133
  });
@@ -1325,8 +1324,8 @@ ${q9t}
1325
1324
  if (inferRunning) return Promise.reject(new Error('Inference already in progress'));
1326
1325
  inferRunning = true;
1327
1326
  // Data to preview: the explicit arg, else undefined \u2014 the modal then seeds from the SOURCE
1328
- // chunks (/__infer-info), the local Data tab, exactly as .com's IDE modal reseeds from the
1329
- // Data tab rather than post-run runtime state.
1327
+ // chunks the page currently holds, else the SOURCE chunks from /__infer-info \u2014 the same
1328
+ // precedence .com's modal seeds by (TB-Inference.md, "Data seed").
1330
1329
  let data = opts.data;
1331
1330
  if (data !== undefined && !Array.isArray(data)) data = [data];
1332
1331
  return new Promise((resolve, reject) => {
@@ -1109,8 +1109,8 @@ ${W9t}
1109
1109
  // tb.setData / tb.setInsight (TB-State.md), on the engine both hosts share. The globals and the
1110
1110
  // transport are all this host owns: encoding round-trips to the server because the page carries
1111
1111
  // no fflate on purpose, and the fragment write is the address bar the setters exist to fill.
1112
- // Resolves the shareable URL, or undefined when there is no address bar to put it in (inline) or
1113
- // the state is too large to encode \u2014 the one failure an author must handle.
1112
+ // Resolves once that write has landed, and hands back nothing: the link is then tb.url() like
1113
+ // any other. An inline bulb has no address bar, so its swap is page-local and never encodes.
1114
1114
  window.__tbState.init({
1115
1115
  applyData: (chunks) => { window.__TB_DATA__ = chunks; },
1116
1116
  applyInsight: (json) => { window.__TB_INSIGHT__ = json; },
@@ -1128,7 +1128,6 @@ ${W9t}
1128
1128
  // earlier fragment, or the address bar keeps addressing a run the page is no longer
1129
1129
  // showing \u2014 and a reload would silently revert to it.
1130
1130
  history.replaceState(null, '', location.pathname + location.search + hash);
1131
- return hash ? location.href : undefined;
1132
1131
  });
1133
1132
  }
1134
1133
  });
@@ -1325,8 +1324,8 @@ ${W9t}
1325
1324
  if (inferRunning) return Promise.reject(new Error('Inference already in progress'));
1326
1325
  inferRunning = true;
1327
1326
  // Data to preview: the explicit arg, else undefined \u2014 the modal then seeds from the SOURCE
1328
- // chunks (/__infer-info), the local Data tab, exactly as .com's IDE modal reseeds from the
1329
- // Data tab rather than post-run runtime state.
1327
+ // chunks the page currently holds, else the SOURCE chunks from /__infer-info \u2014 the same
1328
+ // precedence .com's modal seeds by (TB-Inference.md, "Data seed").
1330
1329
  let data = opts.data;
1331
1330
  if (data !== undefined && !Array.isArray(data)) data = [data];
1332
1331
  return new Promise((resolve, reject) => {
@@ -1 +1 @@
1
- {"version":3,"file":"tbTypings.d.ts","sourceRoot":"","sources":["../../dts/src/tbTypings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA6SH,kEAAkE;AAClE,eAAO,MAAM,eAAe,QAO3B,CAAA;AASD;;;wDAGwD;AACxD,eAAO,MAAM,eAAe,QAO3B,CAAA"}
1
+ {"version":3,"file":"tbTypings.d.ts","sourceRoot":"","sources":["../../dts/src/tbTypings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAgTH,kEAAkE;AAClE,eAAO,MAAM,eAAe,QAO3B,CAAA;AASD;;;wDAGwD;AACxD,eAAO,MAAM,eAAe,QAO3B,CAAA"}