@node9/proxy 1.41.0 → 1.43.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.
- package/README.md +17 -0
- package/dist/cli.js +100 -2
- package/dist/cli.mjs +100 -2
- package/dist/dashboard.mjs +4 -0
- package/dist/index.js +5 -0
- package/dist/index.mjs +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -141,6 +141,23 @@ node9 shield list # show all shields + status
|
|
|
141
141
|
- **Auto-undo** — git snapshot before every AI file edit → `node9 undo` to revert
|
|
142
142
|
- **Skills pinning** — SHA-256 verification of installed Claude skills / plugins between sessions
|
|
143
143
|
|
|
144
|
+
## Review prompts — approve inline, in your agent
|
|
145
|
+
|
|
146
|
+
When node9 flags an action for **review** (e.g. `git push --force`, a `DROP TABLE`), the approve/deny prompt renders **inline in the agent conversation** — no frozen session, no separate terminal, no hook-timeout race. node9 still runs the full evaluator and makes the decision; only the prompt _surface_ moves to the agent.
|
|
147
|
+
|
|
148
|
+
- **On by default** for **Claude Code** and **GitHub Copilot CLI** — the agents whose hook contract honors a native `ask`. Every other agent (Codex, Gemini, Antigravity, Hermes, Cursor, OpenCode, Pi) uses node9's own approver.
|
|
149
|
+
- **Control it** with `reviewChannel` in `~/.node9/config.json` (or `--no-ask` on the hook):
|
|
150
|
+
|
|
151
|
+
```jsonc
|
|
152
|
+
{
|
|
153
|
+
"settings": {
|
|
154
|
+
"reviewChannel": "ask", // "ask" = inline agent prompt (default) | "approver" = node9's own approver
|
|
155
|
+
},
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
- **Team setups:** when a cloud/team approver is configured (`approvers.cloud: true`), reviews route to that approver instead — node9 won't let an inline self-approval bypass routed/second-party approval.
|
|
160
|
+
|
|
144
161
|
## Sandbox — run an agent in a jail
|
|
145
162
|
|
|
146
163
|
When watching isn't enough, **`node9 sandbox`** runs the agent inside a disposable container with a **kernel-enforced egress allowlist** and **scoped mounts** — while node9's hooks govern and audit every tool call _inside_ the box. The hard version of protection: the agent can only touch the folder you mount and reach the hosts you allow; everything else is dropped at the kernel.
|
package/dist/cli.js
CHANGED
|
@@ -298,6 +298,10 @@ var init_config_schema = __esm({
|
|
|
298
298
|
// node9's own approver (terminal/native/cloud). Unset → smart default
|
|
299
299
|
// (ask for ask-capable agents unless a cloud approver is configured).
|
|
300
300
|
reviewChannel: import_zod.z.enum(["ask", "approver"]).optional(),
|
|
301
|
+
// When true, agents may call WEAKENING node9 MCP tools (shield_disable,
|
|
302
|
+
// approver_set). Default (unset/false): those tools refuse over MCP — a human
|
|
303
|
+
// must run them from the CLI. node9's threat model is the agent itself.
|
|
304
|
+
mcpAllowWeakening: import_zod.z.boolean().optional(),
|
|
301
305
|
cloudSyncIntervalHours: import_zod.z.number().positive().optional(),
|
|
302
306
|
// Outbox shipper (audit.log → SaaS batch ingest). enabled defaults
|
|
303
307
|
// to true; set false to fall back to local-only auditing.
|
|
@@ -4203,6 +4207,7 @@ function getConfig(cwd) {
|
|
|
4203
4207
|
mergedSettings.approvalTimeoutMs = s.approvalTimeoutSeconds * 1e3;
|
|
4204
4208
|
if (s.environment !== void 0) mergedSettings.environment = s.environment;
|
|
4205
4209
|
if (s.reviewChannel !== void 0) mergedSettings.reviewChannel = s.reviewChannel;
|
|
4210
|
+
if (s.mcpAllowWeakening !== void 0) mergedSettings.mcpAllowWeakening = s.mcpAllowWeakening;
|
|
4206
4211
|
if (s.cloudSyncIntervalHours !== void 0)
|
|
4207
4212
|
mergedSettings.cloudSyncIntervalHours = s.cloudSyncIntervalHours;
|
|
4208
4213
|
if (s.hud !== void 0) mergedSettings.hud = { ...mergedSettings.hud, ...s.hud };
|
|
@@ -23244,6 +23249,34 @@ function ok(id, result) {
|
|
|
23244
23249
|
function err(id, code, message) {
|
|
23245
23250
|
return JSON.stringify({ jsonrpc: "2.0", id: id ?? null, error: { code, message } });
|
|
23246
23251
|
}
|
|
23252
|
+
var TOOL_CAPABILITY = {
|
|
23253
|
+
// weaken — gated over MCP
|
|
23254
|
+
node9_shield_disable: "weaken",
|
|
23255
|
+
node9_approver_set: "weaken",
|
|
23256
|
+
// add / restorative — always allowed
|
|
23257
|
+
node9_shield_enable: "add",
|
|
23258
|
+
node9_rule_add: "add",
|
|
23259
|
+
// already block/review-only — handleRuleAdd rejects "allow"
|
|
23260
|
+
node9_undo_revert: "add",
|
|
23261
|
+
// restorative
|
|
23262
|
+
// readonly
|
|
23263
|
+
node9_status: "readonly",
|
|
23264
|
+
node9_config_get: "readonly",
|
|
23265
|
+
node9_policy_get: "readonly",
|
|
23266
|
+
node9_audit_get: "readonly",
|
|
23267
|
+
node9_session: "readonly",
|
|
23268
|
+
node9_scan: "readonly",
|
|
23269
|
+
node9_report: "readonly",
|
|
23270
|
+
node9_posture: "readonly",
|
|
23271
|
+
node9_explain: "readonly",
|
|
23272
|
+
node9_shield_list: "readonly",
|
|
23273
|
+
node9_approver_list: "readonly",
|
|
23274
|
+
node9_undo_list: "readonly",
|
|
23275
|
+
node9_undo_detail: "readonly"
|
|
23276
|
+
};
|
|
23277
|
+
function capabilityOf(tool) {
|
|
23278
|
+
return TOOL_CAPABILITY[tool] ?? "readonly";
|
|
23279
|
+
}
|
|
23247
23280
|
var TOOLS = [
|
|
23248
23281
|
{
|
|
23249
23282
|
name: "node9_status",
|
|
@@ -23276,7 +23309,7 @@ var TOOLS = [
|
|
|
23276
23309
|
},
|
|
23277
23310
|
{
|
|
23278
23311
|
name: "node9_shield_disable",
|
|
23279
|
-
description:
|
|
23312
|
+
description: 'Disable a node9 shield. WEAKENING action \u2014 refused over MCP by default (a human must run "node9 shield disable <name>" from the CLI). Use node9_shield_list to see active shields.',
|
|
23280
23313
|
inputSchema: {
|
|
23281
23314
|
type: "object",
|
|
23282
23315
|
properties: {
|
|
@@ -23295,7 +23328,7 @@ var TOOLS = [
|
|
|
23295
23328
|
},
|
|
23296
23329
|
{
|
|
23297
23330
|
name: "node9_approver_set",
|
|
23298
|
-
description: "Enable or disable a specific node9 approver channel in the global config (~/.node9/config.json). Use this to turn individual channels on or off without touching other settings. Channels: native, browser, cloud, terminal. WARNING: disabling all approvers means node9 cannot prompt for human approval \u2014 use with care.",
|
|
23331
|
+
description: "Enable or disable a specific node9 approver channel in the global config (~/.node9/config.json). Use this to turn individual channels on or off without touching other settings. Channels: native, browser, cloud, terminal. WEAKENING action \u2014 refused over MCP by default (a human must run it from the CLI). WARNING: disabling all approvers means node9 cannot prompt for human approval \u2014 use with care.",
|
|
23299
23332
|
inputSchema: {
|
|
23300
23333
|
type: "object",
|
|
23301
23334
|
properties: {
|
|
@@ -23429,6 +23462,38 @@ var TOOLS = [
|
|
|
23429
23462
|
required: []
|
|
23430
23463
|
}
|
|
23431
23464
|
},
|
|
23465
|
+
{
|
|
23466
|
+
name: "node9_posture",
|
|
23467
|
+
description: "Run the node9 security posture scorecard for the agent on this host \u2014 grades how exposed the machine is to a compromised agent across isolation, egress, secrets-on-disk, supply chain, and privilege, with the #1 risk and a concrete fix for each finding. Read-only.",
|
|
23468
|
+
inputSchema: {
|
|
23469
|
+
type: "object",
|
|
23470
|
+
properties: {
|
|
23471
|
+
agent: {
|
|
23472
|
+
type: "string",
|
|
23473
|
+
description: "Optional label / policy scope for the agent being graded."
|
|
23474
|
+
}
|
|
23475
|
+
},
|
|
23476
|
+
required: []
|
|
23477
|
+
}
|
|
23478
|
+
},
|
|
23479
|
+
{
|
|
23480
|
+
name: "node9_explain",
|
|
23481
|
+
description: 'Preview exactly how node9 would evaluate a tool call BEFORE running it \u2014 the full allow / review / block waterfall and step-by-step policy trace. Use this to self-check a command (e.g. "git push --force") and see whether it would be allowed, sent for human review, or blocked, and why. Read-only \u2014 nothing executes.',
|
|
23482
|
+
inputSchema: {
|
|
23483
|
+
type: "object",
|
|
23484
|
+
properties: {
|
|
23485
|
+
tool: {
|
|
23486
|
+
type: "string",
|
|
23487
|
+
description: 'Tool name to evaluate. Defaults to "bash" for plain shell commands.'
|
|
23488
|
+
},
|
|
23489
|
+
args: {
|
|
23490
|
+
type: "string",
|
|
23491
|
+
description: 'Tool arguments as JSON, or a plain shell command string (e.g. "git push --force").'
|
|
23492
|
+
}
|
|
23493
|
+
},
|
|
23494
|
+
required: []
|
|
23495
|
+
}
|
|
23496
|
+
},
|
|
23432
23497
|
{
|
|
23433
23498
|
name: "node9_rule_add",
|
|
23434
23499
|
description: 'Add a new protective smart rule to the global node9 config (~/.node9/config.json). Rules can block or send dangerous commands for human review based on regex conditions. IMPORTANT: only "block" and "review" verdicts are permitted \u2014 "allow" rules are never accepted because they would weaken node9 security. Rules can only be added, never removed.',
|
|
@@ -23735,6 +23800,17 @@ function handleSessionMcp(args) {
|
|
|
23735
23800
|
if (typeof args.detail === "string" && args.detail) cliArgs.push("--detail", args.detail);
|
|
23736
23801
|
return runCliCommand(cliArgs);
|
|
23737
23802
|
}
|
|
23803
|
+
function handlePostureMcp(args) {
|
|
23804
|
+
const cliArgs = ["posture"];
|
|
23805
|
+
if (typeof args.agent === "string" && args.agent) cliArgs.push("--agent", args.agent);
|
|
23806
|
+
return runCliCommand(cliArgs);
|
|
23807
|
+
}
|
|
23808
|
+
function handleExplainMcp(args) {
|
|
23809
|
+
const tool = typeof args.tool === "string" && args.tool ? args.tool : "bash";
|
|
23810
|
+
const cliArgs = ["explain", tool];
|
|
23811
|
+
if (typeof args.args === "string" && args.args) cliArgs.push(args.args);
|
|
23812
|
+
return runCliCommand(cliArgs);
|
|
23813
|
+
}
|
|
23738
23814
|
function handleUndoList(args) {
|
|
23739
23815
|
const cwdFilter = typeof args.cwd === "string" && args.cwd ? args.cwd : null;
|
|
23740
23816
|
let history = getSnapshotHistory();
|
|
@@ -23835,6 +23911,24 @@ function runMcpServer() {
|
|
|
23835
23911
|
const p = params ?? {};
|
|
23836
23912
|
const toolName = p.name;
|
|
23837
23913
|
const toolArgs = p.arguments ?? {};
|
|
23914
|
+
if (capabilityOf(toolName ?? "") === "weaken") {
|
|
23915
|
+
let allowed = false;
|
|
23916
|
+
try {
|
|
23917
|
+
allowed = getConfig().settings.mcpAllowWeakening === true;
|
|
23918
|
+
} catch {
|
|
23919
|
+
allowed = false;
|
|
23920
|
+
}
|
|
23921
|
+
if (!allowed) {
|
|
23922
|
+
process.stdout.write(
|
|
23923
|
+
err(
|
|
23924
|
+
id,
|
|
23925
|
+
-32e3,
|
|
23926
|
+
`${toolName} weakens node9 and is disabled over MCP. A human must run it from the CLI (e.g. "node9 shield disable <name>"), or set "mcpAllowWeakening": true in ~/.node9/config.json to allow agent-driven weakening.`
|
|
23927
|
+
) + "\n"
|
|
23928
|
+
);
|
|
23929
|
+
return;
|
|
23930
|
+
}
|
|
23931
|
+
}
|
|
23838
23932
|
try {
|
|
23839
23933
|
let text;
|
|
23840
23934
|
if (toolName === "node9_status") {
|
|
@@ -23869,6 +23963,10 @@ function runMcpServer() {
|
|
|
23869
23963
|
text = handleReportMcp(toolArgs);
|
|
23870
23964
|
} else if (toolName === "node9_session") {
|
|
23871
23965
|
text = handleSessionMcp(toolArgs);
|
|
23966
|
+
} else if (toolName === "node9_posture") {
|
|
23967
|
+
text = handlePostureMcp(toolArgs);
|
|
23968
|
+
} else if (toolName === "node9_explain") {
|
|
23969
|
+
text = handleExplainMcp(toolArgs);
|
|
23872
23970
|
} else {
|
|
23873
23971
|
process.stdout.write(err(id, -32601, `Unknown tool: ${toolName}`) + "\n");
|
|
23874
23972
|
return;
|
package/dist/cli.mjs
CHANGED
|
@@ -276,6 +276,10 @@ var init_config_schema = __esm({
|
|
|
276
276
|
// node9's own approver (terminal/native/cloud). Unset → smart default
|
|
277
277
|
// (ask for ask-capable agents unless a cloud approver is configured).
|
|
278
278
|
reviewChannel: z.enum(["ask", "approver"]).optional(),
|
|
279
|
+
// When true, agents may call WEAKENING node9 MCP tools (shield_disable,
|
|
280
|
+
// approver_set). Default (unset/false): those tools refuse over MCP — a human
|
|
281
|
+
// must run them from the CLI. node9's threat model is the agent itself.
|
|
282
|
+
mcpAllowWeakening: z.boolean().optional(),
|
|
279
283
|
cloudSyncIntervalHours: z.number().positive().optional(),
|
|
280
284
|
// Outbox shipper (audit.log → SaaS batch ingest). enabled defaults
|
|
281
285
|
// to true; set false to fall back to local-only auditing.
|
|
@@ -4184,6 +4188,7 @@ function getConfig(cwd) {
|
|
|
4184
4188
|
mergedSettings.approvalTimeoutMs = s.approvalTimeoutSeconds * 1e3;
|
|
4185
4189
|
if (s.environment !== void 0) mergedSettings.environment = s.environment;
|
|
4186
4190
|
if (s.reviewChannel !== void 0) mergedSettings.reviewChannel = s.reviewChannel;
|
|
4191
|
+
if (s.mcpAllowWeakening !== void 0) mergedSettings.mcpAllowWeakening = s.mcpAllowWeakening;
|
|
4187
4192
|
if (s.cloudSyncIntervalHours !== void 0)
|
|
4188
4193
|
mergedSettings.cloudSyncIntervalHours = s.cloudSyncIntervalHours;
|
|
4189
4194
|
if (s.hud !== void 0) mergedSettings.hud = { ...mergedSettings.hud, ...s.hud };
|
|
@@ -23216,6 +23221,34 @@ function ok(id, result) {
|
|
|
23216
23221
|
function err(id, code, message) {
|
|
23217
23222
|
return JSON.stringify({ jsonrpc: "2.0", id: id ?? null, error: { code, message } });
|
|
23218
23223
|
}
|
|
23224
|
+
var TOOL_CAPABILITY = {
|
|
23225
|
+
// weaken — gated over MCP
|
|
23226
|
+
node9_shield_disable: "weaken",
|
|
23227
|
+
node9_approver_set: "weaken",
|
|
23228
|
+
// add / restorative — always allowed
|
|
23229
|
+
node9_shield_enable: "add",
|
|
23230
|
+
node9_rule_add: "add",
|
|
23231
|
+
// already block/review-only — handleRuleAdd rejects "allow"
|
|
23232
|
+
node9_undo_revert: "add",
|
|
23233
|
+
// restorative
|
|
23234
|
+
// readonly
|
|
23235
|
+
node9_status: "readonly",
|
|
23236
|
+
node9_config_get: "readonly",
|
|
23237
|
+
node9_policy_get: "readonly",
|
|
23238
|
+
node9_audit_get: "readonly",
|
|
23239
|
+
node9_session: "readonly",
|
|
23240
|
+
node9_scan: "readonly",
|
|
23241
|
+
node9_report: "readonly",
|
|
23242
|
+
node9_posture: "readonly",
|
|
23243
|
+
node9_explain: "readonly",
|
|
23244
|
+
node9_shield_list: "readonly",
|
|
23245
|
+
node9_approver_list: "readonly",
|
|
23246
|
+
node9_undo_list: "readonly",
|
|
23247
|
+
node9_undo_detail: "readonly"
|
|
23248
|
+
};
|
|
23249
|
+
function capabilityOf(tool) {
|
|
23250
|
+
return TOOL_CAPABILITY[tool] ?? "readonly";
|
|
23251
|
+
}
|
|
23219
23252
|
var TOOLS = [
|
|
23220
23253
|
{
|
|
23221
23254
|
name: "node9_status",
|
|
@@ -23248,7 +23281,7 @@ var TOOLS = [
|
|
|
23248
23281
|
},
|
|
23249
23282
|
{
|
|
23250
23283
|
name: "node9_shield_disable",
|
|
23251
|
-
description:
|
|
23284
|
+
description: 'Disable a node9 shield. WEAKENING action \u2014 refused over MCP by default (a human must run "node9 shield disable <name>" from the CLI). Use node9_shield_list to see active shields.',
|
|
23252
23285
|
inputSchema: {
|
|
23253
23286
|
type: "object",
|
|
23254
23287
|
properties: {
|
|
@@ -23267,7 +23300,7 @@ var TOOLS = [
|
|
|
23267
23300
|
},
|
|
23268
23301
|
{
|
|
23269
23302
|
name: "node9_approver_set",
|
|
23270
|
-
description: "Enable or disable a specific node9 approver channel in the global config (~/.node9/config.json). Use this to turn individual channels on or off without touching other settings. Channels: native, browser, cloud, terminal. WARNING: disabling all approvers means node9 cannot prompt for human approval \u2014 use with care.",
|
|
23303
|
+
description: "Enable or disable a specific node9 approver channel in the global config (~/.node9/config.json). Use this to turn individual channels on or off without touching other settings. Channels: native, browser, cloud, terminal. WEAKENING action \u2014 refused over MCP by default (a human must run it from the CLI). WARNING: disabling all approvers means node9 cannot prompt for human approval \u2014 use with care.",
|
|
23271
23304
|
inputSchema: {
|
|
23272
23305
|
type: "object",
|
|
23273
23306
|
properties: {
|
|
@@ -23401,6 +23434,38 @@ var TOOLS = [
|
|
|
23401
23434
|
required: []
|
|
23402
23435
|
}
|
|
23403
23436
|
},
|
|
23437
|
+
{
|
|
23438
|
+
name: "node9_posture",
|
|
23439
|
+
description: "Run the node9 security posture scorecard for the agent on this host \u2014 grades how exposed the machine is to a compromised agent across isolation, egress, secrets-on-disk, supply chain, and privilege, with the #1 risk and a concrete fix for each finding. Read-only.",
|
|
23440
|
+
inputSchema: {
|
|
23441
|
+
type: "object",
|
|
23442
|
+
properties: {
|
|
23443
|
+
agent: {
|
|
23444
|
+
type: "string",
|
|
23445
|
+
description: "Optional label / policy scope for the agent being graded."
|
|
23446
|
+
}
|
|
23447
|
+
},
|
|
23448
|
+
required: []
|
|
23449
|
+
}
|
|
23450
|
+
},
|
|
23451
|
+
{
|
|
23452
|
+
name: "node9_explain",
|
|
23453
|
+
description: 'Preview exactly how node9 would evaluate a tool call BEFORE running it \u2014 the full allow / review / block waterfall and step-by-step policy trace. Use this to self-check a command (e.g. "git push --force") and see whether it would be allowed, sent for human review, or blocked, and why. Read-only \u2014 nothing executes.',
|
|
23454
|
+
inputSchema: {
|
|
23455
|
+
type: "object",
|
|
23456
|
+
properties: {
|
|
23457
|
+
tool: {
|
|
23458
|
+
type: "string",
|
|
23459
|
+
description: 'Tool name to evaluate. Defaults to "bash" for plain shell commands.'
|
|
23460
|
+
},
|
|
23461
|
+
args: {
|
|
23462
|
+
type: "string",
|
|
23463
|
+
description: 'Tool arguments as JSON, or a plain shell command string (e.g. "git push --force").'
|
|
23464
|
+
}
|
|
23465
|
+
},
|
|
23466
|
+
required: []
|
|
23467
|
+
}
|
|
23468
|
+
},
|
|
23404
23469
|
{
|
|
23405
23470
|
name: "node9_rule_add",
|
|
23406
23471
|
description: 'Add a new protective smart rule to the global node9 config (~/.node9/config.json). Rules can block or send dangerous commands for human review based on regex conditions. IMPORTANT: only "block" and "review" verdicts are permitted \u2014 "allow" rules are never accepted because they would weaken node9 security. Rules can only be added, never removed.',
|
|
@@ -23707,6 +23772,17 @@ function handleSessionMcp(args) {
|
|
|
23707
23772
|
if (typeof args.detail === "string" && args.detail) cliArgs.push("--detail", args.detail);
|
|
23708
23773
|
return runCliCommand(cliArgs);
|
|
23709
23774
|
}
|
|
23775
|
+
function handlePostureMcp(args) {
|
|
23776
|
+
const cliArgs = ["posture"];
|
|
23777
|
+
if (typeof args.agent === "string" && args.agent) cliArgs.push("--agent", args.agent);
|
|
23778
|
+
return runCliCommand(cliArgs);
|
|
23779
|
+
}
|
|
23780
|
+
function handleExplainMcp(args) {
|
|
23781
|
+
const tool = typeof args.tool === "string" && args.tool ? args.tool : "bash";
|
|
23782
|
+
const cliArgs = ["explain", tool];
|
|
23783
|
+
if (typeof args.args === "string" && args.args) cliArgs.push(args.args);
|
|
23784
|
+
return runCliCommand(cliArgs);
|
|
23785
|
+
}
|
|
23710
23786
|
function handleUndoList(args) {
|
|
23711
23787
|
const cwdFilter = typeof args.cwd === "string" && args.cwd ? args.cwd : null;
|
|
23712
23788
|
let history = getSnapshotHistory();
|
|
@@ -23807,6 +23883,24 @@ function runMcpServer() {
|
|
|
23807
23883
|
const p = params ?? {};
|
|
23808
23884
|
const toolName = p.name;
|
|
23809
23885
|
const toolArgs = p.arguments ?? {};
|
|
23886
|
+
if (capabilityOf(toolName ?? "") === "weaken") {
|
|
23887
|
+
let allowed = false;
|
|
23888
|
+
try {
|
|
23889
|
+
allowed = getConfig().settings.mcpAllowWeakening === true;
|
|
23890
|
+
} catch {
|
|
23891
|
+
allowed = false;
|
|
23892
|
+
}
|
|
23893
|
+
if (!allowed) {
|
|
23894
|
+
process.stdout.write(
|
|
23895
|
+
err(
|
|
23896
|
+
id,
|
|
23897
|
+
-32e3,
|
|
23898
|
+
`${toolName} weakens node9 and is disabled over MCP. A human must run it from the CLI (e.g. "node9 shield disable <name>"), or set "mcpAllowWeakening": true in ~/.node9/config.json to allow agent-driven weakening.`
|
|
23899
|
+
) + "\n"
|
|
23900
|
+
);
|
|
23901
|
+
return;
|
|
23902
|
+
}
|
|
23903
|
+
}
|
|
23810
23904
|
try {
|
|
23811
23905
|
let text;
|
|
23812
23906
|
if (toolName === "node9_status") {
|
|
@@ -23841,6 +23935,10 @@ function runMcpServer() {
|
|
|
23841
23935
|
text = handleReportMcp(toolArgs);
|
|
23842
23936
|
} else if (toolName === "node9_session") {
|
|
23843
23937
|
text = handleSessionMcp(toolArgs);
|
|
23938
|
+
} else if (toolName === "node9_posture") {
|
|
23939
|
+
text = handlePostureMcp(toolArgs);
|
|
23940
|
+
} else if (toolName === "node9_explain") {
|
|
23941
|
+
text = handleExplainMcp(toolArgs);
|
|
23844
23942
|
} else {
|
|
23845
23943
|
process.stdout.write(err(id, -32601, `Unknown tool: ${toolName}`) + "\n");
|
|
23846
23944
|
return;
|
package/dist/dashboard.mjs
CHANGED
|
@@ -2270,6 +2270,10 @@ var init_config_schema = __esm({
|
|
|
2270
2270
|
// node9's own approver (terminal/native/cloud). Unset → smart default
|
|
2271
2271
|
// (ask for ask-capable agents unless a cloud approver is configured).
|
|
2272
2272
|
reviewChannel: z.enum(["ask", "approver"]).optional(),
|
|
2273
|
+
// When true, agents may call WEAKENING node9 MCP tools (shield_disable,
|
|
2274
|
+
// approver_set). Default (unset/false): those tools refuse over MCP — a human
|
|
2275
|
+
// must run them from the CLI. node9's threat model is the agent itself.
|
|
2276
|
+
mcpAllowWeakening: z.boolean().optional(),
|
|
2273
2277
|
cloudSyncIntervalHours: z.number().positive().optional(),
|
|
2274
2278
|
// Outbox shipper (audit.log → SaaS batch ingest). enabled defaults
|
|
2275
2279
|
// to true; set false to fall back to local-only auditing.
|
package/dist/index.js
CHANGED
|
@@ -283,6 +283,10 @@ var ConfigFileSchema = import_zod.z.object({
|
|
|
283
283
|
// node9's own approver (terminal/native/cloud). Unset → smart default
|
|
284
284
|
// (ask for ask-capable agents unless a cloud approver is configured).
|
|
285
285
|
reviewChannel: import_zod.z.enum(["ask", "approver"]).optional(),
|
|
286
|
+
// When true, agents may call WEAKENING node9 MCP tools (shield_disable,
|
|
287
|
+
// approver_set). Default (unset/false): those tools refuse over MCP — a human
|
|
288
|
+
// must run them from the CLI. node9's threat model is the agent itself.
|
|
289
|
+
mcpAllowWeakening: import_zod.z.boolean().optional(),
|
|
286
290
|
cloudSyncIntervalHours: import_zod.z.number().positive().optional(),
|
|
287
291
|
// Outbox shipper (audit.log → SaaS batch ingest). enabled defaults
|
|
288
292
|
// to true; set false to fall back to local-only auditing.
|
|
@@ -3737,6 +3741,7 @@ function getConfig(cwd) {
|
|
|
3737
3741
|
mergedSettings.approvalTimeoutMs = s.approvalTimeoutSeconds * 1e3;
|
|
3738
3742
|
if (s.environment !== void 0) mergedSettings.environment = s.environment;
|
|
3739
3743
|
if (s.reviewChannel !== void 0) mergedSettings.reviewChannel = s.reviewChannel;
|
|
3744
|
+
if (s.mcpAllowWeakening !== void 0) mergedSettings.mcpAllowWeakening = s.mcpAllowWeakening;
|
|
3740
3745
|
if (s.cloudSyncIntervalHours !== void 0)
|
|
3741
3746
|
mergedSettings.cloudSyncIntervalHours = s.cloudSyncIntervalHours;
|
|
3742
3747
|
if (s.hud !== void 0) mergedSettings.hud = { ...mergedSettings.hud, ...s.hud };
|
package/dist/index.mjs
CHANGED
|
@@ -253,6 +253,10 @@ var ConfigFileSchema = z.object({
|
|
|
253
253
|
// node9's own approver (terminal/native/cloud). Unset → smart default
|
|
254
254
|
// (ask for ask-capable agents unless a cloud approver is configured).
|
|
255
255
|
reviewChannel: z.enum(["ask", "approver"]).optional(),
|
|
256
|
+
// When true, agents may call WEAKENING node9 MCP tools (shield_disable,
|
|
257
|
+
// approver_set). Default (unset/false): those tools refuse over MCP — a human
|
|
258
|
+
// must run them from the CLI. node9's threat model is the agent itself.
|
|
259
|
+
mcpAllowWeakening: z.boolean().optional(),
|
|
256
260
|
cloudSyncIntervalHours: z.number().positive().optional(),
|
|
257
261
|
// Outbox shipper (audit.log → SaaS batch ingest). enabled defaults
|
|
258
262
|
// to true; set false to fall back to local-only auditing.
|
|
@@ -3707,6 +3711,7 @@ function getConfig(cwd) {
|
|
|
3707
3711
|
mergedSettings.approvalTimeoutMs = s.approvalTimeoutSeconds * 1e3;
|
|
3708
3712
|
if (s.environment !== void 0) mergedSettings.environment = s.environment;
|
|
3709
3713
|
if (s.reviewChannel !== void 0) mergedSettings.reviewChannel = s.reviewChannel;
|
|
3714
|
+
if (s.mcpAllowWeakening !== void 0) mergedSettings.mcpAllowWeakening = s.mcpAllowWeakening;
|
|
3710
3715
|
if (s.cloudSyncIntervalHours !== void 0)
|
|
3711
3716
|
mergedSettings.cloudSyncIntervalHours = s.cloudSyncIntervalHours;
|
|
3712
3717
|
if (s.hud !== void 0) mergedSettings.hud = { ...mergedSettings.hud, ...s.hud };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node9/proxy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.43.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",
|