typebulb 0.60.1 → 0.60.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/dist/agents/claude/styles.css +32 -13
- package/dist/agents/codex/styles.css +32 -13
- package/dist/agents/pi/styles.css +32 -13
- package/dist/index.js +1 -1
- package/package.json +1 -1
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.
|
|
4
|
+
version: 0.60.2
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
> Generated from typebulb v0.60.
|
|
7
|
+
> Generated from typebulb v0.60.2. `npx typebulb agent` prints the running version alongside the path to its packaged SKILL.md: if that version is newer than this one, replace this file with that one.
|
|
8
8
|
|
|
9
9
|
# typebulb
|
|
10
10
|
|
|
@@ -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
|
-
|
|
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
|
|
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:
|
|
1623
|
+
padding-right: var(--chop-inset);
|
|
1606
1624
|
}
|
|
1607
|
-
.md .table-embed.spread table { max-width: calc(var(--lane-w) -
|
|
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 -
|
|
1620
|
-
full breakout (padding-left
|
|
1621
|
-
stays at prose-right, so a bulb's controls anchored there don't move)
|
|
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 -
|
|
1633
|
-
padding: 1.1rem 0 1.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
|
-
|
|
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
|
|
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:
|
|
1623
|
+
padding-right: var(--chop-inset);
|
|
1606
1624
|
}
|
|
1607
|
-
.md .table-embed.spread table { max-width: calc(var(--lane-w) -
|
|
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 -
|
|
1620
|
-
full breakout (padding-left
|
|
1621
|
-
stays at prose-right, so a bulb's controls anchored there don't move)
|
|
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 -
|
|
1633
|
-
padding: 1.1rem 0 1.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
|
-
|
|
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
|
|
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:
|
|
1623
|
+
padding-right: var(--chop-inset);
|
|
1606
1624
|
}
|
|
1607
|
-
.md .table-embed.spread table { max-width: calc(var(--lane-w) -
|
|
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 -
|
|
1620
|
-
full breakout (padding-left
|
|
1621
|
-
stays at prose-right, so a bulb's controls anchored there don't move)
|
|
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 -
|
|
1633
|
-
padding: 1.1rem 0 1.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). */
|
package/dist/index.js
CHANGED
|
@@ -311,7 +311,7 @@ ${t.comment}`:t.comment}this.doc.range[2]=t.offset;break}default:this.errors.pus
|
|
|
311
311
|
`);if(r<0)return t.bytes>=65536?{cwd:"",subagent:!1}:void 0;try{let s=JSON.parse(t.text.slice(0,r)),i=s?.type==="session_meta"?s.payload:void 0;return typeof i?.cwd!="string"?{cwd:"",subagent:!1}:{cwd:i.cwd,subagent:typeof i.source=="object"&&!!i.source?.subagent}}catch{return{cwd:"",subagent:!1}}}var pT,ys,bu,yT,vT,ST,kT,xT,CT,NT,Ng,LT,zn,BT,wu=S(()=>{"use strict";ms();bo();pT=["<permissions instructions>","<apps_instructions>","<plugins_instructions>","<skills_instructions>","<recommended_plugins>","<environment_context>","<node_repl_review_evidence>","# AGENTS.md instructions for "];ys=n=>!!n&&typeof n=="object"&&!Array.isArray(n),bu=n=>n==="shell_command"||n==="exec_command",yT=new Set(["max_output_tokens","yield_time_ms","timeout_ms"]);vT=/^(Get-Content|gc|cat|type|nl|bat|sed|head|tail)$/i,ST=/^-(Path|LiteralPath)$/i,kT=/^-(Encoding|TotalCount|Head|Tail|ReadCount|Delimiter)$/i,xT=/^(sed -n|head|tail|Select-Object|select)(\s|$)/i;CT={n:`
|
|
312
312
|
`,t:" ",r:"\r",b:"\b",f:"\f",v:"\v",0:"\0"};NT=n=>n?n.replace(/\r?\n$/,"").split(`
|
|
313
313
|
`).length:0;Ng=n=>{let e=fT(n);return process.platform==="win32"?e.toLowerCase():e},LT=12e4,zn=class extends $t{constructor(t=yu(_g(),".codex","sessions")){super();this.root=t}displayName="Codex Mirror";#e=0;#i;#t=new Map;#n=new Map;#f=new Map;#r=new Map;detectsSelf(){return!!process.env.CODEX_THREAD_ID}detectsInstalled(){return uT(yu(_g(),".codex"))}sessionsDir(t){return this.root}listSessionFiles(t){let r=Ng(t),s=[];for(let i of this.#o()){let o=0,a=0;try{let f=Cg(i);if(!f.isFile())continue;o=f.size,a=f.mtimeMs}catch{continue}let l=this.#t.get(i);if(l===void 0){if(l=jT(i),l===void 0)continue;this.#t.set(i,l)}if(l.subagent||Ng(l.cwd)!==r)continue;let c=dT(i,".jsonl");this.#f.set(c,i),s.push({sessionId:c,file:i,mtime:this.#c(i,o,a)})}return s}#c(t,r,s){let i=this.#n.get(t);if(i&&i.size===r&&i.mtime===s)return i.ms;let o=Math.max(s,DT(t)??0);return this.#n.set(t,{size:r,mtime:s,ms:o}),o}#o(){let t=[],r=s=>{try{return cT(s).map(i=>yu(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.#i,this.#i=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=Vn(i.content,!0).trim();a&&s.push({type:"user",text:a})}else if(i.role==="assistant"){let a=Vn(i.content,!1);a&&s.push({type:"assistant",text:a,thinking:"",tools:[],live:o()})}return{events:s}}if(i.type==="reasoning"){let a=Vn(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.call_id??"",{pending:l,...c}=i.type==="custom_tool_call"?gT(i.name??"",i.input):{name:i.name??"",input:$T(i.arguments)};return l&&this.#r.set(a,l),s.push({type:"assistant",text:"",thinking:"",tools:[{id:a,...c}],live:o()}),{events:s}}if(i.type==="custom_tool_call_output"||i.type==="function_call_output"){let a=i.call_id??"",l=this.#r.get(a);return this.#r.delete(a),s.push({type:"tool_result",id:a,...RT(mT(i.output),l)}),{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 l={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:l}}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(t){let r=this.#f.get(t);if(!r)return;let s;try{let i=Cg(r);s=this.#c(r,i.size,i.mtimeMs)}catch{return}return Date.now()-s<LT}readPreview(t){for(let r of(Fg(t,256*1024)?.text??"").split(`
|
|
314
|
-
`))if(!(!r.includes('"user_message"')&&!r.includes('"UserMessage"')))try{let s=JSON.parse(r);if(s?.type!=="event_msg")continue;let i=s.payload,a=((i?.type==="user_message"?i.message:i?.type==="item_completed"&&i.item?.type==="UserMessage"?Vn(i.item.content,!0):void 0)??"").replace(/\s+/g," ").trim();if(a)return a.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"?"":Vn(t.payload.content,r==="user").replace(/\s+/g," ").trim()}};BT=[64*1024,1024*1024]});import{realpathSync as FT}from"fs";import{createHash as UT}from"crypto";import{join as Ao,resolve as qT}from"path";import{homedir as JT}from"os";function Mt(){let n=process.env.TYPEBULB_SERVERS_DIR;return n?Ao(n,".."):Ao(JT(),".typebulb")}function ut(){Ug||(Ug=!0,console.error(`${Mt()} not writable \u2014 continuing stateless: ports won't stick, caches stay cold, and typebulb logs/wait/send/stop may not see this run`))}function dt(){return process.env.TYPEBULB_SERVERS_DIR||Ao(Mt(),"servers")}function qg(n){let e=se(n),t=e.slice(e.lastIndexOf("/")+1).replace(/\.bulb\.md$/,"");return Ao(Mt(),"canvas",`${t}-${bs(n)}.png`)}function bs(n){return UT("sha1").update(se(n)).digest("hex").slice(0,8)}function se(n){let e=qT(n),t=e;try{t=FT.native(e)}catch{}return(process.platform==="win32"?t.toLowerCase():t).replace(/\\/g,"/")}function Jg(n,e){let t=se(n),r=se(e);return t.startsWith(r.endsWith("/")?r:r+"/")?!t.includes("/node_modules/"):!1}var Ug,nt=S(()=>{"use strict";Ug=!1});import*as Hg from"net";import{mkdir as WT,readFile as KT,writeFile as Yg}from"fs/promises";import{existsSync as HT}from"fs";import{join as Vg}from"path";function Xg(){return Vg(Mt(),"blocks")}function vu(n){return Vg(Xg(),`${n}.json`)}function Po(n){return new Promise(e=>{let t=Hg.createServer();t.once("error",()=>e(!1)),t.listen(n,"127.0.0.1",()=>t.close(()=>e(!0)))})}async function GT(n){for(let e=n;e<65535;e++)if(await Po(e))return e;throw new Error(`No free port found above ${n}`)}async function Su(n){let{listBulbServers:e}=await Promise.resolve().then(()=>($e(),Qg)),t=(await e()).find(s=>s.port===n),r=t?` (pid ${t.pid}, ${t.agent?`agent:${t.agent}`:t.file})`:"";console.error(`port ${n} in use${r}`),process.exit(1)}async function Oo(n){try{let e=JSON.parse(await KT(vu(n),"utf8"));return e&&typeof e.cwd=="string"?{cwd:e.cwd,slots:e.slots??{},mirrors:e.mirrors??{}}:void 0}catch{return}}async function Co(n,e){try{return await Yg(vu(n),JSON.stringify(e,null,2)),!0}catch{return ut(),!1}}async function XT(n){let e=se(n);try{await WT(Xg(),{recursive:!0})}catch{return}let t=[];for(let o=0;o<Gg;o++)t.push(zg+o*an);let r=await Promise.all(t.map(async o=>({base:o,block:await Oo(o)})));for(let{base:o,block:a}of r)if(a?.cwd===e)return o;let s={cwd:e,slots:{},mirrors:{}};for(let{base:o,block:a}of r){if(!a)try{return await Yg(vu(o),JSON.stringify(s,null,2),{flag:"wx"}),o}catch(l){if((await Oo(o))?.cwd===e)return o;l.code!=="EEXIST"&&ut();continue}if(!HT(a.cwd))return await Co(o,s)?o:void 0}let i=r.filter(o=>!!o.block).sort((o,a)=>Wg(o.block)-Wg(a.block))[0];if(i)return await Co(i.base,s)?i.base:void 0}function Wg(n){return Object.values(n.slots).reduce((e,t)=>Math.max(e,t.usedAt??0),0)}async function QT(n,e){let t=await Oo(n)??{cwd:"",slots:{},mirrors:{}};if(e.kind==="mirror"){let i=t.mirrors[e.agent];if(i!==void 0)return i;let o=Kg(t),a=o.has(0)?VT:0;for(;a>To&&o.has(a);)a--;return t.mirrors[e.agent]=a,await Co(n,t),a}let r=se(e.file),s=t.slots[r]?.offset;if(s===void 0){let i=Kg(t);for(s=To;s<an&&i.has(s);)s++;if(s>=an){let o=Object.entries(t.slots).sort((a,l)=>(a[1].usedAt??0)-(l[1].usedAt??0))[0];s=o?o[1].offset:To,o&&delete t.slots[o[0]]}}return t.slots[r]={offset:s,usedAt:Date.now()},await Co(n,t),s}function Kg(n){return new Set([...Object.values(n.mirrors),...Object.values(n.slots).map(e=>e.offset)])}async function Gn(n,e){let t=await XT(e);return t===void 0?void 0:t+await QT(t,n)}async function ln(n){let e=se(n);for(let t=0;t<Gg;t++){let r=await Oo(zg+t*an);if(r?.cwd===e)return s=>r.slots[se(s)]?.usedAt??0}return()=>0}async function _o(n){if(n.explicit!==void 0)return await Po(n.explicit)||await Su(n.explicit),n.target.kind==="bulb"&&await Gn(n.target,n.cwd),{port:n.explicit};let e=await Gn(n.target,n.cwd);if(e!==void 0){let r=e-e%an,s=Date.now()+zT;do{if(await Po(e))return{port:e};await new Promise(i=>setTimeout(i,150))}while(Date.now()<s);for(let i=To;i<an;i++){let o=r+i;if(o!==e&&await Po(o))return{port:o,note:`(slot ${e} was busy)`}}}return{port:await GT(YT),note:e===void 0?"(no port block available)":"(this project's block was full)"}}var zg,an,Gg,YT,To,VT,zT,cn=S(()=>{"use strict";nt();zg=20100,an=100,Gg=19,YT=23e3,To=1,VT=an-1,zT=3e3});var Le,Ro=S(()=>{"use strict";Le="0.60.
|
|
314
|
+
`))if(!(!r.includes('"user_message"')&&!r.includes('"UserMessage"')))try{let s=JSON.parse(r);if(s?.type!=="event_msg")continue;let i=s.payload,a=((i?.type==="user_message"?i.message:i?.type==="item_completed"&&i.item?.type==="UserMessage"?Vn(i.item.content,!0):void 0)??"").replace(/\s+/g," ").trim();if(a)return a.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"?"":Vn(t.payload.content,r==="user").replace(/\s+/g," ").trim()}};BT=[64*1024,1024*1024]});import{realpathSync as FT}from"fs";import{createHash as UT}from"crypto";import{join as Ao,resolve as qT}from"path";import{homedir as JT}from"os";function Mt(){let n=process.env.TYPEBULB_SERVERS_DIR;return n?Ao(n,".."):Ao(JT(),".typebulb")}function ut(){Ug||(Ug=!0,console.error(`${Mt()} not writable \u2014 continuing stateless: ports won't stick, caches stay cold, and typebulb logs/wait/send/stop may not see this run`))}function dt(){return process.env.TYPEBULB_SERVERS_DIR||Ao(Mt(),"servers")}function qg(n){let e=se(n),t=e.slice(e.lastIndexOf("/")+1).replace(/\.bulb\.md$/,"");return Ao(Mt(),"canvas",`${t}-${bs(n)}.png`)}function bs(n){return UT("sha1").update(se(n)).digest("hex").slice(0,8)}function se(n){let e=qT(n),t=e;try{t=FT.native(e)}catch{}return(process.platform==="win32"?t.toLowerCase():t).replace(/\\/g,"/")}function Jg(n,e){let t=se(n),r=se(e);return t.startsWith(r.endsWith("/")?r:r+"/")?!t.includes("/node_modules/"):!1}var Ug,nt=S(()=>{"use strict";Ug=!1});import*as Hg from"net";import{mkdir as WT,readFile as KT,writeFile as Yg}from"fs/promises";import{existsSync as HT}from"fs";import{join as Vg}from"path";function Xg(){return Vg(Mt(),"blocks")}function vu(n){return Vg(Xg(),`${n}.json`)}function Po(n){return new Promise(e=>{let t=Hg.createServer();t.once("error",()=>e(!1)),t.listen(n,"127.0.0.1",()=>t.close(()=>e(!0)))})}async function GT(n){for(let e=n;e<65535;e++)if(await Po(e))return e;throw new Error(`No free port found above ${n}`)}async function Su(n){let{listBulbServers:e}=await Promise.resolve().then(()=>($e(),Qg)),t=(await e()).find(s=>s.port===n),r=t?` (pid ${t.pid}, ${t.agent?`agent:${t.agent}`:t.file})`:"";console.error(`port ${n} in use${r}`),process.exit(1)}async function Oo(n){try{let e=JSON.parse(await KT(vu(n),"utf8"));return e&&typeof e.cwd=="string"?{cwd:e.cwd,slots:e.slots??{},mirrors:e.mirrors??{}}:void 0}catch{return}}async function Co(n,e){try{return await Yg(vu(n),JSON.stringify(e,null,2)),!0}catch{return ut(),!1}}async function XT(n){let e=se(n);try{await WT(Xg(),{recursive:!0})}catch{return}let t=[];for(let o=0;o<Gg;o++)t.push(zg+o*an);let r=await Promise.all(t.map(async o=>({base:o,block:await Oo(o)})));for(let{base:o,block:a}of r)if(a?.cwd===e)return o;let s={cwd:e,slots:{},mirrors:{}};for(let{base:o,block:a}of r){if(!a)try{return await Yg(vu(o),JSON.stringify(s,null,2),{flag:"wx"}),o}catch(l){if((await Oo(o))?.cwd===e)return o;l.code!=="EEXIST"&&ut();continue}if(!HT(a.cwd))return await Co(o,s)?o:void 0}let i=r.filter(o=>!!o.block).sort((o,a)=>Wg(o.block)-Wg(a.block))[0];if(i)return await Co(i.base,s)?i.base:void 0}function Wg(n){return Object.values(n.slots).reduce((e,t)=>Math.max(e,t.usedAt??0),0)}async function QT(n,e){let t=await Oo(n)??{cwd:"",slots:{},mirrors:{}};if(e.kind==="mirror"){let i=t.mirrors[e.agent];if(i!==void 0)return i;let o=Kg(t),a=o.has(0)?VT:0;for(;a>To&&o.has(a);)a--;return t.mirrors[e.agent]=a,await Co(n,t),a}let r=se(e.file),s=t.slots[r]?.offset;if(s===void 0){let i=Kg(t);for(s=To;s<an&&i.has(s);)s++;if(s>=an){let o=Object.entries(t.slots).sort((a,l)=>(a[1].usedAt??0)-(l[1].usedAt??0))[0];s=o?o[1].offset:To,o&&delete t.slots[o[0]]}}return t.slots[r]={offset:s,usedAt:Date.now()},await Co(n,t),s}function Kg(n){return new Set([...Object.values(n.mirrors),...Object.values(n.slots).map(e=>e.offset)])}async function Gn(n,e){let t=await XT(e);return t===void 0?void 0:t+await QT(t,n)}async function ln(n){let e=se(n);for(let t=0;t<Gg;t++){let r=await Oo(zg+t*an);if(r?.cwd===e)return s=>r.slots[se(s)]?.usedAt??0}return()=>0}async function _o(n){if(n.explicit!==void 0)return await Po(n.explicit)||await Su(n.explicit),n.target.kind==="bulb"&&await Gn(n.target,n.cwd),{port:n.explicit};let e=await Gn(n.target,n.cwd);if(e!==void 0){let r=e-e%an,s=Date.now()+zT;do{if(await Po(e))return{port:e};await new Promise(i=>setTimeout(i,150))}while(Date.now()<s);for(let i=To;i<an;i++){let o=r+i;if(o!==e&&await Po(o))return{port:o,note:`(slot ${e} was busy)`}}}return{port:await GT(YT),note:e===void 0?"(no port block available)":"(this project's block was full)"}}var zg,an,Gg,YT,To,VT,zT,cn=S(()=>{"use strict";nt();zg=20100,an=100,Gg=19,YT=23e3,To=1,VT=an-1,zT=3e3});var Le,Ro=S(()=>{"use strict";Le="0.60.2"});var Qg={};ci(Qg,{agentViewerCommand:()=>ly,bulbServerCommand:()=>ay,clearServerLog:()=>Tu,findProjectViewer:()=>$o,isAlive:()=>Xn,isMirror:()=>me,isProjectBulb:()=>Ru,isProjectMirror:()=>er,launchAgentViewer:()=>$u,launchBulbServer:()=>Ss,listBulbServers:()=>Q,probePageCount:()=>Nu,readServerLog:()=>Ye,readWaitCursor:()=>No,recordDenial:()=>_u,registerServer:()=>Cu,relayOpen:()=>Iu,runMarker:()=>Pu,serverLogPath:()=>Zn,serversForBulb:()=>dn,sliceRunLog:()=>Ou,startServerLog:()=>vs,stopBulbServer:()=>Qn,stopServer:()=>Bt,stopServersForBulb:()=>Lo,typebulbBinPath:()=>tr,unregisterServer:()=>un,writeWaitCursor:()=>ws});import{spawn as Zg}from"child_process";import{readdir as ZT,readFile as ny,writeFile as ry,unlink as ku,mkdir as eP}from"fs/promises";import{mkdirSync as sy,writeFileSync as Io,appendFileSync as tP,readFileSync as xu}from"fs";import*as Te from"path";import{fileURLToPath as nP}from"url";function Eu(n){return Te.join(dt(),`${n}.json`)}function Zn(n){return Te.join(dt(),`${n}.log`)}function Au(n){return Te.join(dt(),`${n}.wait.json`)}function iy(n){try{let e=JSON.parse(xu(Au(n),"utf8"));return e.cursors&&typeof e.cursors=="object"?e.cursors:{}}catch{return{}}}function No(n,e=""){let t=iy(n)[e];return typeof t=="number"&&Number.isFinite(t)&&t>=0?t:void 0}function ws(n,e,t=""){try{sy(dt(),{recursive:!0});let r=iy(n);r[t]=e,Io(Au(n),JSON.stringify({cursors:r}))}catch{}}function vs(n){let e=Zn(n);try{sy(dt(),{recursive:!0}),Io(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 l=typeof a=="string"?Buffer.from(a,"utf8"):Buffer.from(a);if(tP(e,l),s+=l.length,s>2*ey){let c=xu(e),f=c.subarray(Math.max(0,c.length-ey));Io(e,f),s=f.length}}catch{i=!0}};return process.stdout.write=((a,...l)=>(o(a),t(a,...l))),process.stderr.write=((a,...l)=>(o(a),r(a,...l))),()=>{process.stdout.write=t,process.stderr.write=r}}function Tu(n){try{Io(Zn(n),"")}catch{}}function Ye(n,e=0){try{let t=xu(Zn(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 Pu(n){return`\u2500\u2500 run ${n} \u2500\u2500 ${new Date().toTimeString().slice(0,8)}`}function sP(n){let e=rP.exec(n);return e?Number(e[1]):void 0}function Ou(n,e){let t=n.split(`
|
|
315
315
|
`),r=[];if(t.forEach((o,a)=>{let l=sP(o);l!==void 0&&r.push({id:l,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(`
|
|
316
316
|
`)}function Xn(n){try{return process.kill(n,0),!0}catch(e){return e.code==="EPERM"}}async function Cu(n){try{await eP(dt(),{recursive:!0}),await ry(Eu(n.pid),JSON.stringify({version:Le,...n}))}catch{ut()}}async function _u(n,e){let t=Eu(n);try{let r=JSON.parse(await ny(t,"utf8"));if(r.denied===e)return;r.denied=e,await ry(t,JSON.stringify(r))}catch{}}async function un(n){await ku(Eu(n)).catch(()=>{}),await ku(Zn(n)).catch(()=>{}),await ku(Au(n)).catch(()=>{})}function me(n){return n.agent!=null}function er(n,e){return me(n)&&n.cwd!=null&&se(n.cwd)===se(e)}function Ru(n,e){return!me(n)&&Jg(n.file,e)}async function Q(n){let e;try{e=await ZT(dt())}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 ny(Te.join(dt(),s),"utf8"))}catch{await un(i);return}o&&typeof o.pid=="number"&&Xn(o.pid)?t.push(o):await un(i)})),(n?t.filter(s=>Ru(s,n)):t).sort((s,i)=>s.startedAt-i.startedAt)}async function $o(n,e){return(await Q()).find(t=>er(t,n)&&(e?t.agent===e:!0))}async function Iu(n,e){let t=new URL(n).port,r=(await Q()).filter(a=>String(a.port)!==t),s=r.filter(a=>er(a,e)),i=r.filter(a=>Ru(a,e)),o=0;for(let a of[...s,...i])try{let l=await fetch(`${a.url}/__open`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:n}),signal:AbortSignal.timeout(2e3)});if(!l.ok)continue;let{opened:c,pages:f}=await l.json();if(c)return{where:"editor",via:a.agent?"the agent mirror":`${Te.basename(a.file)}'s page`};me(a)&&(o+=f??0)}catch{}return o>0?{where:"external"}:void 0}async function Qn(n){try{process.kill(n,"SIGTERM")}catch{}await un(n)}async function Nu(n){try{let e=await fetch(`${n.url}/__pages`,{signal:AbortSignal.timeout(iP)});if(!e.ok)return;let{pages:t}=await e.json();return typeof t=="number"?t:void 0}catch{return}}async function Bt(n,e=me(n)?"keep":"close"){try{let t=await fetch(`${n.url}/__stop`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pages:e}),signal:AbortSignal.timeout(ty)});if(!t.ok)throw new Error(`/__stop ${t.status}`);let{closed:r=0,stuck:s=0}=await t.json(),i=Date.now()+ty;for(;Xn(n.pid)&&Date.now()<i;)await oy(100);return Xn(n.pid)?(await Qn(n.pid),"killed"):(await un(n.pid),{closed:r,stuck:s})}catch{return await Qn(n.pid),"killed"}}function dn(n,e){let t=se(e);return n.filter(r=>!me(r)&&r.pid!==process.pid&&se(r.file)===t)}async function Lo(n,e){let t=dn(await Q(),n);for(let r of t)await Bt(r,e!==void 0&&r.port===e?"keep":"close");return t}function oP(n,e,t){(process.platform==="win32"?Zg("cmd",["/c","start","","/b",n,...e],{cwd:t,stdio:"ignore",windowsHide:!0}):Zg(n,e,{cwd:t,detached:!0,stdio:"ignore"})).unref()}function tr(){return Te.join(Te.dirname(nP(import.meta.url)),"index.js")}function ay(n,e={}){return{command:process.execPath,args:[tr(),...e.trust?["--trust"]:[],...e.mode?["--mode",e.mode]:[],n,...e.open===!1?["--no-open"]:[]]}}function ly(n){return{command:process.execPath,args:[tr(),`agent:${n}`,"--no-open"]}}async function cy(n,e,t,r){let s=await n();if(s)return s;oP(e.command,e.args,t);let i=Date.now()+2e4;for(;Date.now()<i;){await oy(150);let o=await n();if(o)return o}throw new Error(`Launched ${r} but it did not register within 20s.`)}async function Ss(n,e={}){let t=e.cwd??process.cwd(),r=Te.resolve(t,n),s=await Gn({kind:"bulb",file:r},t),[i]=await Lo(r,s),o={...e,mode:e.mode??i?.mode};return cy(async()=>dn(await Q(),r)[0],ay(n,o),t,Te.basename(n))}async function $u(n,e=process.cwd()){return cy(()=>$o(e,n),ly(n),e,`the ${n} mirror`)}var ey,rP,ty,iP,oy,$e=S(()=>{"use strict";nt();cn();Ro();ey=1e6;rP=/^── run (\d+) ── /;ty=6e3,iP=500;oy=n=>new Promise(e=>setTimeout(e,n))});function nr(n){return{...Zf(n),server:n.files.get("server.ts")??""}}function Mo(n){return!!n.server&&!n.code}var ks=S(()=>{"use strict";ee();ee()});function Bo(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 Lu(n){return Kn(Bo(n)??"bulb")||"bulb"}var Mu=S(()=>{"use strict";ee()});import{readdirSync as aP,readFileSync as lP,statSync as cP}from"fs";import{join as uy,basename as uP}from"path";function fy(n,e,t){if(e>8)return t;let r;try{r=aP(n,{withFileTypes:!0})}catch{return t}for(let s of r)if(s.isDirectory()){if(s.name.startsWith(".")||s.name==="node_modules")continue;fy(uy(n,s.name),e+1,t)}else s.isFile()&&s.name.endsWith(".bulb.md")&&t.push(uy(n,s.name));return t}function dP(n,e){let t,r=!1;try{let s=lP(n,"utf8");t=Bo(s.slice(0,1024));let i=We(s);r=!!i&&Mo(nr(i))}catch{}return{mtime:e,name:t??uP(n).replace(/\.bulb\.md$/,""),serverOnly:r}}function Do(n){let e=new Map,t=fy(n,0,[]).map(r=>{let s=0;try{s=cP(r).mtimeMs}catch{}let i=s?dy.get(r):void 0,o=i?.mtime===s?i:dP(r,s);return s&&e.set(r,o),{path:r,...o}});return dy=e,t}var dy,py=S(()=>{"use strict";ee();ks();Mu();dy=new Map});function rr(n){if(n.server.trim())return"server-side code (server.ts)";let e=n.code;if(/\btb\s*\.\s*fs\b/.test(e)||e.includes("/__fs"))return"the filesystem";if(/\btb\s*\.\s*ai\b/.test(e)||e.includes("/__ai")||n.infer.trim()||/\btb\s*\.\s*infer\b/.test(e))return"AI (your API keys)";if(/\btb\s*\.\s*server\s*\.\s*\w/.test(e)||e.includes("/__api"))return"server-side code (server.ts)"}var jo=S(()=>{"use strict"});import{readFile as fP}from"fs/promises";async function Bu(n){try{let e=We(await fP(n,"utf-8"));return e?rr(nr(e)):void 0}catch{return}}var hy=S(()=>{"use strict";ks();jo()});function Du(n){let e=n.split(""),t=(i,o)=>{for(let a=i;a<o&&a<e.length;a++)e[a]!==`
|
|
317
317
|
`&&(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]!==`
|