@agentforge-ai/cli 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/default/README.md +81 -81
- package/dist/default/convex/agents.ts +204 -0
- package/dist/default/convex/apiKeys.ts +133 -0
- package/dist/default/convex/cronJobs.ts +224 -0
- package/dist/default/convex/files.ts +103 -0
- package/dist/default/convex/folders.ts +110 -0
- package/dist/default/convex/heartbeat.ts +371 -0
- package/dist/default/convex/logs.ts +66 -0
- package/dist/default/convex/mastraIntegration.ts +184 -0
- package/dist/default/convex/mcpConnections.ts +127 -0
- package/dist/default/convex/messages.ts +90 -0
- package/dist/default/convex/projects.ts +114 -0
- package/dist/default/convex/sessions.ts +174 -0
- package/dist/default/convex/settings.ts +79 -0
- package/dist/default/convex/skills.ts +178 -0
- package/dist/default/convex/threads.ts +100 -0
- package/dist/default/convex/usage.ts +195 -0
- package/dist/default/convex/vault.ts +383 -0
- package/dist/default/dashboard/app/main.tsx +7 -3
- package/dist/default/dashboard/app/routes/agents.tsx +103 -161
- package/dist/default/dashboard/app/routes/chat.tsx +163 -317
- package/dist/default/dashboard/app/routes/connections.tsx +247 -386
- package/dist/default/dashboard/app/routes/cron.tsx +127 -286
- package/dist/default/dashboard/app/routes/files.tsx +184 -167
- package/dist/default/dashboard/app/routes/index.tsx +63 -96
- package/dist/default/dashboard/app/routes/projects.tsx +106 -225
- package/dist/default/dashboard/app/routes/sessions.tsx +87 -253
- package/dist/default/dashboard/app/routes/settings.tsx +316 -532
- package/dist/default/dashboard/app/routes/skills.tsx +329 -216
- package/dist/default/dashboard/app/routes/usage.tsx +107 -150
- package/dist/default/dashboard/tsconfig.json +3 -2
- package/dist/default/dashboard/vite.config.ts +6 -0
- package/dist/index.js +279 -50
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/default/README.md +81 -81
- package/templates/default/convex/agents.ts +204 -0
- package/templates/default/convex/apiKeys.ts +133 -0
- package/templates/default/convex/cronJobs.ts +224 -0
- package/templates/default/convex/files.ts +103 -0
- package/templates/default/convex/folders.ts +110 -0
- package/templates/default/convex/heartbeat.ts +371 -0
- package/templates/default/convex/logs.ts +66 -0
- package/templates/default/convex/mastraIntegration.ts +184 -0
- package/templates/default/convex/mcpConnections.ts +127 -0
- package/templates/default/convex/messages.ts +90 -0
- package/templates/default/convex/projects.ts +114 -0
- package/templates/default/convex/sessions.ts +174 -0
- package/templates/default/convex/settings.ts +79 -0
- package/templates/default/convex/skills.ts +178 -0
- package/templates/default/convex/threads.ts +100 -0
- package/templates/default/convex/usage.ts +195 -0
- package/templates/default/convex/vault.ts +383 -0
- package/templates/default/dashboard/app/main.tsx +7 -3
- package/templates/default/dashboard/app/routes/agents.tsx +103 -161
- package/templates/default/dashboard/app/routes/chat.tsx +163 -317
- package/templates/default/dashboard/app/routes/connections.tsx +247 -386
- package/templates/default/dashboard/app/routes/cron.tsx +127 -286
- package/templates/default/dashboard/app/routes/files.tsx +184 -167
- package/templates/default/dashboard/app/routes/index.tsx +63 -96
- package/templates/default/dashboard/app/routes/projects.tsx +106 -225
- package/templates/default/dashboard/app/routes/sessions.tsx +87 -253
- package/templates/default/dashboard/app/routes/settings.tsx +316 -532
- package/templates/default/dashboard/app/routes/skills.tsx +329 -216
- package/templates/default/dashboard/app/routes/usage.tsx +107 -150
- package/templates/default/dashboard/tsconfig.json +3 -2
- package/templates/default/dashboard/vite.config.ts +6 -0
package/dist/index.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
2
8
|
|
|
3
9
|
// src/index.ts
|
|
4
10
|
import { Command } from "commander";
|
|
@@ -295,11 +301,22 @@ async function deployProject(options) {
|
|
|
295
301
|
}
|
|
296
302
|
|
|
297
303
|
// src/lib/convex-client.ts
|
|
298
|
-
import { ConvexHttpClient } from "convex/browser";
|
|
299
304
|
import fs4 from "fs-extra";
|
|
300
305
|
import path4 from "path";
|
|
306
|
+
function safeCwd() {
|
|
307
|
+
try {
|
|
308
|
+
return process.cwd();
|
|
309
|
+
} catch {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
301
313
|
function getConvexUrl() {
|
|
302
|
-
const cwd =
|
|
314
|
+
const cwd = safeCwd();
|
|
315
|
+
if (!cwd) {
|
|
316
|
+
throw new Error(
|
|
317
|
+
"Current directory does not exist or is not accessible.\nPlease navigate to a valid AgentForge project directory and try again."
|
|
318
|
+
);
|
|
319
|
+
}
|
|
303
320
|
const envFiles = [".env.local", ".env", ".env.production"];
|
|
304
321
|
for (const envFile of envFiles) {
|
|
305
322
|
const envPath = path4.join(cwd, envFile);
|
|
@@ -323,7 +340,8 @@ function getConvexUrl() {
|
|
|
323
340
|
"CONVEX_URL not found. Run `npx convex dev` first, or set CONVEX_URL in your .env file."
|
|
324
341
|
);
|
|
325
342
|
}
|
|
326
|
-
function createClient() {
|
|
343
|
+
async function createClient() {
|
|
344
|
+
const { ConvexHttpClient } = await import("convex/browser");
|
|
327
345
|
const url = getConvexUrl();
|
|
328
346
|
return new ConvexHttpClient(url);
|
|
329
347
|
}
|
|
@@ -334,6 +352,10 @@ async function safeCall(fn, errorMessage) {
|
|
|
334
352
|
if (error2.message?.includes("CONVEX_URL not found")) {
|
|
335
353
|
console.error("\n\u274C Not connected to Convex.");
|
|
336
354
|
console.error(" Run `npx convex dev` in your project directory first.\n");
|
|
355
|
+
} else if (error2.message?.includes("Current directory does not exist")) {
|
|
356
|
+
console.error(`
|
|
357
|
+
\u274C ${error2.message}
|
|
358
|
+
`);
|
|
337
359
|
} else if (error2.message?.includes("fetch failed") || error2.message?.includes("ECONNREFUSED")) {
|
|
338
360
|
console.error("\n\u274C Cannot reach Convex deployment.");
|
|
339
361
|
console.error(" Make sure `npx convex dev` is running.\n");
|
|
@@ -424,7 +446,7 @@ function prompt(question) {
|
|
|
424
446
|
function registerAgentsCommand(program2) {
|
|
425
447
|
const agents = program2.command("agents").description("Manage agents");
|
|
426
448
|
agents.command("list").description("List all agents").option("--active", "Show only active agents").option("--json", "Output as JSON").action(async (opts) => {
|
|
427
|
-
const client = createClient();
|
|
449
|
+
const client = await createClient();
|
|
428
450
|
const result = await safeCall(
|
|
429
451
|
() => client.query("agents:list", {}),
|
|
430
452
|
"Failed to list agents"
|
|
@@ -460,7 +482,7 @@ function registerAgentsCommand(program2) {
|
|
|
460
482
|
}
|
|
461
483
|
const provider = model.includes(":") ? model.split(":")[0] : "openai";
|
|
462
484
|
const agentId = name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
463
|
-
const client = createClient();
|
|
485
|
+
const client = await createClient();
|
|
464
486
|
await safeCall(
|
|
465
487
|
() => client.mutation("agents:create", {
|
|
466
488
|
id: agentId,
|
|
@@ -475,7 +497,7 @@ function registerAgentsCommand(program2) {
|
|
|
475
497
|
success(`Agent "${name}" created with ID: ${agentId}`);
|
|
476
498
|
});
|
|
477
499
|
agents.command("inspect").argument("<id>", "Agent ID").description("Show detailed agent information").action(async (id) => {
|
|
478
|
-
const client = createClient();
|
|
500
|
+
const client = await createClient();
|
|
479
501
|
const agent = await safeCall(
|
|
480
502
|
() => client.query("agents:getByAgentId", { id }),
|
|
481
503
|
"Failed to fetch agent"
|
|
@@ -503,7 +525,7 @@ function registerAgentsCommand(program2) {
|
|
|
503
525
|
`);
|
|
504
526
|
});
|
|
505
527
|
agents.command("edit").argument("<id>", "Agent ID").option("--name <name>", "New name").option("--model <model>", "New model").option("--instructions <text>", "New instructions").description("Edit an agent").action(async (id, opts) => {
|
|
506
|
-
const client = createClient();
|
|
528
|
+
const client = await createClient();
|
|
507
529
|
const agent = await safeCall(
|
|
508
530
|
() => client.query("agents:getByAgentId", { id }),
|
|
509
531
|
"Failed to fetch agent"
|
|
@@ -549,7 +571,7 @@ function registerAgentsCommand(program2) {
|
|
|
549
571
|
return;
|
|
550
572
|
}
|
|
551
573
|
}
|
|
552
|
-
const client = createClient();
|
|
574
|
+
const client = await createClient();
|
|
553
575
|
const agent = await safeCall(
|
|
554
576
|
() => client.query("agents:getByAgentId", { id }),
|
|
555
577
|
"Failed to fetch agent"
|
|
@@ -565,7 +587,7 @@ function registerAgentsCommand(program2) {
|
|
|
565
587
|
success(`Agent "${id}" deleted.`);
|
|
566
588
|
});
|
|
567
589
|
agents.command("enable").argument("<id>", "Agent ID").description("Enable an agent").action(async (id) => {
|
|
568
|
-
const client = createClient();
|
|
590
|
+
const client = await createClient();
|
|
569
591
|
const agent = await safeCall(() => client.query("agents:getByAgentId", { id }), "Failed to fetch agent");
|
|
570
592
|
if (!agent) {
|
|
571
593
|
error(`Agent "${id}" not found.`);
|
|
@@ -575,7 +597,7 @@ function registerAgentsCommand(program2) {
|
|
|
575
597
|
success(`Agent "${id}" enabled.`);
|
|
576
598
|
});
|
|
577
599
|
agents.command("disable").argument("<id>", "Agent ID").description("Disable an agent").action(async (id) => {
|
|
578
|
-
const client = createClient();
|
|
600
|
+
const client = await createClient();
|
|
579
601
|
const agent = await safeCall(() => client.query("agents:getByAgentId", { id }), "Failed to fetch agent");
|
|
580
602
|
if (!agent) {
|
|
581
603
|
error(`Agent "${id}" not found.`);
|
|
@@ -590,7 +612,7 @@ function registerAgentsCommand(program2) {
|
|
|
590
612
|
import readline2 from "readline";
|
|
591
613
|
function registerChatCommand(program2) {
|
|
592
614
|
program2.command("chat").argument("[agent-id]", "Agent ID to chat with").option("-s, --session <id>", "Resume an existing session").description("Start an interactive chat session with an agent").action(async (agentId, opts) => {
|
|
593
|
-
const client = createClient();
|
|
615
|
+
const client = await createClient();
|
|
594
616
|
if (!agentId && !opts.session) {
|
|
595
617
|
const agents = await safeCall(() => client.query("agents:list", {}), "Failed to list agents");
|
|
596
618
|
if (!agents || agents.length === 0) {
|
|
@@ -683,7 +705,7 @@ function registerChatCommand(program2) {
|
|
|
683
705
|
function registerSessionsCommand(program2) {
|
|
684
706
|
const sessions = program2.command("sessions").description("Manage sessions");
|
|
685
707
|
sessions.command("list").option("--status <status>", "Filter by status (active, ended)").option("--json", "Output as JSON").description("List all sessions").action(async (opts) => {
|
|
686
|
-
const client = createClient();
|
|
708
|
+
const client = await createClient();
|
|
687
709
|
const result = await safeCall(() => client.query("sessions:list", {}), "Failed to list sessions");
|
|
688
710
|
if (opts.json) {
|
|
689
711
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -706,7 +728,7 @@ function registerSessionsCommand(program2) {
|
|
|
706
728
|
})));
|
|
707
729
|
});
|
|
708
730
|
sessions.command("inspect").argument("<id>", "Session ID").description("Show session details").action(async (id) => {
|
|
709
|
-
const client = createClient();
|
|
731
|
+
const client = await createClient();
|
|
710
732
|
const session = await safeCall(() => client.query("sessions:getById", { id }), "Failed to fetch session");
|
|
711
733
|
if (!session) {
|
|
712
734
|
error(`Session "${id}" not found.`);
|
|
@@ -717,7 +739,7 @@ function registerSessionsCommand(program2) {
|
|
|
717
739
|
details({ ID: s._id, Name: s.name, Agent: s.agentId, Status: s.status, Started: formatDate(s.startedAt), "Last Activity": formatDate(s.lastActivityAt) });
|
|
718
740
|
});
|
|
719
741
|
sessions.command("end").argument("<id>", "Session ID").description("End an active session").action(async (id) => {
|
|
720
|
-
const client = createClient();
|
|
742
|
+
const client = await createClient();
|
|
721
743
|
await safeCall(() => client.mutation("sessions:update", { _id: id, status: "ended" }), "Failed to end session");
|
|
722
744
|
success(`Session "${id}" ended.`);
|
|
723
745
|
});
|
|
@@ -725,7 +747,7 @@ function registerSessionsCommand(program2) {
|
|
|
725
747
|
function registerThreadsCommand(program2) {
|
|
726
748
|
const threads = program2.command("threads").description("Manage conversation threads");
|
|
727
749
|
threads.command("list").option("--agent <id>", "Filter by agent ID").option("--json", "Output as JSON").description("List all threads").action(async (opts) => {
|
|
728
|
-
const client = createClient();
|
|
750
|
+
const client = await createClient();
|
|
729
751
|
const args = opts.agent ? { agentId: opts.agent } : {};
|
|
730
752
|
const result = await safeCall(() => client.query("threads:list", args), "Failed to list threads");
|
|
731
753
|
if (opts.json) {
|
|
@@ -747,7 +769,7 @@ function registerThreadsCommand(program2) {
|
|
|
747
769
|
})));
|
|
748
770
|
});
|
|
749
771
|
threads.command("inspect").argument("<id>", "Thread ID").description("Show thread messages").action(async (id) => {
|
|
750
|
-
const client = createClient();
|
|
772
|
+
const client = await createClient();
|
|
751
773
|
const messages = await safeCall(() => client.query("messages:listByThread", { threadId: id }), "Failed to fetch messages");
|
|
752
774
|
header(`Thread: ${id}`);
|
|
753
775
|
const items = messages || [];
|
|
@@ -762,7 +784,7 @@ function registerThreadsCommand(program2) {
|
|
|
762
784
|
console.log();
|
|
763
785
|
});
|
|
764
786
|
threads.command("delete").argument("<id>", "Thread ID").description("Delete a thread and its messages").action(async (id) => {
|
|
765
|
-
const client = createClient();
|
|
787
|
+
const client = await createClient();
|
|
766
788
|
await safeCall(() => client.mutation("threads:remove", { _id: id }), "Failed to delete thread");
|
|
767
789
|
success(`Thread "${id}" deleted.`);
|
|
768
790
|
});
|
|
@@ -782,7 +804,7 @@ function prompt2(q) {
|
|
|
782
804
|
function registerSkillsCommand(program2) {
|
|
783
805
|
const skills = program2.command("skills").description("Manage agent skills");
|
|
784
806
|
skills.command("list").option("--installed", "Show only installed skills").option("--json", "Output as JSON").description("List all skills").action(async (opts) => {
|
|
785
|
-
const client = createClient();
|
|
807
|
+
const client = await createClient();
|
|
786
808
|
const result = await safeCall(() => client.query("skills:list", {}), "Failed to list skills");
|
|
787
809
|
if (opts.json) {
|
|
788
810
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -894,7 +916,7 @@ Edit \`skills/${name}/config.json\` to customize.
|
|
|
894
916
|
info(`Edit skills/${name}/index.ts to implement your tool logic.`);
|
|
895
917
|
});
|
|
896
918
|
skills.command("install").argument("<name>", "Skill name to install").description("Install a skill").action(async (name) => {
|
|
897
|
-
const client = createClient();
|
|
919
|
+
const client = await createClient();
|
|
898
920
|
await safeCall(
|
|
899
921
|
() => client.mutation("skills:create", {
|
|
900
922
|
name,
|
|
@@ -915,7 +937,7 @@ Edit \`skills/${name}/config.json\` to customize.
|
|
|
915
937
|
success(`Skill "${name}" removed from disk.`);
|
|
916
938
|
}
|
|
917
939
|
}
|
|
918
|
-
const client = createClient();
|
|
940
|
+
const client = await createClient();
|
|
919
941
|
try {
|
|
920
942
|
const skills2 = await client.query("skills:list", {});
|
|
921
943
|
const skill = skills2.find((s) => s.name === name);
|
|
@@ -961,7 +983,7 @@ function prompt3(q) {
|
|
|
961
983
|
function registerCronCommand(program2) {
|
|
962
984
|
const cron = program2.command("cron").description("Manage cron jobs");
|
|
963
985
|
cron.command("list").option("--json", "Output as JSON").description("List all cron jobs").action(async (opts) => {
|
|
964
|
-
const client = createClient();
|
|
986
|
+
const client = await createClient();
|
|
965
987
|
const result = await safeCall(() => client.query("cronJobs:list", {}), "Failed to list cron jobs");
|
|
966
988
|
if (opts.json) {
|
|
967
989
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -992,7 +1014,7 @@ function registerCronCommand(program2) {
|
|
|
992
1014
|
error("All fields are required.");
|
|
993
1015
|
process.exit(1);
|
|
994
1016
|
}
|
|
995
|
-
const client = createClient();
|
|
1017
|
+
const client = await createClient();
|
|
996
1018
|
await safeCall(
|
|
997
1019
|
() => client.mutation("cronJobs:create", { name, schedule, agentId, action, isEnabled: true }),
|
|
998
1020
|
"Failed to create cron job"
|
|
@@ -1000,17 +1022,17 @@ function registerCronCommand(program2) {
|
|
|
1000
1022
|
success(`Cron job "${name}" created.`);
|
|
1001
1023
|
});
|
|
1002
1024
|
cron.command("delete").argument("<id>", "Cron job ID").description("Delete a cron job").action(async (id) => {
|
|
1003
|
-
const client = createClient();
|
|
1025
|
+
const client = await createClient();
|
|
1004
1026
|
await safeCall(() => client.mutation("cronJobs:remove", { _id: id }), "Failed to delete");
|
|
1005
1027
|
success(`Cron job "${id}" deleted.`);
|
|
1006
1028
|
});
|
|
1007
1029
|
cron.command("enable").argument("<id>", "Cron job ID").description("Enable a cron job").action(async (id) => {
|
|
1008
|
-
const client = createClient();
|
|
1030
|
+
const client = await createClient();
|
|
1009
1031
|
await safeCall(() => client.mutation("cronJobs:update", { _id: id, isEnabled: true }), "Failed");
|
|
1010
1032
|
success(`Cron job "${id}" enabled.`);
|
|
1011
1033
|
});
|
|
1012
1034
|
cron.command("disable").argument("<id>", "Cron job ID").description("Disable a cron job").action(async (id) => {
|
|
1013
|
-
const client = createClient();
|
|
1035
|
+
const client = await createClient();
|
|
1014
1036
|
await safeCall(() => client.mutation("cronJobs:update", { _id: id, isEnabled: false }), "Failed");
|
|
1015
1037
|
success(`Cron job "${id}" disabled.`);
|
|
1016
1038
|
});
|
|
@@ -1028,7 +1050,7 @@ function prompt4(q) {
|
|
|
1028
1050
|
function registerMcpCommand(program2) {
|
|
1029
1051
|
const mcp = program2.command("mcp").description("Manage MCP connections");
|
|
1030
1052
|
mcp.command("list").option("--json", "Output as JSON").description("List all MCP connections").action(async (opts) => {
|
|
1031
|
-
const client = createClient();
|
|
1053
|
+
const client = await createClient();
|
|
1032
1054
|
const result = await safeCall(() => client.query("mcpConnections:list", {}), "Failed to list connections");
|
|
1033
1055
|
if (opts.json) {
|
|
1034
1056
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1057,7 +1079,7 @@ function registerMcpCommand(program2) {
|
|
|
1057
1079
|
error("All fields required.");
|
|
1058
1080
|
process.exit(1);
|
|
1059
1081
|
}
|
|
1060
|
-
const client = createClient();
|
|
1082
|
+
const client = await createClient();
|
|
1061
1083
|
await safeCall(
|
|
1062
1084
|
() => client.mutation("mcpConnections:create", {
|
|
1063
1085
|
name,
|
|
@@ -1071,13 +1093,13 @@ function registerMcpCommand(program2) {
|
|
|
1071
1093
|
success(`MCP connection "${name}" added.`);
|
|
1072
1094
|
});
|
|
1073
1095
|
mcp.command("remove").argument("<id>", "Connection ID").description("Remove an MCP connection").action(async (id) => {
|
|
1074
|
-
const client = createClient();
|
|
1096
|
+
const client = await createClient();
|
|
1075
1097
|
await safeCall(() => client.mutation("mcpConnections:remove", { _id: id }), "Failed");
|
|
1076
1098
|
success(`Connection "${id}" removed.`);
|
|
1077
1099
|
});
|
|
1078
1100
|
mcp.command("test").argument("<id>", "Connection ID").description("Test an MCP connection").action(async (id) => {
|
|
1079
1101
|
info(`Testing connection "${id}"...`);
|
|
1080
|
-
const client = createClient();
|
|
1102
|
+
const client = await createClient();
|
|
1081
1103
|
const conns = await safeCall(() => client.query("mcpConnections:list", {}), "Failed");
|
|
1082
1104
|
const conn = conns.find((c) => c._id === id || c._id?.endsWith(id));
|
|
1083
1105
|
if (!conn) {
|
|
@@ -1102,12 +1124,12 @@ function registerMcpCommand(program2) {
|
|
|
1102
1124
|
}
|
|
1103
1125
|
});
|
|
1104
1126
|
mcp.command("enable").argument("<id>", "Connection ID").description("Enable a connection").action(async (id) => {
|
|
1105
|
-
const client = createClient();
|
|
1127
|
+
const client = await createClient();
|
|
1106
1128
|
await safeCall(() => client.mutation("mcpConnections:update", { _id: id, isEnabled: true }), "Failed");
|
|
1107
1129
|
success(`Connection "${id}" enabled.`);
|
|
1108
1130
|
});
|
|
1109
1131
|
mcp.command("disable").argument("<id>", "Connection ID").description("Disable a connection").action(async (id) => {
|
|
1110
|
-
const client = createClient();
|
|
1132
|
+
const client = await createClient();
|
|
1111
1133
|
await safeCall(() => client.mutation("mcpConnections:update", { _id: id, isEnabled: false }), "Failed");
|
|
1112
1134
|
success(`Connection "${id}" disabled.`);
|
|
1113
1135
|
});
|
|
@@ -1119,7 +1141,7 @@ import path6 from "path";
|
|
|
1119
1141
|
function registerFilesCommand(program2) {
|
|
1120
1142
|
const files = program2.command("files").description("Manage files");
|
|
1121
1143
|
files.command("list").argument("[folder]", "Folder ID to list files from").option("--json", "Output as JSON").description("List files").action(async (folder, opts) => {
|
|
1122
|
-
const client = createClient();
|
|
1144
|
+
const client = await createClient();
|
|
1123
1145
|
const args = folder ? { folderId: folder } : {};
|
|
1124
1146
|
const result = await safeCall(() => client.query("files:list", args), "Failed to list files");
|
|
1125
1147
|
if (opts.json) {
|
|
@@ -1165,7 +1187,7 @@ function registerFilesCommand(program2) {
|
|
|
1165
1187
|
".xml": "text/xml"
|
|
1166
1188
|
};
|
|
1167
1189
|
const mimeType = mimeTypes[ext] || "application/octet-stream";
|
|
1168
|
-
const client = createClient();
|
|
1190
|
+
const client = await createClient();
|
|
1169
1191
|
await safeCall(
|
|
1170
1192
|
() => client.mutation("files:create", {
|
|
1171
1193
|
name,
|
|
@@ -1180,13 +1202,13 @@ function registerFilesCommand(program2) {
|
|
|
1180
1202
|
info("Note: File content storage requires Convex file storage or R2 integration.");
|
|
1181
1203
|
});
|
|
1182
1204
|
files.command("delete").argument("<id>", "File ID").description("Delete a file").action(async (id) => {
|
|
1183
|
-
const client = createClient();
|
|
1205
|
+
const client = await createClient();
|
|
1184
1206
|
await safeCall(() => client.mutation("files:remove", { _id: id }), "Failed to delete file");
|
|
1185
1207
|
success(`File "${id}" deleted.`);
|
|
1186
1208
|
});
|
|
1187
1209
|
const folders = program2.command("folders").description("Manage folders");
|
|
1188
1210
|
folders.command("list").option("--json", "Output as JSON").description("List all folders").action(async (opts) => {
|
|
1189
|
-
const client = createClient();
|
|
1211
|
+
const client = await createClient();
|
|
1190
1212
|
const result = await safeCall(() => client.query("folders:list", {}), "Failed to list folders");
|
|
1191
1213
|
if (opts.json) {
|
|
1192
1214
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1206,7 +1228,7 @@ function registerFilesCommand(program2) {
|
|
|
1206
1228
|
})));
|
|
1207
1229
|
});
|
|
1208
1230
|
folders.command("create").argument("<name>", "Folder name").option("--parent <id>", "Parent folder ID").description("Create a folder").action(async (name, opts) => {
|
|
1209
|
-
const client = createClient();
|
|
1231
|
+
const client = await createClient();
|
|
1210
1232
|
await safeCall(
|
|
1211
1233
|
() => client.mutation("folders:create", { name, parentId: opts.parent }),
|
|
1212
1234
|
"Failed to create folder"
|
|
@@ -1214,7 +1236,7 @@ function registerFilesCommand(program2) {
|
|
|
1214
1236
|
success(`Folder "${name}" created.`);
|
|
1215
1237
|
});
|
|
1216
1238
|
folders.command("delete").argument("<id>", "Folder ID").description("Delete a folder").action(async (id) => {
|
|
1217
|
-
const client = createClient();
|
|
1239
|
+
const client = await createClient();
|
|
1218
1240
|
await safeCall(() => client.mutation("folders:remove", { _id: id }), "Failed to delete folder");
|
|
1219
1241
|
success(`Folder "${id}" deleted.`);
|
|
1220
1242
|
});
|
|
@@ -1237,7 +1259,7 @@ function prompt5(q) {
|
|
|
1237
1259
|
function registerProjectsCommand(program2) {
|
|
1238
1260
|
const projects = program2.command("projects").description("Manage projects and workspaces");
|
|
1239
1261
|
projects.command("list").option("--json", "Output as JSON").description("List all projects").action(async (opts) => {
|
|
1240
|
-
const client = createClient();
|
|
1262
|
+
const client = await createClient();
|
|
1241
1263
|
const result = await safeCall(() => client.query("projects:list", {}), "Failed to list projects");
|
|
1242
1264
|
if (opts.json) {
|
|
1243
1265
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1259,7 +1281,7 @@ function registerProjectsCommand(program2) {
|
|
|
1259
1281
|
});
|
|
1260
1282
|
projects.command("create").argument("<name>", "Project name").option("-d, --description <desc>", "Project description").description("Create a new project").action(async (name, opts) => {
|
|
1261
1283
|
const description = opts.description || await prompt5("Description (optional): ");
|
|
1262
|
-
const client = createClient();
|
|
1284
|
+
const client = await createClient();
|
|
1263
1285
|
await safeCall(
|
|
1264
1286
|
() => client.mutation("projects:create", { name, description, status: "active" }),
|
|
1265
1287
|
"Failed to create project"
|
|
@@ -1267,7 +1289,7 @@ function registerProjectsCommand(program2) {
|
|
|
1267
1289
|
success(`Project "${name}" created.`);
|
|
1268
1290
|
});
|
|
1269
1291
|
projects.command("inspect").argument("<id>", "Project ID").description("Show project details").action(async (id) => {
|
|
1270
|
-
const client = createClient();
|
|
1292
|
+
const client = await createClient();
|
|
1271
1293
|
const projects2 = await safeCall(() => client.query("projects:list", {}), "Failed");
|
|
1272
1294
|
const project = projects2.find((p) => p._id === id || p._id?.endsWith(id));
|
|
1273
1295
|
if (!project) {
|
|
@@ -1292,12 +1314,12 @@ function registerProjectsCommand(program2) {
|
|
|
1292
1314
|
return;
|
|
1293
1315
|
}
|
|
1294
1316
|
}
|
|
1295
|
-
const client = createClient();
|
|
1317
|
+
const client = await createClient();
|
|
1296
1318
|
await safeCall(() => client.mutation("projects:remove", { _id: id }), "Failed");
|
|
1297
1319
|
success(`Project "${id}" deleted.`);
|
|
1298
1320
|
});
|
|
1299
1321
|
projects.command("switch").argument("<id>", "Project ID to switch to").description("Set the active project").action(async (id) => {
|
|
1300
|
-
const client = createClient();
|
|
1322
|
+
const client = await createClient();
|
|
1301
1323
|
const projects2 = await safeCall(() => client.query("projects:list", {}), "Failed");
|
|
1302
1324
|
const project = projects2.find((p) => p._id === id || p._id?.endsWith(id));
|
|
1303
1325
|
if (!project) {
|
|
@@ -1494,7 +1516,7 @@ function promptSecret(q) {
|
|
|
1494
1516
|
function registerVaultCommand(program2) {
|
|
1495
1517
|
const vault = program2.command("vault").description("Manage secrets securely");
|
|
1496
1518
|
vault.command("list").option("--json", "Output as JSON").description("List all stored secrets (values hidden)").action(async (opts) => {
|
|
1497
|
-
const client = createClient();
|
|
1519
|
+
const client = await createClient();
|
|
1498
1520
|
const result = await safeCall(() => client.query("vault:list", {}), "Failed to list secrets");
|
|
1499
1521
|
if (opts.json) {
|
|
1500
1522
|
const safe = (result || []).map((s) => ({ ...s, encryptedValue: void 0 }));
|
|
@@ -1523,7 +1545,7 @@ function registerVaultCommand(program2) {
|
|
|
1523
1545
|
error("Value is required.");
|
|
1524
1546
|
process.exit(1);
|
|
1525
1547
|
}
|
|
1526
|
-
const client = createClient();
|
|
1548
|
+
const client = await createClient();
|
|
1527
1549
|
await safeCall(
|
|
1528
1550
|
() => client.mutation("vault:store", {
|
|
1529
1551
|
name,
|
|
@@ -1536,7 +1558,7 @@ function registerVaultCommand(program2) {
|
|
|
1536
1558
|
success(`Secret "${name}" stored securely.`);
|
|
1537
1559
|
});
|
|
1538
1560
|
vault.command("get").argument("<name>", "Secret name").option("--reveal", "Show the actual value (use with caution)").description("Retrieve a secret").action(async (name, opts) => {
|
|
1539
|
-
const client = createClient();
|
|
1561
|
+
const client = await createClient();
|
|
1540
1562
|
const result = await safeCall(() => client.query("vault:list", {}), "Failed");
|
|
1541
1563
|
const secret = (result || []).find((s) => s.name === name);
|
|
1542
1564
|
if (!secret) {
|
|
@@ -1563,7 +1585,7 @@ function registerVaultCommand(program2) {
|
|
|
1563
1585
|
return;
|
|
1564
1586
|
}
|
|
1565
1587
|
}
|
|
1566
|
-
const client = createClient();
|
|
1588
|
+
const client = await createClient();
|
|
1567
1589
|
const result = await safeCall(() => client.query("vault:list", {}), "Failed");
|
|
1568
1590
|
const secret = (result || []).find((s) => s.name === name);
|
|
1569
1591
|
if (!secret) {
|
|
@@ -1574,7 +1596,7 @@ function registerVaultCommand(program2) {
|
|
|
1574
1596
|
success(`Secret "${name}" deleted.`);
|
|
1575
1597
|
});
|
|
1576
1598
|
vault.command("rotate").argument("<name>", "Secret name").description("Rotate a secret (set a new value)").action(async (name) => {
|
|
1577
|
-
const client = createClient();
|
|
1599
|
+
const client = await createClient();
|
|
1578
1600
|
const result = await safeCall(() => client.query("vault:list", {}), "Failed");
|
|
1579
1601
|
const secret = (result || []).find((s) => s.name === name);
|
|
1580
1602
|
if (!secret) {
|
|
@@ -1594,6 +1616,212 @@ function registerVaultCommand(program2) {
|
|
|
1594
1616
|
});
|
|
1595
1617
|
}
|
|
1596
1618
|
|
|
1619
|
+
// src/commands/keys.ts
|
|
1620
|
+
function safeCall2(fn, msg) {
|
|
1621
|
+
return fn().catch((e) => {
|
|
1622
|
+
error(`${msg}: ${e.message}`);
|
|
1623
|
+
process.exit(1);
|
|
1624
|
+
});
|
|
1625
|
+
}
|
|
1626
|
+
function formatDate4(ts) {
|
|
1627
|
+
return new Date(ts).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
|
|
1628
|
+
}
|
|
1629
|
+
function maskKey(key) {
|
|
1630
|
+
if (key.length <= 12) return key.substring(0, 4) + "****";
|
|
1631
|
+
return key.substring(0, 8) + "..." + key.substring(key.length - 4);
|
|
1632
|
+
}
|
|
1633
|
+
function promptSecret2(question) {
|
|
1634
|
+
return new Promise((resolve2) => {
|
|
1635
|
+
const readline10 = __require("readline");
|
|
1636
|
+
if (process.stdin.isTTY) {
|
|
1637
|
+
process.stdout.write(question);
|
|
1638
|
+
process.stdin.setRawMode(true);
|
|
1639
|
+
process.stdin.resume();
|
|
1640
|
+
process.stdin.setEncoding("utf8");
|
|
1641
|
+
let input = "";
|
|
1642
|
+
const onData = (char) => {
|
|
1643
|
+
if (char === "\n" || char === "\r" || char === "") {
|
|
1644
|
+
process.stdin.setRawMode(false);
|
|
1645
|
+
process.stdin.pause();
|
|
1646
|
+
process.stdin.removeListener("data", onData);
|
|
1647
|
+
process.stdout.write("\n");
|
|
1648
|
+
resolve2(input);
|
|
1649
|
+
} else if (char === "") {
|
|
1650
|
+
process.exit(0);
|
|
1651
|
+
} else if (char === "\x7F" || char === "\b") {
|
|
1652
|
+
if (input.length > 0) {
|
|
1653
|
+
input = input.slice(0, -1);
|
|
1654
|
+
process.stdout.write("\b \b");
|
|
1655
|
+
}
|
|
1656
|
+
} else {
|
|
1657
|
+
input += char;
|
|
1658
|
+
process.stdout.write("*");
|
|
1659
|
+
}
|
|
1660
|
+
};
|
|
1661
|
+
process.stdin.on("data", onData);
|
|
1662
|
+
} else {
|
|
1663
|
+
const rl = readline10.createInterface({ input: process.stdin, output: process.stdout });
|
|
1664
|
+
rl.question(question, (ans) => {
|
|
1665
|
+
rl.close();
|
|
1666
|
+
resolve2(ans.trim());
|
|
1667
|
+
});
|
|
1668
|
+
}
|
|
1669
|
+
});
|
|
1670
|
+
}
|
|
1671
|
+
var PROVIDERS = [
|
|
1672
|
+
{ id: "openai", name: "OpenAI", prefix: "sk-" },
|
|
1673
|
+
{ id: "anthropic", name: "Anthropic", prefix: "sk-ant-" },
|
|
1674
|
+
{ id: "openrouter", name: "OpenRouter", prefix: "sk-or-" },
|
|
1675
|
+
{ id: "google", name: "Google AI", prefix: "AIza" },
|
|
1676
|
+
{ id: "xai", name: "xAI", prefix: "xai-" },
|
|
1677
|
+
{ id: "groq", name: "Groq", prefix: "gsk_" },
|
|
1678
|
+
{ id: "together", name: "Together AI", prefix: "" },
|
|
1679
|
+
{ id: "perplexity", name: "Perplexity", prefix: "pplx-" }
|
|
1680
|
+
];
|
|
1681
|
+
function registerKeysCommand(program2) {
|
|
1682
|
+
const keys = program2.command("keys").description("Manage AI provider API keys");
|
|
1683
|
+
keys.command("list").option("--provider <provider>", "Filter by provider").option("--json", "Output as JSON").description("List all configured API keys").action(async (opts) => {
|
|
1684
|
+
const client = await createClient();
|
|
1685
|
+
const result = await safeCall2(
|
|
1686
|
+
() => client.query("apiKeys:list", opts.provider ? { provider: opts.provider } : {}),
|
|
1687
|
+
"Failed to list API keys"
|
|
1688
|
+
);
|
|
1689
|
+
const items = result || [];
|
|
1690
|
+
if (opts.json) {
|
|
1691
|
+
const safe = items.map((k) => ({ ...k, encryptedKey: maskKey(k.encryptedKey) }));
|
|
1692
|
+
console.log(JSON.stringify(safe, null, 2));
|
|
1693
|
+
return;
|
|
1694
|
+
}
|
|
1695
|
+
header("API Keys");
|
|
1696
|
+
if (items.length === 0) {
|
|
1697
|
+
info("No API keys configured.");
|
|
1698
|
+
dim(" Add one with: agentforge keys add <provider> [key]");
|
|
1699
|
+
dim("");
|
|
1700
|
+
dim(" Supported providers:");
|
|
1701
|
+
PROVIDERS.forEach((p) => dim(` ${p.id.padEnd(12)} ${p.name}`));
|
|
1702
|
+
return;
|
|
1703
|
+
}
|
|
1704
|
+
table(items.map((k) => ({
|
|
1705
|
+
Provider: k.provider,
|
|
1706
|
+
Name: k.keyName,
|
|
1707
|
+
Key: maskKey(k.encryptedKey),
|
|
1708
|
+
Active: k.isActive ? "\u2713" : "\u2717",
|
|
1709
|
+
Created: formatDate4(k.createdAt),
|
|
1710
|
+
"Last Used": k.lastUsedAt ? formatDate4(k.lastUsedAt) : "Never"
|
|
1711
|
+
})));
|
|
1712
|
+
});
|
|
1713
|
+
keys.command("add").argument("<provider>", `Provider (${PROVIDERS.map((p) => p.id).join(", ")})`).argument("[key]", "API key value (omit for secure prompt)").option("--name <name>", "Key display name").description("Add an AI provider API key").action(async (provider, key, opts) => {
|
|
1714
|
+
const providerInfo = PROVIDERS.find((p) => p.id === provider);
|
|
1715
|
+
if (!providerInfo) {
|
|
1716
|
+
error(`Unknown provider "${provider}". Supported: ${PROVIDERS.map((p) => p.id).join(", ")}`);
|
|
1717
|
+
process.exit(1);
|
|
1718
|
+
}
|
|
1719
|
+
if (!key) {
|
|
1720
|
+
key = await promptSecret2(`Enter ${providerInfo.name} API key: `);
|
|
1721
|
+
}
|
|
1722
|
+
if (!key) {
|
|
1723
|
+
error("API key is required.");
|
|
1724
|
+
process.exit(1);
|
|
1725
|
+
}
|
|
1726
|
+
if (providerInfo.prefix && !key.startsWith(providerInfo.prefix)) {
|
|
1727
|
+
info(`Warning: ${providerInfo.name} keys typically start with "${providerInfo.prefix}".`);
|
|
1728
|
+
}
|
|
1729
|
+
const keyName = opts.name || `${providerInfo.name} Key`;
|
|
1730
|
+
const client = await createClient();
|
|
1731
|
+
await safeCall2(
|
|
1732
|
+
() => client.mutation("apiKeys:create", {
|
|
1733
|
+
provider,
|
|
1734
|
+
keyName,
|
|
1735
|
+
encryptedKey: key
|
|
1736
|
+
}),
|
|
1737
|
+
"Failed to store API key"
|
|
1738
|
+
);
|
|
1739
|
+
success(`${providerInfo.name} API key "${keyName}" stored successfully.`);
|
|
1740
|
+
});
|
|
1741
|
+
keys.command("remove").argument("<provider>", "Provider name").option("-f, --force", "Skip confirmation").description("Remove an API key").action(async (provider, opts) => {
|
|
1742
|
+
const client = await createClient();
|
|
1743
|
+
const result = await safeCall2(
|
|
1744
|
+
() => client.query("apiKeys:list", { provider }),
|
|
1745
|
+
"Failed to list keys"
|
|
1746
|
+
);
|
|
1747
|
+
const items = result || [];
|
|
1748
|
+
if (items.length === 0) {
|
|
1749
|
+
error(`No API keys found for "${provider}".`);
|
|
1750
|
+
process.exit(1);
|
|
1751
|
+
}
|
|
1752
|
+
const target = items[0];
|
|
1753
|
+
if (!opts.force) {
|
|
1754
|
+
const readline10 = __require("readline");
|
|
1755
|
+
const rl = readline10.createInterface({ input: process.stdin, output: process.stdout });
|
|
1756
|
+
const answer = await new Promise((resolve2) => {
|
|
1757
|
+
rl.question(`Delete "${target.keyName}" for ${provider}? (y/N): `, (ans) => {
|
|
1758
|
+
rl.close();
|
|
1759
|
+
resolve2(ans.trim());
|
|
1760
|
+
});
|
|
1761
|
+
});
|
|
1762
|
+
if (answer.toLowerCase() !== "y") {
|
|
1763
|
+
info("Cancelled.");
|
|
1764
|
+
return;
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
await safeCall2(
|
|
1768
|
+
() => client.mutation("apiKeys:remove", { id: target._id }),
|
|
1769
|
+
"Failed to remove API key"
|
|
1770
|
+
);
|
|
1771
|
+
success(`API key "${target.keyName}" removed.`);
|
|
1772
|
+
});
|
|
1773
|
+
keys.command("test").argument("<provider>", "Provider to test").description("Test an API key by making a simple request").action(async (provider) => {
|
|
1774
|
+
const client = await createClient();
|
|
1775
|
+
const result = await safeCall2(
|
|
1776
|
+
() => client.query("apiKeys:getActiveForProvider", { provider }),
|
|
1777
|
+
"Failed to get key"
|
|
1778
|
+
);
|
|
1779
|
+
if (!result) {
|
|
1780
|
+
error(`No active API key for "${provider}". Add one with: agentforge keys add ${provider}`);
|
|
1781
|
+
process.exit(1);
|
|
1782
|
+
}
|
|
1783
|
+
const key = result.encryptedKey;
|
|
1784
|
+
info(`Testing ${provider} API key...`);
|
|
1785
|
+
try {
|
|
1786
|
+
let ok = false;
|
|
1787
|
+
if (provider === "openai") {
|
|
1788
|
+
const res = await fetch("https://api.openai.com/v1/models", { headers: { Authorization: `Bearer ${key}` } });
|
|
1789
|
+
ok = res.ok;
|
|
1790
|
+
} else if (provider === "anthropic") {
|
|
1791
|
+
const res = await fetch("https://api.anthropic.com/v1/messages", {
|
|
1792
|
+
method: "POST",
|
|
1793
|
+
headers: { "x-api-key": key, "anthropic-version": "2023-06-01", "Content-Type": "application/json" },
|
|
1794
|
+
body: JSON.stringify({ model: "claude-3-haiku-20240307", max_tokens: 1, messages: [{ role: "user", content: "hi" }] })
|
|
1795
|
+
});
|
|
1796
|
+
ok = res.ok;
|
|
1797
|
+
} else if (provider === "openrouter") {
|
|
1798
|
+
const res = await fetch("https://openrouter.ai/api/v1/models", { headers: { Authorization: `Bearer ${key}` } });
|
|
1799
|
+
ok = res.ok;
|
|
1800
|
+
} else if (provider === "google") {
|
|
1801
|
+
const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${key}`);
|
|
1802
|
+
ok = res.ok;
|
|
1803
|
+
} else if (provider === "groq") {
|
|
1804
|
+
const res = await fetch("https://api.groq.com/openai/v1/models", { headers: { Authorization: `Bearer ${key}` } });
|
|
1805
|
+
ok = res.ok;
|
|
1806
|
+
} else {
|
|
1807
|
+
info(`No test endpoint configured for "${provider}". Key is stored.`);
|
|
1808
|
+
return;
|
|
1809
|
+
}
|
|
1810
|
+
if (ok) {
|
|
1811
|
+
success(`${provider} API key is valid and working.`);
|
|
1812
|
+
await safeCall2(
|
|
1813
|
+
() => client.mutation("apiKeys:updateLastUsed", { id: result._id }),
|
|
1814
|
+
"Failed to update last used"
|
|
1815
|
+
);
|
|
1816
|
+
} else {
|
|
1817
|
+
error(`${provider} API key returned an error. Check that the key is valid.`);
|
|
1818
|
+
}
|
|
1819
|
+
} catch (e) {
|
|
1820
|
+
error(`Connection failed: ${e.message}`);
|
|
1821
|
+
}
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1597
1825
|
// src/commands/status.ts
|
|
1598
1826
|
import { spawn as spawn2 } from "child_process";
|
|
1599
1827
|
import path8 from "path";
|
|
@@ -1610,7 +1838,7 @@ function registerStatusCommand(program2) {
|
|
|
1610
1838
|
checks["Dashboard Dir"] = fs8.existsSync(path8.join(cwd, "dashboard")) ? "\u2714 Found" : "\u2716 Not found";
|
|
1611
1839
|
checks["Env Config"] = fs8.existsSync(path8.join(cwd, ".env.local")) || fs8.existsSync(path8.join(cwd, ".env")) ? "\u2714 Found" : "\u2716 Not found";
|
|
1612
1840
|
try {
|
|
1613
|
-
const client = createClient();
|
|
1841
|
+
const client = await createClient();
|
|
1614
1842
|
const agents = await client.query("agents:list", {});
|
|
1615
1843
|
checks["Convex Connection"] = `\u2714 Connected (${agents?.length || 0} agents)`;
|
|
1616
1844
|
} catch {
|
|
@@ -1720,7 +1948,7 @@ function registerStatusCommand(program2) {
|
|
|
1720
1948
|
});
|
|
1721
1949
|
});
|
|
1722
1950
|
program2.command("logs").description("Show recent activity logs").option("-n, --lines <count>", "Number of log entries", "20").option("--agent <id>", "Filter by agent ID").option("--json", "Output as JSON").action(async (opts) => {
|
|
1723
|
-
const client = createClient();
|
|
1951
|
+
const client = await createClient();
|
|
1724
1952
|
const args = {};
|
|
1725
1953
|
if (opts.agent) args.agentId = opts.agent;
|
|
1726
1954
|
const result = await safeCall(
|
|
@@ -1747,7 +1975,7 @@ function registerStatusCommand(program2) {
|
|
|
1747
1975
|
console.log();
|
|
1748
1976
|
});
|
|
1749
1977
|
program2.command("heartbeat").description("Check and resume pending agent tasks").option("--agent <id>", "Check specific agent").action(async (opts) => {
|
|
1750
|
-
const client = createClient();
|
|
1978
|
+
const client = await createClient();
|
|
1751
1979
|
header("Heartbeat Check");
|
|
1752
1980
|
const args = {};
|
|
1753
1981
|
if (opts.agent) args.agentId = opts.agent;
|
|
@@ -1813,6 +2041,7 @@ registerFilesCommand(program);
|
|
|
1813
2041
|
registerProjectsCommand(program);
|
|
1814
2042
|
registerConfigCommand(program);
|
|
1815
2043
|
registerVaultCommand(program);
|
|
2044
|
+
registerKeysCommand(program);
|
|
1816
2045
|
registerStatusCommand(program);
|
|
1817
2046
|
program.parse();
|
|
1818
2047
|
//# sourceMappingURL=index.js.map
|