agenttop 0.11.0 → 0.11.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/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
startMcpServer,
|
|
25
25
|
unarchiveSession,
|
|
26
26
|
unpinSession
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-27WRQSJY.js";
|
|
28
28
|
|
|
29
29
|
// src/index.tsx
|
|
30
30
|
import { readFileSync as readFileSync3 } from "fs";
|
|
@@ -34,7 +34,7 @@ import React19 from "react";
|
|
|
34
34
|
import { render } from "ink";
|
|
35
35
|
|
|
36
36
|
// src/ui/App.tsx
|
|
37
|
-
import { useState as useState18, useEffect as useEffect10, useCallback as
|
|
37
|
+
import { useState as useState18, useEffect as useEffect10, useCallback as useCallback8 } from "react";
|
|
38
38
|
import { Box as Box18, Text as Text17, useApp, useStdout as useStdout4 } from "ink";
|
|
39
39
|
|
|
40
40
|
// src/config/themes.ts
|
|
@@ -678,7 +678,7 @@ var compareVersions = (a, b) => {
|
|
|
678
678
|
};
|
|
679
679
|
|
|
680
680
|
// src/ui/components/StatusBar.tsx
|
|
681
|
-
import React, { useState, useEffect } from "react";
|
|
681
|
+
import React, { useState, useEffect, useRef } from "react";
|
|
682
682
|
import { Box, Text } from "ink";
|
|
683
683
|
|
|
684
684
|
// src/ui/theme.ts
|
|
@@ -726,13 +726,20 @@ var applyTheme = (theme) => {
|
|
|
726
726
|
|
|
727
727
|
// src/ui/components/StatusBar.tsx
|
|
728
728
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
729
|
+
var formatTime = () => (/* @__PURE__ */ new Date()).toLocaleTimeString("en-GB", { hour12: false });
|
|
729
730
|
var StatusBar = React.memo(({ sessionCount, alertCount, version, updateInfo }) => {
|
|
730
|
-
const [
|
|
731
|
+
const [timeStr, setTimeStr] = useState(formatTime);
|
|
732
|
+
const lastRef = useRef(timeStr);
|
|
731
733
|
useEffect(() => {
|
|
732
|
-
const interval = setInterval(() =>
|
|
734
|
+
const interval = setInterval(() => {
|
|
735
|
+
const next = formatTime();
|
|
736
|
+
if (next !== lastRef.current) {
|
|
737
|
+
lastRef.current = next;
|
|
738
|
+
setTimeStr(next);
|
|
739
|
+
}
|
|
740
|
+
}, 1e3);
|
|
733
741
|
return () => clearInterval(interval);
|
|
734
742
|
}, []);
|
|
735
|
-
const timeStr = time.toLocaleTimeString("en-GB", { hour12: false });
|
|
736
743
|
return /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: colors.border, paddingX: 1, justifyContent: "space-between", children: [
|
|
737
744
|
/* @__PURE__ */ jsxs(Text, { color: colors.header, bold: true, children: [
|
|
738
745
|
"agenttop v",
|
|
@@ -767,7 +774,7 @@ var formatTokens = (n) => {
|
|
|
767
774
|
if (n >= 1e3) return (n / 1e3).toFixed(1) + "k";
|
|
768
775
|
return String(n);
|
|
769
776
|
};
|
|
770
|
-
var
|
|
777
|
+
var formatTime2 = (ts) => {
|
|
771
778
|
const d = new Date(ts);
|
|
772
779
|
return d.toLocaleTimeString("en-GB", { hour12: false });
|
|
773
780
|
};
|
|
@@ -1061,7 +1068,7 @@ var ActivityFeed = React3.memo(
|
|
|
1061
1068
|
const tagColor = merged ? slugColorMap.get(call.sessionId) || colors.muted : void 0;
|
|
1062
1069
|
return /* @__PURE__ */ jsx3(Box3, { paddingX: 1, overflow: "hidden", children: /* @__PURE__ */ jsxs3(Text3, { wrap: "truncate", children: [
|
|
1063
1070
|
tag && /* @__PURE__ */ jsx3(Text3, { color: tagColor, children: tag.padEnd(5) }),
|
|
1064
|
-
/* @__PURE__ */ jsx3(Text3, { color: isSelected ? colors.bright : colors.muted, underline: isSelected, children:
|
|
1071
|
+
/* @__PURE__ */ jsx3(Text3, { color: isSelected ? colors.bright : colors.muted, underline: isSelected, children: formatTime2(call.timestamp) }),
|
|
1065
1072
|
" ",
|
|
1066
1073
|
/* @__PURE__ */ jsx3(Text3, { color: getToolColor(call.toolName), bold: true, underline: isSelected, children: call.toolName.padEnd(8) }),
|
|
1067
1074
|
/* @__PURE__ */ jsxs3(Text3, { color: isSelected ? colors.bright : colors.text, underline: isSelected, children: [
|
|
@@ -1117,7 +1124,7 @@ var AlertBar = React4.memo(({ alerts, maxVisible = 4 }) => {
|
|
|
1117
1124
|
] }),
|
|
1118
1125
|
/* @__PURE__ */ jsxs4(Text4, { color: colors.muted, children: [
|
|
1119
1126
|
" ",
|
|
1120
|
-
|
|
1127
|
+
formatTime2(alert.timestamp),
|
|
1121
1128
|
" "
|
|
1122
1129
|
] }),
|
|
1123
1130
|
/* @__PURE__ */ jsxs4(Text4, { color: colors.warning, children: [
|
|
@@ -1375,6 +1382,71 @@ var FooterBar = React7.memo(
|
|
|
1375
1382
|
import React8, { useState as useState3 } from "react";
|
|
1376
1383
|
import { Box as Box8, Text as Text8, useInput as useInput2 } from "ink";
|
|
1377
1384
|
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1385
|
+
var highlightJsonLine = (line) => {
|
|
1386
|
+
const segments = [];
|
|
1387
|
+
let i = 0;
|
|
1388
|
+
const len = line.length;
|
|
1389
|
+
while (i < len) {
|
|
1390
|
+
const ch = line[i];
|
|
1391
|
+
if (ch === " " || ch === " ") {
|
|
1392
|
+
let end = i;
|
|
1393
|
+
while (end < len && (line[end] === " " || line[end] === " ")) end++;
|
|
1394
|
+
segments.push({ text: line.slice(i, end), color: colors.text });
|
|
1395
|
+
i = end;
|
|
1396
|
+
continue;
|
|
1397
|
+
}
|
|
1398
|
+
if (ch === "{" || ch === "}" || ch === "[" || ch === "]" || ch === "," || ch === ":") {
|
|
1399
|
+
segments.push({ text: ch, color: colors.muted });
|
|
1400
|
+
i++;
|
|
1401
|
+
continue;
|
|
1402
|
+
}
|
|
1403
|
+
if (ch === '"') {
|
|
1404
|
+
let end = i + 1;
|
|
1405
|
+
while (end < len && line[end] !== '"') {
|
|
1406
|
+
if (line[end] === "\\") end++;
|
|
1407
|
+
end++;
|
|
1408
|
+
}
|
|
1409
|
+
end++;
|
|
1410
|
+
const str = line.slice(i, end);
|
|
1411
|
+
let peek = end;
|
|
1412
|
+
while (peek < len && line[peek] === " ") peek++;
|
|
1413
|
+
const isKey = peek < len && line[peek] === ":";
|
|
1414
|
+
segments.push({ text: str, color: isKey ? colors.primary : colors.secondary });
|
|
1415
|
+
i = end;
|
|
1416
|
+
continue;
|
|
1417
|
+
}
|
|
1418
|
+
if (ch >= "0" && ch <= "9" || ch === "-") {
|
|
1419
|
+
let end = i + 1;
|
|
1420
|
+
while (end < len && (line[end] >= "0" && line[end] <= "9" || line[end] === "." || line[end] === "e" || line[end] === "E" || line[end] === "+" || line[end] === "-"))
|
|
1421
|
+
end++;
|
|
1422
|
+
segments.push({ text: line.slice(i, end), color: colors.warning });
|
|
1423
|
+
i = end;
|
|
1424
|
+
continue;
|
|
1425
|
+
}
|
|
1426
|
+
if (line.startsWith("true", i)) {
|
|
1427
|
+
segments.push({ text: "true", color: colors.accent });
|
|
1428
|
+
i += 4;
|
|
1429
|
+
continue;
|
|
1430
|
+
}
|
|
1431
|
+
if (line.startsWith("false", i)) {
|
|
1432
|
+
segments.push({ text: "false", color: colors.accent });
|
|
1433
|
+
i += 5;
|
|
1434
|
+
continue;
|
|
1435
|
+
}
|
|
1436
|
+
if (line.startsWith("null", i)) {
|
|
1437
|
+
segments.push({ text: "null", color: colors.error });
|
|
1438
|
+
i += 4;
|
|
1439
|
+
continue;
|
|
1440
|
+
}
|
|
1441
|
+
segments.push({ text: ch, color: colors.text });
|
|
1442
|
+
i++;
|
|
1443
|
+
}
|
|
1444
|
+
return segments;
|
|
1445
|
+
};
|
|
1446
|
+
var isJsonLine = (line) => {
|
|
1447
|
+
const trimmed = line.trimStart();
|
|
1448
|
+
return trimmed.startsWith("{") || trimmed.startsWith("}") || trimmed.startsWith("[") || trimmed.startsWith("]") || trimmed.startsWith('"') || /^\d/.test(trimmed) || trimmed === "true" || trimmed === "true," || trimmed === "false" || trimmed === "false," || trimmed === "null" || trimmed === "null,";
|
|
1449
|
+
};
|
|
1378
1450
|
var renderBash = (event) => {
|
|
1379
1451
|
const lines = [];
|
|
1380
1452
|
const cmd = String(event.call.toolInput.command || "");
|
|
@@ -1485,7 +1557,7 @@ var renderWebSearch = (event) => {
|
|
|
1485
1557
|
var renderDefault = (event) => {
|
|
1486
1558
|
const lines = [];
|
|
1487
1559
|
lines.push("--- input ---");
|
|
1488
|
-
lines.push(JSON.stringify(event.call.toolInput, null, 2));
|
|
1560
|
+
lines.push(...JSON.stringify(event.call.toolInput, null, 2).split("\n"));
|
|
1489
1561
|
if (event.result) {
|
|
1490
1562
|
lines.push("");
|
|
1491
1563
|
lines.push("--- result ---");
|
|
@@ -1548,7 +1620,7 @@ var ToolCallDetail = React8.memo(({ event, focused, height }) => {
|
|
|
1548
1620
|
/* @__PURE__ */ jsx8(Text8, { color: getToolColor(event.call.toolName), bold: true, children: event.call.toolName }),
|
|
1549
1621
|
/* @__PURE__ */ jsxs8(Text8, { color: colors.muted, children: [
|
|
1550
1622
|
" ",
|
|
1551
|
-
|
|
1623
|
+
formatTime2(event.call.timestamp)
|
|
1552
1624
|
] }),
|
|
1553
1625
|
/* @__PURE__ */ jsxs8(Text8, { color: colors.muted, children: [
|
|
1554
1626
|
" ",
|
|
@@ -1559,13 +1631,26 @@ var ToolCallDetail = React8.memo(({ event, focused, height }) => {
|
|
|
1559
1631
|
/* @__PURE__ */ jsx8(Text8, { color: colors.muted, children: "Esc:back j/k:scroll" })
|
|
1560
1632
|
] }),
|
|
1561
1633
|
/* @__PURE__ */ jsx8(Box8, { flexDirection: "column", paddingX: 1, children: visible.map((line, i) => {
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1634
|
+
if (line.startsWith("- ") && event.call.toolName === "Edit") {
|
|
1635
|
+
return /* @__PURE__ */ jsx8(Text8, { color: colors.error, wrap: "truncate", children: line }, `${start + i}`);
|
|
1636
|
+
}
|
|
1637
|
+
if (line.startsWith("+ ") && event.call.toolName === "Edit") {
|
|
1638
|
+
return /* @__PURE__ */ jsx8(Text8, { color: colors.secondary, wrap: "truncate", children: line }, `${start + i}`);
|
|
1639
|
+
}
|
|
1640
|
+
if (line.startsWith("$ ")) {
|
|
1641
|
+
return /* @__PURE__ */ jsx8(Text8, { color: colors.bright, wrap: "truncate", children: line }, `${start + i}`);
|
|
1642
|
+
}
|
|
1643
|
+
if (line.startsWith("---")) {
|
|
1644
|
+
return /* @__PURE__ */ jsx8(Text8, { color: colors.muted, wrap: "truncate", children: line }, `${start + i}`);
|
|
1645
|
+
}
|
|
1646
|
+
if (event.result?.isError) {
|
|
1647
|
+
return /* @__PURE__ */ jsx8(Text8, { color: colors.error, wrap: "truncate", children: line }, `${start + i}`);
|
|
1648
|
+
}
|
|
1649
|
+
if (isJsonLine(line)) {
|
|
1650
|
+
const segments = highlightJsonLine(line);
|
|
1651
|
+
return /* @__PURE__ */ jsx8(Text8, { wrap: "truncate", children: segments.map((seg, si) => /* @__PURE__ */ jsx8(Text8, { color: seg.color, children: seg.text }, si)) }, `${start + i}`);
|
|
1652
|
+
}
|
|
1653
|
+
return /* @__PURE__ */ jsx8(Text8, { color: colors.text, wrap: "truncate", children: line }, `${start + i}`);
|
|
1569
1654
|
}) }),
|
|
1570
1655
|
contentLines.length > viewportRows && /* @__PURE__ */ jsx8(Box8, { paddingX: 1, justifyContent: "flex-end", children: /* @__PURE__ */ jsxs8(Text8, { color: colors.muted, children: [
|
|
1571
1656
|
"[",
|
|
@@ -1582,7 +1667,7 @@ var ToolCallDetail = React8.memo(({ event, focused, height }) => {
|
|
|
1582
1667
|
});
|
|
1583
1668
|
|
|
1584
1669
|
// src/ui/components/SettingsMenu.tsx
|
|
1585
|
-
import React9, { useState as useState4, useMemo, useEffect as useEffect2, useRef } from "react";
|
|
1670
|
+
import React9, { useState as useState4, useMemo, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
1586
1671
|
import { Box as Box9, Text as Text9, useInput as useInput3, useStdout } from "ink";
|
|
1587
1672
|
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1588
1673
|
var KEYBIND_LABELS = {
|
|
@@ -1751,7 +1836,7 @@ var SettingsMenu = React9.memo(({ config, onClose, onOpenThemeMenu }) => {
|
|
|
1751
1836
|
const [selectablePos, setSelectablePos] = useState4(0);
|
|
1752
1837
|
const [rebinding, setRebinding] = useState4(false);
|
|
1753
1838
|
const [toast, setToast] = useState4("");
|
|
1754
|
-
const toastTimer =
|
|
1839
|
+
const toastTimer = useRef2(null);
|
|
1755
1840
|
const showToast = (msg) => {
|
|
1756
1841
|
if (toastTimer.current) clearTimeout(toastTimer.current);
|
|
1757
1842
|
setToast(msg);
|
|
@@ -1882,7 +1967,7 @@ var SettingsMenu = React9.memo(({ config, onClose, onOpenThemeMenu }) => {
|
|
|
1882
1967
|
});
|
|
1883
1968
|
|
|
1884
1969
|
// src/ui/components/ThemeMenu.tsx
|
|
1885
|
-
import React11, { useState as useState6, useCallback, useRef as
|
|
1970
|
+
import React11, { useState as useState6, useCallback, useRef as useRef3, useEffect as useEffect3 } from "react";
|
|
1886
1971
|
import { Box as Box11, Text as Text11, useInput as useInput5, useStdout as useStdout2 } from "ink";
|
|
1887
1972
|
|
|
1888
1973
|
// src/ui/components/ThemeEditor.tsx
|
|
@@ -2018,7 +2103,7 @@ var ThemeMenu = React11.memo(({ config, onClose }) => {
|
|
|
2018
2103
|
const [nameInput, setNameInput] = useState6("");
|
|
2019
2104
|
const [namingAction, setNamingAction] = useState6("copy");
|
|
2020
2105
|
const [toast, setToast] = useState6("");
|
|
2021
|
-
const toastTimer =
|
|
2106
|
+
const toastTimer = useRef3(null);
|
|
2022
2107
|
const showToast = (msg) => {
|
|
2023
2108
|
if (toastTimer.current) clearTimeout(toastTimer.current);
|
|
2024
2109
|
setToast(msg);
|
|
@@ -2240,7 +2325,7 @@ var ThemeMenu = React11.memo(({ config, onClose }) => {
|
|
|
2240
2325
|
});
|
|
2241
2326
|
|
|
2242
2327
|
// src/ui/components/AlertRulesMenu.tsx
|
|
2243
|
-
import React12, { useState as useState7, useRef as
|
|
2328
|
+
import React12, { useState as useState7, useRef as useRef4, useEffect as useEffect4 } from "react";
|
|
2244
2329
|
import { Box as Box12, Text as Text12, useInput as useInput6, useStdout as useStdout3 } from "ink";
|
|
2245
2330
|
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2246
2331
|
var MATCH_OPTIONS = ["input", "output", "toolName", "all"];
|
|
@@ -2291,7 +2376,7 @@ var AlertRulesMenu = React12.memo(({ config, onClose, onSave }) => {
|
|
|
2291
2376
|
const [selectedIdx, setSelectedIdx] = useState7(0);
|
|
2292
2377
|
const [view, setView] = useState7("list");
|
|
2293
2378
|
const [toast, setToast] = useState7("");
|
|
2294
|
-
const toastTimer =
|
|
2379
|
+
const toastTimer = useRef4(null);
|
|
2295
2380
|
const [formData, setFormData] = useState7(emptyForm());
|
|
2296
2381
|
const [formField, setFormField] = useState7(0);
|
|
2297
2382
|
const [formError, setFormError] = useState7("");
|
|
@@ -2954,7 +3039,7 @@ var SplitPanel = React17.memo(
|
|
|
2954
3039
|
);
|
|
2955
3040
|
|
|
2956
3041
|
// src/ui/hooks/useSessions.ts
|
|
2957
|
-
import { useState as useState11, useEffect as useEffect6, useCallback as useCallback3, useRef as
|
|
3042
|
+
import { useState as useState11, useEffect as useEffect6, useCallback as useCallback3, useRef as useRef5, useMemo as useMemo2 } from "react";
|
|
2958
3043
|
|
|
2959
3044
|
// src/discovery/sessionsAsync.ts
|
|
2960
3045
|
import { readdir, stat as stat2, open as open2 } from "fs/promises";
|
|
@@ -3470,7 +3555,7 @@ var useSessions = (allUsers, filter, archivedIds, viewingArchive) => {
|
|
|
3470
3555
|
const [sessions2, setSessions] = useState11([]);
|
|
3471
3556
|
const [selectedIndex, setSelectedIndex] = useState11(0);
|
|
3472
3557
|
const [expandedKeys, setExpandedKeys] = useState11(/* @__PURE__ */ new Set());
|
|
3473
|
-
const usageOverrides =
|
|
3558
|
+
const usageOverrides = useRef5(/* @__PURE__ */ new Map());
|
|
3474
3559
|
const refresh = useCallback3(() => {
|
|
3475
3560
|
const found = getCachedSessions();
|
|
3476
3561
|
const filtered = enrichAndFilter(found, usageOverrides.current, filter, archivedIds, viewingArchive);
|
|
@@ -3493,7 +3578,7 @@ var useSessions = (allUsers, filter, archivedIds, viewingArchive) => {
|
|
|
3493
3578
|
}, [refresh, sessions2.length > 0]);
|
|
3494
3579
|
const groups = useMemo2(() => buildGroups(sessions2, expandedKeys), [sessions2, expandedKeys]);
|
|
3495
3580
|
const visibleItems = useMemo2(() => buildVisibleItems(groups), [groups]);
|
|
3496
|
-
const itemCountRef =
|
|
3581
|
+
const itemCountRef = useRef5(visibleItems.length);
|
|
3497
3582
|
itemCountRef.current = visibleItems.length;
|
|
3498
3583
|
const selectedItem = visibleItems[selectedIndex] ?? null;
|
|
3499
3584
|
const selectedSession = selectedItem?.type === "ungrouped" ? selectedItem.session : selectedItem?.type === "session" ? selectedItem.session : null;
|
|
@@ -3545,18 +3630,42 @@ var useSessions = (allUsers, filter, archivedIds, viewingArchive) => {
|
|
|
3545
3630
|
};
|
|
3546
3631
|
|
|
3547
3632
|
// src/ui/hooks/useActivityStream.ts
|
|
3548
|
-
import { useState as useState12, useEffect as useEffect7, useRef as
|
|
3633
|
+
import { useState as useState12, useEffect as useEffect7, useRef as useRef6, useMemo as useMemo3, useCallback as useCallback4 } from "react";
|
|
3549
3634
|
var MAX_EVENTS = 200;
|
|
3635
|
+
var DEBOUNCE_MS = 80;
|
|
3550
3636
|
var useActivityStream = (session, allUsers) => {
|
|
3551
3637
|
const [calls, setCalls] = useState12([]);
|
|
3552
3638
|
const [results, setResults] = useState12([]);
|
|
3553
|
-
const watcherRef =
|
|
3639
|
+
const watcherRef = useRef6(null);
|
|
3640
|
+
const pendingCallsRef = useRef6([]);
|
|
3641
|
+
const pendingResultsRef = useRef6([]);
|
|
3642
|
+
const flushTimerRef = useRef6(null);
|
|
3554
3643
|
const sessions2 = session === null ? [] : Array.isArray(session) ? session : [session];
|
|
3555
3644
|
const sessionKey = sessions2.map((s) => s.sessionId).sort().join(",");
|
|
3556
3645
|
const sessionIdSet = new Set(sessions2.map((s) => s.sessionId));
|
|
3646
|
+
const flush = useCallback4(() => {
|
|
3647
|
+
flushTimerRef.current = null;
|
|
3648
|
+
const pc = pendingCallsRef.current;
|
|
3649
|
+
const pr = pendingResultsRef.current;
|
|
3650
|
+
if (pc.length > 0) {
|
|
3651
|
+
const batch = pc.splice(0);
|
|
3652
|
+
setCalls((prev) => [...prev, ...batch].slice(-MAX_EVENTS));
|
|
3653
|
+
}
|
|
3654
|
+
if (pr.length > 0) {
|
|
3655
|
+
const batch = pr.splice(0);
|
|
3656
|
+
setResults((prev) => [...prev, ...batch].slice(-MAX_EVENTS * 2));
|
|
3657
|
+
}
|
|
3658
|
+
}, []);
|
|
3659
|
+
const scheduleFlush = useCallback4(() => {
|
|
3660
|
+
if (!flushTimerRef.current) {
|
|
3661
|
+
flushTimerRef.current = setTimeout(flush, DEBOUNCE_MS);
|
|
3662
|
+
}
|
|
3663
|
+
}, [flush]);
|
|
3557
3664
|
useEffect7(() => {
|
|
3558
3665
|
setCalls([]);
|
|
3559
3666
|
setResults([]);
|
|
3667
|
+
pendingCallsRef.current = [];
|
|
3668
|
+
pendingResultsRef.current = [];
|
|
3560
3669
|
if (sessions2.length === 0) return;
|
|
3561
3670
|
let cancelled = false;
|
|
3562
3671
|
const loadExisting = async () => {
|
|
@@ -3583,18 +3692,21 @@ var useActivityStream = (session, allUsers) => {
|
|
|
3583
3692
|
const callHandler = (newCalls) => {
|
|
3584
3693
|
const matched = newCalls.filter((c) => sessionIdSet.has(c.sessionId));
|
|
3585
3694
|
if (matched.length === 0) return;
|
|
3586
|
-
|
|
3695
|
+
pendingCallsRef.current.push(...matched);
|
|
3696
|
+
scheduleFlush();
|
|
3587
3697
|
};
|
|
3588
3698
|
const resultHandler = (newResults) => {
|
|
3589
3699
|
const matched = newResults.filter((r) => sessionIdSet.has(r.sessionId));
|
|
3590
3700
|
if (matched.length === 0) return;
|
|
3591
|
-
|
|
3701
|
+
pendingResultsRef.current.push(...matched);
|
|
3702
|
+
scheduleFlush();
|
|
3592
3703
|
};
|
|
3593
3704
|
const watcher = new Watcher(callHandler, allUsers, void 0, void 0, resultHandler);
|
|
3594
3705
|
watcherRef.current = watcher;
|
|
3595
3706
|
watcher.start();
|
|
3596
3707
|
return () => {
|
|
3597
3708
|
cancelled = true;
|
|
3709
|
+
if (flushTimerRef.current) clearTimeout(flushTimerRef.current);
|
|
3598
3710
|
watcher.stop();
|
|
3599
3711
|
watcherRef.current = null;
|
|
3600
3712
|
};
|
|
@@ -3623,7 +3735,7 @@ var applyFilter = (events, filter) => {
|
|
|
3623
3735
|
var useFilteredEvents = (rawEvents, filter) => useMemo4(() => applyFilter(rawEvents, filter), [rawEvents, filter]);
|
|
3624
3736
|
|
|
3625
3737
|
// src/ui/hooks/useAlerts.ts
|
|
3626
|
-
import { useState as useState13, useEffect as useEffect8, useRef as
|
|
3738
|
+
import { useState as useState13, useEffect as useEffect8, useRef as useRef7 } from "react";
|
|
3627
3739
|
|
|
3628
3740
|
// src/notifications.ts
|
|
3629
3741
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -3704,9 +3816,9 @@ var AlertLogger = class {
|
|
|
3704
3816
|
var MAX_ALERTS = 100;
|
|
3705
3817
|
var useAlerts = (enabled, alertLevel, allUsers, config) => {
|
|
3706
3818
|
const [alerts, setAlerts] = useState13([]);
|
|
3707
|
-
const engineRef =
|
|
3708
|
-
const watcherRef =
|
|
3709
|
-
const loggerRef =
|
|
3819
|
+
const engineRef = useRef7(new SecurityEngine(alertLevel));
|
|
3820
|
+
const watcherRef = useRef7(null);
|
|
3821
|
+
const loggerRef = useRef7(null);
|
|
3710
3822
|
useEffect8(() => {
|
|
3711
3823
|
if (!enabled) return;
|
|
3712
3824
|
engineRef.current = new SecurityEngine(alertLevel);
|
|
@@ -3743,27 +3855,27 @@ var useAlerts = (enabled, alertLevel, allUsers, config) => {
|
|
|
3743
3855
|
};
|
|
3744
3856
|
|
|
3745
3857
|
// src/ui/hooks/useTextInput.ts
|
|
3746
|
-
import { useState as useState14, useCallback as
|
|
3858
|
+
import { useState as useState14, useCallback as useCallback5 } from "react";
|
|
3747
3859
|
var useTextInput = (onConfirm, onCancel) => {
|
|
3748
3860
|
const [value, setValue] = useState14("");
|
|
3749
3861
|
const [isActive, setIsActive] = useState14(false);
|
|
3750
|
-
const start =
|
|
3862
|
+
const start = useCallback5((initial = "") => {
|
|
3751
3863
|
setValue(initial);
|
|
3752
3864
|
setIsActive(true);
|
|
3753
3865
|
}, []);
|
|
3754
|
-
const cancel =
|
|
3866
|
+
const cancel = useCallback5(() => {
|
|
3755
3867
|
setValue("");
|
|
3756
3868
|
setIsActive(false);
|
|
3757
3869
|
onCancel?.();
|
|
3758
3870
|
}, [onCancel]);
|
|
3759
|
-
const confirm =
|
|
3871
|
+
const confirm = useCallback5(() => {
|
|
3760
3872
|
const result = value;
|
|
3761
3873
|
setIsActive(false);
|
|
3762
3874
|
setValue("");
|
|
3763
3875
|
onConfirm?.(result);
|
|
3764
3876
|
return result;
|
|
3765
3877
|
}, [value, onConfirm]);
|
|
3766
|
-
const handleInput =
|
|
3878
|
+
const handleInput = useCallback5(
|
|
3767
3879
|
(input, key) => {
|
|
3768
3880
|
if (!isActive) return false;
|
|
3769
3881
|
if (key.escape) {
|
|
@@ -4078,7 +4190,7 @@ var useUpdateChecker = (disabled, checkOnLaunch, checkInterval) => {
|
|
|
4078
4190
|
};
|
|
4079
4191
|
|
|
4080
4192
|
// src/ui/hooks/useSetupFlow.ts
|
|
4081
|
-
import { useState as useState16, useCallback as
|
|
4193
|
+
import { useState as useState16, useCallback as useCallback6 } from "react";
|
|
4082
4194
|
|
|
4083
4195
|
// src/hooks/installer.ts
|
|
4084
4196
|
import { existsSync, readFileSync, writeFileSync, copyFileSync, mkdirSync as mkdirSync2, chmodSync } from "fs";
|
|
@@ -4204,19 +4316,19 @@ var useSetupFlow = (initialConfig, firstRun) => {
|
|
|
4204
4316
|
const [showTour, setShowTour] = useState16(false);
|
|
4205
4317
|
const [showSettings, setShowSettings] = useState16(false);
|
|
4206
4318
|
const [showThemeMenu, setShowThemeMenu] = useState16(false);
|
|
4207
|
-
const handleSettingsClose =
|
|
4319
|
+
const handleSettingsClose = useCallback6((c) => {
|
|
4208
4320
|
setLiveConfig(c);
|
|
4209
4321
|
saveConfig(c);
|
|
4210
4322
|
setShowSettings(false);
|
|
4211
4323
|
}, []);
|
|
4212
|
-
const handleThemeMenuClose =
|
|
4324
|
+
const handleThemeMenuClose = useCallback6((c) => {
|
|
4213
4325
|
setLiveConfig(c);
|
|
4214
4326
|
saveConfig(c);
|
|
4215
4327
|
setShowThemeMenu(false);
|
|
4216
4328
|
setShowSettings(true);
|
|
4217
4329
|
}, []);
|
|
4218
|
-
const handleOpenThemeMenu =
|
|
4219
|
-
const handleSetupComplete =
|
|
4330
|
+
const handleOpenThemeMenu = useCallback6(() => setShowThemeMenu(true), []);
|
|
4331
|
+
const handleSetupComplete = useCallback6(
|
|
4220
4332
|
(results) => {
|
|
4221
4333
|
const nc = { ...liveConfig };
|
|
4222
4334
|
const [hc, mc] = results;
|
|
@@ -4241,7 +4353,7 @@ var useSetupFlow = (initialConfig, firstRun) => {
|
|
|
4241
4353
|
},
|
|
4242
4354
|
[liveConfig]
|
|
4243
4355
|
);
|
|
4244
|
-
const handleThemePickerSelect =
|
|
4356
|
+
const handleThemePickerSelect = useCallback6(
|
|
4245
4357
|
(themeName) => {
|
|
4246
4358
|
const nc = { ...liveConfig, theme: themeName, prompts: { ...liveConfig.prompts, theme: "done" } };
|
|
4247
4359
|
setLiveConfig(nc);
|
|
@@ -4251,24 +4363,24 @@ var useSetupFlow = (initialConfig, firstRun) => {
|
|
|
4251
4363
|
},
|
|
4252
4364
|
[liveConfig]
|
|
4253
4365
|
);
|
|
4254
|
-
const handleThemePickerSkip =
|
|
4366
|
+
const handleThemePickerSkip = useCallback6(() => {
|
|
4255
4367
|
setShowThemePicker(false);
|
|
4256
4368
|
if (liveConfig.prompts.tour === "pending") setShowTour(true);
|
|
4257
4369
|
}, [liveConfig]);
|
|
4258
|
-
const handleThemePickerDismiss =
|
|
4370
|
+
const handleThemePickerDismiss = useCallback6(() => {
|
|
4259
4371
|
const nc = { ...liveConfig, prompts: { ...liveConfig.prompts, theme: "dismissed" } };
|
|
4260
4372
|
setLiveConfig(nc);
|
|
4261
4373
|
saveConfig(nc);
|
|
4262
4374
|
setShowThemePicker(false);
|
|
4263
4375
|
if (nc.prompts.tour === "pending") setShowTour(true);
|
|
4264
4376
|
}, [liveConfig]);
|
|
4265
|
-
const handleTourComplete =
|
|
4377
|
+
const handleTourComplete = useCallback6(() => {
|
|
4266
4378
|
const nc = { ...liveConfig, prompts: { ...liveConfig.prompts, tour: "done" } };
|
|
4267
4379
|
setLiveConfig(nc);
|
|
4268
4380
|
saveConfig(nc);
|
|
4269
4381
|
setShowTour(false);
|
|
4270
4382
|
}, [liveConfig]);
|
|
4271
|
-
const handleTourSkip =
|
|
4383
|
+
const handleTourSkip = useCallback6(() => {
|
|
4272
4384
|
setShowTour(false);
|
|
4273
4385
|
}, []);
|
|
4274
4386
|
return {
|
|
@@ -4294,7 +4406,7 @@ var useSetupFlow = (initialConfig, firstRun) => {
|
|
|
4294
4406
|
};
|
|
4295
4407
|
|
|
4296
4408
|
// src/ui/hooks/useSplitPanel.ts
|
|
4297
|
-
import { useState as useState17, useCallback as
|
|
4409
|
+
import { useState as useState17, useCallback as useCallback7 } from "react";
|
|
4298
4410
|
var useSplitPanel = () => {
|
|
4299
4411
|
const [splitMode, setSplitMode] = useState17(false);
|
|
4300
4412
|
const [leftSession, setLeftSession] = useState17(null);
|
|
@@ -4305,7 +4417,7 @@ var useSplitPanel = () => {
|
|
|
4305
4417
|
const [rightFilter, setRightFilter] = useState17("");
|
|
4306
4418
|
const [leftShowDetail, setLeftShowDetail] = useState17(false);
|
|
4307
4419
|
const [rightShowDetail, setRightShowDetail] = useState17(false);
|
|
4308
|
-
const clearSplitState =
|
|
4420
|
+
const clearSplitState = useCallback7(() => {
|
|
4309
4421
|
setSplitMode(false);
|
|
4310
4422
|
setLeftSession(null);
|
|
4311
4423
|
setRightSession(null);
|
|
@@ -4316,7 +4428,7 @@ var useSplitPanel = () => {
|
|
|
4316
4428
|
setLeftShowDetail(false);
|
|
4317
4429
|
setRightShowDetail(false);
|
|
4318
4430
|
}, []);
|
|
4319
|
-
const resetPanel =
|
|
4431
|
+
const resetPanel = useCallback7((side) => {
|
|
4320
4432
|
if (side === "left") {
|
|
4321
4433
|
setLeftSession(null);
|
|
4322
4434
|
setLeftScroll(0);
|
|
@@ -4329,7 +4441,7 @@ var useSplitPanel = () => {
|
|
|
4329
4441
|
setRightShowDetail(false);
|
|
4330
4442
|
}
|
|
4331
4443
|
}, []);
|
|
4332
|
-
const switchPanel =
|
|
4444
|
+
const switchPanel = useCallback7(
|
|
4333
4445
|
(dir, setActivePanel) => {
|
|
4334
4446
|
if (splitMode) {
|
|
4335
4447
|
const order = ["sessions", "left", "right"];
|
|
@@ -4395,8 +4507,8 @@ var App = ({ options: options2, config: initialConfig, version, firstRun }) => {
|
|
|
4395
4507
|
const [showEventDetail, setShowEventDetail] = useState18(false);
|
|
4396
4508
|
const [showUpdateModal, setShowUpdateModal] = useState18(false);
|
|
4397
4509
|
const [showAlertRules, setShowAlertRules] = useState18(false);
|
|
4398
|
-
const refreshArchived =
|
|
4399
|
-
const persistSidebarWidth =
|
|
4510
|
+
const refreshArchived = useCallback8(() => setArchivedIds(new Set(Object.keys(getArchived()))), []);
|
|
4511
|
+
const persistSidebarWidth = useCallback8((v) => {
|
|
4400
4512
|
setSidebarWidth((prev) => {
|
|
4401
4513
|
const next = typeof v === "function" ? v(prev) : v;
|
|
4402
4514
|
if (next !== prev) {
|
|
@@ -4494,21 +4606,21 @@ var App = ({ options: options2, config: initialConfig, version, firstRun }) => {
|
|
|
4494
4606
|
const alertHeight = options2.noSecurity ? 0 : 6;
|
|
4495
4607
|
const mainHeight = termHeight - 3 - alertHeight - 1 - (inputMode !== "normal" ? 1 : 0);
|
|
4496
4608
|
const viewportRows = mainHeight - 2;
|
|
4497
|
-
const switchPanel =
|
|
4609
|
+
const switchPanel = useCallback8(
|
|
4498
4610
|
(dir) => split.switchPanel(dir, setActivePanel),
|
|
4499
4611
|
[split.switchPanel]
|
|
4500
4612
|
);
|
|
4501
|
-
const clearSplitState =
|
|
4613
|
+
const clearSplitState = useCallback8(() => {
|
|
4502
4614
|
split.clearSplitState();
|
|
4503
4615
|
setActivePanel("sessions");
|
|
4504
4616
|
}, [split.clearSplitState]);
|
|
4505
|
-
const getActiveFilter =
|
|
4617
|
+
const getActiveFilter = useCallback8(() => {
|
|
4506
4618
|
if (activePanel === "sessions") return filter;
|
|
4507
4619
|
if (activePanel === "left") return split.leftFilter;
|
|
4508
4620
|
if (activePanel === "right") return split.rightFilter;
|
|
4509
4621
|
return activityFilter;
|
|
4510
4622
|
}, [activePanel, filter, split.leftFilter, split.rightFilter, activityFilter]);
|
|
4511
|
-
const handleTogglePin =
|
|
4623
|
+
const handleTogglePin = useCallback8(
|
|
4512
4624
|
(sessionId) => {
|
|
4513
4625
|
const cfg = loadConfig();
|
|
4514
4626
|
if (cfg.pinnedSessions.includes(sessionId)) {
|
|
@@ -4520,7 +4632,7 @@ var App = ({ options: options2, config: initialConfig, version, firstRun }) => {
|
|
|
4520
4632
|
},
|
|
4521
4633
|
[refresh]
|
|
4522
4634
|
);
|
|
4523
|
-
const handleMovePinned =
|
|
4635
|
+
const handleMovePinned = useCallback8(
|
|
4524
4636
|
(sessionId, dir) => {
|
|
4525
4637
|
movePinned(sessionId, dir);
|
|
4526
4638
|
refresh();
|