@solongate/proxy 0.81.84 → 0.81.86
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/dist/index.js +9 -15
- package/dist/self-update.d.ts +0 -3
- package/dist/tui/index.js +9 -11
- package/hooks/guard.bundled.mjs +7 -7
- package/hooks/guard.mjs +20 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6663,17 +6663,15 @@ async function tuiUpdateFlow(onStatus) {
|
|
|
6663
6663
|
const state = readState();
|
|
6664
6664
|
if (latest) writeState({ ...state, lastCheckAt: Date.now(), latestSeen: latest });
|
|
6665
6665
|
if (!latest || !newerThan(latest, current)) return;
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
}
|
|
6666
|
+
if (readState().installed === latest) {
|
|
6667
|
+
onStatus({ kind: "updated", version: latest });
|
|
6668
|
+
return;
|
|
6669
|
+
}
|
|
6670
|
+
onStatus({ kind: "updating", version: latest });
|
|
6671
|
+
if (await runGlobalInstall(latest)) {
|
|
6672
|
+
writeState({ ...readState(), installed: latest });
|
|
6673
|
+
onStatus({ kind: "updated", version: latest });
|
|
6675
6674
|
}
|
|
6676
|
-
onStatus({ kind: "manual", version: latest });
|
|
6677
6675
|
} catch {
|
|
6678
6676
|
}
|
|
6679
6677
|
}
|
|
@@ -6695,12 +6693,8 @@ function maybeSelfUpdate(notify = (l) => process.stderr.write(l + "\n")) {
|
|
|
6695
6693
|
writeState({ ...readState(), attempts: { [latest]: now } });
|
|
6696
6694
|
if (spawnGlobalInstall(latest)) {
|
|
6697
6695
|
notify(`${c.dim}\u2191 solongate v${latest} available (running v${current}) \u2014 updating in the background, next run uses it${c.reset}`);
|
|
6698
|
-
return;
|
|
6699
6696
|
}
|
|
6700
|
-
} else {
|
|
6701
|
-
return;
|
|
6702
6697
|
}
|
|
6703
|
-
notify(`${c.dim}\u2191 solongate v${latest} available (running v${current}) \u2014 update: ${c.reset}${c.cyan}npm i -g ${PKG}@latest${c.reset}`);
|
|
6704
6698
|
} catch {
|
|
6705
6699
|
}
|
|
6706
6700
|
})();
|
|
@@ -11072,7 +11066,7 @@ function App() {
|
|
|
11072
11066
|
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "account: " }),
|
|
11073
11067
|
/* @__PURE__ */ jsx8(Text8, { color: locked ? theme.warn : theme.accentBright, bold: true, children: acctLabel2 }),
|
|
11074
11068
|
locked ? /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " \xB7 log in from Settings to unlock the dataroom" }) : accounts.length > 1 ? /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: ` (${acctIdx + 1}/${accounts.length} \xB7 a switch \xB7 Settings to manage)` }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " \xB7 Settings to add another" }),
|
|
11075
|
-
update2.kind === "updating" ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: ` \u2191 updating to v${update2.version}\u2026` }) : update2.kind === "updated" ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, bold: true, children: ` \u2191 v${update2.version} installed \u2014 restart (q, then solongate) to apply` }) :
|
|
11069
|
+
update2.kind === "updating" ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: ` \u2191 updating to v${update2.version}\u2026` }) : update2.kind === "updated" ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, bold: true, children: ` \u2191 v${update2.version} installed \u2014 restart (q, then solongate) to apply` }) : null
|
|
11076
11070
|
] }),
|
|
11077
11071
|
/* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexGrow: 1, children: [
|
|
11078
11072
|
/* @__PURE__ */ jsx8(Box8, { flexDirection: "column", flexShrink: 0, width: 16, borderStyle: "round", borderColor: focus === "nav" ? theme.accent : "gray", paddingX: 1, children: SECTIONS.map((s, i) => {
|
package/dist/self-update.d.ts
CHANGED
package/dist/tui/index.js
CHANGED
|
@@ -4138,17 +4138,15 @@ async function tuiUpdateFlow(onStatus) {
|
|
|
4138
4138
|
const state = readState2();
|
|
4139
4139
|
if (latest) writeState2({ ...state, lastCheckAt: Date.now(), latestSeen: latest });
|
|
4140
4140
|
if (!latest || !newerThan(latest, current)) return;
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
}
|
|
4141
|
+
if (readState2().installed === latest) {
|
|
4142
|
+
onStatus({ kind: "updated", version: latest });
|
|
4143
|
+
return;
|
|
4144
|
+
}
|
|
4145
|
+
onStatus({ kind: "updating", version: latest });
|
|
4146
|
+
if (await runGlobalInstall(latest)) {
|
|
4147
|
+
writeState2({ ...readState2(), installed: latest });
|
|
4148
|
+
onStatus({ kind: "updated", version: latest });
|
|
4150
4149
|
}
|
|
4151
|
-
onStatus({ kind: "manual", version: latest });
|
|
4152
4150
|
} catch {
|
|
4153
4151
|
}
|
|
4154
4152
|
}
|
|
@@ -4292,7 +4290,7 @@ function App() {
|
|
|
4292
4290
|
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "account: " }),
|
|
4293
4291
|
/* @__PURE__ */ jsx8(Text8, { color: locked ? theme.warn : theme.accentBright, bold: true, children: acctLabel2 }),
|
|
4294
4292
|
locked ? /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " \xB7 log in from Settings to unlock the dataroom" }) : accounts.length > 1 ? /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: ` (${acctIdx + 1}/${accounts.length} \xB7 a switch \xB7 Settings to manage)` }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " \xB7 Settings to add another" }),
|
|
4295
|
-
update2.kind === "updating" ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: ` \u2191 updating to v${update2.version}\u2026` }) : update2.kind === "updated" ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, bold: true, children: ` \u2191 v${update2.version} installed \u2014 restart (q, then solongate) to apply` }) :
|
|
4293
|
+
update2.kind === "updating" ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: ` \u2191 updating to v${update2.version}\u2026` }) : update2.kind === "updated" ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, bold: true, children: ` \u2191 v${update2.version} installed \u2014 restart (q, then solongate) to apply` }) : null
|
|
4296
4294
|
] }),
|
|
4297
4295
|
/* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexGrow: 1, children: [
|
|
4298
4296
|
/* @__PURE__ */ jsx8(Box8, { flexDirection: "column", flexShrink: 0, width: 16, borderStyle: "round", borderColor: focus === "nav" ? theme.accent : "gray", paddingX: 1, children: SECTIONS.map((s, i) => {
|
package/hooks/guard.bundled.mjs
CHANGED
|
@@ -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 =
|
|
6539
|
+
var HOOK_VERSION = 42;
|
|
6540
6540
|
function localLogsOnly(security) {
|
|
6541
6541
|
if (security && typeof security === "object") {
|
|
6542
6542
|
const l = security.localLogs;
|
|
@@ -6804,17 +6804,16 @@ function blockTool(reason) {
|
|
|
6804
6804
|
}));
|
|
6805
6805
|
sgFinish(0);
|
|
6806
6806
|
} else {
|
|
6807
|
+
const msg = reason || "[SolonGate] Blocked by policy";
|
|
6807
6808
|
process.stdout.write(JSON.stringify({
|
|
6808
6809
|
hookSpecificOutput: {
|
|
6809
6810
|
hookEventName: "PreToolUse",
|
|
6810
6811
|
permissionDecision: "deny",
|
|
6811
|
-
|
|
6812
|
-
// with empty content, which the API rejects and crashes the agent. Always
|
|
6813
|
-
// carry a SolonGate-worded reason so the block says WHAT stopped it.
|
|
6814
|
-
permissionDecisionReason: reason || "[SolonGate] Blocked by policy"
|
|
6812
|
+
permissionDecisionReason: msg
|
|
6815
6813
|
}
|
|
6816
6814
|
}));
|
|
6817
|
-
|
|
6815
|
+
process.stderr.write(msg + "\n");
|
|
6816
|
+
sgFinish(2);
|
|
6818
6817
|
}
|
|
6819
6818
|
}
|
|
6820
6819
|
function allowTool() {
|
|
@@ -7924,7 +7923,8 @@ if (!REFRESH_MODE) {
|
|
|
7924
7923
|
sgFinish(0);
|
|
7925
7924
|
}
|
|
7926
7925
|
process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: ghostHit } }));
|
|
7927
|
-
|
|
7926
|
+
process.stderr.write(ghostHit + "\n");
|
|
7927
|
+
sgFinish(2);
|
|
7928
7928
|
}
|
|
7929
7929
|
if (AGENT_TYPE !== "gemini-cli" && toolName === "Bash") {
|
|
7930
7930
|
const rw = ghostListingRewrite(args, securityCfg.ghost);
|
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 =
|
|
35
|
+
const HOOK_VERSION = 42;
|
|
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.
|
|
@@ -385,23 +385,25 @@ function blockTool(reason) {
|
|
|
385
385
|
}));
|
|
386
386
|
sgFinish(0);
|
|
387
387
|
} else {
|
|
388
|
-
// Claude Code —
|
|
389
|
-
//
|
|
390
|
-
//
|
|
391
|
-
//
|
|
392
|
-
//
|
|
393
|
-
//
|
|
388
|
+
// Claude Code — emit the JSON PreToolUse deny on stdout AND exit 2 (reason on
|
|
389
|
+
// stderr). Exit 2 is the ONLY block Claude Code enforces in EVERY permission
|
|
390
|
+
// mode: JSON + exit 0 goes through the NORMAL permission flow, which
|
|
391
|
+
// AUTO-ACCEPT ("auto mode") OVERRIDES — the tool then runs despite the deny
|
|
392
|
+
// (observed: a DLP-blocked Write still landed on disk in auto mode). Exit 2
|
|
393
|
+
// hard-blocks BEFORE the permission system, in every mode. The JSON on stdout
|
|
394
|
+
// stays as the Windows/PowerShell fallback (there a native exit code may not
|
|
395
|
+
// propagate reliably; Claude Code parses the JSON instead). Reason is never
|
|
396
|
+
// empty — an empty deny becomes an is_error tool_result the API rejects.
|
|
397
|
+
const msg = reason || '[SolonGate] Blocked by policy';
|
|
394
398
|
process.stdout.write(JSON.stringify({
|
|
395
399
|
hookSpecificOutput: {
|
|
396
400
|
hookEventName: 'PreToolUse',
|
|
397
401
|
permissionDecision: 'deny',
|
|
398
|
-
|
|
399
|
-
// with empty content, which the API rejects and crashes the agent. Always
|
|
400
|
-
// carry a SolonGate-worded reason so the block says WHAT stopped it.
|
|
401
|
-
permissionDecisionReason: reason || '[SolonGate] Blocked by policy',
|
|
402
|
+
permissionDecisionReason: msg,
|
|
402
403
|
},
|
|
403
404
|
}));
|
|
404
|
-
|
|
405
|
+
process.stderr.write(msg + '\n');
|
|
406
|
+
sgFinish(2);
|
|
405
407
|
}
|
|
406
408
|
}
|
|
407
409
|
|
|
@@ -1761,10 +1763,13 @@ if (!REFRESH_MODE) { try { input += readFileSync(0, 'utf-8'); } catch {} }
|
|
|
1761
1763
|
} catch {}
|
|
1762
1764
|
await maybeSelfUpdate();
|
|
1763
1765
|
if (AGENT_TYPE === 'gemini-cli') { process.stdout.write(JSON.stringify({ decision: 'deny', reason: ghostHit })); sgFinish(0); }
|
|
1764
|
-
// Claude Code: JSON deny on stdout + exit
|
|
1765
|
-
//
|
|
1766
|
+
// Claude Code: JSON deny on stdout + exit 2 (reason on stderr). Exit 2 is
|
|
1767
|
+
// the only block enforced in auto-accept mode (see blockTool); the JSON is
|
|
1768
|
+
// the Windows fallback. ghostHit is a bare "No such file or directory", so
|
|
1769
|
+
// the stderr text keeps the stealth (looks like the path simply isn't there).
|
|
1766
1770
|
process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: ghostHit } }));
|
|
1767
|
-
|
|
1771
|
+
process.stderr.write(ghostHit + '\n');
|
|
1772
|
+
sgFinish(2);
|
|
1768
1773
|
}
|
|
1769
1774
|
// No direct hit: if this is a listing command, rewrite it so hidden
|
|
1770
1775
|
// entries are filtered out of its output (Claude Code only).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.86",
|
|
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": {
|