@solongate/proxy 0.83.36 → 0.83.37

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.
@@ -1438,7 +1438,7 @@ async function run7(argv) {
1438
1438
  }
1439
1439
 
1440
1440
  // src/commands/trace.ts
1441
- import { readFileSync as readFileSync6 } from "fs";
1441
+ import { readdirSync as readdirSync3, readFileSync as readFileSync6 } from "fs";
1442
1442
  import { homedir as homedir5 } from "os";
1443
1443
  import { join as join5, resolve as resolve3 } from "path";
1444
1444
  var USAGE7 = usage("solongate trace", "what the guard saw here", [
@@ -1446,15 +1446,40 @@ var USAGE7 = usage("solongate trace", "what the guard saw here", [
1446
1446
  ["trace --limit N", "how many to show (default 20)"],
1447
1447
  ["trace --json", "the raw records"]
1448
1448
  ]);
1449
- function projectKey(dir) {
1450
- let h = 2166136261;
1451
- const s = String(dir || "");
1452
- for (let i = 0; i < s.length; i++) {
1453
- h ^= s.charCodeAt(i);
1454
- h = h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24)) >>> 0;
1449
+ function readAllRings() {
1450
+ const root = join5(homedir5(), ".solongate", "projects");
1451
+ let dirs;
1452
+ try {
1453
+ dirs = readdirSync3(root);
1454
+ } catch {
1455
+ return [];
1456
+ }
1457
+ const out2 = [];
1458
+ for (const d of dirs) {
1459
+ let text;
1460
+ try {
1461
+ text = readFileSync6(join5(root, d, ".eval-ring.jsonl"), "utf-8");
1462
+ } catch {
1463
+ continue;
1464
+ }
1465
+ for (const line of text.split("\n")) {
1466
+ const t = line.trim();
1467
+ if (!t) continue;
1468
+ try {
1469
+ out2.push(JSON.parse(t));
1470
+ } catch {
1471
+ }
1472
+ }
1455
1473
  }
1456
- return h.toString(16);
1474
+ return out2.sort((a, b) => (b.ts ?? 0) - (a.ts ?? 0));
1457
1475
  }
1476
+ var sameDir = (a, b) => {
1477
+ const clean = (s) => {
1478
+ const t = String(s ?? "").replaceAll("\\", "/");
1479
+ return t.length > 1 ? t.replace(/\/+$/, "") : t;
1480
+ };
1481
+ return !!a && clean(a) === clean(b);
1482
+ };
1458
1483
  var countCell = (n) => {
1459
1484
  if (n === void 0 || n === null) return dim("-");
1460
1485
  if (n === 0) return red("0");
@@ -1466,29 +1491,30 @@ async function run8(argv) {
1466
1491
  if (sub === "help") return err(USAGE7), 0;
1467
1492
  if (sub) return unknownSub("trace", sub, USAGE7);
1468
1493
  const limit = flagNum(flags, "limit") || 20;
1469
- const dir = join5(homedir5(), ".solongate", "projects", projectKey(resolve3(process.cwd())));
1470
- let records;
1471
- try {
1472
- records = readFileSync6(join5(dir, ".eval-ring.jsonl"), "utf-8").split("\n").map((l) => l.trim()).filter(Boolean).map((l) => {
1473
- try {
1474
- return JSON.parse(l);
1475
- } catch {
1476
- return null;
1477
- }
1478
- }).filter((r) => r !== null).sort((a, b) => (b.ts ?? 0) - (a.ts ?? 0));
1479
- } catch {
1480
- err("");
1481
- err(" No local records for this directory.");
1482
- err(dim(` ${dir}`));
1494
+ const here = resolve3(process.cwd());
1495
+ const all = readAllRings();
1496
+ let records = all.filter((r) => sameDir(r.cwd, here));
1497
+ if (!records.length) {
1483
1498
  err("");
1484
- err(dim(" The guard writes one per evaluation, in the directory the call was"));
1485
- err(dim(" made in. Run this from the project you are testing."));
1499
+ err(" No calls recorded for this directory.");
1500
+ err(dim(` ${here}`));
1501
+ if (all.length) {
1502
+ err("");
1503
+ err(dim(" The guard has recorded calls in:"));
1504
+ const seen = /* @__PURE__ */ new Set();
1505
+ for (const r of all) {
1506
+ if (!r.cwd || seen.has(r.cwd) || seen.size >= 8) continue;
1507
+ seen.add(r.cwd);
1508
+ err(` ${dim("\u2022")} ${r.cwd}`);
1509
+ }
1510
+ if (!seen.size) err(dim(" (older records carry no directory; make one more call and retry)"));
1511
+ }
1486
1512
  return 1;
1487
1513
  }
1488
1514
  records = records.slice(0, limit);
1489
1515
  if (flagBool(flags, "json")) return printJson(records), 0;
1490
1516
  err("");
1491
- err(` ${records.length} local evaluation(s) \xB7 ${dim(dir)}`);
1517
+ err(` ${records.length} local evaluation(s) \xB7 ${dim(here)}`);
1492
1518
  table(
1493
1519
  ["WHEN", "CLIENT", "TOOL", "PERM", "PATHS", "CMDS", "URLS", "ARGS", "MS"],
1494
1520
  records.map((r) => [
package/dist/index.js CHANGED
@@ -13646,17 +13646,35 @@ var init_agents2 = __esm({
13646
13646
  });
13647
13647
 
13648
13648
  // src/commands/trace.ts
13649
- import { readFileSync as readFileSync12 } from "fs";
13649
+ import { readdirSync as readdirSync3, readFileSync as readFileSync12 } from "fs";
13650
13650
  import { homedir as homedir12 } from "os";
13651
13651
  import { join as join14, resolve as resolve6 } from "path";
13652
- function projectKey2(dir) {
13653
- let h = 2166136261;
13654
- const s = String(dir || "");
13655
- for (let i = 0; i < s.length; i++) {
13656
- h ^= s.charCodeAt(i);
13657
- h = h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24)) >>> 0;
13652
+ function readAllRings() {
13653
+ const root = join14(homedir12(), ".solongate", "projects");
13654
+ let dirs;
13655
+ try {
13656
+ dirs = readdirSync3(root);
13657
+ } catch {
13658
+ return [];
13659
+ }
13660
+ const out2 = [];
13661
+ for (const d of dirs) {
13662
+ let text;
13663
+ try {
13664
+ text = readFileSync12(join14(root, d, ".eval-ring.jsonl"), "utf-8");
13665
+ } catch {
13666
+ continue;
13667
+ }
13668
+ for (const line of text.split("\n")) {
13669
+ const t = line.trim();
13670
+ if (!t) continue;
13671
+ try {
13672
+ out2.push(JSON.parse(t));
13673
+ } catch {
13674
+ }
13675
+ }
13658
13676
  }
13659
- return h.toString(16);
13677
+ return out2.sort((a, b) => (b.ts ?? 0) - (a.ts ?? 0));
13660
13678
  }
13661
13679
  async function run8(argv) {
13662
13680
  const { positionals, flags } = parse(argv);
@@ -13664,29 +13682,30 @@ async function run8(argv) {
13664
13682
  if (sub === "help") return err(USAGE7), 0;
13665
13683
  if (sub) return unknownSub("trace", sub, USAGE7);
13666
13684
  const limit = flagNum(flags, "limit") || 20;
13667
- const dir = join14(homedir12(), ".solongate", "projects", projectKey2(resolve6(process.cwd())));
13668
- let records;
13669
- try {
13670
- records = readFileSync12(join14(dir, ".eval-ring.jsonl"), "utf-8").split("\n").map((l) => l.trim()).filter(Boolean).map((l) => {
13671
- try {
13672
- return JSON.parse(l);
13673
- } catch {
13674
- return null;
13675
- }
13676
- }).filter((r) => r !== null).sort((a, b) => (b.ts ?? 0) - (a.ts ?? 0));
13677
- } catch {
13685
+ const here = resolve6(process.cwd());
13686
+ const all = readAllRings();
13687
+ let records = all.filter((r) => sameDir(r.cwd, here));
13688
+ if (!records.length) {
13678
13689
  err("");
13679
- err(" No local records for this directory.");
13680
- err(dim(` ${dir}`));
13681
- err("");
13682
- err(dim(" The guard writes one per evaluation, in the directory the call was"));
13683
- err(dim(" made in. Run this from the project you are testing."));
13690
+ err(" No calls recorded for this directory.");
13691
+ err(dim(` ${here}`));
13692
+ if (all.length) {
13693
+ err("");
13694
+ err(dim(" The guard has recorded calls in:"));
13695
+ const seen = /* @__PURE__ */ new Set();
13696
+ for (const r of all) {
13697
+ if (!r.cwd || seen.has(r.cwd) || seen.size >= 8) continue;
13698
+ seen.add(r.cwd);
13699
+ err(` ${dim("\u2022")} ${r.cwd}`);
13700
+ }
13701
+ if (!seen.size) err(dim(" (older records carry no directory; make one more call and retry)"));
13702
+ }
13684
13703
  return 1;
13685
13704
  }
13686
13705
  records = records.slice(0, limit);
13687
13706
  if (flagBool(flags, "json")) return printJson(records), 0;
13688
13707
  err("");
13689
- err(` ${records.length} local evaluation(s) \xB7 ${dim(dir)}`);
13708
+ err(` ${records.length} local evaluation(s) \xB7 ${dim(here)}`);
13690
13709
  table(
13691
13710
  ["WHEN", "CLIENT", "TOOL", "PERM", "PATHS", "CMDS", "URLS", "ARGS", "MS"],
13692
13711
  records.map((r) => [
@@ -13708,7 +13727,7 @@ async function run8(argv) {
13708
13727
  err(dim(" cannot fire on a call whose PATHS is 0, whatever the rule says."));
13709
13728
  return 0;
13710
13729
  }
13711
- var USAGE7, countCell;
13730
+ var USAGE7, sameDir, countCell;
13712
13731
  var init_trace = __esm({
13713
13732
  "src/commands/trace.ts"() {
13714
13733
  "use strict";
@@ -13719,6 +13738,13 @@ var init_trace = __esm({
13719
13738
  ["trace --limit N", "how many to show (default 20)"],
13720
13739
  ["trace --json", "the raw records"]
13721
13740
  ]);
13741
+ sameDir = (a, b) => {
13742
+ const clean = (s) => {
13743
+ const t = String(s ?? "").replaceAll("\\", "/");
13744
+ return t.length > 1 ? t.replace(/\/+$/, "") : t;
13745
+ };
13746
+ return !!a && clean(a) === clean(b);
13747
+ };
13722
13748
  countCell = (n) => {
13723
13749
  if (n === void 0 || n === null) return dim("-");
13724
13750
  if (n === 0) return red("0");
@@ -14048,7 +14074,7 @@ import { createServer } from "http";
14048
14074
  import { readFileSync as readFileSync13, statSync as statSync5 } from "fs";
14049
14075
  import { resolve as resolve7, join as join15, isAbsolute as isAbsolute2 } from "path";
14050
14076
  import { homedir as homedir13 } from "os";
14051
- import { readdirSync as readdirSync3 } from "fs";
14077
+ import { readdirSync as readdirSync4 } from "fs";
14052
14078
  function allowedOrigins() {
14053
14079
  const base = [
14054
14080
  "https://dashboard.solongate.com",
@@ -14069,7 +14095,7 @@ function resolveLocalLogDir(rawPath) {
14069
14095
  async function findLogDir() {
14070
14096
  const base = resolve7(homedir13(), ".solongate");
14071
14097
  try {
14072
- const files = readdirSync3(base).filter((f) => f.startsWith(".policy-cache-") && f.endsWith(".json"));
14098
+ const files = readdirSync4(base).filter((f) => f.startsWith(".policy-cache-") && f.endsWith(".json"));
14073
14099
  for (const f of files) {
14074
14100
  try {
14075
14101
  const c2 = JSON.parse(readFileSync13(join15(base, f), "utf-8"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.83.36",
3
+ "version": "0.83.37",
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": {
@@ -61,12 +61,12 @@
61
61
  "node": ">=20.0.0"
62
62
  },
63
63
  "optionalDependencies": {
64
- "@solongate/guard-linux-x64": "0.83.36",
65
- "@solongate/guard-linux-arm64": "0.83.36",
66
- "@solongate/guard-darwin-x64": "0.83.36",
67
- "@solongate/guard-darwin-arm64": "0.83.36",
68
- "@solongate/guard-win32-x64": "0.83.36",
69
- "@solongate/guard-win32-arm64": "0.83.36"
64
+ "@solongate/guard-linux-x64": "0.83.37",
65
+ "@solongate/guard-linux-arm64": "0.83.37",
66
+ "@solongate/guard-darwin-x64": "0.83.37",
67
+ "@solongate/guard-darwin-arm64": "0.83.37",
68
+ "@solongate/guard-win32-x64": "0.83.37",
69
+ "@solongate/guard-win32-arm64": "0.83.37"
70
70
  },
71
71
  "dependencies": {
72
72
  "@modelcontextprotocol/sdk": "^1.26.0",