@solongate/proxy 0.83.34 → 0.83.36

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.
@@ -15,6 +15,23 @@ export declare const cyan: (s: string) => string;
15
15
  * (used for long or continuation lines). Returns the whole block as one string.
16
16
  */
17
17
  export declare function usage(title: string, tagline: string, rows: Array<[string, string?]>, footer?: string): string;
18
+ /**
19
+ * What a command's switch falls through to when the first positional is not one
20
+ * of its subcommands.
21
+ *
22
+ * Printing the usage block on its own was the old behaviour everywhere, and it
23
+ * reads as though the command simply has no default: a correct-looking help
24
+ * screen appears, and finding the mistake means diffing it against what you
25
+ * typed. Naming the token first costs one line and removes that step.
26
+ *
27
+ * `solongate ghost -g` is the case that made it obvious. The parser treats only
28
+ * `--x` as a flag, so a single-dash token arrives as a SUBCOMMAND, and the
29
+ * result was a help screen that looked like a successful command.
30
+ *
31
+ * The empty case still happens: a command invoked with a flag and no subcommand
32
+ * has nothing to name, and `Unknown subcommand: ""` would be worse than none.
33
+ */
34
+ export declare function unknownSub(command: string, sub: string, usageText: string): number;
18
35
  /** Color a decision string (ALLOW green, DENY/DENIED red). */
19
36
  export declare function decisionColor(decision: string): string;
20
37
  /**
@@ -606,6 +606,11 @@ function usage(title, tagline, rows, footer = "Add --json for machine-readable o
606
606
  if (footer) lines.push("", ` ${c.dim}${footer}${c.reset}`);
607
607
  return lines.join("\n");
608
608
  }
609
+ function unknownSub(command, sub, usageText) {
610
+ if (sub) err(`${red(" \u2717 ")}Unknown ${command} subcommand: ${cyan(sub)}`);
611
+ err(usageText);
612
+ return 1;
613
+ }
609
614
  function decisionColor(decision) {
610
615
  const d = decision.toUpperCase();
611
616
  if (d === "ALLOW") return green(d);
@@ -833,10 +838,7 @@ async function run(argv) {
833
838
  return 0;
834
839
  }
835
840
  default:
836
- err(` Unknown: policy ${sub}
837
- `);
838
- err(USAGE);
839
- return 1;
841
+ return unknownSub("policy", sub, USAGE);
840
842
  }
841
843
  }
842
844
  function printRules(rules) {
@@ -925,7 +927,7 @@ async function run2(argv) {
925
927
  return 0;
926
928
  }
927
929
  default:
928
- return err(USAGE2), 1;
930
+ return unknownSub("ratelimit", sub, USAGE2);
929
931
  }
930
932
  }
931
933
 
@@ -1004,7 +1006,7 @@ async function run3(argv) {
1004
1006
  return err(green(` \u2713 Removed custom pattern "${name}"`)), 0;
1005
1007
  }
1006
1008
  default:
1007
- return err(USAGE3), 1;
1009
+ return unknownSub("dlp", sub, USAGE3);
1008
1010
  }
1009
1011
  }
1010
1012
 
@@ -1089,7 +1091,7 @@ async function run4(argv) {
1089
1091
  return err(green(` \u2713 Stopped hiding "${glob}"`) + dim(` (${saved.ghost.patterns.length} route(s) left)`)), 0;
1090
1092
  }
1091
1093
  default:
1092
- return err(USAGE4), 1;
1094
+ return unknownSub("ghost", sub, USAGE4);
1093
1095
  }
1094
1096
  }
1095
1097
 
@@ -1158,7 +1160,7 @@ async function run5(argv) {
1158
1160
  return 0;
1159
1161
  }
1160
1162
  default:
1161
- return err(USAGE5), 1;
1163
+ return unknownSub("stats", sub, USAGE5);
1162
1164
  }
1163
1165
  }
1164
1166
 
@@ -1435,6 +1437,80 @@ async function run7(argv) {
1435
1437
  return bad ? 1 : 0;
1436
1438
  }
1437
1439
 
1440
+ // src/commands/trace.ts
1441
+ import { readFileSync as readFileSync6 } from "fs";
1442
+ import { homedir as homedir5 } from "os";
1443
+ import { join as join5, resolve as resolve3 } from "path";
1444
+ var USAGE7 = usage("solongate trace", "what the guard saw here", [
1445
+ ["trace", "the last evaluations in this directory"],
1446
+ ["trace --limit N", "how many to show (default 20)"],
1447
+ ["trace --json", "the raw records"]
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;
1455
+ }
1456
+ return h.toString(16);
1457
+ }
1458
+ var countCell = (n) => {
1459
+ if (n === void 0 || n === null) return dim("-");
1460
+ if (n === 0) return red("0");
1461
+ return String(n);
1462
+ };
1463
+ async function run8(argv) {
1464
+ const { positionals, flags } = parse(argv);
1465
+ const sub = positionals[0] ?? "";
1466
+ if (sub === "help") return err(USAGE7), 0;
1467
+ if (sub) return unknownSub("trace", sub, USAGE7);
1468
+ 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}`));
1483
+ 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."));
1486
+ return 1;
1487
+ }
1488
+ records = records.slice(0, limit);
1489
+ if (flagBool(flags, "json")) return printJson(records), 0;
1490
+ err("");
1491
+ err(` ${records.length} local evaluation(s) \xB7 ${dim(dir)}`);
1492
+ table(
1493
+ ["WHEN", "CLIENT", "TOOL", "PERM", "PATHS", "CMDS", "URLS", "ARGS", "MS"],
1494
+ records.map((r) => [
1495
+ r.ts ? new Date(r.ts).toTimeString().slice(0, 8) : "",
1496
+ r.client ?? "",
1497
+ r.tool ?? "",
1498
+ dim(r.perm ?? ""),
1499
+ countCell(r.paths),
1500
+ countCell(r.cmds),
1501
+ countCell(r.urls),
1502
+ // An empty list is not the same as an absent one: it means the guard
1503
+ // parsed the payload and found no arguments in it at all.
1504
+ r.args === void 0 ? dim("-") : r.args.length ? r.args.join(",") : red("(none)"),
1505
+ dim(`${Math.round(r.ms ?? 0)}ms`)
1506
+ ])
1507
+ );
1508
+ err("");
1509
+ err(dim(" PATHS/CMDS/URLS is what the guard extracted from the call. A path rule"));
1510
+ err(dim(" cannot fire on a call whose PATHS is 0, whatever the rule says."));
1511
+ return 0;
1512
+ }
1513
+
1438
1514
  // src/commands/watch.ts
1439
1515
  import { closeSync as closeSync2, existsSync as existsSync5, openSync as openSync2, readSync as readSync2, statSync as statSync4 } from "fs";
1440
1516
  var trunc = (s, n) => s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
@@ -1462,7 +1538,7 @@ function print(r, json) {
1462
1538
  `${c.dim}[${time(r.at)}]${c.reset} ${src}${c.reset} ${dec}${r.decision.padEnd(6)}${c.reset} ${c.cyan}${trunc(r.tool, 12).padEnd(13)}${c.reset}${c.dim}${r.permission.slice(0, 4).padEnd(5)}${c.reset}${r.dlp ? c.red + "DLP! " + c.reset : ""}${c.dim}${trunc(r.agent || "-", 12).padEnd(13)}${r.detail}${c.reset}`
1463
1539
  );
1464
1540
  }
1465
- async function run8(argv) {
1541
+ async function run9(argv) {
1466
1542
  const { flags } = parse(argv);
1467
1543
  const json = flagBool(flags, "json");
1468
1544
  const decisionFilter = (flagStr(flags, "filter") || "").toUpperCase();
@@ -1540,19 +1616,19 @@ async function run8(argv) {
1540
1616
  }
1541
1617
 
1542
1618
  // src/commands/alerts.ts
1543
- var USAGE7 = usage("solongate alerts", "spike alerts (Telegram / email)", [
1619
+ var USAGE8 = usage("solongate alerts", "spike alerts (Telegram / email)", [
1544
1620
  ["alerts list"],
1545
1621
  ["alerts add --signal deny|dlp|ratelimit|any --threshold N --window S"],
1546
1622
  [" (--email <a> | --telegram <chatId> | --slack <url>)"],
1547
1623
  ["alerts remove <id>"]
1548
1624
  ]);
1549
- async function run9(argv) {
1625
+ async function run10(argv) {
1550
1626
  const { positionals, flags } = parse(argv);
1551
1627
  const sub = positionals[0] ?? "list";
1552
1628
  const json = flagBool(flags, "json");
1553
1629
  switch (sub) {
1554
1630
  case "help":
1555
- return err(USAGE7), 0;
1631
+ return err(USAGE8), 0;
1556
1632
  case "list": {
1557
1633
  const { rules } = await api.settings.getAlerts();
1558
1634
  if (json) return printJson(rules), 0;
@@ -1594,23 +1670,23 @@ async function run9(argv) {
1594
1670
  return err(green(` \u2713 Removed ${id}`)), 0;
1595
1671
  }
1596
1672
  default:
1597
- return err(USAGE7), 1;
1673
+ return unknownSub("alerts", sub, USAGE8);
1598
1674
  }
1599
1675
  }
1600
1676
 
1601
1677
  // src/commands/webhooks.ts
1602
- var USAGE8 = usage("solongate webhooks", "event webhooks", [
1678
+ var USAGE9 = usage("solongate webhooks", "event webhooks", [
1603
1679
  ["webhooks list"],
1604
1680
  ["webhooks add --url <https://\u2026> [--events denials|allowed|all]"],
1605
1681
  ["webhooks remove <id>"]
1606
1682
  ]);
1607
- async function run10(argv) {
1683
+ async function run11(argv) {
1608
1684
  const { positionals, flags } = parse(argv);
1609
1685
  const sub = positionals[0] ?? "list";
1610
1686
  const json = flagBool(flags, "json");
1611
1687
  switch (sub) {
1612
1688
  case "help":
1613
- return err(USAGE8), 0;
1689
+ return err(USAGE9), 0;
1614
1690
  case "list": {
1615
1691
  const { webhooks } = await api.settings.getWebhooks();
1616
1692
  if (json) return printJson(webhooks), 0;
@@ -1636,7 +1712,7 @@ async function run10(argv) {
1636
1712
  return err(green(` \u2713 Removed ${id}`)), 0;
1637
1713
  }
1638
1714
  default:
1639
- return err(USAGE8), 1;
1715
+ return unknownSub("webhooks", sub, USAGE9);
1640
1716
  }
1641
1717
  }
1642
1718
 
@@ -1661,12 +1737,14 @@ async function dispatch(command, argv) {
1661
1737
  return runAgent(argv);
1662
1738
  case "doctor":
1663
1739
  return run7(argv);
1664
- case "watch":
1740
+ case "trace":
1665
1741
  return run8(argv);
1666
- case "alerts":
1742
+ case "watch":
1667
1743
  return run9(argv);
1668
- case "webhooks":
1744
+ case "alerts":
1669
1745
  return run10(argv);
1746
+ case "webhooks":
1747
+ return run11(argv);
1670
1748
  default:
1671
1749
  err(` Unknown command: ${command}`);
1672
1750
  return 1;
@@ -0,0 +1 @@
1
+ export declare function run(argv: string[]): Promise<number>;
package/dist/index.js CHANGED
@@ -3043,12 +3043,12 @@ ${ctx.indent}`;
3043
3043
  for (const {
3044
3044
  format,
3045
3045
  test,
3046
- resolve: resolve7
3046
+ resolve: resolve8
3047
3047
  } of tags) {
3048
3048
  if (test) {
3049
3049
  const match = str.match(test);
3050
3050
  if (match) {
3051
- let res = resolve7.apply(null, match);
3051
+ let res = resolve8.apply(null, match);
3052
3052
  if (!(res instanceof Scalar)) res = new Scalar(res);
3053
3053
  if (format) res.format = format;
3054
3054
  return res;
@@ -7303,7 +7303,7 @@ async function runUpdateCommand() {
7303
7303
  return 0;
7304
7304
  }
7305
7305
  function runGlobalInstall2(version) {
7306
- return new Promise((resolve7) => {
7306
+ return new Promise((resolve8) => {
7307
7307
  try {
7308
7308
  mkdirSync4(join5(homedir3(), ".solongate"), { recursive: true });
7309
7309
  execFile(
@@ -7319,11 +7319,11 @@ ${output}
7319
7319
  `, { flag: "a" });
7320
7320
  } catch {
7321
7321
  }
7322
- resolve7({ ok: !err2, needsAdmin: !!err2 && NEEDS_ADMIN_RE.test(output) });
7322
+ resolve8({ ok: !err2, needsAdmin: !!err2 && NEEDS_ADMIN_RE.test(output) });
7323
7323
  }
7324
7324
  );
7325
7325
  } catch {
7326
- resolve7({ ok: false, needsAdmin: false });
7326
+ resolve8({ ok: false, needsAdmin: false });
7327
7327
  }
7328
7328
  });
7329
7329
  }
@@ -7364,13 +7364,13 @@ function ownNodeModules() {
7364
7364
  return null;
7365
7365
  }
7366
7366
  function globalInstallCheck() {
7367
- prefixCheck ??= new Promise((resolve7) => {
7367
+ prefixCheck ??= new Promise((resolve8) => {
7368
7368
  try {
7369
7369
  const dir = ownNodeModules();
7370
- if (!dir) return resolve7({ writable: null, dir: null });
7371
- access(dir, FS.W_OK, (e) => resolve7({ writable: !e, dir }));
7370
+ if (!dir) return resolve8({ writable: null, dir: null });
7371
+ access(dir, FS.W_OK, (e) => resolve8({ writable: !e, dir }));
7372
7372
  } catch {
7373
- resolve7({ writable: null, dir: null });
7373
+ resolve8({ writable: null, dir: null });
7374
7374
  }
7375
7375
  });
7376
7376
  return prefixCheck;
@@ -9755,7 +9755,7 @@ function DryRunPanel({ focused }) {
9755
9755
  const [off, setOff] = useState3(0);
9756
9756
  const { cols, rows } = usePanelSize();
9757
9757
  const selected = policies[Math.min(pi, Math.max(0, policies.length - 1))];
9758
- function run11(policyIdx = pi, lim = limit) {
9758
+ function run12(policyIdx = pi, lim = limit) {
9759
9759
  const p = policies[policyIdx];
9760
9760
  if (!p) return;
9761
9761
  setRunning(true);
@@ -9773,7 +9773,7 @@ function DryRunPanel({ focused }) {
9773
9773
  pendingPolicyId = null;
9774
9774
  }
9775
9775
  setPi(idx);
9776
- run11(idx, limit);
9776
+ run12(idx, limit);
9777
9777
  }, [policies.length]);
9778
9778
  useInput2((input, key) => {
9779
9779
  if (!focused || editLogs !== null) return;
@@ -9782,10 +9782,10 @@ function DryRunPanel({ focused }) {
9782
9782
  else if (input === "p" || input === "P") {
9783
9783
  const n = policies.length ? (pi + 1) % policies.length : 0;
9784
9784
  setPi(n);
9785
- run11(n, limit);
9785
+ run12(n, limit);
9786
9786
  } else if (input === "n" || input === "N") {
9787
9787
  setEditLogs(String(limit));
9788
- } else if (input === "r" || input === "R") run11(pi, limit);
9788
+ } else if (input === "r" || input === "R") run12(pi, limit);
9789
9789
  });
9790
9790
  function commitLogs(raw) {
9791
9791
  const cap = Math.min(MAX_LIMIT, totalLogs && totalLogs > 0 ? totalLogs : MAX_LIMIT);
@@ -9793,7 +9793,7 @@ function DryRunPanel({ focused }) {
9793
9793
  const next = Number.isFinite(parsed) && parsed > 0 ? Math.min(parsed, cap) : limit;
9794
9794
  setEditLogs(null);
9795
9795
  setLimit(next);
9796
- run11(pi, next);
9796
+ run12(pi, next);
9797
9797
  }
9798
9798
  const w = Math.max(40, cols);
9799
9799
  const lines = [];
@@ -11090,7 +11090,7 @@ function AuditPanel({ active: active2, focused }) {
11090
11090
  const sessLoading = source === "cloud" ? agentsQ.loading : localQ.loading;
11091
11091
  const doDelete = (kind) => {
11092
11092
  setMsg({ text: "deleting\u2026", level: "ok" });
11093
- const run11 = async () => {
11093
+ const run12 = async () => {
11094
11094
  if (source === "cloud") {
11095
11095
  if (kind === "one") {
11096
11096
  if (!current) throw new Error("nothing selected");
@@ -11106,14 +11106,14 @@ function AuditPanel({ active: active2, focused }) {
11106
11106
  localQ.reload();
11107
11107
  }
11108
11108
  };
11109
- run11().then(() => {
11109
+ run12().then(() => {
11110
11110
  setMsg({ text: kind === "one" ? "\u2713 entry deleted" : `\u2713 ALL ${source} logs deleted`, level: "ok" });
11111
11111
  toTop();
11112
11112
  }).catch((e) => setMsg({ text: "\u2717 " + (e instanceof Error ? e.message : String(e)), level: "bad" }));
11113
11113
  };
11114
11114
  const doExport = (kind) => {
11115
11115
  setMsg({ text: "exporting\u2026", level: "ok" });
11116
- const run11 = async () => {
11116
+ const run12 = async () => {
11117
11117
  const dir = join11(homedir9(), ".solongate");
11118
11118
  const file = join11(dir, `audit-export-${source}.jsonl`);
11119
11119
  let rows2;
@@ -11126,7 +11126,7 @@ function AuditPanel({ active: active2, focused }) {
11126
11126
  writeFileSync9(file, rows2.map((x) => JSON.stringify(x)).join("\n") + (rows2.length ? "\n" : ""));
11127
11127
  return { n: rows2.length, file };
11128
11128
  };
11129
- run11().then(({ n, file }) => setMsg({ text: `\u2713 exported ${n} rows \u2192 ${file}`, level: "ok" })).catch((e) => setMsg({ text: "\u2717 export failed: " + (e instanceof Error ? e.message : String(e)), level: "bad" }));
11129
+ run12().then(({ n, file }) => setMsg({ text: `\u2713 exported ${n} rows \u2192 ${file}`, level: "ok" })).catch((e) => setMsg({ text: "\u2717 export failed: " + (e instanceof Error ? e.message : String(e)), level: "bad" }));
11130
11130
  };
11131
11131
  useInput6(
11132
11132
  (input, key) => {
@@ -11620,6 +11620,11 @@ function usage(title, tagline, rows, footer = "Add --json for machine-readable o
11620
11620
  if (footer) lines.push("", ` ${c.dim}${footer}${c.reset}`);
11621
11621
  return lines.join("\n");
11622
11622
  }
11623
+ function unknownSub(command, sub, usageText) {
11624
+ if (sub) err(`${red(" \u2717 ")}Unknown ${command} subcommand: ${cyan(sub)}`);
11625
+ err(usageText);
11626
+ return 1;
11627
+ }
11623
11628
  function decisionColor2(decision) {
11624
11629
  const d = decision.toUpperCase();
11625
11630
  if (d === "ALLOW") return green(d);
@@ -12008,7 +12013,7 @@ function SettingsPanel({
12008
12013
  guardQ.reload();
12009
12014
  selfQ.reload();
12010
12015
  };
12011
- const run11 = (label, fn, reload) => {
12016
+ const run12 = (label, fn, reload) => {
12012
12017
  if (busy) return;
12013
12018
  setBusy(true);
12014
12019
  setMsg({ text: label + "\u2026", level: "ok" });
@@ -12090,8 +12095,8 @@ function SettingsPanel({
12090
12095
  const body = { signal: editor.signal, threshold: editor.threshold, windowSeconds: editor.windowSeconds, enabled: editor.enabled, ...channels };
12091
12096
  const id = editor.id;
12092
12097
  setEditor(null);
12093
- if (id) run11("alert updated", () => api.settings.updateAlert(id, body), alertQ.reload);
12094
- else run11(`${editor.channel} alert added`, () => api.settings.createAlert({ name: "SolonGate alert", ...body }), alertQ.reload);
12098
+ if (id) run12("alert updated", () => api.settings.updateAlert(id, body), alertQ.reload);
12099
+ else run12(`${editor.channel} alert added`, () => api.settings.createAlert({ name: "SolonGate alert", ...body }), alertQ.reload);
12095
12100
  };
12096
12101
  const activate = (r) => {
12097
12102
  if (r.kind === "acct") {
@@ -12165,7 +12170,7 @@ function SettingsPanel({
12165
12170
  })();
12166
12171
  } else if (r.kind === "self") {
12167
12172
  if (!selfProt) return;
12168
- run11(selfProt.enabled ? "self-protection disabled" : "self-protection enabled", () => api.settings.setSelfProtection(!selfProt.enabled), selfQ.reload);
12173
+ run12(selfProt.enabled ? "self-protection disabled" : "self-protection enabled", () => api.settings.setSelfProtection(!selfProt.enabled), selfQ.reload);
12169
12174
  } else if (r.kind === "cli-update") {
12170
12175
  if (updBusy) return;
12171
12176
  setUpdBusy(true);
@@ -12212,7 +12217,7 @@ function SettingsPanel({
12212
12217
  setMsg({ text: "set a path first (\u2193 then enter)", level: "bad" });
12213
12218
  return;
12214
12219
  }
12215
- run11(local.enabled ? "local logs disabled" : "local logs enabled", () => api.settings.setLocalLogs({ enabled: !local.enabled, path: local.path }), localQ.reload);
12220
+ run12(local.enabled ? "local logs disabled" : "local logs enabled", () => api.settings.setLocalLogs({ enabled: !local.enabled, path: local.path }), localQ.reload);
12216
12221
  } else if (r.kind === "ll-path") {
12217
12222
  setInput(local?.path ?? "");
12218
12223
  setEditing("path");
@@ -12223,7 +12228,7 @@ function SettingsPanel({
12223
12228
  next.running ? { text: `\u2713 dashboard link running on 127.0.0.1:${next.port} \u2014 keeps running after you close the dataroom`, level: "ok" } : { text: "\u2713 dashboard link stopped (disabled until you start it again)", level: "ok" }
12224
12229
  );
12225
12230
  } else if (r.kind === "wh") {
12226
- run11(r.wh.enabled ? "webhook disabled" : "webhook enabled", () => api.settings.updateWebhook(r.wh.id, { enabled: !r.wh.enabled }), whQ.reload);
12231
+ run12(r.wh.enabled ? "webhook disabled" : "webhook enabled", () => api.settings.updateWebhook(r.wh.id, { enabled: !r.wh.enabled }), whQ.reload);
12227
12232
  } else if (r.kind === "wh-add") {
12228
12233
  setInput("");
12229
12234
  setEditing("wh-url");
@@ -12242,7 +12247,7 @@ function SettingsPanel({
12242
12247
  setEditing(null);
12243
12248
  if (which === "path") {
12244
12249
  const enabled = (local?.enabled ?? false) && v.length > 0;
12245
- run11(v ? `path saved${enabled ? "" : " (press enter on enabled to turn on)"}` : "path cleared (local logs off)", () => api.settings.setLocalLogs({ enabled, path: v }), localQ.reload);
12250
+ run12(v ? `path saved${enabled ? "" : " (press enter on enabled to turn on)"}` : "path cleared (local logs off)", () => api.settings.setLocalLogs({ enabled, path: v }), localQ.reload);
12246
12251
  } else if (which === "wh-url") {
12247
12252
  const url = v.replace(/^["'<]+|["'>]+$/g, "").trim();
12248
12253
  if (!url) return;
@@ -12250,7 +12255,7 @@ function SettingsPanel({
12250
12255
  setMsg({ text: "\u2717 webhook url must start with http:// or https://", level: "bad" });
12251
12256
  return;
12252
12257
  }
12253
- run11("webhook added", () => api.settings.createWebhook({ url, events: "denials" }), whQ.reload);
12258
+ run12("webhook added", () => api.settings.createWebhook({ url, events: "denials" }), whQ.reload);
12254
12259
  } else if (which === "alert-target" && editor) {
12255
12260
  setEditor({ ...editor, target: v, field: 1 });
12256
12261
  }
@@ -12305,7 +12310,7 @@ function SettingsPanel({
12305
12310
  setMsg(ok ? { text: `\u2713 ${acctLabel(cur.acc)} is now the ACTIVE key (guard + logging)`, level: "ok" } : { text: "\u2717 could not set active", level: "bad" });
12306
12311
  refreshAccounts();
12307
12312
  } else if (cur.kind === "wh" || cur.kind === "alert" || cur.kind === "self" || cur.kind === "auto-update" || cur.kind === "ll-enabled" || cur.kind === "ll-server") {
12308
- if (cur.kind === "alert") run11(cur.rule.enabled ? "alert disabled" : "alert enabled", () => api.settings.setAlertEnabled(cur.rule.id, !cur.rule.enabled), alertQ.reload);
12313
+ if (cur.kind === "alert") run12(cur.rule.enabled ? "alert disabled" : "alert enabled", () => api.settings.setAlertEnabled(cur.rule.id, !cur.rule.enabled), alertQ.reload);
12309
12314
  else activate(cur);
12310
12315
  }
12311
12316
  } else if (inp === "x" && cur.kind === "acct") {
@@ -12336,13 +12341,13 @@ function SettingsPanel({
12336
12341
  refreshAccounts();
12337
12342
  onAccountsChanged?.();
12338
12343
  } else if (inp === "t" && cur.kind === "wh") {
12339
- run11("webhook test sent \u2014 check your endpoint", () => api.settings.sendTestWebhook(cur.wh.id).then((r) => {
12344
+ run12("webhook test sent \u2014 check your endpoint", () => api.settings.sendTestWebhook(cur.wh.id).then((r) => {
12340
12345
  if (!r.delivered) throw new Error("endpoint rejected the test (non-2xx)");
12341
12346
  }), whQ.reload);
12342
12347
  } else if (inp === "e" && cur.kind === "ll-path") activate(cur);
12343
12348
  else if (inp === "e" && cur.kind === "wh") {
12344
12349
  const next = EVENTS[(EVENTS.indexOf(cur.wh.events) + 1) % EVENTS.length];
12345
- run11(`webhook events \u2192 ${next}`, () => api.settings.updateWebhook(cur.wh.id, { events: next }), whQ.reload);
12350
+ run12(`webhook events \u2192 ${next}`, () => api.settings.updateWebhook(cur.wh.id, { events: next }), whQ.reload);
12346
12351
  } else if (inp === "e" && cur.kind === "alert") {
12347
12352
  const ch = alertChannel(cur.rule);
12348
12353
  if (ch) openAlertEditor(ch, cur.rule);
@@ -12379,10 +12384,10 @@ function SettingsPanel({
12379
12384
  setConfirmDel(null);
12380
12385
  if (cur.kind === "wh") {
12381
12386
  const id = cur.wh.id;
12382
- run11("webhook deleted", () => api.settings.deleteWebhook(id).then(() => setHidden((h) => new Set(h).add("wh:" + id))), whQ.reload);
12387
+ run12("webhook deleted", () => api.settings.deleteWebhook(id).then(() => setHidden((h) => new Set(h).add("wh:" + id))), whQ.reload);
12383
12388
  } else {
12384
12389
  const id = cur.rule.id;
12385
- run11("alert deleted", () => api.settings.deleteAlert(id).then(() => setHidden((h) => new Set(h).add("alert:" + id))), alertQ.reload);
12390
+ run12("alert deleted", () => api.settings.deleteAlert(id).then(() => setHidden((h) => new Set(h).add("alert:" + id))), alertQ.reload);
12386
12391
  }
12387
12392
  } else if (inp === "r") reloadAll();
12388
12393
  },
@@ -12770,9 +12775,9 @@ function App() {
12770
12775
  const [update2, setUpdate] = useState9({ kind: "idle" });
12771
12776
  useEffect8(() => {
12772
12777
  let alive = true;
12773
- const run11 = () => void tuiUpdateFlow((s) => alive && setUpdate(s));
12774
- run11();
12775
- const t = setInterval(run11, 30 * 6e4);
12778
+ const run12 = () => void tuiUpdateFlow((s) => alive && setUpdate(s));
12779
+ run12();
12780
+ const t = setInterval(run12, 30 * 6e4);
12776
12781
  return () => {
12777
12782
  alive = false;
12778
12783
  clearInterval(t);
@@ -13127,10 +13132,7 @@ async function run2(argv) {
13127
13132
  return 0;
13128
13133
  }
13129
13134
  default:
13130
- err(` Unknown: policy ${sub}
13131
- `);
13132
- err(USAGE);
13133
- return 1;
13135
+ return unknownSub("policy", sub, USAGE);
13134
13136
  }
13135
13137
  }
13136
13138
  function printRules(rules) {
@@ -13234,7 +13236,7 @@ async function run3(argv) {
13234
13236
  return 0;
13235
13237
  }
13236
13238
  default:
13237
- return err(USAGE2), 1;
13239
+ return unknownSub("ratelimit", sub, USAGE2);
13238
13240
  }
13239
13241
  }
13240
13242
  var USAGE2, modeColor2;
@@ -13319,7 +13321,7 @@ async function run4(argv) {
13319
13321
  return err(green(` \u2713 Removed custom pattern "${name}"`)), 0;
13320
13322
  }
13321
13323
  default:
13322
- return err(USAGE3), 1;
13324
+ return unknownSub("dlp", sub, USAGE3);
13323
13325
  }
13324
13326
  }
13325
13327
  var USAGE3, modeColor3;
@@ -13413,7 +13415,7 @@ async function run5(argv) {
13413
13415
  return err(green(` \u2713 Stopped hiding "${glob}"`) + dim(` (${saved.ghost.patterns.length} route(s) left)`)), 0;
13414
13416
  }
13415
13417
  default:
13416
- return err(USAGE4), 1;
13418
+ return unknownSub("ghost", sub, USAGE4);
13417
13419
  }
13418
13420
  }
13419
13421
  var USAGE4, modeColor4, isBlanketGlob;
@@ -13495,7 +13497,7 @@ async function run6(argv) {
13495
13497
  return 0;
13496
13498
  }
13497
13499
  default:
13498
- return err(USAGE5), 1;
13500
+ return unknownSub("stats", sub, USAGE5);
13499
13501
  }
13500
13502
  }
13501
13503
  var USAGE5;
@@ -13643,6 +13645,88 @@ var init_agents2 = __esm({
13643
13645
  }
13644
13646
  });
13645
13647
 
13648
+ // src/commands/trace.ts
13649
+ import { readFileSync as readFileSync12 } from "fs";
13650
+ import { homedir as homedir12 } from "os";
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;
13658
+ }
13659
+ return h.toString(16);
13660
+ }
13661
+ async function run8(argv) {
13662
+ const { positionals, flags } = parse(argv);
13663
+ const sub = positionals[0] ?? "";
13664
+ if (sub === "help") return err(USAGE7), 0;
13665
+ if (sub) return unknownSub("trace", sub, USAGE7);
13666
+ 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 {
13678
+ 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."));
13684
+ return 1;
13685
+ }
13686
+ records = records.slice(0, limit);
13687
+ if (flagBool(flags, "json")) return printJson(records), 0;
13688
+ err("");
13689
+ err(` ${records.length} local evaluation(s) \xB7 ${dim(dir)}`);
13690
+ table(
13691
+ ["WHEN", "CLIENT", "TOOL", "PERM", "PATHS", "CMDS", "URLS", "ARGS", "MS"],
13692
+ records.map((r) => [
13693
+ r.ts ? new Date(r.ts).toTimeString().slice(0, 8) : "",
13694
+ r.client ?? "",
13695
+ r.tool ?? "",
13696
+ dim(r.perm ?? ""),
13697
+ countCell(r.paths),
13698
+ countCell(r.cmds),
13699
+ countCell(r.urls),
13700
+ // An empty list is not the same as an absent one: it means the guard
13701
+ // parsed the payload and found no arguments in it at all.
13702
+ r.args === void 0 ? dim("-") : r.args.length ? r.args.join(",") : red("(none)"),
13703
+ dim(`${Math.round(r.ms ?? 0)}ms`)
13704
+ ])
13705
+ );
13706
+ err("");
13707
+ err(dim(" PATHS/CMDS/URLS is what the guard extracted from the call. A path rule"));
13708
+ err(dim(" cannot fire on a call whose PATHS is 0, whatever the rule says."));
13709
+ return 0;
13710
+ }
13711
+ var USAGE7, countCell;
13712
+ var init_trace = __esm({
13713
+ "src/commands/trace.ts"() {
13714
+ "use strict";
13715
+ init_args();
13716
+ init_format();
13717
+ USAGE7 = usage("solongate trace", "what the guard saw here", [
13718
+ ["trace", "the last evaluations in this directory"],
13719
+ ["trace --limit N", "how many to show (default 20)"],
13720
+ ["trace --json", "the raw records"]
13721
+ ]);
13722
+ countCell = (n) => {
13723
+ if (n === void 0 || n === null) return dim("-");
13724
+ if (n === 0) return red("0");
13725
+ return String(n);
13726
+ };
13727
+ }
13728
+ });
13729
+
13646
13730
  // src/commands/watch.ts
13647
13731
  import { closeSync as closeSync2, existsSync as existsSync7, openSync as openSync4, readSync as readSync2, statSync as statSync4 } from "fs";
13648
13732
  function tailLocal(file, maxBytes = 131072) {
@@ -13668,7 +13752,7 @@ function print(r, json) {
13668
13752
  `${c.dim}[${time(r.at)}]${c.reset} ${src}${c.reset} ${dec}${r.decision.padEnd(6)}${c.reset} ${c.cyan}${trunc(r.tool, 12).padEnd(13)}${c.reset}${c.dim}${r.permission.slice(0, 4).padEnd(5)}${c.reset}${r.dlp ? c.red + "DLP! " + c.reset : ""}${c.dim}${trunc(r.agent || "-", 12).padEnd(13)}${r.detail}${c.reset}`
13669
13753
  );
13670
13754
  }
13671
- async function run8(argv) {
13755
+ async function run9(argv) {
13672
13756
  const { flags } = parse(argv);
13673
13757
  const json = flagBool(flags, "json");
13674
13758
  const decisionFilter = (flagStr(flags, "filter") || "").toUpperCase();
@@ -13759,13 +13843,13 @@ var init_watch = __esm({
13759
13843
  });
13760
13844
 
13761
13845
  // src/commands/alerts.ts
13762
- async function run9(argv) {
13846
+ async function run10(argv) {
13763
13847
  const { positionals, flags } = parse(argv);
13764
13848
  const sub = positionals[0] ?? "list";
13765
13849
  const json = flagBool(flags, "json");
13766
13850
  switch (sub) {
13767
13851
  case "help":
13768
- return err(USAGE7), 0;
13852
+ return err(USAGE8), 0;
13769
13853
  case "list": {
13770
13854
  const { rules } = await api.settings.getAlerts();
13771
13855
  if (json) return printJson(rules), 0;
@@ -13807,17 +13891,17 @@ async function run9(argv) {
13807
13891
  return err(green(` \u2713 Removed ${id}`)), 0;
13808
13892
  }
13809
13893
  default:
13810
- return err(USAGE7), 1;
13894
+ return unknownSub("alerts", sub, USAGE8);
13811
13895
  }
13812
13896
  }
13813
- var USAGE7;
13897
+ var USAGE8;
13814
13898
  var init_alerts = __esm({
13815
13899
  "src/commands/alerts.ts"() {
13816
13900
  "use strict";
13817
13901
  init_api_client();
13818
13902
  init_args();
13819
13903
  init_format();
13820
- USAGE7 = usage("solongate alerts", "spike alerts (Telegram / email)", [
13904
+ USAGE8 = usage("solongate alerts", "spike alerts (Telegram / email)", [
13821
13905
  ["alerts list"],
13822
13906
  ["alerts add --signal deny|dlp|ratelimit|any --threshold N --window S"],
13823
13907
  [" (--email <a> | --telegram <chatId> | --slack <url>)"],
@@ -13827,13 +13911,13 @@ var init_alerts = __esm({
13827
13911
  });
13828
13912
 
13829
13913
  // src/commands/webhooks.ts
13830
- async function run10(argv) {
13914
+ async function run11(argv) {
13831
13915
  const { positionals, flags } = parse(argv);
13832
13916
  const sub = positionals[0] ?? "list";
13833
13917
  const json = flagBool(flags, "json");
13834
13918
  switch (sub) {
13835
13919
  case "help":
13836
- return err(USAGE8), 0;
13920
+ return err(USAGE9), 0;
13837
13921
  case "list": {
13838
13922
  const { webhooks } = await api.settings.getWebhooks();
13839
13923
  if (json) return printJson(webhooks), 0;
@@ -13859,17 +13943,17 @@ async function run10(argv) {
13859
13943
  return err(green(` \u2713 Removed ${id}`)), 0;
13860
13944
  }
13861
13945
  default:
13862
- return err(USAGE8), 1;
13946
+ return unknownSub("webhooks", sub, USAGE9);
13863
13947
  }
13864
13948
  }
13865
- var USAGE8;
13949
+ var USAGE9;
13866
13950
  var init_webhooks = __esm({
13867
13951
  "src/commands/webhooks.ts"() {
13868
13952
  "use strict";
13869
13953
  init_api_client();
13870
13954
  init_args();
13871
13955
  init_format();
13872
- USAGE8 = usage("solongate webhooks", "event webhooks", [
13956
+ USAGE9 = usage("solongate webhooks", "event webhooks", [
13873
13957
  ["webhooks list"],
13874
13958
  ["webhooks add --url <https://\u2026> [--events denials|allowed|all]"],
13875
13959
  ["webhooks remove <id>"]
@@ -13903,12 +13987,14 @@ async function dispatch(command, argv) {
13903
13987
  return runAgent(argv);
13904
13988
  case "doctor":
13905
13989
  return run(argv);
13906
- case "watch":
13990
+ case "trace":
13907
13991
  return run8(argv);
13908
- case "alerts":
13992
+ case "watch":
13909
13993
  return run9(argv);
13910
- case "webhooks":
13994
+ case "alerts":
13911
13995
  return run10(argv);
13996
+ case "webhooks":
13997
+ return run11(argv);
13912
13998
  default:
13913
13999
  err(` Unknown command: ${command}`);
13914
14000
  return 1;
@@ -13945,6 +14031,7 @@ var init_commands = __esm({
13945
14031
  init_audit2();
13946
14032
  init_agents2();
13947
14033
  init_doctor();
14034
+ init_trace();
13948
14035
  init_watch();
13949
14036
  init_alerts();
13950
14037
  init_webhooks();
@@ -13958,9 +14045,9 @@ __export(logs_server_exports, {
13958
14045
  runLogsServer: () => runLogsServer
13959
14046
  });
13960
14047
  import { createServer } from "http";
13961
- import { readFileSync as readFileSync12, statSync as statSync5 } from "fs";
13962
- import { resolve as resolve6, join as join14, isAbsolute as isAbsolute2 } from "path";
13963
- import { homedir as homedir12 } from "os";
14048
+ import { readFileSync as readFileSync13, statSync as statSync5 } from "fs";
14049
+ import { resolve as resolve7, join as join15, isAbsolute as isAbsolute2 } from "path";
14050
+ import { homedir as homedir13 } from "os";
13964
14051
  import { readdirSync as readdirSync3 } from "fs";
13965
14052
  function allowedOrigins() {
13966
14053
  const base = [
@@ -13977,15 +14064,15 @@ function resolveLocalLogDir(rawPath) {
13977
14064
  const dir = String(rawPath || "").trim().replace(/[\\/]+$/, "");
13978
14065
  if (!dir) return null;
13979
14066
  if (isAbsolute2(dir)) return dir;
13980
- return resolve6(homedir12(), ".solongate", "local-logs");
14067
+ return resolve7(homedir13(), ".solongate", "local-logs");
13981
14068
  }
13982
14069
  async function findLogDir() {
13983
- const base = resolve6(homedir12(), ".solongate");
14070
+ const base = resolve7(homedir13(), ".solongate");
13984
14071
  try {
13985
14072
  const files = readdirSync3(base).filter((f) => f.startsWith(".policy-cache-") && f.endsWith(".json"));
13986
14073
  for (const f of files) {
13987
14074
  try {
13988
- const c2 = JSON.parse(readFileSync12(join14(base, f), "utf-8"));
14075
+ const c2 = JSON.parse(readFileSync13(join15(base, f), "utf-8"));
13989
14076
  const p = c2?.security?.localLogs?.path;
13990
14077
  if (typeof p === "string" && p.trim()) return { dir: resolveLocalLogDir(p), configured: p };
13991
14078
  } catch {
@@ -13994,7 +14081,7 @@ async function findLogDir() {
13994
14081
  } catch {
13995
14082
  }
13996
14083
  try {
13997
- const cfgRaw = readFileSync12(join14(base, "cloud-guard.json"), "utf-8");
14084
+ const cfgRaw = readFileSync13(join15(base, "cloud-guard.json"), "utf-8");
13998
14085
  const { apiKey, apiUrl } = JSON.parse(cfgRaw);
13999
14086
  if (apiKey) {
14000
14087
  const url = `${apiUrl || "https://api.solongate.com"}/api/v1/policies/active`;
@@ -14023,7 +14110,7 @@ function setCors(req, res) {
14023
14110
  }
14024
14111
  function fileInfo(dir) {
14025
14112
  if (!dir) return { file: null, exists: false, size: 0, mtimeMs: 0 };
14026
- const file = join14(dir, LOG_FILENAME);
14113
+ const file = join15(dir, LOG_FILENAME);
14027
14114
  try {
14028
14115
  const st = statSync5(file);
14029
14116
  return { file, exists: true, size: st.size, mtimeMs: st.mtimeMs };
@@ -14106,7 +14193,7 @@ async function runLogsServer() {
14106
14193
  return;
14107
14194
  }
14108
14195
  try {
14109
- const text = readFileSync12(info.file, "utf-8");
14196
+ const text = readFileSync13(info.file, "utf-8");
14110
14197
  res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8", "Last-Modified": lastMod, "X-Solongate-Exists": "1" });
14111
14198
  res.end(text);
14112
14199
  } catch {
@@ -14159,9 +14246,9 @@ var init_logs_server = __esm({
14159
14246
  });
14160
14247
 
14161
14248
  // src/index.ts
14162
- import { readFileSync as readFileSync13 } from "fs";
14249
+ import { readFileSync as readFileSync14 } from "fs";
14163
14250
  import { fileURLToPath as fileURLToPath4 } from "url";
14164
- import { dirname as dirname4, join as join15 } from "path";
14251
+ import { dirname as dirname4, join as join16 } from "path";
14165
14252
 
14166
14253
  // src/config.ts
14167
14254
  import { readFileSync, existsSync } from "fs";
@@ -16937,7 +17024,7 @@ var Mutex = class {
16937
17024
  this.locked = true;
16938
17025
  return;
16939
17026
  }
16940
- return new Promise((resolve7, reject) => {
17027
+ return new Promise((resolve8, reject) => {
16941
17028
  const timer = setTimeout(() => {
16942
17029
  const idx = this.queue.indexOf(onReady);
16943
17030
  if (idx !== -1) this.queue.splice(idx, 1);
@@ -16945,7 +17032,7 @@ var Mutex = class {
16945
17032
  }, timeoutMs);
16946
17033
  const onReady = () => {
16947
17034
  clearTimeout(timer);
16948
- resolve7();
17035
+ resolve8();
16949
17036
  };
16950
17037
  this.queue.push(onReady);
16951
17038
  });
@@ -17537,7 +17624,7 @@ ${msg.content.text}`;
17537
17624
 
17538
17625
  // src/index.ts
17539
17626
  init_cli_utils();
17540
- var CLI_SUBCOMMANDS = /* @__PURE__ */ new Set(["update", "repair", "logs-server", "local-logs", "policy", "ratelimit", "dlp", "ghost", "stats", "audit", "sessions", "session", "doctor", "watch", "alerts", "webhooks", "dataroom"]);
17627
+ var CLI_SUBCOMMANDS = /* @__PURE__ */ new Set(["update", "repair", "logs-server", "local-logs", "policy", "ratelimit", "dlp", "ghost", "stats", "audit", "sessions", "session", "doctor", "trace", "watch", "alerts", "webhooks", "dataroom"]);
17541
17628
  var CLI_INFO_ARGS = /* @__PURE__ */ new Set(["login", "help", "--help", "-h", "--version", "-v", "version"]);
17542
17629
  var IS_HUMAN_CLI = process.argv.length <= 2 || CLI_SUBCOMMANDS.has(process.argv[2] ?? "") || CLI_INFO_ARGS.has(process.argv[2] ?? "");
17543
17630
  if (!IS_HUMAN_CLI) {
@@ -17556,8 +17643,8 @@ if (!IS_HUMAN_CLI) {
17556
17643
  }
17557
17644
  var PKG_VERSION = (() => {
17558
17645
  try {
17559
- const p = join15(dirname4(fileURLToPath4(import.meta.url)), "..", "package.json");
17560
- return JSON.parse(readFileSync13(p, "utf-8")).version || "unknown";
17646
+ const p = join16(dirname4(fileURLToPath4(import.meta.url)), "..", "package.json");
17647
+ return JSON.parse(readFileSync14(p, "utf-8")).version || "unknown";
17561
17648
  } catch {
17562
17649
  return "unknown";
17563
17650
  }
@@ -17602,6 +17689,7 @@ function printHelp() {
17602
17689
  cmd("update auto on|off", "background auto-update (default off \u2014 on macOS npm -g often needs sudo)");
17603
17690
  cmd("repair", "restore the guard + hook + settings files if they were deleted or disarmed");
17604
17691
  cmd("doctor", "health check: login, policy, guard, local logs");
17692
+ cmd("trace [--limit N]", "what the guard saw in this directory, allows included");
17605
17693
  cmd("doctor --json", "the same health check as machine-readable JSON");
17606
17694
  cmd("logs-server start", "start the local audit-log service for the dashboard (background)");
17607
17695
  cmd("logs-server stop", "stop AND disable it (only this makes it stay down)");
@@ -17731,7 +17819,7 @@ async function main() {
17731
17819
  await launchTui2();
17732
17820
  return;
17733
17821
  }
17734
- const MGMT_COMMANDS = /* @__PURE__ */ new Set(["policy", "ratelimit", "dlp", "ghost", "stats", "audit", "sessions", "session", "doctor", "watch", "alerts", "webhooks"]);
17822
+ const MGMT_COMMANDS = /* @__PURE__ */ new Set(["policy", "ratelimit", "dlp", "ghost", "stats", "audit", "sessions", "session", "doctor", "trace", "watch", "alerts", "webhooks"]);
17735
17823
  if (MGMT_COMMANDS.has(subcommand ?? "")) {
17736
17824
  const { runCommand: runCommand2 } = await Promise.resolve().then(() => (init_commands(), commands_exports));
17737
17825
  const code = await runCommand2(subcommand, process.argv.slice(3));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.83.34",
3
+ "version": "0.83.36",
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.34",
65
- "@solongate/guard-linux-arm64": "0.83.34",
66
- "@solongate/guard-darwin-x64": "0.83.34",
67
- "@solongate/guard-darwin-arm64": "0.83.34",
68
- "@solongate/guard-win32-x64": "0.83.34",
69
- "@solongate/guard-win32-arm64": "0.83.34"
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"
70
70
  },
71
71
  "dependencies": {
72
72
  "@modelcontextprotocol/sdk": "^1.26.0",