plazbot-cli 0.3.6 → 0.4.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.
Files changed (117) hide show
  1. package/README.md +38 -2
  2. package/dist/commands/agent/export.js +25 -2
  3. package/dist/commands/auth/browser-login.js +121 -0
  4. package/dist/commands/auth/index.js +5 -1
  5. package/dist/commands/auth/login.js +1 -3
  6. package/dist/commands/auth/logout.js +4 -3
  7. package/dist/commands/auth/status.js +8 -5
  8. package/dist/commands/auth/workspace.js +73 -0
  9. package/dist/commands/whatsapp/connect-flow.js +137 -0
  10. package/dist/commands/whatsapp/connect.js +26 -160
  11. package/dist/commands/whatsapp/index.js +4 -0
  12. package/dist/commands/whatsapp/setup.js +242 -0
  13. package/dist/studio/components/App.js +1 -1
  14. package/dist/studio/runOneShot.js +2 -2
  15. package/dist/studio/runRepl.js +1 -1
  16. package/dist/utils/agent-errors.js +2 -2
  17. package/dist/utils/banner.js +10 -9
  18. package/dist/utils/credentials.js +31 -3
  19. package/dist/utils/open-browser.js +17 -0
  20. package/package.json +14 -6
  21. package/.claude/settings.local.json +0 -15
  22. package/CLAUDE.md +0 -121
  23. package/agent.config.json +0 -21
  24. package/dist/studio/components/AgentPanel.js +0 -35
  25. package/dist/studio/render/json.js +0 -16
  26. package/dist/studio/whatsapp/api.js +0 -63
  27. package/dist/studio/whatsapp/polling.js +0 -77
  28. package/dist/studio/whatsapp/types.js +0 -31
  29. package/src/cli.ts +0 -57
  30. package/src/commands/agent/ai-config.ts +0 -164
  31. package/src/commands/agent/chat.ts +0 -225
  32. package/src/commands/agent/copy.ts +0 -46
  33. package/src/commands/agent/create.ts +0 -103
  34. package/src/commands/agent/delete.ts +0 -71
  35. package/src/commands/agent/enable-widget.ts +0 -67
  36. package/src/commands/agent/export.ts +0 -408
  37. package/src/commands/agent/files.ts +0 -171
  38. package/src/commands/agent/get.ts +0 -233
  39. package/src/commands/agent/index.ts +0 -55
  40. package/src/commands/agent/list.ts +0 -58
  41. package/src/commands/agent/monitor.ts +0 -375
  42. package/src/commands/agent/on-message.ts +0 -82
  43. package/src/commands/agent/set.ts +0 -149
  44. package/src/commands/agent/templates.ts +0 -892
  45. package/src/commands/agent/tools.ts +0 -168
  46. package/src/commands/agent/update.ts +0 -61
  47. package/src/commands/agent/validate.ts +0 -135
  48. package/src/commands/agent/wizard.ts +0 -756
  49. package/src/commands/auth/index.ts +0 -10
  50. package/src/commands/auth/login.ts +0 -72
  51. package/src/commands/auth/logout.ts +0 -28
  52. package/src/commands/auth/status.ts +0 -28
  53. package/src/commands/portal/add-agent.ts +0 -66
  54. package/src/commands/portal/add-link.ts +0 -47
  55. package/src/commands/portal/clear-links.ts +0 -33
  56. package/src/commands/portal/create.ts +0 -58
  57. package/src/commands/portal/delete.ts +0 -70
  58. package/src/commands/portal/get.ts +0 -77
  59. package/src/commands/portal/index.ts +0 -32
  60. package/src/commands/portal/list.ts +0 -79
  61. package/src/commands/portal/update.ts +0 -93
  62. package/src/commands/whatsapp/broadcast.ts +0 -110
  63. package/src/commands/whatsapp/channels.ts +0 -109
  64. package/src/commands/whatsapp/chat.ts +0 -85
  65. package/src/commands/whatsapp/connect.ts +0 -220
  66. package/src/commands/whatsapp/delete-webhook.ts +0 -43
  67. package/src/commands/whatsapp/index.ts +0 -37
  68. package/src/commands/whatsapp/register-webhook.ts +0 -47
  69. package/src/commands/whatsapp/send-template.ts +0 -94
  70. package/src/commands/whatsapp/send.ts +0 -55
  71. package/src/commands/whatsapp/widget.ts +0 -75
  72. package/src/commands/workers/deploy.ts +0 -156
  73. package/src/commands/workers/index.ts +0 -30
  74. package/src/commands/workers/list.ts +0 -105
  75. package/src/commands/workers/logs.ts +0 -99
  76. package/src/commands/workers/remove.ts +0 -103
  77. package/src/commands/workers/secret.ts +0 -191
  78. package/src/commands/workers/test.ts +0 -145
  79. package/src/schemas/agent.config.schema.json +0 -569
  80. package/src/studio/api/sseClient.ts +0 -91
  81. package/src/studio/api/studioApi.ts +0 -27
  82. package/src/studio/api/types.ts +0 -96
  83. package/src/studio/components/App.tsx +0 -274
  84. package/src/studio/components/ChatLog.tsx +0 -121
  85. package/src/studio/components/ConnectCard.tsx +0 -171
  86. package/src/studio/components/Footer.tsx +0 -38
  87. package/src/studio/components/Header.tsx +0 -39
  88. package/src/studio/components/Input.tsx +0 -176
  89. package/src/studio/components/Message.tsx +0 -87
  90. package/src/studio/components/Suggestions.tsx +0 -26
  91. package/src/studio/components/ToolCall.tsx +0 -58
  92. package/src/studio/connect/api.ts +0 -98
  93. package/src/studio/connect/polling.ts +0 -94
  94. package/src/studio/connect/types.ts +0 -141
  95. package/src/studio/index.ts +0 -58
  96. package/src/studio/render/markdown.ts +0 -93
  97. package/src/studio/render/steps.ts +0 -57
  98. package/src/studio/runOneShot.ts +0 -114
  99. package/src/studio/runRepl.tsx +0 -82
  100. package/src/studio/slash/handlers.ts +0 -226
  101. package/src/studio/slash/parser.ts +0 -41
  102. package/src/studio/slash/registry.ts +0 -54
  103. package/src/studio/state/store.ts +0 -279
  104. package/src/types/agent.ts +0 -63
  105. package/src/types/auth.ts +0 -9
  106. package/src/types/common.ts +0 -10
  107. package/src/types/message.ts +0 -34
  108. package/src/types/portal.ts +0 -56
  109. package/src/types/workers.ts +0 -86
  110. package/src/utils/agent-errors.ts +0 -67
  111. package/src/utils/api.ts +0 -35
  112. package/src/utils/banner.ts +0 -99
  113. package/src/utils/credentials.ts +0 -38
  114. package/src/utils/help.ts +0 -51
  115. package/src/utils/logger.ts +0 -40
  116. package/src/utils/ui.ts +0 -109
  117. package/tsconfig.json +0 -18
@@ -1,37 +0,0 @@
1
- import { Command } from 'commander';
2
- import { addExamples } from '../../utils/help.js';
3
- import { sendMessageCommand } from './send.js';
4
- import { sendTemplateCommand } from './send-template.js';
5
- import { registerWebhookCommand } from './register-webhook.js';
6
- import { deleteWebhookCommand } from './delete-webhook.js';
7
- import { broadcastCommand } from './broadcast.js';
8
- import { whatsappChatCommand } from './chat.js';
9
- import { whatsappConnectCommand } from './connect.js';
10
- import { widgetCommand } from './widget.js';
11
- import { channelsCommand, assignCommand } from './channels.js';
12
-
13
- export const whatsappCommands = new Command('whatsapp')
14
- .description('WhatsApp commands: messages, templates, broadcast and more')
15
- .addCommand(whatsappConnectCommand)
16
- .addCommand(sendMessageCommand)
17
- .addCommand(sendTemplateCommand)
18
- .addCommand(registerWebhookCommand)
19
- .addCommand(deleteWebhookCommand)
20
- .addCommand(broadcastCommand)
21
- .addCommand(whatsappChatCommand)
22
- .addCommand(widgetCommand)
23
- .addCommand(channelsCommand)
24
- .addCommand(assignCommand);
25
-
26
- addExamples(whatsappCommands, [
27
- { description: 'Connect a WhatsApp number to the workspace',
28
- command: 'plazbot whatsapp connect' },
29
- { description: 'Send a quick message',
30
- command: 'plazbot whatsapp send-message -t 51912345678 -m "Hello"' },
31
- { description: 'Send a template with variables',
32
- command: 'plazbot whatsapp send-template -p 51912345678 -t welcome --var name=Anna' },
33
- { description: 'Open an interactive chat',
34
- command: 'plazbot whatsapp chat 51912345678' },
35
- { description: 'Assign a number to an agent',
36
- command: 'plazbot whatsapp assign 51912345678 agt_AbcDef123' },
37
- ]);
@@ -1,47 +0,0 @@
1
- import { Command } from 'commander';
2
- import { Message } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials.js';
4
- import { logger } from '../../utils/logger.js';
5
- import { addExamples } from '../../utils/help.js';
6
-
7
- interface RegisterWebhookOptions {
8
- dev?: boolean;
9
- number: string;
10
- url: string;
11
- }
12
-
13
- export const registerWebhookCommand = new Command('register-webhook')
14
- .description('Register a webhook for WhatsApp')
15
- .requiredOption('-n, --number <phone>', 'WhatsApp number (with country code, e.g.: 51912345678)')
16
- .requiredOption('-u, --url <webhook>', 'Webhook URL')
17
- .option('--dev', 'Use development environment', false)
18
- .action(async (options: RegisterWebhookOptions) => {
19
- try {
20
- const credentials = await getStoredCredentials();
21
- const messageClient = new Message({
22
- workspaceId: credentials.workspace,
23
- apiKey: credentials.apiKey,
24
- zone: credentials.zone,
25
- ...(options.dev && { customUrl: "http://localhost:5090" })
26
- });
27
-
28
- logger.title('Registering WhatsApp webhook');
29
- logger.label('Number', options.number);
30
- logger.label('URL', options.url);
31
-
32
- await messageClient.registerWebhook({
33
- number: options.number,
34
- webhookUrl: options.url
35
- });
36
-
37
- logger.success('Webhook registered successfully');
38
- } catch (error: unknown) {
39
- logger.error((error as Error).message);
40
- process.exit(1);
41
- }
42
- });
43
-
44
- addExamples(registerWebhookCommand, [
45
- { description: 'Register an inbound webhook for a WhatsApp number',
46
- command: 'plazbot whatsapp register-webhook -n 51912345678 -u https://api.example.com/webhooks/whatsapp' },
47
- ]);
@@ -1,94 +0,0 @@
1
- import { Command } from 'commander';
2
- import { Message } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials.js';
4
- import { logger } from '../../utils/logger.js';
5
- import { addExamples } from '../../utils/help.js';
6
- import { createSpinner } from '../../utils/ui.js';
7
-
8
- export const sendTemplateCommand = new Command('send-template')
9
- .description('Send a WhatsApp template message with variables')
10
- .requiredOption('-p, --phone <number>', 'Phone number (with country code)')
11
- .requiredOption('-t, --template <name>', 'Template name')
12
- .option('--var <vars...>', 'Body variables (format: name=value)')
13
- .option('--header-var <vars...>', 'Header variables (format: name=value)')
14
- .option('--file-url <url>', 'Attachment file URL')
15
- .option('--file-name <name>', 'Attachment file name')
16
- .option('--dev', 'Use development environment', false)
17
- .action(async (options: any) => {
18
- try {
19
- const credentials = await getStoredCredentials();
20
-
21
- const messageClient = new Message({
22
- workspaceId: credentials.workspace,
23
- apiKey: credentials.apiKey,
24
- zone: credentials.zone,
25
- ...(options.dev && { customUrl: "http://localhost:5090" })
26
- });
27
-
28
- // Parsear variables
29
- const variablesBody = parseVariables(options.var);
30
- const variablesHeader = parseVariables(options.headerVar);
31
-
32
- // Archivo adjunto
33
- const file = options.fileUrl ? {
34
- fileUrl: options.fileUrl,
35
- fileName: options.fileName || 'file',
36
- } : undefined;
37
-
38
- logger.title('Sending WhatsApp template');
39
- logger.label('Destination', options.phone);
40
- logger.label('Template', options.template);
41
- if (variablesBody.length > 0) {
42
- logger.label('Body variables', variablesBody.map(v => `${v.variable}=${v.value}`).join(', '));
43
- }
44
- if (variablesHeader.length > 0) {
45
- logger.label('Header variables', variablesHeader.map(v => `${v.variable}=${v.value}`).join(', '));
46
- }
47
- if (file) {
48
- logger.label('File', file.fileUrl);
49
- }
50
-
51
- const spinner = createSpinner('Sending...');
52
- spinner.start();
53
-
54
- const params: any = {
55
- to: options.phone,
56
- template: options.template,
57
- };
58
- if (variablesBody.length > 0) params.variablesBody = variablesBody;
59
- if (variablesHeader.length > 0) params.variablesHeader = variablesHeader;
60
- if (file) params.file = file;
61
-
62
- const response = await messageClient.onConversation(params);
63
-
64
- spinner.succeed('Template sent successfully');
65
-
66
- if (options.dev) {
67
- logger.warning('Environment: development');
68
- }
69
-
70
- } catch (error: unknown) {
71
- const message = (error as Error)?.message || 'Unknown error while sending the template';
72
- logger.error(message);
73
- process.exit(1);
74
- }
75
- });
76
-
77
- addExamples(sendTemplateCommand, [
78
- { description: 'Send a template with no variables',
79
- command: 'plazbot whatsapp send-template -p 51912345678 -t welcome_message' },
80
- { description: 'Send a template with body variables',
81
- command: 'plazbot whatsapp send-template -p 51912345678 -t order_status --var name=Anna code=PB-123' },
82
- { description: 'Send a template with an attached PDF',
83
- command: 'plazbot whatsapp send-template -p 51912345678 -t invoice_template --file-url https://files.example.com/inv.pdf --file-name invoice.pdf' },
84
- { description: 'Send a template with header and body variables',
85
- command: 'plazbot whatsapp send-template -p 51912345678 -t promo --header-var image=https://img.example.com/banner.png --var amount=20' },
86
- ]);
87
-
88
- function parseVariables(vars: string[] | undefined): { variable: string; value: string }[] {
89
- if (!vars) return [];
90
- return vars.map(v => {
91
- const [variable, ...rest] = v.split('=');
92
- return { variable: variable.trim(), value: rest.join('=').trim() };
93
- }).filter(v => v.variable && v.value);
94
- }
@@ -1,55 +0,0 @@
1
- import { Command } from 'commander';
2
- import { Message } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials.js';
4
- import { logger } from '../../utils/logger.js';
5
- import { addExamples } from '../../utils/help.js';
6
- import { DirectMessageCommandOptions } from '../../types/message.js';
7
- import { createSpinner } from '../../utils/ui.js';
8
-
9
- export const sendMessageCommand = new Command('send-message')
10
- .description('Send a direct WhatsApp message')
11
- .requiredOption('-t, --to <phone>', 'Phone number (with country code, e.g.: 51912345678)')
12
- .requiredOption('-m, --message <text>', 'Message to send')
13
- .option('--dev', 'Use development environment', false)
14
- .action(async (options: DirectMessageCommandOptions) => {
15
- try {
16
- const credentials = await getStoredCredentials();
17
-
18
- const messageClient = new Message({
19
- workspaceId: credentials.workspace,
20
- apiKey: credentials.apiKey,
21
- zone: credentials.zone,
22
- ...(options.dev && { customUrl: "http://localhost:5090" })
23
- });
24
-
25
- logger.title('Sending WhatsApp message');
26
- logger.label('Destination', options.to);
27
- logger.label('Message', options.message);
28
-
29
- const spinner = createSpinner('Sending...');
30
- spinner.start();
31
-
32
- const response = await messageClient.onWhatsappMessage({
33
- message: options.message,
34
- to: options.to
35
- });
36
-
37
- spinner.succeed('Message sent successfully');
38
-
39
- if (options.dev) {
40
- logger.warning('Environment: development');
41
- }
42
-
43
- } catch (error: unknown) {
44
- const message = (error as Error)?.message || 'Unknown error while sending the message';
45
- logger.error(message);
46
- process.exit(1);
47
- }
48
- });
49
-
50
- addExamples(sendMessageCommand, [
51
- { description: 'Send a quick WhatsApp message',
52
- command: 'plazbot whatsapp send-message -t 51912345678 -m "Hello from Plazbot"' },
53
- { description: 'Send through the development backend',
54
- command: 'plazbot whatsapp send-message -t 51912345678 -m "Hi" --dev' },
55
- ]);
@@ -1,75 +0,0 @@
1
- import { Command } from 'commander';
2
- import { Agent } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials.js';
4
- import { logger } from '../../utils/logger.js';
5
- import { addExamples } from '../../utils/help.js';
6
- import { createSpinner } from '../../utils/ui.js';
7
-
8
- const widgetGroup = new Command('widget')
9
- .description('Manage WhatsApp widget');
10
-
11
- addExamples(widgetGroup, [
12
- { description: 'Enable the WhatsApp click-to-chat widget on an agent',
13
- command: 'plazbot whatsapp widget enable agt_AbcDef123 -u https://wa.me/51912345678' },
14
- { description: 'Disable the widget',
15
- command: 'plazbot whatsapp widget disable agt_AbcDef123' },
16
- ]);
17
-
18
- widgetGroup.command('enable')
19
- .description('Enable the WhatsApp widget on an agent')
20
- .argument('<agentId>', 'Agent ID')
21
- .requiredOption('-u, --url <url>', 'WhatsApp URL (e.g.: https://wa.me/51912345678)')
22
- .option('--dev', 'Use development environment', false)
23
- .action(async (agentId: string, options: any) => {
24
- try {
25
- const credentials = await getStoredCredentials();
26
- const agent = new Agent({
27
- workspaceId: credentials.workspace,
28
- apiKey: credentials.apiKey,
29
- zone: credentials.zone,
30
- ...(options.dev && { customUrl: "http://localhost:5090" })
31
- });
32
-
33
- const spinner = createSpinner('Enabling WhatsApp widget...');
34
- spinner.start();
35
- await agent.updateAgent(agentId, {
36
- enableWhatsappWidget: true,
37
- urlWhatsappWidget: options.url,
38
- });
39
- spinner.succeed('WhatsApp widget enabled');
40
- logger.label('URL', options.url);
41
-
42
- } catch (error) {
43
- const message = error instanceof Error ? error.message : 'Unknown error';
44
- logger.error(message);
45
- process.exit(1);
46
- }
47
- });
48
-
49
- widgetGroup.command('disable')
50
- .description('Disable the WhatsApp widget on an agent')
51
- .argument('<agentId>', 'Agent ID')
52
- .option('--dev', 'Use development environment', false)
53
- .action(async (agentId: string, options: any) => {
54
- try {
55
- const credentials = await getStoredCredentials();
56
- const agent = new Agent({
57
- workspaceId: credentials.workspace,
58
- apiKey: credentials.apiKey,
59
- zone: credentials.zone,
60
- ...(options.dev && { customUrl: "http://localhost:5090" })
61
- });
62
-
63
- const spinner = createSpinner('Disabling WhatsApp widget...');
64
- spinner.start();
65
- await agent.updateAgent(agentId, { enableWhatsappWidget: false });
66
- spinner.succeed('WhatsApp widget disabled');
67
-
68
- } catch (error) {
69
- const message = error instanceof Error ? error.message : 'Unknown error';
70
- logger.error(message);
71
- process.exit(1);
72
- }
73
- });
74
-
75
- export const widgetCommand = widgetGroup;
@@ -1,156 +0,0 @@
1
- import { Command } from 'commander';
2
- import fs from 'fs/promises';
3
- import path from 'path';
4
- import { getStoredCredentials } from '../../utils/credentials.js';
5
- import { createApiClient } from '../../utils/api.js';
6
- import { logger } from '../../utils/logger.js';
7
- import { addExamples } from '../../utils/help.js';
8
- import { createSpinner, createTable, theme } from '../../utils/ui.js';
9
- import { WorkerDeployOptions, WorkerDeployResult } from '../../types/workers.js';
10
-
11
- export const deployCommand = new Command('deploy')
12
- .description('Deploy a worker to the Plazbot workspace')
13
- .argument('[file]', 'Worker TypeScript file (e.g.: ./workers/my-tool.ts)')
14
- .option('-n, --name <name>', 'Worker name (overrides the one in the file)')
15
- .option('-d, --description <desc>', 'Worker description')
16
- .option('--dev', 'Use development environment', false)
17
- .action(async (file: string | undefined, options: WorkerDeployOptions) => {
18
- try {
19
- const credentials = await getStoredCredentials();
20
-
21
- // Buscar archivos de workers
22
- const files = await resolveWorkerFiles(file);
23
-
24
- if (files.length === 0) {
25
- logger.error('No worker files found to deploy');
26
- logger.dim('Usage: plazbot workers deploy ./workers/my-tool.ts');
27
- logger.dim(' or: plazbot workers deploy (searches ./workers/ automatically)');
28
- process.exit(1);
29
- }
30
-
31
- const api = createApiClient({
32
- apiKey: credentials.apiKey,
33
- workspace: credentials.workspace,
34
- zone: credentials.zone,
35
- dev: options.dev,
36
- });
37
-
38
- logger.title(`Deploying ${files.length} worker${files.length > 1 ? 's' : ''}`);
39
- console.log();
40
-
41
- const results: { file: string; result?: WorkerDeployResult; error?: string }[] = [];
42
-
43
- for (const filePath of files) {
44
- const fileName = path.basename(filePath);
45
- const spinner = createSpinner(`Deploying ${fileName}...`);
46
- spinner.start();
47
-
48
- try {
49
- // Leer archivo fuente
50
- const sourceCode = await fs.readFile(filePath, 'utf-8');
51
-
52
- // Enviar al API
53
- const response = await api.post('/api/worker/deploy', {
54
- sourceCode,
55
- fileName,
56
- name: files.length === 1 ? options.name : undefined,
57
- description: files.length === 1 ? options.description : undefined,
58
- });
59
-
60
- const data = response.data as WorkerDeployResult;
61
- spinner.succeed(`${fileName} → ${data.name} (${data.type})`);
62
- results.push({ file: fileName, result: data });
63
-
64
- } catch (error: any) {
65
- const msg = error.response?.data?.message || error.message || 'Unknown error';
66
- spinner.fail(`${fileName}: ${msg}`);
67
- results.push({ file: fileName, error: msg });
68
- }
69
- }
70
-
71
- // Resumen
72
- console.log();
73
- const success = results.filter(r => r.result);
74
- const failed = results.filter(r => r.error);
75
-
76
- if (success.length > 0) {
77
- logger.success(`${success.length} worker${success.length > 1 ? 's' : ''} deployed`);
78
-
79
- const rows = success.map(r => [
80
- r.result!.name,
81
- r.result!.type,
82
- r.result!.status,
83
- r.result!.webhookUrl || r.result!.cronExpression || '—',
84
- ]);
85
-
86
- console.log(createTable(
87
- ['Name', 'Type', 'Status', 'URL/Cron'],
88
- rows,
89
- ));
90
- }
91
-
92
- if (failed.length > 0) {
93
- logger.warning(`${failed.length} worker${failed.length > 1 ? 's' : ''} failed`);
94
- failed.forEach(f => logger.dim(` ${f.file}: ${f.error}`));
95
- }
96
-
97
- // Mostrar webhook URLs si hay
98
- const webhooks = success.filter(r => r.result!.webhookUrl);
99
- if (webhooks.length > 0) {
100
- console.log();
101
- logger.title('Webhook URLs');
102
- webhooks.forEach(w => {
103
- logger.label(w.result!.name, theme.secondary(w.result!.webhookUrl!));
104
- });
105
- }
106
-
107
- console.log();
108
-
109
- if (options.dev) {
110
- logger.warning('Environment: development');
111
- }
112
-
113
- } catch (error) {
114
- const message = error instanceof Error ? error.message : 'Unknown error';
115
- logger.error(message);
116
- process.exit(1);
117
- }
118
- });
119
-
120
- addExamples(deployCommand, [
121
- { description: 'Deploy a single worker file',
122
- command: 'plazbot workers deploy ./workers/my-tool.ts' },
123
- { description: 'Deploy every TypeScript file inside ./workers automatically',
124
- command: 'plazbot workers deploy' },
125
- { description: 'Deploy with a custom name and description',
126
- command: 'plazbot workers deploy ./workers/cron.ts -n "Daily Report" -d "Generates daily KPIs"' },
127
- { description: 'Deploy against the local backend',
128
- command: 'plazbot workers deploy ./workers/test.ts --dev' },
129
- ]);
130
-
131
- // Resuelve los archivos a desplegar
132
- async function resolveWorkerFiles(file?: string): Promise<string[]> {
133
- if (file) {
134
- // Archivo especifico
135
- const resolved = path.resolve(file);
136
- try {
137
- await fs.access(resolved);
138
- return [resolved];
139
- } catch {
140
- throw new Error(`File not found: ${file}`);
141
- }
142
- }
143
-
144
- // Buscar en ./workers/ automaticamente
145
- const workersDir = path.resolve('workers');
146
- try {
147
- const entries = await fs.readdir(workersDir);
148
- const tsFiles = entries
149
- .filter(e => e.endsWith('.ts') && !e.endsWith('.d.ts'))
150
- .map(e => path.join(workersDir, e));
151
-
152
- return tsFiles;
153
- } catch {
154
- return [];
155
- }
156
- }
@@ -1,30 +0,0 @@
1
- import { Command } from 'commander';
2
- import { addExamples } from '../../utils/help.js';
3
- import { deployCommand } from './deploy.js';
4
- import { listCommand } from './list.js';
5
- import { logsCommand } from './logs.js';
6
- import { removeCommand } from './remove.js';
7
- import { secretCommand } from './secret.js';
8
- import { testCommand } from './test.js';
9
-
10
- export const workersCommands = new Command('workers')
11
- .description('Commands to manage workers (tools, syncs, schedules, webhooks)')
12
- .addCommand(deployCommand)
13
- .addCommand(listCommand)
14
- .addCommand(logsCommand)
15
- .addCommand(removeCommand)
16
- .addCommand(secretCommand)
17
- .addCommand(testCommand);
18
-
19
- addExamples(workersCommands, [
20
- { description: 'Deploy every worker file in ./workers automatically',
21
- command: 'plazbot workers deploy' },
22
- { description: 'List active workers',
23
- command: 'plazbot workers list -s active' },
24
- { description: 'Run a worker with a JSON payload',
25
- command: 'plazbot workers test my-tool -p \'{"product":"iPhone 15"}\'' },
26
- { description: 'Save a secret for workers (plz.env.KEY)',
27
- command: 'plazbot workers secret set STRIPE_API_KEY sk_live_xxxxx' },
28
- { description: 'View the last 100 executions of a worker',
29
- command: 'plazbot workers logs my-tool -l 100' },
30
- ]);
@@ -1,105 +0,0 @@
1
- import { Command } from 'commander';
2
- import { getStoredCredentials } from '../../utils/credentials.js';
3
- import { createApiClient } from '../../utils/api.js';
4
- import { logger } from '../../utils/logger.js';
5
- import { addExamples } from '../../utils/help.js';
6
- import { createSpinner, createTable, theme, statusBadge, formatDate } from '../../utils/ui.js';
7
- import { WorkerListOptions, WorkerListItem } from '../../types/workers.js';
8
-
9
- export const listCommand = new Command('list')
10
- .description('List all workers in the workspace')
11
- .option('-t, --type <type>', 'Filter by type (tool, worker, sync, schedule, webhook)')
12
- .option('-s, --status <status>', 'Filter by status (active, inactive, error)')
13
- .option('--dev', 'Use development environment', false)
14
- .action(async (options: WorkerListOptions) => {
15
- try {
16
- const credentials = await getStoredCredentials();
17
- const api = createApiClient({
18
- apiKey: credentials.apiKey,
19
- workspace: credentials.workspace,
20
- zone: credentials.zone,
21
- dev: options.dev,
22
- });
23
-
24
- const spinner = createSpinner('Fetching workers...');
25
- spinner.start();
26
-
27
- const params: Record<string, string> = {};
28
- if (options.type) params.type = options.type;
29
- if (options.status) params.status = options.status;
30
-
31
- const response = await api.get('/api/worker', { params });
32
- const workers: WorkerListItem[] = response.data;
33
-
34
- spinner.stop();
35
-
36
- if (!workers || workers.length === 0) {
37
- logger.info('\n No workers found in this workspace');
38
- logger.dim(' Deploy your first worker: plazbot workers deploy ./workers/my-tool.ts');
39
- console.log();
40
- return;
41
- }
42
-
43
- logger.title(`Workers (${workers.length})`);
44
-
45
- const rows = workers.map(w => [
46
- w.name,
47
- typeLabel(w.type),
48
- w.status === 'active' ? theme.success('active')
49
- : w.status === 'error' ? theme.error('error')
50
- : theme.muted('inactive'),
51
- `${w.executionCount}`,
52
- w.errorCount > 0 ? theme.error(`${w.errorCount}`) : theme.muted('0'),
53
- w.avgDurationMs > 0 ? `${w.avgDurationMs}ms` : '—',
54
- w.lastExecutedAt ? formatDate(w.lastExecutedAt) : '—',
55
- ]);
56
-
57
- console.log(createTable(
58
- ['Name', 'Type', 'Status', 'Executions', 'Errors', 'Duration', 'Last execution'],
59
- rows,
60
- ));
61
-
62
- // Mostrar workers con error
63
- const errored = workers.filter(w => w.status === 'error');
64
- if (errored.length > 0) {
65
- console.log();
66
- logger.warning('Workers with errors:');
67
- errored.forEach(w => {
68
- logger.dim(` ${w.name}: ${w.lastError || 'no details'}`);
69
- });
70
- }
71
-
72
- console.log();
73
-
74
- if (options.dev) {
75
- logger.warning('Environment: development');
76
- }
77
-
78
- } catch (error) {
79
- const message = error instanceof Error ? error.message : 'Unknown error';
80
- logger.error(message);
81
- process.exit(1);
82
- }
83
- });
84
-
85
- addExamples(listCommand, [
86
- { description: 'List every worker in the workspace',
87
- command: 'plazbot workers list' },
88
- { description: 'Only show schedules',
89
- command: 'plazbot workers list -t schedule' },
90
- { description: 'Show only workers with errors',
91
- command: 'plazbot workers list -s error' },
92
- { description: 'Filter active webhooks',
93
- command: 'plazbot workers list -t webhook -s active' },
94
- ]);
95
-
96
- function typeLabel(type: string): string {
97
- const labels: Record<string, string> = {
98
- tool: theme.secondary('tool'),
99
- worker: theme.primary('worker'),
100
- sync: theme.accent('sync'),
101
- schedule: theme.muted('schedule'),
102
- webhook: theme.warning('webhook'),
103
- };
104
- return labels[type] || type;
105
- }