@solongate/proxy 0.81.75 → 0.81.76
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 +1 -0
- package/dist/shield.js +1 -0
- package/hooks/audit.mjs +7 -0
- package/hooks/guard.bundled.mjs +4 -1
- package/hooks/guard.mjs +4 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12667,6 +12667,7 @@ function redactDeep(value, cfg) {
|
|
|
12667
12667
|
if (typeof value === "string") {
|
|
12668
12668
|
let out2 = redactString(value, cfg);
|
|
12669
12669
|
if (ghost && ghost.length) out2 = ghostStripLines(out2, ghost);
|
|
12670
|
+
if (out2 === "" && value !== "") out2 = "\n";
|
|
12670
12671
|
return out2;
|
|
12671
12672
|
}
|
|
12672
12673
|
if (Array.isArray(value)) {
|
package/dist/shield.js
CHANGED
|
@@ -182,6 +182,7 @@ function redactDeep(value, cfg) {
|
|
|
182
182
|
if (typeof value === "string") {
|
|
183
183
|
let out = redactString(value, cfg);
|
|
184
184
|
if (ghost && ghost.length) out = ghostStripLines(out, ghost);
|
|
185
|
+
if (out === "" && value !== "") out = "\n";
|
|
185
186
|
return out;
|
|
186
187
|
}
|
|
187
188
|
if (Array.isArray(value)) {
|
package/hooks/audit.mjs
CHANGED
|
@@ -565,6 +565,13 @@ try { input += readFileSync(0, 'utf-8'); } catch {}
|
|
|
565
565
|
}
|
|
566
566
|
}
|
|
567
567
|
if (typeof out === 'string') {
|
|
568
|
+
// Never emit EMPTY content. When ghost/DLP stripping removes every line
|
|
569
|
+
// (e.g. a grep/cat that hit only hidden or secret lines) and the tool
|
|
570
|
+
// ALSO errored, the resulting tool_result is is_error:true with empty
|
|
571
|
+
// content — which the API rejects ("content cannot be empty if is_error
|
|
572
|
+
// is true") and hard-crashes the whole agent conversation. Fall back to
|
|
573
|
+
// a bare newline: still looks like empty output, but is non-empty.
|
|
574
|
+
if (out === '') out = '\n';
|
|
568
575
|
// Preserve the tool's result SHAPE. Bash and other tools deliver a
|
|
569
576
|
// STRUCTURED result ({ stdout, stderr, ... } or { content }); Claude
|
|
570
577
|
// Code rejects a bare-string replacement for those (hook warning) and
|
package/hooks/guard.bundled.mjs
CHANGED
|
@@ -6808,7 +6808,10 @@ function blockTool(reason) {
|
|
|
6808
6808
|
hookSpecificOutput: {
|
|
6809
6809
|
hookEventName: "PreToolUse",
|
|
6810
6810
|
permissionDecision: "deny",
|
|
6811
|
-
|
|
6811
|
+
// Never empty: a deny with an empty reason becomes an is_error tool_result
|
|
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
6815
|
}
|
|
6813
6816
|
}));
|
|
6814
6817
|
sgFinish(0);
|
package/hooks/guard.mjs
CHANGED
|
@@ -395,7 +395,10 @@ function blockTool(reason) {
|
|
|
395
395
|
hookSpecificOutput: {
|
|
396
396
|
hookEventName: 'PreToolUse',
|
|
397
397
|
permissionDecision: 'deny',
|
|
398
|
-
|
|
398
|
+
// Never empty: a deny with an empty reason becomes an is_error tool_result
|
|
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',
|
|
399
402
|
},
|
|
400
403
|
}));
|
|
401
404
|
sgFinish(0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.76",
|
|
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": {
|