@bivy/bivy 0.20.9-staging.5 → 0.20.9-staging.7
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 +5 -3
- package/dist/apps/styles.css +7 -15
- package/dist/ephemeral-teardown.js +11 -1
- package/dist/server.js +2 -1
- package/package.json +2 -2
- package/web/assets/{AutomationsView-88EXNIPQ.js → AutomationsView-D445-bV7.js} +1 -1
- package/web/assets/{ChangesCard-DwHi_6Qt.js → ChangesCard-C67_Ay8t.js} +1 -1
- package/web/assets/{LibraryView-tWv7wXEN.js → LibraryView-DvoQYJWV.js} +1 -1
- package/web/assets/{ProviderConnect-BwPHDImW.js → ProviderConnect-DTK0aMt0.js} +1 -1
- package/web/assets/{Settings-biyPk9go.js → Settings-Vx94BlX0.js} +3 -3
- package/web/assets/{Sheet-B8nU0wgN.js → Sheet-CT1aLpQD.js} +1 -1
- package/web/assets/{Terminal-CnZ1VDIk.js → Terminal-BY2iHE2c.js} +1 -1
- package/web/assets/{VoiceSettings-BTzS72of.js → VoiceSettings-BdNUzVte.js} +1 -1
- package/web/assets/{abnfDiagram-VCTEODGH-B2SWZ7Hk.js → abnfDiagram-VCTEODGH-CojCKgbs.js} +1 -1
- package/web/assets/architecture-7GRP2DOG-D-wTFlHA.js +1 -0
- package/web/assets/{architectureDiagram-5GKGNRK7-foj0DNzV.js → architectureDiagram-5GKGNRK7-NZZSfjvP.js} +1 -1
- package/web/assets/{blockDiagram-I7D4REHJ-D2A__uKh.js → blockDiagram-I7D4REHJ-eRxQprk8.js} +1 -1
- package/web/assets/{c4Diagram-7LVT6UL2-B7FQMCr4.js → c4Diagram-7LVT6UL2-D6Ixot4g.js} +1 -1
- package/web/assets/channel-BZ9q5WkS.js +1 -0
- package/web/assets/{chunk-4HAMMTFA-DPhrei5t.js → chunk-4HAMMTFA-Doy03Ghl.js} +1 -1
- package/web/assets/{chunk-75Z2AOVW-DjsXA9qr.js → chunk-75Z2AOVW-BJ2SE7Qp.js} +1 -1
- package/web/assets/{chunk-DU6HZSFF-7yK82Ixu.js → chunk-DU6HZSFF-Dt5ewPDF.js} +1 -1
- package/web/assets/{chunk-F27PBJKO-zXarTHbA.js → chunk-F27PBJKO-D3guFMr5.js} +1 -1
- package/web/assets/{chunk-GMAD6QVW-DekNL5Z6.js → chunk-GMAD6QVW-BmFGgat8.js} +1 -1
- package/web/assets/{chunk-GVQU2GXP-2-63YaAu.js → chunk-GVQU2GXP-DFBAgenx.js} +1 -1
- package/web/assets/{chunk-IMKFNOWR-BnXS6zTy.js → chunk-IMKFNOWR-8gmgNJLT.js} +1 -1
- package/web/assets/{chunk-L3NEJ4N5-Das1_7VI.js → chunk-L3NEJ4N5-BAK8Ttl3.js} +1 -1
- package/web/assets/{chunk-OSK3NFVY-CZQXFkby.js → chunk-OSK3NFVY-eYZCFV_w.js} +1 -1
- package/web/assets/{chunk-P2QGCYS3-CrrI7snr.js → chunk-P2QGCYS3-DUPAe9pm.js} +1 -1
- package/web/assets/{chunk-POPQ4Y6H-BCWAj0uj.js → chunk-POPQ4Y6H-C0d3tHZO.js} +1 -1
- package/web/assets/{chunk-PWAF6VOD-QU4mwqNG.js → chunk-PWAF6VOD-p19FH_YR.js} +1 -1
- package/web/assets/{chunk-SHT3W25Y-DKK4bYa_.js → chunk-SHT3W25Y-Rpn9d2Rm.js} +1 -1
- package/web/assets/{chunk-SVP7TREG-DVpIpUz5.js → chunk-SVP7TREG-CAPdAg0C.js} +1 -1
- package/web/assets/{chunk-TICWLB2K-CD5I6Urj.js → chunk-TICWLB2K-Bc4LPO1N.js} +1 -1
- package/web/assets/classDiagram-ZZMXUADV-nlLoGCy4.js +1 -0
- package/web/assets/classDiagram-v2-VYDZK3BY-nlLoGCy4.js +1 -0
- package/web/assets/{cynefin-OW5HDTMX-DAZWONdy.js → cynefin-OW5HDTMX-C-O66eOU.js} +1 -1
- package/web/assets/{cynefinDiagram-5FMLGOSQ-Bk4YSWH3.js → cynefinDiagram-5FMLGOSQ-DbnDizEd.js} +1 -1
- package/web/assets/{dagre-GXQ25YYZ-B_QwDXkQ.js → dagre-GXQ25YYZ-uCBN4B8g.js} +1 -1
- package/web/assets/{diagram-S7CK7UJ4-BAUwp4BB.js → diagram-S7CK7UJ4-Bh1aP-3D.js} +1 -1
- package/web/assets/{diagram-UQ7AKVKN-BM-V089U.js → diagram-UQ7AKVKN-itw6v7_J.js} +1 -1
- package/web/assets/{diagram-VSXAHHWV-Cb7dueGC.js → diagram-VSXAHHWV-CWEw-WVn.js} +1 -1
- package/web/assets/{diagram-VX7I27RA-DbaPD2xJ.js → diagram-VX7I27RA-WOJQe21A.js} +1 -1
- package/web/assets/{diagram-Z3DM3KII-C6za-TAl.js → diagram-Z3DM3KII-zhMndslq.js} +1 -1
- package/web/assets/{ebnfDiagram-PWID7BFC-D7a_R6to.js → ebnfDiagram-PWID7BFC-DwNE2Lvt.js} +1 -1
- package/web/assets/{erDiagram-RLTQ6QDP-DVovhc9P.js → erDiagram-RLTQ6QDP-zUhuN-9H.js} +1 -1
- package/web/assets/eventmodeling-NTZA5JFV-D9CvhIf4.js +1 -0
- package/web/assets/flowDiagram-HODETNUW-BDdebgr9.js +1 -0
- package/web/assets/{ganttDiagram-EL5Y4UJY--wdWZHDZ.js → ganttDiagram-EL5Y4UJY-DXdLEN17.js} +1 -1
- package/web/assets/{gitGraph-4MIJSDKK-DQP9nR6k.js → gitGraph-4MIJSDKK-Klcu9ia9.js} +1 -1
- package/web/assets/{gitGraphDiagram-WWUBYQGX-DTSPr47e.js → gitGraphDiagram-WWUBYQGX-BU5YHKgV.js} +1 -1
- package/web/assets/{index-Btqu2K0o.js → index-CplEYkZZ.js} +2 -2
- package/web/assets/index-eLh2Uq9D.css +1 -0
- package/web/assets/{info-A6RAGUB7-tLtHC-qT.js → info-A6RAGUB7-BH-ebc3S.js} +1 -1
- package/web/assets/{infoDiagram-27XIBGKW-CqoUt_T5.js → infoDiagram-27XIBGKW-B_KV6pf8.js} +1 -1
- package/web/assets/{ishikawaDiagram-5VMMS53U-B5H3_AGa.js → ishikawaDiagram-5VMMS53U-BPAiHRbY.js} +1 -1
- package/web/assets/{journeyDiagram-3NMN7TZE-GGCZ2IZq.js → journeyDiagram-3NMN7TZE-DhM5N8fe.js} +1 -1
- package/web/assets/{kanban-definition-UXKFOSKX-CTkRTTQ1.js → kanban-definition-UXKFOSKX-DOCGhg2w.js} +1 -1
- package/web/assets/{line-BHhma6NO.js → line-B4QIneuG.js} +1 -1
- package/web/assets/{mermaid-parser.core-CEooByan.js → mermaid-parser.core-D9vIJCvx.js} +3 -3
- package/web/assets/{mermaid.core-DL7nUcjk.js → mermaid.core-DjgZ8mDF.js} +4 -4
- package/web/assets/{mindmap-definition-YA3MSWOX-lD--tv6u.js → mindmap-definition-YA3MSWOX-xnFcHxVA.js} +1 -1
- package/web/assets/{mount-CBU-u2DV.js → mount-BP8alXTE.js} +6 -6
- package/web/assets/{packet-AYTQ26CC-BUtKNGJC.js → packet-AYTQ26CC-yH38dnyf.js} +1 -1
- package/web/assets/{pegDiagram-XKGWAZYB-CfFP4exu.js → pegDiagram-XKGWAZYB-CevgBOwk.js} +1 -1
- package/web/assets/{pie-WAS4IAKB-B9XAaaAT.js → pie-WAS4IAKB-C7xh6GDD.js} +1 -1
- package/web/assets/{pieDiagram-E7YTZNPT-8mL3GI9A.js → pieDiagram-E7YTZNPT-DKRVnhDT.js} +1 -1
- package/web/assets/{quadrantDiagram-AXDQQJYC-CpScc79Z.js → quadrantDiagram-AXDQQJYC-DXkOkaBM.js} +1 -1
- package/web/assets/{radar-RG4KPBEZ-nZ7fVmAT.js → radar-RG4KPBEZ-CwSQV2mt.js} +1 -1
- package/web/assets/{railroad-74A4TZTK-Dcbk9jaL.js → railroad-74A4TZTK-cuHWOkA0.js} +1 -1
- package/web/assets/railroad-abnf-HS5TGJTU-SDwDddPJ.js +1 -0
- package/web/assets/railroad-ebnf-LZEXJU2U-CgdgpBax.js +1 -0
- package/web/assets/railroad-peg-WCYAUIDC-C98PgZH-.js +1 -0
- package/web/assets/{railroadDiagram-O6MQD6OU-DMoMWEZ8.js → railroadDiagram-O6MQD6OU-CkqsXyWH.js} +1 -1
- package/web/assets/{requirementDiagram-BXWQKSXE-2Gqgo265.js → requirementDiagram-BXWQKSXE-4ysj3ubr.js} +1 -1
- package/web/assets/{sankeyDiagram-P5KCCOFB-DvKL4Prr.js → sankeyDiagram-P5KCCOFB-CTfCHptt.js} +1 -1
- package/web/assets/{sequenceDiagram-WJ2MYXX4-JjZhg4uB.js → sequenceDiagram-WJ2MYXX4-Bt3hLzHR.js} +1 -1
- package/web/assets/{settingsRoute-B7Knsrbc.js → settingsRoute-7vm_XT5W.js} +1 -1
- package/web/assets/{stateDiagram-D77RDMKH-B7_u9TgS.js → stateDiagram-D77RDMKH-DbmwF870.js} +1 -1
- package/web/assets/stateDiagram-v2-MP3YSRHH-DBdwh_1Q.js +1 -0
- package/web/assets/{swimlanes-42K2YHIH-eVUyJa8p.js → swimlanes-42K2YHIH-CS3QAsbj.js} +1 -1
- package/web/assets/swimlanesDiagram-VR7AAH4N-yJeCEj8W.js +8 -0
- package/web/assets/{timeline-definition-24CTP7MA-BsQsAXVS.js → timeline-definition-24CTP7MA-BFY0vMBm.js} +1 -1
- package/web/assets/{treeView-Q6P3EWNA-DtVJjYQP.js → treeView-Q6P3EWNA-BSLxywJi.js} +1 -1
- package/web/assets/{treemap-WGGIJYW6-XKHkQVDs.js → treemap-WGGIJYW6-ZON8ykos.js} +1 -1
- package/web/assets/useStore-CNkjpbem.js +29 -0
- package/web/assets/{vennDiagram-4TSXK5OY-DCwbZ2DM.js → vennDiagram-4TSXK5OY-BQLzgH0P.js} +1 -1
- package/web/assets/{wardley-WFR3VGLG-ExoXJyLY.js → wardley-WFR3VGLG-BeuSz2cJ.js} +1 -1
- package/web/assets/{wardleyDiagram-VM6X3IG4-DNi_8Ot1.js → wardleyDiagram-VM6X3IG4-Drcnk9OV.js} +1 -1
- package/web/assets/{xychartDiagram-S5SC5T6Z-BDbPDbWQ.js → xychartDiagram-S5SC5T6Z-DYhLrcFq.js} +1 -1
- package/web/index.html +2 -2
- package/web/sw.js +1 -1
- package/web/assets/architecture-7GRP2DOG-CdKNHpNr.js +0 -1
- package/web/assets/channel-Bo-_QtP0.js +0 -1
- package/web/assets/classDiagram-ZZMXUADV-B-3oe4TG.js +0 -1
- package/web/assets/classDiagram-v2-VYDZK3BY-B-3oe4TG.js +0 -1
- package/web/assets/eventmodeling-NTZA5JFV-DgZXoSVB.js +0 -1
- package/web/assets/flowDiagram-HODETNUW-GNuKkNfD.js +0 -1
- package/web/assets/index-DVs67yqr.css +0 -1
- package/web/assets/railroad-abnf-HS5TGJTU-Bk5xkNVz.js +0 -1
- package/web/assets/railroad-ebnf-LZEXJU2U-CYO_EiAe.js +0 -1
- package/web/assets/railroad-peg-WCYAUIDC-JlyhMwRV.js +0 -1
- package/web/assets/stateDiagram-v2-MP3YSRHH-DFpDxN-e.js +0 -1
- package/web/assets/swimlanesDiagram-VR7AAH4N-bhrhVbfn.js +0 -8
- package/web/assets/useStore-COC7r3VV.js +0 -29
package/README.md
CHANGED
|
@@ -527,6 +527,8 @@ use, modify, and self-host it under that license. If users interact with your
|
|
|
527
527
|
modified version over a network, section 13 requires you to offer its
|
|
528
528
|
corresponding source. See [LICENSE](LICENSE).
|
|
529
529
|
|
|
530
|
-
Bivy Cloud is the hosted operation of that stack
|
|
531
|
-
separate private
|
|
532
|
-
|
|
530
|
+
Bivy Cloud is the hosted operation of that stack. Its plans, billing and
|
|
531
|
+
managed-compute operations live in a separate private service behind Core's
|
|
532
|
+
deployment extension. Contributions are made under the
|
|
533
|
+
[Contributor License Agreement](CLA.md). The Bivy name and logo are covered by
|
|
534
|
+
the [trademark policy](TRADEMARKS.md).
|
package/dist/apps/styles.css
CHANGED
|
@@ -485,6 +485,12 @@ input, textarea, select { font-family: inherit; font-size: 16px; }
|
|
|
485
485
|
}
|
|
486
486
|
.transcript-turn { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
|
|
487
487
|
.transcript-standalone { display: flex; justify-content: center; min-width: 0; }
|
|
488
|
+
/* A centered flex row lets a child grow past the column on one long unbroken
|
|
489
|
+
token (a path in an error); cap every standalone item to the column. */
|
|
490
|
+
.transcript-standalone > * { min-width: 0; max-width: 100%; }
|
|
491
|
+
/* Errors span the column so their edges line up with the turn content. */
|
|
492
|
+
.transcript-error { flex: 1; display: flex; flex-direction: column; gap: var(--space-2); overflow-wrap: anywhere; }
|
|
493
|
+
.transcript-error .settings-disclosure-body { margin: 0; padding: 0; white-space: pre-wrap; font-size: var(--text-xs); color: var(--muted); }
|
|
488
494
|
.turn-response-body { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
|
|
489
495
|
.jump-latest {
|
|
490
496
|
position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%);
|
|
@@ -655,20 +661,6 @@ input, textarea, select { font-family: inherit; font-size: 16px; }
|
|
|
655
661
|
.entry-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); font-style: normal; }
|
|
656
662
|
.msg.system .entry-actions { justify-content: center; }
|
|
657
663
|
.msg.thinking { align-self: flex-start; color: var(--muted); font-size: 13px; border-left: 2px solid var(--line-strong); padding-left: 10px; }
|
|
658
|
-
.msg.error {
|
|
659
|
-
align-self: stretch; display: flex; gap: 8px; align-items: flex-start;
|
|
660
|
-
background: var(--danger-soft); border: 1px solid color-mix(in srgb, var(--danger) 45%, transparent);
|
|
661
|
-
border-left: 3px solid var(--danger); border-radius: var(--radius-sm); padding: 10px 12px;
|
|
662
|
-
}
|
|
663
|
-
.msg-error-icon {
|
|
664
|
-
flex: none; width: 18px; height: 18px; margin-top: 1px; border-radius: var(--radius-full);
|
|
665
|
-
background: var(--danger); color: var(--danger-contrast); font-weight: 700; font-size: 12px;
|
|
666
|
-
display: grid; place-items: center;
|
|
667
|
-
}
|
|
668
|
-
.msg-error-text {
|
|
669
|
-
flex: 1; min-width: 0; font-size: 13px; line-height: 1.45; color: var(--ink);
|
|
670
|
-
white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word;
|
|
671
|
-
}
|
|
672
664
|
.msg.streaming { position: relative; }
|
|
673
665
|
.msg.streaming::after { content: "▍"; color: var(--accent); animation: blink 1s steps(2) infinite; }
|
|
674
666
|
@keyframes blink { 50% { opacity: 0; } }
|
|
@@ -2647,7 +2639,7 @@ a.queue-item:hover { border-color: var(--line-strong); background: var(--surface
|
|
|
2647
2639
|
.connect-option-link:hover { text-decoration: underline; }
|
|
2648
2640
|
.connect-option-cta { align-self: flex-start; }
|
|
2649
2641
|
/* A one-time "next step" card above the composer (automations, notifications). */
|
|
2650
|
-
.next-step {
|
|
2642
|
+
.next-step { box-sizing: border-box; width: min(100% - 2 * var(--space-3), 800px - 2 * var(--space-3)); margin: 0 auto var(--space-3); display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
|
|
2651
2643
|
.next-step p { margin: var(--space-1) 0 0; color: var(--muted); font-size: var(--text-sm); }
|
|
2652
2644
|
.next-step .banner { margin-top: var(--space-2); }
|
|
2653
2645
|
.next-step .next-step-ok { margin: 0; color: var(--ok); font-weight: var(--weight-medium); }
|
|
@@ -9,6 +9,7 @@ export function readEphemeralTeardownConfig(env = process.env) {
|
|
|
9
9
|
onFinish: env.BIVY_TEARDOWN_ON_FINISH === "1",
|
|
10
10
|
finishGraceMs: Number(env.BIVY_TEARDOWN_FINISH_GRACE_MS) || 10_000,
|
|
11
11
|
idleGraceMs: Number(env.BIVY_SESSION_IDLE_CLOSE_MS) || 30 * 60 * 1000,
|
|
12
|
+
sleep: env.BIVY_EPHEMERAL_SLEEP === "1",
|
|
12
13
|
};
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
@@ -20,8 +21,10 @@ export function readEphemeralTeardownConfig(env = process.env) {
|
|
|
20
21
|
export function shouldSelfTeardown(cfg, state) {
|
|
21
22
|
if (!cfg.enabled)
|
|
22
23
|
return false;
|
|
24
|
+
// A fresh box waits for its first work. A sleeping machine woken for
|
|
25
|
+
// nothing goes back to sleep after the idle window instead of running to TTL.
|
|
23
26
|
if (!state.everBusy)
|
|
24
|
-
return
|
|
27
|
+
return cfg.sleep && state.idleForMs >= cfg.idleGraceMs;
|
|
25
28
|
if (state.anyWorking || state.anyRemoteActive || state.inFlightWork > 0)
|
|
26
29
|
return false;
|
|
27
30
|
const grace = cfg.onFinish ? cfg.finishGraceMs : cfg.idleGraceMs;
|
|
@@ -50,6 +53,13 @@ export async function performSelfTeardown(deps) {
|
|
|
50
53
|
torndown = true;
|
|
51
54
|
const log = deps.log ?? ((m) => console.log(`[ephemeral-teardown] ${m}`));
|
|
52
55
|
const exit = deps.exit ?? ((c) => process.exit(c));
|
|
56
|
+
if (deps.sleep) {
|
|
57
|
+
// Exit only: the provider keeps the stopped machine and its disk, and a
|
|
58
|
+
// wake starts it again. Signalling settled would get it reaped.
|
|
59
|
+
log(`machine idle — sleeping (provider=${deps.provider})`);
|
|
60
|
+
exit(0);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
53
63
|
log(`machine idle — self-teardown (provider=${deps.provider})`);
|
|
54
64
|
try {
|
|
55
65
|
await deps.signalSettled?.();
|
package/dist/server.js
CHANGED
|
@@ -7643,6 +7643,7 @@ function evaluateEphemeralTeardown() {
|
|
|
7643
7643
|
}
|
|
7644
7644
|
await performSelfTeardown({
|
|
7645
7645
|
provider: ephemeralTeardownCfg.provider,
|
|
7646
|
+
sleep: ephemeralTeardownCfg.sleep,
|
|
7646
7647
|
signalSettled: signalSettledToControlPlane,
|
|
7647
7648
|
shutdown: () => { try {
|
|
7648
7649
|
spawnSync("shutdown", ["-h", "now"], { stdio: "ignore" });
|
|
@@ -7657,7 +7658,7 @@ if (ephemeralTeardownCfg.enabled) {
|
|
|
7657
7658
|
const ephemeralEvalMs = Math.max(2_000, Math.min(ephemeralTeardownCfg.finishGraceMs, 15_000));
|
|
7658
7659
|
const ephemeralTeardownTimer = setInterval(() => evaluateEphemeralTeardown(), ephemeralEvalMs);
|
|
7659
7660
|
ephemeralTeardownTimer.unref?.();
|
|
7660
|
-
console.log(`[ephemeral-teardown] armed: provider=${ephemeralTeardownCfg.provider} onFinish=${ephemeralTeardownCfg.onFinish} ttl=${ephemeralTeardownCfg.ttlMin}m`);
|
|
7661
|
+
console.log(`[ephemeral-teardown] armed: provider=${ephemeralTeardownCfg.provider} onFinish=${ephemeralTeardownCfg.onFinish} sleep=${ephemeralTeardownCfg.sleep} ttl=${ephemeralTeardownCfg.ttlMin}m`);
|
|
7661
7662
|
}
|
|
7662
7663
|
setTimeout(() => void sweepDiskGuardrails(), 30_000).unref?.();
|
|
7663
7664
|
// One sweep shortly after boot clears ghosts left by a previous run before any
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bivy/bivy",
|
|
3
|
-
"version": "0.20.9-staging.
|
|
3
|
+
"version": "0.20.9-staging.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"description": "Run coding agents on machines you own. Open-source, self-hostable agent workspace.",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"lodash-es": "4.18.1",
|
|
66
66
|
"undici": "8.11.2"
|
|
67
67
|
},
|
|
68
|
-
"readme": "# Bivy\n\n[](https://www.npmjs.com/package/@bivy/bivy)\n[](LICENSE)\n[](https://nodejs.org)\n\n**Local coding agents that show their work. Anywhere.**\n\nBivy is the open-source workspace for coding agents. It runs Claude Code, Codex,\nPi, OpenCode and other agents on your own machine. Reach them from a browser or\nyour phone, with the live session, its terminal, its approvals, and the app\nthey're building right in the chat. Try it, mark what's wrong, and send it back.\n\n<p align=\"center\">\n <img src=\"docs/images/preview-feedback-loop.gif\" width=\"360\"\n alt=\"On a phone: open the app an agent built, circle the packed items, send a note, and compare the result before and after the agent's fix.\">\n</p>\n\nBivy is not another coding agent and not a cloud development machine. The agent\nstays local and does the coding with your model provider. Your repos, tools,\ndatabases, and services stay where they are. Bivy gives you remote access to all\nof it, plus live previews, automations, and review.\n\n- **Live previews.** The running app beside the chat. Mark it, send it back,\n share it with someone who has no Bivy account.\n- **Automations.** GitHub issues, failed CI, Linear, Slack, schedules, and\n webhooks start the work. It comes back as a preview link or a pull request.\n- **Any agent.** Hit a usage limit? Fork the session to another agent, or let\n Bivy retry when the limit resets.\n- **Your machine, anywhere.** Start at your desk, pick the session up on your\n phone. The machine dials out, so there are no ports to open, and session\n traffic is end-to-end encrypted.\n\n**[Start free on Bivy Cloud](https://app.bivy.sh)** ·\n**[Quickstart](docs/quickstart.md)** ·\n**[Documentation](docs/README.md)** ·\n**[Self-host](docs/deploy-images.md)** ·\n**[Website](https://bivy.sh)**\n\n**Recommended:** sign in at [app.bivy.sh](https://app.bivy.sh), then copy your\npersonalized **Connect a Machine** command into a terminal on your Mac or Linux\ncomputer. It installs and enrolls the machine without another Bivy login. The\nbrowser connects automatically; choose a repository and send your first task\nright there.\n\nPrefer starting from the terminal?\n\n```bash\ncurl -fsSL https://bivy.sh/install.sh | bash # install + guided setup\ncd your-repo\nbivy run claude # or codex, pi, opencode\nbivy open # continue in the web app (needs remote setup)\n```\n\nBivy Cloud hosts the app, control plane, and relay—not the machines running your\nagents. Connect a Mac, Linux computer, or existing server and bring your own\nagent subscription, model API key, or local model. You can also self-host the\nentire remote-access stack.\n\n> **Bivy is 0.x software.** Claude Code, Codex, Pi, OpenCode, and Grok are the\n> release-tested paths. Credential sync, resume, handoffs, approvals, and\n> sandboxing depend on the runtime. See the\n> [runtime support matrix](docs/runtime-support-matrix.md).\n\n## Don't just read the diff. Try the app.\n\nBivy lets you **use what the agent built and show it what to fix**, without a\nseparate deployment step.\n\n1. **Ask for a change.** The agent works in your repo with your existing tools\n and local services.\n2. **Try the app.** Bivy finds the dev server the agent starts and opens it\n beside the chat: web apps, terminals, and desktop apps. Use the running app,\n not a screenshot of what the agent says it finished.\n3. **Mark what needs work.** Press and hold anything in the preview to mark it,\n or drag to circle it, then say what you want. **Mark another** keeps\n separate notes separate. The marks go to the agent with the element and page\n context. No screenshots to paste.\n4. **Follow each note.** Every mark stays in the chat as a pin that resolves\n itself: **Changed** when a later run changes what you marked, **Element\n gone** when it leaves the page, **Done** when you say so.\n5. **Review the next version.** A new version waits on the preview pill instead\n of reloading under you. Take it when you're ready, compare before and after,\n inspect the diff and checks, and decide when the work is done.\n6. **Get a second opinion.** Share a preview link for 1 hour, 1 day, or 7 days.\n Teammates and clients try the running app and leave notes without a Bivy\n account. Make it view-only, or **Stop sharing** to end every link at once.\n\nOn Bivy Cloud, preview delivery is built in: no per-app domains, certificates,\npublic ports, or tunnels to configure. Self-hosters configure preview delivery\nonce for their Bivy deployment, not for every app. The app still needs its normal\nbuild or dev-server setup, and **the machine serving it must stay awake and\nonline**. These are development previews, not production hosting.\n\n**Share deliberately:** anyone with a preview link can use that app, including\nits live backend, until the link expires or you stop sharing.\nReviewer notes aren't sent to the agent automatically; you send them or explicitly\nallow agent access. Preview traffic uses HTTPS through the preview relay, not\nsession end-to-end encryption; the relay operator can see it.\n\n[App previews, visual feedback, and sharing →](docs/apps.md)\n\n## One workflow, from trigger to review\n\n```text\nPrompt · GitHub issue · CI failure · Linear · Slack · Schedule · Webhook\n │\n ▼\n Choose machine + agent + model\n + supported credentials\n │\n ▼\n Live agent session\n Join · steer · approve · stop\n │\n ▼\n Try app · inspect changes · checks\n │\n ▼\n Mark up · send feedback · iterate\n │\n ▼\n Share preview · review PR\n```\n\nA **Machine** is a computer or server you connect. A **Session** is live agent\nwork on that machine. A **Run** is delegated background work that creates a\nsession and tracks its outcome. An **Automation** is a reusable definition that\ncreates runs when an event matches.\n\nManual and automated work use the same kind of live session. You can join a run\nwhen it needs help rather than wait for a black-box job to finish.\n\n### Let events start the work\n\nAutomations turn recurring or incoming work into sessions you can join,\nsupervise, and review. An agent picks the task up on your machine and posts\nback a preview link or a pull request, so you try the result where the task\nlives and reply in the same session. Choose the repository, machine, agent,\nmodel, approval mode, sandbox setting, and maximum attempts.\n\n| Trigger | Example workflow |\n|---|---|\n| **GitHub issues and mentions** | Label an issue `bivy` or `bivy/<machine>`, or mention your Bivy GitHub App, to work toward a pull request. |\n| **Failed CI** | Match a failed workflow, ask the agent to reproduce it, make a fix, and run the affected checks. |\n| **Linear** | Label an issue to start work without copying its description into an agent. |\n| **Slack** | Send a request from the conversation where the work came up. |\n| **Schedules** | Run a weekly dependency review, recurring maintenance, or a one-time task. |\n| **Signed webhooks** | Connect alerts, internal tools, or your own event sources. |\n\nConfigure automations in the app or version them with your repository in\n`.bivy/automations.yaml`:\n\n```bash\nbivy automation init\n# Edit the generated definition for your repository and workflow.\nbivy automation validate\nbivy automation test --event .bivy/events/failed-ci.yaml # supply a local event fixture\nbivy automation apply\n```\n\nOr delegate a one-off job without creating an automation:\n\n```bash\nbivy runs start \"Review outdated dependencies and propose a small, tested update.\"\nbivy runs wait <id>\n```\n\nRuns keep routing and lifecycle evidence, check results, and output references\nin a reviewable Receipt. For unattended issue work, Bivy runs declared repository\nchecks after the agent's turn; failed required checks fail the run even if the\nagent reports success. A completed process alone is not proof that the task\nsucceeded.\n\n[Automation recipes →](docs/capability-recipes.md#let-events-start-runs) ·\n[Automations as code →](docs/automations-as-code.md) ·\n[Run outcomes and reliability limits →](docs/automation-runs.md)\n\n### Use every agent you pay for. Switch mid-task.\n\nRun Claude Code for one task, Codex for another, and Pi or OpenCode where they\nfit, side by side in one session list. Bivy supplies the shared session,\nremote-access, automation, and review surfaces; your chosen agent still does\nthe coding and uses your model provider.\n\n- **Hit a usage limit? Keep going.** When a turn fails on a limit, fork the\n session, with its code and conversation, to another agent and model, or let\n Bivy retry when the limit resets (the provider has to report a reset time).\n- **Get a second opinion.** `bivy delegate` hands a task to another agent, on\n the same machine or a different one, and brings back its answer, branch, and\n PR. `--to codex,claude@linux` sends one task to several agents to compare.\n- Choose an agent and, where supported, a model for each session or run.\n- Import existing Claude Code and Codex sessions.\n- Fork or move work to another agent or machine when a different setup fits\n better. Continuation fidelity varies: some paths preserve native history,\n while others replay portable turns or hand over a summary with the earlier\n transcript as a local file.\n- Use agent-native logins, Bivy-managed credentials, or local inference.\n Bivy's custom OpenAI-compatible endpoint registry currently feeds Pi;\n other agents may need their own provider configuration.\n- Register your own ACP or headless process agent with `bivy agent add`.\n\nBivy does not replace your agent, provide model inference, or make every agent's\nfeatures identical. Consult the [support matrix](docs/runtime-support-matrix.md)\nand [handoff recipes](docs/capability-recipes.md#fork-or-move-a-session).\n\n### Less signing in. Less copying secrets.\n\nBivy syncs **Bivy-managed API keys and supported OAuth credentials** across\nenrolled machines for compatible runtimes. Connect supported credentials once\nand reuse them where you run work, rather than manually distributing keys to\neach machine.\n\nFor ordinary account sync, credentials are encrypted on the node before upload.\nThe control plane stores ciphertext and wrapped-key metadata; enrolled nodes\nshare access by wrapping the vault key to one another. Bivy Cloud does not\nreceive plaintext credentials through this sync path.\n\nYou can also keep credentials local, use labeled keys and project presets, or\nreference environment variables and 1Password instead of embedding secrets in\nconfiguration:\n\n```bash\nbivy provider login\nbivy credentials add anthropic work\nbivy secrets ref github.repo-token op://Bivy/GitHub/repo-token\n```\n\n**Not every CLI login syncs.** Native agent logins may still be per-machine;\nGitHub App private-key sync is separately opt-in. If you lose every node and\ndevice able to unwrap a vault, you must sign in to providers again. Explicit\nhosted-provisioning custody grants are separate from ordinary encrypted sync.\n\n[Credential sync and runtime coverage →](docs/credential-sync.md) ·\n[Credentials guide →](docs/credentials-guide.md) ·\n[Key storage →](docs/key-management.md)\n\n### Work in the environment you already have\n\nA clean cloud sandbox isn't always enough. Your agent may need the database\nrunning on localhost, an uncommitted change, an internal API behind your VPN,\nor a model running on your GPU. Bivy runs the agent where those things already\nexist, subject to that machine's permissions and the runtime's protection.\n\nConnect several machines to the same account: a laptop for interactive work,\na Linux server for background jobs, or a GPU box for local inference. Choose\nthe machine for each session or pin it in an automation. Repository runs can\nuse isolated Git worktrees without rebuilding the whole development environment.\n\n**The execution machine must stay awake and online.** To close your laptop and\nleave work running, run the agent on a different, always-on machine.\n\n[Environment and multi-machine recipes →](docs/capability-recipes.md)\n\n### Start at your desk. Continue anywhere.\n\nOpen the same session in the browser, phone PWA, or terminal. Watch work live,\nanswer questions, approve supported tool calls, or stop the agent.\n\n- Send screenshots, images, logs, and other files from your phone.\n- Download reports and artifacts the agent creates.\n- Open [session apps](docs/apps.md) from chat or the **Apps** menu: live web\n previews, desktop app views, and CLI/TUI tools. Agents can publish views with\n `bivy app publish bivy.app.json` and create share links with `bivy app share`.\n- Use voice input and read-aloud where supported; provider-backed voice may\n send audio or text to the selected provider.\n- Keep a native terminal workflow or use structured chat, depending on the agent.\n\n```bash\nbivy run claude --no-follow # start without attaching\nbivy open # open the web app\nbivy resume # return to the session in your terminal\nbivy link # pair a device directly via QR\n```\n\nNo phone app installation is required. Open [app.bivy.sh](https://app.bivy.sh)\nin your browser; adding it to your home screen is optional.\n\n[Remote access →](docs/remote-access.md) ·\n[Voice, files, and terminal recipes →](docs/capability-recipes.md)\n\n### Agents can reach you, too\n\nEvery session gets the `bivy` CLI, so any agent with a shell can talk back\nthrough the app, not only agents with their own built-in tools:\n\n```bash\nbivy notify \"Tests are green, PR is up\" # chat card + phone push when you're away\nbivy ask \"Ship to staging?\" --option Yes --option No # waits for your answer\nbivy attach report.png --caption \"Before/after\" # show a file in the chat\nbivy suggest \"Add a dark theme to settings\" # a next task you start in one tap\nbivy context --json # session, workspace, machine, apps\n```\n\n`bivy help --json` lists every command, and with `BIVY_OUTPUT=json` failures\ncome back as structured errors with distinct exit codes, so an agent can tell\nwhat went wrong and what to run next. `bivy guide` prints short playbooks for\nagents, and the same commands are served as MCP tools for agents that prefer\nthem. Add your own standing instructions for\nevery session in **Settings → Agent instructions**.\n\n[Commands for agents inside a session →](docs/cli-reference.md#inside-an-agent-session) ·\n[Agent instructions →](docs/agent-instructions.md)\n\n## Get started\n\n### Install\n\nBivy supports **macOS and Linux with Node.js 20+**. The installer installs the\n`@bivy/bivy` package, runs guided setup, and starts a launchd or systemd service:\n\n```bash\ncurl -fsSL https://bivy.sh/install.sh | bash\n```\n\nSetup helps you choose an agent and configure remote access. Existing agents\nkeep their command, login, and configuration. The installer may use `sudo` to\ninstall a missing Node.js, but never for `npm install`. To inspect it first,\ndownload it with `curl -fsSL https://bivy.sh/install.sh -o install.sh`.\n\nAlready have Node.js and want to avoid sudo?\n\n```bash\nnpm install -g @bivy/bivy\nbivy setup\n```\n\nThen try one small task:\n\n```bash\ncd your-repo\nbivy run claude\n# Ask: \"Explain this repo and make one small, safe improvement. Run the relevant checks.\"\nbivy open\n```\n\nOpen that same session on your phone while it runs. For a web app, ask the agent\nto start its dev server, then open **Apps → Running in this workspace → Preview**.\nTry a page, point to something you'd change, and send the feedback back to the\nagent. No separate preview deployment needed.\n\nOnce that works, share a preview for review, connect another machine, or add\nyour first automation.\n\n**Local-only works too.** `bivy run`, `bivy resume`, and `bivy sessions` need no\naccount or server. Choose **local only for now** during setup; use `bivy login`\nlater.\n\n**Just your own devices?** `bivy tailscale` serves the app from the machine\nitself at `https://<machine>.<tailnet>.ts.net`, with no account, control plane\nor relay. You get the core over your tailnet: sessions, chat, approvals,\nquestions, terminals and files. Push notifications, app previews and share\nlinks need Bivy Cloud or a self-hosted server. See [Tailscale](docs/tailscale.md)\nand [Remote access](docs/remote-access.md).\n\n[Full quickstart →](docs/quickstart.md) ·\n[Installer options, service management, and uninstall →](docs/install.md)\n\n### Choose hosted or self-hosted\n\n| Option | What you get |\n|---|---|\n| **Free Cloud — $0** | Every launch feature, including automations; 10 new remote sessions per rolling seven days. No credit card required. |\n| **Cloud — $15/month** | The same features with unlimited remote sessions. |\n| **Self-hosted Core** | Operate the app, control plane, and relay yourself, with no Bivy usage limits. |\n\nManual and automated sessions share the Cloud allowance. Resuming existing\nsessions and viewing history do not consume it. Agent subscriptions and model\nprovider charges are separate. See [current pricing](https://bivy.sh#pricing).\n\n**Self-host anywhere:** deploy the public control-plane (including the web app)\nand relay images with Postgres and [a small set of environment variables](docs/deploy-images.md).\nYour server or container platform handles HTTPS. Set up owner access in the\nbrowser—no SSH, external authentication provider, or Bivy Cloud account required.\nFor a bare VPS, the [Compose installer](docs/self-host-quickstart.md) automates the\nsame stack. These onboarding features require a release containing them.\n\nStart on Cloud and self-host later if you prefer. Deploy the stack, reconnect\nmachines with `bivy relay:setup`, and pair devices to your server. This is not a\none-click migration of your Cloud account; your local repos and agent\nconfiguration stay in place.\n\n```bash\nbivy relay:setup \\\n --control-plane https://bivy.example.com \\\n --relay wss://relay.example.com\n```\n\nSelf-hosting is community-supported: you own TLS, backups, upgrades, and\nhardening. Public multi-architecture images are available as\n`ghcr.io/bivysh/bivy-control-plane` and `ghcr.io/bivysh/bivy-relay`; pin a release\nversion or full commit SHA.\n\n[Deploy the images anywhere →](docs/deploy-images.md) ·\n[Optional VPS installer →](docs/self-host-quickstart.md) ·\n[Operations reference →](docs/self-host.md)\n\n## Architecture\n\nYour environment, with clear security boundaries:\n\n```text\nYour machine Hosted or self-hosted\n┌──────────────────────┐ ┌──────────────────────┐\n│ Node daemon │──outbound──▶│ Relay │\n│ Agents, repos, tools │ │ Encrypted frames │\n│ Local credentials │ └──────────┬───────────┘\n└──────────────────────┘ │\n Browser / phone\n + control plane\n (app, accounts, metadata)\n```\n\n- **Execution stays on your machine.** Bivy Cloud does not run your agents.\n Your model provider still sees whatever the agent sends it.\n- **Interactive session traffic is end-to-end encrypted** between the node and\n paired devices. The relay forwards opaque session frames; your node dials out,\n so no inbound public port is required.\n- **App previews have a separate security boundary.** Preview traffic uses HTTPS\n and an outbound tunnel, not session E2E encryption. The preview ingress/relay\n operator can see it. Public preview links grant anyone holding them access to\n that view and its live backend until expiry or revocation. See\n [preview security and sharing](docs/apps.md#runtime-and-security-boundaries).\n- **Ordinary credential sync uploads ciphertext, not plaintext keys.**\n Supported credentials and recovery limits are documented separately.\n- **Encryption is not universal across integrations.** Slack commands and\n generic webhook instructions reach the control plane in plaintext. Do not\n put secrets in them. Routing and bounded run metadata are also visible there.\n- **Device authorization matters.** QR pairing authorizes a device directly\n through the node. Hosted account pairing trusts the control plane to authorize\n devices and serve the web app that holds client keys.\n- **Bivy is not an OS-level sandbox.** The default approval mode is\n `autonomous`; protection depends on the runtime. Some agents enforce sandbox\n tiers, while process agents may run with your full user permissions.\n Heuristic tool checks help prevent accidents but are not isolation.\n\nReview the runtime's Protection label and configure approval/sandbox settings\nfor the task, especially before enabling unattended work.\n\n[Security model and known limitations →](docs/security-model.md) ·\n[Runtime protection matrix →](docs/runtime-support-matrix.md) ·\n[Configuration →](docs/configuration.md)\n\n## Agents and everyday commands\n\n**Claude Code, Codex, Pi, OpenCode, and Grok are release-tested.** Additional\nadapters include Gemini CLI, Qwen Code, Goose, Aider, Cline, Crush, Cursor, GitHub\nCopilot, Amp, Auggie, Droid, Continue, Kilo Code, and Rovo Dev. Installation,\nresume, model selection, and tool protection vary—see the\n[support matrix](docs/runtime-support-matrix.md) and [agent guides](docs/agents/README.md).\n\nRun an arbitrary command with `bivy run -- ./your-agent --flags`, register a\nreusable entry with `bivy agent add`, or package a declarative integration with\nexperimental [plugins](docs/plugins.md).\n\n```bash\nbivy run claude # launch a durable session; also codex, pi, opencode\nbivy sessions # list live and saved sessions\nbivy resume # resume the most recent session\nbivy open # open the web app (requires remote setup)\nbivy nodes # list connected account machines\nbivy runs list # inspect delegated work\nbivy automation init # scaffold repo-owned automations\nbivy provider login # connect supported model credentials\nbivy agent add # register an ACP or process agent\nbivy doctor # check installation and connectivity\nbivy logs -f # follow node logs\nbivy update # update and restart the service\n```\n\n`bivy update` uses your original installation method and waits for an active\nturn to finish before restarting. Use `--force` to skip that wait.\n\n[CLI reference →](docs/cli-reference.md) ·\n[Node and project configuration →](docs/config-as-code.md) ·\n[GitHub setup →](docs/github-setup.md) ·\n[Linear setup →](docs/linear-work-queue.md)\n\n## Development and contributions\n\n```bash\npnpm install\npnpm run dev # node daemon on http://localhost:4317\npnpm run dev:web # web client dev server\n```\n\n| Directory | Contents |\n|---|---|\n| `src/`, `bin/` | Node daemon, CLI, runtime adapters, sessions, approvals, secrets |\n| `packages/core/` | Shared protocol, pairing, and wire format |\n| `packages/web/`, `packages/ui/` | React PWA and shared design system |\n| `services/relay/` | Self-hostable encrypted relay |\n| `services/control-plane/` | Self-hostable control plane |\n| `deploy/` | Deployment examples |\n\n```bash\npnpm run typecheck\npnpm run typecheck:web\npnpm run lint\npnpm run test:unit\npnpm run test:core\npnpm run check:licenses\npnpm run check:secrets\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the development workflow. Releases\nare published from CI with provenance attestations; see\n[release verification](docs/releasing.md).\n\n**Found a security issue?** Use\n[GitHub private vulnerability reporting](https://github.com/bivysh/bivy/security/advisories/new),\nnot a public issue. See [SECURITY.md](SECURITY.md).\n\n### In development—not available at launch\n\nAutomatically provisioned, short-lived **ephemeral machines** are in development\nfor hosted and bring-your-own-cloud deployments. Neither path is ready or\nsupported for this launch. Use an existing computer or server you operate.\nExperimental provisioning has different credential-custody and encryption\nboundaries; see the [provisioning trust model](docs/hosted-provisioning-trust-model.md).\n\n## License\n\nEverything in this repository—node, CLI, web/PWA, relay, and control plane—is\nfree and open-source **AGPL-3.0-only Core**, with no Bivy usage limits. You may\nuse, modify, and self-host it under that license. If users interact with your\nmodified version over a network, section 13 requires you to offer its\ncorresponding source. See [LICENSE](LICENSE).\n\nBivy Cloud is the hosted operation of that stack plus billing and plans, in a\nseparate private repository. Contributions use the\n[DCO](CONTRIBUTING.md#certificate-of-origin); there is no CLA.\n",
|
|
68
|
+
"readme": "# Bivy\n\n[](https://www.npmjs.com/package/@bivy/bivy)\n[](LICENSE)\n[](https://nodejs.org)\n\n**Local coding agents that show their work. Anywhere.**\n\nBivy is the open-source workspace for coding agents. It runs Claude Code, Codex,\nPi, OpenCode and other agents on your own machine. Reach them from a browser or\nyour phone, with the live session, its terminal, its approvals, and the app\nthey're building right in the chat. Try it, mark what's wrong, and send it back.\n\n<p align=\"center\">\n <img src=\"docs/images/preview-feedback-loop.gif\" width=\"360\"\n alt=\"On a phone: open the app an agent built, circle the packed items, send a note, and compare the result before and after the agent's fix.\">\n</p>\n\nBivy is not another coding agent and not a cloud development machine. The agent\nstays local and does the coding with your model provider. Your repos, tools,\ndatabases, and services stay where they are. Bivy gives you remote access to all\nof it, plus live previews, automations, and review.\n\n- **Live previews.** The running app beside the chat. Mark it, send it back,\n share it with someone who has no Bivy account.\n- **Automations.** GitHub issues, failed CI, Linear, Slack, schedules, and\n webhooks start the work. It comes back as a preview link or a pull request.\n- **Any agent.** Hit a usage limit? Fork the session to another agent, or let\n Bivy retry when the limit resets.\n- **Your machine, anywhere.** Start at your desk, pick the session up on your\n phone. The machine dials out, so there are no ports to open, and session\n traffic is end-to-end encrypted.\n\n**[Start free on Bivy Cloud](https://app.bivy.sh)** ·\n**[Quickstart](docs/quickstart.md)** ·\n**[Documentation](docs/README.md)** ·\n**[Self-host](docs/deploy-images.md)** ·\n**[Website](https://bivy.sh)**\n\n**Recommended:** sign in at [app.bivy.sh](https://app.bivy.sh), then copy your\npersonalized **Connect a Machine** command into a terminal on your Mac or Linux\ncomputer. It installs and enrolls the machine without another Bivy login. The\nbrowser connects automatically; choose a repository and send your first task\nright there.\n\nPrefer starting from the terminal?\n\n```bash\ncurl -fsSL https://bivy.sh/install.sh | bash # install + guided setup\ncd your-repo\nbivy run claude # or codex, pi, opencode\nbivy open # continue in the web app (needs remote setup)\n```\n\nBivy Cloud hosts the app, control plane, and relay—not the machines running your\nagents. Connect a Mac, Linux computer, or existing server and bring your own\nagent subscription, model API key, or local model. You can also self-host the\nentire remote-access stack.\n\n> **Bivy is 0.x software.** Claude Code, Codex, Pi, OpenCode, and Grok are the\n> release-tested paths. Credential sync, resume, handoffs, approvals, and\n> sandboxing depend on the runtime. See the\n> [runtime support matrix](docs/runtime-support-matrix.md).\n\n## Don't just read the diff. Try the app.\n\nBivy lets you **use what the agent built and show it what to fix**, without a\nseparate deployment step.\n\n1. **Ask for a change.** The agent works in your repo with your existing tools\n and local services.\n2. **Try the app.** Bivy finds the dev server the agent starts and opens it\n beside the chat: web apps, terminals, and desktop apps. Use the running app,\n not a screenshot of what the agent says it finished.\n3. **Mark what needs work.** Press and hold anything in the preview to mark it,\n or drag to circle it, then say what you want. **Mark another** keeps\n separate notes separate. The marks go to the agent with the element and page\n context. No screenshots to paste.\n4. **Follow each note.** Every mark stays in the chat as a pin that resolves\n itself: **Changed** when a later run changes what you marked, **Element\n gone** when it leaves the page, **Done** when you say so.\n5. **Review the next version.** A new version waits on the preview pill instead\n of reloading under you. Take it when you're ready, compare before and after,\n inspect the diff and checks, and decide when the work is done.\n6. **Get a second opinion.** Share a preview link for 1 hour, 1 day, or 7 days.\n Teammates and clients try the running app and leave notes without a Bivy\n account. Make it view-only, or **Stop sharing** to end every link at once.\n\nOn Bivy Cloud, preview delivery is built in: no per-app domains, certificates,\npublic ports, or tunnels to configure. Self-hosters configure preview delivery\nonce for their Bivy deployment, not for every app. The app still needs its normal\nbuild or dev-server setup, and **the machine serving it must stay awake and\nonline**. These are development previews, not production hosting.\n\n**Share deliberately:** anyone with a preview link can use that app, including\nits live backend, until the link expires or you stop sharing.\nReviewer notes aren't sent to the agent automatically; you send them or explicitly\nallow agent access. Preview traffic uses HTTPS through the preview relay, not\nsession end-to-end encryption; the relay operator can see it.\n\n[App previews, visual feedback, and sharing →](docs/apps.md)\n\n## One workflow, from trigger to review\n\n```text\nPrompt · GitHub issue · CI failure · Linear · Slack · Schedule · Webhook\n │\n ▼\n Choose machine + agent + model\n + supported credentials\n │\n ▼\n Live agent session\n Join · steer · approve · stop\n │\n ▼\n Try app · inspect changes · checks\n │\n ▼\n Mark up · send feedback · iterate\n │\n ▼\n Share preview · review PR\n```\n\nA **Machine** is a computer or server you connect. A **Session** is live agent\nwork on that machine. A **Run** is delegated background work that creates a\nsession and tracks its outcome. An **Automation** is a reusable definition that\ncreates runs when an event matches.\n\nManual and automated work use the same kind of live session. You can join a run\nwhen it needs help rather than wait for a black-box job to finish.\n\n### Let events start the work\n\nAutomations turn recurring or incoming work into sessions you can join,\nsupervise, and review. An agent picks the task up on your machine and posts\nback a preview link or a pull request, so you try the result where the task\nlives and reply in the same session. Choose the repository, machine, agent,\nmodel, approval mode, sandbox setting, and maximum attempts.\n\n| Trigger | Example workflow |\n|---|---|\n| **GitHub issues and mentions** | Label an issue `bivy` or `bivy/<machine>`, or mention your Bivy GitHub App, to work toward a pull request. |\n| **Failed CI** | Match a failed workflow, ask the agent to reproduce it, make a fix, and run the affected checks. |\n| **Linear** | Label an issue to start work without copying its description into an agent. |\n| **Slack** | Send a request from the conversation where the work came up. |\n| **Schedules** | Run a weekly dependency review, recurring maintenance, or a one-time task. |\n| **Signed webhooks** | Connect alerts, internal tools, or your own event sources. |\n\nConfigure automations in the app or version them with your repository in\n`.bivy/automations.yaml`:\n\n```bash\nbivy automation init\n# Edit the generated definition for your repository and workflow.\nbivy automation validate\nbivy automation test --event .bivy/events/failed-ci.yaml # supply a local event fixture\nbivy automation apply\n```\n\nOr delegate a one-off job without creating an automation:\n\n```bash\nbivy runs start \"Review outdated dependencies and propose a small, tested update.\"\nbivy runs wait <id>\n```\n\nRuns keep routing and lifecycle evidence, check results, and output references\nin a reviewable Receipt. For unattended issue work, Bivy runs declared repository\nchecks after the agent's turn; failed required checks fail the run even if the\nagent reports success. A completed process alone is not proof that the task\nsucceeded.\n\n[Automation recipes →](docs/capability-recipes.md#let-events-start-runs) ·\n[Automations as code →](docs/automations-as-code.md) ·\n[Run outcomes and reliability limits →](docs/automation-runs.md)\n\n### Use every agent you pay for. Switch mid-task.\n\nRun Claude Code for one task, Codex for another, and Pi or OpenCode where they\nfit, side by side in one session list. Bivy supplies the shared session,\nremote-access, automation, and review surfaces; your chosen agent still does\nthe coding and uses your model provider.\n\n- **Hit a usage limit? Keep going.** When a turn fails on a limit, fork the\n session, with its code and conversation, to another agent and model, or let\n Bivy retry when the limit resets (the provider has to report a reset time).\n- **Get a second opinion.** `bivy delegate` hands a task to another agent, on\n the same machine or a different one, and brings back its answer, branch, and\n PR. `--to codex,claude@linux` sends one task to several agents to compare.\n- Choose an agent and, where supported, a model for each session or run.\n- Import existing Claude Code and Codex sessions.\n- Fork or move work to another agent or machine when a different setup fits\n better. Continuation fidelity varies: some paths preserve native history,\n while others replay portable turns or hand over a summary with the earlier\n transcript as a local file.\n- Use agent-native logins, Bivy-managed credentials, or local inference.\n Bivy's custom OpenAI-compatible endpoint registry currently feeds Pi;\n other agents may need their own provider configuration.\n- Register your own ACP or headless process agent with `bivy agent add`.\n\nBivy does not replace your agent, provide model inference, or make every agent's\nfeatures identical. Consult the [support matrix](docs/runtime-support-matrix.md)\nand [handoff recipes](docs/capability-recipes.md#fork-or-move-a-session).\n\n### Less signing in. Less copying secrets.\n\nBivy syncs **Bivy-managed API keys and supported OAuth credentials** across\nenrolled machines for compatible runtimes. Connect supported credentials once\nand reuse them where you run work, rather than manually distributing keys to\neach machine.\n\nFor ordinary account sync, credentials are encrypted on the node before upload.\nThe control plane stores ciphertext and wrapped-key metadata; enrolled nodes\nshare access by wrapping the vault key to one another. Bivy Cloud does not\nreceive plaintext credentials through this sync path.\n\nYou can also keep credentials local, use labeled keys and project presets, or\nreference environment variables and 1Password instead of embedding secrets in\nconfiguration:\n\n```bash\nbivy provider login\nbivy credentials add anthropic work\nbivy secrets ref github.repo-token op://Bivy/GitHub/repo-token\n```\n\n**Not every CLI login syncs.** Native agent logins may still be per-machine;\nGitHub App private-key sync is separately opt-in. If you lose every node and\ndevice able to unwrap a vault, you must sign in to providers again. Explicit\nhosted-provisioning custody grants are separate from ordinary encrypted sync.\n\n[Credential sync and runtime coverage →](docs/credential-sync.md) ·\n[Credentials guide →](docs/credentials-guide.md) ·\n[Key storage →](docs/key-management.md)\n\n### Work in the environment you already have\n\nA clean cloud sandbox isn't always enough. Your agent may need the database\nrunning on localhost, an uncommitted change, an internal API behind your VPN,\nor a model running on your GPU. Bivy runs the agent where those things already\nexist, subject to that machine's permissions and the runtime's protection.\n\nConnect several machines to the same account: a laptop for interactive work,\na Linux server for background jobs, or a GPU box for local inference. Choose\nthe machine for each session or pin it in an automation. Repository runs can\nuse isolated Git worktrees without rebuilding the whole development environment.\n\n**The execution machine must stay awake and online.** To close your laptop and\nleave work running, run the agent on a different, always-on machine.\n\n[Environment and multi-machine recipes →](docs/capability-recipes.md)\n\n### Start at your desk. Continue anywhere.\n\nOpen the same session in the browser, phone PWA, or terminal. Watch work live,\nanswer questions, approve supported tool calls, or stop the agent.\n\n- Send screenshots, images, logs, and other files from your phone.\n- Download reports and artifacts the agent creates.\n- Open [session apps](docs/apps.md) from chat or the **Apps** menu: live web\n previews, desktop app views, and CLI/TUI tools. Agents can publish views with\n `bivy app publish bivy.app.json` and create share links with `bivy app share`.\n- Use voice input and read-aloud where supported; provider-backed voice may\n send audio or text to the selected provider.\n- Keep a native terminal workflow or use structured chat, depending on the agent.\n\n```bash\nbivy run claude --no-follow # start without attaching\nbivy open # open the web app\nbivy resume # return to the session in your terminal\nbivy link # pair a device directly via QR\n```\n\nNo phone app installation is required. Open [app.bivy.sh](https://app.bivy.sh)\nin your browser; adding it to your home screen is optional.\n\n[Remote access →](docs/remote-access.md) ·\n[Voice, files, and terminal recipes →](docs/capability-recipes.md)\n\n### Agents can reach you, too\n\nEvery session gets the `bivy` CLI, so any agent with a shell can talk back\nthrough the app, not only agents with their own built-in tools:\n\n```bash\nbivy notify \"Tests are green, PR is up\" # chat card + phone push when you're away\nbivy ask \"Ship to staging?\" --option Yes --option No # waits for your answer\nbivy attach report.png --caption \"Before/after\" # show a file in the chat\nbivy suggest \"Add a dark theme to settings\" # a next task you start in one tap\nbivy context --json # session, workspace, machine, apps\n```\n\n`bivy help --json` lists every command, and with `BIVY_OUTPUT=json` failures\ncome back as structured errors with distinct exit codes, so an agent can tell\nwhat went wrong and what to run next. `bivy guide` prints short playbooks for\nagents, and the same commands are served as MCP tools for agents that prefer\nthem. Add your own standing instructions for\nevery session in **Settings → Agent instructions**.\n\n[Commands for agents inside a session →](docs/cli-reference.md#inside-an-agent-session) ·\n[Agent instructions →](docs/agent-instructions.md)\n\n## Get started\n\n### Install\n\nBivy supports **macOS and Linux with Node.js 20+**. The installer installs the\n`@bivy/bivy` package, runs guided setup, and starts a launchd or systemd service:\n\n```bash\ncurl -fsSL https://bivy.sh/install.sh | bash\n```\n\nSetup helps you choose an agent and configure remote access. Existing agents\nkeep their command, login, and configuration. The installer may use `sudo` to\ninstall a missing Node.js, but never for `npm install`. To inspect it first,\ndownload it with `curl -fsSL https://bivy.sh/install.sh -o install.sh`.\n\nAlready have Node.js and want to avoid sudo?\n\n```bash\nnpm install -g @bivy/bivy\nbivy setup\n```\n\nThen try one small task:\n\n```bash\ncd your-repo\nbivy run claude\n# Ask: \"Explain this repo and make one small, safe improvement. Run the relevant checks.\"\nbivy open\n```\n\nOpen that same session on your phone while it runs. For a web app, ask the agent\nto start its dev server, then open **Apps → Running in this workspace → Preview**.\nTry a page, point to something you'd change, and send the feedback back to the\nagent. No separate preview deployment needed.\n\nOnce that works, share a preview for review, connect another machine, or add\nyour first automation.\n\n**Local-only works too.** `bivy run`, `bivy resume`, and `bivy sessions` need no\naccount or server. Choose **local only for now** during setup; use `bivy login`\nlater.\n\n**Just your own devices?** `bivy tailscale` serves the app from the machine\nitself at `https://<machine>.<tailnet>.ts.net`, with no account, control plane\nor relay. You get the core over your tailnet: sessions, chat, approvals,\nquestions, terminals and files. Push notifications, app previews and share\nlinks need Bivy Cloud or a self-hosted server. See [Tailscale](docs/tailscale.md)\nand [Remote access](docs/remote-access.md).\n\n[Full quickstart →](docs/quickstart.md) ·\n[Installer options, service management, and uninstall →](docs/install.md)\n\n### Choose hosted or self-hosted\n\n| Option | What you get |\n|---|---|\n| **Free Cloud — $0** | Every launch feature, including automations; 10 new remote sessions per rolling seven days. No credit card required. |\n| **Cloud — $15/month** | The same features with unlimited remote sessions. |\n| **Self-hosted Core** | Operate the app, control plane, and relay yourself, with no Bivy usage limits. |\n\nManual and automated sessions share the Cloud allowance. Resuming existing\nsessions and viewing history do not consume it. Agent subscriptions and model\nprovider charges are separate. See [current pricing](https://bivy.sh#pricing).\n\n**Self-host anywhere:** deploy the public control-plane (including the web app)\nand relay images with Postgres and [a small set of environment variables](docs/deploy-images.md).\nYour server or container platform handles HTTPS. Set up owner access in the\nbrowser—no SSH, external authentication provider, or Bivy Cloud account required.\nFor a bare VPS, the [Compose installer](docs/self-host-quickstart.md) automates the\nsame stack. These onboarding features require a release containing them.\n\nStart on Cloud and self-host later if you prefer. Deploy the stack, reconnect\nmachines with `bivy relay:setup`, and pair devices to your server. This is not a\none-click migration of your Cloud account; your local repos and agent\nconfiguration stay in place.\n\n```bash\nbivy relay:setup \\\n --control-plane https://bivy.example.com \\\n --relay wss://relay.example.com\n```\n\nSelf-hosting is community-supported: you own TLS, backups, upgrades, and\nhardening. Public multi-architecture images are available as\n`ghcr.io/bivysh/bivy-control-plane` and `ghcr.io/bivysh/bivy-relay`; pin a release\nversion or full commit SHA.\n\n[Deploy the images anywhere →](docs/deploy-images.md) ·\n[Optional VPS installer →](docs/self-host-quickstart.md) ·\n[Operations reference →](docs/self-host.md)\n\n## Architecture\n\nYour environment, with clear security boundaries:\n\n```text\nYour machine Hosted or self-hosted\n┌──────────────────────┐ ┌──────────────────────┐\n│ Node daemon │──outbound──▶│ Relay │\n│ Agents, repos, tools │ │ Encrypted frames │\n│ Local credentials │ └──────────┬───────────┘\n└──────────────────────┘ │\n Browser / phone\n + control plane\n (app, accounts, metadata)\n```\n\n- **Execution stays on your machine.** Bivy Cloud does not run your agents.\n Your model provider still sees whatever the agent sends it.\n- **Interactive session traffic is end-to-end encrypted** between the node and\n paired devices. The relay forwards opaque session frames; your node dials out,\n so no inbound public port is required.\n- **App previews have a separate security boundary.** Preview traffic uses HTTPS\n and an outbound tunnel, not session E2E encryption. The preview ingress/relay\n operator can see it. Public preview links grant anyone holding them access to\n that view and its live backend until expiry or revocation. See\n [preview security and sharing](docs/apps.md#runtime-and-security-boundaries).\n- **Ordinary credential sync uploads ciphertext, not plaintext keys.**\n Supported credentials and recovery limits are documented separately.\n- **Encryption is not universal across integrations.** Slack commands and\n generic webhook instructions reach the control plane in plaintext. Do not\n put secrets in them. Routing and bounded run metadata are also visible there.\n- **Device authorization matters.** QR pairing authorizes a device directly\n through the node. Hosted account pairing trusts the control plane to authorize\n devices and serve the web app that holds client keys.\n- **Bivy is not an OS-level sandbox.** The default approval mode is\n `autonomous`; protection depends on the runtime. Some agents enforce sandbox\n tiers, while process agents may run with your full user permissions.\n Heuristic tool checks help prevent accidents but are not isolation.\n\nReview the runtime's Protection label and configure approval/sandbox settings\nfor the task, especially before enabling unattended work.\n\n[Security model and known limitations →](docs/security-model.md) ·\n[Runtime protection matrix →](docs/runtime-support-matrix.md) ·\n[Configuration →](docs/configuration.md)\n\n## Agents and everyday commands\n\n**Claude Code, Codex, Pi, OpenCode, and Grok are release-tested.** Additional\nadapters include Gemini CLI, Qwen Code, Goose, Aider, Cline, Crush, Cursor, GitHub\nCopilot, Amp, Auggie, Droid, Continue, Kilo Code, and Rovo Dev. Installation,\nresume, model selection, and tool protection vary—see the\n[support matrix](docs/runtime-support-matrix.md) and [agent guides](docs/agents/README.md).\n\nRun an arbitrary command with `bivy run -- ./your-agent --flags`, register a\nreusable entry with `bivy agent add`, or package a declarative integration with\nexperimental [plugins](docs/plugins.md).\n\n```bash\nbivy run claude # launch a durable session; also codex, pi, opencode\nbivy sessions # list live and saved sessions\nbivy resume # resume the most recent session\nbivy open # open the web app (requires remote setup)\nbivy nodes # list connected account machines\nbivy runs list # inspect delegated work\nbivy automation init # scaffold repo-owned automations\nbivy provider login # connect supported model credentials\nbivy agent add # register an ACP or process agent\nbivy doctor # check installation and connectivity\nbivy logs -f # follow node logs\nbivy update # update and restart the service\n```\n\n`bivy update` uses your original installation method and waits for an active\nturn to finish before restarting. Use `--force` to skip that wait.\n\n[CLI reference →](docs/cli-reference.md) ·\n[Node and project configuration →](docs/config-as-code.md) ·\n[GitHub setup →](docs/github-setup.md) ·\n[Linear setup →](docs/linear-work-queue.md)\n\n## Development and contributions\n\n```bash\npnpm install\npnpm run dev # node daemon on http://localhost:4317\npnpm run dev:web # web client dev server\n```\n\n| Directory | Contents |\n|---|---|\n| `src/`, `bin/` | Node daemon, CLI, runtime adapters, sessions, approvals, secrets |\n| `packages/core/` | Shared protocol, pairing, and wire format |\n| `packages/web/`, `packages/ui/` | React PWA and shared design system |\n| `services/relay/` | Self-hostable encrypted relay |\n| `services/control-plane/` | Self-hostable control plane |\n| `deploy/` | Deployment examples |\n\n```bash\npnpm run typecheck\npnpm run typecheck:web\npnpm run lint\npnpm run test:unit\npnpm run test:core\npnpm run check:licenses\npnpm run check:secrets\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the development workflow. Releases\nare published from CI with provenance attestations; see\n[release verification](docs/releasing.md).\n\n**Found a security issue?** Use\n[GitHub private vulnerability reporting](https://github.com/bivysh/bivy/security/advisories/new),\nnot a public issue. See [SECURITY.md](SECURITY.md).\n\n### In development—not available at launch\n\nAutomatically provisioned, short-lived **ephemeral machines** are in development\nfor hosted and bring-your-own-cloud deployments. Neither path is ready or\nsupported for this launch. Use an existing computer or server you operate.\nExperimental provisioning has different credential-custody and encryption\nboundaries; see the [provisioning trust model](docs/hosted-provisioning-trust-model.md).\n\n## License\n\nEverything in this repository—node, CLI, web/PWA, relay, and control plane—is\nfree and open-source **AGPL-3.0-only Core**, with no Bivy usage limits. You may\nuse, modify, and self-host it under that license. If users interact with your\nmodified version over a network, section 13 requires you to offer its\ncorresponding source. See [LICENSE](LICENSE).\n\nBivy Cloud is the hosted operation of that stack. Its plans, billing and\nmanaged-compute operations live in a separate private service behind Core's\ndeployment extension. Contributions are made under the\n[Contributor License Agreement](CLA.md). The Bivy name and logo are covered by\nthe [trademark policy](TRADEMARKS.md).\n",
|
|
69
69
|
"readmeFilename": "README.md",
|
|
70
70
|
"agentBridges": {
|
|
71
71
|
"@anthropic-ai/claude-agent-sdk": "0.3.286",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e,t}from"./rolldown-runtime-hePW80VL.js";import{V as n,j as r}from"./index-Btqu2K0o.js";import{$ as i,At as a,Dt as o,G as s,M as c,Mt as l,N as u,Nt as d,Q as f,S as p,V as m,X as h,Z as g,_t as _,at as v,bt as y,ct as b,et as ee,gt as te,ht as x,i as S,it as ne,jt as re,kt as ie,lt as C,n as w,nt as T,ot as ae,st as oe,t as se,tt as ce,wt as le,x as E}from"./useStore-COC7r3VV.js";import{A as D,E as O,M as k,a as ue,f as A,h as de,i as j,j as fe,n as M,s as pe,t as N}from"./Sheet-B8nU0wgN.js";import{t as P}from"./jsx-runtime-NZYk81nU.js";import{A as me,C as he,D as ge,E as F,M as I,O as L,S as _e,T as R,j as ve,k as z,w as B}from"./mount-CBU-u2DV.js";var V=t(((e,t)=>{(function(n,r){typeof e==`object`&&typeof t==`object`?t.exports=r():typeof define==`function`&&define.amd?define(`cronstrue`,[],r):typeof e==`object`?e.cronstrue=r():n.cronstrue=r()})(globalThis,()=>(()=>{var e={6949(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.CronParser=void 0;var r=n(9515);t.CronParser=function(){function e(e,t,n){t===void 0&&(t=!0),n===void 0&&(n=!1),this.expression=e,this.dayOfWeekStartIndexZero=t,this.monthStartIndexZero=n}return e.prototype.parse=function(){var e,t=this.expression??``;if(t===`@reboot`)return e=[`@reboot`,``,``,``,``,``,``],e;if(t.startsWith(`@`)){var n=this.parseSpecial(this.expression);e=this.extractParts(n)}else e=this.extractParts(this.expression);return this.normalize(e),this.validate(e),e},e.prototype.parseSpecial=function(e){var t={"@yearly":`0 0 1 1 *`,"@annually":`0 0 1 1 *`,"@monthly":`0 0 1 * *`,"@weekly":`0 0 * * 0`,"@daily":`0 0 * * *`,"@midnight":`0 0 * * *`,"@hourly":`0 * * * *`,"@reboot":`@reboot`}[e];if(!t)throw Error(`Unknown special expression.`);return t},e.prototype.extractParts=function(e){if(!this.expression)throw Error(`cron expression is empty`);for(var t=e.trim().split(/[ ]+/),n=0;n<t.length;n++)if(t[n].includes(`,`)){var r=t[n].split(`,`).map(function(e){return e.trim()}).filter(function(e){return e!==``}).map(function(e){return isNaN(Number(e))?e:Number(e)}).filter(function(e){return e!==null&&e!==``});r.length===0&&r.push(`*`),r.sort(function(e,t){return e!==null&&t!==null?e-t:0}),t[n]=r.map(function(e){return e===null?``:e.toString()}).join(`,`)}if(t.length<5)throw Error(`Expression has only ${t.length} part${t.length==1?``:`s`}. At least 5 parts are required.`);if(t.length==5)t.unshift(``),t.push(``);else if(t.length==6)/\d{4}$/.test(t[5])||t[4]==`?`||t[2]==`?`?t.unshift(``):t.push(``);else if(t.length>7)throw Error(`Expression has ${t.length} parts; too many!`);return t},e.prototype.normalize=function(e){var t=this;if(e[3]=e[3].replace(`?`,`*`),e[5]=e[5].replace(`?`,`*`),e[2]=e[2].replace(`?`,`*`),e[0].indexOf(`0/`)==0&&(e[0]=e[0].replace(`0/`,`*/`)),e[1].indexOf(`0/`)==0&&(e[1]=e[1].replace(`0/`,`*/`)),e[2].indexOf(`0/`)==0&&(e[2]=e[2].replace(`0/`,`*/`)),e[3].indexOf(`1/`)==0&&(e[3]=e[3].replace(`1/`,`*/`)),e[4].indexOf(`1/`)==0&&(e[4]=e[4].replace(`1/`,`*/`)),e[6].indexOf(`1/`)==0&&(e[6]=e[6].replace(`1/`,`*/`)),e[5]=e[5].replace(/(^\d)|([^#/\s]\d)/g,function(e){var n=e.replace(/\D/,``),r=n;return t.dayOfWeekStartIndexZero?n==`7`&&(r=`0`):r=(parseInt(n)-1).toString(),e.replace(n,r)}),e[5]==`L`&&(e[5]=`6`),e[3]==`?`&&(e[3]=`*`),e[3].indexOf(`W`)>-1&&(e[3].indexOf(`,`)>-1||e[3].indexOf(`-`)>-1))throw Error(`The 'W' character can be specified only when the day-of-month is a single day, not a range or list of days.`);var n={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};for(var r in n)e[5]=e[5].replace(new RegExp(r,`gi`),n[r].toString());e[4]=e[4].replace(/(^\d{1,2})|([^#/\s]\d{1,2})/g,function(e){var n=e.replace(/\D/,``),r=n;return t.monthStartIndexZero&&(r=(parseInt(n)+1).toString()),e.replace(n,r)});var i={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12};for(var a in i)e[4]=e[4].replace(new RegExp(a,`gi`),i[a].toString());e[0]==`0`&&(e[0]=``),!/\*|\-|\,|\//.test(e[2])&&(/\*|\//.test(e[1])||/\*|\//.test(e[0]))&&(e[2]+=`-${e[2]}`);for(var o=0;o<e.length;o++)if(e[o].indexOf(`,`)!=-1&&(e[o]=e[o].split(`,`).filter(function(e){return e!==``}).join(`,`)||`*`),e[o]==`*/1`&&(e[o]=`*`),e[o].indexOf(`/`)>-1&&!/^\*|\-|\,/.test(e[o])){var s=null;switch(o){case 4:s=`12`;break;case 5:s=`6`;break;case 6:s=`9999`;break;default:s=null}if(s!==null){var c=e[o].split(`/`);e[o]=`${c[0]}-${s}/${c[1]}`}}},e.prototype.validate=function(e){var t=`0-9,\\-*/`;this.validateOnlyExpectedCharactersFound(e[0],t),this.validateOnlyExpectedCharactersFound(e[1],t),this.validateOnlyExpectedCharactersFound(e[2],t),this.validateOnlyExpectedCharactersFound(e[3],`0-9,\\-*/LW`),this.validateOnlyExpectedCharactersFound(e[4],t),this.validateOnlyExpectedCharactersFound(e[5],`0-9,\\-*/L#`),this.validateOnlyExpectedCharactersFound(e[6],t),this.validateAnyRanges(e)},e.prototype.validateAnyRanges=function(e){r.default.secondRange(e[0]),r.default.minuteRange(e[1]),r.default.hourRange(e[2]),r.default.dayOfMonthRange(e[3]),r.default.monthRange(e[4],this.monthStartIndexZero),r.default.dayOfWeekRange(e[5],this.dayOfWeekStartIndexZero)},e.prototype.validateOnlyExpectedCharactersFound=function(e,t){var n=e.match(RegExp(`[^${t}]+`,`gi`));if(n&&n.length)throw Error(`Expression contains invalid values: '${n.toString()}'`)},e}()},8333(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.ExpressionDescriptor=void 0;var r=n(1823),i=n(6949);t.ExpressionDescriptor=function(){function e(t,n){if(this.expression=t,this.options=n,this.expressionParts=[,,,,,],!this.options.locale&&e.defaultLocale&&(this.options.locale=e.defaultLocale),!e.locales[this.options.locale]){var r=Object.keys(e.locales)[0];console.warn(`Locale '${this.options.locale}' could not be found; falling back to '${r}'.`),this.options.locale=r}this.i18n=e.locales[this.options.locale],n.use24HourTimeFormat===void 0&&(n.use24HourTimeFormat=this.i18n.use24HourTimeFormatByDefault())}return e.toString=function(t,n){var r=n===void 0?{}:n,i=r.throwExceptionOnParseError,a=i===void 0||i,o=r.verbose,s=o!==void 0&&o,c=r.dayOfWeekStartIndexZero,l=c===void 0||c,u=r.monthStartIndexZero,d=u!==void 0&&u,f=r.use24HourTimeFormat,p=r.trimHoursLeadingZero,m=p!==void 0&&p,h=r.locale,g=h===void 0?null:h,_=r.logicalAndDayFields,v={throwExceptionOnParseError:a,verbose:s,dayOfWeekStartIndexZero:l,monthStartIndexZero:d,use24HourTimeFormat:f,trimHoursLeadingZero:m,locale:g,logicalAndDayFields:_!==void 0&&_};return v.tzOffset&&console.warn(`'tzOffset' option has been deprecated and is no longer supported.`),new e(t,v).getFullDescription()},e.initialize=function(t,n){n===void 0&&(n=`en`),e.specialCharacters=[`/`,`-`,`,`,`*`],e.defaultLocale=n,t.load(e.locales)},e.prototype.getFullDescription=function(){var e,t=``;try{var n=new i.CronParser(this.expression,this.options.dayOfWeekStartIndexZero,this.options.monthStartIndexZero);if(this.expressionParts=n.parse(),this.expressionParts[0]===`@reboot`)return(e=this.i18n).atReboot?.call(e)||`Run once, at startup`;var r=this.getTimeOfDayDescription(),a=this.getDayOfMonthDescription(),o=this.getMonthDescription(),s=this.getDayOfWeekDescription(),c=this.getYearDescription();t+=r+a+s+o+c,t=this.transformVerbosity(t,!!this.options.verbose),t=t.charAt(0).toLocaleUpperCase()+t.substr(1)}catch(e){if(!this.options.throwExceptionOnParseError)t=this.i18n.anErrorOccuredWhenGeneratingTheExpressionD();else throw`${e}`}return t},e.prototype.getTimeOfDayDescription=function(){var t=this.expressionParts[0],n=this.expressionParts[1],i=this.expressionParts[2],a=``;if(!r.StringUtilities.containsAny(n,e.specialCharacters)&&!r.StringUtilities.containsAny(i,e.specialCharacters)&&!r.StringUtilities.containsAny(t,e.specialCharacters))a+=this.i18n.atSpace()+this.formatTime(i,n,t);else if(!t&&n.indexOf(`-`)>-1&&!(n.indexOf(`,`)>-1)&&!(n.indexOf(`/`)>-1)&&!r.StringUtilities.containsAny(i,e.specialCharacters)){var o=n.split(`-`);a+=r.StringUtilities.format(this.i18n.everyMinuteBetweenX0AndX1(),this.formatTime(i,o[0],``),this.formatTime(i,o[1],``))}else if(!t&&i.indexOf(`,`)>-1&&i.indexOf(`-`)==-1&&i.indexOf(`/`)==-1&&!r.StringUtilities.containsAny(n,e.specialCharacters)){var s=i.split(`,`);a+=this.i18n.at();for(var c=0;c<s.length;c++)a&&(a+=` `),a+=this.formatTime(s[c],n,``),c<s.length-2&&(a+=`,`),c==s.length-2&&(a+=this.i18n.spaceAnd())}else{var l=this.getSecondsDescription(),u=this.getMinutesDescription(),d=this.getHoursDescription();if(a+=l,a&&u&&(a+=`, `),a+=u,u===d)return a;a&&d&&(a+=`, `),a+=d}return a},e.prototype.getSecondsDescription=function(){var e=this;return this.getSegmentDescription(this.expressionParts[0],this.i18n.everySecond(),function(e){return e},function(t){return r.StringUtilities.format(e.i18n.everyX0Seconds(t),t)},function(t){return e.i18n.secondsX0ThroughX1PastTheMinute()},function(t){return t==`0`?``:parseInt(t)<20?e.i18n.atX0SecondsPastTheMinute(t):e.i18n.atX0SecondsPastTheMinuteGt20()||e.i18n.atX0SecondsPastTheMinute(t)},{min:0,max:59})},e.prototype.getMinutesDescription=function(){var e=this,t=this.expressionParts[0],n=this.expressionParts[2];return this.getSegmentDescription(this.expressionParts[1],this.i18n.everyMinute(),function(e){return e},function(t){return r.StringUtilities.format(e.i18n.everyX0Minutes(t),t)},function(t){return e.i18n.minutesX0ThroughX1PastTheHour()},function(r){var i;try{return r==`0`&&n.indexOf(`/`)==-1&&t==``?e.i18n.everyHour():r==`0`?(i=e.i18n).onTheHour?.call(i)||e.i18n.atX0MinutesPastTheHour(r):parseInt(r)<20?e.i18n.atX0MinutesPastTheHour(r):e.i18n.atX0MinutesPastTheHourGt20()||e.i18n.atX0MinutesPastTheHour(r)}catch{return e.i18n.atX0MinutesPastTheHour(r)}},{min:0,max:59})},e.prototype.getHoursDescription=function(){var e=this,t=this.expressionParts[2],n=0,i=[];t.split(`/`)[0].split(`,`).forEach(function(e){var t=e.split(`-`);t.length===2&&i.push({value:t[1],index:n+1}),n+=t.length});var a=0;return this.getSegmentDescription(t,this.i18n.everyHour(),function(t){var n=i.find(function(e){return e.value===t&&e.index===a})&&e.expressionParts[1]!==`0`;return a++,n?e.formatTime(t,`59`,``):e.formatTime(t,`0`,``)},function(t){return r.StringUtilities.format(e.i18n.everyX0Hours(t),t)},function(t){return e.i18n.betweenX0AndX1()},function(t){return e.i18n.atX0()},{min:0,max:23})},e.prototype.getDayOfWeekDescription=function(){var e=this,t=this.i18n.daysOfTheWeek(),n=null;return n=this.expressionParts[5]==`*`?``:this.getSegmentDescription(this.expressionParts[5],this.i18n.commaEveryDay(),function(n,r){var i=n;n.indexOf(`#`)>-1?i=n.substring(0,n.indexOf(`#`)):n.indexOf(`L`)>-1&&(i=i.replace(`L`,``));var a=parseInt(i),o=e.i18n.daysOfTheWeekInCase?e.i18n.daysOfTheWeekInCase(r)[a]:t[a];if(n.indexOf(`#`)>-1){var s=null,c=n.substring(n.indexOf(`#`)+1),l=n.substring(0,n.indexOf(`#`));switch(c){case`1`:s=e.i18n.first(l);break;case`2`:s=e.i18n.second(l);break;case`3`:s=e.i18n.third(l);break;case`4`:s=e.i18n.fourth(l);break;case`5`:s=e.i18n.fifth(l)}o=s+` `+o}return o},function(t){return parseInt(t)==1?``:r.StringUtilities.format(e.i18n.commaEveryX0DaysOfTheWeek(t),t)},function(t){var n=t.substring(0,t.indexOf(`-`));return e.expressionParts[3]==`*`?e.i18n.commaX0ThroughX1(n):e.i18n.commaAndX0ThroughX1(n)},function(t){var n=null;if(t.indexOf(`#`)>-1){var r=t.substring(t.indexOf(`#`)+1),i=t.substring(0,t.indexOf(`#`));n=e.i18n.commaOnThe(r,i).trim()+e.i18n.spaceX0OfTheMonth()}else n=t.indexOf(`L`)>-1?e.i18n.commaOnTheLastX0OfTheMonth(t.replace(`L`,``)):e.expressionParts[3]==`*`||e.options.logicalAndDayFields?e.i18n.commaOnlyOnX0(t):e.i18n.commaAndOnX0();return n}),n},e.prototype.getMonthDescription=function(){var e=this,t=this.i18n.monthsOfTheYear();return this.getSegmentDescription(this.expressionParts[4],``,function(n,r){return r&&e.i18n.monthsOfTheYearInCase?e.i18n.monthsOfTheYearInCase(r)[parseInt(n)-1]:t[parseInt(n)-1]},function(t){return parseInt(t)==1?``:r.StringUtilities.format(e.i18n.commaEveryX0Months(t),t)},function(t){return e.i18n.commaMonthX0ThroughMonthX1()||e.i18n.commaX0ThroughX1()},function(t){return e.i18n.commaOnlyInMonthX0?e.i18n.commaOnlyInMonthX0():e.i18n.commaOnlyInX0()})},e.prototype.getDayOfMonthDescription=function(){var e=this,t=null,n=this.expressionParts[3];switch(n){case`L`:t=this.i18n.commaOnTheLastDayOfTheMonth();break;case`WL`:case`LW`:t=this.i18n.commaOnTheLastWeekdayOfTheMonth();break;default:var i=n.match(/(\d{1,2}W)|(W\d{1,2})/);if(i){var a=parseInt(i[0].replace(`W`,``)),o=a==1?this.i18n.firstWeekday():r.StringUtilities.format(this.i18n.weekdayNearestDayX0(),a.toString());t=r.StringUtilities.format(this.i18n.commaOnTheX0OfTheMonth(),o);break}var s=n.match(/L-(\d{1,2})/);if(s){var c=s[1];t=r.StringUtilities.format(this.i18n.commaDaysBeforeTheLastDayOfTheMonth(c),c);break}if(n==`*`&&this.expressionParts[5]!=`*`)return``;t=this.getSegmentDescription(n,this.i18n.commaEveryDay(),function(t){return t==`L`?e.i18n.lastDay():e.i18n.dayX0?r.StringUtilities.format(e.i18n.dayX0(),t):t},function(t){return t==`1`?e.i18n.commaEveryDay():e.i18n.commaEveryX0Days(t)},function(t){return e.i18n.commaBetweenDayX0AndX1OfTheMonth(t)},function(t){return e.i18n.commaOnDayX0OfTheMonth(t)})}return t},e.prototype.getYearDescription=function(){var e=this;return this.getSegmentDescription(this.expressionParts[6],``,function(e){return/^\d+$/.test(e)?new Date(parseInt(e),1).getFullYear().toString():e},function(t){return r.StringUtilities.format(e.i18n.commaEveryX0Years(t),t)},function(t){return e.i18n.commaYearX0ThroughYearX1()||e.i18n.commaX0ThroughX1()},function(t){return e.i18n.commaOnlyInYearX0?e.i18n.commaOnlyInYearX0():e.i18n.commaOnlyInX0()})},e.prototype.getSegmentDescription=function(e,t,n,i,a,o,s){var c=null,l=e.indexOf(`/`)>-1,u=e.indexOf(`-`)>-1,d=e.indexOf(`,`)>-1;if(!e)c=``;else if(e===`*`)c=t;else if(!l&&!u&&!d)c=r.StringUtilities.format(o(e),n(e));else if(d){for(var f=e.split(`,`),p=``,m=this.i18n.spaceAnd(),h=0;h<f.length;h++)if(h>0&&f.length>2&&(p+=`,`,h<f.length-1&&(p+=` `)),h>0&&f.length>1&&(h==f.length-1||f.length==2)&&(p+=m==`,`&&f.length>2?` `:`${m} `),f[h].indexOf(`/`)>-1||f[h].indexOf(`-`)>-1){var g=f[h].indexOf(`-`)>-1&&f[h].indexOf(`/`)==-1,_=this.getSegmentDescription(f[h],t,n,i,g?this.i18n.commaX0ThroughX1:a,o);g&&(_=_.replace(`, `,``)),p+=_}else if(!l)p+=n(f[h]);else{var v=this.getSegmentDescription(f[h],t,n,i,a,o);v&&v.startsWith(`, `)&&(v=v.substring(2)),p+=v}c=l?p:r.StringUtilities.format(o(e),p)}else if(l){var f=e.split(`/`);if(c=r.StringUtilities.format(i(f[1]),f[1]),f[0].indexOf(`-`)>-1){var y=this.generateRangeSegmentDescription(f[0],a,n);y.indexOf(`, `)!=0&&(c+=`, `),c+=y}else if(f[0].indexOf(`*`)==-1){var b=r.StringUtilities.format(o(f[0]),n(f[0]));b=b.replace(`, `,``),c+=r.StringUtilities.format(this.i18n.commaStartingX0(),b)}c+=this.getWrappingIncrementDescription(e,s,t,n,i,a,o)}else u&&(c=this.generateRangeSegmentDescription(e,a,n));return c},e.prototype.getWrappingIncrementDescription=function(e,t,n,r,i,a,o){if(!this.options.verbose||!t)return``;var s=e.split(`/`),c=s[0],l=s[1],u=parseInt(l),d=t.max-t.min+1,f=c===`*`,p=Number.isInteger(u)&&u>1,m=p&&d%u===0;if(!f||!p||m)return``;for(var h=[],g=t.min;g<=t.max;g+=u)h.push(g);if(h.length<2)return``;var _=this.getSegmentDescription(h.join(`,`),n,r,i,a,o);return _?`, ${_}`:``},e.prototype.generateRangeSegmentDescription=function(e,t,n){var i=``,a=e.split(`-`),o=n(a[0],1),s=n(a[1],2),c=t(e);return i+=r.StringUtilities.format(c,o,s),i},e.prototype.formatTime=function(e,t,n){var r=0,i=0,a=parseInt(e)+r,o=parseInt(t)+i;o>=60?(o-=60,a+=1):o<0&&(o+=60,--a),a>=24?a-=24:a<0&&(a=24+a);var s=``,c=!1;this.options.use24HourTimeFormat||(c=!!(this.i18n.setPeriodBeforeTime&&this.i18n.setPeriodBeforeTime()),s=c?`${this.getPeriod(a)} `:` ${this.getPeriod(a)}`,a>12&&(a-=12),a===0&&(a=12));var l=``;n&&(l=`:${(`00`+n).substring(n.length)}`);var u=a.toString(),d=(`00`+u).substring(u.length),f=o.toString(),p=(`00`+f).substring(f.length),m=this.options.trimHoursLeadingZero?u:d;return`${c?s:``}${m}:${p}${l}${c?``:s}`},e.prototype.transformVerbosity=function(e,t){if(!t&&(e=e.replace(RegExp(`, ${this.i18n.everyMinute()}`,`g`),``),e=e.replace(RegExp(`, ${this.i18n.everyHour()}`,`g`),``),e=e.replace(new RegExp(this.i18n.commaEveryDay(),`g`),``),e=e.replace(/\, ?$/,``),this.i18n.conciseVerbosityReplacements))for(var n=0,r=Object.entries(this.i18n.conciseVerbosityReplacements());n<r.length;n++){var i=r[n],a=i[0],o=i[1];e=e.replace(new RegExp(a,`g`),o)}return e},e.prototype.getPeriod=function(e){return e>=12?this.i18n.pm&&this.i18n.pm()||`PM`:this.i18n.am&&this.i18n.am()||`AM`},e.locales={},e}()},3747(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.enLocaleLoader=void 0;var r=n(9486);t.enLocaleLoader=function(){function e(){}return e.prototype.load=function(e){e.en=new r.en},e}()},9486(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.en=void 0,t.en=function(){function e(){}return e.prototype.atX0SecondsPastTheMinuteGt20=function(){return null},e.prototype.atX0MinutesPastTheHourGt20=function(){return null},e.prototype.commaMonthX0ThroughMonthX1=function(){return null},e.prototype.commaYearX0ThroughYearX1=function(){return null},e.prototype.use24HourTimeFormatByDefault=function(){return!1},e.prototype.anErrorOccuredWhenGeneratingTheExpressionD=function(){return`An error occurred when generating the expression description. Check the cron expression syntax.`},e.prototype.everyMinute=function(){return`every minute`},e.prototype.everyHour=function(){return`every hour`},e.prototype.atSpace=function(){return`At `},e.prototype.everyMinuteBetweenX0AndX1=function(){return`Every minute between %s and %s`},e.prototype.at=function(){return`At`},e.prototype.spaceAnd=function(){return` and`},e.prototype.everySecond=function(){return`every second`},e.prototype.everyX0Seconds=function(){return`every %s seconds`},e.prototype.secondsX0ThroughX1PastTheMinute=function(){return`seconds %s through %s past the minute`},e.prototype.atX0SecondsPastTheMinute=function(){return`at %s seconds past the minute`},e.prototype.everyX0Minutes=function(){return`every %s minutes`},e.prototype.minutesX0ThroughX1PastTheHour=function(){return`minutes %s through %s past the hour`},e.prototype.atX0MinutesPastTheHour=function(){return`at %s minutes past the hour`},e.prototype.everyX0Hours=function(){return`every %s hours`},e.prototype.betweenX0AndX1=function(){return`between %s and %s`},e.prototype.atX0=function(){return`at %s`},e.prototype.commaEveryDay=function(){return`, every day`},e.prototype.commaEveryX0DaysOfTheWeek=function(){return`, every %s days of the week`},e.prototype.commaX0ThroughX1=function(){return`, %s through %s`},e.prototype.commaAndX0ThroughX1=function(){return`, %s through %s`},e.prototype.first=function(){return`first`},e.prototype.second=function(){return`second`},e.prototype.third=function(){return`third`},e.prototype.fourth=function(){return`fourth`},e.prototype.fifth=function(){return`fifth`},e.prototype.commaOnThe=function(){return`, on the `},e.prototype.spaceX0OfTheMonth=function(){return` %s of the month`},e.prototype.lastDay=function(){return`the last day`},e.prototype.commaOnTheLastX0OfTheMonth=function(){return`, on the last %s of the month`},e.prototype.commaOnlyOnX0=function(){return`, only on %s`},e.prototype.commaAndOnX0=function(){return`, and on %s`},e.prototype.commaEveryX0Months=function(){return`, every %s months`},e.prototype.commaOnlyInX0=function(){return`, only in %s`},e.prototype.commaOnTheLastDayOfTheMonth=function(){return`, on the last day of the month`},e.prototype.commaOnTheLastWeekdayOfTheMonth=function(){return`, on the last weekday of the month`},e.prototype.commaDaysBeforeTheLastDayOfTheMonth=function(){return`, %s days before the last day of the month`},e.prototype.firstWeekday=function(){return`first weekday`},e.prototype.weekdayNearestDayX0=function(){return`weekday nearest day %s`},e.prototype.commaOnTheX0OfTheMonth=function(){return`, on the %s of the month`},e.prototype.commaEveryX0Days=function(){return`, every %s days in a month`},e.prototype.commaBetweenDayX0AndX1OfTheMonth=function(){return`, between day %s and %s of the month`},e.prototype.commaOnDayX0OfTheMonth=function(){return`, on day %s of the month`},e.prototype.commaEveryHour=function(){return`, every hour`},e.prototype.commaEveryX0Years=function(){return`, every %s years`},e.prototype.commaStartingX0=function(){return`, starting %s`},e.prototype.daysOfTheWeek=function(){return[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`]},e.prototype.monthsOfTheYear=function(){return[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`]},e.prototype.atReboot=function(){return`Run once, at startup`},e.prototype.onTheHour=function(){return`on the hour`},e}()},9515(e,t){Object.defineProperty(t,"__esModule",{value:!0});function n(e,t){if(!e)throw Error(t)}t.default=function(){function e(){}return e.secondRange=function(e){for(var t=e.split(`,`),r=0;r<t.length;r++)if(!isNaN(parseInt(t[r],10))){var i=parseInt(t[r],10);n(i>=0&&i<=59,`seconds part must be >= 0 and <= 59`)}},e.minuteRange=function(e){for(var t=e.split(`,`),r=0;r<t.length;r++)if(!isNaN(parseInt(t[r],10))){var i=parseInt(t[r],10);n(i>=0&&i<=59,`minutes part must be >= 0 and <= 59`)}},e.hourRange=function(e){for(var t=e.split(`,`),r=0;r<t.length;r++)if(!isNaN(parseInt(t[r],10))){var i=parseInt(t[r],10);n(i>=0&&i<=23,`hours part must be >= 0 and <= 23`)}},e.dayOfMonthRange=function(e){for(var t=e.split(`,`),r=0;r<t.length;r++)if(!isNaN(parseInt(t[r],10))){var i=parseInt(t[r],10);n(i>=1&&i<=31,`DOM part must be >= 1 and <= 31`)}},e.monthRange=function(e,t){for(var r=e.split(`,`),i=0;i<r.length;i++)if(!isNaN(parseInt(r[i],10))){var a=parseInt(r[i],10);n(a>=1&&a<=12,t?`month part must be >= 0 and <= 11`:`month part must be >= 1 and <= 12`)}},e.dayOfWeekRange=function(e,t){for(var r=e.split(`,`),i=0;i<r.length;i++)if(!isNaN(parseInt(r[i],10))){var a=parseInt(r[i],10);n(a>=0&&a<=6,t?`DOW part must be >= 0 and <= 6`:`DOW part must be >= 1 and <= 7`)}},e}()},1823(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.StringUtilities=void 0,t.StringUtilities=function(){function e(){}return e.format=function(e){var t=[...arguments].slice(1);return e.replace(/%s/g,function(e){return t.shift()})},e.containsAny=function(e,t){return t.some(function(t){return e.indexOf(t)>-1})},e}()}},t={};function n(r){var i=t[r];if(i!==void 0)return i.exports;var a=t[r]={exports:{}};return e[r](a,a.exports,n),a.exports}var r={};return(()=>{var e=r;Object.defineProperty(e,"__esModule",{value:!0}),e.toString=void 0;var t=n(8333),i=n(3747);t.ExpressionDescriptor.initialize(new i.enLocaleLoader),e.default=t.ExpressionDescriptor,e.toString=t.ExpressionDescriptor.toString})(),r})())})),ye=k(),be=e(V(),1),H=d();function U(e){if(!e.parentElement||!e.clientWidth)return;let t=getComputedStyle(e),n=e.cloneNode(!1);n.removeAttribute(`id`),n.removeAttribute(`name`),n.setAttribute(`aria-hidden`,`true`),n.tabIndex=-1,n.value=e.value,Object.assign(n.style,{position:`fixed`,visibility:`hidden`,pointerEvents:`none`,width:t.width,height:`0`,minHeight:`0`,maxHeight:`none`}),e.parentElement.append(n);let r=n.scrollHeight+(t.boxSizing===`border-box`?parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth):-parseFloat(t.paddingTop)-parseFloat(t.paddingBottom));n.remove(),e.style.height=`${r}px`}function xe(e,t){(0,H.useLayoutEffect)(()=>{e.current&&U(e.current)},[e,t]),(0,H.useLayoutEffect)(()=>{let t=e.current;if(!t)return;let n=t.clientWidth,r=new ResizeObserver(()=>{t.clientWidth!==n&&(n=t.clientWidth,U(t))});return r.observe(t),()=>r.disconnect()},[e])}var W=`bivy-automation-v1
|
|
1
|
+
import{r as e,t}from"./rolldown-runtime-hePW80VL.js";import{V as n,j as r}from"./index-CplEYkZZ.js";import{$ as i,At as a,Dt as o,G as s,M as c,Mt as l,N as u,Nt as d,Q as f,S as p,V as m,X as h,Z as g,_t as _,at as v,bt as y,ct as b,et as ee,gt as te,ht as x,i as S,it as ne,jt as re,kt as ie,lt as C,n as w,nt as T,ot as ae,st as oe,t as se,tt as ce,wt as le,x as E}from"./useStore-CNkjpbem.js";import{A as D,E as O,M as k,a as ue,f as A,h as de,i as j,j as fe,n as M,s as pe,t as N}from"./Sheet-CT1aLpQD.js";import{t as P}from"./jsx-runtime-NZYk81nU.js";import{A as me,C as he,D as ge,E as F,M as I,O as L,S as _e,T as R,j as ve,k as z,w as B}from"./mount-BP8alXTE.js";var V=t(((e,t)=>{(function(n,r){typeof e==`object`&&typeof t==`object`?t.exports=r():typeof define==`function`&&define.amd?define(`cronstrue`,[],r):typeof e==`object`?e.cronstrue=r():n.cronstrue=r()})(globalThis,()=>(()=>{var e={6949(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.CronParser=void 0;var r=n(9515);t.CronParser=function(){function e(e,t,n){t===void 0&&(t=!0),n===void 0&&(n=!1),this.expression=e,this.dayOfWeekStartIndexZero=t,this.monthStartIndexZero=n}return e.prototype.parse=function(){var e,t=this.expression??``;if(t===`@reboot`)return e=[`@reboot`,``,``,``,``,``,``],e;if(t.startsWith(`@`)){var n=this.parseSpecial(this.expression);e=this.extractParts(n)}else e=this.extractParts(this.expression);return this.normalize(e),this.validate(e),e},e.prototype.parseSpecial=function(e){var t={"@yearly":`0 0 1 1 *`,"@annually":`0 0 1 1 *`,"@monthly":`0 0 1 * *`,"@weekly":`0 0 * * 0`,"@daily":`0 0 * * *`,"@midnight":`0 0 * * *`,"@hourly":`0 * * * *`,"@reboot":`@reboot`}[e];if(!t)throw Error(`Unknown special expression.`);return t},e.prototype.extractParts=function(e){if(!this.expression)throw Error(`cron expression is empty`);for(var t=e.trim().split(/[ ]+/),n=0;n<t.length;n++)if(t[n].includes(`,`)){var r=t[n].split(`,`).map(function(e){return e.trim()}).filter(function(e){return e!==``}).map(function(e){return isNaN(Number(e))?e:Number(e)}).filter(function(e){return e!==null&&e!==``});r.length===0&&r.push(`*`),r.sort(function(e,t){return e!==null&&t!==null?e-t:0}),t[n]=r.map(function(e){return e===null?``:e.toString()}).join(`,`)}if(t.length<5)throw Error(`Expression has only ${t.length} part${t.length==1?``:`s`}. At least 5 parts are required.`);if(t.length==5)t.unshift(``),t.push(``);else if(t.length==6)/\d{4}$/.test(t[5])||t[4]==`?`||t[2]==`?`?t.unshift(``):t.push(``);else if(t.length>7)throw Error(`Expression has ${t.length} parts; too many!`);return t},e.prototype.normalize=function(e){var t=this;if(e[3]=e[3].replace(`?`,`*`),e[5]=e[5].replace(`?`,`*`),e[2]=e[2].replace(`?`,`*`),e[0].indexOf(`0/`)==0&&(e[0]=e[0].replace(`0/`,`*/`)),e[1].indexOf(`0/`)==0&&(e[1]=e[1].replace(`0/`,`*/`)),e[2].indexOf(`0/`)==0&&(e[2]=e[2].replace(`0/`,`*/`)),e[3].indexOf(`1/`)==0&&(e[3]=e[3].replace(`1/`,`*/`)),e[4].indexOf(`1/`)==0&&(e[4]=e[4].replace(`1/`,`*/`)),e[6].indexOf(`1/`)==0&&(e[6]=e[6].replace(`1/`,`*/`)),e[5]=e[5].replace(/(^\d)|([^#/\s]\d)/g,function(e){var n=e.replace(/\D/,``),r=n;return t.dayOfWeekStartIndexZero?n==`7`&&(r=`0`):r=(parseInt(n)-1).toString(),e.replace(n,r)}),e[5]==`L`&&(e[5]=`6`),e[3]==`?`&&(e[3]=`*`),e[3].indexOf(`W`)>-1&&(e[3].indexOf(`,`)>-1||e[3].indexOf(`-`)>-1))throw Error(`The 'W' character can be specified only when the day-of-month is a single day, not a range or list of days.`);var n={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};for(var r in n)e[5]=e[5].replace(new RegExp(r,`gi`),n[r].toString());e[4]=e[4].replace(/(^\d{1,2})|([^#/\s]\d{1,2})/g,function(e){var n=e.replace(/\D/,``),r=n;return t.monthStartIndexZero&&(r=(parseInt(n)+1).toString()),e.replace(n,r)});var i={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12};for(var a in i)e[4]=e[4].replace(new RegExp(a,`gi`),i[a].toString());e[0]==`0`&&(e[0]=``),!/\*|\-|\,|\//.test(e[2])&&(/\*|\//.test(e[1])||/\*|\//.test(e[0]))&&(e[2]+=`-${e[2]}`);for(var o=0;o<e.length;o++)if(e[o].indexOf(`,`)!=-1&&(e[o]=e[o].split(`,`).filter(function(e){return e!==``}).join(`,`)||`*`),e[o]==`*/1`&&(e[o]=`*`),e[o].indexOf(`/`)>-1&&!/^\*|\-|\,/.test(e[o])){var s=null;switch(o){case 4:s=`12`;break;case 5:s=`6`;break;case 6:s=`9999`;break;default:s=null}if(s!==null){var c=e[o].split(`/`);e[o]=`${c[0]}-${s}/${c[1]}`}}},e.prototype.validate=function(e){var t=`0-9,\\-*/`;this.validateOnlyExpectedCharactersFound(e[0],t),this.validateOnlyExpectedCharactersFound(e[1],t),this.validateOnlyExpectedCharactersFound(e[2],t),this.validateOnlyExpectedCharactersFound(e[3],`0-9,\\-*/LW`),this.validateOnlyExpectedCharactersFound(e[4],t),this.validateOnlyExpectedCharactersFound(e[5],`0-9,\\-*/L#`),this.validateOnlyExpectedCharactersFound(e[6],t),this.validateAnyRanges(e)},e.prototype.validateAnyRanges=function(e){r.default.secondRange(e[0]),r.default.minuteRange(e[1]),r.default.hourRange(e[2]),r.default.dayOfMonthRange(e[3]),r.default.monthRange(e[4],this.monthStartIndexZero),r.default.dayOfWeekRange(e[5],this.dayOfWeekStartIndexZero)},e.prototype.validateOnlyExpectedCharactersFound=function(e,t){var n=e.match(RegExp(`[^${t}]+`,`gi`));if(n&&n.length)throw Error(`Expression contains invalid values: '${n.toString()}'`)},e}()},8333(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.ExpressionDescriptor=void 0;var r=n(1823),i=n(6949);t.ExpressionDescriptor=function(){function e(t,n){if(this.expression=t,this.options=n,this.expressionParts=[,,,,,],!this.options.locale&&e.defaultLocale&&(this.options.locale=e.defaultLocale),!e.locales[this.options.locale]){var r=Object.keys(e.locales)[0];console.warn(`Locale '${this.options.locale}' could not be found; falling back to '${r}'.`),this.options.locale=r}this.i18n=e.locales[this.options.locale],n.use24HourTimeFormat===void 0&&(n.use24HourTimeFormat=this.i18n.use24HourTimeFormatByDefault())}return e.toString=function(t,n){var r=n===void 0?{}:n,i=r.throwExceptionOnParseError,a=i===void 0||i,o=r.verbose,s=o!==void 0&&o,c=r.dayOfWeekStartIndexZero,l=c===void 0||c,u=r.monthStartIndexZero,d=u!==void 0&&u,f=r.use24HourTimeFormat,p=r.trimHoursLeadingZero,m=p!==void 0&&p,h=r.locale,g=h===void 0?null:h,_=r.logicalAndDayFields,v={throwExceptionOnParseError:a,verbose:s,dayOfWeekStartIndexZero:l,monthStartIndexZero:d,use24HourTimeFormat:f,trimHoursLeadingZero:m,locale:g,logicalAndDayFields:_!==void 0&&_};return v.tzOffset&&console.warn(`'tzOffset' option has been deprecated and is no longer supported.`),new e(t,v).getFullDescription()},e.initialize=function(t,n){n===void 0&&(n=`en`),e.specialCharacters=[`/`,`-`,`,`,`*`],e.defaultLocale=n,t.load(e.locales)},e.prototype.getFullDescription=function(){var e,t=``;try{var n=new i.CronParser(this.expression,this.options.dayOfWeekStartIndexZero,this.options.monthStartIndexZero);if(this.expressionParts=n.parse(),this.expressionParts[0]===`@reboot`)return(e=this.i18n).atReboot?.call(e)||`Run once, at startup`;var r=this.getTimeOfDayDescription(),a=this.getDayOfMonthDescription(),o=this.getMonthDescription(),s=this.getDayOfWeekDescription(),c=this.getYearDescription();t+=r+a+s+o+c,t=this.transformVerbosity(t,!!this.options.verbose),t=t.charAt(0).toLocaleUpperCase()+t.substr(1)}catch(e){if(!this.options.throwExceptionOnParseError)t=this.i18n.anErrorOccuredWhenGeneratingTheExpressionD();else throw`${e}`}return t},e.prototype.getTimeOfDayDescription=function(){var t=this.expressionParts[0],n=this.expressionParts[1],i=this.expressionParts[2],a=``;if(!r.StringUtilities.containsAny(n,e.specialCharacters)&&!r.StringUtilities.containsAny(i,e.specialCharacters)&&!r.StringUtilities.containsAny(t,e.specialCharacters))a+=this.i18n.atSpace()+this.formatTime(i,n,t);else if(!t&&n.indexOf(`-`)>-1&&!(n.indexOf(`,`)>-1)&&!(n.indexOf(`/`)>-1)&&!r.StringUtilities.containsAny(i,e.specialCharacters)){var o=n.split(`-`);a+=r.StringUtilities.format(this.i18n.everyMinuteBetweenX0AndX1(),this.formatTime(i,o[0],``),this.formatTime(i,o[1],``))}else if(!t&&i.indexOf(`,`)>-1&&i.indexOf(`-`)==-1&&i.indexOf(`/`)==-1&&!r.StringUtilities.containsAny(n,e.specialCharacters)){var s=i.split(`,`);a+=this.i18n.at();for(var c=0;c<s.length;c++)a&&(a+=` `),a+=this.formatTime(s[c],n,``),c<s.length-2&&(a+=`,`),c==s.length-2&&(a+=this.i18n.spaceAnd())}else{var l=this.getSecondsDescription(),u=this.getMinutesDescription(),d=this.getHoursDescription();if(a+=l,a&&u&&(a+=`, `),a+=u,u===d)return a;a&&d&&(a+=`, `),a+=d}return a},e.prototype.getSecondsDescription=function(){var e=this;return this.getSegmentDescription(this.expressionParts[0],this.i18n.everySecond(),function(e){return e},function(t){return r.StringUtilities.format(e.i18n.everyX0Seconds(t),t)},function(t){return e.i18n.secondsX0ThroughX1PastTheMinute()},function(t){return t==`0`?``:parseInt(t)<20?e.i18n.atX0SecondsPastTheMinute(t):e.i18n.atX0SecondsPastTheMinuteGt20()||e.i18n.atX0SecondsPastTheMinute(t)},{min:0,max:59})},e.prototype.getMinutesDescription=function(){var e=this,t=this.expressionParts[0],n=this.expressionParts[2];return this.getSegmentDescription(this.expressionParts[1],this.i18n.everyMinute(),function(e){return e},function(t){return r.StringUtilities.format(e.i18n.everyX0Minutes(t),t)},function(t){return e.i18n.minutesX0ThroughX1PastTheHour()},function(r){var i;try{return r==`0`&&n.indexOf(`/`)==-1&&t==``?e.i18n.everyHour():r==`0`?(i=e.i18n).onTheHour?.call(i)||e.i18n.atX0MinutesPastTheHour(r):parseInt(r)<20?e.i18n.atX0MinutesPastTheHour(r):e.i18n.atX0MinutesPastTheHourGt20()||e.i18n.atX0MinutesPastTheHour(r)}catch{return e.i18n.atX0MinutesPastTheHour(r)}},{min:0,max:59})},e.prototype.getHoursDescription=function(){var e=this,t=this.expressionParts[2],n=0,i=[];t.split(`/`)[0].split(`,`).forEach(function(e){var t=e.split(`-`);t.length===2&&i.push({value:t[1],index:n+1}),n+=t.length});var a=0;return this.getSegmentDescription(t,this.i18n.everyHour(),function(t){var n=i.find(function(e){return e.value===t&&e.index===a})&&e.expressionParts[1]!==`0`;return a++,n?e.formatTime(t,`59`,``):e.formatTime(t,`0`,``)},function(t){return r.StringUtilities.format(e.i18n.everyX0Hours(t),t)},function(t){return e.i18n.betweenX0AndX1()},function(t){return e.i18n.atX0()},{min:0,max:23})},e.prototype.getDayOfWeekDescription=function(){var e=this,t=this.i18n.daysOfTheWeek(),n=null;return n=this.expressionParts[5]==`*`?``:this.getSegmentDescription(this.expressionParts[5],this.i18n.commaEveryDay(),function(n,r){var i=n;n.indexOf(`#`)>-1?i=n.substring(0,n.indexOf(`#`)):n.indexOf(`L`)>-1&&(i=i.replace(`L`,``));var a=parseInt(i),o=e.i18n.daysOfTheWeekInCase?e.i18n.daysOfTheWeekInCase(r)[a]:t[a];if(n.indexOf(`#`)>-1){var s=null,c=n.substring(n.indexOf(`#`)+1),l=n.substring(0,n.indexOf(`#`));switch(c){case`1`:s=e.i18n.first(l);break;case`2`:s=e.i18n.second(l);break;case`3`:s=e.i18n.third(l);break;case`4`:s=e.i18n.fourth(l);break;case`5`:s=e.i18n.fifth(l)}o=s+` `+o}return o},function(t){return parseInt(t)==1?``:r.StringUtilities.format(e.i18n.commaEveryX0DaysOfTheWeek(t),t)},function(t){var n=t.substring(0,t.indexOf(`-`));return e.expressionParts[3]==`*`?e.i18n.commaX0ThroughX1(n):e.i18n.commaAndX0ThroughX1(n)},function(t){var n=null;if(t.indexOf(`#`)>-1){var r=t.substring(t.indexOf(`#`)+1),i=t.substring(0,t.indexOf(`#`));n=e.i18n.commaOnThe(r,i).trim()+e.i18n.spaceX0OfTheMonth()}else n=t.indexOf(`L`)>-1?e.i18n.commaOnTheLastX0OfTheMonth(t.replace(`L`,``)):e.expressionParts[3]==`*`||e.options.logicalAndDayFields?e.i18n.commaOnlyOnX0(t):e.i18n.commaAndOnX0();return n}),n},e.prototype.getMonthDescription=function(){var e=this,t=this.i18n.monthsOfTheYear();return this.getSegmentDescription(this.expressionParts[4],``,function(n,r){return r&&e.i18n.monthsOfTheYearInCase?e.i18n.monthsOfTheYearInCase(r)[parseInt(n)-1]:t[parseInt(n)-1]},function(t){return parseInt(t)==1?``:r.StringUtilities.format(e.i18n.commaEveryX0Months(t),t)},function(t){return e.i18n.commaMonthX0ThroughMonthX1()||e.i18n.commaX0ThroughX1()},function(t){return e.i18n.commaOnlyInMonthX0?e.i18n.commaOnlyInMonthX0():e.i18n.commaOnlyInX0()})},e.prototype.getDayOfMonthDescription=function(){var e=this,t=null,n=this.expressionParts[3];switch(n){case`L`:t=this.i18n.commaOnTheLastDayOfTheMonth();break;case`WL`:case`LW`:t=this.i18n.commaOnTheLastWeekdayOfTheMonth();break;default:var i=n.match(/(\d{1,2}W)|(W\d{1,2})/);if(i){var a=parseInt(i[0].replace(`W`,``)),o=a==1?this.i18n.firstWeekday():r.StringUtilities.format(this.i18n.weekdayNearestDayX0(),a.toString());t=r.StringUtilities.format(this.i18n.commaOnTheX0OfTheMonth(),o);break}var s=n.match(/L-(\d{1,2})/);if(s){var c=s[1];t=r.StringUtilities.format(this.i18n.commaDaysBeforeTheLastDayOfTheMonth(c),c);break}if(n==`*`&&this.expressionParts[5]!=`*`)return``;t=this.getSegmentDescription(n,this.i18n.commaEveryDay(),function(t){return t==`L`?e.i18n.lastDay():e.i18n.dayX0?r.StringUtilities.format(e.i18n.dayX0(),t):t},function(t){return t==`1`?e.i18n.commaEveryDay():e.i18n.commaEveryX0Days(t)},function(t){return e.i18n.commaBetweenDayX0AndX1OfTheMonth(t)},function(t){return e.i18n.commaOnDayX0OfTheMonth(t)})}return t},e.prototype.getYearDescription=function(){var e=this;return this.getSegmentDescription(this.expressionParts[6],``,function(e){return/^\d+$/.test(e)?new Date(parseInt(e),1).getFullYear().toString():e},function(t){return r.StringUtilities.format(e.i18n.commaEveryX0Years(t),t)},function(t){return e.i18n.commaYearX0ThroughYearX1()||e.i18n.commaX0ThroughX1()},function(t){return e.i18n.commaOnlyInYearX0?e.i18n.commaOnlyInYearX0():e.i18n.commaOnlyInX0()})},e.prototype.getSegmentDescription=function(e,t,n,i,a,o,s){var c=null,l=e.indexOf(`/`)>-1,u=e.indexOf(`-`)>-1,d=e.indexOf(`,`)>-1;if(!e)c=``;else if(e===`*`)c=t;else if(!l&&!u&&!d)c=r.StringUtilities.format(o(e),n(e));else if(d){for(var f=e.split(`,`),p=``,m=this.i18n.spaceAnd(),h=0;h<f.length;h++)if(h>0&&f.length>2&&(p+=`,`,h<f.length-1&&(p+=` `)),h>0&&f.length>1&&(h==f.length-1||f.length==2)&&(p+=m==`,`&&f.length>2?` `:`${m} `),f[h].indexOf(`/`)>-1||f[h].indexOf(`-`)>-1){var g=f[h].indexOf(`-`)>-1&&f[h].indexOf(`/`)==-1,_=this.getSegmentDescription(f[h],t,n,i,g?this.i18n.commaX0ThroughX1:a,o);g&&(_=_.replace(`, `,``)),p+=_}else if(!l)p+=n(f[h]);else{var v=this.getSegmentDescription(f[h],t,n,i,a,o);v&&v.startsWith(`, `)&&(v=v.substring(2)),p+=v}c=l?p:r.StringUtilities.format(o(e),p)}else if(l){var f=e.split(`/`);if(c=r.StringUtilities.format(i(f[1]),f[1]),f[0].indexOf(`-`)>-1){var y=this.generateRangeSegmentDescription(f[0],a,n);y.indexOf(`, `)!=0&&(c+=`, `),c+=y}else if(f[0].indexOf(`*`)==-1){var b=r.StringUtilities.format(o(f[0]),n(f[0]));b=b.replace(`, `,``),c+=r.StringUtilities.format(this.i18n.commaStartingX0(),b)}c+=this.getWrappingIncrementDescription(e,s,t,n,i,a,o)}else u&&(c=this.generateRangeSegmentDescription(e,a,n));return c},e.prototype.getWrappingIncrementDescription=function(e,t,n,r,i,a,o){if(!this.options.verbose||!t)return``;var s=e.split(`/`),c=s[0],l=s[1],u=parseInt(l),d=t.max-t.min+1,f=c===`*`,p=Number.isInteger(u)&&u>1,m=p&&d%u===0;if(!f||!p||m)return``;for(var h=[],g=t.min;g<=t.max;g+=u)h.push(g);if(h.length<2)return``;var _=this.getSegmentDescription(h.join(`,`),n,r,i,a,o);return _?`, ${_}`:``},e.prototype.generateRangeSegmentDescription=function(e,t,n){var i=``,a=e.split(`-`),o=n(a[0],1),s=n(a[1],2),c=t(e);return i+=r.StringUtilities.format(c,o,s),i},e.prototype.formatTime=function(e,t,n){var r=0,i=0,a=parseInt(e)+r,o=parseInt(t)+i;o>=60?(o-=60,a+=1):o<0&&(o+=60,--a),a>=24?a-=24:a<0&&(a=24+a);var s=``,c=!1;this.options.use24HourTimeFormat||(c=!!(this.i18n.setPeriodBeforeTime&&this.i18n.setPeriodBeforeTime()),s=c?`${this.getPeriod(a)} `:` ${this.getPeriod(a)}`,a>12&&(a-=12),a===0&&(a=12));var l=``;n&&(l=`:${(`00`+n).substring(n.length)}`);var u=a.toString(),d=(`00`+u).substring(u.length),f=o.toString(),p=(`00`+f).substring(f.length),m=this.options.trimHoursLeadingZero?u:d;return`${c?s:``}${m}:${p}${l}${c?``:s}`},e.prototype.transformVerbosity=function(e,t){if(!t&&(e=e.replace(RegExp(`, ${this.i18n.everyMinute()}`,`g`),``),e=e.replace(RegExp(`, ${this.i18n.everyHour()}`,`g`),``),e=e.replace(new RegExp(this.i18n.commaEveryDay(),`g`),``),e=e.replace(/\, ?$/,``),this.i18n.conciseVerbosityReplacements))for(var n=0,r=Object.entries(this.i18n.conciseVerbosityReplacements());n<r.length;n++){var i=r[n],a=i[0],o=i[1];e=e.replace(new RegExp(a,`g`),o)}return e},e.prototype.getPeriod=function(e){return e>=12?this.i18n.pm&&this.i18n.pm()||`PM`:this.i18n.am&&this.i18n.am()||`AM`},e.locales={},e}()},3747(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.enLocaleLoader=void 0;var r=n(9486);t.enLocaleLoader=function(){function e(){}return e.prototype.load=function(e){e.en=new r.en},e}()},9486(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.en=void 0,t.en=function(){function e(){}return e.prototype.atX0SecondsPastTheMinuteGt20=function(){return null},e.prototype.atX0MinutesPastTheHourGt20=function(){return null},e.prototype.commaMonthX0ThroughMonthX1=function(){return null},e.prototype.commaYearX0ThroughYearX1=function(){return null},e.prototype.use24HourTimeFormatByDefault=function(){return!1},e.prototype.anErrorOccuredWhenGeneratingTheExpressionD=function(){return`An error occurred when generating the expression description. Check the cron expression syntax.`},e.prototype.everyMinute=function(){return`every minute`},e.prototype.everyHour=function(){return`every hour`},e.prototype.atSpace=function(){return`At `},e.prototype.everyMinuteBetweenX0AndX1=function(){return`Every minute between %s and %s`},e.prototype.at=function(){return`At`},e.prototype.spaceAnd=function(){return` and`},e.prototype.everySecond=function(){return`every second`},e.prototype.everyX0Seconds=function(){return`every %s seconds`},e.prototype.secondsX0ThroughX1PastTheMinute=function(){return`seconds %s through %s past the minute`},e.prototype.atX0SecondsPastTheMinute=function(){return`at %s seconds past the minute`},e.prototype.everyX0Minutes=function(){return`every %s minutes`},e.prototype.minutesX0ThroughX1PastTheHour=function(){return`minutes %s through %s past the hour`},e.prototype.atX0MinutesPastTheHour=function(){return`at %s minutes past the hour`},e.prototype.everyX0Hours=function(){return`every %s hours`},e.prototype.betweenX0AndX1=function(){return`between %s and %s`},e.prototype.atX0=function(){return`at %s`},e.prototype.commaEveryDay=function(){return`, every day`},e.prototype.commaEveryX0DaysOfTheWeek=function(){return`, every %s days of the week`},e.prototype.commaX0ThroughX1=function(){return`, %s through %s`},e.prototype.commaAndX0ThroughX1=function(){return`, %s through %s`},e.prototype.first=function(){return`first`},e.prototype.second=function(){return`second`},e.prototype.third=function(){return`third`},e.prototype.fourth=function(){return`fourth`},e.prototype.fifth=function(){return`fifth`},e.prototype.commaOnThe=function(){return`, on the `},e.prototype.spaceX0OfTheMonth=function(){return` %s of the month`},e.prototype.lastDay=function(){return`the last day`},e.prototype.commaOnTheLastX0OfTheMonth=function(){return`, on the last %s of the month`},e.prototype.commaOnlyOnX0=function(){return`, only on %s`},e.prototype.commaAndOnX0=function(){return`, and on %s`},e.prototype.commaEveryX0Months=function(){return`, every %s months`},e.prototype.commaOnlyInX0=function(){return`, only in %s`},e.prototype.commaOnTheLastDayOfTheMonth=function(){return`, on the last day of the month`},e.prototype.commaOnTheLastWeekdayOfTheMonth=function(){return`, on the last weekday of the month`},e.prototype.commaDaysBeforeTheLastDayOfTheMonth=function(){return`, %s days before the last day of the month`},e.prototype.firstWeekday=function(){return`first weekday`},e.prototype.weekdayNearestDayX0=function(){return`weekday nearest day %s`},e.prototype.commaOnTheX0OfTheMonth=function(){return`, on the %s of the month`},e.prototype.commaEveryX0Days=function(){return`, every %s days in a month`},e.prototype.commaBetweenDayX0AndX1OfTheMonth=function(){return`, between day %s and %s of the month`},e.prototype.commaOnDayX0OfTheMonth=function(){return`, on day %s of the month`},e.prototype.commaEveryHour=function(){return`, every hour`},e.prototype.commaEveryX0Years=function(){return`, every %s years`},e.prototype.commaStartingX0=function(){return`, starting %s`},e.prototype.daysOfTheWeek=function(){return[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`]},e.prototype.monthsOfTheYear=function(){return[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`]},e.prototype.atReboot=function(){return`Run once, at startup`},e.prototype.onTheHour=function(){return`on the hour`},e}()},9515(e,t){Object.defineProperty(t,"__esModule",{value:!0});function n(e,t){if(!e)throw Error(t)}t.default=function(){function e(){}return e.secondRange=function(e){for(var t=e.split(`,`),r=0;r<t.length;r++)if(!isNaN(parseInt(t[r],10))){var i=parseInt(t[r],10);n(i>=0&&i<=59,`seconds part must be >= 0 and <= 59`)}},e.minuteRange=function(e){for(var t=e.split(`,`),r=0;r<t.length;r++)if(!isNaN(parseInt(t[r],10))){var i=parseInt(t[r],10);n(i>=0&&i<=59,`minutes part must be >= 0 and <= 59`)}},e.hourRange=function(e){for(var t=e.split(`,`),r=0;r<t.length;r++)if(!isNaN(parseInt(t[r],10))){var i=parseInt(t[r],10);n(i>=0&&i<=23,`hours part must be >= 0 and <= 23`)}},e.dayOfMonthRange=function(e){for(var t=e.split(`,`),r=0;r<t.length;r++)if(!isNaN(parseInt(t[r],10))){var i=parseInt(t[r],10);n(i>=1&&i<=31,`DOM part must be >= 1 and <= 31`)}},e.monthRange=function(e,t){for(var r=e.split(`,`),i=0;i<r.length;i++)if(!isNaN(parseInt(r[i],10))){var a=parseInt(r[i],10);n(a>=1&&a<=12,t?`month part must be >= 0 and <= 11`:`month part must be >= 1 and <= 12`)}},e.dayOfWeekRange=function(e,t){for(var r=e.split(`,`),i=0;i<r.length;i++)if(!isNaN(parseInt(r[i],10))){var a=parseInt(r[i],10);n(a>=0&&a<=6,t?`DOW part must be >= 0 and <= 6`:`DOW part must be >= 1 and <= 7`)}},e}()},1823(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.StringUtilities=void 0,t.StringUtilities=function(){function e(){}return e.format=function(e){var t=[...arguments].slice(1);return e.replace(/%s/g,function(e){return t.shift()})},e.containsAny=function(e,t){return t.some(function(t){return e.indexOf(t)>-1})},e}()}},t={};function n(r){var i=t[r];if(i!==void 0)return i.exports;var a=t[r]={exports:{}};return e[r](a,a.exports,n),a.exports}var r={};return(()=>{var e=r;Object.defineProperty(e,"__esModule",{value:!0}),e.toString=void 0;var t=n(8333),i=n(3747);t.ExpressionDescriptor.initialize(new i.enLocaleLoader),e.default=t.ExpressionDescriptor,e.toString=t.ExpressionDescriptor.toString})(),r})())})),ye=k(),be=e(V(),1),H=d();function U(e){if(!e.parentElement||!e.clientWidth)return;let t=getComputedStyle(e),n=e.cloneNode(!1);n.removeAttribute(`id`),n.removeAttribute(`name`),n.setAttribute(`aria-hidden`,`true`),n.tabIndex=-1,n.value=e.value,Object.assign(n.style,{position:`fixed`,visibility:`hidden`,pointerEvents:`none`,width:t.width,height:`0`,minHeight:`0`,maxHeight:`none`}),e.parentElement.append(n);let r=n.scrollHeight+(t.boxSizing===`border-box`?parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth):-parseFloat(t.paddingTop)-parseFloat(t.paddingBottom));n.remove(),e.style.height=`${r}px`}function xe(e,t){(0,H.useLayoutEffect)(()=>{e.current&&U(e.current)},[e,t]),(0,H.useLayoutEffect)(()=>{let t=e.current;if(!t)return;let n=t.clientWidth,r=new ResizeObserver(()=>{t.clientWidth!==n&&(n=t.clientWidth,U(t))});return r.observe(t),()=>r.disconnect()},[e])}var W=`bivy-automation-v1
|
|
2
2
|
`;function G(e){let t=e;if(!t||typeof t!=`object`||Array.isArray(t)||Object.keys(t).some(e=>![`command`,`cwd`,`timeoutSeconds`].includes(e))||!Array.isArray(t.command)||!t.command.length||t.command.length>64||t.command.some(e=>typeof e!=`string`||e.length>4096||e.includes(`\0`))||!t.command[0]?.trim()||typeof t.cwd!=`string`||t.cwd.length>4096||t.cwd.includes(`\0`)||!/^(\/|[A-Za-z]:[\\/])/.test(t.cwd)||t.timeoutSeconds!==void 0&&(!Number.isInteger(t.timeoutSeconds)||t.timeoutSeconds<1||t.timeoutSeconds>60))throw Error(`filter requires command (non-empty argv list), cwd (absolute trusted directory), and optional timeoutSeconds (1-60)`);return{command:[...t.command],cwd:t.cwd,timeoutSeconds:t.timeoutSeconds??5}}function Se(e,t,n){return n||Object.keys(t).length||e.startsWith(W)?W+JSON.stringify({instructions:e,credentialLabels:t,...n?{filter:G(n)}:{}}):e}function Ce(e){if(!e.startsWith(W))return{instructions:e,credentialLabels:{}};let t=JSON.parse(e.slice(19));if(!t||typeof t.instructions!=`string`||!t.credentialLabels||typeof t.credentialLabels!=`object`||Array.isArray(t.credentialLabels)||Object.entries(t.credentialLabels).some(([e,t])=>!e.trim()||e!==e.trim().toLowerCase()||typeof t!=`string`||!t.trim()))throw Error(`Invalid automation account selections`);return{instructions:t.instructions,credentialLabels:t.credentialLabels,...t.filter===void 0?{}:{filter:G(t.filter)}}}var we={sunday:0,sun:0,monday:1,mon:1,tuesday:2,tue:2,tues:2,wednesday:3,wed:3,weds:3,thursday:4,thu:4,thur:4,thurs:4,friday:5,fri:5,saturday:6,sat:6},Te={january:1,jan:1,february:2,feb:2,march:3,mar:3,april:4,apr:4,may:5,june:6,jun:6,july:7,jul:7,august:8,aug:8,september:9,sep:9,sept:9,october:10,oct:10,november:11,nov:11,december:12,dec:12};function Ee(e){let t=[],n=new Set,r=(e,r)=>{if(e<0||e>23||r<0||r>59)return;let i=`${e}:${r}`;n.has(i)||(n.add(i),t.push({h:e,m:r}))};/\bnoon\b/.test(e)&&r(12,0),/\bmidnight\b/.test(e)&&r(0,0);for(let t of e.matchAll(/\b(\d{1,2})(?::(\d{2}))?\s*(am|pm)\b/g)){let e=Number(t[1]),n=t[2]?Number(t[2]):0;e===12&&(e=0),t[3]===`pm`&&(e+=12),r(e,n)}for(let t of e.matchAll(/\b(\d{1,2}):(\d{2})\b(?!\s*(?:am|pm))/g))r(Number(t[1]),Number(t[2]));return t.sort((e,t)=>e.h-t.h||e.m-t.m)}function K(e){let t=new Set;/\b(weekday|weekdays|every weekday|business day|business days)\b/.test(e)&&[1,2,3,4,5].forEach(e=>t.add(e)),/\b(weekend|weekends)\b/.test(e)&&[0,6].forEach(e=>t.add(e));for(let n of e.matchAll(/\b([a-z]+?)(?:s)?\b/g)){let e=n[1];e&&e in we&&t.add(we[e])}return[...t].sort((e,t)=>e-t)}function q(e){let t=new Set;for(let n of e.matchAll(/\b([a-z]+)\b/g)){let e=n[1];e&&e in Te&&t.add(Te[e])}return[...t].sort((e,t)=>e-t)}function J(e){let t=e.match(/\b(?:on the|the)\s+(\d{1,2})(?:st|nd|rd|th)?\b/)||e.match(/\b(\d{1,2})(?:st|nd|rd|th)\s+(?:of|day)\b/);if(t&&t[1]){let e=Number(t[1]);if(e>=1&&e<=31)return e}return null}function De(e){let t=` ${e.toLowerCase().trim().replace(/\s+/g,` `)} `;if(!t.trim())return{error:`Describe a schedule, e.g. “every day at 9am”.`};let n=t.match(/\bevery\s+(\d+)\s*(minute|minutes|min|mins|hour|hours|hr|hrs)\b/),r=Ee(t),i=K(t),a=q(t),o=J(t),s=o==null?`*`:String(o),c=a.length?a.join(`,`):`*`,l=i.join(`,`)===`1,2,3,4,5`?`1-5`:i.length?i.join(`,`):`*`;if(n){let e=Number(n[1]),t=n[2]??``,i=/^h/.test(t);return e<1?{error:`Interval must be at least 1.`}:i?e>23?{error:`Hour interval must be 23 or less. Use a daily time instead.`}:Y({minute:r.length?String(r[0].m):`0`,hour:e===1?`*`:`*/${e}`,dom:s,month:c,dow:l}):e>59?{error:`Minute interval must be 59 or less. Use an hourly interval instead.`}:Y({minute:e===1?`*`:`*/${e}`,hour:`*`,dom:s,month:c,dow:l})}if(/\bevery\s+minute\b/.test(t))return Y({minute:`*`,hour:`*`,dom:s,month:c,dow:l});if(/\b(every\s+hour|hourly)\b/.test(t))return Y({minute:r.length?String(r[0].m):`0`,hour:`*`,dom:s,month:c,dow:l});let u,d;if(r.length===0){if(i.length===0&&o==null&&a.length===0)return{error:`Add a time, e.g. “every day at 9am” or “every 15 minutes”.`};u=`0`,d=`0`}else if(r.length===1)u=String(r[0].m),d=String(r[0].h);else{if(new Set(r.map(e=>e.m)).size>1)return{error:`Multiple times must share the same minute (e.g. “at 9am and 5pm”).`};u=String(r[0].m),d=r.map(e=>e.h).join(`,`)}return Y({minute:u,hour:d,dom:s,month:c,dow:l})}function Y(e){return{cron:`${e.minute} ${e.hour} ${e.dom} ${e.month} ${e.dow}`,fields:e}}function X(e){return e.cron!==void 0}function Oe(e){if(!e)return{tone:`warn`,label:`Status unavailable`,detail:`Refresh to check the GitHub App connection.`};if(!e.connected||!e.apps.length)return{tone:`off`,label:`Not connected`,detail:`Install the hosted Bivy App or connect a custom GitHub App.`};let t=e.apps.filter(e=>e.installed||(e.installCount??0)>0);if(!t.length)return{tone:`warn`,label:`App connected · installation needed`,detail:`Install the app on repositories, or refresh if installation status has not synced.`};let n=t.some(e=>e.central),r=t.some(e=>!e.central);return{tone:`on`,label:n&&r?`Hosted + custom apps connected`:n?`Hosted Bivy App connected`:`Custom GitHub App connected`,detail:`Repository access is connected. Automations separately need an available executor.`}}function ke(e,t=``){return[...new Set((e?.apps??[]).filter(e=>!t||e.appId===t).map(e=>e.mention?.replace(/^@/,``)).filter(e=>!!e))]}function Ae(e){let t=encodeURIComponent(e.installationId);return e.githubAccountType===`Organization`&&e.githubAccount?`https://github.com/organizations/${encodeURIComponent(e.githubAccount)}/settings/installations/${t}`:`https://github.com/settings/installations/${t}`}var Z=P();function je({info:e,onChanged:t}){let n=(0,H.useId)(),r=e.apps.find(e=>e.triggerAccess)?.triggerAccess??e.triggerAccess??`everyone`,[i,a]=(0,H.useState)(r),[o,s]=(0,H.useState)(!1),[c,l]=(0,H.useState)(``),[u,d]=(0,H.useState)(!1);(0,H.useEffect)(()=>{a(r)},[r]);async function f(e){s(!0),l(``),d(!1);try{a(await S.setGithubAppTriggerAccess(e)),d(!0),t?.()}catch(e){l(String(e.message||e))}finally{s(!1)}}return(0,Z.jsxs)(`div`,{className:`settings-field`,children:[(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:n,children:`Who can trigger with a GitHub mention?`}),(0,Z.jsxs)(`select`,{id:n,className:`picker-search`,value:i,disabled:o,onChange:e=>void f(e.target.value),children:[(0,Z.jsx)(`option`,{value:`everyone`,children:`Anyone on GitHub`}),(0,Z.jsx)(`option`,{value:`contributor`,children:`Contributors and collaborators`}),(0,Z.jsx)(`option`,{value:`collaborator`,children:`Collaborators with write access`})]}),(0,Z.jsx)(`p`,{className:`settings-hint`,children:`Applies to every GitHub App on your Bivy account, not just this automation. Changes save immediately. Label events already require permission to apply labels on GitHub.`}),o&&(0,Z.jsx)(`p`,{className:`settings-hint`,role:`status`,children:`Saving permissions…`}),u&&!o&&(0,Z.jsx)(`p`,{className:`settings-hint`,role:`status`,children:`Permissions saved.`}),c&&(0,Z.jsx)(`p`,{className:`settings-error`,role:`alert`,children:c})]})}function Me(){try{sessionStorage.setItem(`bivy.githubAppPending`,`1`)}catch{}}function Q(e){return e.appId||e.hookId||e.slug||``}function Ne(e){return e.installUrl||(e.slug?`https://github.com/apps/${e.slug}/installations/new`:`https://github.com/settings/installations`)}function Pe(e){switch(e){case`linear`:return`Connect Linear`;case`slack`:return`Connect Slack`;default:return`GitHub App setup`}}function Fe(e){switch(e){case`linear`:return`Connect Linear to receive issue events. Your automation chooses which labels start a run and what the agent does.`;case`slack`:return`Turn a Slack slash command into an unattended run. Connect, copy the Request URL, or disconnect — all here.`;default:return`Manage the hosted Bivy GitHub App and your custom apps. App installation grants repository access; each automation configures which events start a run.`}}function Ie({state:e,onClose:t,focus:n=`github`,onChanged:r}){let i=!S.direct,a=(0,H.useRef)(r);a.current=r;let o=D(t);fe(o);let[s,c]=(0,H.useState)(null),[l,u]=(0,H.useState)(null),[d,f]=(0,H.useState)(!0),[p,m]=(0,H.useState)([]),[_,v]=(0,H.useState)(null),[y,te]=(0,H.useState)(null),[x,ne]=(0,H.useState)(null),[re,ie]=(0,H.useState)(``),[T,ae]=(0,H.useState)(``),[se,le]=(0,H.useState)(``),[E,O]=(0,H.useState)(!1),[k,ue]=(0,H.useState)(null),[A,de]=(0,H.useState)(!1),[j,M]=(0,H.useState)(``),[pe,N]=(0,H.useState)(``),[P,me]=(0,H.useState)(``),[he,ge]=(0,H.useState)(!1),[F,I]=(0,H.useState)(null),[L,_e]=(0,H.useState)(``),[R,ve]=(0,H.useState)(!1),[z,B]=(0,H.useState)(null),[V,ye]=(0,H.useState)(!1),be=(0,H.useRef)(null),[U,xe]=(0,H.useState)(null),[W,G]=(0,H.useState)(null),[Se,Ce]=(0,H.useState)(!1),[we,Te]=(0,H.useState)(null),[Ee,K]=(0,H.useState)(``),[q,J]=(0,H.useState)(``),[De,Y]=(0,H.useState)(!1),[X,Oe]=(0,H.useState)(``),[ke,Ie]=(0,H.useState)(!1),[Be,Ve]=(0,H.useState)(``),[He,Ue]=(0,H.useState)(``),[We,Ge]=(0,H.useState)(!1),[Ke,qe]=(0,H.useState)(``),[Je,Ye]=(0,H.useState)(!1),Xe=e.presentation.githubApp,$=Xe?.phase??`idle`,Ze=$===`submitting`&&Xe?.action&&Xe?.manifest,Qe=n===`github`||n===`work-queue`,$e=n===`linear`,et=n===`slack`,tt=(0,H.useCallback)(async()=>{if(!i){ie(`Source setup needs a hosted account connection.`),f(!1);return}ie(``),f(!0);try{let[e,t,n,r,i,a]=await Promise.all([S.fetchGithubApp(),S.listNodes(),b(S.local).catch(()=>null),C(S.local).catch(()=>null),oe(S.local).catch(()=>null),S.centralGithubApp().catch(()=>null)]);u(a),c(e),m(t),v(n),te(r),ne(i);let o=e.apps.find(e=>e.defaultNode)?.defaultNode??e.defaultNode??``;le(o||``),n?.defaultNode&&J(n.defaultNode),r?.defaultNode&&Ue(r.defaultNode)}catch(e){ie(String(e.message||e))}finally{f(!1)}},[i]);(0,H.useEffect)(()=>{tt();let e=()=>{tt(),a.current?.()};return window.addEventListener(`focus`,e),()=>window.removeEventListener(`focus`,e)},[tt]),(0,H.useEffect)(()=>{$===`done`&&(tt(),a.current?.())},[$,tt]);let nt=s?.apps??[],rt=nt.some(e=>e.installed),it=nt.some(e=>e.servedBy?.online),at=!!x?.execution.ready,ot=nt.length>0&&rt&&(at||it);async function st(){Ce(!0),Te(null);try{let e=await S.createCentralGithubInstall(`/automations`);window.location.assign(e.installUrl)}catch(e){Te(String(e?.message||e)),Ce(!1)}}async function ct(){O(!0),ue(null);try{let e=await S.setGithubAppDefaultNode(se.trim());ue(`Saved`),c(t=>t&&{...t,defaultNode:e,apps:t.apps.map(t=>({...t,defaultNode:e}))}),r?.(),setTimeout(()=>ue(null),1500)}catch(e){ue(String(e.message||e))}finally{O(!1)}}async function lt(){ge(!0),_e(``),ve(!1),I(null);try{if(e.connection.currentNodeId)await S.githubAppConnectExisting({appId:j.trim(),privateKeyPem:pe.trim()}),ve(!0);else{let e=await S.connectHostedGithubApp({appId:j.trim(),privateKeyPem:pe.trim(),...P.trim()?{installationId:P.trim()}:{}});I({webhookUrl:e.webhookUrl,webhookSecret:e.webhookSecret})}N(``),await tt(),r?.()}catch(e){_e(String(e?.message||e))}finally{ge(!1)}}async function ut(e){let t=Q(e);if(confirm(`Disconnect ${e.name||e.mention||`this GitHub App`}? The key is wiped on this machine; the app is not deleted on GitHub.`)){G(null),xe(t);try{await S.githubAppDisconnect(e.appId,e.hookId),await tt(),r?.(),(await S.fetchGithubApp()).apps.some(e=>Q(e)===t)&&G(`Disconnect didn't take effect — try again shortly.`)}catch(e){G(String(e.message||e))}finally{xe(null)}}}function dt(e){B(e??null),M(e?.appId??``),N(``),_e(``),ve(!1),I(null),de(!0),ye(!0)}(0,H.useEffect)(()=>{V&&A&&be.current?.scrollIntoView({behavior:`smooth`,block:`nearest`})},[V,A,z]);function ft(e){let t=e.target.files?.[0];if(!t)return;let n=new FileReader;n.onload=()=>N(String(n.result||``).trim()),n.readAsText(t)}async function pt(){Y(!0),Oe(``);try{let e=await h(S.local,{defaultNode:q||void 0});v(e),r?.()}catch(e){Oe(String(e.message||e))}finally{Y(!1)}}async function mt(){Y(!0),Oe(``);try{let e=await h(S.local,{signingSecret:Ee.trim(),defaultNode:q||void 0});v(e),K(``),Ie(!!e.enabled),r?.()}catch(e){Oe(String(e.message||e))}finally{Y(!1)}}async function ht(){if(confirm(`Disconnect Linear? Its webhook URL will stop accepting issues.`)){Y(!0),Oe(``);try{await ee(S.local),v(null),Ie(!1),r?.()}catch(e){Oe(String(e.message||e))}finally{Y(!1)}}}async function gt(){Ge(!0),qe(``);try{let e=await g(S.local,{signingSecret:Be.trim(),defaultNode:He||void 0});te(e),Ve(``),Ye(!0),r?.()}catch(e){qe(String(e.message||e))}finally{Ge(!1)}}async function _t(){if(confirm(`Disconnect Slack? The slash-command URL will stop accepting requests.`)){Ge(!0),qe(``);try{await ce(S.local),te(null),Ye(!1),r?.()}catch(e){qe(String(e.message||e))}finally{Ge(!1)}}}let vt=n===`github`&&(s?.connected||rt)?`Manage GitHub Apps`:Pe(n),yt=n===`slack`&&y?.enabled?`Done — Slack is live`:n===`linear`&&_?.enabled?`Done — Linear is live`:n===`github`&&ot?`Done — GitHub is live`:ot&&n===`work-queue`?`Done — ready to run`:`Done`;return(0,Z.jsx)(`div`,{className:`wizard-scrim`,onClick:o,children:(0,Z.jsxs)(`div`,{className:`wizard autom-editor wq-setup`,role:`dialog`,"aria-modal":`true`,"aria-label":vt,onClick:e=>e.stopPropagation(),children:[(0,Z.jsxs)(`div`,{className:`wizard-head`,children:[(0,Z.jsxs)(`div`,{className:`wq-head-text`,children:[(0,Z.jsx)(`strong`,{children:vt}),(0,Z.jsx)(`span`,{className:`wq-head-sub`,children:`Automations · Sources`})]}),(0,Z.jsx)(`button`,{type:`button`,className:`btn ghost icon`,onClick:o,"aria-label":`Close`,children:`✕`})]}),(0,Z.jsxs)(`div`,{className:`wizard-body`,children:[(0,Z.jsx)(`p`,{className:`settings-hint wq-lead`,children:Fe(n)}),d&&(0,Z.jsx)(`p`,{className:`settings-hint`,role:`status`,children:`Checking source connection…`}),re&&(0,Z.jsxs)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:[re,(0,Z.jsx)(`button`,{type:`button`,className:`btn sm`,onClick:()=>void tt(),children:`Retry`})]}),Qe&&s&&(0,Z.jsxs)(`div`,{className:`autom-field-block`,children:[(0,Z.jsxs)(`div`,{className:`autom-field-label`,children:[(0,Z.jsx)(`span`,{className:`wq-section-icon`,"aria-hidden":`true`,children:(0,Z.jsx)(Le,{})}),`GitHub Apps`]}),(0,Z.jsx)(`p`,{className:`settings-hint`,children:`Enable label or mention events in an automation to start runs. Labels are configurable per automation; mention events use the app handles below and do not require a label.`}),!nt.some(e=>e.central)&&(0,Z.jsxs)(`div`,{className:`card wq-status-card`,"data-tone":`muted`,children:[(0,Z.jsx)(`strong`,{children:`Hosted Bivy GitHub App · Recommended`}),(0,Z.jsx)(`p`,{className:`settings-hint`,children:`Choose repositories on GitHub and start using Bivy. No app creation or private key is needed.`}),!l?.configured&&(0,Z.jsx)(`p`,{className:`settings-hint`,children:l?`The hosted app is not enabled on this deployment. You can use your own app below.`:`Could not check hosted app availability. Refresh status to try again.`}),(0,Z.jsx)(`button`,{type:`button`,className:`btn primary`,disabled:Se||!l?.configured,onClick:()=>void st(),children:Se?`Opening GitHub…`:`Install hosted Bivy App`}),(0,Z.jsx)(`a`,{className:`btn sm`,href:`https://github.com/settings/installations`,target:`_blank`,rel:`noreferrer`,children:`Manage hosted app access on GitHub ↗`}),(0,Z.jsx)(`p`,{className:`settings-hint`,children:`Change repository access or uninstall the Bivy App on GitHub. For organization installations, use the organization’s Settings → GitHub Apps.`}),we&&(0,Z.jsx)(`p`,{className:`settings-error`,role:`alert`,children:we})]}),nt.length===0?(0,Z.jsxs)(`details`,{className:`card wq-status-card`,"data-tone":`muted`,children:[(0,Z.jsx)(`summary`,{children:`Use your own GitHub App`}),(0,Z.jsx)(`p`,{className:`settings-hint`,children:`No custom GitHub App connected. Create your own app on a connected machine, or connect an app you already own.`}),(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`wq-org`,children:`Organization (optional)`}),(0,Z.jsx)(`input`,{id:`wq-org`,className:`picker-search`,value:T,placeholder:`leave blank for your personal account`,disabled:$===`starting`||$===`submitting`||$===`completing`,onChange:e=>ae(e.target.value)}),Ze?(0,Z.jsxs)(`form`,{method:`post`,action:Xe.action,onSubmit:Me,children:[(0,Z.jsx)(`input`,{type:`hidden`,name:`manifest`,value:JSON.stringify(Xe.manifest)}),(0,Z.jsx)(`button`,{className:`btn primary block`,type:`submit`,children:`Continue to GitHub →`})]}):(0,Z.jsx)(`button`,{type:`button`,className:`btn primary`,disabled:$===`starting`||$===`completing`||!i,onClick:()=>S.githubAppManifestStart(T.trim()||void 0),children:$===`starting`?`Preparing…`:$===`completing`?`Finishing…`:`Create GitHub App`}),!A&&(0,Z.jsx)(`button`,{type:`button`,className:`btn link`,onClick:()=>de(!0),children:`Connect an existing app instead →`}),A&&(0,Z.jsxs)(`div`,{className:`ce-form`,children:[(0,Z.jsx)(`label`,{className:`field-label`,children:`App ID`}),(0,Z.jsx)(`input`,{className:`picker-search`,value:j,placeholder:`e.g. 123456`,onChange:e=>M(e.target.value)}),(0,Z.jsx)(`label`,{className:`field-label`,children:`Private key (.pem)`}),(0,Z.jsx)(`input`,{className:`ce-file`,type:`file`,accept:`.pem,application/x-pem-file,text/plain`,onChange:ft}),(0,Z.jsx)(`textarea`,{className:`picker-search ce-pem`,value:pe,rows:3,placeholder:`…or paste the PEM here`,onChange:e=>N(e.target.value)}),!e.connection.currentNodeId&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`label`,{className:`field-label`,children:`Installation ID (only needed for apps installed on multiple accounts)`}),(0,Z.jsx)(`input`,{className:`picker-search`,value:P,placeholder:`auto-selected when there is one`,onChange:e=>me(e.target.value)})]}),(0,Z.jsx)(`button`,{type:`button`,className:`btn primary`,disabled:!j.trim()||!pe.trim()||$===`completing`||he,onClick:()=>void lt(),children:$===`completing`||he?`Connecting…`:e.connection.currentNodeId?`Connect app to this machine`:`Connect app for isolated runs`}),L&&(0,Z.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:L}),R&&(0,Z.jsxs)(`div`,{className:`banner inline`,"data-tone":`ok`,role:`status`,children:[(0,Z.jsx)(`strong`,{children:`App connected.`}),` This machine now holds the key and can claim GitHub work.`]}),F&&(0,Z.jsxs)(`div`,{className:`banner inline`,"data-tone":`ok`,role:`status`,children:[(0,Z.jsx)(`strong`,{children:`Hosted App ready.`}),` Set its webhook URL to `,(0,Z.jsx)(`code`,{children:F.webhookUrl}),` and secret to `,(0,Z.jsx)(`code`,{children:F.webhookSecret}),`.`]})]}),$===`completing`&&(0,Z.jsx)(`p`,{className:`settings-hint`,children:`Finishing on the machine…`}),$===`done`&&(0,Z.jsxs)(`div`,{className:`banner inline`,"data-tone":`ok`,role:`status`,children:[(0,Z.jsx)(`strong`,{children:`App ready.`}),` Install it on a repository so it can receive issues.`,` `,(0,Z.jsx)(`a`,{href:Xe?.installUrl||`https://github.com/settings/installations`,target:`_blank`,rel:`noreferrer`,children:`Install on GitHub →`})]}),$===`error`&&(0,Z.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,children:Xe?.error||`GitHub App setup failed.`})]}):(0,Z.jsxs)(`div`,{className:`card wq-status-card`,"data-tone":`muted`,children:[nt.map(t=>(0,Z.jsx)(`div`,{className:`wq-app-row`,children:(0,Z.jsxs)(`div`,{className:`wq-app-row-main`,children:[(0,Z.jsxs)(`div`,{className:`wq-app-title-row`,children:[(0,Z.jsx)(`strong`,{children:t.name||t.mention||`GitHub App`}),(0,Z.jsx)(w,{tone:t.installed?`ok`:`warn`,children:t.installed?`Connected`:t.installed===!1?`Needs install`:`Installation not verified`})]}),t.owner&&(0,Z.jsxs)(`span`,{className:`settings-hint`,children:[t.ownerType===`Organization`?`org`:`personal`,` · `,t.owner]}),(0,Z.jsxs)(`span`,{className:`settings-hint`,children:[(0,Z.jsx)(`strong`,{children:`Mention trigger:`}),` `,t.mention?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`code`,{children:[`@`,t.mention]}),` followed by your instructions`]}):`Handle not available yet — refresh app status.`]}),t.central?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`span`,{className:`settings-hint`,children:[`Hosted Bivy App · `,(t.installations??[]).map(e=>e.githubAccount).filter(Boolean).join(`, `)||`installed`]}),(t.installations??[]).map(e=>(0,Z.jsxs)(`a`,{className:`btn sm`,href:Ae(e),target:`_blank`,rel:`noreferrer`,children:[`Configure / uninstall · `,e.githubAccount||e.installationId,` ↗`]},e.installationId)),(0,Z.jsx)(`span`,{className:`settings-hint`,children:`Change repository access or uninstall on GitHub. Uninstalling stops events for that installation.`}),(0,Z.jsx)(`button`,{type:`button`,className:`btn link`,disabled:Se,onClick:()=>void st(),children:Se?`Opening GitHub…`:`Add another account or organization →`})]}):t.installed===!1?(0,Z.jsxs)(`p`,{className:`schedule-hint warn`,children:[`Not installed on any repo yet.`,` `,(0,Z.jsx)(`a`,{href:Ne(t),target:`_blank`,rel:`noreferrer`,children:`Install it now →`})]}):(0,Z.jsxs)(`span`,{className:`settings-hint`,children:[`Installed on `,t.installCount??`some`,` `,t.installCount===1?`repo`:`repos`,`.`,` `,(0,Z.jsx)(`a`,{href:Ne(t),target:`_blank`,rel:`noreferrer`,children:`Manage →`})]}),t.central?(0,Z.jsx)(`span`,{className:`settings-hint`,children:`Repository access is connected. Runs separately need an online machine or a ready isolated profile.`}):at?(0,Z.jsx)(`span`,{className:`settings-hint`,children:`An isolated machine profile is ready to run automations.`}):t.hosted?(0,Z.jsx)(`span`,{className:`settings-hint`,children:`Hosted custom app connected; configure an isolated machine profile to run automations.`}):t.servedBy===null?(0,Z.jsxs)(`p`,{className:`schedule-hint warn`,children:[`No online machine holds this app's key — queue items won't be claimed.`,` `]}):t.servedBy&&(0,Z.jsxs)(`span`,{className:`settings-hint`,children:[`Served by `,(0,Z.jsx)(`strong`,{children:t.servedBy.name||t.servedBy.id}),t.servedBy.online?``:` (offline)`,`.`]}),!t.central&&e.connection.currentNodeId&&(0,Z.jsx)(`span`,{className:`settings-hint`,children:`Using a new machine? Connect the existing App’s private key below — no reinstall on GitHub needed.`}),!t.central&&(0,Z.jsxs)(`div`,{className:`row-actions`,style:{marginTop:6},children:[e.connection.currentNodeId&&(0,Z.jsx)(`button`,{type:`button`,className:`btn sm`,onClick:()=>dt(t),children:`Connect key on this machine`}),(0,Z.jsx)(`button`,{type:`button`,className:`btn sm danger-ghost`,disabled:U!==null,onClick:()=>void ut(t),children:U===Q(t)?`Disconnecting…`:`Disconnect`})]})]})},Q(t))),(W||we)&&(0,Z.jsx)(`p`,{className:`settings-error`,children:W||we}),(0,Z.jsxs)(`div`,{className:`settings-field`,style:{marginTop:4},children:[(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`wq-default-node`,children:`Default machine for untagged work`}),(0,Z.jsxs)(`select`,{id:`wq-default-node`,className:`picker-search`,value:se,onChange:e=>le(e.target.value),children:[(0,Z.jsx)(`option`,{value:``,children:`Shared queue (any online machine)`}),p.map(e=>(0,Z.jsx)(`option`,{value:String(e.name||e.id),children:String(e.name||e.id)},e.id))]}),(0,Z.jsxs)(`div`,{className:`row-actions`,children:[(0,Z.jsx)(`button`,{type:`button`,className:`btn sm`,disabled:E,onClick:()=>void ct(),children:E?`Saving…`:`Save`}),k&&(0,Z.jsx)(`span`,{className:`settings-hint`,children:k})]})]}),(0,Z.jsx)(je,{info:s,onChanged:()=>{tt(),r?.()}}),V?(0,Z.jsxs)(`div`,{ref:be,className:`card wq-status-card`,"data-tone":`muted`,style:{marginTop:4},children:[(0,Z.jsx)(`div`,{className:`autom-field-label`,children:z?`Reconnect ${z.name||z.mention||`GitHub App`}`:`Add another app`}),z?(0,Z.jsxs)(`p`,{className:`settings-hint`,children:[`Choose the private key for App ID `,j,` to connect it to this machine.`]}):(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`p`,{className:`settings-hint`,children:`One app per personal account or organization you want Bivy to cover.`}),(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`wq-org-2`,children:`Organization (optional)`}),(0,Z.jsx)(`input`,{id:`wq-org-2`,className:`picker-search`,value:T,placeholder:`leave blank for your personal account`,disabled:$===`starting`||$===`submitting`||$===`completing`,onChange:e=>ae(e.target.value)}),Ze?(0,Z.jsxs)(`form`,{method:`post`,action:Xe.action,onSubmit:Me,children:[(0,Z.jsx)(`input`,{type:`hidden`,name:`manifest`,value:JSON.stringify(Xe.manifest)}),(0,Z.jsx)(`button`,{className:`btn primary block`,type:`submit`,children:`Continue to GitHub →`})]}):(0,Z.jsx)(`button`,{type:`button`,className:`btn primary`,disabled:$===`starting`||$===`completing`||!i,onClick:()=>S.githubAppManifestStart(T.trim()||void 0),children:$===`starting`?`Preparing…`:$===`completing`?`Finishing…`:`Create GitHub App`}),(0,Z.jsx)(`button`,{type:`button`,className:`btn link`,onClick:()=>dt(),children:`Connect an existing app instead →`})]}),A&&(0,Z.jsxs)(`div`,{className:`ce-form`,children:[(0,Z.jsx)(`label`,{className:`field-label`,children:`App ID`}),(0,Z.jsx)(`input`,{className:`picker-search`,value:j,placeholder:`e.g. 123456`,onChange:e=>M(e.target.value)}),(0,Z.jsx)(`label`,{className:`field-label`,children:`Private key (.pem)`}),(0,Z.jsx)(`input`,{className:`ce-file`,type:`file`,accept:`.pem,application/x-pem-file,text/plain`,onChange:ft}),(0,Z.jsx)(`textarea`,{className:`picker-search ce-pem`,value:pe,rows:3,placeholder:`…or paste the PEM here`,onChange:e=>N(e.target.value)}),!e.connection.currentNodeId&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`label`,{className:`field-label`,children:`Installation ID (only needed for apps installed on multiple accounts)`}),(0,Z.jsx)(`input`,{className:`picker-search`,value:P,placeholder:`auto-selected when there is one`,onChange:e=>me(e.target.value)})]}),(0,Z.jsx)(`button`,{type:`button`,className:`btn primary`,disabled:!j.trim()||!pe.trim()||$===`completing`||he,onClick:()=>void lt(),children:$===`completing`||he?`Connecting…`:e.connection.currentNodeId?`Connect app to this machine`:`Connect app for isolated runs`}),L&&(0,Z.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,role:`alert`,children:L}),R&&(0,Z.jsxs)(`div`,{className:`banner inline`,"data-tone":`ok`,role:`status`,children:[(0,Z.jsx)(`strong`,{children:`App connected.`}),` This machine now holds the key and can claim GitHub work.`]}),F&&(0,Z.jsxs)(`div`,{className:`banner inline`,"data-tone":`ok`,role:`status`,children:[(0,Z.jsx)(`strong`,{children:`Hosted App ready.`}),` Set its webhook URL to `,(0,Z.jsx)(`code`,{children:F.webhookUrl}),` and secret to `,(0,Z.jsx)(`code`,{children:F.webhookSecret}),`.`]})]}),(0,Z.jsx)(`button`,{type:`button`,className:`btn link`,onClick:()=>{ye(!1),B(null)},children:`Cancel`})]}):(0,Z.jsx)(`button`,{type:`button`,className:`btn sm`,onClick:()=>{ye(!0),de(!1),B(null)},children:`+ Connect another custom GitHub App`}),ot&&(0,Z.jsxs)(`div`,{className:`banner inline`,"data-tone":`ok`,role:`status`,children:[(0,Z.jsx)(`strong`,{children:`App installed.`}),` Configure and enable an automation to choose its labels, mention events, and instructions.`]})]})]}),$e&&(0,Z.jsxs)(`div`,{className:`autom-field-block`,children:[(0,Z.jsxs)(`div`,{className:`autom-field-label`,children:[(0,Z.jsx)(`span`,{className:`wq-section-icon`,"aria-hidden":`true`,children:(0,Z.jsx)(Re,{})}),`Linear`]}),(0,Z.jsxs)(`div`,{className:`card wq-status-card`,"data-tone":`muted`,children:[X&&(0,Z.jsx)(`p`,{className:`settings-error`,children:X}),ke&&_?.enabled&&(0,Z.jsxs)(`div`,{className:`banner inline`,"data-tone":`ok`,role:`status`,children:[(0,Z.jsx)(`strong`,{children:`Linear is live.`}),` Label an issue `,(0,Z.jsx)(`code`,{children:`bivy`}),` (or `,(0,Z.jsx)(`code`,{children:`bivy/<machine>`}),`) to enqueue it.`]}),_?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`wq-app-title-row`,children:[(0,Z.jsx)(`strong`,{children:_.enabled?`Connected`:`Finish connecting`}),(0,Z.jsx)(w,{tone:_.enabled?`ok`:`warn`,children:_.enabled?`Live`:`Needs secret`})]}),(0,Z.jsxs)(`p`,{className:`settings-hint`,children:[`In `,(0,Z.jsx)(`strong`,{children:`Linear → Settings → API → Webhooks`}),`, create an `,(0,Z.jsx)(`strong`,{children:`Issue`}),` webhook with this URL:`]}),(0,Z.jsxs)(`div`,{className:`reveal-row`,children:[(0,Z.jsx)(`code`,{className:`reveal-value`,children:_.endpoint}),(0,Z.jsx)(`button`,{type:`button`,className:`btn sm`,onClick:()=>void navigator.clipboard?.writeText(_.endpoint),children:`Copy`})]}),(0,Z.jsxs)(`ol`,{className:`wq-how-list`,style:{paddingLeft:18},children:[(0,Z.jsx)(`li`,{children:`Copy the signing secret Linear generates.`}),(0,Z.jsxs)(`li`,{children:[`Paste it below`,_.enabled?` to rotate`:` to finish`,`.`]}),(0,Z.jsxs)(`li`,{children:[`Create labels `,(0,Z.jsx)(`code`,{children:`bivy`}),` and optionally use the compatibility label `,(0,Z.jsx)(`code`,{children:`bivy/node-name`}),` to choose a machine.`]})]}),(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`lin-secret`,children:_.enabled?`Replace signing secret`:`Linear signing secret`}),(0,Z.jsx)(`input`,{id:`lin-secret`,className:`picker-search`,type:`password`,autoComplete:`off`,value:Ee,disabled:De,placeholder:`Signing secret from Linear`,onChange:e=>K(e.target.value)}),(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`lin-route-2`,children:`Default machine (optional)`}),(0,Z.jsxs)(`select`,{id:`lin-route-2`,className:`picker-search`,value:q,disabled:De,onChange:e=>J(e.target.value),children:[(0,Z.jsx)(`option`,{value:``,children:`Shared queue`}),p.map(e=>(0,Z.jsx)(`option`,{value:String(e.name||e.id),children:String(e.name||e.id)},e.id))]}),(0,Z.jsx)(`button`,{type:`button`,className:`btn primary`,disabled:De||Ee.trim().length<16,onClick:()=>void mt(),children:De?`Saving…`:_.enabled?`Update connection`:`Connect Linear`}),(0,Z.jsxs)(`p`,{className:`settings-hint`,children:[`Each trusted workstation also needs `,(0,Z.jsx)(`code`,{children:`BIVY_LINEAR_API_KEY`}),` and a default `,(0,Z.jsx)(`code`,{children:`BIVY_LINEAR_REPO=owner/repo`}),`.`]}),(0,Z.jsx)(`button`,{type:`button`,className:`btn sm danger-ghost`,disabled:De,onClick:()=>void ht(),children:`Disconnect Linear`})]}):(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`p`,{className:`settings-hint`,children:`Create a Bivy webhook URL, paste it into Linear, then bring Linear's signing secret back here.`}),(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`lin-route`,children:`Default machine (optional)`}),(0,Z.jsxs)(`select`,{id:`lin-route`,className:`picker-search`,value:q,disabled:De,onChange:e=>J(e.target.value),children:[(0,Z.jsx)(`option`,{value:``,children:`Shared queue`}),p.map(e=>(0,Z.jsx)(`option`,{value:String(e.name||e.id),children:String(e.name||e.id)},e.id))]}),(0,Z.jsx)(`button`,{type:`button`,className:`btn primary`,disabled:De||!i,onClick:()=>void pt(),children:De?`Creating…`:`Create webhook URL`})]})]})]}),et&&(0,Z.jsxs)(`div`,{className:`autom-field-block`,children:[(0,Z.jsxs)(`div`,{className:`autom-field-label`,children:[(0,Z.jsx)(`span`,{className:`wq-section-icon`,"aria-hidden":`true`,children:(0,Z.jsx)(ze,{})}),`Slack`]}),(0,Z.jsxs)(`div`,{className:`card wq-status-card`,"data-tone":`muted`,children:[Ke&&(0,Z.jsx)(`p`,{className:`settings-error`,children:Ke}),Je&&y?.enabled&&(0,Z.jsxs)(`div`,{className:`banner inline`,"data-tone":`ok`,role:`status`,children:[(0,Z.jsx)(`strong`,{children:`Slack is live.`}),` Paste the Request URL into your slash command, then try`,` `,(0,Z.jsx)(`code`,{children:`/bivy fix the failing tests`}),`.`]}),y?.enabled?(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`wq-app-title-row`,children:[(0,Z.jsx)(`strong`,{children:`Connected`}),(0,Z.jsx)(w,{tone:`ok`,children:`Live`})]}),(0,Z.jsx)(`p`,{className:`settings-hint`,children:`Use this as your Slack app's slash-command Request URL:`}),(0,Z.jsxs)(`div`,{className:`reveal-row`,children:[(0,Z.jsx)(`code`,{className:`reveal-value`,children:y.endpoint}),(0,Z.jsx)(`button`,{type:`button`,className:`btn sm`,onClick:()=>void navigator.clipboard?.writeText(y.endpoint),children:`Copy`})]}),(0,Z.jsx)(`div`,{className:`autom-field-label`,style:{marginTop:4},children:`Commands`}),(0,Z.jsx)(`code`,{className:`wq-cmd`,children:`/bivy fix the failing tests`}),(0,Z.jsx)(`code`,{className:`wq-cmd`,children:`/bivy on macbook fix the failing tests`}),(0,Z.jsx)(`code`,{className:`wq-cmd`,children:`/bivy in owner/repo fix the failing tests`}),(0,Z.jsxs)(`p`,{className:`settings-hint`,children:[`Add `,(0,Z.jsx)(`code`,{children:`in owner/repo`}),` for an isolated checkout + PR. Add `,(0,Z.jsx)(`code`,{children:`on machine-name`}),` to choose a machine.`]}),(0,Z.jsx)(`button`,{type:`button`,className:`btn sm danger-ghost`,disabled:We,onClick:()=>void _t(),children:`Disconnect Slack`})]}):(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`ol`,{className:`wq-how-list`,style:{paddingLeft:18},children:[(0,Z.jsxs)(`li`,{children:[`Create a Slack app, then open `,(0,Z.jsx)(`strong`,{children:`Basic Information`}),`.`]}),(0,Z.jsxs)(`li`,{children:[`Copy its `,(0,Z.jsx)(`strong`,{children:`Signing Secret`}),` below.`]}),(0,Z.jsxs)(`li`,{children:[`After connecting, create a slash command named `,(0,Z.jsx)(`code`,{children:`/bivy`}),` and paste the Request URL shown here.`]})]}),(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`slack-secret`,children:`Slack signing secret`}),(0,Z.jsx)(`input`,{id:`slack-secret`,className:`picker-search`,type:`password`,autoComplete:`off`,value:Be,disabled:We,placeholder:`Signing Secret`,onChange:e=>Ve(e.target.value)}),(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`slack-route`,children:`Default machine (optional)`}),(0,Z.jsxs)(`select`,{id:`slack-route`,className:`picker-search`,value:He,disabled:We,onChange:e=>Ue(e.target.value),children:[(0,Z.jsx)(`option`,{value:``,children:`Shared queue`}),p.map(e=>(0,Z.jsx)(`option`,{value:String(e.name||e.id),children:String(e.name||e.id)},e.id))]}),(0,Z.jsx)(`button`,{type:`button`,className:`btn primary`,disabled:We||Be.trim().length<16||!i,onClick:()=>void gt(),children:We?`Connecting…`:`Connect Slack`})]})]})]})]}),(0,Z.jsxs)(`div`,{className:`wizard-actions`,children:[(0,Z.jsx)(`button`,{type:`button`,className:`btn ghost`,"aria-label":`Refresh source status`,disabled:d,onClick:()=>{tt(),a.current?.()},children:`Refresh`}),(0,Z.jsx)(`button`,{type:`button`,className:`btn primary`,onClick:o,children:yt})]})]})})}function Le(){return(0,Z.jsx)(`svg`,{viewBox:`0 0 16 16`,width:`14`,height:`14`,fill:`currentColor`,"aria-hidden":`true`,children:(0,Z.jsx)(`path`,{d:`M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z`})})}function Re(){return(0,Z.jsxs)(`svg`,{viewBox:`0 0 24 24`,width:`14`,height:`14`,fill:`currentColor`,"aria-hidden":`true`,children:[(0,Z.jsx)(`path`,{d:`M2.86 16.14a3.43 3.43 0 0 0 4.85 4.85L21.14 7.56A3.43 3.43 0 0 0 16.29 2.7L2.86 16.14Z`,opacity:`.35`}),(0,Z.jsx)(`path`,{d:`M3.43 12a.86.86 0 0 0-.86.86v4.28A5.14 5.14 0 0 0 7.71 22.3h4.29a.86.86 0 0 0 0-1.72H7.71A3.43 3.43 0 0 1 4.29 17.14v-4.28A.86.86 0 0 0 3.43 12Zm8.57-9.43a.86.86 0 0 0 0 1.72h4.29a3.43 3.43 0 0 1 3.42 3.42v4.29a.86.86 0 0 0 1.72 0V7.71A5.14 5.14 0 0 0 16.29 2.57H12Z`})]})}function ze(){return(0,Z.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`14`,height:`14`,fill:`currentColor`,"aria-hidden":`true`,children:(0,Z.jsx)(`path`,{d:`M6 15a2 2 0 1 1-2-2h2v2Zm1 0a2 2 0 1 1 4 0v5a2 2 0 1 1-4 0v-5Zm2-8a2 2 0 1 1 2-2v2H9Zm0 1a2 2 0 1 1 0 4H4a2 2 0 1 1 0-4h5Zm8 2a2 2 0 1 1 2 2h-2V10Zm-1 0a2 2 0 1 1-4 0V5a2 2 0 1 1 4 0v5Zm-2 8a2 2 0 1 1-2 2v-2h2Zm0-1a2 2 0 1 1 0-4h5a2 2 0 1 1 0 4h-5Z`})})}function Be(e){if(e.trigger===`github_ci`)return{issuesLabeled:!1,issueMention:!1,prLabeled:!1,prMention:!1,workflowFailed:!0};let t=e.on;return t?.length?{issuesLabeled:t.some(e=>e.event===`issues`&&!e.mention),issueMention:t.some(e=>[`issues`,`pull_request`,`issue_comment`].includes(e.event)&&e.mention),prLabeled:t.some(e=>e.event===`pull_request`&&!e.mention),prMention:t.some(e=>e.event===`pull_request_review_comment`&&e.mention),workflowFailed:t.some(e=>e.event===`workflow_run`)}:{issuesLabeled:!0,issueMention:!0,prLabeled:!1,prMention:!1,workflowFailed:!1}}function Ve(e,t,n){let r=t?.length?t:[`bivy`],i=[];return e.issuesLabeled&&i.push({event:`issues`,labels:r}),e.issueMention&&i.push({event:`issues`,mention:!0},{event:`pull_request`,mention:!0},{event:`issue_comment`,mention:!0}),e.prLabeled&&i.push({event:`pull_request`,labels:r}),e.prMention&&i.push({event:`pull_request_review_comment`,mention:!0}),e.workflowFailed&&i.push({event:`workflow_run`,actions:[`completed`],conclusions:[`failure`,`timed_out`,`startup_failure`],workflows:n?.length?n:void 0}),i}function He({mode:e,header:t,secret:n,existing:r,onMode:i,onHeader:a,onSecret:o}){return(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`settings-field`,children:[(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`webhook-auth-mode`,children:`Authentication method`}),(0,Z.jsxs)(`select`,{id:`webhook-auth-mode`,className:`picker-search`,value:e,onChange:e=>i(e.target.value),children:[(0,Z.jsx)(`option`,{value:`hmac`,children:`HMAC-SHA256 signature (recommended)`}),(0,Z.jsx)(`option`,{value:`header`,children:`Static secret header`})]}),(0,Z.jsx)(`p`,{className:`settings-hint`,children:e===`hmac`?`The sender signs the raw request body with your secret. The header value is sha256= followed by the hexadecimal HMAC digest, not the secret itself.`:`The sender puts the exact secret value in this header. Use HTTPS; unlike HMAC, this does not bind authentication to the request body.`})]}),(0,Z.jsxs)(`div`,{className:`settings-field`,children:[(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`webhook-auth-header`,children:`Header name`}),(0,Z.jsx)(`input`,{id:`webhook-auth-header`,className:`picker-search`,value:t,maxLength:128,spellCheck:!1,onChange:e=>a(e.target.value)})]}),(0,Z.jsxs)(`div`,{className:`settings-field`,children:[(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`webhook-auth-secret`,children:e===`hmac`?`Custom signing secret (optional)`:`Custom header value (optional)`}),(0,Z.jsx)(`input`,{id:`webhook-auth-secret`,className:`picker-search`,type:`password`,autoComplete:`new-password`,value:n,minLength:32,maxLength:256,onChange:e=>o(e.target.value)}),(0,Z.jsxs)(`p`,{className:`settings-hint`,children:[r?`Leave blank to keep the current secret. Enter a value to replace it immediately on save.`:`Leave blank to generate a secure secret on save.`,` Custom values must be 32–256 printable characters. Secrets are never included in list responses.`]})]})]})}function Ue({value:e,error:t,onChange:n}){let r=(0,H.useId)(),i=(t,r)=>n({...e,[t]:r});return(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`label`,{className:`settings-toggle-row webhook-signing-toggle`,children:[(0,Z.jsxs)(`span`,{className:`settings-toggle-text`,children:[(0,Z.jsx)(`strong`,{className:`settings-toggle-title`,children:`Filter deliveries with a script`}),(0,Z.jsx)(`small`,{className:`muted`,children:`Run a script on the machine first. It decides whether each delivery starts the agent.`})]}),(0,Z.jsx)(`input`,{className:`sr-only`,type:`checkbox`,checked:e.enabled,onChange:e=>i(`enabled`,e.target.checked)}),(0,Z.jsx)(`span`,{className:`settings-toggle${e.enabled?` on`:``}`,"aria-hidden":`true`,children:(0,Z.jsx)(`span`,{className:`settings-toggle-knob`})})]}),e.enabled&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`settings-field`,children:[(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`${r}-command`,children:`Command`}),(0,Z.jsx)(`input`,{id:`${r}-command`,className:`picker-search`,value:e.command,placeholder:`node filter.mjs`,autoComplete:`off`,autoCapitalize:`off`,spellCheck:!1,onChange:e=>i(`command`,e.target.value)}),(0,Z.jsxs)(`p`,{className:`settings-hint`,children:[`Runs directly, without a shell. Quote arguments that contain spaces. The script receives `,(0,Z.jsx)(`code`,{children:`{"event":{"payload":…}}`}),` on stdin and must print `,(0,Z.jsx)(`code`,{children:`{"decision":"accept"}`}),` or `,(0,Z.jsx)(`code`,{children:`{"decision":"skip","reason":"…"}`}),`.`]})]}),(0,Z.jsxs)(`div`,{className:`settings-field`,children:[(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`${r}-cwd`,children:`Directory on the machine`}),(0,Z.jsx)(`input`,{id:`${r}-cwd`,className:`picker-search`,value:e.cwd,placeholder:`/srv/bivy/trusted-filters`,autoComplete:`off`,autoCapitalize:`off`,spellCheck:!1,onChange:e=>i(`cwd`,e.target.value)}),(0,Z.jsx)(`p`,{className:`settings-hint`,children:`Absolute path to scripts you put there yourself. Do not use a repository the agent can edit: the script runs as the Bivy user and is not sandboxed.`})]}),(0,Z.jsxs)(`div`,{className:`settings-field`,children:[(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:`${r}-timeout`,children:`Timeout (seconds)`}),(0,Z.jsx)(`input`,{id:`${r}-timeout`,className:`picker-search`,type:`number`,inputMode:`numeric`,min:1,max:60,step:1,value:e.timeoutSeconds,onChange:e=>i(`timeoutSeconds`,e.target.value)}),(0,Z.jsx)(`p`,{className:`settings-hint`,children:`A skip completes the run without starting the agent. A script error, invalid output, or timeout marks the run as needing attention.`})]}),t&&(0,Z.jsx)(`p`,{className:`schedule-hint warn`,children:t})]})]})}function We(e){return e?{enabled:!0,command:qe(e.command),cwd:e.cwd,timeoutSeconds:String(e.timeoutSeconds)}:{enabled:!1,command:``,cwd:``,timeoutSeconds:`5`}}function Ge(e){if(!e.enabled)return{};let t=Ke(e.command);if(t===null)return{error:`Close the quote in the filter command.`};if(!t.length)return{error:`Enter the filter command.`};let n=e.cwd.trim();if(!/^(\/|[A-Za-z]:[\\/])/.test(n))return{error:`The filter directory must be an absolute path on the machine.`};let r=Number(e.timeoutSeconds.trim()||`5`);if(!Number.isInteger(r)||r<1||r>60)return{error:`The filter timeout must be a whole number from 1 to 60 seconds.`};try{return{filter:G({command:t,cwd:n,timeoutSeconds:r})}}catch(e){return{error:String(e.message||e)}}}function Ke(e){let t=[],n=``,r=!1,i=null;for(let a of e)i?a===i?i=null:n+=a:a===`'`||a===`"`?(i=a,r=!0):/\s/.test(a)?(r&&t.push(n),n=``,r=!1):(n+=a,r=!0);return i?null:(r&&t.push(n),t)}function qe(e){return e.map(e=>e&&!/[\s'"]/.test(e)?e:`'${e.replaceAll(`'`,`'"'"'`)}'`).join(` `)}function Je({value:e,onChange:t,github:n}){let r=(0,H.useId)();return(0,Z.jsxs)(`div`,{className:`settings-field`,children:[(0,Z.jsx)(`label`,{className:`field-label`,htmlFor:r,children:`Limit to these repositories (optional)`}),(0,Z.jsx)(`input`,{id:r,className:`picker-search`,value:e,onChange:e=>t(e.target.value),placeholder:`acme/website, acme/api`}),(0,Z.jsx)(`p`,{className:`settings-hint`,children:n?`Leave blank for any repository the selected GitHub App can access. To accept events only from specific repositories, enter their owner/name, separated by commas. This filters events; it does not grant repository access.`:`Leave blank for any repository. To limit which linked repositories can start this automation, enter their owner/name, separated by commas.`})]})}var Ye=new Set([`succeeded`,`failed`,`cancelled`,`done`]);function Xe(e){return Ye.has(e.status)}function $(e){let t=o(e),n=e.checks??[],r=n.filter(e=>e.status===`passed`).length,i=n.filter(e=>e.status===`failed`).length,a=n.filter(e=>e.status===`skipped`).length,s=n.length?[r?`${r} passed`:``,i?`${i} failed`:``,a?`${a} skipped`:``].filter(Boolean).join(` · `):void 0,c=e.output,l=c?.prUrl?{kind:`pull_request`,label:`Pull request`,url:c.prUrl}:c?.artifactUrl?{kind:`artifact`,label:`Artifact`,url:c.artifactUrl}:c?.branch?{kind:`branch`,label:`Branch ${c.branch}`}:c?.commit?{kind:`commit`,label:`Commit ${c.commit.slice(0,12)}`}:c?.checkpoint?{kind:`checkpoint`,label:`Checkpoint`}:void 0,u=[];return c?.sessionId&&u.push(`open_session`),c?.prUrl?u.push(`view_pull_request`):c?.artifactUrl&&u.push(`view_artifact`),{outcome:t,sessionId:c?.sessionId,attempt:Math.max(1,e.attempt??1),agent:[e.runtimeId,e.model].filter(Boolean).join(` · `)||void 0,failure:c?.failure,checks:n,checksSummary:s,artifact:l,availableActions:u}}var Ze=5;function Qe(e){let t=c(e);if(t)return`${t.repo} #${t.issueNumber}`;if(typeof e==`string`&&e.startsWith(`queue:`)){let t=e.slice(6);return t===`slack`?`Slack`:t===`github:comment`?`GitHub @-mention`:t===`github:issue`?`GitHub issue`:t===`linear:issue`?`Linear issue`:t||`Queue`}return``}function $e(e){return e===`github:comment`?`GitHub @-mention`:e===`github:issue`?`GitHub labelled issue`:e===`linear:issue`?`Linear issue`:e}function et({queue:e,onRefresh:t,onPick:n,onOpenRun:r,onOpenGithubSettings:i,showHistory:a=!0}){let{sessionIndex:{sessions:o},activeSession:{activeSessionId:s},presentation:{prRefreshAllResult:l},catalogs:{runtimes:d}}=se(),f=E(),m=p&&f,h=!S.direct,g=(0,H.useMemo)(()=>[{id:``,label:`Machine default`},...d.map(e=>({id:e.id,label:String(e.displayName||e.name||e.id)}))],[d]),[_,v]=(0,H.useState)(null),[y,b]=(0,H.useState)([]),[ee,te]=(0,H.useState)(null),[x,ne]=(0,H.useState)(`shared`),[re,ie]=(0,H.useState)(``),[C,T]=(0,H.useState)([]),[ae,oe]=(0,H.useState)(``),[ce,le]=(0,H.useState)(``),[D,O]=(0,H.useState)(!1),[k,A]=(0,H.useState)(null),[de,fe]=(0,H.useState)(null),[M,pe]=(0,H.useState)(!1),[N,P]=(0,H.useState)(null),[he,_e]=(0,H.useState)(!1),[R,B]=(0,H.useState)(null),[V,ye]=(0,H.useState)(null),[be,U]=(0,H.useState)(!1);(0,H.useEffect)(()=>{be&&U(!1)},[l]),(0,H.useEffect)(()=>{if(!l)return;let e=setTimeout(()=>S.store.clearPrRefreshAllResult(),8e3);return()=>clearTimeout(e)},[l]);let xe=async()=>{let e=R;if(e){B(null),P(null),ye(e.id);try{await S.cancelAutomationRun(e.id),t()}catch(e){P(String(e?.message||e))}finally{ye(null)}}},W=()=>{U(!0),S.refreshAllPrStatus()},[G,Se]=(0,H.useState)(!1),[Ce,we]=(0,H.useState)(null),Te=(0,H.useRef)(null);(0,H.useEffect)(()=>()=>{Te.current&&clearTimeout(Te.current)},[]);let Ee=async e=>{let t={id:e.id,source:e.source,status:e.status,repo:e.repo,issueNumber:e.issueNumber,url:e.url,createdAt:e.createdAt,claimedAt:e.claimedAt,startedAt:e.startedAt,completedAt:e.completedAt,attempt:e.attempt,runtimeId:e.runtimeId,model:e.model,routingReason:e.routingReason,approvalMode:e.approvalMode,sandbox:e.sandbox,output:e.output,checks:e.checks,events:e.events};await j(JSON.stringify(t,null,2))&&(we(e.id),Te.current&&clearTimeout(Te.current),Te.current=setTimeout(()=>we(null),1800))};(0,H.useEffect)(()=>{S.listRuntimes()},[]);let[K,q]=(0,H.useState)([]),[J,De]=(0,H.useState)(``),[Y,X]=(0,H.useState)(!1),[Oe,ke]=(0,H.useState)(!1);(0,H.useEffect)(()=>{h&&(S.fetchGithubApp().then(v).catch(()=>v(null)),S.listNodes().then(b).catch(()=>{}),S.listEphemeralKeys().then(q).catch(()=>{}),m&&S.listEphemeralConfigs().then(T).catch(()=>{}),S.getGithubTaskToken().then(e=>X(!!e)).catch(()=>{}))},[h,m]);let Ae=(0,H.useMemo)(()=>K.filter(e=>e.configured),[K]),je=(0,H.useMemo)(()=>y.filter(e=>!e.id.startsWith(`eph-`)),[y]),Me=(0,H.useMemo)(()=>new Map(C.map(e=>[e.id,e])),[C]),Q=(e=>e.startsWith(`config:`)?{kind:`config`,id:e.slice(7)}:e.startsWith(`node:`)?{kind:`node`,node:e.slice(5)}:{kind:`shared`})(x),Ne=Q.kind===`node`?Q.node:``,Pe=Q.kind===`config`?Me.get(Q.id):void 0,Fe=re.startsWith(`config:`)?Me.get(re.slice(7)):void 0,Ie=!!Pe||!!Fe,Le=e=>{A(null),te(e.id);let t=e.label&&e.label.startsWith(`bivy/`)?e.label.slice(5):``;ne(t?`node:${t}`:`shared`),ie(``),oe(e.runtimeId??``),le(e.model??``)},Re=async e=>{A(null),O(!0);try{let n=t=>S.runWorkItemOnEphemeral(e,{provider:t.provider,region:t.region||void 0,size:t.size||void 0,ttlMinutes:t.ttlMinutes||void 0,runtimeId:ae||void 0,model:ce||void 0,configId:t.id});if(Q.kind===`config`){let e=Me.get(Q.id);if(!e)throw Error(`That isolated machine profile is no longer available`);await n(e)}else if(Q.kind===`node`){let t=je.find(e=>(e.name||e.id)===Q.node);t&&!t.online&&Fe?await n(Fe):await S.assignWorkItem(e,{node:Q.node,runtimeId:ae,model:ce})}else await S.assignWorkItem(e,{node:``,runtimeId:ae,model:ce});te(null),t()}catch(e){A(String(e?.message||e))}finally{O(!1)}},ze=async()=>{if(J.trim()){ke(!0);try{await S.setGithubTaskToken(J.trim()),De(``),X(!0)}catch(e){A(String(e?.message||e))}finally{ke(!1)}}},Be=async e=>{fe(e),P(null);try{await S.deleteWorkItem(e),ee===e&&te(null),t()}catch(e){P(String(e?.message||e))}finally{fe(null)}},Ve=async()=>{pe(!0),P(null);try{await S.clearWorkQueue(),te(null),t()}catch(e){P(String(e?.message||e))}finally{pe(!1)}},He=(0,H.useMemo)(()=>[...o].filter(e=>u(e.source)).sort((e,t)=>z(t.updatedAt)-z(e.updatedAt)),[o]),Ue=G?He:He.slice(0,Ze),We=He.length-Ue.length,Ge=(0,H.useMemo)(()=>{let e=new Set;for(let t of He){let n=c(t.source);n&&e.add(`${n.repo}#${n.issueNumber}`)}return e},[He]),Ke=(0,H.useMemo)(()=>e&&e.filter(e=>!(e.status!==`pending`||e.repo&&e.issueNumber!=null&&Ge.has(`${e.repo}#${e.issueNumber}`))),[e,Ge]),qe=(0,H.useMemo)(()=>(e??[]).filter(e=>e.status!==`pending`&&!!e.events?.length).sort((e,t)=>z(t.startedAt??t.claimedAt??t.createdAt)-z(e.startedAt??e.claimedAt??e.createdAt)),[e]),Je=_?.apps??[],Ye=Je.filter(e=>e.servedBy===null);return(0,Z.jsxs)(`div`,{className:`settings-form`,children:[h&&_&&Je.length===0&&(0,Z.jsxs)(`div`,{className:`banner inline`,"data-tone":`neutral`,children:[`Install the hosted Bivy GitHub App, or connect your own app.`,` `,(0,Z.jsx)(`button`,{className:`btn link`,onClick:i,children:`Set up GitHub Apps →`})]}),h&&Ye.length>0&&(0,Z.jsxs)(`div`,{className:`banner inline`,"data-tone":`warn`,children:[Ye.length===Je.length?`${Je.length===1?`Your GitHub App is`:`Your GitHub Apps are`} set up, but no online machine is running ${Je.length===1?`it`:`them`} — nothing will pick these up.`:`${Ye.length} of your ${Je.length} GitHub Apps (${Ye.map(e=>e.name||e.mention||e.appId).join(`, `)}) aren't running on any machine — work for those won't be picked up.`,` `,(0,Z.jsx)(`button`,{className:`btn link`,onClick:i,children:Ye.length===1?`Connect it on a machine →`:`Connect them on a machine →`})]}),a&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`queue-head`,children:[(0,Z.jsx)(`h4`,{className:`settings-subhead`,children:`Sessions`}),(0,Z.jsxs)(`div`,{className:`queue-head-actions`,children:[l&&!be&&(0,Z.jsx)(`span`,{className:`muted`,children:l.error?l.error:`Checked ${l.scanned}, updated ${l.changed}`}),(0,Z.jsx)(`button`,{className:`btn link`,onClick:W,disabled:be,title:`Reconcile every session's PR status against GitHub now`,children:be?`Refreshing GitHub status…`:`Refresh GitHub status`})]})]}),He.length===0?(0,Z.jsxs)(`p`,{className:`muted`,children:[`No GitHub-triggered sessions yet. Label an issue `,(0,Z.jsx)(`code`,{children:`bivy`}),` or @-mention your app to see one here.`]}):(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`ul`,{className:`queue-session-list`,children:Ue.map(e=>{let t=Qe(e.source),r=I(e),i=me(e.source);return(0,Z.jsx)(`li`,{className:`session-row`,children:(0,Z.jsx)(`button`,{className:`session-item${e.sessionId===s?` active`:``}`,onClick:()=>n(e.sessionId,e.path,e.nodeId),children:(0,Z.jsxs)(`span`,{className:`session-body`,children:[(0,Z.jsxs)(`span`,{className:`session-title-row`,children:[(0,Z.jsx)(ge,{status:ve(e),srLabel:`${i.label} · ${r}`}),(0,Z.jsx)(`span`,{className:`session-name`,children:e.name}),(0,Z.jsx)(F,{prs:e.prs}),L(e.updatedAt)&&(0,Z.jsx)(`span`,{className:`session-age`,title:r,children:L(e.updatedAt)})]}),t&&(0,Z.jsx)(`span`,{className:`session-meta`,children:t})]})})},e.sessionId)})}),He.length>Ze&&(0,Z.jsx)(`button`,{className:`btn link`,onClick:()=>Se(e=>!e),children:G?`Show less`:`Show more (${We})`})]})]}),h&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`queue-head`,children:[(0,Z.jsxs)(`h4`,{className:`settings-subhead`,children:[`Waiting to be picked up`,Ke&&Ke.length>0&&(0,Z.jsx)(`span`,{className:`queue-count`,children:Ke.length})]}),(0,Z.jsxs)(`div`,{className:`queue-head-actions`,children:[Ke&&Ke.length>0&&(0,Z.jsx)(`button`,{className:`btn link danger`,onClick:()=>_e(!0),disabled:M,children:M?`Clearing…`:`Clear queue`}),(0,Z.jsx)(`button`,{className:`btn link`,onClick:t,children:`Refresh`})]})]}),he&&(0,Z.jsx)(ue,{title:`Clear the queue?`,message:`Remove all waiting items from the queue? Items already picked up keep running.`,confirmLabel:`Clear queue`,danger:!0,onCancel:()=>_e(!1),onConfirm:()=>{_e(!1),Ve()}}),N&&(0,Z.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,children:N}),Ke===null?(0,Z.jsx)(`p`,{className:`muted`,children:`—`}):Ke.length===0?(0,Z.jsx)(`p`,{className:`muted`,children:`Nothing waiting right now.`}):(0,Z.jsx)(`div`,{className:`queue-list`,children:Ke.map(e=>{let t=ee===e.id,n=e.title||`${e.repo??``}#${e.issueNumber??``}`,r=`${e.repo??``}${e.issueNumber?` #${e.issueNumber}`:``} · ${$e(e.source)}`;return(0,Z.jsxs)(`div`,{className:`card queue-card${t?` open`:``}`,"data-tone":`muted`,children:[(0,Z.jsxs)(`div`,{className:`queue-card-row`,children:[e.url?(0,Z.jsxs)(`a`,{className:`queue-item-main link`,href:e.url,target:`_blank`,rel:`noopener noreferrer`,title:n,children:[(0,Z.jsxs)(`span`,{className:`queue-item-title`,children:[n,m&&e.ephemeral&&(0,Z.jsx)(w,{title:`Dispatched to an ephemeral server`,children:`⚡ ephemeral`})]}),(0,Z.jsx)(`span`,{className:`queue-item-meta`,children:r})]}):(0,Z.jsxs)(`div`,{className:`queue-item-main`,title:n,children:[(0,Z.jsxs)(`span`,{className:`queue-item-title`,children:[n,m&&e.ephemeral&&(0,Z.jsx)(w,{title:`Dispatched to an ephemeral server`,children:`⚡ ephemeral`})]}),(0,Z.jsx)(`span`,{className:`queue-item-meta`,children:r})]}),(0,Z.jsxs)(`div`,{className:`queue-card-actions`,children:[(0,Z.jsx)(`button`,{className:`queue-action-btn${t?` active`:``}`,onClick:()=>t?te(null):Le(e),title:`Dispatch to a machine + agent`,children:t?`Cancel`:`Run…`}),(0,Z.jsx)(`button`,{className:`queue-action-btn danger icon`,onClick:()=>Be(e.id),disabled:de===e.id,title:`Remove from queue`,"aria-label":`Remove from queue`,children:de===e.id?`…`:`×`})]})]}),t&&(0,Z.jsxs)(`div`,{className:`queue-run`,children:[(0,Z.jsxs)(`label`,{className:`queue-run-field`,children:[(0,Z.jsx)(`span`,{children:`Machine`}),(0,Z.jsxs)(`select`,{value:x,onChange:e=>ne(e.target.value),children:[(0,Z.jsx)(`option`,{value:`shared`,children:`Shared queue (any online machine)`}),je.length>0&&(0,Z.jsx)(`optgroup`,{label:`Persistent machines`,children:je.map(e=>(0,Z.jsxs)(`option`,{value:`node:${e.name||e.id}`,children:[e.name||e.id,e.online?``:` (offline)`]},e.id))}),m&&C.length>0&&(0,Z.jsx)(`optgroup`,{label:`Cloud machine profiles`,children:C.map(e=>(0,Z.jsxs)(`option`,{value:`config:${e.id}`,children:[e.name,` · `,e.provider]},e.id))}),Q.kind===`node`&&!je.some(e=>(e.name||e.id)===Ne)&&(0,Z.jsx)(`option`,{value:x,children:Ne})]})]}),m&&Q.kind===`node`&&C.length>0&&(0,Z.jsxs)(`label`,{className:`queue-run-field`,children:[(0,Z.jsx)(`span`,{children:`Fallback if machine is offline`}),(0,Z.jsxs)(`select`,{value:re,onChange:e=>ie(e.target.value),children:[(0,Z.jsx)(`option`,{value:``,children:`None — wait for the machine`}),C.map(e=>(0,Z.jsxs)(`option`,{value:`config:${e.id}`,children:[e.name,` · `,e.provider]},e.id))]})]}),Ie&&(()=>{let e=Pe??Fe,t=Ae.some(t=>t.id===e.provider);return(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`p`,{className:`muted small`,children:[Pe?`Runs on`:`Falls back to`,` a fresh `,e.provider,` machine`,e.region?` · ${e.region}`:``,e.size?` · ${e.size}`:``,e.ttlMinutes?` · auto-destroy ${e.ttlMinutes}m`:``,`.`,!t&&` Add a ${e.provider} token on this device to launch it.`]}),(0,Z.jsxs)(`label`,{className:`queue-run-field`,children:[(0,Z.jsxs)(`span`,{children:[`GitHub token `,Y?`(saved on this device — leave blank to reuse it)`:`(needed to clone/push/open PRs)`]}),(0,Z.jsxs)(`div`,{className:`row-actions`,children:[(0,Z.jsx)(`input`,{type:`password`,value:J,placeholder:Y?`•••• saved`:`paste a token`,onChange:e=>De(e.target.value)}),(0,Z.jsx)(`button`,{className:`btn link`,disabled:!J.trim()||Oe,onClick:ze,children:Oe?`Saving…`:`Save`})]})]})]})})(),(0,Z.jsxs)(`label`,{className:`queue-run-field`,children:[(0,Z.jsx)(`span`,{children:`Agent`}),(0,Z.jsx)(`select`,{value:ae,onChange:e=>oe(e.target.value),children:g.map(e=>(0,Z.jsx)(`option`,{value:e.id,children:e.label},e.id))})]}),(0,Z.jsxs)(`label`,{className:`queue-run-field`,children:[(0,Z.jsx)(`span`,{children:`Model`}),(0,Z.jsx)(`input`,{value:ce,placeholder:`optional, e.g. claude-sonnet-5`,onChange:e=>le(e.target.value)})]}),(0,Z.jsxs)(`div`,{className:`queue-run-actions`,children:[(0,Z.jsx)(`button`,{className:`btn`,disabled:D||Q.kind===`config`&&!Pe,onClick:()=>Re(e.id),children:D?`Dispatching…`:Q.kind===`config`?`Provision & run`:`Run`}),k&&(0,Z.jsx)(w,{tone:`danger`,children:k})]})]})]},e.id)})})]}),a&&h&&qe.length>0&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`div`,{className:`queue-head`,children:(0,Z.jsx)(`h4`,{className:`settings-subhead`,children:`Run details`})}),R&&(0,Z.jsx)(ue,{title:`Cancel Run?`,message:`Request cancellation of this Run? It will remain active until the refreshed durable record reports a terminal result.`,confirmLabel:`Cancel Run`,danger:!0,onCancel:()=>B(null),onConfirm:()=>void xe()}),(0,Z.jsx)(`div`,{className:`evidence-list`,children:qe.map(e=>{let t=$(e),n=t.outcome.tone===`danger`?`danger`:t.outcome.tone===`success`?`ok`:t.outcome.tone===`warning`?`warn`:void 0;return(0,Z.jsxs)(`details`,{className:`evidence-report`,children:[(0,Z.jsxs)(`summary`,{children:[(0,Z.jsxs)(`span`,{children:[e.repo,e.issueNumber?` #${e.issueNumber}`:``,` · `,$e(e.source)]}),(0,Z.jsx)(w,{tone:n,children:t.outcome.label})]}),(0,Z.jsxs)(`div`,{className:`evidence-meta`,children:[(0,Z.jsxs)(`span`,{children:[`Trigger: `,e.triggerKind??e.source]}),t.attempt>1&&(0,Z.jsxs)(`span`,{children:[`Attempt `,t.attempt]}),t.agent&&(0,Z.jsxs)(`span`,{children:[`Agent: `,t.agent]}),t.checksSummary&&(0,Z.jsxs)(`span`,{children:[`Checks: `,t.checksSummary]}),e.routingReason&&(0,Z.jsxs)(`span`,{children:[`Routing: `,e.routingReason]}),e.sandbox&&(0,Z.jsxs)(`span`,{children:[`Sandbox: `,e.sandbox]}),e.approvalMode&&(0,Z.jsxs)(`span`,{children:[`Approval: `,e.approvalMode]}),e.output?.branch&&(0,Z.jsxs)(`span`,{children:[`Branch: `,(0,Z.jsx)(`code`,{children:e.output.branch})]}),e.output?.commit&&(0,Z.jsxs)(`span`,{children:[`Commit: `,(0,Z.jsx)(`code`,{children:e.output.commit.slice(0,12)})]}),e.output?.prUrl&&(0,Z.jsx)(`a`,{href:e.output.prUrl,target:`_blank`,rel:`noreferrer`,children:`Pull request`}),e.output?.artifactUrl&&(0,Z.jsx)(`a`,{href:e.output.artifactUrl,target:`_blank`,rel:`noreferrer`,children:`Artifact`})]}),t.failure&&(0,Z.jsx)(`p`,{className:`muted`,children:t.failure}),(0,Z.jsx)(`ol`,{className:`evidence-timeline`,children:e.events.map((e,t)=>(0,Z.jsxs)(`li`,{children:[(0,Z.jsx)(`time`,{children:new Date(e.at).toLocaleString()}),(0,Z.jsx)(`span`,{children:e.summary}),e.attempt!==void 0&&(0,Z.jsxs)(`small`,{children:[`Attempt `,e.attempt]})]},`${e.at}-${t}`))}),e.checks&&e.checks.length>0&&(0,Z.jsx)(`ul`,{className:`evidence-checks`,children:e.checks.map((e,t)=>(0,Z.jsxs)(`li`,{children:[e.name,`: `,e.status,e.exitCode===void 0?``:` (exit ${e.exitCode})`,e.durationMs===void 0?``:` · ${(e.durationMs/1e3).toFixed(1)}s`]},`${e.name}-${t}`))}),(0,Z.jsxs)(`div`,{className:`row-actions`,children:[r&&(0,Z.jsx)(`button`,{className:`btn link`,onClick:()=>r(e.id),children:`Open Run details`}),!Xe(e)&&(0,Z.jsx)(`button`,{className:`btn link danger`,disabled:V===e.id,onClick:()=>{P(null),B(e)},children:V===e.id?`Cancelling…`:`Cancel Run`}),(0,Z.jsx)(`button`,{className:`btn link`,onClick:()=>void Ee(e),children:Ce===e.id?`Copied!`:`Copy sanitized Run JSON`})]})]},e.id)})})]}),!h&&(0,Z.jsx)(`p`,{className:`muted`,children:`Direct/local mode has no shared account queue — sessions a labelled issue starts on this machine still show above.`})]})}var tt=[{id:`rate_limited`,label:`Rate limited`,hint:`429 / overloaded / retry-after`},{id:`credits_exhausted`,label:`Session / credits`,hint:`quota, credit balance, or session usage limit; Retry waits for a supplied reset time`},{id:`context_overflow`,label:`Context overflow`,hint:`prompt exceeds the context window`},{id:`auth_failed`,label:`Auth failed`,hint:`401 / invalid key`},{id:`node_offline`,label:`Machine offline`,hint:`connection refused / unreachable`},{id:`transport_error`,label:`Transport error`,hint:`socket hang up / timeout / 502`},{id:`task_failed`,label:`Task failed`,hint:`tests failed / made no changes`},{id:`unknown`,label:`Unknown`,hint:`anything unclassified`}],nt=[{id:`retry`,label:`Retry`,hint:`Resume at the provider's reset/retry time when supplied; otherwise use backoff, up to the attempt limit.`},{id:`reroute`,label:`Reroute`,hint:`Fall back down a chain of routes, then park/give up.`},{id:`park`,label:`Park`,hint:`Stop and flag for a human — no automatic recovery.`}],rt=[{id:`queue`,label:`Work queue`,hint:`Unattended runs (GitHub / webhooks).`},{id:`session`,label:`Session`,hint:`Interactive chats — resume when a usage/rate limit resets, or reroute to a fallback model.`}],it={baseMs:2e3,factor:2,capMs:6e4,jitter:.3};function at(){return{version:1,name:``,appliesTo:[`queue`],rules:[{when:[`transport_error`,`node_offline`],action:`retry`,maxAttempts:3,backoff:{...it}}]}}function ot(e){let t=e.appliesTo.map(e=>rt.find(t=>t.id===e)?.label??e).join(` + `);return`${e.rules.length} rule${e.rules.length===1?``:`s`} · ${t||`no contexts`}`}function st(e){let t={when:e.when,action:e.action,maxAttempts:e.maxAttempts};return(e.action===`retry`||e.action===`reroute`)&&(e.backoff&&(t.backoff=e.backoff),e.onExhausted&&(t.onExhausted=e.onExhausted)),e.action===`reroute`&&(t.chain=(e.chain??[]).map(e=>{let t={};return e.runtimeId?.trim()&&(t.runtimeId=e.runtimeId.trim()),e.model?.trim()&&(t.model=e.model.trim()),e.account?.trim()&&(t.account=e.account.trim()),e.label?.trim()&&(t.label=e.label.trim()),t})),t}function ct({state:e}){let[t,n]=(0,H.useState)(null),[r,i]=(0,H.useState)(!1),[a,o]=(0,H.useState)(!1),[s,c]=(0,H.useState)(!1),[l,u]=(0,H.useState)(null),[d,f]=(0,H.useState)(null);(0,H.useEffect)(()=>{S.listRulesets()},[]);let p=()=>{u(null),o(!1),i(!0),n(at())},m=e=>{u(null),o(e.active),i(!1);let{active:t,...r}=e;n(JSON.parse(JSON.stringify(r)))},h=()=>{n(null),u(null)};return t?(0,Z.jsx)(lt,{draft:t,setDraft:n,isNew:r,active:a,setActive:o,busy:s,error:l,onCancel:h,onSave:async()=>{c(!0),u(null);try{let e={...t,name:t.name.trim(),rules:t.rules.map(st)};await S.saveRuleset(e,a),S.listRulesets(),h()}catch(e){u(String(e?.message||e))}finally{c(!1)}}}):(0,Z.jsxs)(`div`,{className:`settings-form`,children:[d&&(0,Z.jsx)(ue,{title:d.title,message:d.message,confirmLabel:`Remove`,danger:!0,onCancel:()=>f(null),onConfirm:()=>{d.action(),f(null)}}),(0,Z.jsxs)(`p`,{className:`muted settings-intro`,children:[`A ruleset is policy for what happens when a run fails — a rate limit, an exhausted quota, an offline machine. Each rule matches one or more failure conditions and decides whether to retry, reroute through a fallback chain, or park the run for a human. The `,(0,Z.jsx)(`strong`,{children:`active`}),` ruleset steers this machine's work queue and interactive sessions (per the contexts it applies to); with none active, a safe built-in default applies. Rulesets are stored on this machine.`]}),(0,Z.jsxs)(`div`,{className:`picker-list`,children:[e.settings.rulesets.length===0&&(0,Z.jsx)(`div`,{className:`picker-empty`,children:`No rulesets yet.`}),e.settings.rulesets.map(e=>(0,Z.jsx)(N,{title:e.name,meta:ot(e),right:(0,Z.jsxs)(`span`,{className:`row-actions`,children:[e.active&&(0,Z.jsx)(w,{tone:`ok`,children:`Active`}),(0,Z.jsx)(`button`,{className:`btn danger-ghost sm`,onClick:t=>{t.stopPropagation(),f({title:`Remove ruleset?`,message:`Remove "${e.name}"?${e.active?` It's currently active — the work queue will fall back to the built-in default.`:``}`,action:()=>{S.removeRuleset(e.name),setTimeout(()=>S.listRulesets(),400)}})},children:`Remove`})]}),onClick:()=>m(e)},e.name))]}),(0,Z.jsx)(`button`,{className:`btn primary block`,onClick:p,children:`+ New ruleset`})]})}function lt({draft:e,setDraft:t,isNew:n,active:r,setActive:i,busy:a,error:o,onCancel:s,onSave:c}){let l=n=>t({...e,...n}),u=(t,n)=>l({rules:e.rules.map((e,r)=>r===t?n:e)}),d=t=>{let n=e.appliesTo.includes(t)?e.appliesTo.filter(e=>e!==t):[...e.appliesTo,t];l({appliesTo:n})},f=e.appliesTo.includes(`queue`),p=e.appliesTo.includes(`session`),m=f||p,h=e.name.trim().length>0,g=e.rules.length>0&&e.rules.every(e=>e.when.length>0),_=h&&e.appliesTo.length>0&&g&&!a;return(0,Z.jsxs)(`div`,{className:`settings-form`,children:[(0,Z.jsx)(`button`,{className:`btn link`,onClick:s,children:`‹ All rulesets`}),(0,Z.jsx)(`h3`,{children:n?`New ruleset`:e.name}),(0,Z.jsx)(`label`,{className:`field-label`,children:`Name`}),(0,Z.jsx)(`input`,{className:`picker-search`,value:e.name,placeholder:`my-fallback-policy`,disabled:!n,onChange:e=>l({name:e.target.value})}),!n&&(0,Z.jsx)(`p`,{className:`muted small`,children:`The name is the identifier and can't be changed — create a new ruleset to rename.`}),(0,Z.jsx)(`label`,{className:`field-label`,style:{marginTop:8},children:`Applies to`}),(0,Z.jsx)(`div`,{className:`seg-row`,children:rt.map(t=>(0,Z.jsx)(`button`,{type:`button`,className:`selectable`,"aria-pressed":e.appliesTo.includes(t.id),title:t.hint,onClick:()=>d(t.id),children:t.label},t.id))}),(0,Z.jsxs)(`div`,{className:`settings-toggle-row`,style:{marginTop:8},children:[(0,Z.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Z.jsx)(`span`,{className:`settings-toggle-title`,children:`Active on this machine`}),(0,Z.jsx)(`span`,{className:`muted small`,children:m?`Use this ruleset for ${f&&p?`queue runs and interactive sessions`:f?`unattended queue runs`:`interactive sessions`} on this machine. Only one ruleset is active at a time.`:`Add a context above (Work queue or Session) to make this ruleset selectable as active.`})]}),(0,Z.jsx)(mt,{checked:r&&m,disabled:!m,onChange:i,label:`Active on this machine`})]}),(0,Z.jsx)(`label`,{className:`field-label`,style:{marginTop:8},children:`Rules`}),(0,Z.jsx)(`p`,{className:`muted small`,children:`Rules are matched top to bottom; the first rule whose conditions include the failure wins.`}),e.rules.map((t,n)=>(0,Z.jsx)(ut,{index:n,rule:t,onChange:e=>u(n,e),onRemove:()=>l({rules:e.rules.filter((e,t)=>t!==n)})},n)),(0,Z.jsx)(`button`,{className:`btn block`,onClick:()=>l({rules:[...e.rules,{when:[],action:`retry`,maxAttempts:3,backoff:{...it}}]}),children:`+ Add rule`}),(0,Z.jsxs)(`div`,{className:`row-actions`,style:{marginTop:12},children:[(0,Z.jsx)(`button`,{className:`btn primary`,disabled:!_,onClick:c,children:a?`Saving…`:n?`Create ruleset`:`Save changes`}),(0,Z.jsx)(`button`,{className:`btn`,onClick:s,children:`Cancel`})]}),o&&(0,Z.jsx)(`div`,{className:`banner inline`,"data-tone":`danger`,children:o})]})}function ut({index:e,rule:t,onChange:n,onRemove:r}){let i=e=>n({...t,...e}),a=e=>{let n=t.when.includes(e);i({when:n?t.when.filter(t=>t!==e):[...t.when,e]})},o=e=>i({backoff:{...t.backoff??it,...e}}),s=t.action===`retry`||t.action===`reroute`;return(0,Z.jsxs)(`div`,{className:`card ruleset-rule-card`,"data-tone":`muted`,children:[(0,Z.jsxs)(`div`,{className:`ruleset-rule-head`,children:[(0,Z.jsxs)(`span`,{className:`settings-toggle-title`,children:[`Rule `,e+1]}),(0,Z.jsx)(`button`,{className:`btn danger-ghost sm`,onClick:r,children:`Remove`})]}),(0,Z.jsx)(`label`,{className:`field-label`,children:`When any of`}),(0,Z.jsx)(`div`,{className:`ruleset-choice-row`,children:tt.map(e=>(0,Z.jsx)(`button`,{type:`button`,className:`selectable`,title:e.hint,"aria-pressed":t.when.includes(e.id),onClick:()=>a(e.id),children:e.label},e.id))}),t.when.length===0&&(0,Z.jsx)(`p`,{className:`muted small`,children:`Pick at least one condition.`}),(0,Z.jsx)(`label`,{className:`field-label`,children:`Then`}),(0,Z.jsx)(`div`,{className:`seg-row`,children:nt.map(e=>(0,Z.jsx)(`button`,{type:`button`,className:`selectable`,"aria-pressed":t.action===e.id,title:e.hint,onClick:()=>i({action:e.id}),children:e.label},e.id))}),(0,Z.jsx)(`p`,{className:`muted small`,children:nt.find(e=>e.id===t.action)?.hint}),(0,Z.jsxs)(`div`,{className:`ruleset-field-grid`,children:[(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`label`,{className:`field-label`,children:`Max attempts`}),(0,Z.jsx)(`input`,{className:`picker-search`,type:`number`,min:1,max:100,value:t.maxAttempts,onChange:e=>i({maxAttempts:ft(e.target.value,1,100,t.maxAttempts)})})]}),s&&(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`label`,{className:`field-label`,children:`When exhausted`}),(0,Z.jsxs)(`select`,{className:`picker-search`,value:t.onExhausted??`park`,onChange:e=>i({onExhausted:e.target.value}),children:[(0,Z.jsx)(`option`,{value:`park`,children:`Park for a human`}),(0,Z.jsx)(`option`,{value:`give_up`,children:`Give up (fail the run)`})]})]})]}),t.action===`reroute`&&(0,Z.jsx)(dt,{chain:t.chain??[],onChange:e=>i({chain:e})}),s&&(0,Z.jsx)(ht,{label:`Backoff (advanced)`,children:(0,Z.jsxs)(`div`,{className:`ruleset-field-grid`,children:[(0,Z.jsx)(pt,{label:`Base (ms)`,value:t.backoff?.baseMs??it.baseMs,min:0,onChange:e=>o({baseMs:e})}),(0,Z.jsx)(pt,{label:`Factor`,value:t.backoff?.factor??it.factor,min:1,step:.1,onChange:e=>o({factor:e})}),(0,Z.jsx)(pt,{label:`Cap (ms)`,value:t.backoff?.capMs??it.capMs,min:0,onChange:e=>o({capMs:e})}),(0,Z.jsx)(pt,{label:`Jitter (0–1)`,value:t.backoff?.jitter??it.jitter,min:0,max:1,step:.05,onChange:e=>o({jitter:e})})]})})]})}function dt({chain:e,onChange:t}){let n=(n,r)=>t(e.map((e,t)=>t===n?{...e,...r}:e));return(0,Z.jsxs)(`div`,{className:`ruleset-chain`,children:[(0,Z.jsx)(`label`,{className:`field-label`,children:`Fallback chain`}),(0,Z.jsx)(`p`,{className:`muted small`,children:`Tried in order; the first candidate with valid credentials on the machine wins. Leave a field blank to keep the failed run's current value.`}),e.map((r,i)=>(0,Z.jsxs)(`div`,{className:`ruleset-chain-row`,children:[(0,Z.jsxs)(`div`,{className:`ruleset-chain-fields`,children:[(0,Z.jsxs)(`label`,{className:`ruleset-chain-field`,children:[(0,Z.jsx)(`span`,{children:`Model`}),(0,Z.jsx)(`input`,{className:`picker-search`,placeholder:`e.g. claude-sonnet`,value:r.model??``,onChange:e=>n(i,{model:e.target.value})})]}),(0,Z.jsxs)(`label`,{className:`ruleset-chain-field`,children:[(0,Z.jsx)(`span`,{children:`Agent`}),(0,Z.jsx)(`input`,{className:`picker-search`,placeholder:`e.g. codex`,value:r.runtimeId??``,onChange:e=>n(i,{runtimeId:e.target.value})})]}),(0,Z.jsxs)(`label`,{className:`ruleset-chain-field`,children:[(0,Z.jsx)(`span`,{children:`Account`}),(0,Z.jsx)(`input`,{className:`picker-search`,placeholder:`Keep current`,value:r.account??``,onChange:e=>n(i,{account:e.target.value})})]})]}),(0,Z.jsx)(`button`,{className:`btn danger-ghost sm ruleset-chain-remove`,onClick:()=>t(e.filter((e,t)=>t!==i)),"aria-label":`Remove candidate ${i+1}`,children:`Remove`})]},i)),(0,Z.jsx)(`button`,{className:`btn sm`,onClick:()=>t([...e,{}]),children:`+ Add candidate`})]})}function ft(e,t,n,r){let i=Math.round(Number(e));return Number.isFinite(i)?Math.min(n,Math.max(t,i)):r}function pt({label:e,value:t,min:n,max:r,step:i,onChange:a}){return(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`label`,{className:`field-label`,children:e}),(0,Z.jsx)(`input`,{className:`picker-search`,type:`number`,value:t,min:n,max:r,step:i,onChange:e=>{let t=Number(e.target.value);Number.isFinite(t)&&a(t)}})]})}function mt({checked:e,onChange:t,disabled:n,label:r}){return(0,Z.jsx)(`button`,{type:`button`,role:`switch`,"aria-checked":e,"aria-label":r,disabled:n,className:`settings-toggle${e?` on`:``}`,onClick:()=>t(!e),children:(0,Z.jsx)(`span`,{className:`settings-toggle-knob`,"aria-hidden":!0})})}function ht({label:e,children:t}){let[n,r]=(0,H.useState)(!1);return(0,Z.jsxs)(`div`,{className:`ruleset-collapsible`,children:[(0,Z.jsxs)(`button`,{type:`button`,className:`btn link`,onClick:()=>r(e=>!e),"aria-expanded":n,children:[n?`▾`:`▸`,` `,e]}),n&&(0,Z.jsx)(`div`,{className:`ruleset-collapsible-body`,children:t})]})}var gt=[{v:30,label:`30 min`},{v:60,label:`1 hour`},{v:180,label:`3 hours`}];function _t({hosted:e,onConfigureCredentials:t}){let[n,r]=(0,H.useState)([]),[i,a]=(0,H.useState)([]),[o,s]=(0,H.useState)(null),[c,l]=(0,H.useState)([]),[u,d]=(0,H.useState)(!1),[f,p]=(0,H.useState)(null),[h,g]=(0,H.useState)(null),[_,v]=(0,H.useState)(null),y=()=>S.listEphemeralConfigs().then(a).catch(()=>{});(0,H.useEffect)(()=>{S.listNodes().then(r).catch(()=>{}),S.listEphemeralKeys().then(l).catch(()=>{}),S.getQueueRouting().then(s).catch(()=>s(null)),y()},[]);let b=n.filter(e=>!e.id.startsWith(`eph-`)),ee=o?.primary.kind===`node`?`node:${o.primary.node}`:o?.primary.kind===`config`?`config:${o.primary.configId}`:`shared`,te=o?.fallback?.kind===`config`?`config:${o.fallback.configId}`:``,x=o?.primary.kind===`node`,ne=e=>c.find(t=>t.id===e)?.name||e,re=e=>!!c.find(t=>t.id===e)?.configured,ie=async(e,t)=>{p(null),d(!0);try{let n=e.startsWith(`node:`)?{kind:`node`,node:e.slice(5)}:e.startsWith(`config:`)?{kind:`config`,configId:e.slice(7)}:{kind:`shared`},r=n.kind===`node`&&t.startsWith(`config:`)?{primary:n,fallback:{kind:`config`,configId:t.slice(7)}}:{primary:n};s(await S.setQueueRouting(r))}catch(e){p(String(e?.message||e))}finally{d(!1)}},C=async()=>{if(!h)return;let e=h.name.trim();if(!e){p(`Profile name is required`);return}if(!h.provider){p(`Choose a provider`);return}p(null),d(!0);try{let t={name:e,provider:h.provider,region:h.region.trim()||null,size:h.size.trim()||null,ttlMinutes:h.ttlMinutes??null,readyCapacity:T&&h.readyCapacity?1:0,teardownOnAgentFinish:h.teardownOnAgentFinish};h.editing?await S.updateEphemeralConfig(h.editing,t):await S.createEphemeralConfig(t),g(null),y()}catch(e){p(String(e?.message||e))}finally{d(!1)}},T=h?m(h.provider)?.computeClass===`byo-cloud`:!1,ae=async e=>{v(null),d(!0);try{await S.removeEphemeralConfig(e.id),y()}catch(e){p(String(e?.message||e))}finally{d(!1)}},oe=o?.primary.kind===`config`?o.primary.configId:``,se=o?.fallback?.configId??``,ce=oe?i.find(e=>e.id===oe):void 0,le=se?i.find(e=>e.id===se):void 0,E=t=>!!(t&&(t.computeSource===`managed`?e?.execution.ready&&(!e.execution.configId||e.execution.configId===t.id):e?.enabled&&e.validatedProviders.includes(t.provider)&&e.credential!==`none`&&e.encryptionReady)),D=o?.primary.kind===`node`?o.primary.node:``,O=o?.primary.kind===`config`?E(ce):o?.primary.kind===`node`?b.some(e=>(e.name||e.id)===D&&e.online)||E(le):b.some(e=>e.online);return(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`banner routing-status`,"data-tone":O?`ok`:`warn`,role:`status`,children:[(0,Z.jsxs)(`div`,{className:`banner-text routing-status-copy`,children:[(0,Z.jsx)(`strong`,{children:o===null?`Checking run readiness…`:O?`Ready for unattended runs`:`Setup needs attention`}),(0,Z.jsx)(`span`,{children:o===null?`Loading machines, routing, and credential status.`:o.primary.kind===`config`?O?`${ce?.name||`Isolated profile`} can start without an online personal machine.`:`Ephemeral-only runs need hosted provisioning, a validated cloud credential, and GitHub/model sign-ins available to the fresh runner.`:o.primary.kind===`node`?`The selected persistent machine must be online, or have an isolated fallback.`:`The shared queue needs at least one online persistent machine.`})]}),o!==null&&!O&&t&&(0,Z.jsx)(`button`,{type:`button`,className:`btn sm`,onClick:t,children:`Fix setup`})]}),(0,Z.jsxs)(`label`,{className:`field-label`,children:[(0,Z.jsx)(`span`,{children:`Primary machine`}),(0,Z.jsxs)(`select`,{className:`picker-search`,value:ee,disabled:u,onChange:e=>ie(e.target.value,te),children:[(0,Z.jsx)(`option`,{value:`shared`,children:`Shared queue (any online machine)`}),b.length>0&&(0,Z.jsx)(`optgroup`,{label:`Trusted workstations`,children:b.map(e=>(0,Z.jsx)(`option`,{value:`node:${e.name||e.id}`,children:e.name||e.id},e.id))}),i.length>0&&(0,Z.jsx)(`optgroup`,{label:`Cloud machine profiles`,children:i.map(e=>(0,Z.jsxs)(`option`,{value:`config:${e.id}`,children:[e.name,` · `,e.provider]},e.id))})]})]}),x&&(0,Z.jsxs)(`label`,{className:`field-label`,children:[(0,Z.jsx)(`span`,{children:`Fallback if machine is offline`}),(0,Z.jsxs)(`select`,{className:`picker-search`,value:te,disabled:u,onChange:e=>ie(ee,e.target.value),children:[(0,Z.jsx)(`option`,{value:``,children:`None — wait for the machine`}),i.map(e=>(0,Z.jsxs)(`option`,{value:`config:${e.id}`,children:[e.name,` · `,e.provider]},e.id))]})]}),(0,Z.jsx)(`p`,{className:`muted small`,children:x?`Runs wait for this machine; if it's offline and a fallback is set, a fresh isolated machine is provisioned instead.`:o?.primary.kind===`config`?`Every run starts from this isolated profile. Cloud credentials authorize machine creation; GitHub credentials clone and push; model credentials authorize the agent. These sign-ins are separate and secret values are never shown here.`:`Runs are picked up by any online persistent machine. No cloud credential is needed.`}),(0,Z.jsx)(`h4`,{className:`settings-subhead`,children:`Cloud machine profiles`}),h?(0,Z.jsxs)(`div`,{className:`settings-form`,children:[(0,Z.jsxs)(`label`,{className:`field-label`,children:[(0,Z.jsx)(`span`,{children:`Name`}),(0,Z.jsx)(`input`,{className:`picker-search`,value:h.name,placeholder:`e.g. fly-small-iad`,onChange:e=>g({...h,name:e.target.value})})]}),(0,Z.jsxs)(`label`,{className:`field-label`,children:[(0,Z.jsx)(`span`,{children:`Provider`}),(0,Z.jsxs)(`select`,{className:`picker-search`,value:h.provider,onChange:e=>g({...h,provider:e.target.value}),children:[(0,Z.jsx)(`option`,{value:``,disabled:!0,children:`Choose a provider`}),c.map(e=>(0,Z.jsxs)(`option`,{value:e.id,children:[e.name,e.configured?``:` (no token on this device)`]},e.id))]})]}),(0,Z.jsxs)(`label`,{className:`field-label`,children:[(0,Z.jsx)(`span`,{children:`Region (optional)`}),(0,Z.jsx)(`input`,{className:`picker-search`,value:h.region,placeholder:`provider default`,onChange:e=>g({...h,region:e.target.value})})]}),(0,Z.jsxs)(`label`,{className:`field-label`,children:[(0,Z.jsx)(`span`,{children:`Server type (optional)`}),(0,Z.jsx)(`input`,{className:`picker-search`,value:h.size,placeholder:`provider default`,onChange:e=>g({...h,size:e.target.value})})]}),(0,Z.jsxs)(`label`,{className:`field-label`,children:[(0,Z.jsx)(`span`,{children:`Auto-destroy after`}),(0,Z.jsxs)(`select`,{className:`picker-search`,value:h.ttlMinutes??``,onChange:e=>g({...h,ttlMinutes:e.target.value?Number(e.target.value):null}),children:[(0,Z.jsx)(`option`,{value:``,children:`Provider default`}),gt.map(e=>(0,Z.jsx)(`option`,{value:e.v,children:e.label},e.v))]})]}),(0,Z.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Z.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Z.jsx)(`span`,{className:`settings-toggle-title`,children:`Destroy after the agent finishes`}),(0,Z.jsx)(`span`,{className:`muted small`,children:`Tear the machine down on agent_end; the TTL stays a safety fallback.`})]}),(0,Z.jsx)(R,{checked:h.teardownOnAgentFinish,onChange:e=>g({...h,teardownOnAgentFinish:e}),label:`Destroy after the agent finishes`})]}),(0,Z.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,Z.jsxs)(`div`,{className:`settings-toggle-text`,children:[(0,Z.jsx)(`span`,{className:`settings-toggle-title`,children:`Keep one machine ready`}),(0,Z.jsx)(`span`,{className:`muted small`,children:`Starts an account-owned machine before a Run arrives for faster startup. It may incur idle provider charges and remains bounded by the TTL.`})]}),(0,Z.jsx)(R,{checked:h.readyCapacity&&T,disabled:!T,onChange:e=>g({...h,readyCapacity:e}),label:`Keep one machine ready`})]}),!T&&(0,Z.jsx)(`p`,{className:`muted small`,children:`Managed-compute providers use their native fast-start or suspend path instead of Bivy ready capacity.`}),(0,Z.jsxs)(`div`,{className:`row-actions`,children:[(0,Z.jsx)(`button`,{className:`btn primary`,disabled:u||!h.name.trim()||!h.provider,onClick:C,children:u?`Saving…`:h.editing?`Save changes`:`Add profile`}),(0,Z.jsx)(`button`,{className:`btn`,onClick:()=>{p(null),g(null)},children:`Cancel`})]})]}):(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`picker-list`,children:[i.length===0&&(0,Z.jsx)(`div`,{className:`picker-empty`,children:`No cloud machine profiles yet.`}),i.map(e=>(0,Z.jsx)(N,{title:e.name,meta:`${ne(e.provider)}${e.region?` · `+e.region:``}${e.size?` · `+e.size:``}${e.ttlMinutes?` · `+e.ttlMinutes+`m`:``}${e.readyCapacity?` · 1 ready`:``}${re(e.provider)?``:` · no token here`}`,right:(0,Z.jsx)(`button`,{className:`btn danger-ghost sm`,onClick:t=>{t.stopPropagation(),v(e)},children:`Remove`}),onClick:()=>{p(null),g({editing:e.id,name:e.name,provider:e.provider,region:e.region??``,size:e.size??``,ttlMinutes:e.ttlMinutes??null,readyCapacity:!!e.readyCapacity,teardownOnAgentFinish:!!e.teardownOnAgentFinish})}},e.id))]}),(0,Z.jsx)(`button`,{className:`btn primary block`,onClick:()=>{p(null),g({name:``,provider:c[0]?.id??``,region:``,size:``,ttlMinutes:null,readyCapacity:!1,teardownOnAgentFinish:!1})},children:`+ Add profile`})]}),f&&(0,Z.jsx)(w,{tone:`danger`,children:f}),_&&(0,Z.jsx)(ue,{title:`Remove profile?`,message:`Remove ${_.name}? Runs assigned to it will fall back to the shared queue.`,confirmLabel:`Remove`,danger:!0,onCancel:()=>v(null),onConfirm:()=>ae(_)})]})}var vt={requested:`Requesting…`,enrolled:`Enrolling…`,"provider-accepted":`Booting…`,tracked:`Booting…`,ready:`Ready`,claimed:`Claimed`,working:`Working`,deleting:`Tearing down…`,deleted:`Deleted`,failed:`Failed`};function yt(e){return e.desiredState===`deleted`&&e.lifecycleState!==`deleted`?`Tearing down…`:(e.lifecycleState?vt[e.lifecycleState]:void 0)||s({milestones:e.milestones,purpose:e.purpose,claimedAt:e.claimedAt},!!e.lastError)}function bt(e,t){return t||e===`Failed`||e===`teardown-failed`?`err`:e===`Tearing down…`||e===`Requesting…`||e===`Enrolling…`||e===`Booting…`?`warn`:`ok`}function xt(e,t){if(!e)return null;let n=Date.parse(e)-t;if(!Number.isFinite(n))return null;if(n<=0)return`any moment`;let r=Math.round(n/6e4);return r<1?`under a minute`:r<60?`${r}m`:`${Math.round(r/60)}h`}function St(){let[e,t]=(0,H.useState)(null),[n,r]=(0,H.useState)(null),[i,a]=(0,H.useState)(null),[o,s]=(0,H.useState)(null),c=()=>S.listHostedMachines().then(t).catch(()=>t(e=>e??[]));if((0,H.useEffect)(()=>{c();let e=setInterval(c,15e3);return()=>clearInterval(e)},[]),!e||e.length===0)return null;let l=async e=>{r(e),s(null);try{await S.destroyHostedMachine(e)}catch(e){s(String(e.message||e))}finally{r(null),await c()}};return(0,Z.jsxs)(`section`,{className:`autom-section`,children:[(0,Z.jsx)(`h2`,{className:`autom-section-label`,children:`Hosted machines`}),(0,Z.jsx)(`p`,{className:`settings-hint`,children:`Control-plane-launched runners for unattended work — phase, TTL, and teardown status.`}),(0,Z.jsx)(`div`,{className:`picker-list`,children:e.map(e=>{let t=m(e.provider),r=yt(e),i=bt(r,!!e.lastError),o=i===`err`?`danger`:i===`ok`?`ok`:i===`warn`?`warn`:void 0,s=xt(e.deadlineAt,Date.now()),c=!!e.milestones?.snapshotReadyAt,l=e.nodeId||e.id;return(0,Z.jsxs)(`div`,{className:`automation-row`,children:[(0,Z.jsxs)(`div`,{className:`automation-row-main`,children:[(0,Z.jsxs)(`div`,{className:`automation-row-title`,children:[(0,Z.jsx)(`strong`,{children:e.name||t?.name||e.provider}),(0,Z.jsx)(w,{tone:o,children:r})]}),(0,Z.jsx)(`div`,{className:`settings-hint`,children:[t?.name??e.provider,e.region,s?`next deadline ~${s}`:null,c?`snapshot ready`:null].filter(Boolean).join(` · `)}),e.lastError&&(0,Z.jsx)(`div`,{className:`settings-hint warn-text`,children:e.lastError})]}),(0,Z.jsx)(`div`,{className:`automation-row-actions`,children:e.nodeId&&(0,Z.jsx)(`button`,{type:`button`,className:`btn sm danger`,disabled:n===e.nodeId||e.desiredState===`deleted`,onClick:()=>a(e),children:e.desiredState===`deleted`?`Tearing down…`:n===e.nodeId?`…`:`Force destroy`})})]},l)})}),o&&(0,Z.jsx)(`p`,{className:`settings-hint warn-text`,children:o}),i&&(0,Z.jsx)(ue,{title:`Force destroy this machine?`,message:`This immediately asks the provider to delete it. If that request fails, the record stays visible and the reconciler keeps retrying automatically until deletion is confirmed — it never silently disappears while it might still be billing.`,confirmLabel:`Force destroy`,danger:!0,onCancel:()=>a(null),onConfirm:()=>{let e=i.nodeId;a(null),l(e)}})]})}function Ct({sources:e}){let t=e.filter(e=>e.status.tone===`on`),n=e.filter(e=>e.status.tone===`warn`),r=n.length?`${n.length} ${n.length===1?`source needs`:`sources need`} attention`:t.length===e.length?`${t.length} sources connected`:t.length?`${t.map(e=>e.name).join(`, `)} connected · ${e.length-t.length} more`:`Connect GitHub, Linear, and Slack`;return(0,Z.jsxs)(`details`,{className:`autom-sources-panel`,children:[(0,Z.jsxs)(`summary`,{className:`autom-sources-summary`,children:[(0,Z.jsxs)(`span`,{className:`autom-sources-summary-copy`,children:[(0,Z.jsx)(`strong`,{children:`Sources`}),(0,Z.jsx)(`span`,{children:r})]}),(0,Z.jsx)(`span`,{className:`autom-sources-chevron`,children:(0,Z.jsx)(A,{})})]}),(0,Z.jsx)(`div`,{className:`autom-sources-list`,children:e.map(e=>{let t=e.status.tone===`off`?`Connect`:e.status.tone===`warn`?`Fix`:`Manage`;return(0,Z.jsxs)(`button`,{type:`button`,className:`autom-source-row`,onClick:e.onClick,children:[(0,Z.jsxs)(`span`,{className:`autom-source-row-copy`,children:[(0,Z.jsx)(`strong`,{children:e.name}),(0,Z.jsx)(`span`,{children:e.status.label})]}),(0,Z.jsx)(`span`,{className:`autom-source-row-cta`,children:t}),(0,Z.jsx)(A,{size:16})]},e.name)})})]})}function wt(e,t={}){let n=e instanceof Date?e:new Date(e);if(Number.isNaN(n.getTime()))return`Unknown time`;let r=t.now??new Date,i=t.locale,a=new Date(r.getFullYear(),r.getMonth(),r.getDate()),o=new Date(n.getFullYear(),n.getMonth(),n.getDate()),s=Math.round((o.getTime()-a.getTime())/864e5),c=new Intl.DateTimeFormat(i,{hour:`2-digit`,minute:`2-digit`}).format(n);return s===0?`Today at ${c}`:s===1?`Tomorrow at ${c}`:s===-1?`Yesterday at ${c}`:s>1&&s<7?`${new Intl.DateTimeFormat(i,{weekday:`long`}).format(n)} at ${c}`:`${new Intl.DateTimeFormat(i,{day:`numeric`,month:`short`,year:n.getFullYear()===r.getFullYear()?void 0:`numeric`}).format(n)} at ${c}`}function Tt(e,t={}){let n=wt(e,t).replace(/^Today/,`today`).replace(/^Tomorrow/,`tomorrow`);return`Next ${n.startsWith(`today`)?n:n.replace(/ at .+$/,``)}`}function Et(e,t){let[n,r,i,a,o,...s]=e.trim().split(/\s+/);if(s.length||!/^\d+$/.test(n||``)||!/^\d+$/.test(r||``))return null;let c=Number(r),l=Number(n);if(c>23||l>59||a!==`*`)return null;let u=new Intl.DateTimeFormat(t,{hour:`numeric`,minute:`2-digit`}).format(new Date(2020,0,1,c,l));return i===`*`&&o===`*`?`Daily at ${u}`:i===`*`&&/^[0-6]$/.test(o||``)?`Every ${new Intl.DateTimeFormat(t,{weekday:`long`}).format(new Date(2020,0,5+Number(o)))} at ${u}`:/^\d+$/.test(i||``)&&o===`*`?`Monthly on day ${Number(i)} at ${u}`:null}function Dt(e){return e.status===`needs_attention`||e.status===`waiting`?`parked`:e.status===`failed`?`dead_letter`:[`pending`,`claimed`,`running`].includes(e.status)?`active`:`all`}function Ot(e){return!!e.attention||e.status===`needs_attention`||e.status===`failed`||e.notification?.status===`failed`}function kt({runs:e,definitions:t,cancelBusyId:n,onRefresh:r,onCancel:i,onOpenRun:a,onOpenSession:o,compact:s=!1}){let[c,l]=(0,H.useState)(`all`),u=e.filter(Ot).length,d=(0,H.useMemo)(()=>e.filter(e=>c===`all`?!0:c===`attention`?Ot(e):Dt(e)===c),[c,e]),f=t=>t===`all`?e.length:t===`attention`?u:e.filter(e=>Dt(e)===t).length,p=[{id:`all`,label:`All · ${f(`all`)}`},{id:`active`,label:`Active · ${f(`active`)}`},{id:`attention`,label:`Attention · ${u}`},{id:`parked`,label:`Parked · ${f(`parked`)}`},{id:`dead_letter`,label:`Dead letter · ${f(`dead_letter`)}`}];return(0,Z.jsxs)(`section`,{className:`autom-section runs-overview`,children:[(0,Z.jsxs)(`div`,{className:`autom-section-head`,children:[(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`h2`,{className:`autom-section-label`,children:s?`History`:`Recent runs`}),!s&&(0,Z.jsx)(`p`,{className:`settings-hint`,children:`Live status and recent outcomes.`})]}),!s&&(0,Z.jsx)(`div`,{className:`autom-section-actions`,children:(0,Z.jsx)(`button`,{type:`button`,className:`btn sm`,onClick:r,children:`Refresh`})})]}),u>0&&(0,Z.jsx)(`div`,{className:`banner`,"data-tone":`warn`,role:`alert`,children:(0,Z.jsxs)(`div`,{className:`banner-text`,children:[(0,Z.jsxs)(`strong`,{children:[u,` Run`,u===1?``:`s`,` need attention`]}),(0,Z.jsx)(`span`,{children:`Review parked work, failed notification delivery, or terminal failures before retrying.`})]})}),!s&&(0,Z.jsx)(`div`,{className:`run-history-filters`,role:`group`,"aria-label":`Filter Runs`,children:p.map(e=>(0,Z.jsx)(`button`,{type:`button`,className:`btn sm${c===e.id?` primary`:``}`,"aria-pressed":c===e.id,onClick:()=>l(e.id),children:e.label},e.id))}),d.length===0?(0,Z.jsx)(`p`,{className:`settings-hint autom-empty-hint`,children:s?`No runs yet. Run this automation now, or wait for its trigger.`:`No Runs match this filter.`}):(0,Z.jsx)(`div`,{className:`automation-list`,children:d.slice(0,30).map(e=>{let r=$(e),c=le(e),l=r.outcome.tone===`success`?`ok`:r.outcome.tone===`danger`?`danger`:r.outcome.tone===`warning`?`warn`:void 0;if(s&&a)return(0,Z.jsxs)(`button`,{type:`button`,className:`automation-history-row`,onClick:()=>a(e.id),children:[(0,Z.jsxs)(`span`,{className:`automation-history-row-copy`,children:[(0,Z.jsx)(`strong`,{children:e.title}),(0,Z.jsx)(`span`,{className:`settings-hint`,children:wt(e.createdAt)})]}),(0,Z.jsx)(w,{tone:l,children:r.outcome.label}),(0,Z.jsx)(`span`,{"aria-hidden":`true`,children:`›`})]},e.id);let u=t.find(t=>t.id===e.definitionId)?.name,d=(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`automation-row-title`,children:[(0,Z.jsx)(`strong`,{children:e.title}),(0,Z.jsx)(w,{tone:l,children:r.outcome.label}),c.operationalState===`parked`&&(0,Z.jsx)(w,{tone:`warn`,children:`Parked`}),c.operationalState===`dead_letter`&&(0,Z.jsx)(w,{tone:`danger`,children:`Dead letter`})]}),(0,Z.jsx)(`div`,{className:`settings-hint`,children:[s?null:u,wt(e.createdAt),s?null:e.triggerKind,r.checksSummary,s?null:`attempt ${c.attempt}${c.maxAttempts?`/${c.maxAttempts}`:``}`].filter(Boolean).join(` · `)}),c.attemptReason&&(0,Z.jsx)(`div`,{className:`settings-hint`,children:c.attemptReason}),r.failure&&(0,Z.jsx)(`div`,{className:`settings-hint warn-text`,children:r.failure})]});return(0,Z.jsxs)(`div`,{className:`automation-row run-row`,children:[a?(0,Z.jsx)(`button`,{type:`button`,className:`automation-row-main run-row-open`,onClick:()=>a(e.id),children:d}):(0,Z.jsx)(`div`,{className:`automation-row-main`,children:d}),(0,Z.jsxs)(`div`,{className:`automation-row-actions`,children:[c.actions.some(e=>e.kind===`cancel`)&&(0,Z.jsx)(`button`,{type:`button`,className:`btn sm danger`,disabled:n===e.id,onClick:()=>i(e),children:n===e.id?`Cancelling…`:`Cancel`}),c.sessionId&&(0,Z.jsx)(`button`,{type:`button`,className:`btn sm primary`,onClick:()=>o(c.sessionId),children:`Open session`}),e.output?.prUrl&&(0,Z.jsx)(`a`,{className:`btn sm`,href:e.output.prUrl,target:`_blank`,rel:`noreferrer`,children:`View PR`}),a&&(0,Z.jsx)(`button`,{type:`button`,className:`run-row-chevron`,"aria-label":`Open Run details for ${e.title}`,onClick:()=>a(e.id),children:`›`})]})]},e.id)})})]})}function At(e){return e.trigger&&e.trigger!==`schedule`?!0:e.schedule.kind!==`once`}var jt=[{kind:`schedule`,key:`upgrade-dependencies`,title:`Upgrade dependencies`,tagline:`Bump dependencies on a schedule, run the checks, open a PR.`,prefill:{name:`Upgrade dependencies`,instructions:`Update this project's dependencies to safe, current versions.
|
|
3
3
|
|
|
4
4
|
1. Inspect the manifest and lockfile to find what is outdated.
|