maxclaw 0.7.0 → 0.7.2
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/index.js +662 -66
- package/dist/index.pkg.cjs +687 -91
- package/package.json +1 -1
package/dist/index.pkg.cjs
CHANGED
|
@@ -4805,14 +4805,14 @@ var require_templates = __commonJS({
|
|
|
4805
4805
|
}
|
|
4806
4806
|
return results;
|
|
4807
4807
|
}
|
|
4808
|
-
function buildStyle(
|
|
4808
|
+
function buildStyle(chalk13, styles) {
|
|
4809
4809
|
const enabled = {};
|
|
4810
4810
|
for (const layer of styles) {
|
|
4811
4811
|
for (const style of layer.styles) {
|
|
4812
4812
|
enabled[style[0]] = layer.inverse ? null : style.slice(1);
|
|
4813
4813
|
}
|
|
4814
4814
|
}
|
|
4815
|
-
let current =
|
|
4815
|
+
let current = chalk13;
|
|
4816
4816
|
for (const [styleName, styles2] of Object.entries(enabled)) {
|
|
4817
4817
|
if (!Array.isArray(styles2)) {
|
|
4818
4818
|
continue;
|
|
@@ -4824,7 +4824,7 @@ var require_templates = __commonJS({
|
|
|
4824
4824
|
}
|
|
4825
4825
|
return current;
|
|
4826
4826
|
}
|
|
4827
|
-
module2.exports = (
|
|
4827
|
+
module2.exports = (chalk13, temporary) => {
|
|
4828
4828
|
const styles = [];
|
|
4829
4829
|
const chunks = [];
|
|
4830
4830
|
let chunk = [];
|
|
@@ -4834,13 +4834,13 @@ var require_templates = __commonJS({
|
|
|
4834
4834
|
} else if (style) {
|
|
4835
4835
|
const string = chunk.join("");
|
|
4836
4836
|
chunk = [];
|
|
4837
|
-
chunks.push(styles.length === 0 ? string : buildStyle(
|
|
4837
|
+
chunks.push(styles.length === 0 ? string : buildStyle(chalk13, styles)(string));
|
|
4838
4838
|
styles.push({ inverse, styles: parseStyle(style) });
|
|
4839
4839
|
} else if (close) {
|
|
4840
4840
|
if (styles.length === 0) {
|
|
4841
4841
|
throw new Error("Found extraneous } in Chalk template literal");
|
|
4842
4842
|
}
|
|
4843
|
-
chunks.push(buildStyle(
|
|
4843
|
+
chunks.push(buildStyle(chalk13, styles)(chunk.join("")));
|
|
4844
4844
|
chunk = [];
|
|
4845
4845
|
styles.pop();
|
|
4846
4846
|
} else {
|
|
@@ -4888,16 +4888,16 @@ var require_source = __commonJS({
|
|
|
4888
4888
|
}
|
|
4889
4889
|
};
|
|
4890
4890
|
var chalkFactory = (options) => {
|
|
4891
|
-
const
|
|
4892
|
-
applyOptions(
|
|
4893
|
-
|
|
4894
|
-
Object.setPrototypeOf(
|
|
4895
|
-
Object.setPrototypeOf(
|
|
4896
|
-
|
|
4891
|
+
const chalk14 = {};
|
|
4892
|
+
applyOptions(chalk14, options);
|
|
4893
|
+
chalk14.template = (...arguments_) => chalkTag(chalk14.template, ...arguments_);
|
|
4894
|
+
Object.setPrototypeOf(chalk14, Chalk.prototype);
|
|
4895
|
+
Object.setPrototypeOf(chalk14.template, chalk14);
|
|
4896
|
+
chalk14.template.constructor = () => {
|
|
4897
4897
|
throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
|
|
4898
4898
|
};
|
|
4899
|
-
|
|
4900
|
-
return
|
|
4899
|
+
chalk14.template.Instance = ChalkClass;
|
|
4900
|
+
return chalk14.template;
|
|
4901
4901
|
};
|
|
4902
4902
|
function Chalk(options) {
|
|
4903
4903
|
return chalkFactory(options);
|
|
@@ -5008,7 +5008,7 @@ var require_source = __commonJS({
|
|
|
5008
5008
|
return openAll + string + closeAll;
|
|
5009
5009
|
};
|
|
5010
5010
|
var template;
|
|
5011
|
-
var chalkTag = (
|
|
5011
|
+
var chalkTag = (chalk14, ...strings) => {
|
|
5012
5012
|
const [firstString] = strings;
|
|
5013
5013
|
if (!isArray(firstString) || !isArray(firstString.raw)) {
|
|
5014
5014
|
return strings.join(" ");
|
|
@@ -5024,14 +5024,14 @@ var require_source = __commonJS({
|
|
|
5024
5024
|
if (template === void 0) {
|
|
5025
5025
|
template = require_templates();
|
|
5026
5026
|
}
|
|
5027
|
-
return template(
|
|
5027
|
+
return template(chalk14, parts.join(""));
|
|
5028
5028
|
};
|
|
5029
5029
|
Object.defineProperties(Chalk.prototype, styles);
|
|
5030
|
-
var
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
module2.exports =
|
|
5030
|
+
var chalk13 = Chalk();
|
|
5031
|
+
chalk13.supportsColor = stdoutColor;
|
|
5032
|
+
chalk13.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
5033
|
+
chalk13.stderr.supportsColor = stderrColor;
|
|
5034
|
+
module2.exports = chalk13;
|
|
5035
5035
|
}
|
|
5036
5036
|
});
|
|
5037
5037
|
|
|
@@ -5154,21 +5154,23 @@ function getOpenClawHome(profile) {
|
|
|
5154
5154
|
return (0, import_node_path4.join)((0, import_node_os2.homedir)(), ".openclaw");
|
|
5155
5155
|
}
|
|
5156
5156
|
function findOpenClawBin() {
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
(
|
|
5161
|
-
|
|
5162
|
-
for (const plist of plists) {
|
|
5163
|
-
const content = (0, import_node_fs3.readFileSync)((0, import_node_path4.join)(plistDir, plist), "utf-8");
|
|
5164
|
-
const nodeMatch = content.match(
|
|
5165
|
-
/<string>(\/[^<]*\/bin\/node)<\/string>/
|
|
5157
|
+
if (PLATFORM === "darwin") {
|
|
5158
|
+
const plistDir = (0, import_node_path4.join)((0, import_node_os2.homedir)(), "Library", "LaunchAgents");
|
|
5159
|
+
if ((0, import_node_fs3.existsSync)(plistDir)) {
|
|
5160
|
+
const plists = (0, import_node_fs3.readdirSync)(plistDir).filter(
|
|
5161
|
+
(f) => f.includes("openclaw") && f.endsWith(".plist")
|
|
5166
5162
|
);
|
|
5167
|
-
const
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5163
|
+
for (const plist of plists) {
|
|
5164
|
+
const content = (0, import_node_fs3.readFileSync)((0, import_node_path4.join)(plistDir, plist), "utf-8");
|
|
5165
|
+
const nodeMatch = content.match(
|
|
5166
|
+
/<string>(\/[^<]*\/bin\/node)<\/string>/
|
|
5167
|
+
);
|
|
5168
|
+
const cliMatch = content.match(
|
|
5169
|
+
/<string>(\/[^<]*openclaw[^<]*\.(?:js|mjs))<\/string>/
|
|
5170
|
+
);
|
|
5171
|
+
if (nodeMatch && cliMatch) {
|
|
5172
|
+
return { nodePath: nodeMatch[1], cliBinPath: cliMatch[1] };
|
|
5173
|
+
}
|
|
5172
5174
|
}
|
|
5173
5175
|
}
|
|
5174
5176
|
}
|
|
@@ -5180,6 +5182,7 @@ function findOpenClawBin() {
|
|
|
5180
5182
|
return null;
|
|
5181
5183
|
}
|
|
5182
5184
|
function findLaunchdLabel() {
|
|
5185
|
+
if (PLATFORM !== "darwin") return "ai.openclaw.gateway";
|
|
5183
5186
|
const plistDir = (0, import_node_path4.join)((0, import_node_os2.homedir)(), "Library", "LaunchAgents");
|
|
5184
5187
|
if (!(0, import_node_fs3.existsSync)(plistDir)) return "ai.openclaw.gateway";
|
|
5185
5188
|
const plists = (0, import_node_fs3.readdirSync)(plistDir).filter(
|
|
@@ -5190,6 +5193,18 @@ function findLaunchdLabel() {
|
|
|
5190
5193
|
}
|
|
5191
5194
|
return "ai.openclaw.gateway";
|
|
5192
5195
|
}
|
|
5196
|
+
function hasSystemdService() {
|
|
5197
|
+
try {
|
|
5198
|
+
const { status } = require("child_process").spawnSync(
|
|
5199
|
+
"systemctl",
|
|
5200
|
+
["--user", "status", "openclaw"],
|
|
5201
|
+
{ stdio: "ignore" }
|
|
5202
|
+
);
|
|
5203
|
+
return status === 0 || status === 3;
|
|
5204
|
+
} catch {
|
|
5205
|
+
return false;
|
|
5206
|
+
}
|
|
5207
|
+
}
|
|
5193
5208
|
function detectOpenClaw(profile = "default") {
|
|
5194
5209
|
const home = getOpenClawHome(profile);
|
|
5195
5210
|
const configPath = (0, import_node_path4.join)(home, "openclaw.json");
|
|
@@ -5285,19 +5300,46 @@ async function getGatewayHealth(info) {
|
|
|
5285
5300
|
}
|
|
5286
5301
|
}
|
|
5287
5302
|
function getRestartCommand(info) {
|
|
5303
|
+
if (PLATFORM === "win32") {
|
|
5304
|
+
throw new Error("Windows native is not supported. Please use WSL 2.");
|
|
5305
|
+
}
|
|
5306
|
+
if (PLATFORM === "linux") {
|
|
5307
|
+
if (hasSystemdService()) {
|
|
5308
|
+
return "systemctl --user restart openclaw";
|
|
5309
|
+
}
|
|
5310
|
+
return `(pgrep -f "openclaw.*gateway" | xargs kill 2>/dev/null || true) && nohup openclaw gateway > /dev/null 2>&1 &`;
|
|
5311
|
+
}
|
|
5288
5312
|
const uid = process.getuid?.() ?? 501;
|
|
5289
5313
|
return `launchctl kickstart -k gui/${uid}/${info.launchdLabel}`;
|
|
5290
5314
|
}
|
|
5291
5315
|
function getStopCommand(info) {
|
|
5316
|
+
if (PLATFORM === "win32") {
|
|
5317
|
+
throw new Error("Windows native is not supported. Please use WSL 2.");
|
|
5318
|
+
}
|
|
5319
|
+
if (PLATFORM === "linux") {
|
|
5320
|
+
if (hasSystemdService()) {
|
|
5321
|
+
return "systemctl --user stop openclaw";
|
|
5322
|
+
}
|
|
5323
|
+
return `pgrep -f "openclaw.*gateway" | xargs kill 2>/dev/null || true`;
|
|
5324
|
+
}
|
|
5292
5325
|
const uid = process.getuid?.() ?? 501;
|
|
5293
5326
|
return `launchctl bootout gui/${uid}/${info.launchdLabel} 2>/dev/null || launchctl kill SIGTERM gui/${uid}/${info.launchdLabel} 2>/dev/null || true`;
|
|
5294
5327
|
}
|
|
5295
5328
|
function getStartCommand(info) {
|
|
5329
|
+
if (PLATFORM === "win32") {
|
|
5330
|
+
throw new Error("Windows native is not supported. Please use WSL 2.");
|
|
5331
|
+
}
|
|
5332
|
+
if (PLATFORM === "linux") {
|
|
5333
|
+
if (hasSystemdService()) {
|
|
5334
|
+
return "systemctl --user start openclaw";
|
|
5335
|
+
}
|
|
5336
|
+
return `nohup openclaw gateway > /dev/null 2>&1 &`;
|
|
5337
|
+
}
|
|
5296
5338
|
const uid = process.getuid?.() ?? 501;
|
|
5297
5339
|
const plistDir = `${process.env.HOME}/Library/LaunchAgents`;
|
|
5298
5340
|
return `(launchctl bootstrap gui/${uid} ${plistDir}/${info.launchdLabel}.plist 2>/dev/null || true) && launchctl kickstart gui/${uid}/${info.launchdLabel}`;
|
|
5299
5341
|
}
|
|
5300
|
-
var import_node_fs3, import_node_path4, import_node_os2, import_node_child_process, import_node_child_process2, import_node_util, http, execAsync;
|
|
5342
|
+
var import_node_fs3, import_node_path4, import_node_os2, import_node_child_process, import_node_child_process2, import_node_util, http, execAsync, PLATFORM;
|
|
5301
5343
|
var init_openclaw = __esm({
|
|
5302
5344
|
"src/core/openclaw.ts"() {
|
|
5303
5345
|
"use strict";
|
|
@@ -5309,6 +5351,7 @@ var init_openclaw = __esm({
|
|
|
5309
5351
|
import_node_util = require("util");
|
|
5310
5352
|
http = __toESM(require("http"), 1);
|
|
5311
5353
|
execAsync = (0, import_node_util.promisify)(import_node_child_process2.exec);
|
|
5354
|
+
PLATFORM = (0, import_node_os2.platform)();
|
|
5312
5355
|
}
|
|
5313
5356
|
});
|
|
5314
5357
|
|
|
@@ -6342,13 +6385,13 @@ var init_server = __esm({
|
|
|
6342
6385
|
init_process_manager();
|
|
6343
6386
|
init_workspace_scanner();
|
|
6344
6387
|
init_cost_scanner();
|
|
6345
|
-
_PKG_VER = true ? "0.7.
|
|
6388
|
+
_PKG_VER = true ? "0.7.2" : "0.2.1";
|
|
6346
6389
|
pkgVersion = _PKG_VER;
|
|
6347
6390
|
}
|
|
6348
6391
|
});
|
|
6349
6392
|
|
|
6350
6393
|
// src/index.ts
|
|
6351
|
-
var
|
|
6394
|
+
var import_node_child_process8 = require("child_process");
|
|
6352
6395
|
|
|
6353
6396
|
// node_modules/commander/esm.mjs
|
|
6354
6397
|
var import_index = __toESM(require_commander(), 1);
|
|
@@ -6392,7 +6435,7 @@ var API_SECRET = "qkqms1nURj2S02Q3WqO7GQ";
|
|
|
6392
6435
|
var ENDPOINT = `https://www.google-analytics.com/mp/collect?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`;
|
|
6393
6436
|
var TELEMETRY_FILE = (0, import_node_path5.join)(APP_HOME, "telemetry.json");
|
|
6394
6437
|
var SESSION_ID = (0, import_node_crypto.randomUUID)();
|
|
6395
|
-
var _version = true ? "0.7.
|
|
6438
|
+
var _version = true ? "0.7.2" : "0.0.0";
|
|
6396
6439
|
function getVersion() {
|
|
6397
6440
|
return _version;
|
|
6398
6441
|
}
|
|
@@ -6901,22 +6944,22 @@ function showLogs(options) {
|
|
|
6901
6944
|
console.log();
|
|
6902
6945
|
}
|
|
6903
6946
|
function showDoctorLogs(maxLines) {
|
|
6904
|
-
const { readdirSync:
|
|
6905
|
-
const { join:
|
|
6947
|
+
const { readdirSync: readdirSync7 } = require("fs");
|
|
6948
|
+
const { join: join14 } = require("path");
|
|
6906
6949
|
if (!(0, import_node_fs10.existsSync)(DOCTOR_LOG_DIR)) {
|
|
6907
6950
|
console.log(import_chalk6.default.yellow("No doctor logs found."));
|
|
6908
6951
|
return;
|
|
6909
6952
|
}
|
|
6910
|
-
const files =
|
|
6953
|
+
const files = readdirSync7(DOCTOR_LOG_DIR).filter((f) => f.endsWith(".log")).sort().reverse();
|
|
6911
6954
|
if (files.length === 0) {
|
|
6912
6955
|
console.log(import_chalk6.default.yellow("No doctor log files found."));
|
|
6913
6956
|
return;
|
|
6914
6957
|
}
|
|
6915
6958
|
const latest = files[0];
|
|
6916
6959
|
console.log(import_chalk6.default.blue.bold(`
|
|
6917
|
-
${
|
|
6960
|
+
${join14(DOCTOR_LOG_DIR, latest)}
|
|
6918
6961
|
`));
|
|
6919
|
-
const content = (0, import_node_fs10.readFileSync)(
|
|
6962
|
+
const content = (0, import_node_fs10.readFileSync)(join14(DOCTOR_LOG_DIR, latest), "utf-8");
|
|
6920
6963
|
const lines = content.trim().split("\n");
|
|
6921
6964
|
const tail = lines.slice(-maxLines);
|
|
6922
6965
|
for (const line of tail) {
|
|
@@ -6936,13 +6979,20 @@ function showDoctorLogs(maxLines) {
|
|
|
6936
6979
|
// src/commands/gateway.ts
|
|
6937
6980
|
var import_chalk7 = __toESM(require_source(), 1);
|
|
6938
6981
|
var import_node_fs11 = require("fs");
|
|
6982
|
+
var import_node_os6 = require("os");
|
|
6939
6983
|
init_config();
|
|
6940
6984
|
init_config();
|
|
6941
6985
|
init_openclaw();
|
|
6942
6986
|
init_process_manager();
|
|
6943
6987
|
init_logger();
|
|
6944
|
-
|
|
6988
|
+
function showPlatformNote() {
|
|
6989
|
+
if ((0, import_node_os6.platform)() === "linux") {
|
|
6990
|
+
console.log(import_chalk7.default.cyan("Running on Linux/WSL. Using systemd or direct process management (launchctl not available)."));
|
|
6991
|
+
}
|
|
6992
|
+
}
|
|
6993
|
+
var _VER = true ? "0.7.2" : void 0;
|
|
6945
6994
|
async function gatewayStart(options) {
|
|
6995
|
+
showPlatformNote();
|
|
6946
6996
|
const config = loadConfig(options.config);
|
|
6947
6997
|
initLogger();
|
|
6948
6998
|
ensureDoctorHome();
|
|
@@ -6964,6 +7014,7 @@ async function gatewayStart(options) {
|
|
|
6964
7014
|
}
|
|
6965
7015
|
}
|
|
6966
7016
|
async function gatewayStop(options) {
|
|
7017
|
+
showPlatformNote();
|
|
6967
7018
|
const config = loadConfig(options.config);
|
|
6968
7019
|
initLogger();
|
|
6969
7020
|
ensureDoctorHome();
|
|
@@ -6983,6 +7034,7 @@ async function gatewayStop(options) {
|
|
|
6983
7034
|
}
|
|
6984
7035
|
}
|
|
6985
7036
|
async function gatewayRestart(options) {
|
|
7037
|
+
showPlatformNote();
|
|
6986
7038
|
const config = loadConfig(options.config);
|
|
6987
7039
|
initLogger();
|
|
6988
7040
|
ensureDoctorHome();
|
|
@@ -7008,11 +7060,24 @@ async function gatewayRestart(options) {
|
|
|
7008
7060
|
var import_chalk8 = __toESM(require_source(), 1);
|
|
7009
7061
|
var import_node_fs12 = require("fs");
|
|
7010
7062
|
var import_node_path10 = require("path");
|
|
7011
|
-
var
|
|
7063
|
+
var import_node_os7 = require("os");
|
|
7064
|
+
var import_node_readline = require("readline");
|
|
7012
7065
|
init_config();
|
|
7013
7066
|
init_openclaw();
|
|
7014
7067
|
function expandHome2(p) {
|
|
7015
|
-
return p.startsWith("~/") ? (0, import_node_path10.join)((0,
|
|
7068
|
+
return p.startsWith("~/") ? (0, import_node_path10.join)((0, import_node_os7.homedir)(), p.slice(2)) : p;
|
|
7069
|
+
}
|
|
7070
|
+
function getAgentMemoryPaths(agents) {
|
|
7071
|
+
const paths = [];
|
|
7072
|
+
for (const agent of agents) {
|
|
7073
|
+
const ws = agent.workspace;
|
|
7074
|
+
if (!ws) continue;
|
|
7075
|
+
const wsPath = expandHome2(ws);
|
|
7076
|
+
if ((0, import_node_fs12.existsSync)(wsPath)) {
|
|
7077
|
+
paths.push({ agent: agent.name, dir: wsPath });
|
|
7078
|
+
}
|
|
7079
|
+
}
|
|
7080
|
+
return paths;
|
|
7016
7081
|
}
|
|
7017
7082
|
async function memoryStatus(options) {
|
|
7018
7083
|
const config = loadConfig(options.config);
|
|
@@ -7038,11 +7103,54 @@ async function memorySearch(query, options) {
|
|
|
7038
7103
|
console.log(import_chalk8.default.bold(`
|
|
7039
7104
|
Searching memory: "${query}"
|
|
7040
7105
|
`));
|
|
7041
|
-
const
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7106
|
+
const agentPaths = getAgentMemoryPaths(info.agents);
|
|
7107
|
+
let found = false;
|
|
7108
|
+
for (const { agent, dir } of agentPaths) {
|
|
7109
|
+
const filesToSearch = [];
|
|
7110
|
+
const memPath = (0, import_node_path10.join)(dir, "MEMORY.md");
|
|
7111
|
+
if ((0, import_node_fs12.existsSync)(memPath)) filesToSearch.push(memPath);
|
|
7112
|
+
const memDir = (0, import_node_path10.join)(dir, "memory");
|
|
7113
|
+
if ((0, import_node_fs12.existsSync)(memDir)) {
|
|
7114
|
+
try {
|
|
7115
|
+
const files = (0, import_node_fs12.readdirSync)(memDir).filter((f) => f.endsWith(".md"));
|
|
7116
|
+
for (const f of files) {
|
|
7117
|
+
filesToSearch.push((0, import_node_path10.join)(memDir, f));
|
|
7118
|
+
}
|
|
7119
|
+
} catch {
|
|
7120
|
+
}
|
|
7121
|
+
}
|
|
7122
|
+
for (const filePath of filesToSearch) {
|
|
7123
|
+
try {
|
|
7124
|
+
const content = (0, import_node_fs12.readFileSync)(filePath, "utf-8");
|
|
7125
|
+
const lines = content.split("\n");
|
|
7126
|
+
const lowerQuery = query.toLowerCase();
|
|
7127
|
+
for (let i = 0; i < lines.length; i++) {
|
|
7128
|
+
if (lines[i].toLowerCase().includes(lowerQuery)) {
|
|
7129
|
+
if (!found) found = true;
|
|
7130
|
+
const relPath = (0, import_node_path10.basename)(filePath);
|
|
7131
|
+
const contextStart = Math.max(0, i - 1);
|
|
7132
|
+
const contextEnd = Math.min(lines.length, i + 2);
|
|
7133
|
+
const context = lines.slice(contextStart, contextEnd).map((l, idx) => {
|
|
7134
|
+
const lineNum = contextStart + idx + 1;
|
|
7135
|
+
const prefix = lineNum === i + 1 ? import_chalk8.default.yellow("\u2192") : " ";
|
|
7136
|
+
return ` ${prefix} ${import_chalk8.default.gray(`${lineNum}:`)} ${l}`;
|
|
7137
|
+
}).join("\n");
|
|
7138
|
+
console.log(` ${import_chalk8.default.cyan(agent)} ${import_chalk8.default.gray("/")} ${import_chalk8.default.white(relPath)}${import_chalk8.default.gray(`:${i + 1}`)}`);
|
|
7139
|
+
console.log(context);
|
|
7140
|
+
console.log();
|
|
7141
|
+
}
|
|
7142
|
+
}
|
|
7143
|
+
} catch {
|
|
7144
|
+
}
|
|
7145
|
+
}
|
|
7146
|
+
}
|
|
7147
|
+
if (!found) {
|
|
7148
|
+
const output = await runOpenClawCmd(info, `memory search "${query}"`);
|
|
7149
|
+
if (output) {
|
|
7150
|
+
console.log(output);
|
|
7151
|
+
} else {
|
|
7152
|
+
console.log(import_chalk8.default.yellow(" No results found."));
|
|
7153
|
+
}
|
|
7046
7154
|
}
|
|
7047
7155
|
console.log();
|
|
7048
7156
|
}
|
|
@@ -7061,39 +7169,515 @@ async function memoryCompact(options) {
|
|
|
7061
7169
|
}
|
|
7062
7170
|
console.log();
|
|
7063
7171
|
}
|
|
7172
|
+
async function memoryGc(options) {
|
|
7173
|
+
const config = loadConfig(options.config);
|
|
7174
|
+
const info = detectOpenClaw(options.profile ?? config.openclawProfile);
|
|
7175
|
+
const maxAgeDays = parseInt(options.days ?? "30", 10);
|
|
7176
|
+
const cutoff = Date.now() - maxAgeDays * 24 * 3600 * 1e3;
|
|
7177
|
+
console.log(import_chalk8.default.bold(`
|
|
7178
|
+
Memory GC \u2014 removing daily files older than ${maxAgeDays} days
|
|
7179
|
+
`));
|
|
7180
|
+
const agentPaths = getAgentMemoryPaths(info.agents);
|
|
7181
|
+
const filesToDelete = [];
|
|
7182
|
+
const dailyPattern = /^\d{4}-\d{2}-\d{2}\.md$/;
|
|
7183
|
+
for (const { agent, dir } of agentPaths) {
|
|
7184
|
+
const memDir = (0, import_node_path10.join)(dir, "memory");
|
|
7185
|
+
if (!(0, import_node_fs12.existsSync)(memDir)) continue;
|
|
7186
|
+
try {
|
|
7187
|
+
const files = (0, import_node_fs12.readdirSync)(memDir).filter((f) => dailyPattern.test(f));
|
|
7188
|
+
for (const f of files) {
|
|
7189
|
+
const fpath = (0, import_node_path10.join)(memDir, f);
|
|
7190
|
+
try {
|
|
7191
|
+
const stat = (0, import_node_fs12.statSync)(fpath);
|
|
7192
|
+
if (stat.mtimeMs < cutoff) {
|
|
7193
|
+
filesToDelete.push({ path: fpath, agent, name: f, size: stat.size });
|
|
7194
|
+
}
|
|
7195
|
+
} catch {
|
|
7196
|
+
}
|
|
7197
|
+
}
|
|
7198
|
+
} catch {
|
|
7199
|
+
}
|
|
7200
|
+
}
|
|
7201
|
+
if (filesToDelete.length === 0) {
|
|
7202
|
+
console.log(import_chalk8.default.green(" No old daily memory files found. Nothing to clean up.\n"));
|
|
7203
|
+
return;
|
|
7204
|
+
}
|
|
7205
|
+
console.log(` Found ${import_chalk8.default.yellow(String(filesToDelete.length))} files to remove:
|
|
7206
|
+
`);
|
|
7207
|
+
for (const f of filesToDelete) {
|
|
7208
|
+
const sizeKB = Math.round(f.size / 1024);
|
|
7209
|
+
console.log(` ${import_chalk8.default.gray("\u2022")} ${f.agent} / ${f.name} ${import_chalk8.default.gray(`(${sizeKB}KB)`)}`);
|
|
7210
|
+
}
|
|
7211
|
+
console.log();
|
|
7212
|
+
const totalKB = Math.round(filesToDelete.reduce((s, f) => s + f.size, 0) / 1024);
|
|
7213
|
+
console.log(` Total: ${import_chalk8.default.yellow(`${totalKB}KB`)} across ${filesToDelete.length} files
|
|
7214
|
+
`);
|
|
7215
|
+
if (!options.force) {
|
|
7216
|
+
const rl = (0, import_node_readline.createInterface)({ input: process.stdin, output: process.stdout });
|
|
7217
|
+
const answer = await new Promise((resolve3) => {
|
|
7218
|
+
rl.question(" Delete these files? [y/N] ", resolve3);
|
|
7219
|
+
});
|
|
7220
|
+
rl.close();
|
|
7221
|
+
if (answer.toLowerCase() !== "y") {
|
|
7222
|
+
console.log(import_chalk8.default.gray(" Cancelled.\n"));
|
|
7223
|
+
return;
|
|
7224
|
+
}
|
|
7225
|
+
}
|
|
7226
|
+
let deleted = 0;
|
|
7227
|
+
for (const f of filesToDelete) {
|
|
7228
|
+
try {
|
|
7229
|
+
(0, import_node_fs12.unlinkSync)(f.path);
|
|
7230
|
+
deleted++;
|
|
7231
|
+
} catch (err) {
|
|
7232
|
+
console.log(import_chalk8.default.red(` Failed to delete ${f.name}: ${err}`));
|
|
7233
|
+
}
|
|
7234
|
+
}
|
|
7235
|
+
console.log(import_chalk8.default.green(`
|
|
7236
|
+
Deleted ${deleted} files.
|
|
7237
|
+
`));
|
|
7238
|
+
}
|
|
7239
|
+
async function memoryExport(options) {
|
|
7240
|
+
const config = loadConfig(options.config);
|
|
7241
|
+
const info = detectOpenClaw(options.profile ?? config.openclawProfile);
|
|
7242
|
+
const agentPaths = getAgentMemoryPaths(info.agents);
|
|
7243
|
+
const parts = [];
|
|
7244
|
+
parts.push(`# OpenClaw Memory Export`);
|
|
7245
|
+
parts.push(`# Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
7246
|
+
`);
|
|
7247
|
+
for (const { agent, dir } of agentPaths) {
|
|
7248
|
+
const agentParts = [];
|
|
7249
|
+
const memPath = (0, import_node_path10.join)(dir, "MEMORY.md");
|
|
7250
|
+
if ((0, import_node_fs12.existsSync)(memPath)) {
|
|
7251
|
+
try {
|
|
7252
|
+
const content = (0, import_node_fs12.readFileSync)(memPath, "utf-8");
|
|
7253
|
+
agentParts.push(`### MEMORY.md
|
|
7254
|
+
|
|
7255
|
+
${content}`);
|
|
7256
|
+
} catch {
|
|
7257
|
+
}
|
|
7258
|
+
}
|
|
7259
|
+
const memDir = (0, import_node_path10.join)(dir, "memory");
|
|
7260
|
+
if ((0, import_node_fs12.existsSync)(memDir)) {
|
|
7261
|
+
try {
|
|
7262
|
+
const files = (0, import_node_fs12.readdirSync)(memDir).filter((f) => f.endsWith(".md")).sort();
|
|
7263
|
+
for (const f of files) {
|
|
7264
|
+
try {
|
|
7265
|
+
const content = (0, import_node_fs12.readFileSync)((0, import_node_path10.join)(memDir, f), "utf-8");
|
|
7266
|
+
agentParts.push(`### memory/${f}
|
|
7267
|
+
|
|
7268
|
+
${content}`);
|
|
7269
|
+
} catch {
|
|
7270
|
+
}
|
|
7271
|
+
}
|
|
7272
|
+
} catch {
|
|
7273
|
+
}
|
|
7274
|
+
}
|
|
7275
|
+
if (agentParts.length > 0) {
|
|
7276
|
+
parts.push(`## Agent: ${agent}
|
|
7277
|
+
`);
|
|
7278
|
+
parts.push(agentParts.join("\n---\n\n"));
|
|
7279
|
+
parts.push("");
|
|
7280
|
+
}
|
|
7281
|
+
}
|
|
7282
|
+
if (parts.length <= 2) {
|
|
7283
|
+
console.log(import_chalk8.default.yellow("\n No memory files found to export.\n"));
|
|
7284
|
+
return;
|
|
7285
|
+
}
|
|
7286
|
+
const result = parts.join("\n");
|
|
7287
|
+
if (options.output) {
|
|
7288
|
+
(0, import_node_fs12.writeFileSync)(options.output, result, "utf-8");
|
|
7289
|
+
console.log(import_chalk8.default.green(`
|
|
7290
|
+
Exported memory to ${options.output}
|
|
7291
|
+
`));
|
|
7292
|
+
} else {
|
|
7293
|
+
console.log(result);
|
|
7294
|
+
}
|
|
7295
|
+
}
|
|
7296
|
+
|
|
7297
|
+
// src/commands/cost.ts
|
|
7298
|
+
var import_chalk9 = __toESM(require_source(), 1);
|
|
7299
|
+
var import_node_fs13 = require("fs");
|
|
7300
|
+
var import_node_path11 = require("path");
|
|
7301
|
+
var import_node_os8 = require("os");
|
|
7302
|
+
init_config();
|
|
7303
|
+
init_openclaw();
|
|
7304
|
+
var RATES = {
|
|
7305
|
+
"claude-opus-4": { input: 15, output: 75 },
|
|
7306
|
+
"claude-sonnet-4": { input: 3, output: 15 },
|
|
7307
|
+
"claude-haiku-3-5": { input: 0.8, output: 4 },
|
|
7308
|
+
"gpt-4o": { input: 2.5, output: 10 },
|
|
7309
|
+
"gpt-4o-mini": { input: 0.15, output: 0.6 }
|
|
7310
|
+
};
|
|
7311
|
+
var DEFAULT_RATE = { input: 3, output: 15 };
|
|
7312
|
+
function getRate(model) {
|
|
7313
|
+
if (RATES[model]) return RATES[model];
|
|
7314
|
+
for (const [key, rate] of Object.entries(RATES)) {
|
|
7315
|
+
if (model.startsWith(key)) return rate;
|
|
7316
|
+
}
|
|
7317
|
+
return DEFAULT_RATE;
|
|
7318
|
+
}
|
|
7319
|
+
function calcCost(model, inputTokens, outputTokens) {
|
|
7320
|
+
const rate = getRate(model);
|
|
7321
|
+
return (inputTokens * rate.input + outputTokens * rate.output) / 1e6;
|
|
7322
|
+
}
|
|
7323
|
+
function expandHome3(p) {
|
|
7324
|
+
return p.startsWith("~/") ? (0, import_node_path11.join)((0, import_node_os8.homedir)(), p.slice(2)) : p;
|
|
7325
|
+
}
|
|
7326
|
+
function scanSessionFiles(agents, sinceDays) {
|
|
7327
|
+
const entries = [];
|
|
7328
|
+
const cutoff = Date.now() - sinceDays * 24 * 3600 * 1e3;
|
|
7329
|
+
for (const agent of agents) {
|
|
7330
|
+
const searchPaths = [];
|
|
7331
|
+
searchPaths.push((0, import_node_path11.join)((0, import_node_os8.homedir)(), ".openclaw", "agents", agent.id, "sessions"));
|
|
7332
|
+
if (agent.workspace) {
|
|
7333
|
+
const ws = expandHome3(agent.workspace);
|
|
7334
|
+
searchPaths.push((0, import_node_path11.join)(ws, "sessions"));
|
|
7335
|
+
searchPaths.push((0, import_node_path11.join)(ws, "logs"));
|
|
7336
|
+
}
|
|
7337
|
+
for (const sessDir of searchPaths) {
|
|
7338
|
+
if (!(0, import_node_fs13.existsSync)(sessDir)) continue;
|
|
7339
|
+
const files = (0, import_node_fs13.readdirSync)(sessDir).filter((f) => f.endsWith(".jsonl") || f.endsWith(".json"));
|
|
7340
|
+
for (const file of files) {
|
|
7341
|
+
const fpath = (0, import_node_path11.join)(sessDir, file);
|
|
7342
|
+
try {
|
|
7343
|
+
const mtime = (0, import_node_fs13.statSync)(fpath).mtimeMs;
|
|
7344
|
+
if (mtime < cutoff) continue;
|
|
7345
|
+
} catch {
|
|
7346
|
+
continue;
|
|
7347
|
+
}
|
|
7348
|
+
try {
|
|
7349
|
+
const lines = (0, import_node_fs13.readFileSync)(fpath, "utf-8").split("\n").filter(Boolean);
|
|
7350
|
+
for (const line of lines) {
|
|
7351
|
+
try {
|
|
7352
|
+
const msg = JSON.parse(line);
|
|
7353
|
+
if (msg.type !== "message" || !msg.message?.usage) continue;
|
|
7354
|
+
const usage = msg.message.usage;
|
|
7355
|
+
const ts = msg.timestamp ? new Date(msg.timestamp).getTime() : msg.message?.timestamp ?? 0;
|
|
7356
|
+
if (ts < cutoff) continue;
|
|
7357
|
+
const model = msg.message?.model ?? msg.model ?? "unknown";
|
|
7358
|
+
const inputTokens = usage.input_tokens ?? usage.inputTokens ?? 0;
|
|
7359
|
+
const outputTokens = usage.output_tokens ?? usage.outputTokens ?? 0;
|
|
7360
|
+
if (inputTokens === 0 && outputTokens === 0) continue;
|
|
7361
|
+
entries.push({
|
|
7362
|
+
model,
|
|
7363
|
+
inputTokens,
|
|
7364
|
+
outputTokens,
|
|
7365
|
+
timestamp: ts,
|
|
7366
|
+
agentName: agent.name,
|
|
7367
|
+
agentId: agent.id
|
|
7368
|
+
});
|
|
7369
|
+
} catch {
|
|
7370
|
+
}
|
|
7371
|
+
}
|
|
7372
|
+
} catch {
|
|
7373
|
+
}
|
|
7374
|
+
}
|
|
7375
|
+
}
|
|
7376
|
+
}
|
|
7377
|
+
const globalLogDir = (0, import_node_path11.join)((0, import_node_os8.homedir)(), ".openclaw", "logs");
|
|
7378
|
+
if ((0, import_node_fs13.existsSync)(globalLogDir)) {
|
|
7379
|
+
const files = (0, import_node_fs13.readdirSync)(globalLogDir).filter((f) => f.endsWith(".jsonl"));
|
|
7380
|
+
for (const file of files) {
|
|
7381
|
+
const fpath = (0, import_node_path11.join)(globalLogDir, file);
|
|
7382
|
+
try {
|
|
7383
|
+
const mtime = (0, import_node_fs13.statSync)(fpath).mtimeMs;
|
|
7384
|
+
if (mtime < cutoff) continue;
|
|
7385
|
+
} catch {
|
|
7386
|
+
continue;
|
|
7387
|
+
}
|
|
7388
|
+
try {
|
|
7389
|
+
const lines = (0, import_node_fs13.readFileSync)(fpath, "utf-8").split("\n").filter(Boolean);
|
|
7390
|
+
for (const line of lines) {
|
|
7391
|
+
try {
|
|
7392
|
+
const msg = JSON.parse(line);
|
|
7393
|
+
if (msg.type !== "message" || !msg.message?.usage) continue;
|
|
7394
|
+
const usage = msg.message.usage;
|
|
7395
|
+
const ts = msg.timestamp ? new Date(msg.timestamp).getTime() : msg.message?.timestamp ?? 0;
|
|
7396
|
+
if (ts < cutoff) continue;
|
|
7397
|
+
const model = msg.message?.model ?? msg.model ?? "unknown";
|
|
7398
|
+
const inputTokens = usage.input_tokens ?? usage.inputTokens ?? 0;
|
|
7399
|
+
const outputTokens = usage.output_tokens ?? usage.outputTokens ?? 0;
|
|
7400
|
+
if (inputTokens === 0 && outputTokens === 0) continue;
|
|
7401
|
+
const agentId = msg.agentId ?? msg.message?.agentId ?? "unknown";
|
|
7402
|
+
const agentName = msg.agentName ?? msg.message?.agentName ?? agentId;
|
|
7403
|
+
entries.push({ model, inputTokens, outputTokens, timestamp: ts, agentName, agentId });
|
|
7404
|
+
} catch {
|
|
7405
|
+
}
|
|
7406
|
+
}
|
|
7407
|
+
} catch {
|
|
7408
|
+
}
|
|
7409
|
+
}
|
|
7410
|
+
}
|
|
7411
|
+
return entries;
|
|
7412
|
+
}
|
|
7413
|
+
function formatCost(cost) {
|
|
7414
|
+
if (cost < 0.01) return `$${cost.toFixed(4)}`;
|
|
7415
|
+
return `$${cost.toFixed(2)}`;
|
|
7416
|
+
}
|
|
7417
|
+
function formatTokens(n) {
|
|
7418
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
7419
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
7420
|
+
return String(n);
|
|
7421
|
+
}
|
|
7422
|
+
async function showCost(options) {
|
|
7423
|
+
const config = loadConfig(options.config);
|
|
7424
|
+
const info = detectOpenClaw(options.profile ?? config.openclawProfile);
|
|
7425
|
+
const days = parseInt(options.days ?? "30", 10);
|
|
7426
|
+
if (info.agents.length === 0) {
|
|
7427
|
+
console.log(import_chalk9.default.yellow("\n No agents found in openclaw config."));
|
|
7428
|
+
console.log(import_chalk9.default.gray(" Make sure openclaw is installed and configured.\n"));
|
|
7429
|
+
return;
|
|
7430
|
+
}
|
|
7431
|
+
const entries = scanSessionFiles(
|
|
7432
|
+
info.agents.map((a) => ({ id: a.id, name: a.name, workspace: a.workspace })),
|
|
7433
|
+
days
|
|
7434
|
+
);
|
|
7435
|
+
if (entries.length === 0) {
|
|
7436
|
+
console.log(import_chalk9.default.yellow("\n No session logs found."));
|
|
7437
|
+
console.log(import_chalk9.default.gray(" OpenClaw stores session logs in:"));
|
|
7438
|
+
console.log(import_chalk9.default.gray(` ~/.openclaw/agents/<agent-id>/sessions/`));
|
|
7439
|
+
console.log(import_chalk9.default.gray(` ~/.openclaw/logs/
|
|
7440
|
+
`));
|
|
7441
|
+
return;
|
|
7442
|
+
}
|
|
7443
|
+
const now = Date.now();
|
|
7444
|
+
const todayStart = /* @__PURE__ */ new Date();
|
|
7445
|
+
todayStart.setHours(0, 0, 0, 0);
|
|
7446
|
+
const weekStart = now - 7 * 24 * 3600 * 1e3;
|
|
7447
|
+
const monthStart = now - 30 * 24 * 3600 * 1e3;
|
|
7448
|
+
const byAgent = {};
|
|
7449
|
+
const byModel = {};
|
|
7450
|
+
for (const e of entries) {
|
|
7451
|
+
const cost = calcCost(e.model, e.inputTokens, e.outputTokens);
|
|
7452
|
+
if (!byAgent[e.agentName]) byAgent[e.agentName] = { today: 0, week: 0, month: 0, tokens: 0 };
|
|
7453
|
+
const ag = byAgent[e.agentName];
|
|
7454
|
+
ag.tokens += e.inputTokens + e.outputTokens;
|
|
7455
|
+
if (e.timestamp >= monthStart) ag.month += cost;
|
|
7456
|
+
if (e.timestamp >= weekStart) ag.week += cost;
|
|
7457
|
+
if (e.timestamp >= todayStart.getTime()) ag.today += cost;
|
|
7458
|
+
if (!byModel[e.model]) byModel[e.model] = { today: 0, week: 0, month: 0, input: 0, output: 0 };
|
|
7459
|
+
const md = byModel[e.model];
|
|
7460
|
+
md.input += e.inputTokens;
|
|
7461
|
+
md.output += e.outputTokens;
|
|
7462
|
+
if (e.timestamp >= monthStart) md.month += cost;
|
|
7463
|
+
if (e.timestamp >= weekStart) md.week += cost;
|
|
7464
|
+
if (e.timestamp >= todayStart.getTime()) md.today += cost;
|
|
7465
|
+
}
|
|
7466
|
+
const totalToday = Object.values(byAgent).reduce((s, a) => s + a.today, 0);
|
|
7467
|
+
const totalWeek = Object.values(byAgent).reduce((s, a) => s + a.week, 0);
|
|
7468
|
+
const totalMonth = Object.values(byAgent).reduce((s, a) => s + a.month, 0);
|
|
7469
|
+
if (options.json) {
|
|
7470
|
+
console.log(JSON.stringify({
|
|
7471
|
+
period: { days },
|
|
7472
|
+
summary: { today: totalToday, week: totalWeek, month: totalMonth, currency: "USD" },
|
|
7473
|
+
byAgent: Object.entries(byAgent).map(([name, v]) => ({ name, ...v })),
|
|
7474
|
+
byModel: Object.entries(byModel).map(([model, v]) => ({ model, ...v })),
|
|
7475
|
+
entries: entries.length
|
|
7476
|
+
}, null, 2));
|
|
7477
|
+
return;
|
|
7478
|
+
}
|
|
7479
|
+
console.log(import_chalk9.default.bold("\n Token Cost Summary\n"));
|
|
7480
|
+
console.log(` ${"Period".padEnd(14)} ${"Cost".padStart(10)}`);
|
|
7481
|
+
console.log(` ${"\u2500".repeat(14)} ${"\u2500".repeat(10)}`);
|
|
7482
|
+
console.log(` ${"Today".padEnd(14)} ${import_chalk9.default.green(formatCost(totalToday).padStart(10))}`);
|
|
7483
|
+
console.log(` ${"This week".padEnd(14)} ${import_chalk9.default.cyan(formatCost(totalWeek).padStart(10))}`);
|
|
7484
|
+
console.log(` ${"Last 30 days".padEnd(14)} ${import_chalk9.default.yellow(formatCost(totalMonth).padStart(10))}`);
|
|
7485
|
+
const agentEntries = Object.entries(byAgent).sort((a, b) => b[1].month - a[1].month);
|
|
7486
|
+
if (agentEntries.length > 0) {
|
|
7487
|
+
console.log(import_chalk9.default.bold("\n By Agent\n"));
|
|
7488
|
+
console.log(` ${"Agent".padEnd(20)} ${"Today".padStart(10)} ${"Week".padStart(10)} ${"Month".padStart(10)} ${"Tokens".padStart(10)}`);
|
|
7489
|
+
console.log(` ${"\u2500".repeat(20)} ${"\u2500".repeat(10)} ${"\u2500".repeat(10)} ${"\u2500".repeat(10)} ${"\u2500".repeat(10)}`);
|
|
7490
|
+
for (const [name, v] of agentEntries) {
|
|
7491
|
+
console.log(` ${name.padEnd(20)} ${formatCost(v.today).padStart(10)} ${formatCost(v.week).padStart(10)} ${formatCost(v.month).padStart(10)} ${import_chalk9.default.gray(formatTokens(v.tokens).padStart(10))}`);
|
|
7492
|
+
}
|
|
7493
|
+
}
|
|
7494
|
+
const modelEntries = Object.entries(byModel).sort((a, b) => b[1].month - a[1].month);
|
|
7495
|
+
if (modelEntries.length > 0) {
|
|
7496
|
+
console.log(import_chalk9.default.bold("\n By Model\n"));
|
|
7497
|
+
console.log(` ${"Model".padEnd(24)} ${"Today".padStart(10)} ${"Week".padStart(10)} ${"Month".padStart(10)} ${"In Tokens".padStart(10)} ${"Out Tokens".padStart(10)}`);
|
|
7498
|
+
console.log(` ${"\u2500".repeat(24)} ${"\u2500".repeat(10)} ${"\u2500".repeat(10)} ${"\u2500".repeat(10)} ${"\u2500".repeat(10)} ${"\u2500".repeat(10)}`);
|
|
7499
|
+
for (const [model, v] of modelEntries) {
|
|
7500
|
+
console.log(` ${model.padEnd(24)} ${formatCost(v.today).padStart(10)} ${formatCost(v.week).padStart(10)} ${formatCost(v.month).padStart(10)} ${import_chalk9.default.gray(formatTokens(v.input).padStart(10))} ${import_chalk9.default.gray(formatTokens(v.output).padStart(10))}`);
|
|
7501
|
+
}
|
|
7502
|
+
}
|
|
7503
|
+
console.log();
|
|
7504
|
+
}
|
|
7505
|
+
|
|
7506
|
+
// src/commands/mcp.ts
|
|
7507
|
+
var import_chalk10 = __toESM(require_source(), 1);
|
|
7508
|
+
var import_node_fs14 = require("fs");
|
|
7509
|
+
var import_node_path12 = require("path");
|
|
7510
|
+
var import_node_os9 = require("os");
|
|
7511
|
+
var import_node_child_process6 = require("child_process");
|
|
7512
|
+
var CONFIG_LOCATIONS = [
|
|
7513
|
+
{ path: (0, import_node_path12.join)((0, import_node_os9.homedir)(), ".config", "claude", "claude_desktop_config.json"), label: "Claude Desktop" },
|
|
7514
|
+
{ path: (0, import_node_path12.join)((0, import_node_os9.homedir)(), "Library", "Application Support", "Claude", "claude_desktop_config.json"), label: "Claude Desktop (macOS)" },
|
|
7515
|
+
{ path: (0, import_node_path12.join)((0, import_node_os9.homedir)(), ".config", "cursor", "mcp.json"), label: "Cursor" },
|
|
7516
|
+
{ path: (0, import_node_path12.join)((0, import_node_os9.homedir)(), ".openclaw", "config.yaml"), label: "OpenClaw" },
|
|
7517
|
+
{ path: (0, import_node_path12.join)((0, import_node_os9.homedir)(), ".openclaw", "mcp.json"), label: "OpenClaw MCP" }
|
|
7518
|
+
];
|
|
7519
|
+
function findMcpConfigs() {
|
|
7520
|
+
const servers = [];
|
|
7521
|
+
for (const loc of CONFIG_LOCATIONS) {
|
|
7522
|
+
if (!(0, import_node_fs14.existsSync)(loc.path)) continue;
|
|
7523
|
+
try {
|
|
7524
|
+
const raw = (0, import_node_fs14.readFileSync)(loc.path, "utf-8");
|
|
7525
|
+
if (loc.path.endsWith(".yaml") || loc.path.endsWith(".yml")) {
|
|
7526
|
+
const mcpMatch = raw.match(/mcp_servers:\s*\n([\s\S]*?)(?:\n\w|\n*$)/);
|
|
7527
|
+
if (mcpMatch) {
|
|
7528
|
+
const lines = mcpMatch[1].split("\n");
|
|
7529
|
+
for (const line of lines) {
|
|
7530
|
+
const nameMatch = line.match(/^\s+-\s+name:\s*(.+)/);
|
|
7531
|
+
if (nameMatch) {
|
|
7532
|
+
servers.push({
|
|
7533
|
+
name: nameMatch[1].trim(),
|
|
7534
|
+
type: "unknown",
|
|
7535
|
+
source: loc.label,
|
|
7536
|
+
status: "UNKNOWN"
|
|
7537
|
+
});
|
|
7538
|
+
}
|
|
7539
|
+
}
|
|
7540
|
+
}
|
|
7541
|
+
continue;
|
|
7542
|
+
}
|
|
7543
|
+
const config = JSON.parse(raw);
|
|
7544
|
+
const mcpServers = config.mcpServers ?? config.mcp_servers ?? config.servers ?? {};
|
|
7545
|
+
for (const [name, def] of Object.entries(mcpServers)) {
|
|
7546
|
+
const d = def;
|
|
7547
|
+
const server = {
|
|
7548
|
+
name,
|
|
7549
|
+
type: d.command ? "stdio" : d.url ? "http" : "unknown",
|
|
7550
|
+
command: d.command,
|
|
7551
|
+
url: d.url,
|
|
7552
|
+
args: d.args,
|
|
7553
|
+
env: d.env,
|
|
7554
|
+
source: loc.label,
|
|
7555
|
+
status: "UNKNOWN"
|
|
7556
|
+
};
|
|
7557
|
+
if (server.type === "stdio" && server.command) {
|
|
7558
|
+
server.status = checkProcessRunning(server.command) ? "RUNNING" : "STOPPED";
|
|
7559
|
+
} else if (server.type === "http") {
|
|
7560
|
+
server.status = "UNKNOWN";
|
|
7561
|
+
}
|
|
7562
|
+
servers.push(server);
|
|
7563
|
+
}
|
|
7564
|
+
} catch {
|
|
7565
|
+
}
|
|
7566
|
+
}
|
|
7567
|
+
return servers;
|
|
7568
|
+
}
|
|
7569
|
+
function checkProcessRunning(command) {
|
|
7570
|
+
try {
|
|
7571
|
+
const baseName = command.split("/").pop() ?? command;
|
|
7572
|
+
const result = (0, import_node_child_process6.execSync)(`pgrep -f "${baseName}"`, { encoding: "utf-8", timeout: 3e3 });
|
|
7573
|
+
return result.trim().length > 0;
|
|
7574
|
+
} catch {
|
|
7575
|
+
return false;
|
|
7576
|
+
}
|
|
7577
|
+
}
|
|
7578
|
+
function statusColor(status) {
|
|
7579
|
+
switch (status) {
|
|
7580
|
+
case "RUNNING":
|
|
7581
|
+
return import_chalk10.default.green(status);
|
|
7582
|
+
case "STOPPED":
|
|
7583
|
+
return import_chalk10.default.red(status);
|
|
7584
|
+
default:
|
|
7585
|
+
return import_chalk10.default.gray(status);
|
|
7586
|
+
}
|
|
7587
|
+
}
|
|
7588
|
+
async function mcpList() {
|
|
7589
|
+
const servers = findMcpConfigs();
|
|
7590
|
+
if (servers.length === 0) {
|
|
7591
|
+
console.log(import_chalk10.default.yellow("\n No MCP server configurations found."));
|
|
7592
|
+
console.log(import_chalk10.default.gray(" Checked:"));
|
|
7593
|
+
for (const loc of CONFIG_LOCATIONS) {
|
|
7594
|
+
console.log(import_chalk10.default.gray(` ${loc.path}`));
|
|
7595
|
+
}
|
|
7596
|
+
console.log(import_chalk10.default.gray("\n Configure MCP servers in Claude Desktop:"));
|
|
7597
|
+
console.log(import_chalk10.default.gray(` ${CONFIG_LOCATIONS[0].path}
|
|
7598
|
+
`));
|
|
7599
|
+
return;
|
|
7600
|
+
}
|
|
7601
|
+
console.log(import_chalk10.default.bold("\n MCP Servers\n"));
|
|
7602
|
+
console.log(` ${"Name".padEnd(24)} ${"Type".padEnd(8)} ${"Status".padEnd(12)} ${"Source".padEnd(20)} ${"Command/URL"}`);
|
|
7603
|
+
console.log(` ${"\u2500".repeat(24)} ${"\u2500".repeat(8)} ${"\u2500".repeat(12)} ${"\u2500".repeat(20)} ${"\u2500".repeat(30)}`);
|
|
7604
|
+
for (const s of servers) {
|
|
7605
|
+
const endpoint = s.command ? `${s.command}${s.args?.length ? " " + s.args.join(" ") : ""}` : s.url ?? "";
|
|
7606
|
+
const truncEndpoint = endpoint.length > 50 ? endpoint.slice(0, 47) + "..." : endpoint;
|
|
7607
|
+
console.log(
|
|
7608
|
+
` ${s.name.padEnd(24)} ${s.type.padEnd(8)} ${statusColor(s.status).padEnd(12 + 10)} ${import_chalk10.default.gray(s.source.padEnd(20))} ${import_chalk10.default.gray(truncEndpoint)}`
|
|
7609
|
+
);
|
|
7610
|
+
}
|
|
7611
|
+
console.log();
|
|
7612
|
+
}
|
|
7613
|
+
async function mcpStatus(name) {
|
|
7614
|
+
const servers = findMcpConfigs();
|
|
7615
|
+
const server = servers.find((s) => s.name === name);
|
|
7616
|
+
if (!server) {
|
|
7617
|
+
console.log(import_chalk10.default.red(`
|
|
7618
|
+
MCP server "${name}" not found.`));
|
|
7619
|
+
const available = servers.map((s) => s.name).join(", ");
|
|
7620
|
+
if (available) {
|
|
7621
|
+
console.log(import_chalk10.default.gray(` Available: ${available}
|
|
7622
|
+
`));
|
|
7623
|
+
} else {
|
|
7624
|
+
console.log(import_chalk10.default.gray(" No MCP servers configured.\n"));
|
|
7625
|
+
}
|
|
7626
|
+
return;
|
|
7627
|
+
}
|
|
7628
|
+
console.log(import_chalk10.default.bold(`
|
|
7629
|
+
MCP Server: ${server.name}
|
|
7630
|
+
`));
|
|
7631
|
+
console.log(` Status: ${statusColor(server.status)}`);
|
|
7632
|
+
console.log(` Type: ${server.type}`);
|
|
7633
|
+
console.log(` Source: ${import_chalk10.default.gray(server.source)}`);
|
|
7634
|
+
if (server.command) {
|
|
7635
|
+
console.log(` Command: ${server.command}`);
|
|
7636
|
+
if (server.args?.length) {
|
|
7637
|
+
console.log(` Args: ${server.args.join(" ")}`);
|
|
7638
|
+
}
|
|
7639
|
+
}
|
|
7640
|
+
if (server.url) {
|
|
7641
|
+
console.log(` URL: ${server.url}`);
|
|
7642
|
+
}
|
|
7643
|
+
if (server.env && Object.keys(server.env).length > 0) {
|
|
7644
|
+
console.log(` Env: ${Object.keys(server.env).join(", ")}`);
|
|
7645
|
+
}
|
|
7646
|
+
console.log();
|
|
7647
|
+
}
|
|
7064
7648
|
|
|
7065
7649
|
// src/index.ts
|
|
7066
7650
|
init_server();
|
|
7067
7651
|
init_openclaw();
|
|
7068
7652
|
|
|
7069
7653
|
// src/commands/telemetry.ts
|
|
7070
|
-
var
|
|
7654
|
+
var import_chalk11 = __toESM(require_source(), 1);
|
|
7071
7655
|
function telemetryOn() {
|
|
7072
7656
|
setOptOut(false);
|
|
7073
|
-
console.log(
|
|
7657
|
+
console.log(import_chalk11.default.green("\u2713 Telemetry enabled. Thanks for helping improve OpenClaw!"));
|
|
7074
7658
|
}
|
|
7075
7659
|
function telemetryOff() {
|
|
7076
7660
|
setOptOut(true);
|
|
7077
|
-
console.log(
|
|
7661
|
+
console.log(import_chalk11.default.yellow("\u2713 Telemetry disabled. Set OPENCLAW_NO_TELEMETRY=1 to suppress permanently."));
|
|
7078
7662
|
}
|
|
7079
7663
|
function telemetryStatus() {
|
|
7080
7664
|
const { optOut, clientId } = getTelemetryStatus();
|
|
7081
|
-
const status = optOut ?
|
|
7665
|
+
const status = optOut ? import_chalk11.default.red("disabled") : import_chalk11.default.green("enabled");
|
|
7082
7666
|
console.log(`Telemetry: ${status}`);
|
|
7083
|
-
console.log(`Client ID: ${
|
|
7667
|
+
console.log(`Client ID: ${import_chalk11.default.dim(clientId)}`);
|
|
7084
7668
|
console.log();
|
|
7085
|
-
console.log(
|
|
7086
|
-
console.log(
|
|
7669
|
+
console.log(import_chalk11.default.dim("Toggle: openclaw telemetry on/off"));
|
|
7670
|
+
console.log(import_chalk11.default.dim("Env: OPENCLAW_NO_TELEMETRY=1"));
|
|
7087
7671
|
}
|
|
7088
7672
|
|
|
7089
7673
|
// src/commands/remote.ts
|
|
7090
|
-
var
|
|
7091
|
-
var
|
|
7092
|
-
var
|
|
7674
|
+
var import_chalk12 = __toESM(require_source(), 1);
|
|
7675
|
+
var import_node_fs15 = require("fs");
|
|
7676
|
+
var import_node_path13 = require("path");
|
|
7093
7677
|
var import_node_crypto2 = require("crypto");
|
|
7094
7678
|
var import_node_http2 = require("http");
|
|
7095
|
-
var
|
|
7096
|
-
var
|
|
7679
|
+
var import_node_child_process7 = require("child_process");
|
|
7680
|
+
var import_node_os10 = require("os");
|
|
7097
7681
|
init_config();
|
|
7098
7682
|
async function proxyFetch(url, init) {
|
|
7099
7683
|
const proxyUrl = process.env.HTTPS_PROXY || process.env.https_proxy || process.env.ALL_PROXY || process.env.all_proxy;
|
|
@@ -7108,11 +7692,11 @@ async function proxyFetch(url, init) {
|
|
|
7108
7692
|
return fetch(url, init);
|
|
7109
7693
|
}
|
|
7110
7694
|
var REMOTE_API_URL = "https://api.openclaw-cli.app";
|
|
7111
|
-
var REMOTE_CONFIG_FILE = (0,
|
|
7695
|
+
var REMOTE_CONFIG_FILE = (0, import_node_path13.join)(DOCTOR_HOME, "remote.json");
|
|
7112
7696
|
function loadRemoteConfig() {
|
|
7113
7697
|
try {
|
|
7114
|
-
if ((0,
|
|
7115
|
-
return JSON.parse((0,
|
|
7698
|
+
if ((0, import_node_fs15.existsSync)(REMOTE_CONFIG_FILE)) {
|
|
7699
|
+
return JSON.parse((0, import_node_fs15.readFileSync)(REMOTE_CONFIG_FILE, "utf-8"));
|
|
7116
7700
|
}
|
|
7117
7701
|
} catch {
|
|
7118
7702
|
}
|
|
@@ -7125,9 +7709,9 @@ function loadRemoteConfig() {
|
|
|
7125
7709
|
};
|
|
7126
7710
|
}
|
|
7127
7711
|
function saveRemoteConfig(config) {
|
|
7128
|
-
const dir = (0,
|
|
7129
|
-
if (!(0,
|
|
7130
|
-
(0,
|
|
7712
|
+
const dir = (0, import_node_path13.join)(REMOTE_CONFIG_FILE, "..");
|
|
7713
|
+
if (!(0, import_node_fs15.existsSync)(dir)) (0, import_node_fs15.mkdirSync)(dir, { recursive: true });
|
|
7714
|
+
(0, import_node_fs15.writeFileSync)(REMOTE_CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
7131
7715
|
}
|
|
7132
7716
|
var OAUTH_CLIENT_ID = Buffer.from(
|
|
7133
7717
|
"MjM5NDk1OTI0Nzk4LTJtZWFhaTllcjZybTR1bnN0bW4zZmRldHRqZHM2bGJjLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29t",
|
|
@@ -7147,7 +7731,7 @@ function generateCodeChallenge(verifier) {
|
|
|
7147
7731
|
}
|
|
7148
7732
|
function openBrowser(url) {
|
|
7149
7733
|
const cmd = process.platform === "win32" ? `start "" "${url}"` : process.platform === "darwin" ? `open "${url}"` : `xdg-open "${url}"`;
|
|
7150
|
-
(0,
|
|
7734
|
+
(0, import_node_child_process7.exec)(cmd);
|
|
7151
7735
|
}
|
|
7152
7736
|
function waitForOAuthCallback(codeVerifier) {
|
|
7153
7737
|
return new Promise((resolve3, reject) => {
|
|
@@ -7217,8 +7801,8 @@ function waitForOAuthCallback(codeVerifier) {
|
|
|
7217
7801
|
}
|
|
7218
7802
|
async function remoteLogin(_options) {
|
|
7219
7803
|
const config = loadRemoteConfig();
|
|
7220
|
-
console.log(
|
|
7221
|
-
console.log(
|
|
7804
|
+
console.log(import_chalk12.default.cyan.bold("\n Remote Monitoring Login\n"));
|
|
7805
|
+
console.log(import_chalk12.default.gray(" Opening browser for Google sign-in...\n"));
|
|
7222
7806
|
const codeVerifier = generateCodeVerifier();
|
|
7223
7807
|
const codeChallenge = generateCodeChallenge(codeVerifier);
|
|
7224
7808
|
const authUrl = OAUTH_AUTH_ENDPOINT + "?" + new URLSearchParams({
|
|
@@ -7238,13 +7822,13 @@ async function remoteLogin(_options) {
|
|
|
7238
7822
|
idToken = result.idToken;
|
|
7239
7823
|
email = result.email;
|
|
7240
7824
|
} catch (err) {
|
|
7241
|
-
console.log(
|
|
7825
|
+
console.log(import_chalk12.default.red(` ${String(err)}`));
|
|
7242
7826
|
await trackCommand("remote login", false, getVersion());
|
|
7243
7827
|
return;
|
|
7244
7828
|
}
|
|
7245
|
-
console.log(
|
|
7829
|
+
console.log(import_chalk12.default.gray(" Registering this machine..."));
|
|
7246
7830
|
try {
|
|
7247
|
-
const host = (0,
|
|
7831
|
+
const host = (0, import_node_os10.hostname)();
|
|
7248
7832
|
const os = process.platform + "/" + process.arch;
|
|
7249
7833
|
const controller = new AbortController();
|
|
7250
7834
|
const timer = setTimeout(() => controller.abort(), 1e4);
|
|
@@ -7260,7 +7844,7 @@ async function remoteLogin(_options) {
|
|
|
7260
7844
|
clearTimeout(timer);
|
|
7261
7845
|
if (!res.ok) {
|
|
7262
7846
|
const err = await res.text();
|
|
7263
|
-
console.log(
|
|
7847
|
+
console.log(import_chalk12.default.red(` Registration failed: ${res.status} ${err}`));
|
|
7264
7848
|
return;
|
|
7265
7849
|
}
|
|
7266
7850
|
const data = await res.json();
|
|
@@ -7269,15 +7853,15 @@ async function remoteLogin(_options) {
|
|
|
7269
7853
|
config.enabled = true;
|
|
7270
7854
|
config.reportUrl = REMOTE_API_URL + "/v1/report";
|
|
7271
7855
|
saveRemoteConfig(config);
|
|
7272
|
-
console.log(
|
|
7856
|
+
console.log(import_chalk12.default.green.bold(`
|
|
7273
7857
|
Logged in as ${email}`));
|
|
7274
|
-
console.log(
|
|
7858
|
+
console.log(import_chalk12.default.gray(` Machine registered: ${host}`));
|
|
7275
7859
|
console.log(
|
|
7276
|
-
|
|
7860
|
+
import_chalk12.default.gray(" Remote monitoring ready. Run: openclaw-cli remote enable\n")
|
|
7277
7861
|
);
|
|
7278
7862
|
await trackCommand("remote login", true, getVersion());
|
|
7279
7863
|
} catch (err) {
|
|
7280
|
-
console.log(
|
|
7864
|
+
console.log(import_chalk12.default.red(` Error: ${err}`));
|
|
7281
7865
|
await trackCommand("remote login", false, getVersion());
|
|
7282
7866
|
}
|
|
7283
7867
|
}
|
|
@@ -7285,47 +7869,47 @@ async function remoteEnable(_options) {
|
|
|
7285
7869
|
const config = loadRemoteConfig();
|
|
7286
7870
|
if (!config.machineToken) {
|
|
7287
7871
|
console.log(
|
|
7288
|
-
|
|
7872
|
+
import_chalk12.default.red(" \u2717 Not logged in. Run: openclaw-cli remote login")
|
|
7289
7873
|
);
|
|
7290
7874
|
await trackCommand("remote enable", false, getVersion());
|
|
7291
7875
|
return;
|
|
7292
7876
|
}
|
|
7293
7877
|
config.enabled = true;
|
|
7294
7878
|
saveRemoteConfig(config);
|
|
7295
|
-
console.log(
|
|
7879
|
+
console.log(import_chalk12.default.green(" Remote reporting enabled."));
|
|
7296
7880
|
await trackCommand("remote enable", true, getVersion());
|
|
7297
7881
|
}
|
|
7298
7882
|
async function remoteDisable(_options) {
|
|
7299
7883
|
const config = loadRemoteConfig();
|
|
7300
7884
|
config.enabled = false;
|
|
7301
7885
|
saveRemoteConfig(config);
|
|
7302
|
-
console.log(
|
|
7886
|
+
console.log(import_chalk12.default.yellow(" Remote reporting disabled."));
|
|
7303
7887
|
await trackCommand("remote disable", true, getVersion());
|
|
7304
7888
|
}
|
|
7305
7889
|
async function remoteStatus(_options) {
|
|
7306
7890
|
await trackCommand("remote status", true, getVersion());
|
|
7307
7891
|
const config = loadRemoteConfig();
|
|
7308
|
-
console.log(
|
|
7892
|
+
console.log(import_chalk12.default.cyan.bold("\n Remote Monitoring Status\n"));
|
|
7309
7893
|
console.log(
|
|
7310
|
-
` Enabled: ${config.enabled ?
|
|
7894
|
+
` Enabled: ${config.enabled ? import_chalk12.default.green("yes") : import_chalk12.default.gray("no")}`
|
|
7311
7895
|
);
|
|
7312
7896
|
console.log(
|
|
7313
|
-
` Machine ID: ${
|
|
7897
|
+
` Machine ID: ${import_chalk12.default.white(config.machineId || "(none)")}`
|
|
7314
7898
|
);
|
|
7315
7899
|
console.log(
|
|
7316
|
-
` Token: ${config.machineToken ?
|
|
7900
|
+
` Token: ${config.machineToken ? import_chalk12.default.green("configured") : import_chalk12.default.red("not set")}`
|
|
7317
7901
|
);
|
|
7318
7902
|
console.log(
|
|
7319
|
-
` Report URL: ${
|
|
7903
|
+
` Report URL: ${import_chalk12.default.gray(config.reportUrl)}`
|
|
7320
7904
|
);
|
|
7321
7905
|
console.log(
|
|
7322
|
-
` Last Report: ${config.lastReport ?
|
|
7906
|
+
` Last Report: ${config.lastReport ? import_chalk12.default.gray(config.lastReport) : import_chalk12.default.gray("never")}`
|
|
7323
7907
|
);
|
|
7324
7908
|
console.log();
|
|
7325
7909
|
}
|
|
7326
7910
|
|
|
7327
7911
|
// src/index.ts
|
|
7328
|
-
var _PKG_VER2 = true ? "0.7.
|
|
7912
|
+
var _PKG_VER2 = true ? "0.7.2" : "0.2.1";
|
|
7329
7913
|
var version = _PKG_VER2;
|
|
7330
7914
|
printFirstRunNotice();
|
|
7331
7915
|
var program2 = new Command();
|
|
@@ -7350,6 +7934,12 @@ var gw = program2.command("gateway").description("Manage the OpenClaw gateway se
|
|
|
7350
7934
|
addGlobalOpts(gw.command("start").description("Start the gateway")).action(gatewayStart);
|
|
7351
7935
|
addGlobalOpts(gw.command("stop").description("Stop the gateway")).action(gatewayStop);
|
|
7352
7936
|
addGlobalOpts(gw.command("restart").description("Restart the gateway")).action(gatewayRestart);
|
|
7937
|
+
addGlobalOpts(
|
|
7938
|
+
program2.command("cost").description("Show token usage and cost summary per agent/model").option("--json", "Machine-readable JSON output").option("--days <n>", "Limit date range (default: 30)")
|
|
7939
|
+
).action(showCost);
|
|
7940
|
+
var mcp = program2.command("mcp").description("Manage local MCP (Model Context Protocol) servers");
|
|
7941
|
+
mcp.command("list").description("List configured MCP servers and their status").action(mcpList);
|
|
7942
|
+
mcp.command("status").description("Show detailed info for an MCP server").argument("<name>", "Server name").action(mcpStatus);
|
|
7353
7943
|
var tele = program2.command("telemetry").description("Manage anonymous usage telemetry");
|
|
7354
7944
|
tele.command("on").description("Enable telemetry").action(telemetryOn);
|
|
7355
7945
|
tele.command("off").description("Disable telemetry").action(telemetryOff);
|
|
@@ -7362,6 +7952,12 @@ addGlobalOpts(
|
|
|
7362
7952
|
addGlobalOpts(
|
|
7363
7953
|
mem.command("compact").description("Compact agent memory (proxies to openclaw memory compact)").option("--dry-run", "Preview without applying")
|
|
7364
7954
|
).action(memoryCompact);
|
|
7955
|
+
addGlobalOpts(
|
|
7956
|
+
mem.command("gc").description("Remove old daily memory files").option("--days <n>", "Max age in days (default: 30)").option("--force", "Skip confirmation prompt")
|
|
7957
|
+
).action(memoryGc);
|
|
7958
|
+
addGlobalOpts(
|
|
7959
|
+
mem.command("export").description("Export all memory files to a single markdown file").option("-o, --output <file>", "Output file (default: stdout)")
|
|
7960
|
+
).action(memoryExport);
|
|
7365
7961
|
var remote = program2.command("remote").description("Remote monitoring \u2014 report gateway status to openclaw-cli.app");
|
|
7366
7962
|
addGlobalOpts(remote.command("login").description("Authenticate and register this machine")).action(remoteLogin);
|
|
7367
7963
|
addGlobalOpts(remote.command("enable").description("Enable remote reporting")).action(remoteEnable);
|
|
@@ -7398,7 +7994,7 @@ function proxyToOpenclaw(args, override) {
|
|
|
7398
7994
|
process.exit(1);
|
|
7399
7995
|
}
|
|
7400
7996
|
const passArgs = override ?? args;
|
|
7401
|
-
const result = (0,
|
|
7997
|
+
const result = (0, import_node_child_process8.spawnSync)(info.nodePath, [bin, ...passArgs], {
|
|
7402
7998
|
stdio: "inherit",
|
|
7403
7999
|
env: process.env
|
|
7404
8000
|
});
|