nextclaw 0.4.16 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +246 -244
- package/package.json +4 -4
package/dist/cli/index.js
CHANGED
|
@@ -82,7 +82,7 @@ import {
|
|
|
82
82
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from "fs";
|
|
83
83
|
import { join, resolve } from "path";
|
|
84
84
|
import { spawn } from "child_process";
|
|
85
|
-
import {
|
|
85
|
+
import { isIP } from "net";
|
|
86
86
|
import { fileURLToPath } from "url";
|
|
87
87
|
import { getDataDir, getPackageVersion as getCorePackageVersion } from "@nextclaw/core";
|
|
88
88
|
function resolveUiConfig(config2, overrides) {
|
|
@@ -128,48 +128,9 @@ async function resolvePublicIp(timeoutMs = 1500) {
|
|
|
128
128
|
}
|
|
129
129
|
return null;
|
|
130
130
|
}
|
|
131
|
-
function isDevRuntime() {
|
|
132
|
-
return import.meta.url.includes("/src/cli/") || process.env.NEXTCLAW_DEV === "1";
|
|
133
|
-
}
|
|
134
|
-
function normalizeHostForPortCheck(host) {
|
|
135
|
-
return host === "0.0.0.0" || host === "::" ? "127.0.0.1" : host;
|
|
136
|
-
}
|
|
137
|
-
async function findAvailablePort(port, host, attempts = 20) {
|
|
138
|
-
const basePort = Number.isFinite(port) ? port : 0;
|
|
139
|
-
let candidate = basePort;
|
|
140
|
-
for (let i = 0; i < attempts; i += 1) {
|
|
141
|
-
const ok = await isPortAvailable(candidate, host);
|
|
142
|
-
if (ok) {
|
|
143
|
-
return candidate;
|
|
144
|
-
}
|
|
145
|
-
candidate += 1;
|
|
146
|
-
}
|
|
147
|
-
return basePort;
|
|
148
|
-
}
|
|
149
|
-
async function isPortAvailable(port, host) {
|
|
150
|
-
const checkHost = normalizeHostForPortCheck(host);
|
|
151
|
-
return await canBindPort(port, checkHost);
|
|
152
|
-
}
|
|
153
|
-
async function canBindPort(port, host) {
|
|
154
|
-
return await new Promise((resolve5) => {
|
|
155
|
-
const server = createServer();
|
|
156
|
-
server.unref();
|
|
157
|
-
server.once("error", () => resolve5(false));
|
|
158
|
-
server.listen({ port, host }, () => {
|
|
159
|
-
server.close(() => resolve5(true));
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
131
|
function buildServeArgs(options) {
|
|
164
132
|
const cliPath = fileURLToPath(new URL("./index.js", import.meta.url));
|
|
165
|
-
|
|
166
|
-
if (options.frontend) {
|
|
167
|
-
args.push("--frontend");
|
|
168
|
-
}
|
|
169
|
-
if (Number.isFinite(options.frontendPort)) {
|
|
170
|
-
args.push("--frontend-port", String(options.frontendPort));
|
|
171
|
-
}
|
|
172
|
-
return args;
|
|
133
|
+
return [cliPath, "serve", "--ui-host", options.uiHost, "--ui-port", String(options.uiPort)];
|
|
173
134
|
}
|
|
174
135
|
function readServiceState() {
|
|
175
136
|
const path = resolveServiceStatePath();
|
|
@@ -298,64 +259,6 @@ function getPackageVersion() {
|
|
|
298
259
|
const cliDir = resolve(fileURLToPath(new URL(".", import.meta.url)));
|
|
299
260
|
return resolveVersionFromPackageTree(cliDir, "nextclaw") ?? resolveVersionFromPackageTree(cliDir) ?? getCorePackageVersion();
|
|
300
261
|
}
|
|
301
|
-
function startUiFrontend(options) {
|
|
302
|
-
const uiDir = options.dir ?? resolveUiFrontendDir();
|
|
303
|
-
if (!uiDir) {
|
|
304
|
-
return null;
|
|
305
|
-
}
|
|
306
|
-
const runner = resolveUiFrontendRunner();
|
|
307
|
-
if (!runner) {
|
|
308
|
-
console.log("Warning: pnpm/npm not found. Skipping UI frontend.");
|
|
309
|
-
return null;
|
|
310
|
-
}
|
|
311
|
-
const args = [...runner.args];
|
|
312
|
-
if (options.port) {
|
|
313
|
-
if (runner.useArgSeparator) {
|
|
314
|
-
args.push("--");
|
|
315
|
-
}
|
|
316
|
-
args.push("--port", String(options.port));
|
|
317
|
-
}
|
|
318
|
-
const env = { ...process.env, VITE_API_BASE: options.apiBase };
|
|
319
|
-
const child = spawn(runner.cmd, args, { cwd: uiDir, stdio: "inherit", env });
|
|
320
|
-
child.on("exit", (code) => {
|
|
321
|
-
if (code && code !== 0) {
|
|
322
|
-
console.log(`UI frontend exited with code ${code}`);
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
const url = `http://127.0.0.1:${options.port}`;
|
|
326
|
-
console.log(`\u2713 UI frontend: ${url}`);
|
|
327
|
-
return { url, dir: uiDir };
|
|
328
|
-
}
|
|
329
|
-
function resolveUiFrontendRunner() {
|
|
330
|
-
if (which("pnpm")) {
|
|
331
|
-
return { cmd: "pnpm", args: ["dev"], useArgSeparator: false };
|
|
332
|
-
}
|
|
333
|
-
if (which("npm")) {
|
|
334
|
-
return { cmd: "npm", args: ["run", "dev"], useArgSeparator: true };
|
|
335
|
-
}
|
|
336
|
-
return null;
|
|
337
|
-
}
|
|
338
|
-
function resolveUiFrontendDir() {
|
|
339
|
-
const candidates = [];
|
|
340
|
-
const envDir = process.env.NEXTCLAW_UI_DIR;
|
|
341
|
-
if (envDir) {
|
|
342
|
-
candidates.push(envDir);
|
|
343
|
-
}
|
|
344
|
-
const cwd = process.cwd();
|
|
345
|
-
candidates.push(join(cwd, "packages", "nextclaw-ui"));
|
|
346
|
-
candidates.push(join(cwd, "nextclaw-ui"));
|
|
347
|
-
const cliDir = resolve(fileURLToPath(new URL(".", import.meta.url)));
|
|
348
|
-
const pkgRoot = resolve(cliDir, "..", "..");
|
|
349
|
-
candidates.push(join(pkgRoot, "..", "nextclaw-ui"));
|
|
350
|
-
candidates.push(join(pkgRoot, "..", "..", "packages", "nextclaw-ui"));
|
|
351
|
-
candidates.push(join(pkgRoot, "..", "..", "nextclaw-ui"));
|
|
352
|
-
for (const dir of candidates) {
|
|
353
|
-
if (existsSync(join(dir, "package.json"))) {
|
|
354
|
-
return dir;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
return null;
|
|
358
|
-
}
|
|
359
262
|
function printAgentResponse(response) {
|
|
360
263
|
console.log("\n" + response + "\n");
|
|
361
264
|
}
|
|
@@ -461,17 +364,21 @@ var mergeDeep = (base, patch) => {
|
|
|
461
364
|
}
|
|
462
365
|
return next;
|
|
463
366
|
};
|
|
464
|
-
var scheduleRestart = (delayMs, reason) => {
|
|
465
|
-
const delay = typeof delayMs === "number" && Number.isFinite(delayMs) ? Math.max(0, delayMs) : 100;
|
|
466
|
-
console.log(`Gateway restart requested via tool${reason ? ` (${reason})` : ""}.`);
|
|
467
|
-
setTimeout(() => {
|
|
468
|
-
process.exit(0);
|
|
469
|
-
}, delay);
|
|
470
|
-
};
|
|
471
367
|
var GatewayControllerImpl = class {
|
|
472
368
|
constructor(deps) {
|
|
473
369
|
this.deps = deps;
|
|
474
370
|
}
|
|
371
|
+
async requestRestart(options) {
|
|
372
|
+
if (this.deps.requestRestart) {
|
|
373
|
+
await this.deps.requestRestart(options);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
const delay = typeof options?.delayMs === "number" && Number.isFinite(options.delayMs) ? Math.max(0, options.delayMs) : 100;
|
|
377
|
+
console.log(`Gateway restart requested via tool${options?.reason ? ` (${options.reason})` : ""}.`);
|
|
378
|
+
setTimeout(() => {
|
|
379
|
+
process.exit(0);
|
|
380
|
+
}, delay);
|
|
381
|
+
}
|
|
475
382
|
status() {
|
|
476
383
|
return {
|
|
477
384
|
channels: this.deps.reloader.getChannels().enabledChannels,
|
|
@@ -483,7 +390,7 @@ var GatewayControllerImpl = class {
|
|
|
483
390
|
return this.deps.reloader.reloadConfig(reason);
|
|
484
391
|
}
|
|
485
392
|
async restart(options) {
|
|
486
|
-
|
|
393
|
+
await this.requestRestart(options);
|
|
487
394
|
return "Restart scheduled";
|
|
488
395
|
}
|
|
489
396
|
async getConfig() {
|
|
@@ -528,7 +435,7 @@ var GatewayControllerImpl = class {
|
|
|
528
435
|
}
|
|
529
436
|
this.deps.saveConfig(validated);
|
|
530
437
|
const delayMs = params.restartDelayMs ?? 0;
|
|
531
|
-
|
|
438
|
+
await this.requestRestart({ delayMs, reason: "config.apply" });
|
|
532
439
|
return {
|
|
533
440
|
ok: true,
|
|
534
441
|
note: params.note ?? null,
|
|
@@ -564,7 +471,7 @@ var GatewayControllerImpl = class {
|
|
|
564
471
|
}
|
|
565
472
|
this.deps.saveConfig(validated);
|
|
566
473
|
const delayMs = params.restartDelayMs ?? 0;
|
|
567
|
-
|
|
474
|
+
await this.requestRestart({ delayMs, reason: "config.patch" });
|
|
568
475
|
return {
|
|
569
476
|
ok: true,
|
|
570
477
|
note: params.note ?? null,
|
|
@@ -579,7 +486,7 @@ var GatewayControllerImpl = class {
|
|
|
579
486
|
return { ok: false, error: result.error ?? "update failed", steps: result.steps };
|
|
580
487
|
}
|
|
581
488
|
const delayMs = params.restartDelayMs ?? 0;
|
|
582
|
-
|
|
489
|
+
await this.requestRestart({ delayMs, reason: "update.run" });
|
|
583
490
|
return {
|
|
584
491
|
ok: true,
|
|
585
492
|
note: params.note ?? null,
|
|
@@ -590,6 +497,63 @@ var GatewayControllerImpl = class {
|
|
|
590
497
|
}
|
|
591
498
|
};
|
|
592
499
|
|
|
500
|
+
// src/cli/restart-coordinator.ts
|
|
501
|
+
var RestartCoordinator = class {
|
|
502
|
+
constructor(deps) {
|
|
503
|
+
this.deps = deps;
|
|
504
|
+
}
|
|
505
|
+
restartingService = false;
|
|
506
|
+
exitScheduled = false;
|
|
507
|
+
async requestRestart(request) {
|
|
508
|
+
const reason = request.reason.trim() || "config changed";
|
|
509
|
+
const strategy = request.strategy ?? "background-service-or-manual";
|
|
510
|
+
if (strategy !== "exit-process") {
|
|
511
|
+
const state = this.deps.readServiceState();
|
|
512
|
+
const serviceRunning = Boolean(state && this.deps.isProcessRunning(state.pid));
|
|
513
|
+
const managedByCurrentProcess = Boolean(state && state.pid === this.deps.currentPid());
|
|
514
|
+
if (serviceRunning && !managedByCurrentProcess) {
|
|
515
|
+
if (this.restartingService) {
|
|
516
|
+
return {
|
|
517
|
+
status: "restart-in-progress",
|
|
518
|
+
message: "Restart already in progress; skipping duplicate request."
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
this.restartingService = true;
|
|
522
|
+
try {
|
|
523
|
+
const restarted = await this.deps.restartBackgroundService(reason);
|
|
524
|
+
if (restarted) {
|
|
525
|
+
return {
|
|
526
|
+
status: "service-restarted",
|
|
527
|
+
message: `Restarted background service to apply changes (${reason}).`
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
} finally {
|
|
531
|
+
this.restartingService = false;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
if (strategy === "background-service-or-exit" || strategy === "exit-process") {
|
|
536
|
+
if (this.exitScheduled) {
|
|
537
|
+
return {
|
|
538
|
+
status: "exit-scheduled",
|
|
539
|
+
message: "Restart already scheduled; skipping duplicate request."
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
const delay = typeof request.delayMs === "number" && Number.isFinite(request.delayMs) ? Math.max(0, Math.floor(request.delayMs)) : 100;
|
|
543
|
+
this.exitScheduled = true;
|
|
544
|
+
this.deps.scheduleProcessExit(delay, reason);
|
|
545
|
+
return {
|
|
546
|
+
status: "exit-scheduled",
|
|
547
|
+
message: `Restart scheduled (${reason}).`
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
return {
|
|
551
|
+
status: "manual-required",
|
|
552
|
+
message: request.manualMessage ?? "Restart the gateway to apply changes."
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
|
|
593
557
|
// src/cli/skills/clawhub.ts
|
|
594
558
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
595
559
|
import { existsSync as existsSync3 } from "fs";
|
|
@@ -663,6 +627,7 @@ function buildClawHubArgs(slug, options) {
|
|
|
663
627
|
// src/cli/runtime.ts
|
|
664
628
|
var LOGO = "\u{1F916}";
|
|
665
629
|
var EXIT_COMMANDS = /* @__PURE__ */ new Set(["exit", "quit", "/exit", "/quit", ":q"]);
|
|
630
|
+
var FORCED_PUBLIC_UI_HOST = "0.0.0.0";
|
|
666
631
|
function isIndexSegment(raw) {
|
|
667
632
|
return /^[0-9]+$/.test(raw);
|
|
668
633
|
}
|
|
@@ -986,12 +951,75 @@ var ConfigReloader = class {
|
|
|
986
951
|
};
|
|
987
952
|
var CliRuntime = class {
|
|
988
953
|
logo;
|
|
954
|
+
restartCoordinator;
|
|
955
|
+
serviceRestartTask = null;
|
|
989
956
|
constructor(options = {}) {
|
|
990
957
|
this.logo = options.logo ?? LOGO;
|
|
958
|
+
this.restartCoordinator = new RestartCoordinator({
|
|
959
|
+
readServiceState,
|
|
960
|
+
isProcessRunning,
|
|
961
|
+
currentPid: () => process.pid,
|
|
962
|
+
restartBackgroundService: async (reason) => this.restartBackgroundService(reason),
|
|
963
|
+
scheduleProcessExit: (delayMs, reason) => this.scheduleProcessExit(delayMs, reason)
|
|
964
|
+
});
|
|
991
965
|
}
|
|
992
966
|
get version() {
|
|
993
967
|
return getPackageVersion();
|
|
994
968
|
}
|
|
969
|
+
scheduleProcessExit(delayMs, reason) {
|
|
970
|
+
console.warn(`Gateway restart requested (${reason}).`);
|
|
971
|
+
setTimeout(() => {
|
|
972
|
+
process.exit(0);
|
|
973
|
+
}, delayMs);
|
|
974
|
+
}
|
|
975
|
+
async restartBackgroundService(reason) {
|
|
976
|
+
if (this.serviceRestartTask) {
|
|
977
|
+
return this.serviceRestartTask;
|
|
978
|
+
}
|
|
979
|
+
this.serviceRestartTask = (async () => {
|
|
980
|
+
const state = readServiceState();
|
|
981
|
+
if (!state || !isProcessRunning(state.pid) || state.pid === process.pid) {
|
|
982
|
+
return false;
|
|
983
|
+
}
|
|
984
|
+
const uiHost = FORCED_PUBLIC_UI_HOST;
|
|
985
|
+
const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 18791;
|
|
986
|
+
console.log(`Applying changes (${reason}): restarting ${APP_NAME} background service...`);
|
|
987
|
+
await this.stopService();
|
|
988
|
+
await this.startService({
|
|
989
|
+
uiOverrides: {
|
|
990
|
+
enabled: true,
|
|
991
|
+
host: uiHost,
|
|
992
|
+
port: uiPort
|
|
993
|
+
},
|
|
994
|
+
open: false
|
|
995
|
+
});
|
|
996
|
+
return true;
|
|
997
|
+
})();
|
|
998
|
+
try {
|
|
999
|
+
return await this.serviceRestartTask;
|
|
1000
|
+
} finally {
|
|
1001
|
+
this.serviceRestartTask = null;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
async requestRestart(params) {
|
|
1005
|
+
const result = await this.restartCoordinator.requestRestart({
|
|
1006
|
+
reason: params.reason,
|
|
1007
|
+
strategy: params.strategy,
|
|
1008
|
+
delayMs: params.delayMs,
|
|
1009
|
+
manualMessage: params.manualMessage
|
|
1010
|
+
});
|
|
1011
|
+
if (result.status === "manual-required" || result.status === "restart-in-progress") {
|
|
1012
|
+
console.log(result.message);
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
if (result.status === "service-restarted") {
|
|
1016
|
+
if (!params.silentOnServiceRestart) {
|
|
1017
|
+
console.log(result.message);
|
|
1018
|
+
}
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
console.warn(result.message);
|
|
1022
|
+
}
|
|
995
1023
|
async onboard() {
|
|
996
1024
|
console.warn(`Warning: ${APP_NAME} onboard is deprecated. Use "${APP_NAME} init" instead.`);
|
|
997
1025
|
await this.init({ source: "onboard" });
|
|
@@ -1036,87 +1064,43 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1036
1064
|
}
|
|
1037
1065
|
}
|
|
1038
1066
|
async gateway(opts) {
|
|
1039
|
-
const uiOverrides = {
|
|
1067
|
+
const uiOverrides = {
|
|
1068
|
+
host: FORCED_PUBLIC_UI_HOST
|
|
1069
|
+
};
|
|
1040
1070
|
if (opts.ui) {
|
|
1041
1071
|
uiOverrides.enabled = true;
|
|
1042
1072
|
}
|
|
1043
|
-
if (opts.uiHost) {
|
|
1044
|
-
uiOverrides.host = String(opts.uiHost);
|
|
1045
|
-
}
|
|
1046
1073
|
if (opts.uiPort) {
|
|
1047
1074
|
uiOverrides.port = Number(opts.uiPort);
|
|
1048
1075
|
}
|
|
1049
1076
|
if (opts.uiOpen) {
|
|
1050
1077
|
uiOverrides.open = true;
|
|
1051
1078
|
}
|
|
1052
|
-
if (opts.public) {
|
|
1053
|
-
uiOverrides.enabled = true;
|
|
1054
|
-
if (!opts.uiHost) {
|
|
1055
|
-
uiOverrides.host = "0.0.0.0";
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
1079
|
await this.startGateway({ uiOverrides });
|
|
1059
1080
|
}
|
|
1060
1081
|
async ui(opts) {
|
|
1061
1082
|
const uiOverrides = {
|
|
1062
1083
|
enabled: true,
|
|
1084
|
+
host: FORCED_PUBLIC_UI_HOST,
|
|
1063
1085
|
open: Boolean(opts.open)
|
|
1064
1086
|
};
|
|
1065
|
-
if (opts.host) {
|
|
1066
|
-
uiOverrides.host = String(opts.host);
|
|
1067
|
-
}
|
|
1068
1087
|
if (opts.port) {
|
|
1069
1088
|
uiOverrides.port = Number(opts.port);
|
|
1070
1089
|
}
|
|
1071
|
-
if (opts.public && !opts.host) {
|
|
1072
|
-
uiOverrides.host = "0.0.0.0";
|
|
1073
|
-
}
|
|
1074
1090
|
await this.startGateway({ uiOverrides, allowMissingProvider: true });
|
|
1075
1091
|
}
|
|
1076
1092
|
async start(opts) {
|
|
1077
1093
|
await this.init({ source: "start", auto: true });
|
|
1078
1094
|
const uiOverrides = {
|
|
1079
1095
|
enabled: true,
|
|
1096
|
+
host: FORCED_PUBLIC_UI_HOST,
|
|
1080
1097
|
open: false
|
|
1081
1098
|
};
|
|
1082
|
-
if (opts.uiHost) {
|
|
1083
|
-
uiOverrides.host = String(opts.uiHost);
|
|
1084
|
-
}
|
|
1085
1099
|
if (opts.uiPort) {
|
|
1086
1100
|
uiOverrides.port = Number(opts.uiPort);
|
|
1087
1101
|
}
|
|
1088
|
-
if (opts.public && !opts.uiHost) {
|
|
1089
|
-
uiOverrides.host = "0.0.0.0";
|
|
1090
|
-
}
|
|
1091
|
-
const devMode = isDevRuntime();
|
|
1092
|
-
if (devMode) {
|
|
1093
|
-
const requestedUiPort = Number.isFinite(Number(opts.uiPort)) ? Number(opts.uiPort) : 18792;
|
|
1094
|
-
const requestedFrontendPort = Number.isFinite(Number(opts.frontendPort)) ? Number(opts.frontendPort) : 5174;
|
|
1095
|
-
const uiHost = uiOverrides.host ?? "127.0.0.1";
|
|
1096
|
-
const devUiPort = await findAvailablePort(requestedUiPort, uiHost);
|
|
1097
|
-
const shouldStartFrontend = opts.frontend === void 0 ? true : Boolean(opts.frontend);
|
|
1098
|
-
const devFrontendPort = shouldStartFrontend ? await findAvailablePort(requestedFrontendPort, "127.0.0.1") : requestedFrontendPort;
|
|
1099
|
-
uiOverrides.port = devUiPort;
|
|
1100
|
-
if (requestedUiPort !== devUiPort) {
|
|
1101
|
-
console.log(`Dev mode: UI port ${requestedUiPort} is in use, switched to ${devUiPort}.`);
|
|
1102
|
-
}
|
|
1103
|
-
if (shouldStartFrontend && requestedFrontendPort !== devFrontendPort) {
|
|
1104
|
-
console.log(`Dev mode: Frontend port ${requestedFrontendPort} is in use, switched to ${devFrontendPort}.`);
|
|
1105
|
-
}
|
|
1106
|
-
console.log(`Dev mode: UI ${devUiPort}, Frontend ${devFrontendPort}`);
|
|
1107
|
-
console.log("Dev mode runs in the foreground (Ctrl+C to stop).");
|
|
1108
|
-
await this.runForeground({
|
|
1109
|
-
uiOverrides,
|
|
1110
|
-
frontend: shouldStartFrontend,
|
|
1111
|
-
frontendPort: devFrontendPort,
|
|
1112
|
-
open: Boolean(opts.open)
|
|
1113
|
-
});
|
|
1114
|
-
return;
|
|
1115
|
-
}
|
|
1116
1102
|
await this.startService({
|
|
1117
1103
|
uiOverrides,
|
|
1118
|
-
frontend: Boolean(opts.frontend),
|
|
1119
|
-
frontendPort: Number(opts.frontendPort),
|
|
1120
1104
|
open: Boolean(opts.open)
|
|
1121
1105
|
});
|
|
1122
1106
|
}
|
|
@@ -1136,40 +1120,14 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1136
1120
|
async serve(opts) {
|
|
1137
1121
|
const uiOverrides = {
|
|
1138
1122
|
enabled: true,
|
|
1123
|
+
host: FORCED_PUBLIC_UI_HOST,
|
|
1139
1124
|
open: false
|
|
1140
1125
|
};
|
|
1141
|
-
if (opts.uiHost) {
|
|
1142
|
-
uiOverrides.host = String(opts.uiHost);
|
|
1143
|
-
}
|
|
1144
1126
|
if (opts.uiPort) {
|
|
1145
1127
|
uiOverrides.port = Number(opts.uiPort);
|
|
1146
1128
|
}
|
|
1147
|
-
if (opts.public && !opts.uiHost) {
|
|
1148
|
-
uiOverrides.host = "0.0.0.0";
|
|
1149
|
-
}
|
|
1150
|
-
const devMode = isDevRuntime();
|
|
1151
|
-
if (devMode && uiOverrides.port === void 0) {
|
|
1152
|
-
uiOverrides.port = 18792;
|
|
1153
|
-
}
|
|
1154
|
-
const shouldStartFrontend = Boolean(opts.frontend);
|
|
1155
|
-
const defaultFrontendPort = devMode ? 5174 : 5173;
|
|
1156
|
-
const requestedFrontendPort = Number.isFinite(Number(opts.frontendPort)) ? Number(opts.frontendPort) : defaultFrontendPort;
|
|
1157
|
-
if (devMode && uiOverrides.port !== void 0) {
|
|
1158
|
-
const uiHost = uiOverrides.host ?? "127.0.0.1";
|
|
1159
|
-
const uiPort = await findAvailablePort(uiOverrides.port, uiHost);
|
|
1160
|
-
if (uiPort !== uiOverrides.port) {
|
|
1161
|
-
console.log(`Dev mode: UI port ${uiOverrides.port} is in use, switched to ${uiPort}.`);
|
|
1162
|
-
uiOverrides.port = uiPort;
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
const frontendPort = devMode && shouldStartFrontend ? await findAvailablePort(requestedFrontendPort, "127.0.0.1") : requestedFrontendPort;
|
|
1166
|
-
if (devMode && shouldStartFrontend && frontendPort !== requestedFrontendPort) {
|
|
1167
|
-
console.log(`Dev mode: Frontend port ${requestedFrontendPort} is in use, switched to ${frontendPort}.`);
|
|
1168
|
-
}
|
|
1169
1129
|
await this.runForeground({
|
|
1170
1130
|
uiOverrides,
|
|
1171
|
-
frontend: shouldStartFrontend,
|
|
1172
|
-
frontendPort,
|
|
1173
1131
|
open: Boolean(opts.open)
|
|
1174
1132
|
});
|
|
1175
1133
|
}
|
|
@@ -1189,6 +1147,10 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1189
1147
|
bus,
|
|
1190
1148
|
providerManager,
|
|
1191
1149
|
workspace,
|
|
1150
|
+
model: config2.agents.defaults.model,
|
|
1151
|
+
maxIterations: config2.agents.defaults.maxToolIterations,
|
|
1152
|
+
maxTokens: config2.agents.defaults.maxTokens,
|
|
1153
|
+
temperature: config2.agents.defaults.temperature,
|
|
1192
1154
|
braveApiKey: config2.tools.web.search.apiKey || void 0,
|
|
1193
1155
|
execConfig: config2.tools.exec,
|
|
1194
1156
|
restrictToWorkspace: config2.tools.restrictToWorkspace,
|
|
@@ -1428,7 +1390,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1428
1390
|
}
|
|
1429
1391
|
console.log(JSON.stringify(result.value ?? null, null, 2));
|
|
1430
1392
|
}
|
|
1431
|
-
configSet(pathExpr, value, opts = {}) {
|
|
1393
|
+
async configSet(pathExpr, value, opts = {}) {
|
|
1432
1394
|
let parsedPath;
|
|
1433
1395
|
try {
|
|
1434
1396
|
parsedPath = parseRequiredConfigPath(pathExpr);
|
|
@@ -1445,18 +1407,24 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1445
1407
|
process.exit(1);
|
|
1446
1408
|
return;
|
|
1447
1409
|
}
|
|
1448
|
-
const
|
|
1410
|
+
const prevConfig = loadConfig();
|
|
1411
|
+
const nextConfig = structuredClone(prevConfig);
|
|
1449
1412
|
try {
|
|
1450
|
-
setAtConfigPath(
|
|
1413
|
+
setAtConfigPath(nextConfig, parsedPath, parsedValue);
|
|
1451
1414
|
} catch (error) {
|
|
1452
1415
|
console.error(String(error));
|
|
1453
1416
|
process.exit(1);
|
|
1454
1417
|
return;
|
|
1455
1418
|
}
|
|
1456
|
-
saveConfig(
|
|
1457
|
-
|
|
1419
|
+
saveConfig(nextConfig);
|
|
1420
|
+
await this.requestRestartForConfigDiff({
|
|
1421
|
+
prevConfig,
|
|
1422
|
+
nextConfig,
|
|
1423
|
+
reason: `config.set ${pathExpr}`,
|
|
1424
|
+
manualMessage: `Updated ${pathExpr}. Restart the gateway to apply.`
|
|
1425
|
+
});
|
|
1458
1426
|
}
|
|
1459
|
-
configUnset(pathExpr) {
|
|
1427
|
+
async configUnset(pathExpr) {
|
|
1460
1428
|
let parsedPath;
|
|
1461
1429
|
try {
|
|
1462
1430
|
parsedPath = parseRequiredConfigPath(pathExpr);
|
|
@@ -1465,27 +1433,53 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1465
1433
|
process.exit(1);
|
|
1466
1434
|
return;
|
|
1467
1435
|
}
|
|
1468
|
-
const
|
|
1469
|
-
const
|
|
1436
|
+
const prevConfig = loadConfig();
|
|
1437
|
+
const nextConfig = structuredClone(prevConfig);
|
|
1438
|
+
const removed = unsetAtConfigPath(nextConfig, parsedPath);
|
|
1470
1439
|
if (!removed) {
|
|
1471
1440
|
console.error(`Config path not found: ${pathExpr}`);
|
|
1472
1441
|
process.exit(1);
|
|
1473
1442
|
return;
|
|
1474
1443
|
}
|
|
1475
|
-
saveConfig(
|
|
1476
|
-
|
|
1444
|
+
saveConfig(nextConfig);
|
|
1445
|
+
await this.requestRestartForConfigDiff({
|
|
1446
|
+
prevConfig,
|
|
1447
|
+
nextConfig,
|
|
1448
|
+
reason: `config.unset ${pathExpr}`,
|
|
1449
|
+
manualMessage: `Removed ${pathExpr}. Restart the gateway to apply.`
|
|
1450
|
+
});
|
|
1477
1451
|
}
|
|
1478
|
-
|
|
1452
|
+
async requestRestartForConfigDiff(params) {
|
|
1453
|
+
const changedPaths = diffConfigPaths(params.prevConfig, params.nextConfig);
|
|
1454
|
+
if (!changedPaths.length) {
|
|
1455
|
+
return;
|
|
1456
|
+
}
|
|
1457
|
+
const plan = buildReloadPlan(changedPaths);
|
|
1458
|
+
if (plan.restartRequired.length === 0) {
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
await this.requestRestart({
|
|
1462
|
+
reason: `${params.reason} (${plan.restartRequired.join(", ")})`,
|
|
1463
|
+
manualMessage: params.manualMessage
|
|
1464
|
+
});
|
|
1465
|
+
}
|
|
1466
|
+
async pluginsEnable(id) {
|
|
1479
1467
|
const config2 = loadConfig();
|
|
1480
1468
|
const next = enablePluginInConfig(config2, id);
|
|
1481
1469
|
saveConfig(next);
|
|
1482
|
-
|
|
1470
|
+
await this.requestRestart({
|
|
1471
|
+
reason: `plugin enabled: ${id}`,
|
|
1472
|
+
manualMessage: `Enabled plugin "${id}". Restart the gateway to apply.`
|
|
1473
|
+
});
|
|
1483
1474
|
}
|
|
1484
|
-
pluginsDisable(id) {
|
|
1475
|
+
async pluginsDisable(id) {
|
|
1485
1476
|
const config2 = loadConfig();
|
|
1486
1477
|
const next = disablePluginInConfig(config2, id);
|
|
1487
1478
|
saveConfig(next);
|
|
1488
|
-
|
|
1479
|
+
await this.requestRestart({
|
|
1480
|
+
reason: `plugin disabled: ${id}`,
|
|
1481
|
+
manualMessage: `Disabled plugin "${id}". Restart the gateway to apply.`
|
|
1482
|
+
});
|
|
1489
1483
|
}
|
|
1490
1484
|
async pluginsUninstall(id, opts = {}) {
|
|
1491
1485
|
const config2 = loadConfig();
|
|
@@ -1582,7 +1576,10 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1582
1576
|
removed.push("directory");
|
|
1583
1577
|
}
|
|
1584
1578
|
console.log(`Uninstalled plugin "${pluginId}". Removed: ${removed.length > 0 ? removed.join(", ") : "nothing"}.`);
|
|
1585
|
-
|
|
1579
|
+
await this.requestRestart({
|
|
1580
|
+
reason: `plugin uninstalled: ${pluginId}`,
|
|
1581
|
+
manualMessage: "Restart the gateway to apply changes."
|
|
1582
|
+
});
|
|
1586
1583
|
}
|
|
1587
1584
|
async pluginsInstall(pathOrSpec, opts = {}) {
|
|
1588
1585
|
const fileSpec = this.resolveFileNpmSpecToLocalPath(pathOrSpec);
|
|
@@ -1611,7 +1608,10 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1611
1608
|
});
|
|
1612
1609
|
saveConfig(next3);
|
|
1613
1610
|
console.log(`Linked plugin path: ${resolved}`);
|
|
1614
|
-
|
|
1611
|
+
await this.requestRestart({
|
|
1612
|
+
reason: `plugin linked: ${probe.pluginId}`,
|
|
1613
|
+
manualMessage: "Restart the gateway to load plugins."
|
|
1614
|
+
});
|
|
1615
1615
|
return;
|
|
1616
1616
|
}
|
|
1617
1617
|
const result2 = await installPluginFromPath({
|
|
@@ -1635,7 +1635,10 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1635
1635
|
});
|
|
1636
1636
|
saveConfig(next2);
|
|
1637
1637
|
console.log(`Installed plugin: ${result2.pluginId}`);
|
|
1638
|
-
|
|
1638
|
+
await this.requestRestart({
|
|
1639
|
+
reason: `plugin installed: ${result2.pluginId}`,
|
|
1640
|
+
manualMessage: "Restart the gateway to load plugins."
|
|
1641
|
+
});
|
|
1639
1642
|
return;
|
|
1640
1643
|
}
|
|
1641
1644
|
if (opts.link) {
|
|
@@ -1667,7 +1670,10 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1667
1670
|
});
|
|
1668
1671
|
saveConfig(next);
|
|
1669
1672
|
console.log(`Installed plugin: ${result.pluginId}`);
|
|
1670
|
-
|
|
1673
|
+
await this.requestRestart({
|
|
1674
|
+
reason: `plugin installed: ${result.pluginId}`,
|
|
1675
|
+
manualMessage: "Restart the gateway to load plugins."
|
|
1676
|
+
});
|
|
1671
1677
|
}
|
|
1672
1678
|
pluginsDoctor() {
|
|
1673
1679
|
const config2 = loadConfig();
|
|
@@ -1757,7 +1763,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1757
1763
|
console.error(`Bridge failed: ${result.status ?? 1}`);
|
|
1758
1764
|
}
|
|
1759
1765
|
}
|
|
1760
|
-
channelsAdd(opts) {
|
|
1766
|
+
async channelsAdd(opts) {
|
|
1761
1767
|
const channelId = opts.channel?.trim();
|
|
1762
1768
|
if (!channelId) {
|
|
1763
1769
|
console.error("--channel is required");
|
|
@@ -1808,7 +1814,10 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1808
1814
|
next = enablePluginInConfig(next, binding.pluginId);
|
|
1809
1815
|
saveConfig(next);
|
|
1810
1816
|
console.log(`Configured channel "${binding.channelId}" via plugin "${binding.pluginId}".`);
|
|
1811
|
-
|
|
1817
|
+
await this.requestRestart({
|
|
1818
|
+
reason: `channel configured via plugin: ${binding.pluginId}`,
|
|
1819
|
+
manualMessage: "Restart the gateway to apply changes."
|
|
1820
|
+
});
|
|
1812
1821
|
}
|
|
1813
1822
|
toPluginConfigView(config2, bindings) {
|
|
1814
1823
|
const view = JSON.parse(JSON.stringify(config2));
|
|
@@ -2032,7 +2041,11 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
2032
2041
|
loadConfig,
|
|
2033
2042
|
getExtensionChannels: () => extensionRegistry.channels,
|
|
2034
2043
|
onRestartRequired: (paths) => {
|
|
2035
|
-
|
|
2044
|
+
void this.requestRestart({
|
|
2045
|
+
reason: `config reload requires restart: ${paths.join(", ")}`,
|
|
2046
|
+
manualMessage: `Config changes require restart: ${paths.join(", ")}`,
|
|
2047
|
+
strategy: "background-service-or-manual"
|
|
2048
|
+
});
|
|
2036
2049
|
}
|
|
2037
2050
|
});
|
|
2038
2051
|
const gatewayController = new GatewayControllerImpl({
|
|
@@ -2040,7 +2053,16 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
2040
2053
|
cron: cron2,
|
|
2041
2054
|
getConfigPath,
|
|
2042
2055
|
saveConfig,
|
|
2043
|
-
getPluginUiMetadata: () => pluginUiMetadata
|
|
2056
|
+
getPluginUiMetadata: () => pluginUiMetadata,
|
|
2057
|
+
requestRestart: async (options2) => {
|
|
2058
|
+
await this.requestRestart({
|
|
2059
|
+
reason: options2?.reason ?? "gateway tool restart",
|
|
2060
|
+
manualMessage: "Restart the gateway to apply changes.",
|
|
2061
|
+
strategy: "background-service-or-exit",
|
|
2062
|
+
delayMs: options2?.delayMs,
|
|
2063
|
+
silentOnServiceRestart: true
|
|
2064
|
+
});
|
|
2065
|
+
}
|
|
2044
2066
|
});
|
|
2045
2067
|
const agent = new AgentLoop({
|
|
2046
2068
|
bus,
|
|
@@ -2048,6 +2070,8 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
2048
2070
|
workspace,
|
|
2049
2071
|
model: config2.agents.defaults.model,
|
|
2050
2072
|
maxIterations: config2.agents.defaults.maxToolIterations,
|
|
2073
|
+
maxTokens: config2.agents.defaults.maxTokens,
|
|
2074
|
+
temperature: config2.agents.defaults.temperature,
|
|
2051
2075
|
braveApiKey: config2.tools.web.search.apiKey || void 0,
|
|
2052
2076
|
execConfig: config2.tools.exec,
|
|
2053
2077
|
cronService: cron2,
|
|
@@ -2178,7 +2202,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
2178
2202
|
}
|
|
2179
2203
|
async printPublicUiUrls(host, port) {
|
|
2180
2204
|
if (isLoopbackHost(host)) {
|
|
2181
|
-
console.log(
|
|
2205
|
+
console.log("Public URL: disabled (UI host is loopback). Current release expects public exposure; run nextclaw restart.");
|
|
2182
2206
|
return;
|
|
2183
2207
|
}
|
|
2184
2208
|
const publicIp = await resolvePublicIp();
|
|
@@ -2213,34 +2237,14 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
2213
2237
|
async runForeground(options) {
|
|
2214
2238
|
const config2 = loadConfig();
|
|
2215
2239
|
const uiConfig = resolveUiConfig(config2, options.uiOverrides);
|
|
2216
|
-
const
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
const staticDir = resolveUiStaticDir();
|
|
2220
|
-
let frontendUrl = null;
|
|
2221
|
-
if (shouldStartFrontend && frontendDir) {
|
|
2222
|
-
const frontend = startUiFrontend({
|
|
2223
|
-
apiBase: resolveUiApiBase(uiConfig.host, uiConfig.port),
|
|
2224
|
-
port: frontendPort,
|
|
2225
|
-
dir: frontendDir
|
|
2226
|
-
});
|
|
2227
|
-
frontendUrl = frontend?.url ?? null;
|
|
2228
|
-
} else if (shouldStartFrontend && !frontendDir) {
|
|
2229
|
-
console.log("Warning: UI frontend not found. Start it separately.");
|
|
2230
|
-
}
|
|
2231
|
-
if (!frontendUrl && staticDir) {
|
|
2232
|
-
frontendUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
|
|
2233
|
-
}
|
|
2234
|
-
if (options.open && frontendUrl) {
|
|
2235
|
-
openBrowser(frontendUrl);
|
|
2236
|
-
} else if (options.open && !frontendUrl) {
|
|
2237
|
-
console.log("Warning: UI frontend not started. Browser not opened.");
|
|
2240
|
+
const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
|
|
2241
|
+
if (options.open) {
|
|
2242
|
+
openBrowser(uiUrl);
|
|
2238
2243
|
}
|
|
2239
|
-
const uiStaticDir = shouldStartFrontend && frontendDir ? null : staticDir;
|
|
2240
2244
|
await this.startGateway({
|
|
2241
2245
|
uiOverrides: options.uiOverrides,
|
|
2242
2246
|
allowMissingProvider: true,
|
|
2243
|
-
uiStaticDir
|
|
2247
|
+
uiStaticDir: resolveUiStaticDir()
|
|
2244
2248
|
});
|
|
2245
2249
|
}
|
|
2246
2250
|
async startService(options) {
|
|
@@ -2274,7 +2278,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
2274
2278
|
console.log(
|
|
2275
2279
|
`Note: requested UI bind (${uiConfig.host}:${uiConfig.port}) differs from running service (${parsedUi.host}:${parsedUi.port}).`
|
|
2276
2280
|
);
|
|
2277
|
-
console.log(`Run: ${APP_NAME} restart
|
|
2281
|
+
console.log(`Run: ${APP_NAME} restart`);
|
|
2278
2282
|
}
|
|
2279
2283
|
console.log(`Logs: ${existing.logPath}`);
|
|
2280
2284
|
console.log(`Stop: ${APP_NAME} stop`);
|
|
@@ -2283,8 +2287,8 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
2283
2287
|
if (existing) {
|
|
2284
2288
|
clearServiceState();
|
|
2285
2289
|
}
|
|
2286
|
-
if (!staticDir
|
|
2287
|
-
console.log("Warning: UI frontend not found
|
|
2290
|
+
if (!staticDir) {
|
|
2291
|
+
console.log("Warning: UI frontend not found in package assets.");
|
|
2288
2292
|
}
|
|
2289
2293
|
const logPath = resolveServiceLogPath();
|
|
2290
2294
|
const logDir = resolve4(logPath, "..");
|
|
@@ -2292,9 +2296,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
2292
2296
|
const logFd = openSync(logPath, "a");
|
|
2293
2297
|
const serveArgs = buildServeArgs({
|
|
2294
2298
|
uiHost: uiConfig.host,
|
|
2295
|
-
uiPort: uiConfig.port
|
|
2296
|
-
frontend: options.frontend,
|
|
2297
|
-
frontendPort: options.frontendPort
|
|
2299
|
+
uiPort: uiConfig.port
|
|
2298
2300
|
});
|
|
2299
2301
|
const child = spawn2(process.execPath, [...process.execArgv, ...serveArgs], {
|
|
2300
2302
|
env: process.env,
|
|
@@ -2595,11 +2597,11 @@ var runtime = new CliRuntime({ logo: LOGO });
|
|
|
2595
2597
|
program.name(APP_NAME2).description(`${LOGO} ${APP_NAME2} - ${APP_TAGLINE}`).version(getPackageVersion(), "-v, --version", "show version");
|
|
2596
2598
|
program.command("onboard").description(`Initialize ${APP_NAME2} configuration and workspace`).action(async () => runtime.onboard());
|
|
2597
2599
|
program.command("init").description(`Initialize ${APP_NAME2} configuration and workspace`).option("-f, --force", "Overwrite existing template files").action(async (opts) => runtime.init({ force: Boolean(opts.force) }));
|
|
2598
|
-
program.command("gateway").description(`Start the ${APP_NAME2} gateway`).option("-p, --port <port>", "Gateway port", "18790").option("-v, --verbose", "Verbose output", false).option("--ui", "Enable UI server", false).option("--ui-
|
|
2599
|
-
program.command("ui").description(`Start the ${APP_NAME2} UI with gateway`).option("--
|
|
2600
|
-
program.command("start").description(`Start the ${APP_NAME2} gateway + UI in the background`).option("--ui-
|
|
2601
|
-
program.command("restart").description(`Restart the ${APP_NAME2} background service`).option("--ui-
|
|
2602
|
-
program.command("serve").description(`Run the ${APP_NAME2} gateway + UI in the foreground`).option("--ui-
|
|
2600
|
+
program.command("gateway").description(`Start the ${APP_NAME2} gateway`).option("-p, --port <port>", "Gateway port", "18790").option("-v, --verbose", "Verbose output", false).option("--ui", "Enable UI server", false).option("--ui-port <port>", "UI port").option("--ui-open", "Open browser when UI starts", false).action(async (opts) => runtime.gateway(opts));
|
|
2601
|
+
program.command("ui").description(`Start the ${APP_NAME2} UI with gateway`).option("--port <port>", "UI port").option("--no-open", "Disable opening browser").action(async (opts) => runtime.ui(opts));
|
|
2602
|
+
program.command("start").description(`Start the ${APP_NAME2} gateway + UI in the background`).option("--ui-port <port>", "UI port").option("--open", "Open browser after start", false).action(async (opts) => runtime.start(opts));
|
|
2603
|
+
program.command("restart").description(`Restart the ${APP_NAME2} background service`).option("--ui-port <port>", "UI port").option("--open", "Open browser after restart", false).action(async (opts) => runtime.restart(opts));
|
|
2604
|
+
program.command("serve").description(`Run the ${APP_NAME2} gateway + UI in the foreground`).option("--ui-port <port>", "UI port").option("--open", "Open browser after start", false).action(async (opts) => runtime.serve(opts));
|
|
2603
2605
|
program.command("stop").description(`Stop the ${APP_NAME2} background service`).action(async () => runtime.stop());
|
|
2604
2606
|
program.command("agent").description("Interact with the agent directly").option("-m, --message <message>", "Message to send to the agent").option("-s, --session <session>", "Session ID", "cli:default").option("--no-markdown", "Disable Markdown rendering").action(async (opts) => runtime.agent(opts));
|
|
2605
2607
|
program.command("update").description(`Update ${APP_NAME2}`).option("--timeout <ms>", "Update command timeout in milliseconds").action(async (opts) => runtime.update(opts));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextclaw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"chokidar": "^3.6.0",
|
|
40
40
|
"commander": "^12.1.0",
|
|
41
|
-
"@nextclaw/core": "^0.
|
|
42
|
-
"@nextclaw/server": "^0.3.
|
|
43
|
-
"@nextclaw/openclaw-compat": "^0.1.
|
|
41
|
+
"@nextclaw/core": "^0.5.0",
|
|
42
|
+
"@nextclaw/server": "^0.3.6",
|
|
43
|
+
"@nextclaw/openclaw-compat": "^0.1.3"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "^20.17.6",
|