plazbot-cli 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +67 -111
  2. package/dist/cli.js +26 -11
  3. package/dist/commands/agent/ai-config.js +264 -63
  4. package/dist/commands/agent/chat.js +16 -11
  5. package/dist/commands/agent/copy.js +49 -13
  6. package/dist/commands/agent/create.js +62 -17
  7. package/dist/commands/agent/delete.js +50 -39
  8. package/dist/commands/agent/enable-widget.js +47 -27
  9. package/dist/commands/agent/export.js +179 -88
  10. package/dist/commands/agent/files.js +155 -73
  11. package/dist/commands/agent/get.js +24 -16
  12. package/dist/commands/agent/index.js +12 -10
  13. package/dist/commands/agent/list.js +20 -11
  14. package/dist/commands/agent/monitor.js +101 -53
  15. package/dist/commands/agent/on-message.js +55 -32
  16. package/dist/commands/agent/set.js +230 -82
  17. package/dist/commands/agent/templates.js +259 -156
  18. package/dist/commands/agent/tools.js +356 -123
  19. package/dist/commands/agent/update.js +69 -28
  20. package/dist/commands/agent/validate.js +72 -40
  21. package/dist/commands/agent/wizard.js +240 -329
  22. package/dist/commands/auth/browser-login.js +37 -31
  23. package/dist/commands/auth/login.js +49 -45
  24. package/dist/commands/auth/logout.js +20 -11
  25. package/dist/commands/auth/status.js +36 -12
  26. package/dist/commands/auth/workspace.js +61 -27
  27. package/dist/commands/portal/add-agent.js +106 -45
  28. package/dist/commands/portal/add-link.js +25 -28
  29. package/dist/commands/portal/clear-links.js +39 -19
  30. package/dist/commands/portal/create.js +66 -37
  31. package/dist/commands/portal/delete.js +40 -45
  32. package/dist/commands/portal/get.js +21 -54
  33. package/dist/commands/portal/index.js +12 -12
  34. package/dist/commands/portal/list.js +34 -52
  35. package/dist/commands/portal/shared.js +92 -0
  36. package/dist/commands/portal/update.js +100 -70
  37. package/dist/commands/whatsapp/broadcast.js +169 -77
  38. package/dist/commands/whatsapp/channels.js +167 -65
  39. package/dist/commands/whatsapp/chat.js +45 -46
  40. package/dist/commands/whatsapp/connect-flow.js +16 -15
  41. package/dist/commands/whatsapp/connect.js +36 -21
  42. package/dist/commands/whatsapp/delete-webhook.js +42 -25
  43. package/dist/commands/whatsapp/index.js +15 -16
  44. package/dist/commands/whatsapp/register-webhook.js +43 -26
  45. package/dist/commands/whatsapp/send-template.js +62 -61
  46. package/dist/commands/whatsapp/send.js +46 -33
  47. package/dist/commands/whatsapp/setup.js +62 -52
  48. package/dist/commands/whatsapp/shared.js +75 -0
  49. package/dist/commands/whatsapp/widget.js +82 -45
  50. package/dist/commands/workers/deploy.js +80 -58
  51. package/dist/commands/workers/index.js +8 -8
  52. package/dist/commands/workers/list.js +42 -20
  53. package/dist/commands/workers/logs.js +139 -36
  54. package/dist/commands/workers/remove.js +45 -47
  55. package/dist/commands/workers/secret.js +159 -83
  56. package/dist/commands/workers/test.js +108 -60
  57. package/dist/schemas/agent.config.schema.json +159 -8
  58. package/dist/studio/api/sseClient.js +1 -1
  59. package/dist/studio/api/studioApi.js +8 -0
  60. package/dist/studio/components/App.js +12 -0
  61. package/dist/studio/components/Footer.js +1 -1
  62. package/dist/studio/index.js +77 -14
  63. package/dist/studio/runOneShot.js +62 -23
  64. package/dist/studio/runRepl.js +5 -5
  65. package/dist/studio/slash/handlers.js +11 -8
  66. package/dist/studio/state/store.js +1 -1
  67. package/dist/utils/agent-errors.js +14 -11
  68. package/dist/utils/agent-patch.js +60 -0
  69. package/dist/utils/banner.js +9 -5
  70. package/dist/utils/confirm.js +31 -0
  71. package/dist/utils/credentials.js +13 -3
  72. package/dist/utils/logger.js +13 -10
  73. package/dist/utils/output.js +78 -0
  74. package/dist/utils/phone.js +22 -0
  75. package/dist/utils/ui.js +14 -11
  76. package/package.json +2 -2
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'node:url';
5
5
  import Ajv from 'ajv';
6
6
  import addFormats from 'ajv-formats';
7
7
  import chalk from 'chalk';
8
- import { logger } from '../../utils/logger.js';
8
+ import { jsonOption, isJsonMode, printJson, fail, CliError } from '../../utils/output.js';
9
9
  import { addExamples } from '../../utils/help.js';
10
10
  const __filename = fileURLToPath(import.meta.url);
11
11
  const __dirname = dirname(__filename);
@@ -21,63 +21,86 @@ function loadSchema() {
21
21
  return JSON.parse(readFileSync(candidate, 'utf-8'));
22
22
  }
23
23
  }
24
- throw new Error('No se encontro el schema agent.config.schema.json. Reinstala el CLI.');
24
+ throw new CliError('The agent schema (agent.config.schema.json) was not found.', 'schema_missing', 'Reinstall the CLI: npm install -g plazbot-cli');
25
+ }
26
+ // --strict: cierra con additionalProperties:false todo objeto del schema que declare
27
+ // properties y no lo fije ya, para detectar campos desconocidos (typos) en objetos anidados.
28
+ function closeObjects(node) {
29
+ if (!node || typeof node !== 'object')
30
+ return;
31
+ if (node.properties && typeof node.properties === 'object') {
32
+ if (node.additionalProperties === undefined)
33
+ node.additionalProperties = false;
34
+ Object.values(node.properties).forEach(closeObjects);
35
+ }
36
+ if (Array.isArray(node.items))
37
+ node.items.forEach(closeObjects);
38
+ else
39
+ closeObjects(node.items);
40
+ if (typeof node.additionalProperties === 'object')
41
+ closeObjects(node.additionalProperties);
25
42
  }
26
43
  // Traduce una ruta de AJV (e.g. "/actions/0/action/2") en migas legibles
27
- // estilo "acciones -> 0 -> action -> 2".
44
+ // estilo "actions -> 0 -> action -> 2".
28
45
  function humanizePath(instancePath) {
29
46
  if (!instancePath || instancePath === '')
30
- return '(raiz)';
47
+ return '(root)';
31
48
  return instancePath
32
49
  .replace(/^\//, '')
33
50
  .split('/')
34
51
  .filter(Boolean)
35
52
  .join(' -> ');
36
53
  }
37
- function formatError(err) {
38
- const path = humanizePath(err.instancePath);
39
- const keyword = err.keyword;
40
- let detail = err.message || 'error de validacion';
41
- if (keyword === 'required' && err.params && err.params.missingProperty) {
42
- detail = `debe tener la propiedad requerida '${err.params.missingProperty}'`;
54
+ function describeAjvError(err) {
55
+ const params = (err.params || {});
56
+ let detail = err.message || 'validation error';
57
+ if (err.keyword === 'required' && params.missingProperty) {
58
+ detail = `missing required property '${params.missingProperty}'`;
43
59
  }
44
- else if (keyword === 'enum' && err.params && err.params.allowedValues) {
45
- const allowed = err.params.allowedValues;
46
- detail = `debe ser uno de: ${allowed.join(', ')}`;
60
+ else if (err.keyword === 'enum' && params.allowedValues) {
61
+ detail = `must be one of: ${params.allowedValues.join(', ')}`;
47
62
  }
48
- else if (keyword === 'type' && err.params && err.params.type) {
49
- detail = `debe ser de tipo ${err.params.type}`;
63
+ else if (err.keyword === 'type' && params.type) {
64
+ detail = `must be of type ${params.type}`;
50
65
  }
51
- else if (keyword === 'minLength') {
52
- detail = 'no puede estar vacio';
66
+ else if (err.keyword === 'minLength') {
67
+ detail = 'cannot be empty';
53
68
  }
54
- else if (keyword === 'pattern') {
55
- detail = `no cumple el patron ${err.params.pattern}`;
69
+ else if (err.keyword === 'pattern') {
70
+ detail = `does not match the pattern ${params.pattern}`;
56
71
  }
57
- return `${path}: ${detail}`;
72
+ else if (err.keyword === 'additionalProperties' && params.additionalProperty) {
73
+ detail = `unknown property '${params.additionalProperty}'`;
74
+ }
75
+ return { path: humanizePath(err.instancePath), message: detail };
58
76
  }
59
77
  export const validateCommand = new Command('validate')
60
78
  .description('Validate an agent JSON file against the official schema')
61
79
  .argument('<file>', 'Path to the agent JSON file')
62
- .option('--strict', 'Fail on additional unknown properties', false)
63
- .option('--raw', 'Print raw AJV errors as JSON', false)
80
+ .option('--strict', 'Also fail on unknown properties (catches typos in nested objects)', false)
81
+ .option('--raw', 'Print the raw AJV errors as JSON', false)
82
+ .addOption(jsonOption('Print the result as JSON ({"valid","errors":[{"path","message"}]})'))
64
83
  .action(async (file, options) => {
65
84
  try {
66
85
  const filePath = resolve(process.cwd(), file);
67
86
  if (!existsSync(filePath)) {
68
- logger.error(`No existe el archivo: ${filePath}`);
69
- process.exit(1);
87
+ throw new CliError(`File not found: ${filePath}`, 'file_not_found');
70
88
  }
71
89
  let data;
72
90
  try {
73
91
  data = JSON.parse(readFileSync(filePath, 'utf-8'));
74
92
  }
75
93
  catch (parseErr) {
76
- const msg = parseErr instanceof Error ? parseErr.message : 'JSON invalido';
77
- logger.error(`JSON con sintaxis invalida: ${msg}`);
78
- process.exit(1);
94
+ const msg = parseErr instanceof Error ? parseErr.message : 'invalid JSON';
95
+ if (isJsonMode()) {
96
+ printJson({ valid: false, errors: [{ path: '(root)', message: `Invalid JSON syntax: ${msg}` }] });
97
+ process.exit(1);
98
+ }
99
+ throw new CliError(`Invalid JSON syntax: ${msg}`, 'invalid_json');
79
100
  }
80
101
  const schema = loadSchema();
102
+ if (options.strict)
103
+ closeObjects(schema);
81
104
  const ajv = new Ajv({
82
105
  allErrors: true,
83
106
  strict: false,
@@ -87,10 +110,14 @@ export const validateCommand = new Command('validate')
87
110
  const validate = ajv.compile(schema);
88
111
  const ok = validate(data);
89
112
  if (ok) {
113
+ if (isJsonMode()) {
114
+ printJson({ valid: true, errors: [] });
115
+ return;
116
+ }
90
117
  console.log();
91
- console.log(chalk.hex('#66BB6A')(' Schema valido'));
92
- const name = data?.name ? ` (${data.name})` : '';
93
- console.log(chalk.gray(` El agente${name} cumple con el schema oficial.`));
118
+ console.log(chalk.hex('#66BB6A')(' Valid schema'));
119
+ const name = data?.name ? ` "${data.name}"` : '';
120
+ console.log(chalk.gray(` The agent${name} matches the official schema${options.strict ? ' (strict mode)' : ''}.`));
94
121
  console.log();
95
122
  return;
96
123
  }
@@ -99,29 +126,34 @@ export const validateCommand = new Command('validate')
99
126
  const rawErrors = validate.errors || [];
100
127
  const errors = rawErrors.filter(e => e.keyword !== 'if' && !/match "then" schema/.test(e.message || ''));
101
128
  if (options.raw) {
102
- console.log(JSON.stringify(errors, null, 2));
129
+ printJson(errors);
130
+ process.exit(1);
131
+ }
132
+ const described = errors.map(describeAjvError);
133
+ if (isJsonMode()) {
134
+ printJson({ valid: false, errors: described });
103
135
  process.exit(1);
104
136
  }
105
137
  console.log();
106
- console.log(chalk.hex('#EF5350')(` Schema invalido (${errors.length} ${errors.length === 1 ? 'error' : 'errores'}):`));
138
+ console.log(chalk.hex('#EF5350')(` Invalid schema (${described.length} ${described.length === 1 ? 'error' : 'errors'}):`));
107
139
  console.log();
108
- errors.forEach((err, i) => {
109
- console.log(chalk.hex('#EF5350')(` ${i + 1}. ${formatError(err)}`));
140
+ described.forEach((err, i) => {
141
+ console.log(chalk.hex('#EF5350')(` ${i + 1}. ${err.path}: ${err.message}`));
110
142
  });
111
143
  console.log();
112
- console.log(chalk.gray(' Sugerencia: usa --raw para inspeccionar los errores AJV en JSON.'));
144
+ console.log(chalk.gray(' Tip: use --raw to inspect the AJV errors as JSON.'));
113
145
  console.log();
114
146
  process.exit(1);
115
147
  }
116
148
  catch (error) {
117
- const message = error instanceof Error ? error.message : 'Error desconocido';
118
- logger.error(message);
119
- process.exit(1);
149
+ fail(error);
120
150
  }
121
151
  });
122
152
  addExamples(validateCommand, [
123
153
  { description: 'Validate an exported agent file against the schema',
124
154
  command: 'plazbot agent validate ./agent.json' },
125
- { description: 'Print raw AJV errors as JSON for tooling',
126
- command: 'plazbot agent validate ./agent.json --raw' },
155
+ { description: 'Also flag unknown properties (typos)',
156
+ command: 'plazbot agent validate ./agent.json --strict' },
157
+ { description: 'Get a machine-readable result (exit code 1 when invalid)',
158
+ command: 'plazbot agent validate ./agent.json --json' },
127
159
  ]);