@solongate/proxy 0.81.62 → 0.81.63

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.
@@ -53,3 +53,8 @@
53
53
  {"ms":2,"ts":1784367428790,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
54
54
  {"ms":3,"ts":1784369708978,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
55
55
  {"ms":4,"ts":1784369720104,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
56
+ {"ms":4,"ts":1784374757475,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
57
+ {"ms":2,"ts":1784374762962,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
58
+ {"ms":4,"ts":1784374792946,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
59
+ {"ms":4,"ts":1784374838495,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
60
+ {"ms":3,"ts":1784374848281,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
@@ -1 +1 @@
1
- {"ms":4,"ts":1784369720104,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
1
+ {"ms":3,"ts":1784374848281,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
@@ -1 +1 @@
1
- 1784369709035
1
+ 1784374838541
@@ -6536,7 +6536,7 @@ import { resolve, join, dirname, isAbsolute } from "node:path";
6536
6536
  import { homedir } from "node:os";
6537
6537
  import { gunzipSync } from "node:zlib";
6538
6538
  import { createHash } from "node:crypto";
6539
- var HOOK_VERSION = 36;
6539
+ var HOOK_VERSION = 37;
6540
6540
  function localLogsOnly(security) {
6541
6541
  if (security && typeof security === "object") {
6542
6542
  const l = security.localLogs;
@@ -6586,11 +6586,9 @@ function writeLocalLog(security, entry) {
6586
6586
  const dir = resolveLocalLogDir(l.path);
6587
6587
  if (!dir)
6588
6588
  return;
6589
- try {
6590
- mkdirSync(dir, { recursive: true });
6591
- } catch {
6592
- }
6593
- appendFileSync(join(dir, "solongate-audit.jsonl"), JSON.stringify(entry) + "\n");
6589
+ const line = JSON.stringify(entry) + "\n";
6590
+ const payload = Buffer.from(JSON.stringify({ dir, line }), "utf-8").toString("base64");
6591
+ spawn(process.execPath, [process.argv[1], "--sg-log-write", payload], { detached: true, stdio: "ignore" }).unref();
6594
6592
  } catch {
6595
6593
  }
6596
6594
  }
@@ -6734,6 +6732,23 @@ var AGENT_TYPE = process.argv[2] || "claude-code";
6734
6732
  var POLICY_SELECTOR = process.env.SOLONGATE_AGENT_ID || "";
6735
6733
  var AGENT_ID = POLICY_SELECTOR || AGENT_TYPE;
6736
6734
  var AGENT_NAME = process.env.SOLONGATE_AGENT_NAME || process.argv[3] || AGENT_TYPE;
6735
+ {
6736
+ const _wi = process.argv.indexOf("--sg-log-write");
6737
+ if (_wi !== -1) {
6738
+ try {
6739
+ const _pl = JSON.parse(Buffer.from(process.argv[_wi + 1] || "", "base64").toString("utf-8"));
6740
+ if (_pl && _pl.dir && _pl.line) {
6741
+ try {
6742
+ mkdirSync(_pl.dir, { recursive: true });
6743
+ } catch {
6744
+ }
6745
+ appendFileSync(join(_pl.dir, "solongate-audit.jsonl"), _pl.line);
6746
+ }
6747
+ } catch {
6748
+ }
6749
+ process.exit(0);
6750
+ }
6751
+ }
6737
6752
  var REFRESH_MODE = process.argv.includes("--sg-refresh-policy");
6738
6753
  async function refreshPolicyCache() {
6739
6754
  try {
package/hooks/guard.mjs CHANGED
@@ -32,7 +32,7 @@ import { createHash } from 'node:crypto';
32
32
  // the installed hook self-updates when the cloud version is higher (see
33
33
  // maybeSelfUpdate). This is what makes guard fixes propagate without a manual
34
34
  // reinstall — the same trust model as the OPA WASM this hook already runs.
35
- const HOOK_VERSION = 36;
35
+ const HOOK_VERSION = 37;
36
36
 
37
37
  // True when local log storage is ON. In that mode logs are kept LOCAL ONLY and
38
38
  // nothing is sent to the cloud audit log.
@@ -102,8 +102,13 @@ function writeLocalLog(security, entry) {
102
102
  if (!l || !l.enabled || typeof l.path !== 'string' || !l.path.trim()) return;
103
103
  const dir = resolveLocalLogDir(l.path);
104
104
  if (!dir) return;
105
- try { mkdirSync(dir, { recursive: true }); } catch { /* ignore */ }
106
- appendFileSync(join(dir, 'solongate-audit.jsonl'), JSON.stringify(entry) + '\n');
105
+ const line = JSON.stringify(entry) + '\n';
106
+ // GUARANTEED write: hand the append to a DETACHED child in its own process
107
+ // group. Even if Claude Code kills this hook mid-write during a concurrent
108
+ // denial burst, the child survives and completes the append — no denial is
109
+ // ever lost from the local log. (Inline appends dropped under burst.)
110
+ const payload = Buffer.from(JSON.stringify({ dir, line }), 'utf-8').toString('base64');
111
+ spawn(process.execPath, [process.argv[1], '--sg-log-write', payload], { detached: true, stdio: 'ignore' }).unref();
107
112
  } catch { /* best-effort */ }
108
113
  }
109
114
 
@@ -285,6 +290,24 @@ const AGENT_NAME = process.env.SOLONGATE_AGENT_NAME || process.argv[3] || AGENT_
285
290
  // serves the cached (or local) policy INSTANTLY and spawns this detached mode to
286
291
  // fetch a fresh policy and rewrite the cache for the NEXT call. Result: fast tool
287
292
  // calls AND ~one-call propagation of policy changes — no long-TTL tradeoff.
293
+ // Survivable local-log writer. A denial's audit line is written by a DETACHED
294
+ // child (this same file, invoked with --sg-log-write <base64>) so the entry
295
+ // lands even if Claude Code kills the parent hook mid-write during a concurrent
296
+ // denial burst. Handled FIRST and exits immediately — the child never loads the
297
+ // heavy guard logic below.
298
+ {
299
+ const _wi = process.argv.indexOf('--sg-log-write');
300
+ if (_wi !== -1) {
301
+ try {
302
+ const _pl = JSON.parse(Buffer.from(process.argv[_wi + 1] || '', 'base64').toString('utf-8'));
303
+ if (_pl && _pl.dir && _pl.line) {
304
+ try { mkdirSync(_pl.dir, { recursive: true }); } catch {}
305
+ appendFileSync(join(_pl.dir, 'solongate-audit.jsonl'), _pl.line);
306
+ }
307
+ } catch {}
308
+ process.exit(0);
309
+ }
310
+ }
288
311
  const REFRESH_MODE = process.argv.includes('--sg-refresh-policy');
289
312
  async function refreshPolicyCache() {
290
313
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.81.62",
3
+ "version": "0.81.63",
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": {