@node9/proxy 1.55.1 → 1.56.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.
@@ -547,9 +547,9 @@ function matchesPattern(text, patterns) {
547
547
  const withoutDotSlash = text.replace(/^\.\//, "");
548
548
  return isMatch(withoutDotSlash) || isMatch(`./${withoutDotSlash}`);
549
549
  }
550
- function getNestedValue(obj, path10) {
550
+ function getNestedValue(obj, path11) {
551
551
  if (!obj || typeof obj !== "object") return null;
552
- const segments = path10.split(".");
552
+ const segments = path11.split(".");
553
553
  for (const seg of segments) {
554
554
  if (FORBIDDEN_PATH_SEGMENTS.has(seg)) return null;
555
555
  }
@@ -2279,6 +2279,10 @@ var init_config_schema = __esm({
2279
2279
  // approver_set). Default (unset/false): those tools refuse over MCP — a human
2280
2280
  // must run them from the CLI. node9's threat model is the agent itself.
2281
2281
  mcpAllowWeakening: z.boolean().optional(),
2282
+ // Auto-wire reconciler (P3 2.6): auto-wrap new ungoverned MCP servers vs
2283
+ // nudge-only (default), and the scan cadence in minutes.
2284
+ mcpAutoWrap: z.boolean().optional(),
2285
+ mcpReconcileIntervalMinutes: z.number().positive().optional(),
2282
2286
  cloudSyncIntervalHours: z.number().positive().optional(),
2283
2287
  // Seconds-granular override for the cloud policy sync cadence. Wins over
2284
2288
  // cloudSyncIntervalHours when set. Lets you opt into fast apply (e.g. 20)
@@ -2419,6 +2423,20 @@ var init_managed = __esm({
2419
2423
  }
2420
2424
  });
2421
2425
 
2426
+ // src/shields/build.ts
2427
+ var init_build = __esm({
2428
+ "src/shields/build.ts"() {
2429
+ "use strict";
2430
+ }
2431
+ });
2432
+
2433
+ // src/auth/trusted-hosts.ts
2434
+ var init_trusted_hosts = __esm({
2435
+ "src/auth/trusted-hosts.ts"() {
2436
+ "use strict";
2437
+ }
2438
+ });
2439
+
2422
2440
  // src/config/index.ts
2423
2441
  var DANGEROUS_WORDS, DEFAULT_CONFIG;
2424
2442
  var init_config = __esm({
@@ -2427,6 +2445,8 @@ var init_config = __esm({
2427
2445
  init_config_schema();
2428
2446
  init_shields();
2429
2447
  init_managed();
2448
+ init_build();
2449
+ init_trusted_hosts();
2430
2450
  DANGEROUS_WORDS = [
2431
2451
  "mkfs",
2432
2452
  // formats/wipes a filesystem partition
@@ -2635,7 +2655,10 @@ var init_config = __esm({
2635
2655
  egress: { enabled: false, mode: "review", allow: [], deny: [], allowPrivate: true },
2636
2656
  loopDetection: { enabled: true, threshold: 5, windowSeconds: 120 },
2637
2657
  injectionScan: { enabled: false, minConfidence: "medium", allow: [] },
2638
- skillPinning: { enabled: false, mode: "warn", roots: [] }
2658
+ skillPinning: { enabled: false, mode: "warn", roots: [] },
2659
+ trustedHosts: [],
2660
+ trustedHostsManaged: false,
2661
+ appPermissions: {}
2639
2662
  },
2640
2663
  environments: {}
2641
2664
  };
@@ -3624,13 +3647,6 @@ var init_provenance = __esm({
3624
3647
  }
3625
3648
  });
3626
3649
 
3627
- // src/auth/trusted-hosts.ts
3628
- var init_trusted_hosts = __esm({
3629
- "src/auth/trusted-hosts.ts"() {
3630
- "use strict";
3631
- }
3632
- });
3633
-
3634
3650
  // src/policy/index.ts
3635
3651
  import pm2 from "picomatch";
3636
3652
  var init_policy = __esm({
@@ -3669,6 +3685,18 @@ var init_mcp_pin = __esm({
3669
3685
  }
3670
3686
  });
3671
3687
 
3688
+ // src/daemon/hook-baseline.ts
3689
+ import path8 from "path";
3690
+ import os8 from "os";
3691
+ var BASELINE_FILE, NOTIFIED_FILE;
3692
+ var init_hook_baseline = __esm({
3693
+ "src/daemon/hook-baseline.ts"() {
3694
+ "use strict";
3695
+ BASELINE_FILE = path8.join(os8.homedir(), ".node9", "hooks-baseline.json");
3696
+ NOTIFIED_FILE = path8.join(os8.homedir(), ".node9", "hook-heal-notified.json");
3697
+ }
3698
+ });
3699
+
3672
3700
  // src/setup-opencode-shim.ts
3673
3701
  var init_setup_opencode_shim = __esm({
3674
3702
  "src/setup-opencode-shim.ts"() {
@@ -3692,6 +3720,7 @@ var init_setup = __esm({
3692
3720
  "src/setup.ts"() {
3693
3721
  "use strict";
3694
3722
  init_mcp_pin();
3723
+ init_hook_baseline();
3695
3724
  init_setup_opencode_shim();
3696
3725
  init_setup_pi_shim();
3697
3726
  }
@@ -3724,8 +3753,8 @@ var init_scan_history = __esm({
3724
3753
  // src/cli/commands/scan.ts
3725
3754
  import chalk4 from "chalk";
3726
3755
  import fs6 from "fs";
3727
- import path8 from "path";
3728
- import os8 from "os";
3756
+ import path9 from "path";
3757
+ import os9 from "os";
3729
3758
  import stringWidth2 from "string-width";
3730
3759
  function claudeModelPrice2(model) {
3731
3760
  const t = pricingFor(model);
@@ -3874,7 +3903,7 @@ function processClaudeFile(file, projPath, projLabel, ruleSources, startDate, re
3874
3903
  const sessionId = file.replace(/\.jsonl$/, "");
3875
3904
  let raw;
3876
3905
  try {
3877
- raw = fs6.readFileSync(path8.join(projPath, file), "utf-8");
3906
+ raw = fs6.readFileSync(path9.join(projPath, file), "utf-8");
3878
3907
  } catch {
3879
3908
  return;
3880
3909
  }
@@ -3926,7 +3955,7 @@ function processClaudeFile(file, projPath, projLabel, ruleSources, startDate, re
3926
3955
  if (block.type !== "tool_result") continue;
3927
3956
  const filePath = block.tool_use_id ? toolUseFilePaths.get(block.tool_use_id) : void 0;
3928
3957
  if (filePath) {
3929
- const ext = path8.extname(filePath).toLowerCase();
3958
+ const ext = path9.extname(filePath).toLowerCase();
3930
3959
  if (CODE_EXTENSIONS.has(ext)) continue;
3931
3960
  }
3932
3961
  const resultText = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map((c) => c.text ?? "").join("\n") : null;
@@ -3983,7 +4012,7 @@ function processClaudeFile(file, projPath, projLabel, ruleSources, startDate, re
3983
4012
  const rawCmd = String(input.command ?? "").trimStart();
3984
4013
  if (/^node9\s+(scan|explain|report|tail|dlp|status|sessions|audit)\b/.test(rawCmd)) continue;
3985
4014
  const inputFilePath = typeof input.file_path === "string" ? input.file_path : "";
3986
- const inputFileExt = inputFilePath ? path8.extname(inputFilePath).toLowerCase() : "";
4015
+ const inputFileExt = inputFilePath ? path9.extname(inputFilePath).toLowerCase() : "";
3987
4016
  if (CODE_EXTENSIONS.has(inputFileExt)) continue;
3988
4017
  const dlpMatch = scanArgs(input);
3989
4018
  if (dlpMatch) {
@@ -4080,13 +4109,13 @@ function processClaudeFile(file, projPath, projLabel, ruleSources, startDate, re
4080
4109
  }
4081
4110
  }
4082
4111
  async function processClaudeProjectAsync(proj, projectsDir, ruleSources, startDate, result, dedup, onProgress, onLine) {
4083
- const projPath = path8.join(projectsDir, proj);
4112
+ const projPath = path9.join(projectsDir, proj);
4084
4113
  try {
4085
4114
  if (!fs6.statSync(projPath).isDirectory()) return;
4086
4115
  } catch {
4087
4116
  return;
4088
4117
  }
4089
- const projLabel = stripTerminalEscapes(decodeURIComponent(proj).replace(os8.homedir(), "~")).slice(
4118
+ const projLabel = stripTerminalEscapes(decodeURIComponent(proj).replace(os9.homedir(), "~")).slice(
4090
4119
  0,
4091
4120
  40
4092
4121
  );
@@ -4130,7 +4159,7 @@ function emptyClaudeScan() {
4130
4159
  };
4131
4160
  }
4132
4161
  async function scanClaudeHistoryAsync(startDate, onProgress, onLine) {
4133
- const projectsDir = path8.join(os8.homedir(), ".claude", "projects");
4162
+ const projectsDir = path9.join(os9.homedir(), ".claude", "projects");
4134
4163
  const result = emptyClaudeScan();
4135
4164
  if (!fs6.existsSync(projectsDir)) return result;
4136
4165
  let projDirs;
@@ -4156,7 +4185,7 @@ async function scanClaudeHistoryAsync(startDate, onProgress, onLine) {
4156
4185
  return result;
4157
4186
  }
4158
4187
  function scanGeminiHistory(startDate, onProgress, onLine) {
4159
- const tmpDir = path8.join(os8.homedir(), ".gemini", "tmp");
4188
+ const tmpDir = path9.join(os9.homedir(), ".gemini", "tmp");
4160
4189
  const result = {
4161
4190
  filesScanned: 0,
4162
4191
  sessions: 0,
@@ -4180,7 +4209,7 @@ function scanGeminiHistory(startDate, onProgress, onLine) {
4180
4209
  }
4181
4210
  const ruleSources = buildRuleSources();
4182
4211
  for (const slug of slugDirs) {
4183
- const slugPath = path8.join(tmpDir, slug);
4212
+ const slugPath = path9.join(tmpDir, slug);
4184
4213
  try {
4185
4214
  if (!fs6.statSync(slugPath).isDirectory()) continue;
4186
4215
  } catch {
@@ -4189,11 +4218,11 @@ function scanGeminiHistory(startDate, onProgress, onLine) {
4189
4218
  let projLabel = stripTerminalEscapes(slug).slice(0, 40);
4190
4219
  try {
4191
4220
  projLabel = stripTerminalEscapes(
4192
- fs6.readFileSync(path8.join(slugPath, ".project_root"), "utf-8").trim()
4193
- ).replace(os8.homedir(), "~").slice(0, 40);
4221
+ fs6.readFileSync(path9.join(slugPath, ".project_root"), "utf-8").trim()
4222
+ ).replace(os9.homedir(), "~").slice(0, 40);
4194
4223
  } catch {
4195
4224
  }
4196
- const chatsDir = path8.join(slugPath, "chats");
4225
+ const chatsDir = path9.join(slugPath, "chats");
4197
4226
  if (!fs6.existsSync(chatsDir)) continue;
4198
4227
  let chatFiles;
4199
4228
  try {
@@ -4210,7 +4239,7 @@ function scanGeminiHistory(startDate, onProgress, onLine) {
4210
4239
  onProgress?.(result.filesScanned);
4211
4240
  let raw;
4212
4241
  try {
4213
- raw = fs6.readFileSync(path8.join(chatsDir, chatFile), "utf-8");
4242
+ raw = fs6.readFileSync(path9.join(chatsDir, chatFile), "utf-8");
4214
4243
  } catch {
4215
4244
  continue;
4216
4245
  }
@@ -4383,7 +4412,7 @@ function scanGeminiHistory(startDate, onProgress, onLine) {
4383
4412
  return result;
4384
4413
  }
4385
4414
  function scanCodexHistory(startDate, onProgress, onLine) {
4386
- const sessionsBase = path8.join(os8.homedir(), ".codex", "sessions");
4415
+ const sessionsBase = path9.join(os9.homedir(), ".codex", "sessions");
4387
4416
  const result = {
4388
4417
  filesScanned: 0,
4389
4418
  sessions: 0,
@@ -4402,28 +4431,28 @@ function scanCodexHistory(startDate, onProgress, onLine) {
4402
4431
  const jsonlFiles = [];
4403
4432
  try {
4404
4433
  for (const year of fs6.readdirSync(sessionsBase)) {
4405
- const yearPath = path8.join(sessionsBase, year);
4434
+ const yearPath = path9.join(sessionsBase, year);
4406
4435
  try {
4407
4436
  if (!fs6.statSync(yearPath).isDirectory()) continue;
4408
4437
  } catch {
4409
4438
  continue;
4410
4439
  }
4411
4440
  for (const month of fs6.readdirSync(yearPath)) {
4412
- const monthPath = path8.join(yearPath, month);
4441
+ const monthPath = path9.join(yearPath, month);
4413
4442
  try {
4414
4443
  if (!fs6.statSync(monthPath).isDirectory()) continue;
4415
4444
  } catch {
4416
4445
  continue;
4417
4446
  }
4418
4447
  for (const day of fs6.readdirSync(monthPath)) {
4419
- const dayPath = path8.join(monthPath, day);
4448
+ const dayPath = path9.join(monthPath, day);
4420
4449
  try {
4421
4450
  if (!fs6.statSync(dayPath).isDirectory()) continue;
4422
4451
  } catch {
4423
4452
  continue;
4424
4453
  }
4425
4454
  for (const file of fs6.readdirSync(dayPath)) {
4426
- if (file.endsWith(".jsonl")) jsonlFiles.push(path8.join(dayPath, file));
4455
+ if (file.endsWith(".jsonl")) jsonlFiles.push(path9.join(dayPath, file));
4427
4456
  }
4428
4457
  }
4429
4458
  }
@@ -4464,7 +4493,7 @@ function scanCodexHistory(startDate, onProgress, onLine) {
4464
4493
  sessionId = String(payload["id"] ?? filePath);
4465
4494
  startTime = String(payload["timestamp"] ?? "");
4466
4495
  const cwd = String(payload["cwd"] ?? "");
4467
- projLabel = stripTerminalEscapes(cwd.replace(os8.homedir(), "~")).slice(0, 40);
4496
+ projLabel = stripTerminalEscapes(cwd.replace(os9.homedir(), "~")).slice(0, 40);
4468
4497
  continue;
4469
4498
  }
4470
4499
  if (entry.type === "turn_context" && typeof payload["model"] === "string") {
@@ -4707,11 +4736,11 @@ var init_scan = __esm({
4707
4736
 
4708
4737
  // src/tui/dashboard/data.ts
4709
4738
  import fs7 from "fs";
4710
- import os9 from "os";
4711
- import path9 from "path";
4739
+ import os10 from "os";
4740
+ import path10 from "path";
4712
4741
  import http from "http";
4713
4742
  function auditLogPath() {
4714
- return path9.join(os9.homedir(), ".node9", "audit.log");
4743
+ return path10.join(os10.homedir(), ".node9", "audit.log");
4715
4744
  }
4716
4745
  function readAuditEntriesAsync(chunkSize = 1e3, customPath) {
4717
4746
  return new Promise((resolve) => {
@@ -4851,13 +4880,13 @@ function loadBlast() {
4851
4880
  }
4852
4881
  }
4853
4882
  function shortenPath(p) {
4854
- const home = os9.homedir();
4883
+ const home = os10.homedir();
4855
4884
  return p.startsWith(home) ? p.replace(home, "~") : p;
4856
4885
  }
4857
4886
  async function loadReportAuditAsync(period) {
4858
- const claudeProjectsDir = path9.join(os9.homedir(), ".claude", "projects");
4859
- const codexSessionsDir = path9.join(os9.homedir(), ".codex", "sessions");
4860
- const geminiTmpDir = path9.join(os9.homedir(), ".gemini", "tmp");
4887
+ const claudeProjectsDir = path10.join(os10.homedir(), ".claude", "projects");
4888
+ const codexSessionsDir = path10.join(os10.homedir(), ".codex", "sessions");
4889
+ const geminiTmpDir = path10.join(os10.homedir(), ".gemini", "tmp");
4861
4890
  const { start, end } = getDateRange(period, /* @__PURE__ */ new Date());
4862
4891
  const entries = await readAuditEntriesAsync();
4863
4892
  void ensurePricingLoaded();
@@ -5963,8 +5992,8 @@ import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-run
5963
5992
  function TopToolsProjects({ audit }) {
5964
5993
  const data = audit?.data;
5965
5994
  const tools = data ? [...data.toolMap.entries()].sort(([, a], [, b]) => b.calls - a.calls).slice(0, ROW_LIMIT) : [];
5966
- const projects = data ? [...data.cost.byProject.entries()].map(([path10, r]) => ({
5967
- name: basenameOf(path10),
5995
+ const projects = data ? [...data.cost.byProject.entries()].map(([path11, r]) => ({
5996
+ name: basenameOf(path11),
5968
5997
  cost: r.cost,
5969
5998
  tokens: r.inputTokens + r.outputTokens
5970
5999
  })).sort((a, b) => b.cost - a.cost).slice(0, ROW_LIMIT) : [];
@@ -6401,8 +6430,8 @@ function pickTopLoopFile(loops) {
6401
6430
  map.set(k, (map.get(k) ?? 0) + (l.count ?? 0));
6402
6431
  }
6403
6432
  if (map.size === 0) return void 0;
6404
- const [path10, count] = [...map.entries()].sort((a, b) => b[1] - a[1])[0];
6405
- return { path: path10, count };
6433
+ const [path11, count] = [...map.entries()].sort((a, b) => b[1] - a[1])[0];
6434
+ return { path: path11, count };
6406
6435
  }
6407
6436
  var EMPTY_FILTERED_SCAN;
6408
6437
  var init_derive = __esm({