@solongate/proxy 0.28.4 → 0.28.6
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 +25 -27
- package/dist/init.js +25 -27
- package/hooks/audit.mjs +15 -4
- package/hooks/guard.mjs +23 -7
- package/hooks/stop.mjs +75 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -678,33 +678,16 @@ function installHooks(selectedTools = []) {
|
|
|
678
678
|
const auditPath = join(hooksDir, "audit.mjs");
|
|
679
679
|
writeFileSync2(auditPath, readHookScript("audit.mjs"));
|
|
680
680
|
console.log(` Created ${auditPath}`);
|
|
681
|
-
const
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
{
|
|
685
|
-
matcher: "",
|
|
686
|
-
hooks: [
|
|
687
|
-
{ type: "command", command: "node .solongate/hooks/guard.mjs" }
|
|
688
|
-
]
|
|
689
|
-
}
|
|
690
|
-
],
|
|
691
|
-
PostToolUse: [
|
|
692
|
-
{
|
|
693
|
-
matcher: "",
|
|
694
|
-
hooks: [
|
|
695
|
-
{ type: "command", command: "node .solongate/hooks/audit.mjs" }
|
|
696
|
-
]
|
|
697
|
-
}
|
|
698
|
-
]
|
|
699
|
-
}
|
|
700
|
-
};
|
|
681
|
+
const stopPath = join(hooksDir, "stop.mjs");
|
|
682
|
+
writeFileSync2(stopPath, readHookScript("stop.mjs"));
|
|
683
|
+
console.log(` Created ${stopPath}`);
|
|
701
684
|
const allClients = [
|
|
702
|
-
{ name: "Claude Code", dir: ".claude", key: "claude" },
|
|
703
|
-
{ name: "Cursor", dir: ".cursor", key: "cursor" },
|
|
704
|
-
{ name: "Gemini CLI", dir: ".gemini", key: "gemini" },
|
|
705
|
-
{ name: "Antigravity", dir: ".antigravity", key: "antigravity" },
|
|
706
|
-
{ name: "OpenClaw", dir: ".openclaw", key: "openclaw" },
|
|
707
|
-
{ name: "Perplexity", dir: ".perplexity", key: "perplexity" }
|
|
685
|
+
{ name: "Claude Code", dir: ".claude", key: "claude", agentId: "claude-code", agentName: "Claude Code" },
|
|
686
|
+
{ name: "Cursor", dir: ".cursor", key: "cursor", agentId: "cursor", agentName: "Cursor" },
|
|
687
|
+
{ name: "Gemini CLI", dir: ".gemini", key: "gemini", agentId: "gemini-cli", agentName: "Gemini CLI" },
|
|
688
|
+
{ name: "Antigravity", dir: ".antigravity", key: "antigravity", agentId: "antigravity", agentName: "Antigravity" },
|
|
689
|
+
{ name: "OpenClaw", dir: ".openclaw", key: "openclaw", agentId: "openclaw", agentName: "OpenClaw" },
|
|
690
|
+
{ name: "Perplexity", dir: ".perplexity", key: "perplexity", agentId: "perplexity", agentName: "Perplexity" }
|
|
708
691
|
];
|
|
709
692
|
const clients = selectedTools.length > 0 ? allClients.filter((c3) => selectedTools.includes(c3.key)) : allClients;
|
|
710
693
|
const activatedNames = [];
|
|
@@ -712,12 +695,26 @@ function installHooks(selectedTools = []) {
|
|
|
712
695
|
const clientDir = resolve3(client.dir);
|
|
713
696
|
mkdirSync2(clientDir, { recursive: true });
|
|
714
697
|
const settingsPath = join(clientDir, "settings.json");
|
|
698
|
+
const guardCmd = `node .solongate/hooks/guard.mjs ${client.agentId} "${client.agentName}"`;
|
|
699
|
+
const auditCmd = `node .solongate/hooks/audit.mjs ${client.agentId} "${client.agentName}"`;
|
|
700
|
+
const stopCmd = `node .solongate/hooks/stop.mjs ${client.agentId} "${client.agentName}"`;
|
|
701
|
+
const hookSettings = {
|
|
702
|
+
PreToolUse: [
|
|
703
|
+
{ matcher: "", hooks: [{ type: "command", command: guardCmd }] }
|
|
704
|
+
],
|
|
705
|
+
PostToolUse: [
|
|
706
|
+
{ matcher: "", hooks: [{ type: "command", command: auditCmd }] }
|
|
707
|
+
],
|
|
708
|
+
Stop: [
|
|
709
|
+
{ matcher: "", hooks: [{ type: "command", command: stopCmd }] }
|
|
710
|
+
]
|
|
711
|
+
};
|
|
715
712
|
let existing = {};
|
|
716
713
|
try {
|
|
717
714
|
existing = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
718
715
|
} catch {
|
|
719
716
|
}
|
|
720
|
-
const merged = { ...existing, hooks: hookSettings
|
|
717
|
+
const merged = { ...existing, hooks: hookSettings };
|
|
721
718
|
writeFileSync2(settingsPath, JSON.stringify(merged, null, 2) + "\n");
|
|
722
719
|
console.log(` Created ${settingsPath}`);
|
|
723
720
|
activatedNames.push(client.name);
|
|
@@ -726,6 +723,7 @@ function installHooks(selectedTools = []) {
|
|
|
726
723
|
console.log(" Hooks installed:");
|
|
727
724
|
console.log(" guard.mjs \u2192 blocks policy-violating calls (pre-execution)");
|
|
728
725
|
console.log(" audit.mjs \u2192 logs all calls to dashboard (post-execution)");
|
|
726
|
+
console.log(" stop.mjs \u2192 tracks text-only responses (no tool calls)");
|
|
729
727
|
console.log(` Activated for: ${activatedNames.join(", ")}`);
|
|
730
728
|
}
|
|
731
729
|
function ensureEnvFile() {
|
package/dist/init.js
CHANGED
|
@@ -261,33 +261,16 @@ function installHooks(selectedTools = []) {
|
|
|
261
261
|
const auditPath = join(hooksDir, "audit.mjs");
|
|
262
262
|
writeFileSync(auditPath, readHookScript("audit.mjs"));
|
|
263
263
|
console.log(` Created ${auditPath}`);
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
{
|
|
268
|
-
matcher: "",
|
|
269
|
-
hooks: [
|
|
270
|
-
{ type: "command", command: "node .solongate/hooks/guard.mjs" }
|
|
271
|
-
]
|
|
272
|
-
}
|
|
273
|
-
],
|
|
274
|
-
PostToolUse: [
|
|
275
|
-
{
|
|
276
|
-
matcher: "",
|
|
277
|
-
hooks: [
|
|
278
|
-
{ type: "command", command: "node .solongate/hooks/audit.mjs" }
|
|
279
|
-
]
|
|
280
|
-
}
|
|
281
|
-
]
|
|
282
|
-
}
|
|
283
|
-
};
|
|
264
|
+
const stopPath = join(hooksDir, "stop.mjs");
|
|
265
|
+
writeFileSync(stopPath, readHookScript("stop.mjs"));
|
|
266
|
+
console.log(` Created ${stopPath}`);
|
|
284
267
|
const allClients = [
|
|
285
|
-
{ name: "Claude Code", dir: ".claude", key: "claude" },
|
|
286
|
-
{ name: "Cursor", dir: ".cursor", key: "cursor" },
|
|
287
|
-
{ name: "Gemini CLI", dir: ".gemini", key: "gemini" },
|
|
288
|
-
{ name: "Antigravity", dir: ".antigravity", key: "antigravity" },
|
|
289
|
-
{ name: "OpenClaw", dir: ".openclaw", key: "openclaw" },
|
|
290
|
-
{ name: "Perplexity", dir: ".perplexity", key: "perplexity" }
|
|
268
|
+
{ name: "Claude Code", dir: ".claude", key: "claude", agentId: "claude-code", agentName: "Claude Code" },
|
|
269
|
+
{ name: "Cursor", dir: ".cursor", key: "cursor", agentId: "cursor", agentName: "Cursor" },
|
|
270
|
+
{ name: "Gemini CLI", dir: ".gemini", key: "gemini", agentId: "gemini-cli", agentName: "Gemini CLI" },
|
|
271
|
+
{ name: "Antigravity", dir: ".antigravity", key: "antigravity", agentId: "antigravity", agentName: "Antigravity" },
|
|
272
|
+
{ name: "OpenClaw", dir: ".openclaw", key: "openclaw", agentId: "openclaw", agentName: "OpenClaw" },
|
|
273
|
+
{ name: "Perplexity", dir: ".perplexity", key: "perplexity", agentId: "perplexity", agentName: "Perplexity" }
|
|
291
274
|
];
|
|
292
275
|
const clients = selectedTools.length > 0 ? allClients.filter((c2) => selectedTools.includes(c2.key)) : allClients;
|
|
293
276
|
const activatedNames = [];
|
|
@@ -295,12 +278,26 @@ function installHooks(selectedTools = []) {
|
|
|
295
278
|
const clientDir = resolve(client.dir);
|
|
296
279
|
mkdirSync(clientDir, { recursive: true });
|
|
297
280
|
const settingsPath = join(clientDir, "settings.json");
|
|
281
|
+
const guardCmd = `node .solongate/hooks/guard.mjs ${client.agentId} "${client.agentName}"`;
|
|
282
|
+
const auditCmd = `node .solongate/hooks/audit.mjs ${client.agentId} "${client.agentName}"`;
|
|
283
|
+
const stopCmd = `node .solongate/hooks/stop.mjs ${client.agentId} "${client.agentName}"`;
|
|
284
|
+
const hookSettings = {
|
|
285
|
+
PreToolUse: [
|
|
286
|
+
{ matcher: "", hooks: [{ type: "command", command: guardCmd }] }
|
|
287
|
+
],
|
|
288
|
+
PostToolUse: [
|
|
289
|
+
{ matcher: "", hooks: [{ type: "command", command: auditCmd }] }
|
|
290
|
+
],
|
|
291
|
+
Stop: [
|
|
292
|
+
{ matcher: "", hooks: [{ type: "command", command: stopCmd }] }
|
|
293
|
+
]
|
|
294
|
+
};
|
|
298
295
|
let existing = {};
|
|
299
296
|
try {
|
|
300
297
|
existing = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
301
298
|
} catch {
|
|
302
299
|
}
|
|
303
|
-
const merged = { ...existing, hooks: hookSettings
|
|
300
|
+
const merged = { ...existing, hooks: hookSettings };
|
|
304
301
|
writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + "\n");
|
|
305
302
|
console.log(` Created ${settingsPath}`);
|
|
306
303
|
activatedNames.push(client.name);
|
|
@@ -309,6 +306,7 @@ function installHooks(selectedTools = []) {
|
|
|
309
306
|
console.log(" Hooks installed:");
|
|
310
307
|
console.log(" guard.mjs \u2192 blocks policy-violating calls (pre-execution)");
|
|
311
308
|
console.log(" audit.mjs \u2192 logs all calls to dashboard (post-execution)");
|
|
309
|
+
console.log(" stop.mjs \u2192 tracks text-only responses (no tool calls)");
|
|
312
310
|
console.log(` Activated for: ${activatedNames.join(", ")}`);
|
|
313
311
|
}
|
|
314
312
|
function ensureEnvFile() {
|
package/hooks/audit.mjs
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Logs tool execution results to SolonGate Cloud.
|
|
5
5
|
* Auto-installed by: npx @solongate/proxy init
|
|
6
6
|
*/
|
|
7
|
-
import { readFileSync, existsSync } from 'node:fs';
|
|
8
|
-
import { resolve } from 'node:path';
|
|
7
|
+
import { readFileSync, existsSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
8
|
+
import { resolve, join } from 'node:path';
|
|
9
9
|
|
|
10
10
|
function loadEnvKey(dir) {
|
|
11
11
|
try {
|
|
@@ -25,6 +25,10 @@ const dotenv = loadEnvKey(process.cwd());
|
|
|
25
25
|
const API_KEY = process.env.SOLONGATE_API_KEY || dotenv.SOLONGATE_API_KEY || '';
|
|
26
26
|
const API_URL = process.env.SOLONGATE_API_URL || dotenv.SOLONGATE_API_URL || 'https://api.solongate.com';
|
|
27
27
|
|
|
28
|
+
// Agent identity from CLI args: node audit.mjs <agent_id> <agent_name>
|
|
29
|
+
const AGENT_ID = process.argv[2] || 'claude-code';
|
|
30
|
+
const AGENT_NAME = process.argv[3] || 'Claude Code';
|
|
31
|
+
|
|
28
32
|
if (!API_KEY || !API_KEY.startsWith('sg_live_')) process.exit(0);
|
|
29
33
|
|
|
30
34
|
let input = '';
|
|
@@ -50,6 +54,13 @@ process.stdin.on('end', async () => {
|
|
|
50
54
|
: v;
|
|
51
55
|
}
|
|
52
56
|
|
|
57
|
+
// Write flag so stop.mjs knows tool calls happened (skip text-only ALLOW)
|
|
58
|
+
try {
|
|
59
|
+
const flagDir = resolve('.solongate');
|
|
60
|
+
mkdirSync(flagDir, { recursive: true });
|
|
61
|
+
writeFileSync(join(flagDir, '.last-tool-call'), Date.now().toString());
|
|
62
|
+
} catch {}
|
|
63
|
+
|
|
53
64
|
await fetch(`${API_URL}/api/v1/audit-logs`, {
|
|
54
65
|
method: 'POST',
|
|
55
66
|
headers: {
|
|
@@ -63,8 +74,8 @@ process.stdin.on('end', async () => {
|
|
|
63
74
|
reason: hasError ? 'tool returned error' : 'allowed',
|
|
64
75
|
source: 'claude-code-hook',
|
|
65
76
|
evaluationTimeMs: 0,
|
|
66
|
-
agent_id:
|
|
67
|
-
agent_name:
|
|
77
|
+
agent_id: AGENT_ID,
|
|
78
|
+
agent_name: AGENT_NAME,
|
|
68
79
|
}),
|
|
69
80
|
signal: AbortSignal.timeout(5000),
|
|
70
81
|
});
|
package/hooks/guard.mjs
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* Reads policy.json and blocks tool calls that violate constraints.
|
|
5
5
|
* Also runs prompt injection detection (Stage 1 rules) on tool arguments.
|
|
6
6
|
* Exit code 2 = BLOCK, exit code 0 = ALLOW.
|
|
7
|
-
* Logs
|
|
7
|
+
* Logs DENY decisions to SolonGate Cloud. ALLOWs are logged by audit.mjs.
|
|
8
8
|
* Auto-installed by: npx @solongate/proxy init
|
|
9
9
|
*/
|
|
10
|
-
import { readFileSync, existsSync, statSync } from 'node:fs';
|
|
11
|
-
import { resolve } from 'node:path';
|
|
10
|
+
import { readFileSync, existsSync, statSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
11
|
+
import { resolve, join } from 'node:path';
|
|
12
12
|
|
|
13
13
|
// Safe file read with size limit (1MB max) to prevent DoS via large files
|
|
14
14
|
const MAX_FILE_READ = 1024 * 1024; // 1MB
|
|
@@ -40,6 +40,19 @@ const dotenv = loadEnvKey(hookCwdEarly);
|
|
|
40
40
|
const API_KEY = process.env.SOLONGATE_API_KEY || dotenv.SOLONGATE_API_KEY || '';
|
|
41
41
|
const API_URL = process.env.SOLONGATE_API_URL || dotenv.SOLONGATE_API_URL || 'https://api.solongate.com';
|
|
42
42
|
|
|
43
|
+
// Agent identity from CLI args: node guard.mjs <agent_id> <agent_name>
|
|
44
|
+
const AGENT_ID = process.argv[2] || 'claude-code';
|
|
45
|
+
const AGENT_NAME = process.argv[3] || 'Claude Code';
|
|
46
|
+
|
|
47
|
+
// Write flag file so stop.mjs knows a tool call (DENY) happened and doesn't log extra ALLOW
|
|
48
|
+
function writeDenyFlag() {
|
|
49
|
+
try {
|
|
50
|
+
const flagDir = resolve('.solongate');
|
|
51
|
+
mkdirSync(flagDir, { recursive: true });
|
|
52
|
+
writeFileSync(join(flagDir, '.last-tool-call'), Date.now().toString());
|
|
53
|
+
} catch {}
|
|
54
|
+
}
|
|
55
|
+
|
|
43
56
|
// ── Prompt Injection Detection (Stage 1: Rule-Based) ──
|
|
44
57
|
const PI_CATEGORIES = [
|
|
45
58
|
{
|
|
@@ -346,12 +359,13 @@ process.stdin.on('end', async () => {
|
|
|
346
359
|
tool: data.tool_name || '', arguments: args,
|
|
347
360
|
decision: 'DENY', reason,
|
|
348
361
|
source: 'claude-code-guard',
|
|
349
|
-
agent_id:
|
|
362
|
+
agent_id: AGENT_ID, agent_name: AGENT_NAME,
|
|
350
363
|
}),
|
|
351
364
|
signal: AbortSignal.timeout(3000),
|
|
352
365
|
});
|
|
353
366
|
} catch {}
|
|
354
367
|
}
|
|
368
|
+
writeDenyFlag();
|
|
355
369
|
process.stderr.write(reason);
|
|
356
370
|
process.exit(2);
|
|
357
371
|
}
|
|
@@ -978,7 +992,7 @@ process.stdin.on('end', async () => {
|
|
|
978
992
|
decision: isLogOnly ? 'ALLOW' : 'DENY',
|
|
979
993
|
reason: msg,
|
|
980
994
|
source: 'claude-code-guard',
|
|
981
|
-
agent_id:
|
|
995
|
+
agent_id: AGENT_ID, agent_name: AGENT_NAME,
|
|
982
996
|
pi_detected: true,
|
|
983
997
|
pi_trust_score: piResult.trustScore,
|
|
984
998
|
pi_blocked: !isLogOnly,
|
|
@@ -1015,6 +1029,7 @@ process.stdin.on('end', async () => {
|
|
|
1015
1029
|
process.stderr.write(msg);
|
|
1016
1030
|
// Fall through to policy evaluation (don't exit)
|
|
1017
1031
|
} else {
|
|
1032
|
+
writeDenyFlag();
|
|
1018
1033
|
process.stderr.write(msg);
|
|
1019
1034
|
process.exit(2);
|
|
1020
1035
|
}
|
|
@@ -1039,7 +1054,7 @@ process.stdin.on('end', async () => {
|
|
|
1039
1054
|
decision: 'ALLOW',
|
|
1040
1055
|
reason: 'Prompt injection detected but below threshold (trust: ' + (piResult.trustScore * 100).toFixed(0) + '%)',
|
|
1041
1056
|
source: 'claude-code-guard',
|
|
1042
|
-
agent_id:
|
|
1057
|
+
agent_id: AGENT_ID, agent_name: AGENT_NAME,
|
|
1043
1058
|
pi_detected: true,
|
|
1044
1059
|
pi_trust_score: piResult.trustScore,
|
|
1045
1060
|
pi_blocked: false,
|
|
@@ -1188,7 +1203,7 @@ Respond with ONLY valid JSON: {"decision": "ALLOW" or "DENY", "reason": "brief e
|
|
|
1188
1203
|
tool: toolName, arguments: args,
|
|
1189
1204
|
decision: 'DENY', reason,
|
|
1190
1205
|
source: 'claude-code-guard',
|
|
1191
|
-
agent_id:
|
|
1206
|
+
agent_id: AGENT_ID, agent_name: AGENT_NAME,
|
|
1192
1207
|
};
|
|
1193
1208
|
if (piResult) {
|
|
1194
1209
|
logEntry.pi_detected = true;
|
|
@@ -1205,6 +1220,7 @@ Respond with ONLY valid JSON: {"decision": "ALLOW" or "DENY", "reason": "brief e
|
|
|
1205
1220
|
});
|
|
1206
1221
|
} catch {}
|
|
1207
1222
|
}
|
|
1223
|
+
writeDenyFlag();
|
|
1208
1224
|
process.stderr.write(reason);
|
|
1209
1225
|
process.exit(2);
|
|
1210
1226
|
}
|
package/hooks/stop.mjs
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* SolonGate Stop Hook (Stop event)
|
|
4
|
+
* Logs a single ALLOW when Claude responds WITHOUT any tool calls.
|
|
5
|
+
* If tool calls were made, audit.mjs already logged them — this hook skips.
|
|
6
|
+
* Auto-installed by: npx @solongate/proxy init
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, existsSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
9
|
+
import { resolve, join } from 'node:path';
|
|
10
|
+
|
|
11
|
+
function loadEnvKey(dir) {
|
|
12
|
+
try {
|
|
13
|
+
const envPath = resolve(dir, '.env');
|
|
14
|
+
if (!existsSync(envPath)) return {};
|
|
15
|
+
const lines = readFileSync(envPath, 'utf-8').split('\n');
|
|
16
|
+
const env = {};
|
|
17
|
+
for (const line of lines) {
|
|
18
|
+
const m = line.match(/^([A-Z_]+)=(.*)$/);
|
|
19
|
+
if (m) env[m[1]] = m[2].replace(/^["']|["']$/g, '').trim();
|
|
20
|
+
}
|
|
21
|
+
return env;
|
|
22
|
+
} catch { return {}; }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const dotenv = loadEnvKey(process.cwd());
|
|
26
|
+
const API_KEY = process.env.SOLONGATE_API_KEY || dotenv.SOLONGATE_API_KEY || '';
|
|
27
|
+
const API_URL = process.env.SOLONGATE_API_URL || dotenv.SOLONGATE_API_URL || 'https://api.solongate.com';
|
|
28
|
+
|
|
29
|
+
// Agent identity from CLI args: node stop.mjs <agent_id> <agent_name>
|
|
30
|
+
const AGENT_ID = process.argv[2] || 'claude-code';
|
|
31
|
+
const AGENT_NAME = process.argv[3] || 'Claude Code';
|
|
32
|
+
|
|
33
|
+
if (!API_KEY || !API_KEY.startsWith('sg_live_')) process.exit(0);
|
|
34
|
+
|
|
35
|
+
// Flag file: audit.mjs writes this when a tool call was logged in this turn.
|
|
36
|
+
// If the flag exists, tool calls were made → skip (already logged).
|
|
37
|
+
// If the flag doesn't exist, no tool calls → log 1 ALLOW for the text response.
|
|
38
|
+
const flagDir = resolve('.solongate');
|
|
39
|
+
const flagFile = join(flagDir, '.last-tool-call');
|
|
40
|
+
|
|
41
|
+
let input = '';
|
|
42
|
+
process.stdin.on('data', c => input += c);
|
|
43
|
+
process.stdin.on('end', async () => {
|
|
44
|
+
try {
|
|
45
|
+
// Check if tool calls were made in this turn
|
|
46
|
+
if (existsSync(flagFile)) {
|
|
47
|
+
// Tool calls happened → audit.mjs already logged them. Clean up flag.
|
|
48
|
+
try { unlinkSync(flagFile); } catch {}
|
|
49
|
+
process.exit(0);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// No tool calls → log 1 ALLOW for the text-only response
|
|
53
|
+
await fetch(`${API_URL}/api/v1/audit-logs`, {
|
|
54
|
+
method: 'POST',
|
|
55
|
+
headers: {
|
|
56
|
+
'Authorization': `Bearer ${API_KEY}`,
|
|
57
|
+
'Content-Type': 'application/json',
|
|
58
|
+
},
|
|
59
|
+
body: JSON.stringify({
|
|
60
|
+
tool: '_response',
|
|
61
|
+
arguments: {},
|
|
62
|
+
decision: 'ALLOW',
|
|
63
|
+
reason: 'text response (no tool calls)',
|
|
64
|
+
source: 'claude-code-hook',
|
|
65
|
+
evaluationTimeMs: 0,
|
|
66
|
+
agent_id: AGENT_ID,
|
|
67
|
+
agent_name: AGENT_NAME,
|
|
68
|
+
}),
|
|
69
|
+
signal: AbortSignal.timeout(5000),
|
|
70
|
+
});
|
|
71
|
+
} catch {
|
|
72
|
+
// Silent
|
|
73
|
+
}
|
|
74
|
+
process.exit(0);
|
|
75
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.6",
|
|
4
4
|
"description": "MCP security proxy — protect any MCP server with customizable policies, path/command constraints, rate limiting, and audit logging. Zero code changes required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|