@solongate/proxy 0.83.26 → 0.83.28

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
@@ -63,11 +63,11 @@ Manage everything from the **Policies**, **Audit**, and **Settings** pages in th
63
63
  <td><a href="https://claude.com/claude-code"><img src="https://solongate.com/cells/claude.png" width="200" alt="Claude Code" /></a></td>
64
64
  <td><a href="https://antigravity.google"><img src="https://solongate.com/cells/antigravity.png?v=2" width="200" alt="Antigravity CLI" /></a></td>
65
65
  <td><a href="https://openai.com/codex"><img src="https://solongate.com/cells/codex.png" width="200" alt="Codex CLI" /></a></td>
66
- <td><a href="https://openclaw.ai"><img src="https://solongate.com/cells/openclaw.png" width="200" alt="OpenClaw (soon)" /></a></td>
66
+ <td><a href="https://openclaw.ai"><img src="https://solongate.com/cells/openclaw.png?v=2" width="200" alt="OpenClaw" /></a></td>
67
67
  </tr>
68
68
  <tr>
69
69
  <td><a href="https://hermes.nousresearch.com"><img src="https://solongate.com/cells/hermes.png" width="200" alt="Hermes (soon)" /></a></td>
70
- <td><a href="https://opencode.ai"><img src="https://solongate.com/cells/opencode.png" width="200" alt="OpenCode (soon)" /></a></td>
70
+ <td><a href="https://opencode.ai"><img src="https://solongate.com/cells/opencode.png?v=2" width="200" alt="OpenCode" /></a></td>
71
71
  <td><a href="https://chainabit.com"><img src="https://solongate.com/cells/chainabit.png?v=3" width="200" alt="Chainabit (soon)" /></a></td>
72
72
  <td><a href="https://solongate.com/contact"><img src="https://solongate.com/cells/yourtool.png" width="200" alt="Your tool" /></a></td>
73
73
  </tr>
@@ -6579,7 +6579,7 @@ function sweepLegacyFlagDir() {
6579
6579
  } catch {
6580
6580
  }
6581
6581
  }
6582
- var HOOK_VERSION = 80;
6582
+ var HOOK_VERSION = 81;
6583
6583
  var SG_REFRESH_ARG = process.argv.includes("--sg-refresh-policy");
6584
6584
  var SG_STDIN = SG_REFRESH_ARG ? "" : (() => {
6585
6585
  try {
@@ -6588,6 +6588,13 @@ var SG_STDIN = SG_REFRESH_ARG ? "" : (() => {
6588
6588
  return "";
6589
6589
  }
6590
6590
  })();
6591
+ var SG_ORIGIN_MS = (() => {
6592
+ try {
6593
+ return Math.round(performance.timeOrigin);
6594
+ } catch {
6595
+ return Date.now();
6596
+ }
6597
+ })();
6591
6598
  function sgGuardCandidates() {
6592
6599
  const out = [];
6593
6600
  if (process.env.SOLONGATE_GUARD_BIN)
@@ -6629,6 +6636,14 @@ function sgTryGoGuard() {
6629
6636
  r = spawnSync(bin, process.argv.slice(2), {
6630
6637
  input: SG_STDIN,
6631
6638
  encoding: "utf-8",
6639
+ // The binary writes the eval record the audit hook reads back, so it is
6640
+ // the one reporting this call's guard time — and from inside a process
6641
+ // that was spawned partway through the work, it can only see its own
6642
+ // share of it. Node's boot, this file's parse, the fd 0 read and the
6643
+ // version probe above are all already spent by the time it starts.
6644
+ // Handing it the origin is what lets the number it reports be the whole
6645
+ // hook instead of the last two milliseconds of it.
6646
+ env: { ...process.env, SOLONGATE_HOOK_ORIGIN_MS: String(SG_ORIGIN_MS) },
6632
6647
  // Well past every network call the guard makes. A binary still running
6633
6648
  // at this point is not going to produce an answer worth waiting for.
6634
6649
  timeout: 1e4
@@ -8554,7 +8569,7 @@ if (!REFRESH_MODE) {
8554
8569
  allowTool();
8555
8570
  return;
8556
8571
  }
8557
- const _evalStart = Date.now();
8572
+ const _evalStart = SG_ORIGIN_MS;
8558
8573
  try {
8559
8574
  const raw = JSON.parse(input);
8560
8575
  if (process.env.SOLONGATE_DEBUG) {
package/hooks/guard.mjs CHANGED
@@ -82,7 +82,7 @@ import { createHash } from 'node:crypto';
82
82
  // the installed hook self-updates when the cloud version is higher (see
83
83
  // maybeSelfUpdate). This is what makes guard fixes propagate without a manual
84
84
  // reinstall — the same trust model as the OPA WASM this hook already runs.
85
- const HOOK_VERSION = 80;
85
+ const HOOK_VERSION = 81;
86
86
 
87
87
  // ── The Go guard, when there is one and it is the right one ──────────────────
88
88
  //
@@ -126,6 +126,24 @@ const SG_STDIN = SG_REFRESH_ARG ? '' : (() => {
126
126
  try { return readFileSync(0, 'utf-8'); } catch { return ''; }
127
127
  })();
128
128
 
129
+ // When this process began, as epoch milliseconds — the instant every reported
130
+ // guard time is measured from.
131
+ //
132
+ // `performance.timeOrigin` is stamped before Node's bootstrap runs, so a
133
+ // duration taken from it includes the interpreter coming up and this file being
134
+ // parsed. That is not an accounting nicety: those two are the MAJORITY of what a
135
+ // tool call pays for enforcement. Starting the clock further down (which is what
136
+ // `Date.now()` at the top of the async body did) left them outside the window
137
+ // and made the audit log report ~1ms for a call that really cost tens of them —
138
+ // a number no process on a real machine can achieve, and one that quietly turned
139
+ // the latency column into fiction.
140
+ //
141
+ // What is still NOT in it: the client's own fork/exec of node, which happens
142
+ // before this process exists and which nothing running inside it can observe.
143
+ const SG_ORIGIN_MS = (() => {
144
+ try { return Math.round(performance.timeOrigin); } catch { return Date.now(); }
145
+ })();
146
+
129
147
  // Where a binary may legitimately live, in the order they are trusted.
130
148
  //
131
149
  // The env override is first so a build can be pointed at without reinstalling.
@@ -180,6 +198,14 @@ function sgTryGoGuard() {
180
198
  r = spawnSync(bin, process.argv.slice(2), {
181
199
  input: SG_STDIN,
182
200
  encoding: 'utf-8',
201
+ // The binary writes the eval record the audit hook reads back, so it is
202
+ // the one reporting this call's guard time — and from inside a process
203
+ // that was spawned partway through the work, it can only see its own
204
+ // share of it. Node's boot, this file's parse, the fd 0 read and the
205
+ // version probe above are all already spent by the time it starts.
206
+ // Handing it the origin is what lets the number it reports be the whole
207
+ // hook instead of the last two milliseconds of it.
208
+ env: { ...process.env, SOLONGATE_HOOK_ORIGIN_MS: String(SG_ORIGIN_MS) },
183
209
  // Well past every network call the guard makes. A binary still running
184
210
  // at this point is not going to produce an answer worth waiting for.
185
211
  timeout: 10000,
@@ -2620,7 +2646,12 @@ if (!REFRESH_MODE) { input += SG_STDIN; }
2620
2646
  allowTool();
2621
2647
  return;
2622
2648
  }
2623
- const _evalStart = Date.now();
2649
+ // NOT `Date.now()`. Every `Date.now() - _evalStart` below becomes an
2650
+ // evaluation_time_ms in the audit log — the number the dashboard, the dataroom
2651
+ // and the TUI print as what this call paid to be guarded. Measured from here
2652
+ // it excluded Node's boot and this file's parse, which is most of the cost,
2653
+ // and reported ~1ms for a hook that was really taking tens. See SG_ORIGIN_MS.
2654
+ const _evalStart = SG_ORIGIN_MS;
2624
2655
  try {
2625
2656
  const raw = JSON.parse(input);
2626
2657
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.83.26",
3
+ "version": "0.83.28",
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.26",
65
- "@solongate/guard-linux-arm64": "0.83.26",
66
- "@solongate/guard-darwin-x64": "0.83.26",
67
- "@solongate/guard-darwin-arm64": "0.83.26",
68
- "@solongate/guard-win32-x64": "0.83.26",
69
- "@solongate/guard-win32-arm64": "0.83.26"
64
+ "@solongate/guard-linux-x64": "0.83.28",
65
+ "@solongate/guard-linux-arm64": "0.83.28",
66
+ "@solongate/guard-darwin-x64": "0.83.28",
67
+ "@solongate/guard-darwin-arm64": "0.83.28",
68
+ "@solongate/guard-win32-x64": "0.83.28",
69
+ "@solongate/guard-win32-arm64": "0.83.28"
70
70
  },
71
71
  "dependencies": {
72
72
  "@modelcontextprotocol/sdk": "^1.26.0",