plazbot-cli 0.2.25 → 0.3.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 (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 +59 -55
  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 +32 -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 +21 -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 +48 -36
  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 +32 -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
@@ -2,7 +2,7 @@ import inquirer from 'inquirer';
2
2
  import chalk from 'chalk';
3
3
  import axios from 'axios';
4
4
  import ora from 'ora';
5
- import { theme, section, kvPair } from '../../utils/ui';
5
+ import { theme, section, kvPair } from '../../utils/ui.js';
6
6
 
7
7
  interface AgentConfig {
8
8
  name: string;
@@ -174,7 +174,7 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
174
174
  const { channelType } = await (inquirer as any).prompt([{
175
175
  type: 'list',
176
176
  name: 'channelType',
177
- message: 'Que canal deseas conectar?',
177
+ message: 'Which channel do you want to connect?',
178
178
  choices: CHANNEL_CHOICES,
179
179
  }]);
180
180
 
@@ -182,7 +182,7 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
182
182
  const targetType = channelType === 'whatsapp_business' ? 'whatsapp' : channelType;
183
183
 
184
184
  // Cargar integraciones existentes del tipo seleccionado
185
- const loadSpinner = ora({ text: chalk.gray('Cargando integraciones...'), spinner: 'dots', color: 'green' }).start();
185
+ const loadSpinner = ora({ text: chalk.gray('Loading integrations...'), spinner: 'dots', color: 'green' }).start();
186
186
  const allIntegrations = await fetchWorkspaceIntegrations(baseUrl, ctx.workspaceId, headers);
187
187
  const existing = allIntegrations.filter((ig: any) => ig.type === targetType);
188
188
  loadSpinner.stop();
@@ -196,12 +196,12 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
196
196
  value: ig.id,
197
197
  }));
198
198
  choices.push(new (inquirer as any).Separator());
199
- choices.push({ name: chalk.hex('#4ade80')('+ Agregar uno nuevo (generar link)'), value: '__new__' });
199
+ choices.push({ name: chalk.hex('#4ade80')('+ Add a new one (generate link)'), value: '__new__' });
200
200
 
201
201
  const { selected } = await (inquirer as any).prompt([{
202
202
  type: 'list',
203
203
  name: 'selected',
204
- message: `Integraciones de ${channelLabel} disponibles:`,
204
+ message: `Available ${channelLabel} integrations:`,
205
205
  choices,
206
206
  }]);
207
207
 
@@ -212,12 +212,12 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
212
212
 
213
213
  // Activar la integracion si no esta activa
214
214
  if (!selectedIntegration.isActive) {
215
- const actSpinner = ora({ text: chalk.gray('Activando integracion...'), spinner: 'dots', color: 'green' }).start();
215
+ const actSpinner = ora({ text: chalk.gray('Activating integration...'), spinner: 'dots', color: 'green' }).start();
216
216
  const activated = await activateIntegration(baseUrl, ctx.workspaceId, selectedIntegration.id, headers);
217
217
  if (activated) {
218
- actSpinner.succeed(chalk.hex('#4ade80')('Integracion activada correctamente.'));
218
+ actSpinner.succeed(chalk.hex('#4ade80')('Integration activated successfully.'));
219
219
  } else {
220
- actSpinner.warn(chalk.hex('#FFA726')('No se pudo activar la integracion. Puedes activarla manualmente desde la plataforma.'));
220
+ actSpinner.warn(chalk.hex('#FFA726')('Could not activate the integration. You can activate it manually from the platform.'));
221
221
  }
222
222
  }
223
223
 
@@ -226,13 +226,13 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
226
226
  key: getIntegrationKey(selectedIntegration),
227
227
  multianswer: false,
228
228
  });
229
- console.log(chalk.hex('#4ade80')(` Canal asociado: ${label}`));
229
+ console.log(chalk.hex('#4ade80')(` Channel linked: ${label}`));
230
230
  }
231
231
  }
232
232
 
233
233
  // Si no hay existentes o eligio "Agregar nuevo" → generar link de onboarding
234
234
  if (!selectedIntegration) {
235
- const spinner = ora({ text: chalk.gray('Generando link de conexion...'), spinner: 'dots', color: 'green' }).start();
235
+ const spinner = ora({ text: chalk.gray('Generating connection link...'), spinner: 'dots', color: 'green' }).start();
236
236
 
237
237
  try {
238
238
  const linkRes = await axios.post(
@@ -242,7 +242,7 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
242
242
  );
243
243
 
244
244
  if (!linkRes.data?.success) {
245
- spinner.fail(chalk.hex('#EF5350')(`Error: ${linkRes.data?.message || 'No se pudo generar el link'}`));
245
+ spinner.fail(chalk.hex('#EF5350')(`Error: ${linkRes.data?.message || 'Could not generate the link'}`));
246
246
  } else {
247
247
  const shortUrl = linkRes.data.data?.shortUrl || '';
248
248
  spinner.stop();
@@ -250,7 +250,7 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
250
250
  // Mostrar link
251
251
  console.log();
252
252
  console.log(chalk.hex('#4CAF50')(' ─'.repeat(32)));
253
- console.log(chalk.bold(` Envia este link para conectar ${channelLabel}:`));
253
+ console.log(chalk.bold(` Send this link to connect ${channelLabel}:`));
254
254
  console.log();
255
255
  console.log(' ' + chalk.hex('#22d3ee')(shortUrl));
256
256
  console.log();
@@ -261,7 +261,7 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
261
261
  const prevIds = new Set(allIntegrations.map((i: any) => i.id));
262
262
 
263
263
  // Polling para detectar nueva integracion (Enter para saltar)
264
- const pollSpinner = ora({ text: chalk.gray('Esperando conexion... (Enter para saltar)'), spinner: 'dots', color: 'cyan' }).start();
264
+ const pollSpinner = ora({ text: chalk.gray('Waiting for connection... (Enter to skip)'), spinner: 'dots', color: 'cyan' }).start();
265
265
  const POLL_INTERVAL = 5000;
266
266
  const MAX_POLLS = 60;
267
267
  let detected: any = null;
@@ -306,20 +306,20 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
306
306
  }
307
307
  } catch {}
308
308
  const elapsed = Math.floor(((i + 1) * POLL_INTERVAL) / 1000);
309
- pollSpinner.text = chalk.gray(`Esperando conexion... ${elapsed}s (Enter para saltar)`);
309
+ pollSpinner.text = chalk.gray(`Waiting for connection... ${elapsed}s (Enter to skip)`);
310
310
  }
311
311
 
312
312
  if (detected) {
313
313
  const detectedName = getIntegrationLabel(detected);
314
- pollSpinner.succeed(chalk.hex('#4ade80')(`Conexion detectada: ${detectedName}`));
314
+ pollSpinner.succeed(chalk.hex('#4ade80')(`Connection detected: ${detectedName}`));
315
315
 
316
316
  // Activar la integracion detectada
317
- const actSpinner = ora({ text: chalk.gray('Activando integracion...'), spinner: 'dots', color: 'green' }).start();
317
+ const actSpinner = ora({ text: chalk.gray('Activating integration...'), spinner: 'dots', color: 'green' }).start();
318
318
  const activated = await activateIntegration(baseUrl, ctx.workspaceId, detected.id, headers);
319
319
  if (activated) {
320
- actSpinner.succeed(chalk.hex('#4ade80')('Integracion activada correctamente.'));
320
+ actSpinner.succeed(chalk.hex('#4ade80')('Integration activated successfully.'));
321
321
  } else {
322
- actSpinner.warn(chalk.hex('#FFA726')('No se pudo activar la integracion. Puedes activarla manualmente desde la plataforma.'));
322
+ actSpinner.warn(chalk.hex('#FFA726')('Could not activate the integration. You can activate it manually from the platform.'));
323
323
  }
324
324
 
325
325
  channels.push({
@@ -327,29 +327,29 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
327
327
  key: getIntegrationKey(detected),
328
328
  multianswer: false,
329
329
  });
330
- console.log(chalk.hex('#4ade80')(' Canal asociado correctamente.'));
330
+ console.log(chalk.hex('#4ade80')(' Channel linked successfully.'));
331
331
  } else {
332
- pollSpinner.warn(chalk.hex('#FFA726')(skipped ? 'Omitido.' : 'Timeout: no se detecto conexion.'));
332
+ pollSpinner.warn(chalk.hex('#FFA726')(skipped ? 'Skipped.' : 'Timeout: no connection detected.'));
333
333
  const { action } = await (inquirer as any).prompt([{
334
334
  type: 'list', name: 'action',
335
- message: 'Que deseas hacer?',
335
+ message: 'What would you like to do?',
336
336
  choices: [
337
- { name: 'Ingresar ID manualmente', value: 'manual' },
338
- { name: 'Saltar', value: 'skip' },
337
+ { name: 'Enter ID manually', value: 'manual' },
338
+ { name: 'Skip', value: 'skip' },
339
339
  ],
340
340
  }]);
341
341
  if (action === 'manual') {
342
342
  const { key } = await (inquirer as any).prompt([
343
- { type: 'input', name: 'key', message: `ID/numero del canal ${channelLabel}:`, validate: (v: string) => v.length > 0 || 'Requerido' },
343
+ { type: 'input', name: 'key', message: `${channelLabel} channel ID/number:`, validate: (v: string) => v.length > 0 || 'Required' },
344
344
  ]);
345
345
 
346
346
  // Activar la integracion ingresada manualmente
347
- const actSpinner = ora({ text: chalk.gray('Activando integracion...'), spinner: 'dots', color: 'green' }).start();
347
+ const actSpinner = ora({ text: chalk.gray('Activating integration...'), spinner: 'dots', color: 'green' }).start();
348
348
  const activated = await activateIntegration(baseUrl, ctx.workspaceId, key, headers);
349
349
  if (activated) {
350
- actSpinner.succeed(chalk.hex('#4ade80')('Integracion activada correctamente.'));
350
+ actSpinner.succeed(chalk.hex('#4ade80')('Integration activated successfully.'));
351
351
  } else {
352
- actSpinner.warn(chalk.hex('#FFA726')('No se pudo activar la integracion. Puedes activarla manualmente desde la plataforma.'));
352
+ actSpinner.warn(chalk.hex('#FFA726')('Could not activate the integration. You can activate it manually from the platform.'));
353
353
  }
354
354
 
355
355
  channels.push({ channel: CHANNEL_AGENT_MAP[channelType], key, multianswer: false });
@@ -361,7 +361,7 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
361
361
  }
362
362
  }
363
363
 
364
- const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Conectar otro canal?', default: false }]);
364
+ const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Connect another channel?', default: false }]);
365
365
  addMore = more;
366
366
  }
367
367
 
@@ -369,144 +369,144 @@ export async function connectChannelFlow(ctx: WizardContext): Promise<AgentChann
369
369
  }
370
370
 
371
371
  export async function runAgentWizard(zone: string, workspaceId?: string, apiKey?: string, dev?: boolean): Promise<AgentConfig> {
372
- console.log(section('Crear nuevo agente de IA'));
373
- console.log(theme.muted(' Responde las siguientes preguntas para configurar tu agente.\n'));
372
+ console.log(section('Create new AI agent'));
373
+ console.log(theme.muted(' Answer the following questions to configure your agent.\n'));
374
374
 
375
375
  // Paso 1: Informacion basica
376
- console.log(theme.bold('\n Paso 1/8: Informacion basica'));
376
+ console.log(theme.bold('\n Step 1/8: Basic information'));
377
377
  const basic = await (inquirer as any).prompt([
378
378
  {
379
379
  type: 'input',
380
380
  name: 'name',
381
- message: 'Nombre del agente:',
382
- validate: (v: string) => v.length > 0 || 'El nombre es requerido',
381
+ message: 'Agent name:',
382
+ validate: (v: string) => v.length > 0 || 'Name is required',
383
383
  },
384
384
  {
385
385
  type: 'input',
386
386
  name: 'description',
387
- message: 'Descripcion breve:',
387
+ message: 'Short description:',
388
388
  default: '',
389
389
  },
390
390
  {
391
391
  type: 'input',
392
392
  name: 'prompt',
393
- message: 'Prompt del sistema (instrucciones principales):',
394
- default: 'Eres un asistente virtual amigable y profesional.',
393
+ message: 'System prompt (main instructions):',
394
+ default: 'You are a friendly and professional virtual assistant.',
395
395
  },
396
396
  {
397
397
  type: 'number',
398
398
  name: 'buffer',
399
- message: 'Buffer de conversacion (3-20 mensajes):',
399
+ message: 'Conversation buffer (3-20 messages):',
400
400
  default: 5,
401
- validate: (v: number) => (v >= 3 && v <= 20) || 'Debe ser entre 3 y 20',
401
+ validate: (v: number) => (v >= 3 && v <= 20) || 'Must be between 3 and 20',
402
402
  },
403
403
  {
404
404
  type: 'list',
405
405
  name: 'color',
406
- message: 'Color del agente:',
406
+ message: 'Agent color:',
407
407
  choices: COLORS,
408
408
  default: 'blue',
409
409
  },
410
410
  ]);
411
411
 
412
412
  // Paso 2: Personalidad
413
- console.log(theme.bold('\n Paso 2/8: Personalidad e instrucciones'));
413
+ console.log(theme.bold('\n Step 2/8: Personality and instructions'));
414
414
  const personality = await (inquirer as any).prompt([
415
415
  {
416
416
  type: 'list',
417
417
  name: 'tone',
418
- message: 'Tono de comunicacion:',
418
+ message: 'Communication tone:',
419
419
  choices: ['profesional', 'amigable', 'formal', 'casual', 'tecnico', 'empatico'],
420
420
  default: 'profesional',
421
421
  },
422
422
  {
423
423
  type: 'list',
424
424
  name: 'style',
425
- message: 'Estilo de respuesta:',
425
+ message: 'Response style:',
426
426
  choices: ['conciso', 'detallado', 'conversacional', 'directo'],
427
427
  default: 'conciso',
428
428
  },
429
429
  {
430
430
  type: 'input',
431
431
  name: 'personality',
432
- message: 'Personalidad en una frase:',
433
- default: 'Servicial y conocedor',
432
+ message: 'Personality in one sentence:',
433
+ default: 'Helpful and knowledgeable',
434
434
  },
435
435
  {
436
436
  type: 'input',
437
437
  name: 'objective',
438
- message: 'Objetivo principal del agente:',
439
- default: 'Ayudar a los usuarios con sus consultas',
438
+ message: 'Main objective of the agent:',
439
+ default: 'Help users with their queries',
440
440
  },
441
441
  {
442
442
  type: 'list',
443
443
  name: 'language',
444
- message: 'Idioma principal:',
444
+ message: 'Primary language:',
445
445
  choices: ['Espanol', 'English', 'Portugues', 'Frances'],
446
446
  default: 'Espanol',
447
447
  },
448
448
  {
449
449
  type: 'confirm',
450
450
  name: 'useEmojis',
451
- message: 'Usar emojis en respuestas?',
451
+ message: 'Use emojis in responses?',
452
452
  default: true,
453
453
  },
454
454
  ]);
455
455
 
456
456
  // Paso 3: Persona
457
- console.log(theme.bold('\n Paso 3/8: Identidad del agente'));
457
+ console.log(theme.bold('\n Step 3/8: Agent identity'));
458
458
  const person = await (inquirer as any).prompt([
459
459
  {
460
460
  type: 'input',
461
461
  name: 'name',
462
- message: 'Nombre del personaje (como se presenta):',
462
+ message: 'Character name (how it introduces itself):',
463
463
  default: basic.name,
464
464
  },
465
465
  {
466
466
  type: 'input',
467
467
  name: 'role',
468
- message: 'Rol (ej: Asistente de ventas, Soporte tecnico):',
469
- default: 'Asistente virtual',
468
+ message: 'Role (e.g. Sales assistant, Tech support):',
469
+ default: 'Virtual assistant',
470
470
  },
471
471
  {
472
472
  type: 'confirm',
473
473
  name: 'firstPerson',
474
- message: 'Hablar en primera persona?',
474
+ message: 'Speak in first person?',
475
475
  default: true,
476
476
  },
477
477
  ]);
478
478
 
479
479
  // Paso 4: Fallbacks
480
- console.log(theme.bold('\n Paso 4/8: Mensajes de fallback'));
480
+ console.log(theme.bold('\n Step 4/8: Fallback messages'));
481
481
  const fallbacks = await (inquirer as any).prompt([
482
482
  {
483
483
  type: 'input',
484
484
  name: 'noAnswer',
485
- message: 'Cuando no tiene respuesta:',
485
+ message: 'When it has no answer:',
486
486
  default: 'Lo siento, no tengo informacion sobre eso. Puedo ayudarte con otra consulta?',
487
487
  },
488
488
  {
489
489
  type: 'input',
490
490
  name: 'serviceError',
491
- message: 'Cuando hay error de servicio:',
491
+ message: 'When there is a service error:',
492
492
  default: 'Disculpa, estamos experimentando dificultades tecnicas. Intenta de nuevo en unos momentos.',
493
493
  },
494
494
  {
495
495
  type: 'input',
496
496
  name: 'misunderstanding',
497
- message: 'Cuando no entiende la pregunta:',
497
+ message: 'When it does not understand the question:',
498
498
  default: 'No estoy seguro de entender tu consulta. Podrias reformularla?',
499
499
  },
500
500
  ]);
501
501
 
502
502
  // Paso 5: Tool Calling
503
- console.log(theme.bold('\n Paso 5/8: Tool Calling'));
504
- console.log(theme.muted(' Tool Calling permite al agente ejecutar acciones automaticas\n'));
503
+ console.log(theme.bold('\n Step 5/8: Tool Calling'));
504
+ console.log(theme.muted(' Tool Calling lets the agent execute automatic actions\n'));
505
505
  const { useToolCalling } = await (inquirer as any).prompt([
506
506
  {
507
507
  type: 'confirm',
508
508
  name: 'useToolCalling',
509
- message: 'Activar Tool Calling?',
509
+ message: 'Enable Tool Calling?',
510
510
  default: true,
511
511
  },
512
512
  ]);
@@ -517,39 +517,39 @@ export async function runAgentWizard(zone: string, workspaceId?: string, apiKey?
517
517
  const { addServices } = await (inquirer as any).prompt([{
518
518
  type: 'confirm',
519
519
  name: 'addServices',
520
- message: 'Agregar servicios externos (API calls)?',
520
+ message: 'Add external services (API calls)?',
521
521
  default: false,
522
522
  }]);
523
523
 
524
524
  if (addServices) {
525
525
  let addMore = true;
526
526
  while (addMore) {
527
- console.log(theme.muted('\n Nuevo servicio:'));
527
+ console.log(theme.muted('\n New service:'));
528
528
  const svc = await (inquirer as any).prompt([
529
- { type: 'input', name: 'intent', message: 'Nombre/intent del servicio:', validate: (v: string) => v.length > 0 || 'Requerido' },
530
- { type: 'input', name: 'reference', message: 'Palabras clave de referencia:', default: '' },
531
- { type: 'list', name: 'method', message: 'Metodo HTTP:', choices: ['GET', 'POST'] },
532
- { type: 'input', name: 'endpoint', message: 'URL del endpoint:', validate: (v: string) => v.length > 0 || 'Requerido' },
533
- { type: 'input', name: 'responseMessage', message: 'Mensaje de respuesta:', default: '' },
529
+ { type: 'input', name: 'intent', message: 'Service name/intent:', validate: (v: string) => v.length > 0 || 'Required' },
530
+ { type: 'input', name: 'reference', message: 'Reference keywords:', default: '' },
531
+ { type: 'list', name: 'method', message: 'HTTP method:', choices: ['GET', 'POST'] },
532
+ { type: 'input', name: 'endpoint', message: 'Endpoint URL:', validate: (v: string) => v.length > 0 || 'Required' },
533
+ { type: 'input', name: 'responseMessage', message: 'Response message:', default: '' },
534
534
  ]);
535
535
 
536
536
  // Required fields
537
537
  const fields: AgentService['requiredFields'] = [];
538
538
  const { addFields } = await (inquirer as any).prompt([{
539
539
  type: 'confirm', name: 'addFields',
540
- message: 'Agregar campos requeridos?', default: false,
540
+ message: 'Add required fields?', default: false,
541
541
  }]);
542
542
  if (addFields) {
543
543
  let moreFields = true;
544
544
  while (moreFields) {
545
545
  const field = await (inquirer as any).prompt([
546
- { type: 'input', name: 'name', message: 'Nombre del campo:' },
547
- { type: 'list', name: 'type', message: 'Tipo:', choices: ['string', 'number', 'boolean', 'date'] },
548
- { type: 'input', name: 'description', message: 'Descripcion:' },
549
- { type: 'input', name: 'promptHint', message: 'Hint para el LLM:' },
546
+ { type: 'input', name: 'name', message: 'Field name:' },
547
+ { type: 'list', name: 'type', message: 'Type:', choices: ['string', 'number', 'boolean', 'date'] },
548
+ { type: 'input', name: 'description', message: 'Description:' },
549
+ { type: 'input', name: 'promptHint', message: 'Hint for the LLM:' },
550
550
  ]);
551
551
  fields.push(field);
552
- const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Agregar otro campo?', default: false }]);
552
+ const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Add another field?', default: false }]);
553
553
  moreFields = more;
554
554
  }
555
555
  }
@@ -568,7 +568,7 @@ export async function runAgentWizard(zone: string, workspaceId?: string, apiKey?
568
568
  responseConditions: [],
569
569
  });
570
570
 
571
- const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Agregar otro servicio?', default: false }]);
571
+ const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Add another service?', default: false }]);
572
572
  addMore = more;
573
573
  }
574
574
  }
@@ -580,34 +580,34 @@ export async function runAgentWizard(zone: string, workspaceId?: string, apiKey?
580
580
  const { addActions } = await (inquirer as any).prompt([{
581
581
  type: 'confirm',
582
582
  name: 'addActions',
583
- message: 'Agregar acciones (tag, stage, asignar agente)?',
583
+ message: 'Add actions (tag, stage, assign agent)?',
584
584
  default: false,
585
585
  }]);
586
586
 
587
587
  if (addActions) {
588
588
  let addMore = true;
589
589
  while (addMore) {
590
- console.log(theme.muted('\n Nueva accion:'));
590
+ console.log(theme.muted('\n New action:'));
591
591
  const act = await (inquirer as any).prompt([
592
- { type: 'input', name: 'intent', message: 'Nombre/intent de la accion:', validate: (v: string) => v.length > 0 || 'Requerido' },
593
- { type: 'input', name: 'reference', message: 'Palabras clave de referencia:', default: '' },
592
+ { type: 'input', name: 'intent', message: 'Action name/intent:', validate: (v: string) => v.length > 0 || 'Required' },
593
+ { type: 'input', name: 'reference', message: 'Reference keywords:', default: '' },
594
594
  {
595
- type: 'list', name: 'actionType', message: 'Tipo de accion:',
595
+ type: 'list', name: 'actionType', message: 'Action type:',
596
596
  choices: [
597
- { name: 'Agendar evento', value: 'action.event.add' },
598
- { name: 'Actualizar evento (reagendar)', value: 'action.event.update' },
599
- { name: 'Listar eventos', value: 'action.event.list' },
600
- { name: 'Eliminar evento (cancelar)', value: 'action.event.delete' },
601
- { name: 'Agregar tag', value: 'action.tag' },
602
- { name: 'Cambiar stage', value: 'action.stage' },
603
- { name: 'Derivar a agente humano', value: 'action.agentShutDown' },
604
- { name: 'Marcar como resuelto', value: 'action.solved' },
605
- { name: 'Asignar agente', value: 'action.asign' },
606
- { name: 'Segmentacion', value: 'action.segmentation' },
597
+ { name: 'Schedule event', value: 'action.event.add' },
598
+ { name: 'Update event (reschedule)', value: 'action.event.update' },
599
+ { name: 'List events', value: 'action.event.list' },
600
+ { name: 'Delete event (cancel)', value: 'action.event.delete' },
601
+ { name: 'Add tag', value: 'action.tag' },
602
+ { name: 'Change stage', value: 'action.stage' },
603
+ { name: 'Hand off to human agent', value: 'action.agentShutDown' },
604
+ { name: 'Mark as resolved', value: 'action.solved' },
605
+ { name: 'Assign agent', value: 'action.asign' },
606
+ { name: 'Segmentation', value: 'action.segmentation' },
607
607
  ],
608
608
  },
609
- { type: 'input', name: 'actionValue', message: 'Valor de la accion:', default: '' },
610
- { type: 'input', name: 'responseMessage', message: 'Mensaje de respuesta:', default: '' },
609
+ { type: 'input', name: 'actionValue', message: 'Action value:', default: '' },
610
+ { type: 'input', name: 'responseMessage', message: 'Response message:', default: '' },
611
611
  ]);
612
612
 
613
613
  actions.push({
@@ -619,30 +619,30 @@ export async function runAgentWizard(zone: string, workspaceId?: string, apiKey?
619
619
  action: [{ type: act.actionType, value: act.actionValue }],
620
620
  });
621
621
 
622
- const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Agregar otra accion?', default: false }]);
622
+ const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Add another action?', default: false }]);
623
623
  addMore = more;
624
624
  }
625
625
  }
626
626
  }
627
627
 
628
628
  // Paso 6: AI Provider
629
- console.log(theme.bold('\n Paso 6/8: Proveedor de IA'));
629
+ console.log(theme.bold('\n Step 6/8: AI provider'));
630
630
  const { configureAI } = await (inquirer as any).prompt([{
631
631
  type: 'confirm',
632
632
  name: 'configureAI',
633
- message: 'Configurar proveedor de IA personalizado?',
633
+ message: 'Configure a custom AI provider?',
634
634
  default: false,
635
635
  }]);
636
636
 
637
637
  const aiProviders: AIProvider[] = [];
638
638
  if (configureAI) {
639
639
  const ai = await (inquirer as any).prompt([
640
- { type: 'list', name: 'provider', message: 'Proveedor:', choices: ['openai', 'claude', 'gemini'] },
640
+ { type: 'list', name: 'provider', message: 'Provider:', choices: ['openai', 'claude', 'gemini'] },
641
641
  ]);
642
642
  const models = MODELS[ai.provider] || MODELS.openai;
643
643
  const aiConfig = await (inquirer as any).prompt([
644
- { type: 'list', name: 'model', message: 'Modelo:', choices: models },
645
- { type: 'password', name: 'apiToken', message: 'API Token:', mask: '*', validate: (v: string) => v.length > 0 || 'Requerido' },
644
+ { type: 'list', name: 'model', message: 'Model:', choices: models },
645
+ { type: 'password', name: 'apiToken', message: 'API Token:', mask: '*', validate: (v: string) => v.length > 0 || 'Required' },
646
646
  ]);
647
647
 
648
648
  aiProviders.push({
@@ -656,12 +656,12 @@ export async function runAgentWizard(zone: string, workspaceId?: string, apiKey?
656
656
  }
657
657
 
658
658
  // Paso 7: Conectar canal
659
- console.log(theme.bold('\n Paso 7/8: Conectar canal'));
659
+ console.log(theme.bold('\n Step 7/8: Connect channel'));
660
660
  let channels: AgentChannel[] = [];
661
661
  const { addChannel } = await (inquirer as any).prompt([{
662
662
  type: 'confirm',
663
663
  name: 'addChannel',
664
- message: 'Deseas conectar un canal (WhatsApp, Instagram, Messenger)?',
664
+ message: 'Connect a channel (WhatsApp, Instagram, Messenger)?',
665
665
  default: false,
666
666
  }]);
667
667
 
@@ -670,19 +670,19 @@ export async function runAgentWizard(zone: string, workspaceId?: string, apiKey?
670
670
  } else if (addChannel) {
671
671
  // Fallback manual si no hay credenciales para API
672
672
  const wa = await (inquirer as any).prompt([
673
- { type: 'input', name: 'key', message: 'Numero de WhatsApp (con codigo de pais):', validate: (v: string) => v.length > 0 || 'Requerido' },
674
- { type: 'confirm', name: 'multianswer', message: 'Permitir multiples respuestas?', default: false },
673
+ { type: 'input', name: 'key', message: 'WhatsApp number (with country code):', validate: (v: string) => v.length > 0 || 'Required' },
674
+ { type: 'confirm', name: 'multianswer', message: 'Allow multiple answers?', default: false },
675
675
  ]);
676
676
  channels.push({ channel: 'whatsapp', key: wa.key, multianswer: wa.multianswer });
677
677
  }
678
678
 
679
679
  // Paso 8: Ejemplos
680
- console.log(theme.bold('\n Paso 8/8: Ejemplos de conversacion'));
680
+ console.log(theme.bold('\n Step 8/8: Conversation examples'));
681
681
  const examples: AgentExample[] = [];
682
682
  const { addExamples } = await (inquirer as any).prompt([{
683
683
  type: 'confirm',
684
684
  name: 'addExamples',
685
- message: 'Agregar ejemplos de conversacion?',
685
+ message: 'Add conversation examples?',
686
686
  default: false,
687
687
  }]);
688
688
 
@@ -690,11 +690,11 @@ export async function runAgentWizard(zone: string, workspaceId?: string, apiKey?
690
690
  let addMore = true;
691
691
  while (addMore) {
692
692
  const ex = await (inquirer as any).prompt([
693
- { type: 'input', name: 'user', message: 'Mensaje del usuario:' },
694
- { type: 'input', name: 'agent', message: 'Respuesta del agente:' },
693
+ { type: 'input', name: 'user', message: 'User message:' },
694
+ { type: 'input', name: 'agent', message: 'Agent response:' },
695
695
  ]);
696
- examples.push({ value: `Usuario: ${ex.user}\nAgente: ${ex.agent}`, color: 'blue' });
697
- const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Agregar otro ejemplo?', default: false }]);
696
+ examples.push({ value: `User: ${ex.user}\nAgent: ${ex.agent}`, color: 'blue' });
697
+ const { more } = await (inquirer as any).prompt([{ type: 'confirm', name: 'more', message: 'Add another example?', default: false }]);
698
698
  addMore = more;
699
699
  }
700
700
  }
@@ -736,19 +736,19 @@ export async function runAgentWizard(zone: string, workspaceId?: string, apiKey?
736
736
  };
737
737
 
738
738
  // Preview
739
- console.log(section('Vista previa de la configuracion'));
740
- console.log(kvPair('Nombre', config.name));
739
+ console.log(section('Configuration preview'));
740
+ console.log(kvPair('Name', config.name));
741
741
  console.log(kvPair('Prompt', config.prompt.substring(0, 80) + '...'));
742
- console.log(kvPair('Tool Calling', config.useToolCalling ? 'Activado' : 'Desactivado'));
743
- console.log(kvPair('Servicios', String(config.services.length)));
744
- console.log(kvPair('Acciones', String(config.actions.length)));
742
+ console.log(kvPair('Tool Calling', config.useToolCalling ? 'Enabled' : 'Disabled'));
743
+ console.log(kvPair('Services', String(config.services.length)));
744
+ console.log(kvPair('Actions', String(config.actions.length)));
745
745
  console.log(kvPair('AI Provider', config.customAIConfig ? config.aiProviders[0]?.provider + ' / ' + config.aiProviders[0]?.model : 'Default (Plazbot)'));
746
746
  if (config.channels.length > 0) {
747
747
  config.channels.forEach((ch, i) => {
748
- console.log(kvPair(`Canal ${i + 1} (${ch.channel})`, ch.key));
748
+ console.log(kvPair(`Channel ${i + 1} (${ch.channel})`, ch.key));
749
749
  });
750
750
  } else {
751
- console.log(kvPair('Canales', 'No configurado'));
751
+ console.log(kvPair('Channels', 'Not configured'));
752
752
  }
753
753
  console.log();
754
754
 
@@ -1,7 +1,7 @@
1
1
  import { Command } from 'commander';
2
- import { loginCommand } from './login';
3
- import { logoutCommand } from './logout';
4
- import { statusCommand } from './status';
2
+ import { loginCommand } from './login.js';
3
+ import { logoutCommand } from './logout.js';
4
+ import { statusCommand } from './status.js';
5
5
 
6
6
  export const authCommands: Command[] = [
7
7
  loginCommand,