typebulb 0.55.3 → 0.55.4
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 +2 -2
- package/SKILL.md +4 -4
- package/dist/index.js +4 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -229,7 +229,7 @@ One exception: if `TYPEBULB_MIRROR=1` is set in your environment, the user is pr
|
|
|
229
229
|
|
|
230
230
|
- **First, can it even run inline?** A bulb needing `tb.ai`, `tb.infer`, `tb.fs`, or `server.ts` must be **local** — inline bulbs are client-only, so those calls fail there. The choice below is only for client-only bulbs.
|
|
231
231
|
- **Is anyone watching?** An inline bulb only renders live when the agent mirror is open; with none it shows as raw text. `npx typebulb agent` starts the mirror if needed and prints its link — share it with the user; don't make the user start anything.
|
|
232
|
-
- **Something to see right now, in the flow of the conversation** — a chart of some numbers, a quick simulation, an illustrative widget. → **inline**: emit it in a `bulb` block
|
|
232
|
+
- **Something to see right now, in the flow of the conversation** — a chart of some numbers, a quick simulation, an illustrative widget. → **inline**: emit it in a `bulb` block, straight into the reply. Don't draft it as a `.bulb.md` and test it first: a broken one reports its own error back to you (below), and the user expects a snappy response with an inline bulb.
|
|
233
233
|
- **A tool worth keeping** — something to reuse, run on its own, or refine over several turns. → **local**: write a `.bulb.md` file run with `npx typebulb`. An inline block is throwaway and can't be edited in place, so it's the wrong fit for anything iterative.
|
|
234
234
|
|
|
235
235
|
### Emitting an inline bulb
|
|
@@ -279,7 +279,7 @@ That one launch *is* the loop: the server watches the file, so every save recomp
|
|
|
279
279
|
- **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.
|
|
280
280
|
- **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`.) Its first line is the page's geometry — viewport, content size, and a fits-or-overflows verdict — so an unwanted scrollbar shows up in the first read.
|
|
281
281
|
- **Measuring layout** — `typebulb send <file> 'tb:rect button "Pass"'` prints that control's viewport-relative rect as JSON (`{x, y, width, height, viewport}`, integers): how big something ended up, whether two things align, whether one is offscreen — arithmetic on rects, no probe handler. Only what the outline names is measurable; give a structural container a `role` **and** an `aria-label` (`<div role="group" aria-label="board">`) to measure it — a label alone leaves it invisible.
|
|
282
|
-
- **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>`.
|
|
282
|
+
- **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. The click is synthetic, so a handler needing user activation (a clipboard write, fullscreen) does nothing and reports nothing. 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>`.
|
|
283
283
|
- **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).
|
|
284
284
|
- **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.
|
|
285
285
|
- **Reading a canvas** — `typebulb send <file> tb:png` writes the page's canvas to a PNG (a stable per-bulb path under `~/.typebulb/`, overwritten each read) and prints the path — rendered truth for a bulb whose output is drawn, with no probe handler and nothing disturbed. One canvas needs no name; several take `tb:png "<name>"` — an `aria-label` on the canvas, or `role="img" aria-label="…"` on the container when a chart library owns the canvas. A WebGL/WebGPU canvas without `preserveDrawingBuffer` reads back blank outside its own frame — capture during the draw instead.
|
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.55.
|
|
4
|
+
version: 0.55.4
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
> Generated from typebulb v0.55.
|
|
7
|
+
> Generated from typebulb v0.55.4. `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
|
|
|
@@ -237,7 +237,7 @@ One exception: if `TYPEBULB_MIRROR=1` is set in your environment, the user is pr
|
|
|
237
237
|
|
|
238
238
|
- **First, can it even run inline?** A bulb needing `tb.ai`, `tb.infer`, `tb.fs`, or `server.ts` must be **local** — inline bulbs are client-only, so those calls fail there. The choice below is only for client-only bulbs.
|
|
239
239
|
- **Is anyone watching?** An inline bulb only renders live when the agent mirror is open; with none it shows as raw text. `npx typebulb agent` starts the mirror if needed and prints its link — share it with the user; don't make the user start anything.
|
|
240
|
-
- **Something to see right now, in the flow of the conversation** — a chart of some numbers, a quick simulation, an illustrative widget. → **inline**: emit it in a `bulb` block
|
|
240
|
+
- **Something to see right now, in the flow of the conversation** — a chart of some numbers, a quick simulation, an illustrative widget. → **inline**: emit it in a `bulb` block, straight into the reply. Don't draft it as a `.bulb.md` and test it first: a broken one reports its own error back to you (below), and the user expects a snappy response with an inline bulb.
|
|
241
241
|
- **A tool worth keeping** — something to reuse, run on its own, or refine over several turns. → **local**: write a `.bulb.md` file run with `npx typebulb`. An inline block is throwaway and can't be edited in place, so it's the wrong fit for anything iterative.
|
|
242
242
|
|
|
243
243
|
### Emitting an inline bulb
|
|
@@ -287,7 +287,7 @@ That one launch *is* the loop: the server watches the file, so every save recomp
|
|
|
287
287
|
- **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.
|
|
288
288
|
- **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`.) Its first line is the page's geometry — viewport, content size, and a fits-or-overflows verdict — so an unwanted scrollbar shows up in the first read.
|
|
289
289
|
- **Measuring layout** — `typebulb send <file> 'tb:rect button "Pass"'` prints that control's viewport-relative rect as JSON (`{x, y, width, height, viewport}`, integers): how big something ended up, whether two things align, whether one is offscreen — arithmetic on rects, no probe handler. Only what the outline names is measurable; give a structural container a `role` **and** an `aria-label` (`<div role="group" aria-label="board">`) to measure it — a label alone leaves it invisible.
|
|
290
|
-
- **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>`.
|
|
290
|
+
- **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. The click is synthetic, so a handler needing user activation (a clipboard write, fullscreen) does nothing and reports nothing. 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>`.
|
|
291
291
|
- **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).
|
|
292
292
|
- **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.
|
|
293
293
|
- **Reading a canvas** — `typebulb send <file> tb:png` writes the page's canvas to a PNG (a stable per-bulb path under `~/.typebulb/`, overwritten each read) and prints the path — rendered truth for a bulb whose output is drawn, with no probe handler and nothing disturbed. One canvas needs no name; several take `tb:png "<name>"` — an `aria-label` on the canvas, or `role="img" aria-label="…"` on the container when a chart library owns the canvas. A WebGL/WebGPU canvas without `preserveDrawingBuffer` reads back blank outside its own frame — capture during the draw instead.
|
package/dist/index.js
CHANGED
|
@@ -248,7 +248,7 @@ ${t.comment}`:t.comment}this.doc.range[2]=t.offset;break}default:this.errors.pus
|
|
|
248
248
|
`),c=i.filter(u=>u.type==="tool_use").map(u=>({id:u.id??"",name:u.name??"",input:u.input??{}}));if(o||a||c.length){let u=Date.parse(e.timestamp??""),d=!isNaN(u)&&u>=t;r.push({type:"assistant",text:o,thinking:a,tools:c,live:d})}let l=e.message?.usage??e.usage,f=l&&{in:l.input_tokens??0,out:l.output_tokens??0,cached:l.cache_read_input_tokens??0,cacheCreate:l.cache_creation_input_tokens??0};return{events:r,usage:f,model:e.message?.model}}return{events:r}}chainWorking(e){let t;for(let o of e)(o.type==="user"||o.type==="assistant")&&(t=o);if(!t)return!1;if(t.type==="user"){try{let o=t.message?.content,a=typeof o=="string"?o:Array.isArray(o)?o.filter(l=>l&&l.type==="text").map(l=>l.text??"").join(""):"";if(!(Array.isArray(o)&&o.some(l=>l&&l.type==="tool_result"))&&a.trim()&&xt(a)==="")return!1}catch{}return!0}let s=(Array.isArray(t.message?.content)?t.message.content:[]).filter(o=>o.type==="tool_use").map(o=>o.id);if(s.length===0)return!1;let i=new Set;for(let o of e){let a=o.message?.content;if(Array.isArray(a))for(let c of a)c.type==="tool_result"&&c.tool_use_id&&i.add(c.tool_use_id)}return s.some(o=>o&&!i.has(o))}sessionAlive(e){return zE(e)}readPreview(e){return VE(e)}searchText(e){if(!e||Hr(e)||e.type!=="user"&&e.type!=="assistant")return"";let t=e.message?.content,r="";if(typeof t=="string")r=xt(t);else if(Array.isArray(t)){let s=t;r=e.type==="user"?s.map(Ll).filter(Boolean).join(" "):s.filter(i=>i.type==="text"&&typeof i.text=="string").map(i=>i.text).join(" ")}return r.replace(/\s+/g," ").trim()}}});import{statSync as GE,readdirSync as XE,openSync as QE,readSync as ZE,closeSync as eA,existsSync as tA}from"fs";import{basename as nA,join as Dl,resolve as rA}from"path";import{homedir as qm}from"os";function iA(n){let e=n.trimStart();return sA.some(t=>e.startsWith(t))}function Vr(n,e){return Array.isArray(n)?n.map(t=>typeof t?.text=="string"?e&&iA(t.text)?"":be(t.text):t?.type==="input_image"&&typeof t.image_url=="string"&&t.image_url.startsWith("data:")?``:"").filter(Boolean).join(`
|
|
249
249
|
`):""}function oA(n){return typeof n=="string"?be(n):Vr(n,!1)}function aA(n){let e=n??"";for(let t of[/tools\.shell_command\((\{[\s\S]*?\})\)/,/tools\.shell_command\((\{[\s\S]*\})\)/]){let r=t.exec(e);if(r)try{return JSON.parse(r[1])}catch{}}return{script:e}}function cA(n){if(typeof n=="string"&&n)try{let e=JSON.parse(n);if(e&&typeof e=="object"&&!Array.isArray(e))return e}catch{}return{arguments:n??""}}function Km(n,e){let t;try{t=QE(n,"r")}catch{return}try{let r=Buffer.alloc(e),s=ZE(t,r,0,e,0);return{text:r.subarray(0,s).toString("utf8"),bytes:s}}finally{eA(t)}}function lA(n){let t=Km(n,65536);if(t===void 0)return;let r=t.text.indexOf(`
|
|
250
250
|
`);if(r<0)return t.bytes>=65536?"":void 0;try{let s=JSON.parse(t.text.slice(0,r));return s?.type==="session_meta"&&typeof s.payload?.cwd=="string"?s.payload.cwd:""}catch{return""}}var sA,Jm,_n,jl=v(()=>{"use strict";Wr();Wi();sA=["<permissions instructions>","<apps_instructions>","<plugins_instructions>","<skills_instructions>","<recommended_plugins>","<environment_context>","<user_instructions>"];Jm=n=>{let e=rA(n);return process.platform==="win32"?e.toLowerCase():e},_n=class extends kt{constructor(t=Dl(qm(),".codex","sessions")){super();this.root=t}displayName="Codex Mirror";#e=0;#s;#t=new Map;detectsSelf(){return!!process.env.CODEX_THREAD_ID}detectsInstalled(){return tA(Dl(qm(),".codex"))}sessionsDir(t){return this.root}listSessionFiles(t){let r=Jm(t),s=[];for(let i of this.#r()){let o;try{let c=GE(i);if(!c.isFile())continue;o=c.mtimeMs}catch{continue}let a=this.#t.get(i);if(a===void 0){if(a=lA(i),a===void 0)continue;this.#t.set(i,a)}Jm(a)===r&&s.push({sessionId:nA(i,".jsonl"),file:i,mtime:o})}return s}#r(){let t=[],r=s=>{try{return XE(s).map(i=>Dl(s,i))}catch{return[]}};for(let s of r(this.root))for(let i of r(s))for(let o of r(i))for(let a of r(o))a.endsWith(".jsonl")&&t.push(a);return t}parseEntry(t){let r;try{r=JSON.parse(t)}catch{return null}return!r||typeof r.type!="string"?null:r}idOf(t){return t.ord===void 0&&(t.ord=String(this.#e++),t.parent=this.#s,this.#s=t.ord),t.ord}parentOf(t){return t.parent}timestampOf(t){return t.timestamp}isSidechain(t){return!1}isLeafType(t){return!0}isRecoveryNoise(t){return!1}apply(t,r){let s=[],i=t.payload;if(!i)return{events:s};let o=()=>{let a=Date.parse(t.timestamp??"");return!isNaN(a)&&a>=r};if(t.type==="response_item"){if(i.type==="message"){if(i.role==="user"){let a=Vr(i.content,!0).trim();a&&s.push({type:"user",text:a})}else if(i.role==="assistant"){let a=Vr(i.content,!1);a&&s.push({type:"assistant",text:a,thinking:"",tools:[],live:o()})}return{events:s}}if(i.type==="reasoning"){let a=Vr(i.summary,!1);return a&&s.push({type:"assistant",text:"",thinking:a,tools:[],live:o()}),{events:s}}if(i.type==="custom_tool_call"||i.type==="function_call"){let a=i.type==="custom_tool_call"?aA(i.input):cA(i.arguments);return s.push({type:"assistant",text:"",thinking:"",tools:[{id:i.call_id??"",name:i.name??"",input:a}],live:o()}),{events:s}}if(i.type==="custom_tool_call_output"||i.type==="function_call_output"){let a=oA(i.output);return s.push({type:"tool_result",id:i.call_id??"",content:a,isError:!1,digest:Le(a)}),{events:s}}return{events:s}}if(t.type==="event_msg"){if(i.type==="token_count"){let a=i.info?.last_token_usage;if(!a)return{events:s};let c={in:Math.max(0,(a.input_tokens??0)-(a.cached_input_tokens??0)),out:a.output_tokens??0,cached:a.cached_input_tokens??0,cacheCreate:a.cache_write_input_tokens??0};return{events:s,usage:c}}return{events:s}}return t.type==="turn_context"?{events:s,model:i.model}:{events:s}}chainWorking(t){let r=!1;for(let s of t){if(s.type!=="event_msg")continue;let i=s.payload?.type;i==="task_started"?r=!0:(i==="task_complete"||i==="turn_aborted")&&(r=!1)}return r}sessionAlive(){}readPreview(t){for(let r of(Km(t,256*1024)?.text??"").split(`
|
|
251
|
-
`))if(r.includes('"user_message"'))try{let s=JSON.parse(r);if(s?.type==="event_msg"&&s.payload?.type==="user_message"&&typeof s.payload.message=="string"){let i=s.payload.message.replace(/\s+/g," ").trim();if(i)return i.slice(0,200)}}catch{}return""}searchText(t){if(t?.type!=="response_item"||t.payload?.type!=="message")return"";let r=t.payload.role;return r!=="user"&&r!=="assistant"?"":Vr(t.payload.content,r==="user").replace(/\s+/g," ").trim()}}});import{realpathSync as uA}from"fs";import{createHash as dA}from"crypto";import{join as Vi,resolve as fA}from"path";import{homedir as pA}from"os";function Et(){let n=process.env.TYPEBULB_SERVERS_DIR;return n?Vi(n,".."):Vi(pA(),".typebulb")}function et(){Wm||(Wm=!0,console.error(`${Et()} not writable \u2014 continuing stateless: ports won't stick, caches stay cold, and typebulb logs/wait/send/stop may not see this run`))}function tt(){return process.env.TYPEBULB_SERVERS_DIR||Vi(Et(),"servers")}function Hm(n){let e=X(n),t=dA("sha1").update(e).digest("hex").slice(0,8),r=e.slice(e.lastIndexOf("/")+1).replace(/\.bulb\.md$/,"");return Vi(Et(),"canvas",`${r}-${t}.png`)}function X(n){let e=fA(n),t=e;try{t=uA.native(e)}catch{}return(process.platform==="win32"?t.toLowerCase():t).replace(/\\/g,"/")}function Ym(n,e){let t=X(n),r=X(e);return t.startsWith(r.endsWith("/")?r:r+"/")?!t.includes("/node_modules/"):!1}var Wm,At=v(()=>{"use strict";Wm=!1});var Be,zi=v(()=>{"use strict";Be="0.55.
|
|
251
|
+
`))if(r.includes('"user_message"'))try{let s=JSON.parse(r);if(s?.type==="event_msg"&&s.payload?.type==="user_message"&&typeof s.payload.message=="string"){let i=s.payload.message.replace(/\s+/g," ").trim();if(i)return i.slice(0,200)}}catch{}return""}searchText(t){if(t?.type!=="response_item"||t.payload?.type!=="message")return"";let r=t.payload.role;return r!=="user"&&r!=="assistant"?"":Vr(t.payload.content,r==="user").replace(/\s+/g," ").trim()}}});import{realpathSync as uA}from"fs";import{createHash as dA}from"crypto";import{join as Vi,resolve as fA}from"path";import{homedir as pA}from"os";function Et(){let n=process.env.TYPEBULB_SERVERS_DIR;return n?Vi(n,".."):Vi(pA(),".typebulb")}function et(){Wm||(Wm=!0,console.error(`${Et()} not writable \u2014 continuing stateless: ports won't stick, caches stay cold, and typebulb logs/wait/send/stop may not see this run`))}function tt(){return process.env.TYPEBULB_SERVERS_DIR||Vi(Et(),"servers")}function Hm(n){let e=X(n),t=dA("sha1").update(e).digest("hex").slice(0,8),r=e.slice(e.lastIndexOf("/")+1).replace(/\.bulb\.md$/,"");return Vi(Et(),"canvas",`${r}-${t}.png`)}function X(n){let e=fA(n),t=e;try{t=uA.native(e)}catch{}return(process.platform==="win32"?t.toLowerCase():t).replace(/\\/g,"/")}function Ym(n,e){let t=X(n),r=X(e);return t.startsWith(r.endsWith("/")?r:r+"/")?!t.includes("/node_modules/"):!1}var Wm,At=v(()=>{"use strict";Wm=!1});var Be,zi=v(()=>{"use strict";Be="0.55.4"});import{spawn as Vm}from"child_process";import{readdir as hA,readFile as Gm,writeFile as Xm,unlink as Fl,mkdir as mA}from"fs/promises";import{mkdirSync as Qm,writeFileSync as Gi,appendFileSync as gA,readFileSync as Ul}from"fs";import*as xe from"path";import{fileURLToPath as yA}from"url";function ql(n){return xe.join(tt(),`${n}.json`)}function Gr(n){return xe.join(tt(),`${n}.log`)}function Jl(n){return xe.join(tt(),`${n}.wait.json`)}function Zm(n){try{let e=JSON.parse(Ul(Jl(n),"utf8"));return e.cursors&&typeof e.cursors=="object"?e.cursors:{}}catch{return{}}}function Kl(n,e=""){let t=Zm(n)[e];return typeof t=="number"&&Number.isFinite(t)&&t>=0?t:void 0}function Xi(n,e,t=""){try{Qm(tt(),{recursive:!0});let r=Zm(n);r[t]=e,Gi(Jl(n),JSON.stringify({cursors:r}))}catch{}}function Qi(n){let e=Gr(n);try{Qm(tt(),{recursive:!0}),Gi(e,"")}catch{return()=>{}}let t=process.stdout.write.bind(process.stdout),r=process.stderr.write.bind(process.stderr),s=0,i=!1,o=a=>{if(!i)try{let c=typeof a=="string"?Buffer.from(a,"utf8"):Buffer.from(a);if(gA(e,c),s+=c.length,s>2*zm){let l=Ul(e),f=l.subarray(Math.max(0,l.length-zm));Gi(e,f),s=f.length}}catch{i=!0}};return process.stdout.write=((a,...c)=>(o(a),t(a,...c))),process.stderr.write=((a,...c)=>(o(a),r(a,...c))),()=>{process.stdout.write=t,process.stderr.write=r}}function eg(n){try{Gi(Gr(n),"")}catch{}}function He(n,e=0){try{let t=Ul(Gr(n)),r=e>=0&&e<=t.length?e:0;return{text:t.subarray(r).toString("utf8"),offset:t.length}}catch{return{text:"",offset:0}}}function Wl(n){return`\u2500\u2500 run ${n} \u2500\u2500 ${new Date().toTimeString().slice(0,8)}`}function wA(n){let e=bA.exec(n);return e?Number(e[1]):void 0}function tg(n,e){let t=n.split(`
|
|
252
252
|
`),r=[];if(t.forEach((o,a)=>{let c=wA(o);c!==void 0&&r.push({id:c,idx:a})}),!r.length)return e==="latest"?n:"";let s=e==="latest"?r[r.length-1]:r.find(o=>o.id===e);if(!s)return"";let i=r.find(o=>o.idx>s.idx);return t.slice(s.idx,i?i.idx:t.length).join(`
|
|
253
253
|
`)}function Hl(n){try{return process.kill(n,0),!0}catch(e){return e.code==="EPERM"}}async function ng(n){try{await mA(tt(),{recursive:!0}),await Xm(ql(n.pid),JSON.stringify({version:Be,...n}))}catch{et()}}async function rg(n,e){let t=ql(n);try{let r=JSON.parse(await Gm(t,"utf8"));if(r.denied===e)return;r.denied=e,await Xm(t,JSON.stringify(r))}catch{}}async function zr(n){await Fl(ql(n)).catch(()=>{}),await Fl(Gr(n)).catch(()=>{}),await Fl(Jl(n)).catch(()=>{})}async function Q(n){let e;try{e=await hA(tt())}catch{return[]}let t=[];return await Promise.all(e.map(async s=>{if(!/^\d+\.json$/.test(s))return;let i=parseInt(s,10),o;try{o=JSON.parse(await Gm(xe.join(tt(),s),"utf8"))}catch{await zr(i);return}o&&typeof o.pid=="number"&&Hl(o.pid)?t.push(o):await zr(i)})),(n?t.filter(s=>s.agent==null&&Ym(s.file,n)):t).sort((s,i)=>s.startedAt-i.startedAt)}async function Yl(n,e){let t=X(n);return(await Q()).find(r=>r.cwd!=null&&X(r.cwd)===t&&(e?r.agent===e:r.agent!=null))}async function Yt(n){try{process.kill(n,"SIGTERM")}catch{}await zr(n)}function Rn(n,e){let t=X(e);return n.filter(r=>r.agent==null&&r.pid!==process.pid&&X(r.file)===t)}async function Vl(n){let e=Rn(await Q(),n);for(let t of e)await Yt(t.pid);return e}function SA(n,e,t){(process.platform==="win32"?Vm("cmd",["/c","start","","/b",n,...e],{cwd:t,stdio:"ignore",windowsHide:!0}):Vm(n,e,{cwd:t,detached:!0,stdio:"ignore"})).unref()}function Xr(){return xe.join(xe.dirname(yA(import.meta.url)),"index.js")}function kA(n,e={}){return{command:process.execPath,args:[Xr(),...e.trust?["--trust"]:[],...e.batch?["--batch",e.batch]:[],...e.mode?["--mode",e.mode]:[],n,...e.open===!1?["--no-open"]:[]]}}function xA(n){return{command:process.execPath,args:[Xr(),`agent:${n}`,"--no-open"]}}async function sg(n,e,t,r){let s=await n();if(s)return s;SA(e.command,e.args,t);let i=Date.now()+2e4;for(;Date.now()<i;){await vA(150);let o=await n();if(o)return o}throw new Error(`Launched ${r} but it did not register within 20s.`)}async function Zi(n,e={}){let t=e.cwd??process.cwd(),r=xe.resolve(t,n),[s]=await Vl(r),i={...e,batch:e.batch??s?.batch,mode:e.mode??s?.mode};return sg(async()=>Rn(await Q(),r)[0],kA(n,i),t,xe.basename(n))}async function ig(n,e=process.cwd()){return sg(()=>Yl(e,n),xA(n),e,`the ${n} mirror`)}var zm,bA,vA,Ee=v(()=>{"use strict";At();zi();zm=1e6;bA=/^── run (\d+) ── /;vA=n=>new Promise(e=>setTimeout(e,n))});function In(n){return{...pf(n),server:n.files.get("server.ts")??""}}function eo(n){return!!n.server&&!n.code}var Qr=v(()=>{"use strict";Z();Z()});function to(n){let e=/^---[^\n]*\n([\s\S]*?)\n---/.exec(n),t=e?/^\s*name:\s*(.+?)\s*$/m.exec(e[1]):null;return t?t[1].replace(/^["']|["']$/g,""):void 0}function zl(n){return On(to(n)??"bulb")||"bulb"}var Gl=v(()=>{"use strict";Z()});import{transform as EA}from"sucrase";function Xl(n,e={}){let t=e.serverOnly?["typescript"]:["typescript","jsx"];try{let{code:r}=EA(n,{transforms:t,jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:r}}catch(r){return{code:"",error:String(r)}}}var og=v(()=>{});function Ql(n){let e=n.split(""),t=(i,o)=>{for(let a=i;a<o&&a<e.length;a++)e[a]!==`
|
|
254
254
|
`&&(e[a]=" ")},r=0,s="";for(;r<n.length;){let i=n[r],o=n[r+1];if(i==="/"&&o==="/"){let a=r;for(;a<n.length&&n[a]!==`
|
|
@@ -1624,6 +1624,7 @@ var TB_MIRROR_BLOCK = [
|
|
|
1624
1624
|
" • no need to end your reply with a mirror link",
|
|
1625
1625
|
" Reusable app/tool → write a .bulb.md",
|
|
1626
1626
|
" Show something inline → emit an inline bulb",
|
|
1627
|
+
" emit it with no .bulb.md draft first",
|
|
1627
1628
|
" Read the authoring skill before writing a bulb:",
|
|
1628
1629
|
" • " + TB_SKILL_PATH,
|
|
1629
1630
|
].join("\n");
|
|
@@ -1862,7 +1863,7 @@ data: ${JSON.stringify(a)}
|
|
|
1862
1863
|
`)?`
|
|
1863
1864
|
`:"";yb(r,i+`OPENROUTER_API_KEY=${e}
|
|
1864
1865
|
`)}}catch(i){return{ok:!1,error:Y(i)}}return process.env.OPENROUTER_API_KEY=e,wb(t,[".env"],"# secrets"),{ok:!0}}function nC(){if(!(!rr&&!Xe)){try{xb(z)}catch{}YP()}}function rC(n,e){return Ab.test(e)?"blocked by your OpenRouter data policy":n===401||n===403||/unauthor|invalid api key|no auth|forbidden/i.test(e)?"auth rejected \u2014 check your OpenRouter key":n===404||/not a valid model|no such model|unknown model|model not found/i.test(e)?"model not found on this route":n===429||/rate limit/i.test(e)?"rate limited":n===402||/insufficient|credit|quota|balance/i.test(e)?"out of credits / quota":e.slice(0,160)}function sC(n){if(Ab.test(n))return"This model's only provider(s) require prompt logging/training, which your OpenRouter account disallows by default. Allow it (or that provider) at openrouter.ai/settings/privacy, then probe again."}function iC(n,e,t){if(!n)return{works:null,read:0,note:t?`couldn't re-test on ${t} \u2014 caching unconfirmed`:"caching unconfirmed"};let r=Ed(e?.cache_read_input_tokens)||Ed(e?.prompt_tokens_details?.cached_tokens),s=e?.cache_read_input_tokens!==void 0||e?.cache_creation_input_tokens!==void 0||e?.prompt_tokens_details!==void 0;return r>0?{works:!0,read:r,note:`${r} tokens read from cache on the 2nd call`}:s?{works:!1,read:r,note:"no cache reads after a warm call \u2014 every turn re-bills the full context"}:{works:null,read:r,note:"route doesn't report cache usage \u2014 caching almost certainly not honored"}}async function oC({model:n}){let e=process.env.OPENROUTER_API_KEY;if(!e)return{ok:!1,error:"OPENROUTER_API_KEY not set \u2014 add a key first"};if(!n)return{ok:!1,error:"no model given"};if(Od(n))return{ok:!1,error:"Anthropic model \u2014 not offered or probed via OpenRouter"};let t=Date.now(),r=Array(350).fill("Caching probe filler sentence; its only purpose is to exceed the prompt-cache minimum token threshold.").join(" "),s={"content-type":"application/json",authorization:`Bearer ${e}`,"anthropic-version":"2023-06-01"},i={model:n,max_tokens:64,system:[{type:"text",text:r,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:"Reply with exactly: ok"}]},o=async a=>{let c=new AbortController,l=setTimeout(()=>c.abort(),2e4);try{let f=JSON.stringify(a?{...i,provider:vb(a)}:i),u=await fetch(Td,{method:"POST",signal:c.signal,headers:s,body:f}),d=await u.json().catch(()=>({}));return{r:u,j:d}}finally{clearTimeout(l)}};try{let{r:a,j:c}=await o();if(!a.ok){let A=c?.error?.message||c?.message||JSON.stringify(c).slice(0,300);return{ok:!0,callable:!1,status:a.status,ms:Date.now()-t,error:rC(a.status,A),restriction:sC(A)}}let l=typeof c?.provider=="string"?c.provider:void 0,f=c?.content?.find?.(A=>A.type==="text")?.text??c?.content?.[0]?.text??"ok",u=Ed(c?.usage?.cache_creation_input_tokens),{r:d,j:p}=await o(l),{works:m,read:h,note:y}=iC(d.ok,p?.usage,l);return m===!0&&l&&(Pd[n]=l,Xe===n&&(fn=l)),{ok:!0,callable:!0,status:a.status,ms:Date.now()-t,provider:l,sample:String(f).trim().slice(0,60),cache:{works:m,created:u,read:h,note:y}}}catch(a){let c=Y(a);return{ok:!0,callable:!1,ms:Date.now()-t,error:/abort/i.test(c)?"timed out (20s)":c}}}var LP,Td,MP,BP,bb,DP,xd,ua,da,aa,Od,rr,dn,Xe,fn,Es,As,Ts,Pd,Ed,vb,Ab,Tb=v(()=>{"use strict";Qn();Lt();LP="https://openrouter.ai/api",Td=`${LP}/v1/messages`,MP="typebulb-proxy-managed",BP="The typebulb model override was reverted to Anthropic, but this Claude Code session still points at the now-idle proxy. Reload the window (VS Code/Cursor: \u201CDeveloper: Reload Window\u201D) or relaunch `claude` in a terminal to return to your Anthropic subscription.",bb=["ANTHROPIC_BASE_URL","ANTHROPIC_AUTH_TOKEN"],DP=5e3,xd=["low","medium","high"],ua=n=>la(n,".claude","settings.local.json"),da=n=>la(n,".claude",".cc-switcher.json"),aa=n=>`http://127.0.0.1:${n}`;Od=n=>/^anthropic\//i.test(n)||/claude/i.test(n),rr=null,dn=null,Xe=null,fn=null,Es=null,As="unknown",Ts=1,Pd={},Ed=n=>typeof n=="number"?n:0,vb=n=>({order:[n],allow_fallbacks:!1});Ab=/data policy|no endpoints|no allowed providers|privacy|requires.*(training|logging|data)/i;(async function(){try{let e=Bt(da(z)),t=e?.active?.model;if(!t)return;let s=(Bt(ua(z))?.env||{}).ANTHROPIC_BASE_URL||"";if(!/127\.0\.0\.1|localhost/.test(s))return;let i=await Eb(t,e.active.provider??Pd[t]??null);console.log(`[switcher] re-adopted override after restart: ${t} via ${aa(i)}`)}catch(e){console.error("[switcher] boot reconcile failed",Y(e))}})()});var Pb={};Na(Pb,{attach:()=>hC,blockToMarkdown:()=>Hi,breakout:()=>cd,capText:()=>be,cleanUserText:()=>xt,clearSwitchModel:()=>eC,composerPasteRead:()=>mC,displayName:()=>aC,downloadSample:()=>bd,firstLineDigest:()=>Le,git:()=>Je,gitChangedFiles:()=>Qu,gitDiff:()=>Zu,info:()=>cC,isHiddenTurn:()=>Hr,launchBulb:()=>pd,listBreakouts:()=>ld,listBulbFiles:()=>dd,listMyBulbs:()=>vd,listSamples:()=>yd,listSessions:()=>dC,listSwitchModels:()=>GP,logInlineStatus:()=>uC,openFile:()=>ad,poll:()=>lC,predictTrustOf:()=>hd,probeModel:()=>oC,pullRemoteBulb:()=>Sd,pushLocalBulb:()=>kd,readBulbLog:()=>gd,repoRoot:()=>cn,saveOpenRouterKey:()=>tC,searchBulbs:()=>fd,searchSessions:()=>fC,sessionPeek:()=>pC,setBulbTrust:()=>md,setReasoning:()=>ZP,setSwitchModel:()=>QP,shutdownSwitcher:()=>nC,stopBreakout:()=>ud,summarizeTurn:()=>gC,switchState:()=>XP,toolResultDigest:()=>Bl});var Ob,aC,cC,lC,uC,dC,fC,pC,hC,mC,gC,Cb=v(()=>{"use strict";sa();Yi();oa();Ss();Tb();Yi();Wr();Ob=new Cn,aC=Ob.displayName,{info:cC,poll:lC,logInlineStatus:uC,listSessions:dC,searchSessions:fC,sessionPeek:pC,attach:hC,composerPasteRead:mC,summarizeTurn:gC}=nr(Ob)});var Rb={};Na(Rb,{attach:()=>EC,breakout:()=>cd,composerPasteRead:()=>AC,displayName:()=>yC,downloadSample:()=>bd,git:()=>Je,gitChangedFiles:()=>Qu,gitDiff:()=>Zu,info:()=>bC,launchBulb:()=>pd,listBreakouts:()=>ld,listBulbFiles:()=>dd,listMyBulbs:()=>vd,listSamples:()=>yd,listSessions:()=>SC,logInlineStatus:()=>vC,openFile:()=>ad,poll:()=>wC,predictTrustOf:()=>hd,pullRemoteBulb:()=>Sd,pushLocalBulb:()=>kd,readBulbLog:()=>gd,repoRoot:()=>cn,searchBulbs:()=>fd,searchSessions:()=>kC,sessionPeek:()=>xC,setBulbTrust:()=>md,stopBreakout:()=>ud,summarizeTurn:()=>TC});var _b,yC,bC,wC,vC,SC,kC,xC,EC,AC,TC,Ib=v(()=>{"use strict";sa();jl();oa();Ss();_b=new _n,yC=_b.displayName,{info:bC,poll:wC,logInlineStatus:vC,listSessions:SC,searchSessions:kC,sessionPeek:xC,attach:EC,composerPasteRead:AC,summarizeTurn:TC}=nr(_b)});import{readFileSync as OC,writeFileSync as PC,mkdirSync as CC}from"fs";import{homedir as _C}from"os";import*as fa from"path";async function Lb(){try{let n=await fetch(new URL("/api/tags",$b()).toString(),{signal:AbortSignal.timeout(RC)});return n.ok?((await n.json()).models??[]).map(t=>t.name).filter(t=>!!t):[]}catch{return[]}}function Mb(n){let e;try{e=OC(n,"utf-8")}catch{return{json:void 0,unreadable:!1}}try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t)){let r=t;return{json:r,unreadable:"providers"in r&&!Cd(r)}}}catch{}return{json:void 0,unreadable:!0}}function Cd(n){let e=n?.providers;return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function IC(n){let e=Cd(n);if(!e||!("ollama"in e))return null;let t=e.ollama?.models;return Array.isArray(t)?t.map(r=>r?.id).filter(r=>typeof r=="string"):[]}async function Bb(){let{json:n,unreadable:e}=Mb(Nb());return e?{installed:[],configured:null}:{installed:await Lb(),configured:IC(n)}}async function Db(){let n=await Lb();return n.length?NC(Nb(),n,$b()):{ok:!1,error:"Ollama is not running (or has no models installed)"}}function NC(n,e,t){let{json:r,unreadable:s}=Mb(n);if(s)return{ok:!1,error:`could not parse ${n} \u2014 edit the ollama provider there yourself`};let i={...r??{},providers:{...Cd(r)??{},ollama:{baseUrl:`${t}/v1`,api:"openai-completions",apiKey:"ollama",models:e.map(o=>({id:o}))}}};try{CC(fa.dirname(n),{recursive:!0}),PC(n,JSON.stringify(i,null,2)+`
|
|
1865
|
-
`)}catch(o){return{ok:!1,error:`could not write ${n}: ${Y(o)}`}}return{ok:!0,count:e.length}}var RC,Nb,$b,jb=v(()=>{"use strict";Lt();Qn();RC=1500,Nb=()=>fa.join(_C(),".pi","agent","models.json"),$b=()=>Jn(process.env.OLLAMA_HOST??"http://localhost:11434")});var Ub={};Na(Ub,{attach:()=>UC,breakout:()=>cd,composerFiles:()=>WC,composerNew:()=>KC,composerPaste:()=>VC,composerPasteRead:()=>zC,composerRpc:()=>YC,composerSend:()=>qC,composerStop:()=>JC,composerUiRespond:()=>HC,displayName:()=>$C,downloadSample:()=>bd,git:()=>Je,gitChangedFiles:()=>Qu,gitDiff:()=>Zu,info:()=>LC,launchBulb:()=>pd,listBreakouts:()=>ld,listBulbFiles:()=>dd,listMyBulbs:()=>vd,listSamples:()=>yd,listSessions:()=>DC,logInlineStatus:()=>BC,ollamaOffer:()=>Bb,ollamaSync:()=>Db,openFile:()=>ad,poll:()=>MC,predictTrustOf:()=>hd,pullRemoteBulb:()=>Sd,pushLocalBulb:()=>kd,readBulbLog:()=>gd,repoRoot:()=>cn,searchBulbs:()=>fd,searchSessions:()=>jC,sessionPeek:()=>FC,setBulbTrust:()=>md,shutdownComposer:()=>XC,stopBreakout:()=>ud,summarizeTurn:()=>GC});var Fb,$C,LC,MC,BC,DC,jC,FC,UC,qC,JC,KC,WC,HC,YC,VC,zC,GC,XC,qb=v(()=>{"use strict";sa();Gu();oa();Ss();jb();Fb=new er,$C=Fb.displayName,{info:LC,poll:MC,logInlineStatus:BC,listSessions:DC,searchSessions:jC,sessionPeek:FC,attach:UC,composerSend:qC,composerStop:JC,composerNew:KC,composerFiles:WC,composerUiRespond:HC,composerRpc:YC,composerPaste:VC,composerPasteRead:zC,summarizeTurn:GC,shutdownComposer:XC}=nr(Fb)});import*as tv from"fs/promises";import*as dt from"path";Ds();Z();function Il(n){if(!Re.includes(n))throw new Error(`Unknown block kind '${n}' (one of: ${Re.join(", ")})`);return n}function Bm(n){let e=[];for(let t of n){let r=t.indexOf("=");if(r<=0||r===t.length-1)throw new Error(`Expected <kind>=<source>, got '${t}' (e.g. data=results.json, or data=- for stdin)`);let s=Il(t.slice(0,r));if(e.some(i=>i.kind===s))throw new Error(`Duplicate block kind '${s}' \u2014 each block can be written once per invocation`);e.push({kind:s,source:t.slice(r+1)})}if(e.filter(t=>t.source==="-").length>1)throw new Error("Only one <kind>=- can read stdin");return e}Yi();jl();Gu();var pa={claude:{adapter:()=>new Cn,server:()=>Promise.resolve().then(()=>(Cb(),Pb))},codex:{adapter:()=>new _n,server:()=>Promise.resolve().then(()=>(Ib(),Rb))},pi:{adapter:()=>new er,server:()=>Promise.resolve().then(()=>(qb(),Ub))}};function Jb(n){return n in pa}function sr(){return Object.keys(pa)}function Kb(){return Object.fromEntries(Object.entries(pa).map(([n,e])=>[n,e.adapter]))}function Wb(n){return pa[n].server()}var Os=Kb();function Hb(){for(let n of Object.values(Os))try{n().ensureHarnessSupport()}catch{}}function pn(){for(let n of Object.keys(Os))try{if(Os[n]().detectsSelf())return n}catch{}}function Yb(n){let e=sr(),t=new Map(e.filter(i=>Os[i]).map(i=>[i,Os[i]()]));for(let[i,o]of t)if(o.detectsSelf())return{name:i};let r=[...t].filter(([,i])=>i.detectsInstalled()).map(([i])=>i);if(r.length===0)return{name:e[0]};if(r.length===1)return{name:r[0]};let s=i=>t.get(i).listSessionFiles(n).length>0;return{ambiguous:[...r].sort((i,o)=>Number(s(o))-Number(s(i)))}}var Rd=5e3;function _d(n){try{return n()}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(1)}}function Vb(n){let t={subcommand:"run",file:"",watch:!0,open:!(process.env.TERM_PROGRAM==="vscode"||pn()!==void 0),server:!1,trust:!1,noTrust:!1,force:!1,follow:!1,clear:!1,help:!1,version:!1,callArgs:[],hasArgsFlag:!1},r=["call","check","predict","logs","wait","stop","trust","untrust","models","slug","send","pull","push","get","put"],s=n[0];if(s==="agent"||s?.startsWith("agent:")){t.subcommand="agent";let o=s.indexOf(":");if(o!==-1){let a=s.slice(o+1);a&&(t.agentTarget=a)}n=n.slice(1)}else s&&r.includes(s)&&(t.subcommand=s,n=n.slice(1));let i=[];for(let o=0;o<n.length;o++){let a=n[o];if(a==="--help"||a==="-h")t.help=!0;else if(a==="--version"||a==="-V")t.version=!0;else if(a==="--no-watch")t.watch=!1;else if(a==="--open")t.open=!0;else if(a==="--no-open")t.open=!1;else if(a==="--server")t.server=!0;else if(a==="--trust")t.trust=!0;else if(a==="--no-trust")t.noTrust=!0;else if(a==="--force")t.force=!0;else if(a==="--mode"){let c=n[++o];(!c||c.startsWith("-"))&&(console.error("Missing value for --mode (e.g. --mode staging)"),process.exit(1)),t.mode=c}else if(a==="--batch"){let c=n[++o];(!c||c.startsWith("-"))&&(console.error("Missing value for --batch (a batch name, e.g. --batch pilot)"),process.exit(1));let l=c.replace(/[\\/]+$/,"");(!l||/[\\/]/.test(l)||l==="."||l==="..")&&(console.error(`Invalid --batch value: ${c} (a single folder name \u2014 no path separators or dot segments)`),process.exit(1)),t.batch=l}else if(a==="--follow"||a==="-f")t.follow=!0;else if(a==="--clear")t.clear=!0;else if(a==="--run"){let c=n[++o];if(c==="latest")t.run="latest";else{let l=parseInt(c,10);(isNaN(l)||l<1)&&(console.error(`Invalid --run value: ${c} (a run number, or 'latest')`),process.exit(1)),t.run=l}}else if(a==="--bulbs")t.stopScope="bulbs";else if(a==="--agent")t.stopScope="agent";else if(a==="--global")t.stopScope="global";else if(a==="--match"){let c=n[++o];c===void 0&&(console.error("Missing value for --match (a literal substring new log lines must contain)"),process.exit(1)),t.match=c}else if(a==="--timeout"){let c=parseInt(n[++o],10);(isNaN(c)||c<=0)&&(console.error(`Invalid --timeout value: ${n[o]} (seconds)`),process.exit(1)),t.timeoutSec=c}else if(a==="--wait"||a.startsWith("--wait="))if(a.startsWith("--wait=")){let c=parseInt(a.slice(7),10);(isNaN(c)||c<=0)&&(console.error(`Invalid --wait value: ${a.slice(7)} (milliseconds)`),process.exit(1)),t.sendWaitMs=c}else t.sendWaitMs=Rd;else if(a==="--lines"||a==="-n"){let c=parseInt(n[++o],10);(isNaN(c)||c<0)&&(console.error(`Invalid --lines value: ${n[o]}`),process.exit(1)),t.lines=c}else if(a==="--port"||a==="-p"){let c=n[++o],l=parseInt(c,10);isNaN(l)&&(console.error(`Invalid port: ${c}`),process.exit(1)),t.port=l}else if(a==="--replace"||a.startsWith("--replace=")){let c=a.startsWith("--replace=")?a.slice(10):n[++o]??"",l=_d(()=>rf(c));t.local&&(console.error(`--replace can only be used once (got '${t.local.name}' and '${l.name}')`),process.exit(1)),t.local=l}else if(a==="--args"||a.startsWith("--args=")){t.hasArgsFlag=!0;let c=a.startsWith("--args=")?a.slice(7):n[++o];c===void 0&&(console.error("Missing value for --args (a JSON array, or - to read it from stdin)"),process.exit(1)),t.argsJson=c}else if(!a.startsWith("-"))["call","send","get","put","slug"].includes(t.subcommand)?i.push(a):t.file=a;else{let c=t.subcommand==="call"?" (for a negative or dash-leading argument, use --args '<json-array>')":"";console.error(`Unknown option: ${a}${c}`),process.exit(1)}}return t.subcommand==="call"&&(i.length<2&&(console.error("Usage: typebulb call <file> <fn> [arg\u2026]"),process.exit(1)),t.file=i[0],t.fn=i[1],t.callArgs=i.slice(2)),t.subcommand==="send"&&(i.length<1&&(console.error("Usage: typebulb send <file> [message]"),process.exit(1)),t.file=i[0],t.sendMessage=i[1]),t.subcommand==="slug"&&(i.length||(console.error("Usage: typebulb slug <bulb name>"),process.exit(1)),t.slugName=i.join(" ")),t.subcommand==="get"&&(i.length!==2&&(console.error("Usage: typebulb get <file> <kind>"),process.exit(1)),t.file=i[0],t.blockKind=_d(()=>Il(i[1]))),t.subcommand==="put"&&(i.length<2&&(console.error("Usage: typebulb put <file> <kind>=<source> [<kind>=<source> \u2026]"),process.exit(1)),t.file=i[0],t.blockPairs=_d(()=>Bm(i.slice(1)))),t}function zb(){console.log(`
|
|
1866
|
+
`)}catch(o){return{ok:!1,error:`could not write ${n}: ${Y(o)}`}}return{ok:!0,count:e.length}}var RC,Nb,$b,jb=v(()=>{"use strict";Lt();Qn();RC=1500,Nb=()=>fa.join(_C(),".pi","agent","models.json"),$b=()=>Jn(process.env.OLLAMA_HOST??"http://localhost:11434")});var Ub={};Na(Ub,{attach:()=>UC,breakout:()=>cd,composerFiles:()=>WC,composerNew:()=>KC,composerPaste:()=>VC,composerPasteRead:()=>zC,composerRpc:()=>YC,composerSend:()=>qC,composerStop:()=>JC,composerUiRespond:()=>HC,displayName:()=>$C,downloadSample:()=>bd,git:()=>Je,gitChangedFiles:()=>Qu,gitDiff:()=>Zu,info:()=>LC,launchBulb:()=>pd,listBreakouts:()=>ld,listBulbFiles:()=>dd,listMyBulbs:()=>vd,listSamples:()=>yd,listSessions:()=>DC,logInlineStatus:()=>BC,ollamaOffer:()=>Bb,ollamaSync:()=>Db,openFile:()=>ad,poll:()=>MC,predictTrustOf:()=>hd,pullRemoteBulb:()=>Sd,pushLocalBulb:()=>kd,readBulbLog:()=>gd,repoRoot:()=>cn,searchBulbs:()=>fd,searchSessions:()=>jC,sessionPeek:()=>FC,setBulbTrust:()=>md,shutdownComposer:()=>XC,stopBreakout:()=>ud,summarizeTurn:()=>GC});var Fb,$C,LC,MC,BC,DC,jC,FC,UC,qC,JC,KC,WC,HC,YC,VC,zC,GC,XC,qb=v(()=>{"use strict";sa();Gu();oa();Ss();jb();Fb=new er,$C=Fb.displayName,{info:LC,poll:MC,logInlineStatus:BC,listSessions:DC,searchSessions:jC,sessionPeek:FC,attach:UC,composerSend:qC,composerStop:JC,composerNew:KC,composerFiles:WC,composerUiRespond:HC,composerRpc:YC,composerPaste:VC,composerPasteRead:zC,summarizeTurn:GC,shutdownComposer:XC}=nr(Fb)});import*as tv from"fs/promises";import*as dt from"path";Ds();Z();function Il(n){if(!Re.includes(n))throw new Error(`Unknown block kind '${n}' (one of: ${Re.join(", ")})`);return n}function Bm(n){let e=[];for(let t of n){let r=t.indexOf("=");if(r<=0||r===t.length-1)throw new Error(`Expected <kind>=<source>, got '${t}' (e.g. data=results.json, or data=- for stdin)`);let s=Il(t.slice(0,r));if(e.some(i=>i.kind===s))throw new Error(`Duplicate block kind '${s}' \u2014 each block can be written once per invocation`);e.push({kind:s,source:t.slice(r+1)})}if(e.filter(t=>t.source==="-").length>1)throw new Error("Only one <kind>=- can read stdin");return e}Yi();jl();Gu();var pa={claude:{adapter:()=>new Cn,server:()=>Promise.resolve().then(()=>(Cb(),Pb))},codex:{adapter:()=>new _n,server:()=>Promise.resolve().then(()=>(Ib(),Rb))},pi:{adapter:()=>new er,server:()=>Promise.resolve().then(()=>(qb(),Ub))}};function Jb(n){return n in pa}function sr(){return Object.keys(pa)}function Kb(){return Object.fromEntries(Object.entries(pa).map(([n,e])=>[n,e.adapter]))}function Wb(n){return pa[n].server()}var Os=Kb();function Hb(){for(let n of Object.values(Os))try{n().ensureHarnessSupport()}catch{}}function pn(){for(let n of Object.keys(Os))try{if(Os[n]().detectsSelf())return n}catch{}}function Yb(n){let e=sr(),t=new Map(e.filter(i=>Os[i]).map(i=>[i,Os[i]()]));for(let[i,o]of t)if(o.detectsSelf())return{name:i};let r=[...t].filter(([,i])=>i.detectsInstalled()).map(([i])=>i);if(r.length===0)return{name:e[0]};if(r.length===1)return{name:r[0]};let s=i=>t.get(i).listSessionFiles(n).length>0;return{ambiguous:[...r].sort((i,o)=>Number(s(o))-Number(s(i)))}}var Rd=5e3;function _d(n){try{return n()}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(1)}}function Vb(n){let t={subcommand:"run",file:"",watch:!0,open:!(process.env.TERM_PROGRAM==="vscode"||pn()!==void 0),server:!1,trust:!1,noTrust:!1,force:!1,follow:!1,clear:!1,help:!1,version:!1,callArgs:[],hasArgsFlag:!1},r=["call","check","predict","logs","wait","stop","trust","untrust","models","slug","send","pull","push","get","put"],s=n[0];if(s==="agent"||s?.startsWith("agent:")){t.subcommand="agent";let o=s.indexOf(":");if(o!==-1){let a=s.slice(o+1);a&&(t.agentTarget=a)}n=n.slice(1)}else s&&r.includes(s)&&(t.subcommand=s,n=n.slice(1));let i=[];for(let o=0;o<n.length;o++){let a=n[o];if(a==="--help"||a==="-h")t.help=!0;else if(a==="--version"||a==="-V")t.version=!0;else if(a==="--no-watch")t.watch=!1;else if(a==="--open")t.open=!0;else if(a==="--no-open")t.open=!1;else if(a==="--server")t.server=!0;else if(a==="--trust")t.trust=!0;else if(a==="--no-trust")t.noTrust=!0;else if(a==="--force")t.force=!0;else if(a==="--mode"){let c=n[++o];(!c||c.startsWith("-"))&&(console.error("Missing value for --mode (e.g. --mode staging)"),process.exit(1)),t.mode=c}else if(a==="--batch"){let c=n[++o];(!c||c.startsWith("-"))&&(console.error("Missing value for --batch (a batch name, e.g. --batch pilot)"),process.exit(1));let l=c.replace(/[\\/]+$/,"");(!l||/[\\/]/.test(l)||l==="."||l==="..")&&(console.error(`Invalid --batch value: ${c} (a single folder name \u2014 no path separators or dot segments)`),process.exit(1)),t.batch=l}else if(a==="--follow"||a==="-f")t.follow=!0;else if(a==="--clear")t.clear=!0;else if(a==="--run"){let c=n[++o];if(c==="latest")t.run="latest";else{let l=parseInt(c,10);(isNaN(l)||l<1)&&(console.error(`Invalid --run value: ${c} (a run number, or 'latest')`),process.exit(1)),t.run=l}}else if(a==="--bulbs")t.stopScope="bulbs";else if(a==="--agent")t.stopScope="agent";else if(a==="--global")t.stopScope="global";else if(a==="--match"){let c=n[++o];c===void 0&&(console.error("Missing value for --match (a literal substring new log lines must contain)"),process.exit(1)),t.match=c}else if(a==="--timeout"){let c=parseInt(n[++o],10);(isNaN(c)||c<=0)&&(console.error(`Invalid --timeout value: ${n[o]} (seconds)`),process.exit(1)),t.timeoutSec=c}else if(a==="--wait"||a.startsWith("--wait="))if(a.startsWith("--wait=")){let c=parseInt(a.slice(7),10);(isNaN(c)||c<=0)&&(console.error(`Invalid --wait value: ${a.slice(7)} (milliseconds)`),process.exit(1)),t.sendWaitMs=c}else t.sendWaitMs=Rd;else if(a==="--lines"||a==="-n"){let c=parseInt(n[++o],10);(isNaN(c)||c<0)&&(console.error(`Invalid --lines value: ${n[o]}`),process.exit(1)),t.lines=c}else if(a==="--port"||a==="-p"){let c=n[++o],l=parseInt(c,10);isNaN(l)&&(console.error(`Invalid port: ${c}`),process.exit(1)),t.port=l}else if(a==="--replace"||a.startsWith("--replace=")){let c=a.startsWith("--replace=")?a.slice(10):n[++o]??"",l=_d(()=>rf(c));t.local&&(console.error(`--replace can only be used once (got '${t.local.name}' and '${l.name}')`),process.exit(1)),t.local=l}else if(a==="--args"||a.startsWith("--args=")){t.hasArgsFlag=!0;let c=a.startsWith("--args=")?a.slice(7):n[++o];c===void 0&&(console.error("Missing value for --args (a JSON array, or - to read it from stdin)"),process.exit(1)),t.argsJson=c}else if(!a.startsWith("-")||a==="-"&&t.subcommand==="send")["call","send","get","put","slug"].includes(t.subcommand)?i.push(a):t.file=a;else{let c=t.subcommand==="call"?" (for a negative or dash-leading argument, use --args '<json-array>')":"";console.error(`Unknown option: ${a}${c}`),process.exit(1)}}return t.subcommand==="call"&&(i.length<2&&(console.error("Usage: typebulb call <file> <fn> [arg\u2026]"),process.exit(1)),t.file=i[0],t.fn=i[1],t.callArgs=i.slice(2)),t.subcommand==="send"&&(i.length<1&&(console.error("Usage: typebulb send <file> [message]"),process.exit(1)),t.file=i[0],t.sendMessage=i[1]),t.subcommand==="slug"&&(i.length||(console.error("Usage: typebulb slug <bulb name>"),process.exit(1)),t.slugName=i.join(" ")),t.subcommand==="get"&&(i.length!==2&&(console.error("Usage: typebulb get <file> <kind>"),process.exit(1)),t.file=i[0],t.blockKind=_d(()=>Il(i[1]))),t.subcommand==="put"&&(i.length<2&&(console.error("Usage: typebulb put <file> <kind>=<source> [<kind>=<source> \u2026]"),process.exit(1)),t.file=i[0],t.blockPairs=_d(()=>Bm(i.slice(1)))),t}function zb(){console.log(`
|
|
1866
1867
|
typebulb - Local bulb runner for Typebulb
|
|
1867
1868
|
|
|
1868
1869
|
Usage:
|
|
@@ -2243,7 +2244,7 @@ declare const tb: {${i_}${Zb}${nw}${rw}${ew}${tw}
|
|
|
2243
2244
|
`);await this.prefetchBareDeps(m,l,d,p,s);let h=c.format(),y=e===h?[e]:[e,h],A=y.some(S=>this.ambientlyDeclares(i,S));return A?this.markFileAmbient(d,f):p.push(...y.map(S=>({module:S,path:f}))),{pkg:e,mainPath:f,files:d,shims:p,ambient:A}}};uu();nt();Mn();ls();cu();Ln();import*as or from"path";var u_=or.join(ao,"pkg"),d_=or.join(ao,"files"),f_=or.join(ao,"negative.json"),Sa=class{pkgMem=new Map;fileMem=new Map;negativeCache=new Qt(new Bn(f_));async getCachedDts(e){if(this.pkgMem.has(e))return this.pkgMem.get(e);await ee();let t=await rt(cw(e));return this.pkgMem.set(e,t),t}async setCachedDts(e,t,r){let s={content:t,url:r};this.pkgMem.set(e,s),await va(async()=>{await ee(),await Ae(cw(e),JSON.stringify(s))})}async getCachedFile(e){if(this.fileMem.has(e))return this.fileMem.get(e);await ee();let t=await oo(lw(e));return this.fileMem.set(e,t),t}async setCachedFile(e,t){this.fileMem.set(e,t),await va(async()=>{await ee(),await Ae(lw(e),t)})}isNegative(e){return this.negativeCache.isNegative(e)}async recordNegative(e){await va(async()=>{await ee(),await this.negativeCache.recordNegative(e)})}clearNegative(e){return va(()=>this.negativeCache.clearNegative(e))}};async function va(n){try{await n()}catch{}}function cw(n){return or.join(u_,De(n)+".json")}function lw(n){return or.join(d_,De(n)+".txt")}Mn();var Dd;function p_(){return Dd||(Dd=new Cs({cache:new Sa,cdnClient:Rg,packageService:fo,versionResolver:_g})),Dd}var uw="file:///node_modules/";async function dw(n){let e=co(n.emitKey,"typecheck");await ee(),await fe.rm(e,{recursive:!0,force:!0}),await fe.mkdir(e,{recursive:!0});let t=y_(n.jsxImportSource,n.dependencies),r=await p_().resolve(n.code,n.dependencies,t),s=n.local?.name,i=s?r.filter(f=>f.pkg!==s):r,o=new Set;for(let f of i)for(let u of f.files){let d=ka(u.path);if(!d||o.has(d))continue;o.add(d);let p=ue.join(e,"node_modules",d);await fe.mkdir(ue.dirname(p),{recursive:!0}),await fe.writeFile(p,u.content,"utf8")}let a={};for(let f of i)for(let u of f.shims){let d=ka(u.path);d&&(a[u.module]=[`./node_modules/${d}`])}for(let f of i){if(f.ambient)continue;let u=ka(f.mainPath);u&&(a[f.pkg]=[`./node_modules/${u}`])}let c=new Set;for(let f of i)for(let u of f.files){if(!u.ambient)continue;let d=ka(u.path);d&&c.add(`node_modules/${d}`)}if(n.local){delete a[n.local.name];let f=await b_(n.local,e);f?a[n.local.name]=[`./node_modules/${n.local.name}/${f}`]:console.warn(` local: '${n.local.name}' ships no type defs; check cannot type against it.`)}let l=h_(n.jsxImportSource,a,[...c]);return await fe.writeFile(ue.join(e,"tsconfig.json"),JSON.stringify(l,null,2)+`
|
|
2244
2245
|
`,"utf8"),await fe.writeFile(ue.join(e,"code.tsx"),n.code,"utf8"),await fe.writeFile(ue.join(e,"tb.d.ts"),Ld,"utf8"),{dir:e}}var jd={target:"es2023",module:"esnext",moduleResolution:"bundler",strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0};function h_(n,e,t=[]){return{compilerOptions:{...jd,lib:m_([...Id,...Nd]),jsx:"react-jsx",jsxImportSource:n??"react",paths:e},include:["code.tsx","tb.d.ts",...t]}}function m_(n){return $d(n).map(e=>g_(e.name))}function g_(n){return n.split(".").map(e=>/^es\d+$/i.test(e)?e.toUpperCase():e==="dom"?"DOM":e==="esnext"?"ESNext":e.charAt(0).toUpperCase()+e.slice(1)).join(".")}function y_(n,e){let t=n??("react"in e?"react":void 0);return t?[`${t}/jsx-runtime`,`${t}/jsx-dev-runtime`]:[]}function ka(n){if(!n.startsWith(uw))return;let e=n.slice(uw.length),t=e.indexOf("/");if(!(t<0))return e.slice(t+1)}async function b_(n,e){if(!n.typesAbs)return;let t=ue.dirname(n.typesAbs),r=ue.join(e,"node_modules",n.name);for(let s of await w_(t)){let i=ue.join(r,ue.relative(t,s));await fe.mkdir(ue.dirname(i),{recursive:!0}),await fe.copyFile(s,i)}return ue.basename(n.typesAbs)}async function w_(n){let e=[];async function t(r){let s=await fe.readdir(r,{withFileTypes:!0});for(let i of s){let o=ue.join(r,i.name);i.isDirectory()?await t(o):/\.d\.ts(\.map)?$/.test(i.name)&&e.push(o)}}return await t(n),e}import*as Pe from"fs/promises";import*as ut from"path";import{existsSync as v_}from"fs";Mn();du();var S_="^22";async function fw(n){let e=co(n.emitKey,"typecheck-server");await ee(),await Pe.rm(e,{recursive:!0,force:!0}),await Pe.mkdir(e,{recursive:!0});let t=ut.join(n.bulbDir,".typebulb"),r=vo(n.server).filter(o=>o!==n.local?.name);await wo([`@types/node@${S_}`,...r],t,n.dependencies,{ignoreScripts:!0});let s=ut.join(t,"node_modules"),i=ut.join(e,"node_modules");return await x_(s,i),await Pe.writeFile(ut.join(e,"server.ts"),n.server,"utf8"),await Pe.writeFile(ut.join(e,"tb.d.ts"),Md,"utf8"),await Pe.writeFile(ut.join(e,"tsconfig.json"),JSON.stringify(k_(n.local),null,2)+`
|
|
2245
2246
|
`,"utf8"),{dir:e}}function k_(n){let e={...jd,lib:["ES2023"],types:["node"]};if(n?.typesAbs){let t=i=>i.replace(/\\/g,"/"),r=t(ut.dirname(n.typesAbs)),s=t(n.typesAbs).replace(/\.d\.ts$/,"");e.paths={[n.name]:[s],[`${n.name}/*`]:[`${r}/*`]}}return{compilerOptions:e,include:["server.ts","tb.d.ts"]}}async function x_(n,e){if(!v_(n)){await Pe.mkdir(e,{recursive:!0});return}await Pe.rm(e,{recursive:!0,force:!0});let t=process.platform==="win32"?"junction":"dir";await Pe.symlink(n,e,t)}no();Z();async function hw(n,e){let{bulb:t,config:r,warnings:s,starts:i}=await qe(n),o=Ce.basename(n),a=h=>i.get(h)??1;!t.code&&!t.server&&(console.error("Bulb has neither **code.tsx** nor **server.ts**; nothing to check."),process.exit(1));let c=!1,l=!1;for(let h of s)console.log(`structure ${h}`);s.length&&(c=!0);let f=Hn(Ce.resolve(n)),u=f?On(t.name):"";f&&u&&u!==f.slug&&(console.log(`naming filename '${f.slug}.bulb.md' doesn't match the title '${t.name}' \u2014 its slug derives to '${u}'. Rename the file to '${u}.bulb.md', or change name: to suit the filename.`),l=!0),t.code&&(c=pw(Zr(t.code,{target:"client",dependencies:r.dependencies??{},lineOffset:a("code.tsx")}),"client")||c),t.server&&(c=pw(Zr(t.server,{target:"server",lineOffset:a("server.ts")}),"server")||c);let d=R_([process.cwd(),Ce.dirname(n)]);if(!d){let h=Ce.relative(process.cwd(),n)||n;console.error("check: TypeScript not found \u2014 install it once, then re-run:"),console.error(" npm i -g typescript"),console.error(` typebulb check ${h}`),process.exit(2)}let p=[];if(t.code){let{dir:h}=await dw({code:t.code,dependencies:r.dependencies??{},jsxImportSource:r.ts?.jsxImportSource,emitKey:n,local:e});p.push({role:"client",dir:h})}if(t.server){let{dir:h}=await fw({server:t.server,bulbDir:Ce.dirname(n),emitKey:n,local:e?{name:e.name,typesAbs:e.typesAbs}:void 0,dependencies:r.dependencies});p.push({role:"server",dir:h})}for(let{role:h,dir:y}of p){let{stdout:A,exitCode:S}=await C_(d,y);for(let P of A.split(/\r?\n/))P.trim()&&console.log(`${h} ${P_(P,o,a)}`);S!==0&&(c=!0)}c&&process.exit(1);let m=[t.code&&"code.tsx",t.server&&"server.ts"].filter(Boolean).join(", ");console.error(l?`\u2713 type-checks (${m}) \u2014 see the naming warning above`:`\u2713 no issues (${m})`)}function pw(n,e){for(let t of n)for(let r of t.message.split(`
|
|
2246
|
-
`))console.log(`${e} ${r}`);return n.length>0}function P_(n,e,t){return n.replace(/\b(code\.tsx|server\.ts)\((\d+),(\d+)\)/g,(r,s,i,o)=>`${e}(${Number(i)+t(s)-1},${o})`)}function C_(n,e){return new Promise(t=>{let r=E_(process.execPath,[n,"--noEmit"],{cwd:e}),s="";r.stdout?.on("data",i=>{s+=i.toString()}),r.stderr?.on("data",i=>{s+=i.toString()}),r.on("close",i=>t({stdout:s,exitCode:i??1}))})}var __=T_(import.meta.url);function R_(n){let e=r=>{try{let s=__.resolve("typescript/package.json",{paths:r}),i=Ce.join(Ce.dirname(s),"lib","tsc.js");return O_(i)?i:void 0}catch{return}},t=e(n);if(t)return t;try{let r=A_("npm root -g",{encoding:"utf8"}).trim();return e([r])}catch{return}}ze();Fo();ys();async function mw(n,e){let{bulb:t}=await qe(n),r=Vn(t);if(on(n)){console.log("remembered-trusted \u2014 runs with filesystem / AI / server.ts automatically (`typebulb untrust` to revoke)."),r&&console.log(` (it uses ${r})`);return}r?(console.log(`This bulb appears to use ${r}; it runs Restricted unless you grant trust:`),console.log(` ${e}`)):console.log("No privileged capability detected \u2014 runs Restricted by default. (A clean scan is a hint, not a guarantee.)")}ys();import*as _s from"path";async function gw(n,e){if(!n){e||(console.error("Usage: typebulb untrust <file.bulb.md>"),process.exit(1));let r=ju();if(!r.length){console.log("No bulbs are remembered as trusted.");return}console.log("Trusted bulbs (run with fs/AI/server.ts without --trust):");for(let s of r)console.log(` ${s}`);return}let t=_s.resolve(n);t.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1));try{zn(t,e)}catch(r){console.error(r.message),process.exit(1)}console.log(e?`Trusted ${_s.basename(t)} \u2014 runs with fs / AI / server.ts (no --trust needed).`:`Untrusted ${_s.basename(t)} \u2014 runs Restricted.`),console.log(` ${t}`)}Ee();import*as ww from"readline";Fu();function Fd(n){let e=t=>r=>n?`\x1B[${t}m${r}\x1B[0m`:r;return{lit:e("38;5;70"),litLink:e("4;38;5;70"),brand:e("38;5;135")}}var I_=5e3,xa=()=>Math.round(performance.now()),yw=n=>n>=1e3?`${(n/1e3).toFixed(1)}s`:`${n}ms`;async function vw(n){let e=Yb(process.cwd()),t=xa();if("ambiguous"in e){let r=await N_(n,e.ambiguous);return r?bw(n,r,{boot:t,from:xa()}):$_(n,e.ambiguous)}return bw(n,e.name,{boot:t,from:xa()})}async function bw(n,e,t){let r,s;try{r=await ig(e)}catch(p){s=p instanceof Error?p.message:String(p)}let i=xa()-t.from,{lit:o,litLink:a,brand:c}=Fd(process.stdout.isTTY===!0),l=[" Read the authoring skill before writing a bulb:",` \u2022 ${o(bs())}`],f=r?[` Agent mirror (${e}) is live\u{1F4A1}`,` ${o("\u25CF")} ${a(r.url)}`," Inline bulbs render live here."," Agents:",` Reusable app/tool \u2192 write a ${o(".bulb.md")}`," Show something inline \u2192 emit an inline bulb",...e==="codex"?[" verify it this turn \u2014 foreground-wait, bounded:",` \u2022 ${o('typebulb wait agent --match "[inline <name>" --timeout 120')}`," raise the shell tool's timeout_ms to 130000"," (its 10s default kills even a clean ok)"]:[e==="pi"?" arm a wait for its render verdict \u2014 run it plainly:":" background a wait for its render verdict:",` \u2022 ${o('typebulb wait agent --match "[inline <name>"')}`],...l," End this reply with the mirror link above"," \u2022 easy to miss the link mid-message"]:[` The mirror did not start (${s})`,` \u25CF Start it manually: ${o(`npx typebulb agent:${e}`)}`," Agents:",...l],u=t.boot+i>I_?[` slow launch: boot ${yw(t.boot)} \xB7 mirror ${yw(i)}`]:[],d=[` ${c(`typebulb v${n}`)}`,...u,...f,""];process.stdout.write(d.join(`
|
|
2247
|
+
`))console.log(`${e} ${r}`);return n.length>0}function P_(n,e,t){return n.replace(/\b(code\.tsx|server\.ts)\((\d+),(\d+)\)/g,(r,s,i,o)=>`${e}(${Number(i)+t(s)-1},${o})`)}function C_(n,e){return new Promise(t=>{let r=E_(process.execPath,[n,"--noEmit"],{cwd:e}),s="";r.stdout?.on("data",i=>{s+=i.toString()}),r.stderr?.on("data",i=>{s+=i.toString()}),r.on("close",i=>t({stdout:s,exitCode:i??1}))})}var __=T_(import.meta.url);function R_(n){let e=r=>{try{let s=__.resolve("typescript/package.json",{paths:r}),i=Ce.join(Ce.dirname(s),"lib","tsc.js");return O_(i)?i:void 0}catch{return}},t=e(n);if(t)return t;try{let r=A_("npm root -g",{encoding:"utf8"}).trim();return e([r])}catch{return}}ze();Fo();ys();async function mw(n,e){let{bulb:t}=await qe(n),r=Vn(t);if(on(n)){console.log("remembered-trusted \u2014 runs with filesystem / AI / server.ts automatically (`typebulb untrust` to revoke)."),r&&console.log(` (it uses ${r})`);return}r?(console.log(`This bulb appears to use ${r}; it runs Restricted unless you grant trust:`),console.log(` ${e}`)):console.log("No privileged capability detected \u2014 runs Restricted by default. (A clean scan is a hint, not a guarantee.)")}ys();import*as _s from"path";async function gw(n,e){if(!n){e||(console.error("Usage: typebulb untrust <file.bulb.md>"),process.exit(1));let r=ju();if(!r.length){console.log("No bulbs are remembered as trusted.");return}console.log("Trusted bulbs (run with fs/AI/server.ts without --trust):");for(let s of r)console.log(` ${s}`);return}let t=_s.resolve(n);t.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1));try{zn(t,e)}catch(r){console.error(r.message),process.exit(1)}console.log(e?`Trusted ${_s.basename(t)} \u2014 runs with fs / AI / server.ts (no --trust needed).`:`Untrusted ${_s.basename(t)} \u2014 runs Restricted.`),console.log(` ${t}`)}Ee();import*as ww from"readline";Fu();function Fd(n){let e=t=>r=>n?`\x1B[${t}m${r}\x1B[0m`:r;return{lit:e("38;5;70"),litLink:e("4;38;5;70"),brand:e("38;5;135")}}var I_=5e3,xa=()=>Math.round(performance.now()),yw=n=>n>=1e3?`${(n/1e3).toFixed(1)}s`:`${n}ms`;async function vw(n){let e=Yb(process.cwd()),t=xa();if("ambiguous"in e){let r=await N_(n,e.ambiguous);return r?bw(n,r,{boot:t,from:xa()}):$_(n,e.ambiguous)}return bw(n,e.name,{boot:t,from:xa()})}async function bw(n,e,t){let r,s;try{r=await ig(e)}catch(p){s=p instanceof Error?p.message:String(p)}let i=xa()-t.from,{lit:o,litLink:a,brand:c}=Fd(process.stdout.isTTY===!0),l=[" Read the authoring skill before writing a bulb:",` \u2022 ${o(bs())}`],f=r?[` Agent mirror (${e}) is live\u{1F4A1}`,` ${o("\u25CF")} ${a(r.url)}`," Inline bulbs render live here."," Agents:",` Reusable app/tool \u2192 write a ${o(".bulb.md")}`," Show something inline \u2192 emit an inline bulb"," emit it with no .bulb.md draft first",...e==="codex"?[" verify it this turn \u2014 foreground-wait, bounded:",` \u2022 ${o('typebulb wait agent --match "[inline <name>" --timeout 120')}`," raise the shell tool's timeout_ms to 130000"," (its 10s default kills even a clean ok)"]:[e==="pi"?" arm a wait for its render verdict \u2014 run it plainly:":" background a wait for its render verdict:",` \u2022 ${o('typebulb wait agent --match "[inline <name>"')}`],...l," End this reply with the mirror link above"," \u2022 easy to miss the link mid-message"]:[` The mirror did not start (${s})`,` \u25CF Start it manually: ${o(`npx typebulb agent:${e}`)}`," Agents:",...l],u=t.boot+i>I_?[` slow launch: boot ${yw(t.boot)} \xB7 mirror ${yw(i)}`]:[],d=[` ${c(`typebulb v${n}`)}`,...u,...f,""];process.stdout.write(d.join(`
|
|
2247
2248
|
`)+`
|
|
2248
2249
|
`)}async function N_(n,e){if(!process.stdin.isTTY||!process.stdout.isTTY)return;let{lit:t,brand:r}=Fd(!0),s=[` ${r(`typebulb v${n}`)}`," More than one agent harness is available here.",...e.map((o,a)=>` ${t(String(a+1))}) ${o}`),""];process.stdout.write(s.join(`
|
|
2249
2250
|
`)+`
|