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,45 +1,39 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.logger = void 0;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- exports.logger = {
1
+ import chalk from 'chalk';
2
+ export const logger = {
9
3
  info: (message) => {
10
- console.log(chalk_1.default.white(message));
4
+ console.log(chalk.white(message));
11
5
  },
12
6
  success: (message) => {
13
- console.log(chalk_1.default.hex('#66BB6A')(`\n ${message}`));
7
+ console.log(chalk.hex('#66BB6A')(`\n ${message}`));
14
8
  },
15
9
  warning: (message) => {
16
- console.log(chalk_1.default.hex('#FFA726')(`\n ${message}`));
10
+ console.log(chalk.hex('#FFA726')(`\n ${message}`));
17
11
  },
18
12
  error: (error) => {
19
13
  const message = error instanceof Error ? error.message : error;
20
- console.error(chalk_1.default.hex('#EF5350')(`\n Error: ${message}`));
14
+ console.error(chalk.hex('#EF5350')(`\n Error: ${message}`));
21
15
  },
22
16
  divider: (length = 50) => {
23
- console.log(chalk_1.default.gray('─'.repeat(length)));
17
+ console.log(chalk.gray('─'.repeat(length)));
24
18
  },
25
19
  doubleDivider: (length = 50) => {
26
- console.log(chalk_1.default.gray('═'.repeat(length)));
20
+ console.log(chalk.gray('═'.repeat(length)));
27
21
  },
28
22
  label: (key, value) => {
29
- console.log(` ${chalk_1.default.gray(key + ':')} ${chalk_1.default.white(value)}`);
23
+ console.log(` ${chalk.gray(key + ':')} ${chalk.white(value)}`);
30
24
  },
31
25
  title: (text) => {
32
- console.log(chalk_1.default.bold.hex('#4CAF50')(`\n ${text}`));
33
- console.log(chalk_1.default.gray(' ' + '─'.repeat(40)));
26
+ console.log(chalk.bold.hex('#4CAF50')(`\n ${text}`));
27
+ console.log(chalk.gray(' ' + '─'.repeat(40)));
34
28
  },
35
29
  dim: (message) => {
36
- console.log(chalk_1.default.gray(` ${message}`));
30
+ console.log(chalk.gray(` ${message}`));
37
31
  },
38
32
  json: (data) => {
39
33
  const formatted = JSON.stringify(data, null, 2)
40
34
  .split('\n')
41
35
  .map(line => ' ' + line)
42
36
  .join('\n');
43
- console.log(chalk_1.default.gray(formatted));
37
+ console.log(chalk.gray(formatted));
44
38
  }
45
39
  };
package/dist/utils/ui.js CHANGED
@@ -1,44 +1,30 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.theme = void 0;
7
- exports.createSpinner = createSpinner;
8
- exports.createTable = createTable;
9
- exports.box = box;
10
- exports.formatDate = formatDate;
11
- exports.statusBadge = statusBadge;
12
- exports.kvPair = kvPair;
13
- exports.section = section;
14
- exports.progressBar = progressBar;
15
- const chalk_1 = __importDefault(require("chalk"));
16
- const ora_1 = __importDefault(require("ora"));
17
- const cli_table3_1 = __importDefault(require("cli-table3"));
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import Table from 'cli-table3';
18
4
  // Colores del tema Plazbot
19
- exports.theme = {
20
- primary: chalk_1.default.hex('#4CAF50'),
21
- secondary: chalk_1.default.hex('#2196F3'),
22
- accent: chalk_1.default.hex('#FFA726'),
23
- success: chalk_1.default.hex('#66BB6A'),
24
- error: chalk_1.default.hex('#EF5350'),
25
- warning: chalk_1.default.hex('#FFA726'),
26
- muted: chalk_1.default.gray,
27
- bold: chalk_1.default.bold,
28
- dim: chalk_1.default.dim,
5
+ export const theme = {
6
+ primary: chalk.hex('#4CAF50'),
7
+ secondary: chalk.hex('#2196F3'),
8
+ accent: chalk.hex('#FFA726'),
9
+ success: chalk.hex('#66BB6A'),
10
+ error: chalk.hex('#EF5350'),
11
+ warning: chalk.hex('#FFA726'),
12
+ muted: chalk.gray,
13
+ bold: chalk.bold,
14
+ dim: chalk.dim,
29
15
  };
30
16
  // Spinner
31
- function createSpinner(text) {
32
- return (0, ora_1.default)({
33
- text: exports.theme.muted(text),
17
+ export function createSpinner(text) {
18
+ return ora({
19
+ text: theme.muted(text),
34
20
  spinner: 'dots',
35
21
  color: 'green',
36
22
  });
37
23
  }
38
24
  // Tabla formateada
39
- function createTable(headers, rows) {
40
- const table = new cli_table3_1.default({
41
- head: headers.map(h => exports.theme.bold.hex('#4CAF50')(h)),
25
+ export function createTable(headers, rows) {
26
+ const table = new Table({
27
+ head: headers.map(h => theme.bold.hex('#4CAF50')(h)),
42
28
  style: {
43
29
  head: [],
44
30
  border: ['gray'],
@@ -54,22 +40,22 @@ function createTable(headers, rows) {
54
40
  return table.toString();
55
41
  }
56
42
  // Box simple
57
- function box(content, title) {
43
+ export function box(content, title) {
58
44
  const lines = content.split('\n');
59
45
  const maxLen = Math.max(...lines.map(l => stripAnsi(l).length), title ? stripAnsi(title).length + 4 : 0);
60
46
  const width = maxLen + 4;
61
47
  let result = '';
62
48
  if (title) {
63
- result += exports.theme.muted(' ┌─ ') + exports.theme.primary(title) + exports.theme.muted(' ' + '─'.repeat(Math.max(0, width - stripAnsi(title).length - 5))) + exports.theme.muted('┐') + '\n';
49
+ result += theme.muted(' ┌─ ') + theme.primary(title) + theme.muted(' ' + '─'.repeat(Math.max(0, width - stripAnsi(title).length - 5))) + theme.muted('┐') + '\n';
64
50
  }
65
51
  else {
66
- result += exports.theme.muted(' ┌' + '─'.repeat(width) + '┐') + '\n';
52
+ result += theme.muted(' ┌' + '─'.repeat(width) + '┐') + '\n';
67
53
  }
68
54
  for (const line of lines) {
69
55
  const pad = ' '.repeat(Math.max(0, maxLen - stripAnsi(line).length));
70
- result += exports.theme.muted(' │') + ' ' + line + pad + ' ' + exports.theme.muted('│') + '\n';
56
+ result += theme.muted(' │') + ' ' + line + pad + ' ' + theme.muted('│') + '\n';
71
57
  }
72
- result += exports.theme.muted(' └' + '─'.repeat(width) + '┘');
58
+ result += theme.muted(' └' + '─'.repeat(width) + '┘');
73
59
  return result;
74
60
  }
75
61
  // Strip ANSI codes para calcular longitud real
@@ -77,7 +63,7 @@ function stripAnsi(str) {
77
63
  return str.replace(/\x1b\[[0-9;]*m/g, '');
78
64
  }
79
65
  // Formato de fecha legible
80
- function formatDate(date) {
66
+ export function formatDate(date) {
81
67
  const d = new Date(date);
82
68
  return d.toLocaleDateString('es-ES', {
83
69
  year: 'numeric',
@@ -88,24 +74,24 @@ function formatDate(date) {
88
74
  });
89
75
  }
90
76
  // Status badge
91
- function statusBadge(enabled) {
77
+ export function statusBadge(enabled) {
92
78
  return enabled
93
- ? exports.theme.success('● activo')
94
- : exports.theme.error('○ inactivo');
79
+ ? theme.success('● activo')
80
+ : theme.error('○ inactivo');
95
81
  }
96
82
  // Key-value pair formateado
97
- function kvPair(key, value) {
98
- return ` ${exports.theme.muted(key + ':')} ${value}`;
83
+ export function kvPair(key, value) {
84
+ return ` ${theme.muted(key + ':')} ${value}`;
99
85
  }
100
86
  // Sección con título
101
- function section(title) {
102
- return '\n' + exports.theme.bold.hex('#4CAF50')(` ${title}`) + '\n' + exports.theme.muted(' ' + '─'.repeat(40));
87
+ export function section(title) {
88
+ return '\n' + theme.bold.hex('#4CAF50')(` ${title}`) + '\n' + theme.muted(' ' + '─'.repeat(40));
103
89
  }
104
90
  // Progress bar simple
105
- function progressBar(current, total, width = 30) {
91
+ export function progressBar(current, total, width = 30) {
106
92
  const percent = Math.round((current / total) * 100);
107
93
  const filled = Math.round((current / total) * width);
108
94
  const empty = width - filled;
109
- const bar = exports.theme.success('█'.repeat(filled)) + exports.theme.muted('░'.repeat(empty));
110
- return `${bar} ${exports.theme.bold(percent + '%')} (${current}/${total})`;
95
+ const bar = theme.success('█'.repeat(filled)) + theme.muted('░'.repeat(empty));
96
+ return `${bar} ${theme.bold(percent + '%')} (${current}/${total})`;
111
97
  }
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "plazbot-cli",
3
- "version": "0.2.26",
3
+ "version": "0.3.2",
4
4
  "description": "CLI para Plazbot SDK",
5
+ "type": "module",
5
6
  "main": "dist/cli.js",
6
7
  "bin": {
7
8
  "plazbot": "dist/cli.js"
8
9
  },
9
10
  "scripts": {
10
- "build": "tsc",
11
+ "build": "tsc && mkdir -p dist/schemas && cp src/schemas/*.json dist/schemas/ && chmod +x dist/cli.js",
11
12
  "start": "node dist/cli.js",
12
13
  "dev": "tsc -w",
14
+ "typecheck": "tsc --noEmit",
13
15
  "prepare:dev": "npm uninstall plazbot && npm install file:../Plazbot-SDK-v2.0",
14
16
  "prepare:prod": "npm uninstall plazbot && npm install plazbot@latest",
15
17
  "prepublishOnly": "npm run prepare:prod && npm run build",
@@ -32,25 +34,35 @@
32
34
  "license": "MIT",
33
35
  "dependencies": {
34
36
  "@microsoft/signalr": "^10.0.0",
35
- "@types/inquirer": "^9.0.8",
37
+ "ajv": "^8.20.0",
38
+ "ajv-formats": "^3.0.1",
36
39
  "axios": "^1.6.0",
37
- "boxen": "^5.1.2",
38
- "chalk": "^4.1.2",
40
+ "boxen": "^7.1.1",
41
+ "chalk": "^5.3.0",
42
+ "cli-highlight": "^2.1.11",
39
43
  "cli-table3": "^0.6.5",
40
44
  "commander": "^12.0.0",
41
- "figures": "^3.2.0",
42
- "gradient-string": "^2.0.2",
45
+ "figures": "^6.1.0",
46
+ "gradient-string": "^3.0.0",
47
+ "ink": "^5.0.1",
48
+ "ink-spinner": "^5.0.0",
49
+ "ink-syntax-highlight": "^2.0.2",
50
+ "ink-text-input": "^6.0.0",
43
51
  "inquirer": "^12.6.3",
44
52
  "marked": "^12.0.2",
45
53
  "marked-terminal": "^7.2.1",
46
- "ora": "^5.4.1",
47
- "plazbot": "^2.1.4"
54
+ "ora": "^8.0.1",
55
+ "plazbot": "^2.1.4",
56
+ "react": "^18.3.1",
57
+ "zustand": "^4.5.4"
48
58
  },
49
59
  "devDependencies": {
60
+ "@types/inquirer": "^9.0.8",
50
61
  "@types/node": "^20.0.0",
62
+ "@types/react": "^18.3.3",
51
63
  "typescript": "^5.0.0"
52
64
  },
53
65
  "engines": {
54
- "node": ">=16.0.0"
66
+ "node": ">=18.17.0"
55
67
  }
56
68
  }
package/src/cli.ts CHANGED
@@ -1,19 +1,32 @@
1
1
  #!/usr/bin/env node
2
2
  import { program } from 'commander';
3
- import { portalCommands } from './commands/portal';
4
- import { authCommands } from './commands/auth';
5
- import { agentCommands } from './commands/agent';
6
- import { whatsappCommands } from './commands/whatsapp';
7
- import { workersCommands } from './commands/workers';
8
- import { showBanner } from './utils/banner';
3
+ import { readFileSync } from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { dirname, join } from 'node:path';
6
+ import { portalCommands } from './commands/portal/index.js';
7
+ import { authCommands } from './commands/auth/index.js';
8
+ import { agentCommands } from './commands/agent/index.js';
9
+ import { whatsappCommands } from './commands/whatsapp/index.js';
10
+ import { workersCommands } from './commands/workers/index.js';
11
+ import { studioCommand } from './studio/index.js';
12
+ import { showBanner } from './utils/banner.js';
13
+
14
+ // Guard de runtime: Plazbot CLI v0.3+ requiere Node 18.17+
15
+ const [major, minor] = process.versions.node.split('.').map(Number);
16
+ if (major < 18 || (major === 18 && minor < 17)) {
17
+ console.error(`Plazbot CLI v0.3+ requires Node.js >=18.17.0. Current version: ${process.versions.node}`);
18
+ process.exit(1);
19
+ }
9
20
 
10
21
  // Leer version desde package.json
11
- const { version } = require('../package.json');
22
+ const __dirname = dirname(fileURLToPath(import.meta.url));
23
+ const pkgPath = join(__dirname, '..', 'package.json');
24
+ const { version } = JSON.parse(readFileSync(pkgPath, 'utf-8'));
12
25
 
13
26
  // Configuracion basica del CLI
14
27
  program
15
28
  .name('plazbot')
16
- .description('CLI oficial de Plazbot - Agentes de IA para WhatsApp, portales y desarrolladores')
29
+ .description('Official Plazbot CLI - AI agents for WhatsApp, portals and developers')
17
30
  .version(version);
18
31
 
19
32
  // Registrar todos los comandos de autenticacion
@@ -31,6 +44,9 @@ program.addCommand(whatsappCommands);
31
44
  // Registrar todos los comandos de Workers
32
45
  program.addCommand(workersCommands);
33
46
 
47
+ // Registrar el comando Studio (REPL interactivo)
48
+ program.addCommand(studioCommand);
49
+
34
50
  // Si no se pasan argumentos, mostrar banner
35
51
  if (process.argv.length <= 2) {
36
52
  showBanner().then(() => {
@@ -1,21 +1,64 @@
1
1
  import { Command } from 'commander';
2
2
  import { Agent } from 'plazbot';
3
3
  import inquirer from 'inquirer';
4
- import { getStoredCredentials } from '../../utils/credentials';
5
- import { logger } from '../../utils/logger';
6
- import { createSpinner, theme, section, kvPair } from '../../utils/ui';
7
- import { AgentCommandOptions } from '../../types/agent';
4
+ import { getStoredCredentials } from '../../utils/credentials.js';
5
+ import { logger } from '../../utils/logger.js';
6
+ import { addExamples } from '../../utils/help.js';
7
+ import { describeAgentLoadError } from '../../utils/agent-errors.js';
8
+ import { createSpinner, theme, section, kvPair } from '../../utils/ui.js';
9
+ import { AgentCommandOptions } from '../../types/agent.js';
8
10
 
11
+ // Catalogo de modelos sincronizado con el front (AIModelSection.tsx).
12
+ // Si se actualiza el dropdown del front, actualizar aqui tambien.
9
13
  const MODELS: Record<string, string[]> = {
10
- openai: ['gpt-4o', 'gpt-4', 'gpt-3.5-turbo', 'o1-preview', 'o1-mini'],
11
- claude: ['claude-3-5-sonnet-20241022', 'claude-3-opus-20240229', 'claude-3-haiku-20240307'],
12
- gemini: ['gemini-2.0-flash', 'gemini-1.5-pro', 'gemini-1.5-flash'],
14
+ openai: [
15
+ // GPT-5.4 (flagship actual)
16
+ 'gpt-5.4', 'gpt-5.4-mini', 'gpt-5.4-nano',
17
+ // GPT-5.2
18
+ 'gpt-5.2',
19
+ // GPT-5.1
20
+ 'gpt-5.1', 'gpt-5.1-codex', 'gpt-5.1-codex-mini',
21
+ // GPT-5
22
+ 'gpt-5', 'gpt-5-mini', 'gpt-5-nano',
23
+ // GPT-4.1
24
+ 'gpt-4.1', 'gpt-4.1-mini', 'gpt-4.1-nano',
25
+ // GPT-4o
26
+ 'gpt-4o', 'gpt-4o-mini',
27
+ // Razonamiento (o-series)
28
+ 'o4-mini', 'o3', 'o3-mini', 'o1-2024-12-17',
29
+ // Legacy
30
+ 'gpt-4-turbo', 'gpt-3.5-turbo',
31
+ ],
32
+ claude: [
33
+ // Mythos-class (flagship)
34
+ 'claude-fable-5',
35
+ // Claude 4.6
36
+ 'claude-opus-4-6', 'claude-sonnet-4-6',
37
+ // Claude 4.5
38
+ 'claude-opus-4-5-20251101', 'claude-sonnet-4-5-20250929', 'claude-haiku-4-5-20251001',
39
+ // Claude 4.x
40
+ 'claude-opus-4-1-20250805', 'claude-opus-4-20250514', 'claude-sonnet-4-20250514',
41
+ ],
42
+ gemini: [
43
+ // Gemini 3.1 (flagship actual)
44
+ 'gemini-3.1-pro-preview', 'gemini-3.1-flash-lite-preview',
45
+ // Gemini 2.5
46
+ 'gemini-2.5-pro', 'gemini-2.5-flash', 'gemini-2.5-flash-lite',
47
+ // Gemini 2.0
48
+ 'gemini-2.0-flash',
49
+ ],
50
+ };
51
+
52
+ const DEFAULT_MODEL: Record<string, string> = {
53
+ openai: 'gpt-4o',
54
+ claude: 'claude-sonnet-4-6',
55
+ gemini: 'gemini-2.5-pro',
13
56
  };
14
57
 
15
58
  export const aiConfigCommand = new Command('ai-config')
16
- .description('Configurar proveedor de IA del agente')
17
- .argument('<agentId>', 'ID del agente')
18
- .option('--dev', 'Usar ambiente de desarrollo', false)
59
+ .description('Configure the agent AI provider')
60
+ .argument('<agentId>', 'Agent ID')
61
+ .option('--dev', 'Use development environment', false)
19
62
  .action(async (agentId: string, options: AgentCommandOptions) => {
20
63
  try {
21
64
  const credentials = await getStoredCredentials();
@@ -26,36 +69,43 @@ export const aiConfigCommand = new Command('ai-config')
26
69
  ...(options.dev && { customUrl: "http://localhost:5090" })
27
70
  });
28
71
 
29
- const spinner = createSpinner('Cargando agente...');
72
+ const spinner = createSpinner('Loading agent...');
30
73
  spinner.start();
31
- const _res: any = await agent.getAgentById({ id: agentId });
32
- const agentData = _res.agent || _res.data || _res;
33
- spinner.stop();
74
+ let agentData: any;
75
+ try {
76
+ const _res: any = await agent.getAgentById({ id: agentId });
77
+ agentData = _res.agent || _res.data || _res;
78
+ spinner.stop();
79
+ } catch (loadErr) {
80
+ spinner.stop();
81
+ logger.error(describeAgentLoadError(loadErr, agentId, credentials, { dev: options.dev }));
82
+ process.exit(1);
83
+ }
34
84
 
35
- console.log(section('Configuracion de IA - ' + (agentData.name || agentId)));
85
+ console.log(section('AI Configuration - ' + (agentData.name || agentId)));
36
86
 
37
87
  const currentProviders = agentData.aiProviders || [];
38
88
  if (currentProviders.length > 0 && agentData.customAIConfig) {
39
- console.log(theme.bold('\n Configuracion actual:'));
89
+ console.log(theme.bold('\n Current configuration:'));
40
90
  currentProviders.forEach((p: any) => {
41
- console.log(kvPair(' Proveedor', p.provider));
42
- console.log(kvPair(' Modelo', p.model));
43
- console.log(kvPair(' Temperatura', String(p.temperature)));
91
+ console.log(kvPair(' Provider', p.provider));
92
+ console.log(kvPair(' Model', p.model));
93
+ console.log(kvPair(' Temperature', String(p.temperature)));
44
94
  console.log(kvPair(' Max Tokens', String(p.maxTokens)));
45
- console.log(kvPair(' Default', p.isDefault ? 'Si' : 'No'));
95
+ console.log(kvPair(' Default', p.isDefault ? 'Yes' : 'No'));
46
96
  });
47
97
  } else {
48
- console.log(theme.muted('\n Usando configuracion de IA por defecto (Plazbot)'));
98
+ console.log(theme.muted('\n Using default AI configuration (Plazbot)'));
49
99
  }
50
100
 
51
101
  const { action } = await (inquirer as any).prompt([{
52
102
  type: 'list',
53
103
  name: 'action',
54
- message: 'Que deseas hacer?',
104
+ message: 'What would you like to do?',
55
105
  choices: [
56
- { name: 'Configurar nuevo proveedor', value: 'set' },
57
- { name: 'Usar configuracion por defecto', value: 'reset' },
58
- { name: 'Salir', value: 'exit' },
106
+ { name: 'Configure new provider', value: 'set' },
107
+ { name: 'Use default configuration', value: 'reset' },
108
+ { name: 'Exit', value: 'exit' },
59
109
  ],
60
110
  }]);
61
111
 
@@ -63,24 +113,24 @@ export const aiConfigCommand = new Command('ai-config')
63
113
 
64
114
  if (action === 'reset') {
65
115
  const { id, _id, ...resetConfig } = { ...agentData, customAIConfig: false, aiProviders: [] };
66
- const resetSpinner = createSpinner('Reseteando configuracion...');
116
+ const resetSpinner = createSpinner('Resetting configuration...');
67
117
  resetSpinner.start();
68
118
  await agent.updateAgent(agentId, resetConfig);
69
- resetSpinner.succeed('Usando configuracion por defecto');
119
+ resetSpinner.succeed('Using default configuration');
70
120
  return;
71
121
  }
72
122
 
73
123
  // Configurar nuevo proveedor
74
124
  const ai = await (inquirer as any).prompt([
75
- { type: 'list', name: 'provider', message: 'Proveedor:', choices: ['openai', 'claude', 'gemini'] },
125
+ { type: 'list', name: 'provider', message: 'Provider:', choices: ['openai', 'claude', 'gemini'] },
76
126
  ]);
77
127
 
78
128
  const models = MODELS[ai.provider] || MODELS.openai;
79
129
 
80
130
  const config = await (inquirer as any).prompt([
81
- { type: 'list', name: 'model', message: 'Modelo:', choices: models },
82
- { type: 'password', name: 'apiToken', message: 'API Token:', mask: '*', validate: (v: string) => v.length > 0 || 'Requerido' },
83
- { type: 'number', name: 'temperature', message: 'Temperatura (0-2):', default: 0.7 },
131
+ { type: 'list', name: 'model', message: 'Model:', choices: models, default: DEFAULT_MODEL[ai.provider] },
132
+ { type: 'password', name: 'apiToken', message: 'API Token:', mask: '*', validate: (v: string) => v.length > 0 || 'Required' },
133
+ { type: 'number', name: 'temperature', message: 'Temperature (0-2):', default: 0.7 },
84
134
  { type: 'number', name: 'maxTokens', message: 'Max tokens (1024-16384):', default: 4096 },
85
135
  ]);
86
136
 
@@ -96,14 +146,19 @@ export const aiConfigCommand = new Command('ai-config')
96
146
  isDefault: true,
97
147
  }],
98
148
  };
99
- const updateSpinner = createSpinner('Guardando configuracion...');
149
+ const updateSpinner = createSpinner('Saving configuration...');
100
150
  updateSpinner.start();
101
151
  await agent.updateAgent(agentId, updatedConfig);
102
- updateSpinner.succeed(`Proveedor configurado: ${ai.provider} / ${config.model}`);
152
+ updateSpinner.succeed(`Provider configured: ${ai.provider} / ${config.model}`);
103
153
 
104
154
  } catch (error) {
105
- const message = error instanceof Error ? error.message : 'Error desconocido';
155
+ const message = error instanceof Error ? error.message : 'Unknown error';
106
156
  logger.error(message);
107
157
  process.exit(1);
108
158
  }
109
159
  });
160
+
161
+ addExamples(aiConfigCommand, [
162
+ { description: 'Pick provider/model/API key for the agent interactively',
163
+ command: 'plazbot agent ai-config agt_AbcDef123' },
164
+ ]);