plazbot-cli 0.2.26 → 0.3.2

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 (178) hide show
  1. package/CLAUDE.md +34 -5
  2. package/README.md +21 -0
  3. package/dist/cli.js +32 -20
  4. package/dist/commands/agent/ai-config.js +98 -50
  5. package/dist/commands/agent/chat.js +80 -74
  6. package/dist/commands/agent/copy.js +23 -21
  7. package/dist/commands/agent/create.js +42 -72
  8. package/dist/commands/agent/delete.js +29 -30
  9. package/dist/commands/agent/enable-widget.js +30 -26
  10. package/dist/commands/agent/export.js +90 -77
  11. package/dist/commands/agent/files.js +68 -60
  12. package/dist/commands/agent/get.js +101 -87
  13. package/dist/commands/agent/index.js +53 -39
  14. package/dist/commands/agent/list.js +26 -24
  15. package/dist/commands/agent/monitor.js +91 -86
  16. package/dist/commands/agent/on-message.js +40 -37
  17. package/dist/commands/agent/set.js +62 -59
  18. package/dist/commands/agent/templates.js +109 -108
  19. package/dist/commands/agent/tools.js +64 -65
  20. package/dist/commands/agent/update.js +28 -27
  21. package/dist/commands/agent/validate.js +127 -0
  22. package/dist/commands/agent/wizard.js +152 -159
  23. package/dist/commands/auth/index.js +7 -10
  24. package/dist/commands/auth/login.js +50 -37
  25. package/dist/commands/auth/logout.js +16 -14
  26. package/dist/commands/auth/status.js +19 -16
  27. package/dist/commands/portal/add-agent.js +26 -24
  28. package/dist/commands/portal/add-link.js +21 -17
  29. package/dist/commands/portal/clear-links.js +17 -15
  30. package/dist/commands/portal/create.js +25 -21
  31. package/dist/commands/portal/delete.js +31 -30
  32. package/dist/commands/portal/get.js +33 -31
  33. package/dist/commands/portal/index.js +30 -22
  34. package/dist/commands/portal/list.js +34 -30
  35. package/dist/commands/portal/update.js +41 -33
  36. package/dist/commands/whatsapp/broadcast.js +40 -37
  37. package/dist/commands/whatsapp/channels.js +40 -34
  38. package/dist/commands/whatsapp/chat.js +33 -32
  39. package/dist/commands/whatsapp/connect.js +53 -52
  40. package/dist/commands/whatsapp/delete-webhook.js +19 -17
  41. package/dist/commands/whatsapp/index.js +35 -25
  42. package/dist/commands/whatsapp/register-webhook.js +21 -19
  43. package/dist/commands/whatsapp/send-template.js +39 -31
  44. package/dist/commands/whatsapp/send.js +27 -23
  45. package/dist/commands/whatsapp/widget.js +35 -31
  46. package/dist/commands/workers/deploy.js +49 -44
  47. package/dist/commands/workers/index.js +28 -18
  48. package/dist/commands/workers/list.js +43 -35
  49. package/dist/commands/workers/logs.js +38 -32
  50. package/dist/commands/workers/remove.js +38 -37
  51. package/dist/commands/workers/secret.js +63 -58
  52. package/dist/commands/workers/test.js +44 -36
  53. package/dist/schemas/agent.config.schema.json +569 -0
  54. package/dist/studio/api/sseClient.js +97 -0
  55. package/dist/studio/api/studioApi.js +25 -0
  56. package/dist/studio/api/types.js +16 -0
  57. package/dist/studio/components/AgentPanel.js +35 -0
  58. package/dist/studio/components/App.js +214 -0
  59. package/dist/studio/components/ChatLog.js +59 -0
  60. package/dist/studio/components/Footer.js +11 -0
  61. package/dist/studio/components/Header.js +8 -0
  62. package/dist/studio/components/Input.js +15 -0
  63. package/dist/studio/components/Message.js +56 -0
  64. package/dist/studio/components/Suggestions.js +11 -0
  65. package/dist/studio/components/ToolCall.js +33 -0
  66. package/dist/studio/components/WhatsappConnectCard.js +57 -0
  67. package/dist/studio/index.js +42 -0
  68. package/dist/studio/render/json.js +16 -0
  69. package/dist/studio/render/markdown.js +86 -0
  70. package/dist/studio/render/steps.js +58 -0
  71. package/dist/studio/runOneShot.js +96 -0
  72. package/dist/studio/runRepl.js +52 -0
  73. package/dist/studio/slash/handlers.js +199 -0
  74. package/dist/studio/slash/parser.js +46 -0
  75. package/dist/studio/slash/registry.js +16 -0
  76. package/dist/studio/state/store.js +181 -0
  77. package/dist/studio/whatsapp/api.js +63 -0
  78. package/dist/studio/whatsapp/polling.js +77 -0
  79. package/dist/studio/whatsapp/types.js +31 -0
  80. package/dist/types/agent.js +1 -2
  81. package/dist/types/auth.js +1 -2
  82. package/dist/types/common.js +1 -2
  83. package/dist/types/message.js +1 -2
  84. package/dist/types/portal.js +1 -2
  85. package/dist/types/workers.js +1 -2
  86. package/dist/utils/agent-errors.js +46 -0
  87. package/dist/utils/api.js +8 -9
  88. package/dist/utils/banner.js +33 -34
  89. package/dist/utils/credentials.js +12 -20
  90. package/dist/utils/help.js +44 -0
  91. package/dist/utils/logger.js +13 -19
  92. package/dist/utils/ui.js +35 -49
  93. package/package.json +22 -10
  94. package/src/cli.ts +24 -8
  95. package/src/commands/agent/ai-config.ts +89 -34
  96. package/src/commands/agent/chat.ts +49 -37
  97. package/src/commands/agent/copy.ts +19 -13
  98. package/src/commands/agent/create.ts +32 -22
  99. package/src/commands/agent/delete.ts +24 -18
  100. package/src/commands/agent/enable-widget.ts +31 -23
  101. package/src/commands/agent/export.ts +72 -51
  102. package/src/commands/agent/files.ts +51 -39
  103. package/src/commands/agent/get.ts +86 -66
  104. package/src/commands/agent/index.ts +36 -18
  105. package/src/commands/agent/list.ts +22 -16
  106. package/src/commands/agent/monitor.ts +67 -56
  107. package/src/commands/agent/on-message.ts +36 -27
  108. package/src/commands/agent/set.ts +47 -37
  109. package/src/commands/agent/templates.ts +90 -82
  110. package/src/commands/agent/tools.ts +53 -47
  111. package/src/commands/agent/update.ts +28 -20
  112. package/src/commands/agent/validate.ts +135 -0
  113. package/src/commands/agent/wizard.ts +114 -114
  114. package/src/commands/auth/index.ts +3 -3
  115. package/src/commands/auth/login.ts +44 -29
  116. package/src/commands/auth/logout.ts +16 -10
  117. package/src/commands/auth/status.ts +14 -8
  118. package/src/commands/portal/add-agent.ts +23 -17
  119. package/src/commands/portal/add-link.ts +17 -9
  120. package/src/commands/portal/clear-links.ts +13 -7
  121. package/src/commands/portal/create.ts +20 -12
  122. package/src/commands/portal/delete.ts +28 -20
  123. package/src/commands/portal/get.ts +25 -19
  124. package/src/commands/portal/index.ts +22 -10
  125. package/src/commands/portal/list.ts +27 -19
  126. package/src/commands/portal/update.ts +38 -26
  127. package/src/commands/whatsapp/broadcast.ts +28 -18
  128. package/src/commands/whatsapp/channels.ts +31 -20
  129. package/src/commands/whatsapp/chat.ts +20 -12
  130. package/src/commands/whatsapp/connect.ts +39 -31
  131. package/src/commands/whatsapp/delete-webhook.ts +15 -9
  132. package/src/commands/whatsapp/index.ts +24 -10
  133. package/src/commands/whatsapp/register-webhook.ts +16 -10
  134. package/src/commands/whatsapp/send-template.ts +33 -21
  135. package/src/commands/whatsapp/send.ts +23 -15
  136. package/src/commands/whatsapp/widget.ts +25 -17
  137. package/src/commands/workers/deploy.ts +34 -22
  138. package/src/commands/workers/index.ts +21 -7
  139. package/src/commands/workers/list.ts +31 -19
  140. package/src/commands/workers/logs.ts +30 -20
  141. package/src/commands/workers/remove.ts +30 -22
  142. package/src/commands/workers/secret.ts +46 -34
  143. package/src/commands/workers/test.ts +34 -22
  144. package/src/schemas/agent.config.schema.json +569 -0
  145. package/src/studio/api/sseClient.ts +91 -0
  146. package/src/studio/api/studioApi.ts +27 -0
  147. package/src/studio/api/types.ts +96 -0
  148. package/src/studio/components/App.tsx +266 -0
  149. package/src/studio/components/ChatLog.tsx +95 -0
  150. package/src/studio/components/Footer.tsx +38 -0
  151. package/src/studio/components/Header.tsx +39 -0
  152. package/src/studio/components/Input.tsx +32 -0
  153. package/src/studio/components/Message.tsx +87 -0
  154. package/src/studio/components/Suggestions.tsx +26 -0
  155. package/src/studio/components/ToolCall.tsx +58 -0
  156. package/src/studio/components/WhatsappConnectCard.tsx +139 -0
  157. package/src/studio/index.ts +58 -0
  158. package/src/studio/render/markdown.ts +93 -0
  159. package/src/studio/render/steps.ts +57 -0
  160. package/src/studio/runOneShot.ts +114 -0
  161. package/src/studio/runRepl.tsx +76 -0
  162. package/src/studio/slash/handlers.ts +226 -0
  163. package/src/studio/slash/parser.ts +41 -0
  164. package/src/studio/slash/registry.ts +54 -0
  165. package/src/studio/state/store.ts +273 -0
  166. package/src/studio/whatsapp/api.ts +96 -0
  167. package/src/studio/whatsapp/polling.ts +93 -0
  168. package/src/studio/whatsapp/types.ts +80 -0
  169. package/src/types/agent.ts +1 -1
  170. package/src/types/auth.ts +4 -3
  171. package/src/types/portal.ts +1 -1
  172. package/src/types/workers.ts +1 -1
  173. package/src/utils/agent-errors.ts +67 -0
  174. package/src/utils/api.ts +6 -0
  175. package/src/utils/banner.ts +14 -9
  176. package/src/utils/credentials.ts +6 -5
  177. package/src/utils/help.ts +51 -0
  178. package/tsconfig.json +9 -6
@@ -1,12 +1,13 @@
1
1
  import { Command } from 'commander';
2
2
  import { Portal } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials';
4
- import { logger } from '../../utils/logger';
5
- import { PortalCommandOptions } from '../../types/portal';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { PortalCommandOptions } from '../../types/portal.js';
6
7
 
7
8
  export const listCommand = new Command('list')
8
- .description('Muestra el portal asociado al workspace')
9
- .option('--dev', 'Usar ambiente de desarrollo', false)
9
+ .description('Show the portal associated with the workspace')
10
+ .option('--dev', 'Use development environment', false)
10
11
  .action(async (options: PortalCommandOptions) => {
11
12
  try {
12
13
  // Obtener credenciales guardadas
@@ -22,50 +23,57 @@ export const listCommand = new Command('list')
22
23
  const response = await portal.getExistsPortal();
23
24
  const portalDetails = response.portal;
24
25
 
25
- logger.title('Portal encontrado');
26
+ logger.title('Portal found');
26
27
  logger.label('ID', portalDetails.id);
27
- logger.label('Nombre', portalDetails.name);
28
+ logger.label('Name', portalDetails.name);
28
29
  logger.label('URL', portalDetails.url);
29
- logger.label('Acceso', portalDetails.access || 'N/A');
30
- logger.label('Estado', portalDetails.disabled ? 'Deshabilitado' : 'Habilitado');
30
+ logger.label('Access', portalDetails.access || 'N/A');
31
+ logger.label('Status', portalDetails.disabled ? 'Disabled' : 'Enabled');
31
32
 
32
33
  if (portalDetails.title) {
33
- logger.label('Titulo', portalDetails.title);
34
+ logger.label('Title', portalDetails.title);
34
35
  }
35
36
  if (portalDetails.subtitle) {
36
- logger.label('Subtitulo', portalDetails.subtitle);
37
+ logger.label('Subtitle', portalDetails.subtitle);
37
38
  }
38
39
 
39
40
  if (portalDetails.logo) {
40
- logger.title('Recursos');
41
+ logger.title('Assets');
41
42
  logger.label('Logo', portalDetails.logo);
42
43
  if (portalDetails.logodark) {
43
- logger.label('Logo (modo oscuro)', portalDetails.logodark);
44
+ logger.label('Logo (dark mode)', portalDetails.logodark);
44
45
  }
45
46
  }
46
47
 
47
48
  const portalAny = portalDetails as any;
48
49
  if (portalAny.links && portalAny.links.length > 0) {
49
- logger.title('Enlaces');
50
+ logger.title('Links');
50
51
  portalAny.links.forEach((link: { value: string; url: string }) => {
51
52
  logger.label(link.value, link.url);
52
53
  });
53
54
  }
54
55
 
55
56
  if (portalAny.agents && portalAny.agents.length > 0) {
56
- logger.title('Agentes asociados');
57
+ logger.title('Associated agents');
57
58
  portalAny.agents.forEach((agent: { name: string; id: string }) => {
58
59
  logger.label(agent.name, agent.id);
59
60
  });
60
61
  }
61
-
62
+
62
63
  if (options.dev) {
63
- logger.warning('\nAmbiente: desarrollo');
64
+ logger.warning('\nEnvironment: development');
64
65
  }
65
66
 
66
67
  } catch (error) {
67
- const message = error instanceof Error ? error.message : 'Error desconocido al listar el portal';
68
+ const message = error instanceof Error ? error.message : 'Unknown error while listing the portal';
68
69
  logger.error(message);
69
70
  process.exit(1);
70
71
  }
71
- });
72
+ });
73
+
74
+ addExamples(listCommand, [
75
+ { description: 'Show the portal of the active workspace',
76
+ command: 'plazbot portal list' },
77
+ { description: 'Use the development backend',
78
+ command: 'plazbot portal list --dev' },
79
+ ]);
@@ -1,21 +1,22 @@
1
1
  import { Command } from 'commander';
2
2
  import { Portal } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials';
4
- import { logger } from '../../utils/logger';
5
- import { PortalCommandOptions } from '../../types/portal';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { PortalCommandOptions } from '../../types/portal.js';
6
7
 
7
8
  export const updateCommand = new Command('update')
8
- .description('Actualiza un portal existente')
9
- .argument('<portalId>', 'ID del portal a actualizar')
10
- .option('-n, --name <name>', 'Nuevo nombre del portal')
11
- .option('-t, --title <title>', 'Nuevo título del portal')
12
- .option('-s, --subtitle <subtitle>', 'Nuevo subtítulo del portal')
13
- .option('-l, --logo <url>', 'Nueva URL del logo')
14
- .option('-d, --logo-dark <url>', 'Nueva URL del logo en modo oscuro')
15
- .option('-a, --access <type>', 'Tipo de acceso (direct o form)')
16
- .option('--disabled <value>', 'Estado de deshabilitación (true o false)')
17
- .option('--brand-off <value>', 'Estado de marca deshabilitada (true o false)')
18
- .option('--dev', 'Usar ambiente de desarrollo', false)
9
+ .description('Update an existing portal')
10
+ .argument('<portalId>', 'ID of the portal to update')
11
+ .option('-n, --name <name>', 'New portal name')
12
+ .option('-t, --title <title>', 'New portal title')
13
+ .option('-s, --subtitle <subtitle>', 'New portal subtitle')
14
+ .option('-l, --logo <url>', 'New logo URL')
15
+ .option('-d, --logo-dark <url>', 'New dark-mode logo URL')
16
+ .option('-a, --access <type>', 'Access type (direct or form)')
17
+ .option('--disabled <value>', 'Disabled state (true or false)')
18
+ .option('--brand-off <value>', 'Brand-off state (true or false)')
19
+ .option('--dev', 'Use development environment', false)
19
20
  .action(async (portalId: string, options: PortalCommandOptions) => {
20
21
  try {
21
22
  // Obtener credenciales guardadas
@@ -31,7 +32,7 @@ export const updateCommand = new Command('update')
31
32
  // Obtener detalles actuales del portal
32
33
  const currentPortal = await portal.getPortal(portalId);
33
34
 
34
- logger.title('Portal actual');
35
+ logger.title('Current portal');
35
36
  logger.json(currentPortal.portal);
36
37
 
37
38
  // Construir objeto de actualización solo con los campos proporcionados
@@ -44,38 +45,49 @@ export const updateCommand = new Command('update')
44
45
  if (options.logoDark) updateData.logodark = options.logoDark;
45
46
  if (options.access) {
46
47
  if (options.access !== 'direct' && options.access !== 'form') {
47
- throw new Error('El tipo de acceso debe ser "direct" o "form"');
48
+ throw new Error('Access type must be "direct" or "form"');
48
49
  }
49
50
  updateData.access = options.access;
50
51
  }
51
52
  if (options.disabled) {
52
53
  if (options.disabled !== 'true' && options.disabled !== 'false') {
53
- throw new Error('El valor de disabled debe ser "true" o "false"');
54
+ throw new Error('The disabled value must be "true" or "false"');
54
55
  }
55
56
  updateData.disabled = options.disabled === 'true';
56
57
  }
57
58
  if (options.brandOff) {
58
59
  if (options.brandOff !== 'true' && options.brandOff !== 'false') {
59
- throw new Error('El valor de brand-off debe ser "true" o "false"');
60
+ throw new Error('The brand-off value must be "true" or "false"');
60
61
  }
61
62
  updateData.brandOff = options.brandOff === 'true';
62
63
  }
63
64
 
64
- logger.title('Cambios a aplicar');
65
+ logger.title('Changes to apply');
65
66
  logger.json(updateData);
66
-
67
+
67
68
  const result = await portal.updatePortal(updateData);
68
69
 
69
- logger.success('Portal actualizado exitosamente');
70
- logger.label('Mensaje', result.message);
71
-
70
+ logger.success('Portal updated successfully');
71
+ logger.label('Message', result.message);
72
+
72
73
  if (options.dev) {
73
- logger.warning('\nAmbiente: desarrollo');
74
+ logger.warning('\nEnvironment: development');
74
75
  }
75
76
 
76
77
  } catch (error) {
77
- const message = error instanceof Error ? error.message : 'Error desconocido al actualizar el portal';
78
+ const message = error instanceof Error ? error.message : 'Unknown error while updating the portal';
78
79
  logger.error(message);
79
80
  process.exit(1);
80
81
  }
81
- });
82
+ });
83
+
84
+ addExamples(updateCommand, [
85
+ { description: 'Rename a portal',
86
+ command: 'plazbot portal update prt_AbcDef123 -n "Support Center"' },
87
+ { description: 'Switch access to form mode and update title',
88
+ command: 'plazbot portal update prt_AbcDef123 -a form -t "Sign in to continue"' },
89
+ { description: 'Disable a portal',
90
+ command: 'plazbot portal update prt_AbcDef123 --disabled true' },
91
+ { description: 'Hide the Plazbot brand and update the logo',
92
+ command: 'plazbot portal update prt_AbcDef123 --brand-off true -l https://files.example.com/logo.png' },
93
+ ]);
@@ -1,17 +1,18 @@
1
1
  import { Command } from 'commander';
2
2
  import { Message } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials';
4
- import { logger } from '../../utils/logger';
5
- import { createSpinner, theme, section, progressBar } from '../../utils/ui';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { createSpinner, theme, section, progressBar } from '../../utils/ui.js';
6
7
  import fs from 'fs/promises';
7
8
 
8
9
  export const broadcastCommand = new Command('broadcast')
9
- .description('Envio masivo de mensajes de template WhatsApp')
10
- .requiredOption('-t, --template <name>', 'Nombre del template')
11
- .requiredOption('--phones <file>', 'Archivo CSV con numeros de telefono (uno por linea)')
12
- .option('--var <vars...>', 'Variables del body (formato: name=valor)')
13
- .option('--delay <ms>', 'Delay entre mensajes en ms', '1000')
14
- .option('--dev', 'Usar ambiente de desarrollo', false)
10
+ .description('Bulk send WhatsApp template messages')
11
+ .requiredOption('-t, --template <name>', 'Template name')
12
+ .requiredOption('--phones <file>', 'CSV file with phone numbers (one per line)')
13
+ .option('--var <vars...>', 'Body variables (format: name=value)')
14
+ .option('--delay <ms>', 'Delay between messages in ms', '1000')
15
+ .option('--dev', 'Use development environment', false)
15
16
  .action(async (options: any) => {
16
17
  try {
17
18
  const credentials = await getStoredCredentials();
@@ -31,19 +32,19 @@ export const broadcastCommand = new Command('broadcast')
31
32
  .map(line => line.trim())
32
33
  .filter(line => line && !line.startsWith('#'));
33
34
  } catch {
34
- throw new Error(`No se pudo leer el archivo: ${options.phones}`);
35
+ throw new Error(`Could not read file: ${options.phones}`);
35
36
  }
36
37
 
37
38
  if (phones.length === 0) {
38
- throw new Error('El archivo no contiene numeros de telefono');
39
+ throw new Error('The file does not contain phone numbers');
39
40
  }
40
41
 
41
42
  // Parsear variables
42
43
  const variablesBody = parseVariables(options.var);
43
44
 
44
- console.log(section('Broadcast WhatsApp'));
45
+ console.log(section('WhatsApp Broadcast'));
45
46
  logger.label('Template', options.template);
46
- logger.label('Destinatarios', String(phones.length));
47
+ logger.label('Recipients', String(phones.length));
47
48
  logger.label('Delay', `${options.delay}ms`);
48
49
  if (variablesBody.length > 0) {
49
50
  logger.label('Variables', variablesBody.map(v => `${v.variable}=${v.value}`).join(', '));
@@ -67,7 +68,7 @@ export const broadcastCommand = new Command('broadcast')
67
68
  sent++;
68
69
  } catch {
69
70
  failed++;
70
- console.log(theme.error(` ✖ Fallo: ${phone}`));
71
+ console.log(theme.error(` ✖ Failed: ${phone}`));
71
72
  }
72
73
 
73
74
  // Progress
@@ -79,18 +80,27 @@ export const broadcastCommand = new Command('broadcast')
79
80
  }
80
81
  }
81
82
 
82
- console.log(section('Resultado'));
83
- logger.label('Enviados', theme.success(String(sent)));
84
- logger.label('Fallidos', failed > 0 ? theme.error(String(failed)) : '0');
83
+ console.log(section('Result'));
84
+ logger.label('Sent', theme.success(String(sent)));
85
+ logger.label('Failed', failed > 0 ? theme.error(String(failed)) : '0');
85
86
  logger.label('Total', String(phones.length));
86
87
 
87
88
  } catch (error: unknown) {
88
- const message = (error as Error)?.message || 'Error desconocido';
89
+ const message = (error as Error)?.message || 'Unknown error';
89
90
  logger.error(message);
90
91
  process.exit(1);
91
92
  }
92
93
  });
93
94
 
95
+ addExamples(broadcastCommand, [
96
+ { description: 'Broadcast a template to a phone list (default 1s delay)',
97
+ command: 'plazbot whatsapp broadcast -t welcome --phones ./phones.csv' },
98
+ { description: 'Broadcast with body variables',
99
+ command: 'plazbot whatsapp broadcast -t promo --phones ./contacts.csv --var amount=20 code=PROMO20' },
100
+ { description: 'Slow broadcast (3s delay) to avoid rate limits',
101
+ command: 'plazbot whatsapp broadcast -t reminder --phones ./list.csv --delay 3000' },
102
+ ]);
103
+
94
104
  function parseVariables(vars: string[] | undefined): { variable: string; value: string }[] {
95
105
  if (!vars) return [];
96
106
  return vars.map(v => {
@@ -1,12 +1,13 @@
1
1
  import { Command } from 'commander';
2
2
  import { Agent } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials';
4
- import { logger } from '../../utils/logger';
5
- import { createSpinner, createTable, theme, section, statusBadge } from '../../utils/ui';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { createSpinner, createTable, theme, section, statusBadge } from '../../utils/ui.js';
6
7
 
7
8
  export const channelsCommand = new Command('channels')
8
- .description('Listar agentes con canales de WhatsApp asignados')
9
- .option('--dev', 'Usar ambiente de desarrollo', false)
9
+ .description('List agents with assigned WhatsApp channels')
10
+ .option('--dev', 'Use development environment', false)
10
11
  .action(async (options: any) => {
11
12
  try {
12
13
  const credentials = await getStoredCredentials();
@@ -17,20 +18,20 @@ export const channelsCommand = new Command('channels')
17
18
  ...(options.dev && { customUrl: "http://localhost:5090" })
18
19
  });
19
20
 
20
- const spinner = createSpinner('Cargando canales...');
21
+ const spinner = createSpinner('Loading channels...');
21
22
  spinner.start();
22
23
  const agents = await agent.getAgents();
23
24
  spinner.stop();
24
25
 
25
- console.log(section('Canales WhatsApp'));
26
+ console.log(section('WhatsApp Channels'));
26
27
 
27
28
  const whatsappAgents = (agents || []).filter((a: any) =>
28
29
  a.channels && a.channels.some((c: any) => c.channel === 'whatsapp')
29
30
  );
30
31
 
31
32
  if (whatsappAgents.length === 0) {
32
- console.log(theme.muted('\n No hay agentes con WhatsApp configurado'));
33
- console.log(theme.muted(' Usa el wizard: plazbot agent create\n'));
33
+ console.log(theme.muted('\n No agents with WhatsApp configured'));
34
+ console.log(theme.muted(' Use the wizard: plazbot agent create\n'));
34
35
  return;
35
36
  }
36
37
 
@@ -44,20 +45,25 @@ export const channelsCommand = new Command('channels')
44
45
  ];
45
46
  });
46
47
 
47
- console.log(createTable(['Agent ID', 'Nombre', 'Numero WhatsApp', 'Estado'], rows));
48
+ console.log(createTable(['Agent ID', 'Name', 'WhatsApp Number', 'Status'], rows));
48
49
 
49
50
  } catch (error) {
50
- const message = error instanceof Error ? error.message : 'Error desconocido';
51
+ const message = error instanceof Error ? error.message : 'Unknown error';
51
52
  logger.error(message);
52
53
  process.exit(1);
53
54
  }
54
55
  });
55
56
 
57
+ addExamples(channelsCommand, [
58
+ { description: 'List agents that have a WhatsApp number assigned',
59
+ command: 'plazbot whatsapp channels' },
60
+ ]);
61
+
56
62
  export const assignCommand = new Command('assign')
57
- .description('Asignar un agente a un numero de WhatsApp')
58
- .argument('<phone>', 'Numero de WhatsApp')
59
- .argument('<agentId>', 'ID del agente')
60
- .option('--dev', 'Usar ambiente de desarrollo', false)
63
+ .description('Assign an agent to a WhatsApp number')
64
+ .argument('<phone>', 'WhatsApp number')
65
+ .argument('<agentId>', 'Agent ID')
66
+ .option('--dev', 'Use development environment', false)
61
67
  .action(async (phone: string, agentId: string, options: any) => {
62
68
  try {
63
69
  const credentials = await getStoredCredentials();
@@ -68,7 +74,7 @@ export const assignCommand = new Command('assign')
68
74
  ...(options.dev && { customUrl: "http://localhost:5090" })
69
75
  });
70
76
 
71
- const spinner = createSpinner('Cargando agente...');
77
+ const spinner = createSpinner('Loading agent...');
72
78
  spinner.start();
73
79
  const agentData = await agent.getAgentById({ id: agentId });
74
80
  spinner.stop();
@@ -78,21 +84,26 @@ export const assignCommand = new Command('assign')
78
84
  // Verificar si ya tiene este canal
79
85
  const existing = channels.findIndex((c: any) => c.channel === 'whatsapp' && c.key === phone);
80
86
  if (existing >= 0) {
81
- logger.warning('Este numero ya esta asignado a este agente');
87
+ logger.warning('This number is already assigned to this agent');
82
88
  return;
83
89
  }
84
90
 
85
91
  // Agregar canal
86
92
  channels.push({ channel: 'whatsapp', key: phone, multianswer: false });
87
93
 
88
- const updateSpinner = createSpinner('Asignando...');
94
+ const updateSpinner = createSpinner('Assigning...');
89
95
  updateSpinner.start();
90
96
  await agent.updateAgent(agentId, { channels });
91
- updateSpinner.succeed(`Agente "${agentData.name}" asignado a WhatsApp ${phone}`);
97
+ updateSpinner.succeed(`Agent "${agentData.name}" assigned to WhatsApp ${phone}`);
92
98
 
93
99
  } catch (error) {
94
- const message = error instanceof Error ? error.message : 'Error desconocido';
100
+ const message = error instanceof Error ? error.message : 'Unknown error';
95
101
  logger.error(message);
96
102
  process.exit(1);
97
103
  }
98
104
  });
105
+
106
+ addExamples(assignCommand, [
107
+ { description: 'Assign a WhatsApp number to an agent',
108
+ command: 'plazbot whatsapp assign 51912345678 agt_AbcDef123' },
109
+ ]);
@@ -1,15 +1,16 @@
1
1
  import { Command } from 'commander';
2
2
  import { Message } from 'plazbot';
3
- import { getStoredCredentials } from '../../utils/credentials';
4
- import { logger } from '../../utils/logger';
5
- import { createSpinner, theme } from '../../utils/ui';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { createSpinner, theme } from '../../utils/ui.js';
6
7
  import readline from 'readline';
7
8
  import chalk from 'chalk';
8
9
 
9
10
  export const whatsappChatCommand = new Command('chat')
10
- .description('Chat interactivo directo por WhatsApp')
11
- .argument('<phone>', 'Numero de telefono destino (con codigo de pais)')
12
- .option('--dev', 'Usar ambiente de desarrollo', false)
11
+ .description('Interactive direct chat over WhatsApp')
12
+ .argument('<phone>', 'Destination phone number (with country code)')
13
+ .option('--dev', 'Use development environment', false)
13
14
  .action(async (phone: string, options: any) => {
14
15
  try {
15
16
  const credentials = await getStoredCredentials();
@@ -30,8 +31,8 @@ export const whatsappChatCommand = new Command('chat')
30
31
  console.log();
31
32
  console.log(chalk.hex('#25D366')(' ┌' + '─'.repeat(50) + '┐'));
32
33
  console.log(chalk.hex('#25D366')(' │') + chalk.bold(` WhatsApp Chat`).padEnd(60) + chalk.hex('#25D366')('│'));
33
- console.log(chalk.hex('#25D366')(' │') + chalk.gray(` Destino: ${phone}`).padEnd(60) + chalk.hex('#25D366')('│'));
34
- console.log(chalk.hex('#25D366')(' │') + chalk.gray(' /exit para salir').padEnd(60) + chalk.hex('#25D366')('│'));
34
+ console.log(chalk.hex('#25D366')(' │') + chalk.gray(` Destination: ${phone}`).padEnd(60) + chalk.hex('#25D366')('│'));
35
+ console.log(chalk.hex('#25D366')(' │') + chalk.gray(' /exit to quit').padEnd(60) + chalk.hex('#25D366')('│'));
35
36
  console.log(chalk.hex('#25D366')(' └' + '─'.repeat(50) + '┘'));
36
37
  console.log();
37
38
 
@@ -43,13 +44,13 @@ export const whatsappChatCommand = new Command('chat')
43
44
  }
44
45
 
45
46
  if (message.toLowerCase() === '/exit') {
46
- console.log(chalk.gray('\n Chat terminado.\n'));
47
+ console.log(chalk.gray('\n Chat ended.\n'));
47
48
  rl.close();
48
49
  return;
49
50
  }
50
51
 
51
52
  try {
52
- const spinner = createSpinner('Enviando...');
53
+ const spinner = createSpinner('Sending...');
53
54
  spinner.start();
54
55
 
55
56
  await messageClient.onWhatsappMessage({
@@ -57,7 +58,7 @@ export const whatsappChatCommand = new Command('chat')
57
58
  to: phone,
58
59
  });
59
60
 
60
- spinner.succeed('Enviado');
61
+ spinner.succeed('Sent');
61
62
  ask();
62
63
  } catch (error) {
63
64
  const msg = error instanceof Error ? error.message : 'Error';
@@ -70,8 +71,15 @@ export const whatsappChatCommand = new Command('chat')
70
71
  ask();
71
72
 
72
73
  } catch (error) {
73
- const message = error instanceof Error ? error.message : 'Error desconocido';
74
+ const message = error instanceof Error ? error.message : 'Unknown error';
74
75
  logger.error(message);
75
76
  process.exit(1);
76
77
  }
77
78
  });
79
+
80
+ addExamples(whatsappChatCommand, [
81
+ { description: 'Open an interactive chat with a WhatsApp number',
82
+ command: 'plazbot whatsapp chat 51912345678' },
83
+ { description: 'Chat through the development backend',
84
+ command: 'plazbot whatsapp chat 51912345678 --dev' },
85
+ ]);