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
@@ -1,14 +1,15 @@
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 } from '../../utils/ui';
6
- import { AgentCommandOptions } from '../../types/agent';
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
+ import { AgentCommandOptions } from '../../types/agent.js';
7
8
 
8
9
  export const copyCommand = new Command('copy')
9
- .description('Clonar un agente existente')
10
- .argument('<agentId>', 'ID del agente a clonar')
11
- .option('--dev', 'Usar ambiente de desarrollo', false)
10
+ .description('Clone an existing agent')
11
+ .argument('<agentId>', 'Agent ID to clone')
12
+ .option('--dev', 'Use development environment', false)
12
13
  .action(async (agentId: string, options: AgentCommandOptions) => {
13
14
  try {
14
15
  const credentials = await getStoredCredentials();
@@ -19,22 +20,27 @@ export const copyCommand = new Command('copy')
19
20
  ...(options.dev && { customUrl: "http://localhost:5090" })
20
21
  });
21
22
 
22
- const spinner = createSpinner('Clonando agente...');
23
+ const spinner = createSpinner('Cloning agent...');
23
24
  spinner.start();
24
25
 
25
26
  const result = await (agent as any).copyAgent({ id: agentId });
26
27
 
27
- spinner.succeed('Agente clonado exitosamente');
28
+ spinner.succeed('Agent cloned successfully');
28
29
 
29
- logger.title('Agente clonado');
30
+ logger.title('Cloned agent');
30
31
  if (result?.agentId || result?.id) {
31
- logger.label('Nuevo ID', result.agentId || result.id);
32
+ logger.label('New ID', result.agentId || result.id);
32
33
  }
33
- logger.dim('\nEl agente clonado tiene el widget deshabilitado por defecto.');
34
+ logger.dim('\nThe cloned agent has the widget disabled by default.');
34
35
 
35
36
  } catch (error) {
36
- const message = error instanceof Error ? error.message : 'Error desconocido';
37
+ const message = error instanceof Error ? error.message : 'Unknown error';
37
38
  logger.error(message);
38
39
  process.exit(1);
39
40
  }
40
41
  });
42
+
43
+ addExamples(copyCommand, [
44
+ { description: 'Clone an agent (widget stays disabled on the copy)',
45
+ command: 'plazbot agent copy agt_AbcDef123' },
46
+ ]);
@@ -1,16 +1,17 @@
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 { AgentCommandOptions } from '../../types/agent';
6
- import { createSpinner } from '../../utils/ui';
7
- import { runAgentWizard } from './wizard';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { AgentCommandOptions } from '../../types/agent.js';
7
+ import { createSpinner } from '../../utils/ui.js';
8
+ import { runAgentWizard } from './wizard.js';
8
9
  import fs from 'fs/promises';
9
10
 
10
11
  export const createCommand = new Command('create')
11
- .description('Crea un nuevo agente de IA (wizard interactivo o archivo JSON)')
12
- .argument('[configPath]', 'Ruta al archivo de configuracion JSON (opcional)')
13
- .option('--dev', 'Usar ambiente de desarrollo', false)
12
+ .description('Create a new AI agent (interactive wizard or JSON file)')
13
+ .argument('[configPath]', 'Path to the JSON config file (optional)')
14
+ .option('--dev', 'Use development environment', false)
14
15
  .action(async (configPath: string | undefined, options: AgentCommandOptions) => {
15
16
  try {
16
17
  const credentials = await getStoredCredentials();
@@ -30,10 +31,10 @@ export const createCommand = new Command('create')
30
31
  const fileContent = await fs.readFile(configPath, 'utf-8');
31
32
  agentConfig = JSON.parse(fileContent);
32
33
  } catch (error) {
33
- const errorMessage = error instanceof Error ? error.message : 'Error desconocido';
34
- throw new Error(`Error al leer el archivo de configuracion: ${errorMessage}`);
34
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
35
+ throw new Error(`Failed to read config file: ${errorMessage}`);
35
36
  }
36
- logger.title('Creando agente desde archivo');
37
+ logger.title('Creating agent from file');
37
38
  logger.json(agentConfig);
38
39
  } else {
39
40
  // Modo wizard interactivo
@@ -43,51 +44,60 @@ export const createCommand = new Command('create')
43
44
  const { confirm } = await inquirer.default.prompt([{
44
45
  type: 'confirm',
45
46
  name: 'confirm',
46
- message: 'Crear el agente con esta configuracion?',
47
+ message: 'Create the agent with this configuration?',
47
48
  default: true,
48
49
  }]);
49
50
 
50
51
  if (!confirm) {
51
- logger.warning('Creacion cancelada');
52
+ logger.warning('Creation cancelled');
52
53
  return;
53
54
  }
54
55
  }
55
56
 
56
- const spinner = createSpinner('Creando agente...');
57
+ const spinner = createSpinner('Creating agent...');
57
58
  spinner.start();
58
59
 
59
60
  const result = await agent.addAgent(agentConfig);
60
61
 
61
- spinner.succeed('Agente creado exitosamente');
62
+ spinner.succeed('Agent created successfully');
62
63
 
63
- logger.title('Detalles del agente');
64
+ logger.title('Agent details');
64
65
  if (result.agentId) {
65
66
  logger.label('ID', result.agentId);
66
67
  }
67
68
  if (agentConfig.name) {
68
- logger.label('Nombre', agentConfig.name);
69
+ logger.label('Name', agentConfig.name);
69
70
  }
70
- logger.label('Tool Calling', agentConfig.useToolCalling ? 'Activado' : 'Desactivado');
71
+ logger.label('Tool Calling', agentConfig.useToolCalling ? 'Enabled' : 'Disabled');
71
72
 
72
73
  if (agentConfig.channels && agentConfig.channels.length > 0) {
73
74
  agentConfig.channels.forEach((ch: any) => {
74
- logger.label(`Canal (${ch.channel})`, ch.key);
75
+ logger.label(`Channel (${ch.channel})`, ch.key);
75
76
  });
76
77
  }
77
78
 
78
79
  console.log();
79
- logger.dim('Siguiente paso: plazbot agent chat -a ' + (result.agentId || '<agentId>'));
80
+ logger.dim('Next step: plazbot agent chat -a ' + (result.agentId || '<agentId>'));
80
81
  console.log();
81
82
 
82
83
  if (options.dev) {
83
- logger.warning('Ambiente: desarrollo');
84
+ logger.warning('Environment: development');
84
85
  }
85
86
 
86
87
  process.exit(0);
87
88
 
88
89
  } catch (error) {
89
- const message = error instanceof Error ? error.message : 'Error desconocido al crear el agente';
90
+ const message = error instanceof Error ? error.message : 'Unknown error while creating the agent';
90
91
  logger.error(message);
91
92
  process.exit(1);
92
93
  }
93
94
  });
95
+
96
+ addExamples(createCommand, [
97
+ { description: 'Launch the interactive wizard to design the agent',
98
+ command: 'plazbot agent create' },
99
+ { description: 'Create directly from a JSON configuration file',
100
+ command: 'plazbot agent create ./agent.json' },
101
+ { description: 'Create against a local backend (dev mode)',
102
+ command: 'plazbot agent create ./agent.json --dev' },
103
+ ]);
@@ -1,14 +1,15 @@
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 { AgentCommandOptions } from '../../types/agent';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { AgentCommandOptions } from '../../types/agent.js';
6
7
  import readline from 'readline';
7
8
 
8
9
  export const deleteCommand = new Command('delete')
9
- .description('Elimina un agente existente')
10
- .argument('<agentId>', 'ID del agente a eliminar')
11
- .option('--dev', 'Usar ambiente de desarrollo', false)
10
+ .description('Delete an existing agent')
11
+ .argument('<agentId>', 'Agent ID to delete')
12
+ .option('--dev', 'Use development environment', false)
12
13
  .action(async (agentId: string, options: AgentCommandOptions) => {
13
14
  try {
14
15
  // Obtener credenciales guardadas
@@ -25,11 +26,11 @@ export const deleteCommand = new Command('delete')
25
26
  const response: any = await agent.getAgentById({ id: agentId });
26
27
  const agentDetails = response.agent || response.data || response;
27
28
 
28
- logger.warning('\nVas a eliminar el siguiente agente:');
29
+ logger.warning('\nYou are about to delete the following agent:');
29
30
  logger.divider();
30
31
  logger.info(`ID: ${agentDetails.id || agentId}`);
31
- logger.info(`Nombre: ${agentDetails.name || '—'}`);
32
- logger.info(`Descripcion: ${agentDetails.description || '—'}`);
32
+ logger.info(`Name: ${agentDetails.name || '—'}`);
33
+ logger.info(`Description: ${agentDetails.description || '—'}`);
33
34
  logger.divider();
34
35
 
35
36
  // Crear interfaz para confirmación
@@ -39,27 +40,32 @@ export const deleteCommand = new Command('delete')
39
40
  });
40
41
 
41
42
  // Preguntar por confirmación
42
- rl.question('\nEstas seguro que deseas eliminar este agente? (y/N): ', async (answer) => {
43
+ rl.question('\nAre you sure you want to delete this agent? (y/N): ', async (answer) => {
43
44
  if (answer.toLowerCase() === 'y') {
44
45
  await agent.deleteAgent({
45
46
  id: agentId
46
47
  });
47
-
48
- logger.success('Agente eliminado exitosamente');
49
-
48
+
49
+ logger.success('Agent deleted successfully');
50
+
50
51
  if (options.dev) {
51
- logger.warning('Ambiente: desarrollo');
52
+ logger.warning('Environment: development');
52
53
  }
53
54
  } else {
54
- logger.error('Operación cancelada');
55
+ logger.error('Operation cancelled');
55
56
  }
56
-
57
+
57
58
  rl.close();
58
59
  });
59
60
 
60
61
  } catch (error) {
61
- const message = error instanceof Error ? error.message : 'Error desconocido al eliminar el agente';
62
+ const message = error instanceof Error ? error.message : 'Unknown error while deleting the agent';
62
63
  logger.error(message);
63
64
  process.exit(1);
64
65
  }
65
- });
66
+ });
67
+
68
+ addExamples(deleteCommand, [
69
+ { description: 'Delete an agent (asks for y/N confirmation)',
70
+ command: 'plazbot agent delete agt_AbcDef123' },
71
+ ]);
@@ -1,14 +1,15 @@
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 { EnableWidgetOptions } from '../../types/agent';
3
+ import { getStoredCredentials } from '../../utils/credentials.js';
4
+ import { logger } from '../../utils/logger.js';
5
+ import { addExamples } from '../../utils/help.js';
6
+ import { EnableWidgetOptions } from '../../types/agent.js';
6
7
 
7
8
  export const enableCommand = new Command('enable-widget')
8
- .description('Habilita o deshabilita el widget de un agente')
9
- .argument('<agentId>', 'ID del agente')
10
- .option('-d, --disable', 'Deshabilitar el widget en lugar de habilitarlo')
11
- .option('--dev', 'Usar ambiente de desarrollo', false)
9
+ .description('Enable or disable an agent widget')
10
+ .argument('<agentId>', 'Agent ID')
11
+ .option('-d, --disable', 'Disable the widget instead of enabling it')
12
+ .option('--dev', 'Use development environment', false)
12
13
  .action(async (agentId: string, options: EnableWidgetOptions) => {
13
14
  try {
14
15
  // Obtener credenciales guardadas
@@ -25,35 +26,42 @@ export const enableCommand = new Command('enable-widget')
25
26
  const _res: any = await agent.getAgentById({ id: agentId });
26
27
  const agentDetails = _res.agent || _res.data || _res;
27
28
 
28
- logger.title('Estado actual del widget');
29
- logger.label('Agente', agentDetails.name);
29
+ logger.title('Current widget status');
30
+ logger.label('Agent', agentDetails.name);
30
31
 
31
32
  // Cambiar estado
32
33
  const newState = !options.disable; // Si --disable está presente, newState será false
33
- const result = await agent.enableWidget({
34
- id: agentId,
35
- enable: newState
34
+ const result = await agent.enableWidget({
35
+ id: agentId,
36
+ enable: newState
36
37
  });
37
38
 
38
- logger.success(`Widget ${newState ? 'habilitado' : 'deshabilitado'} exitosamente`);
39
-
40
- logger.title('Respuesta del servidor');
41
- logger.label('Estado', result.success ? 'Exitoso' : 'Fallido');
42
- logger.label('Mensaje', result.message);
39
+ logger.success(`Widget ${newState ? 'enabled' : 'disabled'} successfully`);
40
+
41
+ logger.title('Server response');
42
+ logger.label('Status', result.success ? 'Success' : 'Failed');
43
+ logger.label('Message', result.message);
43
44
 
44
45
  if (newState && result.script) {
45
- logger.title('Instrucciones de instalacion');
46
- logger.dim('Coloca este script debajo de la etiqueta <HEAD> en tu sitio web:');
46
+ logger.title('Installation instructions');
47
+ logger.dim('Place this script under the <HEAD> tag of your website:');
47
48
  logger.info('\n' + result.script);
48
49
  }
49
-
50
+
50
51
  if (options.dev) {
51
- logger.warning('Ambiente: desarrollo');
52
+ logger.warning('Environment: development');
52
53
  }
53
54
 
54
55
  } catch (error) {
55
- const message = error instanceof Error ? error.message : 'Error desconocido al modificar el widget';
56
+ const message = error instanceof Error ? error.message : 'Unknown error while updating the widget';
56
57
  logger.error(message);
57
58
  process.exit(1);
58
59
  }
59
- });
60
+ });
61
+
62
+ addExamples(enableCommand, [
63
+ { description: 'Enable the widget and print the <script> snippet',
64
+ command: 'plazbot agent enable-widget agt_AbcDef123' },
65
+ { description: 'Disable an existing widget',
66
+ command: 'plazbot agent enable-widget agt_AbcDef123 --disable' },
67
+ ]);
@@ -1,8 +1,9 @@
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 } 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 } from '../../utils/ui.js';
6
7
  import chalk from 'chalk';
7
8
  import fs from 'fs';
8
9
  import path from 'path';
@@ -173,14 +174,14 @@ function cleanAgentForExport(agentData: any): any {
173
174
  }
174
175
 
175
176
  export const exportCommand = new Command('export')
176
- .description('Exportar configuracion limpia de un agente (compatible con importacion)')
177
- .argument('<agentId>', 'ID del agente a exportar')
178
- .option('-w, --workspace <id>', 'Workspace ID origen (sobreescribe config local)')
179
- .option('-z, --zone <zone>', 'Zona LA o EU (sobreescribe config local)')
180
- .option('-o, --output <path>', 'Ruta del archivo de salida (.json)')
181
- .option('--no-channels', 'Excluir canales de la exportacion')
182
- .option('--no-ai', 'Excluir configuracion de IA personalizada')
183
- .option('--dev', 'Usar ambiente de desarrollo', false)
177
+ .description('Export a clean agent configuration (compatible with import)')
178
+ .argument('<agentId>', 'Agent ID to export')
179
+ .option('-w, --workspace <id>', 'Source workspace ID (overrides local config)')
180
+ .option('-z, --zone <zone>', 'Zone LA or EU (overrides local config)')
181
+ .option('-o, --output <path>', 'Output file path (.json)')
182
+ .option('--no-channels', 'Exclude channels from export')
183
+ .option('--no-ai', 'Exclude custom AI configuration')
184
+ .option('--dev', 'Use development environment', false)
184
185
  .action(async (agentId: string, options: {
185
186
  workspace?: string;
186
187
  zone?: string;
@@ -196,7 +197,7 @@ export const exportCommand = new Command('export')
196
197
  const effectiveZone = (options.zone?.toUpperCase() === 'EU' ? 'EU' : options.zone?.toUpperCase() === 'LA' ? 'LA' : credentials.zone) as 'LA' | 'EU';
197
198
 
198
199
  if (options.workspace || options.zone) {
199
- console.log(chalk.hex('#FFA726')(`\n Modo soporte: workspace=${effectiveWorkspace} zona=${effectiveZone}`));
200
+ console.log(chalk.hex('#FFA726')(`\n Support mode: workspace=${effectiveWorkspace} zone=${effectiveZone}`));
200
201
  }
201
202
 
202
203
  const agent = new Agent({
@@ -206,13 +207,13 @@ export const exportCommand = new Command('export')
206
207
  ...(options.dev && { customUrl: 'http://localhost:5090' }),
207
208
  });
208
209
 
209
- const spinner = createSpinner('Obteniendo agente...');
210
+ const spinner = createSpinner('Fetching agent...');
210
211
  spinner.start();
211
212
 
212
213
  const response: any = await agent.getAgentById({ id: agentId });
213
214
  const agentData = response.agent || response.data || response;
214
215
 
215
- spinner.succeed('Agente obtenido');
216
+ spinner.succeed('Agent fetched');
216
217
 
217
218
  // Limpiar para exportacion
218
219
  const cleaned = cleanAgentForExport(agentData);
@@ -233,35 +234,46 @@ export const exportCommand = new Command('export')
233
234
  if (options.output) {
234
235
  const outputPath = path.resolve(options.output);
235
236
  fs.writeFileSync(outputPath, jsonOutput, 'utf-8');
236
- console.log(chalk.hex('#4ade80')(`\n Exportado a: ${outputPath}`));
237
+ console.log(chalk.hex('#4ade80')(`\n Exported to: ${outputPath}`));
237
238
  } else {
238
239
  console.log();
239
240
  console.log(jsonOutput);
240
241
  }
241
242
 
242
243
  console.log();
243
- console.log(chalk.gray(' Este JSON es compatible con:'));
244
- console.log(chalk.gray(' - plazbot agent create <archivo.json>'));
245
- console.log(chalk.gray(' - Importar JSON en la plataforma (AgentTraining)'));
244
+ console.log(chalk.gray(' This JSON is compatible with:'));
245
+ console.log(chalk.gray(' - plazbot agent create <file.json>'));
246
+ console.log(chalk.gray(' - Importing JSON in the platform (AgentTraining)'));
246
247
  console.log();
247
248
 
248
249
  } catch (error) {
249
- const message = error instanceof Error ? error.message : 'Error desconocido';
250
+ const message = error instanceof Error ? error.message : 'Unknown error';
250
251
  logger.error(message);
251
252
  process.exit(1);
252
253
  }
253
254
  });
254
255
 
256
+ addExamples(exportCommand, [
257
+ { description: 'Print the cleaned JSON to stdout',
258
+ command: 'plazbot agent export agt_AbcDef123' },
259
+ { description: 'Write the cleaned JSON to a file',
260
+ command: 'plazbot agent export agt_AbcDef123 -o ./agent.json' },
261
+ { description: 'Export without channels nor AI credentials (portable JSON)',
262
+ command: 'plazbot agent export agt_AbcDef123 -o ./agent.json --no-channels --no-ai' },
263
+ { description: 'Export from a different workspace (support mode)',
264
+ command: 'plazbot agent export agt_AbcDef123 -w wok_Other123 -z LA -o ./agent.json' },
265
+ ]);
266
+
255
267
  export const crossCopyCommand = new Command('cross-copy')
256
- .description('Copiar un agente de un workspace a otro')
257
- .argument('<agentId>', 'ID del agente a copiar')
258
- .requiredOption('--from-workspace <id>', 'Workspace ID de origen')
259
- .requiredOption('--to-workspace <id>', 'Workspace ID de destino')
260
- .option('--from-zone <zone>', 'Zona del workspace origen (LA o EU)', 'LA')
261
- .option('--to-zone <zone>', 'Zona del workspace destino (LA o EU)', 'LA')
262
- .option('--no-channels', 'No copiar canales (recomendado)')
263
- .option('--no-ai', 'No copiar configuracion de IA personalizada')
264
- .option('--dev', 'Usar ambiente de desarrollo', false)
268
+ .description('Copy an agent from one workspace to another')
269
+ .argument('<agentId>', 'Agent ID to copy')
270
+ .requiredOption('--from-workspace <id>', 'Source workspace ID')
271
+ .requiredOption('--to-workspace <id>', 'Target workspace ID')
272
+ .option('--from-zone <zone>', 'Source workspace zone (LA or EU)', 'LA')
273
+ .option('--to-zone <zone>', 'Target workspace zone (LA or EU)', 'LA')
274
+ .option('--no-channels', 'Do not copy channels (recommended)')
275
+ .option('--no-ai', 'Do not copy custom AI configuration')
276
+ .option('--dev', 'Use development environment', false)
265
277
  .action(async (agentId: string, options: {
266
278
  fromWorkspace: string;
267
279
  toWorkspace: string;
@@ -278,16 +290,16 @@ export const crossCopyCommand = new Command('cross-copy')
278
290
 
279
291
  console.log();
280
292
  console.log(chalk.hex('#4CAF50')(' ┌' + '─'.repeat(58) + '┐'));
281
- console.log(chalk.hex('#4CAF50')(' │') + chalk.bold(' Copiar agente entre workspaces').padEnd(68) + chalk.hex('#4CAF50')('│'));
293
+ console.log(chalk.hex('#4CAF50')(' │') + chalk.bold(' Copy agent between workspaces').padEnd(68) + chalk.hex('#4CAF50')('│'));
282
294
  console.log(chalk.hex('#4CAF50')(' └' + '─'.repeat(58) + '┘'));
283
295
  console.log();
284
- console.log(chalk.gray(` Origen: ${options.fromWorkspace} (${fromZone})`));
285
- console.log(chalk.gray(` Destino: ${options.toWorkspace} (${toZone})`));
286
- console.log(chalk.gray(` Agente: ${agentId}`));
296
+ console.log(chalk.gray(` Source: ${options.fromWorkspace} (${fromZone})`));
297
+ console.log(chalk.gray(` Target: ${options.toWorkspace} (${toZone})`));
298
+ console.log(chalk.gray(` Agent: ${agentId}`));
287
299
  console.log();
288
300
 
289
301
  // 1. Obtener agente del workspace origen
290
- const spinnerGet = createSpinner('Obteniendo agente del workspace origen...');
302
+ const spinnerGet = createSpinner('Fetching agent from source workspace...');
291
303
  spinnerGet.start();
292
304
 
293
305
  const sourceAgent = new Agent({
@@ -301,11 +313,11 @@ export const crossCopyCommand = new Command('cross-copy')
301
313
  const agentData = response.agent || response.data || response;
302
314
 
303
315
  if (!agentData || !agentData.name) {
304
- spinnerGet.fail('No se encontro el agente en el workspace origen');
316
+ spinnerGet.fail('Agent not found in source workspace');
305
317
  process.exit(1);
306
318
  }
307
319
 
308
- spinnerGet.succeed(`Agente obtenido: ${agentData.name}`);
320
+ spinnerGet.succeed(`Agent fetched: ${agentData.name}`);
309
321
 
310
322
  // 2. Limpiar JSON
311
323
  const cleaned = cleanAgentForExport(agentData);
@@ -329,29 +341,29 @@ export const crossCopyCommand = new Command('cross-copy')
329
341
 
330
342
  // 3. Mostrar resumen
331
343
  console.log();
332
- console.log(chalk.bold(' Configuracion a copiar:'));
333
- console.log(chalk.gray(` Nombre: ${cleaned.name}`));
334
- console.log(chalk.gray(` Zona destino: ${cleaned.zone}`));
335
- console.log(chalk.gray(` Canales: ${cleaned.channels?.length || 0}`));
336
- console.log(chalk.gray(` Servicios: ${cleaned.services?.length || 0}`));
337
- console.log(chalk.gray(` Acciones: ${cleaned.actions?.length || 0}`));
338
- console.log(chalk.gray(` AI Custom: ${cleaned.customAIConfig ? 'Si' : 'No'}`));
344
+ console.log(chalk.bold(' Configuration to copy:'));
345
+ console.log(chalk.gray(` Name: ${cleaned.name}`));
346
+ console.log(chalk.gray(` Target zone: ${cleaned.zone}`));
347
+ console.log(chalk.gray(` Channels: ${cleaned.channels?.length || 0}`));
348
+ console.log(chalk.gray(` Services: ${cleaned.services?.length || 0}`));
349
+ console.log(chalk.gray(` Actions: ${cleaned.actions?.length || 0}`));
350
+ console.log(chalk.gray(` Custom AI: ${cleaned.customAIConfig ? 'Yes' : 'No'}`));
339
351
  console.log();
340
352
 
341
353
  const { confirm } = await (inquirer as any).prompt([{
342
354
  type: 'confirm',
343
355
  name: 'confirm',
344
- message: 'Crear este agente en el workspace destino?',
356
+ message: 'Create this agent in the target workspace?',
345
357
  default: true,
346
358
  }]);
347
359
 
348
360
  if (!confirm) {
349
- console.log(chalk.gray(' Operacion cancelada.'));
361
+ console.log(chalk.gray(' Operation cancelled.'));
350
362
  return;
351
363
  }
352
364
 
353
365
  // 4. Crear en workspace destino
354
- const spinnerCreate = createSpinner('Creando agente en workspace destino...');
366
+ const spinnerCreate = createSpinner('Creating agent in target workspace...');
355
367
  spinnerCreate.start();
356
368
 
357
369
  const targetAgent = new Agent({
@@ -364,24 +376,33 @@ export const crossCopyCommand = new Command('cross-copy')
364
376
  const result: any = await targetAgent.addAgent(cleaned);
365
377
 
366
378
  if (result?.success === false) {
367
- spinnerCreate.fail(`Error: ${result.message || 'No se pudo crear el agente'}`);
379
+ spinnerCreate.fail(`Error: ${result.message || 'Could not create the agent'}`);
368
380
  process.exit(1);
369
381
  }
370
382
 
371
383
  const newId = result?.agentId || result?.id || result?.data?.agentId;
372
- spinnerCreate.succeed('Agente creado exitosamente');
384
+ spinnerCreate.succeed('Agent created successfully');
373
385
 
374
386
  console.log();
375
387
  if (newId) {
376
- console.log(chalk.hex('#4ade80')(` Nuevo ID: ${newId}`));
388
+ console.log(chalk.hex('#4ade80')(` New ID: ${newId}`));
377
389
  }
378
- console.log(chalk.gray(' Widget deshabilitado por defecto.'));
379
- console.log(chalk.gray(' Canales deben configurarse manualmente en el workspace destino.'));
390
+ console.log(chalk.gray(' Widget disabled by default.'));
391
+ console.log(chalk.gray(' Channels must be configured manually in the target workspace.'));
380
392
  console.log();
381
393
 
382
394
  } catch (error) {
383
- const message = error instanceof Error ? error.message : 'Error desconocido';
395
+ const message = error instanceof Error ? error.message : 'Unknown error';
384
396
  logger.error(message);
385
397
  process.exit(1);
386
398
  }
387
399
  });
400
+
401
+ addExamples(crossCopyCommand, [
402
+ { description: 'Copy an agent between two LA workspaces (skip channels)',
403
+ command: 'plazbot agent cross-copy agt_AbcDef123 --from-workspace wok_Source123 --to-workspace wok_Target456' },
404
+ { description: 'Copy across zones (LA → EU)',
405
+ command: 'plazbot agent cross-copy agt_AbcDef123 --from-workspace wok_Source123 --from-zone LA --to-workspace wok_Target456 --to-zone EU' },
406
+ { description: 'Copy preserving channels and AI providers',
407
+ command: 'plazbot agent cross-copy agt_AbcDef123 --from-workspace wok_Source123 --to-workspace wok_Target456 --channels --ai' },
408
+ ]);