fastclaw-cli 0.2.2 → 0.3.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/index.js +353 -76
- package/dist/sdk.d.ts +40 -1
- package/dist/sdk.js +59 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -156,7 +156,8 @@ function resolveConfig(opts) {
|
|
|
156
156
|
appToken: opts.appToken || process.env.FASTCLAW_APP_TOKEN || file.app_token,
|
|
157
157
|
userId: opts.userId || process.env.FASTCLAW_USER_ID || file.default_user_id || "default",
|
|
158
158
|
botId: opts.botId || process.env.FASTCLAW_BOT_ID || file.default_bot_id,
|
|
159
|
-
json: opts.json ?? false
|
|
159
|
+
json: opts.json ?? false,
|
|
160
|
+
yes: opts.yes ?? false
|
|
160
161
|
};
|
|
161
162
|
}
|
|
162
163
|
function getConfigPath() {
|
|
@@ -165,6 +166,31 @@ function getConfigPath() {
|
|
|
165
166
|
|
|
166
167
|
// src/utils/error.ts
|
|
167
168
|
import chalk from "chalk";
|
|
169
|
+
|
|
170
|
+
// src/utils/prompt.ts
|
|
171
|
+
import { input, select, password, confirm } from "@inquirer/prompts";
|
|
172
|
+
async function promptText(message, defaultValue) {
|
|
173
|
+
return input({ message, default: defaultValue });
|
|
174
|
+
}
|
|
175
|
+
async function promptPassword(message) {
|
|
176
|
+
return password({ message, mask: "\u2022" });
|
|
177
|
+
}
|
|
178
|
+
async function promptSelect(message, choices) {
|
|
179
|
+
return select({ message, choices });
|
|
180
|
+
}
|
|
181
|
+
async function promptConfirm(message, defaultValue = true) {
|
|
182
|
+
return confirm({ message, default: defaultValue });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/utils/error.ts
|
|
186
|
+
async function confirmAction(cfg, message) {
|
|
187
|
+
if (cfg.yes) return;
|
|
188
|
+
const ok = await promptConfirm(message, false);
|
|
189
|
+
if (!ok) {
|
|
190
|
+
console.log(chalk.dim("Cancelled."));
|
|
191
|
+
process.exit(0);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
168
194
|
var ApiError = class extends Error {
|
|
169
195
|
constructor(statusCode, apiCode, message) {
|
|
170
196
|
super(message);
|
|
@@ -293,7 +319,7 @@ function maskToken(token) {
|
|
|
293
319
|
return token.slice(0, 4) + "\u2022\u2022\u2022\u2022" + token.slice(-4);
|
|
294
320
|
}
|
|
295
321
|
|
|
296
|
-
// src/commands/
|
|
322
|
+
// src/commands/app/index.ts
|
|
297
323
|
import chalk4 from "chalk";
|
|
298
324
|
|
|
299
325
|
// src/client.ts
|
|
@@ -484,6 +510,58 @@ var FastClawClient = class {
|
|
|
484
510
|
async deleteSkill(botId, name) {
|
|
485
511
|
return this.request("DELETE", `/bots/${botId}/skills/${name}`);
|
|
486
512
|
}
|
|
513
|
+
// ── Bot Logs ──
|
|
514
|
+
async getBotLogs(botId, opts) {
|
|
515
|
+
const query = {};
|
|
516
|
+
if (opts?.tail !== void 0) query.tail = String(opts.tail);
|
|
517
|
+
if (opts?.sinceSeconds !== void 0) query.sinceSeconds = String(opts.sinceSeconds);
|
|
518
|
+
if (opts?.sinceTime) query.sinceTime = opts.sinceTime;
|
|
519
|
+
if (opts?.timestamps) query.timestamps = "true";
|
|
520
|
+
return this.request("GET", `/bots/${botId}/logs`, { query });
|
|
521
|
+
}
|
|
522
|
+
// ── Bot Runtime (OpenClaw CLI exec) ──
|
|
523
|
+
async getRuntimeStatus(botId, opts) {
|
|
524
|
+
const query = {};
|
|
525
|
+
if (opts?.all) query.all = "true";
|
|
526
|
+
if (opts?.usage) query.usage = "true";
|
|
527
|
+
if (opts?.deep) query.deep = "true";
|
|
528
|
+
if (opts?.timeout) query.timeout = opts.timeout;
|
|
529
|
+
return this.request("GET", `/bots/${botId}/runtime/status`, { query });
|
|
530
|
+
}
|
|
531
|
+
async getRuntimeSessions(botId, opts) {
|
|
532
|
+
const query = {};
|
|
533
|
+
if (opts?.agent) query.agent = opts.agent;
|
|
534
|
+
if (opts?.allAgents) query["all-agents"] = "true";
|
|
535
|
+
if (opts?.active) query.active = "true";
|
|
536
|
+
return this.request("GET", `/bots/${botId}/runtime/sessions`, { query });
|
|
537
|
+
}
|
|
538
|
+
async getRuntimeConfig(botId, path) {
|
|
539
|
+
const query = {};
|
|
540
|
+
if (path) query.path = path;
|
|
541
|
+
return this.request("GET", `/bots/${botId}/runtime/config`, { query });
|
|
542
|
+
}
|
|
543
|
+
async getRuntimeConfigValidate(botId) {
|
|
544
|
+
return this.request("GET", `/bots/${botId}/runtime/config/validate`);
|
|
545
|
+
}
|
|
546
|
+
async getRuntimeModels(botId, opts) {
|
|
547
|
+
const query = {};
|
|
548
|
+
if (opts?.all) query.all = "true";
|
|
549
|
+
if (opts?.agent) query.agent = opts.agent;
|
|
550
|
+
if (opts?.provider) query.provider = opts.provider;
|
|
551
|
+
return this.request("GET", `/bots/${botId}/runtime/models`, { query });
|
|
552
|
+
}
|
|
553
|
+
async getRuntimeSkills(botId, opts) {
|
|
554
|
+
const query = {};
|
|
555
|
+
if (opts?.eligible) query.eligible = "true";
|
|
556
|
+
if (opts?.verbose) query.verbose = "true";
|
|
557
|
+
return this.request("GET", `/bots/${botId}/runtime/skills`, { query });
|
|
558
|
+
}
|
|
559
|
+
async getRuntimeSkillsCheck(botId) {
|
|
560
|
+
return this.request("GET", `/bots/${botId}/runtime/skills/check`);
|
|
561
|
+
}
|
|
562
|
+
async runtimeExec(botId, req) {
|
|
563
|
+
return this.request("POST", `/bots/${botId}/runtime/exec`, { body: req });
|
|
564
|
+
}
|
|
487
565
|
// ── Utility: wait for bot ready ──
|
|
488
566
|
async waitForReady(botId, timeoutMs = 12e4, intervalMs = 3e3) {
|
|
489
567
|
const start = Date.now();
|
|
@@ -507,19 +585,20 @@ var FastClawClient = class {
|
|
|
507
585
|
}
|
|
508
586
|
};
|
|
509
587
|
|
|
510
|
-
// src/commands/
|
|
511
|
-
function getClient(
|
|
512
|
-
const opts =
|
|
588
|
+
// src/commands/app/index.ts
|
|
589
|
+
function getClient(app) {
|
|
590
|
+
const opts = app.parent.opts();
|
|
513
591
|
const cfg = resolveConfig(opts);
|
|
514
592
|
requireOption(cfg.adminToken, "admin-token");
|
|
515
593
|
return { client: new FastClawClient({ url: cfg.url, adminToken: cfg.adminToken }), cfg };
|
|
516
594
|
}
|
|
517
|
-
function
|
|
518
|
-
const
|
|
519
|
-
|
|
595
|
+
function registerAppCommand(program2) {
|
|
596
|
+
const app = program2.command("app").description("Manage apps (requires admin token)");
|
|
597
|
+
app.command("create").description("Create a new app").requiredOption("-n, --name <name>", "App name").option("--url <url>", "App website URL").option("--description <desc>", "App description").option("--owner-email <email>", "Owner email").option("--bot-domain-template <tpl>", "Bot domain template").action(
|
|
520
598
|
withErrorHandler(async (cmdOpts) => {
|
|
521
|
-
const { client, cfg } = getClient(
|
|
522
|
-
|
|
599
|
+
const { client, cfg } = getClient(app);
|
|
600
|
+
await confirmAction(cfg, `Create app '${cmdOpts.name}'?`);
|
|
601
|
+
const result = await client.createApp({
|
|
523
602
|
name: cmdOpts.name,
|
|
524
603
|
url: cmdOpts.url,
|
|
525
604
|
description: cmdOpts.description,
|
|
@@ -527,21 +606,21 @@ function registerAppsCommand(admin) {
|
|
|
527
606
|
bot_domain_template: cmdOpts.botDomainTemplate
|
|
528
607
|
});
|
|
529
608
|
if (cfg.json) {
|
|
530
|
-
printJson(
|
|
609
|
+
printJson(result);
|
|
531
610
|
} else {
|
|
532
|
-
printSuccess(`App created: ${
|
|
611
|
+
printSuccess(`App created: ${result.id}`);
|
|
533
612
|
printKeyValue({
|
|
534
|
-
ID:
|
|
535
|
-
Name:
|
|
536
|
-
Token:
|
|
537
|
-
Status:
|
|
613
|
+
ID: result.id,
|
|
614
|
+
Name: result.name,
|
|
615
|
+
Token: result.api_token,
|
|
616
|
+
Status: result.status
|
|
538
617
|
});
|
|
539
618
|
}
|
|
540
619
|
})
|
|
541
620
|
);
|
|
542
|
-
|
|
621
|
+
app.command("list").description("List all apps").option("-t, --show-token", "Show full API token (masked by default)").action(
|
|
543
622
|
withErrorHandler(async (cmdOpts) => {
|
|
544
|
-
const { client, cfg } = getClient(
|
|
623
|
+
const { client, cfg } = getClient(app);
|
|
545
624
|
const list = await client.listApps();
|
|
546
625
|
if (cfg.json) {
|
|
547
626
|
printJson(list);
|
|
@@ -562,9 +641,46 @@ function registerAppsCommand(admin) {
|
|
|
562
641
|
}
|
|
563
642
|
})
|
|
564
643
|
);
|
|
565
|
-
|
|
644
|
+
app.command("get <id>").description("Get app details").action(
|
|
566
645
|
withErrorHandler(async (id) => {
|
|
567
|
-
const { client, cfg } = getClient(
|
|
646
|
+
const { client, cfg } = getClient(app);
|
|
647
|
+
const result = await client.getApp(id);
|
|
648
|
+
if (cfg.json) {
|
|
649
|
+
printJson(result);
|
|
650
|
+
} else {
|
|
651
|
+
printKeyValue({
|
|
652
|
+
ID: result.id,
|
|
653
|
+
Name: result.name,
|
|
654
|
+
URL: result.url || "(none)",
|
|
655
|
+
Description: result.description || "(none)",
|
|
656
|
+
Status: result.status,
|
|
657
|
+
Created: result.created_at
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
})
|
|
661
|
+
);
|
|
662
|
+
app.command("update <id>").description("Update an app").option("-n, --name <name>", "App name").option("--url <url>", "App website URL").option("--description <desc>", "App description").option("--owner-email <email>", "Owner email").option("--status <status>", "App status (active/disabled)").action(
|
|
663
|
+
withErrorHandler(async (id, cmdOpts) => {
|
|
664
|
+
const { client, cfg } = getClient(app);
|
|
665
|
+
await confirmAction(cfg, `Update app ${id}?`);
|
|
666
|
+
const result = await client.updateApp(id, {
|
|
667
|
+
name: cmdOpts.name,
|
|
668
|
+
url: cmdOpts.url,
|
|
669
|
+
description: cmdOpts.description,
|
|
670
|
+
owner_email: cmdOpts.ownerEmail,
|
|
671
|
+
status: cmdOpts.status
|
|
672
|
+
});
|
|
673
|
+
if (cfg.json) {
|
|
674
|
+
printJson(result);
|
|
675
|
+
} else {
|
|
676
|
+
printSuccess(`App ${id} updated`);
|
|
677
|
+
}
|
|
678
|
+
})
|
|
679
|
+
);
|
|
680
|
+
app.command("delete <id>").description("Delete an app").action(
|
|
681
|
+
withErrorHandler(async (id) => {
|
|
682
|
+
const { client, cfg } = getClient(app);
|
|
683
|
+
await confirmAction(cfg, `Delete app ${id}? This cannot be undone.`);
|
|
568
684
|
const res = await client.deleteApp(id);
|
|
569
685
|
if (cfg.json) {
|
|
570
686
|
printJson(res);
|
|
@@ -573,9 +689,10 @@ function registerAppsCommand(admin) {
|
|
|
573
689
|
}
|
|
574
690
|
})
|
|
575
691
|
);
|
|
576
|
-
|
|
692
|
+
app.command("rotate-token <id>").description("Reset an app's API token").action(
|
|
577
693
|
withErrorHandler(async (id) => {
|
|
578
|
-
const { client, cfg } = getClient(
|
|
694
|
+
const { client, cfg } = getClient(app);
|
|
695
|
+
await confirmAction(cfg, `Rotate API token for app ${id}?`);
|
|
579
696
|
const res = await client.rotateAppToken(id);
|
|
580
697
|
if (cfg.json) {
|
|
581
698
|
printJson(res);
|
|
@@ -587,31 +704,27 @@ function registerAppsCommand(admin) {
|
|
|
587
704
|
);
|
|
588
705
|
}
|
|
589
706
|
|
|
590
|
-
// src/commands/admin/index.ts
|
|
591
|
-
function registerAdminCommand(program2) {
|
|
592
|
-
const admin = program2.command("admin").description("Admin operations");
|
|
593
|
-
registerAppsCommand(admin);
|
|
594
|
-
}
|
|
595
|
-
|
|
596
707
|
// src/commands/bot/crud.ts
|
|
597
708
|
import chalk5 from "chalk";
|
|
598
709
|
|
|
599
710
|
// src/commands/bot/resolve.ts
|
|
711
|
+
function getRootOpts(cmd) {
|
|
712
|
+
let root = cmd;
|
|
713
|
+
while (root.parent) root = root.parent;
|
|
714
|
+
return root.opts();
|
|
715
|
+
}
|
|
600
716
|
function getClient2(cmd) {
|
|
601
|
-
const
|
|
602
|
-
const cfg = resolveConfig(opts);
|
|
717
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
603
718
|
requireOption(cfg.appToken, "app-token");
|
|
604
719
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
605
720
|
}
|
|
606
721
|
function getAdminClient(cmd) {
|
|
607
|
-
const
|
|
608
|
-
const cfg = resolveConfig(opts);
|
|
722
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
609
723
|
requireOption(cfg.adminToken, "admin-token");
|
|
610
724
|
return { client: new FastClawClient({ url: cfg.url, adminToken: cfg.adminToken }), cfg };
|
|
611
725
|
}
|
|
612
726
|
async function resolveClientForBot(cmd, botId) {
|
|
613
|
-
const
|
|
614
|
-
const cfg = resolveConfig(opts);
|
|
727
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
615
728
|
if (cfg.appToken) {
|
|
616
729
|
try {
|
|
617
730
|
const client = new FastClawClient({ url: cfg.url, appToken: cfg.appToken });
|
|
@@ -643,6 +756,7 @@ function registerBotCrudCommands(bot) {
|
|
|
643
756
|
bot.command("create").description("Create a new bot").requiredOption("-n, --name <name>", "Bot name").option("--slug <slug>", "URL slug").option("--user-id <userId>", "User ID").option("--expires-at <date>", "Expiration date (ISO-8601)").action(
|
|
644
757
|
withErrorHandler(async (cmdOpts) => {
|
|
645
758
|
const { client, cfg } = getClient2(bot);
|
|
759
|
+
await confirmAction(cfg, `Create bot '${cmdOpts.name}'?`);
|
|
646
760
|
const userId = cmdOpts.userId || cfg.userId;
|
|
647
761
|
const result = await client.createBot({
|
|
648
762
|
user_id: userId,
|
|
@@ -753,6 +867,7 @@ function registerBotCrudCommands(bot) {
|
|
|
753
867
|
bot.command("update <id>").description("Update a bot").option("-n, --name <name>", "New name").option("--slug <slug>", "New slug").option("--expires-at <date>", "New expiration date").action(
|
|
754
868
|
withErrorHandler(async (id, cmdOpts) => {
|
|
755
869
|
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
870
|
+
await confirmAction(cfg, `Update bot ${id}?`);
|
|
756
871
|
const result = await client.updateBot(id, {
|
|
757
872
|
name: cmdOpts.name,
|
|
758
873
|
slug: cmdOpts.slug,
|
|
@@ -768,6 +883,7 @@ function registerBotCrudCommands(bot) {
|
|
|
768
883
|
bot.command("delete <id>").description("Delete a bot").action(
|
|
769
884
|
withErrorHandler(async (id) => {
|
|
770
885
|
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
886
|
+
await confirmAction(cfg, `Delete bot ${id}? This cannot be undone.`);
|
|
771
887
|
const res = await client.deleteBot(id);
|
|
772
888
|
if (cfg.json) {
|
|
773
889
|
printJson(res);
|
|
@@ -811,6 +927,7 @@ function registerBotLifecycleCommands(bot) {
|
|
|
811
927
|
bot.command("stop <id>").description("Stop a bot").action(
|
|
812
928
|
withErrorHandler(async (id) => {
|
|
813
929
|
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
930
|
+
await confirmAction(cfg, `Stop bot ${id}?`);
|
|
814
931
|
const res = await client.stopBot(id);
|
|
815
932
|
if (cfg.json) {
|
|
816
933
|
printJson(res);
|
|
@@ -822,6 +939,7 @@ function registerBotLifecycleCommands(bot) {
|
|
|
822
939
|
bot.command("restart <id>").description("Restart a bot").action(
|
|
823
940
|
withErrorHandler(async (id) => {
|
|
824
941
|
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
942
|
+
await confirmAction(cfg, `Restart bot ${id}?`);
|
|
825
943
|
const res = await client.restartBot(id);
|
|
826
944
|
if (cfg.json) {
|
|
827
945
|
printJson(res);
|
|
@@ -882,6 +1000,7 @@ function registerBotLifecycleCommands(bot) {
|
|
|
882
1000
|
bot.command("reset-token <id>").description("Reset bot access token").action(
|
|
883
1001
|
withErrorHandler(async (id) => {
|
|
884
1002
|
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
1003
|
+
await confirmAction(cfg, `Reset access token for bot ${id}?`);
|
|
885
1004
|
const res = await client.resetBotToken(id);
|
|
886
1005
|
if (cfg.json) {
|
|
887
1006
|
printJson(res);
|
|
@@ -896,32 +1015,175 @@ function registerBotLifecycleCommands(bot) {
|
|
|
896
1015
|
);
|
|
897
1016
|
}
|
|
898
1017
|
|
|
899
|
-
// src/commands/bot/
|
|
900
|
-
function
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1018
|
+
// src/commands/bot/logs.ts
|
|
1019
|
+
function registerBotLogsCommands(bot) {
|
|
1020
|
+
bot.command("logs <id>").description("Get pod logs for a running bot").option("--tail <lines>", "Number of lines from the end (default: 100)").option("--since <seconds>", "Logs newer than N seconds").option("--since-time <time>", "Logs newer than RFC3339 timestamp").option("--timestamps", "Show timestamps on each line").action(
|
|
1021
|
+
withErrorHandler(async (id, cmdOpts) => {
|
|
1022
|
+
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
1023
|
+
const res = await client.getBotLogs(id, {
|
|
1024
|
+
tail: cmdOpts.tail ? parseInt(cmdOpts.tail, 10) : void 0,
|
|
1025
|
+
sinceSeconds: cmdOpts.since ? parseInt(cmdOpts.since, 10) : void 0,
|
|
1026
|
+
sinceTime: cmdOpts.sinceTime,
|
|
1027
|
+
timestamps: cmdOpts.timestamps
|
|
1028
|
+
});
|
|
1029
|
+
if (cfg.json) {
|
|
1030
|
+
printJson(res);
|
|
1031
|
+
} else {
|
|
1032
|
+
process.stdout.write(res.logs);
|
|
1033
|
+
}
|
|
1034
|
+
})
|
|
1035
|
+
);
|
|
904
1036
|
}
|
|
905
1037
|
|
|
906
|
-
// src/commands/
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1038
|
+
// src/commands/bot/runtime.ts
|
|
1039
|
+
function registerBotRuntimeCommands(bot) {
|
|
1040
|
+
const runtime = bot.command("runtime").description("OpenClaw runtime introspection (requires running bot)");
|
|
1041
|
+
runtime.command("status <id>").description("Get OpenClaw runtime status").option("--all", "Include all status sections").option("--usage", "Include usage info").option("--deep", "Deep connectivity check").option("--timeout <ms>", "Timeout for deep checks").action(
|
|
1042
|
+
withErrorHandler(async (id, cmdOpts) => {
|
|
1043
|
+
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
1044
|
+
const res = await client.getRuntimeStatus(id, {
|
|
1045
|
+
all: cmdOpts.all,
|
|
1046
|
+
usage: cmdOpts.usage,
|
|
1047
|
+
deep: cmdOpts.deep,
|
|
1048
|
+
timeout: cmdOpts.timeout
|
|
1049
|
+
});
|
|
1050
|
+
if (cfg.json) {
|
|
1051
|
+
printJson(res);
|
|
1052
|
+
} else {
|
|
1053
|
+
const data = res;
|
|
1054
|
+
const gw = data.gateway;
|
|
1055
|
+
const os = data.os;
|
|
1056
|
+
const sessions = data.sessions;
|
|
1057
|
+
printKeyValue({
|
|
1058
|
+
"OS": os?.label ?? "unknown",
|
|
1059
|
+
"Gateway": gw?.reachable ? `reachable (${gw.mode})` : `${gw?.error ?? "unreachable"}`,
|
|
1060
|
+
"Sessions": String(sessions?.count ?? "?"),
|
|
1061
|
+
"Update Channel": data.updateChannel ?? "unknown"
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
})
|
|
1065
|
+
);
|
|
1066
|
+
runtime.command("sessions <id>").description("List OpenClaw sessions").option("--agent <name>", "Filter by agent").option("--all-agents", "Show sessions from all agents").option("--active", "Show only active sessions").action(
|
|
1067
|
+
withErrorHandler(async (id, cmdOpts) => {
|
|
1068
|
+
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
1069
|
+
const res = await client.getRuntimeSessions(id, {
|
|
1070
|
+
agent: cmdOpts.agent,
|
|
1071
|
+
allAgents: cmdOpts.allAgents,
|
|
1072
|
+
active: cmdOpts.active
|
|
1073
|
+
});
|
|
1074
|
+
if (cfg.json) {
|
|
1075
|
+
printJson(res);
|
|
1076
|
+
} else {
|
|
1077
|
+
const data = res;
|
|
1078
|
+
const sessions = data.sessions ?? [];
|
|
1079
|
+
if (sessions.length === 0) {
|
|
1080
|
+
console.log(" No sessions found");
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
printTable(
|
|
1084
|
+
["Session ID", "Agent", "Model", "Kind"],
|
|
1085
|
+
sessions.map((s) => [
|
|
1086
|
+
s.sessionId?.slice(0, 8) ?? "?",
|
|
1087
|
+
s.agentId ?? "?",
|
|
1088
|
+
s.model ?? "?",
|
|
1089
|
+
s.kind ?? "?"
|
|
1090
|
+
])
|
|
1091
|
+
);
|
|
1092
|
+
}
|
|
1093
|
+
})
|
|
1094
|
+
);
|
|
1095
|
+
runtime.command("config <id>").description("Get OpenClaw runtime config").option("--path <path>", "Config path (e.g. gateway, models)").action(
|
|
1096
|
+
withErrorHandler(async (id, cmdOpts) => {
|
|
1097
|
+
const { client } = await resolveClientForBot(bot, id);
|
|
1098
|
+
const res = await client.getRuntimeConfig(id, cmdOpts.path);
|
|
1099
|
+
printJson(res);
|
|
1100
|
+
})
|
|
1101
|
+
);
|
|
1102
|
+
runtime.command("config-validate <id>").description("Validate OpenClaw runtime config").action(
|
|
1103
|
+
withErrorHandler(async (id) => {
|
|
1104
|
+
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
1105
|
+
const res = await client.getRuntimeConfigValidate(id);
|
|
1106
|
+
if (cfg.json) {
|
|
1107
|
+
printJson(res);
|
|
1108
|
+
} else {
|
|
1109
|
+
const data = res;
|
|
1110
|
+
printKeyValue({
|
|
1111
|
+
"Path": data.path ?? "?",
|
|
1112
|
+
"Valid": data.valid ? "yes" : "no"
|
|
1113
|
+
});
|
|
1114
|
+
}
|
|
1115
|
+
})
|
|
1116
|
+
);
|
|
1117
|
+
runtime.command("models <id>").description("Get OpenClaw runtime model status").option("--all", "Show all model info").option("--agent <name>", "Filter by agent").option("--provider <name>", "Filter by provider").action(
|
|
1118
|
+
withErrorHandler(async (id, cmdOpts) => {
|
|
1119
|
+
const { client } = await resolveClientForBot(bot, id);
|
|
1120
|
+
const res = await client.getRuntimeModels(id, {
|
|
1121
|
+
all: cmdOpts.all,
|
|
1122
|
+
agent: cmdOpts.agent,
|
|
1123
|
+
provider: cmdOpts.provider
|
|
1124
|
+
});
|
|
1125
|
+
printJson(res);
|
|
1126
|
+
})
|
|
1127
|
+
);
|
|
1128
|
+
runtime.command("skills <id>").description("List OpenClaw runtime skills").option("--eligible", "Show only eligible skills").option("--verbose", "Show detailed skill info").action(
|
|
1129
|
+
withErrorHandler(async (id, cmdOpts) => {
|
|
1130
|
+
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
1131
|
+
const res = await client.getRuntimeSkills(id, {
|
|
1132
|
+
eligible: cmdOpts.eligible,
|
|
1133
|
+
verbose: cmdOpts.verbose
|
|
1134
|
+
});
|
|
1135
|
+
if (cfg.json) {
|
|
1136
|
+
printJson(res);
|
|
1137
|
+
} else {
|
|
1138
|
+
const data = res;
|
|
1139
|
+
const skills = data.skills ?? [];
|
|
1140
|
+
if (skills.length === 0) {
|
|
1141
|
+
console.log(" No skills found");
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
printTable(
|
|
1145
|
+
["Name", "Eligible", "Source"],
|
|
1146
|
+
skills.map((s) => [
|
|
1147
|
+
s.name ?? "?",
|
|
1148
|
+
s.eligible ? "yes" : "no",
|
|
1149
|
+
s.source ?? "?"
|
|
1150
|
+
])
|
|
1151
|
+
);
|
|
1152
|
+
}
|
|
1153
|
+
})
|
|
1154
|
+
);
|
|
1155
|
+
runtime.command("skills-check <id>").description("Check OpenClaw skill requirements").action(
|
|
1156
|
+
withErrorHandler(async (id) => {
|
|
1157
|
+
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
1158
|
+
const res = await client.getRuntimeSkillsCheck(id);
|
|
1159
|
+
if (cfg.json) {
|
|
1160
|
+
printJson(res);
|
|
1161
|
+
} else {
|
|
1162
|
+
const data = res;
|
|
1163
|
+
const eligible = data.eligible ?? [];
|
|
1164
|
+
const blocked = data.blocked ?? [];
|
|
1165
|
+
const disabled = data.disabled ?? [];
|
|
1166
|
+
printKeyValue({
|
|
1167
|
+
"Eligible": eligible.join(", ") || "(none)",
|
|
1168
|
+
"Blocked": blocked.join(", ") || "(none)",
|
|
1169
|
+
"Disabled": disabled.join(", ") || "(none)"
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
})
|
|
1173
|
+
);
|
|
1174
|
+
runtime.command("exec <id>").description("Execute arbitrary openclaw CLI command (e.g. --cmd 'status --all --json')").requiredOption("-c, --cmd <command>", "The openclaw CLI command to execute").action(
|
|
1175
|
+
withErrorHandler(async (id, cmdOpts) => {
|
|
1176
|
+
const { client } = await resolveClientForBot(bot, id);
|
|
1177
|
+
const res = await client.runtimeExec(id, { command: cmdOpts.cmd });
|
|
1178
|
+
printJson(res);
|
|
1179
|
+
})
|
|
1180
|
+
);
|
|
919
1181
|
}
|
|
920
1182
|
|
|
921
1183
|
// src/commands/model/provider.ts
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
const cfg = resolveConfig(
|
|
1184
|
+
import chalk7 from "chalk";
|
|
1185
|
+
function getClient3(cmd) {
|
|
1186
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
925
1187
|
requireOption(cfg.appToken, "app-token");
|
|
926
1188
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
927
1189
|
}
|
|
@@ -961,6 +1223,7 @@ function registerModelProviderCommands(model) {
|
|
|
961
1223
|
apiKey = apiKey || await promptPassword("API Key:");
|
|
962
1224
|
provider = { name: providerName, apiKey, models: [] };
|
|
963
1225
|
}
|
|
1226
|
+
await confirmAction(cfg, `Add provider '${provider.name}' to bot ${botId}?`);
|
|
964
1227
|
const result = await client.addProvider(botId, provider);
|
|
965
1228
|
if (cfg.json) {
|
|
966
1229
|
printJson(result);
|
|
@@ -1006,6 +1269,7 @@ function registerModelProviderCommands(model) {
|
|
|
1006
1269
|
model.command("delete <bot-id> <provider>").description("Delete a model provider").action(
|
|
1007
1270
|
withErrorHandler(async (botId, provider) => {
|
|
1008
1271
|
const { client, cfg } = getClient3(model);
|
|
1272
|
+
await confirmAction(cfg, `Delete provider '${provider}' from bot ${botId}?`);
|
|
1009
1273
|
await client.deleteProvider(botId, provider);
|
|
1010
1274
|
if (cfg.json) {
|
|
1011
1275
|
printJson({ message: "deleted" });
|
|
@@ -1035,6 +1299,7 @@ function registerModelProviderCommands(model) {
|
|
|
1035
1299
|
const body = {};
|
|
1036
1300
|
if (cmdOpts.primary) body.primary_model = cmdOpts.primary;
|
|
1037
1301
|
if (cmdOpts.fallback) body.fallback_model = cmdOpts.fallback;
|
|
1302
|
+
await confirmAction(cfg, `Update default model for bot ${botId}?`);
|
|
1038
1303
|
const d = await client.setDefaults(botId, body);
|
|
1039
1304
|
if (cfg.json) {
|
|
1040
1305
|
printJson(d);
|
|
@@ -1057,9 +1322,8 @@ function registerModelCommand(program2) {
|
|
|
1057
1322
|
|
|
1058
1323
|
// src/commands/channel/crud.ts
|
|
1059
1324
|
import chalk8 from "chalk";
|
|
1060
|
-
function getClient4(
|
|
1061
|
-
const
|
|
1062
|
-
const cfg = resolveConfig(opts);
|
|
1325
|
+
function getClient4(cmd) {
|
|
1326
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
1063
1327
|
requireOption(cfg.appToken, "app-token");
|
|
1064
1328
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
1065
1329
|
}
|
|
@@ -1097,6 +1361,7 @@ function registerChannelCrudCommands(channel) {
|
|
|
1097
1361
|
{ name: "Disabled", value: "disabled" }
|
|
1098
1362
|
]);
|
|
1099
1363
|
}
|
|
1364
|
+
await confirmAction(cfg, `Add channel '${channelType}' to bot ${botId}?`);
|
|
1100
1365
|
const result = await client.addChannel(botId, req);
|
|
1101
1366
|
if (cfg.json) {
|
|
1102
1367
|
printJson(result);
|
|
@@ -1127,6 +1392,7 @@ function registerChannelCrudCommands(channel) {
|
|
|
1127
1392
|
channel.command("remove <bot-id> <channel>").description("Remove a channel").option("--account <name>", "Specific account to remove").action(
|
|
1128
1393
|
withErrorHandler(async (botId, ch, cmdOpts) => {
|
|
1129
1394
|
const { client, cfg } = getClient4(channel);
|
|
1395
|
+
await confirmAction(cfg, `Remove channel '${ch}' from bot ${botId}?`);
|
|
1130
1396
|
const result = await client.removeChannel(botId, ch, cmdOpts.account);
|
|
1131
1397
|
if (cfg.json) {
|
|
1132
1398
|
printJson(result);
|
|
@@ -1138,10 +1404,8 @@ function registerChannelCrudCommands(channel) {
|
|
|
1138
1404
|
}
|
|
1139
1405
|
|
|
1140
1406
|
// src/commands/channel/pairing.ts
|
|
1141
|
-
function getClient5(
|
|
1142
|
-
const
|
|
1143
|
-
const opts = root.opts();
|
|
1144
|
-
const cfg = resolveConfig(opts);
|
|
1407
|
+
function getClient5(cmd) {
|
|
1408
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
1145
1409
|
requireOption(cfg.appToken, "app-token");
|
|
1146
1410
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
1147
1411
|
}
|
|
@@ -1161,6 +1425,7 @@ function registerPairingCommands(channel) {
|
|
|
1161
1425
|
pairing.command("approve <bot-id> <channel>").description("Approve a pairing request").requiredOption("--code <code>", "Pairing code").action(
|
|
1162
1426
|
withErrorHandler(async (botId, ch, cmdOpts) => {
|
|
1163
1427
|
const { client, cfg } = getClient5(pairing);
|
|
1428
|
+
await confirmAction(cfg, `Approve pairing for channel '${ch}'?`);
|
|
1164
1429
|
const result = await client.approvePairing(botId, ch, { code: cmdOpts.code });
|
|
1165
1430
|
if (cfg.json) {
|
|
1166
1431
|
printJson(result);
|
|
@@ -1172,6 +1437,7 @@ function registerPairingCommands(channel) {
|
|
|
1172
1437
|
pairing.command("revoke <bot-id> <channel>").description("Revoke a user's pairing").requiredOption("--user-id <userId>", "User ID to revoke").action(
|
|
1173
1438
|
withErrorHandler(async (botId, ch, cmdOpts) => {
|
|
1174
1439
|
const { client, cfg } = getClient5(pairing);
|
|
1440
|
+
await confirmAction(cfg, `Revoke pairing for user '${cmdOpts.userId}' on channel '${ch}'?`);
|
|
1175
1441
|
const result = await client.revokePairing(botId, ch, { user_id: cmdOpts.userId });
|
|
1176
1442
|
if (cfg.json) {
|
|
1177
1443
|
printJson(result);
|
|
@@ -1202,9 +1468,8 @@ function registerChannelCommand(program2) {
|
|
|
1202
1468
|
|
|
1203
1469
|
// src/commands/device/crud.ts
|
|
1204
1470
|
import chalk9 from "chalk";
|
|
1205
|
-
function getClient6(
|
|
1206
|
-
const
|
|
1207
|
-
const cfg = resolveConfig(opts);
|
|
1471
|
+
function getClient6(cmd) {
|
|
1472
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
1208
1473
|
requireOption(cfg.appToken, "app-token");
|
|
1209
1474
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
1210
1475
|
}
|
|
@@ -1239,6 +1504,7 @@ function registerDeviceCrudCommands(device) {
|
|
|
1239
1504
|
device.command("approve <bot-id> <request-id>").description("Approve a device pairing request").action(
|
|
1240
1505
|
withErrorHandler(async (botId, requestId) => {
|
|
1241
1506
|
const { client, cfg } = getClient6(device);
|
|
1507
|
+
await confirmAction(cfg, `Approve device ${requestId}?`);
|
|
1242
1508
|
const result = await client.approveDevice(botId, requestId);
|
|
1243
1509
|
if (cfg.json) {
|
|
1244
1510
|
printJson(result);
|
|
@@ -1250,6 +1516,7 @@ function registerDeviceCrudCommands(device) {
|
|
|
1250
1516
|
device.command("revoke <bot-id> <device-id>").description("Revoke a paired device").option("--role <role>", "Role to revoke", "operator").action(
|
|
1251
1517
|
withErrorHandler(async (botId, deviceId, cmdOpts) => {
|
|
1252
1518
|
const { client, cfg } = getClient6(device);
|
|
1519
|
+
await confirmAction(cfg, `Revoke device ${deviceId}?`);
|
|
1253
1520
|
const result = await client.revokeDevice(botId, deviceId, cmdOpts.role);
|
|
1254
1521
|
if (cfg.json) {
|
|
1255
1522
|
printJson(result);
|
|
@@ -1269,9 +1536,8 @@ function registerDeviceCommand(program2) {
|
|
|
1269
1536
|
// src/commands/skill/crud.ts
|
|
1270
1537
|
import { readFileSync as readFileSync2 } from "fs";
|
|
1271
1538
|
import chalk10 from "chalk";
|
|
1272
|
-
function getClient7(
|
|
1273
|
-
const
|
|
1274
|
-
const cfg = resolveConfig(opts);
|
|
1539
|
+
function getClient7(cmd) {
|
|
1540
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
1275
1541
|
requireOption(cfg.appToken, "app-token");
|
|
1276
1542
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
1277
1543
|
}
|
|
@@ -1300,6 +1566,7 @@ function registerSkillCrudCommands(skill) {
|
|
|
1300
1566
|
} else {
|
|
1301
1567
|
throw new Error("Either --content or --file is required");
|
|
1302
1568
|
}
|
|
1569
|
+
await confirmAction(cfg, `Set skill '${name}' on bot ${botId}?`);
|
|
1303
1570
|
const result = await client.setSkill(botId, name, { content });
|
|
1304
1571
|
if (cfg.json) {
|
|
1305
1572
|
printJson(result);
|
|
@@ -1311,6 +1578,7 @@ function registerSkillCrudCommands(skill) {
|
|
|
1311
1578
|
skill.command("delete <bot-id> <name>").description("Delete a skill").action(
|
|
1312
1579
|
withErrorHandler(async (botId, name) => {
|
|
1313
1580
|
const { client, cfg } = getClient7(skill);
|
|
1581
|
+
await confirmAction(cfg, `Delete skill '${name}' from bot ${botId}?`);
|
|
1314
1582
|
const result = await client.deleteSkill(botId, name);
|
|
1315
1583
|
if (cfg.json) {
|
|
1316
1584
|
printJson(result);
|
|
@@ -1327,6 +1595,19 @@ function registerSkillCommand(program2) {
|
|
|
1327
1595
|
registerSkillCrudCommands(skill);
|
|
1328
1596
|
}
|
|
1329
1597
|
|
|
1598
|
+
// src/commands/bot/index.ts
|
|
1599
|
+
function registerBotCommand(program2) {
|
|
1600
|
+
const bot = program2.command("bot").description("Manage bots").option("--user-id <userId>", "User ID for bot operations");
|
|
1601
|
+
registerBotCrudCommands(bot);
|
|
1602
|
+
registerBotLifecycleCommands(bot);
|
|
1603
|
+
registerBotLogsCommands(bot);
|
|
1604
|
+
registerBotRuntimeCommands(bot);
|
|
1605
|
+
registerModelCommand(bot);
|
|
1606
|
+
registerChannelCommand(bot);
|
|
1607
|
+
registerDeviceCommand(bot);
|
|
1608
|
+
registerSkillCommand(bot);
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1330
1611
|
// src/commands/setup.ts
|
|
1331
1612
|
import chalk11 from "chalk";
|
|
1332
1613
|
|
|
@@ -1481,8 +1762,8 @@ function registerSetupCommand(program2) {
|
|
|
1481
1762
|
console.log(chalk11.dim("\nUseful commands:"));
|
|
1482
1763
|
console.log(chalk11.dim(` fastclaw bot status ${bot.id}`));
|
|
1483
1764
|
console.log(chalk11.dim(` fastclaw bot connect ${bot.id}`));
|
|
1484
|
-
console.log(chalk11.dim(` fastclaw model list ${bot.id}`));
|
|
1485
|
-
console.log(chalk11.dim(` fastclaw channel add ${bot.id}`));
|
|
1765
|
+
console.log(chalk11.dim(` fastclaw bot model list ${bot.id}`));
|
|
1766
|
+
console.log(chalk11.dim(` fastclaw bot channel add ${bot.id}`));
|
|
1486
1767
|
console.log("");
|
|
1487
1768
|
})
|
|
1488
1769
|
);
|
|
@@ -1491,13 +1772,9 @@ function registerSetupCommand(program2) {
|
|
|
1491
1772
|
// src/index.ts
|
|
1492
1773
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
1493
1774
|
var pkg = JSON.parse(readFileSync3(join2(__dirname, "..", "package.json"), "utf-8"));
|
|
1494
|
-
var program = new Command().name("fastclaw").description("CLI for managing FastClaw bots").version(pkg.version).option("--url <url>", "FastClaw server URL").option("--admin-token <token>", "Admin API token").option("--app-token <token>", "App API token").option("--json", "Output as JSON");
|
|
1775
|
+
var program = new Command().name("fastclaw").description("CLI for managing FastClaw bots").version(pkg.version).option("--url <url>", "FastClaw server URL").option("--admin-token <token>", "Admin API token").option("--app-token <token>", "App API token").option("--json", "Output as JSON").option("-y, --yes", "Skip confirmation prompts");
|
|
1495
1776
|
registerSetupCommand(program);
|
|
1496
1777
|
registerConfigCommand(program);
|
|
1497
|
-
|
|
1778
|
+
registerAppCommand(program);
|
|
1498
1779
|
registerBotCommand(program);
|
|
1499
|
-
registerModelCommand(program);
|
|
1500
|
-
registerChannelCommand(program);
|
|
1501
|
-
registerDeviceCommand(program);
|
|
1502
|
-
registerSkillCommand(program);
|
|
1503
1780
|
program.parse();
|
package/dist/sdk.d.ts
CHANGED
|
@@ -172,6 +172,13 @@ interface SkillInfo {
|
|
|
172
172
|
interface SetSkillRequest {
|
|
173
173
|
content: string;
|
|
174
174
|
}
|
|
175
|
+
interface BotLogsResponse {
|
|
176
|
+
logs: string;
|
|
177
|
+
}
|
|
178
|
+
interface RuntimeExecRequest {
|
|
179
|
+
command?: string;
|
|
180
|
+
args?: string[];
|
|
181
|
+
}
|
|
175
182
|
interface UpgradeRequest {
|
|
176
183
|
image?: string;
|
|
177
184
|
}
|
|
@@ -252,6 +259,36 @@ declare class FastClawClient {
|
|
|
252
259
|
listSkills(botId: string): Promise<SkillInfo[]>;
|
|
253
260
|
setSkill(botId: string, name: string, req: SetSkillRequest): Promise<unknown>;
|
|
254
261
|
deleteSkill(botId: string, name: string): Promise<unknown>;
|
|
262
|
+
getBotLogs(botId: string, opts?: {
|
|
263
|
+
tail?: number;
|
|
264
|
+
sinceSeconds?: number;
|
|
265
|
+
sinceTime?: string;
|
|
266
|
+
timestamps?: boolean;
|
|
267
|
+
}): Promise<BotLogsResponse>;
|
|
268
|
+
getRuntimeStatus(botId: string, opts?: {
|
|
269
|
+
all?: boolean;
|
|
270
|
+
usage?: boolean;
|
|
271
|
+
deep?: boolean;
|
|
272
|
+
timeout?: string;
|
|
273
|
+
}): Promise<unknown>;
|
|
274
|
+
getRuntimeSessions(botId: string, opts?: {
|
|
275
|
+
agent?: string;
|
|
276
|
+
allAgents?: boolean;
|
|
277
|
+
active?: boolean;
|
|
278
|
+
}): Promise<unknown>;
|
|
279
|
+
getRuntimeConfig(botId: string, path?: string): Promise<unknown>;
|
|
280
|
+
getRuntimeConfigValidate(botId: string): Promise<unknown>;
|
|
281
|
+
getRuntimeModels(botId: string, opts?: {
|
|
282
|
+
all?: boolean;
|
|
283
|
+
agent?: string;
|
|
284
|
+
provider?: string;
|
|
285
|
+
}): Promise<unknown>;
|
|
286
|
+
getRuntimeSkills(botId: string, opts?: {
|
|
287
|
+
eligible?: boolean;
|
|
288
|
+
verbose?: boolean;
|
|
289
|
+
}): Promise<unknown>;
|
|
290
|
+
getRuntimeSkillsCheck(botId: string): Promise<unknown>;
|
|
291
|
+
runtimeExec(botId: string, req: RuntimeExecRequest): Promise<unknown>;
|
|
255
292
|
waitForReady(botId: string, timeoutMs?: number, intervalMs?: number): Promise<BotStatusResponse>;
|
|
256
293
|
health(): Promise<boolean>;
|
|
257
294
|
}
|
|
@@ -273,6 +310,7 @@ interface ResolvedConfig {
|
|
|
273
310
|
userId: string;
|
|
274
311
|
botId?: string;
|
|
275
312
|
json: boolean;
|
|
313
|
+
yes: boolean;
|
|
276
314
|
}
|
|
277
315
|
/**
|
|
278
316
|
* Resolve config with priority: CLI flags > env vars > config file > defaults.
|
|
@@ -285,6 +323,7 @@ declare function resolveConfig(opts: {
|
|
|
285
323
|
userId?: string;
|
|
286
324
|
botId?: string;
|
|
287
325
|
json?: boolean;
|
|
326
|
+
yes?: boolean;
|
|
288
327
|
}): ResolvedConfig;
|
|
289
328
|
declare function getConfigPath(): string;
|
|
290
329
|
|
|
@@ -309,4 +348,4 @@ declare function isValidSlug(slug: string): boolean;
|
|
|
309
348
|
declare function isValidUrl(url: string): boolean;
|
|
310
349
|
declare function slugify(name: string): string;
|
|
311
350
|
|
|
312
|
-
export { API_BASE, type AddChannelRequest, ApiError, type ApiResponse, type App, type Bot, type BotConnectResponse, type BotStatus, type BotStatusResponse, type BulkUpgradeResponse, CHANNEL_FIELDS, type ChannelResponse, type ChannelsMap, type ClientOptions, type CreateAppRequest, type CreateBotRequest, DEFAULT_URL, DM_POLICIES, type DeviceInfo, type DeviceListResponse, FastClawClient, type FastClawConfig, GROUP_POLICIES, MODEL_PRESETS, type ModelDefaults, type ModelProvider, PROVIDER_DEFAULTS, type PairedUsersResponse, type PairingApproveRequest, type PairingRequest, type PairingRevokeRequest, type ProviderModel, type ResetTokenResponse, type ResolvedConfig, type SetSkillRequest, type SkillInfo, type UpdateAppRequest, type UpdateBotRequest, type UpgradeRequest, type UpgradeResponse, getConfigPath, isValidSlug, isValidUrl, loadConfig, resolveConfig, saveConfig, slugify, updateConfig };
|
|
351
|
+
export { API_BASE, type AddChannelRequest, ApiError, type ApiResponse, type App, type Bot, type BotConnectResponse, type BotLogsResponse, type BotStatus, type BotStatusResponse, type BulkUpgradeResponse, CHANNEL_FIELDS, type ChannelResponse, type ChannelsMap, type ClientOptions, type CreateAppRequest, type CreateBotRequest, DEFAULT_URL, DM_POLICIES, type DeviceInfo, type DeviceListResponse, FastClawClient, type FastClawConfig, GROUP_POLICIES, MODEL_PRESETS, type ModelDefaults, type ModelProvider, PROVIDER_DEFAULTS, type PairedUsersResponse, type PairingApproveRequest, type PairingRequest, type PairingRevokeRequest, type ProviderModel, type ResetTokenResponse, type ResolvedConfig, type RuntimeExecRequest, type SetSkillRequest, type SkillInfo, type UpdateAppRequest, type UpdateBotRequest, type UpgradeRequest, type UpgradeResponse, getConfigPath, isValidSlug, isValidUrl, loadConfig, resolveConfig, saveConfig, slugify, updateConfig };
|
package/dist/sdk.js
CHANGED
|
@@ -114,6 +114,11 @@ var GROUP_POLICIES = ["open", "allowlist", "disabled"];
|
|
|
114
114
|
|
|
115
115
|
// src/utils/error.ts
|
|
116
116
|
import chalk from "chalk";
|
|
117
|
+
|
|
118
|
+
// src/utils/prompt.ts
|
|
119
|
+
import { input, select, password, confirm } from "@inquirer/prompts";
|
|
120
|
+
|
|
121
|
+
// src/utils/error.ts
|
|
117
122
|
var ApiError = class extends Error {
|
|
118
123
|
constructor(statusCode, apiCode, message) {
|
|
119
124
|
super(message);
|
|
@@ -311,6 +316,58 @@ var FastClawClient = class {
|
|
|
311
316
|
async deleteSkill(botId, name) {
|
|
312
317
|
return this.request("DELETE", `/bots/${botId}/skills/${name}`);
|
|
313
318
|
}
|
|
319
|
+
// ── Bot Logs ──
|
|
320
|
+
async getBotLogs(botId, opts) {
|
|
321
|
+
const query = {};
|
|
322
|
+
if (opts?.tail !== void 0) query.tail = String(opts.tail);
|
|
323
|
+
if (opts?.sinceSeconds !== void 0) query.sinceSeconds = String(opts.sinceSeconds);
|
|
324
|
+
if (opts?.sinceTime) query.sinceTime = opts.sinceTime;
|
|
325
|
+
if (opts?.timestamps) query.timestamps = "true";
|
|
326
|
+
return this.request("GET", `/bots/${botId}/logs`, { query });
|
|
327
|
+
}
|
|
328
|
+
// ── Bot Runtime (OpenClaw CLI exec) ──
|
|
329
|
+
async getRuntimeStatus(botId, opts) {
|
|
330
|
+
const query = {};
|
|
331
|
+
if (opts?.all) query.all = "true";
|
|
332
|
+
if (opts?.usage) query.usage = "true";
|
|
333
|
+
if (opts?.deep) query.deep = "true";
|
|
334
|
+
if (opts?.timeout) query.timeout = opts.timeout;
|
|
335
|
+
return this.request("GET", `/bots/${botId}/runtime/status`, { query });
|
|
336
|
+
}
|
|
337
|
+
async getRuntimeSessions(botId, opts) {
|
|
338
|
+
const query = {};
|
|
339
|
+
if (opts?.agent) query.agent = opts.agent;
|
|
340
|
+
if (opts?.allAgents) query["all-agents"] = "true";
|
|
341
|
+
if (opts?.active) query.active = "true";
|
|
342
|
+
return this.request("GET", `/bots/${botId}/runtime/sessions`, { query });
|
|
343
|
+
}
|
|
344
|
+
async getRuntimeConfig(botId, path) {
|
|
345
|
+
const query = {};
|
|
346
|
+
if (path) query.path = path;
|
|
347
|
+
return this.request("GET", `/bots/${botId}/runtime/config`, { query });
|
|
348
|
+
}
|
|
349
|
+
async getRuntimeConfigValidate(botId) {
|
|
350
|
+
return this.request("GET", `/bots/${botId}/runtime/config/validate`);
|
|
351
|
+
}
|
|
352
|
+
async getRuntimeModels(botId, opts) {
|
|
353
|
+
const query = {};
|
|
354
|
+
if (opts?.all) query.all = "true";
|
|
355
|
+
if (opts?.agent) query.agent = opts.agent;
|
|
356
|
+
if (opts?.provider) query.provider = opts.provider;
|
|
357
|
+
return this.request("GET", `/bots/${botId}/runtime/models`, { query });
|
|
358
|
+
}
|
|
359
|
+
async getRuntimeSkills(botId, opts) {
|
|
360
|
+
const query = {};
|
|
361
|
+
if (opts?.eligible) query.eligible = "true";
|
|
362
|
+
if (opts?.verbose) query.verbose = "true";
|
|
363
|
+
return this.request("GET", `/bots/${botId}/runtime/skills`, { query });
|
|
364
|
+
}
|
|
365
|
+
async getRuntimeSkillsCheck(botId) {
|
|
366
|
+
return this.request("GET", `/bots/${botId}/runtime/skills/check`);
|
|
367
|
+
}
|
|
368
|
+
async runtimeExec(botId, req) {
|
|
369
|
+
return this.request("POST", `/bots/${botId}/runtime/exec`, { body: req });
|
|
370
|
+
}
|
|
314
371
|
// ── Utility: wait for bot ready ──
|
|
315
372
|
async waitForReady(botId, timeoutMs = 12e4, intervalMs = 3e3) {
|
|
316
373
|
const start = Date.now();
|
|
@@ -367,7 +424,8 @@ function resolveConfig(opts) {
|
|
|
367
424
|
appToken: opts.appToken || process.env.FASTCLAW_APP_TOKEN || file.app_token,
|
|
368
425
|
userId: opts.userId || process.env.FASTCLAW_USER_ID || file.default_user_id || "default",
|
|
369
426
|
botId: opts.botId || process.env.FASTCLAW_BOT_ID || file.default_bot_id,
|
|
370
|
-
json: opts.json ?? false
|
|
427
|
+
json: opts.json ?? false,
|
|
428
|
+
yes: opts.yes ?? false
|
|
371
429
|
};
|
|
372
430
|
}
|
|
373
431
|
function getConfigPath() {
|