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.
- package/CLAUDE.md +34 -5
- package/README.md +21 -0
- package/dist/cli.js +32 -20
- package/dist/commands/agent/ai-config.js +98 -50
- package/dist/commands/agent/chat.js +80 -74
- package/dist/commands/agent/copy.js +23 -21
- package/dist/commands/agent/create.js +42 -72
- package/dist/commands/agent/delete.js +29 -30
- package/dist/commands/agent/enable-widget.js +30 -26
- package/dist/commands/agent/export.js +90 -77
- package/dist/commands/agent/files.js +68 -60
- package/dist/commands/agent/get.js +101 -87
- package/dist/commands/agent/index.js +53 -39
- package/dist/commands/agent/list.js +26 -24
- package/dist/commands/agent/monitor.js +91 -86
- package/dist/commands/agent/on-message.js +40 -37
- package/dist/commands/agent/set.js +62 -59
- package/dist/commands/agent/templates.js +109 -108
- package/dist/commands/agent/tools.js +64 -65
- package/dist/commands/agent/update.js +28 -27
- package/dist/commands/agent/validate.js +127 -0
- package/dist/commands/agent/wizard.js +152 -159
- package/dist/commands/auth/index.js +7 -10
- package/dist/commands/auth/login.js +50 -37
- package/dist/commands/auth/logout.js +16 -14
- package/dist/commands/auth/status.js +19 -16
- package/dist/commands/portal/add-agent.js +26 -24
- package/dist/commands/portal/add-link.js +21 -17
- package/dist/commands/portal/clear-links.js +17 -15
- package/dist/commands/portal/create.js +25 -21
- package/dist/commands/portal/delete.js +31 -30
- package/dist/commands/portal/get.js +33 -31
- package/dist/commands/portal/index.js +30 -22
- package/dist/commands/portal/list.js +34 -30
- package/dist/commands/portal/update.js +41 -33
- package/dist/commands/whatsapp/broadcast.js +40 -37
- package/dist/commands/whatsapp/channels.js +40 -34
- package/dist/commands/whatsapp/chat.js +33 -32
- package/dist/commands/whatsapp/connect.js +59 -55
- package/dist/commands/whatsapp/delete-webhook.js +19 -17
- package/dist/commands/whatsapp/index.js +35 -25
- package/dist/commands/whatsapp/register-webhook.js +21 -19
- package/dist/commands/whatsapp/send-template.js +39 -31
- package/dist/commands/whatsapp/send.js +27 -23
- package/dist/commands/whatsapp/widget.js +35 -31
- package/dist/commands/workers/deploy.js +49 -44
- package/dist/commands/workers/index.js +28 -18
- package/dist/commands/workers/list.js +43 -35
- package/dist/commands/workers/logs.js +38 -32
- package/dist/commands/workers/remove.js +38 -37
- package/dist/commands/workers/secret.js +63 -58
- package/dist/commands/workers/test.js +44 -36
- package/dist/schemas/agent.config.schema.json +569 -0
- package/dist/studio/api/sseClient.js +97 -0
- package/dist/studio/api/studioApi.js +25 -0
- package/dist/studio/api/types.js +16 -0
- package/dist/studio/components/AgentPanel.js +35 -0
- package/dist/studio/components/App.js +214 -0
- package/dist/studio/components/ChatLog.js +59 -0
- package/dist/studio/components/Footer.js +11 -0
- package/dist/studio/components/Header.js +8 -0
- package/dist/studio/components/Input.js +15 -0
- package/dist/studio/components/Message.js +56 -0
- package/dist/studio/components/Suggestions.js +11 -0
- package/dist/studio/components/ToolCall.js +33 -0
- package/dist/studio/components/WhatsappConnectCard.js +57 -0
- package/dist/studio/index.js +42 -0
- package/dist/studio/render/json.js +16 -0
- package/dist/studio/render/markdown.js +32 -0
- package/dist/studio/render/steps.js +58 -0
- package/dist/studio/runOneShot.js +96 -0
- package/dist/studio/runRepl.js +52 -0
- package/dist/studio/slash/handlers.js +199 -0
- package/dist/studio/slash/parser.js +46 -0
- package/dist/studio/slash/registry.js +16 -0
- package/dist/studio/state/store.js +181 -0
- package/dist/studio/whatsapp/api.js +63 -0
- package/dist/studio/whatsapp/polling.js +77 -0
- package/dist/studio/whatsapp/types.js +31 -0
- package/dist/types/agent.js +1 -2
- package/dist/types/auth.js +1 -2
- package/dist/types/common.js +1 -2
- package/dist/types/message.js +1 -2
- package/dist/types/portal.js +1 -2
- package/dist/types/workers.js +1 -2
- package/dist/utils/agent-errors.js +46 -0
- package/dist/utils/api.js +8 -9
- package/dist/utils/banner.js +33 -34
- package/dist/utils/credentials.js +12 -20
- package/dist/utils/help.js +44 -0
- package/dist/utils/logger.js +13 -19
- package/dist/utils/ui.js +35 -49
- package/package.json +21 -10
- package/src/cli.ts +24 -8
- package/src/commands/agent/ai-config.ts +89 -34
- package/src/commands/agent/chat.ts +49 -37
- package/src/commands/agent/copy.ts +19 -13
- package/src/commands/agent/create.ts +32 -22
- package/src/commands/agent/delete.ts +24 -18
- package/src/commands/agent/enable-widget.ts +31 -23
- package/src/commands/agent/export.ts +72 -51
- package/src/commands/agent/files.ts +51 -39
- package/src/commands/agent/get.ts +86 -66
- package/src/commands/agent/index.ts +36 -18
- package/src/commands/agent/list.ts +22 -16
- package/src/commands/agent/monitor.ts +67 -56
- package/src/commands/agent/on-message.ts +36 -27
- package/src/commands/agent/set.ts +47 -37
- package/src/commands/agent/templates.ts +90 -82
- package/src/commands/agent/tools.ts +53 -47
- package/src/commands/agent/update.ts +28 -20
- package/src/commands/agent/validate.ts +135 -0
- package/src/commands/agent/wizard.ts +114 -114
- package/src/commands/auth/index.ts +3 -3
- package/src/commands/auth/login.ts +44 -29
- package/src/commands/auth/logout.ts +16 -10
- package/src/commands/auth/status.ts +14 -8
- package/src/commands/portal/add-agent.ts +23 -17
- package/src/commands/portal/add-link.ts +17 -9
- package/src/commands/portal/clear-links.ts +13 -7
- package/src/commands/portal/create.ts +20 -12
- package/src/commands/portal/delete.ts +28 -20
- package/src/commands/portal/get.ts +25 -19
- package/src/commands/portal/index.ts +22 -10
- package/src/commands/portal/list.ts +27 -19
- package/src/commands/portal/update.ts +38 -26
- package/src/commands/whatsapp/broadcast.ts +28 -18
- package/src/commands/whatsapp/channels.ts +31 -20
- package/src/commands/whatsapp/chat.ts +20 -12
- package/src/commands/whatsapp/connect.ts +48 -36
- package/src/commands/whatsapp/delete-webhook.ts +15 -9
- package/src/commands/whatsapp/index.ts +24 -10
- package/src/commands/whatsapp/register-webhook.ts +16 -10
- package/src/commands/whatsapp/send-template.ts +33 -21
- package/src/commands/whatsapp/send.ts +23 -15
- package/src/commands/whatsapp/widget.ts +25 -17
- package/src/commands/workers/deploy.ts +34 -22
- package/src/commands/workers/index.ts +21 -7
- package/src/commands/workers/list.ts +31 -19
- package/src/commands/workers/logs.ts +30 -20
- package/src/commands/workers/remove.ts +30 -22
- package/src/commands/workers/secret.ts +46 -34
- package/src/commands/workers/test.ts +34 -22
- package/src/schemas/agent.config.schema.json +569 -0
- package/src/studio/api/sseClient.ts +91 -0
- package/src/studio/api/studioApi.ts +27 -0
- package/src/studio/api/types.ts +96 -0
- package/src/studio/components/App.tsx +266 -0
- package/src/studio/components/ChatLog.tsx +95 -0
- package/src/studio/components/Footer.tsx +38 -0
- package/src/studio/components/Header.tsx +39 -0
- package/src/studio/components/Input.tsx +32 -0
- package/src/studio/components/Message.tsx +87 -0
- package/src/studio/components/Suggestions.tsx +26 -0
- package/src/studio/components/ToolCall.tsx +58 -0
- package/src/studio/components/WhatsappConnectCard.tsx +139 -0
- package/src/studio/index.ts +58 -0
- package/src/studio/render/markdown.ts +32 -0
- package/src/studio/render/steps.ts +57 -0
- package/src/studio/runOneShot.ts +114 -0
- package/src/studio/runRepl.tsx +76 -0
- package/src/studio/slash/handlers.ts +226 -0
- package/src/studio/slash/parser.ts +41 -0
- package/src/studio/slash/registry.ts +54 -0
- package/src/studio/state/store.ts +273 -0
- package/src/studio/whatsapp/api.ts +96 -0
- package/src/studio/whatsapp/polling.ts +93 -0
- package/src/studio/whatsapp/types.ts +80 -0
- package/src/types/agent.ts +1 -1
- package/src/types/auth.ts +4 -3
- package/src/types/portal.ts +1 -1
- package/src/types/workers.ts +1 -1
- package/src/utils/agent-errors.ts +67 -0
- package/src/utils/api.ts +6 -0
- package/src/utils/banner.ts +14 -9
- package/src/utils/credentials.ts +6 -5
- package/src/utils/help.ts +51 -0
- package/tsconfig.json +9 -6
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import fs from 'fs/promises';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { getStoredCredentials } from '../../utils/credentials';
|
|
5
|
-
import { createApiClient } from '../../utils/api';
|
|
6
|
-
import { logger } from '../../utils/logger';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
4
|
+
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
5
|
+
import { createApiClient } from '../../utils/api.js';
|
|
6
|
+
import { logger } from '../../utils/logger.js';
|
|
7
|
+
import { addExamples } from '../../utils/help.js';
|
|
8
|
+
import { createSpinner, createTable, theme } from '../../utils/ui.js';
|
|
9
|
+
import { WorkerDeployOptions, WorkerDeployResult } from '../../types/workers.js';
|
|
9
10
|
|
|
10
11
|
export const deployCommand = new Command('deploy')
|
|
11
|
-
.description('
|
|
12
|
-
.argument('[file]', '
|
|
13
|
-
.option('-n, --name <name>', '
|
|
14
|
-
.option('-d, --description <desc>', '
|
|
15
|
-
.option('--dev', '
|
|
12
|
+
.description('Deploy a worker to the Plazbot workspace')
|
|
13
|
+
.argument('[file]', 'Worker TypeScript file (e.g.: ./workers/my-tool.ts)')
|
|
14
|
+
.option('-n, --name <name>', 'Worker name (overrides the one in the file)')
|
|
15
|
+
.option('-d, --description <desc>', 'Worker description')
|
|
16
|
+
.option('--dev', 'Use development environment', false)
|
|
16
17
|
.action(async (file: string | undefined, options: WorkerDeployOptions) => {
|
|
17
18
|
try {
|
|
18
19
|
const credentials = await getStoredCredentials();
|
|
@@ -21,9 +22,9 @@ export const deployCommand = new Command('deploy')
|
|
|
21
22
|
const files = await resolveWorkerFiles(file);
|
|
22
23
|
|
|
23
24
|
if (files.length === 0) {
|
|
24
|
-
logger.error('No
|
|
25
|
-
logger.dim('
|
|
26
|
-
logger.dim('
|
|
25
|
+
logger.error('No worker files found to deploy');
|
|
26
|
+
logger.dim('Usage: plazbot workers deploy ./workers/my-tool.ts');
|
|
27
|
+
logger.dim(' or: plazbot workers deploy (searches ./workers/ automatically)');
|
|
27
28
|
process.exit(1);
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -34,14 +35,14 @@ export const deployCommand = new Command('deploy')
|
|
|
34
35
|
dev: options.dev,
|
|
35
36
|
});
|
|
36
37
|
|
|
37
|
-
logger.title(`
|
|
38
|
+
logger.title(`Deploying ${files.length} worker${files.length > 1 ? 's' : ''}`);
|
|
38
39
|
console.log();
|
|
39
40
|
|
|
40
41
|
const results: { file: string; result?: WorkerDeployResult; error?: string }[] = [];
|
|
41
42
|
|
|
42
43
|
for (const filePath of files) {
|
|
43
44
|
const fileName = path.basename(filePath);
|
|
44
|
-
const spinner = createSpinner(`
|
|
45
|
+
const spinner = createSpinner(`Deploying ${fileName}...`);
|
|
45
46
|
spinner.start();
|
|
46
47
|
|
|
47
48
|
try {
|
|
@@ -61,7 +62,7 @@ export const deployCommand = new Command('deploy')
|
|
|
61
62
|
results.push({ file: fileName, result: data });
|
|
62
63
|
|
|
63
64
|
} catch (error: any) {
|
|
64
|
-
const msg = error.response?.data?.message || error.message || '
|
|
65
|
+
const msg = error.response?.data?.message || error.message || 'Unknown error';
|
|
65
66
|
spinner.fail(`${fileName}: ${msg}`);
|
|
66
67
|
results.push({ file: fileName, error: msg });
|
|
67
68
|
}
|
|
@@ -73,7 +74,7 @@ export const deployCommand = new Command('deploy')
|
|
|
73
74
|
const failed = results.filter(r => r.error);
|
|
74
75
|
|
|
75
76
|
if (success.length > 0) {
|
|
76
|
-
logger.success(`${success.length} worker${success.length > 1 ? 's' : ''}
|
|
77
|
+
logger.success(`${success.length} worker${success.length > 1 ? 's' : ''} deployed`);
|
|
77
78
|
|
|
78
79
|
const rows = success.map(r => [
|
|
79
80
|
r.result!.name,
|
|
@@ -83,13 +84,13 @@ export const deployCommand = new Command('deploy')
|
|
|
83
84
|
]);
|
|
84
85
|
|
|
85
86
|
console.log(createTable(
|
|
86
|
-
['
|
|
87
|
+
['Name', 'Type', 'Status', 'URL/Cron'],
|
|
87
88
|
rows,
|
|
88
89
|
));
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
if (failed.length > 0) {
|
|
92
|
-
logger.warning(`${failed.length} worker${failed.length > 1 ? 's' : ''}
|
|
93
|
+
logger.warning(`${failed.length} worker${failed.length > 1 ? 's' : ''} failed`);
|
|
93
94
|
failed.forEach(f => logger.dim(` ${f.file}: ${f.error}`));
|
|
94
95
|
}
|
|
95
96
|
|
|
@@ -106,16 +107,27 @@ export const deployCommand = new Command('deploy')
|
|
|
106
107
|
console.log();
|
|
107
108
|
|
|
108
109
|
if (options.dev) {
|
|
109
|
-
logger.warning('
|
|
110
|
+
logger.warning('Environment: development');
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
} catch (error) {
|
|
113
|
-
const message = error instanceof Error ? error.message : '
|
|
114
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
114
115
|
logger.error(message);
|
|
115
116
|
process.exit(1);
|
|
116
117
|
}
|
|
117
118
|
});
|
|
118
119
|
|
|
120
|
+
addExamples(deployCommand, [
|
|
121
|
+
{ description: 'Deploy a single worker file',
|
|
122
|
+
command: 'plazbot workers deploy ./workers/my-tool.ts' },
|
|
123
|
+
{ description: 'Deploy every TypeScript file inside ./workers automatically',
|
|
124
|
+
command: 'plazbot workers deploy' },
|
|
125
|
+
{ description: 'Deploy with a custom name and description',
|
|
126
|
+
command: 'plazbot workers deploy ./workers/cron.ts -n "Daily Report" -d "Generates daily KPIs"' },
|
|
127
|
+
{ description: 'Deploy against the local backend',
|
|
128
|
+
command: 'plazbot workers deploy ./workers/test.ts --dev' },
|
|
129
|
+
]);
|
|
130
|
+
|
|
119
131
|
// Resuelve los archivos a desplegar
|
|
120
132
|
async function resolveWorkerFiles(file?: string): Promise<string[]> {
|
|
121
133
|
if (file) {
|
|
@@ -125,7 +137,7 @@ async function resolveWorkerFiles(file?: string): Promise<string[]> {
|
|
|
125
137
|
await fs.access(resolved);
|
|
126
138
|
return [resolved];
|
|
127
139
|
} catch {
|
|
128
|
-
throw new Error(`
|
|
140
|
+
throw new Error(`File not found: ${file}`);
|
|
129
141
|
}
|
|
130
142
|
}
|
|
131
143
|
|
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
2
|
+
import { addExamples } from '../../utils/help.js';
|
|
3
|
+
import { deployCommand } from './deploy.js';
|
|
4
|
+
import { listCommand } from './list.js';
|
|
5
|
+
import { logsCommand } from './logs.js';
|
|
6
|
+
import { removeCommand } from './remove.js';
|
|
7
|
+
import { secretCommand } from './secret.js';
|
|
8
|
+
import { testCommand } from './test.js';
|
|
8
9
|
|
|
9
10
|
export const workersCommands = new Command('workers')
|
|
10
|
-
.description('
|
|
11
|
+
.description('Commands to manage workers (tools, syncs, schedules, webhooks)')
|
|
11
12
|
.addCommand(deployCommand)
|
|
12
13
|
.addCommand(listCommand)
|
|
13
14
|
.addCommand(logsCommand)
|
|
14
15
|
.addCommand(removeCommand)
|
|
15
16
|
.addCommand(secretCommand)
|
|
16
17
|
.addCommand(testCommand);
|
|
18
|
+
|
|
19
|
+
addExamples(workersCommands, [
|
|
20
|
+
{ description: 'Deploy every worker file in ./workers automatically',
|
|
21
|
+
command: 'plazbot workers deploy' },
|
|
22
|
+
{ description: 'List active workers',
|
|
23
|
+
command: 'plazbot workers list -s active' },
|
|
24
|
+
{ description: 'Run a worker with a JSON payload',
|
|
25
|
+
command: 'plazbot workers test my-tool -p \'{"product":"iPhone 15"}\'' },
|
|
26
|
+
{ description: 'Save a secret for workers (plz.env.KEY)',
|
|
27
|
+
command: 'plazbot workers secret set STRIPE_API_KEY sk_live_xxxxx' },
|
|
28
|
+
{ description: 'View the last 100 executions of a worker',
|
|
29
|
+
command: 'plazbot workers logs my-tool -l 100' },
|
|
30
|
+
]);
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { getStoredCredentials } from '../../utils/credentials';
|
|
3
|
-
import { createApiClient } from '../../utils/api';
|
|
4
|
-
import { logger } from '../../utils/logger';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
3
|
+
import { createApiClient } from '../../utils/api.js';
|
|
4
|
+
import { logger } from '../../utils/logger.js';
|
|
5
|
+
import { addExamples } from '../../utils/help.js';
|
|
6
|
+
import { createSpinner, createTable, theme, statusBadge, formatDate } from '../../utils/ui.js';
|
|
7
|
+
import { WorkerListOptions, WorkerListItem } from '../../types/workers.js';
|
|
7
8
|
|
|
8
9
|
export const listCommand = new Command('list')
|
|
9
|
-
.description('
|
|
10
|
-
.option('-t, --type <type>', '
|
|
11
|
-
.option('-s, --status <status>', '
|
|
12
|
-
.option('--dev', '
|
|
10
|
+
.description('List all workers in the workspace')
|
|
11
|
+
.option('-t, --type <type>', 'Filter by type (tool, worker, sync, schedule, webhook)')
|
|
12
|
+
.option('-s, --status <status>', 'Filter by status (active, inactive, error)')
|
|
13
|
+
.option('--dev', 'Use development environment', false)
|
|
13
14
|
.action(async (options: WorkerListOptions) => {
|
|
14
15
|
try {
|
|
15
16
|
const credentials = await getStoredCredentials();
|
|
@@ -20,7 +21,7 @@ export const listCommand = new Command('list')
|
|
|
20
21
|
dev: options.dev,
|
|
21
22
|
});
|
|
22
23
|
|
|
23
|
-
const spinner = createSpinner('
|
|
24
|
+
const spinner = createSpinner('Fetching workers...');
|
|
24
25
|
spinner.start();
|
|
25
26
|
|
|
26
27
|
const params: Record<string, string> = {};
|
|
@@ -33,8 +34,8 @@ export const listCommand = new Command('list')
|
|
|
33
34
|
spinner.stop();
|
|
34
35
|
|
|
35
36
|
if (!workers || workers.length === 0) {
|
|
36
|
-
logger.info('\n No
|
|
37
|
-
logger.dim('
|
|
37
|
+
logger.info('\n No workers found in this workspace');
|
|
38
|
+
logger.dim(' Deploy your first worker: plazbot workers deploy ./workers/my-tool.ts');
|
|
38
39
|
console.log();
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
@@ -44,9 +45,9 @@ export const listCommand = new Command('list')
|
|
|
44
45
|
const rows = workers.map(w => [
|
|
45
46
|
w.name,
|
|
46
47
|
typeLabel(w.type),
|
|
47
|
-
w.status === 'active' ? theme.success('
|
|
48
|
+
w.status === 'active' ? theme.success('active')
|
|
48
49
|
: w.status === 'error' ? theme.error('error')
|
|
49
|
-
: theme.muted('
|
|
50
|
+
: theme.muted('inactive'),
|
|
50
51
|
`${w.executionCount}`,
|
|
51
52
|
w.errorCount > 0 ? theme.error(`${w.errorCount}`) : theme.muted('0'),
|
|
52
53
|
w.avgDurationMs > 0 ? `${w.avgDurationMs}ms` : '—',
|
|
@@ -54,7 +55,7 @@ export const listCommand = new Command('list')
|
|
|
54
55
|
]);
|
|
55
56
|
|
|
56
57
|
console.log(createTable(
|
|
57
|
-
['
|
|
58
|
+
['Name', 'Type', 'Status', 'Executions', 'Errors', 'Duration', 'Last execution'],
|
|
58
59
|
rows,
|
|
59
60
|
));
|
|
60
61
|
|
|
@@ -62,25 +63,36 @@ export const listCommand = new Command('list')
|
|
|
62
63
|
const errored = workers.filter(w => w.status === 'error');
|
|
63
64
|
if (errored.length > 0) {
|
|
64
65
|
console.log();
|
|
65
|
-
logger.warning('Workers
|
|
66
|
+
logger.warning('Workers with errors:');
|
|
66
67
|
errored.forEach(w => {
|
|
67
|
-
logger.dim(` ${w.name}: ${w.lastError || '
|
|
68
|
+
logger.dim(` ${w.name}: ${w.lastError || 'no details'}`);
|
|
68
69
|
});
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
console.log();
|
|
72
73
|
|
|
73
74
|
if (options.dev) {
|
|
74
|
-
logger.warning('
|
|
75
|
+
logger.warning('Environment: development');
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
} catch (error) {
|
|
78
|
-
const message = error instanceof Error ? error.message : '
|
|
79
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
79
80
|
logger.error(message);
|
|
80
81
|
process.exit(1);
|
|
81
82
|
}
|
|
82
83
|
});
|
|
83
84
|
|
|
85
|
+
addExamples(listCommand, [
|
|
86
|
+
{ description: 'List every worker in the workspace',
|
|
87
|
+
command: 'plazbot workers list' },
|
|
88
|
+
{ description: 'Only show schedules',
|
|
89
|
+
command: 'plazbot workers list -t schedule' },
|
|
90
|
+
{ description: 'Show only workers with errors',
|
|
91
|
+
command: 'plazbot workers list -s error' },
|
|
92
|
+
{ description: 'Filter active webhooks',
|
|
93
|
+
command: 'plazbot workers list -t webhook -s active' },
|
|
94
|
+
]);
|
|
95
|
+
|
|
84
96
|
function typeLabel(type: string): string {
|
|
85
97
|
const labels: Record<string, string> = {
|
|
86
98
|
tool: theme.secondary('tool'),
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { getStoredCredentials } from '../../utils/credentials';
|
|
3
|
-
import { createApiClient } from '../../utils/api';
|
|
4
|
-
import { logger } from '../../utils/logger';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
3
|
+
import { createApiClient } from '../../utils/api.js';
|
|
4
|
+
import { logger } from '../../utils/logger.js';
|
|
5
|
+
import { addExamples } from '../../utils/help.js';
|
|
6
|
+
import { createSpinner, createTable, theme, formatDate } from '../../utils/ui.js';
|
|
7
|
+
import { WorkerLogsOptions, WorkerLogItem } from '../../types/workers.js';
|
|
7
8
|
|
|
8
9
|
export const logsCommand = new Command('logs')
|
|
9
|
-
.description('
|
|
10
|
-
.argument('<name>', '
|
|
11
|
-
.option('-l, --limit <number>', '
|
|
12
|
-
.option('-s, --status <status>', '
|
|
13
|
-
.option('--dev', '
|
|
10
|
+
.description('View execution logs for a worker')
|
|
11
|
+
.argument('<name>', 'Worker name')
|
|
12
|
+
.option('-l, --limit <number>', 'Number of logs to display', '20')
|
|
13
|
+
.option('-s, --status <status>', 'Filter by status (success, error, timeout)')
|
|
14
|
+
.option('--dev', 'Use development environment', false)
|
|
14
15
|
.action(async (name: string, options: WorkerLogsOptions) => {
|
|
15
16
|
try {
|
|
16
17
|
const credentials = await getStoredCredentials();
|
|
@@ -21,7 +22,7 @@ export const logsCommand = new Command('logs')
|
|
|
21
22
|
dev: options.dev,
|
|
22
23
|
});
|
|
23
24
|
|
|
24
|
-
const spinner = createSpinner(`
|
|
25
|
+
const spinner = createSpinner(`Fetching logs for "${name}"...`);
|
|
25
26
|
spinner.start();
|
|
26
27
|
|
|
27
28
|
const params: Record<string, string> = {
|
|
@@ -35,12 +36,12 @@ export const logsCommand = new Command('logs')
|
|
|
35
36
|
spinner.stop();
|
|
36
37
|
|
|
37
38
|
if (!logs || logs.length === 0) {
|
|
38
|
-
logger.info(`\n No
|
|
39
|
+
logger.info(`\n No logs found for "${name}"`);
|
|
39
40
|
console.log();
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
logger.title(`Logs
|
|
44
|
+
logger.title(`Logs for "${name}" (${logs.length})`);
|
|
44
45
|
|
|
45
46
|
const rows = logs.map(log => [
|
|
46
47
|
formatDate(log.createdAt),
|
|
@@ -53,7 +54,7 @@ export const logsCommand = new Command('logs')
|
|
|
53
54
|
]);
|
|
54
55
|
|
|
55
56
|
console.log(createTable(
|
|
56
|
-
['
|
|
57
|
+
['Date', 'Status', 'Duration', 'Source', 'Error'],
|
|
57
58
|
rows,
|
|
58
59
|
));
|
|
59
60
|
|
|
@@ -63,26 +64,35 @@ export const logsCommand = new Command('logs')
|
|
|
63
64
|
const avgDuration = Math.round(logs.reduce((sum, l) => sum + l.durationMs, 0) / logs.length);
|
|
64
65
|
|
|
65
66
|
console.log();
|
|
66
|
-
logger.label('
|
|
67
|
-
logger.label('
|
|
68
|
-
logger.label('
|
|
67
|
+
logger.label('Successful', theme.success(`${successCount}`));
|
|
68
|
+
logger.label('Errors', errorCount > 0 ? theme.error(`${errorCount}`) : theme.muted('0'));
|
|
69
|
+
logger.label('Average duration', `${avgDuration}ms`);
|
|
69
70
|
console.log();
|
|
70
71
|
|
|
71
72
|
if (options.dev) {
|
|
72
|
-
logger.warning('
|
|
73
|
+
logger.warning('Environment: development');
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
} catch (error: any) {
|
|
76
77
|
if (error.response?.status === 404) {
|
|
77
|
-
logger.error(`Worker "${name}"
|
|
78
|
+
logger.error(`Worker "${name}" not found`);
|
|
78
79
|
} else {
|
|
79
|
-
const message = error instanceof Error ? error.message : '
|
|
80
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
80
81
|
logger.error(message);
|
|
81
82
|
}
|
|
82
83
|
process.exit(1);
|
|
83
84
|
}
|
|
84
85
|
});
|
|
85
86
|
|
|
87
|
+
addExamples(logsCommand, [
|
|
88
|
+
{ description: 'Show the last 20 executions of a worker',
|
|
89
|
+
command: 'plazbot workers logs my-tool' },
|
|
90
|
+
{ description: 'Get the last 100 executions',
|
|
91
|
+
command: 'plazbot workers logs my-tool -l 100' },
|
|
92
|
+
{ description: 'Only show failed executions',
|
|
93
|
+
command: 'plazbot workers logs my-tool -s error' },
|
|
94
|
+
]);
|
|
95
|
+
|
|
86
96
|
function truncate(text: string, max: number): string {
|
|
87
97
|
if (text.length <= max) return text;
|
|
88
98
|
return text.substring(0, max - 3) + '...';
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { getStoredCredentials } from '../../utils/credentials';
|
|
3
|
-
import { createApiClient } from '../../utils/api';
|
|
4
|
-
import { logger } from '../../utils/logger';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { getStoredCredentials } from '../../utils/credentials.js';
|
|
3
|
+
import { createApiClient } from '../../utils/api.js';
|
|
4
|
+
import { logger } from '../../utils/logger.js';
|
|
5
|
+
import { addExamples } from '../../utils/help.js';
|
|
6
|
+
import { createSpinner } from '../../utils/ui.js';
|
|
7
|
+
import { WorkerRemoveOptions } from '../../types/workers.js';
|
|
7
8
|
import readline from 'readline';
|
|
8
9
|
|
|
9
10
|
export const removeCommand = new Command('remove')
|
|
10
|
-
.description('
|
|
11
|
-
.argument('<name>', '
|
|
12
|
-
.option('-f, --force', '
|
|
13
|
-
.option('--dev', '
|
|
11
|
+
.description('Delete a worker from the workspace')
|
|
12
|
+
.argument('<name>', 'Name of the worker to delete')
|
|
13
|
+
.option('-f, --force', 'Delete without confirmation', false)
|
|
14
|
+
.option('--dev', 'Use development environment', false)
|
|
14
15
|
.action(async (name: string, options: WorkerRemoveOptions) => {
|
|
15
16
|
try {
|
|
16
17
|
const credentials = await getStoredCredentials();
|
|
@@ -22,7 +23,7 @@ export const removeCommand = new Command('remove')
|
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
// Verificar que el worker existe
|
|
25
|
-
const spinner = createSpinner(`
|
|
26
|
+
const spinner = createSpinner(`Looking up worker "${name}"...`);
|
|
26
27
|
spinner.start();
|
|
27
28
|
|
|
28
29
|
let workerInfo: any;
|
|
@@ -33,7 +34,7 @@ export const removeCommand = new Command('remove')
|
|
|
33
34
|
} catch (error: any) {
|
|
34
35
|
spinner.stop();
|
|
35
36
|
if (error.response?.status === 404) {
|
|
36
|
-
logger.error(`Worker "${name}"
|
|
37
|
+
logger.error(`Worker "${name}" not found`);
|
|
37
38
|
} else {
|
|
38
39
|
logger.error(error.response?.data?.message || error.message);
|
|
39
40
|
}
|
|
@@ -41,45 +42,52 @@ export const removeCommand = new Command('remove')
|
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
// Mostrar info del worker
|
|
44
|
-
logger.warning(`\n
|
|
45
|
+
logger.warning(`\n You are about to delete the following worker:`);
|
|
45
46
|
logger.divider();
|
|
46
|
-
logger.label('
|
|
47
|
-
logger.label('
|
|
48
|
-
logger.label('
|
|
49
|
-
logger.label('
|
|
47
|
+
logger.label('Name', workerInfo.name);
|
|
48
|
+
logger.label('Type', workerInfo.type);
|
|
49
|
+
logger.label('Status', workerInfo.status);
|
|
50
|
+
logger.label('Executions', `${workerInfo.executionCount || 0}`);
|
|
50
51
|
logger.divider();
|
|
51
52
|
|
|
52
53
|
// Confirmacion
|
|
53
54
|
if (!options.force) {
|
|
54
55
|
const confirmed = await askConfirmation(
|
|
55
|
-
`
|
|
56
|
+
`Delete worker "${name}"? This action cannot be undone (y/N): `
|
|
56
57
|
);
|
|
57
58
|
|
|
58
59
|
if (!confirmed) {
|
|
59
|
-
logger.info('\n
|
|
60
|
+
logger.info('\n Operation cancelled');
|
|
60
61
|
process.exit(0);
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
const deleteSpinner = createSpinner(`
|
|
65
|
+
const deleteSpinner = createSpinner(`Deleting "${name}"...`);
|
|
65
66
|
deleteSpinner.start();
|
|
66
67
|
|
|
67
68
|
await api.delete(`/api/worker/${encodeURIComponent(name)}`);
|
|
68
69
|
|
|
69
|
-
deleteSpinner.succeed(`Worker "${name}"
|
|
70
|
+
deleteSpinner.succeed(`Worker "${name}" deleted`);
|
|
70
71
|
console.log();
|
|
71
72
|
|
|
72
73
|
if (options.dev) {
|
|
73
|
-
logger.warning('
|
|
74
|
+
logger.warning('Environment: development');
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
} catch (error) {
|
|
77
|
-
const message = error instanceof Error ? error.message : '
|
|
78
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
78
79
|
logger.error(message);
|
|
79
80
|
process.exit(1);
|
|
80
81
|
}
|
|
81
82
|
});
|
|
82
83
|
|
|
84
|
+
addExamples(removeCommand, [
|
|
85
|
+
{ description: 'Delete a worker with confirmation prompt',
|
|
86
|
+
command: 'plazbot workers remove my-tool' },
|
|
87
|
+
{ description: 'Delete without confirmation (scripts/CI)',
|
|
88
|
+
command: 'plazbot workers remove my-tool -f' },
|
|
89
|
+
]);
|
|
90
|
+
|
|
83
91
|
function askConfirmation(question: string): Promise<boolean> {
|
|
84
92
|
return new Promise((resolve) => {
|
|
85
93
|
const rl = readline.createInterface({
|