@node9/proxy 2.28.0 → 2.28.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.
- package/dist/cli.js +92 -17
- package/dist/cli.mjs +92 -17
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -57986,15 +57986,25 @@ var VISIBLE_ESCAPES = {
|
|
|
57986
57986
|
function toVisibleEscape(c) {
|
|
57987
57987
|
return VISIBLE_ESCAPES[c] ?? `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`;
|
|
57988
57988
|
}
|
|
57989
|
+
var redact = (s) => redactText(s).result;
|
|
57990
|
+
var escapeUnsafe = (s) => s.replace(UNSAFE_CHARS, toVisibleEscape);
|
|
57989
57991
|
function displaySafe(text) {
|
|
57990
|
-
return
|
|
57992
|
+
return escapeUnsafe(redact(text));
|
|
57991
57993
|
}
|
|
57992
57994
|
var INPUT_PREVIEW_MAX = 80;
|
|
57993
57995
|
function inputPreview(raw) {
|
|
57994
|
-
const
|
|
57995
|
-
|
|
57996
|
+
const redacted = redact(raw);
|
|
57997
|
+
const points = Array.from(redacted);
|
|
57998
|
+
const cut = points.length > INPUT_PREVIEW_MAX ? points.slice(0, INPUT_PREVIEW_MAX - 3).join("") + "\u2026" : redacted;
|
|
57999
|
+
return escapeUnsafe(cut);
|
|
58000
|
+
}
|
|
58001
|
+
var JSON_RAW_UNSAFE = /[\u007f-\u009f\u061c\u200e\u200f\u2028\u2029\u202a-\u202e\u2066-\u2069]/g;
|
|
58002
|
+
function toSafeJson(doc) {
|
|
58003
|
+
return JSON.stringify(doc, null, 2).replace(
|
|
58004
|
+
JSON_RAW_UNSAFE,
|
|
58005
|
+
(c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`
|
|
58006
|
+
);
|
|
57996
58007
|
}
|
|
57997
|
-
var redact = (s) => redactText(s).result;
|
|
57998
58008
|
function buildExplainJson(result, rawInput) {
|
|
57999
58009
|
return {
|
|
58000
58010
|
schemaVersion: 1,
|
|
@@ -58009,7 +58019,11 @@ function buildExplainJson(result, rawInput) {
|
|
|
58009
58019
|
detail: redact(s.detail),
|
|
58010
58020
|
final: s.isFinal === true
|
|
58011
58021
|
})),
|
|
58012
|
-
waterfall: result.waterfall
|
|
58022
|
+
waterfall: result.waterfall.map((t) => ({
|
|
58023
|
+
...t,
|
|
58024
|
+
...t.path !== void 0 && { path: redact(t.path) },
|
|
58025
|
+
...t.note !== void 0 && { note: redact(t.note) }
|
|
58026
|
+
}))
|
|
58013
58027
|
};
|
|
58014
58028
|
}
|
|
58015
58029
|
function buildExplainJsonError(message) {
|
|
@@ -58935,6 +58949,52 @@ ${neutralizeMarkers(text)}
|
|
|
58935
58949
|
${f.footer}`;
|
|
58936
58950
|
}
|
|
58937
58951
|
|
|
58952
|
+
// src/tool-output.ts
|
|
58953
|
+
init_dlp();
|
|
58954
|
+
var MAX_DEPTH3 = 8;
|
|
58955
|
+
function collectToolOutputText(toolResponse, opts = {}) {
|
|
58956
|
+
const maxBytes = opts.maxBytes ?? DLP_SCAN_LIMITS.maxStringBytes;
|
|
58957
|
+
const parts = [];
|
|
58958
|
+
let size = 0;
|
|
58959
|
+
let fields = 0;
|
|
58960
|
+
let truncated = false;
|
|
58961
|
+
const push = (s) => {
|
|
58962
|
+
if (s.length === 0) return true;
|
|
58963
|
+
const room = maxBytes - size;
|
|
58964
|
+
if (s.length > room) {
|
|
58965
|
+
if (room > 0) {
|
|
58966
|
+
parts.push(s.slice(0, room));
|
|
58967
|
+
fields++;
|
|
58968
|
+
}
|
|
58969
|
+
size = maxBytes;
|
|
58970
|
+
truncated = true;
|
|
58971
|
+
return false;
|
|
58972
|
+
}
|
|
58973
|
+
parts.push(s);
|
|
58974
|
+
fields++;
|
|
58975
|
+
size += s.length + 1;
|
|
58976
|
+
return true;
|
|
58977
|
+
};
|
|
58978
|
+
const walk = (v, depth) => {
|
|
58979
|
+
if (typeof v === "string") return push(v);
|
|
58980
|
+
if (depth >= MAX_DEPTH3 || v === null || typeof v !== "object") return true;
|
|
58981
|
+
const children = Array.isArray(v) ? v : Object.values(v);
|
|
58982
|
+
for (const child of children) if (!walk(child, depth + 1)) return false;
|
|
58983
|
+
return true;
|
|
58984
|
+
};
|
|
58985
|
+
walk(toolResponse, 0);
|
|
58986
|
+
return { text: parts.join("\n"), truncated, fields };
|
|
58987
|
+
}
|
|
58988
|
+
function shellOutputText(toolResponse) {
|
|
58989
|
+
if (toolResponse && typeof toolResponse === "object" && !Array.isArray(toolResponse)) {
|
|
58990
|
+
const r = toolResponse;
|
|
58991
|
+
if (typeof r.stdout === "string" || typeof r.stderr === "string") {
|
|
58992
|
+
return [r.stdout, r.stderr].filter((s) => typeof s === "string").join("\n");
|
|
58993
|
+
}
|
|
58994
|
+
}
|
|
58995
|
+
return collectToolOutputText(toolResponse).text;
|
|
58996
|
+
}
|
|
58997
|
+
|
|
58938
58998
|
// src/cli/commands/log.ts
|
|
58939
58999
|
init_hasher();
|
|
58940
59000
|
|
|
@@ -59080,7 +59140,7 @@ function registerLogCommand(program2) {
|
|
|
59080
59140
|
}
|
|
59081
59141
|
if ((tool === "Bash" || tool === "bash") && isDaemonRunning()) {
|
|
59082
59142
|
const bashCommand = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
|
|
59083
|
-
const output = payload.tool_response
|
|
59143
|
+
const output = shellOutputText(payload.tool_response);
|
|
59084
59144
|
if (bashCommand && output) {
|
|
59085
59145
|
const testResult = detectTestResult(bashCommand, output);
|
|
59086
59146
|
if (testResult) {
|
|
@@ -59132,10 +59192,24 @@ function registerLogCommand(program2) {
|
|
|
59132
59192
|
}
|
|
59133
59193
|
}
|
|
59134
59194
|
{
|
|
59135
|
-
const
|
|
59195
|
+
const rawResponse = payload.tool_response;
|
|
59196
|
+
const shimOutput = rawResponse && typeof rawResponse === "object" && typeof rawResponse.output === "string" ? rawResponse.output : void 0;
|
|
59197
|
+
const collected = redactOutputMode ? {
|
|
59198
|
+
text: shimOutput ?? collectToolOutputText(rawResponse, { maxBytes: Number.MAX_SAFE_INTEGER }).text,
|
|
59199
|
+
truncated: false
|
|
59200
|
+
} : collectToolOutputText(rawResponse);
|
|
59201
|
+
const toolOutput = collected.text;
|
|
59202
|
+
if (collected.truncated) {
|
|
59203
|
+
appendToLog(HOOK_DEBUG_LOG, {
|
|
59204
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
59205
|
+
event: "post-tool-scan-truncated",
|
|
59206
|
+
tool,
|
|
59207
|
+
scannedBytes: toolOutput.length
|
|
59208
|
+
});
|
|
59209
|
+
}
|
|
59136
59210
|
const inj = config.policy.injectionScan;
|
|
59137
59211
|
const injectionOn = inj.enabled && !inj.allow.includes(tool);
|
|
59138
|
-
if (
|
|
59212
|
+
if (toolOutput.length > 0) {
|
|
59139
59213
|
if (redactOutputMode) {
|
|
59140
59214
|
const { result, found } = redactText(toolOutput);
|
|
59141
59215
|
let out = result;
|
|
@@ -59196,7 +59270,7 @@ function registerLogCommand(program2) {
|
|
|
59196
59270
|
} catch {
|
|
59197
59271
|
}
|
|
59198
59272
|
}
|
|
59199
|
-
process.exit(0);
|
|
59273
|
+
process.stdout.write("", () => process.exit(0));
|
|
59200
59274
|
};
|
|
59201
59275
|
if (data) {
|
|
59202
59276
|
await logPayload(data);
|
|
@@ -70739,7 +70813,7 @@ program.command("explain").description(
|
|
|
70739
70813
|
'Machine-readable output (one JSON document; no "decision" field means failure)'
|
|
70740
70814
|
).action(async (tool, argsRaw, opts) => {
|
|
70741
70815
|
const failJson = (message) => {
|
|
70742
|
-
console.log(
|
|
70816
|
+
console.log(toSafeJson(buildExplainJsonError(message)));
|
|
70743
70817
|
process.exit(1);
|
|
70744
70818
|
};
|
|
70745
70819
|
let args = {};
|
|
@@ -70751,7 +70825,7 @@ program.command("explain").description(
|
|
|
70751
70825
|
} catch {
|
|
70752
70826
|
if (opts.json) failJson("Invalid JSON in [args]");
|
|
70753
70827
|
console.error(import_chalk47.default.red(`
|
|
70754
|
-
\u274C Invalid JSON: ${
|
|
70828
|
+
\u274C Invalid JSON: ${displaySafe(trimmed)}
|
|
70755
70829
|
`));
|
|
70756
70830
|
process.exit(1);
|
|
70757
70831
|
}
|
|
@@ -70767,7 +70841,7 @@ program.command("explain").description(
|
|
|
70767
70841
|
throw err2;
|
|
70768
70842
|
}
|
|
70769
70843
|
if (opts.json) {
|
|
70770
|
-
console.log(
|
|
70844
|
+
console.log(toSafeJson(buildExplainJson(result, argsRaw)));
|
|
70771
70845
|
return;
|
|
70772
70846
|
}
|
|
70773
70847
|
console.log("");
|
|
@@ -70781,16 +70855,17 @@ program.command("explain").description(
|
|
|
70781
70855
|
console.log(import_chalk47.default.bold("Config Sources (Waterfall):"));
|
|
70782
70856
|
for (const tier of result.waterfall) {
|
|
70783
70857
|
const num3 = import_chalk47.default.gray(` ${tier.tier}.`);
|
|
70784
|
-
const label3 = tier.label.padEnd(16);
|
|
70858
|
+
const label3 = displaySafe(tier.label).padEnd(16);
|
|
70859
|
+
const tierNote = tier.note === void 0 ? void 0 : displaySafe(tier.note);
|
|
70785
70860
|
let statusStr;
|
|
70786
70861
|
if (tier.tier === 1) {
|
|
70787
|
-
statusStr = import_chalk47.default.gray(
|
|
70862
|
+
statusStr = import_chalk47.default.gray(tierNote ?? "");
|
|
70788
70863
|
} else if (tier.status === "active") {
|
|
70789
|
-
const loc = tier.path ? import_chalk47.default.gray(tier.path) : "";
|
|
70790
|
-
const note =
|
|
70864
|
+
const loc = tier.path ? import_chalk47.default.gray(displaySafe(tier.path)) : "";
|
|
70865
|
+
const note = tierNote ? import_chalk47.default.gray(`(${tierNote})`) : "";
|
|
70791
70866
|
statusStr = import_chalk47.default.green("\u2713 active") + (loc ? " " + loc : "") + (note ? " " + note : "");
|
|
70792
70867
|
} else {
|
|
70793
|
-
statusStr = import_chalk47.default.gray("\u25CB " + (
|
|
70868
|
+
statusStr = import_chalk47.default.gray("\u25CB " + (tierNote ?? "not found"));
|
|
70794
70869
|
}
|
|
70795
70870
|
console.log(`${num3} ${import_chalk47.default.white(label3)} ${statusStr}`);
|
|
70796
70871
|
}
|
package/dist/cli.mjs
CHANGED
|
@@ -57968,15 +57968,25 @@ var VISIBLE_ESCAPES = {
|
|
|
57968
57968
|
function toVisibleEscape(c) {
|
|
57969
57969
|
return VISIBLE_ESCAPES[c] ?? `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`;
|
|
57970
57970
|
}
|
|
57971
|
+
var redact = (s) => redactText(s).result;
|
|
57972
|
+
var escapeUnsafe = (s) => s.replace(UNSAFE_CHARS, toVisibleEscape);
|
|
57971
57973
|
function displaySafe(text) {
|
|
57972
|
-
return
|
|
57974
|
+
return escapeUnsafe(redact(text));
|
|
57973
57975
|
}
|
|
57974
57976
|
var INPUT_PREVIEW_MAX = 80;
|
|
57975
57977
|
function inputPreview(raw) {
|
|
57976
|
-
const
|
|
57977
|
-
|
|
57978
|
+
const redacted = redact(raw);
|
|
57979
|
+
const points = Array.from(redacted);
|
|
57980
|
+
const cut = points.length > INPUT_PREVIEW_MAX ? points.slice(0, INPUT_PREVIEW_MAX - 3).join("") + "\u2026" : redacted;
|
|
57981
|
+
return escapeUnsafe(cut);
|
|
57982
|
+
}
|
|
57983
|
+
var JSON_RAW_UNSAFE = /[\u007f-\u009f\u061c\u200e\u200f\u2028\u2029\u202a-\u202e\u2066-\u2069]/g;
|
|
57984
|
+
function toSafeJson(doc) {
|
|
57985
|
+
return JSON.stringify(doc, null, 2).replace(
|
|
57986
|
+
JSON_RAW_UNSAFE,
|
|
57987
|
+
(c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`
|
|
57988
|
+
);
|
|
57978
57989
|
}
|
|
57979
|
-
var redact = (s) => redactText(s).result;
|
|
57980
57990
|
function buildExplainJson(result, rawInput) {
|
|
57981
57991
|
return {
|
|
57982
57992
|
schemaVersion: 1,
|
|
@@ -57991,7 +58001,11 @@ function buildExplainJson(result, rawInput) {
|
|
|
57991
58001
|
detail: redact(s.detail),
|
|
57992
58002
|
final: s.isFinal === true
|
|
57993
58003
|
})),
|
|
57994
|
-
waterfall: result.waterfall
|
|
58004
|
+
waterfall: result.waterfall.map((t) => ({
|
|
58005
|
+
...t,
|
|
58006
|
+
...t.path !== void 0 && { path: redact(t.path) },
|
|
58007
|
+
...t.note !== void 0 && { note: redact(t.note) }
|
|
58008
|
+
}))
|
|
57995
58009
|
};
|
|
57996
58010
|
}
|
|
57997
58011
|
function buildExplainJsonError(message) {
|
|
@@ -58917,6 +58931,52 @@ ${neutralizeMarkers(text)}
|
|
|
58917
58931
|
${f.footer}`;
|
|
58918
58932
|
}
|
|
58919
58933
|
|
|
58934
|
+
// src/tool-output.ts
|
|
58935
|
+
init_dlp();
|
|
58936
|
+
var MAX_DEPTH3 = 8;
|
|
58937
|
+
function collectToolOutputText(toolResponse, opts = {}) {
|
|
58938
|
+
const maxBytes = opts.maxBytes ?? DLP_SCAN_LIMITS.maxStringBytes;
|
|
58939
|
+
const parts = [];
|
|
58940
|
+
let size = 0;
|
|
58941
|
+
let fields = 0;
|
|
58942
|
+
let truncated = false;
|
|
58943
|
+
const push = (s) => {
|
|
58944
|
+
if (s.length === 0) return true;
|
|
58945
|
+
const room = maxBytes - size;
|
|
58946
|
+
if (s.length > room) {
|
|
58947
|
+
if (room > 0) {
|
|
58948
|
+
parts.push(s.slice(0, room));
|
|
58949
|
+
fields++;
|
|
58950
|
+
}
|
|
58951
|
+
size = maxBytes;
|
|
58952
|
+
truncated = true;
|
|
58953
|
+
return false;
|
|
58954
|
+
}
|
|
58955
|
+
parts.push(s);
|
|
58956
|
+
fields++;
|
|
58957
|
+
size += s.length + 1;
|
|
58958
|
+
return true;
|
|
58959
|
+
};
|
|
58960
|
+
const walk = (v, depth) => {
|
|
58961
|
+
if (typeof v === "string") return push(v);
|
|
58962
|
+
if (depth >= MAX_DEPTH3 || v === null || typeof v !== "object") return true;
|
|
58963
|
+
const children = Array.isArray(v) ? v : Object.values(v);
|
|
58964
|
+
for (const child of children) if (!walk(child, depth + 1)) return false;
|
|
58965
|
+
return true;
|
|
58966
|
+
};
|
|
58967
|
+
walk(toolResponse, 0);
|
|
58968
|
+
return { text: parts.join("\n"), truncated, fields };
|
|
58969
|
+
}
|
|
58970
|
+
function shellOutputText(toolResponse) {
|
|
58971
|
+
if (toolResponse && typeof toolResponse === "object" && !Array.isArray(toolResponse)) {
|
|
58972
|
+
const r = toolResponse;
|
|
58973
|
+
if (typeof r.stdout === "string" || typeof r.stderr === "string") {
|
|
58974
|
+
return [r.stdout, r.stderr].filter((s) => typeof s === "string").join("\n");
|
|
58975
|
+
}
|
|
58976
|
+
}
|
|
58977
|
+
return collectToolOutputText(toolResponse).text;
|
|
58978
|
+
}
|
|
58979
|
+
|
|
58920
58980
|
// src/cli/commands/log.ts
|
|
58921
58981
|
init_hasher();
|
|
58922
58982
|
|
|
@@ -59062,7 +59122,7 @@ function registerLogCommand(program2) {
|
|
|
59062
59122
|
}
|
|
59063
59123
|
if ((tool === "Bash" || tool === "bash") && isDaemonRunning()) {
|
|
59064
59124
|
const bashCommand = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
|
|
59065
|
-
const output = payload.tool_response
|
|
59125
|
+
const output = shellOutputText(payload.tool_response);
|
|
59066
59126
|
if (bashCommand && output) {
|
|
59067
59127
|
const testResult = detectTestResult(bashCommand, output);
|
|
59068
59128
|
if (testResult) {
|
|
@@ -59114,10 +59174,24 @@ function registerLogCommand(program2) {
|
|
|
59114
59174
|
}
|
|
59115
59175
|
}
|
|
59116
59176
|
{
|
|
59117
|
-
const
|
|
59177
|
+
const rawResponse = payload.tool_response;
|
|
59178
|
+
const shimOutput = rawResponse && typeof rawResponse === "object" && typeof rawResponse.output === "string" ? rawResponse.output : void 0;
|
|
59179
|
+
const collected = redactOutputMode ? {
|
|
59180
|
+
text: shimOutput ?? collectToolOutputText(rawResponse, { maxBytes: Number.MAX_SAFE_INTEGER }).text,
|
|
59181
|
+
truncated: false
|
|
59182
|
+
} : collectToolOutputText(rawResponse);
|
|
59183
|
+
const toolOutput = collected.text;
|
|
59184
|
+
if (collected.truncated) {
|
|
59185
|
+
appendToLog(HOOK_DEBUG_LOG, {
|
|
59186
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
59187
|
+
event: "post-tool-scan-truncated",
|
|
59188
|
+
tool,
|
|
59189
|
+
scannedBytes: toolOutput.length
|
|
59190
|
+
});
|
|
59191
|
+
}
|
|
59118
59192
|
const inj = config.policy.injectionScan;
|
|
59119
59193
|
const injectionOn = inj.enabled && !inj.allow.includes(tool);
|
|
59120
|
-
if (
|
|
59194
|
+
if (toolOutput.length > 0) {
|
|
59121
59195
|
if (redactOutputMode) {
|
|
59122
59196
|
const { result, found } = redactText(toolOutput);
|
|
59123
59197
|
let out = result;
|
|
@@ -59178,7 +59252,7 @@ function registerLogCommand(program2) {
|
|
|
59178
59252
|
} catch {
|
|
59179
59253
|
}
|
|
59180
59254
|
}
|
|
59181
|
-
process.exit(0);
|
|
59255
|
+
process.stdout.write("", () => process.exit(0));
|
|
59182
59256
|
};
|
|
59183
59257
|
if (data) {
|
|
59184
59258
|
await logPayload(data);
|
|
@@ -70721,7 +70795,7 @@ program.command("explain").description(
|
|
|
70721
70795
|
'Machine-readable output (one JSON document; no "decision" field means failure)'
|
|
70722
70796
|
).action(async (tool, argsRaw, opts) => {
|
|
70723
70797
|
const failJson = (message) => {
|
|
70724
|
-
console.log(
|
|
70798
|
+
console.log(toSafeJson(buildExplainJsonError(message)));
|
|
70725
70799
|
process.exit(1);
|
|
70726
70800
|
};
|
|
70727
70801
|
let args = {};
|
|
@@ -70733,7 +70807,7 @@ program.command("explain").description(
|
|
|
70733
70807
|
} catch {
|
|
70734
70808
|
if (opts.json) failJson("Invalid JSON in [args]");
|
|
70735
70809
|
console.error(chalk47.red(`
|
|
70736
|
-
\u274C Invalid JSON: ${
|
|
70810
|
+
\u274C Invalid JSON: ${displaySafe(trimmed)}
|
|
70737
70811
|
`));
|
|
70738
70812
|
process.exit(1);
|
|
70739
70813
|
}
|
|
@@ -70749,7 +70823,7 @@ program.command("explain").description(
|
|
|
70749
70823
|
throw err2;
|
|
70750
70824
|
}
|
|
70751
70825
|
if (opts.json) {
|
|
70752
|
-
console.log(
|
|
70826
|
+
console.log(toSafeJson(buildExplainJson(result, argsRaw)));
|
|
70753
70827
|
return;
|
|
70754
70828
|
}
|
|
70755
70829
|
console.log("");
|
|
@@ -70763,16 +70837,17 @@ program.command("explain").description(
|
|
|
70763
70837
|
console.log(chalk47.bold("Config Sources (Waterfall):"));
|
|
70764
70838
|
for (const tier of result.waterfall) {
|
|
70765
70839
|
const num3 = chalk47.gray(` ${tier.tier}.`);
|
|
70766
|
-
const label3 = tier.label.padEnd(16);
|
|
70840
|
+
const label3 = displaySafe(tier.label).padEnd(16);
|
|
70841
|
+
const tierNote = tier.note === void 0 ? void 0 : displaySafe(tier.note);
|
|
70767
70842
|
let statusStr;
|
|
70768
70843
|
if (tier.tier === 1) {
|
|
70769
|
-
statusStr = chalk47.gray(
|
|
70844
|
+
statusStr = chalk47.gray(tierNote ?? "");
|
|
70770
70845
|
} else if (tier.status === "active") {
|
|
70771
|
-
const loc = tier.path ? chalk47.gray(tier.path) : "";
|
|
70772
|
-
const note =
|
|
70846
|
+
const loc = tier.path ? chalk47.gray(displaySafe(tier.path)) : "";
|
|
70847
|
+
const note = tierNote ? chalk47.gray(`(${tierNote})`) : "";
|
|
70773
70848
|
statusStr = chalk47.green("\u2713 active") + (loc ? " " + loc : "") + (note ? " " + note : "");
|
|
70774
70849
|
} else {
|
|
70775
|
-
statusStr = chalk47.gray("\u25CB " + (
|
|
70850
|
+
statusStr = chalk47.gray("\u25CB " + (tierNote ?? "not found"));
|
|
70776
70851
|
}
|
|
70777
70852
|
console.log(`${num3} ${chalk47.white(label3)} ${statusStr}`);
|
|
70778
70853
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node9/proxy",
|
|
3
|
-
"version": "2.28.
|
|
3
|
+
"version": "2.28.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",
|