@solongate/proxy 0.81.95 → 0.81.96

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
@@ -9113,6 +9113,7 @@ function RateLimitPanel({ focused }) {
9113
9113
  const [dirty, setDirty] = useState4(false);
9114
9114
  const [fi, setFi] = useState4(0);
9115
9115
  const [status, setStatus] = useState4(null);
9116
+ const [burstOff, setBurstOff] = useState4(0);
9116
9117
  useEffect4(() => {
9117
9118
  if (layersQ.data && !dirty) setDraft({ ...layersQ.data.layers.rateLimit });
9118
9119
  }, [layersQ.data]);
@@ -9146,10 +9147,22 @@ function RateLimitPanel({ focused }) {
9146
9147
  setStatus("\u2717 " + (e instanceof Error ? e.message : String(e)));
9147
9148
  }
9148
9149
  };
9150
+ const history = (historyQ.data?.history ?? []).slice().sort((a, b) => b.ts - a.ts);
9151
+ const lastChange = history[0];
9152
+ const peaks = insightsQ.data?.["peaks"] ?? { minute: 0, hour: 0, day: 0 };
9153
+ const anomalies2 = (insightsQ.data?.["anomalies"] ?? []).slice().sort((a, b) => b.count - a.count || new Date(b.minute).getTime() - new Date(a.minute).getTime());
9154
+ const hasLoad = (draft?.perMinute ?? 0) > 0;
9155
+ const showExtras = rows >= 20;
9156
+ const fixed = 1 + 4 + (showExtras ? (hasLoad ? 1 : 0) + 5 : 0) + 1 + 1 + 1 + 1;
9157
+ const burstBudget = Math.max(1, rows - fixed);
9158
+ const maxOff = Math.max(0, anomalies2.length - burstBudget);
9159
+ const off = Math.min(burstOff, maxOff);
9149
9160
  useInput3(
9150
9161
  (input, key) => {
9151
9162
  const step = key.shift ? 10 : 1;
9152
- if (key.upArrow) setFi((n) => (n - 1 + FIELDS2.length) % FIELDS2.length);
9163
+ if (key.pageDown) setBurstOff((o) => Math.min(o + burstBudget, maxOff));
9164
+ else if (key.pageUp) setBurstOff((o) => Math.max(0, o - burstBudget));
9165
+ else if (key.upArrow) setFi((n) => (n - 1 + FIELDS2.length) % FIELDS2.length);
9153
9166
  else if (key.downArrow) setFi((n) => (n + 1) % FIELDS2.length);
9154
9167
  else if (key.leftArrow) adjust(-1, step);
9155
9168
  else if (key.rightArrow) adjust(1, step);
@@ -9163,23 +9176,15 @@ function RateLimitPanel({ focused }) {
9163
9176
  },
9164
9177
  { isActive: focused }
9165
9178
  );
9166
- const history = (historyQ.data?.history ?? []).slice().sort((a, b) => b.ts - a.ts);
9167
- const lastChange = history[0];
9168
- const peaks = insightsQ.data?.["peaks"] ?? { minute: 0, hour: 0, day: 0 };
9169
- const anomalies2 = (insightsQ.data?.["anomalies"] ?? []).slice().sort((a, b) => b.count - a.count || new Date(b.minute).getTime() - new Date(a.minute).getTime());
9170
9179
  return /* @__PURE__ */ jsx4(DataView, { loading: layersQ.loading && !draft, error: layersQ.error, children: draft ? (() => {
9171
9180
  const lim = draft.perMinute;
9172
9181
  const now = insightsQ.data ? insightsQ.data["activity"]?.minute?.slice(-1)[0]?.count ?? 0 : 0;
9173
9182
  const loadPct = lim > 0 ? Math.min(100, Math.round(now / lim * 100)) : 0;
9174
9183
  const last24h = (insightsQ.data?.["activity"]?.hour ?? []).reduce((s, b) => s + b.count, 0);
9175
- const hasLoad = lim > 0;
9176
- const showExtras = rows >= 20;
9177
- const fixed = 1 + 4 + (showExtras ? (hasLoad ? 1 : 0) + 5 : 0) + 1 + 1 + 1;
9178
- const burstBudget = Math.max(1, rows - fixed);
9179
- const shown = anomalies2.slice(0, burstBudget);
9184
+ const shown = anomalies2.slice(off, off + burstBudget);
9180
9185
  const bw = Math.max(10, cols - 30);
9181
9186
  return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", height: rows, overflow: "hidden", children: [
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" }),
9187
+ /* @__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${maxOff > 0 ? " \xB7 PgUp/PgDn bursts" : ""}` : "press \u2192 to edit" }),
9183
9188
  /* @__PURE__ */ jsxs4(FieldRow, { label: "Mode", active: focused && fi === 0, children: [
9184
9189
  /* @__PURE__ */ jsx4(Text4, { color: modeColor(draft.mode), bold: true, children: draft.mode }),
9185
9190
  /* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: draft.mode === "off" ? " no limit" : draft.mode === "detect" ? " flag bursts, never block" : " DENY calls over the limit" })
@@ -9206,6 +9211,7 @@ function RateLimitPanel({ focused }) {
9206
9211
  /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
9207
9212
  /* @__PURE__ */ jsxs4(Text4, { color: theme.accentBright, bold: true, wrap: "truncate", children: [
9208
9213
  `Recent bursts 7d${anomalies2.length ? ` (${anomalies2.length})` : ""}`,
9214
+ maxOff > 0 ? /* @__PURE__ */ jsx4(Text4, { color: theme.warn, children: ` ${off + 1}-${Math.min(off + burstBudget, anomalies2.length)}/${anomalies2.length}` }) : null,
9209
9215
  /* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: " over the per-minute limit \xB7 Bypassed = detect (not blocked)" })
9210
9216
  ] }),
9211
9217
  anomalies2.length === 0 ? /* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
@@ -9224,6 +9230,7 @@ function RateLimitPanel({ focused }) {
9224
9230
  }
9225
9231
  )
9226
9232
  ] }),
9233
+ /* @__PURE__ */ jsx4(Text4, { children: " " }),
9227
9234
  /* @__PURE__ */ jsxs4(Text4, { wrap: "truncate", children: [
9228
9235
  /* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: "limit now " }),
9229
9236
  /* @__PURE__ */ jsx4(Text4, { children: lim > 0 ? `${lim}/min` : "no per-minute limit" }),
package/dist/tui/index.js CHANGED
@@ -2201,6 +2201,7 @@ function RateLimitPanel({ focused }) {
2201
2201
  const [dirty, setDirty] = useState4(false);
2202
2202
  const [fi, setFi] = useState4(0);
2203
2203
  const [status, setStatus] = useState4(null);
2204
+ const [burstOff, setBurstOff] = useState4(0);
2204
2205
  useEffect4(() => {
2205
2206
  if (layersQ.data && !dirty) setDraft({ ...layersQ.data.layers.rateLimit });
2206
2207
  }, [layersQ.data]);
@@ -2234,10 +2235,22 @@ function RateLimitPanel({ focused }) {
2234
2235
  setStatus("\u2717 " + (e instanceof Error ? e.message : String(e)));
2235
2236
  }
2236
2237
  };
2238
+ const history = (historyQ.data?.history ?? []).slice().sort((a, b) => b.ts - a.ts);
2239
+ const lastChange = history[0];
2240
+ const peaks = insightsQ.data?.["peaks"] ?? { minute: 0, hour: 0, day: 0 };
2241
+ const anomalies2 = (insightsQ.data?.["anomalies"] ?? []).slice().sort((a, b) => b.count - a.count || new Date(b.minute).getTime() - new Date(a.minute).getTime());
2242
+ const hasLoad = (draft?.perMinute ?? 0) > 0;
2243
+ const showExtras = rows >= 20;
2244
+ const fixed = 1 + 4 + (showExtras ? (hasLoad ? 1 : 0) + 5 : 0) + 1 + 1 + 1 + 1;
2245
+ const burstBudget = Math.max(1, rows - fixed);
2246
+ const maxOff = Math.max(0, anomalies2.length - burstBudget);
2247
+ const off = Math.min(burstOff, maxOff);
2237
2248
  useInput3(
2238
2249
  (input, key) => {
2239
2250
  const step = key.shift ? 10 : 1;
2240
- if (key.upArrow) setFi((n) => (n - 1 + FIELDS2.length) % FIELDS2.length);
2251
+ if (key.pageDown) setBurstOff((o) => Math.min(o + burstBudget, maxOff));
2252
+ else if (key.pageUp) setBurstOff((o) => Math.max(0, o - burstBudget));
2253
+ else if (key.upArrow) setFi((n) => (n - 1 + FIELDS2.length) % FIELDS2.length);
2241
2254
  else if (key.downArrow) setFi((n) => (n + 1) % FIELDS2.length);
2242
2255
  else if (key.leftArrow) adjust(-1, step);
2243
2256
  else if (key.rightArrow) adjust(1, step);
@@ -2251,23 +2264,15 @@ function RateLimitPanel({ focused }) {
2251
2264
  },
2252
2265
  { isActive: focused }
2253
2266
  );
2254
- const history = (historyQ.data?.history ?? []).slice().sort((a, b) => b.ts - a.ts);
2255
- const lastChange = history[0];
2256
- const peaks = insightsQ.data?.["peaks"] ?? { minute: 0, hour: 0, day: 0 };
2257
- const anomalies2 = (insightsQ.data?.["anomalies"] ?? []).slice().sort((a, b) => b.count - a.count || new Date(b.minute).getTime() - new Date(a.minute).getTime());
2258
2267
  return /* @__PURE__ */ jsx4(DataView, { loading: layersQ.loading && !draft, error: layersQ.error, children: draft ? (() => {
2259
2268
  const lim = draft.perMinute;
2260
2269
  const now = insightsQ.data ? insightsQ.data["activity"]?.minute?.slice(-1)[0]?.count ?? 0 : 0;
2261
2270
  const loadPct = lim > 0 ? Math.min(100, Math.round(now / lim * 100)) : 0;
2262
2271
  const last24h = (insightsQ.data?.["activity"]?.hour ?? []).reduce((s, b) => s + b.count, 0);
2263
- const hasLoad = lim > 0;
2264
- const showExtras = rows >= 20;
2265
- const fixed = 1 + 4 + (showExtras ? (hasLoad ? 1 : 0) + 5 : 0) + 1 + 1 + 1;
2266
- const burstBudget = Math.max(1, rows - fixed);
2267
- const shown = anomalies2.slice(0, burstBudget);
2272
+ const shown = anomalies2.slice(off, off + burstBudget);
2268
2273
  const bw = Math.max(10, cols - 30);
2269
2274
  return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", height: rows, overflow: "hidden", children: [
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" }),
2275
+ /* @__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${maxOff > 0 ? " \xB7 PgUp/PgDn bursts" : ""}` : "press \u2192 to edit" }),
2271
2276
  /* @__PURE__ */ jsxs4(FieldRow, { label: "Mode", active: focused && fi === 0, children: [
2272
2277
  /* @__PURE__ */ jsx4(Text4, { color: modeColor(draft.mode), bold: true, children: draft.mode }),
2273
2278
  /* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: draft.mode === "off" ? " no limit" : draft.mode === "detect" ? " flag bursts, never block" : " DENY calls over the limit" })
@@ -2294,6 +2299,7 @@ function RateLimitPanel({ focused }) {
2294
2299
  /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
2295
2300
  /* @__PURE__ */ jsxs4(Text4, { color: theme.accentBright, bold: true, wrap: "truncate", children: [
2296
2301
  `Recent bursts 7d${anomalies2.length ? ` (${anomalies2.length})` : ""}`,
2302
+ maxOff > 0 ? /* @__PURE__ */ jsx4(Text4, { color: theme.warn, children: ` ${off + 1}-${Math.min(off + burstBudget, anomalies2.length)}/${anomalies2.length}` }) : null,
2297
2303
  /* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: " over the per-minute limit \xB7 Bypassed = detect (not blocked)" })
2298
2304
  ] }),
2299
2305
  anomalies2.length === 0 ? /* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
@@ -2312,6 +2318,7 @@ function RateLimitPanel({ focused }) {
2312
2318
  }
2313
2319
  )
2314
2320
  ] }),
2321
+ /* @__PURE__ */ jsx4(Text4, { children: " " }),
2315
2322
  /* @__PURE__ */ jsxs4(Text4, { wrap: "truncate", children: [
2316
2323
  /* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: "limit now " }),
2317
2324
  /* @__PURE__ */ jsx4(Text4, { children: lim > 0 ? `${lim}/min` : "no per-minute limit" }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.81.95",
3
+ "version": "0.81.96",
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": {