@node9/proxy 1.35.0 → 1.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/cli.js +452 -354
  2. package/dist/cli.mjs +448 -350
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -206,8 +206,8 @@ function sanitizeConfig(raw) {
206
206
  }
207
207
  }
208
208
  const lines = result.error.issues.map((issue) => {
209
- const path54 = issue.path.length > 0 ? issue.path.join(".") : "root";
210
- return ` \u2022 ${path54}: ${issue.message}`;
209
+ const path55 = issue.path.length > 0 ? issue.path.join(".") : "root";
210
+ return ` \u2022 ${path55}: ${issue.message}`;
211
211
  });
212
212
  return {
213
213
  sanitized,
@@ -1256,9 +1256,9 @@ function matchesPattern(text, patterns) {
1256
1256
  const withoutDotSlash = text.replace(/^\.\//, "");
1257
1257
  return isMatch(withoutDotSlash) || isMatch(`./${withoutDotSlash}`);
1258
1258
  }
1259
- function getNestedValue(obj, path54) {
1259
+ function getNestedValue(obj, path55) {
1260
1260
  if (!obj || typeof obj !== "object") return null;
1261
- const segments = path54.split(".");
1261
+ const segments = path55.split(".");
1262
1262
  for (const seg of segments) {
1263
1263
  if (FORBIDDEN_PATH_SEGMENTS.has(seg)) return null;
1264
1264
  }
@@ -16951,20 +16951,20 @@ function getModelContextLimit(model) {
16951
16951
  return 2e5;
16952
16952
  }
16953
16953
  function readSessionUsage() {
16954
- const projectsDir = import_path51.default.join(import_os45.default.homedir(), ".claude", "projects");
16955
- if (!import_fs50.default.existsSync(projectsDir)) return null;
16954
+ const projectsDir = import_path52.default.join(import_os46.default.homedir(), ".claude", "projects");
16955
+ if (!import_fs51.default.existsSync(projectsDir)) return null;
16956
16956
  let latestFile = null;
16957
16957
  let latestMtime = 0;
16958
16958
  try {
16959
- for (const dir of import_fs50.default.readdirSync(projectsDir)) {
16960
- const dirPath = import_path51.default.join(projectsDir, dir);
16959
+ for (const dir of import_fs51.default.readdirSync(projectsDir)) {
16960
+ const dirPath = import_path52.default.join(projectsDir, dir);
16961
16961
  try {
16962
- if (!import_fs50.default.statSync(dirPath).isDirectory()) continue;
16963
- for (const file of import_fs50.default.readdirSync(dirPath)) {
16962
+ if (!import_fs51.default.statSync(dirPath).isDirectory()) continue;
16963
+ for (const file of import_fs51.default.readdirSync(dirPath)) {
16964
16964
  if (!file.endsWith(".jsonl") || file.startsWith("agent-")) continue;
16965
- const filePath = import_path51.default.join(dirPath, file);
16965
+ const filePath = import_path52.default.join(dirPath, file);
16966
16966
  try {
16967
- const mtime = import_fs50.default.statSync(filePath).mtimeMs;
16967
+ const mtime = import_fs51.default.statSync(filePath).mtimeMs;
16968
16968
  if (mtime > latestMtime) {
16969
16969
  latestMtime = mtime;
16970
16970
  latestFile = filePath;
@@ -16979,7 +16979,7 @@ function readSessionUsage() {
16979
16979
  }
16980
16980
  if (!latestFile) return null;
16981
16981
  try {
16982
- const lines = import_fs50.default.readFileSync(latestFile, "utf-8").split("\n");
16982
+ const lines = import_fs51.default.readFileSync(latestFile, "utf-8").split("\n");
16983
16983
  let lastModel = "";
16984
16984
  let lastInput = 0;
16985
16985
  let lastOutput = 0;
@@ -17040,7 +17040,7 @@ function formatBase(activity) {
17040
17040
  const time = new Date(activity.ts).toLocaleTimeString([], { hour12: false });
17041
17041
  const icon = getIcon(activity.tool);
17042
17042
  const toolName = activity.tool.slice(0, 16).padEnd(16);
17043
- const argsStr = JSON.stringify(activity.args ?? {}).replace(/\s+/g, " ").replaceAll(import_os45.default.homedir(), "~");
17043
+ const argsStr = JSON.stringify(activity.args ?? {}).replace(/\s+/g, " ").replaceAll(import_os46.default.homedir(), "~");
17044
17044
  const argsPreview = argsStr.length > 70 ? argsStr.slice(0, 70) + "\u2026" : argsStr;
17045
17045
  return `${import_chalk29.default.gray(time)} ${icon} ${agentLabel(activity.agent, activity.mcpServer, activity.sessionId)}${import_chalk29.default.white.bold(toolName)} ${import_chalk29.default.dim(argsPreview)}`;
17046
17046
  }
@@ -17079,9 +17079,9 @@ function renderPending(activity) {
17079
17079
  }
17080
17080
  async function ensureDaemon() {
17081
17081
  let pidPort = null;
17082
- if (import_fs50.default.existsSync(PID_FILE)) {
17082
+ if (import_fs51.default.existsSync(PID_FILE)) {
17083
17083
  try {
17084
- const { port } = JSON.parse(import_fs50.default.readFileSync(PID_FILE, "utf-8"));
17084
+ const { port } = JSON.parse(import_fs51.default.readFileSync(PID_FILE, "utf-8"));
17085
17085
  pidPort = port;
17086
17086
  } catch {
17087
17087
  console.error(import_chalk29.default.dim("\u26A0\uFE0F Could not read PID file; falling back to default port."));
@@ -17237,9 +17237,9 @@ function buildRecoveryCardLines(req) {
17237
17237
  ];
17238
17238
  }
17239
17239
  function readApproversFromDisk() {
17240
- const configPath = import_path51.default.join(import_os45.default.homedir(), ".node9", "config.json");
17240
+ const configPath = import_path52.default.join(import_os46.default.homedir(), ".node9", "config.json");
17241
17241
  try {
17242
- const raw = JSON.parse(import_fs50.default.readFileSync(configPath, "utf-8"));
17242
+ const raw = JSON.parse(import_fs51.default.readFileSync(configPath, "utf-8"));
17243
17243
  const settings = raw.settings ?? {};
17244
17244
  return settings.approvers ?? {};
17245
17245
  } catch {
@@ -17255,15 +17255,15 @@ function approverStatusLine() {
17255
17255
  return `${fmt("native", "native")} ${fmt("cloud", "cloud")} ${fmt("terminal", "terminal")}`;
17256
17256
  }
17257
17257
  function toggleApprover(channel) {
17258
- const configPath = import_path51.default.join(import_os45.default.homedir(), ".node9", "config.json");
17258
+ const configPath = import_path52.default.join(import_os46.default.homedir(), ".node9", "config.json");
17259
17259
  try {
17260
- const raw = JSON.parse(import_fs50.default.readFileSync(configPath, "utf-8"));
17260
+ const raw = JSON.parse(import_fs51.default.readFileSync(configPath, "utf-8"));
17261
17261
  const settings = raw.settings ?? {};
17262
17262
  const approvers = settings.approvers ?? {};
17263
17263
  approvers[channel] = approvers[channel] === false;
17264
17264
  settings.approvers = approvers;
17265
17265
  raw.settings = settings;
17266
- import_fs50.default.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
17266
+ import_fs51.default.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
17267
17267
  } catch (err2) {
17268
17268
  process.stderr.write(`[node9] toggleApprover failed: ${String(err2)}
17269
17269
  `);
@@ -17435,8 +17435,8 @@ async function startTail(options = {}) {
17435
17435
  }
17436
17436
  postDecisionHttp(req2.id, httpDecision, authToken, port, httpOpts).catch((err2) => {
17437
17437
  try {
17438
- import_fs50.default.appendFileSync(
17439
- import_path51.default.join(import_os45.default.homedir(), ".node9", "hook-debug.log"),
17438
+ import_fs51.default.appendFileSync(
17439
+ import_path52.default.join(import_os46.default.homedir(), ".node9", "hook-debug.log"),
17440
17440
  `[tail] POST /decision failed: ${String(err2)}
17441
17441
  `
17442
17442
  );
@@ -17500,9 +17500,9 @@ async function startTail(options = {}) {
17500
17500
  };
17501
17501
  process.stdin.on("keypress", onKeypress);
17502
17502
  }
17503
- const auditLog = import_path51.default.join(import_os45.default.homedir(), ".node9", "audit.log");
17503
+ const auditLog = import_path52.default.join(import_os46.default.homedir(), ".node9", "audit.log");
17504
17504
  try {
17505
- const unackedDlp = import_fs50.default.readFileSync(auditLog, "utf-8").split("\n").filter((l) => l.includes('"response-dlp"')).length;
17505
+ const unackedDlp = import_fs51.default.readFileSync(auditLog, "utf-8").split("\n").filter((l) => l.includes('"response-dlp"')).length;
17506
17506
  if (unackedDlp > 0) {
17507
17507
  console.log("");
17508
17508
  console.log(
@@ -17542,7 +17542,7 @@ async function startTail(options = {}) {
17542
17542
  if (stallWarned) return;
17543
17543
  if (Date.now() - lastActivityFromDaemon < STALL_THRESHOLD_MS) return;
17544
17544
  try {
17545
- const auditMtime = import_fs50.default.statSync(auditLog).mtimeMs;
17545
+ const auditMtime = import_fs51.default.statSync(auditLog).mtimeMs;
17546
17546
  if (Date.now() - auditMtime >= STALL_THRESHOLD_MS) return;
17547
17547
  console.log("");
17548
17548
  console.log(
@@ -17727,20 +17727,20 @@ async function startTail(options = {}) {
17727
17727
  process.exit(1);
17728
17728
  });
17729
17729
  }
17730
- var import_http2, import_chalk29, import_fs50, import_os45, import_path51, import_readline6, import_child_process12, PID_FILE, ICONS, MODEL_CONTEXT_LIMITS, RESET2, BOLD2, RED, YELLOW, CYAN, GRAY, GREEN, HIDE_CURSOR, SHOW_CURSOR, ERASE_DOWN, pendingShownForId, pendingWrappedLines, DIVIDER;
17730
+ var import_http2, import_chalk29, import_fs51, import_os46, import_path52, import_readline6, import_child_process12, PID_FILE, ICONS, MODEL_CONTEXT_LIMITS, RESET2, BOLD2, RED, YELLOW, CYAN, GRAY, GREEN, HIDE_CURSOR, SHOW_CURSOR, ERASE_DOWN, pendingShownForId, pendingWrappedLines, DIVIDER;
17731
17731
  var init_tail = __esm({
17732
17732
  "src/tui/tail.ts"() {
17733
17733
  "use strict";
17734
17734
  import_http2 = __toESM(require("http"));
17735
17735
  import_chalk29 = __toESM(require("chalk"));
17736
- import_fs50 = __toESM(require("fs"));
17737
- import_os45 = __toESM(require("os"));
17738
- import_path51 = __toESM(require("path"));
17736
+ import_fs51 = __toESM(require("fs"));
17737
+ import_os46 = __toESM(require("os"));
17738
+ import_path52 = __toESM(require("path"));
17739
17739
  import_readline6 = __toESM(require("readline"));
17740
17740
  import_child_process12 = require("child_process");
17741
17741
  init_daemon2();
17742
17742
  init_daemon();
17743
- PID_FILE = import_path51.default.join(import_os45.default.homedir(), ".node9", "daemon.pid");
17743
+ PID_FILE = import_path52.default.join(import_os46.default.homedir(), ".node9", "daemon.pid");
17744
17744
  ICONS = {
17745
17745
  bash: "\u{1F4BB}",
17746
17746
  shell: "\u{1F4BB}",
@@ -17862,9 +17862,9 @@ function formatTimeLeft(resetsAt) {
17862
17862
  return ` (${m}m left)`;
17863
17863
  }
17864
17864
  function safeReadJson(filePath) {
17865
- if (!import_fs51.default.existsSync(filePath)) return null;
17865
+ if (!import_fs52.default.existsSync(filePath)) return null;
17866
17866
  try {
17867
- return JSON.parse(import_fs51.default.readFileSync(filePath, "utf-8"));
17867
+ return JSON.parse(import_fs52.default.readFileSync(filePath, "utf-8"));
17868
17868
  } catch {
17869
17869
  return null;
17870
17870
  }
@@ -17885,12 +17885,12 @@ function countHooksInFile(filePath) {
17885
17885
  return Object.keys(cfg.hooks).length;
17886
17886
  }
17887
17887
  function countRulesInDir(rulesDir) {
17888
- if (!import_fs51.default.existsSync(rulesDir)) return 0;
17888
+ if (!import_fs52.default.existsSync(rulesDir)) return 0;
17889
17889
  let count = 0;
17890
17890
  try {
17891
- for (const entry of import_fs51.default.readdirSync(rulesDir, { withFileTypes: true })) {
17891
+ for (const entry of import_fs52.default.readdirSync(rulesDir, { withFileTypes: true })) {
17892
17892
  if (entry.isDirectory()) {
17893
- count += countRulesInDir(import_path52.default.join(rulesDir, entry.name));
17893
+ count += countRulesInDir(import_path53.default.join(rulesDir, entry.name));
17894
17894
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
17895
17895
  count++;
17896
17896
  }
@@ -17901,46 +17901,46 @@ function countRulesInDir(rulesDir) {
17901
17901
  }
17902
17902
  function isSamePath(a, b) {
17903
17903
  try {
17904
- return import_path52.default.resolve(a) === import_path52.default.resolve(b);
17904
+ return import_path53.default.resolve(a) === import_path53.default.resolve(b);
17905
17905
  } catch {
17906
17906
  return false;
17907
17907
  }
17908
17908
  }
17909
17909
  function countConfigs(cwd) {
17910
- const homeDir2 = import_os46.default.homedir();
17911
- const claudeDir = import_path52.default.join(homeDir2, ".claude");
17910
+ const homeDir2 = import_os47.default.homedir();
17911
+ const claudeDir = import_path53.default.join(homeDir2, ".claude");
17912
17912
  let claudeMdCount = 0;
17913
17913
  let rulesCount = 0;
17914
17914
  let hooksCount = 0;
17915
17915
  const userMcpServers = /* @__PURE__ */ new Set();
17916
17916
  const projectMcpServers = /* @__PURE__ */ new Set();
17917
- if (import_fs51.default.existsSync(import_path52.default.join(claudeDir, "CLAUDE.md"))) claudeMdCount++;
17918
- rulesCount += countRulesInDir(import_path52.default.join(claudeDir, "rules"));
17919
- const userSettings = import_path52.default.join(claudeDir, "settings.json");
17917
+ if (import_fs52.default.existsSync(import_path53.default.join(claudeDir, "CLAUDE.md"))) claudeMdCount++;
17918
+ rulesCount += countRulesInDir(import_path53.default.join(claudeDir, "rules"));
17919
+ const userSettings = import_path53.default.join(claudeDir, "settings.json");
17920
17920
  for (const name of getMcpServerNames(userSettings)) userMcpServers.add(name);
17921
17921
  hooksCount += countHooksInFile(userSettings);
17922
- const userClaudeJson = import_path52.default.join(homeDir2, ".claude.json");
17922
+ const userClaudeJson = import_path53.default.join(homeDir2, ".claude.json");
17923
17923
  for (const name of getMcpServerNames(userClaudeJson)) userMcpServers.add(name);
17924
17924
  for (const name of getDisabledMcpServers(userClaudeJson, "disabledMcpServers")) {
17925
17925
  userMcpServers.delete(name);
17926
17926
  }
17927
17927
  if (cwd) {
17928
- if (import_fs51.default.existsSync(import_path52.default.join(cwd, "CLAUDE.md"))) claudeMdCount++;
17929
- if (import_fs51.default.existsSync(import_path52.default.join(cwd, "CLAUDE.local.md"))) claudeMdCount++;
17930
- const projectClaudeDir = import_path52.default.join(cwd, ".claude");
17928
+ if (import_fs52.default.existsSync(import_path53.default.join(cwd, "CLAUDE.md"))) claudeMdCount++;
17929
+ if (import_fs52.default.existsSync(import_path53.default.join(cwd, "CLAUDE.local.md"))) claudeMdCount++;
17930
+ const projectClaudeDir = import_path53.default.join(cwd, ".claude");
17931
17931
  const overlapsUserScope = isSamePath(projectClaudeDir, claudeDir);
17932
17932
  if (!overlapsUserScope) {
17933
- if (import_fs51.default.existsSync(import_path52.default.join(projectClaudeDir, "CLAUDE.md"))) claudeMdCount++;
17934
- rulesCount += countRulesInDir(import_path52.default.join(projectClaudeDir, "rules"));
17935
- const projSettings = import_path52.default.join(projectClaudeDir, "settings.json");
17933
+ if (import_fs52.default.existsSync(import_path53.default.join(projectClaudeDir, "CLAUDE.md"))) claudeMdCount++;
17934
+ rulesCount += countRulesInDir(import_path53.default.join(projectClaudeDir, "rules"));
17935
+ const projSettings = import_path53.default.join(projectClaudeDir, "settings.json");
17936
17936
  for (const name of getMcpServerNames(projSettings)) projectMcpServers.add(name);
17937
17937
  hooksCount += countHooksInFile(projSettings);
17938
17938
  }
17939
- if (import_fs51.default.existsSync(import_path52.default.join(projectClaudeDir, "CLAUDE.local.md"))) claudeMdCount++;
17940
- const localSettings = import_path52.default.join(projectClaudeDir, "settings.local.json");
17939
+ if (import_fs52.default.existsSync(import_path53.default.join(projectClaudeDir, "CLAUDE.local.md"))) claudeMdCount++;
17940
+ const localSettings = import_path53.default.join(projectClaudeDir, "settings.local.json");
17941
17941
  for (const name of getMcpServerNames(localSettings)) projectMcpServers.add(name);
17942
17942
  hooksCount += countHooksInFile(localSettings);
17943
- const mcpJsonServers = getMcpServerNames(import_path52.default.join(cwd, ".mcp.json"));
17943
+ const mcpJsonServers = getMcpServerNames(import_path53.default.join(cwd, ".mcp.json"));
17944
17944
  const disabledMcpJson = getDisabledMcpServers(localSettings, "disabledMcpjsonServers");
17945
17945
  for (const name of disabledMcpJson) mcpJsonServers.delete(name);
17946
17946
  for (const name of mcpJsonServers) projectMcpServers.add(name);
@@ -17973,12 +17973,12 @@ function readActiveShieldsHud() {
17973
17973
  return shieldsCache.value;
17974
17974
  }
17975
17975
  try {
17976
- const shieldsPath = import_path52.default.join(import_os46.default.homedir(), ".node9", "shields.json");
17977
- if (!import_fs51.default.existsSync(shieldsPath)) {
17976
+ const shieldsPath = import_path53.default.join(import_os47.default.homedir(), ".node9", "shields.json");
17977
+ if (!import_fs52.default.existsSync(shieldsPath)) {
17978
17978
  shieldsCache = { value: [], ts: now };
17979
17979
  return [];
17980
17980
  }
17981
- const parsed = JSON.parse(import_fs51.default.readFileSync(shieldsPath, "utf-8"));
17981
+ const parsed = JSON.parse(import_fs52.default.readFileSync(shieldsPath, "utf-8"));
17982
17982
  if (!Array.isArray(parsed.active)) {
17983
17983
  shieldsCache = { value: [], ts: now };
17984
17984
  return [];
@@ -18080,17 +18080,17 @@ function renderContextLine(stdin) {
18080
18080
  async function main() {
18081
18081
  try {
18082
18082
  const [stdin, daemonStatus2] = await Promise.all([readStdin(), queryDaemon()]);
18083
- if (import_fs51.default.existsSync(import_path52.default.join(import_os46.default.homedir(), ".node9", "hud-debug"))) {
18083
+ if (import_fs52.default.existsSync(import_path53.default.join(import_os47.default.homedir(), ".node9", "hud-debug"))) {
18084
18084
  try {
18085
- const logPath = import_path52.default.join(import_os46.default.homedir(), ".node9", "hud-debug.log");
18085
+ const logPath = import_path53.default.join(import_os47.default.homedir(), ".node9", "hud-debug.log");
18086
18086
  const MAX_LOG_SIZE = 10 * 1024 * 1024;
18087
18087
  let size = 0;
18088
18088
  try {
18089
- size = import_fs51.default.statSync(logPath).size;
18089
+ size = import_fs52.default.statSync(logPath).size;
18090
18090
  } catch {
18091
18091
  }
18092
18092
  if (size < MAX_LOG_SIZE) {
18093
- import_fs51.default.appendFileSync(
18093
+ import_fs52.default.appendFileSync(
18094
18094
  logPath,
18095
18095
  JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), stdin }) + "\n"
18096
18096
  );
@@ -18111,11 +18111,11 @@ async function main() {
18111
18111
  try {
18112
18112
  const cwd = stdin.cwd ?? process.cwd();
18113
18113
  for (const configPath of [
18114
- import_path52.default.join(cwd, "node9.config.json"),
18115
- import_path52.default.join(import_os46.default.homedir(), ".node9", "config.json")
18114
+ import_path53.default.join(cwd, "node9.config.json"),
18115
+ import_path53.default.join(import_os47.default.homedir(), ".node9", "config.json")
18116
18116
  ]) {
18117
- if (!import_fs51.default.existsSync(configPath)) continue;
18118
- const cfg = JSON.parse(import_fs51.default.readFileSync(configPath, "utf-8"));
18117
+ if (!import_fs52.default.existsSync(configPath)) continue;
18118
+ const cfg = JSON.parse(import_fs52.default.readFileSync(configPath, "utf-8"));
18119
18119
  const hud = cfg.settings?.hud;
18120
18120
  if (hud && "showEnvironmentCounts" in hud) return hud.showEnvironmentCounts !== false;
18121
18121
  }
@@ -18133,13 +18133,13 @@ async function main() {
18133
18133
  renderOffline();
18134
18134
  }
18135
18135
  }
18136
- var import_fs51, import_path52, import_os46, import_http3, RESET3, BOLD3, DIM, RED2, GREEN2, YELLOW2, BLUE, MAGENTA, CYAN2, WHITE, BAR_FILLED, BAR_EMPTY, BAR_WIDTH, shieldsCache, SHIELDS_CACHE_TTL_MS;
18136
+ var import_fs52, import_path53, import_os47, import_http3, RESET3, BOLD3, DIM, RED2, GREEN2, YELLOW2, BLUE, MAGENTA, CYAN2, WHITE, BAR_FILLED, BAR_EMPTY, BAR_WIDTH, shieldsCache, SHIELDS_CACHE_TTL_MS;
18137
18137
  var init_hud = __esm({
18138
18138
  "src/cli/hud.ts"() {
18139
18139
  "use strict";
18140
- import_fs51 = __toESM(require("fs"));
18141
- import_path52 = __toESM(require("path"));
18142
- import_os46 = __toESM(require("os"));
18140
+ import_fs52 = __toESM(require("fs"));
18141
+ import_path53 = __toESM(require("path"));
18142
+ import_os47 = __toESM(require("os"));
18143
18143
  import_http3 = __toESM(require("http"));
18144
18144
  init_daemon();
18145
18145
  RESET3 = "\x1B[0m";
@@ -18166,9 +18166,9 @@ init_core();
18166
18166
  init_setup();
18167
18167
  init_daemon2();
18168
18168
  var import_chalk30 = __toESM(require("chalk"));
18169
- var import_fs52 = __toESM(require("fs"));
18170
- var import_path53 = __toESM(require("path"));
18171
- var import_os47 = __toESM(require("os"));
18169
+ var import_fs53 = __toESM(require("fs"));
18170
+ var import_path54 = __toESM(require("path"));
18171
+ var import_os48 = __toESM(require("os"));
18172
18172
  var import_prompts2 = require("@inquirer/prompts");
18173
18173
 
18174
18174
  // src/utils/duration.ts
@@ -19956,15 +19956,151 @@ function registerConfigShowCommand(program2) {
19956
19956
 
19957
19957
  // src/cli/commands/doctor.ts
19958
19958
  var import_chalk11 = __toESM(require("chalk"));
19959
- var import_fs38 = __toESM(require("fs"));
19960
- var import_path39 = __toESM(require("path"));
19961
- var import_os34 = __toESM(require("os"));
19959
+ var import_fs39 = __toESM(require("fs"));
19960
+ var import_path40 = __toESM(require("path"));
19961
+ var import_os35 = __toESM(require("os"));
19962
19962
  var import_child_process8 = require("child_process");
19963
19963
  init_daemon();
19964
19964
  init_config();
19965
+
19966
+ // src/agent-wiring.ts
19967
+ var import_fs38 = __toESM(require("fs"));
19968
+ var import_path39 = __toESM(require("path"));
19969
+ var import_os34 = __toESM(require("os"));
19970
+ var yaml2 = __toESM(require("yaml"));
19971
+ init_setup();
19972
+ function readJson2(filePath) {
19973
+ if (!import_fs38.default.existsSync(filePath)) return null;
19974
+ try {
19975
+ return JSON.parse(import_fs38.default.readFileSync(filePath, "utf-8"));
19976
+ } catch {
19977
+ return "invalid";
19978
+ }
19979
+ }
19980
+ function matchersHaveNode9Hook(matchers) {
19981
+ return (matchers ?? []).some((m) => (m.hooks ?? []).some((h) => isNode9Hook(h.command)));
19982
+ }
19983
+ function flatHaveNode9Hook(entries) {
19984
+ return (Array.isArray(entries) ? entries : []).some((h) => isNode9Hook(h.command));
19985
+ }
19986
+ function jsonWire(filePath, read) {
19987
+ const parsed = readJson2(filePath);
19988
+ if (parsed === null) return "absent";
19989
+ if (parsed === "invalid") return "invalid";
19990
+ return read(parsed) ? "wired" : "unwired";
19991
+ }
19992
+ function hermesWire(home) {
19993
+ const configPath = hermesConfigPath(home);
19994
+ if (!import_fs38.default.existsSync(configPath)) return "absent";
19995
+ let raw;
19996
+ try {
19997
+ raw = import_fs38.default.readFileSync(configPath, "utf-8");
19998
+ } catch {
19999
+ return "absent";
20000
+ }
20001
+ try {
20002
+ const cfg = yaml2.parse(raw);
20003
+ const pre = (cfg?.hooks?.pre_tool_call ?? []).some(
20004
+ (e) => typeof e?.command === "string" && isNode9Hook(e.command)
20005
+ );
20006
+ return pre ? "wired" : "unwired";
20007
+ } catch {
20008
+ return "invalid";
20009
+ }
20010
+ }
20011
+ var AGENT_SPECS = [
20012
+ {
20013
+ id: "claude",
20014
+ label: "Claude Code",
20015
+ hookLabel: "PreToolUse hook",
20016
+ setupCommand: "node9 setup claude",
20017
+ settingsPath: (h) => import_path39.default.join(h, ".claude", "settings.json"),
20018
+ wireState: (h) => jsonWire(
20019
+ import_path39.default.join(h, ".claude", "settings.json"),
20020
+ (p) => matchersHaveNode9Hook(p.hooks?.PreToolUse)
20021
+ )
20022
+ },
20023
+ {
20024
+ id: "gemini",
20025
+ label: "Gemini CLI",
20026
+ hookLabel: "BeforeTool hook",
20027
+ setupCommand: "node9 setup gemini",
20028
+ settingsPath: (h) => import_path39.default.join(h, ".gemini", "settings.json"),
20029
+ wireState: (h) => jsonWire(
20030
+ import_path39.default.join(h, ".gemini", "settings.json"),
20031
+ (p) => matchersHaveNode9Hook(p.hooks?.BeforeTool)
20032
+ )
20033
+ },
20034
+ {
20035
+ id: "codex",
20036
+ label: "Codex",
20037
+ hookLabel: "PreToolUse hook",
20038
+ setupCommand: "node9 setup codex",
20039
+ settingsPath: (h) => import_path39.default.join(h, ".codex", "hooks.json"),
20040
+ wireState: (h) => jsonWire(
20041
+ import_path39.default.join(h, ".codex", "hooks.json"),
20042
+ (p) => matchersHaveNode9Hook(p.hooks?.PreToolUse)
20043
+ )
20044
+ },
20045
+ {
20046
+ id: "antigravity",
20047
+ label: "Antigravity",
20048
+ hookLabel: "PreToolUse hook",
20049
+ setupCommand: "node9 setup antigravity",
20050
+ settingsPath: (h) => import_path39.default.join(h, ".gemini", "config", "hooks.json"),
20051
+ wireState: (h) => jsonWire(
20052
+ import_path39.default.join(h, ".gemini", "config", "hooks.json"),
20053
+ (p) => matchersHaveNode9Hook(p.hooks?.PreToolUse)
20054
+ )
20055
+ },
20056
+ {
20057
+ id: "copilot",
20058
+ label: "GitHub Copilot",
20059
+ hookLabel: "PreToolUse hook",
20060
+ setupCommand: "node9 setup copilot",
20061
+ settingsPath: (h) => import_path39.default.join(h, ".copilot", "hooks", "node9.json"),
20062
+ wireState: (h) => jsonWire(
20063
+ import_path39.default.join(h, ".copilot", "hooks", "node9.json"),
20064
+ (p) => flatHaveNode9Hook(p.hooks?.PreToolUse)
20065
+ )
20066
+ },
20067
+ {
20068
+ id: "cursor",
20069
+ label: "Cursor",
20070
+ hookLabel: "preToolUse hook",
20071
+ setupCommand: "node9 setup cursor",
20072
+ settingsPath: (h) => import_path39.default.join(h, ".cursor", "hooks.json"),
20073
+ wireState: (h) => jsonWire(
20074
+ import_path39.default.join(h, ".cursor", "hooks.json"),
20075
+ (p) => flatHaveNode9Hook(p.hooks?.preToolUse)
20076
+ )
20077
+ },
20078
+ {
20079
+ id: "hermes",
20080
+ label: "Hermes Agent",
20081
+ hookLabel: "pre_tool_call hook",
20082
+ setupCommand: "node9 setup hermes",
20083
+ settingsPath: (h) => hermesConfigPath(h),
20084
+ wireState: (h) => hermesWire(h)
20085
+ }
20086
+ ];
20087
+ function getAgentWiring(home = import_os34.default.homedir()) {
20088
+ const detected = detectAgents(home);
20089
+ return AGENT_SPECS.map((spec) => ({
20090
+ id: spec.id,
20091
+ label: spec.label,
20092
+ hookLabel: spec.hookLabel,
20093
+ setupCommand: spec.setupCommand,
20094
+ settingsPath: spec.settingsPath(home),
20095
+ installed: detected[spec.id],
20096
+ wireState: spec.wireState(home)
20097
+ }));
20098
+ }
20099
+
20100
+ // src/cli/commands/doctor.ts
19965
20101
  function registerDoctorCommand(program2, version2) {
19966
20102
  program2.command("doctor").description("Check that Node9 is installed and configured correctly").action(async () => {
19967
- const homeDir2 = import_os34.default.homedir();
20103
+ const homeDir2 = import_os35.default.homedir();
19968
20104
  let failures = 0;
19969
20105
  function pass(msg) {
19970
20106
  console.log(import_chalk11.default.green(" \u2705 ") + msg);
@@ -20013,10 +20149,10 @@ function registerDoctorCommand(program2, version2) {
20013
20149
  );
20014
20150
  }
20015
20151
  section("Configuration");
20016
- const globalConfigPath = import_path39.default.join(homeDir2, ".node9", "config.json");
20017
- if (import_fs38.default.existsSync(globalConfigPath)) {
20152
+ const globalConfigPath = import_path40.default.join(homeDir2, ".node9", "config.json");
20153
+ if (import_fs39.default.existsSync(globalConfigPath)) {
20018
20154
  try {
20019
- JSON.parse(import_fs38.default.readFileSync(globalConfigPath, "utf-8"));
20155
+ JSON.parse(import_fs39.default.readFileSync(globalConfigPath, "utf-8"));
20020
20156
  pass("~/.node9/config.json found and valid");
20021
20157
  } catch {
20022
20158
  fail("~/.node9/config.json is invalid JSON", "Run: node9 init --force");
@@ -20024,10 +20160,10 @@ function registerDoctorCommand(program2, version2) {
20024
20160
  } else {
20025
20161
  warn("~/.node9/config.json not found (using defaults)", "Run: node9 init");
20026
20162
  }
20027
- const projectConfigPath = import_path39.default.join(process.cwd(), "node9.config.json");
20028
- if (import_fs38.default.existsSync(projectConfigPath)) {
20163
+ const projectConfigPath = import_path40.default.join(process.cwd(), "node9.config.json");
20164
+ if (import_fs39.default.existsSync(projectConfigPath)) {
20029
20165
  try {
20030
- JSON.parse(import_fs38.default.readFileSync(projectConfigPath, "utf-8"));
20166
+ JSON.parse(import_fs39.default.readFileSync(projectConfigPath, "utf-8"));
20031
20167
  pass("node9.config.json found and valid (project)");
20032
20168
  } catch {
20033
20169
  fail(
@@ -20036,8 +20172,8 @@ function registerDoctorCommand(program2, version2) {
20036
20172
  );
20037
20173
  }
20038
20174
  }
20039
- const credsPath = import_path39.default.join(homeDir2, ".node9", "credentials.json");
20040
- if (import_fs38.default.existsSync(credsPath)) {
20175
+ const credsPath = import_path40.default.join(homeDir2, ".node9", "credentials.json");
20176
+ if (import_fs39.default.existsSync(credsPath)) {
20041
20177
  pass("Cloud credentials found (~/.node9/credentials.json)");
20042
20178
  } else {
20043
20179
  warn(
@@ -20046,62 +20182,24 @@ function registerDoctorCommand(program2, version2) {
20046
20182
  );
20047
20183
  }
20048
20184
  section("Agent Hooks");
20049
- const claudeSettingsPath = import_path39.default.join(homeDir2, ".claude", "settings.json");
20050
- if (import_fs38.default.existsSync(claudeSettingsPath)) {
20051
- try {
20052
- const cs = JSON.parse(import_fs38.default.readFileSync(claudeSettingsPath, "utf-8"));
20053
- const hasHook = cs.hooks?.PreToolUse?.some(
20054
- (m) => m.hooks.some((h) => h.command?.includes("node9") || h.command?.includes("cli.js"))
20055
- );
20056
- if (hasHook) pass("Claude Code \u2014 PreToolUse hook active");
20057
- else
20058
- fail(
20059
- "Claude Code \u2014 hooks file found but node9 hook missing",
20060
- "Run: node9 setup claude"
20061
- );
20062
- } catch {
20063
- fail("Claude Code \u2014 ~/.claude/settings.json is invalid JSON");
20064
- }
20065
- } else {
20066
- warn("Claude Code \u2014 not configured", "Run: node9 setup claude");
20067
- }
20068
- const geminiSettingsPath = import_path39.default.join(homeDir2, ".gemini", "settings.json");
20069
- if (import_fs38.default.existsSync(geminiSettingsPath)) {
20070
- try {
20071
- const gs = JSON.parse(import_fs38.default.readFileSync(geminiSettingsPath, "utf-8"));
20072
- const hasHook = gs.hooks?.BeforeTool?.some(
20073
- (m) => m.hooks.some((h) => h.command?.includes("node9") || h.command?.includes("cli.js"))
20074
- );
20075
- if (hasHook) pass("Gemini CLI \u2014 BeforeTool hook active");
20076
- else
20077
- fail(
20078
- "Gemini CLI \u2014 hooks file found but node9 hook missing",
20079
- "Run: node9 setup gemini"
20080
- );
20081
- } catch {
20082
- fail("Gemini CLI \u2014 ~/.gemini/settings.json is invalid JSON");
20185
+ const notConfigured = [];
20186
+ for (const a of getAgentWiring(homeDir2)) {
20187
+ if (a.wireState === "wired") {
20188
+ pass(`${a.label} \u2014 ${a.hookLabel} active`);
20189
+ } else if (a.wireState === "unwired") {
20190
+ fail(`${a.label} \u2014 settings found but node9 hook missing`, `Run: ${a.setupCommand}`);
20191
+ } else if (a.wireState === "invalid") {
20192
+ fail(`${a.label} \u2014 settings file is invalid JSON`, a.settingsPath);
20193
+ } else {
20194
+ notConfigured.push(a.label);
20083
20195
  }
20084
- } else {
20085
- warn("Gemini CLI \u2014 not configured", "Run: node9 setup gemini (skip if not using Gemini)");
20086
20196
  }
20087
- const cursorHooksPath = import_path39.default.join(homeDir2, ".cursor", "hooks.json");
20088
- if (import_fs38.default.existsSync(cursorHooksPath)) {
20089
- try {
20090
- const cur = JSON.parse(import_fs38.default.readFileSync(cursorHooksPath, "utf-8"));
20091
- const hasHook = cur.hooks?.preToolUse?.some(
20092
- (h) => h.command?.includes("node9") || h.command?.includes("cli.js")
20093
- );
20094
- if (hasHook) pass("Cursor \u2014 preToolUse hook active");
20095
- else
20096
- fail(
20097
- "Cursor \u2014 hooks file found but node9 hook missing",
20098
- "Run: node9 setup cursor"
20099
- );
20100
- } catch {
20101
- fail("Cursor \u2014 ~/.cursor/hooks.json is invalid JSON");
20102
- }
20103
- } else {
20104
- warn("Cursor \u2014 not configured", "Run: node9 setup cursor (skip if not using Cursor)");
20197
+ if (notConfigured.length > 0) {
20198
+ console.log(
20199
+ import_chalk11.default.gray(
20200
+ ` \xB7 Not configured: ${notConfigured.join(", ")} \u2014 run \`node9 setup <agent>\` if you use one`
20201
+ )
20202
+ );
20105
20203
  }
20106
20204
  section("Daemon (optional)");
20107
20205
  if (isDaemonRunning()) {
@@ -20118,7 +20216,7 @@ function registerDoctorCommand(program2, version2) {
20118
20216
  try {
20119
20217
  const { shipLagBytes: shipLagBytes2, readWatermark: readWatermark2, AUDIT_SHIP_WATERMARK: AUDIT_SHIP_WATERMARK2 } = await Promise.resolve().then(() => (init_audit_shipper(), audit_shipper_exports));
20120
20218
  const cfg = getConfig();
20121
- const creds = import_fs38.default.existsSync(import_path39.default.join(import_os34.default.homedir(), ".node9", "credentials.json"));
20219
+ const creds = import_fs39.default.existsSync(import_path40.default.join(import_os35.default.homedir(), ".node9", "credentials.json"));
20122
20220
  if (!creds) {
20123
20221
  warn("Not logged in \u2014 audit rows stay local", "Run: node9 login <api-key>");
20124
20222
  } else if (!cfg.settings.approvers.cloud) {
@@ -20168,9 +20266,9 @@ function registerDoctorCommand(program2, version2) {
20168
20266
 
20169
20267
  // src/cli/commands/audit.ts
20170
20268
  var import_chalk12 = __toESM(require("chalk"));
20171
- var import_fs39 = __toESM(require("fs"));
20172
- var import_path40 = __toESM(require("path"));
20173
- var import_os35 = __toESM(require("os"));
20269
+ var import_fs40 = __toESM(require("fs"));
20270
+ var import_path41 = __toESM(require("path"));
20271
+ var import_os36 = __toESM(require("os"));
20174
20272
  function formatRelativeTime(timestamp) {
20175
20273
  const diff = Date.now() - new Date(timestamp).getTime();
20176
20274
  const sec = Math.floor(diff / 1e3);
@@ -20183,14 +20281,14 @@ function formatRelativeTime(timestamp) {
20183
20281
  }
20184
20282
  function registerAuditCommand(program2) {
20185
20283
  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) => {
20186
- const logPath = import_path40.default.join(import_os35.default.homedir(), ".node9", "audit.log");
20187
- if (!import_fs39.default.existsSync(logPath)) {
20284
+ const logPath = import_path41.default.join(import_os36.default.homedir(), ".node9", "audit.log");
20285
+ if (!import_fs40.default.existsSync(logPath)) {
20188
20286
  console.log(
20189
20287
  import_chalk12.default.yellow("No audit logs found. Run node9 with an agent to generate entries.")
20190
20288
  );
20191
20289
  return;
20192
20290
  }
20193
- const raw = import_fs39.default.readFileSync(logPath, "utf-8");
20291
+ const raw = import_fs40.default.readFileSync(logPath, "utf-8");
20194
20292
  const lines = raw.split("\n").filter((l) => l.trim() !== "");
20195
20293
  let entries = lines.flatMap((line) => {
20196
20294
  try {
@@ -20246,9 +20344,9 @@ function registerAuditCommand(program2) {
20246
20344
  var import_chalk13 = __toESM(require("chalk"));
20247
20345
 
20248
20346
  // src/cli/aggregate/report-audit.ts
20249
- var import_fs40 = __toESM(require("fs"));
20250
- var import_os36 = __toESM(require("os"));
20251
- var import_path41 = __toESM(require("path"));
20347
+ var import_fs41 = __toESM(require("fs"));
20348
+ var import_os37 = __toESM(require("os"));
20349
+ var import_path42 = __toESM(require("path"));
20252
20350
  init_costSync();
20253
20351
  init_litellm();
20254
20352
  init_cost_codex();
@@ -20331,8 +20429,8 @@ function getDateRange(period, now) {
20331
20429
  }
20332
20430
  }
20333
20431
  function parseAuditLog(logPath) {
20334
- if (!import_fs40.default.existsSync(logPath)) return [];
20335
- const raw = import_fs40.default.readFileSync(logPath, "utf-8");
20432
+ if (!import_fs41.default.existsSync(logPath)) return [];
20433
+ const raw = import_fs41.default.readFileSync(logPath, "utf-8");
20336
20434
  return raw.split("\n").flatMap((line) => {
20337
20435
  if (!line.trim()) return [];
20338
20436
  try {
@@ -20379,25 +20477,25 @@ function freezeClaudeCost(acc) {
20379
20477
  };
20380
20478
  }
20381
20479
  function processClaudeCostProject(proj, projectsDir, start, end, acc) {
20382
- const projPath = import_path41.default.join(projectsDir, proj);
20480
+ const projPath = import_path42.default.join(projectsDir, proj);
20383
20481
  let files;
20384
20482
  try {
20385
- const stat = import_fs40.default.statSync(projPath);
20483
+ const stat = import_fs41.default.statSync(projPath);
20386
20484
  if (!stat.isDirectory()) return;
20387
- files = import_fs40.default.readdirSync(projPath).filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
20485
+ files = import_fs41.default.readdirSync(projPath).filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
20388
20486
  } catch {
20389
20487
  return;
20390
20488
  }
20391
20489
  const startMs = start.getTime();
20392
20490
  for (const file of files) {
20393
- const filePath = import_path41.default.join(projPath, file);
20491
+ const filePath = import_path42.default.join(projPath, file);
20394
20492
  try {
20395
- if (import_fs40.default.statSync(filePath).mtimeMs < startMs) continue;
20493
+ if (import_fs41.default.statSync(filePath).mtimeMs < startMs) continue;
20396
20494
  } catch {
20397
20495
  continue;
20398
20496
  }
20399
20497
  try {
20400
- const raw = import_fs40.default.readFileSync(filePath, "utf-8");
20498
+ const raw = import_fs41.default.readFileSync(filePath, "utf-8");
20401
20499
  for (const line of raw.split("\n")) {
20402
20500
  if (!line.trim()) continue;
20403
20501
  let entry;
@@ -20447,10 +20545,10 @@ function processClaudeCostProject(proj, projectsDir, start, end, acc) {
20447
20545
  }
20448
20546
  function loadClaudeCost(start, end, projectsDir) {
20449
20547
  const acc = emptyClaudeCostAccumulator();
20450
- if (!import_fs40.default.existsSync(projectsDir)) return freezeClaudeCost(acc);
20548
+ if (!import_fs41.default.existsSync(projectsDir)) return freezeClaudeCost(acc);
20451
20549
  let dirs;
20452
20550
  try {
20453
- dirs = import_fs40.default.readdirSync(projectsDir);
20551
+ dirs = import_fs41.default.readdirSync(projectsDir);
20454
20552
  } catch {
20455
20553
  return freezeClaudeCost(acc);
20456
20554
  }
@@ -20462,7 +20560,7 @@ function loadClaudeCost(start, end, projectsDir) {
20462
20560
  function processCodexCostFile(filePath, start, end, acc) {
20463
20561
  let lines;
20464
20562
  try {
20465
- lines = import_fs40.default.readFileSync(filePath, "utf-8").split("\n");
20563
+ lines = import_fs41.default.readFileSync(filePath, "utf-8").split("\n");
20466
20564
  } catch {
20467
20565
  return;
20468
20566
  }
@@ -20517,31 +20615,31 @@ function processCodexCostFile(filePath, start, end, acc) {
20517
20615
  }
20518
20616
  function listCodexSessionFiles2(sessionsBase) {
20519
20617
  const jsonlFiles = [];
20520
- if (!import_fs40.default.existsSync(sessionsBase)) return jsonlFiles;
20618
+ if (!import_fs41.default.existsSync(sessionsBase)) return jsonlFiles;
20521
20619
  try {
20522
- for (const year of import_fs40.default.readdirSync(sessionsBase)) {
20523
- const yearPath = import_path41.default.join(sessionsBase, year);
20620
+ for (const year of import_fs41.default.readdirSync(sessionsBase)) {
20621
+ const yearPath = import_path42.default.join(sessionsBase, year);
20524
20622
  try {
20525
- if (!import_fs40.default.statSync(yearPath).isDirectory()) continue;
20623
+ if (!import_fs41.default.statSync(yearPath).isDirectory()) continue;
20526
20624
  } catch {
20527
20625
  continue;
20528
20626
  }
20529
- for (const month of import_fs40.default.readdirSync(yearPath)) {
20530
- const monthPath = import_path41.default.join(yearPath, month);
20627
+ for (const month of import_fs41.default.readdirSync(yearPath)) {
20628
+ const monthPath = import_path42.default.join(yearPath, month);
20531
20629
  try {
20532
- if (!import_fs40.default.statSync(monthPath).isDirectory()) continue;
20630
+ if (!import_fs41.default.statSync(monthPath).isDirectory()) continue;
20533
20631
  } catch {
20534
20632
  continue;
20535
20633
  }
20536
- for (const day of import_fs40.default.readdirSync(monthPath)) {
20537
- const dayPath = import_path41.default.join(monthPath, day);
20634
+ for (const day of import_fs41.default.readdirSync(monthPath)) {
20635
+ const dayPath = import_path42.default.join(monthPath, day);
20538
20636
  try {
20539
- if (!import_fs40.default.statSync(dayPath).isDirectory()) continue;
20637
+ if (!import_fs41.default.statSync(dayPath).isDirectory()) continue;
20540
20638
  } catch {
20541
20639
  continue;
20542
20640
  }
20543
- for (const file of import_fs40.default.readdirSync(dayPath)) {
20544
- if (file.endsWith(".jsonl")) jsonlFiles.push(import_path41.default.join(dayPath, file));
20641
+ for (const file of import_fs41.default.readdirSync(dayPath)) {
20642
+ if (file.endsWith(".jsonl")) jsonlFiles.push(import_path42.default.join(dayPath, file));
20545
20643
  }
20546
20644
  }
20547
20645
  }
@@ -20606,13 +20704,13 @@ function freezeGeminiCost(acc) {
20606
20704
  function processGeminiCostFile(filePath, projectKey, start, end, acc) {
20607
20705
  const startMs = start.getTime();
20608
20706
  try {
20609
- if (import_fs40.default.statSync(filePath).mtimeMs < startMs) return;
20707
+ if (import_fs41.default.statSync(filePath).mtimeMs < startMs) return;
20610
20708
  } catch {
20611
20709
  return;
20612
20710
  }
20613
20711
  let raw;
20614
20712
  try {
20615
- raw = import_fs40.default.readFileSync(filePath, "utf-8");
20713
+ raw = import_fs41.default.readFileSync(filePath, "utf-8");
20616
20714
  } catch {
20617
20715
  return;
20618
20716
  }
@@ -20661,30 +20759,30 @@ function listGeminiSessionFiles2(geminiTmpDir2) {
20661
20759
  const out = [];
20662
20760
  let dirs;
20663
20761
  try {
20664
- if (!import_fs40.default.statSync(geminiTmpDir2).isDirectory()) return out;
20665
- dirs = import_fs40.default.readdirSync(geminiTmpDir2);
20762
+ if (!import_fs41.default.statSync(geminiTmpDir2).isDirectory()) return out;
20763
+ dirs = import_fs41.default.readdirSync(geminiTmpDir2);
20666
20764
  } catch {
20667
20765
  return out;
20668
20766
  }
20669
20767
  for (const proj of dirs) {
20670
- const chatsDir = import_path41.default.join(geminiTmpDir2, proj, "chats");
20768
+ const chatsDir = import_path42.default.join(geminiTmpDir2, proj, "chats");
20671
20769
  let files;
20672
20770
  try {
20673
- if (!import_fs40.default.statSync(chatsDir).isDirectory()) continue;
20674
- files = import_fs40.default.readdirSync(chatsDir);
20771
+ if (!import_fs41.default.statSync(chatsDir).isDirectory()) continue;
20772
+ files = import_fs41.default.readdirSync(chatsDir);
20675
20773
  } catch {
20676
20774
  continue;
20677
20775
  }
20678
20776
  for (const f of files) {
20679
20777
  if (!f.endsWith(".jsonl")) continue;
20680
- out.push({ projectKey: proj, file: import_path41.default.join(chatsDir, f) });
20778
+ out.push({ projectKey: proj, file: import_path42.default.join(chatsDir, f) });
20681
20779
  }
20682
20780
  }
20683
20781
  return out;
20684
20782
  }
20685
20783
  function loadGeminiCost(start, end, geminiTmpDir2) {
20686
20784
  const acc = emptyGeminiAccumulator();
20687
- if (!import_fs40.default.existsSync(geminiTmpDir2)) return freezeGeminiCost(acc);
20785
+ if (!import_fs41.default.existsSync(geminiTmpDir2)) return freezeGeminiCost(acc);
20688
20786
  for (const { projectKey, file } of listGeminiSessionFiles2(geminiTmpDir2)) {
20689
20787
  processGeminiCostFile(file, projectKey, start, end, acc);
20690
20788
  }
@@ -20692,11 +20790,11 @@ function loadGeminiCost(start, end, geminiTmpDir2) {
20692
20790
  }
20693
20791
  function aggregateReportFromAudit(period, opts = {}) {
20694
20792
  const now = opts.now ?? /* @__PURE__ */ new Date();
20695
- const auditLogPath = opts.auditLogPath ?? import_path41.default.join(import_os36.default.homedir(), ".node9", "audit.log");
20696
- const claudeProjectsDir = opts.claudeProjectsDir ?? import_path41.default.join(import_os36.default.homedir(), ".claude", "projects");
20697
- const codexSessionsDir2 = opts.codexSessionsDir ?? import_path41.default.join(import_os36.default.homedir(), ".codex", "sessions");
20698
- const geminiTmpDir2 = opts.geminiTmpDir ?? import_path41.default.join(import_os36.default.homedir(), ".gemini", "tmp");
20699
- const hasAuditFile = import_fs40.default.existsSync(auditLogPath);
20793
+ const auditLogPath = opts.auditLogPath ?? import_path42.default.join(import_os37.default.homedir(), ".node9", "audit.log");
20794
+ const claudeProjectsDir = opts.claudeProjectsDir ?? import_path42.default.join(import_os37.default.homedir(), ".claude", "projects");
20795
+ const codexSessionsDir2 = opts.codexSessionsDir ?? import_path42.default.join(import_os37.default.homedir(), ".codex", "sessions");
20796
+ const geminiTmpDir2 = opts.geminiTmpDir ?? import_path42.default.join(import_os37.default.homedir(), ".gemini", "tmp");
20797
+ const hasAuditFile = import_fs41.default.existsSync(auditLogPath);
20700
20798
  const allEntries = opts.preloadedAuditEntries ?? parseAuditLog(auditLogPath);
20701
20799
  const unackedDlp = allEntries.filter((e) => e.source === "response-dlp");
20702
20800
  const { start, end } = getDateRange(period, now);
@@ -21392,23 +21490,23 @@ function registerDaemonCommand(program2) {
21392
21490
 
21393
21491
  // src/cli/commands/status.ts
21394
21492
  var import_chalk15 = __toESM(require("chalk"));
21395
- var import_fs41 = __toESM(require("fs"));
21396
- var import_path42 = __toESM(require("path"));
21397
- var import_os37 = __toESM(require("os"));
21398
- var yaml2 = __toESM(require("yaml"));
21493
+ var import_fs42 = __toESM(require("fs"));
21494
+ var import_path43 = __toESM(require("path"));
21495
+ var import_os38 = __toESM(require("os"));
21496
+ var yaml3 = __toESM(require("yaml"));
21399
21497
  init_core();
21400
21498
  init_daemon();
21401
21499
  init_setup();
21402
21500
  function readHermesHooks(configPath) {
21403
- if (!import_fs41.default.existsSync(configPath)) return null;
21501
+ if (!import_fs42.default.existsSync(configPath)) return null;
21404
21502
  let raw;
21405
21503
  try {
21406
- raw = import_fs41.default.readFileSync(configPath, "utf-8");
21504
+ raw = import_fs42.default.readFileSync(configPath, "utf-8");
21407
21505
  } catch {
21408
21506
  return null;
21409
21507
  }
21410
21508
  try {
21411
- const cfg = yaml2.parse(raw);
21509
+ const cfg = yaml3.parse(raw);
21412
21510
  const has = (event) => (cfg?.hooks?.[event] ?? []).some(
21413
21511
  (e) => typeof e?.command === "string" && isNode9Hook(e.command)
21414
21512
  );
@@ -21422,17 +21520,17 @@ function readHermesHooks(configPath) {
21422
21520
  return { pre: false, post: false };
21423
21521
  }
21424
21522
  }
21425
- function readJson2(filePath) {
21523
+ function readJson3(filePath) {
21426
21524
  try {
21427
- if (import_fs41.default.existsSync(filePath)) return JSON.parse(import_fs41.default.readFileSync(filePath, "utf-8"));
21525
+ if (import_fs42.default.existsSync(filePath)) return JSON.parse(import_fs42.default.readFileSync(filePath, "utf-8"));
21428
21526
  } catch {
21429
21527
  }
21430
21528
  return null;
21431
21529
  }
21432
- function matchersHaveNode9Hook(matchers) {
21530
+ function matchersHaveNode9Hook2(matchers) {
21433
21531
  return (matchers ?? []).some((m) => (m.hooks ?? []).some((h) => isNode9Hook(h.command)));
21434
21532
  }
21435
- function flatHaveNode9Hook(entries) {
21533
+ function flatHaveNode9Hook2(entries) {
21436
21534
  return (Array.isArray(entries) ? entries : []).some((h) => isNode9Hook(h.command));
21437
21535
  }
21438
21536
  function wrappedMcpServers(servers) {
@@ -21492,42 +21590,42 @@ function registerStatusCommand(program2) {
21492
21590
  console.log("");
21493
21591
  const modeLabel = settings.mode === "audit" ? import_chalk15.default.blue("audit") : settings.mode === "strict" ? import_chalk15.default.red("strict") : import_chalk15.default.white("standard");
21494
21592
  console.log(` Mode: ${modeLabel}`);
21495
- const projectConfig = import_path42.default.join(process.cwd(), "node9.config.json");
21496
- const globalConfig = import_path42.default.join(import_os37.default.homedir(), ".node9", "config.json");
21593
+ const projectConfig = import_path43.default.join(process.cwd(), "node9.config.json");
21594
+ const globalConfig = import_path43.default.join(import_os38.default.homedir(), ".node9", "config.json");
21497
21595
  console.log(
21498
- ` Local: ${import_fs41.default.existsSync(projectConfig) ? import_chalk15.default.green("Active (node9.config.json)") : import_chalk15.default.gray("Not present")}`
21596
+ ` Local: ${import_fs42.default.existsSync(projectConfig) ? import_chalk15.default.green("Active (node9.config.json)") : import_chalk15.default.gray("Not present")}`
21499
21597
  );
21500
21598
  console.log(
21501
- ` Global: ${import_fs41.default.existsSync(globalConfig) ? import_chalk15.default.green("Active (~/.node9/config.json)") : import_chalk15.default.gray("Not present")}`
21599
+ ` Global: ${import_fs42.default.existsSync(globalConfig) ? import_chalk15.default.green("Active (~/.node9/config.json)") : import_chalk15.default.gray("Not present")}`
21502
21600
  );
21503
21601
  if (mergedConfig.policy.sandboxPaths.length > 0) {
21504
21602
  console.log(
21505
21603
  ` Sandbox: ${import_chalk15.default.green(`${mergedConfig.policy.sandboxPaths.length} safe zones active`)}`
21506
21604
  );
21507
21605
  }
21508
- const homeDir2 = import_os37.default.homedir();
21509
- const claudeSettings = readJson2(
21510
- import_path42.default.join(homeDir2, ".claude", "settings.json")
21606
+ const homeDir2 = import_os38.default.homedir();
21607
+ const claudeSettings = readJson3(
21608
+ import_path43.default.join(homeDir2, ".claude", "settings.json")
21511
21609
  );
21512
- const claudeConfig = readJson2(import_path42.default.join(homeDir2, ".claude.json"));
21513
- const geminiSettings = readJson2(
21514
- import_path42.default.join(homeDir2, ".gemini", "settings.json")
21610
+ const claudeConfig = readJson3(import_path43.default.join(homeDir2, ".claude.json"));
21611
+ const geminiSettings = readJson3(
21612
+ import_path43.default.join(homeDir2, ".gemini", "settings.json")
21515
21613
  );
21516
- const cursorConfig = readJson2(import_path42.default.join(homeDir2, ".cursor", "mcp.json"));
21517
- const antigravityHooks = readJson2(
21518
- import_path42.default.join(homeDir2, ".gemini", "config", "hooks.json")
21614
+ const cursorConfig = readJson3(import_path43.default.join(homeDir2, ".cursor", "mcp.json"));
21615
+ const antigravityHooks = readJson3(
21616
+ import_path43.default.join(homeDir2, ".gemini", "config", "hooks.json")
21519
21617
  );
21520
- const antigravityMcp = readJson2(
21521
- import_path42.default.join(homeDir2, ".gemini", "config", "mcp_config.json")
21618
+ const antigravityMcp = readJson3(
21619
+ import_path43.default.join(homeDir2, ".gemini", "config", "mcp_config.json")
21522
21620
  );
21523
- const antigravityPresent = antigravityHooks !== null || import_fs41.default.existsSync(import_path42.default.join(homeDir2, ".gemini", "antigravity-cli")) || import_fs41.default.existsSync(import_path42.default.join(homeDir2, ".gemini", "antigravity-ide"));
21524
- const copilotHooks = readJson2(
21525
- import_path42.default.join(homeDir2, ".copilot", "hooks", "node9.json")
21621
+ const antigravityPresent = antigravityHooks !== null || import_fs42.default.existsSync(import_path43.default.join(homeDir2, ".gemini", "antigravity-cli")) || import_fs42.default.existsSync(import_path43.default.join(homeDir2, ".gemini", "antigravity-ide"));
21622
+ const copilotHooks = readJson3(
21623
+ import_path43.default.join(homeDir2, ".copilot", "hooks", "node9.json")
21526
21624
  );
21527
- const copilotMcp = readJson2(
21528
- import_path42.default.join(homeDir2, ".copilot", "mcp-config.json")
21625
+ const copilotMcp = readJson3(
21626
+ import_path43.default.join(homeDir2, ".copilot", "mcp-config.json")
21529
21627
  );
21530
- const copilotPresent = import_fs41.default.existsSync(import_path42.default.join(homeDir2, ".copilot"));
21628
+ const copilotPresent = import_fs42.default.existsSync(import_path43.default.join(homeDir2, ".copilot"));
21531
21629
  const hermesHooks = readHermesHooks(hermesConfigPath(homeDir2));
21532
21630
  const agentFound = claudeSettings || claudeConfig || geminiSettings || cursorConfig || antigravityPresent || copilotPresent || hermesHooks;
21533
21631
  if (agentFound) {
@@ -21535,8 +21633,8 @@ function registerStatusCommand(program2) {
21535
21633
  console.log(import_chalk15.default.bold(" Agent Wiring:"));
21536
21634
  console.log("");
21537
21635
  if (claudeSettings || claudeConfig) {
21538
- const preHook = matchersHaveNode9Hook(claudeSettings?.hooks?.PreToolUse);
21539
- const postHook = matchersHaveNode9Hook(claudeSettings?.hooks?.PostToolUse);
21636
+ const preHook = matchersHaveNode9Hook2(claudeSettings?.hooks?.PreToolUse);
21637
+ const postHook = matchersHaveNode9Hook2(claudeSettings?.hooks?.PostToolUse);
21540
21638
  printAgentSection(
21541
21639
  "Claude Code",
21542
21640
  [
@@ -21548,8 +21646,8 @@ function registerStatusCommand(program2) {
21548
21646
  console.log("");
21549
21647
  }
21550
21648
  if (geminiSettings) {
21551
- const beforeHook = matchersHaveNode9Hook(geminiSettings.hooks?.BeforeTool);
21552
- const afterHook = matchersHaveNode9Hook(geminiSettings.hooks?.AfterTool);
21649
+ const beforeHook = matchersHaveNode9Hook2(geminiSettings.hooks?.BeforeTool);
21650
+ const afterHook = matchersHaveNode9Hook2(geminiSettings.hooks?.AfterTool);
21553
21651
  printAgentSection(
21554
21652
  "Gemini CLI",
21555
21653
  [
@@ -21561,8 +21659,8 @@ function registerStatusCommand(program2) {
21561
21659
  console.log("");
21562
21660
  }
21563
21661
  if (antigravityPresent) {
21564
- const preHook = matchersHaveNode9Hook(antigravityHooks?.hooks?.PreToolUse);
21565
- const postHook = matchersHaveNode9Hook(antigravityHooks?.hooks?.PostToolUse);
21662
+ const preHook = matchersHaveNode9Hook2(antigravityHooks?.hooks?.PreToolUse);
21663
+ const postHook = matchersHaveNode9Hook2(antigravityHooks?.hooks?.PostToolUse);
21566
21664
  printAgentSection(
21567
21665
  "Antigravity",
21568
21666
  [
@@ -21574,9 +21672,9 @@ function registerStatusCommand(program2) {
21574
21672
  console.log("");
21575
21673
  }
21576
21674
  if (copilotPresent) {
21577
- const preHook = flatHaveNode9Hook(copilotHooks?.hooks?.PreToolUse);
21578
- const postHook = flatHaveNode9Hook(copilotHooks?.hooks?.PostToolUse);
21579
- const promptHook = flatHaveNode9Hook(copilotHooks?.hooks?.UserPromptSubmit);
21675
+ const preHook = flatHaveNode9Hook2(copilotHooks?.hooks?.PreToolUse);
21676
+ const postHook = flatHaveNode9Hook2(copilotHooks?.hooks?.PostToolUse);
21677
+ const promptHook = flatHaveNode9Hook2(copilotHooks?.hooks?.UserPromptSubmit);
21580
21678
  printAgentSection(
21581
21679
  "GitHub Copilot",
21582
21680
  [
@@ -21619,9 +21717,9 @@ function registerStatusCommand(program2) {
21619
21717
 
21620
21718
  // src/cli/commands/init.ts
21621
21719
  var import_chalk16 = __toESM(require("chalk"));
21622
- var import_fs42 = __toESM(require("fs"));
21623
- var import_path43 = __toESM(require("path"));
21624
- var import_os38 = __toESM(require("os"));
21720
+ var import_fs43 = __toESM(require("fs"));
21721
+ var import_path44 = __toESM(require("path"));
21722
+ var import_os39 = __toESM(require("os"));
21625
21723
  var import_https4 = __toESM(require("https"));
21626
21724
  init_core();
21627
21725
  init_setup();
@@ -21711,16 +21809,16 @@ function registerInitCommand(program2) {
21711
21809
  }
21712
21810
  console.log("");
21713
21811
  }
21714
- const configPath = import_path43.default.join(import_os38.default.homedir(), ".node9", "config.json");
21715
- const isFirstInstall = !import_fs42.default.existsSync(configPath);
21716
- if (import_fs42.default.existsSync(configPath) && !options.force) {
21812
+ const configPath = import_path44.default.join(import_os39.default.homedir(), ".node9", "config.json");
21813
+ const isFirstInstall = !import_fs43.default.existsSync(configPath);
21814
+ if (import_fs43.default.existsSync(configPath) && !options.force) {
21717
21815
  try {
21718
- const existing = JSON.parse(import_fs42.default.readFileSync(configPath, "utf-8"));
21816
+ const existing = JSON.parse(import_fs43.default.readFileSync(configPath, "utf-8"));
21719
21817
  const settings = existing.settings ?? {};
21720
21818
  if (settings.mode !== chosenMode) {
21721
21819
  settings.mode = chosenMode;
21722
21820
  existing.settings = settings;
21723
- import_fs42.default.writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n");
21821
+ import_fs43.default.writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n");
21724
21822
  console.log(import_chalk16.default.green(`\u2705 Mode updated: ${chosenMode}`));
21725
21823
  } else {
21726
21824
  console.log(import_chalk16.default.blue(`\u2139\uFE0F Config already exists: ${configPath}`));
@@ -21733,9 +21831,9 @@ function registerInitCommand(program2) {
21733
21831
  ...DEFAULT_CONFIG,
21734
21832
  settings: { ...DEFAULT_CONFIG.settings, mode: chosenMode }
21735
21833
  };
21736
- const dir = import_path43.default.dirname(configPath);
21737
- if (!import_fs42.default.existsSync(dir)) import_fs42.default.mkdirSync(dir, { recursive: true });
21738
- import_fs42.default.writeFileSync(configPath, JSON.stringify(configToSave, null, 2) + "\n");
21834
+ const dir = import_path44.default.dirname(configPath);
21835
+ if (!import_fs43.default.existsSync(dir)) import_fs43.default.mkdirSync(dir, { recursive: true });
21836
+ import_fs43.default.writeFileSync(configPath, JSON.stringify(configToSave, null, 2) + "\n");
21739
21837
  console.log(import_chalk16.default.green(`\u2705 Config created: ${configPath}`));
21740
21838
  console.log(import_chalk16.default.gray(` Mode: ${chosenMode}`));
21741
21839
  }
@@ -21840,7 +21938,7 @@ function registerInitCommand(program2) {
21840
21938
  }
21841
21939
 
21842
21940
  // src/cli/commands/undo.ts
21843
- var import_path44 = __toESM(require("path"));
21941
+ var import_path45 = __toESM(require("path"));
21844
21942
  var import_chalk18 = __toESM(require("chalk"));
21845
21943
 
21846
21944
  // src/tui/undo-navigator.ts
@@ -21999,7 +22097,7 @@ function findMatchingCwd(startDir, history) {
21999
22097
  let dir = startDir;
22000
22098
  while (true) {
22001
22099
  if (cwds.has(dir)) return dir;
22002
- const parent = import_path44.default.dirname(dir);
22100
+ const parent = import_path45.default.dirname(dir);
22003
22101
  if (parent === dir) return null;
22004
22102
  dir = parent;
22005
22103
  }
@@ -22634,9 +22732,9 @@ function registerMcpGatewayCommand(program2) {
22634
22732
 
22635
22733
  // src/mcp-server/index.ts
22636
22734
  var import_readline5 = __toESM(require("readline"));
22637
- var import_fs43 = __toESM(require("fs"));
22638
- var import_os39 = __toESM(require("os"));
22639
- var import_path45 = __toESM(require("path"));
22735
+ var import_fs44 = __toESM(require("fs"));
22736
+ var import_os40 = __toESM(require("os"));
22737
+ var import_path46 = __toESM(require("path"));
22640
22738
  var import_child_process11 = require("child_process");
22641
22739
  init_core();
22642
22740
  init_daemon();
@@ -22887,13 +22985,13 @@ function handleStatus() {
22887
22985
  lines.push(`Active shields: ${activeShields.length > 0 ? activeShields.join(", ") : "none"}`);
22888
22986
  lines.push(`Smart rules: ${config.policy.smartRules.length} loaded`);
22889
22987
  lines.push(`DLP: ${config.policy.dlp?.enabled !== false ? "enabled" : "disabled"}`);
22890
- const projectConfig = import_path45.default.join(process.cwd(), "node9.config.json");
22891
- const globalConfig = import_path45.default.join(import_os39.default.homedir(), ".node9", "config.json");
22988
+ const projectConfig = import_path46.default.join(process.cwd(), "node9.config.json");
22989
+ const globalConfig = import_path46.default.join(import_os40.default.homedir(), ".node9", "config.json");
22892
22990
  lines.push(
22893
- `Project config (node9.config.json): ${import_fs43.default.existsSync(projectConfig) ? "present" : "not found"}`
22991
+ `Project config (node9.config.json): ${import_fs44.default.existsSync(projectConfig) ? "present" : "not found"}`
22894
22992
  );
22895
22993
  lines.push(
22896
- `Global config (~/.node9/config.json): ${import_fs43.default.existsSync(globalConfig) ? "present" : "not found"}`
22994
+ `Global config (~/.node9/config.json): ${import_fs44.default.existsSync(globalConfig) ? "present" : "not found"}`
22897
22995
  );
22898
22996
  return lines.join("\n");
22899
22997
  }
@@ -22967,21 +23065,21 @@ function handleShieldDisable(args) {
22967
23065
  writeActiveShields(active.filter((s) => s !== name));
22968
23066
  return `Shield "${name}" disabled.`;
22969
23067
  }
22970
- var GLOBAL_CONFIG_PATH = import_path45.default.join(import_os39.default.homedir(), ".node9", "config.json");
23068
+ var GLOBAL_CONFIG_PATH = import_path46.default.join(import_os40.default.homedir(), ".node9", "config.json");
22971
23069
  var APPROVER_CHANNELS = ["native", "browser", "cloud", "terminal"];
22972
23070
  function readGlobalConfigRaw() {
22973
23071
  try {
22974
- if (import_fs43.default.existsSync(GLOBAL_CONFIG_PATH)) {
22975
- return JSON.parse(import_fs43.default.readFileSync(GLOBAL_CONFIG_PATH, "utf-8"));
23072
+ if (import_fs44.default.existsSync(GLOBAL_CONFIG_PATH)) {
23073
+ return JSON.parse(import_fs44.default.readFileSync(GLOBAL_CONFIG_PATH, "utf-8"));
22976
23074
  }
22977
23075
  } catch {
22978
23076
  }
22979
23077
  return {};
22980
23078
  }
22981
23079
  function writeGlobalConfigRaw(data) {
22982
- const dir = import_path45.default.dirname(GLOBAL_CONFIG_PATH);
22983
- if (!import_fs43.default.existsSync(dir)) import_fs43.default.mkdirSync(dir, { recursive: true });
22984
- import_fs43.default.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(data, null, 2) + "\n");
23080
+ const dir = import_path46.default.dirname(GLOBAL_CONFIG_PATH);
23081
+ if (!import_fs44.default.existsSync(dir)) import_fs44.default.mkdirSync(dir, { recursive: true });
23082
+ import_fs44.default.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(data, null, 2) + "\n");
22985
23083
  }
22986
23084
  function handleApproverList() {
22987
23085
  const config = getConfig();
@@ -23025,9 +23123,9 @@ function handleApproverSet(args) {
23025
23123
  function handleAuditGet(args) {
23026
23124
  const limit = Math.min(typeof args.limit === "number" ? args.limit : 20, 100);
23027
23125
  const filter = typeof args.filter === "string" && args.filter !== "all" ? args.filter : null;
23028
- const auditPath = import_path45.default.join(import_os39.default.homedir(), ".node9", "audit.log");
23029
- if (!import_fs43.default.existsSync(auditPath)) return "No audit log found.";
23030
- const rawLines = import_fs43.default.readFileSync(auditPath, "utf-8").trim().split("\n").filter(Boolean);
23126
+ const auditPath = import_path46.default.join(import_os40.default.homedir(), ".node9", "audit.log");
23127
+ if (!import_fs44.default.existsSync(auditPath)) return "No audit log found.";
23128
+ const rawLines = import_fs44.default.readFileSync(auditPath, "utf-8").trim().split("\n").filter(Boolean);
23031
23129
  const parsed = [];
23032
23130
  for (const line of rawLines) {
23033
23131
  try {
@@ -23362,7 +23460,7 @@ function registerTrustCommand(program2) {
23362
23460
  // src/cli/commands/mcp-pin.ts
23363
23461
  var import_chalk21 = __toESM(require("chalk"));
23364
23462
  init_mcp_pin();
23365
- var import_fs44 = __toESM(require("fs"));
23463
+ var import_fs45 = __toESM(require("fs"));
23366
23464
  function registerMcpPinCommand(program2) {
23367
23465
  const pinCmd = program2.command("mcp").description("Manage MCP server tool definition pinning (rug pull defense)");
23368
23466
  const pinSubCmd = pinCmd.command("pin").description("Manage pinned MCP server tool definitions");
@@ -23373,7 +23471,7 @@ function registerMcpPinCommand(program2) {
23373
23471
  let repoCorrupt = false;
23374
23472
  if (found.source === "repo") {
23375
23473
  try {
23376
- const raw = import_fs44.default.readFileSync(found.path, "utf-8");
23474
+ const raw = import_fs45.default.readFileSync(found.path, "utf-8");
23377
23475
  const parsed = JSON.parse(raw);
23378
23476
  repoEntries = parsed.servers ?? {};
23379
23477
  } catch {
@@ -23686,9 +23784,9 @@ init_scan();
23686
23784
 
23687
23785
  // src/cli/commands/sessions.ts
23688
23786
  var import_chalk24 = __toESM(require("chalk"));
23689
- var import_fs45 = __toESM(require("fs"));
23690
- var import_path46 = __toESM(require("path"));
23691
- var import_os40 = __toESM(require("os"));
23787
+ var import_fs46 = __toESM(require("fs"));
23788
+ var import_path47 = __toESM(require("path"));
23789
+ var import_os41 = __toESM(require("os"));
23692
23790
  init_scan_summary();
23693
23791
  init_litellm();
23694
23792
  init_cost_gemini();
@@ -23709,10 +23807,10 @@ function encodeProjectPath(projectPath) {
23709
23807
  }
23710
23808
  function sessionJsonlPath(projectPath, sessionId) {
23711
23809
  const encoded = encodeProjectPath(projectPath);
23712
- return import_path46.default.join(import_os40.default.homedir(), ".claude", "projects", encoded, `${sessionId}.jsonl`);
23810
+ return import_path47.default.join(import_os41.default.homedir(), ".claude", "projects", encoded, `${sessionId}.jsonl`);
23713
23811
  }
23714
23812
  function projectLabel(projectPath) {
23715
- return projectPath.replace(import_os40.default.homedir(), "~");
23813
+ return projectPath.replace(import_os41.default.homedir(), "~");
23716
23814
  }
23717
23815
  function parseHistoryLines(lines) {
23718
23816
  const entries = [];
@@ -23781,10 +23879,10 @@ function parseSessionLines(lines) {
23781
23879
  return { toolCalls, costUSD, hasSnapshot, modifiedFiles };
23782
23880
  }
23783
23881
  function loadAuditEntries(auditPath) {
23784
- const aPath = auditPath ?? import_path46.default.join(import_os40.default.homedir(), ".node9", "audit.log");
23882
+ const aPath = auditPath ?? import_path47.default.join(import_os41.default.homedir(), ".node9", "audit.log");
23785
23883
  let raw;
23786
23884
  try {
23787
- raw = import_fs45.default.readFileSync(aPath, "utf-8");
23885
+ raw = import_fs46.default.readFileSync(aPath, "utf-8");
23788
23886
  } catch {
23789
23887
  return [];
23790
23888
  }
@@ -23820,8 +23918,8 @@ function auditEntriesInWindow(entries, windowStart, windowEnd) {
23820
23918
  return result;
23821
23919
  }
23822
23920
  function buildGeminiSessions(days, allAuditEntries) {
23823
- const tmpDir = import_path46.default.join(import_os40.default.homedir(), ".gemini", "tmp");
23824
- if (!import_fs45.default.existsSync(tmpDir)) return [];
23921
+ const tmpDir = import_path47.default.join(import_os41.default.homedir(), ".gemini", "tmp");
23922
+ if (!import_fs46.default.existsSync(tmpDir)) return [];
23825
23923
  const cutoff = days !== null ? (() => {
23826
23924
  const d = /* @__PURE__ */ new Date();
23827
23925
  d.setDate(d.getDate() - days);
@@ -23830,35 +23928,35 @@ function buildGeminiSessions(days, allAuditEntries) {
23830
23928
  })() : null;
23831
23929
  let slugDirs;
23832
23930
  try {
23833
- slugDirs = import_fs45.default.readdirSync(tmpDir);
23931
+ slugDirs = import_fs46.default.readdirSync(tmpDir);
23834
23932
  } catch {
23835
23933
  return [];
23836
23934
  }
23837
23935
  const summaries = [];
23838
23936
  for (const slug of slugDirs) {
23839
- const slugPath = import_path46.default.join(tmpDir, slug);
23937
+ const slugPath = import_path47.default.join(tmpDir, slug);
23840
23938
  try {
23841
- if (!import_fs45.default.statSync(slugPath).isDirectory()) continue;
23939
+ if (!import_fs46.default.statSync(slugPath).isDirectory()) continue;
23842
23940
  } catch {
23843
23941
  continue;
23844
23942
  }
23845
- let projectRoot = import_path46.default.join(import_os40.default.homedir(), slug);
23943
+ let projectRoot = import_path47.default.join(import_os41.default.homedir(), slug);
23846
23944
  try {
23847
- projectRoot = import_fs45.default.readFileSync(import_path46.default.join(slugPath, ".project_root"), "utf-8").trim();
23945
+ projectRoot = import_fs46.default.readFileSync(import_path47.default.join(slugPath, ".project_root"), "utf-8").trim();
23848
23946
  } catch {
23849
23947
  }
23850
- const chatsDir = import_path46.default.join(slugPath, "chats");
23851
- if (!import_fs45.default.existsSync(chatsDir)) continue;
23948
+ const chatsDir = import_path47.default.join(slugPath, "chats");
23949
+ if (!import_fs46.default.existsSync(chatsDir)) continue;
23852
23950
  let chatFiles;
23853
23951
  try {
23854
- chatFiles = import_fs45.default.readdirSync(chatsDir).filter((f) => f.endsWith(".json"));
23952
+ chatFiles = import_fs46.default.readdirSync(chatsDir).filter((f) => f.endsWith(".json"));
23855
23953
  } catch {
23856
23954
  continue;
23857
23955
  }
23858
23956
  for (const chatFile of chatFiles) {
23859
23957
  let raw;
23860
23958
  try {
23861
- raw = import_fs45.default.readFileSync(import_path46.default.join(chatsDir, chatFile), "utf-8");
23959
+ raw = import_fs46.default.readFileSync(import_path47.default.join(chatsDir, chatFile), "utf-8");
23862
23960
  } catch {
23863
23961
  continue;
23864
23962
  }
@@ -23938,8 +24036,8 @@ function buildGeminiSessions(days, allAuditEntries) {
23938
24036
  return summaries;
23939
24037
  }
23940
24038
  function buildCodexSessions(days, allAuditEntries) {
23941
- const sessionsBase = import_path46.default.join(import_os40.default.homedir(), ".codex", "sessions");
23942
- if (!import_fs45.default.existsSync(sessionsBase)) return [];
24039
+ const sessionsBase = import_path47.default.join(import_os41.default.homedir(), ".codex", "sessions");
24040
+ if (!import_fs46.default.existsSync(sessionsBase)) return [];
23943
24041
  const cutoff = days !== null ? (() => {
23944
24042
  const d = /* @__PURE__ */ new Date();
23945
24043
  d.setDate(d.getDate() - days);
@@ -23948,29 +24046,29 @@ function buildCodexSessions(days, allAuditEntries) {
23948
24046
  })() : null;
23949
24047
  const jsonlFiles = [];
23950
24048
  try {
23951
- for (const year of import_fs45.default.readdirSync(sessionsBase)) {
23952
- const yearPath = import_path46.default.join(sessionsBase, year);
24049
+ for (const year of import_fs46.default.readdirSync(sessionsBase)) {
24050
+ const yearPath = import_path47.default.join(sessionsBase, year);
23953
24051
  try {
23954
- if (!import_fs45.default.statSync(yearPath).isDirectory()) continue;
24052
+ if (!import_fs46.default.statSync(yearPath).isDirectory()) continue;
23955
24053
  } catch {
23956
24054
  continue;
23957
24055
  }
23958
- for (const month of import_fs45.default.readdirSync(yearPath)) {
23959
- const monthPath = import_path46.default.join(yearPath, month);
24056
+ for (const month of import_fs46.default.readdirSync(yearPath)) {
24057
+ const monthPath = import_path47.default.join(yearPath, month);
23960
24058
  try {
23961
- if (!import_fs45.default.statSync(monthPath).isDirectory()) continue;
24059
+ if (!import_fs46.default.statSync(monthPath).isDirectory()) continue;
23962
24060
  } catch {
23963
24061
  continue;
23964
24062
  }
23965
- for (const day of import_fs45.default.readdirSync(monthPath)) {
23966
- const dayPath = import_path46.default.join(monthPath, day);
24063
+ for (const day of import_fs46.default.readdirSync(monthPath)) {
24064
+ const dayPath = import_path47.default.join(monthPath, day);
23967
24065
  try {
23968
- if (!import_fs45.default.statSync(dayPath).isDirectory()) continue;
24066
+ if (!import_fs46.default.statSync(dayPath).isDirectory()) continue;
23969
24067
  } catch {
23970
24068
  continue;
23971
24069
  }
23972
- for (const file of import_fs45.default.readdirSync(dayPath)) {
23973
- if (file.endsWith(".jsonl")) jsonlFiles.push(import_path46.default.join(dayPath, file));
24070
+ for (const file of import_fs46.default.readdirSync(dayPath)) {
24071
+ if (file.endsWith(".jsonl")) jsonlFiles.push(import_path47.default.join(dayPath, file));
23974
24072
  }
23975
24073
  }
23976
24074
  }
@@ -23982,7 +24080,7 @@ function buildCodexSessions(days, allAuditEntries) {
23982
24080
  for (const filePath of jsonlFiles) {
23983
24081
  let lines;
23984
24082
  try {
23985
- lines = import_fs45.default.readFileSync(filePath, "utf-8").split("\n");
24083
+ lines = import_fs46.default.readFileSync(filePath, "utf-8").split("\n");
23986
24084
  } catch {
23987
24085
  continue;
23988
24086
  }
@@ -24068,10 +24166,10 @@ function buildCodexSessions(days, allAuditEntries) {
24068
24166
  return summaries;
24069
24167
  }
24070
24168
  function buildSessions(days, historyPath) {
24071
- const hPath = historyPath ?? import_path46.default.join(import_os40.default.homedir(), ".claude", "history.jsonl");
24169
+ const hPath = historyPath ?? import_path47.default.join(import_os41.default.homedir(), ".claude", "history.jsonl");
24072
24170
  let historyRaw = "";
24073
24171
  try {
24074
- historyRaw = import_fs45.default.readFileSync(hPath, "utf-8");
24172
+ historyRaw = import_fs46.default.readFileSync(hPath, "utf-8");
24075
24173
  } catch {
24076
24174
  }
24077
24175
  const cutoff = days !== null ? (() => {
@@ -24095,7 +24193,7 @@ function buildSessions(days, historyPath) {
24095
24193
  const jsonlFile = sessionJsonlPath(entry.project, entry.sessionId);
24096
24194
  let sessionLines = [];
24097
24195
  try {
24098
- sessionLines = import_fs45.default.readFileSync(jsonlFile, "utf-8").split("\n");
24196
+ sessionLines = import_fs46.default.readFileSync(jsonlFile, "utf-8").split("\n");
24099
24197
  } catch {
24100
24198
  }
24101
24199
  const { toolCalls, costUSD, hasSnapshot, modifiedFiles } = parseSessionLines(sessionLines);
@@ -24395,12 +24493,12 @@ function registerSessionsCommand(program2) {
24395
24493
 
24396
24494
  // src/cli/commands/skill-pin.ts
24397
24495
  var import_chalk25 = __toESM(require("chalk"));
24398
- var import_fs46 = __toESM(require("fs"));
24399
- var import_os41 = __toESM(require("os"));
24400
- var import_path47 = __toESM(require("path"));
24496
+ var import_fs47 = __toESM(require("fs"));
24497
+ var import_os42 = __toESM(require("os"));
24498
+ var import_path48 = __toESM(require("path"));
24401
24499
  function wipeSkillSessions() {
24402
24500
  try {
24403
- import_fs46.default.rmSync(import_path47.default.join(import_os41.default.homedir(), ".node9", "skill-sessions"), {
24501
+ import_fs47.default.rmSync(import_path48.default.join(import_os42.default.homedir(), ".node9", "skill-sessions"), {
24404
24502
  recursive: true,
24405
24503
  force: true
24406
24504
  });
@@ -24482,15 +24580,15 @@ function registerSkillPinCommand(program2) {
24482
24580
  }
24483
24581
 
24484
24582
  // src/cli/commands/decisions.ts
24485
- var import_fs47 = __toESM(require("fs"));
24486
- var import_os42 = __toESM(require("os"));
24487
- var import_path48 = __toESM(require("path"));
24583
+ var import_fs48 = __toESM(require("fs"));
24584
+ var import_os43 = __toESM(require("os"));
24585
+ var import_path49 = __toESM(require("path"));
24488
24586
  var import_chalk26 = __toESM(require("chalk"));
24489
- var DECISIONS_FILE2 = import_path48.default.join(import_os42.default.homedir(), ".node9", "decisions.json");
24587
+ var DECISIONS_FILE2 = import_path49.default.join(import_os43.default.homedir(), ".node9", "decisions.json");
24490
24588
  function readDecisions() {
24491
24589
  try {
24492
- if (!import_fs47.default.existsSync(DECISIONS_FILE2)) return {};
24493
- const raw = import_fs47.default.readFileSync(DECISIONS_FILE2, "utf-8");
24590
+ if (!import_fs48.default.existsSync(DECISIONS_FILE2)) return {};
24591
+ const raw = import_fs48.default.readFileSync(DECISIONS_FILE2, "utf-8");
24494
24592
  const parsed = JSON.parse(raw);
24495
24593
  const out = {};
24496
24594
  for (const [k, v] of Object.entries(parsed)) {
@@ -24502,11 +24600,11 @@ function readDecisions() {
24502
24600
  }
24503
24601
  }
24504
24602
  function writeDecisions(d) {
24505
- const dir = import_path48.default.dirname(DECISIONS_FILE2);
24506
- if (!import_fs47.default.existsSync(dir)) import_fs47.default.mkdirSync(dir, { recursive: true });
24603
+ const dir = import_path49.default.dirname(DECISIONS_FILE2);
24604
+ if (!import_fs48.default.existsSync(dir)) import_fs48.default.mkdirSync(dir, { recursive: true });
24507
24605
  const tmp = `${DECISIONS_FILE2}.${process.pid}.tmp`;
24508
- import_fs47.default.writeFileSync(tmp, JSON.stringify(d, null, 2));
24509
- import_fs47.default.renameSync(tmp, DECISIONS_FILE2);
24606
+ import_fs48.default.writeFileSync(tmp, JSON.stringify(d, null, 2));
24607
+ import_fs48.default.renameSync(tmp, DECISIONS_FILE2);
24510
24608
  }
24511
24609
  function registerDecisionsCommand(program2) {
24512
24610
  const cmd = program2.command("decisions").description('Manage persistent "Always Allow" / "Always Deny" tool decisions');
@@ -24563,18 +24661,18 @@ Persistent decisions (${entries.length})
24563
24661
 
24564
24662
  // src/cli/commands/dlp.ts
24565
24663
  var import_chalk27 = __toESM(require("chalk"));
24566
- var import_fs48 = __toESM(require("fs"));
24567
- var import_path49 = __toESM(require("path"));
24568
- var import_os43 = __toESM(require("os"));
24569
- var AUDIT_LOG = import_path49.default.join(import_os43.default.homedir(), ".node9", "audit.log");
24570
- var RESOLVED_FILE = import_path49.default.join(import_os43.default.homedir(), ".node9", "dlp-resolved.json");
24664
+ var import_fs49 = __toESM(require("fs"));
24665
+ var import_path50 = __toESM(require("path"));
24666
+ var import_os44 = __toESM(require("os"));
24667
+ var AUDIT_LOG = import_path50.default.join(import_os44.default.homedir(), ".node9", "audit.log");
24668
+ var RESOLVED_FILE = import_path50.default.join(import_os44.default.homedir(), ".node9", "dlp-resolved.json");
24571
24669
  var ANSI_RE = /\x1b(?:\[[0-9;?]*[a-zA-Z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[@-_])/g;
24572
24670
  function stripAnsi(s) {
24573
24671
  return s.replace(ANSI_RE, "");
24574
24672
  }
24575
24673
  function loadResolved() {
24576
24674
  try {
24577
- const raw = JSON.parse(import_fs48.default.readFileSync(RESOLVED_FILE, "utf-8"));
24675
+ const raw = JSON.parse(import_fs49.default.readFileSync(RESOLVED_FILE, "utf-8"));
24578
24676
  return new Set(raw);
24579
24677
  } catch {
24580
24678
  return /* @__PURE__ */ new Set();
@@ -24582,13 +24680,13 @@ function loadResolved() {
24582
24680
  }
24583
24681
  function saveResolved(resolved) {
24584
24682
  try {
24585
- import_fs48.default.writeFileSync(RESOLVED_FILE, JSON.stringify([...resolved], null, 2), { mode: 384 });
24683
+ import_fs49.default.writeFileSync(RESOLVED_FILE, JSON.stringify([...resolved], null, 2), { mode: 384 });
24586
24684
  } catch {
24587
24685
  }
24588
24686
  }
24589
24687
  function loadDlpFindings() {
24590
- if (!import_fs48.default.existsSync(AUDIT_LOG)) return [];
24591
- return import_fs48.default.readFileSync(AUDIT_LOG, "utf-8").split("\n").flatMap((line) => {
24688
+ if (!import_fs49.default.existsSync(AUDIT_LOG)) return [];
24689
+ return import_fs49.default.readFileSync(AUDIT_LOG, "utf-8").split("\n").flatMap((line) => {
24592
24690
  if (!line.trim()) return [];
24593
24691
  try {
24594
24692
  const e = JSON.parse(line);
@@ -24686,15 +24784,15 @@ function registerDlpCommand(program2) {
24686
24784
 
24687
24785
  // src/cli/commands/mask.ts
24688
24786
  var import_chalk28 = __toESM(require("chalk"));
24689
- var import_fs49 = __toESM(require("fs"));
24690
- var import_path50 = __toESM(require("path"));
24691
- var import_os44 = __toESM(require("os"));
24787
+ var import_fs50 = __toESM(require("fs"));
24788
+ var import_path51 = __toESM(require("path"));
24789
+ var import_os45 = __toESM(require("os"));
24692
24790
  init_dlp();
24693
24791
  function findJsonlFiles(dir) {
24694
24792
  const results = [];
24695
- if (!import_fs49.default.existsSync(dir)) return results;
24696
- for (const entry of import_fs49.default.readdirSync(dir, { withFileTypes: true })) {
24697
- const full = import_path50.default.join(dir, entry.name);
24793
+ if (!import_fs50.default.existsSync(dir)) return results;
24794
+ for (const entry of import_fs50.default.readdirSync(dir, { withFileTypes: true })) {
24795
+ const full = import_path51.default.join(dir, entry.name);
24698
24796
  if (entry.isDirectory()) results.push(...findJsonlFiles(full));
24699
24797
  else if (entry.isFile() && entry.name.endsWith(".jsonl")) results.push(full);
24700
24798
  }
@@ -24737,7 +24835,7 @@ function redactJson(obj) {
24737
24835
  function processFile(filePath, dryRun) {
24738
24836
  let raw;
24739
24837
  try {
24740
- raw = import_fs49.default.readFileSync(filePath, "utf-8");
24838
+ raw = import_fs50.default.readFileSync(filePath, "utf-8");
24741
24839
  } catch {
24742
24840
  return { redactedLines: 0, patterns: [] };
24743
24841
  }
@@ -24769,14 +24867,14 @@ function processFile(filePath, dryRun) {
24769
24867
  }
24770
24868
  }
24771
24869
  if (!dryRun && redactedLines > 0) {
24772
- import_fs49.default.writeFileSync(filePath, newLines.join("\n"), "utf-8");
24870
+ import_fs50.default.writeFileSync(filePath, newLines.join("\n"), "utf-8");
24773
24871
  }
24774
24872
  return { redactedLines, patterns };
24775
24873
  }
24776
24874
  function processJsonFile(filePath, dryRun) {
24777
24875
  let raw;
24778
24876
  try {
24779
- raw = import_fs49.default.readFileSync(filePath, "utf-8");
24877
+ raw = import_fs50.default.readFileSync(filePath, "utf-8");
24780
24878
  } catch {
24781
24879
  return { redactedLines: 0, patterns: [] };
24782
24880
  }
@@ -24789,15 +24887,15 @@ function processJsonFile(filePath, dryRun) {
24789
24887
  const { value, modified, found } = redactJson(parsed);
24790
24888
  if (!modified) return { redactedLines: 0, patterns: [] };
24791
24889
  if (!dryRun) {
24792
- import_fs49.default.writeFileSync(filePath, JSON.stringify(value, null, 2), "utf-8");
24890
+ import_fs50.default.writeFileSync(filePath, JSON.stringify(value, null, 2), "utf-8");
24793
24891
  }
24794
24892
  return { redactedLines: 1, patterns: found };
24795
24893
  }
24796
24894
  function findJsonFiles(dir) {
24797
24895
  const results = [];
24798
- if (!import_fs49.default.existsSync(dir)) return results;
24799
- for (const entry of import_fs49.default.readdirSync(dir, { withFileTypes: true })) {
24800
- const full = import_path50.default.join(dir, entry.name);
24896
+ if (!import_fs50.default.existsSync(dir)) return results;
24897
+ for (const entry of import_fs50.default.readdirSync(dir, { withFileTypes: true })) {
24898
+ const full = import_path51.default.join(dir, entry.name);
24801
24899
  if (entry.isDirectory()) results.push(...findJsonFiles(full));
24802
24900
  else if (entry.isFile() && entry.name.endsWith(".json")) results.push(full);
24803
24901
  }
@@ -24806,9 +24904,9 @@ function findJsonFiles(dir) {
24806
24904
  function registerMaskCommand(program2) {
24807
24905
  program2.command("mask").description("Redact plaintext secrets from local AI session history files").option("--dry-run", "show what would be redacted without making changes").option("--all", "scan all history (default: last 30 days)").action(async (options) => {
24808
24906
  const dryRun = !!options.dryRun;
24809
- const home = import_os44.default.homedir();
24810
- const claudeDir = import_path50.default.join(home, ".claude", "projects");
24811
- const geminiDir = import_path50.default.join(home, ".gemini", "tmp");
24907
+ const home = import_os45.default.homedir();
24908
+ const claudeDir = import_path51.default.join(home, ".claude", "projects");
24909
+ const geminiDir = import_path51.default.join(home, ".gemini", "tmp");
24812
24910
  const allFiles = [
24813
24911
  ...findJsonlFiles(claudeDir).map((p) => ({ path: p, type: "jsonl" })),
24814
24912
  ...findJsonFiles(geminiDir).map((p) => ({ path: p, type: "json" }))
@@ -24816,7 +24914,7 @@ function registerMaskCommand(program2) {
24816
24914
  const cutoff = options.all ? null : new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3);
24817
24915
  const filtered = cutoff ? allFiles.filter((f) => {
24818
24916
  try {
24819
- return import_fs49.default.statSync(f.path).mtime >= cutoff;
24917
+ return import_fs50.default.statSync(f.path).mtime >= cutoff;
24820
24918
  } catch {
24821
24919
  return false;
24822
24920
  }
@@ -24872,20 +24970,20 @@ function registerMaskCommand(program2) {
24872
24970
  // src/cli.ts
24873
24971
  init_blast();
24874
24972
  var { version } = JSON.parse(
24875
- import_fs52.default.readFileSync(import_path53.default.join(__dirname, "../package.json"), "utf-8")
24973
+ import_fs53.default.readFileSync(import_path54.default.join(__dirname, "../package.json"), "utf-8")
24876
24974
  );
24877
24975
  var program = new import_commander.Command();
24878
24976
  program.name("node9").description("The Sudo Command for AI Agents").version(version);
24879
24977
  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) => {
24880
24978
  const DEFAULT_API_URL2 = "https://api.node9.ai/api/v1/intercept";
24881
- const credPath = import_path53.default.join(import_os47.default.homedir(), ".node9", "credentials.json");
24882
- if (!import_fs52.default.existsSync(import_path53.default.dirname(credPath)))
24883
- import_fs52.default.mkdirSync(import_path53.default.dirname(credPath), { recursive: true });
24979
+ const credPath = import_path54.default.join(import_os48.default.homedir(), ".node9", "credentials.json");
24980
+ if (!import_fs53.default.existsSync(import_path54.default.dirname(credPath)))
24981
+ import_fs53.default.mkdirSync(import_path54.default.dirname(credPath), { recursive: true });
24884
24982
  const profileName = options.profile || "default";
24885
24983
  let existingCreds = {};
24886
24984
  try {
24887
- if (import_fs52.default.existsSync(credPath)) {
24888
- const raw = JSON.parse(import_fs52.default.readFileSync(credPath, "utf-8"));
24985
+ if (import_fs53.default.existsSync(credPath)) {
24986
+ const raw = JSON.parse(import_fs53.default.readFileSync(credPath, "utf-8"));
24889
24987
  if (raw.apiKey) {
24890
24988
  existingCreds = {
24891
24989
  default: { apiKey: raw.apiKey, apiUrl: raw.apiUrl || DEFAULT_API_URL2 }
@@ -24897,14 +24995,14 @@ program.command("login").argument("<apiKey>").option("--local", "Save key for au
24897
24995
  } catch {
24898
24996
  }
24899
24997
  existingCreds[profileName] = { apiKey, apiUrl: DEFAULT_API_URL2 };
24900
- import_fs52.default.writeFileSync(credPath, JSON.stringify(existingCreds, null, 2), { mode: 384 });
24998
+ import_fs53.default.writeFileSync(credPath, JSON.stringify(existingCreds, null, 2), { mode: 384 });
24901
24999
  let effectiveCloud = null;
24902
25000
  if (profileName === "default") {
24903
- const configPath = import_path53.default.join(import_os47.default.homedir(), ".node9", "config.json");
25001
+ const configPath = import_path54.default.join(import_os48.default.homedir(), ".node9", "config.json");
24904
25002
  let config = {};
24905
25003
  try {
24906
- if (import_fs52.default.existsSync(configPath))
24907
- config = JSON.parse(import_fs52.default.readFileSync(configPath, "utf-8"));
25004
+ if (import_fs53.default.existsSync(configPath))
25005
+ config = JSON.parse(import_fs53.default.readFileSync(configPath, "utf-8"));
24908
25006
  } catch {
24909
25007
  }
24910
25008
  if (!config.settings || typeof config.settings !== "object") config.settings = {};
@@ -24919,9 +25017,9 @@ program.command("login").argument("<apiKey>").option("--local", "Save key for au
24919
25017
  approvers.cloud = false;
24920
25018
  }
24921
25019
  s.approvers = approvers;
24922
- if (!import_fs52.default.existsSync(import_path53.default.dirname(configPath)))
24923
- import_fs52.default.mkdirSync(import_path53.default.dirname(configPath), { recursive: true });
24924
- import_fs52.default.writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 384 });
25020
+ if (!import_fs53.default.existsSync(import_path54.default.dirname(configPath)))
25021
+ import_fs53.default.mkdirSync(import_path54.default.dirname(configPath), { recursive: true });
25022
+ import_fs53.default.writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 384 });
24925
25023
  effectiveCloud = approvers.cloud === true;
24926
25024
  }
24927
25025
  if (options.profile && profileName !== "default") {
@@ -25080,15 +25178,15 @@ program.command("uninstall").description("Remove all Node9 hooks and optionally
25080
25178
  }
25081
25179
  }
25082
25180
  if (options.purge) {
25083
- const node9Dir = import_path53.default.join(import_os47.default.homedir(), ".node9");
25084
- if (import_fs52.default.existsSync(node9Dir)) {
25181
+ const node9Dir = import_path54.default.join(import_os48.default.homedir(), ".node9");
25182
+ if (import_fs53.default.existsSync(node9Dir)) {
25085
25183
  const confirmed = await (0, import_prompts2.confirm)({
25086
25184
  message: `Permanently delete ${node9Dir} (config, audit log, credentials)?`,
25087
25185
  default: false
25088
25186
  });
25089
25187
  if (confirmed) {
25090
- import_fs52.default.rmSync(node9Dir, { recursive: true });
25091
- if (import_fs52.default.existsSync(node9Dir)) {
25188
+ import_fs53.default.rmSync(node9Dir, { recursive: true });
25189
+ if (import_fs53.default.existsSync(node9Dir)) {
25092
25190
  console.error(
25093
25191
  import_chalk30.default.red("\n \u26A0\uFE0F ~/.node9/ could not be fully deleted \u2014 remove it manually.")
25094
25192
  );
@@ -25203,7 +25301,7 @@ program.command("tail").description("Stream live agent activity to the terminal"
25203
25301
  });
25204
25302
  program.command("monitor").description("Live interactive dashboard \u2014 activity feed, approvals, security signals").action(async () => {
25205
25303
  try {
25206
- const dashboardPath = import_path53.default.join(__dirname, "dashboard.mjs");
25304
+ const dashboardPath = import_path54.default.join(__dirname, "dashboard.mjs");
25207
25305
  const dynamicImport = new Function("id", "return import(id)");
25208
25306
  const mod = await dynamicImport(`file://${dashboardPath}`);
25209
25307
  await mod.startMonitor();
@@ -25241,14 +25339,14 @@ Claude Code spawns this command every ~300ms and writes a JSON payload to stdin.
25241
25339
  Run "node9 addto claude" to register it as the statusLine.`
25242
25340
  ).argument("[subcommand]", 'Optional: "debug on" / "debug off" to toggle stdin logging').argument("[state]", 'on|off \u2014 used with "debug" subcommand').action(async (subcommand, state) => {
25243
25341
  if (subcommand === "debug") {
25244
- const flagFile = import_path53.default.join(import_os47.default.homedir(), ".node9", "hud-debug");
25342
+ const flagFile = import_path54.default.join(import_os48.default.homedir(), ".node9", "hud-debug");
25245
25343
  if (state === "on") {
25246
- import_fs52.default.mkdirSync(import_path53.default.dirname(flagFile), { recursive: true });
25247
- import_fs52.default.writeFileSync(flagFile, "");
25344
+ import_fs53.default.mkdirSync(import_path54.default.dirname(flagFile), { recursive: true });
25345
+ import_fs53.default.writeFileSync(flagFile, "");
25248
25346
  console.log("HUD debug logging enabled \u2192 ~/.node9/hud-debug.log");
25249
25347
  console.log("Tail it with: tail -f ~/.node9/hud-debug.log");
25250
25348
  } else if (state === "off") {
25251
- if (import_fs52.default.existsSync(flagFile)) import_fs52.default.unlinkSync(flagFile);
25349
+ if (import_fs53.default.existsSync(flagFile)) import_fs53.default.unlinkSync(flagFile);
25252
25350
  console.log("HUD debug logging disabled.");
25253
25351
  } else {
25254
25352
  console.error("Usage: node9 hud debug on|off");
@@ -25365,9 +25463,9 @@ if (process.argv[2] !== "daemon") {
25365
25463
  const isCheckHook = process.argv[2] === "check";
25366
25464
  if (isCheckHook) {
25367
25465
  if (process.env.NODE9_DEBUG === "1" || getConfig().settings.enableHookLogDebug) {
25368
- const logPath = import_path53.default.join(import_os47.default.homedir(), ".node9", "hook-debug.log");
25466
+ const logPath = import_path54.default.join(import_os48.default.homedir(), ".node9", "hook-debug.log");
25369
25467
  const msg = reason instanceof Error ? reason.message : String(reason);
25370
- import_fs52.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] UNHANDLED: ${msg}
25468
+ import_fs53.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] UNHANDLED: ${msg}
25371
25469
  `);
25372
25470
  }
25373
25471
  process.exit(0);