@node9/proxy 1.56.0 → 1.58.0

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.
Files changed (4) hide show
  1. package/dist/cli.js +26549 -842
  2. package/dist/cli.mjs +26573 -840
  3. package/dist/dashboard.mjs +46 -1
  4. package/package.json +1 -1
@@ -3435,6 +3435,15 @@ async function loadGeminiCostAsync(start, end, geminiTmpDir) {
3435
3435
  }
3436
3436
  return freezeGeminiCost(acc);
3437
3437
  }
3438
+ function dimensionOfBlock(checkedBy, ruleName) {
3439
+ if (checkedBy.includes("egress")) return "network";
3440
+ if (checkedBy.includes("pii") || checkedBy.includes("dlp")) return "data";
3441
+ if (checkedBy === "app-permission-block" || ruleName.startsWith("app-permission:")) return "mcp";
3442
+ if (ruleName.startsWith("shield:project-jail")) return "files";
3443
+ if (checkedBy === "loop-detected") return "toolRules";
3444
+ if (checkedBy === "timeout" || checkedBy === "local-decision") return "approvals";
3445
+ return "toolRules";
3446
+ }
3438
3447
  function aggregateReportFromAudit(period, opts = {}) {
3439
3448
  const now = opts.now ?? /* @__PURE__ */ new Date();
3440
3449
  const auditLogPath2 = opts.auditLogPath ?? path6.join(os6.homedir(), ".node9", "audit.log");
@@ -3494,7 +3503,9 @@ function aggregateReportFromAudit(period, opts = {}) {
3494
3503
  const ts = new Date(e.ts);
3495
3504
  return ts >= priorStart && ts <= priorEnd;
3496
3505
  });
3497
- const priorBlocked = priorEntries.filter((e) => !isAllow(e.decision)).length;
3506
+ const priorBlocked = priorEntries.filter(
3507
+ (e) => typeof e.decision === "string" && !isAllow(e.decision)
3508
+ ).length;
3498
3509
  const priorBlockRate = priorEntries.length > 0 ? priorBlocked / priorEntries.length : null;
3499
3510
  const excludeTests = opts.excludeTests === true;
3500
3511
  const testTs = excludeTests ? buildTestTimestamps(allEntries) : /* @__PURE__ */ new Set();
@@ -3502,6 +3513,7 @@ function aggregateReportFromAudit(period, opts = {}) {
3502
3513
  const entries = allEntries.filter((e) => {
3503
3514
  if (e.source === "post-hook") return false;
3504
3515
  if (e.source === "response-dlp") return false;
3516
+ if (typeof e.decision !== "string") return false;
3505
3517
  const ts = new Date(e.ts);
3506
3518
  if (ts < start || ts > end) return false;
3507
3519
  if (excludeTests && isTestEntry(e, testTs)) {
@@ -3527,6 +3539,11 @@ function aggregateReportFromAudit(period, opts = {}) {
3527
3539
  const mcpMap = /* @__PURE__ */ new Map();
3528
3540
  const dailyMap = /* @__PURE__ */ new Map();
3529
3541
  const hourMap = /* @__PURE__ */ new Map();
3542
+ let dimNetworkBlocked = 0;
3543
+ let dimDataObserved = 0;
3544
+ let dimFilesBlocked = 0;
3545
+ let dimToolRulesBlocked = 0;
3546
+ let dimMcpBlocked = 0;
3530
3547
  for (const e of entries) {
3531
3548
  if (superseded.has(supersedeKey(e))) continue;
3532
3549
  const allow = isAllow(e.decision);
@@ -3543,6 +3560,26 @@ function aggregateReportFromAudit(period, opts = {}) {
3543
3560
  else if (e.checkedBy !== "loop-detected") hardBlocked++;
3544
3561
  }
3545
3562
  if (e.checkedBy === "loop-detected") loopHits++;
3563
+ const cb = e.checkedBy ?? "";
3564
+ if (cb.includes("would-block") && (cb.includes("pii") || cb.includes("dlp"))) {
3565
+ dimDataObserved++;
3566
+ }
3567
+ if (!allow && !userInteracted) {
3568
+ switch (dimensionOfBlock(cb, e.ruleName ?? "")) {
3569
+ case "network":
3570
+ dimNetworkBlocked++;
3571
+ break;
3572
+ case "files":
3573
+ dimFilesBlocked++;
3574
+ break;
3575
+ case "mcp":
3576
+ dimMcpBlocked++;
3577
+ break;
3578
+ case "toolRules":
3579
+ dimToolRulesBlocked++;
3580
+ break;
3581
+ }
3582
+ }
3546
3583
  const t = toolMap.get(e.tool) ?? { calls: 0, blocked: 0 };
3547
3584
  t.calls++;
3548
3585
  if (!allow) t.blocked++;
@@ -3613,6 +3650,14 @@ function aggregateReportFromAudit(period, opts = {}) {
3613
3650
  mcpMap,
3614
3651
  dailyMap,
3615
3652
  hourMap,
3653
+ dimensions: {
3654
+ network: { blocked: dimNetworkBlocked },
3655
+ data: { blocked: dlpBlocked, observed: dimDataObserved },
3656
+ approvals: { approved: userApproved, denied: userDenied, timedOut },
3657
+ files: { blocked: dimFilesBlocked },
3658
+ toolRules: { blocked: dimToolRulesBlocked, mcp: dimMcpBlocked, loops: loopHits },
3659
+ cost: { totalUSD: claudeCost.total + codexCost.total + geminiCost.total }
3660
+ },
3616
3661
  generatedAt: now.toISOString()
3617
3662
  };
3618
3663
  return { data, hasAuditFile, responseDlpEntries };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node9/proxy",
3
- "version": "1.56.0",
3
+ "version": "1.58.0",
4
4
  "description": "The Sudo Command for AI Agents. Execution Security for Claude Code, Codex, Gemini, Cursor, Opencode, Pi, and any MCP server.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",