@tonk/cli 0.3.2 → 0.4.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 +15 -200
- package/bin/tonk.js +36 -1
- package/package.json +24 -86
- package/dist/commands/auth.d.ts +0 -3
- package/dist/commands/auth.d.ts.map +0 -1
- package/dist/commands/auth.js +0 -184
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/create.d.ts +0 -3
- package/dist/commands/create.d.ts.map +0 -1
- package/dist/commands/create.js +0 -55
- package/dist/commands/create.js.map +0 -1
- package/dist/commands/delete.d.ts +0 -3
- package/dist/commands/delete.d.ts.map +0 -1
- package/dist/commands/delete.js +0 -67
- package/dist/commands/delete.js.map +0 -1
- package/dist/commands/deploy.d.ts +0 -3
- package/dist/commands/deploy.d.ts.map +0 -1
- package/dist/commands/deploy.js +0 -336
- package/dist/commands/deploy.js.map +0 -1
- package/dist/commands/hello/index.d.ts +0 -3
- package/dist/commands/hello/index.d.ts.map +0 -1
- package/dist/commands/hello/index.js +0 -296
- package/dist/commands/hello/index.js.map +0 -1
- package/dist/commands/hello.d.ts +0 -3
- package/dist/commands/hello.d.ts.map +0 -1
- package/dist/commands/hello.js +0 -83
- package/dist/commands/hello.js.map +0 -1
- package/dist/commands/init.d.ts +0 -3
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -137
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/kill.d.ts +0 -3
- package/dist/commands/kill.d.ts.map +0 -1
- package/dist/commands/kill.js +0 -66
- package/dist/commands/kill.js.map +0 -1
- package/dist/commands/ls.d.ts +0 -3
- package/dist/commands/ls.d.ts.map +0 -1
- package/dist/commands/ls.js +0 -52
- package/dist/commands/ls.js.map +0 -1
- package/dist/commands/proxy.d.ts +0 -3
- package/dist/commands/proxy.d.ts.map +0 -1
- package/dist/commands/proxy.js +0 -86
- package/dist/commands/proxy.js.map +0 -1
- package/dist/commands/ps.d.ts +0 -3
- package/dist/commands/ps.d.ts.map +0 -1
- package/dist/commands/ps.js +0 -56
- package/dist/commands/ps.js.map +0 -1
- package/dist/commands/push.d.ts +0 -3
- package/dist/commands/push.d.ts.map +0 -1
- package/dist/commands/push.js +0 -238
- package/dist/commands/push.js.map +0 -1
- package/dist/commands/server.d.ts +0 -3
- package/dist/commands/server.d.ts.map +0 -1
- package/dist/commands/server.js +0 -619
- package/dist/commands/server.js.map +0 -1
- package/dist/commands/start.d.ts +0 -3
- package/dist/commands/start.d.ts.map +0 -1
- package/dist/commands/start.js +0 -82
- package/dist/commands/start.js.map +0 -1
- package/dist/commands/worker/commands.d.ts +0 -42
- package/dist/commands/worker/commands.d.ts.map +0 -1
- package/dist/commands/worker/commands.js +0 -968
- package/dist/commands/worker/commands.js.map +0 -1
- package/dist/commands/worker/index.d.ts +0 -7
- package/dist/commands/worker/index.d.ts.map +0 -1
- package/dist/commands/worker/index.js +0 -30
- package/dist/commands/worker/index.js.map +0 -1
- package/dist/commands/worker/utils/config.d.ts +0 -26
- package/dist/commands/worker/utils/config.d.ts.map +0 -1
- package/dist/commands/worker/utils/config.js +0 -197
- package/dist/commands/worker/utils/config.js.map +0 -1
- package/dist/commands/worker/utils/display.d.ts +0 -6
- package/dist/commands/worker/utils/display.d.ts.map +0 -1
- package/dist/commands/worker/utils/display.js +0 -32
- package/dist/commands/worker/utils/display.js.map +0 -1
- package/dist/commands/worker/utils/finder.d.ts +0 -12
- package/dist/commands/worker/utils/finder.d.ts.map +0 -1
- package/dist/commands/worker/utils/finder.js +0 -60
- package/dist/commands/worker/utils/finder.js.map +0 -1
- package/dist/config/environment.d.ts +0 -52
- package/dist/config/environment.d.ts.map +0 -1
- package/dist/config/environment.js +0 -83
- package/dist/config/environment.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +0 -1
- package/dist/lib/tonkAuth.d.ts +0 -21
- package/dist/lib/tonkAuth.d.ts.map +0 -1
- package/dist/lib/tonkAuth.js +0 -140
- package/dist/lib/tonkAuth.js.map +0 -1
- package/dist/lib/workerManager.d.ts +0 -60
- package/dist/lib/workerManager.d.ts.map +0 -1
- package/dist/lib/workerManager.js +0 -417
- package/dist/lib/workerManager.js.map +0 -1
- package/dist/scripts/aws/create-key.sh +0 -20
- package/dist/scripts/aws/ec2-dns.sh +0 -20
- package/dist/scripts/aws/provision.sh +0 -93
- package/dist/tonk.d.ts +0 -2
- package/dist/tonk.d.ts.map +0 -1
- package/dist/tonk.js +0 -106
- package/dist/tonk.js.map +0 -1
- package/dist/types/worker.d.ts +0 -161
- package/dist/types/worker.d.ts.map +0 -1
- package/dist/types/worker.js +0 -7
- package/dist/types/worker.js.map +0 -1
- package/dist/types/workerConfig.d.ts +0 -164
- package/dist/types/workerConfig.d.ts.map +0 -1
- package/dist/types/workerConfig.js +0 -80
- package/dist/types/workerConfig.js.map +0 -1
- package/dist/utils/analytics.d.ts +0 -26
- package/dist/utils/analytics.d.ts.map +0 -1
- package/dist/utils/analytics.js +0 -218
- package/dist/utils/analytics.js.map +0 -1
- package/dist/utils/messages.d.ts +0 -6
- package/dist/utils/messages.d.ts.map +0 -1
- package/dist/utils/messages.js +0 -18
- package/dist/utils/messages.js.map +0 -1
- package/dist/utils/serverUtils.d.ts +0 -5
- package/dist/utils/serverUtils.d.ts.map +0 -1
- package/dist/utils/serverUtils.js +0 -34
- package/dist/utils/serverUtils.js.map +0 -1
- package/dist/utils/version.d.ts +0 -2
- package/dist/utils/version.d.ts.map +0 -1
- package/dist/utils/version.js +0 -3
- package/dist/utils/version.js.map +0 -1
- package/scripts/aws/create-key.sh +0 -20
- package/scripts/aws/ec2-dns.sh +0 -20
- package/scripts/aws/provision.sh +0 -93
|
@@ -1,968 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import Table from 'cli-table3';
|
|
5
|
-
import { promisify } from 'node:util';
|
|
6
|
-
import { exec } from 'node:child_process';
|
|
7
|
-
import { TonkWorkerManager } from '../../lib/workerManager.js';
|
|
8
|
-
import { displayWorkerDetails } from './utils/display.js';
|
|
9
|
-
import { findWorkerRoot, findAvailablePort } from './utils/finder.js';
|
|
10
|
-
import { trackCommand, trackCommandError, trackCommandSuccess, shutdownAnalytics, } from '../../utils/analytics.js';
|
|
11
|
-
import { readPackageJson, readWorkerConfigJs, updateWorkerConfig, promptForMissingOptions, generatePackageJsonContent, generateWorkerConfigJsContent, } from './utils/config.js';
|
|
12
|
-
/**
|
|
13
|
-
* Register the inspect command
|
|
14
|
-
*/
|
|
15
|
-
export function registerInspectCommand(workerCommand) {
|
|
16
|
-
workerCommand
|
|
17
|
-
.command('inspect <nameOrId>')
|
|
18
|
-
.description('Inspect a specific worker')
|
|
19
|
-
.option('-s, --start', 'Start the worker')
|
|
20
|
-
.option('-S, --stop', 'Stop the worker')
|
|
21
|
-
.option('-c, --config <path>', 'Path to worker configuration file')
|
|
22
|
-
.option('-p, --ping', 'Ping the worker to check its status')
|
|
23
|
-
.action(async (nameOrId, options) => {
|
|
24
|
-
const startTime = Date.now();
|
|
25
|
-
try {
|
|
26
|
-
trackCommand('worker-inspect', {
|
|
27
|
-
nameOrId,
|
|
28
|
-
start: options.start,
|
|
29
|
-
stop: options.stop,
|
|
30
|
-
config: !!options.config,
|
|
31
|
-
ping: options.ping,
|
|
32
|
-
});
|
|
33
|
-
// Create worker manager
|
|
34
|
-
const workerManager = new TonkWorkerManager();
|
|
35
|
-
// Get worker
|
|
36
|
-
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
37
|
-
if (!worker) {
|
|
38
|
-
console.error(chalk.red(`Worker with name or ID '${nameOrId}' not found.`));
|
|
39
|
-
const duration = Date.now() - startTime;
|
|
40
|
-
trackCommandError('worker-inspect', new Error('Worker not found'), duration, {
|
|
41
|
-
nameOrId,
|
|
42
|
-
});
|
|
43
|
-
await shutdownAnalytics();
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
46
|
-
// If no options provided, show worker details
|
|
47
|
-
if (!options.start &&
|
|
48
|
-
!options.stop &&
|
|
49
|
-
!options.config &&
|
|
50
|
-
!options.ping) {
|
|
51
|
-
displayWorkerDetails(worker);
|
|
52
|
-
const duration = Date.now() - startTime;
|
|
53
|
-
trackCommandSuccess('worker-inspect', duration, {
|
|
54
|
-
workerId: worker.id,
|
|
55
|
-
workerName: worker.name,
|
|
56
|
-
action: 'display',
|
|
57
|
-
});
|
|
58
|
-
await shutdownAnalytics();
|
|
59
|
-
process.exit(0);
|
|
60
|
-
}
|
|
61
|
-
// Handle ping option
|
|
62
|
-
if (options.ping) {
|
|
63
|
-
console.log(chalk.blue(`Pinging worker '${worker.name}' at ${worker.endpoint}...`));
|
|
64
|
-
// Check worker health
|
|
65
|
-
const isHealthy = await workerManager.checkHealth(worker.id);
|
|
66
|
-
if (isHealthy) {
|
|
67
|
-
console.log(chalk.green(`Worker '${worker.name}' is active!`));
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
console.log(chalk.red(`Worker '${worker.name}' is not responding.`));
|
|
71
|
-
}
|
|
72
|
-
const duration = Date.now() - startTime;
|
|
73
|
-
trackCommandSuccess('worker-inspect', duration, {
|
|
74
|
-
workerId: worker.id,
|
|
75
|
-
workerName: worker.name,
|
|
76
|
-
action: 'ping',
|
|
77
|
-
isHealthy,
|
|
78
|
-
});
|
|
79
|
-
await shutdownAnalytics();
|
|
80
|
-
process.exit(0);
|
|
81
|
-
}
|
|
82
|
-
// Handle start option
|
|
83
|
-
if (options.start) {
|
|
84
|
-
console.log(chalk.blue(`Starting worker '${worker.name}'...`));
|
|
85
|
-
await workerManager.start(worker.id);
|
|
86
|
-
console.log(chalk.green(`Worker '${worker.name}' started successfully!`));
|
|
87
|
-
const duration = Date.now() - startTime;
|
|
88
|
-
trackCommandSuccess('worker-inspect', duration, {
|
|
89
|
-
workerId: worker.id,
|
|
90
|
-
workerName: worker.name,
|
|
91
|
-
action: 'start',
|
|
92
|
-
});
|
|
93
|
-
await shutdownAnalytics();
|
|
94
|
-
process.exit(0);
|
|
95
|
-
}
|
|
96
|
-
// Handle stop option
|
|
97
|
-
if (options.stop) {
|
|
98
|
-
console.log(chalk.blue(`Stopping worker '${worker.name}'...`));
|
|
99
|
-
await workerManager.stop(worker.id);
|
|
100
|
-
console.log(chalk.green(`Worker '${worker.name}' stopped successfully!`));
|
|
101
|
-
const duration = Date.now() - startTime;
|
|
102
|
-
trackCommandSuccess('worker-inspect', duration, {
|
|
103
|
-
workerId: worker.id,
|
|
104
|
-
workerName: worker.name,
|
|
105
|
-
action: 'stop',
|
|
106
|
-
});
|
|
107
|
-
await shutdownAnalytics();
|
|
108
|
-
process.exit(0);
|
|
109
|
-
}
|
|
110
|
-
// Handle config option
|
|
111
|
-
if (options.config) {
|
|
112
|
-
await updateWorkerConfig(workerManager, worker.id, options.config);
|
|
113
|
-
const duration = Date.now() - startTime;
|
|
114
|
-
trackCommandSuccess('worker-inspect', duration, {
|
|
115
|
-
workerId: worker.id,
|
|
116
|
-
workerName: worker.name,
|
|
117
|
-
action: 'config',
|
|
118
|
-
configPath: options.config,
|
|
119
|
-
});
|
|
120
|
-
await shutdownAnalytics();
|
|
121
|
-
process.exit(0);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
catch (error) {
|
|
125
|
-
const duration = Date.now() - startTime;
|
|
126
|
-
trackCommandError('worker-inspect', error, duration, {
|
|
127
|
-
nameOrId,
|
|
128
|
-
options,
|
|
129
|
-
});
|
|
130
|
-
console.error(chalk.red('Failed to manage worker:'), error);
|
|
131
|
-
await shutdownAnalytics();
|
|
132
|
-
process.exit(1);
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Register the list command
|
|
138
|
-
*/
|
|
139
|
-
export function registerListCommand(workerCommand) {
|
|
140
|
-
workerCommand
|
|
141
|
-
.command('ls')
|
|
142
|
-
.description('List all registered workers')
|
|
143
|
-
.action(async () => {
|
|
144
|
-
const startTime = Date.now();
|
|
145
|
-
try {
|
|
146
|
-
trackCommand('worker-ls', {});
|
|
147
|
-
// Create worker manager
|
|
148
|
-
const workerManager = new TonkWorkerManager();
|
|
149
|
-
// Get all workers
|
|
150
|
-
const workers = await workerManager.list();
|
|
151
|
-
if (workers.length === 0) {
|
|
152
|
-
console.log(chalk.yellow('No workers registered yet.'));
|
|
153
|
-
console.log(chalk.blue(`Use '${chalk.bold('tonk worker register')}' to register a worker.`));
|
|
154
|
-
const duration = Date.now() - startTime;
|
|
155
|
-
trackCommandSuccess('worker-ls', duration, {
|
|
156
|
-
workerCount: 0,
|
|
157
|
-
});
|
|
158
|
-
await shutdownAnalytics();
|
|
159
|
-
process.exit(0);
|
|
160
|
-
}
|
|
161
|
-
// Create a table for display
|
|
162
|
-
const table = new Table({
|
|
163
|
-
head: [
|
|
164
|
-
chalk.cyan('ID'),
|
|
165
|
-
chalk.cyan('Name'),
|
|
166
|
-
chalk.cyan('Endpoint'),
|
|
167
|
-
chalk.cyan('Protocol'),
|
|
168
|
-
chalk.cyan('Status'),
|
|
169
|
-
chalk.cyan('Last Seen'),
|
|
170
|
-
],
|
|
171
|
-
colWidths: [24, 20, 30, 10, 10, 20],
|
|
172
|
-
});
|
|
173
|
-
// Add workers to table
|
|
174
|
-
workers.forEach(worker => {
|
|
175
|
-
const lastSeen = worker.status.lastSeen
|
|
176
|
-
? new Date(worker.status.lastSeen).toLocaleString()
|
|
177
|
-
: 'Never';
|
|
178
|
-
table.push([
|
|
179
|
-
worker.id,
|
|
180
|
-
worker.name,
|
|
181
|
-
worker.endpoint,
|
|
182
|
-
worker.protocol,
|
|
183
|
-
worker.status.active
|
|
184
|
-
? chalk.green('Active')
|
|
185
|
-
: chalk.yellow('Inactive'),
|
|
186
|
-
lastSeen,
|
|
187
|
-
]);
|
|
188
|
-
});
|
|
189
|
-
console.log(chalk.bold(`Registered Workers (${workers.length}):`));
|
|
190
|
-
console.log(table.toString());
|
|
191
|
-
console.log(chalk.blue(`\nUse '${chalk.bold('tonk worker inspect <name or id>')}' to view details of a specific worker.`));
|
|
192
|
-
const duration = Date.now() - startTime;
|
|
193
|
-
trackCommandSuccess('worker-ls', duration, {
|
|
194
|
-
workerCount: workers.length,
|
|
195
|
-
activeWorkers: workers.filter(w => w.status.active).length,
|
|
196
|
-
});
|
|
197
|
-
await shutdownAnalytics();
|
|
198
|
-
process.exit(0);
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
const duration = Date.now() - startTime;
|
|
202
|
-
trackCommandError('worker-ls', error, duration);
|
|
203
|
-
console.error(chalk.red('Failed to list workers:'), error);
|
|
204
|
-
await shutdownAnalytics();
|
|
205
|
-
process.exit(1);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Register the remove command
|
|
211
|
-
*/
|
|
212
|
-
export function registerRemoveCommand(workerCommand) {
|
|
213
|
-
workerCommand
|
|
214
|
-
.command('rm <nameOrId>')
|
|
215
|
-
.description('Remove a registered worker')
|
|
216
|
-
.action(async (nameOrId) => {
|
|
217
|
-
const startTime = Date.now();
|
|
218
|
-
try {
|
|
219
|
-
trackCommand('worker-rm', {
|
|
220
|
-
nameOrId,
|
|
221
|
-
});
|
|
222
|
-
// Create worker manager
|
|
223
|
-
const workerManager = new TonkWorkerManager();
|
|
224
|
-
// Get worker
|
|
225
|
-
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
226
|
-
if (!worker) {
|
|
227
|
-
console.error(chalk.red(`Worker with name or ID '${nameOrId}' not found.`));
|
|
228
|
-
const duration = Date.now() - startTime;
|
|
229
|
-
trackCommandError('worker-rm', new Error('Worker not found'), duration, {
|
|
230
|
-
nameOrId,
|
|
231
|
-
});
|
|
232
|
-
await shutdownAnalytics();
|
|
233
|
-
process.exit(1);
|
|
234
|
-
}
|
|
235
|
-
// Remove worker
|
|
236
|
-
await workerManager.remove(worker.id);
|
|
237
|
-
console.log(chalk.green(`Worker '${worker.name}' (${worker.id}) removed successfully.`));
|
|
238
|
-
const duration = Date.now() - startTime;
|
|
239
|
-
trackCommandSuccess('worker-rm', duration, {
|
|
240
|
-
workerId: worker.id,
|
|
241
|
-
workerName: worker.name,
|
|
242
|
-
});
|
|
243
|
-
await shutdownAnalytics();
|
|
244
|
-
process.exit(0);
|
|
245
|
-
}
|
|
246
|
-
catch (error) {
|
|
247
|
-
const duration = Date.now() - startTime;
|
|
248
|
-
trackCommandError('worker-rm', error, duration, {
|
|
249
|
-
nameOrId,
|
|
250
|
-
});
|
|
251
|
-
console.error(chalk.red('Failed to remove worker:'), error);
|
|
252
|
-
await shutdownAnalytics();
|
|
253
|
-
process.exit(1);
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Register the ping command
|
|
259
|
-
*/
|
|
260
|
-
export function registerPingCommand(workerCommand) {
|
|
261
|
-
workerCommand
|
|
262
|
-
.command('ping <nameOrId>')
|
|
263
|
-
.description('Ping a worker to check its status')
|
|
264
|
-
.action(async (nameOrId) => {
|
|
265
|
-
const startTime = Date.now();
|
|
266
|
-
try {
|
|
267
|
-
trackCommand('worker-ping', {
|
|
268
|
-
nameOrId,
|
|
269
|
-
});
|
|
270
|
-
// Create worker manager
|
|
271
|
-
const workerManager = new TonkWorkerManager();
|
|
272
|
-
// Get worker
|
|
273
|
-
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
274
|
-
if (!worker) {
|
|
275
|
-
console.error(chalk.red(`Worker with name or ID '${nameOrId}' not found.`));
|
|
276
|
-
const duration = Date.now() - startTime;
|
|
277
|
-
trackCommandError('worker-ping', new Error('Worker not found'), duration, {
|
|
278
|
-
nameOrId,
|
|
279
|
-
});
|
|
280
|
-
await shutdownAnalytics();
|
|
281
|
-
process.exit(1);
|
|
282
|
-
}
|
|
283
|
-
console.log(chalk.blue(`Pinging worker '${worker.name}' at ${worker.endpoint}...`));
|
|
284
|
-
// Check worker health
|
|
285
|
-
const isHealthy = await workerManager.checkHealth(worker.id);
|
|
286
|
-
if (isHealthy) {
|
|
287
|
-
console.log(chalk.green(`Worker '${worker.name}' is active!`));
|
|
288
|
-
}
|
|
289
|
-
else {
|
|
290
|
-
console.log(chalk.red(`Worker '${worker.name}' is not responding.`));
|
|
291
|
-
}
|
|
292
|
-
const duration = Date.now() - startTime;
|
|
293
|
-
trackCommandSuccess('worker-ping', duration, {
|
|
294
|
-
workerId: worker.id,
|
|
295
|
-
workerName: worker.name,
|
|
296
|
-
isHealthy,
|
|
297
|
-
});
|
|
298
|
-
await shutdownAnalytics();
|
|
299
|
-
process.exit(0);
|
|
300
|
-
}
|
|
301
|
-
catch (error) {
|
|
302
|
-
const duration = Date.now() - startTime;
|
|
303
|
-
trackCommandError('worker-ping', error, duration, {
|
|
304
|
-
nameOrId,
|
|
305
|
-
});
|
|
306
|
-
console.error(chalk.red('Failed to ping worker:'), error);
|
|
307
|
-
await shutdownAnalytics();
|
|
308
|
-
process.exit(1);
|
|
309
|
-
}
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Register the start command
|
|
314
|
-
*/
|
|
315
|
-
export function registerStartCommand(workerCommand) {
|
|
316
|
-
workerCommand
|
|
317
|
-
.command('start <nameOrId>')
|
|
318
|
-
.description('Start a worker')
|
|
319
|
-
.action(async (nameOrId) => {
|
|
320
|
-
const startTime = Date.now();
|
|
321
|
-
try {
|
|
322
|
-
trackCommand('worker-start', {
|
|
323
|
-
nameOrId,
|
|
324
|
-
});
|
|
325
|
-
// Create worker manager
|
|
326
|
-
const workerManager = new TonkWorkerManager();
|
|
327
|
-
// Get worker
|
|
328
|
-
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
329
|
-
if (!worker) {
|
|
330
|
-
console.error(chalk.red(`Worker with name or ID '${nameOrId}' not found.`));
|
|
331
|
-
const duration = Date.now() - startTime;
|
|
332
|
-
trackCommandError('worker-start', new Error('Worker not found'), duration, {
|
|
333
|
-
nameOrId,
|
|
334
|
-
});
|
|
335
|
-
await shutdownAnalytics();
|
|
336
|
-
process.exit(1);
|
|
337
|
-
}
|
|
338
|
-
console.log(chalk.blue(`Starting worker '${worker.name}'...`));
|
|
339
|
-
await workerManager.start(worker.id);
|
|
340
|
-
console.log(chalk.green(`Worker '${worker.name}' started successfully!`));
|
|
341
|
-
const duration = Date.now() - startTime;
|
|
342
|
-
trackCommandSuccess('worker-start', duration, {
|
|
343
|
-
workerId: worker.id,
|
|
344
|
-
workerName: worker.name,
|
|
345
|
-
});
|
|
346
|
-
await shutdownAnalytics();
|
|
347
|
-
process.exit(0);
|
|
348
|
-
}
|
|
349
|
-
catch (error) {
|
|
350
|
-
const duration = Date.now() - startTime;
|
|
351
|
-
trackCommandError('worker-start', error, duration, {
|
|
352
|
-
nameOrId,
|
|
353
|
-
});
|
|
354
|
-
console.error(chalk.red('Failed to start worker:'), error);
|
|
355
|
-
await shutdownAnalytics();
|
|
356
|
-
process.exit(1);
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
/**
|
|
361
|
-
* Register the stop command
|
|
362
|
-
*/
|
|
363
|
-
export function registerStopCommand(workerCommand) {
|
|
364
|
-
workerCommand
|
|
365
|
-
.command('stop <nameOrId>')
|
|
366
|
-
.description('Stop a worker')
|
|
367
|
-
.action(async (nameOrId) => {
|
|
368
|
-
const startTime = Date.now();
|
|
369
|
-
try {
|
|
370
|
-
trackCommand('worker-stop', {
|
|
371
|
-
nameOrId,
|
|
372
|
-
});
|
|
373
|
-
// Create worker manager
|
|
374
|
-
const workerManager = new TonkWorkerManager();
|
|
375
|
-
// Get worker
|
|
376
|
-
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
377
|
-
if (!worker) {
|
|
378
|
-
console.error(chalk.red(`Worker with name or ID '${nameOrId}' not found.`));
|
|
379
|
-
const duration = Date.now() - startTime;
|
|
380
|
-
trackCommandError('worker-stop', new Error('Worker not found'), duration, {
|
|
381
|
-
nameOrId,
|
|
382
|
-
});
|
|
383
|
-
await shutdownAnalytics();
|
|
384
|
-
process.exit(1);
|
|
385
|
-
}
|
|
386
|
-
console.log(chalk.blue(`Stopping worker '${worker.name}'...`));
|
|
387
|
-
await workerManager.stop(worker.id);
|
|
388
|
-
console.log(chalk.green(`Worker '${worker.name}' stopped successfully!`));
|
|
389
|
-
const duration = Date.now() - startTime;
|
|
390
|
-
trackCommandSuccess('worker-stop', duration, {
|
|
391
|
-
workerId: worker.id,
|
|
392
|
-
workerName: worker.name,
|
|
393
|
-
});
|
|
394
|
-
await shutdownAnalytics();
|
|
395
|
-
process.exit(0);
|
|
396
|
-
}
|
|
397
|
-
catch (error) {
|
|
398
|
-
const duration = Date.now() - startTime;
|
|
399
|
-
trackCommandError('worker-stop', error, duration, {
|
|
400
|
-
nameOrId,
|
|
401
|
-
});
|
|
402
|
-
console.error(chalk.red('Failed to stop worker:'), error);
|
|
403
|
-
await shutdownAnalytics();
|
|
404
|
-
process.exit(1);
|
|
405
|
-
}
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
/**
|
|
409
|
-
* Register the logs command
|
|
410
|
-
*/
|
|
411
|
-
export function registerLogsCommand(workerCommand) {
|
|
412
|
-
workerCommand
|
|
413
|
-
.command('logs <nameOrId>')
|
|
414
|
-
.description('View logs for a worker')
|
|
415
|
-
.option('-f, --follow', 'Follow log output')
|
|
416
|
-
.option('-l, --lines <n>', 'Number of lines to show', '100')
|
|
417
|
-
.option('-e, --error', 'Show only error logs')
|
|
418
|
-
.option('-o, --out', 'Show only standard output logs')
|
|
419
|
-
.action(async (nameOrId, options) => {
|
|
420
|
-
const startTime = Date.now();
|
|
421
|
-
try {
|
|
422
|
-
trackCommand('worker-logs', {
|
|
423
|
-
nameOrId,
|
|
424
|
-
follow: options.follow,
|
|
425
|
-
lines: options.lines,
|
|
426
|
-
error: options.error,
|
|
427
|
-
out: options.out,
|
|
428
|
-
});
|
|
429
|
-
// Create worker manager
|
|
430
|
-
const workerManager = new TonkWorkerManager();
|
|
431
|
-
// Get worker
|
|
432
|
-
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
433
|
-
if (!worker) {
|
|
434
|
-
console.error(chalk.red(`Worker with name or ID '${nameOrId}' not found.`));
|
|
435
|
-
const duration = Date.now() - startTime;
|
|
436
|
-
trackCommandError('worker-logs', new Error('Worker not found'), duration, {
|
|
437
|
-
nameOrId,
|
|
438
|
-
});
|
|
439
|
-
await shutdownAnalytics();
|
|
440
|
-
process.exit(1);
|
|
441
|
-
}
|
|
442
|
-
console.log(chalk.blue(`Fetching logs for worker '${worker.name}'...`));
|
|
443
|
-
const { spawn } = await import('node:child_process');
|
|
444
|
-
try {
|
|
445
|
-
// Build the PM2 logs command arguments
|
|
446
|
-
const args = ['logs', worker.id];
|
|
447
|
-
// Add options
|
|
448
|
-
if (options.lines) {
|
|
449
|
-
args.push('--lines', options.lines);
|
|
450
|
-
}
|
|
451
|
-
if (options.error) {
|
|
452
|
-
args.push('--err');
|
|
453
|
-
}
|
|
454
|
-
else if (options.out) {
|
|
455
|
-
args.push('--out');
|
|
456
|
-
}
|
|
457
|
-
// Always use --raw to get cleaner output
|
|
458
|
-
args.push('--raw');
|
|
459
|
-
// For non-follow mode, we'll use --lines and then kill the process after a short delay
|
|
460
|
-
if (!options.follow) {
|
|
461
|
-
console.log(chalk.blue(`Showing last ${options.lines || '100'} lines of logs...`));
|
|
462
|
-
const child = spawn('pm2', args, {
|
|
463
|
-
stdio: 'inherit',
|
|
464
|
-
});
|
|
465
|
-
// Kill the process after a short delay to get just the initial output
|
|
466
|
-
setTimeout(() => {
|
|
467
|
-
child.kill('SIGINT');
|
|
468
|
-
}, 1000);
|
|
469
|
-
// Wait for the child process to exit
|
|
470
|
-
await new Promise(resolve => {
|
|
471
|
-
child.on('exit', resolve);
|
|
472
|
-
});
|
|
473
|
-
console.log(chalk.blue('\nUse -f or --follow to stream logs in real-time'));
|
|
474
|
-
}
|
|
475
|
-
else {
|
|
476
|
-
// For follow mode
|
|
477
|
-
console.log(chalk.blue('Streaming logs in real-time. Press Ctrl+C to exit.'));
|
|
478
|
-
const child = spawn('pm2', args, {
|
|
479
|
-
stdio: 'inherit',
|
|
480
|
-
});
|
|
481
|
-
// Handle process exit
|
|
482
|
-
process.on('SIGINT', async () => {
|
|
483
|
-
child.kill();
|
|
484
|
-
await shutdownAnalytics();
|
|
485
|
-
process.exit(0);
|
|
486
|
-
});
|
|
487
|
-
// Wait for the child process to exit
|
|
488
|
-
await new Promise(resolve => {
|
|
489
|
-
child.on('exit', resolve);
|
|
490
|
-
});
|
|
491
|
-
}
|
|
492
|
-
const duration = Date.now() - startTime;
|
|
493
|
-
trackCommandSuccess('worker-logs', duration, {
|
|
494
|
-
workerId: worker.id,
|
|
495
|
-
workerName: worker.name,
|
|
496
|
-
follow: options.follow,
|
|
497
|
-
lines: options.lines,
|
|
498
|
-
logType: options.error ? 'error' : options.out ? 'out' : 'all',
|
|
499
|
-
});
|
|
500
|
-
await shutdownAnalytics();
|
|
501
|
-
process.exit(0);
|
|
502
|
-
}
|
|
503
|
-
catch (error) {
|
|
504
|
-
const duration = Date.now() - startTime;
|
|
505
|
-
trackCommandError('worker-logs', error, duration, {
|
|
506
|
-
workerId: worker.id,
|
|
507
|
-
workerName: worker.name,
|
|
508
|
-
options,
|
|
509
|
-
});
|
|
510
|
-
console.error(chalk.red('Failed to fetch logs:'), error);
|
|
511
|
-
await shutdownAnalytics();
|
|
512
|
-
process.exit(1);
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
catch (error) {
|
|
516
|
-
const duration = Date.now() - startTime;
|
|
517
|
-
trackCommandError('worker-logs', error, duration, {
|
|
518
|
-
nameOrId,
|
|
519
|
-
options,
|
|
520
|
-
});
|
|
521
|
-
console.error(chalk.red('Failed to fetch worker logs:'), error);
|
|
522
|
-
await shutdownAnalytics();
|
|
523
|
-
process.exit(1);
|
|
524
|
-
}
|
|
525
|
-
});
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* Register the register command
|
|
529
|
-
*/
|
|
530
|
-
export function registerRegisterCommand(workerCommand) {
|
|
531
|
-
workerCommand
|
|
532
|
-
.command('register')
|
|
533
|
-
.description('Register a worker with Tonk')
|
|
534
|
-
.argument('[dir]', 'Path to worker directory (defaults to current directory)')
|
|
535
|
-
.option('-n, --name <n>', 'Name of the worker')
|
|
536
|
-
.option('-e, --endpoint <endpoint>', 'Endpoint URL of the worker')
|
|
537
|
-
.option('-p, --port <port>', 'Port number for the worker')
|
|
538
|
-
.option('-d, --description <description>', 'Description of the worker')
|
|
539
|
-
.action(async (dir = '.', options) => {
|
|
540
|
-
const startTime = Date.now();
|
|
541
|
-
try {
|
|
542
|
-
trackCommand('worker-register', {
|
|
543
|
-
hasDir: !!dir && dir !== '.',
|
|
544
|
-
hasName: !!options.name,
|
|
545
|
-
hasEndpoint: !!options.endpoint,
|
|
546
|
-
hasPort: !!options.port,
|
|
547
|
-
hasDescription: !!options.description,
|
|
548
|
-
});
|
|
549
|
-
// Create worker manager
|
|
550
|
-
const workerManager = new TonkWorkerManager();
|
|
551
|
-
// If options are provided, use them directly
|
|
552
|
-
if (options.name && options.endpoint) {
|
|
553
|
-
// Register worker using provided options
|
|
554
|
-
const worker = await workerManager.register({
|
|
555
|
-
name: options.name,
|
|
556
|
-
description: options.description || `Worker at ${options.endpoint}`,
|
|
557
|
-
endpoint: options.endpoint,
|
|
558
|
-
protocol: 'http',
|
|
559
|
-
env: options.port ? [`WORKER_PORT=${options.port}`] : [],
|
|
560
|
-
});
|
|
561
|
-
console.log(chalk.green(`Worker '${worker.name}' registered successfully!`));
|
|
562
|
-
console.log(chalk.cyan('Worker ID:'), chalk.bold(worker.id));
|
|
563
|
-
console.log(chalk.cyan('Endpoint:'), chalk.bold(worker.endpoint));
|
|
564
|
-
console.log(chalk.cyan('Protocol:'), chalk.bold(worker.protocol));
|
|
565
|
-
console.log(chalk.cyan('Status:'), worker.status.active
|
|
566
|
-
? chalk.green('Active')
|
|
567
|
-
: chalk.yellow('Inactive'));
|
|
568
|
-
if (Object.keys(worker.env).length > 0) {
|
|
569
|
-
console.log(chalk.cyan('Environment Variables:'));
|
|
570
|
-
Object.entries(worker.env).forEach(([key, value]) => {
|
|
571
|
-
console.log(` ${key}=${value}`);
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
|
-
const duration = Date.now() - startTime;
|
|
575
|
-
trackCommandSuccess('worker-register', duration, {
|
|
576
|
-
workerId: worker.id,
|
|
577
|
-
workerName: worker.name,
|
|
578
|
-
registrationType: 'direct',
|
|
579
|
-
hasCustomPort: !!options.port,
|
|
580
|
-
});
|
|
581
|
-
await shutdownAnalytics();
|
|
582
|
-
process.exit(0);
|
|
583
|
-
}
|
|
584
|
-
// Look for package.json and worker.config.js files
|
|
585
|
-
const workerDir = await findWorkerRoot(dir);
|
|
586
|
-
if (!workerDir) {
|
|
587
|
-
console.error(chalk.red(`No package.json or worker.config.js found in ${path.resolve(dir)} or its parent directories.`));
|
|
588
|
-
console.log(chalk.yellow('Make sure you are in a valid worker directory or specify the path to one, or provide --name and --endpoint options.'));
|
|
589
|
-
const duration = Date.now() - startTime;
|
|
590
|
-
trackCommandError('worker-register', new Error('Worker directory not found'), duration, {
|
|
591
|
-
dir: path.resolve(dir),
|
|
592
|
-
});
|
|
593
|
-
await shutdownAnalytics();
|
|
594
|
-
process.exit(1);
|
|
595
|
-
}
|
|
596
|
-
console.log(chalk.blue(`Found worker directory at: ${workerDir}`));
|
|
597
|
-
// Read package.json for worker metadata
|
|
598
|
-
const packageJsonPath = path.join(workerDir, 'package.json');
|
|
599
|
-
const packageJson = await readPackageJson(packageJsonPath);
|
|
600
|
-
if (!packageJson) {
|
|
601
|
-
console.error(chalk.red(`Failed to parse package.json file at ${packageJsonPath}`));
|
|
602
|
-
const duration = Date.now() - startTime;
|
|
603
|
-
trackCommandError('worker-register', new Error('Failed to parse package.json'), duration, {
|
|
604
|
-
packageJsonPath,
|
|
605
|
-
});
|
|
606
|
-
await shutdownAnalytics();
|
|
607
|
-
process.exit(1);
|
|
608
|
-
}
|
|
609
|
-
// Read worker.config.js for configuration
|
|
610
|
-
const workerConfigPath = path.join(workerDir, 'worker.config.js');
|
|
611
|
-
const workerConfig = await readWorkerConfigJs(workerConfigPath);
|
|
612
|
-
if (!workerConfig) {
|
|
613
|
-
console.error(chalk.red(`Failed to parse worker.config.js file at ${workerConfigPath}`));
|
|
614
|
-
const duration = Date.now() - startTime;
|
|
615
|
-
trackCommandError('worker-register', new Error('Failed to parse worker.config.js'), duration, {
|
|
616
|
-
workerConfigPath,
|
|
617
|
-
});
|
|
618
|
-
await shutdownAnalytics();
|
|
619
|
-
process.exit(1);
|
|
620
|
-
}
|
|
621
|
-
// Determine port from config or use default
|
|
622
|
-
const port = options.port || workerConfig.runtime?.port || 5555;
|
|
623
|
-
// Create worker registration options
|
|
624
|
-
const registrationOptions = {
|
|
625
|
-
name: packageJson.name,
|
|
626
|
-
description: packageJson.description || 'Tonk worker',
|
|
627
|
-
endpoint: options.endpoint || `http://localhost:${port}/tonk`,
|
|
628
|
-
protocol: 'http',
|
|
629
|
-
env: [`WORKER_PORT=${port}`],
|
|
630
|
-
config: {
|
|
631
|
-
...workerConfig,
|
|
632
|
-
version: packageJson.version,
|
|
633
|
-
},
|
|
634
|
-
};
|
|
635
|
-
// Register worker
|
|
636
|
-
const worker = await workerManager.register(registrationOptions);
|
|
637
|
-
console.log(chalk.green(`Worker '${worker.name}' registered successfully!`));
|
|
638
|
-
console.log(chalk.cyan('Worker ID:'), chalk.bold(worker.id));
|
|
639
|
-
console.log(chalk.cyan('Endpoint:'), chalk.bold(worker.endpoint));
|
|
640
|
-
console.log(chalk.cyan('Protocol:'), chalk.bold(worker.protocol));
|
|
641
|
-
console.log(chalk.cyan('Status:'), worker.status.active
|
|
642
|
-
? chalk.green('Active')
|
|
643
|
-
: chalk.yellow('Inactive'));
|
|
644
|
-
if (Object.keys(worker.env).length > 0) {
|
|
645
|
-
console.log(chalk.cyan('Environment Variables:'));
|
|
646
|
-
Object.entries(worker.env).forEach(([key, value]) => {
|
|
647
|
-
console.log(` ${key}=${value}`);
|
|
648
|
-
});
|
|
649
|
-
}
|
|
650
|
-
const duration = Date.now() - startTime;
|
|
651
|
-
trackCommandSuccess('worker-register', duration, {
|
|
652
|
-
workerId: worker.id,
|
|
653
|
-
workerName: worker.name,
|
|
654
|
-
registrationType: 'config-based',
|
|
655
|
-
workerDir,
|
|
656
|
-
port,
|
|
657
|
-
hasCustomEndpoint: !!options.endpoint,
|
|
658
|
-
});
|
|
659
|
-
await shutdownAnalytics();
|
|
660
|
-
process.exit(0);
|
|
661
|
-
}
|
|
662
|
-
catch (error) {
|
|
663
|
-
const duration = Date.now() - startTime;
|
|
664
|
-
trackCommandError('worker-register', error, duration, {
|
|
665
|
-
dir,
|
|
666
|
-
options,
|
|
667
|
-
});
|
|
668
|
-
console.error(chalk.red('Failed to register worker:'), error);
|
|
669
|
-
await shutdownAnalytics();
|
|
670
|
-
process.exit(1);
|
|
671
|
-
}
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
/**
|
|
675
|
-
* Register the install command
|
|
676
|
-
*/
|
|
677
|
-
export function registerInstallCommand(workerCommand) {
|
|
678
|
-
workerCommand
|
|
679
|
-
.command('install <package>')
|
|
680
|
-
.description('Install and start a worker from npm')
|
|
681
|
-
.option('-p, --port <port>', 'Specify a port for the worker (default: auto-detect)')
|
|
682
|
-
.option('-n, --name <n>', 'Custom name for the worker (default: npm package name)')
|
|
683
|
-
.action(async (packageName, options) => {
|
|
684
|
-
const startTime = Date.now();
|
|
685
|
-
try {
|
|
686
|
-
trackCommand('worker-install', {
|
|
687
|
-
packageName,
|
|
688
|
-
hasCustomPort: !!options.port,
|
|
689
|
-
hasCustomName: !!options.name,
|
|
690
|
-
});
|
|
691
|
-
console.log(chalk.blue(`Installing worker from npm package: ${packageName}...`));
|
|
692
|
-
// Create worker manager
|
|
693
|
-
const workerManager = new TonkWorkerManager();
|
|
694
|
-
// Execute npm install
|
|
695
|
-
const execAsync = promisify(exec);
|
|
696
|
-
try {
|
|
697
|
-
console.log(chalk.blue('Installing package...'));
|
|
698
|
-
await execAsync(`npm install -g ${packageName}`);
|
|
699
|
-
console.log(chalk.green('Package installed successfully!'));
|
|
700
|
-
}
|
|
701
|
-
catch (error) {
|
|
702
|
-
console.error(chalk.red('Failed to install package:'), error);
|
|
703
|
-
const duration = Date.now() - startTime;
|
|
704
|
-
trackCommandError('worker-install', error, duration, {
|
|
705
|
-
packageName,
|
|
706
|
-
stage: 'npm-install',
|
|
707
|
-
});
|
|
708
|
-
await shutdownAnalytics();
|
|
709
|
-
process.exit(1);
|
|
710
|
-
}
|
|
711
|
-
// Find an available port starting from 5555
|
|
712
|
-
let port = options.port;
|
|
713
|
-
if (!port) {
|
|
714
|
-
port = await findAvailablePort(5555);
|
|
715
|
-
console.log(chalk.blue(`Found available port: ${port}`));
|
|
716
|
-
}
|
|
717
|
-
// Get package info to determine the worker name and entry point
|
|
718
|
-
let packageInfo;
|
|
719
|
-
try {
|
|
720
|
-
const { stdout } = await execAsync(`npm view ${packageName} --json`);
|
|
721
|
-
packageInfo = JSON.parse(stdout);
|
|
722
|
-
}
|
|
723
|
-
catch (error) {
|
|
724
|
-
console.error(chalk.red('Failed to get package info:'), error);
|
|
725
|
-
const duration = Date.now() - startTime;
|
|
726
|
-
trackCommandError('worker-install', error, duration, {
|
|
727
|
-
packageName,
|
|
728
|
-
stage: 'package-info',
|
|
729
|
-
});
|
|
730
|
-
await shutdownAnalytics();
|
|
731
|
-
process.exit(1);
|
|
732
|
-
}
|
|
733
|
-
// Strip scope from package name for display purposes (e.g., @tonk/worker -> worker)
|
|
734
|
-
const commandName = options.name || packageName.replace(/^@[^/]+\//, '');
|
|
735
|
-
// Verify the package can be executed directly
|
|
736
|
-
let setupCompleted = false;
|
|
737
|
-
try {
|
|
738
|
-
// Check if the command exists by running a simple help command
|
|
739
|
-
await execAsync(`${commandName} --help`);
|
|
740
|
-
console.log(chalk.green(`Verified that '${packageName}' is executable.`));
|
|
741
|
-
// Try running the setup command if it exists
|
|
742
|
-
try {
|
|
743
|
-
console.log(chalk.blue(`Running setup for '${packageName}'...`));
|
|
744
|
-
// Use spawn to allow user interaction during setup
|
|
745
|
-
const { spawn } = await import('node:child_process');
|
|
746
|
-
const setupProcess = spawn(commandName, ['setup'], {
|
|
747
|
-
stdio: 'inherit',
|
|
748
|
-
shell: true,
|
|
749
|
-
});
|
|
750
|
-
// Wait for the setup process to complete
|
|
751
|
-
setupCompleted = await new Promise((resolve, reject) => {
|
|
752
|
-
setupProcess.on('close', code => {
|
|
753
|
-
if (code === 0) {
|
|
754
|
-
console.log(chalk.green(`Setup completed successfully for '${packageName}'`));
|
|
755
|
-
resolve(true);
|
|
756
|
-
}
|
|
757
|
-
else {
|
|
758
|
-
console.warn(chalk.yellow(`Setup command exited with code ${code}`));
|
|
759
|
-
resolve(false);
|
|
760
|
-
}
|
|
761
|
-
});
|
|
762
|
-
setupProcess.on('error', err => {
|
|
763
|
-
reject(err);
|
|
764
|
-
});
|
|
765
|
-
});
|
|
766
|
-
}
|
|
767
|
-
catch (setupError) {
|
|
768
|
-
console.log(chalk.yellow(`Setup command not available for '${packageName}', continuing with installation...`));
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
catch (error) {
|
|
772
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
773
|
-
console.warn(chalk.yellow(`Warning: Could not verify that '${packageName}' is executable. It may not be properly installed or may not provide a CLI.`));
|
|
774
|
-
console.warn(chalk.yellow(`Error: ${errorMessage}`));
|
|
775
|
-
}
|
|
776
|
-
// Register the worker with the npm package name
|
|
777
|
-
const worker = await workerManager.register({
|
|
778
|
-
name: packageName, // Use the actual package name for npm resolution
|
|
779
|
-
description: packageInfo.description || `Worker from npm package ${packageName}`,
|
|
780
|
-
endpoint: `http://localhost:${port}/tonk`,
|
|
781
|
-
protocol: 'http',
|
|
782
|
-
env: [`WORKER_PORT=${port}`],
|
|
783
|
-
type: 'npm',
|
|
784
|
-
});
|
|
785
|
-
console.log(chalk.green(`Worker '${packageName}' registered successfully!`));
|
|
786
|
-
// Start the worker
|
|
787
|
-
console.log(chalk.blue(`Starting worker '${packageName}'...`));
|
|
788
|
-
const success = await workerManager.start(worker.id);
|
|
789
|
-
if (success) {
|
|
790
|
-
console.log(chalk.green(`Worker '${packageName}' started successfully!`));
|
|
791
|
-
console.log(chalk.cyan('Worker ID:'), chalk.bold(worker.id));
|
|
792
|
-
console.log(chalk.cyan('Endpoint:'), chalk.bold(worker.endpoint));
|
|
793
|
-
const duration = Date.now() - startTime;
|
|
794
|
-
trackCommandSuccess('worker-install', duration, {
|
|
795
|
-
workerId: worker.id,
|
|
796
|
-
workerName: worker.name,
|
|
797
|
-
packageName,
|
|
798
|
-
port,
|
|
799
|
-
setupCompleted,
|
|
800
|
-
startedSuccessfully: true,
|
|
801
|
-
});
|
|
802
|
-
await shutdownAnalytics();
|
|
803
|
-
process.exit(0);
|
|
804
|
-
}
|
|
805
|
-
else {
|
|
806
|
-
console.error(chalk.red(`Failed to start worker '${packageName}'.`));
|
|
807
|
-
const duration = Date.now() - startTime;
|
|
808
|
-
trackCommandError('worker-install', new Error('Failed to start worker'), duration, {
|
|
809
|
-
workerId: worker.id,
|
|
810
|
-
packageName,
|
|
811
|
-
stage: 'worker-start',
|
|
812
|
-
});
|
|
813
|
-
await shutdownAnalytics();
|
|
814
|
-
process.exit(1);
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
catch (error) {
|
|
818
|
-
const duration = Date.now() - startTime;
|
|
819
|
-
trackCommandError('worker-install', error, duration, {
|
|
820
|
-
packageName,
|
|
821
|
-
options,
|
|
822
|
-
});
|
|
823
|
-
console.error(chalk.red('Failed to install worker:'), error);
|
|
824
|
-
await shutdownAnalytics();
|
|
825
|
-
process.exit(1);
|
|
826
|
-
}
|
|
827
|
-
});
|
|
828
|
-
}
|
|
829
|
-
/**
|
|
830
|
-
* Register the init command
|
|
831
|
-
*/
|
|
832
|
-
export function registerInitCommand(workerCommand) {
|
|
833
|
-
workerCommand
|
|
834
|
-
.command('init')
|
|
835
|
-
.description('Initialise a new worker configuration file')
|
|
836
|
-
.option('-d, --dir <directory>', 'Directory to create the configuration file in', '.')
|
|
837
|
-
.option('-n, --name <n>', 'Name of the worker')
|
|
838
|
-
.option('-p, --port <port>', 'Port number for the worker', '5555')
|
|
839
|
-
.option('-D, --description <description>', 'Description of the worker')
|
|
840
|
-
.action(async (options) => {
|
|
841
|
-
const startTime = Date.now();
|
|
842
|
-
try {
|
|
843
|
-
trackCommand('worker-init', {
|
|
844
|
-
hasCustomDir: options.dir !== '.',
|
|
845
|
-
hasName: !!options.name,
|
|
846
|
-
hasCustomPort: options.port !== '5555',
|
|
847
|
-
hasDescription: !!options.description,
|
|
848
|
-
});
|
|
849
|
-
// Prompt for missing options
|
|
850
|
-
const answers = await promptForMissingOptions(options);
|
|
851
|
-
const mergedOptions = { ...options, ...answers };
|
|
852
|
-
// Create the directory if it doesn't exist
|
|
853
|
-
const targetDir = path.resolve(mergedOptions.dir);
|
|
854
|
-
let directoryCreated = false;
|
|
855
|
-
if (!fs.existsSync(targetDir)) {
|
|
856
|
-
fs.mkdirSync(targetDir, { recursive: true });
|
|
857
|
-
console.log(chalk.blue(`Created directory: ${targetDir}`));
|
|
858
|
-
directoryCreated = true;
|
|
859
|
-
}
|
|
860
|
-
// Generate the package.json content if it doesn't exist
|
|
861
|
-
const packageJsonPath = path.join(targetDir, 'package.json');
|
|
862
|
-
let packageJsonCreated = false;
|
|
863
|
-
if (!fs.existsSync(packageJsonPath)) {
|
|
864
|
-
const packageJsonContent = generatePackageJsonContent(mergedOptions);
|
|
865
|
-
fs.writeFileSync(packageJsonPath, packageJsonContent);
|
|
866
|
-
console.log(chalk.green(`Created package.json at: ${packageJsonPath}`));
|
|
867
|
-
packageJsonCreated = true;
|
|
868
|
-
}
|
|
869
|
-
// Generate the worker.config.js content
|
|
870
|
-
const workerConfigContent = generateWorkerConfigJsContent();
|
|
871
|
-
const workerConfigPath = path.join(targetDir, 'worker.config.js');
|
|
872
|
-
fs.writeFileSync(workerConfigPath, workerConfigContent);
|
|
873
|
-
// Create src directory if it doesn't exist
|
|
874
|
-
const srcDir = path.join(targetDir, 'src');
|
|
875
|
-
let srcDirCreated = false;
|
|
876
|
-
if (!fs.existsSync(srcDir)) {
|
|
877
|
-
fs.mkdirSync(srcDir, { recursive: true });
|
|
878
|
-
console.log(chalk.blue(`Created src directory: ${srcDir}`));
|
|
879
|
-
srcDirCreated = true;
|
|
880
|
-
}
|
|
881
|
-
// Copy CLI template file
|
|
882
|
-
const cliTemplatePath = path.join(__dirname, 'templates', 'cli.ts.template');
|
|
883
|
-
const cliDestPath = path.join(srcDir, 'cli.ts');
|
|
884
|
-
let cliFileCreated = false;
|
|
885
|
-
if (fs.existsSync(cliTemplatePath)) {
|
|
886
|
-
let cliContent = fs.readFileSync(cliTemplatePath, 'utf-8');
|
|
887
|
-
// Replace template variables
|
|
888
|
-
cliContent = cliContent
|
|
889
|
-
.replace(/{{name}}/g, mergedOptions.name)
|
|
890
|
-
.replace(/{{description}}/g, mergedOptions.description || 'A Tonk worker')
|
|
891
|
-
.replace(/{{version}}/g, '1.0.0');
|
|
892
|
-
fs.writeFileSync(cliDestPath, cliContent);
|
|
893
|
-
console.log(chalk.green(`Created CLI file at: ${cliDestPath}`));
|
|
894
|
-
cliFileCreated = true;
|
|
895
|
-
}
|
|
896
|
-
else {
|
|
897
|
-
console.warn(chalk.yellow(`CLI template not found at: ${cliTemplatePath}`));
|
|
898
|
-
}
|
|
899
|
-
// Copy index.ts template file
|
|
900
|
-
const indexTemplatePath = path.join(__dirname, 'templates', 'index.ts.template');
|
|
901
|
-
const indexDestPath = path.join(srcDir, 'index.ts');
|
|
902
|
-
let indexFileCreated = false;
|
|
903
|
-
if (!fs.existsSync(indexDestPath) && fs.existsSync(indexTemplatePath)) {
|
|
904
|
-
let indexContent = fs.readFileSync(indexTemplatePath, 'utf-8');
|
|
905
|
-
// Replace template variables
|
|
906
|
-
indexContent = indexContent
|
|
907
|
-
.replace(/{{name}}/g, mergedOptions.name)
|
|
908
|
-
.replace(/{{description}}/g, mergedOptions.description || 'A Tonk worker')
|
|
909
|
-
.replace(/{{port}}/g, mergedOptions.port);
|
|
910
|
-
fs.writeFileSync(indexDestPath, indexContent);
|
|
911
|
-
console.log(chalk.green(`Created index.ts file at: ${indexDestPath}`));
|
|
912
|
-
indexFileCreated = true;
|
|
913
|
-
}
|
|
914
|
-
else if (!fs.existsSync(indexTemplatePath)) {
|
|
915
|
-
console.warn(chalk.yellow(`Index template not found at: ${indexTemplatePath}`));
|
|
916
|
-
}
|
|
917
|
-
// Copy tsconfig.json template file
|
|
918
|
-
const tsconfigTemplatePath = path.join(__dirname, 'templates', 'tsconfig.json.template');
|
|
919
|
-
const tsconfigDestPath = path.join(targetDir, 'tsconfig.json');
|
|
920
|
-
let tsconfigFileCreated = false;
|
|
921
|
-
if (!fs.existsSync(tsconfigDestPath) &&
|
|
922
|
-
fs.existsSync(tsconfigTemplatePath)) {
|
|
923
|
-
const tsconfigContent = fs.readFileSync(tsconfigTemplatePath, 'utf-8');
|
|
924
|
-
fs.writeFileSync(tsconfigDestPath, tsconfigContent);
|
|
925
|
-
console.log(chalk.green(`Created tsconfig.json file at: ${tsconfigDestPath}`));
|
|
926
|
-
tsconfigFileCreated = true;
|
|
927
|
-
}
|
|
928
|
-
else if (!fs.existsSync(tsconfigTemplatePath)) {
|
|
929
|
-
console.warn(chalk.yellow(`tsconfig.json template not found at: ${tsconfigTemplatePath}`));
|
|
930
|
-
}
|
|
931
|
-
console.log(chalk.green(`Worker configuration file created at: ${workerConfigPath}`));
|
|
932
|
-
console.log(chalk.blue(`\nYou can now register this worker with:`));
|
|
933
|
-
console.log(chalk.cyan(` tonk worker register ${targetDir}`));
|
|
934
|
-
const duration = Date.now() - startTime;
|
|
935
|
-
trackCommandSuccess('worker-init', duration, {
|
|
936
|
-
workerName: mergedOptions.name,
|
|
937
|
-
targetDir,
|
|
938
|
-
port: mergedOptions.port,
|
|
939
|
-
directoryCreated,
|
|
940
|
-
packageJsonCreated,
|
|
941
|
-
srcDirCreated,
|
|
942
|
-
cliFileCreated,
|
|
943
|
-
indexFileCreated,
|
|
944
|
-
tsconfigFileCreated,
|
|
945
|
-
filesCreated: [
|
|
946
|
-
packageJsonCreated && 'package.json',
|
|
947
|
-
'worker.config.js',
|
|
948
|
-
srcDirCreated && 'src/',
|
|
949
|
-
cliFileCreated && 'cli.ts',
|
|
950
|
-
indexFileCreated && 'index.ts',
|
|
951
|
-
tsconfigFileCreated && 'tsconfig.json',
|
|
952
|
-
].filter(Boolean).length,
|
|
953
|
-
});
|
|
954
|
-
await shutdownAnalytics();
|
|
955
|
-
process.exit(0);
|
|
956
|
-
}
|
|
957
|
-
catch (error) {
|
|
958
|
-
const duration = Date.now() - startTime;
|
|
959
|
-
trackCommandError('worker-init', error, duration, {
|
|
960
|
-
options,
|
|
961
|
-
});
|
|
962
|
-
console.error(chalk.red('Failed to initialise worker configuration:'), error);
|
|
963
|
-
await shutdownAnalytics();
|
|
964
|
-
process.exit(1);
|
|
965
|
-
}
|
|
966
|
-
});
|
|
967
|
-
}
|
|
968
|
-
//# sourceMappingURL=commands.js.map
|