typebulb 0.60.1 → 0.60.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/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.60.1
4
+ version: 0.60.3
5
5
  ---
6
6
 
7
- > Generated from typebulb v0.60.1. `npx typebulb agent` prints the running version alongside the path to its packaged SKILL.md: if that version is newer than this one, replace this file with that one.
7
+ > Generated from typebulb v0.60.3. `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
 
@@ -1508,8 +1508,26 @@ a.agent-name:hover { text-decoration: underline; }
1508
1508
  inline bulb and a spread bulb). `100%` in --lane-ml resolves against each user's own containing block
1509
1509
  (prose width) at point of use, so both centre on the column axis — which is the viewport centre,
1510
1510
  since the gutters are symmetric. One home so the geometry can't drift between the two (the bug
1511
- that let an off-centre nudge survive in one rule after being removed from the other). */
1512
- .md { --lane-w: calc(100vw - 2rem); --lane-ml: calc((100% - var(--lane-w)) / 2); }
1511
+ that let an off-centre nudge survive in one rule after being removed from the other).
1512
+ --chop-inset (the stripe-chop's reach into the gutter) and --chop-bg (the fill that covers the
1513
+ stripe) live here too: all four describe the transcript column, so all four are the container's
1514
+ to declare rather than the artifact's. */
1515
+ .md {
1516
+ --lane-w: calc(100vw - 2rem); --lane-ml: calc((100% - var(--lane-w)) / 2);
1517
+ --chop-inset: 1rem; --chop-bg: var(--bg);
1518
+ }
1519
+
1520
+ /* A padded panel that holds rendered markdown redeclares all four as its own box: a sub-agent
1521
+ hand-back frame (TB-Agent-Children.md), a disclosure, a blockquote. Inside one there is no turn
1522
+ stripe to reach for or to cover, so the reach and the fill go to zero and an embed keeps only its
1523
+ vertical band, while the lane collapses to the panel: a wide table then shares the panel's width
1524
+ through its two ceilings and scrolls in .table-scroll, instead of a band that bleeds over the
1525
+ card's border and paints page colour across its tint. The reset must land on the `.md` element
1526
+ itself, since `.md` declares the defaults on itself and would beat a rule on an ancestor. The
1527
+ next panel is one more selector here. */
1528
+ .bubble.user > .md, .md details, .md blockquote {
1529
+ --lane-w: 100%; --lane-ml: 0px; --chop-inset: 0px; --chop-bg: transparent;
1530
+ }
1513
1531
 
1514
1532
  /* Full-lane breakout — the mermaid embed (whole element) and a SPREAD bulb's iframe step out of
1515
1533
  the prose column to the transcript width so wide content gets room. Both use --lane-w/--lane-ml
@@ -1541,7 +1559,7 @@ a.agent-name:hover { text-decoration: underline; }
1541
1559
  overflow-x: auto;
1542
1560
  display: flex;
1543
1561
  justify-content: safe center;
1544
- box-shadow: 0 0 0 1rem var(--bg);
1562
+ box-shadow: 0 0 0 1rem var(--chop-bg);
1545
1563
  }
1546
1564
  /* flex-shrink:0: otherwise the SVG shrinks to the flex container and its viewBox
1547
1565
  scales it down — no overflow, no scrollbar. Natural width is what scrolls. */
@@ -1593,8 +1611,8 @@ a.agent-name:hover { text-decoration: underline; }
1593
1611
  space that already reads as margin, while on the right the lane's own 1rem inset is all there is
1594
1612
  between the table and the bar. Inset both sides equally and the left gap measures a gutter wider
1595
1613
  than the right; inset neither and the table sits flush against the bar, which is the bug. So the
1596
- band adds back one inset on the right, and the table's cap comes down by the same 1rem or it would
1597
- overflow the band's content box by exactly that at every width — the permanent scrollbar the
1614
+ band adds back one inset on the right, and the table's cap comes down by that same inset or it
1615
+ would overflow the band's content box by exactly that at every width — the permanent scrollbar the
1598
1616
  zeroed inset was avoiding. */
1599
1617
  .md .table-embed.spread {
1600
1618
  justify-content: safe center;
@@ -1602,9 +1620,9 @@ a.agent-name:hover { text-decoration: underline; }
1602
1620
  margin-left: var(--lane-ml);
1603
1621
  margin-right: auto;
1604
1622
  padding-left: 0;
1605
- padding-right: 1rem;
1623
+ padding-right: var(--chop-inset);
1606
1624
  }
1607
- .md .table-embed.spread table { max-width: calc(var(--lane-w) - 1rem); }
1625
+ .md .table-embed.spread table { max-width: calc(var(--lane-w) - var(--chop-inset)); }
1608
1626
 
1609
1627
  /* ````bulb```` inline bulbs: a sandboxed nested app. createBulbFrame owns the iframe (auto-height,
1610
1628
  borderless). No frame of our own — like the mermaid/svg embeds, it sits in the flow rather
@@ -1616,9 +1634,10 @@ a.agent-name:hover { text-decoration: underline; }
1616
1634
  under a live inline bulb (both monospace, muted red). */
1617
1635
  /* The stripe-chop, shared by every opaque in-column visual artifact (the fit bulb and a raw
1618
1636
  `svg` — each opts in by carrying `.embed`). An opaque bg over position:relative + z-index:0
1619
- paints above .bubble::before; a -1rem left extension reaches the stripe in the gutter without a
1620
- full breakout (padding-left:1rem keeps the content in the prose column, and the box's right edge
1621
- stays at prose-right, so a bulb's controls anchored there don't move). The vertical gap is opaque
1637
+ paints above .bubble::before; a --chop-inset left extension reaches the stripe in the gutter
1638
+ without a full breakout (the matching padding-left keeps the content in the prose column, and the
1639
+ box's right edge stays at prose-right, so a bulb's controls anchored there don't move); inside a
1640
+ panel both zero out (the nesting reset above). The vertical gap is opaque
1622
1641
  padding, not margin: it occludes the stripe top and bottom so the cut is flush with the prose (no
1623
1642
  stub in a transparent gap), symmetric above/below to separate the artifact from surrounding text.
1624
1643
  margin top/bottom are zeroed — and the abutting prose margins too (below) — so the gap butts the
@@ -1628,9 +1647,9 @@ a.agent-name:hover { text-decoration: underline; }
1628
1647
  display: flex;
1629
1648
  position: relative;
1630
1649
  z-index: 0;
1631
- background: var(--bg);
1632
- margin: 0 0 0 -1rem;
1633
- padding: 1.1rem 0 1.1rem 1rem;
1650
+ background: var(--chop-bg);
1651
+ margin: 0 0 0 calc(-1 * var(--chop-inset));
1652
+ padding: 1.1rem 0 1.1rem var(--chop-inset);
1634
1653
  }
1635
1654
  /* A bulb stacks its controls/frame/code vertically; in spread mode the inner iframe's own
1636
1655
  breakout covers the stripe too (the wrapper still chops in column). */
@@ -1508,8 +1508,26 @@ a.agent-name:hover { text-decoration: underline; }
1508
1508
  inline bulb and a spread bulb). `100%` in --lane-ml resolves against each user's own containing block
1509
1509
  (prose width) at point of use, so both centre on the column axis — which is the viewport centre,
1510
1510
  since the gutters are symmetric. One home so the geometry can't drift between the two (the bug
1511
- that let an off-centre nudge survive in one rule after being removed from the other). */
1512
- .md { --lane-w: calc(100vw - 2rem); --lane-ml: calc((100% - var(--lane-w)) / 2); }
1511
+ that let an off-centre nudge survive in one rule after being removed from the other).
1512
+ --chop-inset (the stripe-chop's reach into the gutter) and --chop-bg (the fill that covers the
1513
+ stripe) live here too: all four describe the transcript column, so all four are the container's
1514
+ to declare rather than the artifact's. */
1515
+ .md {
1516
+ --lane-w: calc(100vw - 2rem); --lane-ml: calc((100% - var(--lane-w)) / 2);
1517
+ --chop-inset: 1rem; --chop-bg: var(--bg);
1518
+ }
1519
+
1520
+ /* A padded panel that holds rendered markdown redeclares all four as its own box: a sub-agent
1521
+ hand-back frame (TB-Agent-Children.md), a disclosure, a blockquote. Inside one there is no turn
1522
+ stripe to reach for or to cover, so the reach and the fill go to zero and an embed keeps only its
1523
+ vertical band, while the lane collapses to the panel: a wide table then shares the panel's width
1524
+ through its two ceilings and scrolls in .table-scroll, instead of a band that bleeds over the
1525
+ card's border and paints page colour across its tint. The reset must land on the `.md` element
1526
+ itself, since `.md` declares the defaults on itself and would beat a rule on an ancestor. The
1527
+ next panel is one more selector here. */
1528
+ .bubble.user > .md, .md details, .md blockquote {
1529
+ --lane-w: 100%; --lane-ml: 0px; --chop-inset: 0px; --chop-bg: transparent;
1530
+ }
1513
1531
 
1514
1532
  /* Full-lane breakout — the mermaid embed (whole element) and a SPREAD bulb's iframe step out of
1515
1533
  the prose column to the transcript width so wide content gets room. Both use --lane-w/--lane-ml
@@ -1541,7 +1559,7 @@ a.agent-name:hover { text-decoration: underline; }
1541
1559
  overflow-x: auto;
1542
1560
  display: flex;
1543
1561
  justify-content: safe center;
1544
- box-shadow: 0 0 0 1rem var(--bg);
1562
+ box-shadow: 0 0 0 1rem var(--chop-bg);
1545
1563
  }
1546
1564
  /* flex-shrink:0: otherwise the SVG shrinks to the flex container and its viewBox
1547
1565
  scales it down — no overflow, no scrollbar. Natural width is what scrolls. */
@@ -1593,8 +1611,8 @@ a.agent-name:hover { text-decoration: underline; }
1593
1611
  space that already reads as margin, while on the right the lane's own 1rem inset is all there is
1594
1612
  between the table and the bar. Inset both sides equally and the left gap measures a gutter wider
1595
1613
  than the right; inset neither and the table sits flush against the bar, which is the bug. So the
1596
- band adds back one inset on the right, and the table's cap comes down by the same 1rem or it would
1597
- overflow the band's content box by exactly that at every width — the permanent scrollbar the
1614
+ band adds back one inset on the right, and the table's cap comes down by that same inset or it
1615
+ would overflow the band's content box by exactly that at every width — the permanent scrollbar the
1598
1616
  zeroed inset was avoiding. */
1599
1617
  .md .table-embed.spread {
1600
1618
  justify-content: safe center;
@@ -1602,9 +1620,9 @@ a.agent-name:hover { text-decoration: underline; }
1602
1620
  margin-left: var(--lane-ml);
1603
1621
  margin-right: auto;
1604
1622
  padding-left: 0;
1605
- padding-right: 1rem;
1623
+ padding-right: var(--chop-inset);
1606
1624
  }
1607
- .md .table-embed.spread table { max-width: calc(var(--lane-w) - 1rem); }
1625
+ .md .table-embed.spread table { max-width: calc(var(--lane-w) - var(--chop-inset)); }
1608
1626
 
1609
1627
  /* ````bulb```` inline bulbs: a sandboxed nested app. createBulbFrame owns the iframe (auto-height,
1610
1628
  borderless). No frame of our own — like the mermaid/svg embeds, it sits in the flow rather
@@ -1616,9 +1634,10 @@ a.agent-name:hover { text-decoration: underline; }
1616
1634
  under a live inline bulb (both monospace, muted red). */
1617
1635
  /* The stripe-chop, shared by every opaque in-column visual artifact (the fit bulb and a raw
1618
1636
  `svg` — each opts in by carrying `.embed`). An opaque bg over position:relative + z-index:0
1619
- paints above .bubble::before; a -1rem left extension reaches the stripe in the gutter without a
1620
- full breakout (padding-left:1rem keeps the content in the prose column, and the box's right edge
1621
- stays at prose-right, so a bulb's controls anchored there don't move). The vertical gap is opaque
1637
+ paints above .bubble::before; a --chop-inset left extension reaches the stripe in the gutter
1638
+ without a full breakout (the matching padding-left keeps the content in the prose column, and the
1639
+ box's right edge stays at prose-right, so a bulb's controls anchored there don't move); inside a
1640
+ panel both zero out (the nesting reset above). The vertical gap is opaque
1622
1641
  padding, not margin: it occludes the stripe top and bottom so the cut is flush with the prose (no
1623
1642
  stub in a transparent gap), symmetric above/below to separate the artifact from surrounding text.
1624
1643
  margin top/bottom are zeroed — and the abutting prose margins too (below) — so the gap butts the
@@ -1628,9 +1647,9 @@ a.agent-name:hover { text-decoration: underline; }
1628
1647
  display: flex;
1629
1648
  position: relative;
1630
1649
  z-index: 0;
1631
- background: var(--bg);
1632
- margin: 0 0 0 -1rem;
1633
- padding: 1.1rem 0 1.1rem 1rem;
1650
+ background: var(--chop-bg);
1651
+ margin: 0 0 0 calc(-1 * var(--chop-inset));
1652
+ padding: 1.1rem 0 1.1rem var(--chop-inset);
1634
1653
  }
1635
1654
  /* A bulb stacks its controls/frame/code vertically; in spread mode the inner iframe's own
1636
1655
  breakout covers the stripe too (the wrapper still chops in column). */
@@ -1508,8 +1508,26 @@ a.agent-name:hover { text-decoration: underline; }
1508
1508
  inline bulb and a spread bulb). `100%` in --lane-ml resolves against each user's own containing block
1509
1509
  (prose width) at point of use, so both centre on the column axis — which is the viewport centre,
1510
1510
  since the gutters are symmetric. One home so the geometry can't drift between the two (the bug
1511
- that let an off-centre nudge survive in one rule after being removed from the other). */
1512
- .md { --lane-w: calc(100vw - 2rem); --lane-ml: calc((100% - var(--lane-w)) / 2); }
1511
+ that let an off-centre nudge survive in one rule after being removed from the other).
1512
+ --chop-inset (the stripe-chop's reach into the gutter) and --chop-bg (the fill that covers the
1513
+ stripe) live here too: all four describe the transcript column, so all four are the container's
1514
+ to declare rather than the artifact's. */
1515
+ .md {
1516
+ --lane-w: calc(100vw - 2rem); --lane-ml: calc((100% - var(--lane-w)) / 2);
1517
+ --chop-inset: 1rem; --chop-bg: var(--bg);
1518
+ }
1519
+
1520
+ /* A padded panel that holds rendered markdown redeclares all four as its own box: a sub-agent
1521
+ hand-back frame (TB-Agent-Children.md), a disclosure, a blockquote. Inside one there is no turn
1522
+ stripe to reach for or to cover, so the reach and the fill go to zero and an embed keeps only its
1523
+ vertical band, while the lane collapses to the panel: a wide table then shares the panel's width
1524
+ through its two ceilings and scrolls in .table-scroll, instead of a band that bleeds over the
1525
+ card's border and paints page colour across its tint. The reset must land on the `.md` element
1526
+ itself, since `.md` declares the defaults on itself and would beat a rule on an ancestor. The
1527
+ next panel is one more selector here. */
1528
+ .bubble.user > .md, .md details, .md blockquote {
1529
+ --lane-w: 100%; --lane-ml: 0px; --chop-inset: 0px; --chop-bg: transparent;
1530
+ }
1513
1531
 
1514
1532
  /* Full-lane breakout — the mermaid embed (whole element) and a SPREAD bulb's iframe step out of
1515
1533
  the prose column to the transcript width so wide content gets room. Both use --lane-w/--lane-ml
@@ -1541,7 +1559,7 @@ a.agent-name:hover { text-decoration: underline; }
1541
1559
  overflow-x: auto;
1542
1560
  display: flex;
1543
1561
  justify-content: safe center;
1544
- box-shadow: 0 0 0 1rem var(--bg);
1562
+ box-shadow: 0 0 0 1rem var(--chop-bg);
1545
1563
  }
1546
1564
  /* flex-shrink:0: otherwise the SVG shrinks to the flex container and its viewBox
1547
1565
  scales it down — no overflow, no scrollbar. Natural width is what scrolls. */
@@ -1593,8 +1611,8 @@ a.agent-name:hover { text-decoration: underline; }
1593
1611
  space that already reads as margin, while on the right the lane's own 1rem inset is all there is
1594
1612
  between the table and the bar. Inset both sides equally and the left gap measures a gutter wider
1595
1613
  than the right; inset neither and the table sits flush against the bar, which is the bug. So the
1596
- band adds back one inset on the right, and the table's cap comes down by the same 1rem or it would
1597
- overflow the band's content box by exactly that at every width — the permanent scrollbar the
1614
+ band adds back one inset on the right, and the table's cap comes down by that same inset or it
1615
+ would overflow the band's content box by exactly that at every width — the permanent scrollbar the
1598
1616
  zeroed inset was avoiding. */
1599
1617
  .md .table-embed.spread {
1600
1618
  justify-content: safe center;
@@ -1602,9 +1620,9 @@ a.agent-name:hover { text-decoration: underline; }
1602
1620
  margin-left: var(--lane-ml);
1603
1621
  margin-right: auto;
1604
1622
  padding-left: 0;
1605
- padding-right: 1rem;
1623
+ padding-right: var(--chop-inset);
1606
1624
  }
1607
- .md .table-embed.spread table { max-width: calc(var(--lane-w) - 1rem); }
1625
+ .md .table-embed.spread table { max-width: calc(var(--lane-w) - var(--chop-inset)); }
1608
1626
 
1609
1627
  /* ````bulb```` inline bulbs: a sandboxed nested app. createBulbFrame owns the iframe (auto-height,
1610
1628
  borderless). No frame of our own — like the mermaid/svg embeds, it sits in the flow rather
@@ -1616,9 +1634,10 @@ a.agent-name:hover { text-decoration: underline; }
1616
1634
  under a live inline bulb (both monospace, muted red). */
1617
1635
  /* The stripe-chop, shared by every opaque in-column visual artifact (the fit bulb and a raw
1618
1636
  `svg` — each opts in by carrying `.embed`). An opaque bg over position:relative + z-index:0
1619
- paints above .bubble::before; a -1rem left extension reaches the stripe in the gutter without a
1620
- full breakout (padding-left:1rem keeps the content in the prose column, and the box's right edge
1621
- stays at prose-right, so a bulb's controls anchored there don't move). The vertical gap is opaque
1637
+ paints above .bubble::before; a --chop-inset left extension reaches the stripe in the gutter
1638
+ without a full breakout (the matching padding-left keeps the content in the prose column, and the
1639
+ box's right edge stays at prose-right, so a bulb's controls anchored there don't move); inside a
1640
+ panel both zero out (the nesting reset above). The vertical gap is opaque
1622
1641
  padding, not margin: it occludes the stripe top and bottom so the cut is flush with the prose (no
1623
1642
  stub in a transparent gap), symmetric above/below to separate the artifact from surrounding text.
1624
1643
  margin top/bottom are zeroed — and the abutting prose margins too (below) — so the gap butts the
@@ -1628,9 +1647,9 @@ a.agent-name:hover { text-decoration: underline; }
1628
1647
  display: flex;
1629
1648
  position: relative;
1630
1649
  z-index: 0;
1631
- background: var(--bg);
1632
- margin: 0 0 0 -1rem;
1633
- padding: 1.1rem 0 1.1rem 1rem;
1650
+ background: var(--chop-bg);
1651
+ margin: 0 0 0 calc(-1 * var(--chop-inset));
1652
+ padding: 1.1rem 0 1.1rem var(--chop-inset);
1634
1653
  }
1635
1654
  /* A bulb stacks its controls/frame/code vertically; in spread mode the inner iframe's own
1636
1655
  breakout covers the stripe too (the wrapper still chops in column). */