fastclaw-cli 0.2.1 → 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/README.md +2 -1
- package/dist/index.js +362 -83
- package/dist/sdk.d.ts +41 -2
- package/dist/sdk.js +62 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,9 +49,10 @@ fastclaw setup # Interactive one-step bot creation
|
|
|
49
49
|
|
|
50
50
|
fastclaw config set|get|show # Manage local config (~/.fastclaw/config.json)
|
|
51
51
|
|
|
52
|
-
fastclaw admin apps create|list|delete|rotate-token
|
|
52
|
+
fastclaw admin apps create|list [-t]|delete|rotate-token
|
|
53
53
|
|
|
54
54
|
fastclaw bot create|list|get|update|delete
|
|
55
|
+
fastclaw bot list -A [--user-id <uid>] # List bots across all apps (requires admin token)
|
|
55
56
|
fastclaw bot start|stop|restart|status|connect|reset-token <id>
|
|
56
57
|
|
|
57
58
|
fastclaw model add|list|get|delete <bot-id> [provider]
|
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
|
|
@@ -379,7 +405,9 @@ var FastClawClient = class {
|
|
|
379
405
|
return this.request("POST", "/bots", { body: req });
|
|
380
406
|
}
|
|
381
407
|
async listBots(userId) {
|
|
382
|
-
|
|
408
|
+
const query = {};
|
|
409
|
+
if (userId) query.user_id = userId;
|
|
410
|
+
return this.request("GET", "/bots", { query });
|
|
383
411
|
}
|
|
384
412
|
async getBot(id) {
|
|
385
413
|
return this.request("GET", `/bots/${id}`);
|
|
@@ -482,6 +510,58 @@ var FastClawClient = class {
|
|
|
482
510
|
async deleteSkill(botId, name) {
|
|
483
511
|
return this.request("DELETE", `/bots/${botId}/skills/${name}`);
|
|
484
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
|
+
}
|
|
485
565
|
// ── Utility: wait for bot ready ──
|
|
486
566
|
async waitForReady(botId, timeoutMs = 12e4, intervalMs = 3e3) {
|
|
487
567
|
const start = Date.now();
|
|
@@ -505,19 +585,20 @@ var FastClawClient = class {
|
|
|
505
585
|
}
|
|
506
586
|
};
|
|
507
587
|
|
|
508
|
-
// src/commands/
|
|
509
|
-
function getClient(
|
|
510
|
-
const opts =
|
|
588
|
+
// src/commands/app/index.ts
|
|
589
|
+
function getClient(app) {
|
|
590
|
+
const opts = app.parent.opts();
|
|
511
591
|
const cfg = resolveConfig(opts);
|
|
512
592
|
requireOption(cfg.adminToken, "admin-token");
|
|
513
593
|
return { client: new FastClawClient({ url: cfg.url, adminToken: cfg.adminToken }), cfg };
|
|
514
594
|
}
|
|
515
|
-
function
|
|
516
|
-
const
|
|
517
|
-
|
|
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(
|
|
518
598
|
withErrorHandler(async (cmdOpts) => {
|
|
519
|
-
const { client, cfg } = getClient(
|
|
520
|
-
|
|
599
|
+
const { client, cfg } = getClient(app);
|
|
600
|
+
await confirmAction(cfg, `Create app '${cmdOpts.name}'?`);
|
|
601
|
+
const result = await client.createApp({
|
|
521
602
|
name: cmdOpts.name,
|
|
522
603
|
url: cmdOpts.url,
|
|
523
604
|
description: cmdOpts.description,
|
|
@@ -525,21 +606,21 @@ function registerAppsCommand(admin) {
|
|
|
525
606
|
bot_domain_template: cmdOpts.botDomainTemplate
|
|
526
607
|
});
|
|
527
608
|
if (cfg.json) {
|
|
528
|
-
printJson(
|
|
609
|
+
printJson(result);
|
|
529
610
|
} else {
|
|
530
|
-
printSuccess(`App created: ${
|
|
611
|
+
printSuccess(`App created: ${result.id}`);
|
|
531
612
|
printKeyValue({
|
|
532
|
-
ID:
|
|
533
|
-
Name:
|
|
534
|
-
Token:
|
|
535
|
-
Status:
|
|
613
|
+
ID: result.id,
|
|
614
|
+
Name: result.name,
|
|
615
|
+
Token: result.api_token,
|
|
616
|
+
Status: result.status
|
|
536
617
|
});
|
|
537
618
|
}
|
|
538
619
|
})
|
|
539
620
|
);
|
|
540
|
-
|
|
621
|
+
app.command("list").description("List all apps").option("-t, --show-token", "Show full API token (masked by default)").action(
|
|
541
622
|
withErrorHandler(async (cmdOpts) => {
|
|
542
|
-
const { client, cfg } = getClient(
|
|
623
|
+
const { client, cfg } = getClient(app);
|
|
543
624
|
const list = await client.listApps();
|
|
544
625
|
if (cfg.json) {
|
|
545
626
|
printJson(list);
|
|
@@ -560,9 +641,46 @@ function registerAppsCommand(admin) {
|
|
|
560
641
|
}
|
|
561
642
|
})
|
|
562
643
|
);
|
|
563
|
-
|
|
644
|
+
app.command("get <id>").description("Get app details").action(
|
|
564
645
|
withErrorHandler(async (id) => {
|
|
565
|
-
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.`);
|
|
566
684
|
const res = await client.deleteApp(id);
|
|
567
685
|
if (cfg.json) {
|
|
568
686
|
printJson(res);
|
|
@@ -571,9 +689,10 @@ function registerAppsCommand(admin) {
|
|
|
571
689
|
}
|
|
572
690
|
})
|
|
573
691
|
);
|
|
574
|
-
|
|
692
|
+
app.command("rotate-token <id>").description("Reset an app's API token").action(
|
|
575
693
|
withErrorHandler(async (id) => {
|
|
576
|
-
const { client, cfg } = getClient(
|
|
694
|
+
const { client, cfg } = getClient(app);
|
|
695
|
+
await confirmAction(cfg, `Rotate API token for app ${id}?`);
|
|
577
696
|
const res = await client.rotateAppToken(id);
|
|
578
697
|
if (cfg.json) {
|
|
579
698
|
printJson(res);
|
|
@@ -585,31 +704,27 @@ function registerAppsCommand(admin) {
|
|
|
585
704
|
);
|
|
586
705
|
}
|
|
587
706
|
|
|
588
|
-
// src/commands/admin/index.ts
|
|
589
|
-
function registerAdminCommand(program2) {
|
|
590
|
-
const admin = program2.command("admin").description("Admin operations");
|
|
591
|
-
registerAppsCommand(admin);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
707
|
// src/commands/bot/crud.ts
|
|
595
708
|
import chalk5 from "chalk";
|
|
596
709
|
|
|
597
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
|
+
}
|
|
598
716
|
function getClient2(cmd) {
|
|
599
|
-
const
|
|
600
|
-
const cfg = resolveConfig(opts);
|
|
717
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
601
718
|
requireOption(cfg.appToken, "app-token");
|
|
602
719
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
603
720
|
}
|
|
604
721
|
function getAdminClient(cmd) {
|
|
605
|
-
const
|
|
606
|
-
const cfg = resolveConfig(opts);
|
|
722
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
607
723
|
requireOption(cfg.adminToken, "admin-token");
|
|
608
724
|
return { client: new FastClawClient({ url: cfg.url, adminToken: cfg.adminToken }), cfg };
|
|
609
725
|
}
|
|
610
726
|
async function resolveClientForBot(cmd, botId) {
|
|
611
|
-
const
|
|
612
|
-
const cfg = resolveConfig(opts);
|
|
727
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
613
728
|
if (cfg.appToken) {
|
|
614
729
|
try {
|
|
615
730
|
const client = new FastClawClient({ url: cfg.url, appToken: cfg.appToken });
|
|
@@ -641,6 +756,7 @@ function registerBotCrudCommands(bot) {
|
|
|
641
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(
|
|
642
757
|
withErrorHandler(async (cmdOpts) => {
|
|
643
758
|
const { client, cfg } = getClient2(bot);
|
|
759
|
+
await confirmAction(cfg, `Create bot '${cmdOpts.name}'?`);
|
|
644
760
|
const userId = cmdOpts.userId || cfg.userId;
|
|
645
761
|
const result = await client.createBot({
|
|
646
762
|
user_id: userId,
|
|
@@ -667,7 +783,7 @@ function registerBotCrudCommands(bot) {
|
|
|
667
783
|
withErrorHandler(async (cmdOpts) => {
|
|
668
784
|
if (cmdOpts.all) {
|
|
669
785
|
const { client: adminClient, cfg } = getAdminClient(bot);
|
|
670
|
-
const userId = cmdOpts.userId
|
|
786
|
+
const userId = cmdOpts.userId;
|
|
671
787
|
const apps = await adminClient.listApps();
|
|
672
788
|
const allBots = [];
|
|
673
789
|
for (const app of apps) {
|
|
@@ -694,13 +810,13 @@ function registerBotCrudCommands(bot) {
|
|
|
694
810
|
console.log(chalk5.dim("No bots found."));
|
|
695
811
|
} else {
|
|
696
812
|
printTable(
|
|
697
|
-
["App", "ID", "Name", "Slug", "Status", "Ready", "Created"],
|
|
698
|
-
allBots.map((x) => [x.app_name, x.bot.id, x.bot.name, x.bot.slug, x.bot.status, x.ready, x.bot.created_at])
|
|
813
|
+
["App", "User", "ID", "Name", "Slug", "Status", "Ready", "Created"],
|
|
814
|
+
allBots.map((x) => [x.app_name, x.bot.user_id, x.bot.id, x.bot.name, x.bot.slug, x.bot.status, x.ready, x.bot.created_at])
|
|
699
815
|
);
|
|
700
816
|
}
|
|
701
817
|
} else {
|
|
702
818
|
const { client, cfg } = getClient2(bot);
|
|
703
|
-
const userId = cmdOpts.userId
|
|
819
|
+
const userId = cmdOpts.userId;
|
|
704
820
|
const list = await client.listBots(userId);
|
|
705
821
|
if (cfg.json) {
|
|
706
822
|
printJson(list);
|
|
@@ -717,9 +833,9 @@ function registerBotCrudCommands(bot) {
|
|
|
717
833
|
} catch {
|
|
718
834
|
}
|
|
719
835
|
}
|
|
720
|
-
rows.push([b.id, b.name, b.slug, b.status, ready, b.created_at]);
|
|
836
|
+
rows.push([b.user_id, b.id, b.name, b.slug, b.status, ready, b.created_at]);
|
|
721
837
|
}
|
|
722
|
-
printTable(["ID", "Name", "Slug", "Status", "Ready", "Created"], rows);
|
|
838
|
+
printTable(["User", "ID", "Name", "Slug", "Status", "Ready", "Created"], rows);
|
|
723
839
|
}
|
|
724
840
|
}
|
|
725
841
|
})
|
|
@@ -751,6 +867,7 @@ function registerBotCrudCommands(bot) {
|
|
|
751
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(
|
|
752
868
|
withErrorHandler(async (id, cmdOpts) => {
|
|
753
869
|
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
870
|
+
await confirmAction(cfg, `Update bot ${id}?`);
|
|
754
871
|
const result = await client.updateBot(id, {
|
|
755
872
|
name: cmdOpts.name,
|
|
756
873
|
slug: cmdOpts.slug,
|
|
@@ -766,6 +883,7 @@ function registerBotCrudCommands(bot) {
|
|
|
766
883
|
bot.command("delete <id>").description("Delete a bot").action(
|
|
767
884
|
withErrorHandler(async (id) => {
|
|
768
885
|
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
886
|
+
await confirmAction(cfg, `Delete bot ${id}? This cannot be undone.`);
|
|
769
887
|
const res = await client.deleteBot(id);
|
|
770
888
|
if (cfg.json) {
|
|
771
889
|
printJson(res);
|
|
@@ -809,6 +927,7 @@ function registerBotLifecycleCommands(bot) {
|
|
|
809
927
|
bot.command("stop <id>").description("Stop a bot").action(
|
|
810
928
|
withErrorHandler(async (id) => {
|
|
811
929
|
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
930
|
+
await confirmAction(cfg, `Stop bot ${id}?`);
|
|
812
931
|
const res = await client.stopBot(id);
|
|
813
932
|
if (cfg.json) {
|
|
814
933
|
printJson(res);
|
|
@@ -820,6 +939,7 @@ function registerBotLifecycleCommands(bot) {
|
|
|
820
939
|
bot.command("restart <id>").description("Restart a bot").action(
|
|
821
940
|
withErrorHandler(async (id) => {
|
|
822
941
|
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
942
|
+
await confirmAction(cfg, `Restart bot ${id}?`);
|
|
823
943
|
const res = await client.restartBot(id);
|
|
824
944
|
if (cfg.json) {
|
|
825
945
|
printJson(res);
|
|
@@ -880,6 +1000,7 @@ function registerBotLifecycleCommands(bot) {
|
|
|
880
1000
|
bot.command("reset-token <id>").description("Reset bot access token").action(
|
|
881
1001
|
withErrorHandler(async (id) => {
|
|
882
1002
|
const { client, cfg } = await resolveClientForBot(bot, id);
|
|
1003
|
+
await confirmAction(cfg, `Reset access token for bot ${id}?`);
|
|
883
1004
|
const res = await client.resetBotToken(id);
|
|
884
1005
|
if (cfg.json) {
|
|
885
1006
|
printJson(res);
|
|
@@ -894,32 +1015,175 @@ function registerBotLifecycleCommands(bot) {
|
|
|
894
1015
|
);
|
|
895
1016
|
}
|
|
896
1017
|
|
|
897
|
-
// src/commands/bot/
|
|
898
|
-
function
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
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
|
+
);
|
|
902
1036
|
}
|
|
903
1037
|
|
|
904
|
-
// src/commands/
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
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
|
+
);
|
|
917
1181
|
}
|
|
918
1182
|
|
|
919
1183
|
// src/commands/model/provider.ts
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
const cfg = resolveConfig(
|
|
1184
|
+
import chalk7 from "chalk";
|
|
1185
|
+
function getClient3(cmd) {
|
|
1186
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
923
1187
|
requireOption(cfg.appToken, "app-token");
|
|
924
1188
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
925
1189
|
}
|
|
@@ -959,6 +1223,7 @@ function registerModelProviderCommands(model) {
|
|
|
959
1223
|
apiKey = apiKey || await promptPassword("API Key:");
|
|
960
1224
|
provider = { name: providerName, apiKey, models: [] };
|
|
961
1225
|
}
|
|
1226
|
+
await confirmAction(cfg, `Add provider '${provider.name}' to bot ${botId}?`);
|
|
962
1227
|
const result = await client.addProvider(botId, provider);
|
|
963
1228
|
if (cfg.json) {
|
|
964
1229
|
printJson(result);
|
|
@@ -1004,6 +1269,7 @@ function registerModelProviderCommands(model) {
|
|
|
1004
1269
|
model.command("delete <bot-id> <provider>").description("Delete a model provider").action(
|
|
1005
1270
|
withErrorHandler(async (botId, provider) => {
|
|
1006
1271
|
const { client, cfg } = getClient3(model);
|
|
1272
|
+
await confirmAction(cfg, `Delete provider '${provider}' from bot ${botId}?`);
|
|
1007
1273
|
await client.deleteProvider(botId, provider);
|
|
1008
1274
|
if (cfg.json) {
|
|
1009
1275
|
printJson({ message: "deleted" });
|
|
@@ -1033,6 +1299,7 @@ function registerModelProviderCommands(model) {
|
|
|
1033
1299
|
const body = {};
|
|
1034
1300
|
if (cmdOpts.primary) body.primary_model = cmdOpts.primary;
|
|
1035
1301
|
if (cmdOpts.fallback) body.fallback_model = cmdOpts.fallback;
|
|
1302
|
+
await confirmAction(cfg, `Update default model for bot ${botId}?`);
|
|
1036
1303
|
const d = await client.setDefaults(botId, body);
|
|
1037
1304
|
if (cfg.json) {
|
|
1038
1305
|
printJson(d);
|
|
@@ -1055,9 +1322,8 @@ function registerModelCommand(program2) {
|
|
|
1055
1322
|
|
|
1056
1323
|
// src/commands/channel/crud.ts
|
|
1057
1324
|
import chalk8 from "chalk";
|
|
1058
|
-
function getClient4(
|
|
1059
|
-
const
|
|
1060
|
-
const cfg = resolveConfig(opts);
|
|
1325
|
+
function getClient4(cmd) {
|
|
1326
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
1061
1327
|
requireOption(cfg.appToken, "app-token");
|
|
1062
1328
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
1063
1329
|
}
|
|
@@ -1095,6 +1361,7 @@ function registerChannelCrudCommands(channel) {
|
|
|
1095
1361
|
{ name: "Disabled", value: "disabled" }
|
|
1096
1362
|
]);
|
|
1097
1363
|
}
|
|
1364
|
+
await confirmAction(cfg, `Add channel '${channelType}' to bot ${botId}?`);
|
|
1098
1365
|
const result = await client.addChannel(botId, req);
|
|
1099
1366
|
if (cfg.json) {
|
|
1100
1367
|
printJson(result);
|
|
@@ -1125,6 +1392,7 @@ function registerChannelCrudCommands(channel) {
|
|
|
1125
1392
|
channel.command("remove <bot-id> <channel>").description("Remove a channel").option("--account <name>", "Specific account to remove").action(
|
|
1126
1393
|
withErrorHandler(async (botId, ch, cmdOpts) => {
|
|
1127
1394
|
const { client, cfg } = getClient4(channel);
|
|
1395
|
+
await confirmAction(cfg, `Remove channel '${ch}' from bot ${botId}?`);
|
|
1128
1396
|
const result = await client.removeChannel(botId, ch, cmdOpts.account);
|
|
1129
1397
|
if (cfg.json) {
|
|
1130
1398
|
printJson(result);
|
|
@@ -1136,10 +1404,8 @@ function registerChannelCrudCommands(channel) {
|
|
|
1136
1404
|
}
|
|
1137
1405
|
|
|
1138
1406
|
// src/commands/channel/pairing.ts
|
|
1139
|
-
function getClient5(
|
|
1140
|
-
const
|
|
1141
|
-
const opts = root.opts();
|
|
1142
|
-
const cfg = resolveConfig(opts);
|
|
1407
|
+
function getClient5(cmd) {
|
|
1408
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
1143
1409
|
requireOption(cfg.appToken, "app-token");
|
|
1144
1410
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
1145
1411
|
}
|
|
@@ -1159,6 +1425,7 @@ function registerPairingCommands(channel) {
|
|
|
1159
1425
|
pairing.command("approve <bot-id> <channel>").description("Approve a pairing request").requiredOption("--code <code>", "Pairing code").action(
|
|
1160
1426
|
withErrorHandler(async (botId, ch, cmdOpts) => {
|
|
1161
1427
|
const { client, cfg } = getClient5(pairing);
|
|
1428
|
+
await confirmAction(cfg, `Approve pairing for channel '${ch}'?`);
|
|
1162
1429
|
const result = await client.approvePairing(botId, ch, { code: cmdOpts.code });
|
|
1163
1430
|
if (cfg.json) {
|
|
1164
1431
|
printJson(result);
|
|
@@ -1170,6 +1437,7 @@ function registerPairingCommands(channel) {
|
|
|
1170
1437
|
pairing.command("revoke <bot-id> <channel>").description("Revoke a user's pairing").requiredOption("--user-id <userId>", "User ID to revoke").action(
|
|
1171
1438
|
withErrorHandler(async (botId, ch, cmdOpts) => {
|
|
1172
1439
|
const { client, cfg } = getClient5(pairing);
|
|
1440
|
+
await confirmAction(cfg, `Revoke pairing for user '${cmdOpts.userId}' on channel '${ch}'?`);
|
|
1173
1441
|
const result = await client.revokePairing(botId, ch, { user_id: cmdOpts.userId });
|
|
1174
1442
|
if (cfg.json) {
|
|
1175
1443
|
printJson(result);
|
|
@@ -1200,9 +1468,8 @@ function registerChannelCommand(program2) {
|
|
|
1200
1468
|
|
|
1201
1469
|
// src/commands/device/crud.ts
|
|
1202
1470
|
import chalk9 from "chalk";
|
|
1203
|
-
function getClient6(
|
|
1204
|
-
const
|
|
1205
|
-
const cfg = resolveConfig(opts);
|
|
1471
|
+
function getClient6(cmd) {
|
|
1472
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
1206
1473
|
requireOption(cfg.appToken, "app-token");
|
|
1207
1474
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
1208
1475
|
}
|
|
@@ -1237,6 +1504,7 @@ function registerDeviceCrudCommands(device) {
|
|
|
1237
1504
|
device.command("approve <bot-id> <request-id>").description("Approve a device pairing request").action(
|
|
1238
1505
|
withErrorHandler(async (botId, requestId) => {
|
|
1239
1506
|
const { client, cfg } = getClient6(device);
|
|
1507
|
+
await confirmAction(cfg, `Approve device ${requestId}?`);
|
|
1240
1508
|
const result = await client.approveDevice(botId, requestId);
|
|
1241
1509
|
if (cfg.json) {
|
|
1242
1510
|
printJson(result);
|
|
@@ -1248,6 +1516,7 @@ function registerDeviceCrudCommands(device) {
|
|
|
1248
1516
|
device.command("revoke <bot-id> <device-id>").description("Revoke a paired device").option("--role <role>", "Role to revoke", "operator").action(
|
|
1249
1517
|
withErrorHandler(async (botId, deviceId, cmdOpts) => {
|
|
1250
1518
|
const { client, cfg } = getClient6(device);
|
|
1519
|
+
await confirmAction(cfg, `Revoke device ${deviceId}?`);
|
|
1251
1520
|
const result = await client.revokeDevice(botId, deviceId, cmdOpts.role);
|
|
1252
1521
|
if (cfg.json) {
|
|
1253
1522
|
printJson(result);
|
|
@@ -1267,9 +1536,8 @@ function registerDeviceCommand(program2) {
|
|
|
1267
1536
|
// src/commands/skill/crud.ts
|
|
1268
1537
|
import { readFileSync as readFileSync2 } from "fs";
|
|
1269
1538
|
import chalk10 from "chalk";
|
|
1270
|
-
function getClient7(
|
|
1271
|
-
const
|
|
1272
|
-
const cfg = resolveConfig(opts);
|
|
1539
|
+
function getClient7(cmd) {
|
|
1540
|
+
const cfg = resolveConfig(getRootOpts(cmd));
|
|
1273
1541
|
requireOption(cfg.appToken, "app-token");
|
|
1274
1542
|
return { client: new FastClawClient({ url: cfg.url, appToken: cfg.appToken }), cfg };
|
|
1275
1543
|
}
|
|
@@ -1298,6 +1566,7 @@ function registerSkillCrudCommands(skill) {
|
|
|
1298
1566
|
} else {
|
|
1299
1567
|
throw new Error("Either --content or --file is required");
|
|
1300
1568
|
}
|
|
1569
|
+
await confirmAction(cfg, `Set skill '${name}' on bot ${botId}?`);
|
|
1301
1570
|
const result = await client.setSkill(botId, name, { content });
|
|
1302
1571
|
if (cfg.json) {
|
|
1303
1572
|
printJson(result);
|
|
@@ -1309,6 +1578,7 @@ function registerSkillCrudCommands(skill) {
|
|
|
1309
1578
|
skill.command("delete <bot-id> <name>").description("Delete a skill").action(
|
|
1310
1579
|
withErrorHandler(async (botId, name) => {
|
|
1311
1580
|
const { client, cfg } = getClient7(skill);
|
|
1581
|
+
await confirmAction(cfg, `Delete skill '${name}' from bot ${botId}?`);
|
|
1312
1582
|
const result = await client.deleteSkill(botId, name);
|
|
1313
1583
|
if (cfg.json) {
|
|
1314
1584
|
printJson(result);
|
|
@@ -1325,6 +1595,19 @@ function registerSkillCommand(program2) {
|
|
|
1325
1595
|
registerSkillCrudCommands(skill);
|
|
1326
1596
|
}
|
|
1327
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
|
+
|
|
1328
1611
|
// src/commands/setup.ts
|
|
1329
1612
|
import chalk11 from "chalk";
|
|
1330
1613
|
|
|
@@ -1479,8 +1762,8 @@ function registerSetupCommand(program2) {
|
|
|
1479
1762
|
console.log(chalk11.dim("\nUseful commands:"));
|
|
1480
1763
|
console.log(chalk11.dim(` fastclaw bot status ${bot.id}`));
|
|
1481
1764
|
console.log(chalk11.dim(` fastclaw bot connect ${bot.id}`));
|
|
1482
|
-
console.log(chalk11.dim(` fastclaw model list ${bot.id}`));
|
|
1483
|
-
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}`));
|
|
1484
1767
|
console.log("");
|
|
1485
1768
|
})
|
|
1486
1769
|
);
|
|
@@ -1489,13 +1772,9 @@ function registerSetupCommand(program2) {
|
|
|
1489
1772
|
// src/index.ts
|
|
1490
1773
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
1491
1774
|
var pkg = JSON.parse(readFileSync3(join2(__dirname, "..", "package.json"), "utf-8"));
|
|
1492
|
-
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");
|
|
1493
1776
|
registerSetupCommand(program);
|
|
1494
1777
|
registerConfigCommand(program);
|
|
1495
|
-
|
|
1778
|
+
registerAppCommand(program);
|
|
1496
1779
|
registerBotCommand(program);
|
|
1497
|
-
registerModelCommand(program);
|
|
1498
|
-
registerChannelCommand(program);
|
|
1499
|
-
registerDeviceCommand(program);
|
|
1500
|
-
registerSkillCommand(program);
|
|
1501
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
|
}
|
|
@@ -217,7 +224,7 @@ declare class FastClawClient {
|
|
|
217
224
|
upgradeBot(id: string, req?: UpgradeRequest): Promise<UpgradeResponse>;
|
|
218
225
|
upgradeAllBots(req?: UpgradeRequest): Promise<BulkUpgradeResponse>;
|
|
219
226
|
createBot(req: CreateBotRequest): Promise<Bot>;
|
|
220
|
-
listBots(userId
|
|
227
|
+
listBots(userId?: string): Promise<Bot[]>;
|
|
221
228
|
getBot(id: string): Promise<Bot>;
|
|
222
229
|
updateBot(id: string, req: UpdateBotRequest): Promise<Bot>;
|
|
223
230
|
deleteBot(id: string): Promise<{
|
|
@@ -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);
|
|
@@ -206,7 +211,9 @@ var FastClawClient = class {
|
|
|
206
211
|
return this.request("POST", "/bots", { body: req });
|
|
207
212
|
}
|
|
208
213
|
async listBots(userId) {
|
|
209
|
-
|
|
214
|
+
const query = {};
|
|
215
|
+
if (userId) query.user_id = userId;
|
|
216
|
+
return this.request("GET", "/bots", { query });
|
|
210
217
|
}
|
|
211
218
|
async getBot(id) {
|
|
212
219
|
return this.request("GET", `/bots/${id}`);
|
|
@@ -309,6 +316,58 @@ var FastClawClient = class {
|
|
|
309
316
|
async deleteSkill(botId, name) {
|
|
310
317
|
return this.request("DELETE", `/bots/${botId}/skills/${name}`);
|
|
311
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
|
+
}
|
|
312
371
|
// ── Utility: wait for bot ready ──
|
|
313
372
|
async waitForReady(botId, timeoutMs = 12e4, intervalMs = 3e3) {
|
|
314
373
|
const start = Date.now();
|
|
@@ -365,7 +424,8 @@ function resolveConfig(opts) {
|
|
|
365
424
|
appToken: opts.appToken || process.env.FASTCLAW_APP_TOKEN || file.app_token,
|
|
366
425
|
userId: opts.userId || process.env.FASTCLAW_USER_ID || file.default_user_id || "default",
|
|
367
426
|
botId: opts.botId || process.env.FASTCLAW_BOT_ID || file.default_bot_id,
|
|
368
|
-
json: opts.json ?? false
|
|
427
|
+
json: opts.json ?? false,
|
|
428
|
+
yes: opts.yes ?? false
|
|
369
429
|
};
|
|
370
430
|
}
|
|
371
431
|
function getConfigPath() {
|