@solongate/proxy 0.81.39 → 0.81.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  > **Don't `npm i` this.** There's nothing to import. Run the two commands below to pair your machine:
4
4
  > ```bash
5
- > npx -y @solongate/proxy@latest
6
- > npx -y @solongate/proxy@latest login
5
+ > npm i -g @solongate/proxy
6
+ > solongate
7
7
  > ```
8
8
 
9
9
  **Security for AI agents.** SolonGate checks every action an AI agent takes. Each tool call (shell command, file read or write, network request) is allowed, blocked, or logged before it runs, based on a policy you control. No code changes.
@@ -24,8 +24,8 @@ SolonGate is fully managed. There is nothing to host: pair your machine with one
24
24
  Pair the machine and turn on the guard. There are no API keys to copy. First fetch SolonGate, then log in:
25
25
 
26
26
  ```bash
27
- npx -y @solongate/proxy@latest
28
- npx -y @solongate/proxy@latest login
27
+ npm i -g @solongate/proxy
28
+ solongate
29
29
  ```
30
30
 
31
31
  This opens your browser to authorize the device. Approve it from your signed-in dashboard and SolonGate installs a global guard hook that intercepts every tool call from every AI session on the machine and checks it against your active policy.
@@ -60,12 +60,6 @@ Prefer to keep everything local? In **Settings**, turn on **Local log storage**
60
60
 
61
61
  Set a threshold in **Settings** and SolonGate notifies you by Telegram, email, or webhook when blocks spike.
62
62
 
63
- ## Uninstall
64
-
65
- ```bash
66
- npx @solongate/proxy logout
67
- ```
68
-
69
63
  ## Why SolonGate?
70
64
 
71
65
  AI agents get direct access to your system: shell, file system, databases, network. SolonGate sits between the agent and the action, enforcing your policy on every tool call before it runs, and recording every decision for audit.
package/dist/index.js CHANGED
@@ -271,7 +271,7 @@ function parseArgs(argv) {
271
271
  }
272
272
  if (!apiKey) {
273
273
  throw new Error(
274
- "Not logged in. Run this once to get started:\n\n npx -y @solongate/proxy@latest login\n"
274
+ "Not logged in. Run this once to get started:\n\n solongate login\n"
275
275
  );
276
276
  }
277
277
  if (!apiKey.startsWith("sg_live_") && !apiKey.startsWith("sg_test_")) {
@@ -327,7 +327,7 @@ function parseArgs(argv) {
327
327
  }
328
328
  if (upstreamArgs.length === 0) {
329
329
  throw new Error(
330
- "No upstream server command provided.\n\nIf you just want to get started, run:\n npx -y @solongate/proxy@latest login\n"
330
+ "No upstream server command provided.\n\nIf you just want to get started, run:\n solongate login\n"
331
331
  );
332
332
  }
333
333
  const [command, ...commandArgs] = upstreamArgs;
@@ -7505,8 +7505,8 @@ function StreamLine({ e, loc, selected }) {
7505
7505
  /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: e.permission.padEnd(5) }),
7506
7506
  /* @__PURE__ */ jsx2(Text2, { color: e.evalMs != null && e.evalMs > 500 ? theme.warn : theme.dim, children: (e.evalMs != null ? `${e.evalMs}ms` : "\u2014").padEnd(7) }),
7507
7507
  /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: truncate2(e.agent ?? "-", 11).padEnd(12) }),
7508
- e.dlp ? /* @__PURE__ */ jsx2(Text2, { color: theme.bad, children: "DLP! " }) : null,
7509
- e.burst ? /* @__PURE__ */ jsx2(Text2, { color: theme.warn, children: "RL! " }) : null,
7508
+ /* @__PURE__ */ jsx2(Text2, { color: e.dlp ? theme.bad : theme.dim, bold: e.dlp, children: ("dlp:" + (e.dlp ? "yes" : "no")).padEnd(8) }),
7509
+ /* @__PURE__ */ jsx2(Text2, { color: e.burst ? theme.warn : theme.dim, bold: e.burst, children: ("rl:" + (e.burst ? "yes" : "no")).padEnd(7) }),
7510
7510
  e.rule && e.decision !== "ALLOW" ? /* @__PURE__ */ jsx2(Text2, { color: theme.bad, children: truncate2(e.rule, 14) + " " }) : null,
7511
7511
  /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: e.detail })
7512
7512
  ] });
@@ -7815,9 +7815,12 @@ function LivePanel({ active: active2 }) {
7815
7815
  const signalOk = (e) => signal === "none" ? true : signal === "deny" ? e.decision !== "ALLOW" : signal === "dlp" ? e.dlp : e.burst;
7816
7816
  const filtered = (filter === "all" ? mergedAll : mergedAll.filter((e) => filter === "local" ? isLoc(e) : !isLoc(e))).filter(matches).filter(signalOk);
7817
7817
  const visibleDesc = filtered.slice().reverse();
7818
+ const activeAlert = alerts.filter((a) => nowMs < a.until).slice(-1)[0];
7819
+ const activeAction = actionMsg && nowMs < actionMsg.until ? actionMsg : null;
7820
+ const bannerRows = (activeAlert ? 1 : 0) + (activeAction ? 1 : 0);
7818
7821
  const chartH = rows >= 36 ? 6 : 4;
7819
7822
  const colH = rows >= 32 ? 7 : 5;
7820
- const streamRows = Math.max(4, rows - 5 - (1 + chartH) - colH);
7823
+ const streamRows = Math.max(4, rows - 5 - (1 + chartH) - colH - bannerRows);
7821
7824
  const innerW = cols - 2;
7822
7825
  const leftW = Math.floor(innerW * 0.55);
7823
7826
  const rightW = innerW - leftW - 2;
@@ -8165,18 +8168,17 @@ function LivePanel({ active: active2 }) {
8165
8168
  /* @__PURE__ */ jsx2(Text2, { color: guard.data?.up_to_date ? theme.ok : theme.warn, children: guard.data ? `v${guard.data.installed ?? "?"}${guard.data.up_to_date ? "" : "\u2192v" + guard.data.latest} ${guard.data.device_count}dev` : "\xB7" }),
8166
8169
  /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: " \u2502" })
8167
8170
  ] }),
8168
- alerts.filter((a) => nowMs < a.until).slice(-1).map((a) => /* @__PURE__ */ jsx2(
8171
+ activeAlert ? /* @__PURE__ */ jsx2(
8169
8172
  Text2,
8170
8173
  {
8171
8174
  wrap: "truncate",
8172
- backgroundColor: a.level === "bad" ? "#3d1220" : "#3d2a12",
8173
- color: a.level === "bad" ? "#ff6b6b" : "#ffb454",
8175
+ backgroundColor: activeAlert.level === "bad" ? "#3d1220" : "#3d2a12",
8176
+ color: activeAlert.level === "bad" ? "#ff6b6b" : "#ffb454",
8174
8177
  bold: true,
8175
- children: ` ${a.level === "bad" ? "\u26D4 ALERT" : "\u23F8 IDLE"} \xB7 ${truncate2(a.msg, innerW - 14)} `
8176
- },
8177
- a.id
8178
- )),
8179
- actionMsg && nowMs < actionMsg.until ? /* @__PURE__ */ jsx2(Text2, { wrap: "truncate", backgroundColor: actionMsg.level === "bad" ? "#3d1220" : "#123d1f", color: actionMsg.level === "bad" ? "#ff6b6b" : "#7bd88f", bold: true, children: ` ${truncate2(actionMsg.text, innerW - 4)} ` }) : null,
8178
+ children: ` ${activeAlert.level === "bad" ? "\u26D4 ALERT" : "\u23F8 IDLE"} \xB7 ${truncate2(activeAlert.msg, innerW - 14)} `
8179
+ }
8180
+ ) : null,
8181
+ activeAction ? /* @__PURE__ */ jsx2(Text2, { wrap: "truncate", backgroundColor: activeAction.level === "bad" ? "#3d1220" : "#123d1f", color: activeAction.level === "bad" ? "#ff6b6b" : "#7bd88f", bold: true, children: ` ${truncate2(activeAction.text, innerW - 4)} ` }) : null,
8180
8182
  /* @__PURE__ */ jsxs2(Box2, { height: 1 + chartH, children: [
8181
8183
  /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", width: leftW, marginRight: 2, children: [
8182
8184
  /* @__PURE__ */ jsx2(PaneTitle, { label: "TRAFFIC", extra: `${trafficLabel} \xB7 peak ${Math.max(0, ...traffic)} \xB7 red = denials`, width: leftW }),
@@ -11324,17 +11326,6 @@ var init_commands = __esm({
11324
11326
  });
11325
11327
 
11326
11328
  // src/global-install.ts
11327
- var global_install_exports = {};
11328
- __export(global_install_exports, {
11329
- globalPaths: () => globalPaths,
11330
- installClaudeShim: () => installClaudeShim,
11331
- installGlobalWithKey: () => installGlobalWithKey,
11332
- lockProtected: () => lockProtected,
11333
- removeClaudeShim: () => removeClaudeShim,
11334
- runGlobalInstall: () => runGlobalInstall,
11335
- runGlobalRestore: () => runGlobalRestore,
11336
- unlockProtected: () => unlockProtected
11337
- });
11338
11329
  import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, existsSync as existsSync6, mkdirSync as mkdirSync6 } from "fs";
11339
11330
  import { resolve as resolve4, join as join11, dirname } from "path";
11340
11331
  import { homedir as homedir9 } from "os";
@@ -11443,26 +11434,6 @@ function ask(question) {
11443
11434
  res(a.trim());
11444
11435
  }));
11445
11436
  }
11446
- function runGlobalRestore() {
11447
- const p = globalPaths();
11448
- unlockProtected();
11449
- removeClaudeShim();
11450
- if (existsSync6(p.backupPath)) {
11451
- writeFileSync7(p.settingsPath, readFileSync8(p.backupPath, "utf-8"));
11452
- console.log(` Restored ${p.settingsPath} from backup.`);
11453
- } else if (existsSync6(p.settingsPath)) {
11454
- try {
11455
- const s = JSON.parse(readFileSync8(p.settingsPath, "utf-8"));
11456
- delete s.hooks;
11457
- writeFileSync7(p.settingsPath, JSON.stringify(s, null, 2) + "\n");
11458
- console.log(` Removed SolonGate hooks from ${p.settingsPath}.`);
11459
- } catch {
11460
- }
11461
- } else {
11462
- console.log(" Nothing to restore \u2014 no global Claude Code settings found.");
11463
- }
11464
- console.log(" Global SolonGate enforcement uninstalled. Restart Claude Code.");
11465
- }
11466
11437
  function escapeRe(s) {
11467
11438
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11468
11439
  }
@@ -11524,14 +11495,6 @@ ${SHIM_END}`;
11524
11495
  }
11525
11496
  }
11526
11497
  }
11527
- function removeClaudeShim() {
11528
- for (const file of shimTargets()) {
11529
- try {
11530
- writeShimBlock(file, null);
11531
- } catch {
11532
- }
11533
- }
11534
- }
11535
11498
  async function runGlobalInstall(opts = {}) {
11536
11499
  const p = globalPaths();
11537
11500
  let apiKey = opts.apiKey || process.env["SOLONGATE_API_KEY"] || "";
@@ -11595,9 +11558,6 @@ async function runGlobalInstall(opts = {}) {
11595
11558
  console.log(" Locked protection files (OS-level read-only/immutable).");
11596
11559
  }
11597
11560
  }
11598
- async function installGlobalWithKey(apiKey, apiUrl) {
11599
- await runGlobalInstall({ apiKey, apiUrl });
11600
- }
11601
11561
  var __dirname, HOOKS_DIR, SHIM_BEGIN, SHIM_END;
11602
11562
  var init_global_install = __esm({
11603
11563
  "src/global-install.ts"() {
@@ -11733,7 +11693,6 @@ async function main() {
11733
11693
  console.log(" \u2502 Every Claude Code session on this machine is \u2502");
11734
11694
  console.log(" \u2502 now guarded by your cloud policy (OPA WASM). \u2502");
11735
11695
  console.log(" \u2502 \u2502");
11736
- console.log(" \u2502 Undo: npx @solongate/proxy logout \u2502");
11737
11696
  console.log(" \u2502 Manage policy: https://dashboard.solongate.com \u2502");
11738
11697
  console.log(" \u2502 Restart Claude Code to apply. \u2502");
11739
11698
  console.log(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
@@ -16234,7 +16193,7 @@ ${msg.content.text}`;
16234
16193
 
16235
16194
  // src/index.ts
16236
16195
  init_cli_utils();
16237
- var CLI_SUBCOMMANDS = /* @__PURE__ */ new Set(["login", "logout", "shield", "create", "inject", "pull", "push", "list", "ls", "logs-server", "local-logs", "policy", "ratelimit", "dlp", "stats", "audit", "agents", "agent", "doctor", "watch", "keys", "mcp", "alerts", "webhooks", "dataroom"]);
16196
+ var CLI_SUBCOMMANDS = /* @__PURE__ */ new Set(["login", "shield", "create", "inject", "pull", "push", "list", "ls", "logs-server", "local-logs", "policy", "ratelimit", "dlp", "stats", "audit", "agents", "agent", "doctor", "watch", "keys", "mcp", "alerts", "webhooks", "dataroom"]);
16238
16197
  var IS_HUMAN_CLI = process.argv.length <= 2 || CLI_SUBCOMMANDS.has(process.argv[2] ?? "");
16239
16198
  if (!IS_HUMAN_CLI) {
16240
16199
  console.log = (...args) => {
@@ -16256,14 +16215,14 @@ function printWelcome() {
16256
16215
  console.log("");
16257
16216
  console.log(" Get started with one command:");
16258
16217
  console.log("");
16259
- console.log(` ${c.cyan}npx -y @solongate/proxy@latest login${c.reset}`);
16218
+ console.log(` ${c.cyan}solongate login${c.reset}`);
16260
16219
  console.log("");
16261
16220
  console.log(` ${c.dim}This pairs your device and protects every Claude Code session${c.reset}`);
16262
16221
  console.log(` ${c.dim}on this machine with your cloud policy. Manage it at${c.reset}`);
16263
16222
  console.log(` ${c.cyan}https://dashboard.solongate.com${c.reset}`);
16264
16223
  console.log("");
16265
16224
  console.log(` ${c.dim}Using local log storage? Show it live in the dashboard with${c.reset}`);
16266
- console.log(` ${c.cyan}npx -y @solongate/proxy@latest logs-server${c.reset}`);
16225
+ console.log(` ${c.cyan}solongate logs-server${c.reset}`);
16267
16226
  console.log("");
16268
16227
  }
16269
16228
  async function main5() {
@@ -16292,11 +16251,6 @@ async function main5() {
16292
16251
  await Promise.resolve().then(() => (init_login(), login_exports));
16293
16252
  return;
16294
16253
  }
16295
- if (subcommand === "logout") {
16296
- const { runGlobalRestore: runGlobalRestore2 } = await Promise.resolve().then(() => (init_global_install(), global_install_exports));
16297
- runGlobalRestore2();
16298
- return;
16299
- }
16300
16254
  if (subcommand === "shield") {
16301
16255
  const { runShield: runShield2 } = await Promise.resolve().then(() => (init_shield(), shield_exports));
16302
16256
  await runShield2();
package/dist/login.js CHANGED
@@ -410,7 +410,6 @@ async function main() {
410
410
  console.log(" \u2502 Every Claude Code session on this machine is \u2502");
411
411
  console.log(" \u2502 now guarded by your cloud policy (OPA WASM). \u2502");
412
412
  console.log(" \u2502 \u2502");
413
- console.log(" \u2502 Undo: npx @solongate/proxy logout \u2502");
414
413
  console.log(" \u2502 Manage policy: https://dashboard.solongate.com \u2502");
415
414
  console.log(" \u2502 Restart Claude Code to apply. \u2502");
416
415
  console.log(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
package/dist/tui/index.js CHANGED
@@ -892,8 +892,8 @@ function StreamLine({ e, loc, selected }) {
892
892
  /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: e.permission.padEnd(5) }),
893
893
  /* @__PURE__ */ jsx2(Text2, { color: e.evalMs != null && e.evalMs > 500 ? theme.warn : theme.dim, children: (e.evalMs != null ? `${e.evalMs}ms` : "\u2014").padEnd(7) }),
894
894
  /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: truncate(e.agent ?? "-", 11).padEnd(12) }),
895
- e.dlp ? /* @__PURE__ */ jsx2(Text2, { color: theme.bad, children: "DLP! " }) : null,
896
- e.burst ? /* @__PURE__ */ jsx2(Text2, { color: theme.warn, children: "RL! " }) : null,
895
+ /* @__PURE__ */ jsx2(Text2, { color: e.dlp ? theme.bad : theme.dim, bold: e.dlp, children: ("dlp:" + (e.dlp ? "yes" : "no")).padEnd(8) }),
896
+ /* @__PURE__ */ jsx2(Text2, { color: e.burst ? theme.warn : theme.dim, bold: e.burst, children: ("rl:" + (e.burst ? "yes" : "no")).padEnd(7) }),
897
897
  e.rule && e.decision !== "ALLOW" ? /* @__PURE__ */ jsx2(Text2, { color: theme.bad, children: truncate(e.rule, 14) + " " }) : null,
898
898
  /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: e.detail })
899
899
  ] });
@@ -1248,9 +1248,12 @@ function LivePanel({ active: active2 }) {
1248
1248
  const signalOk = (e) => signal === "none" ? true : signal === "deny" ? e.decision !== "ALLOW" : signal === "dlp" ? e.dlp : e.burst;
1249
1249
  const filtered = (filter === "all" ? mergedAll : mergedAll.filter((e) => filter === "local" ? isLoc(e) : !isLoc(e))).filter(matches).filter(signalOk);
1250
1250
  const visibleDesc = filtered.slice().reverse();
1251
+ const activeAlert = alerts.filter((a) => nowMs < a.until).slice(-1)[0];
1252
+ const activeAction = actionMsg && nowMs < actionMsg.until ? actionMsg : null;
1253
+ const bannerRows = (activeAlert ? 1 : 0) + (activeAction ? 1 : 0);
1251
1254
  const chartH = rows >= 36 ? 6 : 4;
1252
1255
  const colH = rows >= 32 ? 7 : 5;
1253
- const streamRows = Math.max(4, rows - 5 - (1 + chartH) - colH);
1256
+ const streamRows = Math.max(4, rows - 5 - (1 + chartH) - colH - bannerRows);
1254
1257
  const innerW = cols - 2;
1255
1258
  const leftW = Math.floor(innerW * 0.55);
1256
1259
  const rightW = innerW - leftW - 2;
@@ -1598,18 +1601,17 @@ function LivePanel({ active: active2 }) {
1598
1601
  /* @__PURE__ */ jsx2(Text2, { color: guard.data?.up_to_date ? theme.ok : theme.warn, children: guard.data ? `v${guard.data.installed ?? "?"}${guard.data.up_to_date ? "" : "\u2192v" + guard.data.latest} ${guard.data.device_count}dev` : "\xB7" }),
1599
1602
  /* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: " \u2502" })
1600
1603
  ] }),
1601
- alerts.filter((a) => nowMs < a.until).slice(-1).map((a) => /* @__PURE__ */ jsx2(
1604
+ activeAlert ? /* @__PURE__ */ jsx2(
1602
1605
  Text2,
1603
1606
  {
1604
1607
  wrap: "truncate",
1605
- backgroundColor: a.level === "bad" ? "#3d1220" : "#3d2a12",
1606
- color: a.level === "bad" ? "#ff6b6b" : "#ffb454",
1608
+ backgroundColor: activeAlert.level === "bad" ? "#3d1220" : "#3d2a12",
1609
+ color: activeAlert.level === "bad" ? "#ff6b6b" : "#ffb454",
1607
1610
  bold: true,
1608
- children: ` ${a.level === "bad" ? "\u26D4 ALERT" : "\u23F8 IDLE"} \xB7 ${truncate(a.msg, innerW - 14)} `
1609
- },
1610
- a.id
1611
- )),
1612
- actionMsg && nowMs < actionMsg.until ? /* @__PURE__ */ jsx2(Text2, { wrap: "truncate", backgroundColor: actionMsg.level === "bad" ? "#3d1220" : "#123d1f", color: actionMsg.level === "bad" ? "#ff6b6b" : "#7bd88f", bold: true, children: ` ${truncate(actionMsg.text, innerW - 4)} ` }) : null,
1611
+ children: ` ${activeAlert.level === "bad" ? "\u26D4 ALERT" : "\u23F8 IDLE"} \xB7 ${truncate(activeAlert.msg, innerW - 14)} `
1612
+ }
1613
+ ) : null,
1614
+ activeAction ? /* @__PURE__ */ jsx2(Text2, { wrap: "truncate", backgroundColor: activeAction.level === "bad" ? "#3d1220" : "#123d1f", color: activeAction.level === "bad" ? "#ff6b6b" : "#7bd88f", bold: true, children: ` ${truncate(activeAction.text, innerW - 4)} ` }) : null,
1613
1615
  /* @__PURE__ */ jsxs2(Box2, { height: 1 + chartH, children: [
1614
1616
  /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", width: leftW, marginRight: 2, children: [
1615
1617
  /* @__PURE__ */ jsx2(PaneTitle, { label: "TRAFFIC", extra: `${trafficLabel} \xB7 peak ${Math.max(0, ...traffic)} \xB7 red = denials`, width: leftW }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.81.39",
3
+ "version": "0.81.41",
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": {