@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 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
@@ -6808,7 +6808,10 @@ function blockTool(reason) {
6808
6808
  hookSpecificOutput: {
6809
6809
  hookEventName: "PreToolUse",
6810
6810
  permissionDecision: "deny",
6811
- permissionDecisionReason: reason
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
- permissionDecisionReason: reason,
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.75",
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": {