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.
- package/README.md +67 -111
- package/dist/cli.js +26 -11
- package/dist/commands/agent/ai-config.js +264 -63
- package/dist/commands/agent/chat.js +16 -11
- package/dist/commands/agent/copy.js +49 -13
- package/dist/commands/agent/create.js +62 -17
- package/dist/commands/agent/delete.js +50 -39
- package/dist/commands/agent/enable-widget.js +47 -27
- package/dist/commands/agent/export.js +179 -88
- package/dist/commands/agent/files.js +155 -73
- package/dist/commands/agent/get.js +24 -16
- package/dist/commands/agent/index.js +12 -10
- package/dist/commands/agent/list.js +20 -11
- package/dist/commands/agent/monitor.js +101 -53
- package/dist/commands/agent/on-message.js +55 -32
- package/dist/commands/agent/set.js +230 -82
- package/dist/commands/agent/templates.js +259 -156
- package/dist/commands/agent/tools.js +356 -123
- package/dist/commands/agent/update.js +69 -28
- package/dist/commands/agent/validate.js +72 -40
- package/dist/commands/agent/wizard.js +240 -329
- package/dist/commands/auth/browser-login.js +37 -31
- package/dist/commands/auth/login.js +49 -45
- package/dist/commands/auth/logout.js +20 -11
- package/dist/commands/auth/status.js +36 -12
- package/dist/commands/auth/workspace.js +61 -27
- package/dist/commands/portal/add-agent.js +106 -45
- package/dist/commands/portal/add-link.js +25 -28
- package/dist/commands/portal/clear-links.js +39 -19
- package/dist/commands/portal/create.js +66 -37
- package/dist/commands/portal/delete.js +40 -45
- package/dist/commands/portal/get.js +21 -54
- package/dist/commands/portal/index.js +12 -12
- package/dist/commands/portal/list.js +34 -52
- package/dist/commands/portal/shared.js +92 -0
- package/dist/commands/portal/update.js +100 -70
- package/dist/commands/whatsapp/broadcast.js +169 -77
- package/dist/commands/whatsapp/channels.js +167 -65
- package/dist/commands/whatsapp/chat.js +45 -46
- package/dist/commands/whatsapp/connect-flow.js +16 -15
- package/dist/commands/whatsapp/connect.js +36 -21
- package/dist/commands/whatsapp/delete-webhook.js +42 -25
- package/dist/commands/whatsapp/index.js +15 -16
- package/dist/commands/whatsapp/register-webhook.js +43 -26
- package/dist/commands/whatsapp/send-template.js +62 -61
- package/dist/commands/whatsapp/send.js +46 -33
- package/dist/commands/whatsapp/setup.js +62 -52
- package/dist/commands/whatsapp/shared.js +75 -0
- package/dist/commands/whatsapp/widget.js +82 -45
- package/dist/commands/workers/deploy.js +80 -58
- package/dist/commands/workers/index.js +8 -8
- package/dist/commands/workers/list.js +42 -20
- package/dist/commands/workers/logs.js +139 -36
- package/dist/commands/workers/remove.js +45 -47
- package/dist/commands/workers/secret.js +159 -83
- package/dist/commands/workers/test.js +108 -60
- package/dist/schemas/agent.config.schema.json +159 -8
- package/dist/studio/api/sseClient.js +1 -1
- package/dist/studio/api/studioApi.js +8 -0
- package/dist/studio/components/App.js +12 -0
- package/dist/studio/components/Footer.js +1 -1
- package/dist/studio/index.js +77 -14
- package/dist/studio/runOneShot.js +62 -23
- package/dist/studio/runRepl.js +5 -5
- package/dist/studio/slash/handlers.js +11 -8
- package/dist/studio/state/store.js +1 -1
- package/dist/utils/agent-errors.js +14 -11
- package/dist/utils/agent-patch.js +60 -0
- package/dist/utils/banner.js +9 -5
- package/dist/utils/confirm.js +31 -0
- package/dist/utils/credentials.js +13 -3
- package/dist/utils/logger.js +13 -10
- package/dist/utils/output.js +78 -0
- package/dist/utils/phone.js +22 -0
- package/dist/utils/ui.js +14 -11
- 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 {
|
|
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
|
|
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 "
|
|
44
|
+
// estilo "actions -> 0 -> action -> 2".
|
|
28
45
|
function humanizePath(instancePath) {
|
|
29
46
|
if (!instancePath || instancePath === '')
|
|
30
|
-
return '(
|
|
47
|
+
return '(root)';
|
|
31
48
|
return instancePath
|
|
32
49
|
.replace(/^\//, '')
|
|
33
50
|
.split('/')
|
|
34
51
|
.filter(Boolean)
|
|
35
52
|
.join(' -> ');
|
|
36
53
|
}
|
|
37
|
-
function
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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' &&
|
|
45
|
-
|
|
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' &&
|
|
49
|
-
detail = `
|
|
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 = '
|
|
66
|
+
else if (err.keyword === 'minLength') {
|
|
67
|
+
detail = 'cannot be empty';
|
|
53
68
|
}
|
|
54
|
-
else if (keyword === 'pattern') {
|
|
55
|
-
detail = `
|
|
69
|
+
else if (err.keyword === 'pattern') {
|
|
70
|
+
detail = `does not match the pattern ${params.pattern}`;
|
|
56
71
|
}
|
|
57
|
-
|
|
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', '
|
|
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
|
-
|
|
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
|
|
77
|
-
|
|
78
|
-
|
|
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')('
|
|
92
|
-
const name = data?.name ? `
|
|
93
|
-
console.log(chalk.gray(`
|
|
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
|
-
|
|
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')(`
|
|
138
|
+
console.log(chalk.hex('#EF5350')(` Invalid schema (${described.length} ${described.length === 1 ? 'error' : 'errors'}):`));
|
|
107
139
|
console.log();
|
|
108
|
-
|
|
109
|
-
console.log(chalk.hex('#EF5350')(` ${i + 1}. ${
|
|
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('
|
|
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
|
-
|
|
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: '
|
|
126
|
-
command: 'plazbot agent validate ./agent.json --
|
|
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
|
]);
|