@node9/proxy 2.30.0 → 2.30.1

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 (3) hide show
  1. package/dist/cli.js +60 -13
  2. package/dist/cli.mjs +60 -13
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -66445,7 +66445,7 @@ function triggerReach(wf, raw) {
66445
66445
  const on = onObject(wf, raw) ?? {};
66446
66446
  const keys = triggerKeys(wf, raw);
66447
66447
  const firable = keys.filter(
66448
- (k) => keyStrangerFirable(on, k) || /^issues$/i.test(k) && testsAutoLabel(allIfText(wf))
66448
+ (k) => keyStrangerFirable(on, k) && !(/^workflow_run$/i.test(k) && upstreamRunTrusted(wf, raw)) || /^issues$/i.test(k) && testsAutoLabel(allIfText(wf))
66449
66449
  );
66450
66450
  const untrusted = firable.length > 0;
66451
66451
  const reusable = !untrusted && keys.some((k) => /^workflow_call$/i.test(k));
@@ -66564,12 +66564,14 @@ function loadWorkflow(content) {
66564
66564
  return LOADED;
66565
66565
  }
66566
66566
  var LOCAL_WORKFLOW_USES_RE = /^\s*\.\/\.github\/workflows\/([\w.-]{1,200}\.ya?ml)\s*$/i;
66567
- function localCallsOf(path91, content, autoLabels) {
66567
+ function localCallsOf(path91, content, autoLabels, trustedRunSources) {
66568
66568
  AUTO_LABELS = autoLabels ?? /* @__PURE__ */ new Set();
66569
+ TRUSTED_RUN_SOURCES = trustedRunSources ?? /* @__PURE__ */ new Set();
66569
66570
  try {
66570
66571
  return localCallsOfInner(path91, content);
66571
66572
  } finally {
66572
66573
  AUTO_LABELS = /* @__PURE__ */ new Set();
66574
+ TRUSTED_RUN_SOURCES = /* @__PURE__ */ new Set();
66573
66575
  }
66574
66576
  }
66575
66577
  function localCallsOfInner(path91, content) {
@@ -67179,8 +67181,9 @@ function hasImplicitActorGate(agentSteps, bypassActive, workflowRun = false) {
67179
67181
  return agentSteps.some((s) => {
67180
67182
  const build = claudeActionBuild(s.uses);
67181
67183
  if (!build) return false;
67184
+ if (!build.official) return false;
67182
67185
  if (!workflowRun) return true;
67183
- return build.official && workflowRunChecked(build.ref);
67186
+ return workflowRunChecked(build.ref);
67184
67187
  });
67185
67188
  }
67186
67189
  function claudeActionBuild(uses) {
@@ -67419,13 +67422,13 @@ function analyzeWorkflowInner(path91, content, callers) {
67419
67422
  "runs the checked-out head's own action (`uses: ./\u2026`): the PR author's code runs with the job's secrets"
67420
67423
  );
67421
67424
  if (head === "subdir") signals.push("checks out the untrusted PR head into an isolated subdir");
67425
+ const thirdParty = agentSteps.map((st) => claudeActionBuild(st.uses)).find((b) => b !== null && !b.official);
67426
+ if (thirdParty && !implicitGate)
67427
+ signals.push(
67428
+ `third-party build of claude-code-action (\`${safeText(thirdParty.owner, 40)}\`): not assumed to check the actor's write access like the official action`
67429
+ );
67422
67430
  if (workflowRunJobs.length) {
67423
67431
  const builds = workflowRunJobs.flatMap((j) => (j.steps ?? []).filter(isAgentStep)).map((st) => claudeActionBuild(st.uses)).filter((b) => b !== null);
67424
- const thirdParty = builds.find((b) => !b.official);
67425
- if (thirdParty)
67426
- signals.push(
67427
- `third-party build of claude-code-action (\`${safeText(thirdParty.owner, 40)}\`): on workflow_run it is not assumed to check the actor (the official action does from v1.0.185)`
67428
- );
67429
67432
  const old = builds.find((b) => b.official && !workflowRunChecked(b.ref));
67430
67433
  if (old)
67431
67434
  signals.push(
@@ -67722,12 +67725,14 @@ function readsItemList(text) {
67722
67725
  if (text.length > 2e5) return ITEM_LIST_RE.test(text);
67723
67726
  return text.replace(/\\\r?\n/g, " ").split("\n").some((l) => ITEM_LIST_RE.test(l) && !sanitizedListing(l));
67724
67727
  }
67725
- function analyzeTrustedReaders(path91, content, autoLabels, callers) {
67728
+ function analyzeTrustedReaders(path91, content, autoLabels, callers, trustedRunSources) {
67726
67729
  AUTO_LABELS = autoLabels ?? /* @__PURE__ */ new Set();
67730
+ TRUSTED_RUN_SOURCES = trustedRunSources ?? /* @__PURE__ */ new Set();
67727
67731
  try {
67728
67732
  return analyzeTrustedReadersInner(path91, content, callers);
67729
67733
  } finally {
67730
67734
  AUTO_LABELS = /* @__PURE__ */ new Set();
67735
+ TRUSTED_RUN_SOURCES = /* @__PURE__ */ new Set();
67731
67736
  }
67732
67737
  }
67733
67738
  function keysWithCallers(keys, callers) {
@@ -67882,12 +67887,14 @@ function requiresTrustedAuthor(src) {
67882
67887
  };
67883
67888
  return req(x);
67884
67889
  }
67885
- function analyzeForkCodeOnTrust(path91, content, callers, autoLabels) {
67890
+ function analyzeForkCodeOnTrust(path91, content, callers, autoLabels, trustedRunSources) {
67886
67891
  AUTO_LABELS = autoLabels ?? /* @__PURE__ */ new Set();
67892
+ TRUSTED_RUN_SOURCES = trustedRunSources ?? /* @__PURE__ */ new Set();
67887
67893
  try {
67888
67894
  return analyzeForkCodeOnTrustInner(path91, content, callers);
67889
67895
  } finally {
67890
67896
  AUTO_LABELS = /* @__PURE__ */ new Set();
67897
+ TRUSTED_RUN_SOURCES = /* @__PURE__ */ new Set();
67891
67898
  }
67892
67899
  }
67893
67900
  function analyzeForkCodeOnTrustInner(path91, content, callers) {
@@ -67972,6 +67979,16 @@ var EXTRA_RUNNER_RE = new RegExp(
67972
67979
  String.raw`^Bash\((?:[A-Z_][A-Z0-9_]{0,40}=\S{0,200} )*(?:/[\w./-]{0,80}/)?` + String.raw`(awk|gawk|mawk|sed|tee|tar|make(?! -n\b)|vim|vi|nvim|less|man|timeout|dd|install|` + String.raw`dotnet (?:run|script)|cargo run|go run|mvn exec|gradle run|npm start|tmux|` + String.raw`rm|git (?:push|config|submodule|filter-branch)|gh (?:repo|secret|auth|release))` + String.raw`(?: --?[A-Za-z][\w-]{0,30}){0,4} ?['"]?(?::\*| \*|\*)\)$`,
67973
67980
  "i"
67974
67981
  );
67982
+ var EXEC_ESCAPE_RE = new RegExp(
67983
+ String.raw`^Bash\((?:[A-Z_][A-Z0-9_]{0,40}=\S{0,200} )*(?:/[\w./-]{0,80}/)?` + String.raw`(find|make -n)` + String.raw`(?: --?[A-Za-z][\w-]{0,30}){0,4} ?['"]?(?::\*| \*|\*)\)$`,
67984
+ "i"
67985
+ );
67986
+ function execEscape(grant) {
67987
+ if (grant.length > OPEN_RUNNER_MAX) return false;
67988
+ return EXEC_ESCAPE_RE.test(
67989
+ grant.replace(/^PowerShell(?=$|\()/, "Bash").replace(/\s+/g, " ").replace(/\(\s+/, "(")
67990
+ );
67991
+ }
67975
67992
  var MCP_EXEC_RE = /^mcp__ide__executeCode$|^mcp__[\w-]{1,80}__(?:execute|exec|run)_(?:code|command|shell|sql|query)$|^mcp__[\w-]{1,80}__(?:ctx_)?(?:batch_)?execute$|^mcp__[\w-]{1,80}__(?:bash|shell|terminal)$/;
67976
67993
  function extraRunner(grant) {
67977
67994
  if (grant.length > OPEN_RUNNER_MAX || INFO_FLAG_RE.test(grant)) return false;
@@ -68152,6 +68169,24 @@ function analyzeAgentConfig(path91, content, tree) {
68152
68169
  })
68153
68170
  });
68154
68171
  }
68172
+ const escapes = allow.filter(execEscape);
68173
+ if (escapes.length) {
68174
+ const at = jsonValueIndex(content, escapes[0]);
68175
+ findings.push({
68176
+ ...at >= 0 ? { line: lineAtIndex(content, at) } : {},
68177
+ check: "CI-1",
68178
+ rule: "CI-1.exec-escape-grant",
68179
+ dimension: "toolRules",
68180
+ severity: "medium",
68181
+ title: "Committed agent config pre-approves a command that can run other programs",
68182
+ file: path91,
68183
+ signals: [
68184
+ `pre-approved: ${escapes.slice(0, 5).map((e) => `\`${safeText(e, 80)}\``).join(", ")}`,
68185
+ "`find -exec` and `make -n --eval` run other programs without a prompt"
68186
+ ],
68187
+ fix: "Pre-approve the exact command you need (for example `Bash(find . -name *.ts)` or `Bash(make test)`), not every argument."
68188
+ });
68189
+ }
68155
68190
  return findings;
68156
68191
  }
68157
68192
  var GRANT_CARRIER_RE = /(^|\/)[Ss][Kk][Ii][Ll][Ll]\.md$|(^|\/)\.claude\/commands\/.+\.md$/;
@@ -68490,6 +68525,7 @@ var CONCEALMENT = /* @__PURE__ */ new Set(["CI-6.unicode-tag-chars", "CI-6.bidi-
68490
68525
  function tierOf(f) {
68491
68526
  const { rule, severity } = f;
68492
68527
  if (rule === "CI-1.skill-allowed-tools") return "review";
68528
+ if (rule === "CI-1.exec-escape-grant") return "review";
68493
68529
  if (rule === "CI-2.trusted-trigger-reader" || rule === "CI-2.fork-code-on-trust" || rule === "CI-1.skill-untrusted-input")
68494
68530
  return "alert";
68495
68531
  if (UNREAD_RULES.has(rule)) return "review";
@@ -68517,6 +68553,8 @@ function reviewQuestion(rule) {
68517
68553
  return "Does this hook exist on every machine that runs it?";
68518
68554
  if (/hidden-chars/.test(rule))
68519
68555
  return "Why does this script hold invisible characters? A list of them to detect is fine.";
68556
+ if (/exec-escape/.test(rule))
68557
+ return "Does the agent need this command with any arguments, or only one exact form?";
68520
68558
  if (/unscanned/.test(rule))
68521
68559
  return "node9 did not read this script (too large, or outside the folders it reads). What does it run?";
68522
68560
  return "Is this an instruction the agent follows, or text for a person?";
@@ -68889,7 +68927,12 @@ function scanTree(tree) {
68889
68927
  if (routeOfFile(file) !== "workflow") continue;
68890
68928
  try {
68891
68929
  const content = file.content;
68892
- for (const { target, caller } of localCallsOf(file.path, content, autoLabels)) {
68930
+ for (const { target, caller } of localCallsOf(
68931
+ file.path,
68932
+ content,
68933
+ autoLabels,
68934
+ trustedRunSources
68935
+ )) {
68893
68936
  const list = callersOf.get(target) ?? [];
68894
68937
  list.push(caller);
68895
68938
  callersOf.set(target, list);
@@ -68925,8 +68968,12 @@ function scanTree(tree) {
68925
68968
  );
68926
68969
  if (s) findings.push(s);
68927
68970
  findings.push(...analyzeWorkflowPlugins(file.path, content, tree.owner));
68928
- findings.push(...analyzeTrustedReaders(file.path, content, autoLabels, callers));
68929
- findings.push(...analyzeForkCodeOnTrust(file.path, content, callers, autoLabels));
68971
+ findings.push(
68972
+ ...analyzeTrustedReaders(file.path, content, autoLabels, callers, trustedRunSources)
68973
+ );
68974
+ findings.push(
68975
+ ...analyzeForkCodeOnTrust(file.path, content, callers, autoLabels, trustedRunSources)
68976
+ );
68930
68977
  break;
68931
68978
  }
68932
68979
  case "agent-config":
package/dist/cli.mjs CHANGED
@@ -66427,7 +66427,7 @@ function triggerReach(wf, raw) {
66427
66427
  const on = onObject(wf, raw) ?? {};
66428
66428
  const keys = triggerKeys(wf, raw);
66429
66429
  const firable = keys.filter(
66430
- (k) => keyStrangerFirable(on, k) || /^issues$/i.test(k) && testsAutoLabel(allIfText(wf))
66430
+ (k) => keyStrangerFirable(on, k) && !(/^workflow_run$/i.test(k) && upstreamRunTrusted(wf, raw)) || /^issues$/i.test(k) && testsAutoLabel(allIfText(wf))
66431
66431
  );
66432
66432
  const untrusted = firable.length > 0;
66433
66433
  const reusable = !untrusted && keys.some((k) => /^workflow_call$/i.test(k));
@@ -66546,12 +66546,14 @@ function loadWorkflow(content) {
66546
66546
  return LOADED;
66547
66547
  }
66548
66548
  var LOCAL_WORKFLOW_USES_RE = /^\s*\.\/\.github\/workflows\/([\w.-]{1,200}\.ya?ml)\s*$/i;
66549
- function localCallsOf(path91, content, autoLabels) {
66549
+ function localCallsOf(path91, content, autoLabels, trustedRunSources) {
66550
66550
  AUTO_LABELS = autoLabels ?? /* @__PURE__ */ new Set();
66551
+ TRUSTED_RUN_SOURCES = trustedRunSources ?? /* @__PURE__ */ new Set();
66551
66552
  try {
66552
66553
  return localCallsOfInner(path91, content);
66553
66554
  } finally {
66554
66555
  AUTO_LABELS = /* @__PURE__ */ new Set();
66556
+ TRUSTED_RUN_SOURCES = /* @__PURE__ */ new Set();
66555
66557
  }
66556
66558
  }
66557
66559
  function localCallsOfInner(path91, content) {
@@ -67161,8 +67163,9 @@ function hasImplicitActorGate(agentSteps, bypassActive, workflowRun = false) {
67161
67163
  return agentSteps.some((s) => {
67162
67164
  const build = claudeActionBuild(s.uses);
67163
67165
  if (!build) return false;
67166
+ if (!build.official) return false;
67164
67167
  if (!workflowRun) return true;
67165
- return build.official && workflowRunChecked(build.ref);
67168
+ return workflowRunChecked(build.ref);
67166
67169
  });
67167
67170
  }
67168
67171
  function claudeActionBuild(uses) {
@@ -67401,13 +67404,13 @@ function analyzeWorkflowInner(path91, content, callers) {
67401
67404
  "runs the checked-out head's own action (`uses: ./\u2026`): the PR author's code runs with the job's secrets"
67402
67405
  );
67403
67406
  if (head === "subdir") signals.push("checks out the untrusted PR head into an isolated subdir");
67407
+ const thirdParty = agentSteps.map((st) => claudeActionBuild(st.uses)).find((b) => b !== null && !b.official);
67408
+ if (thirdParty && !implicitGate)
67409
+ signals.push(
67410
+ `third-party build of claude-code-action (\`${safeText(thirdParty.owner, 40)}\`): not assumed to check the actor's write access like the official action`
67411
+ );
67404
67412
  if (workflowRunJobs.length) {
67405
67413
  const builds = workflowRunJobs.flatMap((j) => (j.steps ?? []).filter(isAgentStep)).map((st) => claudeActionBuild(st.uses)).filter((b) => b !== null);
67406
- const thirdParty = builds.find((b) => !b.official);
67407
- if (thirdParty)
67408
- signals.push(
67409
- `third-party build of claude-code-action (\`${safeText(thirdParty.owner, 40)}\`): on workflow_run it is not assumed to check the actor (the official action does from v1.0.185)`
67410
- );
67411
67414
  const old = builds.find((b) => b.official && !workflowRunChecked(b.ref));
67412
67415
  if (old)
67413
67416
  signals.push(
@@ -67704,12 +67707,14 @@ function readsItemList(text) {
67704
67707
  if (text.length > 2e5) return ITEM_LIST_RE.test(text);
67705
67708
  return text.replace(/\\\r?\n/g, " ").split("\n").some((l) => ITEM_LIST_RE.test(l) && !sanitizedListing(l));
67706
67709
  }
67707
- function analyzeTrustedReaders(path91, content, autoLabels, callers) {
67710
+ function analyzeTrustedReaders(path91, content, autoLabels, callers, trustedRunSources) {
67708
67711
  AUTO_LABELS = autoLabels ?? /* @__PURE__ */ new Set();
67712
+ TRUSTED_RUN_SOURCES = trustedRunSources ?? /* @__PURE__ */ new Set();
67709
67713
  try {
67710
67714
  return analyzeTrustedReadersInner(path91, content, callers);
67711
67715
  } finally {
67712
67716
  AUTO_LABELS = /* @__PURE__ */ new Set();
67717
+ TRUSTED_RUN_SOURCES = /* @__PURE__ */ new Set();
67713
67718
  }
67714
67719
  }
67715
67720
  function keysWithCallers(keys, callers) {
@@ -67864,12 +67869,14 @@ function requiresTrustedAuthor(src) {
67864
67869
  };
67865
67870
  return req(x);
67866
67871
  }
67867
- function analyzeForkCodeOnTrust(path91, content, callers, autoLabels) {
67872
+ function analyzeForkCodeOnTrust(path91, content, callers, autoLabels, trustedRunSources) {
67868
67873
  AUTO_LABELS = autoLabels ?? /* @__PURE__ */ new Set();
67874
+ TRUSTED_RUN_SOURCES = trustedRunSources ?? /* @__PURE__ */ new Set();
67869
67875
  try {
67870
67876
  return analyzeForkCodeOnTrustInner(path91, content, callers);
67871
67877
  } finally {
67872
67878
  AUTO_LABELS = /* @__PURE__ */ new Set();
67879
+ TRUSTED_RUN_SOURCES = /* @__PURE__ */ new Set();
67873
67880
  }
67874
67881
  }
67875
67882
  function analyzeForkCodeOnTrustInner(path91, content, callers) {
@@ -67954,6 +67961,16 @@ var EXTRA_RUNNER_RE = new RegExp(
67954
67961
  String.raw`^Bash\((?:[A-Z_][A-Z0-9_]{0,40}=\S{0,200} )*(?:/[\w./-]{0,80}/)?` + String.raw`(awk|gawk|mawk|sed|tee|tar|make(?! -n\b)|vim|vi|nvim|less|man|timeout|dd|install|` + String.raw`dotnet (?:run|script)|cargo run|go run|mvn exec|gradle run|npm start|tmux|` + String.raw`rm|git (?:push|config|submodule|filter-branch)|gh (?:repo|secret|auth|release))` + String.raw`(?: --?[A-Za-z][\w-]{0,30}){0,4} ?['"]?(?::\*| \*|\*)\)$`,
67955
67962
  "i"
67956
67963
  );
67964
+ var EXEC_ESCAPE_RE = new RegExp(
67965
+ String.raw`^Bash\((?:[A-Z_][A-Z0-9_]{0,40}=\S{0,200} )*(?:/[\w./-]{0,80}/)?` + String.raw`(find|make -n)` + String.raw`(?: --?[A-Za-z][\w-]{0,30}){0,4} ?['"]?(?::\*| \*|\*)\)$`,
67966
+ "i"
67967
+ );
67968
+ function execEscape(grant) {
67969
+ if (grant.length > OPEN_RUNNER_MAX) return false;
67970
+ return EXEC_ESCAPE_RE.test(
67971
+ grant.replace(/^PowerShell(?=$|\()/, "Bash").replace(/\s+/g, " ").replace(/\(\s+/, "(")
67972
+ );
67973
+ }
67957
67974
  var MCP_EXEC_RE = /^mcp__ide__executeCode$|^mcp__[\w-]{1,80}__(?:execute|exec|run)_(?:code|command|shell|sql|query)$|^mcp__[\w-]{1,80}__(?:ctx_)?(?:batch_)?execute$|^mcp__[\w-]{1,80}__(?:bash|shell|terminal)$/;
67958
67975
  function extraRunner(grant) {
67959
67976
  if (grant.length > OPEN_RUNNER_MAX || INFO_FLAG_RE.test(grant)) return false;
@@ -68134,6 +68151,24 @@ function analyzeAgentConfig(path91, content, tree) {
68134
68151
  })
68135
68152
  });
68136
68153
  }
68154
+ const escapes = allow.filter(execEscape);
68155
+ if (escapes.length) {
68156
+ const at = jsonValueIndex(content, escapes[0]);
68157
+ findings.push({
68158
+ ...at >= 0 ? { line: lineAtIndex(content, at) } : {},
68159
+ check: "CI-1",
68160
+ rule: "CI-1.exec-escape-grant",
68161
+ dimension: "toolRules",
68162
+ severity: "medium",
68163
+ title: "Committed agent config pre-approves a command that can run other programs",
68164
+ file: path91,
68165
+ signals: [
68166
+ `pre-approved: ${escapes.slice(0, 5).map((e) => `\`${safeText(e, 80)}\``).join(", ")}`,
68167
+ "`find -exec` and `make -n --eval` run other programs without a prompt"
68168
+ ],
68169
+ fix: "Pre-approve the exact command you need (for example `Bash(find . -name *.ts)` or `Bash(make test)`), not every argument."
68170
+ });
68171
+ }
68137
68172
  return findings;
68138
68173
  }
68139
68174
  var GRANT_CARRIER_RE = /(^|\/)[Ss][Kk][Ii][Ll][Ll]\.md$|(^|\/)\.claude\/commands\/.+\.md$/;
@@ -68472,6 +68507,7 @@ var CONCEALMENT = /* @__PURE__ */ new Set(["CI-6.unicode-tag-chars", "CI-6.bidi-
68472
68507
  function tierOf(f) {
68473
68508
  const { rule, severity } = f;
68474
68509
  if (rule === "CI-1.skill-allowed-tools") return "review";
68510
+ if (rule === "CI-1.exec-escape-grant") return "review";
68475
68511
  if (rule === "CI-2.trusted-trigger-reader" || rule === "CI-2.fork-code-on-trust" || rule === "CI-1.skill-untrusted-input")
68476
68512
  return "alert";
68477
68513
  if (UNREAD_RULES.has(rule)) return "review";
@@ -68499,6 +68535,8 @@ function reviewQuestion(rule) {
68499
68535
  return "Does this hook exist on every machine that runs it?";
68500
68536
  if (/hidden-chars/.test(rule))
68501
68537
  return "Why does this script hold invisible characters? A list of them to detect is fine.";
68538
+ if (/exec-escape/.test(rule))
68539
+ return "Does the agent need this command with any arguments, or only one exact form?";
68502
68540
  if (/unscanned/.test(rule))
68503
68541
  return "node9 did not read this script (too large, or outside the folders it reads). What does it run?";
68504
68542
  return "Is this an instruction the agent follows, or text for a person?";
@@ -68871,7 +68909,12 @@ function scanTree(tree) {
68871
68909
  if (routeOfFile(file) !== "workflow") continue;
68872
68910
  try {
68873
68911
  const content = file.content;
68874
- for (const { target, caller } of localCallsOf(file.path, content, autoLabels)) {
68912
+ for (const { target, caller } of localCallsOf(
68913
+ file.path,
68914
+ content,
68915
+ autoLabels,
68916
+ trustedRunSources
68917
+ )) {
68875
68918
  const list = callersOf.get(target) ?? [];
68876
68919
  list.push(caller);
68877
68920
  callersOf.set(target, list);
@@ -68907,8 +68950,12 @@ function scanTree(tree) {
68907
68950
  );
68908
68951
  if (s) findings.push(s);
68909
68952
  findings.push(...analyzeWorkflowPlugins(file.path, content, tree.owner));
68910
- findings.push(...analyzeTrustedReaders(file.path, content, autoLabels, callers));
68911
- findings.push(...analyzeForkCodeOnTrust(file.path, content, callers, autoLabels));
68953
+ findings.push(
68954
+ ...analyzeTrustedReaders(file.path, content, autoLabels, callers, trustedRunSources)
68955
+ );
68956
+ findings.push(
68957
+ ...analyzeForkCodeOnTrust(file.path, content, callers, autoLabels, trustedRunSources)
68958
+ );
68912
68959
  break;
68913
68960
  }
68914
68961
  case "agent-config":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node9/proxy",
3
- "version": "2.30.0",
3
+ "version": "2.30.1",
4
4
  "description": "Access control for AI agents. Set what Claude Code, Codex, Gemini, Cursor and any MCP server are allowed to do, review risky actions before they run, and keep every action on the record.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",