nextclaw 0.16.20 → 0.16.22
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 +90 -56
- package/package.json +9 -9
- package/templates/USAGE.md +12 -4
package/dist/cli/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadConfig as loadConfig21,
|
|
11
11
|
saveConfig as saveConfig11,
|
|
12
12
|
getConfigPath as getConfigPath11,
|
|
13
|
-
getDataDir as
|
|
13
|
+
getDataDir as getDataDir11,
|
|
14
14
|
getWorkspacePath as getWorkspacePath13,
|
|
15
15
|
expandHome as expandHome2,
|
|
16
16
|
MessageBus as MessageBus3,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
setPluginRuntimeBridge as setPluginRuntimeBridge3
|
|
29
29
|
} from "@nextclaw/openclaw-compat";
|
|
30
30
|
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
|
|
31
|
-
import { join as join9, resolve as
|
|
31
|
+
import { join as join9, resolve as resolve15 } from "path";
|
|
32
32
|
import { createInterface as createInterface3 } from "readline";
|
|
33
33
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
34
34
|
import { spawn as spawn4 } from "child_process";
|
|
@@ -456,8 +456,8 @@ function isRecord(value) {
|
|
|
456
456
|
var MARKETPLACE_NETWORK_RETRY_ATTEMPTS = 5;
|
|
457
457
|
var MARKETPLACE_NETWORK_RETRY_BASE_MS = 350;
|
|
458
458
|
function sleepMs(ms) {
|
|
459
|
-
return new Promise((
|
|
460
|
-
setTimeout(
|
|
459
|
+
return new Promise((resolve16) => {
|
|
460
|
+
setTimeout(resolve16, ms);
|
|
461
461
|
});
|
|
462
462
|
}
|
|
463
463
|
function isRetryableMarketplaceNetworkError(error) {
|
|
@@ -853,6 +853,7 @@ function isRecord2(value) {
|
|
|
853
853
|
// src/cli/update/runner.ts
|
|
854
854
|
import { spawnSync } from "child_process";
|
|
855
855
|
import { resolve as resolve5 } from "path";
|
|
856
|
+
import { createExternalCommandEnv as createExternalCommandEnv2 } from "@nextclaw/core";
|
|
856
857
|
|
|
857
858
|
// src/cli/utils.ts
|
|
858
859
|
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, rmSync as rmSync3 } from "fs";
|
|
@@ -860,7 +861,11 @@ import { join as join2, resolve as resolve4 } from "path";
|
|
|
860
861
|
import { spawn } from "child_process";
|
|
861
862
|
import { isIP } from "net";
|
|
862
863
|
import { fileURLToPath } from "url";
|
|
863
|
-
import {
|
|
864
|
+
import {
|
|
865
|
+
createExternalCommandEnv,
|
|
866
|
+
getDataDir as getDataDir2,
|
|
867
|
+
getPackageVersion as getCorePackageVersion
|
|
868
|
+
} from "@nextclaw/core";
|
|
864
869
|
function resolveUiConfig(config2, overrides) {
|
|
865
870
|
const base = config2.ui ?? { enabled: false, host: "127.0.0.1", port: 55667, open: false };
|
|
866
871
|
return { ...base, ...overrides ?? {} };
|
|
@@ -960,7 +965,7 @@ async function waitForExit(pid, timeoutMs) {
|
|
|
960
965
|
if (!isProcessRunning(pid)) {
|
|
961
966
|
return true;
|
|
962
967
|
}
|
|
963
|
-
await new Promise((
|
|
968
|
+
await new Promise((resolve16) => setTimeout(resolve16, 200));
|
|
964
969
|
}
|
|
965
970
|
return !isProcessRunning(pid);
|
|
966
971
|
}
|
|
@@ -991,7 +996,11 @@ function openBrowser(url) {
|
|
|
991
996
|
command = "xdg-open";
|
|
992
997
|
args = [url];
|
|
993
998
|
}
|
|
994
|
-
const child = spawn(command, args, {
|
|
999
|
+
const child = spawn(command, args, {
|
|
1000
|
+
stdio: "ignore",
|
|
1001
|
+
detached: true,
|
|
1002
|
+
env: createExternalCommandEnv(process.env)
|
|
1003
|
+
});
|
|
995
1004
|
child.unref();
|
|
996
1005
|
}
|
|
997
1006
|
function normalizePathEntries(rawPath, platform) {
|
|
@@ -1087,8 +1096,8 @@ function printAgentResponse(response) {
|
|
|
1087
1096
|
async function prompt(rl, question) {
|
|
1088
1097
|
rl.setPrompt(question);
|
|
1089
1098
|
rl.prompt();
|
|
1090
|
-
return new Promise((
|
|
1091
|
-
rl.once("line", (line) =>
|
|
1099
|
+
return new Promise((resolve16) => {
|
|
1100
|
+
rl.once("line", (line) => resolve16(line));
|
|
1092
1101
|
});
|
|
1093
1102
|
}
|
|
1094
1103
|
|
|
@@ -1108,6 +1117,7 @@ function runSelfUpdate(options = {}) {
|
|
|
1108
1117
|
const runStep = (cmd, args, cwd) => {
|
|
1109
1118
|
const result = spawnSync(cmd, args, {
|
|
1110
1119
|
cwd,
|
|
1120
|
+
env: createExternalCommandEnv2(process.env),
|
|
1111
1121
|
encoding: "utf-8",
|
|
1112
1122
|
timeout: timeoutMs,
|
|
1113
1123
|
stdio: "pipe"
|
|
@@ -1888,8 +1898,8 @@ var PluginCommands = class {
|
|
|
1888
1898
|
input: process.stdin,
|
|
1889
1899
|
output: process.stdout
|
|
1890
1900
|
});
|
|
1891
|
-
const answer = await new Promise((
|
|
1892
|
-
rl.question(`${question} [y/N] `, (line) =>
|
|
1901
|
+
const answer = await new Promise((resolve16) => {
|
|
1902
|
+
rl.question(`${question} [y/N] `, (line) => resolve16(line));
|
|
1893
1903
|
});
|
|
1894
1904
|
rl.close();
|
|
1895
1905
|
const normalized = answer.trim().toLowerCase();
|
|
@@ -3066,7 +3076,7 @@ function printCronJobs(jobs) {
|
|
|
3066
3076
|
return;
|
|
3067
3077
|
}
|
|
3068
3078
|
for (const job of jobs) {
|
|
3069
|
-
console.log(`${job.id} ${job.name} ${formatCronSchedule(job.schedule)}`);
|
|
3079
|
+
console.log(`${job.id} [${job.enabled ? "enabled" : "disabled"}] ${job.name} ${formatCronSchedule(job.schedule)}`);
|
|
3070
3080
|
}
|
|
3071
3081
|
}
|
|
3072
3082
|
|
|
@@ -3142,10 +3152,11 @@ var CronCommands = class {
|
|
|
3142
3152
|
return new UiBridgeApiClient(apiBase);
|
|
3143
3153
|
};
|
|
3144
3154
|
cronList = async (opts) => {
|
|
3155
|
+
const includeDisabled = opts.enabledOnly !== true;
|
|
3145
3156
|
const apiClient = this.createApiClient();
|
|
3146
3157
|
if (apiClient) {
|
|
3147
3158
|
try {
|
|
3148
|
-
const query =
|
|
3159
|
+
const query = includeDisabled ? "" : "?enabledOnly=1";
|
|
3149
3160
|
const data = await apiClient.request({
|
|
3150
3161
|
path: `/api/cron${query}`
|
|
3151
3162
|
});
|
|
@@ -3154,7 +3165,7 @@ var CronCommands = class {
|
|
|
3154
3165
|
} catch {
|
|
3155
3166
|
}
|
|
3156
3167
|
}
|
|
3157
|
-
printCronJobs(this.local.list(
|
|
3168
|
+
printCronJobs(this.local.list(includeDisabled));
|
|
3158
3169
|
};
|
|
3159
3170
|
cronAdd = async (opts) => {
|
|
3160
3171
|
const result = this.local.add(opts);
|
|
@@ -4172,17 +4183,17 @@ var DiagnosticsCommands = class {
|
|
|
4172
4183
|
}
|
|
4173
4184
|
}
|
|
4174
4185
|
async checkPortAvailability(params) {
|
|
4175
|
-
return await new Promise((
|
|
4186
|
+
return await new Promise((resolve16) => {
|
|
4176
4187
|
const server = createNetServer();
|
|
4177
4188
|
server.once("error", (error) => {
|
|
4178
|
-
|
|
4189
|
+
resolve16({
|
|
4179
4190
|
available: false,
|
|
4180
4191
|
detail: `bind failed on ${params.host}:${params.port} (${String(error)})`
|
|
4181
4192
|
});
|
|
4182
4193
|
});
|
|
4183
4194
|
server.listen(params.port, params.host, () => {
|
|
4184
4195
|
server.close(() => {
|
|
4185
|
-
|
|
4196
|
+
resolve16({
|
|
4186
4197
|
available: true,
|
|
4187
4198
|
detail: `bind ok on ${params.host}:${params.port}`
|
|
4188
4199
|
});
|
|
@@ -4200,13 +4211,13 @@ import {
|
|
|
4200
4211
|
stopPluginChannelGateways as stopPluginChannelGateways2
|
|
4201
4212
|
} from "@nextclaw/openclaw-compat";
|
|
4202
4213
|
import { appendFileSync, closeSync as closeSync2, cpSync as cpSync2, existsSync as existsSync11, mkdirSync as mkdirSync5, openSync as openSync2 } from "fs";
|
|
4203
|
-
import { dirname as dirname3, join as join7, resolve as
|
|
4214
|
+
import { dirname as dirname3, join as join7, resolve as resolve13 } from "path";
|
|
4204
4215
|
import { spawn as spawn3 } from "child_process";
|
|
4205
4216
|
import { request as httpRequest } from "http";
|
|
4206
4217
|
import { request as httpsRequest } from "https";
|
|
4207
4218
|
import { createServer as createNetServer2 } from "net";
|
|
4208
4219
|
import { setImmediate as waitForNextTick } from "timers/promises";
|
|
4209
|
-
import
|
|
4220
|
+
import chokidar2 from "chokidar";
|
|
4210
4221
|
|
|
4211
4222
|
// src/cli/missing-provider.ts
|
|
4212
4223
|
import { LLMProvider } from "@nextclaw/core";
|
|
@@ -4461,6 +4472,8 @@ var ServiceMarketplaceInstaller = class {
|
|
|
4461
4472
|
};
|
|
4462
4473
|
|
|
4463
4474
|
// src/cli/commands/service-startup-support.ts
|
|
4475
|
+
import chokidar from "chokidar";
|
|
4476
|
+
import { resolve as resolve9 } from "path";
|
|
4464
4477
|
var pluginGatewayLogger = {
|
|
4465
4478
|
info: (message) => console.log(`[plugins] ${message}`),
|
|
4466
4479
|
warn: (message) => console.warn(`[plugins] ${message}`),
|
|
@@ -4488,16 +4501,35 @@ async function startGatewaySupportServices(params) {
|
|
|
4488
4501
|
await params.startCron();
|
|
4489
4502
|
await params.startHeartbeat();
|
|
4490
4503
|
}
|
|
4504
|
+
function watchCronStoreFile(params) {
|
|
4505
|
+
const cronStorePath = resolve9(params.cronStorePath);
|
|
4506
|
+
const watcher = chokidar.watch(cronStorePath, {
|
|
4507
|
+
ignoreInitial: true,
|
|
4508
|
+
awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 }
|
|
4509
|
+
});
|
|
4510
|
+
watcher.on("all", (event, changedPath) => {
|
|
4511
|
+
if (resolve9(changedPath) !== cronStorePath) {
|
|
4512
|
+
return;
|
|
4513
|
+
}
|
|
4514
|
+
if (event === "add" || event === "change" || event === "unlink") {
|
|
4515
|
+
try {
|
|
4516
|
+
params.reloadCronStore();
|
|
4517
|
+
} catch (error) {
|
|
4518
|
+
console.error(`Cron store reload failed (${event}): ${String(error)}`);
|
|
4519
|
+
}
|
|
4520
|
+
}
|
|
4521
|
+
});
|
|
4522
|
+
}
|
|
4491
4523
|
|
|
4492
4524
|
// src/cli/commands/cli-subcommand-launch.ts
|
|
4493
4525
|
import { createRequire } from "module";
|
|
4494
|
-
import { extname, resolve as
|
|
4526
|
+
import { extname, resolve as resolve10 } from "path";
|
|
4495
4527
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4496
4528
|
var require2 = createRequire(import.meta.url);
|
|
4497
4529
|
var resolveCliSubcommandEntry = (params) => {
|
|
4498
4530
|
const argvEntry = params.argvEntry?.trim();
|
|
4499
4531
|
if (argvEntry) {
|
|
4500
|
-
return
|
|
4532
|
+
return resolve10(argvEntry);
|
|
4501
4533
|
}
|
|
4502
4534
|
return fileURLToPath3(new URL("../index.js", params.importMetaUrl));
|
|
4503
4535
|
};
|
|
@@ -4514,10 +4546,10 @@ import {
|
|
|
4514
4546
|
unlinkSync,
|
|
4515
4547
|
writeFileSync as writeFileSync4
|
|
4516
4548
|
} from "fs";
|
|
4517
|
-
import { dirname as dirname2, resolve as
|
|
4549
|
+
import { dirname as dirname2, resolve as resolve11 } from "path";
|
|
4518
4550
|
import { getDataDir as getDataDir6 } from "@nextclaw/core";
|
|
4519
4551
|
function resolveRemoteOwnershipLockPath() {
|
|
4520
|
-
return
|
|
4552
|
+
return resolve11(getDataDir6(), "run", "remote-owner.lock.json");
|
|
4521
4553
|
}
|
|
4522
4554
|
function readRemoteOwnershipRecord(lockPath) {
|
|
4523
4555
|
try {
|
|
@@ -5051,7 +5083,7 @@ import {
|
|
|
5051
5083
|
} from "@nextclaw/ncp-toolkit";
|
|
5052
5084
|
|
|
5053
5085
|
// src/cli/commands/ncp/ncp-asset-tools.ts
|
|
5054
|
-
import { resolve as
|
|
5086
|
+
import { resolve as resolve12 } from "path";
|
|
5055
5087
|
import {
|
|
5056
5088
|
buildAssetContentPath
|
|
5057
5089
|
} from "@nextclaw/ncp-agent-runtime";
|
|
@@ -5167,7 +5199,7 @@ var AssetExportTool = class {
|
|
|
5167
5199
|
if (!assetUri || !targetPath) {
|
|
5168
5200
|
throw new Error("asset_export requires assetUri and targetPath.");
|
|
5169
5201
|
}
|
|
5170
|
-
const exportedPath = await this.assetStore.export({ uri: assetUri },
|
|
5202
|
+
const exportedPath = await this.assetStore.export({ uri: assetUri }, resolve12(targetPath));
|
|
5171
5203
|
return {
|
|
5172
5204
|
ok: true,
|
|
5173
5205
|
assetUri,
|
|
@@ -9040,6 +9072,7 @@ var ServiceCommands = class {
|
|
|
9040
9072
|
startHeartbeat: () => gateway.heartbeat.start()
|
|
9041
9073
|
})
|
|
9042
9074
|
);
|
|
9075
|
+
watchCronStoreFile({ cronStorePath: resolve13(join7(NextclawCore3.getDataDir(), "cron", "jobs.json")), reloadCronStore: () => gateway.cron.reloadFromStore() });
|
|
9043
9076
|
const deferredGatewayStartupHooks = createDeferredGatewayStartupHooks({
|
|
9044
9077
|
uiStartup,
|
|
9045
9078
|
gateway,
|
|
@@ -9105,13 +9138,13 @@ var ServiceCommands = class {
|
|
|
9105
9138
|
return trimmed || void 0;
|
|
9106
9139
|
}
|
|
9107
9140
|
watchConfigFile(reloader) {
|
|
9108
|
-
const configPath =
|
|
9109
|
-
const watcher =
|
|
9141
|
+
const configPath = resolve13(getConfigPath10());
|
|
9142
|
+
const watcher = chokidar2.watch(configPath, {
|
|
9110
9143
|
ignoreInitial: true,
|
|
9111
9144
|
awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 }
|
|
9112
9145
|
});
|
|
9113
9146
|
watcher.on("all", (event, changedPath) => {
|
|
9114
|
-
if (
|
|
9147
|
+
if (resolve13(changedPath) !== configPath) {
|
|
9115
9148
|
return;
|
|
9116
9149
|
}
|
|
9117
9150
|
if (event === "add") {
|
|
@@ -9180,7 +9213,7 @@ var ServiceCommands = class {
|
|
|
9180
9213
|
if (!sentinel) {
|
|
9181
9214
|
return;
|
|
9182
9215
|
}
|
|
9183
|
-
await new Promise((
|
|
9216
|
+
await new Promise((resolve16) => setTimeout(resolve16, 750));
|
|
9184
9217
|
const payload = sentinel.payload;
|
|
9185
9218
|
const summary = formatRestartSentinelMessage(payload);
|
|
9186
9219
|
const sentinelSessionKey = this.normalizeOptionalString(payload.sessionKey);
|
|
@@ -9299,7 +9332,7 @@ var ServiceCommands = class {
|
|
|
9299
9332
|
return;
|
|
9300
9333
|
}
|
|
9301
9334
|
const logPath = resolveServiceLogPath();
|
|
9302
|
-
const logDir =
|
|
9335
|
+
const logDir = resolve13(logPath, "..");
|
|
9303
9336
|
mkdirSync5(logDir, { recursive: true });
|
|
9304
9337
|
const logFd = openSync2(logPath, "a");
|
|
9305
9338
|
const readinessTimeoutMs = this.resolveStartupTimeoutMs(options.startupTimeoutMs);
|
|
@@ -9441,14 +9474,14 @@ var ServiceCommands = class {
|
|
|
9441
9474
|
const probe = await this.probeHealthEndpoint(params.healthUrl);
|
|
9442
9475
|
if (!probe.healthy) {
|
|
9443
9476
|
lastProbeError = probe.error;
|
|
9444
|
-
await new Promise((
|
|
9477
|
+
await new Promise((resolve16) => setTimeout(resolve16, 200));
|
|
9445
9478
|
continue;
|
|
9446
9479
|
}
|
|
9447
|
-
await new Promise((
|
|
9480
|
+
await new Promise((resolve16) => setTimeout(resolve16, 300));
|
|
9448
9481
|
if (isProcessRunning(params.pid)) {
|
|
9449
9482
|
return { ready: true, lastProbeError: null };
|
|
9450
9483
|
}
|
|
9451
|
-
await new Promise((
|
|
9484
|
+
await new Promise((resolve16) => setTimeout(resolve16, 200));
|
|
9452
9485
|
}
|
|
9453
9486
|
return { ready: false, lastProbeError };
|
|
9454
9487
|
}
|
|
@@ -9519,17 +9552,17 @@ var ServiceCommands = class {
|
|
|
9519
9552
|
};
|
|
9520
9553
|
}
|
|
9521
9554
|
async checkPortAvailability(params) {
|
|
9522
|
-
return await new Promise((
|
|
9555
|
+
return await new Promise((resolve16) => {
|
|
9523
9556
|
const server = createNetServer2();
|
|
9524
9557
|
server.once("error", (error) => {
|
|
9525
|
-
|
|
9558
|
+
resolve16({
|
|
9526
9559
|
available: false,
|
|
9527
9560
|
detail: `bind failed on ${params.host}:${params.port} (${String(error)})`
|
|
9528
9561
|
});
|
|
9529
9562
|
});
|
|
9530
9563
|
server.listen(params.port, params.host, () => {
|
|
9531
9564
|
server.close(() => {
|
|
9532
|
-
|
|
9565
|
+
resolve16({
|
|
9533
9566
|
available: true,
|
|
9534
9567
|
detail: `bind ok on ${params.host}:${params.port}`
|
|
9535
9568
|
});
|
|
@@ -9565,7 +9598,7 @@ var ServiceCommands = class {
|
|
|
9565
9598
|
return { healthy: false, error: "invalid health URL" };
|
|
9566
9599
|
}
|
|
9567
9600
|
const requestImpl = parsed.protocol === "https:" ? httpsRequest : httpRequest;
|
|
9568
|
-
return new Promise((
|
|
9601
|
+
return new Promise((resolve16) => {
|
|
9569
9602
|
const req = requestImpl(
|
|
9570
9603
|
{
|
|
9571
9604
|
protocol: parsed.protocol,
|
|
@@ -9601,19 +9634,19 @@ var ServiceCommands = class {
|
|
|
9601
9634
|
if (bodySnippet) {
|
|
9602
9635
|
details.push(`body=${bodySnippet}`);
|
|
9603
9636
|
}
|
|
9604
|
-
|
|
9637
|
+
resolve16({ healthy: false, error: details.join("; ") });
|
|
9605
9638
|
return;
|
|
9606
9639
|
}
|
|
9607
9640
|
try {
|
|
9608
9641
|
const payload = JSON.parse(responseText);
|
|
9609
9642
|
const healthy = payload?.ok === true && payload?.data?.status === "ok";
|
|
9610
9643
|
if (!healthy) {
|
|
9611
|
-
|
|
9644
|
+
resolve16({ healthy: false, error: "health payload not ok" });
|
|
9612
9645
|
return;
|
|
9613
9646
|
}
|
|
9614
|
-
|
|
9647
|
+
resolve16({ healthy: true, error: null });
|
|
9615
9648
|
} catch {
|
|
9616
|
-
|
|
9649
|
+
resolve16({ healthy: false, error: "invalid health JSON response" });
|
|
9617
9650
|
}
|
|
9618
9651
|
});
|
|
9619
9652
|
}
|
|
@@ -9622,7 +9655,7 @@ var ServiceCommands = class {
|
|
|
9622
9655
|
req.destroy(new Error("probe timeout"));
|
|
9623
9656
|
});
|
|
9624
9657
|
req.on("error", (error) => {
|
|
9625
|
-
|
|
9658
|
+
resolve16({ healthy: false, error: error.message || String(error) });
|
|
9626
9659
|
});
|
|
9627
9660
|
req.end();
|
|
9628
9661
|
});
|
|
@@ -9768,9 +9801,9 @@ ${stderr}`.trim();
|
|
|
9768
9801
|
// src/cli/workspace.ts
|
|
9769
9802
|
import { cpSync as cpSync3, existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync9, readdirSync as readdirSync2, rmSync as rmSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
9770
9803
|
import { createRequire as createRequire2 } from "module";
|
|
9771
|
-
import { dirname as dirname4, join as join8, resolve as
|
|
9804
|
+
import { dirname as dirname4, join as join8, resolve as resolve14 } from "path";
|
|
9772
9805
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
9773
|
-
import { APP_NAME as APP_NAME4, getDataDir as
|
|
9806
|
+
import { APP_NAME as APP_NAME4, getDataDir as getDataDir10 } from "@nextclaw/core";
|
|
9774
9807
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
9775
9808
|
var WorkspaceManager = class {
|
|
9776
9809
|
constructor(logo) {
|
|
@@ -9862,7 +9895,7 @@ var WorkspaceManager = class {
|
|
|
9862
9895
|
try {
|
|
9863
9896
|
const require3 = createRequire2(import.meta.url);
|
|
9864
9897
|
const entry = require3.resolve("@nextclaw/core");
|
|
9865
|
-
const pkgRoot =
|
|
9898
|
+
const pkgRoot = resolve14(dirname4(entry), "..");
|
|
9866
9899
|
const distSkills = join8(pkgRoot, "dist", "skills");
|
|
9867
9900
|
if (existsSync12(distSkills)) {
|
|
9868
9901
|
return distSkills;
|
|
@@ -9881,8 +9914,8 @@ var WorkspaceManager = class {
|
|
|
9881
9914
|
if (override) {
|
|
9882
9915
|
return override;
|
|
9883
9916
|
}
|
|
9884
|
-
const cliDir =
|
|
9885
|
-
const pkgRoot =
|
|
9917
|
+
const cliDir = resolve14(fileURLToPath4(new URL(".", import.meta.url)));
|
|
9918
|
+
const pkgRoot = resolve14(cliDir, "..", "..");
|
|
9886
9919
|
const candidates = [join8(pkgRoot, "templates")];
|
|
9887
9920
|
for (const candidate of candidates) {
|
|
9888
9921
|
if (existsSync12(candidate)) {
|
|
@@ -9892,7 +9925,7 @@ var WorkspaceManager = class {
|
|
|
9892
9925
|
return null;
|
|
9893
9926
|
}
|
|
9894
9927
|
getBridgeDir() {
|
|
9895
|
-
const userBridge = join8(
|
|
9928
|
+
const userBridge = join8(getDataDir10(), "bridge");
|
|
9896
9929
|
if (existsSync12(join8(userBridge, "dist", "index.js"))) {
|
|
9897
9930
|
return userBridge;
|
|
9898
9931
|
}
|
|
@@ -9900,8 +9933,8 @@ var WorkspaceManager = class {
|
|
|
9900
9933
|
console.error("npm not found. Please install Node.js >= 18.");
|
|
9901
9934
|
process.exit(1);
|
|
9902
9935
|
}
|
|
9903
|
-
const cliDir =
|
|
9904
|
-
const pkgRoot =
|
|
9936
|
+
const cliDir = resolve14(fileURLToPath4(new URL(".", import.meta.url)));
|
|
9937
|
+
const pkgRoot = resolve14(cliDir, "..", "..");
|
|
9905
9938
|
const pkgBridge = join8(pkgRoot, "bridge");
|
|
9906
9939
|
const srcBridge = join8(pkgRoot, "..", "..", "bridge");
|
|
9907
9940
|
let source = null;
|
|
@@ -9915,7 +9948,7 @@ var WorkspaceManager = class {
|
|
|
9915
9948
|
process.exit(1);
|
|
9916
9949
|
}
|
|
9917
9950
|
console.log(`${this.logo} Setting up bridge...`);
|
|
9918
|
-
mkdirSync6(
|
|
9951
|
+
mkdirSync6(resolve14(userBridge, ".."), { recursive: true });
|
|
9919
9952
|
if (existsSync12(userBridge)) {
|
|
9920
9953
|
rmSync6(userBridge, { recursive: true, force: true });
|
|
9921
9954
|
}
|
|
@@ -10067,7 +10100,7 @@ var CliRuntime = class {
|
|
|
10067
10100
|
const delayMs = typeof params.delayMs === "number" && Number.isFinite(params.delayMs) ? Math.max(0, Math.floor(params.delayMs)) : 100;
|
|
10068
10101
|
const cliPath = process.env.NEXTCLAW_SELF_RELAUNCH_CLI?.trim() || fileURLToPath5(new URL("./index.js", import.meta.url));
|
|
10069
10102
|
const startArgs = [cliPath, "start", "--ui-port", String(uiPort)];
|
|
10070
|
-
const serviceStatePath =
|
|
10103
|
+
const serviceStatePath = resolve15(getDataDir11(), "run", "service.json");
|
|
10071
10104
|
const helperScript = [
|
|
10072
10105
|
'const { spawnSync } = require("node:child_process");',
|
|
10073
10106
|
'const { readFileSync } = require("node:fs");',
|
|
@@ -10199,7 +10232,7 @@ var CliRuntime = class {
|
|
|
10199
10232
|
const createdConfig = initializeConfigIfMissing(configPath);
|
|
10200
10233
|
const config2 = loadConfig21();
|
|
10201
10234
|
const workspaceSetting = config2.agents.defaults.workspace;
|
|
10202
|
-
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join9(
|
|
10235
|
+
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join9(getDataDir11(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
|
|
10203
10236
|
const workspaceExisted = existsSync13(workspacePath);
|
|
10204
10237
|
mkdirSync7(workspacePath, { recursive: true });
|
|
10205
10238
|
const templateResult = this.workspaceManager.createWorkspaceTemplates(
|
|
@@ -10392,8 +10425,8 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
|
|
|
10392
10425
|
`${this.logo} Interactive mode (type exit or Ctrl+C to quit)
|
|
10393
10426
|
`
|
|
10394
10427
|
);
|
|
10395
|
-
const historyFile = join9(
|
|
10396
|
-
const historyDir =
|
|
10428
|
+
const historyFile = join9(getDataDir11(), "history", "cli_history");
|
|
10429
|
+
const historyDir = resolve15(historyFile, "..");
|
|
10397
10430
|
mkdirSync7(historyDir, { recursive: true });
|
|
10398
10431
|
const history = existsSync13(historyFile) ? readFileSync10(historyFile, "utf-8").split("\n").filter(Boolean) : [];
|
|
10399
10432
|
const rl = createInterface3({
|
|
@@ -10685,10 +10718,11 @@ channels.command("add").description("Configure a plugin channel (OpenClaw-compat
|
|
|
10685
10718
|
channels.command("status").description("Show channel status").action(() => runtime.channelsStatus());
|
|
10686
10719
|
channels.command("login").description("Link device via QR code").option("--channel <id>", "Plugin channel id").option("--account <id>", "Channel account id").option("--url <url>", "Channel API base URL").option("--http-url <url>", "Alias for --url").option("-v, --verbose", "Verbose output", false).action(async (opts) => runtime.channelsLogin(opts));
|
|
10687
10720
|
var cron = program.command("cron").description("Manage scheduled tasks");
|
|
10688
|
-
cron.command("list").option("-a, --all", "
|
|
10721
|
+
cron.command("list").option("--enabled-only", "Show only enabled jobs", false).option("-a, --all", "Deprecated: list all jobs (default behavior)", false).action(async (opts) => runtime.cronList({ enabledOnly: Boolean(opts.enabledOnly) }));
|
|
10689
10722
|
cron.command("add").requiredOption("-n, --name <name>", "Job name").requiredOption("-m, --message <message>", "Message for agent").option("-e, --every <seconds>", "Run every N seconds").option("-c, --cron <expr>", "Cron expression").option("--at <iso>", "Run once at time (ISO format)").option("-d, --deliver", "Deliver response to channel").option("--to <recipient>", "Recipient for delivery").option("--channel <channel>", "Channel for delivery").option("--account <id>", "Account id for channel delivery").action(async (opts) => runtime.cronAdd(opts));
|
|
10690
10723
|
cron.command("remove <jobId>").action(async (jobId) => runtime.cronRemove(jobId));
|
|
10691
10724
|
cron.command("enable <jobId>").option("--disable", "Disable instead of enable").action(async (jobId, opts) => runtime.cronEnable(jobId, opts));
|
|
10725
|
+
cron.command("disable <jobId>").action(async (jobId) => runtime.cronEnable(jobId, { disable: true }));
|
|
10692
10726
|
cron.command("run <jobId>").option("-f, --force", "Run even if disabled").action(async (jobId, opts) => runtime.cronRun(jobId, opts));
|
|
10693
10727
|
program.command("status").description(`Show ${APP_NAME6} status`).option("--json", "Output JSON", false).option("--verbose", "Show extra diagnostics", false).option("--fix", "Fix stale service state when safe", false).action(async (opts) => runtime.status(opts));
|
|
10694
10728
|
program.command("doctor").description(`Run ${APP_NAME6} diagnostics`).option("--json", "Output JSON", false).option("--verbose", "Show extra diagnostics", false).option("--fix", "Fix stale service state when safe", false).action(async (opts) => runtime.doctor(opts));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextclaw",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.22",
|
|
4
4
|
"description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -39,16 +39,16 @@
|
|
|
39
39
|
"chokidar": "^3.6.0",
|
|
40
40
|
"commander": "^12.1.0",
|
|
41
41
|
"yaml": "^2.8.1",
|
|
42
|
-
"@nextclaw/core": "0.11.7",
|
|
43
|
-
"@nextclaw/mcp": "0.1.54",
|
|
44
|
-
"@nextclaw/ncp": "0.4.1",
|
|
45
42
|
"@nextclaw/ncp-agent-runtime": "0.3.1",
|
|
46
|
-
"@nextclaw/
|
|
43
|
+
"@nextclaw/core": "0.11.9",
|
|
44
|
+
"@nextclaw/ncp-mcp": "0.1.57",
|
|
45
|
+
"@nextclaw/ncp": "0.4.1",
|
|
46
|
+
"@nextclaw/mcp": "0.1.56",
|
|
47
|
+
"@nextclaw/remote": "0.1.66",
|
|
48
|
+
"@nextclaw/runtime": "0.2.23",
|
|
47
49
|
"@nextclaw/ncp-toolkit": "0.4.7",
|
|
48
|
-
"@nextclaw/
|
|
49
|
-
"@nextclaw/
|
|
50
|
-
"@nextclaw/server": "0.11.12",
|
|
51
|
-
"@nextclaw/openclaw-compat": "0.3.46"
|
|
50
|
+
"@nextclaw/server": "0.11.14",
|
|
51
|
+
"@nextclaw/openclaw-compat": "0.3.48"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^20.17.6",
|
package/templates/USAGE.md
CHANGED
|
@@ -502,10 +502,11 @@ Created under the workspace:
|
|
|
502
502
|
| `nextclaw doctor` | Run runtime diagnostics (`--json`, `--verbose`, `--fix`) |
|
|
503
503
|
| `nextclaw channels login` | Open QR login for supported channels |
|
|
504
504
|
| `nextclaw channels add --channel <id> ...` | Configure plugin channel via setup adapter |
|
|
505
|
-
| `nextclaw cron list` | List scheduled jobs |
|
|
505
|
+
| `nextclaw cron list` | List all scheduled jobs, including disabled ones |
|
|
506
506
|
| `nextclaw cron add ...` | Add a cron job (see [Cron](#cron--heartbeat)) |
|
|
507
507
|
| `nextclaw cron remove <jobId>` | Remove a job |
|
|
508
|
-
| `nextclaw cron enable <jobId>` | Enable a job
|
|
508
|
+
| `nextclaw cron enable <jobId>` | Enable a disabled job |
|
|
509
|
+
| `nextclaw cron disable <jobId>` | Disable a job without deleting it |
|
|
509
510
|
| `nextclaw cron run <jobId>` | Run a job once (optionally with `--force` if disabled) |
|
|
510
511
|
| `nextclaw skills install <slug>` | Install a skill from NextClaw marketplace |
|
|
511
512
|
| `nextclaw skills publish <dir>` | Upload/create a skill to marketplace |
|
|
@@ -944,12 +945,19 @@ Optional: deliver the agent’s reply to a channel:
|
|
|
944
945
|
nextclaw cron add -n "daily" -m "Daily briefing" -c "0 9 * * *" --deliver --to <recipient> --channel <channel>
|
|
945
946
|
```
|
|
946
947
|
|
|
947
|
-
|
|
948
|
+
List all jobs by default, or only enabled ones if needed:
|
|
949
|
+
|
|
950
|
+
```bash
|
|
951
|
+
nextclaw cron list
|
|
952
|
+
nextclaw cron list --enabled-only
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
Remove or change a job's enabled state:
|
|
948
956
|
|
|
949
957
|
```bash
|
|
950
958
|
nextclaw cron remove <jobId>
|
|
951
959
|
nextclaw cron enable <jobId>
|
|
952
|
-
nextclaw cron
|
|
960
|
+
nextclaw cron disable <jobId>
|
|
953
961
|
```
|
|
954
962
|
|
|
955
963
|
Run a job once (e.g. for testing):
|