@solongate/proxy 0.82.15 → 0.82.17
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/global-install.js +22 -0
- package/dist/index.js +18 -0
- package/dist/tui/index.js +18 -0
- package/hooks/guard.bundled.mjs +5 -5
- package/hooks/guard.mjs +11 -6
- package/package.json +1 -1
package/dist/global-install.js
CHANGED
|
@@ -114,6 +114,17 @@ function clearGuardUpdateCheck() {
|
|
|
114
114
|
function readHook(filename) {
|
|
115
115
|
return readFileSync(join(HOOKS_DIR, filename), "utf-8");
|
|
116
116
|
}
|
|
117
|
+
function firstAccountCredential() {
|
|
118
|
+
try {
|
|
119
|
+
const raw = JSON.parse(readFileSync(join(homedir(), ".solongate", "accounts.json"), "utf-8"));
|
|
120
|
+
if (Array.isArray(raw)) {
|
|
121
|
+
const acc = raw.find((a) => a && typeof a.apiKey === "string" && a.apiKey);
|
|
122
|
+
if (acc) return { apiKey: acc.apiKey, apiUrl: typeof acc.apiUrl === "string" ? acc.apiUrl : void 0 };
|
|
123
|
+
}
|
|
124
|
+
} catch {
|
|
125
|
+
}
|
|
126
|
+
return {};
|
|
127
|
+
}
|
|
117
128
|
function readGuard() {
|
|
118
129
|
const bundled = join(HOOKS_DIR, "guard.bundled.mjs");
|
|
119
130
|
return existsSync(bundled) ? readFileSync(bundled, "utf-8") : readHook("guard.mjs");
|
|
@@ -193,6 +204,13 @@ function installGlobalQuiet() {
|
|
|
193
204
|
if (cfg && typeof cfg.apiUrl === "string") apiUrl = cfg.apiUrl;
|
|
194
205
|
} catch {
|
|
195
206
|
}
|
|
207
|
+
if (!apiKey) {
|
|
208
|
+
const acc = firstAccountCredential();
|
|
209
|
+
if (acc.apiKey) {
|
|
210
|
+
apiKey = acc.apiKey;
|
|
211
|
+
if (acc.apiUrl) apiUrl = acc.apiUrl;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
196
214
|
if (!apiKey) return { ok: false, message: "no login on this device \u2014 add an account first (Accounts \u2192 + add)" };
|
|
197
215
|
mkdirSync(p.hooksDir, { recursive: true });
|
|
198
216
|
mkdirSync(p.claudeDir, { recursive: true });
|
|
@@ -361,6 +379,10 @@ async function runGlobalInstall(opts = {}) {
|
|
|
361
379
|
} catch {
|
|
362
380
|
}
|
|
363
381
|
}
|
|
382
|
+
if (!apiKey || apiKey === "sg_live_your_key_here") {
|
|
383
|
+
const acc = firstAccountCredential();
|
|
384
|
+
if (acc.apiKey) apiKey = acc.apiKey;
|
|
385
|
+
}
|
|
364
386
|
if (!apiKey || apiKey === "sg_live_your_key_here") {
|
|
365
387
|
apiKey = await ask(" Enter your SolonGate API key (sg_live_\u2026 from https://dashboard.solongate.com): ");
|
|
366
388
|
}
|
package/dist/index.js
CHANGED
|
@@ -10245,6 +10245,17 @@ function globalPaths() {
|
|
|
10245
10245
|
function readHook(filename) {
|
|
10246
10246
|
return readFileSync9(join11(HOOKS_DIR, filename), "utf-8");
|
|
10247
10247
|
}
|
|
10248
|
+
function firstAccountCredential() {
|
|
10249
|
+
try {
|
|
10250
|
+
const raw = JSON.parse(readFileSync9(join11(homedir9(), ".solongate", "accounts.json"), "utf-8"));
|
|
10251
|
+
if (Array.isArray(raw)) {
|
|
10252
|
+
const acc = raw.find((a) => a && typeof a.apiKey === "string" && a.apiKey);
|
|
10253
|
+
if (acc) return { apiKey: acc.apiKey, apiUrl: typeof acc.apiUrl === "string" ? acc.apiUrl : void 0 };
|
|
10254
|
+
}
|
|
10255
|
+
} catch {
|
|
10256
|
+
}
|
|
10257
|
+
return {};
|
|
10258
|
+
}
|
|
10248
10259
|
function readGuard() {
|
|
10249
10260
|
const bundled = join11(HOOKS_DIR, "guard.bundled.mjs");
|
|
10250
10261
|
return existsSync4(bundled) ? readFileSync9(bundled, "utf-8") : readHook("guard.mjs");
|
|
@@ -10295,6 +10306,13 @@ function installGlobalQuiet() {
|
|
|
10295
10306
|
if (cfg && typeof cfg.apiUrl === "string") apiUrl = cfg.apiUrl;
|
|
10296
10307
|
} catch {
|
|
10297
10308
|
}
|
|
10309
|
+
if (!apiKey) {
|
|
10310
|
+
const acc = firstAccountCredential();
|
|
10311
|
+
if (acc.apiKey) {
|
|
10312
|
+
apiKey = acc.apiKey;
|
|
10313
|
+
if (acc.apiUrl) apiUrl = acc.apiUrl;
|
|
10314
|
+
}
|
|
10315
|
+
}
|
|
10298
10316
|
if (!apiKey) return { ok: false, message: "no login on this device \u2014 add an account first (Accounts \u2192 + add)" };
|
|
10299
10317
|
mkdirSync8(p.hooksDir, { recursive: true });
|
|
10300
10318
|
mkdirSync8(p.claudeDir, { recursive: true });
|
package/dist/tui/index.js
CHANGED
|
@@ -3303,6 +3303,17 @@ function globalPaths() {
|
|
|
3303
3303
|
function readHook(filename) {
|
|
3304
3304
|
return readFileSync4(join6(HOOKS_DIR, filename), "utf-8");
|
|
3305
3305
|
}
|
|
3306
|
+
function firstAccountCredential() {
|
|
3307
|
+
try {
|
|
3308
|
+
const raw = JSON.parse(readFileSync4(join6(homedir6(), ".solongate", "accounts.json"), "utf-8"));
|
|
3309
|
+
if (Array.isArray(raw)) {
|
|
3310
|
+
const acc = raw.find((a) => a && typeof a.apiKey === "string" && a.apiKey);
|
|
3311
|
+
if (acc) return { apiKey: acc.apiKey, apiUrl: typeof acc.apiUrl === "string" ? acc.apiUrl : void 0 };
|
|
3312
|
+
}
|
|
3313
|
+
} catch {
|
|
3314
|
+
}
|
|
3315
|
+
return {};
|
|
3316
|
+
}
|
|
3306
3317
|
function readGuard() {
|
|
3307
3318
|
const bundled = join6(HOOKS_DIR, "guard.bundled.mjs");
|
|
3308
3319
|
return existsSync2(bundled) ? readFileSync4(bundled, "utf-8") : readHook("guard.mjs");
|
|
@@ -3354,6 +3365,13 @@ function installGlobalQuiet() {
|
|
|
3354
3365
|
if (cfg && typeof cfg.apiUrl === "string") apiUrl = cfg.apiUrl;
|
|
3355
3366
|
} catch {
|
|
3356
3367
|
}
|
|
3368
|
+
if (!apiKey) {
|
|
3369
|
+
const acc = firstAccountCredential();
|
|
3370
|
+
if (acc.apiKey) {
|
|
3371
|
+
apiKey = acc.apiKey;
|
|
3372
|
+
if (acc.apiUrl) apiUrl = acc.apiUrl;
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3357
3375
|
if (!apiKey) return { ok: false, message: "no login on this device \u2014 add an account first (Accounts \u2192 + add)" };
|
|
3358
3376
|
mkdirSync4(p.hooksDir, { recursive: true });
|
|
3359
3377
|
mkdirSync4(p.claudeDir, { recursive: true });
|
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 = 45;
|
|
6540
6540
|
function localLogsOnly(security) {
|
|
6541
6541
|
if (security && typeof security === "object") {
|
|
6542
6542
|
const l = security.localLogs;
|
|
@@ -6799,8 +6799,8 @@ function sgFinish(code) {
|
|
|
6799
6799
|
function blockTool(reason) {
|
|
6800
6800
|
if (AGENT_TYPE === "antigravity") {
|
|
6801
6801
|
process.stdout.write(JSON.stringify({
|
|
6802
|
-
|
|
6803
|
-
|
|
6802
|
+
allow_tool: false,
|
|
6803
|
+
deny_reason: `[SolonGate] ${reason}`
|
|
6804
6804
|
}));
|
|
6805
6805
|
sgFinish(0);
|
|
6806
6806
|
} else {
|
|
@@ -6818,7 +6818,7 @@ function blockTool(reason) {
|
|
|
6818
6818
|
}
|
|
6819
6819
|
function allowTool() {
|
|
6820
6820
|
if (AGENT_TYPE === "antigravity") {
|
|
6821
|
-
process.stdout.write(JSON.stringify({
|
|
6821
|
+
process.stdout.write(JSON.stringify({ allow_tool: true }));
|
|
6822
6822
|
}
|
|
6823
6823
|
sgFinish(0);
|
|
6824
6824
|
}
|
|
@@ -7966,7 +7966,7 @@ if (!REFRESH_MODE) {
|
|
|
7966
7966
|
}
|
|
7967
7967
|
await maybeSelfUpdate();
|
|
7968
7968
|
if (AGENT_TYPE === "antigravity") {
|
|
7969
|
-
process.stdout.write(JSON.stringify({
|
|
7969
|
+
process.stdout.write(JSON.stringify({ allow_tool: false, deny_reason: ghostHit }));
|
|
7970
7970
|
sgFinish(0);
|
|
7971
7971
|
}
|
|
7972
7972
|
process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: ghostHit } }));
|
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 = 45;
|
|
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.
|
|
@@ -345,7 +345,12 @@ if (REFRESH_MODE) { try { setTimeout(() => { try { process.exit(process.exitCode
|
|
|
345
345
|
// ── Per-tool block/allow output ──
|
|
346
346
|
// Response format depends on the agent:
|
|
347
347
|
// Claude Code: exit 2 + stderr = BLOCK, exit 0 = ALLOW
|
|
348
|
-
// Antigravity CLI:
|
|
348
|
+
// Antigravity CLI: its PreToolUse hook result is a protobuf message decoded from
|
|
349
|
+
// stdout JSON — BLOCK = {"allow_tool": false, "deny_reason": "..."}, ALLOW =
|
|
350
|
+
// {"allow_tool": true} (exit 0). NOTE: {"decision":"deny"} is Antigravity's
|
|
351
|
+
// *Stop* hook schema, NOT the tool gate — agy silently runs the tool if we
|
|
352
|
+
// send that, so the field names here are load-bearing (verified in the agy
|
|
353
|
+
// 1.1.5 binary: AllowTool bool / DenyReason string).
|
|
349
354
|
|
|
350
355
|
// Terminate the hook WITHOUT forcing process.exit(). On Windows + Node 24, calling
|
|
351
356
|
// process.exit() right after a fetch() (the cloud audit-log POST) aborts with
|
|
@@ -380,8 +385,8 @@ function sgFinish(code) {
|
|
|
380
385
|
function blockTool(reason) {
|
|
381
386
|
if (AGENT_TYPE === 'antigravity') {
|
|
382
387
|
process.stdout.write(JSON.stringify({
|
|
383
|
-
|
|
384
|
-
|
|
388
|
+
allow_tool: false,
|
|
389
|
+
deny_reason: `[SolonGate] ${reason}`,
|
|
385
390
|
}));
|
|
386
391
|
sgFinish(0);
|
|
387
392
|
} else {
|
|
@@ -409,7 +414,7 @@ function blockTool(reason) {
|
|
|
409
414
|
|
|
410
415
|
function allowTool() {
|
|
411
416
|
if (AGENT_TYPE === 'antigravity') {
|
|
412
|
-
process.stdout.write(JSON.stringify({
|
|
417
|
+
process.stdout.write(JSON.stringify({ allow_tool: true }));
|
|
413
418
|
}
|
|
414
419
|
sgFinish(0);
|
|
415
420
|
}
|
|
@@ -1816,7 +1821,7 @@ if (!REFRESH_MODE) { try { input += readFileSync(0, 'utf-8'); } catch {} }
|
|
|
1816
1821
|
});
|
|
1817
1822
|
} catch {}
|
|
1818
1823
|
await maybeSelfUpdate();
|
|
1819
|
-
if (AGENT_TYPE === 'antigravity') { process.stdout.write(JSON.stringify({
|
|
1824
|
+
if (AGENT_TYPE === 'antigravity') { process.stdout.write(JSON.stringify({ allow_tool: false, deny_reason: ghostHit })); sgFinish(0); }
|
|
1820
1825
|
// Claude Code: JSON deny on stdout + exit 2 (reason on stderr). Exit 2 is
|
|
1821
1826
|
// the only block enforced in auto-accept mode (see blockTool); the JSON is
|
|
1822
1827
|
// the Windows fallback. ghostHit is a bare "No such file or directory", so
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.82.
|
|
3
|
+
"version": "0.82.17",
|
|
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": {
|