@node9/proxy 1.8.2 → 1.8.3
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/README.md +50 -718
- package/dist/cli.js +193 -68
- package/dist/cli.mjs +185 -60
- package/dist/index.js +1 -3
- package/dist/index.mjs +1 -3
- package/dist/shields/builtin/docker.json +120 -0
- package/dist/shields/builtin/k8s.json +92 -0
- package/dist/shields/builtin/mongodb.json +78 -0
- package/dist/shields/builtin/redis.json +78 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2872,9 +2872,7 @@ end run`;
|
|
|
2872
2872
|
"--text",
|
|
2873
2873
|
pangoMessage,
|
|
2874
2874
|
"--ok-label",
|
|
2875
|
-
locked ? "Waiting..." : "Allow \u21B5"
|
|
2876
|
-
"--timeout",
|
|
2877
|
-
"300"
|
|
2875
|
+
locked ? "Waiting..." : "Allow \u21B5"
|
|
2878
2876
|
];
|
|
2879
2877
|
if (!locked) {
|
|
2880
2878
|
argsList.push("--cancel-label", "Block \u238B");
|
|
@@ -5691,6 +5689,12 @@ function estimateToolCost(tool, args) {
|
|
|
5691
5689
|
const newStr = a.new_string ?? "";
|
|
5692
5690
|
return String(newStr).length / BYTES_PER_TOKEN / 1e6 * OUTPUT_PRICE_PER_1M;
|
|
5693
5691
|
}
|
|
5692
|
+
if (t === "bash" || t === "shell" || t === "run_shell_command" || t === "terminal_execute") {
|
|
5693
|
+
const command = String(a.command ?? a.cmd ?? a.input ?? "");
|
|
5694
|
+
if (command.length > 0) {
|
|
5695
|
+
return command.length / BYTES_PER_TOKEN / 1e6 * OUTPUT_PRICE_PER_1M;
|
|
5696
|
+
}
|
|
5697
|
+
}
|
|
5694
5698
|
return void 0;
|
|
5695
5699
|
}
|
|
5696
5700
|
function broadcast(event, data) {
|
|
@@ -6823,7 +6827,7 @@ async function ensureDaemon() {
|
|
|
6823
6827
|
} catch {
|
|
6824
6828
|
}
|
|
6825
6829
|
console.log(import_chalk17.default.dim("\u{1F6E1}\uFE0F Starting Node9 daemon..."));
|
|
6826
|
-
const child = (0,
|
|
6830
|
+
const child = (0, import_child_process14.spawn)(process.execPath, [process.argv[1], "daemon"], {
|
|
6827
6831
|
detached: true,
|
|
6828
6832
|
stdio: "ignore",
|
|
6829
6833
|
env: { ...process.env, NODE9_AUTO_STARTED: "1" }
|
|
@@ -6997,6 +7001,7 @@ async function startTail(options = {}) {
|
|
|
6997
7001
|
return;
|
|
6998
7002
|
}
|
|
6999
7003
|
const connectionTime = Date.now();
|
|
7004
|
+
let initialReplayDone = false;
|
|
7000
7005
|
const activityPending = /* @__PURE__ */ new Map();
|
|
7001
7006
|
const orphanedResults = /* @__PURE__ */ new Map();
|
|
7002
7007
|
let csrfToken = "";
|
|
@@ -7192,10 +7197,10 @@ async function startTail(options = {}) {
|
|
|
7192
7197
|
try {
|
|
7193
7198
|
const browserEnabled = getConfig().settings.approvers?.browser !== false;
|
|
7194
7199
|
if (browserEnabled) {
|
|
7195
|
-
if (process.platform === "darwin") (0,
|
|
7200
|
+
if (process.platform === "darwin") (0, import_child_process14.execSync)(`open "${dashboardUrl}"`, { stdio: "ignore" });
|
|
7196
7201
|
else if (process.platform === "win32")
|
|
7197
|
-
(0,
|
|
7198
|
-
else (0,
|
|
7202
|
+
(0, import_child_process14.execSync)(`cmd /c start "" "${dashboardUrl}"`, { stdio: "ignore" });
|
|
7203
|
+
else (0, import_child_process14.execSync)(`xdg-open "${dashboardUrl}"`, { stdio: "ignore" });
|
|
7199
7204
|
const intToken = getInternalToken();
|
|
7200
7205
|
fetch(`http://127.0.0.1:${port}/browser-opened`, {
|
|
7201
7206
|
method: "POST",
|
|
@@ -7328,11 +7333,17 @@ async function startTail(options = {}) {
|
|
|
7328
7333
|
return;
|
|
7329
7334
|
}
|
|
7330
7335
|
if (event === "activity") {
|
|
7336
|
+
const isReplayEvent = data.status && data.status !== "pending";
|
|
7337
|
+
if (isReplayEvent && !initialReplayDone) {
|
|
7338
|
+
renderResult(data, data);
|
|
7339
|
+
return;
|
|
7340
|
+
}
|
|
7331
7341
|
if (!options.history && data.ts > 0 && data.ts < connectionTime) return;
|
|
7332
|
-
if (
|
|
7342
|
+
if (isReplayEvent) {
|
|
7333
7343
|
renderResult(data, data);
|
|
7334
7344
|
return;
|
|
7335
7345
|
}
|
|
7346
|
+
if (!initialReplayDone) initialReplayDone = true;
|
|
7336
7347
|
const orphaned = orphanedResults.get(data.id);
|
|
7337
7348
|
if (orphaned) {
|
|
7338
7349
|
orphanedResults.delete(data.id);
|
|
@@ -7371,7 +7382,7 @@ async function startTail(options = {}) {
|
|
|
7371
7382
|
process.exit(1);
|
|
7372
7383
|
});
|
|
7373
7384
|
}
|
|
7374
|
-
var import_http2, import_chalk17, import_fs25, import_os21, import_path28, import_readline5,
|
|
7385
|
+
var import_http2, import_chalk17, import_fs25, import_os21, import_path28, import_readline5, import_child_process14, PID_FILE, ICONS, RESET2, BOLD2, RED, YELLOW, CYAN, GRAY, GREEN, HIDE_CURSOR, SHOW_CURSOR, ERASE_DOWN, DIVIDER;
|
|
7375
7386
|
var init_tail = __esm({
|
|
7376
7387
|
"src/tui/tail.ts"() {
|
|
7377
7388
|
"use strict";
|
|
@@ -7381,7 +7392,7 @@ var init_tail = __esm({
|
|
|
7381
7392
|
import_os21 = __toESM(require("os"));
|
|
7382
7393
|
import_path28 = __toESM(require("path"));
|
|
7383
7394
|
import_readline5 = __toESM(require("readline"));
|
|
7384
|
-
|
|
7395
|
+
import_child_process14 = require("child_process");
|
|
7385
7396
|
init_daemon2();
|
|
7386
7397
|
init_daemon();
|
|
7387
7398
|
init_core();
|
|
@@ -7716,6 +7727,24 @@ function renderContextLine(stdin) {
|
|
|
7716
7727
|
async function main() {
|
|
7717
7728
|
try {
|
|
7718
7729
|
const [stdin, daemonStatus2] = await Promise.all([readStdin(), queryDaemon()]);
|
|
7730
|
+
if (import_fs26.default.existsSync(import_path29.default.join(import_os22.default.homedir(), ".node9", "hud-debug"))) {
|
|
7731
|
+
try {
|
|
7732
|
+
const logPath = import_path29.default.join(import_os22.default.homedir(), ".node9", "hud-debug.log");
|
|
7733
|
+
const MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
7734
|
+
let size = 0;
|
|
7735
|
+
try {
|
|
7736
|
+
size = import_fs26.default.statSync(logPath).size;
|
|
7737
|
+
} catch {
|
|
7738
|
+
}
|
|
7739
|
+
if (size < MAX_LOG_SIZE) {
|
|
7740
|
+
import_fs26.default.appendFileSync(
|
|
7741
|
+
logPath,
|
|
7742
|
+
JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), stdin }) + "\n"
|
|
7743
|
+
);
|
|
7744
|
+
}
|
|
7745
|
+
} catch {
|
|
7746
|
+
}
|
|
7747
|
+
}
|
|
7719
7748
|
if (!daemonStatus2) {
|
|
7720
7749
|
renderOffline();
|
|
7721
7750
|
return;
|
|
@@ -7832,7 +7861,7 @@ function isNode9Hook(cmd) {
|
|
|
7832
7861
|
function teardownClaude() {
|
|
7833
7862
|
const homeDir2 = import_os10.default.homedir();
|
|
7834
7863
|
const hooksPath = import_path14.default.join(homeDir2, ".claude", "settings.json");
|
|
7835
|
-
const mcpPath = import_path14.default.join(homeDir2, ".claude.json");
|
|
7864
|
+
const mcpPath = import_path14.default.join(homeDir2, ".claude", ".mcp.json");
|
|
7836
7865
|
let changed = false;
|
|
7837
7866
|
const settings = readJson(hooksPath);
|
|
7838
7867
|
if (settings?.hooks) {
|
|
@@ -7858,11 +7887,12 @@ function teardownClaude() {
|
|
|
7858
7887
|
let mcpChanged = false;
|
|
7859
7888
|
if (removeNode9McpServer(claudeConfig.mcpServers)) {
|
|
7860
7889
|
mcpChanged = true;
|
|
7861
|
-
console.log(import_chalk.default.green(" \u2705 Removed node9 MCP server entry from ~/.claude.json"));
|
|
7890
|
+
console.log(import_chalk.default.green(" \u2705 Removed node9 MCP server entry from ~/.claude/.mcp.json"));
|
|
7862
7891
|
}
|
|
7863
7892
|
for (const [name, server] of Object.entries(claudeConfig.mcpServers)) {
|
|
7864
|
-
|
|
7865
|
-
|
|
7893
|
+
const args = server.args;
|
|
7894
|
+
if (server.command === "node9" && Array.isArray(args) && args[0] === "mcp" && args[1] === "--upstream" && typeof args[2] === "string") {
|
|
7895
|
+
const [originalCmd, ...originalArgs] = args[2].split(" ");
|
|
7866
7896
|
claudeConfig.mcpServers[name] = {
|
|
7867
7897
|
...server,
|
|
7868
7898
|
command: originalCmd,
|
|
@@ -7870,16 +7900,11 @@ function teardownClaude() {
|
|
|
7870
7900
|
};
|
|
7871
7901
|
mcpChanged = true;
|
|
7872
7902
|
} else if (server.command === "node9") {
|
|
7873
|
-
console.warn(
|
|
7874
|
-
import_chalk.default.yellow(
|
|
7875
|
-
` \u26A0\uFE0F Cannot unwrap MCP server "${name}" in ~/.claude.json \u2014 args is empty. Remove it manually.`
|
|
7876
|
-
)
|
|
7877
|
-
);
|
|
7878
7903
|
}
|
|
7879
7904
|
}
|
|
7880
7905
|
if (mcpChanged) {
|
|
7881
7906
|
writeJson(mcpPath, claudeConfig);
|
|
7882
|
-
console.log(import_chalk.default.green(" \u2705 Unwrapped MCP servers in ~/.claude.json"));
|
|
7907
|
+
console.log(import_chalk.default.green(" \u2705 Unwrapped MCP servers in ~/.claude/.mcp.json"));
|
|
7883
7908
|
}
|
|
7884
7909
|
}
|
|
7885
7910
|
}
|
|
@@ -7908,8 +7933,9 @@ function teardownGemini() {
|
|
|
7908
7933
|
console.log(import_chalk.default.green(" \u2705 Removed node9 MCP server entry from ~/.gemini/settings.json"));
|
|
7909
7934
|
}
|
|
7910
7935
|
for (const [name, server] of Object.entries(settings.mcpServers)) {
|
|
7911
|
-
|
|
7912
|
-
|
|
7936
|
+
const args = server.args;
|
|
7937
|
+
if (server.command === "node9" && Array.isArray(args) && args[0] === "mcp" && args[1] === "--upstream" && typeof args[2] === "string") {
|
|
7938
|
+
const [originalCmd, ...originalArgs] = args[2].split(" ");
|
|
7913
7939
|
settings.mcpServers[name] = {
|
|
7914
7940
|
...server,
|
|
7915
7941
|
command: originalCmd,
|
|
@@ -7940,8 +7966,9 @@ function teardownCursor() {
|
|
|
7940
7966
|
console.log(import_chalk.default.green(" \u2705 Removed node9 MCP server entry from ~/.cursor/mcp.json"));
|
|
7941
7967
|
}
|
|
7942
7968
|
for (const [name, server] of Object.entries(mcpConfig.mcpServers)) {
|
|
7943
|
-
|
|
7944
|
-
|
|
7969
|
+
const args = server.args;
|
|
7970
|
+
if (server.command === "node9" && Array.isArray(args) && args[0] === "mcp" && args[1] === "--upstream" && typeof args[2] === "string") {
|
|
7971
|
+
const [originalCmd, ...originalArgs] = args[2].split(" ");
|
|
7945
7972
|
mcpConfig.mcpServers[name] = {
|
|
7946
7973
|
...server,
|
|
7947
7974
|
command: originalCmd,
|
|
@@ -7959,7 +7986,7 @@ function teardownCursor() {
|
|
|
7959
7986
|
}
|
|
7960
7987
|
async function setupClaude() {
|
|
7961
7988
|
const homeDir2 = import_os10.default.homedir();
|
|
7962
|
-
const mcpPath = import_path14.default.join(homeDir2, ".claude.json");
|
|
7989
|
+
const mcpPath = import_path14.default.join(homeDir2, ".claude", ".mcp.json");
|
|
7963
7990
|
const hooksPath = import_path14.default.join(homeDir2, ".claude", "settings.json");
|
|
7964
7991
|
const claudeConfig = readJson(mcpPath) ?? {};
|
|
7965
7992
|
const settings = readJson(hooksPath) ?? {};
|
|
@@ -7974,7 +8001,7 @@ async function setupClaude() {
|
|
|
7974
8001
|
if (!settings.hooks.PreToolUse) settings.hooks.PreToolUse = [];
|
|
7975
8002
|
settings.hooks.PreToolUse.push({
|
|
7976
8003
|
matcher: ".*",
|
|
7977
|
-
hooks: [{ type: "command", command: fullPathCommand("check"), timeout:
|
|
8004
|
+
hooks: [{ type: "command", command: fullPathCommand("check"), timeout: 600 }]
|
|
7978
8005
|
});
|
|
7979
8006
|
console.log(import_chalk.default.green(" \u2705 PreToolUse hook added \u2192 node9 check"));
|
|
7980
8007
|
hooksChanged = true;
|
|
@@ -8000,6 +8027,15 @@ async function setupClaude() {
|
|
|
8000
8027
|
console.log(import_chalk.default.green(" \u2705 node9 MCP server added \u2192 node9 mcp-server"));
|
|
8001
8028
|
anythingChanged = true;
|
|
8002
8029
|
}
|
|
8030
|
+
const hudCommand = fullPathCommand("hud");
|
|
8031
|
+
const statusLineObj = { type: "command", command: hudCommand };
|
|
8032
|
+
const existingStatusLine = settings.statusLine;
|
|
8033
|
+
const existingStatusCommand = typeof existingStatusLine === "object" ? existingStatusLine?.command : existingStatusLine;
|
|
8034
|
+
if (existingStatusCommand !== hudCommand) {
|
|
8035
|
+
settings.statusLine = statusLineObj;
|
|
8036
|
+
hooksChanged = true;
|
|
8037
|
+
anythingChanged = true;
|
|
8038
|
+
}
|
|
8003
8039
|
if (hooksChanged) {
|
|
8004
8040
|
writeJson(hooksPath, settings);
|
|
8005
8041
|
console.log("");
|
|
@@ -8007,20 +8043,24 @@ async function setupClaude() {
|
|
|
8007
8043
|
const serversToWrap = [];
|
|
8008
8044
|
for (const [name, server] of Object.entries(servers)) {
|
|
8009
8045
|
if (!server.command || server.command === "node9") continue;
|
|
8010
|
-
const
|
|
8011
|
-
serversToWrap.push({ name,
|
|
8046
|
+
const upstream = [server.command, ...server.args ?? []].join(" ");
|
|
8047
|
+
serversToWrap.push({ name, upstream });
|
|
8012
8048
|
}
|
|
8013
8049
|
if (serversToWrap.length > 0) {
|
|
8014
8050
|
console.log(import_chalk.default.bold("The following existing entries will be modified:\n"));
|
|
8015
8051
|
console.log(import_chalk.default.white(` ${mcpPath}`));
|
|
8016
|
-
for (const { name,
|
|
8017
|
-
console.log(import_chalk.default.gray(` \u2022 ${name}: "${
|
|
8052
|
+
for (const { name, upstream } of serversToWrap) {
|
|
8053
|
+
console.log(import_chalk.default.gray(` \u2022 ${name}: "${upstream}" \u2192 node9 mcp --upstream "${upstream}"`));
|
|
8018
8054
|
}
|
|
8019
8055
|
console.log("");
|
|
8020
8056
|
const proceed = await (0, import_prompts.confirm)({ message: "Wrap these MCP servers?", default: true });
|
|
8021
8057
|
if (proceed) {
|
|
8022
|
-
for (const { name,
|
|
8023
|
-
servers[name] = {
|
|
8058
|
+
for (const { name, upstream } of serversToWrap) {
|
|
8059
|
+
servers[name] = {
|
|
8060
|
+
...servers[name],
|
|
8061
|
+
command: "node9",
|
|
8062
|
+
args: ["mcp", "--upstream", upstream]
|
|
8063
|
+
};
|
|
8024
8064
|
}
|
|
8025
8065
|
claudeConfig.mcpServers = servers;
|
|
8026
8066
|
writeJson(mcpPath, claudeConfig);
|
|
@@ -8100,20 +8140,24 @@ async function setupGemini() {
|
|
|
8100
8140
|
const serversToWrap = [];
|
|
8101
8141
|
for (const [name, server] of Object.entries(servers)) {
|
|
8102
8142
|
if (!server.command || server.command === "node9") continue;
|
|
8103
|
-
const
|
|
8104
|
-
serversToWrap.push({ name,
|
|
8143
|
+
const upstream = [server.command, ...server.args ?? []].join(" ");
|
|
8144
|
+
serversToWrap.push({ name, upstream });
|
|
8105
8145
|
}
|
|
8106
8146
|
if (serversToWrap.length > 0) {
|
|
8107
8147
|
console.log(import_chalk.default.bold("The following existing entries will be modified:\n"));
|
|
8108
8148
|
console.log(import_chalk.default.white(` ${settingsPath} (mcpServers)`));
|
|
8109
|
-
for (const { name,
|
|
8110
|
-
console.log(import_chalk.default.gray(` \u2022 ${name}: "${
|
|
8149
|
+
for (const { name, upstream } of serversToWrap) {
|
|
8150
|
+
console.log(import_chalk.default.gray(` \u2022 ${name}: "${upstream}" \u2192 node9 mcp --upstream "${upstream}"`));
|
|
8111
8151
|
}
|
|
8112
8152
|
console.log("");
|
|
8113
8153
|
const proceed = await (0, import_prompts.confirm)({ message: "Wrap these MCP servers?", default: true });
|
|
8114
8154
|
if (proceed) {
|
|
8115
|
-
for (const { name,
|
|
8116
|
-
servers[name] = {
|
|
8155
|
+
for (const { name, upstream } of serversToWrap) {
|
|
8156
|
+
servers[name] = {
|
|
8157
|
+
...servers[name],
|
|
8158
|
+
command: "node9",
|
|
8159
|
+
args: ["mcp", "--upstream", upstream]
|
|
8160
|
+
};
|
|
8117
8161
|
}
|
|
8118
8162
|
settings.mcpServers = servers;
|
|
8119
8163
|
writeJson(settingsPath, settings);
|
|
@@ -8172,20 +8216,24 @@ async function setupCursor() {
|
|
|
8172
8216
|
const serversToWrap = [];
|
|
8173
8217
|
for (const [name, server] of Object.entries(servers)) {
|
|
8174
8218
|
if (!server.command || server.command === "node9") continue;
|
|
8175
|
-
const
|
|
8176
|
-
serversToWrap.push({ name,
|
|
8219
|
+
const upstream = [server.command, ...server.args ?? []].join(" ");
|
|
8220
|
+
serversToWrap.push({ name, upstream });
|
|
8177
8221
|
}
|
|
8178
8222
|
if (serversToWrap.length > 0) {
|
|
8179
8223
|
console.log(import_chalk.default.bold("The following existing entries will be modified:\n"));
|
|
8180
8224
|
console.log(import_chalk.default.white(` ${mcpPath}`));
|
|
8181
|
-
for (const { name,
|
|
8182
|
-
console.log(import_chalk.default.gray(` \u2022 ${name}: "${
|
|
8225
|
+
for (const { name, upstream } of serversToWrap) {
|
|
8226
|
+
console.log(import_chalk.default.gray(` \u2022 ${name}: "${upstream}" \u2192 node9 mcp --upstream "${upstream}"`));
|
|
8183
8227
|
}
|
|
8184
8228
|
console.log("");
|
|
8185
8229
|
const proceed = await (0, import_prompts.confirm)({ message: "Wrap these MCP servers?", default: true });
|
|
8186
8230
|
if (proceed) {
|
|
8187
|
-
for (const { name,
|
|
8188
|
-
servers[name] = {
|
|
8231
|
+
for (const { name, upstream } of serversToWrap) {
|
|
8232
|
+
servers[name] = {
|
|
8233
|
+
...servers[name],
|
|
8234
|
+
command: "node9",
|
|
8235
|
+
args: ["mcp", "--upstream", upstream]
|
|
8236
|
+
};
|
|
8189
8237
|
}
|
|
8190
8238
|
mcpConfig.mcpServers = servers;
|
|
8191
8239
|
writeJson(mcpPath, mcpConfig);
|
|
@@ -8248,20 +8296,24 @@ async function setupCodex() {
|
|
|
8248
8296
|
const serversToWrap = [];
|
|
8249
8297
|
for (const [name, server] of Object.entries(servers)) {
|
|
8250
8298
|
if (!server.command || server.command === "node9") continue;
|
|
8251
|
-
const
|
|
8252
|
-
serversToWrap.push({ name,
|
|
8299
|
+
const upstream = [server.command, ...server.args ?? []].join(" ");
|
|
8300
|
+
serversToWrap.push({ name, upstream });
|
|
8253
8301
|
}
|
|
8254
8302
|
if (serversToWrap.length > 0) {
|
|
8255
8303
|
console.log(import_chalk.default.bold("The following existing entries will be modified:\n"));
|
|
8256
8304
|
console.log(import_chalk.default.white(` ${configPath}`));
|
|
8257
|
-
for (const { name,
|
|
8258
|
-
console.log(import_chalk.default.gray(` \u2022 ${name}: "${
|
|
8305
|
+
for (const { name, upstream } of serversToWrap) {
|
|
8306
|
+
console.log(import_chalk.default.gray(` \u2022 ${name}: "${upstream}" \u2192 node9 mcp --upstream "${upstream}"`));
|
|
8259
8307
|
}
|
|
8260
8308
|
console.log("");
|
|
8261
8309
|
const proceed = await (0, import_prompts.confirm)({ message: "Wrap these MCP servers?", default: true });
|
|
8262
8310
|
if (proceed) {
|
|
8263
|
-
for (const { name,
|
|
8264
|
-
servers[name] = {
|
|
8311
|
+
for (const { name, upstream } of serversToWrap) {
|
|
8312
|
+
servers[name] = {
|
|
8313
|
+
...servers[name],
|
|
8314
|
+
command: "node9",
|
|
8315
|
+
args: ["mcp", "--upstream", upstream]
|
|
8316
|
+
};
|
|
8265
8317
|
}
|
|
8266
8318
|
config.mcp_servers = servers;
|
|
8267
8319
|
writeToml(configPath, config);
|
|
@@ -8450,18 +8502,20 @@ async function runProxy(targetCommand) {
|
|
|
8450
8502
|
const cmd = commandParts[0];
|
|
8451
8503
|
const args = commandParts.slice(1);
|
|
8452
8504
|
let executable = cmd;
|
|
8505
|
+
let useShell = false;
|
|
8453
8506
|
try {
|
|
8454
8507
|
const { stdout } = await (0, import_execa.execa)("which", [cmd]);
|
|
8455
8508
|
if (stdout) executable = stdout.trim();
|
|
8456
8509
|
} catch {
|
|
8510
|
+
useShell = true;
|
|
8457
8511
|
}
|
|
8458
8512
|
console.error(import_chalk4.default.green(`\u{1F680} Node9 Proxy Active: Monitoring [${targetCommand}]`));
|
|
8459
|
-
const
|
|
8513
|
+
const spawnEnv = { ...process.env, FORCE_COLOR: "1" };
|
|
8514
|
+
const child = useShell ? (0, import_child_process6.spawn)("/bin/bash", ["-c", targetCommand], {
|
|
8460
8515
|
stdio: ["pipe", "pipe", "inherit"],
|
|
8461
|
-
// We control STDIN and STDOUT
|
|
8462
8516
|
shell: false,
|
|
8463
|
-
env:
|
|
8464
|
-
});
|
|
8517
|
+
env: spawnEnv
|
|
8518
|
+
}) : (0, import_child_process6.spawn)(executable, args, { stdio: ["pipe", "pipe", "inherit"], shell: false, env: spawnEnv });
|
|
8465
8519
|
const agentIn = import_readline.default.createInterface({ input: process.stdin, terminal: false });
|
|
8466
8520
|
agentIn.on("line", async (line) => {
|
|
8467
8521
|
let message;
|
|
@@ -8570,6 +8624,7 @@ async function autoStartDaemonAndWait() {
|
|
|
8570
8624
|
// src/cli/commands/check.ts
|
|
8571
8625
|
var import_chalk5 = __toESM(require("chalk"));
|
|
8572
8626
|
var import_fs18 = __toESM(require("fs"));
|
|
8627
|
+
var import_child_process9 = require("child_process");
|
|
8573
8628
|
var import_path20 = __toESM(require("path"));
|
|
8574
8629
|
var import_os14 = __toESM(require("os"));
|
|
8575
8630
|
init_orchestrator();
|
|
@@ -8953,6 +9008,37 @@ RAW: ${raw}
|
|
|
8953
9008
|
process.exit(0);
|
|
8954
9009
|
}
|
|
8955
9010
|
const config = getConfig(payload.cwd || void 0);
|
|
9011
|
+
if (config.settings.autoStartDaemon && !isDaemonRunning() && !process.env.NODE9_NO_AUTO_DAEMON) {
|
|
9012
|
+
try {
|
|
9013
|
+
const scriptPath = process.argv[1];
|
|
9014
|
+
if (typeof scriptPath !== "string" || !import_path20.default.isAbsolute(scriptPath))
|
|
9015
|
+
throw new Error("node9: argv[1] is not an absolute path");
|
|
9016
|
+
const resolvedScript = import_fs18.default.realpathSync(scriptPath);
|
|
9017
|
+
const expectedCli = import_fs18.default.realpathSync(import_path20.default.resolve(__dirname, "../../cli.js"));
|
|
9018
|
+
if (resolvedScript !== expectedCli)
|
|
9019
|
+
throw new Error(
|
|
9020
|
+
"node9: daemon spawn aborted \u2014 argv[1] does not resolve to the node9 CLI"
|
|
9021
|
+
);
|
|
9022
|
+
const safeEnv = { ...process.env };
|
|
9023
|
+
for (const key of [
|
|
9024
|
+
"NODE_OPTIONS",
|
|
9025
|
+
"LD_PRELOAD",
|
|
9026
|
+
"LD_LIBRARY_PATH",
|
|
9027
|
+
"DYLD_INSERT_LIBRARIES",
|
|
9028
|
+
"NODE_PATH",
|
|
9029
|
+
"ELECTRON_RUN_AS_NODE"
|
|
9030
|
+
]) {
|
|
9031
|
+
delete safeEnv[key];
|
|
9032
|
+
}
|
|
9033
|
+
const d = (0, import_child_process9.spawn)(process.execPath, [scriptPath, "daemon"], {
|
|
9034
|
+
detached: true,
|
|
9035
|
+
stdio: "ignore",
|
|
9036
|
+
env: { ...safeEnv, NODE9_AUTO_STARTED: "1", NODE9_BROWSER_OPENED: "1" }
|
|
9037
|
+
});
|
|
9038
|
+
d.unref();
|
|
9039
|
+
} catch {
|
|
9040
|
+
}
|
|
9041
|
+
}
|
|
8956
9042
|
if (process.env.NODE9_DEBUG === "1" || config.settings.enableHookLogDebug) {
|
|
8957
9043
|
const logPath = import_path20.default.join(import_os14.default.homedir(), ".node9", "hook-debug.log");
|
|
8958
9044
|
if (!import_fs18.default.existsSync(import_path20.default.dirname(logPath)))
|
|
@@ -9621,7 +9707,7 @@ var import_chalk7 = __toESM(require("chalk"));
|
|
|
9621
9707
|
var import_fs20 = __toESM(require("fs"));
|
|
9622
9708
|
var import_path22 = __toESM(require("path"));
|
|
9623
9709
|
var import_os16 = __toESM(require("os"));
|
|
9624
|
-
var
|
|
9710
|
+
var import_child_process10 = require("child_process");
|
|
9625
9711
|
init_daemon();
|
|
9626
9712
|
function registerDoctorCommand(program2, version2) {
|
|
9627
9713
|
program2.command("doctor").description("Check that Node9 is installed and configured correctly").action(() => {
|
|
@@ -9647,7 +9733,7 @@ function registerDoctorCommand(program2, version2) {
|
|
|
9647
9733
|
`));
|
|
9648
9734
|
section("Binary");
|
|
9649
9735
|
try {
|
|
9650
|
-
const which = (0,
|
|
9736
|
+
const which = (0, import_child_process10.execSync)("which node9", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
9651
9737
|
pass(`node9 found at ${which}`);
|
|
9652
9738
|
} catch {
|
|
9653
9739
|
warn(
|
|
@@ -9665,7 +9751,7 @@ function registerDoctorCommand(program2, version2) {
|
|
|
9665
9751
|
);
|
|
9666
9752
|
}
|
|
9667
9753
|
try {
|
|
9668
|
-
const gitVersion = (0,
|
|
9754
|
+
const gitVersion = (0, import_child_process10.execSync)("git --version", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
9669
9755
|
pass(gitVersion);
|
|
9670
9756
|
} catch {
|
|
9671
9757
|
warn(
|
|
@@ -9862,7 +9948,7 @@ function registerAuditCommand(program2) {
|
|
|
9862
9948
|
|
|
9863
9949
|
// src/cli/commands/daemon-cmd.ts
|
|
9864
9950
|
var import_chalk9 = __toESM(require("chalk"));
|
|
9865
|
-
var
|
|
9951
|
+
var import_child_process11 = require("child_process");
|
|
9866
9952
|
init_daemon2();
|
|
9867
9953
|
init_daemon();
|
|
9868
9954
|
function registerDaemonCommand(program2) {
|
|
@@ -9895,7 +9981,7 @@ function registerDaemonCommand(program2) {
|
|
|
9895
9981
|
console.log(import_chalk9.default.green(`\u{1F310} Opened browser: http://${DAEMON_HOST}:${DAEMON_PORT}/`));
|
|
9896
9982
|
process.exit(0);
|
|
9897
9983
|
}
|
|
9898
|
-
const child = (0,
|
|
9984
|
+
const child = (0, import_child_process11.spawn)(process.execPath, [process.argv[1], "daemon"], {
|
|
9899
9985
|
detached: true,
|
|
9900
9986
|
stdio: "ignore"
|
|
9901
9987
|
});
|
|
@@ -9910,7 +9996,7 @@ function registerDaemonCommand(program2) {
|
|
|
9910
9996
|
process.exit(0);
|
|
9911
9997
|
}
|
|
9912
9998
|
if (options.background) {
|
|
9913
|
-
const child = (0,
|
|
9999
|
+
const child = (0, import_child_process11.spawn)(process.execPath, [process.argv[1], "daemon"], {
|
|
9914
10000
|
detached: true,
|
|
9915
10001
|
stdio: "ignore"
|
|
9916
10002
|
});
|
|
@@ -10498,7 +10584,7 @@ function registerUndoCommand(program2) {
|
|
|
10498
10584
|
|
|
10499
10585
|
// src/cli/commands/watch.ts
|
|
10500
10586
|
var import_chalk14 = __toESM(require("chalk"));
|
|
10501
|
-
var
|
|
10587
|
+
var import_child_process12 = require("child_process");
|
|
10502
10588
|
init_daemon();
|
|
10503
10589
|
function registerWatchCommand(program2) {
|
|
10504
10590
|
program2.command("watch").description("Run a command under Node9 watch mode (daemon stays alive for the session)").argument("<command>", "Command to run").argument("[args...]", "Arguments for the command").action(async (cmd, args) => {
|
|
@@ -10515,7 +10601,7 @@ function registerWatchCommand(program2) {
|
|
|
10515
10601
|
}
|
|
10516
10602
|
} catch {
|
|
10517
10603
|
console.error(import_chalk14.default.dim("\u{1F6E1}\uFE0F Starting Node9 daemon (watch mode)..."));
|
|
10518
|
-
const child = (0,
|
|
10604
|
+
const child = (0, import_child_process12.spawn)(process.execPath, [process.argv[1], "daemon"], {
|
|
10519
10605
|
detached: true,
|
|
10520
10606
|
stdio: "ignore",
|
|
10521
10607
|
env: { ...process.env, NODE9_AUTO_STARTED: "1", NODE9_WATCH_MODE: "1" }
|
|
@@ -10545,7 +10631,7 @@ function registerWatchCommand(program2) {
|
|
|
10545
10631
|
"\n Tip: run `node9 tail` in another terminal to review and approve AI actions.\n"
|
|
10546
10632
|
)
|
|
10547
10633
|
);
|
|
10548
|
-
const result = (0,
|
|
10634
|
+
const result = (0, import_child_process12.spawnSync)(cmd, args, {
|
|
10549
10635
|
stdio: "inherit",
|
|
10550
10636
|
env: { ...process.env, NODE9_WATCH_MODE: "1" }
|
|
10551
10637
|
});
|
|
@@ -10560,7 +10646,7 @@ function registerWatchCommand(program2) {
|
|
|
10560
10646
|
// src/mcp-gateway/index.ts
|
|
10561
10647
|
var import_readline3 = __toESM(require("readline"));
|
|
10562
10648
|
var import_chalk15 = __toESM(require("chalk"));
|
|
10563
|
-
var
|
|
10649
|
+
var import_child_process13 = require("child_process");
|
|
10564
10650
|
var import_execa3 = require("execa");
|
|
10565
10651
|
init_orchestrator();
|
|
10566
10652
|
init_provenance();
|
|
@@ -10648,7 +10734,7 @@ async function runMcpGateway(upstreamCommand) {
|
|
|
10648
10734
|
const safeEnv = Object.fromEntries(
|
|
10649
10735
|
Object.entries(process.env).filter(([k]) => !UPSTREAM_INJECTOR_VARS.has(k))
|
|
10650
10736
|
);
|
|
10651
|
-
const child = (0,
|
|
10737
|
+
const child = (0, import_child_process13.spawn)(executable, cmdArgs, {
|
|
10652
10738
|
stdio: ["pipe", "pipe", "inherit"],
|
|
10653
10739
|
// control stdin/stdout; inherit stderr
|
|
10654
10740
|
shell: false,
|
|
@@ -10731,8 +10817,11 @@ async function runMcpGateway(upstreamCommand) {
|
|
|
10731
10817
|
return;
|
|
10732
10818
|
} finally {
|
|
10733
10819
|
authPending = false;
|
|
10734
|
-
|
|
10735
|
-
|
|
10820
|
+
if (deferredStdinEnd) {
|
|
10821
|
+
child.stdin.end();
|
|
10822
|
+
} else {
|
|
10823
|
+
agentIn.resume();
|
|
10824
|
+
}
|
|
10736
10825
|
if (deferredExitCode !== null) process.exit(deferredExitCode);
|
|
10737
10826
|
}
|
|
10738
10827
|
return;
|
|
@@ -11467,7 +11556,43 @@ registerMcpGatewayCommand(program);
|
|
|
11467
11556
|
registerMcpServerCommand(program);
|
|
11468
11557
|
registerCheckCommand(program);
|
|
11469
11558
|
registerLogCommand(program);
|
|
11470
|
-
program.command("hud").description("Render node9 security statusline (spawned by Claude Code statusLine)").
|
|
11559
|
+
program.command("hud").description("Render node9 security statusline (spawned by Claude Code statusLine)").addHelpText(
|
|
11560
|
+
"after",
|
|
11561
|
+
`
|
|
11562
|
+
Outputs up to 3 lines to stdout, then exits:
|
|
11563
|
+
|
|
11564
|
+
Line 1 \u2014 Security state (always shown):
|
|
11565
|
+
\u{1F6E1} node9 | <mode> [shields] | \u2705 allowed \u{1F6D1} blocked \u{1F6A8} dlp ~$cost
|
|
11566
|
+
Shows "offline" if the node9 daemon is not running.
|
|
11567
|
+
|
|
11568
|
+
Line 2 \u2014 Claude context & rate limits (shown when available):
|
|
11569
|
+
<model> \u2502 ctx \u2588\u2588\u2588\u2588\u2588\u2588\u2591\u2591\u2591\u2591 61% \u2502 5h \u2588\u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2591 40% (2h 10m left)
|
|
11570
|
+
Only appears when Claude Code passes context_window / rate_limits data via stdin.
|
|
11571
|
+
|
|
11572
|
+
Line 3 \u2014 Environment counts (shown when non-zero):
|
|
11573
|
+
2 CLAUDE.md | 5 rules | 4 MCPs | 3 hooks
|
|
11574
|
+
Counts CLAUDE.md files, rules/, MCP servers, and hook entries across user + project scope.
|
|
11575
|
+
Disable with: { "settings": { "hud": { "showEnvironmentCounts": false } } } in node9.config.json
|
|
11576
|
+
|
|
11577
|
+
Claude Code spawns this command every ~300ms and writes a JSON payload to stdin.
|
|
11578
|
+
Run "node9 addto claude" to register it as the statusLine.`
|
|
11579
|
+
).argument("[subcommand]", 'Optional: "debug on" / "debug off" to toggle stdin logging').argument("[state]", 'on|off \u2014 used with "debug" subcommand').action(async (subcommand, state) => {
|
|
11580
|
+
if (subcommand === "debug") {
|
|
11581
|
+
const flagFile = import_path30.default.join(import_os23.default.homedir(), ".node9", "hud-debug");
|
|
11582
|
+
if (state === "on") {
|
|
11583
|
+
import_fs27.default.mkdirSync(import_path30.default.dirname(flagFile), { recursive: true });
|
|
11584
|
+
import_fs27.default.writeFileSync(flagFile, "");
|
|
11585
|
+
console.log("HUD debug logging enabled \u2192 ~/.node9/hud-debug.log");
|
|
11586
|
+
console.log("Tail it with: tail -f ~/.node9/hud-debug.log");
|
|
11587
|
+
} else if (state === "off") {
|
|
11588
|
+
if (import_fs27.default.existsSync(flagFile)) import_fs27.default.unlinkSync(flagFile);
|
|
11589
|
+
console.log("HUD debug logging disabled.");
|
|
11590
|
+
} else {
|
|
11591
|
+
console.error("Usage: node9 hud debug on|off");
|
|
11592
|
+
process.exit(1);
|
|
11593
|
+
}
|
|
11594
|
+
return;
|
|
11595
|
+
}
|
|
11471
11596
|
const { main: main2 } = await Promise.resolve().then(() => (init_hud(), hud_exports));
|
|
11472
11597
|
await main2();
|
|
11473
11598
|
});
|