@chanl-ai/cli 2.0.1

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.
Files changed (77) hide show
  1. package/bin/chanl.js +10 -0
  2. package/dist/__tests__/cli.test.d.ts +2 -0
  3. package/dist/__tests__/cli.test.js +2313 -0
  4. package/dist/__tests__/cli.test.js.map +1 -0
  5. package/dist/cli.d.ts +12 -0
  6. package/dist/cli.js +72 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/agents.d.ts +8 -0
  9. package/dist/commands/agents.js +671 -0
  10. package/dist/commands/agents.js.map +1 -0
  11. package/dist/commands/auth.d.ts +16 -0
  12. package/dist/commands/auth.js +294 -0
  13. package/dist/commands/auth.js.map +1 -0
  14. package/dist/commands/call.d.ts +8 -0
  15. package/dist/commands/call.js +166 -0
  16. package/dist/commands/call.js.map +1 -0
  17. package/dist/commands/calls.d.ts +8 -0
  18. package/dist/commands/calls.js +719 -0
  19. package/dist/commands/calls.js.map +1 -0
  20. package/dist/commands/chat.d.ts +8 -0
  21. package/dist/commands/chat.js +203 -0
  22. package/dist/commands/chat.js.map +1 -0
  23. package/dist/commands/config.d.ts +8 -0
  24. package/dist/commands/config.js +231 -0
  25. package/dist/commands/config.js.map +1 -0
  26. package/dist/commands/health.d.ts +8 -0
  27. package/dist/commands/health.js +55 -0
  28. package/dist/commands/health.js.map +1 -0
  29. package/dist/commands/index.d.ts +18 -0
  30. package/dist/commands/index.js +39 -0
  31. package/dist/commands/index.js.map +1 -0
  32. package/dist/commands/knowledge.d.ts +8 -0
  33. package/dist/commands/knowledge.js +539 -0
  34. package/dist/commands/knowledge.js.map +1 -0
  35. package/dist/commands/mcp.d.ts +8 -0
  36. package/dist/commands/mcp.js +589 -0
  37. package/dist/commands/mcp.js.map +1 -0
  38. package/dist/commands/memory.d.ts +8 -0
  39. package/dist/commands/memory.js +408 -0
  40. package/dist/commands/memory.js.map +1 -0
  41. package/dist/commands/personas.d.ts +8 -0
  42. package/dist/commands/personas.js +356 -0
  43. package/dist/commands/personas.js.map +1 -0
  44. package/dist/commands/prompts.d.ts +8 -0
  45. package/dist/commands/prompts.js +295 -0
  46. package/dist/commands/prompts.js.map +1 -0
  47. package/dist/commands/scenarios.d.ts +8 -0
  48. package/dist/commands/scenarios.js +591 -0
  49. package/dist/commands/scenarios.js.map +1 -0
  50. package/dist/commands/scorecards.d.ts +8 -0
  51. package/dist/commands/scorecards.js +570 -0
  52. package/dist/commands/scorecards.js.map +1 -0
  53. package/dist/commands/tools.d.ts +8 -0
  54. package/dist/commands/tools.js +632 -0
  55. package/dist/commands/tools.js.map +1 -0
  56. package/dist/commands/toolsets.d.ts +8 -0
  57. package/dist/commands/toolsets.js +464 -0
  58. package/dist/commands/toolsets.js.map +1 -0
  59. package/dist/commands/workspaces.d.ts +8 -0
  60. package/dist/commands/workspaces.js +170 -0
  61. package/dist/commands/workspaces.js.map +1 -0
  62. package/dist/index.d.ts +2 -0
  63. package/dist/index.js +6 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/utils/config-store.d.ts +117 -0
  66. package/dist/utils/config-store.js +191 -0
  67. package/dist/utils/config-store.js.map +1 -0
  68. package/dist/utils/interactive.d.ts +41 -0
  69. package/dist/utils/interactive.js +83 -0
  70. package/dist/utils/interactive.js.map +1 -0
  71. package/dist/utils/output.d.ts +100 -0
  72. package/dist/utils/output.js +221 -0
  73. package/dist/utils/output.js.map +1 -0
  74. package/dist/utils/sdk-factory.d.ts +15 -0
  75. package/dist/utils/sdk-factory.js +34 -0
  76. package/dist/utils/sdk-factory.js.map +1 -0
  77. package/package.json +67 -0
@@ -0,0 +1,671 @@
1
+ import { Command } from "commander";
2
+ import ora from "ora";
3
+ import chalk from "chalk";
4
+ import { readFileSync } from "fs";
5
+ import { createSdk } from "../utils/sdk-factory.js";
6
+ import {
7
+ printError,
8
+ printSuccess,
9
+ printInfo,
10
+ printBlank,
11
+ printSimpleTable,
12
+ printLabel,
13
+ isJsonOutput,
14
+ printJson,
15
+ formatDate
16
+ } from "../utils/output.js";
17
+ function createAgentsCommand() {
18
+ const agents = new Command("agents").description("Manage AI agents (VAPI, ElevenLabs, custom)").addHelpText(
19
+ "after",
20
+ `
21
+ What are Agents?
22
+ Agents are AI-powered voice assistants from various platforms (VAPI, ElevenLabs)
23
+ or custom implementations. They can be tested with scenarios and analyzed with
24
+ scorecards.
25
+
26
+ Quick Start:
27
+ $ chanl agents list # List all agents
28
+ $ chanl agents get <id> # View agent details
29
+ $ chanl agents sync vapi # Sync from VAPI
30
+ $ chanl agents create --template vapi # Generate VAPI template
31
+ $ chanl agents stats # View statistics
32
+
33
+ Workflow:
34
+ 1. Sync agents from your platform (vapi, elevenlabs)
35
+ 2. Or create custom agents with 'create -f agent.json'
36
+ 3. Test agents with 'chanl scenarios run <id> --agent <agentId>'
37
+ 4. Analyze results with 'chanl calls analysis <id>'`
38
+ );
39
+ agents.command("list").description("List all agents").option("-p, --platform <platform>", "Filter by platform (vapi, elevenlabs, custom)").option("-s, --status <status>", "Filter by status (active, inactive)").option("-l, --limit <number>", "Number of items per page", "20").option("--page <number>", "Page number", "1").addHelpText(
40
+ "after",
41
+ `
42
+ Examples:
43
+ $ chanl agents list # List all agents
44
+ $ chanl agents list --platform vapi # Filter by platform
45
+ $ chanl agents list --status active # Only active agents
46
+ $ chanl agents list --json # Output as JSON`
47
+ ).action(handleAgentsList);
48
+ agents.command("get <id>").description("Get agent details").addHelpText(
49
+ "after",
50
+ `
51
+ Examples:
52
+ $ chanl agents get abc123 # Get agent details
53
+ $ chanl agents get abc123 --json # Output as JSON`
54
+ ).action(handleAgentsGet);
55
+ agents.command("create").description("Create a new agent").option("-f, --file <path>", "Path to JSON file with agent data").option("--template [platform]", "Output a template JSON (vapi, elevenlabs, custom)").addHelpText(
56
+ "after",
57
+ `
58
+ Examples:
59
+ $ chanl agents create --template vapi > agent.json # VAPI template
60
+ $ chanl agents create --template custom > agent.json # Custom template
61
+ $ chanl agents create -f agent.json # Create from file
62
+
63
+ Templates include platform-specific configurations and examples.`
64
+ ).action(handleAgentsCreate);
65
+ agents.command("update <id>").description("Update an existing agent").option("-f, --file <path>", "Path to JSON file with update data").option("--sync-to-vapi", "Sync changes back to VAPI platform").addHelpText(
66
+ "after",
67
+ `
68
+ Examples:
69
+ $ chanl agents update abc123 -f updates.json
70
+ $ chanl agents update abc123 -f updates.json --sync-to-vapi`
71
+ ).action(handleAgentsUpdate);
72
+ agents.command("delete <id>").description("Delete an agent").option("-y, --yes", "Skip confirmation prompt").option("--delete-from-integration", "Also delete from platform (VAPI, etc.)").addHelpText(
73
+ "after",
74
+ `
75
+ Examples:
76
+ $ chanl agents delete abc123
77
+ $ chanl agents delete abc123 --delete-from-integration`
78
+ ).action(handleAgentsDelete);
79
+ agents.command("sync <platform>").description("Sync agents from a platform (vapi, bland, twilio)").option("-f, --force", "Force update existing agents").option("--clean", "Delete all existing agents for this platform before sync").addHelpText(
80
+ "after",
81
+ `
82
+ Examples:
83
+ $ chanl agents sync vapi # Sync from VAPI
84
+ $ chanl agents sync vapi --force # Force update all
85
+ $ chanl agents sync vapi --clean # Clean sync (delete first)`
86
+ ).action(handleAgentsSync);
87
+ agents.command("sync-all").description("Sync agents from all configured platforms").option("-f, --force", "Force update existing agents").addHelpText(
88
+ "after",
89
+ `
90
+ Examples:
91
+ $ chanl agents sync-all # Sync from all platforms
92
+ $ chanl agents sync-all --force # Force update all`
93
+ ).action(handleAgentsSyncAll);
94
+ agents.command("import").description("Import a specific agent from a third-party platform").requiredOption("--from <platform>", "Source platform (vapi, retell, bland)").requiredOption("--agent-id <id>", "External agent ID on the source platform").option("-n, --name <name>", "Override the agent name").addHelpText(
95
+ "after",
96
+ `
97
+ Examples:
98
+ $ chanl agents import --from vapi --agent-id asst_abc123
99
+ $ chanl agents import --from retell --agent-id ret_xyz --name "My Agent"
100
+ $ chanl agents import --from vapi --agent-id asst_abc --json`
101
+ ).action(handleAgentsImport);
102
+ agents.command("publish <agent-id>").description("Publish an agent to a third-party platform").requiredOption("--to <platform>", "Target platform (vapi, retell, bland)").option("--target <ext-id>", "External agent ID to update (omit to create new)").option("--with-mcp", "Include MCP URL for tool access").addHelpText(
103
+ "after",
104
+ `
105
+ Examples:
106
+ $ chanl agents publish agent_123 --to vapi
107
+ $ chanl agents publish agent_123 --to vapi --with-mcp
108
+ $ chanl agents publish agent_123 --to vapi --target ext_456
109
+ $ chanl agents publish agent_123 --to vapi --json`
110
+ ).action(handleAgentsPublish);
111
+ agents.command("push-mcp <agent-id>").description("Push MCP URL to a third-party agent for tool access").requiredOption("--to <platform>", "Target platform (vapi, retell, bland)").option("--target <ext-id>", "External agent ID (omit to use default)").addHelpText(
112
+ "after",
113
+ `
114
+ Examples:
115
+ $ chanl agents push-mcp agent_123 --to vapi
116
+ $ chanl agents push-mcp agent_123 --to vapi --target ext_456
117
+ $ chanl agents push-mcp agent_123 --to vapi --json`
118
+ ).action(handleAgentsPushMcp);
119
+ agents.command("stats").description("View agent statistics").addHelpText(
120
+ "after",
121
+ `
122
+ Examples:
123
+ $ chanl agents stats # View statistics
124
+ $ chanl agents stats --json # Output as JSON`
125
+ ).action(handleAgentsStats);
126
+ return agents;
127
+ }
128
+ function formatStatus(status) {
129
+ switch (status) {
130
+ case "active":
131
+ return chalk.green("active");
132
+ case "inactive":
133
+ return chalk.gray("inactive");
134
+ case "error":
135
+ return chalk.red("error");
136
+ case "training":
137
+ return chalk.cyan("training");
138
+ case "maintenance":
139
+ return chalk.yellow("maintenance");
140
+ default:
141
+ return chalk.gray(status || "unknown");
142
+ }
143
+ }
144
+ function formatPlatform(platform) {
145
+ switch (platform) {
146
+ case "vapi":
147
+ return chalk.blue("vapi");
148
+ case "elevenlabs":
149
+ return chalk.magenta("elevenlabs");
150
+ case "custom":
151
+ return chalk.cyan("custom");
152
+ default:
153
+ return chalk.gray(platform || "unknown");
154
+ }
155
+ }
156
+ function getAgentTemplate(platform = "custom") {
157
+ const baseTemplate = {
158
+ platform: "custom",
159
+ name: "My Custom Agent",
160
+ type: "Voice Assistant",
161
+ status: "inactive",
162
+ useCase: "support",
163
+ description: "A custom AI agent for customer support",
164
+ configuration: {
165
+ prompt: "You are a helpful customer support agent. Be friendly and professional.",
166
+ model: "gpt-4o"
167
+ },
168
+ autoAnalysisEnabled: true,
169
+ simulationMode: "text"
170
+ };
171
+ if (platform === "vapi") {
172
+ return {
173
+ ...baseTemplate,
174
+ platform: "vapi",
175
+ platformAgentId: "YOUR_VAPI_ASSISTANT_ID",
176
+ name: "VAPI Support Agent",
177
+ description: "VAPI-powered customer support agent",
178
+ phoneNumbers: ["+1234567890"],
179
+ testPhoneNumber: "+1234567890",
180
+ configuration: {
181
+ prompt: "You are a helpful customer support agent.",
182
+ model: "gpt-4o",
183
+ voice: "YOUR_VOICE_ID",
184
+ transcriber: "deepgram",
185
+ vapi: {
186
+ firstMessage: "Hello! How can I help you today?",
187
+ webhookUrl: "https://your-domain.com/webhooks/vapi"
188
+ }
189
+ },
190
+ defaultSimulationChannel: "websocket",
191
+ simulationMode: "websocket"
192
+ };
193
+ }
194
+ if (platform === "elevenlabs") {
195
+ return {
196
+ ...baseTemplate,
197
+ platform: "elevenlabs",
198
+ platformAgentId: "YOUR_ELEVENLABS_AGENT_ID",
199
+ name: "ElevenLabs Voice Agent",
200
+ type: "Text-to-Speech",
201
+ description: "ElevenLabs-powered voice agent",
202
+ configuration: {
203
+ prompt: "You are a helpful assistant.",
204
+ voice: "YOUR_ELEVENLABS_VOICE_ID",
205
+ elevenlabs: {}
206
+ }
207
+ };
208
+ }
209
+ return baseTemplate;
210
+ }
211
+ async function handleAgentsList(options) {
212
+ const sdk = createSdk();
213
+ if (!sdk) return;
214
+ const spinner = ora("Fetching agents...").start();
215
+ try {
216
+ const response = await sdk.agents.list({
217
+ provider: options.platform,
218
+ status: options.status,
219
+ limit: parseInt(options.limit, 10),
220
+ page: parseInt(options.page, 10)
221
+ });
222
+ spinner.stop();
223
+ if (!response.success || !response.data) {
224
+ printError("Failed to fetch agents", response.message);
225
+ process.exitCode = 1;
226
+ return;
227
+ }
228
+ const { agents, pagination } = response.data;
229
+ if (isJsonOutput()) {
230
+ printJson(response.data);
231
+ return;
232
+ }
233
+ if (agents.length === 0) {
234
+ printInfo("No agents found");
235
+ printInfo("Use 'chanl agents sync vapi' to import from VAPI");
236
+ printInfo("Or 'chanl agents create --template' to create a custom agent");
237
+ return;
238
+ }
239
+ printBlank();
240
+ printSimpleTable(
241
+ ["ID", "Name", "Platform", "Status", "Created"],
242
+ agents.map((a) => [
243
+ a.id.slice(-12),
244
+ a.name.slice(0, 25),
245
+ formatPlatform(a.provider),
246
+ formatStatus(a.status),
247
+ formatDate(a.createdAt)
248
+ ])
249
+ );
250
+ printBlank();
251
+ if (pagination) {
252
+ printInfo(`Total: ${pagination.total} agents (Page ${pagination.page} of ${pagination.pages})`);
253
+ }
254
+ } catch (error) {
255
+ spinner.fail("Failed to fetch agents");
256
+ const message = error instanceof Error ? error.message : "Unknown error";
257
+ printError("Error", message);
258
+ process.exitCode = 1;
259
+ }
260
+ }
261
+ async function handleAgentsGet(id) {
262
+ const sdk = createSdk();
263
+ if (!sdk) return;
264
+ const spinner = ora("Fetching agent...").start();
265
+ try {
266
+ const response = await sdk.agents.get(id);
267
+ spinner.stop();
268
+ if (!response.success || !response.data) {
269
+ printError("Failed to fetch agent", response.message);
270
+ process.exitCode = 1;
271
+ return;
272
+ }
273
+ if (isJsonOutput()) {
274
+ printJson(response.data);
275
+ return;
276
+ }
277
+ const { agent } = response.data;
278
+ printBlank();
279
+ console.log(chalk.bold("Agent Details:"));
280
+ console.log(` ID: ${agent.id}`);
281
+ console.log(` Name: ${agent.name}`);
282
+ console.log(` Platform: ${formatPlatform(agent.provider)}`);
283
+ console.log(` Status: ${formatStatus(agent.status)}`);
284
+ if (agent.providerId) console.log(` Platform ID: ${agent.providerId}`);
285
+ if (agent.description) console.log(` Description: ${agent.description}`);
286
+ console.log(` Created: ${formatDate(agent.createdAt)}`);
287
+ console.log(` Updated: ${formatDate(agent.updatedAt)}`);
288
+ printBlank();
289
+ } catch (error) {
290
+ spinner.fail("Failed to fetch agent");
291
+ const message = error instanceof Error ? error.message : "Unknown error";
292
+ printError("Error", message);
293
+ process.exitCode = 1;
294
+ }
295
+ }
296
+ async function handleAgentsCreate(options) {
297
+ if (options.template !== void 0) {
298
+ const platform = typeof options.template === "string" ? options.template : "custom";
299
+ const template = getAgentTemplate(platform);
300
+ console.log(JSON.stringify(template, null, 2));
301
+ return;
302
+ }
303
+ if (!options.file) {
304
+ printError("Missing required option", "Use '-f <file>' to specify agent data or '--template [platform]' to get a template");
305
+ process.exitCode = 1;
306
+ return;
307
+ }
308
+ const sdk = createSdk();
309
+ if (!sdk) return;
310
+ let agentData;
311
+ try {
312
+ const content = readFileSync(options.file, "utf-8");
313
+ agentData = JSON.parse(content);
314
+ } catch (error) {
315
+ const message = error instanceof Error ? error.message : "Unknown error";
316
+ printError("Failed to read file", message);
317
+ process.exitCode = 1;
318
+ return;
319
+ }
320
+ const spinner = ora("Creating agent...").start();
321
+ try {
322
+ const response = await sdk.agents.create(agentData);
323
+ spinner.stop();
324
+ if (!response.success || !response.data) {
325
+ printError("Failed to create agent", response.message);
326
+ process.exitCode = 1;
327
+ return;
328
+ }
329
+ if (isJsonOutput()) {
330
+ printJson(response.data);
331
+ return;
332
+ }
333
+ const { agent } = response.data;
334
+ printSuccess(`Agent created: ${agent.name}`);
335
+ printLabel("ID", agent.id);
336
+ printLabel("Platform", agent.provider || "custom");
337
+ } catch (error) {
338
+ spinner.fail("Failed to create agent");
339
+ const message = error instanceof Error ? error.message : "Unknown error";
340
+ printError("Error", message);
341
+ process.exitCode = 1;
342
+ }
343
+ }
344
+ async function handleAgentsUpdate(id, options) {
345
+ if (!options.file) {
346
+ printError("Missing required option", "Use '-f <file>' to specify update data");
347
+ process.exitCode = 1;
348
+ return;
349
+ }
350
+ const sdk = createSdk();
351
+ if (!sdk) return;
352
+ let updateData;
353
+ try {
354
+ const content = readFileSync(options.file, "utf-8");
355
+ updateData = JSON.parse(content);
356
+ } catch (error) {
357
+ const message = error instanceof Error ? error.message : "Unknown error";
358
+ printError("Failed to read file", message);
359
+ process.exitCode = 1;
360
+ return;
361
+ }
362
+ if (options.syncToVapi) {
363
+ updateData.syncToVapi = true;
364
+ }
365
+ const spinner = ora("Updating agent...").start();
366
+ try {
367
+ const response = await sdk.agents.update(id, updateData);
368
+ spinner.stop();
369
+ if (!response.success || !response.data) {
370
+ printError("Failed to update agent", response.message);
371
+ process.exitCode = 1;
372
+ return;
373
+ }
374
+ if (isJsonOutput()) {
375
+ printJson(response.data);
376
+ return;
377
+ }
378
+ const { agent } = response.data;
379
+ printSuccess(`Agent updated: ${agent.name}`);
380
+ if (options.syncToVapi) {
381
+ printInfo("Changes synced to VAPI");
382
+ }
383
+ } catch (error) {
384
+ spinner.fail("Failed to update agent");
385
+ const message = error instanceof Error ? error.message : "Unknown error";
386
+ printError("Error", message);
387
+ process.exitCode = 1;
388
+ }
389
+ }
390
+ async function handleAgentsDelete(id, options) {
391
+ const sdk = createSdk();
392
+ if (!sdk) return;
393
+ if (!options.yes) {
394
+ printInfo(`About to delete agent: ${id}`);
395
+ if (options.deleteFromIntegration) {
396
+ printInfo("This will also delete the agent from the integration platform");
397
+ }
398
+ printInfo("Use '--yes' flag to skip this confirmation");
399
+ }
400
+ const spinner = ora("Deleting agent...").start();
401
+ try {
402
+ const response = await sdk.agents.delete(id, {
403
+ deleteFromIntegration: options.deleteFromIntegration
404
+ });
405
+ spinner.stop();
406
+ if (!response.success) {
407
+ printError("Failed to delete agent", response.message);
408
+ process.exitCode = 1;
409
+ return;
410
+ }
411
+ if (isJsonOutput()) {
412
+ printJson({ success: true, deleted: id });
413
+ return;
414
+ }
415
+ printSuccess(`Agent deleted: ${id}`);
416
+ } catch (error) {
417
+ spinner.fail("Failed to delete agent");
418
+ const message = error instanceof Error ? error.message : "Unknown error";
419
+ printError("Error", message);
420
+ process.exitCode = 1;
421
+ }
422
+ }
423
+ async function handleAgentsSync(platform, options) {
424
+ const sdk = createSdk();
425
+ if (!sdk) return;
426
+ const validPlatforms = ["vapi", "bland", "twilio"];
427
+ if (!validPlatforms.includes(platform)) {
428
+ printError("Invalid platform", `Valid platforms: ${validPlatforms.join(", ")}`);
429
+ process.exitCode = 1;
430
+ return;
431
+ }
432
+ const spinner = ora(`Syncing agents from ${platform}...`).start();
433
+ try {
434
+ const response = await sdk.agents.sync(platform, {
435
+ forceUpdate: options.force,
436
+ cleanBeforeSync: options.clean
437
+ });
438
+ spinner.stop();
439
+ if (!response.success || !response.data) {
440
+ printError("Failed to sync agents", response.message);
441
+ process.exitCode = 1;
442
+ return;
443
+ }
444
+ if (isJsonOutput()) {
445
+ printJson(response.data);
446
+ return;
447
+ }
448
+ const result = response.data.result;
449
+ printBlank();
450
+ console.log(chalk.bold("Sync Results:"));
451
+ console.log(` Processed: ${result.processed}`);
452
+ console.log(` Created: ${chalk.green(result.created.toString())}`);
453
+ console.log(` Updated: ${chalk.cyan(result.updated.toString())}`);
454
+ if (result.errors > 0) {
455
+ console.log(` Errors: ${chalk.red(result.errors.toString())}`);
456
+ }
457
+ if (result.details && result.details.length > 0) {
458
+ console.log(chalk.bold("\nDetails:"));
459
+ for (const detail of result.details.slice(0, 10)) {
460
+ const statusColor = detail.status === "created" ? chalk.green : detail.status === "updated" ? chalk.cyan : detail.status === "error" ? chalk.red : chalk.gray;
461
+ console.log(` ${detail.name.slice(0, 30)}: ${statusColor(detail.status)}`);
462
+ }
463
+ if (result.details.length > 10) {
464
+ printInfo(`... and ${result.details.length - 10} more`);
465
+ }
466
+ }
467
+ printBlank();
468
+ } catch (error) {
469
+ spinner.fail("Failed to sync agents");
470
+ const message = error instanceof Error ? error.message : "Unknown error";
471
+ printError("Error", message);
472
+ process.exitCode = 1;
473
+ }
474
+ }
475
+ async function handleAgentsSyncAll(options) {
476
+ const sdk = createSdk();
477
+ if (!sdk) return;
478
+ const spinner = ora("Syncing agents from all platforms...").start();
479
+ try {
480
+ const response = await sdk.agents.syncAll({
481
+ forceUpdate: options.force
482
+ });
483
+ spinner.stop();
484
+ if (!response.success || !response.data) {
485
+ printError("Failed to sync agents", response.message);
486
+ process.exitCode = 1;
487
+ return;
488
+ }
489
+ if (isJsonOutput()) {
490
+ printJson(response.data);
491
+ return;
492
+ }
493
+ const result = response.data.result;
494
+ printSuccess(result.message || "Sync completed");
495
+ console.log(` Processed: ${result.processed}`);
496
+ console.log(` Created: ${chalk.green(result.created.toString())}`);
497
+ console.log(` Updated: ${chalk.cyan(result.updated.toString())}`);
498
+ if (result.errors > 0) {
499
+ console.log(` Errors: ${chalk.red(result.errors.toString())}`);
500
+ }
501
+ printBlank();
502
+ } catch (error) {
503
+ spinner.fail("Failed to sync agents");
504
+ const message = error instanceof Error ? error.message : "Unknown error";
505
+ printError("Error", message);
506
+ process.exitCode = 1;
507
+ }
508
+ }
509
+ async function handleAgentsImport(options) {
510
+ const sdk = createSdk();
511
+ if (!sdk) return;
512
+ const spinner = ora(`Importing agent from ${options.from}...`).start();
513
+ try {
514
+ const response = await sdk.agents.importFromPlatform({
515
+ platform: options.from,
516
+ externalAgentId: options.agentId,
517
+ ...options.name ? { name: options.name } : {}
518
+ });
519
+ spinner.stop();
520
+ if (!response.success || !response.data) {
521
+ printError("Import failed", response.message || "Could not import agent");
522
+ process.exitCode = 1;
523
+ return;
524
+ }
525
+ const agent = response.data.agent || response.data;
526
+ if (isJsonOutput()) {
527
+ printJson(response.data);
528
+ return;
529
+ }
530
+ printBlank();
531
+ printSuccess(`Agent imported from ${options.from}`);
532
+ printBlank();
533
+ printLabel("Name", agent.name);
534
+ printLabel("Chanl ID", agent.id);
535
+ printLabel("Platform", agent.platform || options.from);
536
+ printLabel("External ID", agent.platformAgentId || options.agentId);
537
+ printLabel("Status", agent.status || "active");
538
+ if (agent.deployments?.length) {
539
+ const dep = agent.deployments[0];
540
+ printLabel("Deployment", `${dep.orchestrator} \u2192 ${dep.externalId} (${dep.status})`);
541
+ }
542
+ printBlank();
543
+ } catch (error) {
544
+ spinner.fail("Import failed");
545
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
546
+ printError("Error", errorMessage);
547
+ process.exitCode = 1;
548
+ }
549
+ }
550
+ async function handleAgentsPublish(agentId, options) {
551
+ const sdk = createSdk();
552
+ if (!sdk) return;
553
+ const spinner = ora(`Publishing agent to ${options.to}...`).start();
554
+ try {
555
+ const response = await sdk.agents.publish(agentId, {
556
+ platform: options.to,
557
+ ...options.target ? { targetExternalId: options.target } : {},
558
+ ...options.withMcp ? { includeMcp: true } : {}
559
+ });
560
+ spinner.stop();
561
+ if (!response.success || !response.data) {
562
+ printError("Publish failed", response.message || "Could not publish agent");
563
+ process.exitCode = 1;
564
+ return;
565
+ }
566
+ const result = response.data;
567
+ if (isJsonOutput()) {
568
+ printJson(response.data);
569
+ return;
570
+ }
571
+ printBlank();
572
+ printSuccess(`Agent ${result.action} on ${result.platform}`);
573
+ printBlank();
574
+ printLabel("Action", result.action);
575
+ printLabel("Platform", result.platform);
576
+ printLabel("External ID", result.externalId);
577
+ printLabel("Status", result.status);
578
+ if (result.mcpUrl) {
579
+ printLabel("MCP URL", result.mcpUrl);
580
+ }
581
+ printBlank();
582
+ } catch (error) {
583
+ spinner.fail("Publish failed");
584
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
585
+ printError("Error", errorMessage);
586
+ process.exitCode = 1;
587
+ }
588
+ }
589
+ async function handleAgentsPushMcp(agentId, options) {
590
+ const sdk = createSdk();
591
+ if (!sdk) return;
592
+ const spinner = ora(`Pushing MCP URL to ${options.to}...`).start();
593
+ try {
594
+ const response = await sdk.agents.pushMcp(agentId, {
595
+ platform: options.to,
596
+ ...options.target ? { targetExternalId: options.target } : {}
597
+ });
598
+ spinner.stop();
599
+ if (!response.success || !response.data) {
600
+ printError("Push MCP failed", response.message || "Could not push MCP URL");
601
+ process.exitCode = 1;
602
+ return;
603
+ }
604
+ const result = response.data;
605
+ if (isJsonOutput()) {
606
+ printJson(response.data);
607
+ return;
608
+ }
609
+ printBlank();
610
+ printSuccess(`MCP URL pushed to ${result.platform}`);
611
+ printBlank();
612
+ printLabel("MCP URL", result.mcpUrl);
613
+ printLabel("Platform", result.platform);
614
+ printLabel("External ID", result.externalId);
615
+ printLabel("Status", result.status);
616
+ printBlank();
617
+ } catch (error) {
618
+ spinner.fail("Push MCP failed");
619
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
620
+ printError("Error", errorMessage);
621
+ process.exitCode = 1;
622
+ }
623
+ }
624
+ async function handleAgentsStats() {
625
+ const sdk = createSdk();
626
+ if (!sdk) return;
627
+ const spinner = ora("Fetching statistics...").start();
628
+ try {
629
+ const response = await sdk.agents.getStats();
630
+ spinner.stop();
631
+ if (!response.success || !response.data) {
632
+ printError("Failed to fetch statistics", response.message);
633
+ process.exitCode = 1;
634
+ return;
635
+ }
636
+ if (isJsonOutput()) {
637
+ printJson(response.data);
638
+ return;
639
+ }
640
+ const { stats } = response.data;
641
+ printBlank();
642
+ console.log(chalk.bold("Agent Statistics:"));
643
+ console.log(chalk.dim("\u2500".repeat(40)));
644
+ console.log(` Total Agents: ${stats.totalAgents}`);
645
+ console.log(` Average Score: ${stats.avgScore !== null ? `${stats.avgScore.toFixed(1)}%` : "-"}`);
646
+ console.log(` Tool Failures: ${stats.toolFailures}`);
647
+ console.log(` Top Provider: ${stats.topProvider || "-"}`);
648
+ if (stats.byPlatform && Object.keys(stats.byPlatform).length > 0) {
649
+ console.log(chalk.bold("\n By Platform:"));
650
+ for (const [platform, count] of Object.entries(stats.byPlatform)) {
651
+ console.log(` ${formatPlatform(platform)}: ${count}`);
652
+ }
653
+ }
654
+ if (stats.byStatus && Object.keys(stats.byStatus).length > 0) {
655
+ console.log(chalk.bold("\n By Status:"));
656
+ for (const [status, count] of Object.entries(stats.byStatus)) {
657
+ console.log(` ${formatStatus(status)}: ${count}`);
658
+ }
659
+ }
660
+ printBlank();
661
+ } catch (error) {
662
+ spinner.fail("Failed to fetch statistics");
663
+ const message = error instanceof Error ? error.message : "Unknown error";
664
+ printError("Error", message);
665
+ process.exitCode = 1;
666
+ }
667
+ }
668
+ export {
669
+ createAgentsCommand
670
+ };
671
+ //# sourceMappingURL=agents.js.map