nextclaw 0.4.5 → 0.4.6
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 +117 -92
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -43,19 +43,16 @@ import {
|
|
|
43
43
|
rmSync as rmSync2,
|
|
44
44
|
writeFileSync as writeFileSync2
|
|
45
45
|
} from "fs";
|
|
46
|
-
import { dirname, join as
|
|
46
|
+
import { dirname, join as join3, resolve as resolve4 } from "path";
|
|
47
47
|
import { spawn as spawn2, spawnSync as spawnSync3 } from "child_process";
|
|
48
48
|
import { createInterface } from "readline";
|
|
49
49
|
import { createRequire } from "module";
|
|
50
|
-
import { fileURLToPath as
|
|
50
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
51
51
|
import chokidar from "chokidar";
|
|
52
52
|
|
|
53
53
|
// src/cli/gateway/controller.ts
|
|
54
54
|
import { createHash } from "crypto";
|
|
55
55
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
56
|
-
import { spawnSync } from "child_process";
|
|
57
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
58
|
-
import { join as join2, resolve as resolve2 } from "path";
|
|
59
56
|
import {
|
|
60
57
|
ConfigSchema
|
|
61
58
|
} from "nextclaw-core";
|
|
@@ -297,6 +294,50 @@ async function prompt(rl, question) {
|
|
|
297
294
|
});
|
|
298
295
|
}
|
|
299
296
|
|
|
297
|
+
// src/cli/update/runner.ts
|
|
298
|
+
import { spawnSync } from "child_process";
|
|
299
|
+
import { resolve as resolve2 } from "path";
|
|
300
|
+
var DEFAULT_TIMEOUT_MS = 20 * 6e4;
|
|
301
|
+
function runSelfUpdate(options = {}) {
|
|
302
|
+
const steps = [];
|
|
303
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
304
|
+
const updateCommand = options.updateCommand ?? process.env.NEXTCLAW_UPDATE_COMMAND?.trim();
|
|
305
|
+
const packageName = options.packageName ?? "nextclaw";
|
|
306
|
+
const runStep = (cmd, args, cwd) => {
|
|
307
|
+
const result = spawnSync(cmd, args, {
|
|
308
|
+
cwd,
|
|
309
|
+
encoding: "utf-8",
|
|
310
|
+
timeout: timeoutMs,
|
|
311
|
+
stdio: "pipe"
|
|
312
|
+
});
|
|
313
|
+
steps.push({
|
|
314
|
+
cmd,
|
|
315
|
+
args,
|
|
316
|
+
cwd,
|
|
317
|
+
code: result.status,
|
|
318
|
+
stdout: (result.stdout ?? "").toString().slice(0, 4e3),
|
|
319
|
+
stderr: (result.stderr ?? "").toString().slice(0, 4e3)
|
|
320
|
+
});
|
|
321
|
+
return { ok: result.status === 0, code: result.status };
|
|
322
|
+
};
|
|
323
|
+
if (updateCommand) {
|
|
324
|
+
const cwd = options.cwd ? resolve2(options.cwd) : process.cwd();
|
|
325
|
+
const ok = runStep("sh", ["-c", updateCommand], cwd);
|
|
326
|
+
if (!ok.ok) {
|
|
327
|
+
return { ok: false, error: "update command failed", strategy: "command", steps };
|
|
328
|
+
}
|
|
329
|
+
return { ok: true, strategy: "command", steps };
|
|
330
|
+
}
|
|
331
|
+
if (which("npm")) {
|
|
332
|
+
const ok = runStep("npm", ["i", "-g", packageName], process.cwd());
|
|
333
|
+
if (!ok.ok) {
|
|
334
|
+
return { ok: false, error: `npm install -g ${packageName} failed`, strategy: "npm", steps };
|
|
335
|
+
}
|
|
336
|
+
return { ok: true, strategy: "npm", steps };
|
|
337
|
+
}
|
|
338
|
+
return { ok: false, error: "no update strategy available", strategy: "none", steps };
|
|
339
|
+
}
|
|
340
|
+
|
|
300
341
|
// src/cli/gateway/controller.ts
|
|
301
342
|
var hashRaw = (raw) => createHash("sha256").update(raw).digest("hex");
|
|
302
343
|
var redactConfig = (value) => {
|
|
@@ -503,62 +544,9 @@ var GatewayControllerImpl = class {
|
|
|
503
544
|
};
|
|
504
545
|
}
|
|
505
546
|
async updateRun(params) {
|
|
506
|
-
const
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
const pkgRoot = resolve2(cliDir, "..", "..");
|
|
510
|
-
const repoRoot = existsSync2(join2(pkgRoot, ".git")) ? pkgRoot : resolve2(pkgRoot, "..", "..");
|
|
511
|
-
const steps = [];
|
|
512
|
-
const runStep = (cmd, args, cwd) => {
|
|
513
|
-
const result = spawnSync(cmd, args, {
|
|
514
|
-
cwd,
|
|
515
|
-
encoding: "utf-8",
|
|
516
|
-
timeout: timeoutMs,
|
|
517
|
-
stdio: "pipe"
|
|
518
|
-
});
|
|
519
|
-
const step = {
|
|
520
|
-
cmd,
|
|
521
|
-
args,
|
|
522
|
-
cwd,
|
|
523
|
-
code: result.status,
|
|
524
|
-
stdout: (result.stdout ?? "").toString().slice(0, 4e3),
|
|
525
|
-
stderr: (result.stderr ?? "").toString().slice(0, 4e3)
|
|
526
|
-
};
|
|
527
|
-
steps.push(step);
|
|
528
|
-
return { ok: result.status === 0, code: result.status };
|
|
529
|
-
};
|
|
530
|
-
const updateCommand = process.env.NEXTCLAW_UPDATE_COMMAND?.trim();
|
|
531
|
-
if (updateCommand) {
|
|
532
|
-
const ok = runStep("sh", ["-c", updateCommand], process.cwd());
|
|
533
|
-
if (!ok.ok) {
|
|
534
|
-
return { ok: false, error: "update command failed", steps };
|
|
535
|
-
}
|
|
536
|
-
} else if (existsSync2(join2(repoRoot, ".git"))) {
|
|
537
|
-
if (!which("git")) {
|
|
538
|
-
return { ok: false, error: "git not found for repo update", steps };
|
|
539
|
-
}
|
|
540
|
-
const ok = runStep("git", ["-C", repoRoot, "pull", "--rebase"], repoRoot);
|
|
541
|
-
if (!ok.ok) {
|
|
542
|
-
return { ok: false, error: "git pull failed", steps };
|
|
543
|
-
}
|
|
544
|
-
if (existsSync2(join2(repoRoot, "pnpm-lock.yaml")) && which("pnpm")) {
|
|
545
|
-
const installOk = runStep("pnpm", ["install"], repoRoot);
|
|
546
|
-
if (!installOk.ok) {
|
|
547
|
-
return { ok: false, error: "pnpm install failed", steps };
|
|
548
|
-
}
|
|
549
|
-
} else if (existsSync2(join2(repoRoot, "package.json")) && which("npm")) {
|
|
550
|
-
const installOk = runStep("npm", ["install"], repoRoot);
|
|
551
|
-
if (!installOk.ok) {
|
|
552
|
-
return { ok: false, error: "npm install failed", steps };
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
} else if (which("npm")) {
|
|
556
|
-
const ok = runStep("npm", ["i", "-g", "nextclaw"], process.cwd());
|
|
557
|
-
if (!ok.ok) {
|
|
558
|
-
return { ok: false, error: "npm install -g nextclaw failed", steps };
|
|
559
|
-
}
|
|
560
|
-
} else {
|
|
561
|
-
return { ok: false, error: "no update strategy available", steps };
|
|
547
|
+
const result = runSelfUpdate({ timeoutMs: params.timeoutMs });
|
|
548
|
+
if (!result.ok) {
|
|
549
|
+
return { ok: false, error: result.error ?? "update failed", steps: result.steps };
|
|
562
550
|
}
|
|
563
551
|
const delayMs = params.restartDelayMs ?? 0;
|
|
564
552
|
scheduleRestart(delayMs, "update.run");
|
|
@@ -566,7 +554,8 @@ var GatewayControllerImpl = class {
|
|
|
566
554
|
ok: true,
|
|
567
555
|
note: params.note ?? null,
|
|
568
556
|
restart: { scheduled: true, delayMs },
|
|
569
|
-
|
|
557
|
+
strategy: result.strategy,
|
|
558
|
+
steps: result.steps
|
|
570
559
|
};
|
|
571
560
|
}
|
|
572
561
|
};
|
|
@@ -574,7 +563,7 @@ var GatewayControllerImpl = class {
|
|
|
574
563
|
// src/cli/skills/clawhub.ts
|
|
575
564
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
576
565
|
import { existsSync as existsSync3 } from "fs";
|
|
577
|
-
import { isAbsolute, join as
|
|
566
|
+
import { isAbsolute, join as join2, resolve as resolve3 } from "path";
|
|
578
567
|
async function installClawHubSkill(options) {
|
|
579
568
|
const slug = options.slug.trim();
|
|
580
569
|
if (!slug) {
|
|
@@ -586,7 +575,7 @@ async function installClawHubSkill(options) {
|
|
|
586
575
|
}
|
|
587
576
|
const dirName = options.dir?.trim() || "skills";
|
|
588
577
|
const destinationDir = isAbsolute(dirName) ? resolve3(dirName, slug) : resolve3(workdir, dirName, slug);
|
|
589
|
-
const skillFile =
|
|
578
|
+
const skillFile = join2(destinationDir, "SKILL.md");
|
|
590
579
|
if (!options.force && existsSync3(destinationDir)) {
|
|
591
580
|
if (existsSync3(skillFile)) {
|
|
592
581
|
return {
|
|
@@ -776,7 +765,7 @@ var CliRuntime = class {
|
|
|
776
765
|
}
|
|
777
766
|
const config = loadConfig();
|
|
778
767
|
const workspaceSetting = config.agents.defaults.workspace;
|
|
779
|
-
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ?
|
|
768
|
+
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join3(getDataDir2(), DEFAULT_WORKSPACE_DIR) : expandHome(workspaceSetting);
|
|
780
769
|
const workspaceExisted = existsSync4(workspacePath);
|
|
781
770
|
mkdirSync2(workspacePath, { recursive: true });
|
|
782
771
|
const templateResult = this.createWorkspaceTemplates(workspacePath, { force });
|
|
@@ -941,7 +930,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
941
930
|
}
|
|
942
931
|
console.log(`${this.logo} Interactive mode (type exit or Ctrl+C to quit)
|
|
943
932
|
`);
|
|
944
|
-
const historyFile =
|
|
933
|
+
const historyFile = join3(getDataDir2(), "history", "cli_history");
|
|
945
934
|
const historyDir = resolve4(historyFile, "..");
|
|
946
935
|
mkdirSync2(historyDir, { recursive: true });
|
|
947
936
|
const history = existsSync4(historyFile) ? readFileSync3(historyFile, "utf-8").split("\n").filter(Boolean) : [];
|
|
@@ -970,6 +959,41 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
970
959
|
printAgentResponse(response);
|
|
971
960
|
}
|
|
972
961
|
}
|
|
962
|
+
async update(opts) {
|
|
963
|
+
let timeoutMs;
|
|
964
|
+
if (opts.timeout !== void 0) {
|
|
965
|
+
const parsed = Number(opts.timeout);
|
|
966
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
967
|
+
console.error("Invalid --timeout value. Provide milliseconds (e.g. 1200000).");
|
|
968
|
+
process.exit(1);
|
|
969
|
+
}
|
|
970
|
+
timeoutMs = parsed;
|
|
971
|
+
}
|
|
972
|
+
const result = runSelfUpdate({ timeoutMs, cwd: process.cwd() });
|
|
973
|
+
const printSteps = () => {
|
|
974
|
+
for (const step of result.steps) {
|
|
975
|
+
console.log(`- ${step.cmd} ${step.args.join(" ")} (code ${step.code ?? "?"})`);
|
|
976
|
+
if (step.stderr) {
|
|
977
|
+
console.log(` stderr: ${step.stderr}`);
|
|
978
|
+
}
|
|
979
|
+
if (step.stdout) {
|
|
980
|
+
console.log(` stdout: ${step.stdout}`);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
if (!result.ok) {
|
|
985
|
+
console.error(`Update failed: ${result.error ?? "unknown error"}`);
|
|
986
|
+
if (result.steps.length > 0) {
|
|
987
|
+
printSteps();
|
|
988
|
+
}
|
|
989
|
+
process.exit(1);
|
|
990
|
+
}
|
|
991
|
+
console.log(`\u2713 Update complete (${result.strategy})`);
|
|
992
|
+
const state = readServiceState();
|
|
993
|
+
if (state && isProcessRunning(state.pid)) {
|
|
994
|
+
console.log(`Tip: restart ${APP_NAME} to apply the update.`);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
973
997
|
async skillsInstall(options) {
|
|
974
998
|
const workdir = options.workdir ? expandHome(options.workdir) : getWorkspacePath();
|
|
975
999
|
const result = await installClawHubSkill({
|
|
@@ -1012,7 +1036,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1012
1036
|
}
|
|
1013
1037
|
}
|
|
1014
1038
|
cronList(opts) {
|
|
1015
|
-
const storePath =
|
|
1039
|
+
const storePath = join3(getDataDir2(), "cron", "jobs.json");
|
|
1016
1040
|
const service = new CronService(storePath);
|
|
1017
1041
|
const jobs = service.listJobs(Boolean(opts.all));
|
|
1018
1042
|
if (!jobs.length) {
|
|
@@ -1032,7 +1056,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1032
1056
|
}
|
|
1033
1057
|
}
|
|
1034
1058
|
cronAdd(opts) {
|
|
1035
|
-
const storePath =
|
|
1059
|
+
const storePath = join3(getDataDir2(), "cron", "jobs.json");
|
|
1036
1060
|
const service = new CronService(storePath);
|
|
1037
1061
|
let schedule = null;
|
|
1038
1062
|
if (opts.every) {
|
|
@@ -1057,7 +1081,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1057
1081
|
console.log(`\u2713 Added job '${job.name}' (${job.id})`);
|
|
1058
1082
|
}
|
|
1059
1083
|
cronRemove(jobId) {
|
|
1060
|
-
const storePath =
|
|
1084
|
+
const storePath = join3(getDataDir2(), "cron", "jobs.json");
|
|
1061
1085
|
const service = new CronService(storePath);
|
|
1062
1086
|
if (service.removeJob(jobId)) {
|
|
1063
1087
|
console.log(`\u2713 Removed job ${jobId}`);
|
|
@@ -1066,7 +1090,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1066
1090
|
}
|
|
1067
1091
|
}
|
|
1068
1092
|
cronEnable(jobId, opts) {
|
|
1069
|
-
const storePath =
|
|
1093
|
+
const storePath = join3(getDataDir2(), "cron", "jobs.json");
|
|
1070
1094
|
const service = new CronService(storePath);
|
|
1071
1095
|
const job = service.enableJob(jobId, !opts.disable);
|
|
1072
1096
|
if (job) {
|
|
@@ -1076,7 +1100,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1076
1100
|
}
|
|
1077
1101
|
}
|
|
1078
1102
|
async cronRun(jobId, opts) {
|
|
1079
|
-
const storePath =
|
|
1103
|
+
const storePath = join3(getDataDir2(), "cron", "jobs.json");
|
|
1080
1104
|
const service = new CronService(storePath);
|
|
1081
1105
|
const ok = await service.runJob(jobId, Boolean(opts.force));
|
|
1082
1106
|
console.log(ok ? "\u2713 Job executed" : `Failed to run job ${jobId}`);
|
|
@@ -1108,7 +1132,7 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1108
1132
|
const provider = options.allowMissingProvider === true ? this.makeProvider(config, { allowMissing: true }) : this.makeProvider(config);
|
|
1109
1133
|
const providerManager = provider ? new ProviderManager(provider) : null;
|
|
1110
1134
|
const sessionManager = new SessionManager(getWorkspacePath(config.agents.defaults.workspace));
|
|
1111
|
-
const cronStorePath =
|
|
1135
|
+
const cronStorePath = join3(getDataDir2(), "cron", "jobs.json");
|
|
1112
1136
|
const cron2 = new CronService(cronStorePath);
|
|
1113
1137
|
const uiConfig = resolveUiConfig(config, options.uiOverrides);
|
|
1114
1138
|
const uiStaticDir = options.uiStaticDir === void 0 ? resolveUiStaticDir() : options.uiStaticDir;
|
|
@@ -1382,11 +1406,11 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1382
1406
|
{ source: "memory/MEMORY.md", target: "memory/MEMORY.md" }
|
|
1383
1407
|
];
|
|
1384
1408
|
for (const entry of templateFiles) {
|
|
1385
|
-
const filePath =
|
|
1409
|
+
const filePath = join3(workspace, entry.target);
|
|
1386
1410
|
if (!force && existsSync4(filePath)) {
|
|
1387
1411
|
continue;
|
|
1388
1412
|
}
|
|
1389
|
-
const templatePath =
|
|
1413
|
+
const templatePath = join3(templateDir, entry.source);
|
|
1390
1414
|
if (!existsSync4(templatePath)) {
|
|
1391
1415
|
console.warn(`Warning: Template file missing: ${templatePath}`);
|
|
1392
1416
|
continue;
|
|
@@ -1397,15 +1421,15 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1397
1421
|
writeFileSync2(filePath, content);
|
|
1398
1422
|
created.push(entry.target);
|
|
1399
1423
|
}
|
|
1400
|
-
const memoryDir =
|
|
1424
|
+
const memoryDir = join3(workspace, "memory");
|
|
1401
1425
|
if (!existsSync4(memoryDir)) {
|
|
1402
1426
|
mkdirSync2(memoryDir, { recursive: true });
|
|
1403
|
-
created.push(
|
|
1427
|
+
created.push(join3("memory", ""));
|
|
1404
1428
|
}
|
|
1405
|
-
const skillsDir =
|
|
1429
|
+
const skillsDir = join3(workspace, "skills");
|
|
1406
1430
|
if (!existsSync4(skillsDir)) {
|
|
1407
1431
|
mkdirSync2(skillsDir, { recursive: true });
|
|
1408
|
-
created.push(
|
|
1432
|
+
created.push(join3("skills", ""));
|
|
1409
1433
|
}
|
|
1410
1434
|
const seeded = this.seedBuiltinSkills(skillsDir, { force });
|
|
1411
1435
|
if (seeded > 0) {
|
|
@@ -1428,11 +1452,11 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1428
1452
|
if (!entry.isDirectory()) {
|
|
1429
1453
|
continue;
|
|
1430
1454
|
}
|
|
1431
|
-
const src =
|
|
1432
|
-
if (!existsSync4(
|
|
1455
|
+
const src = join3(sourceDir, entry.name);
|
|
1456
|
+
if (!existsSync4(join3(src, "SKILL.md"))) {
|
|
1433
1457
|
continue;
|
|
1434
1458
|
}
|
|
1435
|
-
const dest =
|
|
1459
|
+
const dest = join3(targetDir, entry.name);
|
|
1436
1460
|
if (!force && existsSync4(dest)) {
|
|
1437
1461
|
continue;
|
|
1438
1462
|
}
|
|
@@ -1446,11 +1470,11 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1446
1470
|
const require2 = createRequire(import.meta.url);
|
|
1447
1471
|
const entry = require2.resolve("nextclaw-core");
|
|
1448
1472
|
const pkgRoot = resolve4(dirname(entry), "..");
|
|
1449
|
-
const distSkills =
|
|
1473
|
+
const distSkills = join3(pkgRoot, "dist", "skills");
|
|
1450
1474
|
if (existsSync4(distSkills)) {
|
|
1451
1475
|
return distSkills;
|
|
1452
1476
|
}
|
|
1453
|
-
const srcSkills =
|
|
1477
|
+
const srcSkills = join3(pkgRoot, "src", "agent", "skills");
|
|
1454
1478
|
if (existsSync4(srcSkills)) {
|
|
1455
1479
|
return srcSkills;
|
|
1456
1480
|
}
|
|
@@ -1464,9 +1488,9 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1464
1488
|
if (override) {
|
|
1465
1489
|
return override;
|
|
1466
1490
|
}
|
|
1467
|
-
const cliDir = resolve4(
|
|
1491
|
+
const cliDir = resolve4(fileURLToPath2(new URL(".", import.meta.url)));
|
|
1468
1492
|
const pkgRoot = resolve4(cliDir, "..", "..");
|
|
1469
|
-
const candidates = [
|
|
1493
|
+
const candidates = [join3(pkgRoot, "templates")];
|
|
1470
1494
|
for (const candidate of candidates) {
|
|
1471
1495
|
if (existsSync4(candidate)) {
|
|
1472
1496
|
return candidate;
|
|
@@ -1475,22 +1499,22 @@ ${this.logo} ${APP_NAME} is ready! (${source})`);
|
|
|
1475
1499
|
return null;
|
|
1476
1500
|
}
|
|
1477
1501
|
getBridgeDir() {
|
|
1478
|
-
const userBridge =
|
|
1479
|
-
if (existsSync4(
|
|
1502
|
+
const userBridge = join3(getDataDir2(), "bridge");
|
|
1503
|
+
if (existsSync4(join3(userBridge, "dist", "index.js"))) {
|
|
1480
1504
|
return userBridge;
|
|
1481
1505
|
}
|
|
1482
1506
|
if (!which("npm")) {
|
|
1483
1507
|
console.error("npm not found. Please install Node.js >= 18.");
|
|
1484
1508
|
process.exit(1);
|
|
1485
1509
|
}
|
|
1486
|
-
const cliDir = resolve4(
|
|
1510
|
+
const cliDir = resolve4(fileURLToPath2(new URL(".", import.meta.url)));
|
|
1487
1511
|
const pkgRoot = resolve4(cliDir, "..", "..");
|
|
1488
|
-
const pkgBridge =
|
|
1489
|
-
const srcBridge =
|
|
1512
|
+
const pkgBridge = join3(pkgRoot, "bridge");
|
|
1513
|
+
const srcBridge = join3(pkgRoot, "..", "..", "bridge");
|
|
1490
1514
|
let source = null;
|
|
1491
|
-
if (existsSync4(
|
|
1515
|
+
if (existsSync4(join3(pkgBridge, "package.json"))) {
|
|
1492
1516
|
source = pkgBridge;
|
|
1493
|
-
} else if (existsSync4(
|
|
1517
|
+
} else if (existsSync4(join3(srcBridge, "package.json"))) {
|
|
1494
1518
|
source = srcBridge;
|
|
1495
1519
|
}
|
|
1496
1520
|
if (!source) {
|
|
@@ -1539,6 +1563,7 @@ program.command("start").description(`Start the ${APP_NAME2} gateway + UI in the
|
|
|
1539
1563
|
program.command("serve").description(`Run the ${APP_NAME2} gateway + UI in the foreground`).option("--ui-host <host>", "UI host").option("--ui-port <port>", "UI port").option("--frontend", "Start UI frontend dev server").option("--frontend-port <port>", "UI frontend dev server port").option("--open", "Open browser after start", false).action(async (opts) => runtime.serve(opts));
|
|
1540
1564
|
program.command("stop").description(`Stop the ${APP_NAME2} background service`).action(async () => runtime.stop());
|
|
1541
1565
|
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));
|
|
1566
|
+
program.command("update").description(`Update ${APP_NAME2}`).option("--timeout <ms>", "Update command timeout in milliseconds").action(async (opts) => runtime.update(opts));
|
|
1542
1567
|
var registerClawHubInstall = (cmd) => {
|
|
1543
1568
|
cmd.command("install <slug>").description("Install a skill from ClawHub").option("--version <version>", "Skill version (default: latest)").option("--registry <url>", "ClawHub registry base URL").option("--workdir <dir>", "Workspace directory to install into").option("--dir <dir>", "Skills directory name (default: skills)").option("-f, --force", "Overwrite existing skill files", false).action(async (slug, opts) => runtime.skillsInstall({ slug, ...opts }));
|
|
1544
1569
|
};
|