typebulb 0.39.3 → 0.41.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.
@@ -2357,7 +2357,7 @@ var Patcher = class {
2357
2357
 
2358
2358
  // cli/agents/pi/server/piPatcherExtension.ts
2359
2359
  var DESCRIPTION = true ? "Apply unified diffs to files \u2014 tolerant of form, strict about intent. Repairs sloppy AI-generated diffs (mangled headers, whitespace drift, missing prefixes; line numbers can be wrong or absent \u2014 hunks anchor by fuzzy-matched context lines) and applies all hunks atomically when the intent is unambiguous; fails with a precise, typed error when it isn't. Use for multi-hunk edits in one step, or when exact string-replacement editing fails on whitespace or invisible characters." : "Apply unified diffs to files.";
2360
- var BUILD_TAG = true ? "matchu-patchu-pi 0.3.3, built 2026-07-25 21:21:48" : "matchu-patchu-pi dev";
2360
+ var BUILD_TAG = true ? "matchu-patchu-pi 0.3.3, built 2026-07-26 14:38:40" : "matchu-patchu-pi dev";
2361
2361
  var errorBlocks = (errors) => {
2362
2362
  const parts = [`Patch failed with ${errors.length} error(s):`];
2363
2363
  for (const e of errors) parts.push("", e.toString());
@@ -118,21 +118,27 @@ body {
118
118
  gap: .4rem;
119
119
  align-items: center;
120
120
  }
121
- /* Chip shape shared by EVERY word-label control — the status-bar pills (interactive and
122
- passive) AND the floating overlay pills (copy, breakout, code⇄run). One rule = one source
123
- of vertical alignment; when these drift apart it reads as amateurish.
124
- THE CENTERING RECIPE (don't re-tweak per button — fix it here or nowhere): Segoe UI's font
121
+ /* THE CENTERING RECIPE for EVERY word-label control on any surface — the status-bar pills and
122
+ floating overlay pills below, and the launcher row's trust switch + B scope chip. One rule = one
123
+ source of vertical alignment; when these drift apart it reads as amateurish, so a new word
124
+ control joins this selector rather than centering itself (don't re-tweak per button — fix it
125
+ here or nowhere). Icon buttons opt back out, keeping flex (see .pill.glyph). Segoe UI's font
125
126
  ascent (~1.08em) dwarfs its descent (~0.25em), so anything that centers the LINE BOX —
126
127
  flex, line-height, padding — parks the glyphs ~2px low at pill sizes. `text-box` trims the
127
128
  line box to the glyphs (cap→baseline) so centering centers the letters themselves. It only
128
129
  applies to block containers (not flex), hence inline-block + align-content, not inline-flex
129
- + align-items. Browsers without text-box (Firefox) fall back to plain line-box centering.
130
- Opaque so pills read cleanly over the message text the transparent strip lets through. */
131
- .pill, .token, .overlay-pill {
130
+ + align-items. Browsers without text-box (Firefox) fall back to plain line-box centering. */
131
+ .pill, .token, .overlay-pill, .trust-toggle, .batch-b {
132
132
  display: inline-block;
133
133
  align-content: center;
134
134
  text-align: center;
135
135
  text-box: trim-both cap alphabetic;
136
+ }
137
+ /* Chip shape shared by the status-bar pills (interactive and passive) AND the floating overlay
138
+ pills (copy, breakout, code⇄run) — opaque, so they read cleanly over the message text the
139
+ transparent strip lets through. The launcher row's pills take only the recipe above; their
140
+ shape is the row's (.trust-toggle, .batch-b). */
141
+ .pill, .token, .overlay-pill {
136
142
  height: var(--pill-h);
137
143
  padding: 0 .7rem;
138
144
  border-radius: 7px;
@@ -821,9 +827,10 @@ a.server-port:hover { text-decoration: underline; }
821
827
  row's snippet line bleeds under the next row as overlapping text. max-content tracks never
822
828
  compress; the list scrolls, rows keep their content height. */
823
829
  .bulb-list { display: grid; grid-template-columns: auto 1fr auto auto auto auto; grid-auto-rows: max-content; column-gap: .6rem; row-gap: .15rem; align-items: center; align-content: start; padding-right: 4px; flex: 1; min-height: 0; overflow-y: auto; }
824
- /* The scope column (TB-Batch.md Invariant 7): a seventh track between name and the control
825
- cluster, present only while some row carries a scope (bulbsPill.ts anyScope — rows emit a
826
- matching cell, spacer included). The B affordance keeps it ~1.3rem wide. */
830
+ /* The scope column (TB-Batch.md Invariant 7): a seventh track heading the control cluster (before
831
+ trust — a launch scope is an execution concern, like a trust tier), present only while some row
832
+ carries a scope (bulbsPill.ts anyScope — rows emit a matching cell, spacer included). The B
833
+ affordance keeps it one --pill-h square. */
827
834
  .bulb-list.has-scope { grid-template-columns: auto 1fr auto auto auto auto auto; }
828
835
  /* A stopped bulb's name isn't a link (no running URL), so it stays plain foreground. */
829
836
  .server-name.stopped { color: var(--fg); }
@@ -839,7 +846,11 @@ a.server-port:hover { text-decoration: underline; }
839
846
  the row shows THAT a scope applies, the tooltip and click-menu name it. Dim = batches exist but
840
847
  launch is unscoped; lit (.on) = play launches scoped (newest default) or running scoped.
841
848
  Static (running) keeps the lit look without the hand cursor. */
842
- .batch-b { font-size: .72rem; font-family: ui-monospace, monospace; line-height: 1; color: var(--muted); background: transparent; border: 1px solid var(--border); border-radius: 4px; width: 1.3rem; height: 1.15rem; padding: 0; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
849
+ /* Square (its one glyph has no text pill's width to earn) and otherwise typography-free: the shared
850
+ pill box, font and trim, so its B is the same size and sits on the same baseline as the trust
851
+ switch beside it. Its own font-family was the bug — a monospace cap is a different size from a
852
+ Segoe cap at one font-size, which reads as two badly-aligned widgets. */
853
+ .batch-b { font-size: var(--pill-font); color: var(--muted); background: transparent; border: 1px solid var(--border); border-radius: 5px; width: var(--pill-h); height: var(--pill-h); padding: 0; cursor: pointer; }
843
854
  .batch-b.on { color: var(--accent); border-color: var(--accent); }
844
855
  .batch-b.static { cursor: default; }
845
856
  /* The B's menu rides the composer popup register (.at-popup/.at-row/.dlg-catcher — one mini-menu
@@ -876,18 +887,21 @@ a.server-port:hover { text-decoration: underline; }
876
887
  .bulb-list .picker-snippet { grid-column: 2 / -1; margin: 0 .4rem .2rem 0; }
877
888
  .bulb-time { color: var(--muted); font-size: .72rem; font-variant-numeric: tabular-nums; text-align: right; margin-right: .4rem; }
878
889
  /* The row's chrome buttons share one reset; sizing + colour differ below. Play/stop are round icon
879
- buttons (friendlier, space-economic); the trust switch is text. Logs is a link, not a button
880
- (see .server-logs above), so it's not in this group. */
890
+ buttons (friendlier, space-economic) and stay flex — a replaced SVG mis-seats under the
891
+ word-pill trim, the .pill.glyph case; the trust switch is a word, so it seats via the shared
892
+ recipe. Logs is a link, not a button (see .server-logs above), so it's not in this group. */
881
893
  .server-stop, .bulb-launch, .trust-toggle {
882
894
  font: inherit; appearance: none; margin: 0; cursor: pointer; box-sizing: border-box;
883
895
  background: transparent; border: 1px solid var(--border); border-radius: 5px;
884
- height: 1.7rem; display: inline-flex; align-items: center; justify-content: center;
896
+ height: 1.7rem;
885
897
  }
886
898
  /* Shorter than the icon buttons: a bordered text pill at full row height reads as cramped, where
887
- the round play/stop icons are meant to fill it. */
888
- .trust-toggle { font-size: .76rem; height: 1.45rem; padding: 0 .5rem; color: var(--muted); justify-self: center; }
899
+ the round play/stop icons are meant to fill it. The shared pill box + font, not a bespoke pair —
900
+ its own .76rem/1.45rem seated the word a full 1px below every statusbar pill, which is exactly how
901
+ this drifts (measured: a per-control size is a per-control seating). */
902
+ .trust-toggle { font-size: var(--pill-font); height: var(--pill-h); padding: 0 .5rem; color: var(--muted); justify-self: center; }
889
903
  .trust-toggle:hover, .trust-toggle.on { color: var(--accent); border-color: var(--accent); }
890
- .server-stop, .bulb-launch { width: 1.7rem; padding: 0; border-radius: 50%; margin-left: .4rem; }
904
+ .server-stop, .bulb-launch { display: inline-flex; align-items: center; justify-content: center; width: 1.7rem; padding: 0; border-radius: 50%; margin-left: .4rem; }
891
905
  .btn-icon { width: 16px; height: 16px; }
892
906
  /* A stopped bulb's play button is dormant — the title is the primary launch target — so it's
893
907
  hidden until the row is hovered or keyboard-selected. visibility (not display) reserves its slot,
@@ -895,9 +909,10 @@ a.server-port:hover { text-decoration: underline; }
895
909
  :port link: green is the live-app axis (play to launch → :port to open it), distinct from the
896
910
  blue source/name. The green even travels left→right as a bulb goes stopped→running. */
897
911
  .bulb-launch { color: var(--fold-marker); visibility: hidden; }
898
- /* A right triangle's visual mass sits left of its bounding box, so geometric centring reads
899
- too-far-left in a round button — shift the play glyph. */
900
- .bulb-launch .icon svg { transform: translateX(1px); }
912
+ /* No optical nudge on the play glyph, deliberately: Material's play_arrow already carries one (its
913
+ path spans 320→760 in a 0→960 frame — ~1px right at icon size, compensating a right triangle's
914
+ left-leaning mass). Our own translateX(1px) stacked a second correction and measured 2px right of
915
+ the button's centre. Any glyph that reads off-centre here is the frame's business, not the app's. */
901
916
  .server-row:hover .bulb-launch, .server-row.active .bulb-launch { visibility: visible; }
902
917
  .bulb-launch:hover { border-color: var(--fold-marker); background: color-mix(in srgb, var(--fold-marker) 12%, transparent); }
903
918
  /* Launching: stays visible (hover-independent) and shimmers until the row flips to a stop button,
@@ -9,9 +9,10 @@
9
9
  * TypeChecker, and the CLI's emitted typecheck dirs.
10
10
  */
11
11
  /** Typebulb globals available in browser-side code (code.tsx). */
12
- export declare const clientTbTypings = "\n/** A single streamed delta from `tb.ai.stream()`. Discriminated by `kind`. */\ntype AiChunk =\n | { kind: \"text\"; text: string }\n | { kind: \"reasoning\"; text: string };\n\n/**\n * Typebulb utilities namespace.\n * Type `tb.` to discover available helpers.\n */\ndeclare const tb: {\n /**\n * Get raw data chunk from the Data tab.\n * @param index - Chunk index (0-based). Separate chunks with 2 blank lines.\n */\n data(index: number): string;\n /**\n * Get data chunk parsed as JSON (handles JSON-ish with unquoted keys).\n * @param index - Chunk index (0-based)\n * @throws If chunk is not valid JSON/JSON-ish\n */\n json<T = unknown>(index: number): T;\n /**\n * Async value inspector for tensor-like objects.\n *\n * Materializes lazy values (like GPU tensors) and logs them with metadata.\n * Handles objects with `.js()`, `.data()`, `.array()`, `.arraySync()`, etc.\n *\n * @remarks\n * - Always use `await` - materialization may be async (GPU\u2192CPU readback)\n * - Large values are truncated (max 1000 elements)\n * - Promises are logged as `[Promise]` (not awaited - could hang)\n */\n dump(...args: any[]): Promise<void>;\n /**\n * Trigger inference to generate new insight data.\n *\n * Opens a confirmation modal showing the data to be analyzed, then streams\n * the inference result. On success, updates the insight so subsequent\n * `tb.insight()` calls return the new value.\n *\n * @param opts - Options for inference\n * @param opts.data - Data to pre-populate in the modal (string or array of strings). If omitted, modal opens with empty textarea for user to paste.\n * @returns Promise that resolves with the parsed insight JSON\n * @throws If inference is already in progress, or on network/parse/rate limit errors\n */\n infer<T = unknown>(opts?: { data?: string | string[] }): Promise<T>;\n /**\n * Get the current inference state.\n *\n * @returns 'idle' | 'running' | 'complete' | 'error'\n */\n inferenceState(): 'idle' | 'running' | 'complete' | 'error';\n /**\n * Set a data chunk for the next inference call.\n *\n * Use this to programmatically set data that will be sent when `tb.infer()` is called\n * without the `data` option.\n *\n * @param index - The chunk index (0-based)\n * @param content - The content for this chunk\n */\n setData(index: number, content: string): void;\n /**\n * Proxy a CDN URL through the sandbox origin for Web Worker/WASM same-origin loading.\n *\n * In the sandbox, prepends `/proxy/` so the URL is served from the same origin.\n * Outside the sandbox (exported HTML, CLI), returns the URL unchanged.\n *\n * @param url - Full HTTPS URL to an allowlisted CDN (esm.sh, unpkg.com, cdn.jsdelivr.net, cdnjs.cloudflare.com)\n * @returns The proxied URL (sandbox) or the original URL (standalone/CLI)\n */\n proxy(url: string): string;\n /**\n * Copy text to clipboard.\n * Must be called synchronously within a user gesture (click/keydown).\n * @returns true if successful, false otherwise\n */\n copy(text: string): Promise<boolean>;\n /**\n * Get the canonical URL of this bulb.\n *\n * Returns the parent typebulb.com URL (including path, query, and `#tb=` fragment),\n * resolving correctly from inside the cross-origin sandbox iframe.\n * Use this instead of `location.href` or `document.referrer`.\n *\n * @returns The full canonical URL\n */\n url(): Promise<string>;\n /**\n * Get the insight data produced by the inference layer.\n *\n * Returns the parsed JSON from insight.json, populated by the inference LLM.\n * Use a type parameter to get typed access to the insight data.\n *\n * @returns The parsed insight JSON, or undefined if no insight is available\n */\n insight<T = unknown>(): T | undefined;\n /**\n * Server-side function proxy.\n *\n * In the CLI, calls exported functions from the `**server.ts**` section.\n * `tb.server.log(...)` is a built-in that prints to CLI stdout (falls back to console.log on web).\n * User exports override built-ins of the same name.\n *\n * A normal export is awaited for its result (`await tb.server.fn()`). An `async function*`\n * export streams: `for await (const chunk of tb.server.gen())`. The call object supports both;\n * break the `for await` to cancel and tear down the server generator.\n */\n server: Record<string, (...args: any[]) => Promise<any> & AsyncIterable<any>>;\n /**\n * Subscribe to a value pushed from the terminal via `typebulb send <file> [message]`.\n *\n * The dual of `tb.server.log` (data out): a value sent *in* from the CLI, no `--trust` required.\n * Use it to start expensive work on demand instead of on load \u2014 e.g. `tb.onMessage(() => start())`\n * \u2014 so hot reloads don't re-trigger it while you edit, and an agent kicks off one run when ready.\n *\n * The message is the JSON-parsed value of what `send` was given (or the raw string if it isn't\n * JSON; `undefined` for a bare `typebulb send <file>`). A non-`undefined` return value (awaited)\n * becomes the reply `send --wait` prints on stdout \u2014 JSON-serializable, at most one handler\n * replying \u2014 the structured read-back for self-tests. Returns an unsubscribe function. Inert in\n * an embedded bulb (no sender) \u2014 the handler is registered but never fires.\n *\n * @param handler - Called with each pushed message; may return a JSON-serializable reply.\n * @returns An unsubscribe function.\n */\n onMessage(handler: (message: any) => unknown): () => void;\n /**\n * General-purpose AI call. `tb.ai(opts)` resolves with the full text; `tb.ai.stream(opts)`\n * returns an async iterable of {@link AiChunk} deltas you consume with `for await`.\n *\n * @returns Promise resolving to { text: string }\n * @throws On rate limit, network error, or provider error\n */\n ai: {\n (options: {\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>;\n system?: string;\n /** Reasoning effort hint: 0=minimal, 1=low, 2=med, 3=high. Mapped to each provider's native mechanism (OpenAI/OpenRouter reasoning effort, Gemini thinking budget, Anthropic adaptive thinking). 0 minimizes reasoning \u2014 a floor, not a guaranteed \"off\": some models still think a little at 0, and adaptive models already self-skip at 1 (low). Level 1 (low) is the sensible default for most work; reach for 0 only when you truly want minimal deliberation. Omit for the model's own default. */\n effort?: 0 | 1 | 2 | 3;\n provider?: string;\n model?: string;\n /** Enable/disable web search. Default: on for BYOK, always off for free model. */\n webSearch?: boolean;\n /** Abort the request. On abort the promise rejects / the stream ends. */\n signal?: AbortSignal;\n }): Promise<{ text: string }>;\n /**\n * Streaming counterpart of `tb.ai()`. Yields `{ kind: \"text\" | \"reasoning\", text }` deltas\n * as they arrive; break the loop (or abort `signal`) to cancel and stop the upstream.\n *\n * `kind: \"reasoning\"` deltas only arrive when you pass `effort: 1-3` AND use a\n * thinking-capable model; otherwise the stream is `text`-only.\n *\n * @example\n * let answer = \"\";\n * for await (const c of tb.ai.stream({ messages })) {\n * if (c.kind === \"text\") answer += c.text;\n * }\n */\n stream(options: {\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>;\n system?: string;\n /** Reasoning effort hint: 0=minimal, 1=low, 2=med, 3=high. Mapped to each provider's native mechanism (OpenAI/OpenRouter reasoning effort, Gemini thinking budget, Anthropic adaptive thinking). 0 minimizes reasoning \u2014 a floor, not a guaranteed \"off\": some models still think a little at 0, and adaptive models already self-skip at 1 (low). Level 1 (low) is the sensible default for most work; reach for 0 only when you truly want minimal deliberation. Omit for the model's own default. */\n effort?: 0 | 1 | 2 | 3;\n provider?: string;\n model?: string;\n /** Enable/disable web search. Default: on for BYOK, always off for free model. */\n webSearch?: boolean;\n /** Abort the request. On abort the promise rejects / the stream ends. */\n signal?: AbortSignal;\n }): AsyncIterable<AiChunk>;\n };\n /**\n * Local filesystem access (CLI only).\n *\n * Relative paths resolve against the bulb's folder (`tb.dir` \u2014\n * `<bulb-dir>/<filename-stem>/`, created on demand), so\n * `tb.fs.write('results.json')` lands beside the bulb. `../` reaches sibling\n * bulbs' folders; everything stays confined to the project (the launch cwd).\n * Throws in editor/published mode.\n */\n fs: {\n /** Read a file as UTF-8 text. Throws if the file is not valid UTF-8 \u2014 use readBytes for binary. */\n read(path: string): Promise<string>;\n /** Read a file as raw bytes. */\n readBytes(path: string): Promise<Uint8Array>;\n /** Write text or raw bytes to a file. Creates parent directories if needed. */\n write(path: string, content: string | Uint8Array): Promise<boolean>;\n };\n /**\n * The bulb's folder \u2014 absolute path to `<bulb-dir>/<filename-stem>/`\n * (or its `batches/<name>/` folder when the run is scoped with `--batch`).\n *\n * For interop only (handing a path to `server.ts` or a spawned tool):\n * `tb.fs` already resolves relative paths against it, so bulb code writing\n * its own files never needs it. CLI only \u2014 throws in editor/published/embedded mode.\n */\n readonly dir: string;\n /**\n * Returns AI models available to the current user.\n * Models are filtered by the user's configured API keys.\n * If no keys are configured, returns only the courtesy model.\n */\n models(): Promise<Array<{\n /** Provider protocol: \"anthropic\", \"openai\", \"gemini\", \"openrouter\" */\n provider: string;\n /** Model identifier, e.g. \"claude-sonnet-4-6\" */\n name: string;\n /** Human-readable display name, e.g. \"Sonnet 4.6\" */\n friendlyName: string;\n /** Provider display name, e.g. \"Anthropic\" */\n providerName: string;\n /** True on the .env-configured default model (TB_AI_PROVIDER + TB_AI_MODEL); absent otherwise */\n default?: boolean;\n }>>;\n /**\n * Whether the user's own AI keys back `tb.ai`. False means only the\n * quota-limited courtesy model is available (or no AI at all) \u2014 a bulb\n * making many AI calls should check this and show a \"use your own keys\"\n * notice instead of running.\n */\n hasOwnKeys(): Promise<boolean>;\n /**\n * The bulb's theme override (`<html data-theme>`).\n *\n * - Get: the current override \u2014 `'dark'` | `'light'`, or `undefined` when\n * following the OS preference.\n * - Set `'dark'`/`'light'` to force and persist it (per-bulb); set\n * `undefined` to clear the override and follow the OS again.\n *\n * Drives `<html data-theme>`, so render off `html[data-theme=\"\u2026\"]` selectors\n * (or observe the attribute) rather than reading `tb.theme`.\n */\n theme: 'light' | 'dark' | undefined;\n /**\n * The mode this bulb is running in.\n *\n * - `'local'` \u2014 Running via the typebulb CLI\n * - `'editor'` \u2014 Running in the typebulb.com editor\n * - `'published'` \u2014 Running as a published/standalone bulb on typebulb.com\n * - `'embedded'` \u2014 Running as a bulb embedded inside another bulb (sandboxed,\n * client-only: AI, filesystem, and server RPC are unavailable)\n */\n mode: 'local' | 'editor' | 'published' | 'embedded';\n};\n";
12
+ export declare const clientTbTypings = "\n/** A single streamed delta from `tb.ai.stream()`. Discriminated by `kind`. */\ntype AiChunk =\n | { kind: \"text\"; text: string }\n | { kind: \"reasoning\"; text: string };\n\n/**\n * Typebulb utilities namespace.\n * Type `tb.` to discover available helpers.\n */\ndeclare const tb: {\n /**\n * Get raw data chunk from the Data tab.\n * @param index - Chunk index (0-based). Separate chunks with 2 blank lines.\n */\n data(index: number): string;\n /**\n * Get data chunk parsed as JSON (handles JSON-ish with unquoted keys).\n * @param index - Chunk index (0-based)\n * @throws If chunk is not valid JSON/JSON-ish\n */\n json<T = unknown>(index: number): T;\n /**\n * Async value inspector for tensor-like objects.\n *\n * Materializes lazy values (like GPU tensors) and logs them with metadata.\n * Handles objects with `.js()`, `.data()`, `.array()`, `.arraySync()`, etc.\n *\n * @remarks\n * - Always use `await` - materialization may be async (GPU\u2192CPU readback)\n * - Large values are truncated (max 1000 elements)\n * - Promises are logged as `[Promise]` (not awaited - could hang)\n */\n dump(...args: any[]): Promise<void>;\n /**\n * Trigger inference to generate new insight data.\n *\n * Opens a confirmation modal showing the data to be analyzed, then streams\n * the inference result. On success, updates the insight so subsequent\n * `tb.insight()` calls return the new value.\n *\n * @param opts - Options for inference\n * @param opts.data - Data to pre-populate in the modal (string or array of strings). If omitted, modal opens with empty textarea for user to paste.\n * @returns Promise that resolves with the parsed insight JSON\n * @throws If inference is already in progress, or on network/parse/rate limit errors\n */\n infer<T = unknown>(opts?: { data?: string | string[] }): Promise<T>;\n /**\n * Get the current inference state.\n *\n * @returns 'idle' | 'running' | 'complete' | 'error'\n */\n inferenceState(): 'idle' | 'running' | 'complete' | 'error';\n /**\n * Set a data chunk for the next inference call.\n *\n * Use this to programmatically set data that will be sent when `tb.infer()` is called\n * without the `data` option.\n *\n * @param index - The chunk index (0-based)\n * @param content - The content for this chunk\n */\n setData(index: number, content: string): void;\n /**\n * Proxy a CDN URL through the sandbox origin for Web Worker/WASM same-origin loading.\n *\n * In the sandbox, prepends `/proxy/` so the URL is served from the same origin.\n * Outside the sandbox (exported HTML, CLI), returns the URL unchanged.\n *\n * @param url - Full HTTPS URL to an allowlisted CDN (esm.sh, unpkg.com, cdn.jsdelivr.net, cdnjs.cloudflare.com)\n * @returns The proxied URL (sandbox) or the original URL (standalone/CLI)\n */\n proxy(url: string): string;\n /**\n * Copy text to clipboard.\n * Must be called synchronously within a user gesture (click/keydown).\n * @returns true if successful, false otherwise\n */\n copy(text: string): Promise<boolean>;\n /**\n * Get the canonical URL of this bulb.\n *\n * Returns the parent typebulb.com URL (including path, query, and `#tb=` fragment),\n * resolving correctly from inside the cross-origin sandbox iframe.\n * Use this instead of `location.href` or `document.referrer`.\n *\n * @returns The full canonical URL\n */\n url(): Promise<string>;\n /**\n * Get the insight data produced by the inference layer.\n *\n * Returns the parsed JSON from insight.json, populated by the inference LLM.\n * Use a type parameter to get typed access to the insight data.\n *\n * @returns The parsed insight JSON, or undefined if no insight is available\n */\n insight<T = unknown>(): T | undefined;\n /**\n * Print to the CLI's stdout \u2014 the bulb's log channel, read back with `typebulb logs <file>`.\n *\n * Ungated: needs no `server.ts` block and no `--trust`, so a Restricted client-only bulb can\n * instrument itself. Args cross to the CLI as JSON; where no CLI serves the page (web, embedded,\n * or a transport failure) it falls back to the browser console. Works in `server.ts` too (same\n * as `console.log` there).\n */\n log(...args: any[]): void;\n /**\n * Server-side function proxy.\n *\n * In the CLI, calls exported functions from the `**server.ts**` section.\n *\n * A normal export is awaited for its result (`await tb.server.fn()`). An `async function*`\n * export streams: `for await (const chunk of tb.server.gen())`. The call object supports both;\n * break the `for await` to cancel and tear down the server generator.\n */\n server: Record<string, (...args: any[]) => Promise<any> & AsyncIterable<any>>;\n /**\n * Subscribe to a value pushed from the terminal via `typebulb send <file> [message]`.\n *\n * The dual of `tb.log` (data out): a value sent *in* from the CLI, no `--trust` required.\n * Use it to start expensive work on demand instead of on load \u2014 e.g. `tb.onMessage(() => start())`\n * \u2014 so hot reloads don't re-trigger it while you edit, and an agent kicks off one run when ready.\n *\n * The message is the JSON-parsed value of what `send` was given (or the raw string if it isn't\n * JSON; `undefined` for a bare `typebulb send <file>`). A non-`undefined` return value (awaited)\n * becomes the reply `send --wait` prints on stdout \u2014 JSON-serializable, at most one handler\n * replying \u2014 the structured read-back for self-tests. Returns an unsubscribe function. Inert in\n * an embedded bulb (no sender) \u2014 the handler is registered but never fires.\n *\n * @param handler - Called with each pushed message; may return a JSON-serializable reply.\n * @returns An unsubscribe function.\n */\n onMessage(handler: (message: any) => unknown): () => void;\n /**\n * General-purpose AI call. `tb.ai(opts)` resolves with the full text; `tb.ai.stream(opts)`\n * returns an async iterable of {@link AiChunk} deltas you consume with `for await`.\n *\n * @returns Promise resolving to { text: string }\n * @throws On rate limit, network error, or provider error\n */\n ai: {\n (options: {\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>;\n system?: string;\n /** Reasoning effort hint: 0=minimal, 1=low, 2=med, 3=high. Mapped to each provider's native mechanism (OpenAI/OpenRouter reasoning effort, Gemini thinking budget, Anthropic adaptive thinking). 0 minimizes reasoning \u2014 a floor, not a guaranteed \"off\": some models still think a little at 0, and adaptive models already self-skip at 1 (low). Level 1 (low) is the sensible default for most work; reach for 0 only when you truly want minimal deliberation. Omit for the model's own default. */\n effort?: 0 | 1 | 2 | 3;\n provider?: string;\n model?: string;\n /** Enable/disable web search. Default: on for BYOK, always off for free model. */\n webSearch?: boolean;\n /** Abort the request. On abort the promise rejects / the stream ends. */\n signal?: AbortSignal;\n }): Promise<{ text: string }>;\n /**\n * Streaming counterpart of `tb.ai()`. Yields `{ kind: \"text\" | \"reasoning\", text }` deltas\n * as they arrive; break the loop (or abort `signal`) to cancel and stop the upstream.\n *\n * `kind: \"reasoning\"` deltas only arrive when you pass `effort: 1-3` AND use a\n * thinking-capable model; otherwise the stream is `text`-only.\n *\n * @example\n * let answer = \"\";\n * for await (const c of tb.ai.stream({ messages })) {\n * if (c.kind === \"text\") answer += c.text;\n * }\n */\n stream(options: {\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>;\n system?: string;\n /** Reasoning effort hint: 0=minimal, 1=low, 2=med, 3=high. Mapped to each provider's native mechanism (OpenAI/OpenRouter reasoning effort, Gemini thinking budget, Anthropic adaptive thinking). 0 minimizes reasoning \u2014 a floor, not a guaranteed \"off\": some models still think a little at 0, and adaptive models already self-skip at 1 (low). Level 1 (low) is the sensible default for most work; reach for 0 only when you truly want minimal deliberation. Omit for the model's own default. */\n effort?: 0 | 1 | 2 | 3;\n provider?: string;\n model?: string;\n /** Enable/disable web search. Default: on for BYOK, always off for free model. */\n webSearch?: boolean;\n /** Abort the request. On abort the promise rejects / the stream ends. */\n signal?: AbortSignal;\n }): AsyncIterable<AiChunk>;\n };\n /**\n * Local filesystem access (CLI only).\n *\n * Relative paths resolve against the bulb's folder (`tb.dir` \u2014\n * `<bulb-dir>/<filename-stem>/`, created on demand), so\n * `tb.fs.write('results.json')` lands beside the bulb. `../` reaches sibling\n * bulbs' folders; everything stays confined to the project (the launch cwd).\n * Throws in editor/published mode.\n */\n fs: {\n /** Read a file as UTF-8 text. Throws if the file is not valid UTF-8 \u2014 use readBytes for binary. */\n read(path: string): Promise<string>;\n /** Read a file as raw bytes. */\n readBytes(path: string): Promise<Uint8Array>;\n /** Write text or raw bytes to a file. Creates parent directories if needed. */\n write(path: string, content: string | Uint8Array): Promise<boolean>;\n };\n /**\n * The bulb's folder \u2014 absolute path to `<bulb-dir>/<filename-stem>/`\n * (or its `batches/<name>/` folder when the run is scoped with `--batch`).\n *\n * For interop only (handing a path to `server.ts` or a spawned tool):\n * `tb.fs` already resolves relative paths against it, so bulb code writing\n * its own files never needs it. CLI only \u2014 throws in editor/published/embedded mode.\n */\n readonly dir: string;\n /**\n * Returns AI models available to the current user.\n * Models are filtered by the user's configured API keys.\n * If no keys are configured, returns only the courtesy model.\n */\n models(): Promise<Array<{\n /** Provider protocol: \"anthropic\", \"openai\", \"gemini\", \"openrouter\" */\n provider: string;\n /** Model identifier, e.g. \"claude-sonnet-4-6\" */\n name: string;\n /** Human-readable display name, e.g. \"Sonnet 4.6\" */\n friendlyName: string;\n /** Provider display name, e.g. \"Anthropic\" */\n providerName: string;\n /** True on the .env-configured default model (TB_AI_PROVIDER + TB_AI_MODEL); absent otherwise */\n default?: boolean;\n }>>;\n /**\n * Whether the user's own AI keys back `tb.ai`. False means only the\n * quota-limited courtesy model is available (or no AI at all) \u2014 a bulb\n * making many AI calls should check this and show a \"use your own keys\"\n * notice instead of running.\n */\n hasOwnKeys(): Promise<boolean>;\n /**\n * The bulb's theme override (`<html data-theme>`).\n *\n * - Get: the current override \u2014 `'dark'` | `'light'`, or `undefined` when\n * following the OS preference.\n * - Set `'dark'`/`'light'` to force and persist it (per-bulb); set\n * `undefined` to clear the override and follow the OS again.\n *\n * Drives `<html data-theme>`, so render off `html[data-theme=\"\u2026\"]` selectors\n * (or observe the attribute) rather than reading `tb.theme`.\n */\n theme: 'light' | 'dark' | undefined;\n /**\n * The mode this bulb is running in.\n *\n * - `'local'` \u2014 Running via the typebulb CLI\n * - `'editor'` \u2014 Running in the typebulb.com editor\n * - `'published'` \u2014 Running as a published/standalone bulb on typebulb.com\n * - `'embedded'` \u2014 Running as a bulb embedded inside another bulb (sandboxed,\n * client-only: AI, filesystem, and server RPC are unavailable)\n */\n mode: 'local' | 'editor' | 'published' | 'embedded';\n};\n";
13
13
  /** Typebulb globals available in Node-side code (server.ts).
14
14
  * Only what carries a bulb-specific rule Node can't know — tb.ai, tb.fs, tb.dir (TB-FS.md);
15
- * the browser-only helpers are intentionally absent. Must match serverTb.ts's runtime surface. */
16
- export declare const serverTbTypings = "\n/** A single streamed delta from `tb.ai.stream()`. Discriminated by `kind`. */\ntype AiChunk =\n | { kind: \"text\"; text: string }\n | { kind: \"reasoning\"; text: string };\n\n/**\n * Typebulb utilities namespace (server-side).\n * Type `tb.` to discover available helpers.\n */\ndeclare const tb: {\n /**\n * General-purpose AI call. `tb.ai(opts)` resolves with the full text; `tb.ai.stream(opts)`\n * returns an async iterable of {@link AiChunk} deltas you consume with `for await`.\n *\n * @returns Promise resolving to { text: string }\n * @throws On rate limit, network error, or provider error\n */\n ai: {\n (options: {\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>;\n system?: string;\n /** Reasoning effort hint: 0=minimal, 1=low, 2=med, 3=high. Mapped to each provider's native mechanism (OpenAI/OpenRouter reasoning effort, Gemini thinking budget, Anthropic adaptive thinking). 0 minimizes reasoning \u2014 a floor, not a guaranteed \"off\": some models still think a little at 0, and adaptive models already self-skip at 1 (low). Level 1 (low) is the sensible default for most work; reach for 0 only when you truly want minimal deliberation. Omit for the model's own default. */\n effort?: 0 | 1 | 2 | 3;\n provider?: string;\n model?: string;\n /** Enable/disable web search. Default: on for BYOK, always off for free model. */\n webSearch?: boolean;\n /** Abort the request. On abort the promise rejects / the stream ends. */\n signal?: AbortSignal;\n }): Promise<{ text: string }>;\n /**\n * Streaming counterpart of `tb.ai()`. Yields `{ kind: \"text\" | \"reasoning\", text }` deltas\n * as they arrive; break the loop (or abort `signal`) to cancel and stop the upstream.\n *\n * `kind: \"reasoning\"` deltas only arrive when you pass `effort: 1-3` AND use a\n * thinking-capable model; otherwise the stream is `text`-only.\n *\n * @example\n * let answer = \"\";\n * for await (const c of tb.ai.stream({ messages })) {\n * if (c.kind === \"text\") answer += c.text;\n * }\n */\n stream(options: {\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>;\n system?: string;\n /** Reasoning effort hint: 0=minimal, 1=low, 2=med, 3=high. Mapped to each provider's native mechanism (OpenAI/OpenRouter reasoning effort, Gemini thinking budget, Anthropic adaptive thinking). 0 minimizes reasoning \u2014 a floor, not a guaranteed \"off\": some models still think a little at 0, and adaptive models already self-skip at 1 (low). Level 1 (low) is the sensible default for most work; reach for 0 only when you truly want minimal deliberation. Omit for the model's own default. */\n effort?: 0 | 1 | 2 | 3;\n provider?: string;\n model?: string;\n /** Enable/disable web search. Default: on for BYOK, always off for free model. */\n webSearch?: boolean;\n /** Abort the request. On abort the promise rejects / the stream ends. */\n signal?: AbortSignal;\n }): AsyncIterable<AiChunk>;\n };\n /**\n * Local filesystem access (CLI only).\n *\n * Relative paths resolve against the bulb's folder (`tb.dir` \u2014\n * `<bulb-dir>/<filename-stem>/`, created on demand), so\n * `tb.fs.write('results.json')` lands beside the bulb. `../` reaches sibling\n * bulbs' folders; everything stays confined to the project (the launch cwd).\n * Throws in editor/published mode.\n */\n fs: {\n /** Read a file as UTF-8 text. Throws if the file is not valid UTF-8 \u2014 use readBytes for binary. */\n read(path: string): Promise<string>;\n /** Read a file as raw bytes. */\n readBytes(path: string): Promise<Uint8Array>;\n /** Write text or raw bytes to a file. Creates parent directories if needed. */\n write(path: string, content: string | Uint8Array): Promise<boolean>;\n };\n /**\n * The bulb's folder \u2014 absolute path to `<bulb-dir>/<filename-stem>/`\n * (or its `batches/<name>/` folder when the run is scoped with `--batch`).\n *\n * For interop only (handing a path to `server.ts` or a spawned tool):\n * `tb.fs` already resolves relative paths against it, so bulb code writing\n * its own files never needs it. CLI only \u2014 throws in editor/published/embedded mode.\n */\n readonly dir: string;\n /**\n * Returns AI models available to the current user.\n * Models are filtered by the user's configured API keys.\n * If no keys are configured, returns only the courtesy model.\n */\n models(): Promise<Array<{\n /** Provider protocol: \"anthropic\", \"openai\", \"gemini\", \"openrouter\" */\n provider: string;\n /** Model identifier, e.g. \"claude-sonnet-4-6\" */\n name: string;\n /** Human-readable display name, e.g. \"Sonnet 4.6\" */\n friendlyName: string;\n /** Provider display name, e.g. \"Anthropic\" */\n providerName: string;\n /** True on the .env-configured default model (TB_AI_PROVIDER + TB_AI_MODEL); absent otherwise */\n default?: boolean;\n }>>;\n /**\n * Whether the user's own AI keys back `tb.ai`. False means only the\n * quota-limited courtesy model is available (or no AI at all) \u2014 a bulb\n * making many AI calls should check this and show a \"use your own keys\"\n * notice instead of running.\n */\n hasOwnKeys(): Promise<boolean>;\n /**\n * The mode this bulb is running in.\n *\n * - `'local'` \u2014 Running via the typebulb CLI\n * - `'editor'` \u2014 Running in the typebulb.com editor\n * - `'published'` \u2014 Running as a published/standalone bulb on typebulb.com\n * - `'embedded'` \u2014 Running as a bulb embedded inside another bulb (sandboxed,\n * client-only: AI, filesystem, and server RPC are unavailable)\n */\n mode: 'local' | 'editor' | 'published' | 'embedded';\n};\n";
15
+ * plus the tb.log uniformity exception (serverTb.ts). The browser-only helpers are intentionally
16
+ * absent. Must match serverTb.ts's runtime surface. */
17
+ export declare const serverTbTypings = "\n/** A single streamed delta from `tb.ai.stream()`. Discriminated by `kind`. */\ntype AiChunk =\n | { kind: \"text\"; text: string }\n | { kind: \"reasoning\"; text: string };\n\n/**\n * Typebulb utilities namespace (server-side).\n * Type `tb.` to discover available helpers.\n */\ndeclare const tb: {\n /**\n * Print to the CLI's stdout \u2014 the same channel as `console.log` here (the server's console IS\n * the bulb's log). One log verb across blocks: page-side `tb.log` reaches this same stdout.\n */\n log(...args: any[]): void;\n /**\n * General-purpose AI call. `tb.ai(opts)` resolves with the full text; `tb.ai.stream(opts)`\n * returns an async iterable of {@link AiChunk} deltas you consume with `for await`.\n *\n * @returns Promise resolving to { text: string }\n * @throws On rate limit, network error, or provider error\n */\n ai: {\n (options: {\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>;\n system?: string;\n /** Reasoning effort hint: 0=minimal, 1=low, 2=med, 3=high. Mapped to each provider's native mechanism (OpenAI/OpenRouter reasoning effort, Gemini thinking budget, Anthropic adaptive thinking). 0 minimizes reasoning \u2014 a floor, not a guaranteed \"off\": some models still think a little at 0, and adaptive models already self-skip at 1 (low). Level 1 (low) is the sensible default for most work; reach for 0 only when you truly want minimal deliberation. Omit for the model's own default. */\n effort?: 0 | 1 | 2 | 3;\n provider?: string;\n model?: string;\n /** Enable/disable web search. Default: on for BYOK, always off for free model. */\n webSearch?: boolean;\n /** Abort the request. On abort the promise rejects / the stream ends. */\n signal?: AbortSignal;\n }): Promise<{ text: string }>;\n /**\n * Streaming counterpart of `tb.ai()`. Yields `{ kind: \"text\" | \"reasoning\", text }` deltas\n * as they arrive; break the loop (or abort `signal`) to cancel and stop the upstream.\n *\n * `kind: \"reasoning\"` deltas only arrive when you pass `effort: 1-3` AND use a\n * thinking-capable model; otherwise the stream is `text`-only.\n *\n * @example\n * let answer = \"\";\n * for await (const c of tb.ai.stream({ messages })) {\n * if (c.kind === \"text\") answer += c.text;\n * }\n */\n stream(options: {\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>;\n system?: string;\n /** Reasoning effort hint: 0=minimal, 1=low, 2=med, 3=high. Mapped to each provider's native mechanism (OpenAI/OpenRouter reasoning effort, Gemini thinking budget, Anthropic adaptive thinking). 0 minimizes reasoning \u2014 a floor, not a guaranteed \"off\": some models still think a little at 0, and adaptive models already self-skip at 1 (low). Level 1 (low) is the sensible default for most work; reach for 0 only when you truly want minimal deliberation. Omit for the model's own default. */\n effort?: 0 | 1 | 2 | 3;\n provider?: string;\n model?: string;\n /** Enable/disable web search. Default: on for BYOK, always off for free model. */\n webSearch?: boolean;\n /** Abort the request. On abort the promise rejects / the stream ends. */\n signal?: AbortSignal;\n }): AsyncIterable<AiChunk>;\n };\n /**\n * Local filesystem access (CLI only).\n *\n * Relative paths resolve against the bulb's folder (`tb.dir` \u2014\n * `<bulb-dir>/<filename-stem>/`, created on demand), so\n * `tb.fs.write('results.json')` lands beside the bulb. `../` reaches sibling\n * bulbs' folders; everything stays confined to the project (the launch cwd).\n * Throws in editor/published mode.\n */\n fs: {\n /** Read a file as UTF-8 text. Throws if the file is not valid UTF-8 \u2014 use readBytes for binary. */\n read(path: string): Promise<string>;\n /** Read a file as raw bytes. */\n readBytes(path: string): Promise<Uint8Array>;\n /** Write text or raw bytes to a file. Creates parent directories if needed. */\n write(path: string, content: string | Uint8Array): Promise<boolean>;\n };\n /**\n * The bulb's folder \u2014 absolute path to `<bulb-dir>/<filename-stem>/`\n * (or its `batches/<name>/` folder when the run is scoped with `--batch`).\n *\n * For interop only (handing a path to `server.ts` or a spawned tool):\n * `tb.fs` already resolves relative paths against it, so bulb code writing\n * its own files never needs it. CLI only \u2014 throws in editor/published/embedded mode.\n */\n readonly dir: string;\n /**\n * Returns AI models available to the current user.\n * Models are filtered by the user's configured API keys.\n * If no keys are configured, returns only the courtesy model.\n */\n models(): Promise<Array<{\n /** Provider protocol: \"anthropic\", \"openai\", \"gemini\", \"openrouter\" */\n provider: string;\n /** Model identifier, e.g. \"claude-sonnet-4-6\" */\n name: string;\n /** Human-readable display name, e.g. \"Sonnet 4.6\" */\n friendlyName: string;\n /** Provider display name, e.g. \"Anthropic\" */\n providerName: string;\n /** True on the .env-configured default model (TB_AI_PROVIDER + TB_AI_MODEL); absent otherwise */\n default?: boolean;\n }>>;\n /**\n * Whether the user's own AI keys back `tb.ai`. False means only the\n * quota-limited courtesy model is available (or no AI at all) \u2014 a bulb\n * making many AI calls should check this and show a \"use your own keys\"\n * notice instead of running.\n */\n hasOwnKeys(): Promise<boolean>;\n /**\n * The mode this bulb is running in.\n *\n * - `'local'` \u2014 Running via the typebulb CLI\n * - `'editor'` \u2014 Running in the typebulb.com editor\n * - `'published'` \u2014 Running as a published/standalone bulb on typebulb.com\n * - `'embedded'` \u2014 Running as a bulb embedded inside another bulb (sandboxed,\n * client-only: AI, filesystem, and server RPC are unavailable)\n */\n mode: 'local' | 'editor' | 'published' | 'embedded';\n};\n";
17
18
  //# sourceMappingURL=tbTypings.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tbTypings.d.ts","sourceRoot":"","sources":["../../dts/src/tbTypings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkQH,kEAAkE;AAClE,eAAO,MAAM,eAAe,g6WAO3B,CAAA;AAED;;mGAEmG;AACnG,eAAO,MAAM,eAAe,mtLAO3B,CAAA"}
1
+ {"version":3,"file":"tbTypings.d.ts","sourceRoot":"","sources":["../../dts/src/tbTypings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA2QH,kEAAkE;AAClE,eAAO,MAAM,eAAe,0tXAO3B,CAAA;AASD;;;wDAGwD;AACxD,eAAO,MAAM,eAAe,s8LAO3B,CAAA"}
@@ -224,7 +224,7 @@ const onMessage = `
224
224
  /**
225
225
  * Subscribe to a value pushed from the terminal via \`typebulb send <file> [message]\`.
226
226
  *
227
- * The dual of \`tb.server.log\` (data out): a value sent *in* from the CLI, no \`--trust\` required.
227
+ * The dual of \`tb.log\` (data out): a value sent *in* from the CLI, no \`--trust\` required.
228
228
  * Use it to start expensive work on demand instead of on load — e.g. \`tb.onMessage(() => start())\`
229
229
  * — so hot reloads don't re-trigger it while you edit, and an agent kicks off one run when ready.
230
230
  *
@@ -238,13 +238,21 @@ const onMessage = `
238
238
  * @returns An unsubscribe function.
239
239
  */
240
240
  onMessage(handler: (message: any) => unknown): () => void;`;
241
+ const log = `
242
+ /**
243
+ * Print to the CLI's stdout — the bulb's log channel, read back with \`typebulb logs <file>\`.
244
+ *
245
+ * Ungated: needs no \`server.ts\` block and no \`--trust\`, so a Restricted client-only bulb can
246
+ * instrument itself. Args cross to the CLI as JSON; where no CLI serves the page (web, embedded,
247
+ * or a transport failure) it falls back to the browser console. Works in \`server.ts\` too (same
248
+ * as \`console.log\` there).
249
+ */
250
+ log(...args: any[]): void;`;
241
251
  const clientServerProxy = `
242
252
  /**
243
253
  * Server-side function proxy.
244
254
  *
245
255
  * In the CLI, calls exported functions from the \`**server.ts**\` section.
246
- * \`tb.server.log(...)\` is a built-in that prints to CLI stdout (falls back to console.log on web).
247
- * User exports override built-ins of the same name.
248
256
  *
249
257
  * A normal export is awaited for its result (\`await tb.server.fn()\`). An \`async function*\`
250
258
  * export streams: \`for await (const chunk of tb.server.gen())\`. The call object supports both;
@@ -257,18 +265,25 @@ export const clientTbTypings = `${aiChunkType}
257
265
  * Typebulb utilities namespace.
258
266
  * Type \`tb.\` to discover available helpers.
259
267
  */
260
- declare const tb: {${dataAndJson}${clientOnlyMembers}${insight}${clientServerProxy}${onMessage}${ai}${fs}${dir}${models}${theme}${mode}
268
+ declare const tb: {${dataAndJson}${clientOnlyMembers}${insight}${log}${clientServerProxy}${onMessage}${ai}${fs}${dir}${models}${theme}${mode}
261
269
  };
262
270
  `;
271
+ const serverLog = `
272
+ /**
273
+ * Print to the CLI's stdout — the same channel as \`console.log\` here (the server's console IS
274
+ * the bulb's log). One log verb across blocks: page-side \`tb.log\` reaches this same stdout.
275
+ */
276
+ log(...args: any[]): void;`;
263
277
  /** Typebulb globals available in Node-side code (server.ts).
264
278
  * Only what carries a bulb-specific rule Node can't know — tb.ai, tb.fs, tb.dir (TB-FS.md);
265
- * the browser-only helpers are intentionally absent. Must match serverTb.ts's runtime surface. */
279
+ * plus the tb.log uniformity exception (serverTb.ts). The browser-only helpers are intentionally
280
+ * absent. Must match serverTb.ts's runtime surface. */
266
281
  export const serverTbTypings = `${aiChunkType}
267
282
  /**
268
283
  * Typebulb utilities namespace (server-side).
269
284
  * Type \`tb.\` to discover available helpers.
270
285
  */
271
- declare const tb: {${ai}${fs}${dir}${models}${mode}
286
+ declare const tb: {${serverLog}${ai}${fs}${dir}${models}${mode}
272
287
  };
273
288
  `;
274
289
  //# sourceMappingURL=tbTypings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tbTypings.js","sourceRoot":"","sources":["../../dts/src/tbTypings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,GAAG;;;;;;;;;;;uCAWmB,CAAA;AAEvC,MAAM,OAAO,GAAG;;;;;;;;;yCASyB,CAAA;AAEzC,2DAA2D;AAC3D,MAAM,SAAS,GAAG;;;;;;;;;;;IAWd,CAAA;AAEJ,oGAAoG;AACpG,MAAM,WAAW,GAAG;;;;;CAKnB,CAAA;AAED,MAAM,EAAE,GAAG;;;;;;;;;OASJ,SAAS;;;;;;;;;;;;;;aAcH,SAAS;KACjB,CAAA;AAEL,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;kCAwBmB,CAAA;AAElC,MAAM,KAAK,GAAG;;;;;;;;;;;;uCAYyB,CAAA;AAEvC,MAAM,IAAI,GAAG;;;;;;;;;;uDAU0C,CAAA;AAEvD,MAAM,EAAE,GAAG;;;;;;;;;;;;;;;;;KAiBN,CAAA;AAEL,MAAM,GAAG,GAAG;;;;;;;;;wBASY,CAAA;AAExB,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAmEA,CAAA;AAE1B,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;6DAiB2C,CAAA;AAE7D,MAAM,iBAAiB,GAAG;;;;;;;;;;;;iFAYuD,CAAA;AAEjF,kEAAkE;AAClE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,WAAW;;;;;qBAKxB,WAAW,GAAG,iBAAiB,GAAG,OAAO,GAAG,iBAAiB,GAAG,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI;;CAErI,CAAA;AAED;;mGAEmG;AACnG,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,WAAW;;;;;qBAKxB,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,MAAM,GAAG,IAAI;;CAEjD,CAAA"}
1
+ {"version":3,"file":"tbTypings.js","sourceRoot":"","sources":["../../dts/src/tbTypings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,GAAG;;;;;;;;;;;uCAWmB,CAAA;AAEvC,MAAM,OAAO,GAAG;;;;;;;;;yCASyB,CAAA;AAEzC,2DAA2D;AAC3D,MAAM,SAAS,GAAG;;;;;;;;;;;IAWd,CAAA;AAEJ,oGAAoG;AACpG,MAAM,WAAW,GAAG;;;;;CAKnB,CAAA;AAED,MAAM,EAAE,GAAG;;;;;;;;;OASJ,SAAS;;;;;;;;;;;;;;aAcH,SAAS;KACjB,CAAA;AAEL,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;kCAwBmB,CAAA;AAElC,MAAM,KAAK,GAAG;;;;;;;;;;;;uCAYyB,CAAA;AAEvC,MAAM,IAAI,GAAG;;;;;;;;;;uDAU0C,CAAA;AAEvD,MAAM,EAAE,GAAG;;;;;;;;;;;;;;;;;KAiBN,CAAA;AAEL,MAAM,GAAG,GAAG;;;;;;;;;wBASY,CAAA;AAExB,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAmEA,CAAA;AAE1B,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;6DAiB2C,CAAA;AAE7D,MAAM,GAAG,GAAG;;;;;;;;;6BASiB,CAAA;AAE7B,MAAM,iBAAiB,GAAG;;;;;;;;;;iFAUuD,CAAA;AAEjF,kEAAkE;AAClE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,WAAW;;;;;qBAKxB,WAAW,GAAG,iBAAiB,GAAG,OAAO,GAAG,GAAG,GAAG,iBAAiB,GAAG,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI;;CAE3I,CAAA;AAED,MAAM,SAAS,GAAG;;;;;6BAKW,CAAA;AAE7B;;;wDAGwD;AACxD,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,WAAW;;;;;qBAKxB,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,MAAM,GAAG,IAAI;;CAE7D,CAAA"}
@@ -11,6 +11,13 @@ export interface ParsedBulb {
11
11
  frontmatter: BulbFrontmatter;
12
12
  /** Block contents keyed by filename (e.g. `code.tsx`). */
13
13
  files: Map<string, string>;
14
+ /**
15
+ * 1-based line number, in the `.bulb.md`, of each block's FIRST content line (the line after its
16
+ * opening fence), keyed by filename. A bulb is a container: every tool inside it — tsc, lint, a
17
+ * browser stack trace — reports block coordinates, while the only file the user can open and link
18
+ * to is the bulb. This is the offset that maps one to the other (TB-CLI.md, One coordinate space).
19
+ */
20
+ starts: Map<string, number>;
14
21
  /** Structural defects tolerated during parse (an unterminated fence); empty when well-formed. */
15
22
  warnings: string[];
16
23
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../format/src/parse.ts"],"names":[],"mappings":"AAAA,uGAAuG;AAEvG,OAAO,EAAE,KAAK,aAAa,EAAsC,MAAM,eAAe,CAAA;AAOtF,eAAO,MAAM,aAAa,QAAsB,CAAA;AAGhD,wGAAwG;AACxG,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,MAAsC,CAAA;AAEnF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,eAAe,CAAA;IAC5B,0DAA0D;IAC1D,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1B,iGAAiG;IACjG,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,mDAAmD;AACnD,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;AAEvE,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAqE5D;AA6CD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAE/D;AAED;;sGAEsG;AACtG,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAkBjE;AAED,wFAAwF;AACxF,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,CAKvD"}
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../format/src/parse.ts"],"names":[],"mappings":"AAAA,uGAAuG;AAEvG,OAAO,EAAE,KAAK,aAAa,EAAsC,MAAM,eAAe,CAAA;AAOtF,eAAO,MAAM,aAAa,QAAsB,CAAA;AAGhD,wGAAwG;AACxG,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,MAAsC,CAAA;AAEnF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,eAAe,CAAA;IAC5B,0DAA0D;IAC1D,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1B;;;;;OAKG;IACH,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3B,iGAAiG;IACjG,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,mDAAmD;AACnD,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;AAEvE,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAwE5D;AA6CD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAE/D;AAED;;sGAEsG;AACtG,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAkBjE;AAED,wFAAwF;AACxF,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,CAKvD"}
@@ -31,6 +31,7 @@ export function parseBulb(content) {
31
31
  return null;
32
32
  // Parse file sections
33
33
  const files = new Map();
34
+ const starts = new Map();
34
35
  const warnings = [];
35
36
  // Where the body ends: bumped to the line past each captured block's closing fence. Starts at the
36
37
  // first line after the frontmatter, so a block-less bulb reports that.
@@ -55,6 +56,7 @@ export function parseBulb(content) {
55
56
  }
56
57
  const fence = fenceMatch[1];
57
58
  i++;
59
+ const startLine = i + 1; // 1-based: the first line inside the fence
58
60
  const contentLines = [];
59
61
  const closeRe = fenceCloseRe(fence);
60
62
  while (i < lines.length && !lines[i]?.match(closeRe)) {
@@ -65,13 +67,14 @@ export function parseBulb(content) {
65
67
  i++; // Skip closing fence (no-op past EOF)
66
68
  warnings.push(...blockWarnings(filename, contentLines, terminated));
67
69
  files.set(filename, contentLines.join('\n'));
70
+ starts.set(filename, startLine);
68
71
  bodyEndLine = i;
69
72
  }
70
73
  else {
71
74
  i++;
72
75
  }
73
76
  }
74
- return { frontmatter, files, warnings, bodyEndLine };
77
+ return { frontmatter, files, warnings, bodyEndLine, starts };
75
78
  }
76
79
  catch {
77
80
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../format/src/parse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../format/src/parse.ts"],"names":[],"mappings":"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"}