@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.
- package/dist/cli.js +452 -354
- package/dist/cli.mjs +448 -350
- 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
|
|
210
|
-
return ` \u2022 ${
|
|
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,
|
|
1259
|
+
function getNestedValue(obj, path55) {
|
|
1260
1260
|
if (!obj || typeof obj !== "object") return null;
|
|
1261
|
-
const segments =
|
|
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 =
|
|
16955
|
-
if (!
|
|
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
|
|
16960
|
-
const dirPath =
|
|
16959
|
+
for (const dir of import_fs51.default.readdirSync(projectsDir)) {
|
|
16960
|
+
const dirPath = import_path52.default.join(projectsDir, dir);
|
|
16961
16961
|
try {
|
|
16962
|
-
if (!
|
|
16963
|
-
for (const file of
|
|
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 =
|
|
16965
|
+
const filePath = import_path52.default.join(dirPath, file);
|
|
16966
16966
|
try {
|
|
16967
|
-
const mtime =
|
|
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 =
|
|
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(
|
|
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 (
|
|
17082
|
+
if (import_fs51.default.existsSync(PID_FILE)) {
|
|
17083
17083
|
try {
|
|
17084
|
-
const { port } = JSON.parse(
|
|
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 =
|
|
17240
|
+
const configPath = import_path52.default.join(import_os46.default.homedir(), ".node9", "config.json");
|
|
17241
17241
|
try {
|
|
17242
|
-
const raw = JSON.parse(
|
|
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 =
|
|
17258
|
+
const configPath = import_path52.default.join(import_os46.default.homedir(), ".node9", "config.json");
|
|
17259
17259
|
try {
|
|
17260
|
-
const raw = JSON.parse(
|
|
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
|
-
|
|
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
|
-
|
|
17439
|
-
|
|
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 =
|
|
17503
|
+
const auditLog = import_path52.default.join(import_os46.default.homedir(), ".node9", "audit.log");
|
|
17504
17504
|
try {
|
|
17505
|
-
const unackedDlp =
|
|
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 =
|
|
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,
|
|
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
|
-
|
|
17737
|
-
|
|
17738
|
-
|
|
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 =
|
|
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 (!
|
|
17865
|
+
if (!import_fs52.default.existsSync(filePath)) return null;
|
|
17866
17866
|
try {
|
|
17867
|
-
return JSON.parse(
|
|
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 (!
|
|
17888
|
+
if (!import_fs52.default.existsSync(rulesDir)) return 0;
|
|
17889
17889
|
let count = 0;
|
|
17890
17890
|
try {
|
|
17891
|
-
for (const entry of
|
|
17891
|
+
for (const entry of import_fs52.default.readdirSync(rulesDir, { withFileTypes: true })) {
|
|
17892
17892
|
if (entry.isDirectory()) {
|
|
17893
|
-
count += countRulesInDir(
|
|
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
|
|
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 =
|
|
17911
|
-
const claudeDir =
|
|
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 (
|
|
17918
|
-
rulesCount += countRulesInDir(
|
|
17919
|
-
const userSettings =
|
|
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 =
|
|
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 (
|
|
17929
|
-
if (
|
|
17930
|
-
const projectClaudeDir =
|
|
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 (
|
|
17934
|
-
rulesCount += countRulesInDir(
|
|
17935
|
-
const projSettings =
|
|
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 (
|
|
17940
|
-
const localSettings =
|
|
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(
|
|
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 =
|
|
17977
|
-
if (!
|
|
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(
|
|
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 (
|
|
18083
|
+
if (import_fs52.default.existsSync(import_path53.default.join(import_os47.default.homedir(), ".node9", "hud-debug"))) {
|
|
18084
18084
|
try {
|
|
18085
|
-
const logPath =
|
|
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 =
|
|
18089
|
+
size = import_fs52.default.statSync(logPath).size;
|
|
18090
18090
|
} catch {
|
|
18091
18091
|
}
|
|
18092
18092
|
if (size < MAX_LOG_SIZE) {
|
|
18093
|
-
|
|
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
|
-
|
|
18115
|
-
|
|
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 (!
|
|
18118
|
-
const cfg = JSON.parse(
|
|
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
|
|
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
|
-
|
|
18141
|
-
|
|
18142
|
-
|
|
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
|
|
18170
|
-
var
|
|
18171
|
-
var
|
|
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
|
|
19960
|
-
var
|
|
19961
|
-
var
|
|
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 =
|
|
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 =
|
|
20017
|
-
if (
|
|
20152
|
+
const globalConfigPath = import_path40.default.join(homeDir2, ".node9", "config.json");
|
|
20153
|
+
if (import_fs39.default.existsSync(globalConfigPath)) {
|
|
20018
20154
|
try {
|
|
20019
|
-
JSON.parse(
|
|
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 =
|
|
20028
|
-
if (
|
|
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(
|
|
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 =
|
|
20040
|
-
if (
|
|
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
|
|
20050
|
-
|
|
20051
|
-
|
|
20052
|
-
|
|
20053
|
-
|
|
20054
|
-
|
|
20055
|
-
|
|
20056
|
-
|
|
20057
|
-
|
|
20058
|
-
|
|
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
|
-
|
|
20088
|
-
|
|
20089
|
-
|
|
20090
|
-
|
|
20091
|
-
|
|
20092
|
-
|
|
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 =
|
|
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
|
|
20172
|
-
var
|
|
20173
|
-
var
|
|
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 =
|
|
20187
|
-
if (!
|
|
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 =
|
|
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
|
|
20250
|
-
var
|
|
20251
|
-
var
|
|
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 (!
|
|
20335
|
-
const raw =
|
|
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 =
|
|
20480
|
+
const projPath = import_path42.default.join(projectsDir, proj);
|
|
20383
20481
|
let files;
|
|
20384
20482
|
try {
|
|
20385
|
-
const stat =
|
|
20483
|
+
const stat = import_fs41.default.statSync(projPath);
|
|
20386
20484
|
if (!stat.isDirectory()) return;
|
|
20387
|
-
files =
|
|
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 =
|
|
20491
|
+
const filePath = import_path42.default.join(projPath, file);
|
|
20394
20492
|
try {
|
|
20395
|
-
if (
|
|
20493
|
+
if (import_fs41.default.statSync(filePath).mtimeMs < startMs) continue;
|
|
20396
20494
|
} catch {
|
|
20397
20495
|
continue;
|
|
20398
20496
|
}
|
|
20399
20497
|
try {
|
|
20400
|
-
const raw =
|
|
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 (!
|
|
20548
|
+
if (!import_fs41.default.existsSync(projectsDir)) return freezeClaudeCost(acc);
|
|
20451
20549
|
let dirs;
|
|
20452
20550
|
try {
|
|
20453
|
-
dirs =
|
|
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 =
|
|
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 (!
|
|
20618
|
+
if (!import_fs41.default.existsSync(sessionsBase)) return jsonlFiles;
|
|
20521
20619
|
try {
|
|
20522
|
-
for (const year of
|
|
20523
|
-
const yearPath =
|
|
20620
|
+
for (const year of import_fs41.default.readdirSync(sessionsBase)) {
|
|
20621
|
+
const yearPath = import_path42.default.join(sessionsBase, year);
|
|
20524
20622
|
try {
|
|
20525
|
-
if (!
|
|
20623
|
+
if (!import_fs41.default.statSync(yearPath).isDirectory()) continue;
|
|
20526
20624
|
} catch {
|
|
20527
20625
|
continue;
|
|
20528
20626
|
}
|
|
20529
|
-
for (const month of
|
|
20530
|
-
const monthPath =
|
|
20627
|
+
for (const month of import_fs41.default.readdirSync(yearPath)) {
|
|
20628
|
+
const monthPath = import_path42.default.join(yearPath, month);
|
|
20531
20629
|
try {
|
|
20532
|
-
if (!
|
|
20630
|
+
if (!import_fs41.default.statSync(monthPath).isDirectory()) continue;
|
|
20533
20631
|
} catch {
|
|
20534
20632
|
continue;
|
|
20535
20633
|
}
|
|
20536
|
-
for (const day of
|
|
20537
|
-
const dayPath =
|
|
20634
|
+
for (const day of import_fs41.default.readdirSync(monthPath)) {
|
|
20635
|
+
const dayPath = import_path42.default.join(monthPath, day);
|
|
20538
20636
|
try {
|
|
20539
|
-
if (!
|
|
20637
|
+
if (!import_fs41.default.statSync(dayPath).isDirectory()) continue;
|
|
20540
20638
|
} catch {
|
|
20541
20639
|
continue;
|
|
20542
20640
|
}
|
|
20543
|
-
for (const file of
|
|
20544
|
-
if (file.endsWith(".jsonl")) jsonlFiles.push(
|
|
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 (
|
|
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 =
|
|
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 (!
|
|
20665
|
-
dirs =
|
|
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 =
|
|
20768
|
+
const chatsDir = import_path42.default.join(geminiTmpDir2, proj, "chats");
|
|
20671
20769
|
let files;
|
|
20672
20770
|
try {
|
|
20673
|
-
if (!
|
|
20674
|
-
files =
|
|
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:
|
|
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 (!
|
|
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 ??
|
|
20696
|
-
const claudeProjectsDir = opts.claudeProjectsDir ??
|
|
20697
|
-
const codexSessionsDir2 = opts.codexSessionsDir ??
|
|
20698
|
-
const geminiTmpDir2 = opts.geminiTmpDir ??
|
|
20699
|
-
const hasAuditFile =
|
|
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
|
|
21396
|
-
var
|
|
21397
|
-
var
|
|
21398
|
-
var
|
|
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 (!
|
|
21501
|
+
if (!import_fs42.default.existsSync(configPath)) return null;
|
|
21404
21502
|
let raw;
|
|
21405
21503
|
try {
|
|
21406
|
-
raw =
|
|
21504
|
+
raw = import_fs42.default.readFileSync(configPath, "utf-8");
|
|
21407
21505
|
} catch {
|
|
21408
21506
|
return null;
|
|
21409
21507
|
}
|
|
21410
21508
|
try {
|
|
21411
|
-
const cfg =
|
|
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
|
|
21523
|
+
function readJson3(filePath) {
|
|
21426
21524
|
try {
|
|
21427
|
-
if (
|
|
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
|
|
21530
|
+
function matchersHaveNode9Hook2(matchers) {
|
|
21433
21531
|
return (matchers ?? []).some((m) => (m.hooks ?? []).some((h) => isNode9Hook(h.command)));
|
|
21434
21532
|
}
|
|
21435
|
-
function
|
|
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 =
|
|
21496
|
-
const globalConfig =
|
|
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: ${
|
|
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: ${
|
|
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 =
|
|
21509
|
-
const claudeSettings =
|
|
21510
|
-
|
|
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 =
|
|
21513
|
-
const geminiSettings =
|
|
21514
|
-
|
|
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 =
|
|
21517
|
-
const antigravityHooks =
|
|
21518
|
-
|
|
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 =
|
|
21521
|
-
|
|
21618
|
+
const antigravityMcp = readJson3(
|
|
21619
|
+
import_path43.default.join(homeDir2, ".gemini", "config", "mcp_config.json")
|
|
21522
21620
|
);
|
|
21523
|
-
const antigravityPresent = antigravityHooks !== null ||
|
|
21524
|
-
const copilotHooks =
|
|
21525
|
-
|
|
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 =
|
|
21528
|
-
|
|
21625
|
+
const copilotMcp = readJson3(
|
|
21626
|
+
import_path43.default.join(homeDir2, ".copilot", "mcp-config.json")
|
|
21529
21627
|
);
|
|
21530
|
-
const copilotPresent =
|
|
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 =
|
|
21539
|
-
const postHook =
|
|
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 =
|
|
21552
|
-
const afterHook =
|
|
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 =
|
|
21565
|
-
const postHook =
|
|
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 =
|
|
21578
|
-
const postHook =
|
|
21579
|
-
const promptHook =
|
|
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
|
|
21623
|
-
var
|
|
21624
|
-
var
|
|
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 =
|
|
21715
|
-
const isFirstInstall = !
|
|
21716
|
-
if (
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
21737
|
-
if (!
|
|
21738
|
-
|
|
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
|
|
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 =
|
|
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
|
|
22638
|
-
var
|
|
22639
|
-
var
|
|
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 =
|
|
22891
|
-
const globalConfig =
|
|
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): ${
|
|
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): ${
|
|
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 =
|
|
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 (
|
|
22975
|
-
return JSON.parse(
|
|
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 =
|
|
22983
|
-
if (!
|
|
22984
|
-
|
|
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 =
|
|
23029
|
-
if (!
|
|
23030
|
-
const rawLines =
|
|
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
|
|
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 =
|
|
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
|
|
23690
|
-
var
|
|
23691
|
-
var
|
|
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
|
|
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(
|
|
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 ??
|
|
23882
|
+
const aPath = auditPath ?? import_path47.default.join(import_os41.default.homedir(), ".node9", "audit.log");
|
|
23785
23883
|
let raw;
|
|
23786
23884
|
try {
|
|
23787
|
-
raw =
|
|
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 =
|
|
23824
|
-
if (!
|
|
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 =
|
|
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 =
|
|
23937
|
+
const slugPath = import_path47.default.join(tmpDir, slug);
|
|
23840
23938
|
try {
|
|
23841
|
-
if (!
|
|
23939
|
+
if (!import_fs46.default.statSync(slugPath).isDirectory()) continue;
|
|
23842
23940
|
} catch {
|
|
23843
23941
|
continue;
|
|
23844
23942
|
}
|
|
23845
|
-
let projectRoot =
|
|
23943
|
+
let projectRoot = import_path47.default.join(import_os41.default.homedir(), slug);
|
|
23846
23944
|
try {
|
|
23847
|
-
projectRoot =
|
|
23945
|
+
projectRoot = import_fs46.default.readFileSync(import_path47.default.join(slugPath, ".project_root"), "utf-8").trim();
|
|
23848
23946
|
} catch {
|
|
23849
23947
|
}
|
|
23850
|
-
const chatsDir =
|
|
23851
|
-
if (!
|
|
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 =
|
|
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 =
|
|
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 =
|
|
23942
|
-
if (!
|
|
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
|
|
23952
|
-
const yearPath =
|
|
24049
|
+
for (const year of import_fs46.default.readdirSync(sessionsBase)) {
|
|
24050
|
+
const yearPath = import_path47.default.join(sessionsBase, year);
|
|
23953
24051
|
try {
|
|
23954
|
-
if (!
|
|
24052
|
+
if (!import_fs46.default.statSync(yearPath).isDirectory()) continue;
|
|
23955
24053
|
} catch {
|
|
23956
24054
|
continue;
|
|
23957
24055
|
}
|
|
23958
|
-
for (const month of
|
|
23959
|
-
const monthPath =
|
|
24056
|
+
for (const month of import_fs46.default.readdirSync(yearPath)) {
|
|
24057
|
+
const monthPath = import_path47.default.join(yearPath, month);
|
|
23960
24058
|
try {
|
|
23961
|
-
if (!
|
|
24059
|
+
if (!import_fs46.default.statSync(monthPath).isDirectory()) continue;
|
|
23962
24060
|
} catch {
|
|
23963
24061
|
continue;
|
|
23964
24062
|
}
|
|
23965
|
-
for (const day of
|
|
23966
|
-
const dayPath =
|
|
24063
|
+
for (const day of import_fs46.default.readdirSync(monthPath)) {
|
|
24064
|
+
const dayPath = import_path47.default.join(monthPath, day);
|
|
23967
24065
|
try {
|
|
23968
|
-
if (!
|
|
24066
|
+
if (!import_fs46.default.statSync(dayPath).isDirectory()) continue;
|
|
23969
24067
|
} catch {
|
|
23970
24068
|
continue;
|
|
23971
24069
|
}
|
|
23972
|
-
for (const file of
|
|
23973
|
-
if (file.endsWith(".jsonl")) jsonlFiles.push(
|
|
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 =
|
|
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 ??
|
|
24169
|
+
const hPath = historyPath ?? import_path47.default.join(import_os41.default.homedir(), ".claude", "history.jsonl");
|
|
24072
24170
|
let historyRaw = "";
|
|
24073
24171
|
try {
|
|
24074
|
-
historyRaw =
|
|
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 =
|
|
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
|
|
24399
|
-
var
|
|
24400
|
-
var
|
|
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
|
-
|
|
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
|
|
24486
|
-
var
|
|
24487
|
-
var
|
|
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 =
|
|
24587
|
+
var DECISIONS_FILE2 = import_path49.default.join(import_os43.default.homedir(), ".node9", "decisions.json");
|
|
24490
24588
|
function readDecisions() {
|
|
24491
24589
|
try {
|
|
24492
|
-
if (!
|
|
24493
|
-
const raw =
|
|
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 =
|
|
24506
|
-
if (!
|
|
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
|
-
|
|
24509
|
-
|
|
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
|
|
24567
|
-
var
|
|
24568
|
-
var
|
|
24569
|
-
var AUDIT_LOG =
|
|
24570
|
-
var RESOLVED_FILE =
|
|
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(
|
|
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
|
-
|
|
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 (!
|
|
24591
|
-
return
|
|
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
|
|
24690
|
-
var
|
|
24691
|
-
var
|
|
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 (!
|
|
24696
|
-
for (const entry of
|
|
24697
|
-
const full =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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 (!
|
|
24799
|
-
for (const entry of
|
|
24800
|
-
const full =
|
|
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 =
|
|
24810
|
-
const claudeDir =
|
|
24811
|
-
const geminiDir =
|
|
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
|
|
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
|
-
|
|
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 =
|
|
24882
|
-
if (!
|
|
24883
|
-
|
|
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 (
|
|
24888
|
-
const raw = JSON.parse(
|
|
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
|
-
|
|
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 =
|
|
25001
|
+
const configPath = import_path54.default.join(import_os48.default.homedir(), ".node9", "config.json");
|
|
24904
25002
|
let config = {};
|
|
24905
25003
|
try {
|
|
24906
|
-
if (
|
|
24907
|
-
config = JSON.parse(
|
|
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 (!
|
|
24923
|
-
|
|
24924
|
-
|
|
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 =
|
|
25084
|
-
if (
|
|
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
|
-
|
|
25091
|
-
if (
|
|
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 =
|
|
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 =
|
|
25342
|
+
const flagFile = import_path54.default.join(import_os48.default.homedir(), ".node9", "hud-debug");
|
|
25245
25343
|
if (state === "on") {
|
|
25246
|
-
|
|
25247
|
-
|
|
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 (
|
|
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 =
|
|
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
|
-
|
|
25468
|
+
import_fs53.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] UNHANDLED: ${msg}
|
|
25371
25469
|
`);
|
|
25372
25470
|
}
|
|
25373
25471
|
process.exit(0);
|