typebulb 0.11.2 → 0.11.3
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 +8 -8
- package/dist/agents/claude/client.js +1 -1
- package/dist/index.js +2 -2
- package/dist/render.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# typebulb
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Typebulb** runs apps in markdown files called **bulbs**. To run bulbs:
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
* `npx typebulb`. When you want a quick local app or tool where the overhead of an entire npm project is overkill *(trivial for your LLM to convert to when you actually need to)*. Can be entirely client code, or both client and nodejs code that talk via a secure bridge.
|
|
6
|
+
* `npx typebulb agent:claude`. When you want to view Claude Code conversations with embedded bulbs in the agent messages.
|
|
7
|
+
* **[typebulb.com](https://typebulb.com)**. When you want to share tools, visualizations, experiments etc. See [FAQ](https://typebulb.com/faq).
|
|
8
8
|
|
|
9
|
-
`typebulb`
|
|
9
|
+
The `typebulb` CLI enables the first two cases, by compiling and serving hot-reloadable bulbs locally.
|
|
10
10
|
|
|
11
11
|
A `.bulb.md` file bundles code, styles, data, and config in one file.
|
|
12
12
|
|
|
@@ -94,8 +94,8 @@ button {
|
|
|
94
94
|
{
|
|
95
95
|
"description": "A button that increments a counter.",
|
|
96
96
|
"dependencies": {
|
|
97
|
-
"react": "^19.2.
|
|
98
|
-
"react-dom": "^19.2.
|
|
97
|
+
"react": "^19.2.7",
|
|
98
|
+
"react-dom": "^19.2.7"
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
```
|
|
@@ -251,7 +251,7 @@ The agent viewer turns that block into a live, sandboxed app, with a *breakout
|
|
|
251
251
|
|
|
252
252
|
**Sizing is the viewer's job, not yours.** The agent viewer renders each embed *inline* by default — fit to the conversation column, with height capped so a tall bulb doesn't run away — plus a per-embed toggle to *spread* it to the full transcript width and height. Don't fight the layout from inside the bulb: no need to set a width, reserve height, or guess how much room you'll get.
|
|
253
253
|
|
|
254
|
-
**
|
|
254
|
+
**Prefer `padding` over `margin` for vertical space on the root.** The viewer measures an embed by `document.body.scrollHeight`, and the runtime makes `body` a block formatting context so a root child's vertical margin (yours, or a UA default like `<h1>`'s) is contained rather than escaping the measurement — so you no longer have to get this exactly right. It's still cleaner to keep the horizontal `auto` for centering and move the vertical space to padding:
|
|
255
255
|
|
|
256
256
|
```css
|
|
257
257
|
.wrap { margin: 0 auto; padding: 24px 16px; } /* not: margin: 24px auto */
|
|
@@ -761,7 +761,7 @@ ${h.map(({variableName:p,uniqueLocalName:b})=>` reactHotLoader.register(${p}, "
|
|
|
761
761
|
}
|
|
762
762
|
})();
|
|
763
763
|
`;function i9t(o){return o.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var s9t=` *, *::before, *::after { box-sizing: border-box; }
|
|
764
|
-
body { margin: 0; font-family: system-ui, -apple-system, sans-serif; }
|
|
764
|
+
body { margin: 0; display: flow-root; font-family: system-ui, -apple-system, sans-serif; }
|
|
765
765
|
html[data-theme="dark"] { color-scheme: dark; }
|
|
766
766
|
html[data-theme="light"] { color-scheme: light; }`;function o9t(o,u){let h=p=>p.replace(/<\/script/gi,"<\\/script");return` <script>
|
|
767
767
|
(function() {
|
package/dist/index.js
CHANGED
|
@@ -481,7 +481,7 @@ declare const tb: {${en}${tn}${rn}${on}${wo}${nn}${sn}
|
|
|
481
481
|
}
|
|
482
482
|
})();
|
|
483
483
|
`;function wt(r){return r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var vt=` *, *::before, *::after { box-sizing: border-box; }
|
|
484
|
-
body { margin: 0; font-family: system-ui, -apple-system, sans-serif; }
|
|
484
|
+
body { margin: 0; display: flow-root; font-family: system-ui, -apple-system, sans-serif; }
|
|
485
485
|
html[data-theme="dark"] { color-scheme: dark; }
|
|
486
486
|
html[data-theme="light"] { color-scheme: light; }`;function xt(r,e){let t=n=>n.replace(/<\/script/gi,"<\\/script");return` <script>
|
|
487
487
|
(function() {
|
|
@@ -731,6 +731,6 @@ ${Ji}
|
|
|
731
731
|
`);async function v(){await(await import("esbuild")).build({entryPoints:[I.join(c,"client","index.ts")],bundle:!0,platform:"browser",format:"esm",outfile:I.join(a,"client.js")});for(let T of["styles.css","index.html"])Ba(I.join(c,T),I.join(a,T))}let $;if(r.watch&&n){let E=Ma(c),T=!1;$=Ut({dir:E?c:a,onChange:async()=>{if(!T){T=!0;try{E&&await v(),console.log(`Viewer rebuilt. Browser reloading...
|
|
732
732
|
`),n.emit("reload")}catch(p){console.error("Viewer rebuild failed:",p instanceof Error?p.message:p)}finally{T=!1}}}})}r.open&&await Pe(g);let O=async()=>{console.log(`
|
|
733
733
|
Shutting down...`),m.close(),$?.(),t(),await Ze(process.pid),process.exit(0)};process.on("SIGINT",O),process.on("SIGTERM",O)}import*as Vs from"path";import{EventEmitter as Na}from"events";async function zs(r,e,t,n,s){let o=ne(t),i=!1,a=async()=>{let{bulb:c,config:l}=await G(r);i||(_e(o,r,c.server),i=!0),await dr(c.server,s,n,l.dependencies)};if(console.log(`Running ${Vs.basename(r)}...`),await a(),e){console.log(`Watching for changes...
|
|
734
|
-
`);let c=new Na;c.on("reload",async()=>{try{console.log("Re-running..."),await a()}catch(l){console.error("Error:",l)}}),Lt({bulbPath:r,emitter:c})}}var qs="0.11.
|
|
734
|
+
`);let c=new Na;c.on("reload",async()=>{try{console.log("Re-running..."),await a()}catch(l){console.error("Error:",l)}}),Lt({bulbPath:r,emitter:c})}}var qs="0.11.3";async function La(){let r=Vr(process.argv.slice(2));if(r.version&&(console.log(`typebulb ${qs}`),process.exit(0)),r.help&&(zr(),process.exit(0)),r.subcommand==="logs"){await rs(r.file||void 0,{follow:r.follow,lines:r.lines});return}if(r.subcommand==="stop"){r.all?await ss():await ns(r.file||void 0);return}if(r.subcommand==="skill"){await Qn(qs);return}if(r.subcommand==="models"){await Kn(r.mode);return}if(r.subcommand==="agent"){if(!r.agentTarget){await Vn();return}_n(r.agentTarget)||(console.error(`Unknown agent '${r.agentTarget}'. Known: ${hr().join(", ")}.`),process.exit(1));let l=await br(process.cwd(),r.agentTarget);if(l){console.log(`Viewer '${r.agentTarget}' is already running for this project:
|
|
735
735
|
${l.url}`),r.open&&await Pe(l.url);return}await Hs(r);return}if(r.subcommand==="trust"||r.subcommand==="untrust"){await Fn(r.file||void 0,r.subcommand==="trust");return}let e;if(!r.file||r.file==="."){let l=await En(process.cwd());l||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=l}else e=X.resolve(r.file);await Gs.access(e).then(()=>!0,()=>!1)||(hr().includes(r.file)&&(console.error(`To open the ${r.file} agent viewer, run: npx typebulb agent:${r.file}`),process.exit(1)),console.error(`File not found: ${e}`),process.exit(1)),e.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1));let n=r.file&&r.file!=="."?r.file:X.relative(process.cwd(),e)||X.basename(e),s=`npx typebulb --trust ${n.includes(" ")?`"${n}"`:n}`;if(r.subcommand==="predict"){await Mn(e,s);return}let o=!r.noTrust&&le(e);o&&!r.trust&&console.log("trust: granted from memory (run `typebulb untrust` to revoke)"),r.trust=r.noTrust?!1:r.trust||o;let i;try{i=await G(e)}catch{}let a;if(r.local){i&&!(r.local.name in(i.config.dependencies??{}))&&(console.error(`--replace: '${r.local.name}' is not a dependency in this bulb's config.json; nothing to replace.`),process.exit(1)),i&&(!i.bulb.code||r.server)&&console.warn("warning: --replace has no effect in server mode (the override is client-only).");try{a=await Jr(r.local)}catch(l){console.error(l instanceof Error?l.message:String(l)),process.exit(1)}console.log(`replace: ${a.name} \u2192 ${X.relative(process.cwd(),a.dir)||"."}`)}if(r.subcommand==="check"){await Bn(e,a);return}let c=X.dirname(e);if(i&&i.bulb.server&&(!i.bulb.code||r.server)){r.trust||(console.error(`This bulb runs server-side Node code (server.ts), which --trust must authorize:
|
|
736
736
|
${s}`),process.exit(1)),await zs(e,r.watch,r.mode,a,c);return}await ms(e,r,s,a,c)}La().catch(r=>{console.error("Error:",r.message),process.exit(1)});
|
package/dist/render.js
CHANGED
|
@@ -345,7 +345,7 @@ ${s.map(({variableName:n,uniqueLocalName:i})=>` reactHotLoader.register(${n}, "
|
|
|
345
345
|
}
|
|
346
346
|
})();
|
|
347
347
|
`;function ic(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var ac=` *, *::before, *::after { box-sizing: border-box; }
|
|
348
|
-
body { margin: 0; font-family: system-ui, -apple-system, sans-serif; }
|
|
348
|
+
body { margin: 0; display: flow-root; font-family: system-ui, -apple-system, sans-serif; }
|
|
349
349
|
html[data-theme="dark"] { color-scheme: dark; }
|
|
350
350
|
html[data-theme="light"] { color-scheme: light; }`;function cc(e,t){let s=n=>n.replace(/<\/script/gi,"<\\/script");return` <script>
|
|
351
351
|
(function() {
|