@node9/proxy 1.11.13 → 1.12.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/README.md +1 -1
  2. package/dist/cli.js +287 -251
  3. package/dist/cli.mjs +274 -238
  4. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -147,8 +147,8 @@ function sanitizeConfig(raw) {
147
147
  }
148
148
  }
149
149
  const lines = result.error.issues.map((issue) => {
150
- const path44 = issue.path.length > 0 ? issue.path.join(".") : "root";
151
- return ` \u2022 ${path44}: ${issue.message}`;
150
+ const path45 = issue.path.length > 0 ? issue.path.join(".") : "root";
151
+ return ` \u2022 ${path45}: ${issue.message}`;
152
152
  });
153
153
  return {
154
154
  sanitized,
@@ -2066,9 +2066,9 @@ function matchesPattern(text, patterns) {
2066
2066
  const withoutDotSlash = text.replace(/^\.\//, "");
2067
2067
  return isMatch(withoutDotSlash) || isMatch(`./${withoutDotSlash}`);
2068
2068
  }
2069
- function getNestedValue(obj, path44) {
2069
+ function getNestedValue(obj, path45) {
2070
2070
  if (!obj || typeof obj !== "object") return null;
2071
- return path44.split(".").reduce((prev, curr) => prev?.[curr], obj);
2071
+ return path45.split(".").reduce((prev, curr) => prev?.[curr], obj);
2072
2072
  }
2073
2073
  function normalizeCommandForPolicy(command) {
2074
2074
  try {
@@ -5243,6 +5243,10 @@ var init_ui = __esm({
5243
5243
  border-color: rgba(83, 155, 245, 0.35);
5244
5244
  background: rgba(83, 155, 245, 0.04);
5245
5245
  }
5246
+ .pending-card.discovery-card {
5247
+ border-color: rgba(120, 100, 255, 0.45);
5248
+ background: rgba(100, 80, 255, 0.06);
5249
+ }
5246
5250
  .pending-card-header {
5247
5251
  display: flex;
5248
5252
  align-items: center;
@@ -7429,7 +7433,7 @@ var init_ui = __esm({
7429
7433
  });
7430
7434
 
7431
7435
  try {
7432
- await fetch('/mcp/approve', {
7436
+ const res = await fetch('/mcp/approve', {
7433
7437
  method: 'POST',
7434
7438
  headers: {
7435
7439
  'Content-Type': 'application/json',
@@ -7437,9 +7441,19 @@ var init_ui = __esm({
7437
7441
  },
7438
7442
  body: JSON.stringify({ id, serverKey, disabledTools }),
7439
7443
  });
7444
+ if (!res.ok) {
7445
+ showToast(
7446
+ '\u26A0\uFE0F',
7447
+ 'Approval failed',
7448
+ \`Server responded with \${res.status}\`,
7449
+ 'toast-block'
7450
+ );
7451
+ return;
7452
+ }
7440
7453
  closeMcpReview();
7441
7454
  refreshMcpTools();
7442
7455
  } catch (err) {
7456
+ showToast('\u26A0\uFE0F', 'Approval failed', 'Network error \u2014 check the daemon', 'toast-block');
7443
7457
  console.error('Failed to approve MCP server:', err);
7444
7458
  }
7445
7459
  }
@@ -8254,6 +8268,10 @@ var init_ui2 = __esm({
8254
8268
 
8255
8269
  // src/cli/daemon-starter.ts
8256
8270
  import { spawn as spawn2, execSync } from "child_process";
8271
+ import path16 from "path";
8272
+ function isTestingMode() {
8273
+ return /^(1|true|yes)$/i.test(process.env.NODE9_TESTING ?? "");
8274
+ }
8257
8275
  function openBrowserLocal() {
8258
8276
  const url = `http://${DAEMON_HOST}:${DAEMON_PORT}/`;
8259
8277
  try {
@@ -8264,8 +8282,9 @@ function openBrowserLocal() {
8264
8282
  } catch {
8265
8283
  }
8266
8284
  }
8267
- async function autoStartDaemonAndWait() {
8268
- if (process.env.NODE9_TESTING === "1") return false;
8285
+ async function autoStartDaemonAndWait(openBrowser2 = true) {
8286
+ if (isTestingMode()) return false;
8287
+ if (!path16.isAbsolute(process.argv[1])) return false;
8269
8288
  try {
8270
8289
  const child = spawn2(process.execPath, [process.argv[1], "daemon"], {
8271
8290
  detached: true,
@@ -8283,7 +8302,9 @@ async function autoStartDaemonAndWait() {
8283
8302
  signal: AbortSignal.timeout(500)
8284
8303
  });
8285
8304
  if (res.ok) {
8286
- openBrowserLocal();
8305
+ if (openBrowser2) {
8306
+ openBrowserLocal();
8307
+ }
8287
8308
  return true;
8288
8309
  }
8289
8310
  } catch {
@@ -8492,7 +8513,7 @@ var init_scan_summary = __esm({
8492
8513
  // src/cli/commands/scan.ts
8493
8514
  import chalk2 from "chalk";
8494
8515
  import fs13 from "fs";
8495
- import path16 from "path";
8516
+ import path17 from "path";
8496
8517
  import os12 from "os";
8497
8518
  function claudeModelPrice(model) {
8498
8519
  const base = model.replace(/@.*$/, "").replace(/-\d{8}$/, "");
@@ -8592,11 +8613,11 @@ function buildRuleSources() {
8592
8613
  }
8593
8614
  function countScanFiles() {
8594
8615
  let total = 0;
8595
- const claudeDir = path16.join(os12.homedir(), ".claude", "projects");
8616
+ const claudeDir = path17.join(os12.homedir(), ".claude", "projects");
8596
8617
  if (fs13.existsSync(claudeDir)) {
8597
8618
  try {
8598
8619
  for (const proj of fs13.readdirSync(claudeDir)) {
8599
- const p = path16.join(claudeDir, proj);
8620
+ const p = path17.join(claudeDir, proj);
8600
8621
  try {
8601
8622
  if (!fs13.statSync(p).isDirectory()) continue;
8602
8623
  total += fs13.readdirSync(p).filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-")).length;
@@ -8607,14 +8628,14 @@ function countScanFiles() {
8607
8628
  } catch {
8608
8629
  }
8609
8630
  }
8610
- const geminiDir = path16.join(os12.homedir(), ".gemini", "tmp");
8631
+ const geminiDir = path17.join(os12.homedir(), ".gemini", "tmp");
8611
8632
  if (fs13.existsSync(geminiDir)) {
8612
8633
  try {
8613
8634
  for (const slug of fs13.readdirSync(geminiDir)) {
8614
- const p = path16.join(geminiDir, slug);
8635
+ const p = path17.join(geminiDir, slug);
8615
8636
  try {
8616
8637
  if (!fs13.statSync(p).isDirectory()) continue;
8617
- const chatsDir = path16.join(p, "chats");
8638
+ const chatsDir = path17.join(p, "chats");
8618
8639
  if (fs13.existsSync(chatsDir)) {
8619
8640
  try {
8620
8641
  total += fs13.readdirSync(chatsDir).filter((f) => f.endsWith(".json")).length;
@@ -8628,19 +8649,19 @@ function countScanFiles() {
8628
8649
  } catch {
8629
8650
  }
8630
8651
  }
8631
- const codexDir = path16.join(os12.homedir(), ".codex", "sessions");
8652
+ const codexDir = path17.join(os12.homedir(), ".codex", "sessions");
8632
8653
  if (fs13.existsSync(codexDir)) {
8633
8654
  try {
8634
8655
  for (const year of fs13.readdirSync(codexDir)) {
8635
- const yp = path16.join(codexDir, year);
8656
+ const yp = path17.join(codexDir, year);
8636
8657
  try {
8637
8658
  if (!fs13.statSync(yp).isDirectory()) continue;
8638
8659
  for (const month of fs13.readdirSync(yp)) {
8639
- const mp = path16.join(yp, month);
8660
+ const mp = path17.join(yp, month);
8640
8661
  try {
8641
8662
  if (!fs13.statSync(mp).isDirectory()) continue;
8642
8663
  for (const day of fs13.readdirSync(mp)) {
8643
- const dp = path16.join(mp, day);
8664
+ const dp = path17.join(mp, day);
8644
8665
  try {
8645
8666
  if (!fs13.statSync(dp).isDirectory()) continue;
8646
8667
  total += fs13.readdirSync(dp).filter((f) => f.endsWith(".jsonl")).length;
@@ -8672,7 +8693,7 @@ function renderProgressBar(done, total) {
8672
8693
  );
8673
8694
  }
8674
8695
  function scanClaudeHistory(startDate, onProgress) {
8675
- const projectsDir = path16.join(os12.homedir(), ".claude", "projects");
8696
+ const projectsDir = path17.join(os12.homedir(), ".claude", "projects");
8676
8697
  const result = {
8677
8698
  filesScanned: 0,
8678
8699
  sessions: 0,
@@ -8694,7 +8715,7 @@ function scanClaudeHistory(startDate, onProgress) {
8694
8715
  }
8695
8716
  const ruleSources = buildRuleSources();
8696
8717
  for (const proj of projDirs) {
8697
- const projPath = path16.join(projectsDir, proj);
8718
+ const projPath = path17.join(projectsDir, proj);
8698
8719
  try {
8699
8720
  if (!fs13.statSync(projPath).isDirectory()) continue;
8700
8721
  } catch {
@@ -8714,7 +8735,7 @@ function scanClaudeHistory(startDate, onProgress) {
8714
8735
  const sessionId = file.replace(/\.jsonl$/, "");
8715
8736
  let raw;
8716
8737
  try {
8717
- raw = fs13.readFileSync(path16.join(projPath, file), "utf-8");
8738
+ raw = fs13.readFileSync(path17.join(projPath, file), "utf-8");
8718
8739
  } catch {
8719
8740
  continue;
8720
8741
  }
@@ -8867,7 +8888,7 @@ function scanClaudeHistory(startDate, onProgress) {
8867
8888
  return result;
8868
8889
  }
8869
8890
  function scanGeminiHistory(startDate, onProgress) {
8870
- const tmpDir = path16.join(os12.homedir(), ".gemini", "tmp");
8891
+ const tmpDir = path17.join(os12.homedir(), ".gemini", "tmp");
8871
8892
  const result = {
8872
8893
  filesScanned: 0,
8873
8894
  sessions: 0,
@@ -8889,7 +8910,7 @@ function scanGeminiHistory(startDate, onProgress) {
8889
8910
  }
8890
8911
  const ruleSources = buildRuleSources();
8891
8912
  for (const slug of slugDirs) {
8892
- const slugPath = path16.join(tmpDir, slug);
8913
+ const slugPath = path17.join(tmpDir, slug);
8893
8914
  try {
8894
8915
  if (!fs13.statSync(slugPath).isDirectory()) continue;
8895
8916
  } catch {
@@ -8897,10 +8918,10 @@ function scanGeminiHistory(startDate, onProgress) {
8897
8918
  }
8898
8919
  let projLabel = slug;
8899
8920
  try {
8900
- projLabel = fs13.readFileSync(path16.join(slugPath, ".project_root"), "utf-8").trim().replace(os12.homedir(), "~").slice(0, 40);
8921
+ projLabel = fs13.readFileSync(path17.join(slugPath, ".project_root"), "utf-8").trim().replace(os12.homedir(), "~").slice(0, 40);
8901
8922
  } catch {
8902
8923
  }
8903
- const chatsDir = path16.join(slugPath, "chats");
8924
+ const chatsDir = path17.join(slugPath, "chats");
8904
8925
  if (!fs13.existsSync(chatsDir)) continue;
8905
8926
  let chatFiles;
8906
8927
  try {
@@ -8914,7 +8935,7 @@ function scanGeminiHistory(startDate, onProgress) {
8914
8935
  const sessionId = chatFile.replace(/\.json$/, "");
8915
8936
  let raw;
8916
8937
  try {
8917
- raw = fs13.readFileSync(path16.join(chatsDir, chatFile), "utf-8");
8938
+ raw = fs13.readFileSync(path17.join(chatsDir, chatFile), "utf-8");
8918
8939
  } catch {
8919
8940
  continue;
8920
8941
  }
@@ -9063,7 +9084,7 @@ function scanGeminiHistory(startDate, onProgress) {
9063
9084
  return result;
9064
9085
  }
9065
9086
  function scanCodexHistory(startDate, onProgress) {
9066
- const sessionsBase = path16.join(os12.homedir(), ".codex", "sessions");
9087
+ const sessionsBase = path17.join(os12.homedir(), ".codex", "sessions");
9067
9088
  const result = {
9068
9089
  filesScanned: 0,
9069
9090
  sessions: 0,
@@ -9080,28 +9101,28 @@ function scanCodexHistory(startDate, onProgress) {
9080
9101
  const jsonlFiles = [];
9081
9102
  try {
9082
9103
  for (const year of fs13.readdirSync(sessionsBase)) {
9083
- const yearPath = path16.join(sessionsBase, year);
9104
+ const yearPath = path17.join(sessionsBase, year);
9084
9105
  try {
9085
9106
  if (!fs13.statSync(yearPath).isDirectory()) continue;
9086
9107
  } catch {
9087
9108
  continue;
9088
9109
  }
9089
9110
  for (const month of fs13.readdirSync(yearPath)) {
9090
- const monthPath = path16.join(yearPath, month);
9111
+ const monthPath = path17.join(yearPath, month);
9091
9112
  try {
9092
9113
  if (!fs13.statSync(monthPath).isDirectory()) continue;
9093
9114
  } catch {
9094
9115
  continue;
9095
9116
  }
9096
9117
  for (const day of fs13.readdirSync(monthPath)) {
9097
- const dayPath = path16.join(monthPath, day);
9118
+ const dayPath = path17.join(monthPath, day);
9098
9119
  try {
9099
9120
  if (!fs13.statSync(dayPath).isDirectory()) continue;
9100
9121
  } catch {
9101
9122
  continue;
9102
9123
  }
9103
9124
  for (const file of fs13.readdirSync(dayPath)) {
9104
- if (file.endsWith(".jsonl")) jsonlFiles.push(path16.join(dayPath, file));
9125
+ if (file.endsWith(".jsonl")) jsonlFiles.push(path17.join(dayPath, file));
9105
9126
  }
9106
9127
  }
9107
9128
  }
@@ -9343,7 +9364,7 @@ function registerScanCommand(program2) {
9343
9364
  d.setHours(0, 0, 0, 0);
9344
9365
  return d;
9345
9366
  })();
9346
- const isInstalled = fs13.existsSync(path16.join(os12.homedir(), ".node9", "audit.log"));
9367
+ const isInstalled = fs13.existsSync(path17.join(os12.homedir(), ".node9", "audit.log"));
9347
9368
  console.log("");
9348
9369
  if (!isInstalled) {
9349
9370
  console.log(
@@ -9568,7 +9589,7 @@ function registerScanCommand(program2) {
9568
9589
  console.log(" " + chalk2.dim("\u2192 ") + chalk2.underline("https://node9.ai"));
9569
9590
  }
9570
9591
  console.log("");
9571
- if (isDaemonRunning() && process.env.NODE9_TESTING !== "1") {
9592
+ if (!isTestingMode() && isDaemonRunning()) {
9572
9593
  const internalToken = getInternalToken();
9573
9594
  if (internalToken) {
9574
9595
  try {
@@ -9734,7 +9755,7 @@ var init_suggestion_tracker = __esm({
9734
9755
 
9735
9756
  // src/daemon/taint-store.ts
9736
9757
  import fs14 from "fs";
9737
- import path17 from "path";
9758
+ import path18 from "path";
9738
9759
  var DEFAULT_TTL_MS, TaintStore;
9739
9760
  var init_taint_store = __esm({
9740
9761
  "src/daemon/taint-store.ts"() {
@@ -9803,9 +9824,9 @@ var init_taint_store = __esm({
9803
9824
  /** Resolve to absolute path, falling back to path.resolve if file doesn't exist yet. */
9804
9825
  _resolve(filePath) {
9805
9826
  try {
9806
- return fs14.realpathSync.native(path17.resolve(filePath));
9827
+ return fs14.realpathSync.native(path18.resolve(filePath));
9807
9828
  } catch {
9808
- return path17.resolve(filePath);
9829
+ return path18.resolve(filePath);
9809
9830
  }
9810
9831
  }
9811
9832
  };
@@ -9923,7 +9944,7 @@ var init_session_history = __esm({
9923
9944
  // src/daemon/state.ts
9924
9945
  import net2 from "net";
9925
9946
  import fs15 from "fs";
9926
- import path18 from "path";
9947
+ import path19 from "path";
9927
9948
  import os13 from "os";
9928
9949
  import { spawn as spawn3 } from "child_process";
9929
9950
  import { randomUUID as randomUUID3 } from "crypto";
@@ -9973,7 +9994,7 @@ function setCachedScanResult(result) {
9973
9994
  cachedScanTs = Date.now();
9974
9995
  }
9975
9996
  function atomicWriteSync2(filePath, data, options) {
9976
- const dir = path18.dirname(filePath);
9997
+ const dir = path19.dirname(filePath);
9977
9998
  if (!fs15.existsSync(dir)) fs15.mkdirSync(dir, { recursive: true });
9978
9999
  const tmpPath = `${filePath}.${randomUUID3()}.tmp`;
9979
10000
  try {
@@ -10013,7 +10034,7 @@ function appendAuditLog(data) {
10013
10034
  decision: data.decision,
10014
10035
  source: "daemon"
10015
10036
  };
10016
- const dir = path18.dirname(AUDIT_LOG_FILE);
10037
+ const dir = path19.dirname(AUDIT_LOG_FILE);
10017
10038
  if (!fs15.existsSync(dir)) fs15.mkdirSync(dir, { recursive: true });
10018
10039
  fs15.appendFileSync(AUDIT_LOG_FILE, JSON.stringify(entry) + "\n");
10019
10040
  } catch {
@@ -10277,13 +10298,13 @@ var init_state2 = __esm({
10277
10298
  init_session_counters();
10278
10299
  init_session_history();
10279
10300
  homeDir = os13.homedir();
10280
- DAEMON_PID_FILE = path18.join(homeDir, ".node9", "daemon.pid");
10281
- DECISIONS_FILE = path18.join(homeDir, ".node9", "decisions.json");
10282
- AUDIT_LOG_FILE = path18.join(homeDir, ".node9", "audit.log");
10283
- TRUST_FILE2 = path18.join(homeDir, ".node9", "trust.json");
10284
- GLOBAL_CONFIG_FILE = path18.join(homeDir, ".node9", "config.json");
10285
- CREDENTIALS_FILE = path18.join(homeDir, ".node9", "credentials.json");
10286
- INSIGHT_COUNTS_FILE = path18.join(homeDir, ".node9", "insight-counts.json");
10301
+ DAEMON_PID_FILE = path19.join(homeDir, ".node9", "daemon.pid");
10302
+ DECISIONS_FILE = path19.join(homeDir, ".node9", "decisions.json");
10303
+ AUDIT_LOG_FILE = path19.join(homeDir, ".node9", "audit.log");
10304
+ TRUST_FILE2 = path19.join(homeDir, ".node9", "trust.json");
10305
+ GLOBAL_CONFIG_FILE = path19.join(homeDir, ".node9", "config.json");
10306
+ CREDENTIALS_FILE = path19.join(homeDir, ".node9", "credentials.json");
10307
+ INSIGHT_COUNTS_FILE = path19.join(homeDir, ".node9", "insight-counts.json");
10287
10308
  pending = /* @__PURE__ */ new Map();
10288
10309
  sseClients = /* @__PURE__ */ new Set();
10289
10310
  suggestionTracker = new SuggestionTracker(3);
@@ -10301,7 +10322,7 @@ var init_state2 = __esm({
10301
10322
  "2h": 2 * 60 * 6e4
10302
10323
  };
10303
10324
  autoStarted = process.env.NODE9_AUTO_STARTED === "1";
10304
- ACTIVITY_SOCKET_PATH2 = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : path18.join(os13.tmpdir(), "node9-activity.sock");
10325
+ ACTIVITY_SOCKET_PATH2 = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : path19.join(os13.tmpdir(), "node9-activity.sock");
10305
10326
  ACTIVITY_RING_SIZE = 100;
10306
10327
  activityRing = [];
10307
10328
  LARGE_RESPONSE_RING_SIZE = 20;
@@ -10329,7 +10350,7 @@ var init_state2 = __esm({
10329
10350
 
10330
10351
  // src/config/patch.ts
10331
10352
  import fs16 from "fs";
10332
- import path19 from "path";
10353
+ import path20 from "path";
10333
10354
  import os14 from "os";
10334
10355
  function patchConfig(configPath, patch) {
10335
10356
  let config = {};
@@ -10354,7 +10375,7 @@ function patchConfig(configPath, patch) {
10354
10375
  ignored.push(patch.toolName);
10355
10376
  }
10356
10377
  }
10357
- const dir = path19.dirname(configPath);
10378
+ const dir = path20.dirname(configPath);
10358
10379
  fs16.mkdirSync(dir, { recursive: true });
10359
10380
  const tmp = configPath + ".node9-tmp";
10360
10381
  try {
@@ -10380,13 +10401,13 @@ var GLOBAL_CONFIG_PATH;
10380
10401
  var init_patch = __esm({
10381
10402
  "src/config/patch.ts"() {
10382
10403
  "use strict";
10383
- GLOBAL_CONFIG_PATH = path19.join(os14.homedir(), ".node9", "config.json");
10404
+ GLOBAL_CONFIG_PATH = path20.join(os14.homedir(), ".node9", "config.json");
10384
10405
  }
10385
10406
  });
10386
10407
 
10387
10408
  // src/costSync.ts
10388
10409
  import fs17 from "fs";
10389
- import path20 from "path";
10410
+ import path21 from "path";
10390
10411
  import os15 from "os";
10391
10412
  function normalizeModel(raw) {
10392
10413
  return raw.replace(/-\d{8}$/, "");
@@ -10455,7 +10476,7 @@ function parseJSONLFile(filePath) {
10455
10476
  return daily;
10456
10477
  }
10457
10478
  function collectEntries() {
10458
- const projectsDir = path20.join(os15.homedir(), ".claude", "projects");
10479
+ const projectsDir = path21.join(os15.homedir(), ".claude", "projects");
10459
10480
  if (!fs17.existsSync(projectsDir)) return [];
10460
10481
  const combined = /* @__PURE__ */ new Map();
10461
10482
  let dirs;
@@ -10465,7 +10486,7 @@ function collectEntries() {
10465
10486
  return [];
10466
10487
  }
10467
10488
  for (const dir of dirs) {
10468
- const dirPath = path20.join(projectsDir, dir);
10489
+ const dirPath = path21.join(projectsDir, dir);
10469
10490
  try {
10470
10491
  if (!fs17.statSync(dirPath).isDirectory()) continue;
10471
10492
  } catch {
@@ -10478,7 +10499,7 @@ function collectEntries() {
10478
10499
  continue;
10479
10500
  }
10480
10501
  for (const file of files) {
10481
- const entries = parseJSONLFile(path20.join(dirPath, file));
10502
+ const entries = parseJSONLFile(path21.join(dirPath, file));
10482
10503
  for (const [key, e] of entries) {
10483
10504
  const prev = combined.get(key);
10484
10505
  if (prev) {
@@ -10554,7 +10575,7 @@ var init_costSync = __esm({
10554
10575
  import fs18 from "fs";
10555
10576
  import https from "https";
10556
10577
  import os16 from "os";
10557
- import path21 from "path";
10578
+ import path22 from "path";
10558
10579
  function readCredentials() {
10559
10580
  if (process.env.NODE9_API_KEY) {
10560
10581
  return {
@@ -10563,7 +10584,7 @@ function readCredentials() {
10563
10584
  };
10564
10585
  }
10565
10586
  try {
10566
- const credPath = path21.join(os16.homedir(), ".node9", "credentials.json");
10587
+ const credPath = path22.join(os16.homedir(), ".node9", "credentials.json");
10567
10588
  const creds = JSON.parse(fs18.readFileSync(credPath, "utf-8"));
10568
10589
  const profileName = process.env.NODE9_PROFILE ?? "default";
10569
10590
  const profile = creds[profileName];
@@ -10626,7 +10647,7 @@ async function syncOnce() {
10626
10647
  try {
10627
10648
  const rules = await fetchCloudRules(creds.apiKey, creds.apiUrl);
10628
10649
  const cache = { fetchedAt: (/* @__PURE__ */ new Date()).toISOString(), rules };
10629
- const dir = path21.dirname(rulesCacheFile());
10650
+ const dir = path22.dirname(rulesCacheFile());
10630
10651
  if (!fs18.existsSync(dir)) fs18.mkdirSync(dir, { recursive: true });
10631
10652
  fs18.writeFileSync(rulesCacheFile(), JSON.stringify(cache, null, 2) + "\n", "utf-8");
10632
10653
  } catch {
@@ -10640,7 +10661,7 @@ async function runCloudSync() {
10640
10661
  try {
10641
10662
  const rules = await fetchCloudRules(creds.apiKey, creds.apiUrl);
10642
10663
  const cache = { fetchedAt: (/* @__PURE__ */ new Date()).toISOString(), rules };
10643
- const dir = path21.dirname(rulesCacheFile());
10664
+ const dir = path22.dirname(rulesCacheFile());
10644
10665
  if (!fs18.existsSync(dir)) fs18.mkdirSync(dir, { recursive: true });
10645
10666
  fs18.writeFileSync(rulesCacheFile(), JSON.stringify(cache, null, 2) + "\n", "utf-8");
10646
10667
  return { ok: true, rules: rules.length, fetchedAt: cache.fetchedAt };
@@ -10679,7 +10700,7 @@ var init_sync = __esm({
10679
10700
  "src/daemon/sync.ts"() {
10680
10701
  "use strict";
10681
10702
  init_config();
10682
- rulesCacheFile = () => path21.join(os16.homedir(), ".node9", "rules-cache.json");
10703
+ rulesCacheFile = () => path22.join(os16.homedir(), ".node9", "rules-cache.json");
10683
10704
  DEFAULT_API_URL = "https://api.node9.ai/api/v1/policy";
10684
10705
  DEFAULT_INTERVAL_HOURS = 5;
10685
10706
  MIN_INTERVAL_HOURS = 1;
@@ -10688,7 +10709,7 @@ var init_sync = __esm({
10688
10709
 
10689
10710
  // src/daemon/dlp-scanner.ts
10690
10711
  import fs19 from "fs";
10691
- import path22 from "path";
10712
+ import path23 from "path";
10692
10713
  import os17 from "os";
10693
10714
  function loadIndex() {
10694
10715
  try {
@@ -10720,11 +10741,11 @@ function runDlpScan() {
10720
10741
  return;
10721
10742
  }
10722
10743
  for (const proj of projDirs) {
10723
- const projPath = path22.join(PROJECTS_DIR, proj);
10744
+ const projPath = path23.join(PROJECTS_DIR, proj);
10724
10745
  try {
10725
10746
  if (!fs19.lstatSync(projPath).isDirectory()) continue;
10726
10747
  const real = fs19.realpathSync(projPath);
10727
- if (!real.startsWith(PROJECTS_DIR + path22.sep) && real !== PROJECTS_DIR) continue;
10748
+ if (!real.startsWith(PROJECTS_DIR + path23.sep) && real !== PROJECTS_DIR) continue;
10728
10749
  } catch {
10729
10750
  continue;
10730
10751
  }
@@ -10735,7 +10756,7 @@ function runDlpScan() {
10735
10756
  continue;
10736
10757
  }
10737
10758
  for (const file of files) {
10738
- const filePath = path22.join(projPath, file);
10759
+ const filePath = path23.join(projPath, file);
10739
10760
  const lastOffset = index[filePath] ?? 0;
10740
10761
  let size;
10741
10762
  try {
@@ -10831,17 +10852,17 @@ var init_dlp_scanner = __esm({
10831
10852
  init_dlp();
10832
10853
  init_native();
10833
10854
  init_state2();
10834
- INDEX_FILE = path22.join(os17.homedir(), ".node9", "dlp-index.json");
10835
- PROJECTS_DIR = path22.join(os17.homedir(), ".claude", "projects");
10855
+ INDEX_FILE = path23.join(os17.homedir(), ".node9", "dlp-index.json");
10856
+ PROJECTS_DIR = path23.join(os17.homedir(), ".claude", "projects");
10836
10857
  }
10837
10858
  });
10838
10859
 
10839
10860
  // src/daemon/mcp-tools.ts
10840
10861
  import fs20 from "fs";
10841
- import path23 from "path";
10862
+ import path24 from "path";
10842
10863
  import os18 from "os";
10843
10864
  function getMcpToolsFile() {
10844
- return path23.join(os18.homedir(), ".node9", "mcp-tools.json");
10865
+ return path24.join(os18.homedir(), ".node9", "mcp-tools.json");
10845
10866
  }
10846
10867
  function readMcpToolsConfig() {
10847
10868
  try {
@@ -10856,7 +10877,7 @@ function readMcpToolsConfig() {
10856
10877
  function writeMcpToolsConfig(config) {
10857
10878
  try {
10858
10879
  const file = getMcpToolsFile();
10859
- const dir = path23.dirname(file);
10880
+ const dir = path24.dirname(file);
10860
10881
  if (!fs20.existsSync(dir)) fs20.mkdirSync(dir, { recursive: true });
10861
10882
  const tmpPath = `${file}.${os18.hostname()}.${process.pid}.tmp`;
10862
10883
  fs20.writeFileSync(tmpPath, JSON.stringify(config, null, 2));
@@ -10908,7 +10929,7 @@ var init_mcp_tools = __esm({
10908
10929
  // src/daemon/server.ts
10909
10930
  import http from "http";
10910
10931
  import fs21 from "fs";
10911
- import path24 from "path";
10932
+ import path25 from "path";
10912
10933
  import os19 from "os";
10913
10934
  import { randomUUID as randomUUID4 } from "crypto";
10914
10935
  import { spawnSync as spawnSync2 } from "child_process";
@@ -11103,7 +11124,7 @@ data: ${JSON.stringify(item.data)}
11103
11124
  status: "pending"
11104
11125
  });
11105
11126
  }
11106
- const projectCwd = typeof cwd === "string" && path24.isAbsolute(cwd) ? cwd : void 0;
11127
+ const projectCwd = typeof cwd === "string" && path25.isAbsolute(cwd) ? cwd : void 0;
11107
11128
  const projectConfig = getConfig(projectCwd);
11108
11129
  const browserEnabled = projectConfig.settings.approvers?.browser !== false;
11109
11130
  const terminalEnabled = projectConfig.settings.approvers?.terminal !== false;
@@ -11467,7 +11488,7 @@ data: ${JSON.stringify(item.data)}
11467
11488
  if (!validToken(req)) return res.writeHead(403).end();
11468
11489
  const periodParam = reqUrl.searchParams.get("period") || "7d";
11469
11490
  const period = ["today", "7d", "30d", "month"].includes(periodParam) ? periodParam : "7d";
11470
- const logPath = path24.join(os19.homedir(), ".node9", "audit.log");
11491
+ const logPath = path25.join(os19.homedir(), ".node9", "audit.log");
11471
11492
  if (!fs21.existsSync(logPath)) {
11472
11493
  res.writeHead(200, { "Content-Type": "application/json" });
11473
11494
  return res.end(
@@ -11661,8 +11682,8 @@ data: ${JSON.stringify(item.data)}
11661
11682
  const body = await readBody(req);
11662
11683
  const data = body ? JSON.parse(body) : {};
11663
11684
  const configPath = data.configPath ?? GLOBAL_CONFIG_PATH;
11664
- const node9Dir = path24.dirname(GLOBAL_CONFIG_PATH);
11665
- if (!path24.resolve(configPath).startsWith(node9Dir + path24.sep)) {
11685
+ const node9Dir = path25.dirname(GLOBAL_CONFIG_PATH);
11686
+ if (!path25.resolve(configPath).startsWith(node9Dir + path25.sep)) {
11666
11687
  res.writeHead(400, { "Content-Type": "application/json" });
11667
11688
  return res.end(
11668
11689
  JSON.stringify({ error: "configPath must be within the node9 config directory" })
@@ -11781,6 +11802,11 @@ data: ${JSON.stringify(item.data)}
11781
11802
  return;
11782
11803
  }
11783
11804
  approveServer(serverKey, disabledTools);
11805
+ appendAuditLog({
11806
+ toolName: `mcp-server:${serverKey}`,
11807
+ args: { disabledTools },
11808
+ decision: "allow"
11809
+ });
11784
11810
  broadcast("mcp-tools-updated", { serverKey, disabledTools });
11785
11811
  res.writeHead(200).end();
11786
11812
  return;
@@ -11799,6 +11825,11 @@ data: ${JSON.stringify(item.data)}
11799
11825
  }
11800
11826
  const status = updateServerDiscovery(serverKey, tools);
11801
11827
  if (status === "new" || status === "drift") {
11828
+ appendAuditLog({
11829
+ toolName: `mcp-server:${serverKey}`,
11830
+ args: { toolCount: tools.length, status },
11831
+ decision: "mcp-discovered"
11832
+ });
11802
11833
  const id = randomUUID4();
11803
11834
  const entry = {
11804
11835
  id,
@@ -11867,6 +11898,11 @@ data: ${JSON.stringify(item.data)}
11867
11898
  }
11868
11899
  clearTimeout(entry.timer);
11869
11900
  approveServer(serverKey, disabledTools);
11901
+ appendAuditLog({
11902
+ toolName: `mcp-server:${serverKey}`,
11903
+ args: { disabledTools },
11904
+ decision: "allow"
11905
+ });
11870
11906
  pending.delete(id);
11871
11907
  broadcast("remove", { id, decision: "allow" });
11872
11908
  res.writeHead(200).end();
@@ -11976,13 +12012,13 @@ var init_server = __esm({
11976
12012
 
11977
12013
  // src/daemon/service.ts
11978
12014
  import fs22 from "fs";
11979
- import path25 from "path";
12015
+ import path26 from "path";
11980
12016
  import os20 from "os";
11981
12017
  import { spawnSync as spawnSync3, execFileSync } from "child_process";
11982
12018
  function resolveNode9Binary() {
11983
12019
  try {
11984
12020
  const script = process.argv[1];
11985
- if (typeof script === "string" && path25.isAbsolute(script) && fs22.existsSync(script)) {
12021
+ if (typeof script === "string" && path26.isAbsolute(script) && fs22.existsSync(script)) {
11986
12022
  return fs22.realpathSync(script);
11987
12023
  }
11988
12024
  } catch {
@@ -12001,11 +12037,11 @@ function xmlEscape(s) {
12001
12037
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
12002
12038
  }
12003
12039
  function launchdPlist(binaryPath) {
12004
- const logDir = path25.join(os20.homedir(), ".node9");
12040
+ const logDir = path26.join(os20.homedir(), ".node9");
12005
12041
  const nodePath = xmlEscape(process.execPath);
12006
12042
  const scriptPath = xmlEscape(binaryPath);
12007
- const outLog = xmlEscape(path25.join(logDir, "daemon.log"));
12008
- const errLog = xmlEscape(path25.join(logDir, "daemon-error.log"));
12043
+ const outLog = xmlEscape(path26.join(logDir, "daemon.log"));
12044
+ const errLog = xmlEscape(path26.join(logDir, "daemon-error.log"));
12009
12045
  return `<?xml version="1.0" encoding="UTF-8"?>
12010
12046
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
12011
12047
  <plist version="1.0">
@@ -12040,7 +12076,7 @@ function launchdPlist(binaryPath) {
12040
12076
  `;
12041
12077
  }
12042
12078
  function installLaunchd(binaryPath) {
12043
- const dir = path25.dirname(LAUNCHD_PLIST);
12079
+ const dir = path26.dirname(LAUNCHD_PLIST);
12044
12080
  if (!fs22.existsSync(dir)) fs22.mkdirSync(dir, { recursive: true });
12045
12081
  fs22.writeFileSync(LAUNCHD_PLIST, launchdPlist(binaryPath), "utf-8");
12046
12082
  spawnSync3("launchctl", ["unload", LAUNCHD_PLIST], { encoding: "utf8" });
@@ -12117,7 +12153,7 @@ function isSystemdInstalled() {
12117
12153
  return fs22.existsSync(SYSTEMD_UNIT);
12118
12154
  }
12119
12155
  function stopRunningDaemon() {
12120
- const pidFile = path25.join(os20.homedir(), ".node9", "daemon.pid");
12156
+ const pidFile = path26.join(os20.homedir(), ".node9", "daemon.pid");
12121
12157
  if (!fs22.existsSync(pidFile)) return;
12122
12158
  try {
12123
12159
  const data = JSON.parse(fs22.readFileSync(pidFile, "utf-8"));
@@ -12215,9 +12251,9 @@ var init_service = __esm({
12215
12251
  "src/daemon/service.ts"() {
12216
12252
  "use strict";
12217
12253
  LAUNCHD_LABEL = "ai.node9.daemon";
12218
- LAUNCHD_PLIST = path25.join(os20.homedir(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
12219
- SYSTEMD_UNIT_DIR = path25.join(os20.homedir(), ".config", "systemd", "user");
12220
- SYSTEMD_UNIT = path25.join(SYSTEMD_UNIT_DIR, "node9-daemon.service");
12254
+ LAUNCHD_PLIST = path26.join(os20.homedir(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
12255
+ SYSTEMD_UNIT_DIR = path26.join(os20.homedir(), ".config", "systemd", "user");
12256
+ SYSTEMD_UNIT = path26.join(SYSTEMD_UNIT_DIR, "node9-daemon.service");
12221
12257
  }
12222
12258
  });
12223
12259
 
@@ -12303,7 +12339,7 @@ import http2 from "http";
12303
12339
  import chalk25 from "chalk";
12304
12340
  import fs38 from "fs";
12305
12341
  import os35 from "os";
12306
- import path41 from "path";
12342
+ import path42 from "path";
12307
12343
  import readline5 from "readline";
12308
12344
  import { spawn as spawn10, execSync as execSync3 } from "child_process";
12309
12345
  function getIcon(tool) {
@@ -12321,18 +12357,18 @@ function getModelContextLimit(model) {
12321
12357
  return 2e5;
12322
12358
  }
12323
12359
  function readSessionUsage() {
12324
- const projectsDir = path41.join(os35.homedir(), ".claude", "projects");
12360
+ const projectsDir = path42.join(os35.homedir(), ".claude", "projects");
12325
12361
  if (!fs38.existsSync(projectsDir)) return null;
12326
12362
  let latestFile = null;
12327
12363
  let latestMtime = 0;
12328
12364
  try {
12329
12365
  for (const dir of fs38.readdirSync(projectsDir)) {
12330
- const dirPath = path41.join(projectsDir, dir);
12366
+ const dirPath = path42.join(projectsDir, dir);
12331
12367
  try {
12332
12368
  if (!fs38.statSync(dirPath).isDirectory()) continue;
12333
12369
  for (const file of fs38.readdirSync(dirPath)) {
12334
12370
  if (!file.endsWith(".jsonl") || file.startsWith("agent-")) continue;
12335
- const filePath = path41.join(dirPath, file);
12371
+ const filePath = path42.join(dirPath, file);
12336
12372
  try {
12337
12373
  const mtime = fs38.statSync(filePath).mtimeMs;
12338
12374
  if (mtime > latestMtime) {
@@ -12593,7 +12629,7 @@ function buildRecoveryCardLines(req) {
12593
12629
  ];
12594
12630
  }
12595
12631
  function readApproversFromDisk() {
12596
- const configPath = path41.join(os35.homedir(), ".node9", "config.json");
12632
+ const configPath = path42.join(os35.homedir(), ".node9", "config.json");
12597
12633
  try {
12598
12634
  const raw = JSON.parse(fs38.readFileSync(configPath, "utf-8"));
12599
12635
  const settings = raw.settings ?? {};
@@ -12611,7 +12647,7 @@ function approverStatusLine() {
12611
12647
  return `${fmt("native", "native")} ${fmt("browser", "browser")} ${fmt("cloud", "cloud")} ${fmt("terminal", "terminal")}`;
12612
12648
  }
12613
12649
  function toggleApprover(channel) {
12614
- const configPath = path41.join(os35.homedir(), ".node9", "config.json");
12650
+ const configPath = path42.join(os35.homedir(), ".node9", "config.json");
12615
12651
  try {
12616
12652
  const raw = JSON.parse(fs38.readFileSync(configPath, "utf-8"));
12617
12653
  const settings = raw.settings ?? {};
@@ -12790,7 +12826,7 @@ async function startTail(options = {}) {
12790
12826
  postDecisionHttp(req2.id, httpDecision, csrfToken, port, httpOpts).catch((err2) => {
12791
12827
  try {
12792
12828
  fs38.appendFileSync(
12793
- path41.join(os35.homedir(), ".node9", "hook-debug.log"),
12829
+ path42.join(os35.homedir(), ".node9", "hook-debug.log"),
12794
12830
  `[tail] POST /decision failed: ${String(err2)}
12795
12831
  `
12796
12832
  );
@@ -12871,7 +12907,7 @@ async function startTail(options = {}) {
12871
12907
  }
12872
12908
  } catch {
12873
12909
  }
12874
- const auditLog = path41.join(os35.homedir(), ".node9", "audit.log");
12910
+ const auditLog = path42.join(os35.homedir(), ".node9", "audit.log");
12875
12911
  try {
12876
12912
  const unackedDlp = fs38.readFileSync(auditLog, "utf-8").split("\n").filter((l) => l.includes('"response-dlp"')).length;
12877
12913
  if (unackedDlp > 0) {
@@ -13065,7 +13101,7 @@ var init_tail = __esm({
13065
13101
  init_daemon2();
13066
13102
  init_daemon();
13067
13103
  init_core();
13068
- PID_FILE = path41.join(os35.homedir(), ".node9", "daemon.pid");
13104
+ PID_FILE = path42.join(os35.homedir(), ".node9", "daemon.pid");
13069
13105
  ICONS = {
13070
13106
  bash: "\u{1F4BB}",
13071
13107
  shell: "\u{1F4BB}",
@@ -13114,7 +13150,7 @@ __export(hud_exports, {
13114
13150
  renderEnvironmentLine: () => renderEnvironmentLine
13115
13151
  });
13116
13152
  import fs39 from "fs";
13117
- import path42 from "path";
13153
+ import path43 from "path";
13118
13154
  import os36 from "os";
13119
13155
  import http3 from "http";
13120
13156
  async function readStdin() {
@@ -13219,7 +13255,7 @@ function countRulesInDir(rulesDir) {
13219
13255
  try {
13220
13256
  for (const entry of fs39.readdirSync(rulesDir, { withFileTypes: true })) {
13221
13257
  if (entry.isDirectory()) {
13222
- count += countRulesInDir(path42.join(rulesDir, entry.name));
13258
+ count += countRulesInDir(path43.join(rulesDir, entry.name));
13223
13259
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
13224
13260
  count++;
13225
13261
  }
@@ -13230,46 +13266,46 @@ function countRulesInDir(rulesDir) {
13230
13266
  }
13231
13267
  function isSamePath(a, b) {
13232
13268
  try {
13233
- return path42.resolve(a) === path42.resolve(b);
13269
+ return path43.resolve(a) === path43.resolve(b);
13234
13270
  } catch {
13235
13271
  return false;
13236
13272
  }
13237
13273
  }
13238
13274
  function countConfigs(cwd) {
13239
13275
  const homeDir2 = os36.homedir();
13240
- const claudeDir = path42.join(homeDir2, ".claude");
13276
+ const claudeDir = path43.join(homeDir2, ".claude");
13241
13277
  let claudeMdCount = 0;
13242
13278
  let rulesCount = 0;
13243
13279
  let hooksCount = 0;
13244
13280
  const userMcpServers = /* @__PURE__ */ new Set();
13245
13281
  const projectMcpServers = /* @__PURE__ */ new Set();
13246
- if (fs39.existsSync(path42.join(claudeDir, "CLAUDE.md"))) claudeMdCount++;
13247
- rulesCount += countRulesInDir(path42.join(claudeDir, "rules"));
13248
- const userSettings = path42.join(claudeDir, "settings.json");
13282
+ if (fs39.existsSync(path43.join(claudeDir, "CLAUDE.md"))) claudeMdCount++;
13283
+ rulesCount += countRulesInDir(path43.join(claudeDir, "rules"));
13284
+ const userSettings = path43.join(claudeDir, "settings.json");
13249
13285
  for (const name of getMcpServerNames(userSettings)) userMcpServers.add(name);
13250
13286
  hooksCount += countHooksInFile(userSettings);
13251
- const userClaudeJson = path42.join(homeDir2, ".claude.json");
13287
+ const userClaudeJson = path43.join(homeDir2, ".claude.json");
13252
13288
  for (const name of getMcpServerNames(userClaudeJson)) userMcpServers.add(name);
13253
13289
  for (const name of getDisabledMcpServers(userClaudeJson, "disabledMcpServers")) {
13254
13290
  userMcpServers.delete(name);
13255
13291
  }
13256
13292
  if (cwd) {
13257
- if (fs39.existsSync(path42.join(cwd, "CLAUDE.md"))) claudeMdCount++;
13258
- if (fs39.existsSync(path42.join(cwd, "CLAUDE.local.md"))) claudeMdCount++;
13259
- const projectClaudeDir = path42.join(cwd, ".claude");
13293
+ if (fs39.existsSync(path43.join(cwd, "CLAUDE.md"))) claudeMdCount++;
13294
+ if (fs39.existsSync(path43.join(cwd, "CLAUDE.local.md"))) claudeMdCount++;
13295
+ const projectClaudeDir = path43.join(cwd, ".claude");
13260
13296
  const overlapsUserScope = isSamePath(projectClaudeDir, claudeDir);
13261
13297
  if (!overlapsUserScope) {
13262
- if (fs39.existsSync(path42.join(projectClaudeDir, "CLAUDE.md"))) claudeMdCount++;
13263
- rulesCount += countRulesInDir(path42.join(projectClaudeDir, "rules"));
13264
- const projSettings = path42.join(projectClaudeDir, "settings.json");
13298
+ if (fs39.existsSync(path43.join(projectClaudeDir, "CLAUDE.md"))) claudeMdCount++;
13299
+ rulesCount += countRulesInDir(path43.join(projectClaudeDir, "rules"));
13300
+ const projSettings = path43.join(projectClaudeDir, "settings.json");
13265
13301
  for (const name of getMcpServerNames(projSettings)) projectMcpServers.add(name);
13266
13302
  hooksCount += countHooksInFile(projSettings);
13267
13303
  }
13268
- if (fs39.existsSync(path42.join(projectClaudeDir, "CLAUDE.local.md"))) claudeMdCount++;
13269
- const localSettings = path42.join(projectClaudeDir, "settings.local.json");
13304
+ if (fs39.existsSync(path43.join(projectClaudeDir, "CLAUDE.local.md"))) claudeMdCount++;
13305
+ const localSettings = path43.join(projectClaudeDir, "settings.local.json");
13270
13306
  for (const name of getMcpServerNames(localSettings)) projectMcpServers.add(name);
13271
13307
  hooksCount += countHooksInFile(localSettings);
13272
- const mcpJsonServers = getMcpServerNames(path42.join(cwd, ".mcp.json"));
13308
+ const mcpJsonServers = getMcpServerNames(path43.join(cwd, ".mcp.json"));
13273
13309
  const disabledMcpJson = getDisabledMcpServers(localSettings, "disabledMcpjsonServers");
13274
13310
  for (const name of disabledMcpJson) mcpJsonServers.delete(name);
13275
13311
  for (const name of mcpJsonServers) projectMcpServers.add(name);
@@ -13302,7 +13338,7 @@ function readActiveShieldsHud() {
13302
13338
  return shieldsCache.value;
13303
13339
  }
13304
13340
  try {
13305
- const shieldsPath = path42.join(os36.homedir(), ".node9", "shields.json");
13341
+ const shieldsPath = path43.join(os36.homedir(), ".node9", "shields.json");
13306
13342
  if (!fs39.existsSync(shieldsPath)) {
13307
13343
  shieldsCache = { value: [], ts: now };
13308
13344
  return [];
@@ -13409,9 +13445,9 @@ function renderContextLine(stdin) {
13409
13445
  async function main() {
13410
13446
  try {
13411
13447
  const [stdin, daemonStatus2] = await Promise.all([readStdin(), queryDaemon()]);
13412
- if (fs39.existsSync(path42.join(os36.homedir(), ".node9", "hud-debug"))) {
13448
+ if (fs39.existsSync(path43.join(os36.homedir(), ".node9", "hud-debug"))) {
13413
13449
  try {
13414
- const logPath = path42.join(os36.homedir(), ".node9", "hud-debug.log");
13450
+ const logPath = path43.join(os36.homedir(), ".node9", "hud-debug.log");
13415
13451
  const MAX_LOG_SIZE = 10 * 1024 * 1024;
13416
13452
  let size = 0;
13417
13453
  try {
@@ -13440,8 +13476,8 @@ async function main() {
13440
13476
  try {
13441
13477
  const cwd = stdin.cwd ?? process.cwd();
13442
13478
  for (const configPath of [
13443
- path42.join(cwd, "node9.config.json"),
13444
- path42.join(os36.homedir(), ".node9", "config.json")
13479
+ path43.join(cwd, "node9.config.json"),
13480
+ path43.join(os36.homedir(), ".node9", "config.json")
13445
13481
  ]) {
13446
13482
  if (!fs39.existsSync(configPath)) continue;
13447
13483
  const cfg = JSON.parse(fs39.readFileSync(configPath, "utf-8"));
@@ -14513,7 +14549,7 @@ function getAgentsStatus(homeDir2 = os11.homedir()) {
14513
14549
  init_daemon2();
14514
14550
  import chalk26 from "chalk";
14515
14551
  import fs40 from "fs";
14516
- import path43 from "path";
14552
+ import path44 from "path";
14517
14553
  import os37 from "os";
14518
14554
  import { confirm as confirm2 } from "@inquirer/prompts";
14519
14555
 
@@ -14705,7 +14741,7 @@ init_policy();
14705
14741
  import chalk6 from "chalk";
14706
14742
  import fs26 from "fs";
14707
14743
  import { spawn as spawn6 } from "child_process";
14708
- import path28 from "path";
14744
+ import path29 from "path";
14709
14745
  import os23 from "os";
14710
14746
 
14711
14747
  // src/undo.ts
@@ -14713,9 +14749,9 @@ import { spawnSync as spawnSync5, spawn as spawn5 } from "child_process";
14713
14749
  import crypto3 from "crypto";
14714
14750
  import fs24 from "fs";
14715
14751
  import net3 from "net";
14716
- import path26 from "path";
14752
+ import path27 from "path";
14717
14753
  import os21 from "os";
14718
- var ACTIVITY_SOCKET_PATH3 = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : path26.join(os21.tmpdir(), "node9-activity.sock");
14754
+ var ACTIVITY_SOCKET_PATH3 = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : path27.join(os21.tmpdir(), "node9-activity.sock");
14719
14755
  function notifySnapshotTaken(hash, tool, argsSummary, fileCount) {
14720
14756
  try {
14721
14757
  const payload = JSON.stringify({
@@ -14735,8 +14771,8 @@ function notifySnapshotTaken(hash, tool, argsSummary, fileCount) {
14735
14771
  } catch {
14736
14772
  }
14737
14773
  }
14738
- var SNAPSHOT_STACK_PATH = path26.join(os21.homedir(), ".node9", "snapshots.json");
14739
- var UNDO_LATEST_PATH = path26.join(os21.homedir(), ".node9", "undo_latest.txt");
14774
+ var SNAPSHOT_STACK_PATH = path27.join(os21.homedir(), ".node9", "snapshots.json");
14775
+ var UNDO_LATEST_PATH = path27.join(os21.homedir(), ".node9", "undo_latest.txt");
14740
14776
  var MAX_SNAPSHOTS = 10;
14741
14777
  var GIT_TIMEOUT = 15e3;
14742
14778
  function readStack() {
@@ -14748,7 +14784,7 @@ function readStack() {
14748
14784
  return [];
14749
14785
  }
14750
14786
  function writeStack(stack) {
14751
- const dir = path26.dirname(SNAPSHOT_STACK_PATH);
14787
+ const dir = path27.dirname(SNAPSHOT_STACK_PATH);
14752
14788
  if (!fs24.existsSync(dir)) fs24.mkdirSync(dir, { recursive: true });
14753
14789
  fs24.writeFileSync(SNAPSHOT_STACK_PATH, JSON.stringify(stack, null, 2));
14754
14790
  }
@@ -14770,12 +14806,12 @@ function buildArgsSummary(tool, args) {
14770
14806
  return "";
14771
14807
  }
14772
14808
  function findProjectRoot(filePath) {
14773
- let dir = path26.dirname(filePath);
14809
+ let dir = path27.dirname(filePath);
14774
14810
  while (true) {
14775
- if (fs24.existsSync(path26.join(dir, ".git")) || fs24.existsSync(path26.join(dir, "package.json"))) {
14811
+ if (fs24.existsSync(path27.join(dir, ".git")) || fs24.existsSync(path27.join(dir, "package.json"))) {
14776
14812
  return dir;
14777
14813
  }
14778
- const parent = path26.dirname(dir);
14814
+ const parent = path27.dirname(dir);
14779
14815
  if (parent === dir) return process.cwd();
14780
14816
  dir = parent;
14781
14817
  }
@@ -14793,14 +14829,14 @@ function normalizeCwdForHash(cwd) {
14793
14829
  }
14794
14830
  function getShadowRepoDir(cwd) {
14795
14831
  const hash = crypto3.createHash("sha256").update(normalizeCwdForHash(cwd)).digest("hex").slice(0, 16);
14796
- return path26.join(os21.homedir(), ".node9", "snapshots", hash);
14832
+ return path27.join(os21.homedir(), ".node9", "snapshots", hash);
14797
14833
  }
14798
14834
  function cleanOrphanedIndexFiles(shadowDir) {
14799
14835
  try {
14800
14836
  const cutoff = Date.now() - 6e4;
14801
14837
  for (const f of fs24.readdirSync(shadowDir)) {
14802
14838
  if (f.startsWith("index_")) {
14803
- const fp = path26.join(shadowDir, f);
14839
+ const fp = path27.join(shadowDir, f);
14804
14840
  try {
14805
14841
  if (fs24.statSync(fp).mtimeMs < cutoff) fs24.unlinkSync(fp);
14806
14842
  } catch {
@@ -14814,7 +14850,7 @@ function writeShadowExcludes(shadowDir, ignorePaths) {
14814
14850
  const hardcoded = [".git", ".node9"];
14815
14851
  const lines = [...hardcoded, ...ignorePaths].join("\n");
14816
14852
  try {
14817
- fs24.writeFileSync(path26.join(shadowDir, "info", "exclude"), lines + "\n", "utf8");
14853
+ fs24.writeFileSync(path27.join(shadowDir, "info", "exclude"), lines + "\n", "utf8");
14818
14854
  } catch {
14819
14855
  }
14820
14856
  }
@@ -14827,7 +14863,7 @@ function ensureShadowRepo(shadowDir, cwd) {
14827
14863
  timeout: 3e3
14828
14864
  });
14829
14865
  if (check.status === 0) {
14830
- const ptPath = path26.join(shadowDir, "project-path.txt");
14866
+ const ptPath = path27.join(shadowDir, "project-path.txt");
14831
14867
  try {
14832
14868
  const stored = fs24.readFileSync(ptPath, "utf8").trim();
14833
14869
  if (stored === normalizedCwd) return true;
@@ -14854,7 +14890,7 @@ function ensureShadowRepo(shadowDir, cwd) {
14854
14890
  if (process.env.NODE9_DEBUG === "1") console.error("[Node9] git init --bare failed:", reason);
14855
14891
  return false;
14856
14892
  }
14857
- const configFile = path26.join(shadowDir, "config");
14893
+ const configFile = path27.join(shadowDir, "config");
14858
14894
  spawnSync5("git", ["config", "--file", configFile, "core.untrackedCache", "true"], {
14859
14895
  timeout: 3e3
14860
14896
  });
@@ -14862,7 +14898,7 @@ function ensureShadowRepo(shadowDir, cwd) {
14862
14898
  timeout: 3e3
14863
14899
  });
14864
14900
  try {
14865
- fs24.writeFileSync(path26.join(shadowDir, "project-path.txt"), normalizedCwd, "utf8");
14901
+ fs24.writeFileSync(path27.join(shadowDir, "project-path.txt"), normalizedCwd, "utf8");
14866
14902
  } catch {
14867
14903
  }
14868
14904
  return true;
@@ -14882,12 +14918,12 @@ async function createShadowSnapshot(tool = "unknown", args = {}, ignorePaths = [
14882
14918
  let indexFile = null;
14883
14919
  try {
14884
14920
  const rawFilePath = extractFilePath(args);
14885
- const absFilePath = rawFilePath && path26.isAbsolute(rawFilePath) ? rawFilePath : null;
14921
+ const absFilePath = rawFilePath && path27.isAbsolute(rawFilePath) ? rawFilePath : null;
14886
14922
  const cwd = absFilePath ? findProjectRoot(absFilePath) : process.cwd();
14887
14923
  const shadowDir = getShadowRepoDir(cwd);
14888
14924
  if (!ensureShadowRepo(shadowDir, cwd)) return null;
14889
14925
  writeShadowExcludes(shadowDir, ignorePaths);
14890
- indexFile = path26.join(shadowDir, `index_${process.pid}_${Date.now()}`);
14926
+ indexFile = path27.join(shadowDir, `index_${process.pid}_${Date.now()}`);
14891
14927
  const shadowEnv = {
14892
14928
  ...process.env,
14893
14929
  GIT_DIR: shadowDir,
@@ -15046,7 +15082,7 @@ function applyUndo(hash, cwd) {
15046
15082
  timeout: GIT_TIMEOUT
15047
15083
  }).stdout?.toString().trim().split("\n").filter(Boolean) ?? [];
15048
15084
  for (const file of [...tracked, ...untracked]) {
15049
- const fullPath = path26.join(dir, file);
15085
+ const fullPath = path27.join(dir, file);
15050
15086
  if (!snapshotFiles.has(file) && fs24.existsSync(fullPath)) {
15051
15087
  fs24.unlinkSync(fullPath);
15052
15088
  }
@@ -15062,11 +15098,11 @@ init_daemon_starter();
15062
15098
 
15063
15099
  // src/skill-pin.ts
15064
15100
  import fs25 from "fs";
15065
- import path27 from "path";
15101
+ import path28 from "path";
15066
15102
  import os22 from "os";
15067
15103
  import crypto4 from "crypto";
15068
15104
  function getPinsFilePath() {
15069
- return path27.join(os22.homedir(), ".node9", "skill-pins.json");
15105
+ return path28.join(os22.homedir(), ".node9", "skill-pins.json");
15070
15106
  }
15071
15107
  var MAX_FILES = 5e3;
15072
15108
  var MAX_TOTAL_BYTES = 50 * 1024 * 1024;
@@ -15087,8 +15123,8 @@ function walkDir(root) {
15087
15123
  entries.sort((a, b) => a.name.localeCompare(b.name));
15088
15124
  for (const entry of entries) {
15089
15125
  if (out.length >= MAX_FILES) return;
15090
- const full = path27.join(dir, entry.name);
15091
- const rel = relDir ? path27.posix.join(relDir, entry.name) : entry.name;
15126
+ const full = path28.join(dir, entry.name);
15127
+ const rel = relDir ? path28.posix.join(relDir, entry.name) : entry.name;
15092
15128
  let lst;
15093
15129
  try {
15094
15130
  lst = fs25.lstatSync(full);
@@ -15162,7 +15198,7 @@ function readSkillPins() {
15162
15198
  }
15163
15199
  function writeSkillPins(data) {
15164
15200
  const filePath = getPinsFilePath();
15165
- fs25.mkdirSync(path27.dirname(filePath), { recursive: true });
15201
+ fs25.mkdirSync(path28.dirname(filePath), { recursive: true });
15166
15202
  const tmp = `${filePath}.${crypto4.randomBytes(6).toString("hex")}.tmp`;
15167
15203
  fs25.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
15168
15204
  fs25.renameSync(tmp, filePath);
@@ -15209,7 +15245,7 @@ function verifyAndPinRoots(roots) {
15209
15245
  return { kind: "verified" };
15210
15246
  }
15211
15247
  function defaultSkillRoots(_cwd) {
15212
- const marketplaces = path27.join(os22.homedir(), ".claude", "plugins", "marketplaces");
15248
+ const marketplaces = path28.join(os22.homedir(), ".claude", "plugins", "marketplaces");
15213
15249
  const roots = [];
15214
15250
  let registries;
15215
15251
  try {
@@ -15219,7 +15255,7 @@ function defaultSkillRoots(_cwd) {
15219
15255
  }
15220
15256
  for (const registry of registries) {
15221
15257
  if (!registry.isDirectory()) continue;
15222
- const pluginsDir = path27.join(marketplaces, registry.name, "plugins");
15258
+ const pluginsDir = path28.join(marketplaces, registry.name, "plugins");
15223
15259
  let plugins;
15224
15260
  try {
15225
15261
  plugins = fs25.readdirSync(pluginsDir, { withFileTypes: true });
@@ -15228,17 +15264,17 @@ function defaultSkillRoots(_cwd) {
15228
15264
  }
15229
15265
  for (const plugin of plugins) {
15230
15266
  if (!plugin.isDirectory()) continue;
15231
- roots.push(path27.join(pluginsDir, plugin.name));
15267
+ roots.push(path28.join(pluginsDir, plugin.name));
15232
15268
  }
15233
15269
  }
15234
15270
  return roots;
15235
15271
  }
15236
15272
  function resolveUserSkillRoot(entry, cwd) {
15237
15273
  if (!entry) return null;
15238
- if (entry.startsWith("~/") || entry === "~") return path27.join(os22.homedir(), entry.slice(1));
15239
- if (path27.isAbsolute(entry)) return entry;
15240
- if (!cwd || !path27.isAbsolute(cwd)) return null;
15241
- return path27.join(cwd, entry);
15274
+ if (entry.startsWith("~/") || entry === "~") return path28.join(os22.homedir(), entry.slice(1));
15275
+ if (path28.isAbsolute(entry)) return entry;
15276
+ if (!cwd || !path28.isAbsolute(cwd)) return null;
15277
+ return path28.join(cwd, entry);
15242
15278
  }
15243
15279
 
15244
15280
  // src/cli/commands/check.ts
@@ -15256,7 +15292,7 @@ function registerCheckCommand(program2) {
15256
15292
  } catch (err2) {
15257
15293
  const tempConfig = getConfig();
15258
15294
  if (process.env.NODE9_DEBUG === "1" || tempConfig.settings.enableHookLogDebug) {
15259
- const logPath = path28.join(os23.homedir(), ".node9", "hook-debug.log");
15295
+ const logPath = path29.join(os23.homedir(), ".node9", "hook-debug.log");
15260
15296
  const errMsg = err2 instanceof Error ? err2.message : String(err2);
15261
15297
  fs26.appendFileSync(
15262
15298
  logPath,
@@ -15271,11 +15307,11 @@ RAW: ${raw}
15271
15307
  if (config.settings.autoStartDaemon && !isDaemonRunning() && !process.env.NODE9_NO_AUTO_DAEMON) {
15272
15308
  try {
15273
15309
  const scriptPath = process.argv[1];
15274
- if (typeof scriptPath !== "string" || !path28.isAbsolute(scriptPath))
15310
+ if (typeof scriptPath !== "string" || !path29.isAbsolute(scriptPath))
15275
15311
  throw new Error("node9: argv[1] is not an absolute path");
15276
15312
  const resolvedScript = fs26.realpathSync(scriptPath);
15277
- const packageDist = fs26.realpathSync(path28.resolve(__dirname, "../.."));
15278
- if (!resolvedScript.startsWith(packageDist + path28.sep) && resolvedScript !== packageDist)
15313
+ const packageDist = fs26.realpathSync(path29.resolve(__dirname, "../.."));
15314
+ if (!resolvedScript.startsWith(packageDist + path29.sep) && resolvedScript !== packageDist)
15279
15315
  throw new Error(
15280
15316
  `node9: daemon spawn aborted \u2014 argv[1] (${resolvedScript}) is outside package dist (${packageDist})`
15281
15317
  );
@@ -15297,7 +15333,7 @@ RAW: ${raw}
15297
15333
  });
15298
15334
  d.unref();
15299
15335
  } catch (spawnErr) {
15300
- const logPath = path28.join(os23.homedir(), ".node9", "hook-debug.log");
15336
+ const logPath = path29.join(os23.homedir(), ".node9", "hook-debug.log");
15301
15337
  const msg = spawnErr instanceof Error ? spawnErr.message : String(spawnErr);
15302
15338
  try {
15303
15339
  fs26.appendFileSync(
@@ -15310,9 +15346,9 @@ RAW: ${raw}
15310
15346
  }
15311
15347
  }
15312
15348
  if (process.env.NODE9_DEBUG === "1" || config.settings.enableHookLogDebug) {
15313
- const logPath = path28.join(os23.homedir(), ".node9", "hook-debug.log");
15314
- if (!fs26.existsSync(path28.dirname(logPath)))
15315
- fs26.mkdirSync(path28.dirname(logPath), { recursive: true });
15349
+ const logPath = path29.join(os23.homedir(), ".node9", "hook-debug.log");
15350
+ if (!fs26.existsSync(path29.dirname(logPath)))
15351
+ fs26.mkdirSync(path29.dirname(logPath), { recursive: true });
15316
15352
  fs26.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${raw}
15317
15353
  `);
15318
15354
  }
@@ -15380,8 +15416,8 @@ RAW: ${raw}
15380
15416
  const safeSessionId = /^[A-Za-z0-9_\-]{1,128}$/.test(rawSessionId) ? rawSessionId : "";
15381
15417
  if (skillPinCfg.enabled && safeSessionId) {
15382
15418
  try {
15383
- const sessionsDir = path28.join(os23.homedir(), ".node9", "skill-sessions");
15384
- const flagPath = path28.join(sessionsDir, `${safeSessionId}.json`);
15419
+ const sessionsDir = path29.join(os23.homedir(), ".node9", "skill-sessions");
15420
+ const flagPath = path29.join(sessionsDir, `${safeSessionId}.json`);
15385
15421
  let flag = null;
15386
15422
  try {
15387
15423
  flag = JSON.parse(fs26.readFileSync(flagPath, "utf-8"));
@@ -15433,7 +15469,7 @@ RAW: ${raw}
15433
15469
  return;
15434
15470
  }
15435
15471
  if (!flag || flag.state !== "verified" && flag.state !== "warned") {
15436
- const absoluteCwd = typeof payload.cwd === "string" && path28.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15472
+ const absoluteCwd = typeof payload.cwd === "string" && path29.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15437
15473
  const extraRoots = skillPinCfg.roots;
15438
15474
  const resolvedExtra = extraRoots.map((r) => resolveUserSkillRoot(r, absoluteCwd)).filter((r) => typeof r === "string");
15439
15475
  const roots = [...defaultSkillRoots(absoluteCwd), ...resolvedExtra];
@@ -15475,7 +15511,7 @@ RAW: ${raw}
15475
15511
  try {
15476
15512
  const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1e3;
15477
15513
  for (const name of fs26.readdirSync(sessionsDir)) {
15478
- const p = path28.join(sessionsDir, name);
15514
+ const p = path29.join(sessionsDir, name);
15479
15515
  try {
15480
15516
  if (fs26.statSync(p).mtimeMs < cutoff) fs26.unlinkSync(p);
15481
15517
  } catch {
@@ -15487,7 +15523,7 @@ RAW: ${raw}
15487
15523
  } catch (err2) {
15488
15524
  if (process.env.NODE9_DEBUG === "1") {
15489
15525
  try {
15490
- const dbg = path28.join(os23.homedir(), ".node9", "hook-debug.log");
15526
+ const dbg = path29.join(os23.homedir(), ".node9", "hook-debug.log");
15491
15527
  const msg = err2 instanceof Error ? err2.message : String(err2);
15492
15528
  fs26.appendFileSync(dbg, `[${(/* @__PURE__ */ new Date()).toISOString()}] SKILL_PIN_ERROR: ${msg}
15493
15529
  `);
@@ -15499,7 +15535,7 @@ RAW: ${raw}
15499
15535
  if (shouldSnapshot(toolName, toolInput, config)) {
15500
15536
  await createShadowSnapshot(toolName, toolInput, config.policy.snapshot.ignorePaths);
15501
15537
  }
15502
- const safeCwdForAuth = typeof payload.cwd === "string" && path28.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15538
+ const safeCwdForAuth = typeof payload.cwd === "string" && path29.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15503
15539
  const result = await authorizeHeadless(toolName, toolInput, meta, {
15504
15540
  cwd: safeCwdForAuth
15505
15541
  });
@@ -15543,7 +15579,7 @@ RAW: ${raw}
15543
15579
  });
15544
15580
  } catch (err2) {
15545
15581
  if (process.env.NODE9_DEBUG === "1") {
15546
- const logPath = path28.join(os23.homedir(), ".node9", "hook-debug.log");
15582
+ const logPath = path29.join(os23.homedir(), ".node9", "hook-debug.log");
15547
15583
  const errMsg = err2 instanceof Error ? err2.message : String(err2);
15548
15584
  fs26.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] ERROR: ${errMsg}
15549
15585
  `);
@@ -15582,7 +15618,7 @@ RAW: ${raw}
15582
15618
  init_audit();
15583
15619
  init_config();
15584
15620
  import fs27 from "fs";
15585
- import path29 from "path";
15621
+ import path30 from "path";
15586
15622
  import os24 from "os";
15587
15623
  init_daemon();
15588
15624
 
@@ -15656,9 +15692,9 @@ function registerLogCommand(program2) {
15656
15692
  decision: "allowed",
15657
15693
  source: "post-hook"
15658
15694
  };
15659
- const logPath = path29.join(os24.homedir(), ".node9", "audit.log");
15660
- if (!fs27.existsSync(path29.dirname(logPath)))
15661
- fs27.mkdirSync(path29.dirname(logPath), { recursive: true });
15695
+ const logPath = path30.join(os24.homedir(), ".node9", "audit.log");
15696
+ if (!fs27.existsSync(path30.dirname(logPath)))
15697
+ fs27.mkdirSync(path30.dirname(logPath), { recursive: true });
15662
15698
  fs27.appendFileSync(logPath, JSON.stringify(entry) + "\n");
15663
15699
  if ((tool === "Bash" || tool === "bash") && isDaemonRunning()) {
15664
15700
  const command = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
@@ -15692,7 +15728,7 @@ function registerLogCommand(program2) {
15692
15728
  }
15693
15729
  }
15694
15730
  }
15695
- const safeCwd = typeof payload.cwd === "string" && path29.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15731
+ const safeCwd = typeof payload.cwd === "string" && path30.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15696
15732
  const config = getConfig(safeCwd);
15697
15733
  if ((tool === "Bash" || tool === "bash") && config.settings.enableUndo !== false) {
15698
15734
  const bashCommand = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
@@ -15713,7 +15749,7 @@ function registerLogCommand(program2) {
15713
15749
  const msg = err2 instanceof Error ? err2.message : String(err2);
15714
15750
  process.stderr.write(`[Node9] audit log error: ${msg}
15715
15751
  `);
15716
- const debugPath = path29.join(os24.homedir(), ".node9", "hook-debug.log");
15752
+ const debugPath = path30.join(os24.homedir(), ".node9", "hook-debug.log");
15717
15753
  try {
15718
15754
  fs27.appendFileSync(debugPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] LOG_ERROR: ${msg}
15719
15755
  `);
@@ -16117,7 +16153,7 @@ function registerConfigShowCommand(program2) {
16117
16153
  init_daemon();
16118
16154
  import chalk8 from "chalk";
16119
16155
  import fs28 from "fs";
16120
- import path30 from "path";
16156
+ import path31 from "path";
16121
16157
  import os25 from "os";
16122
16158
  import { execSync as execSync2 } from "child_process";
16123
16159
  function registerDoctorCommand(program2, version2) {
@@ -16171,7 +16207,7 @@ function registerDoctorCommand(program2, version2) {
16171
16207
  );
16172
16208
  }
16173
16209
  section("Configuration");
16174
- const globalConfigPath = path30.join(homeDir2, ".node9", "config.json");
16210
+ const globalConfigPath = path31.join(homeDir2, ".node9", "config.json");
16175
16211
  if (fs28.existsSync(globalConfigPath)) {
16176
16212
  try {
16177
16213
  JSON.parse(fs28.readFileSync(globalConfigPath, "utf-8"));
@@ -16182,7 +16218,7 @@ function registerDoctorCommand(program2, version2) {
16182
16218
  } else {
16183
16219
  warn("~/.node9/config.json not found (using defaults)", "Run: node9 init");
16184
16220
  }
16185
- const projectConfigPath = path30.join(process.cwd(), "node9.config.json");
16221
+ const projectConfigPath = path31.join(process.cwd(), "node9.config.json");
16186
16222
  if (fs28.existsSync(projectConfigPath)) {
16187
16223
  try {
16188
16224
  JSON.parse(fs28.readFileSync(projectConfigPath, "utf-8"));
@@ -16194,7 +16230,7 @@ function registerDoctorCommand(program2, version2) {
16194
16230
  );
16195
16231
  }
16196
16232
  }
16197
- const credsPath = path30.join(homeDir2, ".node9", "credentials.json");
16233
+ const credsPath = path31.join(homeDir2, ".node9", "credentials.json");
16198
16234
  if (fs28.existsSync(credsPath)) {
16199
16235
  pass("Cloud credentials found (~/.node9/credentials.json)");
16200
16236
  } else {
@@ -16204,7 +16240,7 @@ function registerDoctorCommand(program2, version2) {
16204
16240
  );
16205
16241
  }
16206
16242
  section("Agent Hooks");
16207
- const claudeSettingsPath = path30.join(homeDir2, ".claude", "settings.json");
16243
+ const claudeSettingsPath = path31.join(homeDir2, ".claude", "settings.json");
16208
16244
  if (fs28.existsSync(claudeSettingsPath)) {
16209
16245
  try {
16210
16246
  const cs = JSON.parse(fs28.readFileSync(claudeSettingsPath, "utf-8"));
@@ -16223,7 +16259,7 @@ function registerDoctorCommand(program2, version2) {
16223
16259
  } else {
16224
16260
  warn("Claude Code \u2014 not configured", "Run: node9 setup claude");
16225
16261
  }
16226
- const geminiSettingsPath = path30.join(homeDir2, ".gemini", "settings.json");
16262
+ const geminiSettingsPath = path31.join(homeDir2, ".gemini", "settings.json");
16227
16263
  if (fs28.existsSync(geminiSettingsPath)) {
16228
16264
  try {
16229
16265
  const gs = JSON.parse(fs28.readFileSync(geminiSettingsPath, "utf-8"));
@@ -16242,7 +16278,7 @@ function registerDoctorCommand(program2, version2) {
16242
16278
  } else {
16243
16279
  warn("Gemini CLI \u2014 not configured", "Run: node9 setup gemini (skip if not using Gemini)");
16244
16280
  }
16245
- const cursorHooksPath = path30.join(homeDir2, ".cursor", "hooks.json");
16281
+ const cursorHooksPath = path31.join(homeDir2, ".cursor", "hooks.json");
16246
16282
  if (fs28.existsSync(cursorHooksPath)) {
16247
16283
  try {
16248
16284
  const cur = JSON.parse(fs28.readFileSync(cursorHooksPath, "utf-8"));
@@ -16284,7 +16320,7 @@ function registerDoctorCommand(program2, version2) {
16284
16320
  // src/cli/commands/audit.ts
16285
16321
  import chalk9 from "chalk";
16286
16322
  import fs29 from "fs";
16287
- import path31 from "path";
16323
+ import path32 from "path";
16288
16324
  import os26 from "os";
16289
16325
  function formatRelativeTime(timestamp) {
16290
16326
  const diff = Date.now() - new Date(timestamp).getTime();
@@ -16298,7 +16334,7 @@ function formatRelativeTime(timestamp) {
16298
16334
  }
16299
16335
  function registerAuditCommand(program2) {
16300
16336
  program2.command("audit").description("View local execution audit log").option("--tail <n>", "Number of entries to show", "20").option("--tool <pattern>", "Filter by tool name (substring match)").option("--deny", "Show only denied actions").option("--json", "Output raw JSON").action((options) => {
16301
- const logPath = path31.join(os26.homedir(), ".node9", "audit.log");
16337
+ const logPath = path32.join(os26.homedir(), ".node9", "audit.log");
16302
16338
  if (!fs29.existsSync(logPath)) {
16303
16339
  console.log(
16304
16340
  chalk9.yellow("No audit logs found. Run node9 with an agent to generate entries.")
@@ -16360,7 +16396,7 @@ function registerAuditCommand(program2) {
16360
16396
  // src/cli/commands/report.ts
16361
16397
  import chalk10 from "chalk";
16362
16398
  import fs30 from "fs";
16363
- import path32 from "path";
16399
+ import path33 from "path";
16364
16400
  import os27 from "os";
16365
16401
  var TEST_COMMAND_RE3 = /(?:^|\s)(npm\s+(?:run\s+)?test|npx\s+(?:vitest|jest|mocha)|yarn\s+(?:run\s+)?test|pnpm\s+(?:run\s+)?test|vitest|jest|mocha|pytest|py\.test|cargo\s+test|go\s+test|bundle\s+exec\s+rspec|rspec|phpunit|dotnet\s+test)\b/i;
16366
16402
  function buildTestTimestamps(allEntries) {
@@ -16488,7 +16524,7 @@ function loadClaudeCost(start, end) {
16488
16524
  cacheWriteTokens: 0,
16489
16525
  cacheReadTokens: 0
16490
16526
  };
16491
- const projectsDir = path32.join(os27.homedir(), ".claude", "projects");
16527
+ const projectsDir = path33.join(os27.homedir(), ".claude", "projects");
16492
16528
  if (!fs30.existsSync(projectsDir)) return empty;
16493
16529
  let dirs;
16494
16530
  try {
@@ -16504,7 +16540,7 @@ function loadClaudeCost(start, end) {
16504
16540
  const byDay = /* @__PURE__ */ new Map();
16505
16541
  const byModel = /* @__PURE__ */ new Map();
16506
16542
  for (const proj of dirs) {
16507
- const projPath = path32.join(projectsDir, proj);
16543
+ const projPath = path33.join(projectsDir, proj);
16508
16544
  let files;
16509
16545
  try {
16510
16546
  const stat = fs30.statSync(projPath);
@@ -16515,7 +16551,7 @@ function loadClaudeCost(start, end) {
16515
16551
  }
16516
16552
  for (const file of files) {
16517
16553
  try {
16518
- const raw = fs30.readFileSync(path32.join(projPath, file), "utf-8");
16554
+ const raw = fs30.readFileSync(path33.join(projPath, file), "utf-8");
16519
16555
  for (const line of raw.split("\n")) {
16520
16556
  if (!line.trim()) continue;
16521
16557
  let entry;
@@ -16556,7 +16592,7 @@ function loadClaudeCost(start, end) {
16556
16592
  return { total, byDay, byModel, inputTokens, outputTokens, cacheWriteTokens, cacheReadTokens };
16557
16593
  }
16558
16594
  function loadCodexCost(start, end) {
16559
- const sessionsBase = path32.join(os27.homedir(), ".codex", "sessions");
16595
+ const sessionsBase = path33.join(os27.homedir(), ".codex", "sessions");
16560
16596
  const byDay = /* @__PURE__ */ new Map();
16561
16597
  let total = 0;
16562
16598
  let toolCalls = 0;
@@ -16564,28 +16600,28 @@ function loadCodexCost(start, end) {
16564
16600
  const jsonlFiles = [];
16565
16601
  try {
16566
16602
  for (const year of fs30.readdirSync(sessionsBase)) {
16567
- const yearPath = path32.join(sessionsBase, year);
16603
+ const yearPath = path33.join(sessionsBase, year);
16568
16604
  try {
16569
16605
  if (!fs30.statSync(yearPath).isDirectory()) continue;
16570
16606
  } catch {
16571
16607
  continue;
16572
16608
  }
16573
16609
  for (const month of fs30.readdirSync(yearPath)) {
16574
- const monthPath = path32.join(yearPath, month);
16610
+ const monthPath = path33.join(yearPath, month);
16575
16611
  try {
16576
16612
  if (!fs30.statSync(monthPath).isDirectory()) continue;
16577
16613
  } catch {
16578
16614
  continue;
16579
16615
  }
16580
16616
  for (const day of fs30.readdirSync(monthPath)) {
16581
- const dayPath = path32.join(monthPath, day);
16617
+ const dayPath = path33.join(monthPath, day);
16582
16618
  try {
16583
16619
  if (!fs30.statSync(dayPath).isDirectory()) continue;
16584
16620
  } catch {
16585
16621
  continue;
16586
16622
  }
16587
16623
  for (const file of fs30.readdirSync(dayPath)) {
16588
- if (file.endsWith(".jsonl")) jsonlFiles.push(path32.join(dayPath, file));
16624
+ if (file.endsWith(".jsonl")) jsonlFiles.push(path33.join(dayPath, file));
16589
16625
  }
16590
16626
  }
16591
16627
  }
@@ -16646,7 +16682,7 @@ function registerReportCommand(program2) {
16646
16682
  const period = ["today", "7d", "30d", "month"].includes(
16647
16683
  options.period
16648
16684
  ) ? options.period : "7d";
16649
- const logPath = path32.join(os27.homedir(), ".node9", "audit.log");
16685
+ const logPath = path33.join(os27.homedir(), ".node9", "audit.log");
16650
16686
  const allEntries = parseAuditLog(logPath);
16651
16687
  const unackedDlp = allEntries.filter((e) => e.source === "response-dlp");
16652
16688
  if (unackedDlp.length > 0) {
@@ -17154,7 +17190,7 @@ init_core();
17154
17190
  init_daemon();
17155
17191
  import chalk12 from "chalk";
17156
17192
  import fs31 from "fs";
17157
- import path33 from "path";
17193
+ import path34 from "path";
17158
17194
  import os28 from "os";
17159
17195
  function readJson2(filePath) {
17160
17196
  try {
@@ -17223,8 +17259,8 @@ function registerStatusCommand(program2) {
17223
17259
  console.log("");
17224
17260
  const modeLabel = settings.mode === "audit" ? chalk12.blue("audit") : settings.mode === "strict" ? chalk12.red("strict") : chalk12.white("standard");
17225
17261
  console.log(` Mode: ${modeLabel}`);
17226
- const projectConfig = path33.join(process.cwd(), "node9.config.json");
17227
- const globalConfig = path33.join(os28.homedir(), ".node9", "config.json");
17262
+ const projectConfig = path34.join(process.cwd(), "node9.config.json");
17263
+ const globalConfig = path34.join(os28.homedir(), ".node9", "config.json");
17228
17264
  console.log(
17229
17265
  ` Local: ${fs31.existsSync(projectConfig) ? chalk12.green("Active (node9.config.json)") : chalk12.gray("Not present")}`
17230
17266
  );
@@ -17238,13 +17274,13 @@ function registerStatusCommand(program2) {
17238
17274
  }
17239
17275
  const homeDir2 = os28.homedir();
17240
17276
  const claudeSettings = readJson2(
17241
- path33.join(homeDir2, ".claude", "settings.json")
17277
+ path34.join(homeDir2, ".claude", "settings.json")
17242
17278
  );
17243
- const claudeConfig = readJson2(path33.join(homeDir2, ".claude.json"));
17279
+ const claudeConfig = readJson2(path34.join(homeDir2, ".claude.json"));
17244
17280
  const geminiSettings = readJson2(
17245
- path33.join(homeDir2, ".gemini", "settings.json")
17281
+ path34.join(homeDir2, ".gemini", "settings.json")
17246
17282
  );
17247
- const cursorConfig = readJson2(path33.join(homeDir2, ".cursor", "mcp.json"));
17283
+ const cursorConfig = readJson2(path34.join(homeDir2, ".cursor", "mcp.json"));
17248
17284
  const agentFound = claudeSettings || claudeConfig || geminiSettings || cursorConfig;
17249
17285
  if (agentFound) {
17250
17286
  console.log("");
@@ -17305,7 +17341,7 @@ function registerStatusCommand(program2) {
17305
17341
  init_core();
17306
17342
  import chalk13 from "chalk";
17307
17343
  import fs32 from "fs";
17308
- import path34 from "path";
17344
+ import path35 from "path";
17309
17345
  import os29 from "os";
17310
17346
  import https3 from "https";
17311
17347
  init_shields();
@@ -17366,7 +17402,7 @@ function registerInitCommand(program2) {
17366
17402
  }
17367
17403
  console.log("");
17368
17404
  }
17369
- const configPath = path34.join(os29.homedir(), ".node9", "config.json");
17405
+ const configPath = path35.join(os29.homedir(), ".node9", "config.json");
17370
17406
  if (fs32.existsSync(configPath) && !options.force) {
17371
17407
  try {
17372
17408
  const existing = JSON.parse(fs32.readFileSync(configPath, "utf-8"));
@@ -17387,7 +17423,7 @@ function registerInitCommand(program2) {
17387
17423
  ...DEFAULT_CONFIG,
17388
17424
  settings: { ...DEFAULT_CONFIG.settings, mode: chosenMode }
17389
17425
  };
17390
- const dir = path34.dirname(configPath);
17426
+ const dir = path35.dirname(configPath);
17391
17427
  if (!fs32.existsSync(dir)) fs32.mkdirSync(dir, { recursive: true });
17392
17428
  fs32.writeFileSync(configPath, JSON.stringify(configToSave, null, 2) + "\n");
17393
17429
  console.log(chalk13.green(`\u2705 Config created: ${configPath}`));
@@ -17474,7 +17510,7 @@ function registerInitCommand(program2) {
17474
17510
  }
17475
17511
 
17476
17512
  // src/cli/commands/undo.ts
17477
- import path35 from "path";
17513
+ import path36 from "path";
17478
17514
  import chalk15 from "chalk";
17479
17515
 
17480
17516
  // src/tui/undo-navigator.ts
@@ -17633,7 +17669,7 @@ function findMatchingCwd(startDir, history) {
17633
17669
  let dir = startDir;
17634
17670
  while (true) {
17635
17671
  if (cwds.has(dir)) return dir;
17636
- const parent = path35.dirname(dir);
17672
+ const parent = path36.dirname(dir);
17637
17673
  if (parent === dir) return null;
17638
17674
  dir = parent;
17639
17675
  }
@@ -17830,11 +17866,11 @@ init_provenance();
17830
17866
 
17831
17867
  // src/mcp-pin.ts
17832
17868
  import fs33 from "fs";
17833
- import path36 from "path";
17869
+ import path37 from "path";
17834
17870
  import os30 from "os";
17835
17871
  import crypto5 from "crypto";
17836
17872
  function getPinsFilePath2() {
17837
- return path36.join(os30.homedir(), ".node9", "mcp-pins.json");
17873
+ return path37.join(os30.homedir(), ".node9", "mcp-pins.json");
17838
17874
  }
17839
17875
  function hashToolDefinitions(tools) {
17840
17876
  const sorted = [...tools].sort((a, b) => {
@@ -17875,7 +17911,7 @@ function readMcpPins() {
17875
17911
  }
17876
17912
  function writeMcpPins(data) {
17877
17913
  const filePath = getPinsFilePath2();
17878
- fs33.mkdirSync(path36.dirname(filePath), { recursive: true });
17914
+ fs33.mkdirSync(path37.dirname(filePath), { recursive: true });
17879
17915
  const tmp = `${filePath}.${crypto5.randomBytes(6).toString("hex")}.tmp`;
17880
17916
  fs33.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
17881
17917
  fs33.renameSync(tmp, filePath);
@@ -18328,7 +18364,7 @@ function registerMcpGatewayCommand(program2) {
18328
18364
  import readline4 from "readline";
18329
18365
  import fs34 from "fs";
18330
18366
  import os31 from "os";
18331
- import path37 from "path";
18367
+ import path38 from "path";
18332
18368
  import { spawnSync as spawnSync7 } from "child_process";
18333
18369
  init_core();
18334
18370
  init_daemon();
@@ -18579,8 +18615,8 @@ function handleStatus() {
18579
18615
  lines.push(`Active shields: ${activeShields.length > 0 ? activeShields.join(", ") : "none"}`);
18580
18616
  lines.push(`Smart rules: ${config.policy.smartRules.length} loaded`);
18581
18617
  lines.push(`DLP: ${config.policy.dlp?.enabled !== false ? "enabled" : "disabled"}`);
18582
- const projectConfig = path37.join(process.cwd(), "node9.config.json");
18583
- const globalConfig = path37.join(os31.homedir(), ".node9", "config.json");
18618
+ const projectConfig = path38.join(process.cwd(), "node9.config.json");
18619
+ const globalConfig = path38.join(os31.homedir(), ".node9", "config.json");
18584
18620
  lines.push(
18585
18621
  `Project config (node9.config.json): ${fs34.existsSync(projectConfig) ? "present" : "not found"}`
18586
18622
  );
@@ -18659,7 +18695,7 @@ function handleShieldDisable(args) {
18659
18695
  writeActiveShields(active.filter((s) => s !== name));
18660
18696
  return `Shield "${name}" disabled.`;
18661
18697
  }
18662
- var GLOBAL_CONFIG_PATH2 = path37.join(os31.homedir(), ".node9", "config.json");
18698
+ var GLOBAL_CONFIG_PATH2 = path38.join(os31.homedir(), ".node9", "config.json");
18663
18699
  var APPROVER_CHANNELS = ["native", "browser", "cloud", "terminal"];
18664
18700
  function readGlobalConfigRaw() {
18665
18701
  try {
@@ -18671,7 +18707,7 @@ function readGlobalConfigRaw() {
18671
18707
  return {};
18672
18708
  }
18673
18709
  function writeGlobalConfigRaw(data) {
18674
- const dir = path37.dirname(GLOBAL_CONFIG_PATH2);
18710
+ const dir = path38.dirname(GLOBAL_CONFIG_PATH2);
18675
18711
  if (!fs34.existsSync(dir)) fs34.mkdirSync(dir, { recursive: true });
18676
18712
  fs34.writeFileSync(GLOBAL_CONFIG_PATH2, JSON.stringify(data, null, 2) + "\n");
18677
18713
  }
@@ -18717,7 +18753,7 @@ function handleApproverSet(args) {
18717
18753
  function handleAuditGet(args) {
18718
18754
  const limit = Math.min(typeof args.limit === "number" ? args.limit : 20, 100);
18719
18755
  const filter = typeof args.filter === "string" && args.filter !== "all" ? args.filter : null;
18720
- const auditPath = path37.join(os31.homedir(), ".node9", "audit.log");
18756
+ const auditPath = path38.join(os31.homedir(), ".node9", "audit.log");
18721
18757
  if (!fs34.existsSync(auditPath)) return "No audit log found.";
18722
18758
  const rawLines = fs34.readFileSync(auditPath, "utf-8").trim().split("\n").filter(Boolean);
18723
18759
  const parsed = [];
@@ -19274,7 +19310,7 @@ init_scan();
19274
19310
  // src/cli/commands/sessions.ts
19275
19311
  import chalk22 from "chalk";
19276
19312
  import fs35 from "fs";
19277
- import path38 from "path";
19313
+ import path39 from "path";
19278
19314
  import os32 from "os";
19279
19315
  var CLAUDE_PRICING3 = {
19280
19316
  "claude-opus-4-6": { i: 5e-6, o: 25e-6, cw: 625e-8, cr: 5e-7 },
@@ -19316,7 +19352,7 @@ function encodeProjectPath(projectPath) {
19316
19352
  }
19317
19353
  function sessionJsonlPath(projectPath, sessionId) {
19318
19354
  const encoded = encodeProjectPath(projectPath);
19319
- return path38.join(os32.homedir(), ".claude", "projects", encoded, `${sessionId}.jsonl`);
19355
+ return path39.join(os32.homedir(), ".claude", "projects", encoded, `${sessionId}.jsonl`);
19320
19356
  }
19321
19357
  function projectLabel(projectPath) {
19322
19358
  return projectPath.replace(os32.homedir(), "~");
@@ -19388,7 +19424,7 @@ function parseSessionLines(lines) {
19388
19424
  return { toolCalls, costUSD, hasSnapshot, modifiedFiles };
19389
19425
  }
19390
19426
  function loadAuditEntries(auditPath) {
19391
- const aPath = auditPath ?? path38.join(os32.homedir(), ".node9", "audit.log");
19427
+ const aPath = auditPath ?? path39.join(os32.homedir(), ".node9", "audit.log");
19392
19428
  let raw;
19393
19429
  try {
19394
19430
  raw = fs35.readFileSync(aPath, "utf-8");
@@ -19427,7 +19463,7 @@ function auditEntriesInWindow(entries, windowStart, windowEnd) {
19427
19463
  return result;
19428
19464
  }
19429
19465
  function buildGeminiSessions(days, allAuditEntries) {
19430
- const tmpDir = path38.join(os32.homedir(), ".gemini", "tmp");
19466
+ const tmpDir = path39.join(os32.homedir(), ".gemini", "tmp");
19431
19467
  if (!fs35.existsSync(tmpDir)) return [];
19432
19468
  const cutoff = days !== null ? (() => {
19433
19469
  const d = /* @__PURE__ */ new Date();
@@ -19443,18 +19479,18 @@ function buildGeminiSessions(days, allAuditEntries) {
19443
19479
  }
19444
19480
  const summaries = [];
19445
19481
  for (const slug of slugDirs) {
19446
- const slugPath = path38.join(tmpDir, slug);
19482
+ const slugPath = path39.join(tmpDir, slug);
19447
19483
  try {
19448
19484
  if (!fs35.statSync(slugPath).isDirectory()) continue;
19449
19485
  } catch {
19450
19486
  continue;
19451
19487
  }
19452
- let projectRoot = path38.join(os32.homedir(), slug);
19488
+ let projectRoot = path39.join(os32.homedir(), slug);
19453
19489
  try {
19454
- projectRoot = fs35.readFileSync(path38.join(slugPath, ".project_root"), "utf-8").trim();
19490
+ projectRoot = fs35.readFileSync(path39.join(slugPath, ".project_root"), "utf-8").trim();
19455
19491
  } catch {
19456
19492
  }
19457
- const chatsDir = path38.join(slugPath, "chats");
19493
+ const chatsDir = path39.join(slugPath, "chats");
19458
19494
  if (!fs35.existsSync(chatsDir)) continue;
19459
19495
  let chatFiles;
19460
19496
  try {
@@ -19465,7 +19501,7 @@ function buildGeminiSessions(days, allAuditEntries) {
19465
19501
  for (const chatFile of chatFiles) {
19466
19502
  let raw;
19467
19503
  try {
19468
- raw = fs35.readFileSync(path38.join(chatsDir, chatFile), "utf-8");
19504
+ raw = fs35.readFileSync(path39.join(chatsDir, chatFile), "utf-8");
19469
19505
  } catch {
19470
19506
  continue;
19471
19507
  }
@@ -19545,7 +19581,7 @@ function buildGeminiSessions(days, allAuditEntries) {
19545
19581
  return summaries;
19546
19582
  }
19547
19583
  function buildCodexSessions(days, allAuditEntries) {
19548
- const sessionsBase = path38.join(os32.homedir(), ".codex", "sessions");
19584
+ const sessionsBase = path39.join(os32.homedir(), ".codex", "sessions");
19549
19585
  if (!fs35.existsSync(sessionsBase)) return [];
19550
19586
  const cutoff = days !== null ? (() => {
19551
19587
  const d = /* @__PURE__ */ new Date();
@@ -19556,28 +19592,28 @@ function buildCodexSessions(days, allAuditEntries) {
19556
19592
  const jsonlFiles = [];
19557
19593
  try {
19558
19594
  for (const year of fs35.readdirSync(sessionsBase)) {
19559
- const yearPath = path38.join(sessionsBase, year);
19595
+ const yearPath = path39.join(sessionsBase, year);
19560
19596
  try {
19561
19597
  if (!fs35.statSync(yearPath).isDirectory()) continue;
19562
19598
  } catch {
19563
19599
  continue;
19564
19600
  }
19565
19601
  for (const month of fs35.readdirSync(yearPath)) {
19566
- const monthPath = path38.join(yearPath, month);
19602
+ const monthPath = path39.join(yearPath, month);
19567
19603
  try {
19568
19604
  if (!fs35.statSync(monthPath).isDirectory()) continue;
19569
19605
  } catch {
19570
19606
  continue;
19571
19607
  }
19572
19608
  for (const day of fs35.readdirSync(monthPath)) {
19573
- const dayPath = path38.join(monthPath, day);
19609
+ const dayPath = path39.join(monthPath, day);
19574
19610
  try {
19575
19611
  if (!fs35.statSync(dayPath).isDirectory()) continue;
19576
19612
  } catch {
19577
19613
  continue;
19578
19614
  }
19579
19615
  for (const file of fs35.readdirSync(dayPath)) {
19580
- if (file.endsWith(".jsonl")) jsonlFiles.push(path38.join(dayPath, file));
19616
+ if (file.endsWith(".jsonl")) jsonlFiles.push(path39.join(dayPath, file));
19581
19617
  }
19582
19618
  }
19583
19619
  }
@@ -19667,7 +19703,7 @@ function buildCodexSessions(days, allAuditEntries) {
19667
19703
  return summaries;
19668
19704
  }
19669
19705
  function buildSessions(days, historyPath) {
19670
- const hPath = historyPath ?? path38.join(os32.homedir(), ".claude", "history.jsonl");
19706
+ const hPath = historyPath ?? path39.join(os32.homedir(), ".claude", "history.jsonl");
19671
19707
  let historyRaw;
19672
19708
  try {
19673
19709
  historyRaw = fs35.readFileSync(hPath, "utf-8");
@@ -19961,7 +19997,7 @@ function registerSessionsCommand(program2) {
19961
19997
  console.log("");
19962
19998
  console.log(chalk22.cyan.bold("\u{1F4CB} node9 sessions") + chalk22.dim(" \u2014 what your AI agent did"));
19963
19999
  console.log("");
19964
- const historyPath = path38.join(os32.homedir(), ".claude", "history.jsonl");
20000
+ const historyPath = path39.join(os32.homedir(), ".claude", "history.jsonl");
19965
20001
  if (!fs35.existsSync(historyPath)) {
19966
20002
  console.log(chalk22.yellow(" No Claude session history found at ~/.claude/history.jsonl"));
19967
20003
  console.log(chalk22.gray(" Install Claude Code, run a few sessions, then try again.\n"));
@@ -20001,10 +20037,10 @@ function registerSessionsCommand(program2) {
20001
20037
  import chalk23 from "chalk";
20002
20038
  import fs36 from "fs";
20003
20039
  import os33 from "os";
20004
- import path39 from "path";
20040
+ import path40 from "path";
20005
20041
  function wipeSkillSessions() {
20006
20042
  try {
20007
- fs36.rmSync(path39.join(os33.homedir(), ".node9", "skill-sessions"), {
20043
+ fs36.rmSync(path40.join(os33.homedir(), ".node9", "skill-sessions"), {
20008
20044
  recursive: true,
20009
20045
  force: true
20010
20046
  });
@@ -20088,10 +20124,10 @@ function registerSkillPinCommand(program2) {
20088
20124
  // src/cli/commands/dlp.ts
20089
20125
  import chalk24 from "chalk";
20090
20126
  import fs37 from "fs";
20091
- import path40 from "path";
20127
+ import path41 from "path";
20092
20128
  import os34 from "os";
20093
- var AUDIT_LOG = path40.join(os34.homedir(), ".node9", "audit.log");
20094
- var RESOLVED_FILE = path40.join(os34.homedir(), ".node9", "dlp-resolved.json");
20129
+ var AUDIT_LOG = path41.join(os34.homedir(), ".node9", "audit.log");
20130
+ var RESOLVED_FILE = path41.join(os34.homedir(), ".node9", "dlp-resolved.json");
20095
20131
  var ANSI_RE = /\x1b(?:\[[0-9;?]*[a-zA-Z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[@-_])/g;
20096
20132
  function stripAnsi(s) {
20097
20133
  return s.replace(ANSI_RE, "");
@@ -20210,15 +20246,15 @@ function registerDlpCommand(program2) {
20210
20246
 
20211
20247
  // src/cli.ts
20212
20248
  var { version } = JSON.parse(
20213
- fs40.readFileSync(path43.join(__dirname, "../package.json"), "utf-8")
20249
+ fs40.readFileSync(path44.join(__dirname, "../package.json"), "utf-8")
20214
20250
  );
20215
20251
  var program = new Command();
20216
20252
  program.name("node9").description("The Sudo Command for AI Agents").version(version);
20217
20253
  program.command("login").argument("<apiKey>").option("--local", "Save key for audit/logging only \u2014 local config still controls all decisions").option("--profile <name>", 'Save as a named profile (default: "default")').action((apiKey, options) => {
20218
20254
  const DEFAULT_API_URL2 = "https://api.node9.ai/api/v1/intercept";
20219
- const credPath = path43.join(os37.homedir(), ".node9", "credentials.json");
20220
- if (!fs40.existsSync(path43.dirname(credPath)))
20221
- fs40.mkdirSync(path43.dirname(credPath), { recursive: true });
20255
+ const credPath = path44.join(os37.homedir(), ".node9", "credentials.json");
20256
+ if (!fs40.existsSync(path44.dirname(credPath)))
20257
+ fs40.mkdirSync(path44.dirname(credPath), { recursive: true });
20222
20258
  const profileName = options.profile || "default";
20223
20259
  let existingCreds = {};
20224
20260
  try {
@@ -20237,7 +20273,7 @@ program.command("login").argument("<apiKey>").option("--local", "Save key for au
20237
20273
  existingCreds[profileName] = { apiKey, apiUrl: DEFAULT_API_URL2 };
20238
20274
  fs40.writeFileSync(credPath, JSON.stringify(existingCreds, null, 2), { mode: 384 });
20239
20275
  if (profileName === "default") {
20240
- const configPath = path43.join(os37.homedir(), ".node9", "config.json");
20276
+ const configPath = path44.join(os37.homedir(), ".node9", "config.json");
20241
20277
  let config = {};
20242
20278
  try {
20243
20279
  if (fs40.existsSync(configPath))
@@ -20256,8 +20292,8 @@ program.command("login").argument("<apiKey>").option("--local", "Save key for au
20256
20292
  approvers.cloud = false;
20257
20293
  }
20258
20294
  s.approvers = approvers;
20259
- if (!fs40.existsSync(path43.dirname(configPath)))
20260
- fs40.mkdirSync(path43.dirname(configPath), { recursive: true });
20295
+ if (!fs40.existsSync(path44.dirname(configPath)))
20296
+ fs40.mkdirSync(path44.dirname(configPath), { recursive: true });
20261
20297
  fs40.writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 384 });
20262
20298
  }
20263
20299
  if (options.profile && profileName !== "default") {
@@ -20395,7 +20431,7 @@ program.command("uninstall").description("Remove all Node9 hooks and optionally
20395
20431
  }
20396
20432
  }
20397
20433
  if (options.purge) {
20398
- const node9Dir = path43.join(os37.homedir(), ".node9");
20434
+ const node9Dir = path44.join(os37.homedir(), ".node9");
20399
20435
  if (fs40.existsSync(node9Dir)) {
20400
20436
  const confirmed = await confirm2({
20401
20437
  message: `Permanently delete ${node9Dir} (config, audit log, credentials)?`,
@@ -20545,9 +20581,9 @@ Claude Code spawns this command every ~300ms and writes a JSON payload to stdin.
20545
20581
  Run "node9 addto claude" to register it as the statusLine.`
20546
20582
  ).argument("[subcommand]", 'Optional: "debug on" / "debug off" to toggle stdin logging').argument("[state]", 'on|off \u2014 used with "debug" subcommand').action(async (subcommand, state) => {
20547
20583
  if (subcommand === "debug") {
20548
- const flagFile = path43.join(os37.homedir(), ".node9", "hud-debug");
20584
+ const flagFile = path44.join(os37.homedir(), ".node9", "hud-debug");
20549
20585
  if (state === "on") {
20550
- fs40.mkdirSync(path43.dirname(flagFile), { recursive: true });
20586
+ fs40.mkdirSync(path44.dirname(flagFile), { recursive: true });
20551
20587
  fs40.writeFileSync(flagFile, "");
20552
20588
  console.log("HUD debug logging enabled \u2192 ~/.node9/hud-debug.log");
20553
20589
  console.log("Tail it with: tail -f ~/.node9/hud-debug.log");
@@ -20664,7 +20700,7 @@ if (process.argv[2] !== "daemon") {
20664
20700
  const isCheckHook = process.argv[2] === "check";
20665
20701
  if (isCheckHook) {
20666
20702
  if (process.env.NODE9_DEBUG === "1" || getConfig().settings.enableHookLogDebug) {
20667
- const logPath = path43.join(os37.homedir(), ".node9", "hook-debug.log");
20703
+ const logPath = path44.join(os37.homedir(), ".node9", "hook-debug.log");
20668
20704
  const msg = reason instanceof Error ? reason.message : String(reason);
20669
20705
  fs40.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] UNHANDLED: ${msg}
20670
20706
  `);