@solongate/proxy 0.81.93 → 0.81.95
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 +49 -30
- package/dist/tui/index.js +49 -30
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8849,7 +8849,7 @@ function PoliciesPanel({ focused }) {
|
|
|
8849
8849
|
usePoll(() => {
|
|
8850
8850
|
list6.reloadQuiet();
|
|
8851
8851
|
activeQ.reloadQuiet();
|
|
8852
|
-
},
|
|
8852
|
+
}, 3e3);
|
|
8853
8853
|
const mutate = (nextRules, nextMode = mode) => {
|
|
8854
8854
|
setRules(nextRules);
|
|
8855
8855
|
setMode(nextMode);
|
|
@@ -8886,11 +8886,11 @@ function PoliciesPanel({ focused }) {
|
|
|
8886
8886
|
};
|
|
8887
8887
|
useInput2(
|
|
8888
8888
|
(input, key) => {
|
|
8889
|
-
if (input === "r" && !editing) {
|
|
8889
|
+
if (key.ctrl && input === "r" && !editing) {
|
|
8890
8890
|
list6.reload();
|
|
8891
8891
|
activeQ.reload();
|
|
8892
8892
|
detail.reload();
|
|
8893
|
-
setStatus(
|
|
8893
|
+
setStatus(`\u27F3 refreshed ${(/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false })}`);
|
|
8894
8894
|
return;
|
|
8895
8895
|
}
|
|
8896
8896
|
if (view === "list") {
|
|
@@ -8983,7 +8983,7 @@ function PoliciesPanel({ focused }) {
|
|
|
8983
8983
|
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: activeBy ? ` (${activeBy})` : "" })
|
|
8984
8984
|
] }) : /* @__PURE__ */ jsx3(Text3, { color: theme.bad, bold: true, children: "\u25CB NONE \u2014 nothing enforced, grants refused" })
|
|
8985
8985
|
] }),
|
|
8986
|
-
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: focused ? "\u2191\u2193 select \xB7 enter open \xB7 a activate \xB7 x deactivate \xB7
|
|
8986
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: focused ? "\u2191\u2193 select \xB7 enter open \xB7 a activate \xB7 x deactivate \xB7 ^R refresh" : "press \u2192 to browse" }),
|
|
8987
8987
|
/* @__PURE__ */ jsx3(Box3, { marginTop: 1, flexDirection: "column", children: policies.map((p, i) => /* @__PURE__ */ jsxs3(Text3, { color: i === pi ? theme.accentBright : void 0, bold: i === pi, children: [
|
|
8988
8988
|
(i === pi ? "\u25B8 " : " ") + truncate2(p.name, 26).padEnd(27),
|
|
8989
8989
|
/* @__PURE__ */ jsxs3(Text3, { color: theme.dim, children: [
|
|
@@ -9103,7 +9103,7 @@ var init_Policies = __esm({
|
|
|
9103
9103
|
// src/tui/panels/RateLimit.tsx
|
|
9104
9104
|
import { Box as Box4, Text as Text4, useInput as useInput3 } from "ink";
|
|
9105
9105
|
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
9106
|
-
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
9106
|
+
import { Fragment as Fragment4, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
9107
9107
|
function RateLimitPanel({ focused }) {
|
|
9108
9108
|
const { cols, rows } = usePanelSize();
|
|
9109
9109
|
const layersQ = useLoader(() => api.settings.getSecurityLayers());
|
|
@@ -9118,9 +9118,11 @@ function RateLimitPanel({ focused }) {
|
|
|
9118
9118
|
}, [layersQ.data]);
|
|
9119
9119
|
usePoll(() => {
|
|
9120
9120
|
if (!dirty) layersQ.reloadQuiet();
|
|
9121
|
+
}, 3e3);
|
|
9122
|
+
usePoll(() => {
|
|
9121
9123
|
historyQ.reloadQuiet();
|
|
9122
9124
|
insightsQ.reloadQuiet();
|
|
9123
|
-
},
|
|
9125
|
+
}, 1e4);
|
|
9124
9126
|
const adjust = (dir, step) => {
|
|
9125
9127
|
if (!draft) return;
|
|
9126
9128
|
const field = FIELDS2[fi];
|
|
@@ -9152,11 +9154,11 @@ function RateLimitPanel({ focused }) {
|
|
|
9152
9154
|
else if (key.leftArrow) adjust(-1, step);
|
|
9153
9155
|
else if (key.rightArrow) adjust(1, step);
|
|
9154
9156
|
else if (input === "s") void save();
|
|
9155
|
-
else if (input === "r") {
|
|
9157
|
+
else if (key.ctrl && input === "r") {
|
|
9156
9158
|
layersQ.reload();
|
|
9157
9159
|
historyQ.reload();
|
|
9158
9160
|
insightsQ.reload();
|
|
9159
|
-
setStatus(
|
|
9161
|
+
setStatus(`\u27F3 refreshed ${when(Date.now())}`);
|
|
9160
9162
|
}
|
|
9161
9163
|
},
|
|
9162
9164
|
{ isActive: focused }
|
|
@@ -9171,12 +9173,13 @@ function RateLimitPanel({ focused }) {
|
|
|
9171
9173
|
const loadPct = lim > 0 ? Math.min(100, Math.round(now / lim * 100)) : 0;
|
|
9172
9174
|
const last24h = (insightsQ.data?.["activity"]?.hour ?? []).reduce((s, b) => s + b.count, 0);
|
|
9173
9175
|
const hasLoad = lim > 0;
|
|
9174
|
-
const
|
|
9176
|
+
const showExtras = rows >= 20;
|
|
9177
|
+
const fixed = 1 + 4 + (showExtras ? (hasLoad ? 1 : 0) + 5 : 0) + 1 + 1 + 1;
|
|
9175
9178
|
const burstBudget = Math.max(1, rows - fixed);
|
|
9176
9179
|
const shown = anomalies2.slice(0, burstBudget);
|
|
9177
9180
|
const bw = Math.max(10, cols - 30);
|
|
9178
9181
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", height: rows, overflow: "hidden", children: [
|
|
9179
|
-
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 field \xB7 \u2190\u2192 \xB11 \xB7 shift+\u2190\u2192 \xB110 \xB7 s save \xB7
|
|
9182
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 field \xB7 \u2190\u2192 \xB11 \xB7 shift+\u2190\u2192 \xB110 \xB7 s save \xB7 ^R refresh" : "press \u2192 to edit" }),
|
|
9180
9183
|
/* @__PURE__ */ jsxs4(FieldRow, { label: "Mode", active: focused && fi === 0, children: [
|
|
9181
9184
|
/* @__PURE__ */ jsx4(Text4, { color: modeColor(draft.mode), bold: true, children: draft.mode }),
|
|
9182
9185
|
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: draft.mode === "off" ? " no limit" : draft.mode === "detect" ? " flag bursts, never block" : " DENY calls over the limit" })
|
|
@@ -9184,20 +9187,22 @@ function RateLimitPanel({ focused }) {
|
|
|
9184
9187
|
/* @__PURE__ */ jsx4(FieldRow, { label: "Per minute", active: focused && fi === 1, children: /* @__PURE__ */ jsx4(Text4, { bold: true, children: draft.perMinute || "off" }) }),
|
|
9185
9188
|
/* @__PURE__ */ jsx4(FieldRow, { label: "Per hour", active: focused && fi === 2, children: /* @__PURE__ */ jsx4(Text4, { bold: true, children: draft.perHour || "off" }) }),
|
|
9186
9189
|
/* @__PURE__ */ jsx4(FieldRow, { label: "Per day", active: focused && fi === 3, children: /* @__PURE__ */ jsx4(Text4, { bold: true, children: draft.perDay || "off" }) }),
|
|
9187
|
-
|
|
9188
|
-
/* @__PURE__ */
|
|
9189
|
-
|
|
9190
|
-
|
|
9191
|
-
|
|
9192
|
-
|
|
9193
|
-
|
|
9194
|
-
|
|
9195
|
-
|
|
9190
|
+
showExtras && /* @__PURE__ */ jsxs4(Fragment4, { children: [
|
|
9191
|
+
hasLoad ? /* @__PURE__ */ jsxs4(Text4, { wrap: "truncate", children: [
|
|
9192
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: "load now".padEnd(13) }),
|
|
9193
|
+
/* @__PURE__ */ jsx4(Text4, { color: loadPct >= 100 ? theme.bad : loadPct >= 80 ? theme.warn : theme.ok, children: "\u2588".repeat(Math.min(18, Math.round(now / lim * 18))) }),
|
|
9194
|
+
/* @__PURE__ */ jsx4(Text4, { color: "#233457", children: "\u2591".repeat(Math.max(0, 18 - Math.round(now / lim * 18))) }),
|
|
9195
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: ` ${now}/${lim} this minute (${loadPct}%)` })
|
|
9196
|
+
] }) : null,
|
|
9197
|
+
/* @__PURE__ */ jsxs4(Text4, { color: theme.accentBright, bold: true, wrap: "truncate", children: [
|
|
9198
|
+
"Busiest 7d",
|
|
9199
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: " most calls in one window vs your limit" })
|
|
9200
|
+
] }),
|
|
9201
|
+
/* @__PURE__ */ jsx4(BusiestRow, { label: "minute", peak: peaks.minute, limit: draft.perMinute }),
|
|
9202
|
+
/* @__PURE__ */ jsx4(BusiestRow, { label: "hour", peak: peaks.hour, limit: draft.perHour }),
|
|
9203
|
+
/* @__PURE__ */ jsx4(BusiestRow, { label: "day", peak: peaks.day, limit: draft.perDay }),
|
|
9204
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: `activity`.padEnd(11) + ` last 24h \xB7 ${last24h} calls \xB7 busiest hour ${peaks.hour}/hr` })
|
|
9196
9205
|
] }),
|
|
9197
|
-
/* @__PURE__ */ jsx4(BusiestRow, { label: "minute", peak: peaks.minute, limit: draft.perMinute }),
|
|
9198
|
-
/* @__PURE__ */ jsx4(BusiestRow, { label: "hour", peak: peaks.hour, limit: draft.perHour }),
|
|
9199
|
-
/* @__PURE__ */ jsx4(BusiestRow, { label: "day", peak: peaks.day, limit: draft.perDay }),
|
|
9200
|
-
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: `activity`.padEnd(11) + ` last 24h \xB7 ${last24h} calls \xB7 busiest hour ${peaks.hour}/hr` }),
|
|
9201
9206
|
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
9202
9207
|
/* @__PURE__ */ jsxs4(Text4, { color: theme.accentBright, bold: true, wrap: "truncate", children: [
|
|
9203
9208
|
`Recent bursts 7d${anomalies2.length ? ` (${anomalies2.length})` : ""}`,
|
|
@@ -9289,7 +9294,7 @@ function DlpPanel({ focused }) {
|
|
|
9289
9294
|
}, [q.data]);
|
|
9290
9295
|
usePoll(() => {
|
|
9291
9296
|
if (!dirty && !adding) q.reloadQuiet();
|
|
9292
|
-
},
|
|
9297
|
+
}, 3e3);
|
|
9293
9298
|
const mutate = (next) => {
|
|
9294
9299
|
setDlp(next);
|
|
9295
9300
|
setDirty(true);
|
|
@@ -9329,6 +9334,11 @@ function DlpPanel({ focused }) {
|
|
|
9329
9334
|
useInput4(
|
|
9330
9335
|
(input2, key) => {
|
|
9331
9336
|
if (!dlp) return;
|
|
9337
|
+
if (key.ctrl && input2 === "r") {
|
|
9338
|
+
q.reload();
|
|
9339
|
+
setStatus(`\u27F3 refreshed ${(/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false })}`);
|
|
9340
|
+
return;
|
|
9341
|
+
}
|
|
9332
9342
|
if (key.upArrow) setSel(() => Math.max(0, selC - 1));
|
|
9333
9343
|
else if (key.downArrow) setSel(() => Math.min(entries.length - 1, selC + 1));
|
|
9334
9344
|
else if (input2 === "m") mutate({ ...dlp, mode: MODES2[(MODES2.indexOf(dlp.mode) + 1) % MODES2.length] });
|
|
@@ -9434,7 +9444,7 @@ function DlpPanel({ focused }) {
|
|
|
9434
9444
|
/* @__PURE__ */ jsx5(Text5, { color: theme.dim, children: dlp.mode === "off" ? " (scanning disabled)" : dlp.mode === "detect" ? " (flag dlp:yes, redact output)" : " (deny + redact secrets)" }),
|
|
9435
9445
|
dirty ? /* @__PURE__ */ jsx5(Text5, { color: theme.warn, children: " \u25CF unsaved (s save \xB7 x discard)" }) : null
|
|
9436
9446
|
] }),
|
|
9437
|
-
/* @__PURE__ */ jsx5(Text5, { color: theme.dim, wrap: "truncate", children: focused ? `\u2191\u2193 move \xB7 space on/off \xB7 m mode \xB7 a add pattern \xB7 r add route \xB7 d remove \xB7 g ghost \xB7 s save${moreAbove ? ` \xB7 \u25B2${moreAbove}` : ""}${moreBelow ? ` \xB7 \u25BC${moreBelow}` : ""}` : "press \u2192 to edit" }),
|
|
9447
|
+
/* @__PURE__ */ jsx5(Text5, { color: theme.dim, wrap: "truncate", children: focused ? `\u2191\u2193 move \xB7 space on/off \xB7 m mode \xB7 a add pattern \xB7 r add route \xB7 d remove \xB7 g ghost \xB7 s save \xB7 ^R refresh${moreAbove ? ` \xB7 \u25B2${moreAbove}` : ""}${moreBelow ? ` \xB7 \u25BC${moreBelow}` : ""}` : "press \u2192 to edit" }),
|
|
9438
9448
|
adding ? /* @__PURE__ */ jsx5(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
9439
9449
|
/* @__PURE__ */ jsx5(Text5, { color: theme.warn, children: adding === "name" ? "new pattern name: " : adding === "re" ? `pattern for "${newName}" (glob, * = any chars, e.g. sk-* AKIA*): ` : "ghost path to hide (glob, * = any chars, e.g. */.env *.pem): " }),
|
|
9440
9450
|
/* @__PURE__ */ jsx5(
|
|
@@ -9656,6 +9666,15 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9656
9666
|
return;
|
|
9657
9667
|
}
|
|
9658
9668
|
if (frozen) return;
|
|
9669
|
+
if (key.ctrl && input === "r") {
|
|
9670
|
+
if (source === "cloud") {
|
|
9671
|
+
cloudQ.reload();
|
|
9672
|
+
agentsQ.reload();
|
|
9673
|
+
statsQ.reloadQuiet();
|
|
9674
|
+
} else localQ.reload();
|
|
9675
|
+
setMsg({ text: `\u27F3 refreshed ${(/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false })}`, level: "ok" });
|
|
9676
|
+
return;
|
|
9677
|
+
}
|
|
9659
9678
|
if (showHelp) {
|
|
9660
9679
|
setShowHelp(false);
|
|
9661
9680
|
return;
|
|
@@ -9908,7 +9927,7 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9908
9927
|
chip("status", SESS_STATUS[si] ?? "all", si !== 0),
|
|
9909
9928
|
chip("search", sessSearch || "\xB7", !!sessSearch)
|
|
9910
9929
|
] }),
|
|
9911
|
-
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 select \xB7 enter \u2192 session logs \xB7 v logs \xB7 ? all keys" : "press \u2192 to browse" }),
|
|
9930
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 select \xB7 enter \u2192 session logs \xB7 v logs \xB7 ^R refresh \xB7 ? all keys" : "press \u2192 to browse" }),
|
|
9912
9931
|
editing === "sess-search" ? /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
9913
9932
|
/* @__PURE__ */ jsx6(Text6, { color: theme.warn, children: "search: " }),
|
|
9914
9933
|
/* @__PURE__ */ jsx6(
|
|
@@ -9982,7 +10001,7 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9982
10001
|
chip("search", search || "\xB7", !!search),
|
|
9983
10002
|
sessFilter ? chip("sess", sessFilter.slice(0, 8), true) : null
|
|
9984
10003
|
] }),
|
|
9985
|
-
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 select \xB7 enter full entry \xB7 \u2190\u2192 page \xB7 v sessions \xB7 ? all keys" : "press \u2192 to browse" }),
|
|
10004
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 select \xB7 enter full entry \xB7 \u2190\u2192 page \xB7 v sessions \xB7 ^R refresh \xB7 ? all keys" : "press \u2192 to browse" }),
|
|
9986
10005
|
msg ? /* @__PURE__ */ jsx6(Text6, { color: msg.level === "bad" ? theme.bad : theme.ok, children: truncate2(msg.text, cols) }) : null,
|
|
9987
10006
|
editing && editing !== "sess-search" ? /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
9988
10007
|
/* @__PURE__ */ jsxs6(Text6, { color: theme.warn, children: [
|
|
@@ -10346,7 +10365,7 @@ var init_global_install = __esm({
|
|
|
10346
10365
|
import { Box as Box7, Text as Text7, useInput as useInput6 } from "ink";
|
|
10347
10366
|
import TextInput5 from "ink-text-input";
|
|
10348
10367
|
import { useEffect as useEffect6, useRef as useRef3, useState as useState7 } from "react";
|
|
10349
|
-
import { Fragment as
|
|
10368
|
+
import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
10350
10369
|
function SettingsPanel({
|
|
10351
10370
|
active: active2,
|
|
10352
10371
|
focused,
|
|
@@ -10817,11 +10836,11 @@ function SettingsPanel({
|
|
|
10817
10836
|
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10818
10837
|
cursor(r),
|
|
10819
10838
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "guard".padEnd(11) }),
|
|
10820
|
-
!guardHere ? /* @__PURE__ */ jsxs7(
|
|
10839
|
+
!guardHere ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
10821
10840
|
/* @__PURE__ */ jsx7(Text7, { color: theme.bad, bold: true, children: "removed" }),
|
|
10822
10841
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " \xB7 " }),
|
|
10823
10842
|
/* @__PURE__ */ jsx7(Text7, { color: theme.accentBright, children: "enter to install" })
|
|
10824
|
-
] }) : /* @__PURE__ */ jsxs7(
|
|
10843
|
+
] }) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
10825
10844
|
/* @__PURE__ */ jsx7(Text7, { color: guardOld ? theme.warn : theme.ok, children: `v${guardVer ?? "?"}` }),
|
|
10826
10845
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: guardOld ? " \xB7 update available \xB7 enter update" : " (latest) \xB7 enter reinstall" }),
|
|
10827
10846
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " \xB7 d remove" })
|
package/dist/tui/index.js
CHANGED
|
@@ -1962,7 +1962,7 @@ function PoliciesPanel({ focused }) {
|
|
|
1962
1962
|
usePoll(() => {
|
|
1963
1963
|
list5.reloadQuiet();
|
|
1964
1964
|
activeQ.reloadQuiet();
|
|
1965
|
-
},
|
|
1965
|
+
}, 3e3);
|
|
1966
1966
|
const mutate = (nextRules, nextMode = mode) => {
|
|
1967
1967
|
setRules(nextRules);
|
|
1968
1968
|
setMode(nextMode);
|
|
@@ -1999,11 +1999,11 @@ function PoliciesPanel({ focused }) {
|
|
|
1999
1999
|
};
|
|
2000
2000
|
useInput2(
|
|
2001
2001
|
(input, key) => {
|
|
2002
|
-
if (input === "r" && !editing) {
|
|
2002
|
+
if (key.ctrl && input === "r" && !editing) {
|
|
2003
2003
|
list5.reload();
|
|
2004
2004
|
activeQ.reload();
|
|
2005
2005
|
detail.reload();
|
|
2006
|
-
setStatus(
|
|
2006
|
+
setStatus(`\u27F3 refreshed ${(/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false })}`);
|
|
2007
2007
|
return;
|
|
2008
2008
|
}
|
|
2009
2009
|
if (view === "list") {
|
|
@@ -2096,7 +2096,7 @@ function PoliciesPanel({ focused }) {
|
|
|
2096
2096
|
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: activeBy ? ` (${activeBy})` : "" })
|
|
2097
2097
|
] }) : /* @__PURE__ */ jsx3(Text3, { color: theme.bad, bold: true, children: "\u25CB NONE \u2014 nothing enforced, grants refused" })
|
|
2098
2098
|
] }),
|
|
2099
|
-
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: focused ? "\u2191\u2193 select \xB7 enter open \xB7 a activate \xB7 x deactivate \xB7
|
|
2099
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: focused ? "\u2191\u2193 select \xB7 enter open \xB7 a activate \xB7 x deactivate \xB7 ^R refresh" : "press \u2192 to browse" }),
|
|
2100
2100
|
/* @__PURE__ */ jsx3(Box3, { marginTop: 1, flexDirection: "column", children: policies.map((p, i) => /* @__PURE__ */ jsxs3(Text3, { color: i === pi ? theme.accentBright : void 0, bold: i === pi, children: [
|
|
2101
2101
|
(i === pi ? "\u25B8 " : " ") + truncate(p.name, 26).padEnd(27),
|
|
2102
2102
|
/* @__PURE__ */ jsxs3(Text3, { color: theme.dim, children: [
|
|
@@ -2185,7 +2185,7 @@ function PoliciesPanel({ focused }) {
|
|
|
2185
2185
|
// src/tui/panels/RateLimit.tsx
|
|
2186
2186
|
import { Box as Box4, Text as Text4, useInput as useInput3 } from "ink";
|
|
2187
2187
|
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
2188
|
-
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2188
|
+
import { Fragment as Fragment4, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2189
2189
|
var MODES = ["off", "detect", "block"];
|
|
2190
2190
|
var FIELDS2 = ["mode", "perMinute", "perHour", "perDay"];
|
|
2191
2191
|
var when = (ms) => {
|
|
@@ -2206,9 +2206,11 @@ function RateLimitPanel({ focused }) {
|
|
|
2206
2206
|
}, [layersQ.data]);
|
|
2207
2207
|
usePoll(() => {
|
|
2208
2208
|
if (!dirty) layersQ.reloadQuiet();
|
|
2209
|
+
}, 3e3);
|
|
2210
|
+
usePoll(() => {
|
|
2209
2211
|
historyQ.reloadQuiet();
|
|
2210
2212
|
insightsQ.reloadQuiet();
|
|
2211
|
-
},
|
|
2213
|
+
}, 1e4);
|
|
2212
2214
|
const adjust = (dir, step) => {
|
|
2213
2215
|
if (!draft) return;
|
|
2214
2216
|
const field = FIELDS2[fi];
|
|
@@ -2240,11 +2242,11 @@ function RateLimitPanel({ focused }) {
|
|
|
2240
2242
|
else if (key.leftArrow) adjust(-1, step);
|
|
2241
2243
|
else if (key.rightArrow) adjust(1, step);
|
|
2242
2244
|
else if (input === "s") void save();
|
|
2243
|
-
else if (input === "r") {
|
|
2245
|
+
else if (key.ctrl && input === "r") {
|
|
2244
2246
|
layersQ.reload();
|
|
2245
2247
|
historyQ.reload();
|
|
2246
2248
|
insightsQ.reload();
|
|
2247
|
-
setStatus(
|
|
2249
|
+
setStatus(`\u27F3 refreshed ${when(Date.now())}`);
|
|
2248
2250
|
}
|
|
2249
2251
|
},
|
|
2250
2252
|
{ isActive: focused }
|
|
@@ -2259,12 +2261,13 @@ function RateLimitPanel({ focused }) {
|
|
|
2259
2261
|
const loadPct = lim > 0 ? Math.min(100, Math.round(now / lim * 100)) : 0;
|
|
2260
2262
|
const last24h = (insightsQ.data?.["activity"]?.hour ?? []).reduce((s, b) => s + b.count, 0);
|
|
2261
2263
|
const hasLoad = lim > 0;
|
|
2262
|
-
const
|
|
2264
|
+
const showExtras = rows >= 20;
|
|
2265
|
+
const fixed = 1 + 4 + (showExtras ? (hasLoad ? 1 : 0) + 5 : 0) + 1 + 1 + 1;
|
|
2263
2266
|
const burstBudget = Math.max(1, rows - fixed);
|
|
2264
2267
|
const shown = anomalies2.slice(0, burstBudget);
|
|
2265
2268
|
const bw = Math.max(10, cols - 30);
|
|
2266
2269
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", height: rows, overflow: "hidden", children: [
|
|
2267
|
-
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 field \xB7 \u2190\u2192 \xB11 \xB7 shift+\u2190\u2192 \xB110 \xB7 s save \xB7
|
|
2270
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 field \xB7 \u2190\u2192 \xB11 \xB7 shift+\u2190\u2192 \xB110 \xB7 s save \xB7 ^R refresh" : "press \u2192 to edit" }),
|
|
2268
2271
|
/* @__PURE__ */ jsxs4(FieldRow, { label: "Mode", active: focused && fi === 0, children: [
|
|
2269
2272
|
/* @__PURE__ */ jsx4(Text4, { color: modeColor(draft.mode), bold: true, children: draft.mode }),
|
|
2270
2273
|
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: draft.mode === "off" ? " no limit" : draft.mode === "detect" ? " flag bursts, never block" : " DENY calls over the limit" })
|
|
@@ -2272,20 +2275,22 @@ function RateLimitPanel({ focused }) {
|
|
|
2272
2275
|
/* @__PURE__ */ jsx4(FieldRow, { label: "Per minute", active: focused && fi === 1, children: /* @__PURE__ */ jsx4(Text4, { bold: true, children: draft.perMinute || "off" }) }),
|
|
2273
2276
|
/* @__PURE__ */ jsx4(FieldRow, { label: "Per hour", active: focused && fi === 2, children: /* @__PURE__ */ jsx4(Text4, { bold: true, children: draft.perHour || "off" }) }),
|
|
2274
2277
|
/* @__PURE__ */ jsx4(FieldRow, { label: "Per day", active: focused && fi === 3, children: /* @__PURE__ */ jsx4(Text4, { bold: true, children: draft.perDay || "off" }) }),
|
|
2275
|
-
|
|
2276
|
-
/* @__PURE__ */
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2278
|
+
showExtras && /* @__PURE__ */ jsxs4(Fragment4, { children: [
|
|
2279
|
+
hasLoad ? /* @__PURE__ */ jsxs4(Text4, { wrap: "truncate", children: [
|
|
2280
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: "load now".padEnd(13) }),
|
|
2281
|
+
/* @__PURE__ */ jsx4(Text4, { color: loadPct >= 100 ? theme.bad : loadPct >= 80 ? theme.warn : theme.ok, children: "\u2588".repeat(Math.min(18, Math.round(now / lim * 18))) }),
|
|
2282
|
+
/* @__PURE__ */ jsx4(Text4, { color: "#233457", children: "\u2591".repeat(Math.max(0, 18 - Math.round(now / lim * 18))) }),
|
|
2283
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: ` ${now}/${lim} this minute (${loadPct}%)` })
|
|
2284
|
+
] }) : null,
|
|
2285
|
+
/* @__PURE__ */ jsxs4(Text4, { color: theme.accentBright, bold: true, wrap: "truncate", children: [
|
|
2286
|
+
"Busiest 7d",
|
|
2287
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: " most calls in one window vs your limit" })
|
|
2288
|
+
] }),
|
|
2289
|
+
/* @__PURE__ */ jsx4(BusiestRow, { label: "minute", peak: peaks.minute, limit: draft.perMinute }),
|
|
2290
|
+
/* @__PURE__ */ jsx4(BusiestRow, { label: "hour", peak: peaks.hour, limit: draft.perHour }),
|
|
2291
|
+
/* @__PURE__ */ jsx4(BusiestRow, { label: "day", peak: peaks.day, limit: draft.perDay }),
|
|
2292
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: `activity`.padEnd(11) + ` last 24h \xB7 ${last24h} calls \xB7 busiest hour ${peaks.hour}/hr` })
|
|
2284
2293
|
] }),
|
|
2285
|
-
/* @__PURE__ */ jsx4(BusiestRow, { label: "minute", peak: peaks.minute, limit: draft.perMinute }),
|
|
2286
|
-
/* @__PURE__ */ jsx4(BusiestRow, { label: "hour", peak: peaks.hour, limit: draft.perHour }),
|
|
2287
|
-
/* @__PURE__ */ jsx4(BusiestRow, { label: "day", peak: peaks.day, limit: draft.perDay }),
|
|
2288
|
-
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: `activity`.padEnd(11) + ` last 24h \xB7 ${last24h} calls \xB7 busiest hour ${peaks.hour}/hr` }),
|
|
2289
2294
|
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
2290
2295
|
/* @__PURE__ */ jsxs4(Text4, { color: theme.accentBright, bold: true, wrap: "truncate", children: [
|
|
2291
2296
|
`Recent bursts 7d${anomalies2.length ? ` (${anomalies2.length})` : ""}`,
|
|
@@ -2362,7 +2367,7 @@ function DlpPanel({ focused }) {
|
|
|
2362
2367
|
}, [q.data]);
|
|
2363
2368
|
usePoll(() => {
|
|
2364
2369
|
if (!dirty && !adding) q.reloadQuiet();
|
|
2365
|
-
},
|
|
2370
|
+
}, 3e3);
|
|
2366
2371
|
const mutate = (next) => {
|
|
2367
2372
|
setDlp(next);
|
|
2368
2373
|
setDirty(true);
|
|
@@ -2402,6 +2407,11 @@ function DlpPanel({ focused }) {
|
|
|
2402
2407
|
useInput4(
|
|
2403
2408
|
(input2, key) => {
|
|
2404
2409
|
if (!dlp) return;
|
|
2410
|
+
if (key.ctrl && input2 === "r") {
|
|
2411
|
+
q.reload();
|
|
2412
|
+
setStatus(`\u27F3 refreshed ${(/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false })}`);
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
2405
2415
|
if (key.upArrow) setSel(() => Math.max(0, selC - 1));
|
|
2406
2416
|
else if (key.downArrow) setSel(() => Math.min(entries.length - 1, selC + 1));
|
|
2407
2417
|
else if (input2 === "m") mutate({ ...dlp, mode: MODES2[(MODES2.indexOf(dlp.mode) + 1) % MODES2.length] });
|
|
@@ -2507,7 +2517,7 @@ function DlpPanel({ focused }) {
|
|
|
2507
2517
|
/* @__PURE__ */ jsx5(Text5, { color: theme.dim, children: dlp.mode === "off" ? " (scanning disabled)" : dlp.mode === "detect" ? " (flag dlp:yes, redact output)" : " (deny + redact secrets)" }),
|
|
2508
2518
|
dirty ? /* @__PURE__ */ jsx5(Text5, { color: theme.warn, children: " \u25CF unsaved (s save \xB7 x discard)" }) : null
|
|
2509
2519
|
] }),
|
|
2510
|
-
/* @__PURE__ */ jsx5(Text5, { color: theme.dim, wrap: "truncate", children: focused ? `\u2191\u2193 move \xB7 space on/off \xB7 m mode \xB7 a add pattern \xB7 r add route \xB7 d remove \xB7 g ghost \xB7 s save${moreAbove ? ` \xB7 \u25B2${moreAbove}` : ""}${moreBelow ? ` \xB7 \u25BC${moreBelow}` : ""}` : "press \u2192 to edit" }),
|
|
2520
|
+
/* @__PURE__ */ jsx5(Text5, { color: theme.dim, wrap: "truncate", children: focused ? `\u2191\u2193 move \xB7 space on/off \xB7 m mode \xB7 a add pattern \xB7 r add route \xB7 d remove \xB7 g ghost \xB7 s save \xB7 ^R refresh${moreAbove ? ` \xB7 \u25B2${moreAbove}` : ""}${moreBelow ? ` \xB7 \u25BC${moreBelow}` : ""}` : "press \u2192 to edit" }),
|
|
2511
2521
|
adding ? /* @__PURE__ */ jsx5(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
2512
2522
|
/* @__PURE__ */ jsx5(Text5, { color: theme.warn, children: adding === "name" ? "new pattern name: " : adding === "re" ? `pattern for "${newName}" (glob, * = any chars, e.g. sk-* AKIA*): ` : "ghost path to hide (glob, * = any chars, e.g. */.env *.pem): " }),
|
|
2513
2523
|
/* @__PURE__ */ jsx5(
|
|
@@ -2801,6 +2811,15 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
2801
2811
|
return;
|
|
2802
2812
|
}
|
|
2803
2813
|
if (frozen) return;
|
|
2814
|
+
if (key.ctrl && input === "r") {
|
|
2815
|
+
if (source === "cloud") {
|
|
2816
|
+
cloudQ.reload();
|
|
2817
|
+
agentsQ.reload();
|
|
2818
|
+
statsQ.reloadQuiet();
|
|
2819
|
+
} else localQ.reload();
|
|
2820
|
+
setMsg({ text: `\u27F3 refreshed ${(/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false })}`, level: "ok" });
|
|
2821
|
+
return;
|
|
2822
|
+
}
|
|
2804
2823
|
if (showHelp) {
|
|
2805
2824
|
setShowHelp(false);
|
|
2806
2825
|
return;
|
|
@@ -3053,7 +3072,7 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
3053
3072
|
chip("status", SESS_STATUS[si] ?? "all", si !== 0),
|
|
3054
3073
|
chip("search", sessSearch || "\xB7", !!sessSearch)
|
|
3055
3074
|
] }),
|
|
3056
|
-
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 select \xB7 enter \u2192 session logs \xB7 v logs \xB7 ? all keys" : "press \u2192 to browse" }),
|
|
3075
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 select \xB7 enter \u2192 session logs \xB7 v logs \xB7 ^R refresh \xB7 ? all keys" : "press \u2192 to browse" }),
|
|
3057
3076
|
editing === "sess-search" ? /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
3058
3077
|
/* @__PURE__ */ jsx6(Text6, { color: theme.warn, children: "search: " }),
|
|
3059
3078
|
/* @__PURE__ */ jsx6(
|
|
@@ -3127,7 +3146,7 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
3127
3146
|
chip("search", search || "\xB7", !!search),
|
|
3128
3147
|
sessFilter ? chip("sess", sessFilter.slice(0, 8), true) : null
|
|
3129
3148
|
] }),
|
|
3130
|
-
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 select \xB7 enter full entry \xB7 \u2190\u2192 page \xB7 v sessions \xB7 ? all keys" : "press \u2192 to browse" }),
|
|
3149
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 select \xB7 enter full entry \xB7 \u2190\u2192 page \xB7 v sessions \xB7 ^R refresh \xB7 ? all keys" : "press \u2192 to browse" }),
|
|
3131
3150
|
msg ? /* @__PURE__ */ jsx6(Text6, { color: msg.level === "bad" ? theme.bad : theme.ok, children: truncate(msg.text, cols) }) : null,
|
|
3132
3151
|
editing && editing !== "sess-search" ? /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
3133
3152
|
/* @__PURE__ */ jsxs6(Text6, { color: theme.warn, children: [
|
|
@@ -3574,7 +3593,7 @@ async function tuiUpdateFlow(onStatus) {
|
|
|
3574
3593
|
}
|
|
3575
3594
|
|
|
3576
3595
|
// src/tui/panels/Settings.tsx
|
|
3577
|
-
import { Fragment as
|
|
3596
|
+
import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3578
3597
|
var EVENTS = ["denials", "allowed", "all"];
|
|
3579
3598
|
var SPIN2 = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
3580
3599
|
var SIGNALS2 = ["any", "deny", "dlp", "ratelimit"];
|
|
@@ -4061,11 +4080,11 @@ function SettingsPanel({
|
|
|
4061
4080
|
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
4062
4081
|
cursor(r),
|
|
4063
4082
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "guard".padEnd(11) }),
|
|
4064
|
-
!guardHere ? /* @__PURE__ */ jsxs7(
|
|
4083
|
+
!guardHere ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
4065
4084
|
/* @__PURE__ */ jsx7(Text7, { color: theme.bad, bold: true, children: "removed" }),
|
|
4066
4085
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " \xB7 " }),
|
|
4067
4086
|
/* @__PURE__ */ jsx7(Text7, { color: theme.accentBright, children: "enter to install" })
|
|
4068
|
-
] }) : /* @__PURE__ */ jsxs7(
|
|
4087
|
+
] }) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
4069
4088
|
/* @__PURE__ */ jsx7(Text7, { color: guardOld ? theme.warn : theme.ok, children: `v${guardVer ?? "?"}` }),
|
|
4070
4089
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: guardOld ? " \xB7 update available \xB7 enter update" : " (latest) \xB7 enter reinstall" }),
|
|
4071
4090
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " \xB7 d remove" })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.95",
|
|
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": {
|