@solongate/proxy 0.82.24 → 0.82.25

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.
@@ -1,4 +1,4 @@
1
- /** `solongate agents` the live feed. */
1
+ /** `solongate agents` - the live feed. */
2
2
  export declare function runAgents(argv: string[]): Promise<number>;
3
- /** `solongate agent <id>` deep detail for one agent. */
3
+ /** `solongate agent <id>` - deep detail for one agent. */
4
4
  export declare function runAgent(argv: string[]): Promise<number>;
@@ -8,6 +8,13 @@ export declare const green: (s: string) => string;
8
8
  export declare const red: (s: string) => string;
9
9
  export declare const yellow: (s: string) => string;
10
10
  export declare const cyan: (s: string) => string;
11
+ /**
12
+ * Render a colored command usage block, matching the top-level `solongate --help`
13
+ * style: bold title, cyan command syntax, dim descriptions. `rows` are
14
+ * [syntax, description?] pairs; a syntax with no description prints on its own
15
+ * (used for long or continuation lines). Returns the whole block as one string.
16
+ */
17
+ export declare function usage(title: string, tagline: string, rows: Array<[string, string?]>, footer?: string): string;
11
18
  /** Color a decision string (ALLOW green, DENY/DENIED red). */
12
19
  export declare function decisionColor(decision: string): string;
13
20
  /**
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Run a management command. `command` is the subcommand name (e.g. 'policy'),
3
- * `argv` are the tokens after it. Never throws resolves to an exit code.
3
+ * `argv` are the tokens after it. Never throws - resolves to an exit code.
4
4
  */
5
5
  export declare function runCommand(command: string, argv: string[]): Promise<number>;
6
6
  /** The subcommand names this router owns (used by src/index.ts to route). */
@@ -418,6 +418,28 @@ var green = (s) => `${c.green}${s}${c.reset}`;
418
418
  var red = (s) => `${c.red}${s}${c.reset}`;
419
419
  var yellow = (s) => `${c.yellow}${s}${c.reset}`;
420
420
  var cyan = (s) => `${c.cyan}${s}${c.reset}`;
421
+ function usage(title, tagline, rows, footer = "Add --json for machine-readable output.") {
422
+ const W = 40;
423
+ const lines = ["", ` ${c.bold}${c.blue4}${title}${c.reset} ${c.dim}${tagline}${c.reset}`, ""];
424
+ for (const [syntax, desc] of rows) {
425
+ if (!syntax) {
426
+ lines.push("");
427
+ continue;
428
+ }
429
+ if (desc === void 0) {
430
+ lines.push(` ${c.cyan}${syntax}${c.reset}`);
431
+ continue;
432
+ }
433
+ if (syntax.length <= W) {
434
+ lines.push(` ${c.cyan}${syntax}${c.reset}${" ".repeat(W - syntax.length)}${c.dim}${desc}${c.reset}`);
435
+ } else {
436
+ lines.push(` ${c.cyan}${syntax}${c.reset}`);
437
+ lines.push(` ${" ".repeat(W)}${c.dim}${desc}${c.reset}`);
438
+ }
439
+ }
440
+ if (footer) lines.push("", ` ${c.dim}${footer}${c.reset}`);
441
+ return lines.join("\n");
442
+ }
421
443
  function decisionColor(decision) {
422
444
  const d = decision.toUpperCase();
423
445
  if (d === "ALLOW") return green(d);
@@ -495,20 +517,16 @@ function flagBool(flags, name) {
495
517
  }
496
518
 
497
519
  // src/commands/policy.ts
498
- var USAGE = `${bold("solongate policy")} \u2014 manage cloud policies
499
-
500
- policy list List all policies
501
- policy show <id> [--version N] Show one policy (rules, mode)
502
- policy rules <id> List a policy's rules
503
- policy allow <id> --tool <p> [--command|--path|--url <val>]
504
- Append an ALLOW rule
505
- policy revoke <id> <ruleId> Remove a rule
506
- policy active Show the resolved active policy
507
- policy activate <id> | --clear Pin / unpin the active policy
508
- policy dry-run <id|file.json> [--limit N] [--mode denylist|whitelist]
509
- Replay recent traffic against a policy's rules
510
-
511
- Add --json to any read command for machine-readable output.`;
520
+ var USAGE = usage("solongate policy", "manage cloud policies", [
521
+ ["policy list", "list all policies"],
522
+ ["policy show <id> [--version N]", "show one policy (rules, mode)"],
523
+ ["policy rules <id>", "list a policy's rules"],
524
+ ["policy allow <id> --tool <p> [--command|--path|--url <val>]", "append an ALLOW rule"],
525
+ ["policy revoke <id> <ruleId>", "remove a rule"],
526
+ ["policy active", "show the resolved active policy"],
527
+ ["policy activate <id> | --clear", "pin / unpin the active policy"],
528
+ ["policy dry-run <id|file.json> [--limit N] [--mode denylist|whitelist]", "replay recent traffic against rules"]
529
+ ], "Add --json to any read command for machine-readable output.");
512
530
  async function run(argv) {
513
531
  const { positionals, flags } = parse(argv);
514
532
  const sub = positionals[0];
@@ -533,7 +551,7 @@ async function run(argv) {
533
551
  p.mode === "whitelist" ? green("whitelist") : "denylist",
534
552
  String(p.rules?.length ?? 0),
535
553
  `v${p.version}`,
536
- dim(truncate(p.created_by || "\u2014", 20))
554
+ dim(truncate(p.created_by || "-", 20))
537
555
  ])
538
556
  );
539
557
  return 0;
@@ -596,7 +614,7 @@ async function run(argv) {
596
614
  }
597
615
  err("");
598
616
  err(` Active: ${bold(a.policy.name)} ${dim(`(${a.policy.id})`)} v${a.version}`);
599
- err(` matched by: ${cyan(a.matched_by ?? "\u2014")} self-protection: ${a.self_protection_enabled ? green("on") : dim("off")}`);
617
+ err(` matched by: ${cyan(a.matched_by ?? "-")} self-protection: ${a.self_protection_enabled ? green("on") : dim("off")}`);
600
618
  const rl = a.security?.rateLimit;
601
619
  if (rl) err(` rate limit: ${rl.perMinute}/min ${rl.perHour}/h ${rl.perDay}/day`);
602
620
  if (a.security?.dlpBlock) err(` DLP block: ${a.security.dlpBlock.patterns.length} patterns`);
@@ -651,7 +669,7 @@ function printRules(rules) {
651
669
  String(r.priority),
652
670
  cyan(truncate(r.toolPattern, 24)),
653
671
  dim(truncate(r.id, 22)),
654
- truncate(r.description || "\u2014", 40)
672
+ truncate(r.description || "-", 40)
655
673
  ])
656
674
  );
657
675
  }
@@ -665,13 +683,11 @@ async function resolveRules(target) {
665
683
  }
666
684
 
667
685
  // src/commands/ratelimit.ts
668
- var USAGE2 = `${bold("solongate ratelimit")} \u2014 request throttling
669
-
670
- ratelimit show Current limits + change history
671
- ratelimit set --minute N [--hour N] [--day N] [--mode off|detect|block]
672
- ratelimit history Recent limit changes
673
-
674
- Add --json for machine-readable output.`;
686
+ var USAGE2 = usage("solongate ratelimit", "request throttling", [
687
+ ["ratelimit show", "current limits + change history"],
688
+ ["ratelimit set --minute N [--hour N] [--day N] [--mode off|detect|block]"],
689
+ ["ratelimit history", "recent limit changes"]
690
+ ]);
675
691
  var modeColor = (m) => m === "block" ? green(m) : m === "detect" ? yellow(m) : dim(m);
676
692
  async function run2(argv) {
677
693
  const { positionals, flags } = parse(argv);
@@ -736,16 +752,14 @@ async function run2(argv) {
736
752
  }
737
753
 
738
754
  // src/commands/dlp.ts
739
- var USAGE3 = `${bold("solongate dlp")} \u2014 data-loss prevention
740
-
741
- dlp show Current mode + enabled patterns
742
- dlp mode <off|detect|block> Set enforcement mode
743
- dlp enable <pattern> Enable a built-in pattern
744
- dlp disable <pattern> Disable a built-in pattern
745
- dlp add-custom --name X --re <regex> Add a custom pattern
746
- dlp remove-custom <name> Remove a custom pattern
747
-
748
- Add --json for machine-readable output.`;
755
+ var USAGE3 = usage("solongate dlp", "data-loss prevention", [
756
+ ["dlp show", "current mode + enabled patterns"],
757
+ ["dlp mode <off|detect|block>", "set enforcement mode"],
758
+ ["dlp enable <pattern>", "enable a built-in pattern"],
759
+ ["dlp disable <pattern>", "disable a built-in pattern"],
760
+ ["dlp add-custom --name X --re <regex>", "add a custom pattern"],
761
+ ["dlp remove-custom <name>", "remove a custom pattern"]
762
+ ]);
749
763
  var modeColor2 = (m) => m === "block" ? green(m) : m === "detect" ? yellow(m) : dim(m);
750
764
  async function run3(argv) {
751
765
  const { positionals, flags } = parse(argv);
@@ -817,13 +831,11 @@ async function run3(argv) {
817
831
  }
818
832
 
819
833
  // src/commands/stats.ts
820
- var USAGE4 = `${bold("solongate stats")} \u2014 traffic & security stats
821
-
822
- stats Overview (totals, recent activity)
823
- stats timeseries [--period 24h|7d|30d|all]
824
- stats drift [--days N] Denials rising/falling vs previous window
825
-
826
- Add --json for machine-readable output.`;
834
+ var USAGE4 = usage("solongate stats", "traffic & security stats", [
835
+ ["stats", "overview (totals, recent activity)"],
836
+ ["stats timeseries [--period 24h|7d|30d|all]"],
837
+ ["stats drift [--days N]", "denials rising/falling vs previous window"]
838
+ ]);
827
839
  async function run4(argv) {
828
840
  const { positionals, flags } = parse(argv);
829
841
  const sub = positionals[0] ?? "overview";
@@ -845,7 +857,7 @@ async function run4(argv) {
845
857
  decisionColor(a.decision),
846
858
  cyan(truncate(a.tool_name, 24)),
847
859
  dim(a.trust_level),
848
- String(a.evaluation_time_ms ?? "\u2014"),
860
+ String(a.evaluation_time_ms ?? "-"),
849
861
  dim(a.created_at)
850
862
  ])
851
863
  );
@@ -876,8 +888,8 @@ async function run4(argv) {
876
888
  bold(String(r.current)),
877
889
  dim(String(r.previous)),
878
890
  r.is_new ? green("NEW") : r.spike ? red(`+${r.delta}`) : String(r.delta),
879
- cyan(truncate(r.rule_id ?? "\u2014", 22)),
880
- truncate(r.reason ?? r.last_tool ?? "\u2014", 36)
891
+ cyan(truncate(r.rule_id ?? "-", 22)),
892
+ truncate(r.reason ?? r.last_tool ?? "-", 36)
881
893
  ])
882
894
  );
883
895
  return 0;
@@ -888,14 +900,12 @@ async function run4(argv) {
888
900
  }
889
901
 
890
902
  // src/commands/audit.ts
891
- var USAGE5 = `${bold("solongate audit")} \u2014 audit log
892
-
893
- audit [--filter ALLOW|DENY] [--tool <substr>] [--signal dlp|ratelimit]
894
- [--search <text>] [--agent-name <name>] [--limit N]
895
- audit whitelist <logId> [--scope exact|tool]
896
- Turn a denied call into an ALLOW rule
897
-
898
- Add --json for machine-readable output.`;
903
+ var USAGE5 = usage("solongate audit", "audit log", [
904
+ ["audit [--filter ALLOW|DENY] [--tool <substr>] [--signal dlp|ratelimit]"],
905
+ [" [--search <text>] [--agent-name <name>] [--limit N]"],
906
+ ["audit whitelist <logId> [--scope exact|tool]", "turn a denied call into an ALLOW rule"],
907
+ ["audit block <logId> [--scope exact|tool]", "turn a call into a DENY rule"]
908
+ ]);
899
909
  async function run5(argv) {
900
910
  const { positionals, flags } = parse(argv);
901
911
  const json = flagBool(flags, "json");
@@ -938,8 +948,8 @@ async function run5(argv) {
938
948
  res.entries.map((e) => [
939
949
  decisionColor(e.decision),
940
950
  cyan(truncate(e.tool_name, 22)),
941
- dim(truncate(e.agent_name ?? "\u2014", 16)),
942
- truncate(e.reason ?? "\u2014", 30),
951
+ dim(truncate(e.agent_name ?? "-", 16)),
952
+ truncate(e.reason ?? "-", 30),
943
953
  e.dlp_matches?.length ? red(String(e.dlp_matches.length)) : dim("0"),
944
954
  dim(e.created_at),
945
955
  dim(truncate(e.id, 10))
@@ -967,7 +977,7 @@ async function runAgents(argv) {
967
977
  a.denied_calls ? red(String(a.denied_calls)) : dim("0"),
968
978
  a.dlp_events ? red(String(a.dlp_events)) : dim("0"),
969
979
  `${a.trust_score}`,
970
- dim(truncate(a.character || "\u2014", 22))
980
+ dim(truncate(a.character || "-", 22))
971
981
  ])
972
982
  );
973
983
  return 0;
@@ -983,7 +993,7 @@ async function runAgent(argv) {
983
993
  err(` ${bold(a.agent_id)} status: ${statusColor(String(a.status))}`);
984
994
  const base = a.baseline;
985
995
  if (base) {
986
- err(` ${dim(base.character ?? "")} trust ${bold(String(base.trustScore ?? "\u2014"))}/100 deny-rate ${(Number(base.denyRate ?? 0) * 100).toFixed(0)}%`);
996
+ err(` ${dim(base.character ?? "")} trust ${bold(String(base.trustScore ?? "-"))}/100 deny-rate ${(Number(base.denyRate ?? 0) * 100).toFixed(0)}%`);
987
997
  }
988
998
  const feed = a.recent_feed ?? [];
989
999
  if (feed.length) {
@@ -993,7 +1003,7 @@ async function runAgent(argv) {
993
1003
  feed.slice(0, 15).map((f) => [
994
1004
  f.decision === "ALLOW" ? green("ALLOW") : red(String(f.decision)),
995
1005
  cyan(truncate(String(f.tool), 22)),
996
- truncate(String(f.reason ?? "\u2014"), 30),
1006
+ truncate(String(f.reason ?? "-"), 30),
997
1007
  dim(String(f.created_at))
998
1008
  ])
999
1009
  );
@@ -1011,7 +1021,7 @@ async function run6(argv) {
1011
1021
  const json = flagBool(flags, "json");
1012
1022
  const checks = [];
1013
1023
  if (!isAuthenticated()) {
1014
- checks.push({ name: "login", ok: false, detail: "not logged in \u2014 run `solongate`, add your account in the Accounts panel" });
1024
+ checks.push({ name: "login", ok: false, detail: "not logged in - run `solongate`, add your account in the Accounts panel" });
1015
1025
  } else {
1016
1026
  const { apiUrl } = resolveCredentials();
1017
1027
  checks.push({ name: "login", ok: true, detail: `paired \xB7 ${apiUrl}` });
@@ -1020,7 +1030,7 @@ async function run6(argv) {
1020
1030
  if (active2.policy) {
1021
1031
  checks.push({ name: "active policy", ok: true, detail: `${active2.policy.name} v${active2.version} \xB7 ${active2.policy.mode ?? "denylist"} \xB7 matched by ${active2.matched_by}` });
1022
1032
  } else {
1023
- checks.push({ name: "active policy", ok: "warn", detail: "no policy resolves \u2014 every call falls back to default" });
1033
+ checks.push({ name: "active policy", ok: "warn", detail: "no policy resolves - every call falls back to default" });
1024
1034
  }
1025
1035
  const sec = active2.security;
1026
1036
  checks.push({ name: "rate limit", ok: sec?.rateLimit ? true : "warn", detail: sec?.rateLimit ? `${sec.rateLimit.perMinute}/min` : "off" });
@@ -1040,7 +1050,7 @@ async function run6(argv) {
1040
1050
  const ageMin = (Date.now() - st.mtimeMs) / 6e4;
1041
1051
  checks.push({ name: "local logs", ok: true, detail: `on \xB7 ${(st.size / 1024).toFixed(0)}KB \xB7 last write ${ageMin < 1 ? "just now" : Math.round(ageMin) + "m ago"}` });
1042
1052
  } else {
1043
- checks.push({ name: "local logs", ok: "warn", detail: "off (logs go to cloud) \u2014 enable in dashboard \u2192 Settings" });
1053
+ checks.push({ name: "local logs", ok: "warn", detail: "off (logs go to cloud) - enable in dashboard \u2192 Settings" });
1044
1054
  }
1045
1055
  if (json) return printJson(checks), checks.some((c2) => c2.ok === false) ? 1 : 0;
1046
1056
  err("");
@@ -1054,7 +1064,7 @@ async function run6(argv) {
1054
1064
  const bad = checks.filter((c2) => c2.ok === false).length;
1055
1065
  const warn = checks.filter((c2) => c2.ok === "warn").length;
1056
1066
  if (bad) err(` ${red(`${bad} problem(s)`)}${warn ? dim(` \xB7 ${warn} warning(s)`) : ""}`);
1057
- else if (warn) err(` ${yellow(`${warn} warning(s)`)} ${dim("\u2014 guard is working")}`);
1067
+ else if (warn) err(` ${yellow(`${warn} warning(s)`)} ${dim("- guard is working")}`);
1058
1068
  else err(` ${green("all good")}`);
1059
1069
  return bad ? 1 : 0;
1060
1070
  }
@@ -1155,7 +1165,7 @@ async function run7(argv) {
1155
1165
  } catch {
1156
1166
  }
1157
1167
  };
1158
- if (!json) err(` ${c.dim}watching guard stream \u2014 Ctrl+C to stop${c.reset}`);
1168
+ if (!json) err(` ${c.dim}watching guard stream - Ctrl+C to stop${c.reset}`);
1159
1169
  pollLocal();
1160
1170
  await pollCloud();
1161
1171
  first = false;
@@ -1166,14 +1176,12 @@ async function run7(argv) {
1166
1176
  }
1167
1177
 
1168
1178
  // src/commands/alerts.ts
1169
- var USAGE6 = `${bold("solongate alerts")} \u2014 spike alerts (Telegram / email)
1170
-
1171
- alerts list
1172
- alerts add --signal deny|dlp|ratelimit|any --threshold N --window S
1173
- (--email <a> | --telegram <chatId> | --slack <url>)
1174
- alerts remove <id>
1175
-
1176
- Add --json for machine-readable output.`;
1179
+ var USAGE6 = usage("solongate alerts", "spike alerts (Telegram / email)", [
1180
+ ["alerts list"],
1181
+ ["alerts add --signal deny|dlp|ratelimit|any --threshold N --window S"],
1182
+ [" (--email <a> | --telegram <chatId> | --slack <url>)"],
1183
+ ["alerts remove <id>"]
1184
+ ]);
1177
1185
  async function run8(argv) {
1178
1186
  const { positionals, flags } = parse(argv);
1179
1187
  const sub = positionals[0] ?? "list";
@@ -1193,7 +1201,7 @@ async function run8(argv) {
1193
1201
  cyan(r.signal),
1194
1202
  `${r.threshold}`,
1195
1203
  `${r.windowSeconds}s`,
1196
- dim([...r.emails ?? [], ...(r.telegram ?? []).map((t) => "tg:" + t), ...(r.slackUrls ?? []).map(() => "slack")].join(" ") || "\u2014")
1204
+ dim([...r.emails ?? [], ...(r.telegram ?? []).map((t) => "tg:" + t), ...(r.slackUrls ?? []).map(() => "slack")].join(" ") || "-")
1197
1205
  ])
1198
1206
  );
1199
1207
  return 0;
@@ -1227,13 +1235,11 @@ async function run8(argv) {
1227
1235
  }
1228
1236
 
1229
1237
  // src/commands/webhooks.ts
1230
- var USAGE7 = `${bold("solongate webhooks")} \u2014 event webhooks
1231
-
1232
- webhooks list
1233
- webhooks add --url <https://\u2026> [--events denials|allowed|all]
1234
- webhooks remove <id>
1235
-
1236
- Add --json for machine-readable output.`;
1238
+ var USAGE7 = usage("solongate webhooks", "event webhooks", [
1239
+ ["webhooks list"],
1240
+ ["webhooks add --url <https://\u2026> [--events denials|allowed|all]"],
1241
+ ["webhooks remove <id>"]
1242
+ ]);
1237
1243
  async function run9(argv) {
1238
1244
  const { positionals, flags } = parse(argv);
1239
1245
  const sub = positionals[0] ?? "list";
package/dist/index.js CHANGED
@@ -11326,6 +11326,28 @@ var init_tui = __esm({
11326
11326
  function printJson(value) {
11327
11327
  out(JSON.stringify(value, null, 2));
11328
11328
  }
11329
+ function usage(title, tagline, rows, footer = "Add --json for machine-readable output.") {
11330
+ const W = 40;
11331
+ const lines = ["", ` ${c.bold}${c.blue4}${title}${c.reset} ${c.dim}${tagline}${c.reset}`, ""];
11332
+ for (const [syntax, desc] of rows) {
11333
+ if (!syntax) {
11334
+ lines.push("");
11335
+ continue;
11336
+ }
11337
+ if (desc === void 0) {
11338
+ lines.push(` ${c.cyan}${syntax}${c.reset}`);
11339
+ continue;
11340
+ }
11341
+ if (syntax.length <= W) {
11342
+ lines.push(` ${c.cyan}${syntax}${c.reset}${" ".repeat(W - syntax.length)}${c.dim}${desc}${c.reset}`);
11343
+ } else {
11344
+ lines.push(` ${c.cyan}${syntax}${c.reset}`);
11345
+ lines.push(` ${" ".repeat(W)}${c.dim}${desc}${c.reset}`);
11346
+ }
11347
+ }
11348
+ if (footer) lines.push("", ` ${c.dim}${footer}${c.reset}`);
11349
+ return lines.join("\n");
11350
+ }
11329
11351
  function decisionColor2(decision) {
11330
11352
  const d = decision.toUpperCase();
11331
11353
  if (d === "ALLOW") return green(d);
@@ -11445,7 +11467,7 @@ async function run(argv) {
11445
11467
  p.mode === "whitelist" ? green("whitelist") : "denylist",
11446
11468
  String(p.rules?.length ?? 0),
11447
11469
  `v${p.version}`,
11448
- dim(truncate3(p.created_by || "\u2014", 20))
11470
+ dim(truncate3(p.created_by || "-", 20))
11449
11471
  ])
11450
11472
  );
11451
11473
  return 0;
@@ -11508,7 +11530,7 @@ async function run(argv) {
11508
11530
  }
11509
11531
  err("");
11510
11532
  err(` Active: ${bold(a.policy.name)} ${dim(`(${a.policy.id})`)} v${a.version}`);
11511
- err(` matched by: ${cyan(a.matched_by ?? "\u2014")} self-protection: ${a.self_protection_enabled ? green("on") : dim("off")}`);
11533
+ err(` matched by: ${cyan(a.matched_by ?? "-")} self-protection: ${a.self_protection_enabled ? green("on") : dim("off")}`);
11512
11534
  const rl = a.security?.rateLimit;
11513
11535
  if (rl) err(` rate limit: ${rl.perMinute}/min ${rl.perHour}/h ${rl.perDay}/day`);
11514
11536
  if (a.security?.dlpBlock) err(` DLP block: ${a.security.dlpBlock.patterns.length} patterns`);
@@ -11563,7 +11585,7 @@ function printRules(rules) {
11563
11585
  String(r.priority),
11564
11586
  cyan(truncate3(r.toolPattern, 24)),
11565
11587
  dim(truncate3(r.id, 22)),
11566
- truncate3(r.description || "\u2014", 40)
11588
+ truncate3(r.description || "-", 40)
11567
11589
  ])
11568
11590
  );
11569
11591
  }
@@ -11582,20 +11604,16 @@ var init_policy = __esm({
11582
11604
  init_api_client();
11583
11605
  init_args();
11584
11606
  init_format();
11585
- USAGE = `${bold("solongate policy")} \u2014 manage cloud policies
11586
-
11587
- policy list List all policies
11588
- policy show <id> [--version N] Show one policy (rules, mode)
11589
- policy rules <id> List a policy's rules
11590
- policy allow <id> --tool <p> [--command|--path|--url <val>]
11591
- Append an ALLOW rule
11592
- policy revoke <id> <ruleId> Remove a rule
11593
- policy active Show the resolved active policy
11594
- policy activate <id> | --clear Pin / unpin the active policy
11595
- policy dry-run <id|file.json> [--limit N] [--mode denylist|whitelist]
11596
- Replay recent traffic against a policy's rules
11597
-
11598
- Add --json to any read command for machine-readable output.`;
11607
+ USAGE = usage("solongate policy", "manage cloud policies", [
11608
+ ["policy list", "list all policies"],
11609
+ ["policy show <id> [--version N]", "show one policy (rules, mode)"],
11610
+ ["policy rules <id>", "list a policy's rules"],
11611
+ ["policy allow <id> --tool <p> [--command|--path|--url <val>]", "append an ALLOW rule"],
11612
+ ["policy revoke <id> <ruleId>", "remove a rule"],
11613
+ ["policy active", "show the resolved active policy"],
11614
+ ["policy activate <id> | --clear", "pin / unpin the active policy"],
11615
+ ["policy dry-run <id|file.json> [--limit N] [--mode denylist|whitelist]", "replay recent traffic against rules"]
11616
+ ], "Add --json to any read command for machine-readable output.");
11599
11617
  }
11600
11618
  });
11601
11619
 
@@ -11668,13 +11686,11 @@ var init_ratelimit = __esm({
11668
11686
  init_api_client();
11669
11687
  init_args();
11670
11688
  init_format();
11671
- USAGE2 = `${bold("solongate ratelimit")} \u2014 request throttling
11672
-
11673
- ratelimit show Current limits + change history
11674
- ratelimit set --minute N [--hour N] [--day N] [--mode off|detect|block]
11675
- ratelimit history Recent limit changes
11676
-
11677
- Add --json for machine-readable output.`;
11689
+ USAGE2 = usage("solongate ratelimit", "request throttling", [
11690
+ ["ratelimit show", "current limits + change history"],
11691
+ ["ratelimit set --minute N [--hour N] [--day N] [--mode off|detect|block]"],
11692
+ ["ratelimit history", "recent limit changes"]
11693
+ ]);
11678
11694
  modeColor2 = (m) => m === "block" ? green(m) : m === "detect" ? yellow(m) : dim(m);
11679
11695
  }
11680
11696
  });
@@ -11755,16 +11771,14 @@ var init_dlp = __esm({
11755
11771
  init_api_client();
11756
11772
  init_args();
11757
11773
  init_format();
11758
- USAGE3 = `${bold("solongate dlp")} \u2014 data-loss prevention
11759
-
11760
- dlp show Current mode + enabled patterns
11761
- dlp mode <off|detect|block> Set enforcement mode
11762
- dlp enable <pattern> Enable a built-in pattern
11763
- dlp disable <pattern> Disable a built-in pattern
11764
- dlp add-custom --name X --re <regex> Add a custom pattern
11765
- dlp remove-custom <name> Remove a custom pattern
11766
-
11767
- Add --json for machine-readable output.`;
11774
+ USAGE3 = usage("solongate dlp", "data-loss prevention", [
11775
+ ["dlp show", "current mode + enabled patterns"],
11776
+ ["dlp mode <off|detect|block>", "set enforcement mode"],
11777
+ ["dlp enable <pattern>", "enable a built-in pattern"],
11778
+ ["dlp disable <pattern>", "disable a built-in pattern"],
11779
+ ["dlp add-custom --name X --re <regex>", "add a custom pattern"],
11780
+ ["dlp remove-custom <name>", "remove a custom pattern"]
11781
+ ]);
11768
11782
  modeColor3 = (m) => m === "block" ? green(m) : m === "detect" ? yellow(m) : dim(m);
11769
11783
  }
11770
11784
  });
@@ -11791,7 +11805,7 @@ async function run4(argv) {
11791
11805
  decisionColor2(a.decision),
11792
11806
  cyan(truncate3(a.tool_name, 24)),
11793
11807
  dim(a.trust_level),
11794
- String(a.evaluation_time_ms ?? "\u2014"),
11808
+ String(a.evaluation_time_ms ?? "-"),
11795
11809
  dim(a.created_at)
11796
11810
  ])
11797
11811
  );
@@ -11822,8 +11836,8 @@ async function run4(argv) {
11822
11836
  bold(String(r.current)),
11823
11837
  dim(String(r.previous)),
11824
11838
  r.is_new ? green("NEW") : r.spike ? red(`+${r.delta}`) : String(r.delta),
11825
- cyan(truncate3(r.rule_id ?? "\u2014", 22)),
11826
- truncate3(r.reason ?? r.last_tool ?? "\u2014", 36)
11839
+ cyan(truncate3(r.rule_id ?? "-", 22)),
11840
+ truncate3(r.reason ?? r.last_tool ?? "-", 36)
11827
11841
  ])
11828
11842
  );
11829
11843
  return 0;
@@ -11839,13 +11853,11 @@ var init_stats2 = __esm({
11839
11853
  init_api_client();
11840
11854
  init_args();
11841
11855
  init_format();
11842
- USAGE4 = `${bold("solongate stats")} \u2014 traffic & security stats
11843
-
11844
- stats Overview (totals, recent activity)
11845
- stats timeseries [--period 24h|7d|30d|all]
11846
- stats drift [--days N] Denials rising/falling vs previous window
11847
-
11848
- Add --json for machine-readable output.`;
11856
+ USAGE4 = usage("solongate stats", "traffic & security stats", [
11857
+ ["stats", "overview (totals, recent activity)"],
11858
+ ["stats timeseries [--period 24h|7d|30d|all]"],
11859
+ ["stats drift [--days N]", "denials rising/falling vs previous window"]
11860
+ ]);
11849
11861
  }
11850
11862
  });
11851
11863
 
@@ -11892,8 +11904,8 @@ async function run5(argv) {
11892
11904
  res.entries.map((e) => [
11893
11905
  decisionColor2(e.decision),
11894
11906
  cyan(truncate3(e.tool_name, 22)),
11895
- dim(truncate3(e.agent_name ?? "\u2014", 16)),
11896
- truncate3(e.reason ?? "\u2014", 30),
11907
+ dim(truncate3(e.agent_name ?? "-", 16)),
11908
+ truncate3(e.reason ?? "-", 30),
11897
11909
  e.dlp_matches?.length ? red(String(e.dlp_matches.length)) : dim("0"),
11898
11910
  dim(e.created_at),
11899
11911
  dim(truncate3(e.id, 10))
@@ -11908,14 +11920,12 @@ var init_audit2 = __esm({
11908
11920
  init_api_client();
11909
11921
  init_args();
11910
11922
  init_format();
11911
- USAGE5 = `${bold("solongate audit")} \u2014 audit log
11912
-
11913
- audit [--filter ALLOW|DENY] [--tool <substr>] [--signal dlp|ratelimit]
11914
- [--search <text>] [--agent-name <name>] [--limit N]
11915
- audit whitelist <logId> [--scope exact|tool]
11916
- Turn a denied call into an ALLOW rule
11917
-
11918
- Add --json for machine-readable output.`;
11923
+ USAGE5 = usage("solongate audit", "audit log", [
11924
+ ["audit [--filter ALLOW|DENY] [--tool <substr>] [--signal dlp|ratelimit]"],
11925
+ [" [--search <text>] [--agent-name <name>] [--limit N]"],
11926
+ ["audit whitelist <logId> [--scope exact|tool]", "turn a denied call into an ALLOW rule"],
11927
+ ["audit block <logId> [--scope exact|tool]", "turn a call into a DENY rule"]
11928
+ ]);
11919
11929
  }
11920
11930
  });
11921
11931
 
@@ -11937,7 +11947,7 @@ async function runAgents(argv) {
11937
11947
  a.denied_calls ? red(String(a.denied_calls)) : dim("0"),
11938
11948
  a.dlp_events ? red(String(a.dlp_events)) : dim("0"),
11939
11949
  `${a.trust_score}`,
11940
- dim(truncate3(a.character || "\u2014", 22))
11950
+ dim(truncate3(a.character || "-", 22))
11941
11951
  ])
11942
11952
  );
11943
11953
  return 0;
@@ -11953,7 +11963,7 @@ async function runAgent(argv) {
11953
11963
  err(` ${bold(a.agent_id)} status: ${statusColor(String(a.status))}`);
11954
11964
  const base = a.baseline;
11955
11965
  if (base) {
11956
- err(` ${dim(base.character ?? "")} trust ${bold(String(base.trustScore ?? "\u2014"))}/100 deny-rate ${(Number(base.denyRate ?? 0) * 100).toFixed(0)}%`);
11966
+ err(` ${dim(base.character ?? "")} trust ${bold(String(base.trustScore ?? "-"))}/100 deny-rate ${(Number(base.denyRate ?? 0) * 100).toFixed(0)}%`);
11957
11967
  }
11958
11968
  const feed = a.recent_feed ?? [];
11959
11969
  if (feed.length) {
@@ -11963,7 +11973,7 @@ async function runAgent(argv) {
11963
11973
  feed.slice(0, 15).map((f) => [
11964
11974
  f.decision === "ALLOW" ? green("ALLOW") : red(String(f.decision)),
11965
11975
  cyan(truncate3(String(f.tool), 22)),
11966
- truncate3(String(f.reason ?? "\u2014"), 30),
11976
+ truncate3(String(f.reason ?? "-"), 30),
11967
11977
  dim(String(f.created_at))
11968
11978
  ])
11969
11979
  );
@@ -11990,7 +12000,7 @@ async function run6(argv) {
11990
12000
  const json = flagBool(flags, "json");
11991
12001
  const checks = [];
11992
12002
  if (!isAuthenticated()) {
11993
- checks.push({ name: "login", ok: false, detail: "not logged in \u2014 run `solongate`, add your account in the Accounts panel" });
12003
+ checks.push({ name: "login", ok: false, detail: "not logged in - run `solongate`, add your account in the Accounts panel" });
11994
12004
  } else {
11995
12005
  const { apiUrl } = resolveCredentials();
11996
12006
  checks.push({ name: "login", ok: true, detail: `paired \xB7 ${apiUrl}` });
@@ -11999,7 +12009,7 @@ async function run6(argv) {
11999
12009
  if (active2.policy) {
12000
12010
  checks.push({ name: "active policy", ok: true, detail: `${active2.policy.name} v${active2.version} \xB7 ${active2.policy.mode ?? "denylist"} \xB7 matched by ${active2.matched_by}` });
12001
12011
  } else {
12002
- checks.push({ name: "active policy", ok: "warn", detail: "no policy resolves \u2014 every call falls back to default" });
12012
+ checks.push({ name: "active policy", ok: "warn", detail: "no policy resolves - every call falls back to default" });
12003
12013
  }
12004
12014
  const sec = active2.security;
12005
12015
  checks.push({ name: "rate limit", ok: sec?.rateLimit ? true : "warn", detail: sec?.rateLimit ? `${sec.rateLimit.perMinute}/min` : "off" });
@@ -12019,7 +12029,7 @@ async function run6(argv) {
12019
12029
  const ageMin = (Date.now() - st.mtimeMs) / 6e4;
12020
12030
  checks.push({ name: "local logs", ok: true, detail: `on \xB7 ${(st.size / 1024).toFixed(0)}KB \xB7 last write ${ageMin < 1 ? "just now" : Math.round(ageMin) + "m ago"}` });
12021
12031
  } else {
12022
- checks.push({ name: "local logs", ok: "warn", detail: "off (logs go to cloud) \u2014 enable in dashboard \u2192 Settings" });
12032
+ checks.push({ name: "local logs", ok: "warn", detail: "off (logs go to cloud) - enable in dashboard \u2192 Settings" });
12023
12033
  }
12024
12034
  if (json) return printJson(checks), checks.some((c2) => c2.ok === false) ? 1 : 0;
12025
12035
  err("");
@@ -12033,7 +12043,7 @@ async function run6(argv) {
12033
12043
  const bad = checks.filter((c2) => c2.ok === false).length;
12034
12044
  const warn = checks.filter((c2) => c2.ok === "warn").length;
12035
12045
  if (bad) err(` ${red(`${bad} problem(s)`)}${warn ? dim(` \xB7 ${warn} warning(s)`) : ""}`);
12036
- else if (warn) err(` ${yellow(`${warn} warning(s)`)} ${dim("\u2014 guard is working")}`);
12046
+ else if (warn) err(` ${yellow(`${warn} warning(s)`)} ${dim("- guard is working")}`);
12037
12047
  else err(` ${green("all good")}`);
12038
12048
  return bad ? 1 : 0;
12039
12049
  }
@@ -12141,7 +12151,7 @@ async function run7(argv) {
12141
12151
  } catch {
12142
12152
  }
12143
12153
  };
12144
- if (!json) err(` ${c.dim}watching guard stream \u2014 Ctrl+C to stop${c.reset}`);
12154
+ if (!json) err(` ${c.dim}watching guard stream - Ctrl+C to stop${c.reset}`);
12145
12155
  pollLocal();
12146
12156
  await pollCloud();
12147
12157
  first = false;
@@ -12184,7 +12194,7 @@ async function run8(argv) {
12184
12194
  cyan(r.signal),
12185
12195
  `${r.threshold}`,
12186
12196
  `${r.windowSeconds}s`,
12187
- dim([...r.emails ?? [], ...(r.telegram ?? []).map((t) => "tg:" + t), ...(r.slackUrls ?? []).map(() => "slack")].join(" ") || "\u2014")
12197
+ dim([...r.emails ?? [], ...(r.telegram ?? []).map((t) => "tg:" + t), ...(r.slackUrls ?? []).map(() => "slack")].join(" ") || "-")
12188
12198
  ])
12189
12199
  );
12190
12200
  return 0;
@@ -12223,14 +12233,12 @@ var init_alerts = __esm({
12223
12233
  init_api_client();
12224
12234
  init_args();
12225
12235
  init_format();
12226
- USAGE6 = `${bold("solongate alerts")} \u2014 spike alerts (Telegram / email)
12227
-
12228
- alerts list
12229
- alerts add --signal deny|dlp|ratelimit|any --threshold N --window S
12230
- (--email <a> | --telegram <chatId> | --slack <url>)
12231
- alerts remove <id>
12232
-
12233
- Add --json for machine-readable output.`;
12236
+ USAGE6 = usage("solongate alerts", "spike alerts (Telegram / email)", [
12237
+ ["alerts list"],
12238
+ ["alerts add --signal deny|dlp|ratelimit|any --threshold N --window S"],
12239
+ [" (--email <a> | --telegram <chatId> | --slack <url>)"],
12240
+ ["alerts remove <id>"]
12241
+ ]);
12234
12242
  }
12235
12243
  });
12236
12244
 
@@ -12277,13 +12285,11 @@ var init_webhooks = __esm({
12277
12285
  init_api_client();
12278
12286
  init_args();
12279
12287
  init_format();
12280
- USAGE7 = `${bold("solongate webhooks")} \u2014 event webhooks
12281
-
12282
- webhooks list
12283
- webhooks add --url <https://\u2026> [--events denials|allowed|all]
12284
- webhooks remove <id>
12285
-
12286
- Add --json for machine-readable output.`;
12288
+ USAGE7 = usage("solongate webhooks", "event webhooks", [
12289
+ ["webhooks list"],
12290
+ ["webhooks add --url <https://\u2026> [--events denials|allowed|all]"],
12291
+ ["webhooks remove <id>"]
12292
+ ]);
12287
12293
  }
12288
12294
  });
12289
12295
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.82.24",
3
+ "version": "0.82.25",
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": {