@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.js CHANGED
@@ -168,8 +168,8 @@ function sanitizeConfig(raw) {
168
168
  }
169
169
  }
170
170
  const lines = result.error.issues.map((issue) => {
171
- const path44 = issue.path.length > 0 ? issue.path.join(".") : "root";
172
- return ` \u2022 ${path44}: ${issue.message}`;
171
+ const path45 = issue.path.length > 0 ? issue.path.join(".") : "root";
172
+ return ` \u2022 ${path45}: ${issue.message}`;
173
173
  });
174
174
  return {
175
175
  sanitized,
@@ -2083,9 +2083,9 @@ function matchesPattern(text, patterns) {
2083
2083
  const withoutDotSlash = text.replace(/^\.\//, "");
2084
2084
  return isMatch(withoutDotSlash) || isMatch(`./${withoutDotSlash}`);
2085
2085
  }
2086
- function getNestedValue(obj, path44) {
2086
+ function getNestedValue(obj, path45) {
2087
2087
  if (!obj || typeof obj !== "object") return null;
2088
- return path44.split(".").reduce((prev, curr) => prev?.[curr], obj);
2088
+ return path45.split(".").reduce((prev, curr) => prev?.[curr], obj);
2089
2089
  }
2090
2090
  function normalizeCommandForPolicy(command) {
2091
2091
  try {
@@ -5266,6 +5266,10 @@ var init_ui = __esm({
5266
5266
  border-color: rgba(83, 155, 245, 0.35);
5267
5267
  background: rgba(83, 155, 245, 0.04);
5268
5268
  }
5269
+ .pending-card.discovery-card {
5270
+ border-color: rgba(120, 100, 255, 0.45);
5271
+ background: rgba(100, 80, 255, 0.06);
5272
+ }
5269
5273
  .pending-card-header {
5270
5274
  display: flex;
5271
5275
  align-items: center;
@@ -7452,7 +7456,7 @@ var init_ui = __esm({
7452
7456
  });
7453
7457
 
7454
7458
  try {
7455
- await fetch('/mcp/approve', {
7459
+ const res = await fetch('/mcp/approve', {
7456
7460
  method: 'POST',
7457
7461
  headers: {
7458
7462
  'Content-Type': 'application/json',
@@ -7460,9 +7464,19 @@ var init_ui = __esm({
7460
7464
  },
7461
7465
  body: JSON.stringify({ id, serverKey, disabledTools }),
7462
7466
  });
7467
+ if (!res.ok) {
7468
+ showToast(
7469
+ '\u26A0\uFE0F',
7470
+ 'Approval failed',
7471
+ \`Server responded with \${res.status}\`,
7472
+ 'toast-block'
7473
+ );
7474
+ return;
7475
+ }
7463
7476
  closeMcpReview();
7464
7477
  refreshMcpTools();
7465
7478
  } catch (err) {
7479
+ showToast('\u26A0\uFE0F', 'Approval failed', 'Network error \u2014 check the daemon', 'toast-block');
7466
7480
  console.error('Failed to approve MCP server:', err);
7467
7481
  }
7468
7482
  }
@@ -8276,6 +8290,9 @@ var init_ui2 = __esm({
8276
8290
  });
8277
8291
 
8278
8292
  // src/cli/daemon-starter.ts
8293
+ function isTestingMode() {
8294
+ return /^(1|true|yes)$/i.test(process.env.NODE9_TESTING ?? "");
8295
+ }
8279
8296
  function openBrowserLocal() {
8280
8297
  const url = `http://${DAEMON_HOST}:${DAEMON_PORT}/`;
8281
8298
  try {
@@ -8286,8 +8303,9 @@ function openBrowserLocal() {
8286
8303
  } catch {
8287
8304
  }
8288
8305
  }
8289
- async function autoStartDaemonAndWait() {
8290
- if (process.env.NODE9_TESTING === "1") return false;
8306
+ async function autoStartDaemonAndWait(openBrowser2 = true) {
8307
+ if (isTestingMode()) return false;
8308
+ if (!import_path16.default.isAbsolute(process.argv[1])) return false;
8291
8309
  try {
8292
8310
  const child = (0, import_child_process3.spawn)(process.execPath, [process.argv[1], "daemon"], {
8293
8311
  detached: true,
@@ -8305,7 +8323,9 @@ async function autoStartDaemonAndWait() {
8305
8323
  signal: AbortSignal.timeout(500)
8306
8324
  });
8307
8325
  if (res.ok) {
8308
- openBrowserLocal();
8326
+ if (openBrowser2) {
8327
+ openBrowserLocal();
8328
+ }
8309
8329
  return true;
8310
8330
  }
8311
8331
  } catch {
@@ -8315,11 +8335,12 @@ async function autoStartDaemonAndWait() {
8315
8335
  }
8316
8336
  return false;
8317
8337
  }
8318
- var import_child_process3;
8338
+ var import_child_process3, import_path16;
8319
8339
  var init_daemon_starter = __esm({
8320
8340
  "src/cli/daemon-starter.ts"() {
8321
8341
  "use strict";
8322
8342
  import_child_process3 = require("child_process");
8343
+ import_path16 = __toESM(require("path"));
8323
8344
  init_daemon();
8324
8345
  }
8325
8346
  });
@@ -8612,11 +8633,11 @@ function buildRuleSources() {
8612
8633
  }
8613
8634
  function countScanFiles() {
8614
8635
  let total = 0;
8615
- const claudeDir = import_path16.default.join(import_os12.default.homedir(), ".claude", "projects");
8636
+ const claudeDir = import_path17.default.join(import_os12.default.homedir(), ".claude", "projects");
8616
8637
  if (import_fs13.default.existsSync(claudeDir)) {
8617
8638
  try {
8618
8639
  for (const proj of import_fs13.default.readdirSync(claudeDir)) {
8619
- const p = import_path16.default.join(claudeDir, proj);
8640
+ const p = import_path17.default.join(claudeDir, proj);
8620
8641
  try {
8621
8642
  if (!import_fs13.default.statSync(p).isDirectory()) continue;
8622
8643
  total += import_fs13.default.readdirSync(p).filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-")).length;
@@ -8627,14 +8648,14 @@ function countScanFiles() {
8627
8648
  } catch {
8628
8649
  }
8629
8650
  }
8630
- const geminiDir = import_path16.default.join(import_os12.default.homedir(), ".gemini", "tmp");
8651
+ const geminiDir = import_path17.default.join(import_os12.default.homedir(), ".gemini", "tmp");
8631
8652
  if (import_fs13.default.existsSync(geminiDir)) {
8632
8653
  try {
8633
8654
  for (const slug of import_fs13.default.readdirSync(geminiDir)) {
8634
- const p = import_path16.default.join(geminiDir, slug);
8655
+ const p = import_path17.default.join(geminiDir, slug);
8635
8656
  try {
8636
8657
  if (!import_fs13.default.statSync(p).isDirectory()) continue;
8637
- const chatsDir = import_path16.default.join(p, "chats");
8658
+ const chatsDir = import_path17.default.join(p, "chats");
8638
8659
  if (import_fs13.default.existsSync(chatsDir)) {
8639
8660
  try {
8640
8661
  total += import_fs13.default.readdirSync(chatsDir).filter((f) => f.endsWith(".json")).length;
@@ -8648,19 +8669,19 @@ function countScanFiles() {
8648
8669
  } catch {
8649
8670
  }
8650
8671
  }
8651
- const codexDir = import_path16.default.join(import_os12.default.homedir(), ".codex", "sessions");
8672
+ const codexDir = import_path17.default.join(import_os12.default.homedir(), ".codex", "sessions");
8652
8673
  if (import_fs13.default.existsSync(codexDir)) {
8653
8674
  try {
8654
8675
  for (const year of import_fs13.default.readdirSync(codexDir)) {
8655
- const yp = import_path16.default.join(codexDir, year);
8676
+ const yp = import_path17.default.join(codexDir, year);
8656
8677
  try {
8657
8678
  if (!import_fs13.default.statSync(yp).isDirectory()) continue;
8658
8679
  for (const month of import_fs13.default.readdirSync(yp)) {
8659
- const mp = import_path16.default.join(yp, month);
8680
+ const mp = import_path17.default.join(yp, month);
8660
8681
  try {
8661
8682
  if (!import_fs13.default.statSync(mp).isDirectory()) continue;
8662
8683
  for (const day of import_fs13.default.readdirSync(mp)) {
8663
- const dp = import_path16.default.join(mp, day);
8684
+ const dp = import_path17.default.join(mp, day);
8664
8685
  try {
8665
8686
  if (!import_fs13.default.statSync(dp).isDirectory()) continue;
8666
8687
  total += import_fs13.default.readdirSync(dp).filter((f) => f.endsWith(".jsonl")).length;
@@ -8692,7 +8713,7 @@ function renderProgressBar(done, total) {
8692
8713
  );
8693
8714
  }
8694
8715
  function scanClaudeHistory(startDate, onProgress) {
8695
- const projectsDir = import_path16.default.join(import_os12.default.homedir(), ".claude", "projects");
8716
+ const projectsDir = import_path17.default.join(import_os12.default.homedir(), ".claude", "projects");
8696
8717
  const result = {
8697
8718
  filesScanned: 0,
8698
8719
  sessions: 0,
@@ -8714,7 +8735,7 @@ function scanClaudeHistory(startDate, onProgress) {
8714
8735
  }
8715
8736
  const ruleSources = buildRuleSources();
8716
8737
  for (const proj of projDirs) {
8717
- const projPath = import_path16.default.join(projectsDir, proj);
8738
+ const projPath = import_path17.default.join(projectsDir, proj);
8718
8739
  try {
8719
8740
  if (!import_fs13.default.statSync(projPath).isDirectory()) continue;
8720
8741
  } catch {
@@ -8734,7 +8755,7 @@ function scanClaudeHistory(startDate, onProgress) {
8734
8755
  const sessionId = file.replace(/\.jsonl$/, "");
8735
8756
  let raw;
8736
8757
  try {
8737
- raw = import_fs13.default.readFileSync(import_path16.default.join(projPath, file), "utf-8");
8758
+ raw = import_fs13.default.readFileSync(import_path17.default.join(projPath, file), "utf-8");
8738
8759
  } catch {
8739
8760
  continue;
8740
8761
  }
@@ -8887,7 +8908,7 @@ function scanClaudeHistory(startDate, onProgress) {
8887
8908
  return result;
8888
8909
  }
8889
8910
  function scanGeminiHistory(startDate, onProgress) {
8890
- const tmpDir = import_path16.default.join(import_os12.default.homedir(), ".gemini", "tmp");
8911
+ const tmpDir = import_path17.default.join(import_os12.default.homedir(), ".gemini", "tmp");
8891
8912
  const result = {
8892
8913
  filesScanned: 0,
8893
8914
  sessions: 0,
@@ -8909,7 +8930,7 @@ function scanGeminiHistory(startDate, onProgress) {
8909
8930
  }
8910
8931
  const ruleSources = buildRuleSources();
8911
8932
  for (const slug of slugDirs) {
8912
- const slugPath = import_path16.default.join(tmpDir, slug);
8933
+ const slugPath = import_path17.default.join(tmpDir, slug);
8913
8934
  try {
8914
8935
  if (!import_fs13.default.statSync(slugPath).isDirectory()) continue;
8915
8936
  } catch {
@@ -8917,10 +8938,10 @@ function scanGeminiHistory(startDate, onProgress) {
8917
8938
  }
8918
8939
  let projLabel = slug;
8919
8940
  try {
8920
- projLabel = import_fs13.default.readFileSync(import_path16.default.join(slugPath, ".project_root"), "utf-8").trim().replace(import_os12.default.homedir(), "~").slice(0, 40);
8941
+ projLabel = import_fs13.default.readFileSync(import_path17.default.join(slugPath, ".project_root"), "utf-8").trim().replace(import_os12.default.homedir(), "~").slice(0, 40);
8921
8942
  } catch {
8922
8943
  }
8923
- const chatsDir = import_path16.default.join(slugPath, "chats");
8944
+ const chatsDir = import_path17.default.join(slugPath, "chats");
8924
8945
  if (!import_fs13.default.existsSync(chatsDir)) continue;
8925
8946
  let chatFiles;
8926
8947
  try {
@@ -8934,7 +8955,7 @@ function scanGeminiHistory(startDate, onProgress) {
8934
8955
  const sessionId = chatFile.replace(/\.json$/, "");
8935
8956
  let raw;
8936
8957
  try {
8937
- raw = import_fs13.default.readFileSync(import_path16.default.join(chatsDir, chatFile), "utf-8");
8958
+ raw = import_fs13.default.readFileSync(import_path17.default.join(chatsDir, chatFile), "utf-8");
8938
8959
  } catch {
8939
8960
  continue;
8940
8961
  }
@@ -9083,7 +9104,7 @@ function scanGeminiHistory(startDate, onProgress) {
9083
9104
  return result;
9084
9105
  }
9085
9106
  function scanCodexHistory(startDate, onProgress) {
9086
- const sessionsBase = import_path16.default.join(import_os12.default.homedir(), ".codex", "sessions");
9107
+ const sessionsBase = import_path17.default.join(import_os12.default.homedir(), ".codex", "sessions");
9087
9108
  const result = {
9088
9109
  filesScanned: 0,
9089
9110
  sessions: 0,
@@ -9100,28 +9121,28 @@ function scanCodexHistory(startDate, onProgress) {
9100
9121
  const jsonlFiles = [];
9101
9122
  try {
9102
9123
  for (const year of import_fs13.default.readdirSync(sessionsBase)) {
9103
- const yearPath = import_path16.default.join(sessionsBase, year);
9124
+ const yearPath = import_path17.default.join(sessionsBase, year);
9104
9125
  try {
9105
9126
  if (!import_fs13.default.statSync(yearPath).isDirectory()) continue;
9106
9127
  } catch {
9107
9128
  continue;
9108
9129
  }
9109
9130
  for (const month of import_fs13.default.readdirSync(yearPath)) {
9110
- const monthPath = import_path16.default.join(yearPath, month);
9131
+ const monthPath = import_path17.default.join(yearPath, month);
9111
9132
  try {
9112
9133
  if (!import_fs13.default.statSync(monthPath).isDirectory()) continue;
9113
9134
  } catch {
9114
9135
  continue;
9115
9136
  }
9116
9137
  for (const day of import_fs13.default.readdirSync(monthPath)) {
9117
- const dayPath = import_path16.default.join(monthPath, day);
9138
+ const dayPath = import_path17.default.join(monthPath, day);
9118
9139
  try {
9119
9140
  if (!import_fs13.default.statSync(dayPath).isDirectory()) continue;
9120
9141
  } catch {
9121
9142
  continue;
9122
9143
  }
9123
9144
  for (const file of import_fs13.default.readdirSync(dayPath)) {
9124
- if (file.endsWith(".jsonl")) jsonlFiles.push(import_path16.default.join(dayPath, file));
9145
+ if (file.endsWith(".jsonl")) jsonlFiles.push(import_path17.default.join(dayPath, file));
9125
9146
  }
9126
9147
  }
9127
9148
  }
@@ -9363,7 +9384,7 @@ function registerScanCommand(program2) {
9363
9384
  d.setHours(0, 0, 0, 0);
9364
9385
  return d;
9365
9386
  })();
9366
- const isInstalled = import_fs13.default.existsSync(import_path16.default.join(import_os12.default.homedir(), ".node9", "audit.log"));
9387
+ const isInstalled = import_fs13.default.existsSync(import_path17.default.join(import_os12.default.homedir(), ".node9", "audit.log"));
9367
9388
  console.log("");
9368
9389
  if (!isInstalled) {
9369
9390
  console.log(
@@ -9588,7 +9609,7 @@ function registerScanCommand(program2) {
9588
9609
  console.log(" " + import_chalk2.default.dim("\u2192 ") + import_chalk2.default.underline("https://node9.ai"));
9589
9610
  }
9590
9611
  console.log("");
9591
- if (isDaemonRunning() && process.env.NODE9_TESTING !== "1") {
9612
+ if (!isTestingMode() && isDaemonRunning()) {
9592
9613
  const internalToken = getInternalToken();
9593
9614
  if (internalToken) {
9594
9615
  try {
@@ -9614,13 +9635,13 @@ function registerScanCommand(program2) {
9614
9635
  }
9615
9636
  });
9616
9637
  }
9617
- var import_chalk2, import_fs13, import_path16, import_os12, CLAUDE_PRICING, GEMINI_PRICING, LOOP_TOOLS, LOOP_THRESHOLD, DEFAULT_RULE_NAMES;
9638
+ var import_chalk2, import_fs13, import_path17, import_os12, CLAUDE_PRICING, GEMINI_PRICING, LOOP_TOOLS, LOOP_THRESHOLD, DEFAULT_RULE_NAMES;
9618
9639
  var init_scan = __esm({
9619
9640
  "src/cli/commands/scan.ts"() {
9620
9641
  "use strict";
9621
9642
  import_chalk2 = __toESM(require("chalk"));
9622
9643
  import_fs13 = __toESM(require("fs"));
9623
- import_path16 = __toESM(require("path"));
9644
+ import_path17 = __toESM(require("path"));
9624
9645
  import_os12 = __toESM(require("os"));
9625
9646
  init_shields();
9626
9647
  init_config();
@@ -9757,12 +9778,12 @@ var init_suggestion_tracker = __esm({
9757
9778
  });
9758
9779
 
9759
9780
  // src/daemon/taint-store.ts
9760
- var import_fs14, import_path17, DEFAULT_TTL_MS, TaintStore;
9781
+ var import_fs14, import_path18, DEFAULT_TTL_MS, TaintStore;
9761
9782
  var init_taint_store = __esm({
9762
9783
  "src/daemon/taint-store.ts"() {
9763
9784
  "use strict";
9764
9785
  import_fs14 = __toESM(require("fs"));
9765
- import_path17 = __toESM(require("path"));
9786
+ import_path18 = __toESM(require("path"));
9766
9787
  DEFAULT_TTL_MS = 60 * 60 * 1e3;
9767
9788
  TaintStore = class {
9768
9789
  records = /* @__PURE__ */ new Map();
@@ -9827,9 +9848,9 @@ var init_taint_store = __esm({
9827
9848
  /** Resolve to absolute path, falling back to path.resolve if file doesn't exist yet. */
9828
9849
  _resolve(filePath) {
9829
9850
  try {
9830
- return import_fs14.default.realpathSync.native(import_path17.default.resolve(filePath));
9851
+ return import_fs14.default.realpathSync.native(import_path18.default.resolve(filePath));
9831
9852
  } catch {
9832
- return import_path17.default.resolve(filePath);
9853
+ return import_path18.default.resolve(filePath);
9833
9854
  }
9834
9855
  }
9835
9856
  };
@@ -9991,7 +10012,7 @@ function setCachedScanResult(result) {
9991
10012
  cachedScanTs = Date.now();
9992
10013
  }
9993
10014
  function atomicWriteSync2(filePath, data, options) {
9994
- const dir = import_path18.default.dirname(filePath);
10015
+ const dir = import_path19.default.dirname(filePath);
9995
10016
  if (!import_fs15.default.existsSync(dir)) import_fs15.default.mkdirSync(dir, { recursive: true });
9996
10017
  const tmpPath = `${filePath}.${(0, import_crypto6.randomUUID)()}.tmp`;
9997
10018
  try {
@@ -10031,7 +10052,7 @@ function appendAuditLog(data) {
10031
10052
  decision: data.decision,
10032
10053
  source: "daemon"
10033
10054
  };
10034
- const dir = import_path18.default.dirname(AUDIT_LOG_FILE);
10055
+ const dir = import_path19.default.dirname(AUDIT_LOG_FILE);
10035
10056
  if (!import_fs15.default.existsSync(dir)) import_fs15.default.mkdirSync(dir, { recursive: true });
10036
10057
  import_fs15.default.appendFileSync(AUDIT_LOG_FILE, JSON.stringify(entry) + "\n");
10037
10058
  } catch {
@@ -10285,13 +10306,13 @@ function startActivitySocket() {
10285
10306
  }
10286
10307
  });
10287
10308
  }
10288
- var import_net2, import_fs15, import_path18, import_os13, import_child_process4, import_crypto6, homeDir, DAEMON_PID_FILE, DECISIONS_FILE, AUDIT_LOG_FILE, TRUST_FILE2, GLOBAL_CONFIG_FILE, CREDENTIALS_FILE, INSIGHT_COUNTS_FILE, pending, sseClients, suggestionTracker, suggestions, taintStore, insightCounts, _abandonTimer, _hadBrowserClient, _daemonServer, daemonRejectionHandlerRegistered, AUTO_DENY_MS, TRUST_DURATIONS, autoStarted, ACTIVITY_SOCKET_PATH2, ACTIVITY_RING_SIZE, activityRing, LARGE_RESPONSE_RING_SIZE, largeResponseRing, cachedScanResult, cachedScanTs, SCAN_CACHE_TTL_MS, SECRET_KEY_RE, INPUT_PRICE_PER_1M, OUTPUT_PRICE_PER_1M, BYTES_PER_TOKEN, WRITE_TOOL_NAMES;
10309
+ var import_net2, import_fs15, import_path19, import_os13, import_child_process4, import_crypto6, homeDir, DAEMON_PID_FILE, DECISIONS_FILE, AUDIT_LOG_FILE, TRUST_FILE2, GLOBAL_CONFIG_FILE, CREDENTIALS_FILE, INSIGHT_COUNTS_FILE, pending, sseClients, suggestionTracker, suggestions, taintStore, insightCounts, _abandonTimer, _hadBrowserClient, _daemonServer, daemonRejectionHandlerRegistered, AUTO_DENY_MS, TRUST_DURATIONS, autoStarted, ACTIVITY_SOCKET_PATH2, ACTIVITY_RING_SIZE, activityRing, LARGE_RESPONSE_RING_SIZE, largeResponseRing, cachedScanResult, cachedScanTs, SCAN_CACHE_TTL_MS, SECRET_KEY_RE, INPUT_PRICE_PER_1M, OUTPUT_PRICE_PER_1M, BYTES_PER_TOKEN, WRITE_TOOL_NAMES;
10289
10310
  var init_state2 = __esm({
10290
10311
  "src/daemon/state.ts"() {
10291
10312
  "use strict";
10292
10313
  import_net2 = __toESM(require("net"));
10293
10314
  import_fs15 = __toESM(require("fs"));
10294
- import_path18 = __toESM(require("path"));
10315
+ import_path19 = __toESM(require("path"));
10295
10316
  import_os13 = __toESM(require("os"));
10296
10317
  import_child_process4 = require("child_process");
10297
10318
  import_crypto6 = require("crypto");
@@ -10301,13 +10322,13 @@ var init_state2 = __esm({
10301
10322
  init_session_counters();
10302
10323
  init_session_history();
10303
10324
  homeDir = import_os13.default.homedir();
10304
- DAEMON_PID_FILE = import_path18.default.join(homeDir, ".node9", "daemon.pid");
10305
- DECISIONS_FILE = import_path18.default.join(homeDir, ".node9", "decisions.json");
10306
- AUDIT_LOG_FILE = import_path18.default.join(homeDir, ".node9", "audit.log");
10307
- TRUST_FILE2 = import_path18.default.join(homeDir, ".node9", "trust.json");
10308
- GLOBAL_CONFIG_FILE = import_path18.default.join(homeDir, ".node9", "config.json");
10309
- CREDENTIALS_FILE = import_path18.default.join(homeDir, ".node9", "credentials.json");
10310
- INSIGHT_COUNTS_FILE = import_path18.default.join(homeDir, ".node9", "insight-counts.json");
10325
+ DAEMON_PID_FILE = import_path19.default.join(homeDir, ".node9", "daemon.pid");
10326
+ DECISIONS_FILE = import_path19.default.join(homeDir, ".node9", "decisions.json");
10327
+ AUDIT_LOG_FILE = import_path19.default.join(homeDir, ".node9", "audit.log");
10328
+ TRUST_FILE2 = import_path19.default.join(homeDir, ".node9", "trust.json");
10329
+ GLOBAL_CONFIG_FILE = import_path19.default.join(homeDir, ".node9", "config.json");
10330
+ CREDENTIALS_FILE = import_path19.default.join(homeDir, ".node9", "credentials.json");
10331
+ INSIGHT_COUNTS_FILE = import_path19.default.join(homeDir, ".node9", "insight-counts.json");
10311
10332
  pending = /* @__PURE__ */ new Map();
10312
10333
  sseClients = /* @__PURE__ */ new Set();
10313
10334
  suggestionTracker = new SuggestionTracker(3);
@@ -10325,7 +10346,7 @@ var init_state2 = __esm({
10325
10346
  "2h": 2 * 60 * 6e4
10326
10347
  };
10327
10348
  autoStarted = process.env.NODE9_AUTO_STARTED === "1";
10328
- ACTIVITY_SOCKET_PATH2 = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : import_path18.default.join(import_os13.default.tmpdir(), "node9-activity.sock");
10349
+ ACTIVITY_SOCKET_PATH2 = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : import_path19.default.join(import_os13.default.tmpdir(), "node9-activity.sock");
10329
10350
  ACTIVITY_RING_SIZE = 100;
10330
10351
  activityRing = [];
10331
10352
  LARGE_RESPONSE_RING_SIZE = 20;
@@ -10375,7 +10396,7 @@ function patchConfig(configPath, patch) {
10375
10396
  ignored.push(patch.toolName);
10376
10397
  }
10377
10398
  }
10378
- const dir = import_path19.default.dirname(configPath);
10399
+ const dir = import_path20.default.dirname(configPath);
10379
10400
  import_fs16.default.mkdirSync(dir, { recursive: true });
10380
10401
  const tmp = configPath + ".node9-tmp";
10381
10402
  try {
@@ -10397,14 +10418,14 @@ function patchConfig(configPath, patch) {
10397
10418
  throw err2;
10398
10419
  }
10399
10420
  }
10400
- var import_fs16, import_path19, import_os14, GLOBAL_CONFIG_PATH;
10421
+ var import_fs16, import_path20, import_os14, GLOBAL_CONFIG_PATH;
10401
10422
  var init_patch = __esm({
10402
10423
  "src/config/patch.ts"() {
10403
10424
  "use strict";
10404
10425
  import_fs16 = __toESM(require("fs"));
10405
- import_path19 = __toESM(require("path"));
10426
+ import_path20 = __toESM(require("path"));
10406
10427
  import_os14 = __toESM(require("os"));
10407
- GLOBAL_CONFIG_PATH = import_path19.default.join(import_os14.default.homedir(), ".node9", "config.json");
10428
+ GLOBAL_CONFIG_PATH = import_path20.default.join(import_os14.default.homedir(), ".node9", "config.json");
10408
10429
  }
10409
10430
  });
10410
10431
 
@@ -10476,7 +10497,7 @@ function parseJSONLFile(filePath) {
10476
10497
  return daily;
10477
10498
  }
10478
10499
  function collectEntries() {
10479
- const projectsDir = import_path20.default.join(import_os15.default.homedir(), ".claude", "projects");
10500
+ const projectsDir = import_path21.default.join(import_os15.default.homedir(), ".claude", "projects");
10480
10501
  if (!import_fs17.default.existsSync(projectsDir)) return [];
10481
10502
  const combined = /* @__PURE__ */ new Map();
10482
10503
  let dirs;
@@ -10486,7 +10507,7 @@ function collectEntries() {
10486
10507
  return [];
10487
10508
  }
10488
10509
  for (const dir of dirs) {
10489
- const dirPath = import_path20.default.join(projectsDir, dir);
10510
+ const dirPath = import_path21.default.join(projectsDir, dir);
10490
10511
  try {
10491
10512
  if (!import_fs17.default.statSync(dirPath).isDirectory()) continue;
10492
10513
  } catch {
@@ -10499,7 +10520,7 @@ function collectEntries() {
10499
10520
  continue;
10500
10521
  }
10501
10522
  for (const file of files) {
10502
- const entries = parseJSONLFile(import_path20.default.join(dirPath, file));
10523
+ const entries = parseJSONLFile(import_path21.default.join(dirPath, file));
10503
10524
  for (const [key, e] of entries) {
10504
10525
  const prev = combined.get(key);
10505
10526
  if (prev) {
@@ -10552,12 +10573,12 @@ function startCostSync() {
10552
10573
  }, SYNC_INTERVAL_MS);
10553
10574
  timer.unref();
10554
10575
  }
10555
- var import_fs17, import_path20, import_os15, SYNC_INTERVAL_MS, PRICING;
10576
+ var import_fs17, import_path21, import_os15, SYNC_INTERVAL_MS, PRICING;
10556
10577
  var init_costSync = __esm({
10557
10578
  "src/costSync.ts"() {
10558
10579
  "use strict";
10559
10580
  import_fs17 = __toESM(require("fs"));
10560
- import_path20 = __toESM(require("path"));
10581
+ import_path21 = __toESM(require("path"));
10561
10582
  import_os15 = __toESM(require("os"));
10562
10583
  init_config();
10563
10584
  init_audit();
@@ -10583,7 +10604,7 @@ function readCredentials() {
10583
10604
  };
10584
10605
  }
10585
10606
  try {
10586
- const credPath = import_path21.default.join(import_os16.default.homedir(), ".node9", "credentials.json");
10607
+ const credPath = import_path22.default.join(import_os16.default.homedir(), ".node9", "credentials.json");
10587
10608
  const creds = JSON.parse(import_fs18.default.readFileSync(credPath, "utf-8"));
10588
10609
  const profileName = process.env.NODE9_PROFILE ?? "default";
10589
10610
  const profile = creds[profileName];
@@ -10646,7 +10667,7 @@ async function syncOnce() {
10646
10667
  try {
10647
10668
  const rules = await fetchCloudRules(creds.apiKey, creds.apiUrl);
10648
10669
  const cache = { fetchedAt: (/* @__PURE__ */ new Date()).toISOString(), rules };
10649
- const dir = import_path21.default.dirname(rulesCacheFile());
10670
+ const dir = import_path22.default.dirname(rulesCacheFile());
10650
10671
  if (!import_fs18.default.existsSync(dir)) import_fs18.default.mkdirSync(dir, { recursive: true });
10651
10672
  import_fs18.default.writeFileSync(rulesCacheFile(), JSON.stringify(cache, null, 2) + "\n", "utf-8");
10652
10673
  } catch {
@@ -10660,7 +10681,7 @@ async function runCloudSync() {
10660
10681
  try {
10661
10682
  const rules = await fetchCloudRules(creds.apiKey, creds.apiUrl);
10662
10683
  const cache = { fetchedAt: (/* @__PURE__ */ new Date()).toISOString(), rules };
10663
- const dir = import_path21.default.dirname(rulesCacheFile());
10684
+ const dir = import_path22.default.dirname(rulesCacheFile());
10664
10685
  if (!import_fs18.default.existsSync(dir)) import_fs18.default.mkdirSync(dir, { recursive: true });
10665
10686
  import_fs18.default.writeFileSync(rulesCacheFile(), JSON.stringify(cache, null, 2) + "\n", "utf-8");
10666
10687
  return { ok: true, rules: rules.length, fetchedAt: cache.fetchedAt };
@@ -10694,16 +10715,16 @@ function startCloudSync() {
10694
10715
  const recurring = setInterval(() => void syncOnce(), intervalMs);
10695
10716
  recurring.unref();
10696
10717
  }
10697
- var import_fs18, import_https, import_os16, import_path21, rulesCacheFile, DEFAULT_API_URL, DEFAULT_INTERVAL_HOURS, MIN_INTERVAL_HOURS;
10718
+ var import_fs18, import_https, import_os16, import_path22, rulesCacheFile, DEFAULT_API_URL, DEFAULT_INTERVAL_HOURS, MIN_INTERVAL_HOURS;
10698
10719
  var init_sync = __esm({
10699
10720
  "src/daemon/sync.ts"() {
10700
10721
  "use strict";
10701
10722
  import_fs18 = __toESM(require("fs"));
10702
10723
  import_https = __toESM(require("https"));
10703
10724
  import_os16 = __toESM(require("os"));
10704
- import_path21 = __toESM(require("path"));
10725
+ import_path22 = __toESM(require("path"));
10705
10726
  init_config();
10706
- rulesCacheFile = () => import_path21.default.join(import_os16.default.homedir(), ".node9", "rules-cache.json");
10727
+ rulesCacheFile = () => import_path22.default.join(import_os16.default.homedir(), ".node9", "rules-cache.json");
10707
10728
  DEFAULT_API_URL = "https://api.node9.ai/api/v1/policy";
10708
10729
  DEFAULT_INTERVAL_HOURS = 5;
10709
10730
  MIN_INTERVAL_HOURS = 1;
@@ -10741,11 +10762,11 @@ function runDlpScan() {
10741
10762
  return;
10742
10763
  }
10743
10764
  for (const proj of projDirs) {
10744
- const projPath = import_path22.default.join(PROJECTS_DIR, proj);
10765
+ const projPath = import_path23.default.join(PROJECTS_DIR, proj);
10745
10766
  try {
10746
10767
  if (!import_fs19.default.lstatSync(projPath).isDirectory()) continue;
10747
10768
  const real = import_fs19.default.realpathSync(projPath);
10748
- if (!real.startsWith(PROJECTS_DIR + import_path22.default.sep) && real !== PROJECTS_DIR) continue;
10769
+ if (!real.startsWith(PROJECTS_DIR + import_path23.default.sep) && real !== PROJECTS_DIR) continue;
10749
10770
  } catch {
10750
10771
  continue;
10751
10772
  }
@@ -10756,7 +10777,7 @@ function runDlpScan() {
10756
10777
  continue;
10757
10778
  }
10758
10779
  for (const file of files) {
10759
- const filePath = import_path22.default.join(projPath, file);
10780
+ const filePath = import_path23.default.join(projPath, file);
10760
10781
  const lastOffset = index[filePath] ?? 0;
10761
10782
  let size;
10762
10783
  try {
@@ -10845,24 +10866,24 @@ function startDlpScanner() {
10845
10866
  );
10846
10867
  timer.unref();
10847
10868
  }
10848
- var import_fs19, import_path22, import_os17, INDEX_FILE, PROJECTS_DIR;
10869
+ var import_fs19, import_path23, import_os17, INDEX_FILE, PROJECTS_DIR;
10849
10870
  var init_dlp_scanner = __esm({
10850
10871
  "src/daemon/dlp-scanner.ts"() {
10851
10872
  "use strict";
10852
10873
  import_fs19 = __toESM(require("fs"));
10853
- import_path22 = __toESM(require("path"));
10874
+ import_path23 = __toESM(require("path"));
10854
10875
  import_os17 = __toESM(require("os"));
10855
10876
  init_dlp();
10856
10877
  init_native();
10857
10878
  init_state2();
10858
- INDEX_FILE = import_path22.default.join(import_os17.default.homedir(), ".node9", "dlp-index.json");
10859
- PROJECTS_DIR = import_path22.default.join(import_os17.default.homedir(), ".claude", "projects");
10879
+ INDEX_FILE = import_path23.default.join(import_os17.default.homedir(), ".node9", "dlp-index.json");
10880
+ PROJECTS_DIR = import_path23.default.join(import_os17.default.homedir(), ".claude", "projects");
10860
10881
  }
10861
10882
  });
10862
10883
 
10863
10884
  // src/daemon/mcp-tools.ts
10864
10885
  function getMcpToolsFile() {
10865
- return import_path23.default.join(import_os18.default.homedir(), ".node9", "mcp-tools.json");
10886
+ return import_path24.default.join(import_os18.default.homedir(), ".node9", "mcp-tools.json");
10866
10887
  }
10867
10888
  function readMcpToolsConfig() {
10868
10889
  try {
@@ -10877,7 +10898,7 @@ function readMcpToolsConfig() {
10877
10898
  function writeMcpToolsConfig(config) {
10878
10899
  try {
10879
10900
  const file = getMcpToolsFile();
10880
- const dir = import_path23.default.dirname(file);
10901
+ const dir = import_path24.default.dirname(file);
10881
10902
  if (!import_fs20.default.existsSync(dir)) import_fs20.default.mkdirSync(dir, { recursive: true });
10882
10903
  const tmpPath = `${file}.${import_os18.default.hostname()}.${process.pid}.tmp`;
10883
10904
  import_fs20.default.writeFileSync(tmpPath, JSON.stringify(config, null, 2));
@@ -10920,12 +10941,12 @@ function approveServer(serverKey, disabledTools) {
10920
10941
  writeMcpToolsConfig(config);
10921
10942
  }
10922
10943
  }
10923
- var import_fs20, import_path23, import_os18;
10944
+ var import_fs20, import_path24, import_os18;
10924
10945
  var init_mcp_tools = __esm({
10925
10946
  "src/daemon/mcp-tools.ts"() {
10926
10947
  "use strict";
10927
10948
  import_fs20 = __toESM(require("fs"));
10928
- import_path23 = __toESM(require("path"));
10949
+ import_path24 = __toESM(require("path"));
10929
10950
  import_os18 = __toESM(require("os"));
10930
10951
  }
10931
10952
  });
@@ -11121,7 +11142,7 @@ data: ${JSON.stringify(item.data)}
11121
11142
  status: "pending"
11122
11143
  });
11123
11144
  }
11124
- const projectCwd = typeof cwd === "string" && import_path24.default.isAbsolute(cwd) ? cwd : void 0;
11145
+ const projectCwd = typeof cwd === "string" && import_path25.default.isAbsolute(cwd) ? cwd : void 0;
11125
11146
  const projectConfig = getConfig(projectCwd);
11126
11147
  const browserEnabled = projectConfig.settings.approvers?.browser !== false;
11127
11148
  const terminalEnabled = projectConfig.settings.approvers?.terminal !== false;
@@ -11485,7 +11506,7 @@ data: ${JSON.stringify(item.data)}
11485
11506
  if (!validToken(req)) return res.writeHead(403).end();
11486
11507
  const periodParam = reqUrl.searchParams.get("period") || "7d";
11487
11508
  const period = ["today", "7d", "30d", "month"].includes(periodParam) ? periodParam : "7d";
11488
- const logPath = import_path24.default.join(import_os19.default.homedir(), ".node9", "audit.log");
11509
+ const logPath = import_path25.default.join(import_os19.default.homedir(), ".node9", "audit.log");
11489
11510
  if (!import_fs21.default.existsSync(logPath)) {
11490
11511
  res.writeHead(200, { "Content-Type": "application/json" });
11491
11512
  return res.end(
@@ -11679,8 +11700,8 @@ data: ${JSON.stringify(item.data)}
11679
11700
  const body = await readBody(req);
11680
11701
  const data = body ? JSON.parse(body) : {};
11681
11702
  const configPath = data.configPath ?? GLOBAL_CONFIG_PATH;
11682
- const node9Dir = import_path24.default.dirname(GLOBAL_CONFIG_PATH);
11683
- if (!import_path24.default.resolve(configPath).startsWith(node9Dir + import_path24.default.sep)) {
11703
+ const node9Dir = import_path25.default.dirname(GLOBAL_CONFIG_PATH);
11704
+ if (!import_path25.default.resolve(configPath).startsWith(node9Dir + import_path25.default.sep)) {
11684
11705
  res.writeHead(400, { "Content-Type": "application/json" });
11685
11706
  return res.end(
11686
11707
  JSON.stringify({ error: "configPath must be within the node9 config directory" })
@@ -11799,6 +11820,11 @@ data: ${JSON.stringify(item.data)}
11799
11820
  return;
11800
11821
  }
11801
11822
  approveServer(serverKey, disabledTools);
11823
+ appendAuditLog({
11824
+ toolName: `mcp-server:${serverKey}`,
11825
+ args: { disabledTools },
11826
+ decision: "allow"
11827
+ });
11802
11828
  broadcast("mcp-tools-updated", { serverKey, disabledTools });
11803
11829
  res.writeHead(200).end();
11804
11830
  return;
@@ -11817,6 +11843,11 @@ data: ${JSON.stringify(item.data)}
11817
11843
  }
11818
11844
  const status = updateServerDiscovery(serverKey, tools);
11819
11845
  if (status === "new" || status === "drift") {
11846
+ appendAuditLog({
11847
+ toolName: `mcp-server:${serverKey}`,
11848
+ args: { toolCount: tools.length, status },
11849
+ decision: "mcp-discovered"
11850
+ });
11820
11851
  const id = (0, import_crypto7.randomUUID)();
11821
11852
  const entry = {
11822
11853
  id,
@@ -11885,6 +11916,11 @@ data: ${JSON.stringify(item.data)}
11885
11916
  }
11886
11917
  clearTimeout(entry.timer);
11887
11918
  approveServer(serverKey, disabledTools);
11919
+ appendAuditLog({
11920
+ toolName: `mcp-server:${serverKey}`,
11921
+ args: { disabledTools },
11922
+ decision: "allow"
11923
+ });
11888
11924
  pending.delete(id);
11889
11925
  broadcast("remove", { id, decision: "allow" });
11890
11926
  res.writeHead(200).end();
@@ -11973,13 +12009,13 @@ data: ${JSON.stringify(item.data)}
11973
12009
  }
11974
12010
  startActivitySocket();
11975
12011
  }
11976
- var import_http, import_fs21, import_path24, import_os19, import_crypto7, import_child_process5, import_chalk3;
12012
+ var import_http, import_fs21, import_path25, import_os19, import_crypto7, import_child_process5, import_chalk3;
11977
12013
  var init_server = __esm({
11978
12014
  "src/daemon/server.ts"() {
11979
12015
  "use strict";
11980
12016
  import_http = __toESM(require("http"));
11981
12017
  import_fs21 = __toESM(require("fs"));
11982
- import_path24 = __toESM(require("path"));
12018
+ import_path25 = __toESM(require("path"));
11983
12019
  import_os19 = __toESM(require("os"));
11984
12020
  import_crypto7 = require("crypto");
11985
12021
  import_child_process5 = require("child_process");
@@ -12004,7 +12040,7 @@ var init_server = __esm({
12004
12040
  function resolveNode9Binary() {
12005
12041
  try {
12006
12042
  const script = process.argv[1];
12007
- if (typeof script === "string" && import_path25.default.isAbsolute(script) && import_fs22.default.existsSync(script)) {
12043
+ if (typeof script === "string" && import_path26.default.isAbsolute(script) && import_fs22.default.existsSync(script)) {
12008
12044
  return import_fs22.default.realpathSync(script);
12009
12045
  }
12010
12046
  } catch {
@@ -12023,11 +12059,11 @@ function xmlEscape(s) {
12023
12059
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
12024
12060
  }
12025
12061
  function launchdPlist(binaryPath) {
12026
- const logDir = import_path25.default.join(import_os20.default.homedir(), ".node9");
12062
+ const logDir = import_path26.default.join(import_os20.default.homedir(), ".node9");
12027
12063
  const nodePath = xmlEscape(process.execPath);
12028
12064
  const scriptPath = xmlEscape(binaryPath);
12029
- const outLog = xmlEscape(import_path25.default.join(logDir, "daemon.log"));
12030
- const errLog = xmlEscape(import_path25.default.join(logDir, "daemon-error.log"));
12065
+ const outLog = xmlEscape(import_path26.default.join(logDir, "daemon.log"));
12066
+ const errLog = xmlEscape(import_path26.default.join(logDir, "daemon-error.log"));
12031
12067
  return `<?xml version="1.0" encoding="UTF-8"?>
12032
12068
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
12033
12069
  <plist version="1.0">
@@ -12062,7 +12098,7 @@ function launchdPlist(binaryPath) {
12062
12098
  `;
12063
12099
  }
12064
12100
  function installLaunchd(binaryPath) {
12065
- const dir = import_path25.default.dirname(LAUNCHD_PLIST);
12101
+ const dir = import_path26.default.dirname(LAUNCHD_PLIST);
12066
12102
  if (!import_fs22.default.existsSync(dir)) import_fs22.default.mkdirSync(dir, { recursive: true });
12067
12103
  import_fs22.default.writeFileSync(LAUNCHD_PLIST, launchdPlist(binaryPath), "utf-8");
12068
12104
  (0, import_child_process6.spawnSync)("launchctl", ["unload", LAUNCHD_PLIST], { encoding: "utf8" });
@@ -12139,7 +12175,7 @@ function isSystemdInstalled() {
12139
12175
  return import_fs22.default.existsSync(SYSTEMD_UNIT);
12140
12176
  }
12141
12177
  function stopRunningDaemon() {
12142
- const pidFile = import_path25.default.join(import_os20.default.homedir(), ".node9", "daemon.pid");
12178
+ const pidFile = import_path26.default.join(import_os20.default.homedir(), ".node9", "daemon.pid");
12143
12179
  if (!import_fs22.default.existsSync(pidFile)) return;
12144
12180
  try {
12145
12181
  const data = JSON.parse(import_fs22.default.readFileSync(pidFile, "utf-8"));
@@ -12232,18 +12268,18 @@ function isDaemonServiceInstalled() {
12232
12268
  if (process.platform === "linux") return isSystemdInstalled();
12233
12269
  return false;
12234
12270
  }
12235
- var import_fs22, import_path25, import_os20, import_child_process6, LAUNCHD_LABEL, LAUNCHD_PLIST, SYSTEMD_UNIT_DIR, SYSTEMD_UNIT;
12271
+ var import_fs22, import_path26, import_os20, import_child_process6, LAUNCHD_LABEL, LAUNCHD_PLIST, SYSTEMD_UNIT_DIR, SYSTEMD_UNIT;
12236
12272
  var init_service = __esm({
12237
12273
  "src/daemon/service.ts"() {
12238
12274
  "use strict";
12239
12275
  import_fs22 = __toESM(require("fs"));
12240
- import_path25 = __toESM(require("path"));
12276
+ import_path26 = __toESM(require("path"));
12241
12277
  import_os20 = __toESM(require("os"));
12242
12278
  import_child_process6 = require("child_process");
12243
12279
  LAUNCHD_LABEL = "ai.node9.daemon";
12244
- LAUNCHD_PLIST = import_path25.default.join(import_os20.default.homedir(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
12245
- SYSTEMD_UNIT_DIR = import_path25.default.join(import_os20.default.homedir(), ".config", "systemd", "user");
12246
- SYSTEMD_UNIT = import_path25.default.join(SYSTEMD_UNIT_DIR, "node9-daemon.service");
12280
+ LAUNCHD_PLIST = import_path26.default.join(import_os20.default.homedir(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
12281
+ SYSTEMD_UNIT_DIR = import_path26.default.join(import_os20.default.homedir(), ".config", "systemd", "user");
12282
+ SYSTEMD_UNIT = import_path26.default.join(SYSTEMD_UNIT_DIR, "node9-daemon.service");
12247
12283
  }
12248
12284
  });
12249
12285
 
@@ -12340,18 +12376,18 @@ function getModelContextLimit(model) {
12340
12376
  return 2e5;
12341
12377
  }
12342
12378
  function readSessionUsage() {
12343
- const projectsDir = import_path41.default.join(import_os35.default.homedir(), ".claude", "projects");
12379
+ const projectsDir = import_path42.default.join(import_os35.default.homedir(), ".claude", "projects");
12344
12380
  if (!import_fs38.default.existsSync(projectsDir)) return null;
12345
12381
  let latestFile = null;
12346
12382
  let latestMtime = 0;
12347
12383
  try {
12348
12384
  for (const dir of import_fs38.default.readdirSync(projectsDir)) {
12349
- const dirPath = import_path41.default.join(projectsDir, dir);
12385
+ const dirPath = import_path42.default.join(projectsDir, dir);
12350
12386
  try {
12351
12387
  if (!import_fs38.default.statSync(dirPath).isDirectory()) continue;
12352
12388
  for (const file of import_fs38.default.readdirSync(dirPath)) {
12353
12389
  if (!file.endsWith(".jsonl") || file.startsWith("agent-")) continue;
12354
- const filePath = import_path41.default.join(dirPath, file);
12390
+ const filePath = import_path42.default.join(dirPath, file);
12355
12391
  try {
12356
12392
  const mtime = import_fs38.default.statSync(filePath).mtimeMs;
12357
12393
  if (mtime > latestMtime) {
@@ -12612,7 +12648,7 @@ function buildRecoveryCardLines(req) {
12612
12648
  ];
12613
12649
  }
12614
12650
  function readApproversFromDisk() {
12615
- const configPath = import_path41.default.join(import_os35.default.homedir(), ".node9", "config.json");
12651
+ const configPath = import_path42.default.join(import_os35.default.homedir(), ".node9", "config.json");
12616
12652
  try {
12617
12653
  const raw = JSON.parse(import_fs38.default.readFileSync(configPath, "utf-8"));
12618
12654
  const settings = raw.settings ?? {};
@@ -12630,7 +12666,7 @@ function approverStatusLine() {
12630
12666
  return `${fmt("native", "native")} ${fmt("browser", "browser")} ${fmt("cloud", "cloud")} ${fmt("terminal", "terminal")}`;
12631
12667
  }
12632
12668
  function toggleApprover(channel) {
12633
- const configPath = import_path41.default.join(import_os35.default.homedir(), ".node9", "config.json");
12669
+ const configPath = import_path42.default.join(import_os35.default.homedir(), ".node9", "config.json");
12634
12670
  try {
12635
12671
  const raw = JSON.parse(import_fs38.default.readFileSync(configPath, "utf-8"));
12636
12672
  const settings = raw.settings ?? {};
@@ -12809,7 +12845,7 @@ async function startTail(options = {}) {
12809
12845
  postDecisionHttp(req2.id, httpDecision, csrfToken, port, httpOpts).catch((err2) => {
12810
12846
  try {
12811
12847
  import_fs38.default.appendFileSync(
12812
- import_path41.default.join(import_os35.default.homedir(), ".node9", "hook-debug.log"),
12848
+ import_path42.default.join(import_os35.default.homedir(), ".node9", "hook-debug.log"),
12813
12849
  `[tail] POST /decision failed: ${String(err2)}
12814
12850
  `
12815
12851
  );
@@ -12890,7 +12926,7 @@ async function startTail(options = {}) {
12890
12926
  }
12891
12927
  } catch {
12892
12928
  }
12893
- const auditLog = import_path41.default.join(import_os35.default.homedir(), ".node9", "audit.log");
12929
+ const auditLog = import_path42.default.join(import_os35.default.homedir(), ".node9", "audit.log");
12894
12930
  try {
12895
12931
  const unackedDlp = import_fs38.default.readFileSync(auditLog, "utf-8").split("\n").filter((l) => l.includes('"response-dlp"')).length;
12896
12932
  if (unackedDlp > 0) {
@@ -13077,7 +13113,7 @@ async function startTail(options = {}) {
13077
13113
  process.exit(1);
13078
13114
  });
13079
13115
  }
13080
- var import_http2, import_chalk25, import_fs38, import_os35, import_path41, import_readline5, import_child_process16, PID_FILE, ICONS, MODEL_CONTEXT_LIMITS, RESET2, BOLD2, RED, YELLOW, CYAN, GRAY, GREEN, HIDE_CURSOR, SHOW_CURSOR, ERASE_DOWN, pendingShownForId, pendingWrappedLines, DIVIDER;
13116
+ var import_http2, import_chalk25, import_fs38, import_os35, import_path42, import_readline5, import_child_process16, PID_FILE, ICONS, MODEL_CONTEXT_LIMITS, RESET2, BOLD2, RED, YELLOW, CYAN, GRAY, GREEN, HIDE_CURSOR, SHOW_CURSOR, ERASE_DOWN, pendingShownForId, pendingWrappedLines, DIVIDER;
13081
13117
  var init_tail = __esm({
13082
13118
  "src/tui/tail.ts"() {
13083
13119
  "use strict";
@@ -13085,13 +13121,13 @@ var init_tail = __esm({
13085
13121
  import_chalk25 = __toESM(require("chalk"));
13086
13122
  import_fs38 = __toESM(require("fs"));
13087
13123
  import_os35 = __toESM(require("os"));
13088
- import_path41 = __toESM(require("path"));
13124
+ import_path42 = __toESM(require("path"));
13089
13125
  import_readline5 = __toESM(require("readline"));
13090
13126
  import_child_process16 = require("child_process");
13091
13127
  init_daemon2();
13092
13128
  init_daemon();
13093
13129
  init_core();
13094
- PID_FILE = import_path41.default.join(import_os35.default.homedir(), ".node9", "daemon.pid");
13130
+ PID_FILE = import_path42.default.join(import_os35.default.homedir(), ".node9", "daemon.pid");
13095
13131
  ICONS = {
13096
13132
  bash: "\u{1F4BB}",
13097
13133
  shell: "\u{1F4BB}",
@@ -13241,7 +13277,7 @@ function countRulesInDir(rulesDir) {
13241
13277
  try {
13242
13278
  for (const entry of import_fs39.default.readdirSync(rulesDir, { withFileTypes: true })) {
13243
13279
  if (entry.isDirectory()) {
13244
- count += countRulesInDir(import_path42.default.join(rulesDir, entry.name));
13280
+ count += countRulesInDir(import_path43.default.join(rulesDir, entry.name));
13245
13281
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
13246
13282
  count++;
13247
13283
  }
@@ -13252,46 +13288,46 @@ function countRulesInDir(rulesDir) {
13252
13288
  }
13253
13289
  function isSamePath(a, b) {
13254
13290
  try {
13255
- return import_path42.default.resolve(a) === import_path42.default.resolve(b);
13291
+ return import_path43.default.resolve(a) === import_path43.default.resolve(b);
13256
13292
  } catch {
13257
13293
  return false;
13258
13294
  }
13259
13295
  }
13260
13296
  function countConfigs(cwd) {
13261
13297
  const homeDir2 = import_os36.default.homedir();
13262
- const claudeDir = import_path42.default.join(homeDir2, ".claude");
13298
+ const claudeDir = import_path43.default.join(homeDir2, ".claude");
13263
13299
  let claudeMdCount = 0;
13264
13300
  let rulesCount = 0;
13265
13301
  let hooksCount = 0;
13266
13302
  const userMcpServers = /* @__PURE__ */ new Set();
13267
13303
  const projectMcpServers = /* @__PURE__ */ new Set();
13268
- if (import_fs39.default.existsSync(import_path42.default.join(claudeDir, "CLAUDE.md"))) claudeMdCount++;
13269
- rulesCount += countRulesInDir(import_path42.default.join(claudeDir, "rules"));
13270
- const userSettings = import_path42.default.join(claudeDir, "settings.json");
13304
+ if (import_fs39.default.existsSync(import_path43.default.join(claudeDir, "CLAUDE.md"))) claudeMdCount++;
13305
+ rulesCount += countRulesInDir(import_path43.default.join(claudeDir, "rules"));
13306
+ const userSettings = import_path43.default.join(claudeDir, "settings.json");
13271
13307
  for (const name of getMcpServerNames(userSettings)) userMcpServers.add(name);
13272
13308
  hooksCount += countHooksInFile(userSettings);
13273
- const userClaudeJson = import_path42.default.join(homeDir2, ".claude.json");
13309
+ const userClaudeJson = import_path43.default.join(homeDir2, ".claude.json");
13274
13310
  for (const name of getMcpServerNames(userClaudeJson)) userMcpServers.add(name);
13275
13311
  for (const name of getDisabledMcpServers(userClaudeJson, "disabledMcpServers")) {
13276
13312
  userMcpServers.delete(name);
13277
13313
  }
13278
13314
  if (cwd) {
13279
- if (import_fs39.default.existsSync(import_path42.default.join(cwd, "CLAUDE.md"))) claudeMdCount++;
13280
- if (import_fs39.default.existsSync(import_path42.default.join(cwd, "CLAUDE.local.md"))) claudeMdCount++;
13281
- const projectClaudeDir = import_path42.default.join(cwd, ".claude");
13315
+ if (import_fs39.default.existsSync(import_path43.default.join(cwd, "CLAUDE.md"))) claudeMdCount++;
13316
+ if (import_fs39.default.existsSync(import_path43.default.join(cwd, "CLAUDE.local.md"))) claudeMdCount++;
13317
+ const projectClaudeDir = import_path43.default.join(cwd, ".claude");
13282
13318
  const overlapsUserScope = isSamePath(projectClaudeDir, claudeDir);
13283
13319
  if (!overlapsUserScope) {
13284
- if (import_fs39.default.existsSync(import_path42.default.join(projectClaudeDir, "CLAUDE.md"))) claudeMdCount++;
13285
- rulesCount += countRulesInDir(import_path42.default.join(projectClaudeDir, "rules"));
13286
- const projSettings = import_path42.default.join(projectClaudeDir, "settings.json");
13320
+ if (import_fs39.default.existsSync(import_path43.default.join(projectClaudeDir, "CLAUDE.md"))) claudeMdCount++;
13321
+ rulesCount += countRulesInDir(import_path43.default.join(projectClaudeDir, "rules"));
13322
+ const projSettings = import_path43.default.join(projectClaudeDir, "settings.json");
13287
13323
  for (const name of getMcpServerNames(projSettings)) projectMcpServers.add(name);
13288
13324
  hooksCount += countHooksInFile(projSettings);
13289
13325
  }
13290
- if (import_fs39.default.existsSync(import_path42.default.join(projectClaudeDir, "CLAUDE.local.md"))) claudeMdCount++;
13291
- const localSettings = import_path42.default.join(projectClaudeDir, "settings.local.json");
13326
+ if (import_fs39.default.existsSync(import_path43.default.join(projectClaudeDir, "CLAUDE.local.md"))) claudeMdCount++;
13327
+ const localSettings = import_path43.default.join(projectClaudeDir, "settings.local.json");
13292
13328
  for (const name of getMcpServerNames(localSettings)) projectMcpServers.add(name);
13293
13329
  hooksCount += countHooksInFile(localSettings);
13294
- const mcpJsonServers = getMcpServerNames(import_path42.default.join(cwd, ".mcp.json"));
13330
+ const mcpJsonServers = getMcpServerNames(import_path43.default.join(cwd, ".mcp.json"));
13295
13331
  const disabledMcpJson = getDisabledMcpServers(localSettings, "disabledMcpjsonServers");
13296
13332
  for (const name of disabledMcpJson) mcpJsonServers.delete(name);
13297
13333
  for (const name of mcpJsonServers) projectMcpServers.add(name);
@@ -13324,7 +13360,7 @@ function readActiveShieldsHud() {
13324
13360
  return shieldsCache.value;
13325
13361
  }
13326
13362
  try {
13327
- const shieldsPath = import_path42.default.join(import_os36.default.homedir(), ".node9", "shields.json");
13363
+ const shieldsPath = import_path43.default.join(import_os36.default.homedir(), ".node9", "shields.json");
13328
13364
  if (!import_fs39.default.existsSync(shieldsPath)) {
13329
13365
  shieldsCache = { value: [], ts: now };
13330
13366
  return [];
@@ -13431,9 +13467,9 @@ function renderContextLine(stdin) {
13431
13467
  async function main() {
13432
13468
  try {
13433
13469
  const [stdin, daemonStatus2] = await Promise.all([readStdin(), queryDaemon()]);
13434
- if (import_fs39.default.existsSync(import_path42.default.join(import_os36.default.homedir(), ".node9", "hud-debug"))) {
13470
+ if (import_fs39.default.existsSync(import_path43.default.join(import_os36.default.homedir(), ".node9", "hud-debug"))) {
13435
13471
  try {
13436
- const logPath = import_path42.default.join(import_os36.default.homedir(), ".node9", "hud-debug.log");
13472
+ const logPath = import_path43.default.join(import_os36.default.homedir(), ".node9", "hud-debug.log");
13437
13473
  const MAX_LOG_SIZE = 10 * 1024 * 1024;
13438
13474
  let size = 0;
13439
13475
  try {
@@ -13462,8 +13498,8 @@ async function main() {
13462
13498
  try {
13463
13499
  const cwd = stdin.cwd ?? process.cwd();
13464
13500
  for (const configPath of [
13465
- import_path42.default.join(cwd, "node9.config.json"),
13466
- import_path42.default.join(import_os36.default.homedir(), ".node9", "config.json")
13501
+ import_path43.default.join(cwd, "node9.config.json"),
13502
+ import_path43.default.join(import_os36.default.homedir(), ".node9", "config.json")
13467
13503
  ]) {
13468
13504
  if (!import_fs39.default.existsSync(configPath)) continue;
13469
13505
  const cfg = JSON.parse(import_fs39.default.readFileSync(configPath, "utf-8"));
@@ -13484,12 +13520,12 @@ async function main() {
13484
13520
  renderOffline();
13485
13521
  }
13486
13522
  }
13487
- var import_fs39, import_path42, import_os36, import_http3, RESET3, BOLD3, DIM, RED2, GREEN2, YELLOW2, BLUE, MAGENTA, CYAN2, WHITE, BAR_FILLED, BAR_EMPTY, BAR_WIDTH, shieldsCache, SHIELDS_CACHE_TTL_MS;
13523
+ var import_fs39, import_path43, import_os36, import_http3, RESET3, BOLD3, DIM, RED2, GREEN2, YELLOW2, BLUE, MAGENTA, CYAN2, WHITE, BAR_FILLED, BAR_EMPTY, BAR_WIDTH, shieldsCache, SHIELDS_CACHE_TTL_MS;
13488
13524
  var init_hud = __esm({
13489
13525
  "src/cli/hud.ts"() {
13490
13526
  "use strict";
13491
13527
  import_fs39 = __toESM(require("fs"));
13492
- import_path42 = __toESM(require("path"));
13528
+ import_path43 = __toESM(require("path"));
13493
13529
  import_os36 = __toESM(require("os"));
13494
13530
  import_http3 = __toESM(require("http"));
13495
13531
  init_daemon();
@@ -14539,7 +14575,7 @@ function getAgentsStatus(homeDir2 = import_os11.default.homedir()) {
14539
14575
  init_daemon2();
14540
14576
  var import_chalk26 = __toESM(require("chalk"));
14541
14577
  var import_fs40 = __toESM(require("fs"));
14542
- var import_path43 = __toESM(require("path"));
14578
+ var import_path44 = __toESM(require("path"));
14543
14579
  var import_os37 = __toESM(require("os"));
14544
14580
  var import_prompts2 = require("@inquirer/prompts");
14545
14581
 
@@ -14727,7 +14763,7 @@ init_daemon_starter();
14727
14763
  var import_chalk6 = __toESM(require("chalk"));
14728
14764
  var import_fs26 = __toESM(require("fs"));
14729
14765
  var import_child_process10 = require("child_process");
14730
- var import_path28 = __toESM(require("path"));
14766
+ var import_path29 = __toESM(require("path"));
14731
14767
  var import_os23 = __toESM(require("os"));
14732
14768
  init_orchestrator();
14733
14769
  init_daemon();
@@ -14739,9 +14775,9 @@ var import_child_process9 = require("child_process");
14739
14775
  var import_crypto8 = __toESM(require("crypto"));
14740
14776
  var import_fs24 = __toESM(require("fs"));
14741
14777
  var import_net3 = __toESM(require("net"));
14742
- var import_path26 = __toESM(require("path"));
14778
+ var import_path27 = __toESM(require("path"));
14743
14779
  var import_os21 = __toESM(require("os"));
14744
- var ACTIVITY_SOCKET_PATH3 = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : import_path26.default.join(import_os21.default.tmpdir(), "node9-activity.sock");
14780
+ var ACTIVITY_SOCKET_PATH3 = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : import_path27.default.join(import_os21.default.tmpdir(), "node9-activity.sock");
14745
14781
  function notifySnapshotTaken(hash, tool, argsSummary, fileCount) {
14746
14782
  try {
14747
14783
  const payload = JSON.stringify({
@@ -14761,8 +14797,8 @@ function notifySnapshotTaken(hash, tool, argsSummary, fileCount) {
14761
14797
  } catch {
14762
14798
  }
14763
14799
  }
14764
- var SNAPSHOT_STACK_PATH = import_path26.default.join(import_os21.default.homedir(), ".node9", "snapshots.json");
14765
- var UNDO_LATEST_PATH = import_path26.default.join(import_os21.default.homedir(), ".node9", "undo_latest.txt");
14800
+ var SNAPSHOT_STACK_PATH = import_path27.default.join(import_os21.default.homedir(), ".node9", "snapshots.json");
14801
+ var UNDO_LATEST_PATH = import_path27.default.join(import_os21.default.homedir(), ".node9", "undo_latest.txt");
14766
14802
  var MAX_SNAPSHOTS = 10;
14767
14803
  var GIT_TIMEOUT = 15e3;
14768
14804
  function readStack() {
@@ -14774,7 +14810,7 @@ function readStack() {
14774
14810
  return [];
14775
14811
  }
14776
14812
  function writeStack(stack) {
14777
- const dir = import_path26.default.dirname(SNAPSHOT_STACK_PATH);
14813
+ const dir = import_path27.default.dirname(SNAPSHOT_STACK_PATH);
14778
14814
  if (!import_fs24.default.existsSync(dir)) import_fs24.default.mkdirSync(dir, { recursive: true });
14779
14815
  import_fs24.default.writeFileSync(SNAPSHOT_STACK_PATH, JSON.stringify(stack, null, 2));
14780
14816
  }
@@ -14796,12 +14832,12 @@ function buildArgsSummary(tool, args) {
14796
14832
  return "";
14797
14833
  }
14798
14834
  function findProjectRoot(filePath) {
14799
- let dir = import_path26.default.dirname(filePath);
14835
+ let dir = import_path27.default.dirname(filePath);
14800
14836
  while (true) {
14801
- if (import_fs24.default.existsSync(import_path26.default.join(dir, ".git")) || import_fs24.default.existsSync(import_path26.default.join(dir, "package.json"))) {
14837
+ if (import_fs24.default.existsSync(import_path27.default.join(dir, ".git")) || import_fs24.default.existsSync(import_path27.default.join(dir, "package.json"))) {
14802
14838
  return dir;
14803
14839
  }
14804
- const parent = import_path26.default.dirname(dir);
14840
+ const parent = import_path27.default.dirname(dir);
14805
14841
  if (parent === dir) return process.cwd();
14806
14842
  dir = parent;
14807
14843
  }
@@ -14819,14 +14855,14 @@ function normalizeCwdForHash(cwd) {
14819
14855
  }
14820
14856
  function getShadowRepoDir(cwd) {
14821
14857
  const hash = import_crypto8.default.createHash("sha256").update(normalizeCwdForHash(cwd)).digest("hex").slice(0, 16);
14822
- return import_path26.default.join(import_os21.default.homedir(), ".node9", "snapshots", hash);
14858
+ return import_path27.default.join(import_os21.default.homedir(), ".node9", "snapshots", hash);
14823
14859
  }
14824
14860
  function cleanOrphanedIndexFiles(shadowDir) {
14825
14861
  try {
14826
14862
  const cutoff = Date.now() - 6e4;
14827
14863
  for (const f of import_fs24.default.readdirSync(shadowDir)) {
14828
14864
  if (f.startsWith("index_")) {
14829
- const fp = import_path26.default.join(shadowDir, f);
14865
+ const fp = import_path27.default.join(shadowDir, f);
14830
14866
  try {
14831
14867
  if (import_fs24.default.statSync(fp).mtimeMs < cutoff) import_fs24.default.unlinkSync(fp);
14832
14868
  } catch {
@@ -14840,7 +14876,7 @@ function writeShadowExcludes(shadowDir, ignorePaths) {
14840
14876
  const hardcoded = [".git", ".node9"];
14841
14877
  const lines = [...hardcoded, ...ignorePaths].join("\n");
14842
14878
  try {
14843
- import_fs24.default.writeFileSync(import_path26.default.join(shadowDir, "info", "exclude"), lines + "\n", "utf8");
14879
+ import_fs24.default.writeFileSync(import_path27.default.join(shadowDir, "info", "exclude"), lines + "\n", "utf8");
14844
14880
  } catch {
14845
14881
  }
14846
14882
  }
@@ -14853,7 +14889,7 @@ function ensureShadowRepo(shadowDir, cwd) {
14853
14889
  timeout: 3e3
14854
14890
  });
14855
14891
  if (check.status === 0) {
14856
- const ptPath = import_path26.default.join(shadowDir, "project-path.txt");
14892
+ const ptPath = import_path27.default.join(shadowDir, "project-path.txt");
14857
14893
  try {
14858
14894
  const stored = import_fs24.default.readFileSync(ptPath, "utf8").trim();
14859
14895
  if (stored === normalizedCwd) return true;
@@ -14880,7 +14916,7 @@ function ensureShadowRepo(shadowDir, cwd) {
14880
14916
  if (process.env.NODE9_DEBUG === "1") console.error("[Node9] git init --bare failed:", reason);
14881
14917
  return false;
14882
14918
  }
14883
- const configFile = import_path26.default.join(shadowDir, "config");
14919
+ const configFile = import_path27.default.join(shadowDir, "config");
14884
14920
  (0, import_child_process9.spawnSync)("git", ["config", "--file", configFile, "core.untrackedCache", "true"], {
14885
14921
  timeout: 3e3
14886
14922
  });
@@ -14888,7 +14924,7 @@ function ensureShadowRepo(shadowDir, cwd) {
14888
14924
  timeout: 3e3
14889
14925
  });
14890
14926
  try {
14891
- import_fs24.default.writeFileSync(import_path26.default.join(shadowDir, "project-path.txt"), normalizedCwd, "utf8");
14927
+ import_fs24.default.writeFileSync(import_path27.default.join(shadowDir, "project-path.txt"), normalizedCwd, "utf8");
14892
14928
  } catch {
14893
14929
  }
14894
14930
  return true;
@@ -14908,12 +14944,12 @@ async function createShadowSnapshot(tool = "unknown", args = {}, ignorePaths = [
14908
14944
  let indexFile = null;
14909
14945
  try {
14910
14946
  const rawFilePath = extractFilePath(args);
14911
- const absFilePath = rawFilePath && import_path26.default.isAbsolute(rawFilePath) ? rawFilePath : null;
14947
+ const absFilePath = rawFilePath && import_path27.default.isAbsolute(rawFilePath) ? rawFilePath : null;
14912
14948
  const cwd = absFilePath ? findProjectRoot(absFilePath) : process.cwd();
14913
14949
  const shadowDir = getShadowRepoDir(cwd);
14914
14950
  if (!ensureShadowRepo(shadowDir, cwd)) return null;
14915
14951
  writeShadowExcludes(shadowDir, ignorePaths);
14916
- indexFile = import_path26.default.join(shadowDir, `index_${process.pid}_${Date.now()}`);
14952
+ indexFile = import_path27.default.join(shadowDir, `index_${process.pid}_${Date.now()}`);
14917
14953
  const shadowEnv = {
14918
14954
  ...process.env,
14919
14955
  GIT_DIR: shadowDir,
@@ -15072,7 +15108,7 @@ function applyUndo(hash, cwd) {
15072
15108
  timeout: GIT_TIMEOUT
15073
15109
  }).stdout?.toString().trim().split("\n").filter(Boolean) ?? [];
15074
15110
  for (const file of [...tracked, ...untracked]) {
15075
- const fullPath = import_path26.default.join(dir, file);
15111
+ const fullPath = import_path27.default.join(dir, file);
15076
15112
  if (!snapshotFiles.has(file) && import_fs24.default.existsSync(fullPath)) {
15077
15113
  import_fs24.default.unlinkSync(fullPath);
15078
15114
  }
@@ -15088,11 +15124,11 @@ init_daemon_starter();
15088
15124
 
15089
15125
  // src/skill-pin.ts
15090
15126
  var import_fs25 = __toESM(require("fs"));
15091
- var import_path27 = __toESM(require("path"));
15127
+ var import_path28 = __toESM(require("path"));
15092
15128
  var import_os22 = __toESM(require("os"));
15093
15129
  var import_crypto9 = __toESM(require("crypto"));
15094
15130
  function getPinsFilePath() {
15095
- return import_path27.default.join(import_os22.default.homedir(), ".node9", "skill-pins.json");
15131
+ return import_path28.default.join(import_os22.default.homedir(), ".node9", "skill-pins.json");
15096
15132
  }
15097
15133
  var MAX_FILES = 5e3;
15098
15134
  var MAX_TOTAL_BYTES = 50 * 1024 * 1024;
@@ -15113,8 +15149,8 @@ function walkDir(root) {
15113
15149
  entries.sort((a, b) => a.name.localeCompare(b.name));
15114
15150
  for (const entry of entries) {
15115
15151
  if (out.length >= MAX_FILES) return;
15116
- const full = import_path27.default.join(dir, entry.name);
15117
- const rel = relDir ? import_path27.default.posix.join(relDir, entry.name) : entry.name;
15152
+ const full = import_path28.default.join(dir, entry.name);
15153
+ const rel = relDir ? import_path28.default.posix.join(relDir, entry.name) : entry.name;
15118
15154
  let lst;
15119
15155
  try {
15120
15156
  lst = import_fs25.default.lstatSync(full);
@@ -15188,7 +15224,7 @@ function readSkillPins() {
15188
15224
  }
15189
15225
  function writeSkillPins(data) {
15190
15226
  const filePath = getPinsFilePath();
15191
- import_fs25.default.mkdirSync(import_path27.default.dirname(filePath), { recursive: true });
15227
+ import_fs25.default.mkdirSync(import_path28.default.dirname(filePath), { recursive: true });
15192
15228
  const tmp = `${filePath}.${import_crypto9.default.randomBytes(6).toString("hex")}.tmp`;
15193
15229
  import_fs25.default.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
15194
15230
  import_fs25.default.renameSync(tmp, filePath);
@@ -15235,7 +15271,7 @@ function verifyAndPinRoots(roots) {
15235
15271
  return { kind: "verified" };
15236
15272
  }
15237
15273
  function defaultSkillRoots(_cwd) {
15238
- const marketplaces = import_path27.default.join(import_os22.default.homedir(), ".claude", "plugins", "marketplaces");
15274
+ const marketplaces = import_path28.default.join(import_os22.default.homedir(), ".claude", "plugins", "marketplaces");
15239
15275
  const roots = [];
15240
15276
  let registries;
15241
15277
  try {
@@ -15245,7 +15281,7 @@ function defaultSkillRoots(_cwd) {
15245
15281
  }
15246
15282
  for (const registry of registries) {
15247
15283
  if (!registry.isDirectory()) continue;
15248
- const pluginsDir = import_path27.default.join(marketplaces, registry.name, "plugins");
15284
+ const pluginsDir = import_path28.default.join(marketplaces, registry.name, "plugins");
15249
15285
  let plugins;
15250
15286
  try {
15251
15287
  plugins = import_fs25.default.readdirSync(pluginsDir, { withFileTypes: true });
@@ -15254,17 +15290,17 @@ function defaultSkillRoots(_cwd) {
15254
15290
  }
15255
15291
  for (const plugin of plugins) {
15256
15292
  if (!plugin.isDirectory()) continue;
15257
- roots.push(import_path27.default.join(pluginsDir, plugin.name));
15293
+ roots.push(import_path28.default.join(pluginsDir, plugin.name));
15258
15294
  }
15259
15295
  }
15260
15296
  return roots;
15261
15297
  }
15262
15298
  function resolveUserSkillRoot(entry, cwd) {
15263
15299
  if (!entry) return null;
15264
- if (entry.startsWith("~/") || entry === "~") return import_path27.default.join(import_os22.default.homedir(), entry.slice(1));
15265
- if (import_path27.default.isAbsolute(entry)) return entry;
15266
- if (!cwd || !import_path27.default.isAbsolute(cwd)) return null;
15267
- return import_path27.default.join(cwd, entry);
15300
+ if (entry.startsWith("~/") || entry === "~") return import_path28.default.join(import_os22.default.homedir(), entry.slice(1));
15301
+ if (import_path28.default.isAbsolute(entry)) return entry;
15302
+ if (!cwd || !import_path28.default.isAbsolute(cwd)) return null;
15303
+ return import_path28.default.join(cwd, entry);
15268
15304
  }
15269
15305
 
15270
15306
  // src/cli/commands/check.ts
@@ -15282,7 +15318,7 @@ function registerCheckCommand(program2) {
15282
15318
  } catch (err2) {
15283
15319
  const tempConfig = getConfig();
15284
15320
  if (process.env.NODE9_DEBUG === "1" || tempConfig.settings.enableHookLogDebug) {
15285
- const logPath = import_path28.default.join(import_os23.default.homedir(), ".node9", "hook-debug.log");
15321
+ const logPath = import_path29.default.join(import_os23.default.homedir(), ".node9", "hook-debug.log");
15286
15322
  const errMsg = err2 instanceof Error ? err2.message : String(err2);
15287
15323
  import_fs26.default.appendFileSync(
15288
15324
  logPath,
@@ -15297,11 +15333,11 @@ RAW: ${raw}
15297
15333
  if (config.settings.autoStartDaemon && !isDaemonRunning() && !process.env.NODE9_NO_AUTO_DAEMON) {
15298
15334
  try {
15299
15335
  const scriptPath = process.argv[1];
15300
- if (typeof scriptPath !== "string" || !import_path28.default.isAbsolute(scriptPath))
15336
+ if (typeof scriptPath !== "string" || !import_path29.default.isAbsolute(scriptPath))
15301
15337
  throw new Error("node9: argv[1] is not an absolute path");
15302
15338
  const resolvedScript = import_fs26.default.realpathSync(scriptPath);
15303
- const packageDist = import_fs26.default.realpathSync(import_path28.default.resolve(__dirname, "../.."));
15304
- if (!resolvedScript.startsWith(packageDist + import_path28.default.sep) && resolvedScript !== packageDist)
15339
+ const packageDist = import_fs26.default.realpathSync(import_path29.default.resolve(__dirname, "../.."));
15340
+ if (!resolvedScript.startsWith(packageDist + import_path29.default.sep) && resolvedScript !== packageDist)
15305
15341
  throw new Error(
15306
15342
  `node9: daemon spawn aborted \u2014 argv[1] (${resolvedScript}) is outside package dist (${packageDist})`
15307
15343
  );
@@ -15323,7 +15359,7 @@ RAW: ${raw}
15323
15359
  });
15324
15360
  d.unref();
15325
15361
  } catch (spawnErr) {
15326
- const logPath = import_path28.default.join(import_os23.default.homedir(), ".node9", "hook-debug.log");
15362
+ const logPath = import_path29.default.join(import_os23.default.homedir(), ".node9", "hook-debug.log");
15327
15363
  const msg = spawnErr instanceof Error ? spawnErr.message : String(spawnErr);
15328
15364
  try {
15329
15365
  import_fs26.default.appendFileSync(
@@ -15336,9 +15372,9 @@ RAW: ${raw}
15336
15372
  }
15337
15373
  }
15338
15374
  if (process.env.NODE9_DEBUG === "1" || config.settings.enableHookLogDebug) {
15339
- const logPath = import_path28.default.join(import_os23.default.homedir(), ".node9", "hook-debug.log");
15340
- if (!import_fs26.default.existsSync(import_path28.default.dirname(logPath)))
15341
- import_fs26.default.mkdirSync(import_path28.default.dirname(logPath), { recursive: true });
15375
+ const logPath = import_path29.default.join(import_os23.default.homedir(), ".node9", "hook-debug.log");
15376
+ if (!import_fs26.default.existsSync(import_path29.default.dirname(logPath)))
15377
+ import_fs26.default.mkdirSync(import_path29.default.dirname(logPath), { recursive: true });
15342
15378
  import_fs26.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${raw}
15343
15379
  `);
15344
15380
  }
@@ -15406,8 +15442,8 @@ RAW: ${raw}
15406
15442
  const safeSessionId = /^[A-Za-z0-9_\-]{1,128}$/.test(rawSessionId) ? rawSessionId : "";
15407
15443
  if (skillPinCfg.enabled && safeSessionId) {
15408
15444
  try {
15409
- const sessionsDir = import_path28.default.join(import_os23.default.homedir(), ".node9", "skill-sessions");
15410
- const flagPath = import_path28.default.join(sessionsDir, `${safeSessionId}.json`);
15445
+ const sessionsDir = import_path29.default.join(import_os23.default.homedir(), ".node9", "skill-sessions");
15446
+ const flagPath = import_path29.default.join(sessionsDir, `${safeSessionId}.json`);
15411
15447
  let flag = null;
15412
15448
  try {
15413
15449
  flag = JSON.parse(import_fs26.default.readFileSync(flagPath, "utf-8"));
@@ -15459,7 +15495,7 @@ RAW: ${raw}
15459
15495
  return;
15460
15496
  }
15461
15497
  if (!flag || flag.state !== "verified" && flag.state !== "warned") {
15462
- const absoluteCwd = typeof payload.cwd === "string" && import_path28.default.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15498
+ const absoluteCwd = typeof payload.cwd === "string" && import_path29.default.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15463
15499
  const extraRoots = skillPinCfg.roots;
15464
15500
  const resolvedExtra = extraRoots.map((r) => resolveUserSkillRoot(r, absoluteCwd)).filter((r) => typeof r === "string");
15465
15501
  const roots = [...defaultSkillRoots(absoluteCwd), ...resolvedExtra];
@@ -15501,7 +15537,7 @@ RAW: ${raw}
15501
15537
  try {
15502
15538
  const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1e3;
15503
15539
  for (const name of import_fs26.default.readdirSync(sessionsDir)) {
15504
- const p = import_path28.default.join(sessionsDir, name);
15540
+ const p = import_path29.default.join(sessionsDir, name);
15505
15541
  try {
15506
15542
  if (import_fs26.default.statSync(p).mtimeMs < cutoff) import_fs26.default.unlinkSync(p);
15507
15543
  } catch {
@@ -15513,7 +15549,7 @@ RAW: ${raw}
15513
15549
  } catch (err2) {
15514
15550
  if (process.env.NODE9_DEBUG === "1") {
15515
15551
  try {
15516
- const dbg = import_path28.default.join(import_os23.default.homedir(), ".node9", "hook-debug.log");
15552
+ const dbg = import_path29.default.join(import_os23.default.homedir(), ".node9", "hook-debug.log");
15517
15553
  const msg = err2 instanceof Error ? err2.message : String(err2);
15518
15554
  import_fs26.default.appendFileSync(dbg, `[${(/* @__PURE__ */ new Date()).toISOString()}] SKILL_PIN_ERROR: ${msg}
15519
15555
  `);
@@ -15525,7 +15561,7 @@ RAW: ${raw}
15525
15561
  if (shouldSnapshot(toolName, toolInput, config)) {
15526
15562
  await createShadowSnapshot(toolName, toolInput, config.policy.snapshot.ignorePaths);
15527
15563
  }
15528
- const safeCwdForAuth = typeof payload.cwd === "string" && import_path28.default.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15564
+ const safeCwdForAuth = typeof payload.cwd === "string" && import_path29.default.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15529
15565
  const result = await authorizeHeadless(toolName, toolInput, meta, {
15530
15566
  cwd: safeCwdForAuth
15531
15567
  });
@@ -15569,7 +15605,7 @@ RAW: ${raw}
15569
15605
  });
15570
15606
  } catch (err2) {
15571
15607
  if (process.env.NODE9_DEBUG === "1") {
15572
- const logPath = import_path28.default.join(import_os23.default.homedir(), ".node9", "hook-debug.log");
15608
+ const logPath = import_path29.default.join(import_os23.default.homedir(), ".node9", "hook-debug.log");
15573
15609
  const errMsg = err2 instanceof Error ? err2.message : String(err2);
15574
15610
  import_fs26.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] ERROR: ${errMsg}
15575
15611
  `);
@@ -15606,7 +15642,7 @@ RAW: ${raw}
15606
15642
 
15607
15643
  // src/cli/commands/log.ts
15608
15644
  var import_fs27 = __toESM(require("fs"));
15609
- var import_path29 = __toESM(require("path"));
15645
+ var import_path30 = __toESM(require("path"));
15610
15646
  var import_os24 = __toESM(require("os"));
15611
15647
  init_audit();
15612
15648
  init_config();
@@ -15682,9 +15718,9 @@ function registerLogCommand(program2) {
15682
15718
  decision: "allowed",
15683
15719
  source: "post-hook"
15684
15720
  };
15685
- const logPath = import_path29.default.join(import_os24.default.homedir(), ".node9", "audit.log");
15686
- if (!import_fs27.default.existsSync(import_path29.default.dirname(logPath)))
15687
- import_fs27.default.mkdirSync(import_path29.default.dirname(logPath), { recursive: true });
15721
+ const logPath = import_path30.default.join(import_os24.default.homedir(), ".node9", "audit.log");
15722
+ if (!import_fs27.default.existsSync(import_path30.default.dirname(logPath)))
15723
+ import_fs27.default.mkdirSync(import_path30.default.dirname(logPath), { recursive: true });
15688
15724
  import_fs27.default.appendFileSync(logPath, JSON.stringify(entry) + "\n");
15689
15725
  if ((tool === "Bash" || tool === "bash") && isDaemonRunning()) {
15690
15726
  const command = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
@@ -15718,7 +15754,7 @@ function registerLogCommand(program2) {
15718
15754
  }
15719
15755
  }
15720
15756
  }
15721
- const safeCwd = typeof payload.cwd === "string" && import_path29.default.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15757
+ const safeCwd = typeof payload.cwd === "string" && import_path30.default.isAbsolute(payload.cwd) ? payload.cwd : void 0;
15722
15758
  const config = getConfig(safeCwd);
15723
15759
  if ((tool === "Bash" || tool === "bash") && config.settings.enableUndo !== false) {
15724
15760
  const bashCommand = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
@@ -15739,7 +15775,7 @@ function registerLogCommand(program2) {
15739
15775
  const msg = err2 instanceof Error ? err2.message : String(err2);
15740
15776
  process.stderr.write(`[Node9] audit log error: ${msg}
15741
15777
  `);
15742
- const debugPath = import_path29.default.join(import_os24.default.homedir(), ".node9", "hook-debug.log");
15778
+ const debugPath = import_path30.default.join(import_os24.default.homedir(), ".node9", "hook-debug.log");
15743
15779
  try {
15744
15780
  import_fs27.default.appendFileSync(debugPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] LOG_ERROR: ${msg}
15745
15781
  `);
@@ -16142,7 +16178,7 @@ function registerConfigShowCommand(program2) {
16142
16178
  // src/cli/commands/doctor.ts
16143
16179
  var import_chalk8 = __toESM(require("chalk"));
16144
16180
  var import_fs28 = __toESM(require("fs"));
16145
- var import_path30 = __toESM(require("path"));
16181
+ var import_path31 = __toESM(require("path"));
16146
16182
  var import_os25 = __toESM(require("os"));
16147
16183
  var import_child_process11 = require("child_process");
16148
16184
  init_daemon();
@@ -16197,7 +16233,7 @@ function registerDoctorCommand(program2, version2) {
16197
16233
  );
16198
16234
  }
16199
16235
  section("Configuration");
16200
- const globalConfigPath = import_path30.default.join(homeDir2, ".node9", "config.json");
16236
+ const globalConfigPath = import_path31.default.join(homeDir2, ".node9", "config.json");
16201
16237
  if (import_fs28.default.existsSync(globalConfigPath)) {
16202
16238
  try {
16203
16239
  JSON.parse(import_fs28.default.readFileSync(globalConfigPath, "utf-8"));
@@ -16208,7 +16244,7 @@ function registerDoctorCommand(program2, version2) {
16208
16244
  } else {
16209
16245
  warn("~/.node9/config.json not found (using defaults)", "Run: node9 init");
16210
16246
  }
16211
- const projectConfigPath = import_path30.default.join(process.cwd(), "node9.config.json");
16247
+ const projectConfigPath = import_path31.default.join(process.cwd(), "node9.config.json");
16212
16248
  if (import_fs28.default.existsSync(projectConfigPath)) {
16213
16249
  try {
16214
16250
  JSON.parse(import_fs28.default.readFileSync(projectConfigPath, "utf-8"));
@@ -16220,7 +16256,7 @@ function registerDoctorCommand(program2, version2) {
16220
16256
  );
16221
16257
  }
16222
16258
  }
16223
- const credsPath = import_path30.default.join(homeDir2, ".node9", "credentials.json");
16259
+ const credsPath = import_path31.default.join(homeDir2, ".node9", "credentials.json");
16224
16260
  if (import_fs28.default.existsSync(credsPath)) {
16225
16261
  pass("Cloud credentials found (~/.node9/credentials.json)");
16226
16262
  } else {
@@ -16230,7 +16266,7 @@ function registerDoctorCommand(program2, version2) {
16230
16266
  );
16231
16267
  }
16232
16268
  section("Agent Hooks");
16233
- const claudeSettingsPath = import_path30.default.join(homeDir2, ".claude", "settings.json");
16269
+ const claudeSettingsPath = import_path31.default.join(homeDir2, ".claude", "settings.json");
16234
16270
  if (import_fs28.default.existsSync(claudeSettingsPath)) {
16235
16271
  try {
16236
16272
  const cs = JSON.parse(import_fs28.default.readFileSync(claudeSettingsPath, "utf-8"));
@@ -16249,7 +16285,7 @@ function registerDoctorCommand(program2, version2) {
16249
16285
  } else {
16250
16286
  warn("Claude Code \u2014 not configured", "Run: node9 setup claude");
16251
16287
  }
16252
- const geminiSettingsPath = import_path30.default.join(homeDir2, ".gemini", "settings.json");
16288
+ const geminiSettingsPath = import_path31.default.join(homeDir2, ".gemini", "settings.json");
16253
16289
  if (import_fs28.default.existsSync(geminiSettingsPath)) {
16254
16290
  try {
16255
16291
  const gs = JSON.parse(import_fs28.default.readFileSync(geminiSettingsPath, "utf-8"));
@@ -16268,7 +16304,7 @@ function registerDoctorCommand(program2, version2) {
16268
16304
  } else {
16269
16305
  warn("Gemini CLI \u2014 not configured", "Run: node9 setup gemini (skip if not using Gemini)");
16270
16306
  }
16271
- const cursorHooksPath = import_path30.default.join(homeDir2, ".cursor", "hooks.json");
16307
+ const cursorHooksPath = import_path31.default.join(homeDir2, ".cursor", "hooks.json");
16272
16308
  if (import_fs28.default.existsSync(cursorHooksPath)) {
16273
16309
  try {
16274
16310
  const cur = JSON.parse(import_fs28.default.readFileSync(cursorHooksPath, "utf-8"));
@@ -16310,7 +16346,7 @@ function registerDoctorCommand(program2, version2) {
16310
16346
  // src/cli/commands/audit.ts
16311
16347
  var import_chalk9 = __toESM(require("chalk"));
16312
16348
  var import_fs29 = __toESM(require("fs"));
16313
- var import_path31 = __toESM(require("path"));
16349
+ var import_path32 = __toESM(require("path"));
16314
16350
  var import_os26 = __toESM(require("os"));
16315
16351
  function formatRelativeTime(timestamp) {
16316
16352
  const diff = Date.now() - new Date(timestamp).getTime();
@@ -16324,7 +16360,7 @@ function formatRelativeTime(timestamp) {
16324
16360
  }
16325
16361
  function registerAuditCommand(program2) {
16326
16362
  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) => {
16327
- const logPath = import_path31.default.join(import_os26.default.homedir(), ".node9", "audit.log");
16363
+ const logPath = import_path32.default.join(import_os26.default.homedir(), ".node9", "audit.log");
16328
16364
  if (!import_fs29.default.existsSync(logPath)) {
16329
16365
  console.log(
16330
16366
  import_chalk9.default.yellow("No audit logs found. Run node9 with an agent to generate entries.")
@@ -16386,7 +16422,7 @@ function registerAuditCommand(program2) {
16386
16422
  // src/cli/commands/report.ts
16387
16423
  var import_chalk10 = __toESM(require("chalk"));
16388
16424
  var import_fs30 = __toESM(require("fs"));
16389
- var import_path32 = __toESM(require("path"));
16425
+ var import_path33 = __toESM(require("path"));
16390
16426
  var import_os27 = __toESM(require("os"));
16391
16427
  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;
16392
16428
  function buildTestTimestamps(allEntries) {
@@ -16514,7 +16550,7 @@ function loadClaudeCost(start, end) {
16514
16550
  cacheWriteTokens: 0,
16515
16551
  cacheReadTokens: 0
16516
16552
  };
16517
- const projectsDir = import_path32.default.join(import_os27.default.homedir(), ".claude", "projects");
16553
+ const projectsDir = import_path33.default.join(import_os27.default.homedir(), ".claude", "projects");
16518
16554
  if (!import_fs30.default.existsSync(projectsDir)) return empty;
16519
16555
  let dirs;
16520
16556
  try {
@@ -16530,7 +16566,7 @@ function loadClaudeCost(start, end) {
16530
16566
  const byDay = /* @__PURE__ */ new Map();
16531
16567
  const byModel = /* @__PURE__ */ new Map();
16532
16568
  for (const proj of dirs) {
16533
- const projPath = import_path32.default.join(projectsDir, proj);
16569
+ const projPath = import_path33.default.join(projectsDir, proj);
16534
16570
  let files;
16535
16571
  try {
16536
16572
  const stat = import_fs30.default.statSync(projPath);
@@ -16541,7 +16577,7 @@ function loadClaudeCost(start, end) {
16541
16577
  }
16542
16578
  for (const file of files) {
16543
16579
  try {
16544
- const raw = import_fs30.default.readFileSync(import_path32.default.join(projPath, file), "utf-8");
16580
+ const raw = import_fs30.default.readFileSync(import_path33.default.join(projPath, file), "utf-8");
16545
16581
  for (const line of raw.split("\n")) {
16546
16582
  if (!line.trim()) continue;
16547
16583
  let entry;
@@ -16582,7 +16618,7 @@ function loadClaudeCost(start, end) {
16582
16618
  return { total, byDay, byModel, inputTokens, outputTokens, cacheWriteTokens, cacheReadTokens };
16583
16619
  }
16584
16620
  function loadCodexCost(start, end) {
16585
- const sessionsBase = import_path32.default.join(import_os27.default.homedir(), ".codex", "sessions");
16621
+ const sessionsBase = import_path33.default.join(import_os27.default.homedir(), ".codex", "sessions");
16586
16622
  const byDay = /* @__PURE__ */ new Map();
16587
16623
  let total = 0;
16588
16624
  let toolCalls = 0;
@@ -16590,28 +16626,28 @@ function loadCodexCost(start, end) {
16590
16626
  const jsonlFiles = [];
16591
16627
  try {
16592
16628
  for (const year of import_fs30.default.readdirSync(sessionsBase)) {
16593
- const yearPath = import_path32.default.join(sessionsBase, year);
16629
+ const yearPath = import_path33.default.join(sessionsBase, year);
16594
16630
  try {
16595
16631
  if (!import_fs30.default.statSync(yearPath).isDirectory()) continue;
16596
16632
  } catch {
16597
16633
  continue;
16598
16634
  }
16599
16635
  for (const month of import_fs30.default.readdirSync(yearPath)) {
16600
- const monthPath = import_path32.default.join(yearPath, month);
16636
+ const monthPath = import_path33.default.join(yearPath, month);
16601
16637
  try {
16602
16638
  if (!import_fs30.default.statSync(monthPath).isDirectory()) continue;
16603
16639
  } catch {
16604
16640
  continue;
16605
16641
  }
16606
16642
  for (const day of import_fs30.default.readdirSync(monthPath)) {
16607
- const dayPath = import_path32.default.join(monthPath, day);
16643
+ const dayPath = import_path33.default.join(monthPath, day);
16608
16644
  try {
16609
16645
  if (!import_fs30.default.statSync(dayPath).isDirectory()) continue;
16610
16646
  } catch {
16611
16647
  continue;
16612
16648
  }
16613
16649
  for (const file of import_fs30.default.readdirSync(dayPath)) {
16614
- if (file.endsWith(".jsonl")) jsonlFiles.push(import_path32.default.join(dayPath, file));
16650
+ if (file.endsWith(".jsonl")) jsonlFiles.push(import_path33.default.join(dayPath, file));
16615
16651
  }
16616
16652
  }
16617
16653
  }
@@ -16672,7 +16708,7 @@ function registerReportCommand(program2) {
16672
16708
  const period = ["today", "7d", "30d", "month"].includes(
16673
16709
  options.period
16674
16710
  ) ? options.period : "7d";
16675
- const logPath = import_path32.default.join(import_os27.default.homedir(), ".node9", "audit.log");
16711
+ const logPath = import_path33.default.join(import_os27.default.homedir(), ".node9", "audit.log");
16676
16712
  const allEntries = parseAuditLog(logPath);
16677
16713
  const unackedDlp = allEntries.filter((e) => e.source === "response-dlp");
16678
16714
  if (unackedDlp.length > 0) {
@@ -17178,7 +17214,7 @@ function registerDaemonCommand(program2) {
17178
17214
  // src/cli/commands/status.ts
17179
17215
  var import_chalk12 = __toESM(require("chalk"));
17180
17216
  var import_fs31 = __toESM(require("fs"));
17181
- var import_path33 = __toESM(require("path"));
17217
+ var import_path34 = __toESM(require("path"));
17182
17218
  var import_os28 = __toESM(require("os"));
17183
17219
  init_core();
17184
17220
  init_daemon();
@@ -17249,8 +17285,8 @@ function registerStatusCommand(program2) {
17249
17285
  console.log("");
17250
17286
  const modeLabel = settings.mode === "audit" ? import_chalk12.default.blue("audit") : settings.mode === "strict" ? import_chalk12.default.red("strict") : import_chalk12.default.white("standard");
17251
17287
  console.log(` Mode: ${modeLabel}`);
17252
- const projectConfig = import_path33.default.join(process.cwd(), "node9.config.json");
17253
- const globalConfig = import_path33.default.join(import_os28.default.homedir(), ".node9", "config.json");
17288
+ const projectConfig = import_path34.default.join(process.cwd(), "node9.config.json");
17289
+ const globalConfig = import_path34.default.join(import_os28.default.homedir(), ".node9", "config.json");
17254
17290
  console.log(
17255
17291
  ` Local: ${import_fs31.default.existsSync(projectConfig) ? import_chalk12.default.green("Active (node9.config.json)") : import_chalk12.default.gray("Not present")}`
17256
17292
  );
@@ -17264,13 +17300,13 @@ function registerStatusCommand(program2) {
17264
17300
  }
17265
17301
  const homeDir2 = import_os28.default.homedir();
17266
17302
  const claudeSettings = readJson2(
17267
- import_path33.default.join(homeDir2, ".claude", "settings.json")
17303
+ import_path34.default.join(homeDir2, ".claude", "settings.json")
17268
17304
  );
17269
- const claudeConfig = readJson2(import_path33.default.join(homeDir2, ".claude.json"));
17305
+ const claudeConfig = readJson2(import_path34.default.join(homeDir2, ".claude.json"));
17270
17306
  const geminiSettings = readJson2(
17271
- import_path33.default.join(homeDir2, ".gemini", "settings.json")
17307
+ import_path34.default.join(homeDir2, ".gemini", "settings.json")
17272
17308
  );
17273
- const cursorConfig = readJson2(import_path33.default.join(homeDir2, ".cursor", "mcp.json"));
17309
+ const cursorConfig = readJson2(import_path34.default.join(homeDir2, ".cursor", "mcp.json"));
17274
17310
  const agentFound = claudeSettings || claudeConfig || geminiSettings || cursorConfig;
17275
17311
  if (agentFound) {
17276
17312
  console.log("");
@@ -17330,7 +17366,7 @@ function registerStatusCommand(program2) {
17330
17366
  // src/cli/commands/init.ts
17331
17367
  var import_chalk13 = __toESM(require("chalk"));
17332
17368
  var import_fs32 = __toESM(require("fs"));
17333
- var import_path34 = __toESM(require("path"));
17369
+ var import_path35 = __toESM(require("path"));
17334
17370
  var import_os29 = __toESM(require("os"));
17335
17371
  var import_https3 = __toESM(require("https"));
17336
17372
  init_core();
@@ -17392,7 +17428,7 @@ function registerInitCommand(program2) {
17392
17428
  }
17393
17429
  console.log("");
17394
17430
  }
17395
- const configPath = import_path34.default.join(import_os29.default.homedir(), ".node9", "config.json");
17431
+ const configPath = import_path35.default.join(import_os29.default.homedir(), ".node9", "config.json");
17396
17432
  if (import_fs32.default.existsSync(configPath) && !options.force) {
17397
17433
  try {
17398
17434
  const existing = JSON.parse(import_fs32.default.readFileSync(configPath, "utf-8"));
@@ -17413,7 +17449,7 @@ function registerInitCommand(program2) {
17413
17449
  ...DEFAULT_CONFIG,
17414
17450
  settings: { ...DEFAULT_CONFIG.settings, mode: chosenMode }
17415
17451
  };
17416
- const dir = import_path34.default.dirname(configPath);
17452
+ const dir = import_path35.default.dirname(configPath);
17417
17453
  if (!import_fs32.default.existsSync(dir)) import_fs32.default.mkdirSync(dir, { recursive: true });
17418
17454
  import_fs32.default.writeFileSync(configPath, JSON.stringify(configToSave, null, 2) + "\n");
17419
17455
  console.log(import_chalk13.default.green(`\u2705 Config created: ${configPath}`));
@@ -17500,7 +17536,7 @@ function registerInitCommand(program2) {
17500
17536
  }
17501
17537
 
17502
17538
  // src/cli/commands/undo.ts
17503
- var import_path35 = __toESM(require("path"));
17539
+ var import_path36 = __toESM(require("path"));
17504
17540
  var import_chalk15 = __toESM(require("chalk"));
17505
17541
 
17506
17542
  // src/tui/undo-navigator.ts
@@ -17659,7 +17695,7 @@ function findMatchingCwd(startDir, history) {
17659
17695
  let dir = startDir;
17660
17696
  while (true) {
17661
17697
  if (cwds.has(dir)) return dir;
17662
- const parent = import_path35.default.dirname(dir);
17698
+ const parent = import_path36.default.dirname(dir);
17663
17699
  if (parent === dir) return null;
17664
17700
  dir = parent;
17665
17701
  }
@@ -17856,11 +17892,11 @@ init_provenance();
17856
17892
 
17857
17893
  // src/mcp-pin.ts
17858
17894
  var import_fs33 = __toESM(require("fs"));
17859
- var import_path36 = __toESM(require("path"));
17895
+ var import_path37 = __toESM(require("path"));
17860
17896
  var import_os30 = __toESM(require("os"));
17861
17897
  var import_crypto10 = __toESM(require("crypto"));
17862
17898
  function getPinsFilePath2() {
17863
- return import_path36.default.join(import_os30.default.homedir(), ".node9", "mcp-pins.json");
17899
+ return import_path37.default.join(import_os30.default.homedir(), ".node9", "mcp-pins.json");
17864
17900
  }
17865
17901
  function hashToolDefinitions(tools) {
17866
17902
  const sorted = [...tools].sort((a, b) => {
@@ -17901,7 +17937,7 @@ function readMcpPins() {
17901
17937
  }
17902
17938
  function writeMcpPins(data) {
17903
17939
  const filePath = getPinsFilePath2();
17904
- import_fs33.default.mkdirSync(import_path36.default.dirname(filePath), { recursive: true });
17940
+ import_fs33.default.mkdirSync(import_path37.default.dirname(filePath), { recursive: true });
17905
17941
  const tmp = `${filePath}.${import_crypto10.default.randomBytes(6).toString("hex")}.tmp`;
17906
17942
  import_fs33.default.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
17907
17943
  import_fs33.default.renameSync(tmp, filePath);
@@ -18354,7 +18390,7 @@ function registerMcpGatewayCommand(program2) {
18354
18390
  var import_readline4 = __toESM(require("readline"));
18355
18391
  var import_fs34 = __toESM(require("fs"));
18356
18392
  var import_os31 = __toESM(require("os"));
18357
- var import_path37 = __toESM(require("path"));
18393
+ var import_path38 = __toESM(require("path"));
18358
18394
  var import_child_process15 = require("child_process");
18359
18395
  init_core();
18360
18396
  init_daemon();
@@ -18605,8 +18641,8 @@ function handleStatus() {
18605
18641
  lines.push(`Active shields: ${activeShields.length > 0 ? activeShields.join(", ") : "none"}`);
18606
18642
  lines.push(`Smart rules: ${config.policy.smartRules.length} loaded`);
18607
18643
  lines.push(`DLP: ${config.policy.dlp?.enabled !== false ? "enabled" : "disabled"}`);
18608
- const projectConfig = import_path37.default.join(process.cwd(), "node9.config.json");
18609
- const globalConfig = import_path37.default.join(import_os31.default.homedir(), ".node9", "config.json");
18644
+ const projectConfig = import_path38.default.join(process.cwd(), "node9.config.json");
18645
+ const globalConfig = import_path38.default.join(import_os31.default.homedir(), ".node9", "config.json");
18610
18646
  lines.push(
18611
18647
  `Project config (node9.config.json): ${import_fs34.default.existsSync(projectConfig) ? "present" : "not found"}`
18612
18648
  );
@@ -18685,7 +18721,7 @@ function handleShieldDisable(args) {
18685
18721
  writeActiveShields(active.filter((s) => s !== name));
18686
18722
  return `Shield "${name}" disabled.`;
18687
18723
  }
18688
- var GLOBAL_CONFIG_PATH2 = import_path37.default.join(import_os31.default.homedir(), ".node9", "config.json");
18724
+ var GLOBAL_CONFIG_PATH2 = import_path38.default.join(import_os31.default.homedir(), ".node9", "config.json");
18689
18725
  var APPROVER_CHANNELS = ["native", "browser", "cloud", "terminal"];
18690
18726
  function readGlobalConfigRaw() {
18691
18727
  try {
@@ -18697,7 +18733,7 @@ function readGlobalConfigRaw() {
18697
18733
  return {};
18698
18734
  }
18699
18735
  function writeGlobalConfigRaw(data) {
18700
- const dir = import_path37.default.dirname(GLOBAL_CONFIG_PATH2);
18736
+ const dir = import_path38.default.dirname(GLOBAL_CONFIG_PATH2);
18701
18737
  if (!import_fs34.default.existsSync(dir)) import_fs34.default.mkdirSync(dir, { recursive: true });
18702
18738
  import_fs34.default.writeFileSync(GLOBAL_CONFIG_PATH2, JSON.stringify(data, null, 2) + "\n");
18703
18739
  }
@@ -18743,7 +18779,7 @@ function handleApproverSet(args) {
18743
18779
  function handleAuditGet(args) {
18744
18780
  const limit = Math.min(typeof args.limit === "number" ? args.limit : 20, 100);
18745
18781
  const filter = typeof args.filter === "string" && args.filter !== "all" ? args.filter : null;
18746
- const auditPath = import_path37.default.join(import_os31.default.homedir(), ".node9", "audit.log");
18782
+ const auditPath = import_path38.default.join(import_os31.default.homedir(), ".node9", "audit.log");
18747
18783
  if (!import_fs34.default.existsSync(auditPath)) return "No audit log found.";
18748
18784
  const rawLines = import_fs34.default.readFileSync(auditPath, "utf-8").trim().split("\n").filter(Boolean);
18749
18785
  const parsed = [];
@@ -19300,7 +19336,7 @@ init_scan();
19300
19336
  // src/cli/commands/sessions.ts
19301
19337
  var import_chalk22 = __toESM(require("chalk"));
19302
19338
  var import_fs35 = __toESM(require("fs"));
19303
- var import_path38 = __toESM(require("path"));
19339
+ var import_path39 = __toESM(require("path"));
19304
19340
  var import_os32 = __toESM(require("os"));
19305
19341
  var CLAUDE_PRICING3 = {
19306
19342
  "claude-opus-4-6": { i: 5e-6, o: 25e-6, cw: 625e-8, cr: 5e-7 },
@@ -19342,7 +19378,7 @@ function encodeProjectPath(projectPath) {
19342
19378
  }
19343
19379
  function sessionJsonlPath(projectPath, sessionId) {
19344
19380
  const encoded = encodeProjectPath(projectPath);
19345
- return import_path38.default.join(import_os32.default.homedir(), ".claude", "projects", encoded, `${sessionId}.jsonl`);
19381
+ return import_path39.default.join(import_os32.default.homedir(), ".claude", "projects", encoded, `${sessionId}.jsonl`);
19346
19382
  }
19347
19383
  function projectLabel(projectPath) {
19348
19384
  return projectPath.replace(import_os32.default.homedir(), "~");
@@ -19414,7 +19450,7 @@ function parseSessionLines(lines) {
19414
19450
  return { toolCalls, costUSD, hasSnapshot, modifiedFiles };
19415
19451
  }
19416
19452
  function loadAuditEntries(auditPath) {
19417
- const aPath = auditPath ?? import_path38.default.join(import_os32.default.homedir(), ".node9", "audit.log");
19453
+ const aPath = auditPath ?? import_path39.default.join(import_os32.default.homedir(), ".node9", "audit.log");
19418
19454
  let raw;
19419
19455
  try {
19420
19456
  raw = import_fs35.default.readFileSync(aPath, "utf-8");
@@ -19453,7 +19489,7 @@ function auditEntriesInWindow(entries, windowStart, windowEnd) {
19453
19489
  return result;
19454
19490
  }
19455
19491
  function buildGeminiSessions(days, allAuditEntries) {
19456
- const tmpDir = import_path38.default.join(import_os32.default.homedir(), ".gemini", "tmp");
19492
+ const tmpDir = import_path39.default.join(import_os32.default.homedir(), ".gemini", "tmp");
19457
19493
  if (!import_fs35.default.existsSync(tmpDir)) return [];
19458
19494
  const cutoff = days !== null ? (() => {
19459
19495
  const d = /* @__PURE__ */ new Date();
@@ -19469,18 +19505,18 @@ function buildGeminiSessions(days, allAuditEntries) {
19469
19505
  }
19470
19506
  const summaries = [];
19471
19507
  for (const slug of slugDirs) {
19472
- const slugPath = import_path38.default.join(tmpDir, slug);
19508
+ const slugPath = import_path39.default.join(tmpDir, slug);
19473
19509
  try {
19474
19510
  if (!import_fs35.default.statSync(slugPath).isDirectory()) continue;
19475
19511
  } catch {
19476
19512
  continue;
19477
19513
  }
19478
- let projectRoot = import_path38.default.join(import_os32.default.homedir(), slug);
19514
+ let projectRoot = import_path39.default.join(import_os32.default.homedir(), slug);
19479
19515
  try {
19480
- projectRoot = import_fs35.default.readFileSync(import_path38.default.join(slugPath, ".project_root"), "utf-8").trim();
19516
+ projectRoot = import_fs35.default.readFileSync(import_path39.default.join(slugPath, ".project_root"), "utf-8").trim();
19481
19517
  } catch {
19482
19518
  }
19483
- const chatsDir = import_path38.default.join(slugPath, "chats");
19519
+ const chatsDir = import_path39.default.join(slugPath, "chats");
19484
19520
  if (!import_fs35.default.existsSync(chatsDir)) continue;
19485
19521
  let chatFiles;
19486
19522
  try {
@@ -19491,7 +19527,7 @@ function buildGeminiSessions(days, allAuditEntries) {
19491
19527
  for (const chatFile of chatFiles) {
19492
19528
  let raw;
19493
19529
  try {
19494
- raw = import_fs35.default.readFileSync(import_path38.default.join(chatsDir, chatFile), "utf-8");
19530
+ raw = import_fs35.default.readFileSync(import_path39.default.join(chatsDir, chatFile), "utf-8");
19495
19531
  } catch {
19496
19532
  continue;
19497
19533
  }
@@ -19571,7 +19607,7 @@ function buildGeminiSessions(days, allAuditEntries) {
19571
19607
  return summaries;
19572
19608
  }
19573
19609
  function buildCodexSessions(days, allAuditEntries) {
19574
- const sessionsBase = import_path38.default.join(import_os32.default.homedir(), ".codex", "sessions");
19610
+ const sessionsBase = import_path39.default.join(import_os32.default.homedir(), ".codex", "sessions");
19575
19611
  if (!import_fs35.default.existsSync(sessionsBase)) return [];
19576
19612
  const cutoff = days !== null ? (() => {
19577
19613
  const d = /* @__PURE__ */ new Date();
@@ -19582,28 +19618,28 @@ function buildCodexSessions(days, allAuditEntries) {
19582
19618
  const jsonlFiles = [];
19583
19619
  try {
19584
19620
  for (const year of import_fs35.default.readdirSync(sessionsBase)) {
19585
- const yearPath = import_path38.default.join(sessionsBase, year);
19621
+ const yearPath = import_path39.default.join(sessionsBase, year);
19586
19622
  try {
19587
19623
  if (!import_fs35.default.statSync(yearPath).isDirectory()) continue;
19588
19624
  } catch {
19589
19625
  continue;
19590
19626
  }
19591
19627
  for (const month of import_fs35.default.readdirSync(yearPath)) {
19592
- const monthPath = import_path38.default.join(yearPath, month);
19628
+ const monthPath = import_path39.default.join(yearPath, month);
19593
19629
  try {
19594
19630
  if (!import_fs35.default.statSync(monthPath).isDirectory()) continue;
19595
19631
  } catch {
19596
19632
  continue;
19597
19633
  }
19598
19634
  for (const day of import_fs35.default.readdirSync(monthPath)) {
19599
- const dayPath = import_path38.default.join(monthPath, day);
19635
+ const dayPath = import_path39.default.join(monthPath, day);
19600
19636
  try {
19601
19637
  if (!import_fs35.default.statSync(dayPath).isDirectory()) continue;
19602
19638
  } catch {
19603
19639
  continue;
19604
19640
  }
19605
19641
  for (const file of import_fs35.default.readdirSync(dayPath)) {
19606
- if (file.endsWith(".jsonl")) jsonlFiles.push(import_path38.default.join(dayPath, file));
19642
+ if (file.endsWith(".jsonl")) jsonlFiles.push(import_path39.default.join(dayPath, file));
19607
19643
  }
19608
19644
  }
19609
19645
  }
@@ -19693,7 +19729,7 @@ function buildCodexSessions(days, allAuditEntries) {
19693
19729
  return summaries;
19694
19730
  }
19695
19731
  function buildSessions(days, historyPath) {
19696
- const hPath = historyPath ?? import_path38.default.join(import_os32.default.homedir(), ".claude", "history.jsonl");
19732
+ const hPath = historyPath ?? import_path39.default.join(import_os32.default.homedir(), ".claude", "history.jsonl");
19697
19733
  let historyRaw;
19698
19734
  try {
19699
19735
  historyRaw = import_fs35.default.readFileSync(hPath, "utf-8");
@@ -19987,7 +20023,7 @@ function registerSessionsCommand(program2) {
19987
20023
  console.log("");
19988
20024
  console.log(import_chalk22.default.cyan.bold("\u{1F4CB} node9 sessions") + import_chalk22.default.dim(" \u2014 what your AI agent did"));
19989
20025
  console.log("");
19990
- const historyPath = import_path38.default.join(import_os32.default.homedir(), ".claude", "history.jsonl");
20026
+ const historyPath = import_path39.default.join(import_os32.default.homedir(), ".claude", "history.jsonl");
19991
20027
  if (!import_fs35.default.existsSync(historyPath)) {
19992
20028
  console.log(import_chalk22.default.yellow(" No Claude session history found at ~/.claude/history.jsonl"));
19993
20029
  console.log(import_chalk22.default.gray(" Install Claude Code, run a few sessions, then try again.\n"));
@@ -20027,10 +20063,10 @@ function registerSessionsCommand(program2) {
20027
20063
  var import_chalk23 = __toESM(require("chalk"));
20028
20064
  var import_fs36 = __toESM(require("fs"));
20029
20065
  var import_os33 = __toESM(require("os"));
20030
- var import_path39 = __toESM(require("path"));
20066
+ var import_path40 = __toESM(require("path"));
20031
20067
  function wipeSkillSessions() {
20032
20068
  try {
20033
- import_fs36.default.rmSync(import_path39.default.join(import_os33.default.homedir(), ".node9", "skill-sessions"), {
20069
+ import_fs36.default.rmSync(import_path40.default.join(import_os33.default.homedir(), ".node9", "skill-sessions"), {
20034
20070
  recursive: true,
20035
20071
  force: true
20036
20072
  });
@@ -20114,10 +20150,10 @@ function registerSkillPinCommand(program2) {
20114
20150
  // src/cli/commands/dlp.ts
20115
20151
  var import_chalk24 = __toESM(require("chalk"));
20116
20152
  var import_fs37 = __toESM(require("fs"));
20117
- var import_path40 = __toESM(require("path"));
20153
+ var import_path41 = __toESM(require("path"));
20118
20154
  var import_os34 = __toESM(require("os"));
20119
- var AUDIT_LOG = import_path40.default.join(import_os34.default.homedir(), ".node9", "audit.log");
20120
- var RESOLVED_FILE = import_path40.default.join(import_os34.default.homedir(), ".node9", "dlp-resolved.json");
20155
+ var AUDIT_LOG = import_path41.default.join(import_os34.default.homedir(), ".node9", "audit.log");
20156
+ var RESOLVED_FILE = import_path41.default.join(import_os34.default.homedir(), ".node9", "dlp-resolved.json");
20121
20157
  var ANSI_RE = /\x1b(?:\[[0-9;?]*[a-zA-Z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[@-_])/g;
20122
20158
  function stripAnsi(s) {
20123
20159
  return s.replace(ANSI_RE, "");
@@ -20236,15 +20272,15 @@ function registerDlpCommand(program2) {
20236
20272
 
20237
20273
  // src/cli.ts
20238
20274
  var { version } = JSON.parse(
20239
- import_fs40.default.readFileSync(import_path43.default.join(__dirname, "../package.json"), "utf-8")
20275
+ import_fs40.default.readFileSync(import_path44.default.join(__dirname, "../package.json"), "utf-8")
20240
20276
  );
20241
20277
  var program = new import_commander.Command();
20242
20278
  program.name("node9").description("The Sudo Command for AI Agents").version(version);
20243
20279
  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) => {
20244
20280
  const DEFAULT_API_URL2 = "https://api.node9.ai/api/v1/intercept";
20245
- const credPath = import_path43.default.join(import_os37.default.homedir(), ".node9", "credentials.json");
20246
- if (!import_fs40.default.existsSync(import_path43.default.dirname(credPath)))
20247
- import_fs40.default.mkdirSync(import_path43.default.dirname(credPath), { recursive: true });
20281
+ const credPath = import_path44.default.join(import_os37.default.homedir(), ".node9", "credentials.json");
20282
+ if (!import_fs40.default.existsSync(import_path44.default.dirname(credPath)))
20283
+ import_fs40.default.mkdirSync(import_path44.default.dirname(credPath), { recursive: true });
20248
20284
  const profileName = options.profile || "default";
20249
20285
  let existingCreds = {};
20250
20286
  try {
@@ -20263,7 +20299,7 @@ program.command("login").argument("<apiKey>").option("--local", "Save key for au
20263
20299
  existingCreds[profileName] = { apiKey, apiUrl: DEFAULT_API_URL2 };
20264
20300
  import_fs40.default.writeFileSync(credPath, JSON.stringify(existingCreds, null, 2), { mode: 384 });
20265
20301
  if (profileName === "default") {
20266
- const configPath = import_path43.default.join(import_os37.default.homedir(), ".node9", "config.json");
20302
+ const configPath = import_path44.default.join(import_os37.default.homedir(), ".node9", "config.json");
20267
20303
  let config = {};
20268
20304
  try {
20269
20305
  if (import_fs40.default.existsSync(configPath))
@@ -20282,8 +20318,8 @@ program.command("login").argument("<apiKey>").option("--local", "Save key for au
20282
20318
  approvers.cloud = false;
20283
20319
  }
20284
20320
  s.approvers = approvers;
20285
- if (!import_fs40.default.existsSync(import_path43.default.dirname(configPath)))
20286
- import_fs40.default.mkdirSync(import_path43.default.dirname(configPath), { recursive: true });
20321
+ if (!import_fs40.default.existsSync(import_path44.default.dirname(configPath)))
20322
+ import_fs40.default.mkdirSync(import_path44.default.dirname(configPath), { recursive: true });
20287
20323
  import_fs40.default.writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 384 });
20288
20324
  }
20289
20325
  if (options.profile && profileName !== "default") {
@@ -20421,7 +20457,7 @@ program.command("uninstall").description("Remove all Node9 hooks and optionally
20421
20457
  }
20422
20458
  }
20423
20459
  if (options.purge) {
20424
- const node9Dir = import_path43.default.join(import_os37.default.homedir(), ".node9");
20460
+ const node9Dir = import_path44.default.join(import_os37.default.homedir(), ".node9");
20425
20461
  if (import_fs40.default.existsSync(node9Dir)) {
20426
20462
  const confirmed = await (0, import_prompts2.confirm)({
20427
20463
  message: `Permanently delete ${node9Dir} (config, audit log, credentials)?`,
@@ -20571,9 +20607,9 @@ Claude Code spawns this command every ~300ms and writes a JSON payload to stdin.
20571
20607
  Run "node9 addto claude" to register it as the statusLine.`
20572
20608
  ).argument("[subcommand]", 'Optional: "debug on" / "debug off" to toggle stdin logging').argument("[state]", 'on|off \u2014 used with "debug" subcommand').action(async (subcommand, state) => {
20573
20609
  if (subcommand === "debug") {
20574
- const flagFile = import_path43.default.join(import_os37.default.homedir(), ".node9", "hud-debug");
20610
+ const flagFile = import_path44.default.join(import_os37.default.homedir(), ".node9", "hud-debug");
20575
20611
  if (state === "on") {
20576
- import_fs40.default.mkdirSync(import_path43.default.dirname(flagFile), { recursive: true });
20612
+ import_fs40.default.mkdirSync(import_path44.default.dirname(flagFile), { recursive: true });
20577
20613
  import_fs40.default.writeFileSync(flagFile, "");
20578
20614
  console.log("HUD debug logging enabled \u2192 ~/.node9/hud-debug.log");
20579
20615
  console.log("Tail it with: tail -f ~/.node9/hud-debug.log");
@@ -20690,7 +20726,7 @@ if (process.argv[2] !== "daemon") {
20690
20726
  const isCheckHook = process.argv[2] === "check";
20691
20727
  if (isCheckHook) {
20692
20728
  if (process.env.NODE9_DEBUG === "1" || getConfig().settings.enableHookLogDebug) {
20693
- const logPath = import_path43.default.join(import_os37.default.homedir(), ".node9", "hook-debug.log");
20729
+ const logPath = import_path44.default.join(import_os37.default.homedir(), ".node9", "hook-debug.log");
20694
20730
  const msg = reason instanceof Error ? reason.message : String(reason);
20695
20731
  import_fs40.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] UNHANDLED: ${msg}
20696
20732
  `);