@solongate/proxy 0.81.43 → 0.81.45

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
@@ -7534,6 +7534,7 @@ function LivePanel({ active: active2 }) {
7534
7534
  const [detailScroll, setDetailScroll] = useState2(0);
7535
7535
  const [inspect, setInspect] = useState2(null);
7536
7536
  const [inspectScroll, setInspectScroll] = useState2(0);
7537
+ const [layersScroll, setLayersScroll] = useState2(0);
7537
7538
  const inspectFromRef = useRef2("stream");
7538
7539
  const seenRef = useRef2(/* @__PURE__ */ new Set());
7539
7540
  const lastLocalTs = useRef2(0);
@@ -7706,20 +7707,45 @@ function LivePanel({ active: active2 }) {
7706
7707
  }, [active2, frozen]);
7707
7708
  const startRef = useRef2(Date.now());
7708
7709
  const lastNotifyAt = useRef2(0);
7710
+ const toastQueue = useRef2(/* @__PURE__ */ new Map());
7711
+ const toastTimer = useRef2(null);
7712
+ const TOAST_RANK = { "DLP hit": 0, "Call denied": 1, "Rate-limit burst": 2 };
7713
+ const flushToasts = useCallback2(function flush() {
7714
+ toastTimer.current = null;
7715
+ const q2 = toastQueue.current;
7716
+ if (!q2.size) return;
7717
+ const wait = 3e3 - (Date.now() - lastNotifyAt.current);
7718
+ if (wait > 0) {
7719
+ toastTimer.current = setTimeout(flush, wait);
7720
+ return;
7721
+ }
7722
+ lastNotifyAt.current = Date.now();
7723
+ const items = [...q2.entries()].sort((a, b) => (TOAST_RANK[a[0]] ?? 9) - (TOAST_RANK[b[0]] ?? 9));
7724
+ q2.clear();
7725
+ try {
7726
+ process.stdout.write("\x07");
7727
+ } catch {
7728
+ }
7729
+ const total = items.reduce((n, [, v]) => n + v.count, 0);
7730
+ if (items.length === 1 && total === 1) desktopNotify(items[0][0], items[0][1].msg);
7731
+ else desktopNotify("Security alerts", items.map(([t, v]) => `${v.count}\xD7 ${t}`).join(" \xB7 "));
7732
+ }, []);
7733
+ useEffect2(
7734
+ () => () => {
7735
+ if (toastTimer.current) clearTimeout(toastTimer.current);
7736
+ },
7737
+ []
7738
+ );
7709
7739
  const fireAlert = useCallback2(
7710
7740
  (id, title, msg, level = "warn", desktop = true) => {
7711
7741
  pushLog(`${level === "bad" ? "\u26D4" : "\u23F8"} ${msg}`, level);
7712
7742
  setAlerts((a) => [...a.filter((x) => x.id !== id), { id, msg, level, until: Date.now() + 15e3 }].slice(-4));
7713
7743
  if (!desktop || !CONFIG.notifications) return;
7714
- if (Date.now() - lastNotifyAt.current < 3e3) return;
7715
- lastNotifyAt.current = Date.now();
7716
- try {
7717
- process.stdout.write("\x07");
7718
- } catch {
7719
- }
7720
- desktopNotify(title, msg);
7744
+ const cur = toastQueue.current.get(title);
7745
+ toastQueue.current.set(title, { count: (cur?.count ?? 0) + 1, msg: cur?.msg ?? msg });
7746
+ if (!toastTimer.current) toastTimer.current = setTimeout(flushToasts, 400);
7721
7747
  },
7722
- [pushLog]
7748
+ [pushLog, flushToasts]
7723
7749
  );
7724
7750
  useEffect2(() => {
7725
7751
  if (!active2) return;
@@ -7908,6 +7934,14 @@ function LivePanel({ active: active2 }) {
7908
7934
  else if (key.pageDown) setInspectScroll((n) => n + 10);
7909
7935
  return;
7910
7936
  }
7937
+ if (mode === "layers") {
7938
+ if (key.leftArrow || input === "l") setMode("stream");
7939
+ else if (key.upArrow) setLayersScroll((n) => Math.max(0, n - 1));
7940
+ else if (key.downArrow) setLayersScroll((n) => n + 1);
7941
+ else if (key.pageUp) setLayersScroll((n) => Math.max(0, n - 10));
7942
+ else if (key.pageDown) setLayersScroll((n) => n + 10);
7943
+ return;
7944
+ }
7911
7945
  if (mode === "detail") {
7912
7946
  const maxD = Math.max(0, detailEntries.length - 1);
7913
7947
  if (key.leftArrow) {
@@ -7957,6 +7991,9 @@ function LivePanel({ active: active2 }) {
7957
7991
  } else if (input === "s") {
7958
7992
  setPickIdx(0);
7959
7993
  setMode("pick");
7994
+ } else if (input === "l") {
7995
+ setLayersScroll(0);
7996
+ setMode("layers");
7960
7997
  } else if (input === "w") void doAction("whitelist");
7961
7998
  else if (input === "b") void doAction("block");
7962
7999
  else if (input === "d") toggleSignal("deny");
@@ -8076,6 +8113,87 @@ function LivePanel({ active: active2 }) {
8076
8113
  ] })
8077
8114
  ] });
8078
8115
  }
8116
+ if (mode === "layers") {
8117
+ const modeColor4 = (m) => m === "block" || m === "on" ? theme.ok : m === "detect" ? theme.warn : theme.dim;
8118
+ const barW = Math.max(10, Math.min(40, innerW - 30));
8119
+ const burstsInBuf = mergedAll.filter((e) => e.burst).length;
8120
+ const dlpInBuf = mergedAll.filter((e) => e.dlp).length;
8121
+ const allHits = ins.dlpByPattern ?? [];
8122
+ const maxHit = allHits[0]?.count ?? 1;
8123
+ const L = [];
8124
+ const push2 = (el) => L.push(/* @__PURE__ */ jsx2(Box2, { children: el }, L.length));
8125
+ const blank = () => push2(/* @__PURE__ */ jsx2(Text2, { children: " " }));
8126
+ const section = (label, m, note) => push2(
8127
+ /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
8128
+ /* @__PURE__ */ jsxs2(Text2, { bold: true, color: theme.accentBright, children: [
8129
+ "\u258E",
8130
+ label.padEnd(10)
8131
+ ] }),
8132
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: modeColor4(m), children: (m ?? "?").padEnd(8) }),
8133
+ note ? /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: note }) : null
8134
+ ] })
8135
+ );
8136
+ const kv = (k, v) => push2(
8137
+ /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
8138
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: (" " + k).padEnd(16) }),
8139
+ v
8140
+ ] })
8141
+ );
8142
+ section("RATELIMIT", rl?.mode, rl?.mode === "block" ? "over-limit calls are DENIED" : rl?.mode === "detect" ? "over-limit calls are observed & flagged rl:yes" : "no limit enforcement");
8143
+ kv("limits", /* @__PURE__ */ jsx2(Text2, { children: rl?.perMinute || rl?.perHour || rl?.perDay ? `${rl?.perMinute || "\u2014"}/min \xB7 ${rl?.perHour || "\u2014"}/hour \xB7 ${rl?.perDay || "\u2014"}/day` : "none configured" }));
8144
+ kv("load now", /* @__PURE__ */ jsx2(Text2, { children: `${minuteNow} calls in the last 60s` }));
8145
+ if (rl?.perMinute) push2(/* @__PURE__ */ jsx2(HBar, { label: " load/min", value: minuteNow, max: rl.perMinute, width: barW, color: minuteNow > rl.perMinute ? theme.bad : theme.accent }));
8146
+ kv("bursts", /* @__PURE__ */ jsx2(Text2, { color: burstsInBuf ? theme.warn : theme.dim, children: `${burstsInBuf} flagged in the live buffer` }));
8147
+ blank();
8148
+ section("DLP", dl?.mode, dl?.mode === "block" ? "secrets in arguments are DENIED + redacted" : dl?.mode === "detect" ? "secrets observed & flagged dlp:yes, output redacted" : "no secret scanning");
8149
+ kv("hits", /* @__PURE__ */ jsx2(Text2, { color: dlpInBuf ? theme.bad : theme.dim, children: `${dlpInBuf} flagged in the live buffer` }));
8150
+ const builtin = dl?.patterns ?? [];
8151
+ kv("builtin", /* @__PURE__ */ jsx2(Text2, { children: builtin.length ? `${builtin.length} patterns enabled` : "none enabled" }));
8152
+ for (const line of wrapLines(builtin.join(" \xB7 "), Math.max(20, innerW - 18))) push2(/* @__PURE__ */ jsx2(Text2, { wrap: "truncate", color: theme.dim, children: " " + line }));
8153
+ const custom = dl?.custom ?? [];
8154
+ kv("custom", /* @__PURE__ */ jsx2(Text2, { children: custom.length ? `${custom.length} patterns` : "none" }));
8155
+ for (const c2 of custom)
8156
+ push2(
8157
+ /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
8158
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: " " }),
8159
+ /* @__PURE__ */ jsx2(Text2, { color: theme.accent, children: truncate2(c2.name ?? "custom", 24).padEnd(25) }),
8160
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: truncate2(c2.re ?? "", Math.max(10, innerW - 44)) })
8161
+ ] })
8162
+ );
8163
+ kv("pattern hits", /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: allHits.length ? "last 7 days" : "none in the last 7 days" }));
8164
+ for (const h of allHits) push2(/* @__PURE__ */ jsx2(HBar, { label: " " + truncate2(h.pattern, 10), value: h.count, max: maxHit, width: barW, color: theme.bad }));
8165
+ blank();
8166
+ section("GHOST", gh?.mode, gh?.mode === "on" ? "matching paths are hidden from agents" : "no hidden paths");
8167
+ const ghostPats = gh?.patterns ?? [];
8168
+ kv("patterns", /* @__PURE__ */ jsx2(Text2, { children: ghostPats.length ? `${ghostPats.length}` : "none" }));
8169
+ for (const line of wrapLines(ghostPats.join(" \xB7 "), Math.max(20, innerW - 18))) push2(/* @__PURE__ */ jsx2(Text2, { wrap: "truncate", color: theme.dim, children: " " + line }));
8170
+ blank();
8171
+ section("GUARD", guard.data ? guard.data.up_to_date ? "ok" : "stale" : "?", "the PreToolUse hook enforcing all of the above");
8172
+ kv(
8173
+ "hooks",
8174
+ guard.data ? /* @__PURE__ */ jsx2(Text2, { color: guard.data.up_to_date ? theme.ok : theme.warn, children: `v${guard.data.installed ?? "?"}${guard.data.up_to_date ? " (latest)" : ` \u2192 v${guard.data.latest} available`} \xB7 ${guard.data.device_count} device${guard.data.device_count === 1 ? "" : "s"}` }) : /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: "loading\u2026" })
8175
+ );
8176
+ kv("local eval", ring ? /* @__PURE__ */ jsx2(Text2, { color: theme.ok, children: `avg ${ring.avgMs}ms over ${ring.count} recent calls` }) : /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: "no local ring in cwd" }));
8177
+ const bodyRows = Math.max(4, rows - 5);
8178
+ const maxLScroll = Math.max(0, L.length - bodyRows);
8179
+ const lOff = Math.min(layersScroll, maxLScroll);
8180
+ const win = L.slice(lOff, lOff + bodyRows);
8181
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
8182
+ titleBar,
8183
+ /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
8184
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "white", bold: true, children: " LAYERS " }),
8185
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: " security layers, limits and patterns \xB7 insights window: last 7 days" }),
8186
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: " \u2190 back" })
8187
+ ] }),
8188
+ /* @__PURE__ */ jsx2(PaneTitle, { label: "LAYERS", extra: `${insights.data ? "" : spin + " loading \xB7 "}${maxLScroll ? `\u25BC${maxLScroll - lOff} more \xB7 \u2191\u2193 scroll \xB7 ` : ""}l or \u2190 back`, width: innerW }),
8189
+ /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", height: bodyRows, overflow: "hidden", children: win }),
8190
+ /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
8191
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "white", bold: true, children: " LAYERS " }),
8192
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#0b1530", color: "white", children: " rate limit \xB7 dlp \xB7 ghost \xB7 guard " }),
8193
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "white", children: " \u2191\u2193 scroll \xB7 ? all keys \xB7 \u2190 back \xB7 esc menu " })
8194
+ ] })
8195
+ ] });
8196
+ }
8079
8197
  if (mode === "detail" && detail) {
8080
8198
  const d = detailEntries;
8081
8199
  const allow = d.filter((e) => e.decision === "ALLOW").length;
@@ -8195,7 +8313,7 @@ function LivePanel({ active: active2 }) {
8195
8313
  ] }),
8196
8314
  /* @__PURE__ */ jsxs2(Box2, { height: colH, children: [
8197
8315
  /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", width: colW, marginRight: 2, overflow: "hidden", children: [
8198
- /* @__PURE__ */ jsx2(PaneTitle, { label: "LAYERS", width: colW }),
8316
+ /* @__PURE__ */ jsx2(PaneTitle, { label: "LAYERS", extra: "l = inspect", width: colW }),
8199
8317
  /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
8200
8318
  /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: "RATELIMIT ".padEnd(10) }),
8201
8319
  /* @__PURE__ */ jsx2(Text2, { color: rl?.mode === "block" ? theme.ok : rl?.mode === "detect" ? theme.warn : theme.dim, children: (rl?.mode ?? "?").padEnd(7) }),
@@ -8228,7 +8346,8 @@ function LivePanel({ active: active2 }) {
8228
8346
  " "
8229
8347
  ] }),
8230
8348
  /* @__PURE__ */ jsx2(Text2, { color: st.color, children: st.label.padEnd(7) }),
8231
- /* @__PURE__ */ jsx2(Text2, { color: theme.accentBright, children: truncate2(r.isMe ? "this machine" : r.agent, 12).padEnd(13) }),
8349
+ /* @__PURE__ */ jsx2(Text2, { color: theme.accentBright, children: truncate2(r.agent, r.isMe ? 9 : 12).padEnd(r.isMe ? 10 : 13) }),
8350
+ r.isMe ? /* @__PURE__ */ jsx2(Text2, { color: theme.ok, children: "me " }) : null,
8232
8351
  /* @__PURE__ */ jsxs2(Text2, { children: [
8233
8352
  String(r.calls).padStart(4),
8234
8353
  "c "
@@ -8323,6 +8442,7 @@ var init_Live = __esm({
8323
8442
  ["f", "source filter: all \u2192 local \u2192 cloud"],
8324
8443
  ["/", "live search (tool, agent, command\u2026) \xB7 enter done"],
8325
8444
  ["s", "session picker"],
8445
+ ["l", "layers detail (rate limit \xB7 dlp \xB7 ghost \xB7 guard)"],
8326
8446
  ["e", "export visible rows \u2192 ~/.solongate/live-export.jsonl"],
8327
8447
  ["space", "copy mode: freeze screen for mouse selection"],
8328
8448
  ["esc", "back to menu"],
package/dist/tui/index.js CHANGED
@@ -920,6 +920,7 @@ var LIVE_HELP = [
920
920
  ["f", "source filter: all \u2192 local \u2192 cloud"],
921
921
  ["/", "live search (tool, agent, command\u2026) \xB7 enter done"],
922
922
  ["s", "session picker"],
923
+ ["l", "layers detail (rate limit \xB7 dlp \xB7 ghost \xB7 guard)"],
923
924
  ["e", "export visible rows \u2192 ~/.solongate/live-export.jsonl"],
924
925
  ["space", "copy mode: freeze screen for mouse selection"],
925
926
  ["esc", "back to menu"],
@@ -970,6 +971,7 @@ function LivePanel({ active: active2 }) {
970
971
  const [detailScroll, setDetailScroll] = useState2(0);
971
972
  const [inspect, setInspect] = useState2(null);
972
973
  const [inspectScroll, setInspectScroll] = useState2(0);
974
+ const [layersScroll, setLayersScroll] = useState2(0);
973
975
  const inspectFromRef = useRef2("stream");
974
976
  const seenRef = useRef2(/* @__PURE__ */ new Set());
975
977
  const lastLocalTs = useRef2(0);
@@ -1142,20 +1144,45 @@ function LivePanel({ active: active2 }) {
1142
1144
  }, [active2, frozen]);
1143
1145
  const startRef = useRef2(Date.now());
1144
1146
  const lastNotifyAt = useRef2(0);
1147
+ const toastQueue = useRef2(/* @__PURE__ */ new Map());
1148
+ const toastTimer = useRef2(null);
1149
+ const TOAST_RANK = { "DLP hit": 0, "Call denied": 1, "Rate-limit burst": 2 };
1150
+ const flushToasts = useCallback2(function flush() {
1151
+ toastTimer.current = null;
1152
+ const q2 = toastQueue.current;
1153
+ if (!q2.size) return;
1154
+ const wait = 3e3 - (Date.now() - lastNotifyAt.current);
1155
+ if (wait > 0) {
1156
+ toastTimer.current = setTimeout(flush, wait);
1157
+ return;
1158
+ }
1159
+ lastNotifyAt.current = Date.now();
1160
+ const items = [...q2.entries()].sort((a, b) => (TOAST_RANK[a[0]] ?? 9) - (TOAST_RANK[b[0]] ?? 9));
1161
+ q2.clear();
1162
+ try {
1163
+ process.stdout.write("\x07");
1164
+ } catch {
1165
+ }
1166
+ const total = items.reduce((n, [, v]) => n + v.count, 0);
1167
+ if (items.length === 1 && total === 1) desktopNotify(items[0][0], items[0][1].msg);
1168
+ else desktopNotify("Security alerts", items.map(([t, v]) => `${v.count}\xD7 ${t}`).join(" \xB7 "));
1169
+ }, []);
1170
+ useEffect2(
1171
+ () => () => {
1172
+ if (toastTimer.current) clearTimeout(toastTimer.current);
1173
+ },
1174
+ []
1175
+ );
1145
1176
  const fireAlert = useCallback2(
1146
1177
  (id, title, msg, level = "warn", desktop = true) => {
1147
1178
  pushLog(`${level === "bad" ? "\u26D4" : "\u23F8"} ${msg}`, level);
1148
1179
  setAlerts((a) => [...a.filter((x) => x.id !== id), { id, msg, level, until: Date.now() + 15e3 }].slice(-4));
1149
1180
  if (!desktop || !CONFIG.notifications) return;
1150
- if (Date.now() - lastNotifyAt.current < 3e3) return;
1151
- lastNotifyAt.current = Date.now();
1152
- try {
1153
- process.stdout.write("\x07");
1154
- } catch {
1155
- }
1156
- desktopNotify(title, msg);
1181
+ const cur = toastQueue.current.get(title);
1182
+ toastQueue.current.set(title, { count: (cur?.count ?? 0) + 1, msg: cur?.msg ?? msg });
1183
+ if (!toastTimer.current) toastTimer.current = setTimeout(flushToasts, 400);
1157
1184
  },
1158
- [pushLog]
1185
+ [pushLog, flushToasts]
1159
1186
  );
1160
1187
  useEffect2(() => {
1161
1188
  if (!active2) return;
@@ -1344,6 +1371,14 @@ function LivePanel({ active: active2 }) {
1344
1371
  else if (key.pageDown) setInspectScroll((n) => n + 10);
1345
1372
  return;
1346
1373
  }
1374
+ if (mode === "layers") {
1375
+ if (key.leftArrow || input === "l") setMode("stream");
1376
+ else if (key.upArrow) setLayersScroll((n) => Math.max(0, n - 1));
1377
+ else if (key.downArrow) setLayersScroll((n) => n + 1);
1378
+ else if (key.pageUp) setLayersScroll((n) => Math.max(0, n - 10));
1379
+ else if (key.pageDown) setLayersScroll((n) => n + 10);
1380
+ return;
1381
+ }
1347
1382
  if (mode === "detail") {
1348
1383
  const maxD = Math.max(0, detailEntries.length - 1);
1349
1384
  if (key.leftArrow) {
@@ -1393,6 +1428,9 @@ function LivePanel({ active: active2 }) {
1393
1428
  } else if (input === "s") {
1394
1429
  setPickIdx(0);
1395
1430
  setMode("pick");
1431
+ } else if (input === "l") {
1432
+ setLayersScroll(0);
1433
+ setMode("layers");
1396
1434
  } else if (input === "w") void doAction("whitelist");
1397
1435
  else if (input === "b") void doAction("block");
1398
1436
  else if (input === "d") toggleSignal("deny");
@@ -1512,6 +1550,87 @@ function LivePanel({ active: active2 }) {
1512
1550
  ] })
1513
1551
  ] });
1514
1552
  }
1553
+ if (mode === "layers") {
1554
+ const modeColor2 = (m) => m === "block" || m === "on" ? theme.ok : m === "detect" ? theme.warn : theme.dim;
1555
+ const barW = Math.max(10, Math.min(40, innerW - 30));
1556
+ const burstsInBuf = mergedAll.filter((e) => e.burst).length;
1557
+ const dlpInBuf = mergedAll.filter((e) => e.dlp).length;
1558
+ const allHits = ins.dlpByPattern ?? [];
1559
+ const maxHit = allHits[0]?.count ?? 1;
1560
+ const L = [];
1561
+ const push = (el) => L.push(/* @__PURE__ */ jsx2(Box2, { children: el }, L.length));
1562
+ const blank = () => push(/* @__PURE__ */ jsx2(Text2, { children: " " }));
1563
+ const section = (label, m, note) => push(
1564
+ /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
1565
+ /* @__PURE__ */ jsxs2(Text2, { bold: true, color: theme.accentBright, children: [
1566
+ "\u258E",
1567
+ label.padEnd(10)
1568
+ ] }),
1569
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: modeColor2(m), children: (m ?? "?").padEnd(8) }),
1570
+ note ? /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: note }) : null
1571
+ ] })
1572
+ );
1573
+ const kv = (k, v) => push(
1574
+ /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
1575
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: (" " + k).padEnd(16) }),
1576
+ v
1577
+ ] })
1578
+ );
1579
+ section("RATELIMIT", rl?.mode, rl?.mode === "block" ? "over-limit calls are DENIED" : rl?.mode === "detect" ? "over-limit calls are observed & flagged rl:yes" : "no limit enforcement");
1580
+ kv("limits", /* @__PURE__ */ jsx2(Text2, { children: rl?.perMinute || rl?.perHour || rl?.perDay ? `${rl?.perMinute || "\u2014"}/min \xB7 ${rl?.perHour || "\u2014"}/hour \xB7 ${rl?.perDay || "\u2014"}/day` : "none configured" }));
1581
+ kv("load now", /* @__PURE__ */ jsx2(Text2, { children: `${minuteNow} calls in the last 60s` }));
1582
+ if (rl?.perMinute) push(/* @__PURE__ */ jsx2(HBar, { label: " load/min", value: minuteNow, max: rl.perMinute, width: barW, color: minuteNow > rl.perMinute ? theme.bad : theme.accent }));
1583
+ kv("bursts", /* @__PURE__ */ jsx2(Text2, { color: burstsInBuf ? theme.warn : theme.dim, children: `${burstsInBuf} flagged in the live buffer` }));
1584
+ blank();
1585
+ section("DLP", dl?.mode, dl?.mode === "block" ? "secrets in arguments are DENIED + redacted" : dl?.mode === "detect" ? "secrets observed & flagged dlp:yes, output redacted" : "no secret scanning");
1586
+ kv("hits", /* @__PURE__ */ jsx2(Text2, { color: dlpInBuf ? theme.bad : theme.dim, children: `${dlpInBuf} flagged in the live buffer` }));
1587
+ const builtin = dl?.patterns ?? [];
1588
+ kv("builtin", /* @__PURE__ */ jsx2(Text2, { children: builtin.length ? `${builtin.length} patterns enabled` : "none enabled" }));
1589
+ for (const line of wrapLines(builtin.join(" \xB7 "), Math.max(20, innerW - 18))) push(/* @__PURE__ */ jsx2(Text2, { wrap: "truncate", color: theme.dim, children: " " + line }));
1590
+ const custom = dl?.custom ?? [];
1591
+ kv("custom", /* @__PURE__ */ jsx2(Text2, { children: custom.length ? `${custom.length} patterns` : "none" }));
1592
+ for (const c2 of custom)
1593
+ push(
1594
+ /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
1595
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: " " }),
1596
+ /* @__PURE__ */ jsx2(Text2, { color: theme.accent, children: truncate(c2.name ?? "custom", 24).padEnd(25) }),
1597
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: truncate(c2.re ?? "", Math.max(10, innerW - 44)) })
1598
+ ] })
1599
+ );
1600
+ kv("pattern hits", /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: allHits.length ? "last 7 days" : "none in the last 7 days" }));
1601
+ for (const h of allHits) push(/* @__PURE__ */ jsx2(HBar, { label: " " + truncate(h.pattern, 10), value: h.count, max: maxHit, width: barW, color: theme.bad }));
1602
+ blank();
1603
+ section("GHOST", gh?.mode, gh?.mode === "on" ? "matching paths are hidden from agents" : "no hidden paths");
1604
+ const ghostPats = gh?.patterns ?? [];
1605
+ kv("patterns", /* @__PURE__ */ jsx2(Text2, { children: ghostPats.length ? `${ghostPats.length}` : "none" }));
1606
+ for (const line of wrapLines(ghostPats.join(" \xB7 "), Math.max(20, innerW - 18))) push(/* @__PURE__ */ jsx2(Text2, { wrap: "truncate", color: theme.dim, children: " " + line }));
1607
+ blank();
1608
+ section("GUARD", guard.data ? guard.data.up_to_date ? "ok" : "stale" : "?", "the PreToolUse hook enforcing all of the above");
1609
+ kv(
1610
+ "hooks",
1611
+ guard.data ? /* @__PURE__ */ jsx2(Text2, { color: guard.data.up_to_date ? theme.ok : theme.warn, children: `v${guard.data.installed ?? "?"}${guard.data.up_to_date ? " (latest)" : ` \u2192 v${guard.data.latest} available`} \xB7 ${guard.data.device_count} device${guard.data.device_count === 1 ? "" : "s"}` }) : /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: "loading\u2026" })
1612
+ );
1613
+ kv("local eval", ring ? /* @__PURE__ */ jsx2(Text2, { color: theme.ok, children: `avg ${ring.avgMs}ms over ${ring.count} recent calls` }) : /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: "no local ring in cwd" }));
1614
+ const bodyRows = Math.max(4, rows - 5);
1615
+ const maxLScroll = Math.max(0, L.length - bodyRows);
1616
+ const lOff = Math.min(layersScroll, maxLScroll);
1617
+ const win = L.slice(lOff, lOff + bodyRows);
1618
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
1619
+ titleBar,
1620
+ /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
1621
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "white", bold: true, children: " LAYERS " }),
1622
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: " security layers, limits and patterns \xB7 insights window: last 7 days" }),
1623
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: " \u2190 back" })
1624
+ ] }),
1625
+ /* @__PURE__ */ jsx2(PaneTitle, { label: "LAYERS", extra: `${insights.data ? "" : spin + " loading \xB7 "}${maxLScroll ? `\u25BC${maxLScroll - lOff} more \xB7 \u2191\u2193 scroll \xB7 ` : ""}l or \u2190 back`, width: innerW }),
1626
+ /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", height: bodyRows, overflow: "hidden", children: win }),
1627
+ /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
1628
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "white", bold: true, children: " LAYERS " }),
1629
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#0b1530", color: "white", children: " rate limit \xB7 dlp \xB7 ghost \xB7 guard " }),
1630
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "white", children: " \u2191\u2193 scroll \xB7 ? all keys \xB7 \u2190 back \xB7 esc menu " })
1631
+ ] })
1632
+ ] });
1633
+ }
1515
1634
  if (mode === "detail" && detail) {
1516
1635
  const d = detailEntries;
1517
1636
  const allow = d.filter((e) => e.decision === "ALLOW").length;
@@ -1631,7 +1750,7 @@ function LivePanel({ active: active2 }) {
1631
1750
  ] }),
1632
1751
  /* @__PURE__ */ jsxs2(Box2, { height: colH, children: [
1633
1752
  /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", width: colW, marginRight: 2, overflow: "hidden", children: [
1634
- /* @__PURE__ */ jsx2(PaneTitle, { label: "LAYERS", width: colW }),
1753
+ /* @__PURE__ */ jsx2(PaneTitle, { label: "LAYERS", extra: "l = inspect", width: colW }),
1635
1754
  /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
1636
1755
  /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: "RATELIMIT ".padEnd(10) }),
1637
1756
  /* @__PURE__ */ jsx2(Text2, { color: rl?.mode === "block" ? theme.ok : rl?.mode === "detect" ? theme.warn : theme.dim, children: (rl?.mode ?? "?").padEnd(7) }),
@@ -1664,7 +1783,8 @@ function LivePanel({ active: active2 }) {
1664
1783
  " "
1665
1784
  ] }),
1666
1785
  /* @__PURE__ */ jsx2(Text2, { color: st.color, children: st.label.padEnd(7) }),
1667
- /* @__PURE__ */ jsx2(Text2, { color: theme.accentBright, children: truncate(r.isMe ? "this machine" : r.agent, 12).padEnd(13) }),
1786
+ /* @__PURE__ */ jsx2(Text2, { color: theme.accentBright, children: truncate(r.agent, r.isMe ? 9 : 12).padEnd(r.isMe ? 10 : 13) }),
1787
+ r.isMe ? /* @__PURE__ */ jsx2(Text2, { color: theme.ok, children: "me " }) : null,
1668
1788
  /* @__PURE__ */ jsxs2(Text2, { children: [
1669
1789
  String(r.calls).padStart(4),
1670
1790
  "c "
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.81.43",
3
+ "version": "0.81.45",
4
4
  "description": "AI tool security proxy: protect any AI tool server with customizable policies, path/command constraints, rate limiting, and audit logging. No code changes required.",
5
5
  "type": "module",
6
6
  "bin": {