@solongate/proxy 0.82.98 → 0.82.100

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.
@@ -122,6 +122,16 @@ function codexHooksStatus() {
122
122
  }
123
123
  return { registered, trusted, disabled };
124
124
  }
125
+ function installedGuardVersion() {
126
+ try {
127
+ const p = globalPaths();
128
+ const s = readFileSync(join(p.hooksDir, "guard.mjs"), "utf-8");
129
+ const m = s.match(/HOOK_VERSION\s*=\s*(\d+)/);
130
+ return m ? parseInt(m[1], 10) : null;
131
+ } catch {
132
+ return null;
133
+ }
134
+ }
125
135
 
126
136
  // src/api-client/client.ts
127
137
  var DEFAULT_API_URL = "https://api.solongate.com";
@@ -1248,7 +1258,14 @@ async function collectChecks() {
1248
1258
  }
1249
1259
  try {
1250
1260
  const g = await api.settings.getGuardStatus();
1251
- checks.push({ name: "guard hook", ok: g.up_to_date ? true : "warn", detail: g.up_to_date ? `v${g.installed} (latest) \xB7 ${g.device_count} device(s)` : `v${g.installed} \u2192 v${g.latest} available \xB7 run \`solongate update\` in your terminal` });
1261
+ const here = installedGuardVersion();
1262
+ const latest = g.latest ?? here;
1263
+ const current = here != null && latest != null ? here >= latest : g.up_to_date;
1264
+ checks.push({
1265
+ name: "guard hook",
1266
+ ok: current ? true : "warn",
1267
+ detail: current ? `v${here ?? g.installed} (latest) \xB7 ${g.device_count} device(s)` : `v${here ?? g.installed} \u2192 v${latest} available \xB7 run \`solongate update\` in your terminal`
1268
+ });
1252
1269
  } catch {
1253
1270
  }
1254
1271
  }
package/dist/index.js CHANGED
@@ -10148,7 +10148,8 @@ function RateLimitPanel({ focused }) {
10148
10148
  const anomalies2 = (insightsQ.data?.["anomalies"] ?? []).slice().sort((a, b) => b.count - a.count || new Date(b.minute).getTime() - new Date(a.minute).getTime());
10149
10149
  const hasLoad = (draft?.perMinute ?? 0) > 0;
10150
10150
  const showExtras = rows >= 20;
10151
- const fixed = 1 + 4 + (showExtras ? (hasLoad ? 1 : 0) + 5 : 0) + 1 + 1 + 1 + 1;
10151
+ const spacerRows = showExtras ? 1 : 0;
10152
+ const fixed = 1 + 4 + (showExtras ? (hasLoad ? 1 : 0) + 5 : 0) + 1 + 1 + spacerRows + 1 + 1;
10152
10153
  const burstBudget = Math.max(1, rows - fixed);
10153
10154
  const maxOff = Math.max(0, anomalies2.length - burstBudget);
10154
10155
  const total = 4 + anomalies2.length;
@@ -10217,23 +10218,28 @@ function RateLimitPanel({ focused }) {
10217
10218
  anomalies2.length === 0 ? /* @__PURE__ */ jsxs5(Text5, { color: theme.dim, children: [
10218
10219
  " ",
10219
10220
  insightsQ.loading ? "loading\u2026" : insightsQ.error ? `couldn't load bursts: ${String(insightsQ.error).slice(0, 60)}` : "no bursts in the last 7 days"
10220
- ] }) : /* @__PURE__ */ jsx5(
10221
- Table,
10222
- {
10223
- columns: [{ header: "WHEN", width: 15 }, { header: "RESULT", width: 9 }, { header: "CALLS", width: 7 }, { header: "AGENT", width: Math.max(8, bw - 31) }],
10224
- rows: shown.map((a, i) => {
10225
- const isSel = off + i === bcur;
10226
- return [
10227
- { value: (isSel ? "\u25B8 " : " ") + when(new Date(a.minute).getTime()), color: isSel ? theme.accentBright : void 0, dim: !isSel },
10228
- { value: a.blocked ? "Blocked" : "Bypassed", color: a.blocked ? theme.bad : theme.warn },
10229
- { value: `${a.count}/${a.limit}`, color: theme.warn },
10230
- { value: truncate2(a.agent, Math.max(8, bw - 31)), dim: !isSel }
10231
- ];
10232
- })
10233
- }
10221
+ ] }) : (
10222
+ // Bounded here as well as on the outer frame, so a list longer than
10223
+ // the budget is clipped inside its own box instead of shoving the
10224
+ // footer out of the panel and taking the scroll window with it.
10225
+ /* @__PURE__ */ jsx5(Box5, { flexDirection: "column", height: burstBudget + 1, overflow: "hidden", children: /* @__PURE__ */ jsx5(
10226
+ Table,
10227
+ {
10228
+ columns: [{ header: "WHEN", width: 15 }, { header: "RESULT", width: 9 }, { header: "CALLS", width: 7 }, { header: "AGENT", width: Math.max(8, bw - 31) }],
10229
+ rows: shown.map((a, i) => {
10230
+ const isSel = off + i === bcur;
10231
+ return [
10232
+ { value: (isSel ? "\u25B8 " : " ") + when(new Date(a.minute).getTime()), color: isSel ? theme.accentBright : void 0, dim: !isSel },
10233
+ { value: a.blocked ? "Blocked" : "Bypassed", color: a.blocked ? theme.bad : theme.warn },
10234
+ { value: `${a.count}/${a.limit}`, color: theme.warn },
10235
+ { value: truncate2(a.agent, Math.max(8, bw - 31)), dim: !isSel }
10236
+ ];
10237
+ })
10238
+ }
10239
+ ) })
10234
10240
  )
10235
10241
  ] }),
10236
- /* @__PURE__ */ jsx5(Text5, { children: " " }),
10242
+ spacerRows ? /* @__PURE__ */ jsx5(Text5, { children: " " }) : null,
10237
10243
  /* @__PURE__ */ jsxs5(Text5, { wrap: "truncate", children: [
10238
10244
  /* @__PURE__ */ jsx5(Text5, { color: theme.dim, children: "limit now " }),
10239
10245
  /* @__PURE__ */ jsx5(Text5, { children: lim > 0 ? `${lim}/min` : "no per-minute limit" }),
@@ -11335,7 +11341,14 @@ async function collectChecks() {
11335
11341
  }
11336
11342
  try {
11337
11343
  const g = await api.settings.getGuardStatus();
11338
- checks.push({ name: "guard hook", ok: g.up_to_date ? true : "warn", detail: g.up_to_date ? `v${g.installed} (latest) \xB7 ${g.device_count} device(s)` : `v${g.installed} \u2192 v${g.latest} available \xB7 run \`solongate update\` in your terminal` });
11344
+ const here = installedGuardVersion();
11345
+ const latest = g.latest ?? here;
11346
+ const current = here != null && latest != null ? here >= latest : g.up_to_date;
11347
+ checks.push({
11348
+ name: "guard hook",
11349
+ ok: current ? true : "warn",
11350
+ detail: current ? `v${here ?? g.installed} (latest) \xB7 ${g.device_count} device(s)` : `v${here ?? g.installed} \u2192 v${latest} available \xB7 run \`solongate update\` in your terminal`
11351
+ });
11339
11352
  } catch {
11340
11353
  }
11341
11354
  }
package/dist/tui/index.js CHANGED
@@ -3326,7 +3326,8 @@ function RateLimitPanel({ focused }) {
3326
3326
  const anomalies2 = (insightsQ.data?.["anomalies"] ?? []).slice().sort((a, b) => b.count - a.count || new Date(b.minute).getTime() - new Date(a.minute).getTime());
3327
3327
  const hasLoad = (draft?.perMinute ?? 0) > 0;
3328
3328
  const showExtras = rows >= 20;
3329
- const fixed = 1 + 4 + (showExtras ? (hasLoad ? 1 : 0) + 5 : 0) + 1 + 1 + 1 + 1;
3329
+ const spacerRows = showExtras ? 1 : 0;
3330
+ const fixed = 1 + 4 + (showExtras ? (hasLoad ? 1 : 0) + 5 : 0) + 1 + 1 + spacerRows + 1 + 1;
3330
3331
  const burstBudget = Math.max(1, rows - fixed);
3331
3332
  const maxOff = Math.max(0, anomalies2.length - burstBudget);
3332
3333
  const total = 4 + anomalies2.length;
@@ -3395,23 +3396,28 @@ function RateLimitPanel({ focused }) {
3395
3396
  anomalies2.length === 0 ? /* @__PURE__ */ jsxs5(Text5, { color: theme.dim, children: [
3396
3397
  " ",
3397
3398
  insightsQ.loading ? "loading\u2026" : insightsQ.error ? `couldn't load bursts: ${String(insightsQ.error).slice(0, 60)}` : "no bursts in the last 7 days"
3398
- ] }) : /* @__PURE__ */ jsx5(
3399
- Table,
3400
- {
3401
- columns: [{ header: "WHEN", width: 15 }, { header: "RESULT", width: 9 }, { header: "CALLS", width: 7 }, { header: "AGENT", width: Math.max(8, bw - 31) }],
3402
- rows: shown.map((a, i) => {
3403
- const isSel = off + i === bcur;
3404
- return [
3405
- { value: (isSel ? "\u25B8 " : " ") + when(new Date(a.minute).getTime()), color: isSel ? theme.accentBright : void 0, dim: !isSel },
3406
- { value: a.blocked ? "Blocked" : "Bypassed", color: a.blocked ? theme.bad : theme.warn },
3407
- { value: `${a.count}/${a.limit}`, color: theme.warn },
3408
- { value: truncate(a.agent, Math.max(8, bw - 31)), dim: !isSel }
3409
- ];
3410
- })
3411
- }
3399
+ ] }) : (
3400
+ // Bounded here as well as on the outer frame, so a list longer than
3401
+ // the budget is clipped inside its own box instead of shoving the
3402
+ // footer out of the panel and taking the scroll window with it.
3403
+ /* @__PURE__ */ jsx5(Box5, { flexDirection: "column", height: burstBudget + 1, overflow: "hidden", children: /* @__PURE__ */ jsx5(
3404
+ Table,
3405
+ {
3406
+ columns: [{ header: "WHEN", width: 15 }, { header: "RESULT", width: 9 }, { header: "CALLS", width: 7 }, { header: "AGENT", width: Math.max(8, bw - 31) }],
3407
+ rows: shown.map((a, i) => {
3408
+ const isSel = off + i === bcur;
3409
+ return [
3410
+ { value: (isSel ? "\u25B8 " : " ") + when(new Date(a.minute).getTime()), color: isSel ? theme.accentBright : void 0, dim: !isSel },
3411
+ { value: a.blocked ? "Blocked" : "Bypassed", color: a.blocked ? theme.bad : theme.warn },
3412
+ { value: `${a.count}/${a.limit}`, color: theme.warn },
3413
+ { value: truncate(a.agent, Math.max(8, bw - 31)), dim: !isSel }
3414
+ ];
3415
+ })
3416
+ }
3417
+ ) })
3412
3418
  )
3413
3419
  ] }),
3414
- /* @__PURE__ */ jsx5(Text5, { children: " " }),
3420
+ spacerRows ? /* @__PURE__ */ jsx5(Text5, { children: " " }) : null,
3415
3421
  /* @__PURE__ */ jsxs5(Text5, { wrap: "truncate", children: [
3416
3422
  /* @__PURE__ */ jsx5(Text5, { color: theme.dim, children: "limit now " }),
3417
3423
  /* @__PURE__ */ jsx5(Text5, { children: lim > 0 ? `${lim}/min` : "no per-minute limit" }),
@@ -4364,7 +4370,14 @@ async function collectChecks() {
4364
4370
  }
4365
4371
  try {
4366
4372
  const g = await api.settings.getGuardStatus();
4367
- checks.push({ name: "guard hook", ok: g.up_to_date ? true : "warn", detail: g.up_to_date ? `v${g.installed} (latest) \xB7 ${g.device_count} device(s)` : `v${g.installed} \u2192 v${g.latest} available \xB7 run \`solongate update\` in your terminal` });
4373
+ const here = installedGuardVersion();
4374
+ const latest = g.latest ?? here;
4375
+ const current = here != null && latest != null ? here >= latest : g.up_to_date;
4376
+ checks.push({
4377
+ name: "guard hook",
4378
+ ok: current ? true : "warn",
4379
+ detail: current ? `v${here ?? g.installed} (latest) \xB7 ${g.device_count} device(s)` : `v${here ?? g.installed} \u2192 v${latest} available \xB7 run \`solongate update\` in your terminal`
4380
+ });
4368
4381
  } catch {
4369
4382
  }
4370
4383
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.82.98",
3
+ "version": "0.82.100",
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": {