plazbot-cli 0.3.7 → 0.4.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.
- package/README.md +38 -2
- package/dist/commands/auth/browser-login.js +121 -0
- package/dist/commands/auth/index.js +5 -1
- package/dist/commands/auth/login.js +1 -3
- package/dist/commands/auth/logout.js +4 -3
- package/dist/commands/auth/status.js +8 -5
- package/dist/commands/auth/workspace.js +73 -0
- package/dist/commands/whatsapp/connect-flow.js +137 -0
- package/dist/commands/whatsapp/connect.js +26 -160
- package/dist/commands/whatsapp/index.js +4 -0
- package/dist/commands/whatsapp/setup.js +242 -0
- package/dist/schemas/agent.config.schema.json +24 -0
- package/dist/studio/components/App.js +1 -1
- package/dist/studio/runOneShot.js +2 -2
- package/dist/studio/runRepl.js +1 -1
- package/dist/utils/agent-errors.js +2 -2
- package/dist/utils/banner.js +10 -9
- package/dist/utils/credentials.js +31 -3
- package/dist/utils/open-browser.js +17 -0
- package/package.json +14 -6
- package/.claude/settings.local.json +0 -19
- package/CLAUDE.md +0 -121
- package/agent.config.json +0 -21
- package/dist/studio/components/AgentPanel.js +0 -35
- package/dist/studio/render/json.js +0 -16
- package/dist/studio/whatsapp/api.js +0 -63
- package/dist/studio/whatsapp/polling.js +0 -77
- package/dist/studio/whatsapp/types.js +0 -31
- package/src/cli.ts +0 -57
- package/src/commands/agent/ai-config.ts +0 -164
- package/src/commands/agent/chat.ts +0 -225
- package/src/commands/agent/copy.ts +0 -46
- package/src/commands/agent/create.ts +0 -103
- package/src/commands/agent/delete.ts +0 -71
- package/src/commands/agent/enable-widget.ts +0 -67
- package/src/commands/agent/export.ts +0 -430
- package/src/commands/agent/files.ts +0 -171
- package/src/commands/agent/get.ts +0 -233
- package/src/commands/agent/index.ts +0 -55
- package/src/commands/agent/list.ts +0 -58
- package/src/commands/agent/monitor.ts +0 -375
- package/src/commands/agent/on-message.ts +0 -82
- package/src/commands/agent/set.ts +0 -149
- package/src/commands/agent/templates.ts +0 -892
- package/src/commands/agent/tools.ts +0 -168
- package/src/commands/agent/update.ts +0 -61
- package/src/commands/agent/validate.ts +0 -135
- package/src/commands/agent/wizard.ts +0 -756
- package/src/commands/auth/index.ts +0 -10
- package/src/commands/auth/login.ts +0 -72
- package/src/commands/auth/logout.ts +0 -28
- package/src/commands/auth/status.ts +0 -28
- package/src/commands/portal/add-agent.ts +0 -66
- package/src/commands/portal/add-link.ts +0 -47
- package/src/commands/portal/clear-links.ts +0 -33
- package/src/commands/portal/create.ts +0 -58
- package/src/commands/portal/delete.ts +0 -70
- package/src/commands/portal/get.ts +0 -77
- package/src/commands/portal/index.ts +0 -32
- package/src/commands/portal/list.ts +0 -79
- package/src/commands/portal/update.ts +0 -93
- package/src/commands/whatsapp/broadcast.ts +0 -110
- package/src/commands/whatsapp/channels.ts +0 -109
- package/src/commands/whatsapp/chat.ts +0 -85
- package/src/commands/whatsapp/connect.ts +0 -220
- package/src/commands/whatsapp/delete-webhook.ts +0 -43
- package/src/commands/whatsapp/index.ts +0 -37
- package/src/commands/whatsapp/register-webhook.ts +0 -47
- package/src/commands/whatsapp/send-template.ts +0 -94
- package/src/commands/whatsapp/send.ts +0 -55
- package/src/commands/whatsapp/widget.ts +0 -75
- package/src/commands/workers/deploy.ts +0 -156
- package/src/commands/workers/index.ts +0 -30
- package/src/commands/workers/list.ts +0 -105
- package/src/commands/workers/logs.ts +0 -99
- package/src/commands/workers/remove.ts +0 -103
- package/src/commands/workers/secret.ts +0 -191
- package/src/commands/workers/test.ts +0 -145
- package/src/schemas/agent.config.schema.json +0 -569
- package/src/studio/api/sseClient.ts +0 -91
- package/src/studio/api/studioApi.ts +0 -27
- package/src/studio/api/types.ts +0 -96
- package/src/studio/components/App.tsx +0 -274
- package/src/studio/components/ChatLog.tsx +0 -121
- package/src/studio/components/ConnectCard.tsx +0 -171
- package/src/studio/components/Footer.tsx +0 -38
- package/src/studio/components/Header.tsx +0 -39
- package/src/studio/components/Input.tsx +0 -176
- package/src/studio/components/Message.tsx +0 -87
- package/src/studio/components/Suggestions.tsx +0 -26
- package/src/studio/components/ToolCall.tsx +0 -58
- package/src/studio/connect/api.ts +0 -98
- package/src/studio/connect/polling.ts +0 -94
- package/src/studio/connect/types.ts +0 -141
- package/src/studio/index.ts +0 -58
- package/src/studio/render/markdown.ts +0 -93
- package/src/studio/render/steps.ts +0 -57
- package/src/studio/runOneShot.ts +0 -114
- package/src/studio/runRepl.tsx +0 -82
- package/src/studio/slash/handlers.ts +0 -226
- package/src/studio/slash/parser.ts +0 -41
- package/src/studio/slash/registry.ts +0 -54
- package/src/studio/state/store.ts +0 -279
- package/src/types/agent.ts +0 -63
- package/src/types/auth.ts +0 -9
- package/src/types/common.ts +0 -10
- package/src/types/message.ts +0 -34
- package/src/types/portal.ts +0 -56
- package/src/types/workers.ts +0 -86
- package/src/utils/agent-errors.ts +0 -67
- package/src/utils/api.ts +0 -35
- package/src/utils/banner.ts +0 -99
- package/src/utils/credentials.ts +0 -38
- package/src/utils/help.ts +0 -51
- package/src/utils/logger.ts +0 -40
- package/src/utils/ui.ts +0 -109
- package/tsconfig.json +0 -18
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { Agent } from 'plazbot';
|
|
3
|
-
import inquirer from 'inquirer';
|
|
4
|
-
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
5
|
-
import { logger } from '../../utils/logger.js';
|
|
6
|
-
import { addExamples } from '../../utils/help.js';
|
|
7
|
-
import { createSpinner, createTable, theme, section, kvPair, statusBadge } from '../../utils/ui.js';
|
|
8
|
-
import { AgentCommandOptions } from '../../types/agent.js';
|
|
9
|
-
|
|
10
|
-
export const toolsCommand = new Command('tools')
|
|
11
|
-
.description('Manage agent Tool Calling tools')
|
|
12
|
-
.argument('<agentId>', 'Agent ID')
|
|
13
|
-
.option('--dev', 'Use development environment', false)
|
|
14
|
-
.action(async (agentId: string, options: AgentCommandOptions) => {
|
|
15
|
-
try {
|
|
16
|
-
const credentials = await getStoredCredentials();
|
|
17
|
-
const agent = new Agent({
|
|
18
|
-
workspaceId: credentials.workspace,
|
|
19
|
-
apiKey: credentials.apiKey,
|
|
20
|
-
zone: credentials.zone,
|
|
21
|
-
...(options.dev && { customUrl: "http://localhost:5090" })
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const spinner = createSpinner('Loading agent...');
|
|
25
|
-
spinner.start();
|
|
26
|
-
const _res: any = await agent.getAgentById({ id: agentId });
|
|
27
|
-
const agentData = _res.agent || _res.data || _res;
|
|
28
|
-
spinner.stop();
|
|
29
|
-
|
|
30
|
-
console.log(section('Tool Calling - ' + (agentData.name || agentId)));
|
|
31
|
-
console.log(kvPair('Status', agentData.useToolCalling ? theme.success('Enabled') : theme.error('Disabled')));
|
|
32
|
-
|
|
33
|
-
// Servicios
|
|
34
|
-
const services = agentData.services || [];
|
|
35
|
-
if (services.length > 0) {
|
|
36
|
-
console.log(section('Services (API calls)'));
|
|
37
|
-
const rows = services.map((s: any) => [
|
|
38
|
-
s.intent,
|
|
39
|
-
s.method || 'POST',
|
|
40
|
-
s.endpoint ? s.endpoint.substring(0, 40) + '...' : 'N/A',
|
|
41
|
-
statusBadge(s.enabled !== false),
|
|
42
|
-
]);
|
|
43
|
-
console.log(createTable(['Intent', 'Method', 'Endpoint', 'Status'], rows));
|
|
44
|
-
} else {
|
|
45
|
-
console.log(theme.muted('\n No services configured'));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Acciones
|
|
49
|
-
const actions = agentData.actions || [];
|
|
50
|
-
if (actions.length > 0) {
|
|
51
|
-
console.log(section('Actions'));
|
|
52
|
-
const rows = actions.map((a: any) => [
|
|
53
|
-
a.intent,
|
|
54
|
-
(a.action || []).map((ac: any) => ac.type).join(', '),
|
|
55
|
-
statusBadge(a.enabled !== false),
|
|
56
|
-
]);
|
|
57
|
-
console.log(createTable(['Intent', 'Type', 'Status'], rows));
|
|
58
|
-
} else {
|
|
59
|
-
console.log(theme.muted('\n No actions configured'));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Menu de opciones
|
|
63
|
-
console.log();
|
|
64
|
-
const { action } = await (inquirer as any).prompt([{
|
|
65
|
-
type: 'list',
|
|
66
|
-
name: 'action',
|
|
67
|
-
message: 'What would you like to do?',
|
|
68
|
-
choices: [
|
|
69
|
-
{ name: 'Add service (API call)', value: 'add-service' },
|
|
70
|
-
{ name: 'Add action', value: 'add-action' },
|
|
71
|
-
{ name: agentData.useToolCalling ? 'Disable Tool Calling' : 'Enable Tool Calling', value: 'toggle' },
|
|
72
|
-
{ name: 'Exit', value: 'exit' },
|
|
73
|
-
],
|
|
74
|
-
}]);
|
|
75
|
-
|
|
76
|
-
if (action === 'exit') return;
|
|
77
|
-
|
|
78
|
-
if (action === 'toggle') {
|
|
79
|
-
const toggleSpinner = createSpinner('Updating...');
|
|
80
|
-
toggleSpinner.start();
|
|
81
|
-
const { id: _i1, _id: _o1, ...updatedConfig } = { ...agentData, useToolCalling: !agentData.useToolCalling };
|
|
82
|
-
await agent.updateAgent(agentId, updatedConfig);
|
|
83
|
-
toggleSpinner.succeed(`Tool Calling ${!agentData.useToolCalling ? 'enabled' : 'disabled'}`);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (action === 'add-service') {
|
|
88
|
-
const svc = await (inquirer as any).prompt([
|
|
89
|
-
{ type: 'input', name: 'intent', message: 'Service name/intent:', validate: (v: string) => v.length > 0 || 'Required' },
|
|
90
|
-
{ type: 'input', name: 'reference', message: 'Keywords:', default: '' },
|
|
91
|
-
{ type: 'list', name: 'method', message: 'HTTP method:', choices: ['GET', 'POST'] },
|
|
92
|
-
{ type: 'input', name: 'endpoint', message: 'Endpoint URL:', validate: (v: string) => v.length > 0 || 'Required' },
|
|
93
|
-
{ type: 'input', name: 'responseMessage', message: 'Response message:', default: '' },
|
|
94
|
-
]);
|
|
95
|
-
|
|
96
|
-
const newService = {
|
|
97
|
-
intent: svc.intent,
|
|
98
|
-
reference: svc.reference,
|
|
99
|
-
enabled: true,
|
|
100
|
-
method: svc.method,
|
|
101
|
-
endpoint: svc.endpoint,
|
|
102
|
-
requiredFields: [],
|
|
103
|
-
headers: {},
|
|
104
|
-
bodyTemplate: {},
|
|
105
|
-
responseMapping: {},
|
|
106
|
-
responseMessage: svc.responseMessage,
|
|
107
|
-
responseConditions: [],
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const updatedServices = [...services, newService];
|
|
111
|
-
const { id: _i2, _id: _o2, ...updatedConfig } = { ...agentData, services: updatedServices, useToolCalling: true };
|
|
112
|
-
const updateSpinner = createSpinner('Saving service...');
|
|
113
|
-
updateSpinner.start();
|
|
114
|
-
await agent.updateAgent(agentId, updatedConfig);
|
|
115
|
-
updateSpinner.succeed(`Service "${svc.intent}" added`);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (action === 'add-action') {
|
|
119
|
-
const act = await (inquirer as any).prompt([
|
|
120
|
-
{ type: 'input', name: 'intent', message: 'Action name/intent:', validate: (v: string) => v.length > 0 || 'Required' },
|
|
121
|
-
{ type: 'input', name: 'reference', message: 'Keywords:', default: '' },
|
|
122
|
-
{
|
|
123
|
-
type: 'list', name: 'actionType', message: 'Action type:',
|
|
124
|
-
choices: [
|
|
125
|
-
{ name: 'Schedule event', value: 'action.event.add' },
|
|
126
|
-
{ name: 'Update event (reschedule)', value: 'action.event.update' },
|
|
127
|
-
{ name: 'List events', value: 'action.event.list' },
|
|
128
|
-
{ name: 'Delete event (cancel)', value: 'action.event.delete' },
|
|
129
|
-
{ name: 'Add tag', value: 'action.tag' },
|
|
130
|
-
{ name: 'Change stage', value: 'action.stage' },
|
|
131
|
-
{ name: 'Hand off to human agent', value: 'action.agentShutDown' },
|
|
132
|
-
{ name: 'Mark as resolved', value: 'action.solved' },
|
|
133
|
-
{ name: 'Assign agent', value: 'action.asign' },
|
|
134
|
-
{ name: 'Segmentation', value: 'action.segmentation' },
|
|
135
|
-
],
|
|
136
|
-
},
|
|
137
|
-
{ type: 'input', name: 'actionValue', message: 'Value (optional):', default: '' },
|
|
138
|
-
{ type: 'input', name: 'responseMessage', message: 'Response message:', default: '' },
|
|
139
|
-
]);
|
|
140
|
-
|
|
141
|
-
const newAction = {
|
|
142
|
-
intent: act.intent,
|
|
143
|
-
reference: act.reference,
|
|
144
|
-
enabled: true,
|
|
145
|
-
requiredFields: [],
|
|
146
|
-
responseMessage: act.responseMessage,
|
|
147
|
-
action: [{ type: act.actionType, value: act.actionValue }],
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
const updatedActions = [...actions, newAction];
|
|
151
|
-
const { id: _i3, _id: _o3, ...updatedConfig } = { ...agentData, actions: updatedActions, useToolCalling: true };
|
|
152
|
-
const updateSpinner = createSpinner('Saving action...');
|
|
153
|
-
updateSpinner.start();
|
|
154
|
-
await agent.updateAgent(agentId, updatedConfig);
|
|
155
|
-
updateSpinner.succeed(`Action "${act.intent}" added`);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
} catch (error) {
|
|
159
|
-
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
160
|
-
logger.error(message);
|
|
161
|
-
process.exit(1);
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
addExamples(toolsCommand, [
|
|
166
|
-
{ description: 'View services/actions and add new ones interactively',
|
|
167
|
-
command: 'plazbot agent tools agt_AbcDef123' },
|
|
168
|
-
]);
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { Agent } from 'plazbot';
|
|
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 fs from 'fs/promises';
|
|
8
|
-
|
|
9
|
-
export const updateCommand = new Command('update')
|
|
10
|
-
.description('Update an existing agent in Plazbot')
|
|
11
|
-
.argument('<agentId>', 'Agent ID to update')
|
|
12
|
-
.argument('<configPath>', 'Path to the agent JSON configuration file')
|
|
13
|
-
.option('--dev', 'Use development environment', false)
|
|
14
|
-
.action(async (agentId: string, configPath: string, options: AgentCommandOptions) => {
|
|
15
|
-
try {
|
|
16
|
-
// Obtener credenciales guardadas
|
|
17
|
-
const credentials = await getStoredCredentials();
|
|
18
|
-
|
|
19
|
-
// Leer archivo de configuración del agente
|
|
20
|
-
let agentConfig;
|
|
21
|
-
try {
|
|
22
|
-
const fileContent = await fs.readFile(configPath, 'utf-8');
|
|
23
|
-
agentConfig = JSON.parse(fileContent);
|
|
24
|
-
} catch (error) {
|
|
25
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
26
|
-
throw new Error(`Error reading configuration file: ${errorMessage}`);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Crear instancia del agente con las credenciales guardadas
|
|
30
|
-
const agent = new Agent({
|
|
31
|
-
workspaceId: credentials.workspace,
|
|
32
|
-
apiKey: credentials.apiKey,
|
|
33
|
-
zone: credentials.zone,
|
|
34
|
-
...(options.dev && { customUrl: "http://localhost:5090" })
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
logger.dim('Updating agent...');
|
|
38
|
-
|
|
39
|
-
// Actualizar el agente
|
|
40
|
-
const result = await agent.updateAgent(agentId, agentConfig);
|
|
41
|
-
|
|
42
|
-
logger.success('Agent updated successfully');
|
|
43
|
-
logger.info(`Message: ${result.message}`);
|
|
44
|
-
|
|
45
|
-
if (options.dev) {
|
|
46
|
-
logger.warning('Environment: development');
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
} catch (error) {
|
|
50
|
-
const message = error instanceof Error ? error.message : 'Unknown error while updating the agent';
|
|
51
|
-
logger.error(message);
|
|
52
|
-
process.exit(1);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
addExamples(updateCommand, [
|
|
57
|
-
{ description: 'Push a new configuration to the agent',
|
|
58
|
-
command: 'plazbot agent update agt_AbcDef123 ./agent.json' },
|
|
59
|
-
{ description: 'Tip: export → edit → update workflow',
|
|
60
|
-
command: 'plazbot agent export agt_AbcDef123 -o agent.json && plazbot agent update agt_AbcDef123 ./agent.json' },
|
|
61
|
-
]);
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { readFileSync, existsSync } from 'node:fs';
|
|
3
|
-
import { resolve, dirname, join } from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import Ajv, { ErrorObject } from 'ajv';
|
|
6
|
-
import addFormats from 'ajv-formats';
|
|
7
|
-
import chalk from 'chalk';
|
|
8
|
-
import { logger } from '../../utils/logger.js';
|
|
9
|
-
import { addExamples } from '../../utils/help.js';
|
|
10
|
-
|
|
11
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
-
const __dirname = dirname(__filename);
|
|
13
|
-
|
|
14
|
-
// El schema se copia a dist/schemas durante el build.
|
|
15
|
-
// Buscar primero en dist/schemas (produccion) y luego en src/schemas (dev/ts-node).
|
|
16
|
-
function loadSchema(): any {
|
|
17
|
-
const candidates = [
|
|
18
|
-
join(__dirname, '..', '..', 'schemas', 'agent.config.schema.json'), // dist/commands/agent -> dist/schemas
|
|
19
|
-
join(__dirname, '..', '..', '..', 'src', 'schemas', 'agent.config.schema.json'), // fallback dev
|
|
20
|
-
];
|
|
21
|
-
for (const candidate of candidates) {
|
|
22
|
-
if (existsSync(candidate)) {
|
|
23
|
-
return JSON.parse(readFileSync(candidate, 'utf-8'));
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
throw new Error('No se encontro el schema agent.config.schema.json. Reinstala el CLI.');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Traduce una ruta de AJV (e.g. "/actions/0/action/2") en migas legibles
|
|
30
|
-
// estilo "acciones -> 0 -> action -> 2".
|
|
31
|
-
function humanizePath(instancePath: string): string {
|
|
32
|
-
if (!instancePath || instancePath === '') return '(raiz)';
|
|
33
|
-
return instancePath
|
|
34
|
-
.replace(/^\//, '')
|
|
35
|
-
.split('/')
|
|
36
|
-
.filter(Boolean)
|
|
37
|
-
.join(' -> ');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function formatError(err: ErrorObject): string {
|
|
41
|
-
const path = humanizePath(err.instancePath);
|
|
42
|
-
const keyword = err.keyword;
|
|
43
|
-
let detail = err.message || 'error de validacion';
|
|
44
|
-
|
|
45
|
-
if (keyword === 'required' && err.params && (err.params as any).missingProperty) {
|
|
46
|
-
detail = `debe tener la propiedad requerida '${(err.params as any).missingProperty}'`;
|
|
47
|
-
} else if (keyword === 'enum' && err.params && (err.params as any).allowedValues) {
|
|
48
|
-
const allowed = (err.params as any).allowedValues as string[];
|
|
49
|
-
detail = `debe ser uno de: ${allowed.join(', ')}`;
|
|
50
|
-
} else if (keyword === 'type' && err.params && (err.params as any).type) {
|
|
51
|
-
detail = `debe ser de tipo ${(err.params as any).type}`;
|
|
52
|
-
} else if (keyword === 'minLength') {
|
|
53
|
-
detail = 'no puede estar vacio';
|
|
54
|
-
} else if (keyword === 'pattern') {
|
|
55
|
-
detail = `no cumple el patron ${(err.params as any).pattern}`;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return `${path}: ${detail}`;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export const validateCommand = new Command('validate')
|
|
62
|
-
.description('Validate an agent JSON file against the official schema')
|
|
63
|
-
.argument('<file>', 'Path to the agent JSON file')
|
|
64
|
-
.option('--strict', 'Fail on additional unknown properties', false)
|
|
65
|
-
.option('--raw', 'Print raw AJV errors as JSON', false)
|
|
66
|
-
.action(async (file: string, options: { strict: boolean; raw: boolean }) => {
|
|
67
|
-
try {
|
|
68
|
-
const filePath = resolve(process.cwd(), file);
|
|
69
|
-
if (!existsSync(filePath)) {
|
|
70
|
-
logger.error(`No existe el archivo: ${filePath}`);
|
|
71
|
-
process.exit(1);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
let data: unknown;
|
|
75
|
-
try {
|
|
76
|
-
data = JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
77
|
-
} catch (parseErr) {
|
|
78
|
-
const msg = parseErr instanceof Error ? parseErr.message : 'JSON invalido';
|
|
79
|
-
logger.error(`JSON con sintaxis invalida: ${msg}`);
|
|
80
|
-
process.exit(1);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const schema = loadSchema();
|
|
84
|
-
const ajv = new (Ajv as any)({
|
|
85
|
-
allErrors: true,
|
|
86
|
-
strict: false,
|
|
87
|
-
strictTypes: false,
|
|
88
|
-
});
|
|
89
|
-
(addFormats as any)(ajv);
|
|
90
|
-
|
|
91
|
-
const validate = ajv.compile(schema);
|
|
92
|
-
const ok = validate(data);
|
|
93
|
-
|
|
94
|
-
if (ok) {
|
|
95
|
-
console.log();
|
|
96
|
-
console.log(chalk.hex('#66BB6A')(' Schema valido'));
|
|
97
|
-
const name = (data as any)?.name ? ` (${(data as any).name})` : '';
|
|
98
|
-
console.log(chalk.gray(` El agente${name} cumple con el schema oficial.`));
|
|
99
|
-
console.log();
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Filtrar errores AJV redundantes generados por allOf/if-then:
|
|
104
|
-
// "must match 'then' schema" siempre acompana a un error real con misma path.
|
|
105
|
-
const rawErrors: ErrorObject[] = validate.errors || [];
|
|
106
|
-
const errors = rawErrors.filter(e => e.keyword !== 'if' && !/match "then" schema/.test(e.message || ''));
|
|
107
|
-
|
|
108
|
-
if (options.raw) {
|
|
109
|
-
console.log(JSON.stringify(errors, null, 2));
|
|
110
|
-
process.exit(1);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
console.log();
|
|
114
|
-
console.log(chalk.hex('#EF5350')(` Schema invalido (${errors.length} ${errors.length === 1 ? 'error' : 'errores'}):`));
|
|
115
|
-
console.log();
|
|
116
|
-
errors.forEach((err: ErrorObject, i: number) => {
|
|
117
|
-
console.log(chalk.hex('#EF5350')(` ${i + 1}. ${formatError(err)}`));
|
|
118
|
-
});
|
|
119
|
-
console.log();
|
|
120
|
-
console.log(chalk.gray(' Sugerencia: usa --raw para inspeccionar los errores AJV en JSON.'));
|
|
121
|
-
console.log();
|
|
122
|
-
process.exit(1);
|
|
123
|
-
} catch (error) {
|
|
124
|
-
const message = error instanceof Error ? error.message : 'Error desconocido';
|
|
125
|
-
logger.error(message);
|
|
126
|
-
process.exit(1);
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
addExamples(validateCommand, [
|
|
131
|
-
{ description: 'Validate an exported agent file against the schema',
|
|
132
|
-
command: 'plazbot agent validate ./agent.json' },
|
|
133
|
-
{ description: 'Print raw AJV errors as JSON for tooling',
|
|
134
|
-
command: 'plazbot agent validate ./agent.json --raw' },
|
|
135
|
-
]);
|