@solongate/proxy 0.81.20 → 0.81.22

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
@@ -7356,7 +7356,6 @@ function LivePanel({ active: active2 }) {
7356
7356
  const [actionMsg, setActionMsg] = useState2(null);
7357
7357
  const notifiedRef = useRef2(/* @__PURE__ */ new Set());
7358
7358
  const openedAtRef = useRef2(Date.now());
7359
- const activePolicyRef = useRef2(null);
7360
7359
  const [mode, setMode] = useState2("stream");
7361
7360
  const [pickIdx, setPickIdx] = useState2(0);
7362
7361
  const [detail, setDetail] = useState2(null);
@@ -7375,6 +7374,7 @@ function LivePanel({ active: active2 }) {
7375
7374
  const [frozen, setFrozen] = useState2(false);
7376
7375
  const frozenRef = useRef2(false);
7377
7376
  frozenRef.current = frozen;
7377
+ const [showHelp, setShowHelp] = useState2(false);
7378
7378
  const pushLog = useCallback2((msg, level = "ok") => {
7379
7379
  setLog((prev) => [...prev.slice(-59), { ts: Date.now(), msg, level }]);
7380
7380
  }, []);
@@ -7679,18 +7679,14 @@ function LivePanel({ active: active2 }) {
7679
7679
  }
7680
7680
  setActionMsg({ text: act === "whitelist" ? "whitelisting\u2026" : "blocking\u2026", level: "ok", until: Date.now() + 4e3 });
7681
7681
  try {
7682
+ const a = await api.policies.active();
7683
+ const pid = a.policy?.id ?? null;
7684
+ if (!pid) throw new Error("no active policy \u2014 rule NOT added. Activate a policy first (Policies section).");
7682
7685
  let res;
7683
7686
  if (e.source === "cloud") {
7684
7687
  const realId = e.id.slice(2);
7685
7688
  res = act === "whitelist" ? await api.audit.whitelist(realId) : await api.audit.block(realId);
7686
7689
  } else {
7687
- let pid = activePolicyRef.current;
7688
- if (!pid) {
7689
- const a = await api.policies.active();
7690
- pid = a.policy?.id ?? null;
7691
- activePolicyRef.current = pid;
7692
- }
7693
- if (!pid) throw new Error("no active policy resolves for this machine");
7694
7690
  const t = extractTarget(e.detail);
7695
7691
  res = await api.policies.addRule(pid, { toolPattern: e.tool, kind: t?.kind ?? "tool", value: t?.value, effect: act === "whitelist" ? "ALLOW" : "DENY" });
7696
7692
  }
@@ -7712,6 +7708,14 @@ function LivePanel({ active: active2 }) {
7712
7708
  return;
7713
7709
  }
7714
7710
  if (frozen) return;
7711
+ if (showHelp) {
7712
+ setShowHelp(false);
7713
+ return;
7714
+ }
7715
+ if (input === "?") {
7716
+ setShowHelp(true);
7717
+ return;
7718
+ }
7715
7719
  if (input === "/" && mode !== "pick") {
7716
7720
  setEditingSearch(true);
7717
7721
  return;
@@ -7834,6 +7838,20 @@ function LivePanel({ active: active2 }) {
7834
7838
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: ` ${spin} up ${fmtUp(nowMs - startRef.current)} \xB7 ${hhmmss(nowMs)} \xB7 api ${latNow}ms ` }),
7835
7839
  frozen ? /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#123d1f", color: "#7bd88f", bold: true, children: " \u23F5 COPY MODE \u2014 screen frozen, select & copy freely \xB7 space resume " }) : backingOff ? /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#3d2a12", color: "#ffb454", bold: true, children: " RATE LIMITED \xB7 backing off " }) : lastDeny ? /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#3d1220", color: "#ff6b6b", bold: true, children: ` \u26A0 ${hhmmss(lastDeny.at)} ${lastDeny.tool} DENIED ` }) : /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#4f6db8", children: " \u2713 clean " })
7836
7840
  ] });
7841
+ if (showHelp) {
7842
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
7843
+ titleBar,
7844
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: theme.accentBright, children: "LIVE \u2014 all keys" }),
7845
+ /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginTop: 1, children: LIVE_HELP.map(([group, keys]) => /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginBottom: 1, children: [
7846
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: theme.accent, children: group }),
7847
+ keys.map(([k, desc]) => /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
7848
+ /* @__PURE__ */ jsx2(Text2, { color: theme.accentBright, children: (" " + k).padEnd(20) }),
7849
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: desc })
7850
+ ] }, k))
7851
+ ] }, group)) }),
7852
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: "press any key to close" })
7853
+ ] });
7854
+ }
7837
7855
  if (mode === "inspect" && inspect) {
7838
7856
  const e = inspect;
7839
7857
  const bodyW = Math.max(20, cols - 4);
@@ -7876,7 +7894,7 @@ function LivePanel({ active: active2 }) {
7876
7894
  /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
7877
7895
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", bold: true, children: " ENTRY " }),
7878
7896
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#0b1530", color: "#4f6db8", children: ` ${e.id} ` }),
7879
- /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: " \u2191\u2193 scroll \xB7 space copy mode \xB7 \u2190 back \xB7 esc menu " })
7897
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: " \u2191\u2193 scroll \xB7 space copy \xB7 ? all keys \xB7 \u2190 back \xB7 esc menu " })
7880
7898
  ] })
7881
7899
  ] });
7882
7900
  }
@@ -7949,7 +7967,7 @@ function LivePanel({ active: active2 }) {
7949
7967
  /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
7950
7968
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", bold: true, children: " SESSION " }),
7951
7969
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#0b1530", color: "#4f6db8", children: ` ${detail.id} ` }),
7952
- /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: " \u2191\u2193 select \xB7 enter full entry \xB7 \u2190 back \xB7 esc menu " })
7970
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: " \u2191\u2193 select \xB7 enter full entry \xB7 ? all keys \xB7 \u2190 back \xB7 esc menu " })
7953
7971
  ] })
7954
7972
  ] });
7955
7973
  }
@@ -8062,7 +8080,7 @@ function LivePanel({ active: active2 }) {
8062
8080
  PaneTitle,
8063
8081
  {
8064
8082
  label: "TOOL STREAM",
8065
- extra: `${selClamped + 1}/${visibleDesc.length}${signal !== "none" ? ` \xB7 ${signal}` : ""}${q ? " \xB7 search" : ""} \xB7 \u2191\u2193 select \xB7 enter full \xB7 w allow \xB7 b block \xB7 d/x/r ${filter} \xB7 s`,
8083
+ extra: `${selClamped + 1}/${visibleDesc.length}${signal !== "none" ? ` \xB7 ${signal}` : ""}${q ? " \xB7 search" : ""}${filter !== "all" ? ` \xB7 source:${filter}` : ""} \xB7 enter full entry \xB7 ? all keys`,
8066
8084
  width: innerW
8067
8085
  }
8068
8086
  ),
@@ -8081,11 +8099,11 @@ function LivePanel({ active: active2 }) {
8081
8099
  /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
8082
8100
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", bold: true, children: " LIVE " }),
8083
8101
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#0b1530", color: "#4f6db8", children: ` local ${localOn ? "on" : "off"} \xB7 ${localBuf.length} loc/${cloudBuf.length} cld \xB7 top ${topTools.map(([t, c2]) => `${t}\xD7${c2}`).join(" ") || "\u2014"} ` }),
8084
- /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: " \u2191\u2193 select \xB7 enter full \xB7 w allow \xB7 b block \xB7 d/x/r \xB7 / search \xB7 f \xB7 s \xB7 space copy \xB7 esc \xB7 q " })
8102
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: ` \u2191\u2193 select \xB7 enter full entry \xB7 / search \xB7 space copy \xB7 ? all keys \xB7 esc menu \xB7 q quit ` })
8085
8103
  ] })
8086
8104
  ] });
8087
8105
  }
8088
- var CONFIG, SPIN, BG, DIM_FLOOR, LOCAL_LOG, RING, hhmmss, fmtUp, FILTERS, sessStatus, STATUS_STYLE;
8106
+ var CONFIG, SPIN, BG, DIM_FLOOR, LOCAL_LOG, RING, hhmmss, fmtUp, FILTERS, sessStatus, STATUS_STYLE, LIVE_HELP;
8089
8107
  var init_Live = __esm({
8090
8108
  "src/tui/panels/Live.tsx"() {
8091
8109
  "use strict";
@@ -8116,6 +8134,45 @@ var init_Live = __esm({
8116
8134
  idle: { dot: "\u25D0", label: "IDLE", color: theme.warn },
8117
8135
  ended: { dot: "\u25CB", label: "ENDED", color: theme.dim }
8118
8136
  };
8137
+ LIVE_HELP = [
8138
+ [
8139
+ "Stream",
8140
+ [
8141
+ ["\u2191\u2193 / PgUp PgDn", "select a row (window follows)"],
8142
+ ["enter", "open the FULL entry content"],
8143
+ ["w", "whitelist the selected DENY (adds ALLOW rule)"],
8144
+ ["b", "block the selected ALLOW (adds DENY rule)"],
8145
+ ["d / x / r", "filter: denies / dlp hits / rate-limit bursts"],
8146
+ ["f", "source filter: all \u2192 local \u2192 cloud"],
8147
+ ["/", "live search (tool, agent, command\u2026) \xB7 enter done"],
8148
+ ["s", "session picker"],
8149
+ ["e", "export visible rows \u2192 ~/.solongate/live-export.jsonl"],
8150
+ ["space", "copy mode: freeze screen for mouse selection"],
8151
+ ["esc", "back to menu"],
8152
+ ["q", "quit dataroom"]
8153
+ ]
8154
+ ],
8155
+ [
8156
+ "Entry (full content)",
8157
+ [
8158
+ ["\u2191\u2193 / PgUp PgDn", "scroll the content"],
8159
+ ["space", "copy mode (freeze, then select with mouse)"],
8160
+ ["\u2190", "back to where you came from"]
8161
+ ]
8162
+ ],
8163
+ [
8164
+ "Sessions",
8165
+ [
8166
+ ["\u2191\u2193 + enter", "pick & open a session (picker)"],
8167
+ ["s or \u2190", "cancel the picker"],
8168
+ ["\u2191\u2193", "select a timeline row (detail)"],
8169
+ ["enter", "full entry content of the selected row"],
8170
+ ["/", "search within the timeline"],
8171
+ ["\u2190", "back to stream"]
8172
+ ]
8173
+ ],
8174
+ ["Anywhere", [["?", "this help"], ["any key", "close this help"]]]
8175
+ ];
8119
8176
  }
8120
8177
  });
8121
8178
 
package/dist/tui/index.js CHANGED
@@ -745,6 +745,45 @@ var STATUS_STYLE = {
745
745
  idle: { dot: "\u25D0", label: "IDLE", color: theme.warn },
746
746
  ended: { dot: "\u25CB", label: "ENDED", color: theme.dim }
747
747
  };
748
+ var LIVE_HELP = [
749
+ [
750
+ "Stream",
751
+ [
752
+ ["\u2191\u2193 / PgUp PgDn", "select a row (window follows)"],
753
+ ["enter", "open the FULL entry content"],
754
+ ["w", "whitelist the selected DENY (adds ALLOW rule)"],
755
+ ["b", "block the selected ALLOW (adds DENY rule)"],
756
+ ["d / x / r", "filter: denies / dlp hits / rate-limit bursts"],
757
+ ["f", "source filter: all \u2192 local \u2192 cloud"],
758
+ ["/", "live search (tool, agent, command\u2026) \xB7 enter done"],
759
+ ["s", "session picker"],
760
+ ["e", "export visible rows \u2192 ~/.solongate/live-export.jsonl"],
761
+ ["space", "copy mode: freeze screen for mouse selection"],
762
+ ["esc", "back to menu"],
763
+ ["q", "quit dataroom"]
764
+ ]
765
+ ],
766
+ [
767
+ "Entry (full content)",
768
+ [
769
+ ["\u2191\u2193 / PgUp PgDn", "scroll the content"],
770
+ ["space", "copy mode (freeze, then select with mouse)"],
771
+ ["\u2190", "back to where you came from"]
772
+ ]
773
+ ],
774
+ [
775
+ "Sessions",
776
+ [
777
+ ["\u2191\u2193 + enter", "pick & open a session (picker)"],
778
+ ["s or \u2190", "cancel the picker"],
779
+ ["\u2191\u2193", "select a timeline row (detail)"],
780
+ ["enter", "full entry content of the selected row"],
781
+ ["/", "search within the timeline"],
782
+ ["\u2190", "back to stream"]
783
+ ]
784
+ ],
785
+ ["Anywhere", [["?", "this help"], ["any key", "close this help"]]]
786
+ ];
748
787
  function LivePanel({ active: active2 }) {
749
788
  const [s, setS] = useState2(null);
750
789
  const [lat, setLat] = useState2([]);
@@ -761,7 +800,6 @@ function LivePanel({ active: active2 }) {
761
800
  const [actionMsg, setActionMsg] = useState2(null);
762
801
  const notifiedRef = useRef2(/* @__PURE__ */ new Set());
763
802
  const openedAtRef = useRef2(Date.now());
764
- const activePolicyRef = useRef2(null);
765
803
  const [mode, setMode] = useState2("stream");
766
804
  const [pickIdx, setPickIdx] = useState2(0);
767
805
  const [detail, setDetail] = useState2(null);
@@ -780,6 +818,7 @@ function LivePanel({ active: active2 }) {
780
818
  const [frozen, setFrozen] = useState2(false);
781
819
  const frozenRef = useRef2(false);
782
820
  frozenRef.current = frozen;
821
+ const [showHelp, setShowHelp] = useState2(false);
783
822
  const pushLog = useCallback2((msg, level = "ok") => {
784
823
  setLog((prev) => [...prev.slice(-59), { ts: Date.now(), msg, level }]);
785
824
  }, []);
@@ -1084,18 +1123,14 @@ function LivePanel({ active: active2 }) {
1084
1123
  }
1085
1124
  setActionMsg({ text: act === "whitelist" ? "whitelisting\u2026" : "blocking\u2026", level: "ok", until: Date.now() + 4e3 });
1086
1125
  try {
1126
+ const a = await api.policies.active();
1127
+ const pid = a.policy?.id ?? null;
1128
+ if (!pid) throw new Error("no active policy \u2014 rule NOT added. Activate a policy first (Policies section).");
1087
1129
  let res;
1088
1130
  if (e.source === "cloud") {
1089
1131
  const realId = e.id.slice(2);
1090
1132
  res = act === "whitelist" ? await api.audit.whitelist(realId) : await api.audit.block(realId);
1091
1133
  } else {
1092
- let pid = activePolicyRef.current;
1093
- if (!pid) {
1094
- const a = await api.policies.active();
1095
- pid = a.policy?.id ?? null;
1096
- activePolicyRef.current = pid;
1097
- }
1098
- if (!pid) throw new Error("no active policy resolves for this machine");
1099
1134
  const t = extractTarget(e.detail);
1100
1135
  res = await api.policies.addRule(pid, { toolPattern: e.tool, kind: t?.kind ?? "tool", value: t?.value, effect: act === "whitelist" ? "ALLOW" : "DENY" });
1101
1136
  }
@@ -1117,6 +1152,14 @@ function LivePanel({ active: active2 }) {
1117
1152
  return;
1118
1153
  }
1119
1154
  if (frozen) return;
1155
+ if (showHelp) {
1156
+ setShowHelp(false);
1157
+ return;
1158
+ }
1159
+ if (input === "?") {
1160
+ setShowHelp(true);
1161
+ return;
1162
+ }
1120
1163
  if (input === "/" && mode !== "pick") {
1121
1164
  setEditingSearch(true);
1122
1165
  return;
@@ -1239,6 +1282,20 @@ function LivePanel({ active: active2 }) {
1239
1282
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: ` ${spin} up ${fmtUp(nowMs - startRef.current)} \xB7 ${hhmmss(nowMs)} \xB7 api ${latNow}ms ` }),
1240
1283
  frozen ? /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#123d1f", color: "#7bd88f", bold: true, children: " \u23F5 COPY MODE \u2014 screen frozen, select & copy freely \xB7 space resume " }) : backingOff ? /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#3d2a12", color: "#ffb454", bold: true, children: " RATE LIMITED \xB7 backing off " }) : lastDeny ? /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#3d1220", color: "#ff6b6b", bold: true, children: ` \u26A0 ${hhmmss(lastDeny.at)} ${lastDeny.tool} DENIED ` }) : /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#4f6db8", children: " \u2713 clean " })
1241
1284
  ] });
1285
+ if (showHelp) {
1286
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
1287
+ titleBar,
1288
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: theme.accentBright, children: "LIVE \u2014 all keys" }),
1289
+ /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginTop: 1, children: LIVE_HELP.map(([group, keys]) => /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginBottom: 1, children: [
1290
+ /* @__PURE__ */ jsx2(Text2, { bold: true, color: theme.accent, children: group }),
1291
+ keys.map(([k, desc]) => /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
1292
+ /* @__PURE__ */ jsx2(Text2, { color: theme.accentBright, children: (" " + k).padEnd(20) }),
1293
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: desc })
1294
+ ] }, k))
1295
+ ] }, group)) }),
1296
+ /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: "press any key to close" })
1297
+ ] });
1298
+ }
1242
1299
  if (mode === "inspect" && inspect) {
1243
1300
  const e = inspect;
1244
1301
  const bodyW = Math.max(20, cols - 4);
@@ -1281,7 +1338,7 @@ function LivePanel({ active: active2 }) {
1281
1338
  /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
1282
1339
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", bold: true, children: " ENTRY " }),
1283
1340
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#0b1530", color: "#4f6db8", children: ` ${e.id} ` }),
1284
- /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: " \u2191\u2193 scroll \xB7 space copy mode \xB7 \u2190 back \xB7 esc menu " })
1341
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: " \u2191\u2193 scroll \xB7 space copy \xB7 ? all keys \xB7 \u2190 back \xB7 esc menu " })
1285
1342
  ] })
1286
1343
  ] });
1287
1344
  }
@@ -1354,7 +1411,7 @@ function LivePanel({ active: active2 }) {
1354
1411
  /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
1355
1412
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", bold: true, children: " SESSION " }),
1356
1413
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#0b1530", color: "#4f6db8", children: ` ${detail.id} ` }),
1357
- /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: " \u2191\u2193 select \xB7 enter full entry \xB7 \u2190 back \xB7 esc menu " })
1414
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: " \u2191\u2193 select \xB7 enter full entry \xB7 ? all keys \xB7 \u2190 back \xB7 esc menu " })
1358
1415
  ] })
1359
1416
  ] });
1360
1417
  }
@@ -1467,7 +1524,7 @@ function LivePanel({ active: active2 }) {
1467
1524
  PaneTitle,
1468
1525
  {
1469
1526
  label: "TOOL STREAM",
1470
- extra: `${selClamped + 1}/${visibleDesc.length}${signal !== "none" ? ` \xB7 ${signal}` : ""}${q ? " \xB7 search" : ""} \xB7 \u2191\u2193 select \xB7 enter full \xB7 w allow \xB7 b block \xB7 d/x/r ${filter} \xB7 s`,
1527
+ extra: `${selClamped + 1}/${visibleDesc.length}${signal !== "none" ? ` \xB7 ${signal}` : ""}${q ? " \xB7 search" : ""}${filter !== "all" ? ` \xB7 source:${filter}` : ""} \xB7 enter full entry \xB7 ? all keys`,
1471
1528
  width: innerW
1472
1529
  }
1473
1530
  ),
@@ -1486,7 +1543,7 @@ function LivePanel({ active: active2 }) {
1486
1543
  /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
1487
1544
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", bold: true, children: " LIVE " }),
1488
1545
  /* @__PURE__ */ jsx2(Text2, { backgroundColor: "#0b1530", color: "#4f6db8", children: ` local ${localOn ? "on" : "off"} \xB7 ${localBuf.length} loc/${cloudBuf.length} cld \xB7 top ${topTools.map(([t, c2]) => `${t}\xD7${c2}`).join(" ") || "\u2014"} ` }),
1489
- /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: " \u2191\u2193 select \xB7 enter full \xB7 w allow \xB7 b block \xB7 d/x/r \xB7 / search \xB7 f \xB7 s \xB7 space copy \xB7 esc \xB7 q " })
1546
+ /* @__PURE__ */ jsx2(Text2, { backgroundColor: BG, color: "#82AAF0", children: ` \u2191\u2193 select \xB7 enter full entry \xB7 / search \xB7 space copy \xB7 ? all keys \xB7 esc menu \xB7 q quit ` })
1490
1547
  ] })
1491
1548
  ] });
1492
1549
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.81.20",
3
+ "version": "0.81.22",
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": {