@bojackduy/opencode-loopd 1.8.3 → 1.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands/goal.md +3 -2
- package/dist/server.js +705 -172
- package/dist/tui.js +411 -147
- package/package.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -322,13 +322,15 @@ function tokenize(input) {
|
|
|
322
322
|
function commandHelp() {
|
|
323
323
|
return [
|
|
324
324
|
"Modes: : insert \u2192 send/commands | Ctrl+N \u2192 normal | ? toggle help | Shift+B bug report",
|
|
325
|
-
"Nav: j/k move | g/G top/bottom | o open child | c toggle done | p/r/R/x pause/resume/retry/clear | L logs | q close",
|
|
325
|
+
"Nav: j/k move | g/G top/bottom | o open child | c toggle done | p/r/R/x pause/resume/retry/clear | A abort worker | N nudge | L logs | q close",
|
|
326
326
|
"Commands (insert mode, : prefix):",
|
|
327
|
-
" :send <message> Send
|
|
327
|
+
" :send <message> Send bare words now as their own turn (no steering)",
|
|
328
328
|
" :open Open child session (same as o)",
|
|
329
329
|
" :force <summary> --evidence <text> Force-complete (bypass checks)",
|
|
330
330
|
" :block <reason> --needed <text> Force-block the selected goal",
|
|
331
331
|
" :pause / :resume / :retry / :clear Quick controls (also p/r/R/x)",
|
|
332
|
+
" :abort Abort worker session now (status unchanged; A)",
|
|
333
|
+
" :nudge Force re-prompt now with full steering (N)",
|
|
332
334
|
" :bug / :report Open prefilled GitHub bug report",
|
|
333
335
|
" :logs / :help / :q Toggle logs / help / close",
|
|
334
336
|
" Tip: create goals via /goal in the parent chat (agent clarifies first)."
|
|
@@ -427,6 +429,29 @@ function prevent(evt) {
|
|
|
427
429
|
e.preventDefault?.();
|
|
428
430
|
e.stopPropagation?.();
|
|
429
431
|
}
|
|
432
|
+
function keyName(evt) {
|
|
433
|
+
return (evt.name || "").toLowerCase();
|
|
434
|
+
}
|
|
435
|
+
function keySeq(evt) {
|
|
436
|
+
const e = evt;
|
|
437
|
+
return e.sequence || e.raw || "";
|
|
438
|
+
}
|
|
439
|
+
function isEnterKey(evt) {
|
|
440
|
+
const name = keyName(evt);
|
|
441
|
+
if (name === "return" || name === "enter" || name === "kp_enter")
|
|
442
|
+
return true;
|
|
443
|
+
const seq = keySeq(evt);
|
|
444
|
+
return seq === "\r" || seq === `
|
|
445
|
+
`;
|
|
446
|
+
}
|
|
447
|
+
function isEscapeKey(evt) {
|
|
448
|
+
if (keyName(evt) === "escape" || keyName(evt) === "esc")
|
|
449
|
+
return true;
|
|
450
|
+
return keySeq(evt) === "\x1B";
|
|
451
|
+
}
|
|
452
|
+
function isCtrlN(evt) {
|
|
453
|
+
return Boolean(evt.ctrl) && keyName(evt) === "n";
|
|
454
|
+
}
|
|
430
455
|
function statusColor(status, theme) {
|
|
431
456
|
switch (status) {
|
|
432
457
|
case "active":
|
|
@@ -543,6 +568,66 @@ function countdownLabel(targetIso, now) {
|
|
|
543
568
|
return `${minutes}m ${diff % 60}s`;
|
|
544
569
|
return `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
|
|
545
570
|
}
|
|
571
|
+
function formatTokens(n) {
|
|
572
|
+
if (!n)
|
|
573
|
+
return "0";
|
|
574
|
+
if (n < 1000)
|
|
575
|
+
return String(Math.round(n));
|
|
576
|
+
if (n < 1e6)
|
|
577
|
+
return `${(n / 1000).toFixed(1)}k`;
|
|
578
|
+
return `${(n / 1e6).toFixed(2)}M`;
|
|
579
|
+
}
|
|
580
|
+
function formatCost(c) {
|
|
581
|
+
if (!c)
|
|
582
|
+
return "$0.00";
|
|
583
|
+
if (c < 0.01)
|
|
584
|
+
return `$${c.toFixed(4)}`;
|
|
585
|
+
return `$${c.toFixed(2)}`;
|
|
586
|
+
}
|
|
587
|
+
function formatDuration(seconds) {
|
|
588
|
+
if (!seconds || seconds <= 0)
|
|
589
|
+
return "0s";
|
|
590
|
+
if (seconds < 60)
|
|
591
|
+
return `${Math.round(seconds)}s`;
|
|
592
|
+
const minutes = Math.floor(seconds / 60);
|
|
593
|
+
if (minutes < 60)
|
|
594
|
+
return `${minutes}m`;
|
|
595
|
+
return `${(seconds / 3600).toFixed(1)}h`;
|
|
596
|
+
}
|
|
597
|
+
function agentColor(color, theme) {
|
|
598
|
+
if (!color)
|
|
599
|
+
return theme.text;
|
|
600
|
+
const named = {
|
|
601
|
+
primary: theme.primary,
|
|
602
|
+
secondary: theme.secondary,
|
|
603
|
+
accent: theme.accent,
|
|
604
|
+
success: theme.success,
|
|
605
|
+
warning: theme.warning,
|
|
606
|
+
error: theme.error,
|
|
607
|
+
info: theme.info
|
|
608
|
+
};
|
|
609
|
+
if (named[color])
|
|
610
|
+
return named[color];
|
|
611
|
+
if (/^#[0-9a-fA-F]{3,8}$/.test(color))
|
|
612
|
+
return color;
|
|
613
|
+
return theme.text;
|
|
614
|
+
}
|
|
615
|
+
function indexAgents(list) {
|
|
616
|
+
const map = {};
|
|
617
|
+
for (const a of list) {
|
|
618
|
+
if (!a?.name)
|
|
619
|
+
continue;
|
|
620
|
+
map[a.name] = {
|
|
621
|
+
color: a.color,
|
|
622
|
+
mode: a.mode
|
|
623
|
+
};
|
|
624
|
+
map[a.name.toLowerCase()] = {
|
|
625
|
+
color: a.color,
|
|
626
|
+
mode: a.mode
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
return map;
|
|
630
|
+
}
|
|
546
631
|
function LoopDashboard(props) {
|
|
547
632
|
const theme = () => props.api.theme.current;
|
|
548
633
|
const [mode, setMode] = createSignal("normal");
|
|
@@ -556,6 +641,7 @@ function LoopDashboard(props) {
|
|
|
556
641
|
const [showHelp, setShowHelp] = createSignal(false);
|
|
557
642
|
const [showCompleted, setShowCompleted] = createSignal(false);
|
|
558
643
|
const [clock, setClock] = createSignal(Date.now());
|
|
644
|
+
const [agentIndex, setAgentIndex] = createSignal({});
|
|
559
645
|
let inputEl;
|
|
560
646
|
let focusTimer;
|
|
561
647
|
const client = createControlClient(props.directory);
|
|
@@ -584,6 +670,15 @@ function LoopDashboard(props) {
|
|
|
584
670
|
}
|
|
585
671
|
}
|
|
586
672
|
refresh();
|
|
673
|
+
async function refreshAgents() {
|
|
674
|
+
try {
|
|
675
|
+
const res = await props.api.client?.app?.agents?.();
|
|
676
|
+
const list = res?.data ?? res ?? [];
|
|
677
|
+
if (Array.isArray(list))
|
|
678
|
+
setAgentIndex(indexAgents(list));
|
|
679
|
+
} catch {}
|
|
680
|
+
}
|
|
681
|
+
refreshAgents();
|
|
587
682
|
const unsubs = [props.api.event.on("session.idle", () => refresh()), props.api.event.on("session.status", () => refresh()), props.api.event.on("session.error", () => refresh()), props.api.event.on("session.compacted", () => refresh()), setInterval(refresh, 1e4), setInterval(() => setClock(Date.now()), 500)];
|
|
588
683
|
onCleanup(() => {
|
|
589
684
|
popMode();
|
|
@@ -595,9 +690,9 @@ function LoopDashboard(props) {
|
|
|
595
690
|
onMount(() => {
|
|
596
691
|
try {
|
|
597
692
|
const {
|
|
598
|
-
|
|
693
|
+
appendFileSync
|
|
599
694
|
} = __require("fs");
|
|
600
|
-
|
|
695
|
+
appendFileSync(LOG_FILE, `[${new Date().toISOString()}] dashboard mounted dir=${props.directory} mode=${mode()} dialogOpen=${props.api.ui.dialog.open}
|
|
601
696
|
`);
|
|
602
697
|
} catch {}
|
|
603
698
|
debugLog("mounted", "dialogOpen", props.api.ui.dialog.open, "directory", props.directory);
|
|
@@ -633,10 +728,17 @@ function LoopDashboard(props) {
|
|
|
633
728
|
const isQuestion = name === "?" || seq === "?" || raw === "?" || seq.includes("?") || raw.includes("?");
|
|
634
729
|
debugLog("isColon", isColon, "isQuestion", isQuestion, "modeBefore", mode());
|
|
635
730
|
if (mode() === "insert") {
|
|
636
|
-
if (evt
|
|
731
|
+
if (isEnterKey(evt)) {
|
|
732
|
+
prevent(evt);
|
|
733
|
+
debugLog("insert enter -> execute");
|
|
734
|
+
executeCommand(commandInput());
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
if (isEscapeKey(evt) || isCtrlN(evt)) {
|
|
637
738
|
prevent(evt);
|
|
638
739
|
returnToNormalMode();
|
|
639
|
-
debugLog("insert -> normal via ctrl+n");
|
|
740
|
+
debugLog("insert -> normal via esc/ctrl+n");
|
|
741
|
+
return;
|
|
640
742
|
}
|
|
641
743
|
return;
|
|
642
744
|
}
|
|
@@ -700,6 +802,16 @@ function LoopDashboard(props) {
|
|
|
700
802
|
executeCommand("clear");
|
|
701
803
|
return;
|
|
702
804
|
}
|
|
805
|
+
if (key === "A") {
|
|
806
|
+
prevent(evt);
|
|
807
|
+
executeCommand("abort");
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
if (key === "N") {
|
|
811
|
+
prevent(evt);
|
|
812
|
+
executeCommand("nudge");
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
703
815
|
if (key === "L") {
|
|
704
816
|
prevent(evt);
|
|
705
817
|
setShowLogs((value) => !value);
|
|
@@ -737,6 +849,9 @@ function LoopDashboard(props) {
|
|
|
737
849
|
debugLog("empty command");
|
|
738
850
|
return;
|
|
739
851
|
}
|
|
852
|
+
if (!["help", "logs", "q", "close"].includes(parsed.command)) {
|
|
853
|
+
setStatusText(`sending ${parsed.command}\u2026`);
|
|
854
|
+
}
|
|
740
855
|
try {
|
|
741
856
|
switch (parsed.command) {
|
|
742
857
|
case "send": {
|
|
@@ -890,6 +1005,40 @@ function LoopDashboard(props) {
|
|
|
890
1005
|
await refresh();
|
|
891
1006
|
break;
|
|
892
1007
|
}
|
|
1008
|
+
case "abort": {
|
|
1009
|
+
if (!selectedGoal()) {
|
|
1010
|
+
setStatusText("No goal");
|
|
1011
|
+
break;
|
|
1012
|
+
}
|
|
1013
|
+
const r = await client.execute({
|
|
1014
|
+
version: 1,
|
|
1015
|
+
requestID: randomUUID(),
|
|
1016
|
+
requestedAt: new Date().toISOString(),
|
|
1017
|
+
command: "abort_worker",
|
|
1018
|
+
goalID: selectedGoal().id
|
|
1019
|
+
});
|
|
1020
|
+
setStatusText(r.ok ? r.message : `Error: ${r.message}`);
|
|
1021
|
+
if (r.ok)
|
|
1022
|
+
await refresh();
|
|
1023
|
+
break;
|
|
1024
|
+
}
|
|
1025
|
+
case "nudge": {
|
|
1026
|
+
if (!selectedGoal()) {
|
|
1027
|
+
setStatusText("No goal");
|
|
1028
|
+
break;
|
|
1029
|
+
}
|
|
1030
|
+
const r = await client.execute({
|
|
1031
|
+
version: 1,
|
|
1032
|
+
requestID: randomUUID(),
|
|
1033
|
+
requestedAt: new Date().toISOString(),
|
|
1034
|
+
command: "nudge",
|
|
1035
|
+
goalID: selectedGoal().id
|
|
1036
|
+
});
|
|
1037
|
+
setStatusText(r.ok ? r.message : `Error: ${r.message}`);
|
|
1038
|
+
if (r.ok)
|
|
1039
|
+
await refresh();
|
|
1040
|
+
break;
|
|
1041
|
+
}
|
|
893
1042
|
case "goal": {
|
|
894
1043
|
setStatusText("Create goals via /goal in the parent chat (agent clarifies first). Dashboard: :send to steer the worker.");
|
|
895
1044
|
break;
|
|
@@ -1041,7 +1190,7 @@ function LoopDashboard(props) {
|
|
|
1041
1190
|
_$setProp(_el$32, "maxHeight", 14);
|
|
1042
1191
|
_$setProp(_el$32, "overflow", "hidden");
|
|
1043
1192
|
_$insertNode(_el$33, _el$34);
|
|
1044
|
-
_$insertNode(_el$34, _$createTextNode(`\u2501\u2501\u2501 Keys: ? toggle help c toggle done : insert Ctrl+N normal o open
|
|
1193
|
+
_$insertNode(_el$34, _$createTextNode(`\u2501\u2501\u2501 Keys: ? toggle help c toggle done : insert Ctrl+N normal o open A abort worker N nudge q close \u2501\u2501\u2501`));
|
|
1045
1194
|
_$setProp(_el$34, "style", {
|
|
1046
1195
|
fg: "yellow",
|
|
1047
1196
|
bold: true
|
|
@@ -1484,7 +1633,7 @@ function LoopDashboard(props) {
|
|
|
1484
1633
|
_$setProp(_el$121, "border", true);
|
|
1485
1634
|
_$setProp(_el$121, "padding", 1);
|
|
1486
1635
|
_$setProp(_el$121, "flexShrink", 0);
|
|
1487
|
-
_$setProp(_el$121, "maxHeight",
|
|
1636
|
+
_$setProp(_el$121, "maxHeight", 13);
|
|
1488
1637
|
_$insertNode(_el$122, _el$123);
|
|
1489
1638
|
_$insertNode(_el$122, _el$125);
|
|
1490
1639
|
_$insertNode(_el$122, _el$127);
|
|
@@ -1526,212 +1675,339 @@ function LoopDashboard(props) {
|
|
|
1526
1675
|
return _el$133;
|
|
1527
1676
|
})()];
|
|
1528
1677
|
})(), _el$127);
|
|
1529
|
-
_$insert(_el$128, () => goal().objective.slice(0, 160));
|
|
1530
1678
|
_$insert(_el$122, (() => {
|
|
1531
|
-
var _c$11 = _$memo(() => !!
|
|
1679
|
+
var _c$11 = _$memo(() => !!rt()?.workerAbortedAt);
|
|
1532
1680
|
return () => _c$11() && [(() => {
|
|
1533
|
-
var _el$137 = _$createElement("span")
|
|
1534
|
-
\
|
|
1535
|
-
_$insertNode(_el$137, _el$138);
|
|
1681
|
+
var _el$137 = _$createElement("span");
|
|
1682
|
+
_$insertNode(_el$137, _$createTextNode(` \u2502 \u26A0 worker aborted `));
|
|
1536
1683
|
_$effect((_$p) => _$setProp(_el$137, "style", {
|
|
1537
|
-
fg: theme().
|
|
1684
|
+
fg: theme().warning,
|
|
1685
|
+
bold: true
|
|
1538
1686
|
}, _$p));
|
|
1539
1687
|
return _el$137;
|
|
1540
1688
|
})(), (() => {
|
|
1541
|
-
var _el$
|
|
1542
|
-
_$
|
|
1543
|
-
_$
|
|
1544
|
-
|
|
1689
|
+
var _el$139 = _$createElement("span"), _el$140 = _$createTextNode(` \u2014 session kept, next turn reuses it`);
|
|
1690
|
+
_$insertNode(_el$139, _el$140);
|
|
1691
|
+
_$insert(_el$139, () => ageLabel(rt().workerAbortedAt, clock()), _el$140);
|
|
1692
|
+
_$effect((_$p) => _$setProp(_el$139, "style", {
|
|
1693
|
+
fg: theme().textMuted
|
|
1545
1694
|
}, _$p));
|
|
1546
|
-
return _el$
|
|
1547
|
-
})()
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1695
|
+
return _el$139;
|
|
1696
|
+
})()];
|
|
1697
|
+
})(), _el$127);
|
|
1698
|
+
_$insert(_el$122, () => {
|
|
1699
|
+
const agentName = goal().config.agent;
|
|
1700
|
+
const meta = agentName ? agentIndex()[agentName] ?? agentIndex()[agentName.toLowerCase()] : undefined;
|
|
1701
|
+
const model = goal().config.model;
|
|
1702
|
+
const slash = model?.indexOf("/") ?? -1;
|
|
1703
|
+
return [`
|
|
1704
|
+
`, (() => {
|
|
1705
|
+
var _el$141 = _$createElement("span");
|
|
1706
|
+
_$insertNode(_el$141, _$createTextNode(`\uD83E\uDD16 `));
|
|
1551
1707
|
_$effect((_$p) => _$setProp(_el$141, "style", {
|
|
1552
1708
|
fg: theme().textMuted
|
|
1553
1709
|
}, _$p));
|
|
1554
1710
|
return _el$141;
|
|
1711
|
+
})(), agentName ? [(() => {
|
|
1712
|
+
var _el$153 = _$createElement("span");
|
|
1713
|
+
_$insert(_el$153, agentName);
|
|
1714
|
+
_$effect((_$p) => _$setProp(_el$153, "style", {
|
|
1715
|
+
fg: agentColor(meta?.color, theme()),
|
|
1716
|
+
bold: true
|
|
1717
|
+
}, _$p));
|
|
1718
|
+
return _el$153;
|
|
1719
|
+
})(), _$memo(() => _$memo(() => !!meta?.mode)() && (() => {
|
|
1720
|
+
var _el$154 = _$createElement("span"), _el$155 = _$createTextNode(` (`), _el$156 = _$createTextNode(`)`);
|
|
1721
|
+
_$insertNode(_el$154, _el$155);
|
|
1722
|
+
_$insertNode(_el$154, _el$156);
|
|
1723
|
+
_$insert(_el$154, () => meta.mode, _el$156);
|
|
1724
|
+
_$effect((_$p) => _$setProp(_el$154, "style", {
|
|
1725
|
+
fg: theme().textMuted
|
|
1726
|
+
}, _$p));
|
|
1727
|
+
return _el$154;
|
|
1728
|
+
})())] : (() => {
|
|
1729
|
+
var _el$157 = _$createElement("span");
|
|
1730
|
+
_$insertNode(_el$157, _$createTextNode(`parent default`));
|
|
1731
|
+
_$effect((_$p) => _$setProp(_el$157, "style", {
|
|
1732
|
+
fg: theme().textMuted
|
|
1733
|
+
}, _$p));
|
|
1734
|
+
return _el$157;
|
|
1735
|
+
})(), (() => {
|
|
1736
|
+
var _el$143 = _$createElement("span");
|
|
1737
|
+
_$insertNode(_el$143, _$createTextNode(` \u2502 \uD83E\uDDE0 `));
|
|
1738
|
+
_$effect((_$p) => _$setProp(_el$143, "style", {
|
|
1739
|
+
fg: theme().textMuted
|
|
1740
|
+
}, _$p));
|
|
1741
|
+
return _el$143;
|
|
1742
|
+
})(), model && slash > 0 ? [(() => {
|
|
1743
|
+
var _el$159 = _$createElement("span"), _el$160 = _$createTextNode(`/`);
|
|
1744
|
+
_$insertNode(_el$159, _el$160);
|
|
1745
|
+
_$insert(_el$159, () => model.slice(0, slash), _el$160);
|
|
1746
|
+
_$effect((_$p) => _$setProp(_el$159, "style", {
|
|
1747
|
+
fg: theme().textMuted
|
|
1748
|
+
}, _$p));
|
|
1749
|
+
return _el$159;
|
|
1750
|
+
})(), (() => {
|
|
1751
|
+
var _el$161 = _$createElement("span");
|
|
1752
|
+
_$insert(_el$161, () => model.slice(slash + 1));
|
|
1753
|
+
_$effect((_$p) => _$setProp(_el$161, "style", {
|
|
1754
|
+
fg: theme().info,
|
|
1755
|
+
bold: true
|
|
1756
|
+
}, _$p));
|
|
1757
|
+
return _el$161;
|
|
1758
|
+
})()] : (() => {
|
|
1759
|
+
var _el$162 = _$createElement("span");
|
|
1760
|
+
_$insertNode(_el$162, _$createTextNode(`session default`));
|
|
1761
|
+
_$effect((_$p) => _$setProp(_el$162, "style", {
|
|
1762
|
+
fg: theme().textMuted
|
|
1763
|
+
}, _$p));
|
|
1764
|
+
return _el$162;
|
|
1765
|
+
})(), (() => {
|
|
1766
|
+
var _el$145 = _$createElement("span");
|
|
1767
|
+
_$insertNode(_el$145, _$createTextNode(` \u2502 \uD83D\uDCB0 `));
|
|
1768
|
+
_$effect((_$p) => _$setProp(_el$145, "style", {
|
|
1769
|
+
fg: theme().textMuted
|
|
1770
|
+
}, _$p));
|
|
1771
|
+
return _el$145;
|
|
1772
|
+
})(), (() => {
|
|
1773
|
+
var _el$147 = _$createElement("span");
|
|
1774
|
+
_$insert(_el$147, () => formatTokens(goal().tokensUsed));
|
|
1775
|
+
_$effect((_$p) => _$setProp(_el$147, "style", {
|
|
1776
|
+
fg: theme().warning,
|
|
1777
|
+
bold: true
|
|
1778
|
+
}, _$p));
|
|
1779
|
+
return _el$147;
|
|
1780
|
+
})(), (() => {
|
|
1781
|
+
var _el$148 = _$createElement("span");
|
|
1782
|
+
_$insertNode(_el$148, _$createTextNode(` tokens \xB7 `));
|
|
1783
|
+
_$effect((_$p) => _$setProp(_el$148, "style", {
|
|
1784
|
+
fg: theme().textMuted
|
|
1785
|
+
}, _$p));
|
|
1786
|
+
return _el$148;
|
|
1787
|
+
})(), (() => {
|
|
1788
|
+
var _el$150 = _$createElement("span");
|
|
1789
|
+
_$insert(_el$150, () => formatCost(goal().costUsed));
|
|
1790
|
+
_$effect((_$p) => _$setProp(_el$150, "style", {
|
|
1791
|
+
fg: theme().success,
|
|
1792
|
+
bold: true
|
|
1793
|
+
}, _$p));
|
|
1794
|
+
return _el$150;
|
|
1795
|
+
})(), (() => {
|
|
1796
|
+
var _el$151 = _$createElement("span"), _el$152 = _$createTextNode(` \xB7 `);
|
|
1797
|
+
_$insertNode(_el$151, _el$152);
|
|
1798
|
+
_$insert(_el$151, () => formatDuration(goal().timeUsedSeconds), null);
|
|
1799
|
+
_$effect((_$p) => _$setProp(_el$151, "style", {
|
|
1800
|
+
fg: theme().textMuted
|
|
1801
|
+
}, _$p));
|
|
1802
|
+
return _el$151;
|
|
1555
1803
|
})()];
|
|
1556
|
-
}
|
|
1804
|
+
}, _el$127);
|
|
1805
|
+
_$insert(_el$128, () => goal().objective.slice(0, 160));
|
|
1557
1806
|
_$insert(_el$122, (() => {
|
|
1558
|
-
var _c$12 = _$memo(() => !!
|
|
1807
|
+
var _c$12 = _$memo(() => !!lp());
|
|
1559
1808
|
return () => _c$12() && [(() => {
|
|
1560
|
-
var _el$
|
|
1809
|
+
var _el$164 = _$createElement("span"), _el$165 = _$createTextNode(`
|
|
1810
|
+
\u2714 `);
|
|
1811
|
+
_$insertNode(_el$164, _el$165);
|
|
1812
|
+
_$effect((_$p) => _$setProp(_el$164, "style", {
|
|
1813
|
+
fg: theme().success
|
|
1814
|
+
}, _$p));
|
|
1815
|
+
return _el$164;
|
|
1816
|
+
})(), (() => {
|
|
1817
|
+
var _el$167 = _$createElement("span");
|
|
1818
|
+
_$insert(_el$167, () => lp().summary.slice(0, 100));
|
|
1819
|
+
_$effect((_$p) => _$setProp(_el$167, "style", {
|
|
1820
|
+
fg: theme().text
|
|
1821
|
+
}, _$p));
|
|
1822
|
+
return _el$167;
|
|
1823
|
+
})(), (() => {
|
|
1824
|
+
var _el$168 = _$createElement("span"), _el$169 = _$createTextNode(` \u2192 `);
|
|
1825
|
+
_$insertNode(_el$168, _el$169);
|
|
1826
|
+
_$insert(_el$168, () => lp().next?.slice(0, 60) || "", null);
|
|
1827
|
+
_$effect((_$p) => _$setProp(_el$168, "style", {
|
|
1828
|
+
fg: theme().textMuted
|
|
1829
|
+
}, _$p));
|
|
1830
|
+
return _el$168;
|
|
1831
|
+
})()];
|
|
1832
|
+
})(), null);
|
|
1833
|
+
_$insert(_el$122, (() => {
|
|
1834
|
+
var _c$13 = _$memo(() => !!blk());
|
|
1835
|
+
return () => _c$13() && [(() => {
|
|
1836
|
+
var _el$170 = _$createElement("span"), _el$171 = _$createTextNode(`
|
|
1561
1837
|
\u2716 blocked: `);
|
|
1562
|
-
_$insertNode(_el$
|
|
1563
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1838
|
+
_$insertNode(_el$170, _el$171);
|
|
1839
|
+
_$effect((_$p) => _$setProp(_el$170, "style", {
|
|
1564
1840
|
fg: theme().error,
|
|
1565
1841
|
bold: true
|
|
1566
1842
|
}, _$p));
|
|
1567
|
-
return _el$
|
|
1843
|
+
return _el$170;
|
|
1568
1844
|
})(), (() => {
|
|
1569
|
-
var _el$
|
|
1570
|
-
_$insert(_el$
|
|
1571
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1845
|
+
var _el$173 = _$createElement("span");
|
|
1846
|
+
_$insert(_el$173, () => blk().reason.slice(0, 140));
|
|
1847
|
+
_$effect((_$p) => _$setProp(_el$173, "style", {
|
|
1572
1848
|
fg: theme().error
|
|
1573
1849
|
}, _$p));
|
|
1574
|
-
return _el$
|
|
1850
|
+
return _el$173;
|
|
1575
1851
|
})(), (() => {
|
|
1576
|
-
var _el$
|
|
1577
|
-
_$insertNode(_el$
|
|
1578
|
-
_$insert(_el$
|
|
1579
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1852
|
+
var _el$174 = _$createElement("span"), _el$175 = _$createTextNode(` \u2014 `);
|
|
1853
|
+
_$insertNode(_el$174, _el$175);
|
|
1854
|
+
_$insert(_el$174, () => blk().needed.slice(0, 60), null);
|
|
1855
|
+
_$effect((_$p) => _$setProp(_el$174, "style", {
|
|
1580
1856
|
fg: theme().textMuted
|
|
1581
1857
|
}, _$p));
|
|
1582
|
-
return _el$
|
|
1858
|
+
return _el$174;
|
|
1583
1859
|
})()];
|
|
1584
1860
|
})(), null);
|
|
1585
1861
|
_$insert(_el$122, (() => {
|
|
1586
|
-
var _c$
|
|
1587
|
-
return () => _c$
|
|
1588
|
-
var _el$
|
|
1862
|
+
var _c$14 = _$memo(() => !!goal().config.artifactDir);
|
|
1863
|
+
return () => _c$14() && [(() => {
|
|
1864
|
+
var _el$176 = _$createElement("span"), _el$177 = _$createTextNode(`
|
|
1589
1865
|
\uD83D\uDCC1 `);
|
|
1590
|
-
_$insertNode(_el$
|
|
1591
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1866
|
+
_$insertNode(_el$176, _el$177);
|
|
1867
|
+
_$effect((_$p) => _$setProp(_el$176, "style", {
|
|
1592
1868
|
fg: theme().accent
|
|
1593
1869
|
}, _$p));
|
|
1594
|
-
return _el$
|
|
1870
|
+
return _el$176;
|
|
1595
1871
|
})(), (() => {
|
|
1596
|
-
var _el$
|
|
1597
|
-
_$insert(_el$
|
|
1598
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1872
|
+
var _el$179 = _$createElement("span");
|
|
1873
|
+
_$insert(_el$179, () => String(goal().config.artifactDir).replace(String(props.directory), "."));
|
|
1874
|
+
_$effect((_$p) => _$setProp(_el$179, "style", {
|
|
1599
1875
|
fg: theme().textMuted
|
|
1600
1876
|
}, _$p));
|
|
1601
|
-
return _el$
|
|
1877
|
+
return _el$179;
|
|
1602
1878
|
})()];
|
|
1603
1879
|
})(), null);
|
|
1604
1880
|
_$insert(_el$122, (() => {
|
|
1605
|
-
var _c$
|
|
1606
|
-
return () => _c$
|
|
1607
|
-
var _el$
|
|
1881
|
+
var _c$15 = _$memo(() => (goal().config.checks?.length ?? 0) > 0);
|
|
1882
|
+
return () => _c$15() ? [(() => {
|
|
1883
|
+
var _el$180 = _$createElement("span"), _el$181 = _$createTextNode(`
|
|
1608
1884
|
\u25A3 checks: `);
|
|
1609
|
-
_$insertNode(_el$
|
|
1610
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1885
|
+
_$insertNode(_el$180, _el$181);
|
|
1886
|
+
_$effect((_$p) => _$setProp(_el$180, "style", {
|
|
1611
1887
|
fg: theme().warning
|
|
1612
1888
|
}, _$p));
|
|
1613
|
-
return _el$
|
|
1889
|
+
return _el$180;
|
|
1614
1890
|
})(), (() => {
|
|
1615
|
-
var _el$
|
|
1616
|
-
_$insert(_el$
|
|
1617
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1891
|
+
var _el$183 = _$createElement("span");
|
|
1892
|
+
_$insert(_el$183, () => goal().config.checks.join(", ").slice(0, 100));
|
|
1893
|
+
_$effect((_$p) => _$setProp(_el$183, "style", {
|
|
1618
1894
|
fg: theme().textMuted
|
|
1619
1895
|
}, _$p));
|
|
1620
|
-
return _el$
|
|
1896
|
+
return _el$183;
|
|
1621
1897
|
})()] : null;
|
|
1622
1898
|
})(), null);
|
|
1623
1899
|
_$insert(_el$122, (() => {
|
|
1624
|
-
var _c$
|
|
1625
|
-
return () => _c$
|
|
1626
|
-
var _el$
|
|
1900
|
+
var _c$16 = _$memo(() => rt()?.evaluatorRejectionCount > 0);
|
|
1901
|
+
return () => _c$16() && [(() => {
|
|
1902
|
+
var _el$184 = _$createElement("span"), _el$185 = _$createTextNode(`
|
|
1627
1903
|
\u26A0 rejections: `);
|
|
1628
|
-
_$insertNode(_el$
|
|
1629
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1904
|
+
_$insertNode(_el$184, _el$185);
|
|
1905
|
+
_$effect((_$p) => _$setProp(_el$184, "style", {
|
|
1630
1906
|
fg: theme().warning
|
|
1631
1907
|
}, _$p));
|
|
1632
|
-
return _el$
|
|
1908
|
+
return _el$184;
|
|
1633
1909
|
})(), (() => {
|
|
1634
|
-
var _el$
|
|
1635
|
-
_$insertNode(_el$
|
|
1636
|
-
_$insert(_el$
|
|
1637
|
-
_$insert(_el$
|
|
1638
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1910
|
+
var _el$187 = _$createElement("span"), _el$188 = _$createTextNode(` \u2014 `);
|
|
1911
|
+
_$insertNode(_el$187, _el$188);
|
|
1912
|
+
_$insert(_el$187, () => String(rt().evaluatorRejectionCount), _el$188);
|
|
1913
|
+
_$insert(_el$187, () => String(rt().lastRejectionDetails || "").slice(0, 80), null);
|
|
1914
|
+
_$effect((_$p) => _$setProp(_el$187, "style", {
|
|
1639
1915
|
fg: theme().warning
|
|
1640
1916
|
}, _$p));
|
|
1641
|
-
return _el$
|
|
1917
|
+
return _el$187;
|
|
1642
1918
|
})()];
|
|
1643
1919
|
})(), null);
|
|
1644
1920
|
_$insert(_el$122, (() => {
|
|
1645
|
-
var _c$
|
|
1646
|
-
return () => _c$
|
|
1647
|
-
var _el$
|
|
1921
|
+
var _c$17 = _$memo(() => rt()?.unknownStatusCount > 0);
|
|
1922
|
+
return () => _c$17() && [(() => {
|
|
1923
|
+
var _el$189 = _$createElement("span"), _el$190 = _$createTextNode(`
|
|
1648
1924
|
\u26A0\uFE0F unreachable: `);
|
|
1649
|
-
_$insertNode(_el$
|
|
1650
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1925
|
+
_$insertNode(_el$189, _el$190);
|
|
1926
|
+
_$effect((_$p) => _$setProp(_el$189, "style", {
|
|
1651
1927
|
fg: theme().error
|
|
1652
1928
|
}, _$p));
|
|
1653
|
-
return _el$
|
|
1929
|
+
return _el$189;
|
|
1654
1930
|
})(), (() => {
|
|
1655
|
-
var _el$
|
|
1656
|
-
_$insertNode(_el$
|
|
1657
|
-
_$insert(_el$
|
|
1658
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1931
|
+
var _el$192 = _$createElement("span"), _el$193 = _$createTextNode(`/3`);
|
|
1932
|
+
_$insertNode(_el$192, _el$193);
|
|
1933
|
+
_$insert(_el$192, () => String(rt().unknownStatusCount), _el$193);
|
|
1934
|
+
_$effect((_$p) => _$setProp(_el$192, "style", {
|
|
1659
1935
|
fg: theme().error
|
|
1660
1936
|
}, _$p));
|
|
1661
|
-
return _el$
|
|
1937
|
+
return _el$192;
|
|
1662
1938
|
})(), (() => {
|
|
1663
|
-
var _el$
|
|
1664
|
-
_$insertNode(_el$
|
|
1665
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1939
|
+
var _el$194 = _$createElement("span");
|
|
1940
|
+
_$insertNode(_el$194, _$createTextNode(` \u2014 nudge to recover`));
|
|
1941
|
+
_$effect((_$p) => _$setProp(_el$194, "style", {
|
|
1666
1942
|
fg: theme().textMuted
|
|
1667
1943
|
}, _$p));
|
|
1668
|
-
return _el$
|
|
1944
|
+
return _el$194;
|
|
1669
1945
|
})()];
|
|
1670
1946
|
})(), null);
|
|
1671
1947
|
_$insert(_el$122, (() => {
|
|
1672
|
-
var _c$
|
|
1673
|
-
return () => _c$
|
|
1674
|
-
var _el$
|
|
1948
|
+
var _c$18 = _$memo(() => !!rt()?.retryAfter);
|
|
1949
|
+
return () => _c$18() && [(() => {
|
|
1950
|
+
var _el$196 = _$createElement("span"), _el$197 = _$createTextNode(`
|
|
1675
1951
|
\u21BB retry in: `);
|
|
1676
|
-
_$insertNode(_el$
|
|
1677
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1952
|
+
_$insertNode(_el$196, _el$197);
|
|
1953
|
+
_$effect((_$p) => _$setProp(_el$196, "style", {
|
|
1678
1954
|
fg: theme().accent
|
|
1679
1955
|
}, _$p));
|
|
1680
|
-
return _el$
|
|
1956
|
+
return _el$196;
|
|
1681
1957
|
})(), (() => {
|
|
1682
|
-
var _el$
|
|
1683
|
-
_$insert(_el$
|
|
1684
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1958
|
+
var _el$199 = _$createElement("span");
|
|
1959
|
+
_$insert(_el$199, () => countdownLabel(rt().retryAfter, clock()));
|
|
1960
|
+
_$effect((_$p) => _$setProp(_el$199, "style", {
|
|
1685
1961
|
fg: theme().accent
|
|
1686
1962
|
}, _$p));
|
|
1687
|
-
return _el$
|
|
1963
|
+
return _el$199;
|
|
1688
1964
|
})()];
|
|
1689
1965
|
})(), null);
|
|
1690
1966
|
_$insert(_el$122, (() => {
|
|
1691
|
-
var _c$
|
|
1692
|
-
return () => _c$
|
|
1693
|
-
var _el$
|
|
1967
|
+
var _c$19 = _$memo(() => !!rt()?.nextRunAt);
|
|
1968
|
+
return () => _c$19() && [(() => {
|
|
1969
|
+
var _el$200 = _$createElement("span"), _el$201 = _$createTextNode(`
|
|
1694
1970
|
\u23F0 next run: `);
|
|
1695
|
-
_$insertNode(_el$
|
|
1696
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1971
|
+
_$insertNode(_el$200, _el$201);
|
|
1972
|
+
_$effect((_$p) => _$setProp(_el$200, "style", {
|
|
1697
1973
|
fg: theme().accent
|
|
1698
1974
|
}, _$p));
|
|
1699
|
-
return _el$
|
|
1975
|
+
return _el$200;
|
|
1700
1976
|
})(), (() => {
|
|
1701
|
-
var _el$
|
|
1702
|
-
_$insert(_el$
|
|
1703
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1977
|
+
var _el$203 = _$createElement("span");
|
|
1978
|
+
_$insert(_el$203, () => countdownLabel(rt().nextRunAt, clock()));
|
|
1979
|
+
_$effect((_$p) => _$setProp(_el$203, "style", {
|
|
1704
1980
|
fg: theme().accent
|
|
1705
1981
|
}, _$p));
|
|
1706
|
-
return _el$
|
|
1982
|
+
return _el$203;
|
|
1707
1983
|
})(), (() => {
|
|
1708
|
-
var _el$
|
|
1709
|
-
_$insertNode(_el$
|
|
1710
|
-
_$insertNode(_el$
|
|
1711
|
-
_$insert(_el$
|
|
1712
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1984
|
+
var _el$204 = _$createElement("span"), _el$205 = _$createTextNode(` (`), _el$206 = _$createTextNode(` runs)`);
|
|
1985
|
+
_$insertNode(_el$204, _el$205);
|
|
1986
|
+
_$insertNode(_el$204, _el$206);
|
|
1987
|
+
_$insert(_el$204, () => String(rt().scheduleRunCount || 0), _el$206);
|
|
1988
|
+
_$effect((_$p) => _$setProp(_el$204, "style", {
|
|
1713
1989
|
fg: theme().textMuted
|
|
1714
1990
|
}, _$p));
|
|
1715
|
-
return _el$
|
|
1991
|
+
return _el$204;
|
|
1716
1992
|
})()];
|
|
1717
1993
|
})(), null);
|
|
1718
1994
|
_$insert(_el$122, (() => {
|
|
1719
|
-
var _c$
|
|
1720
|
-
return () => _c$
|
|
1721
|
-
var _el$
|
|
1995
|
+
var _c$20 = _$memo(() => !!rt()?.lastError);
|
|
1996
|
+
return () => _c$20() && [(() => {
|
|
1997
|
+
var _el$207 = _$createElement("span"), _el$208 = _$createTextNode(`
|
|
1722
1998
|
\u26A0 `);
|
|
1723
|
-
_$insertNode(_el$
|
|
1724
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1999
|
+
_$insertNode(_el$207, _el$208);
|
|
2000
|
+
_$effect((_$p) => _$setProp(_el$207, "style", {
|
|
1725
2001
|
fg: theme().error
|
|
1726
2002
|
}, _$p));
|
|
1727
|
-
return _el$
|
|
2003
|
+
return _el$207;
|
|
1728
2004
|
})(), (() => {
|
|
1729
|
-
var _el$
|
|
1730
|
-
_$insert(_el$
|
|
1731
|
-
_$effect((_$p) => _$setProp(_el$
|
|
2005
|
+
var _el$210 = _$createElement("span");
|
|
2006
|
+
_$insert(_el$210, () => rt().lastError.slice(0, 120));
|
|
2007
|
+
_$effect((_$p) => _$setProp(_el$210, "style", {
|
|
1732
2008
|
fg: theme().error
|
|
1733
2009
|
}, _$p));
|
|
1734
|
-
return _el$
|
|
2010
|
+
return _el$210;
|
|
1735
2011
|
})()];
|
|
1736
2012
|
})(), null);
|
|
1737
2013
|
_$effect((_p$) => {
|
|
@@ -1781,29 +2057,29 @@ function LoopDashboard(props) {
|
|
|
1781
2057
|
},
|
|
1782
2058
|
children: (ev) => [`
|
|
1783
2059
|
`, (() => {
|
|
1784
|
-
var _el$
|
|
1785
|
-
_$insert(_el$
|
|
1786
|
-
_$effect((_$p) => _$setProp(_el$
|
|
2060
|
+
var _el$211 = _$createElement("span");
|
|
2061
|
+
_$insert(_el$211, () => String(ev.type));
|
|
2062
|
+
_$effect((_$p) => _$setProp(_el$211, "style", {
|
|
1787
2063
|
fg: eventColor(String(ev.type), theme()),
|
|
1788
2064
|
bold: true
|
|
1789
2065
|
}, _$p));
|
|
1790
|
-
return _el$
|
|
2066
|
+
return _el$211;
|
|
1791
2067
|
})(), (() => {
|
|
1792
|
-
var _el$
|
|
1793
|
-
_$insertNode(_el$
|
|
1794
|
-
_$insert(_el$
|
|
1795
|
-
_$effect((_$p) => _$setProp(_el$
|
|
2068
|
+
var _el$212 = _$createElement("span"), _el$213 = _$createTextNode(` `);
|
|
2069
|
+
_$insertNode(_el$212, _el$213);
|
|
2070
|
+
_$insert(_el$212, () => ev.goalID?.slice(0, 8), null);
|
|
2071
|
+
_$effect((_$p) => _$setProp(_el$212, "style", {
|
|
1796
2072
|
fg: theme().textMuted
|
|
1797
2073
|
}, _$p));
|
|
1798
|
-
return _el$
|
|
2074
|
+
return _el$212;
|
|
1799
2075
|
})(), _$memo(() => _$memo(() => !!ev.summary)() && (() => {
|
|
1800
|
-
var _el$
|
|
1801
|
-
_$insertNode(_el$
|
|
1802
|
-
_$insert(_el$
|
|
1803
|
-
_$effect((_$p) => _$setProp(_el$
|
|
2076
|
+
var _el$214 = _$createElement("span"), _el$215 = _$createTextNode(` \u2014 `);
|
|
2077
|
+
_$insertNode(_el$214, _el$215);
|
|
2078
|
+
_$insert(_el$214, () => String(ev.summary).slice(0, 60), null);
|
|
2079
|
+
_$effect((_$p) => _$setProp(_el$214, "style", {
|
|
1804
2080
|
fg: theme().text
|
|
1805
2081
|
}, _$p));
|
|
1806
|
-
return _el$
|
|
2082
|
+
return _el$214;
|
|
1807
2083
|
})())]
|
|
1808
2084
|
}), null);
|
|
1809
2085
|
_$effect((_p$) => {
|
|
@@ -1857,18 +2133,6 @@ function LoopDashboard(props) {
|
|
|
1857
2133
|
prevent(evt);
|
|
1858
2134
|
return;
|
|
1859
2135
|
}
|
|
1860
|
-
if (name === "return" || name === "enter") {
|
|
1861
|
-
prevent(evt);
|
|
1862
|
-
debugLog("input enter -> execute");
|
|
1863
|
-
executeCommand(commandInput());
|
|
1864
|
-
return;
|
|
1865
|
-
}
|
|
1866
|
-
if (evt.ctrl && name.toLowerCase() === "n") {
|
|
1867
|
-
prevent(evt);
|
|
1868
|
-
debugLog("input ctrl+n -> normal");
|
|
1869
|
-
returnToNormalMode();
|
|
1870
|
-
return;
|
|
1871
|
-
}
|
|
1872
2136
|
});
|
|
1873
2137
|
_$effect((_p$) => {
|
|
1874
2138
|
var _v$4 = theme().border, _v$5 = {
|