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-LPXME2WB.js";
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 useCallback7 } from "react";
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 [time, setTime] = useState(/* @__PURE__ */ new Date());
731
+ const [timeStr, setTimeStr] = useState(formatTime);
732
+ const lastRef = useRef(timeStr);
731
733
  useEffect(() => {
732
- const interval = setInterval(() => setTime(/* @__PURE__ */ new Date()), 1e3);
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 formatTime = (ts) => {
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: formatTime(call.timestamp) }),
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
- formatTime(alert.timestamp),
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
- formatTime(event.call.timestamp)
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
- let lineColor = colors.text;
1563
- if (line.startsWith("- ") && event.call.toolName === "Edit") lineColor = colors.error;
1564
- else if (line.startsWith("+ ") && event.call.toolName === "Edit") lineColor = colors.secondary;
1565
- else if (line.startsWith("$ ")) lineColor = colors.bright;
1566
- else if (line.startsWith("---")) lineColor = colors.muted;
1567
- else if (event.result?.isError) lineColor = colors.error;
1568
- return /* @__PURE__ */ jsx8(Text8, { color: lineColor, wrap: "truncate", children: line }, `${start + i}`);
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 = useRef(null);
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 useRef2, useEffect as useEffect3 } from "react";
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 = useRef2(null);
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 useRef3, useEffect as useEffect4 } from "react";
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 = useRef3(null);
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 useRef4, useMemo as useMemo2 } from "react";
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 = useRef4(/* @__PURE__ */ new Map());
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 = useRef4(visibleItems.length);
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 useRef5, useMemo as useMemo3 } from "react";
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 = useRef5(null);
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
- setCalls((prev) => [...prev, ...matched].slice(-MAX_EVENTS));
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
- setResults((prev) => [...prev, ...matched].slice(-MAX_EVENTS * 2));
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 useRef6 } from "react";
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 = useRef6(new SecurityEngine(alertLevel));
3708
- const watcherRef = useRef6(null);
3709
- const loggerRef = useRef6(null);
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 useCallback4 } from "react";
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 = useCallback4((initial = "") => {
3862
+ const start = useCallback5((initial = "") => {
3751
3863
  setValue(initial);
3752
3864
  setIsActive(true);
3753
3865
  }, []);
3754
- const cancel = useCallback4(() => {
3866
+ const cancel = useCallback5(() => {
3755
3867
  setValue("");
3756
3868
  setIsActive(false);
3757
3869
  onCancel?.();
3758
3870
  }, [onCancel]);
3759
- const confirm = useCallback4(() => {
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 = useCallback4(
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 useCallback5 } from "react";
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 = useCallback5((c) => {
4319
+ const handleSettingsClose = useCallback6((c) => {
4208
4320
  setLiveConfig(c);
4209
4321
  saveConfig(c);
4210
4322
  setShowSettings(false);
4211
4323
  }, []);
4212
- const handleThemeMenuClose = useCallback5((c) => {
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 = useCallback5(() => setShowThemeMenu(true), []);
4219
- const handleSetupComplete = useCallback5(
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 = useCallback5(
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 = useCallback5(() => {
4366
+ const handleThemePickerSkip = useCallback6(() => {
4255
4367
  setShowThemePicker(false);
4256
4368
  if (liveConfig.prompts.tour === "pending") setShowTour(true);
4257
4369
  }, [liveConfig]);
4258
- const handleThemePickerDismiss = useCallback5(() => {
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 = useCallback5(() => {
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 = useCallback5(() => {
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 useCallback6 } from "react";
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 = useCallback6(() => {
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 = useCallback6((side) => {
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 = useCallback6(
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 = useCallback7(() => setArchivedIds(new Set(Object.keys(getArchived()))), []);
4399
- const persistSidebarWidth = useCallback7((v) => {
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 = useCallback7(
4609
+ const switchPanel = useCallback8(
4498
4610
  (dir) => split.switchPanel(dir, setActivePanel),
4499
4611
  [split.switchPanel]
4500
4612
  );
4501
- const clearSplitState = useCallback7(() => {
4613
+ const clearSplitState = useCallback8(() => {
4502
4614
  split.clearSplitState();
4503
4615
  setActivePanel("sessions");
4504
4616
  }, [split.clearSplitState]);
4505
- const getActiveFilter = useCallback7(() => {
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 = useCallback7(
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 = useCallback7(
4635
+ const handleMovePinned = useCallback8(
4524
4636
  (sessionId, dir) => {
4525
4637
  movePinned(sessionId, dir);
4526
4638
  refresh();