@tonk/cli 0.2.6 → 0.2.7
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/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +8 -6
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/hello.d.ts.map +1 -1
- package/dist/commands/hello.js +12 -0
- package/dist/commands/hello.js.map +1 -1
- package/dist/commands/kill.d.ts.map +1 -1
- package/dist/commands/kill.js +24 -0
- package/dist/commands/kill.js.map +1 -1
- package/dist/commands/ls.d.ts.map +1 -1
- package/dist/commands/ls.js +18 -0
- package/dist/commands/ls.js.map +1 -1
- package/dist/commands/proxy.d.ts.map +1 -1
- package/dist/commands/proxy.js +18 -0
- package/dist/commands/proxy.js.map +1 -1
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +18 -0
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +25 -1
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +19 -0
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/worker/commands.d.ts.map +1 -1
- package/dist/commands/worker/commands.js +331 -5
- package/dist/commands/worker/commands.js.map +1 -1
- package/dist/commands/worker/index.d.ts.map +1 -1
- package/dist/commands/worker/index.js +2 -0
- package/dist/commands/worker/index.js.map +1 -1
- package/dist/commands/worker.d.ts +3 -0
- package/dist/commands/worker.d.ts.map +1 -0
- package/dist/commands/worker.js +527 -0
- package/dist/commands/worker.js.map +1 -0
- package/dist/lib/workerManager.d.ts.map +1 -1
- package/dist/lib/workerManager.js +16 -36
- package/dist/lib/workerManager.js.map +1 -1
- package/dist/tonk.js +8 -0
- package/dist/tonk.js.map +1 -1
- package/dist/utils/analytics.d.ts +26 -0
- package/dist/utils/analytics.d.ts.map +1 -0
- package/dist/utils/analytics.js +155 -0
- package/dist/utils/analytics.js.map +1 -0
- package/package.json +3 -1
|
@@ -7,6 +7,7 @@ import { exec } from 'node:child_process';
|
|
|
7
7
|
import { TonkWorkerManager } from '../../lib/workerManager.js';
|
|
8
8
|
import { displayWorkerDetails } from './utils/display.js';
|
|
9
9
|
import { findWorkerRoot, findAvailablePort } from './utils/finder.js';
|
|
10
|
+
import { trackCommand, trackCommandError, trackCommandSuccess, } from '../../utils/analytics.js';
|
|
10
11
|
import { readPackageJson, readWorkerConfigJs, updateWorkerConfig, promptForMissingOptions, generatePackageJsonContent, generateWorkerConfigJsContent, } from './utils/config.js';
|
|
11
12
|
/**
|
|
12
13
|
* Register the inspect command
|
|
@@ -20,13 +21,25 @@ export function registerInspectCommand(workerCommand) {
|
|
|
20
21
|
.option('-c, --config <path>', 'Path to worker configuration file')
|
|
21
22
|
.option('-p, --ping', 'Ping the worker to check its status')
|
|
22
23
|
.action(async (nameOrId, options) => {
|
|
24
|
+
const startTime = Date.now();
|
|
23
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
|
+
});
|
|
24
33
|
// Create worker manager
|
|
25
34
|
const workerManager = new TonkWorkerManager();
|
|
26
35
|
// Get worker
|
|
27
36
|
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
28
37
|
if (!worker) {
|
|
29
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
|
+
});
|
|
30
43
|
return;
|
|
31
44
|
}
|
|
32
45
|
// If no options provided, show worker details
|
|
@@ -35,6 +48,12 @@ export function registerInspectCommand(workerCommand) {
|
|
|
35
48
|
!options.config &&
|
|
36
49
|
!options.ping) {
|
|
37
50
|
displayWorkerDetails(worker);
|
|
51
|
+
const duration = Date.now() - startTime;
|
|
52
|
+
trackCommandSuccess('worker-inspect', duration, {
|
|
53
|
+
workerId: worker.id,
|
|
54
|
+
workerName: worker.name,
|
|
55
|
+
action: 'display',
|
|
56
|
+
});
|
|
38
57
|
return;
|
|
39
58
|
}
|
|
40
59
|
// Handle ping option
|
|
@@ -48,6 +67,13 @@ export function registerInspectCommand(workerCommand) {
|
|
|
48
67
|
else {
|
|
49
68
|
console.log(chalk.red(`Worker '${worker.name}' is not responding.`));
|
|
50
69
|
}
|
|
70
|
+
const duration = Date.now() - startTime;
|
|
71
|
+
trackCommandSuccess('worker-inspect', duration, {
|
|
72
|
+
workerId: worker.id,
|
|
73
|
+
workerName: worker.name,
|
|
74
|
+
action: 'ping',
|
|
75
|
+
isHealthy,
|
|
76
|
+
});
|
|
51
77
|
return;
|
|
52
78
|
}
|
|
53
79
|
// Handle start option
|
|
@@ -55,6 +81,12 @@ export function registerInspectCommand(workerCommand) {
|
|
|
55
81
|
console.log(chalk.blue(`Starting worker '${worker.name}'...`));
|
|
56
82
|
await workerManager.start(worker.id);
|
|
57
83
|
console.log(chalk.green(`Worker '${worker.name}' started successfully!`));
|
|
84
|
+
const duration = Date.now() - startTime;
|
|
85
|
+
trackCommandSuccess('worker-inspect', duration, {
|
|
86
|
+
workerId: worker.id,
|
|
87
|
+
workerName: worker.name,
|
|
88
|
+
action: 'start',
|
|
89
|
+
});
|
|
58
90
|
return;
|
|
59
91
|
}
|
|
60
92
|
// Handle stop option
|
|
@@ -62,14 +94,32 @@ export function registerInspectCommand(workerCommand) {
|
|
|
62
94
|
console.log(chalk.blue(`Stopping worker '${worker.name}'...`));
|
|
63
95
|
await workerManager.stop(worker.id);
|
|
64
96
|
console.log(chalk.green(`Worker '${worker.name}' stopped successfully!`));
|
|
97
|
+
const duration = Date.now() - startTime;
|
|
98
|
+
trackCommandSuccess('worker-inspect', duration, {
|
|
99
|
+
workerId: worker.id,
|
|
100
|
+
workerName: worker.name,
|
|
101
|
+
action: 'stop',
|
|
102
|
+
});
|
|
65
103
|
return;
|
|
66
104
|
}
|
|
67
105
|
// Handle config option
|
|
68
106
|
if (options.config) {
|
|
69
107
|
await updateWorkerConfig(workerManager, worker.id, options.config);
|
|
108
|
+
const duration = Date.now() - startTime;
|
|
109
|
+
trackCommandSuccess('worker-inspect', duration, {
|
|
110
|
+
workerId: worker.id,
|
|
111
|
+
workerName: worker.name,
|
|
112
|
+
action: 'config',
|
|
113
|
+
configPath: options.config,
|
|
114
|
+
});
|
|
70
115
|
}
|
|
71
116
|
}
|
|
72
117
|
catch (error) {
|
|
118
|
+
const duration = Date.now() - startTime;
|
|
119
|
+
trackCommandError('worker-inspect', error, duration, {
|
|
120
|
+
nameOrId,
|
|
121
|
+
options,
|
|
122
|
+
});
|
|
73
123
|
console.error(chalk.red('Failed to manage worker:'), error);
|
|
74
124
|
}
|
|
75
125
|
});
|
|
@@ -82,7 +132,9 @@ export function registerListCommand(workerCommand) {
|
|
|
82
132
|
.command('ls')
|
|
83
133
|
.description('List all registered workers')
|
|
84
134
|
.action(async () => {
|
|
135
|
+
const startTime = Date.now();
|
|
85
136
|
try {
|
|
137
|
+
trackCommand('worker-ls', {});
|
|
86
138
|
// Create worker manager
|
|
87
139
|
const workerManager = new TonkWorkerManager();
|
|
88
140
|
// Get all workers
|
|
@@ -90,6 +142,10 @@ export function registerListCommand(workerCommand) {
|
|
|
90
142
|
if (workers.length === 0) {
|
|
91
143
|
console.log(chalk.yellow('No workers registered yet.'));
|
|
92
144
|
console.log(chalk.blue(`Use '${chalk.bold('tonk worker register')}' to register a worker.`));
|
|
145
|
+
const duration = Date.now() - startTime;
|
|
146
|
+
trackCommandSuccess('worker-ls', duration, {
|
|
147
|
+
workerCount: 0,
|
|
148
|
+
});
|
|
93
149
|
return;
|
|
94
150
|
}
|
|
95
151
|
// Create a table for display
|
|
@@ -123,8 +179,15 @@ export function registerListCommand(workerCommand) {
|
|
|
123
179
|
console.log(chalk.bold(`Registered Workers (${workers.length}):`));
|
|
124
180
|
console.log(table.toString());
|
|
125
181
|
console.log(chalk.blue(`\nUse '${chalk.bold('tonk worker inspect <name or id>')}' to view details of a specific worker.`));
|
|
182
|
+
const duration = Date.now() - startTime;
|
|
183
|
+
trackCommandSuccess('worker-ls', duration, {
|
|
184
|
+
workerCount: workers.length,
|
|
185
|
+
activeWorkers: workers.filter(w => w.status.active).length,
|
|
186
|
+
});
|
|
126
187
|
}
|
|
127
188
|
catch (error) {
|
|
189
|
+
const duration = Date.now() - startTime;
|
|
190
|
+
trackCommandError('worker-ls', error, duration);
|
|
128
191
|
console.error(chalk.red('Failed to list workers:'), error);
|
|
129
192
|
}
|
|
130
193
|
});
|
|
@@ -137,20 +200,37 @@ export function registerRemoveCommand(workerCommand) {
|
|
|
137
200
|
.command('rm <nameOrId>')
|
|
138
201
|
.description('Remove a registered worker')
|
|
139
202
|
.action(async (nameOrId) => {
|
|
203
|
+
const startTime = Date.now();
|
|
140
204
|
try {
|
|
205
|
+
trackCommand('worker-rm', {
|
|
206
|
+
nameOrId,
|
|
207
|
+
});
|
|
141
208
|
// Create worker manager
|
|
142
209
|
const workerManager = new TonkWorkerManager();
|
|
143
210
|
// Get worker
|
|
144
211
|
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
145
212
|
if (!worker) {
|
|
146
213
|
console.error(chalk.red(`Worker with name or ID '${nameOrId}' not found.`));
|
|
214
|
+
const duration = Date.now() - startTime;
|
|
215
|
+
trackCommandError('worker-rm', new Error('Worker not found'), duration, {
|
|
216
|
+
nameOrId,
|
|
217
|
+
});
|
|
147
218
|
return;
|
|
148
219
|
}
|
|
149
220
|
// Remove worker
|
|
150
221
|
await workerManager.remove(worker.id);
|
|
151
222
|
console.log(chalk.green(`Worker '${worker.name}' (${worker.id}) removed successfully.`));
|
|
223
|
+
const duration = Date.now() - startTime;
|
|
224
|
+
trackCommandSuccess('worker-rm', duration, {
|
|
225
|
+
workerId: worker.id,
|
|
226
|
+
workerName: worker.name,
|
|
227
|
+
});
|
|
152
228
|
}
|
|
153
229
|
catch (error) {
|
|
230
|
+
const duration = Date.now() - startTime;
|
|
231
|
+
trackCommandError('worker-rm', error, duration, {
|
|
232
|
+
nameOrId,
|
|
233
|
+
});
|
|
154
234
|
console.error(chalk.red('Failed to remove worker:'), error);
|
|
155
235
|
}
|
|
156
236
|
});
|
|
@@ -163,13 +243,21 @@ export function registerPingCommand(workerCommand) {
|
|
|
163
243
|
.command('ping <nameOrId>')
|
|
164
244
|
.description('Ping a worker to check its status')
|
|
165
245
|
.action(async (nameOrId) => {
|
|
246
|
+
const startTime = Date.now();
|
|
166
247
|
try {
|
|
248
|
+
trackCommand('worker-ping', {
|
|
249
|
+
nameOrId,
|
|
250
|
+
});
|
|
167
251
|
// Create worker manager
|
|
168
252
|
const workerManager = new TonkWorkerManager();
|
|
169
253
|
// Get worker
|
|
170
254
|
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
171
255
|
if (!worker) {
|
|
172
256
|
console.error(chalk.red(`Worker with name or ID '${nameOrId}' not found.`));
|
|
257
|
+
const duration = Date.now() - startTime;
|
|
258
|
+
trackCommandError('worker-ping', new Error('Worker not found'), duration, {
|
|
259
|
+
nameOrId,
|
|
260
|
+
});
|
|
173
261
|
return;
|
|
174
262
|
}
|
|
175
263
|
console.log(chalk.blue(`Pinging worker '${worker.name}' at ${worker.endpoint}...`));
|
|
@@ -181,8 +269,18 @@ export function registerPingCommand(workerCommand) {
|
|
|
181
269
|
else {
|
|
182
270
|
console.log(chalk.red(`Worker '${worker.name}' is not responding.`));
|
|
183
271
|
}
|
|
272
|
+
const duration = Date.now() - startTime;
|
|
273
|
+
trackCommandSuccess('worker-ping', duration, {
|
|
274
|
+
workerId: worker.id,
|
|
275
|
+
workerName: worker.name,
|
|
276
|
+
isHealthy,
|
|
277
|
+
});
|
|
184
278
|
}
|
|
185
279
|
catch (error) {
|
|
280
|
+
const duration = Date.now() - startTime;
|
|
281
|
+
trackCommandError('worker-ping', error, duration, {
|
|
282
|
+
nameOrId,
|
|
283
|
+
});
|
|
186
284
|
console.error(chalk.red('Failed to ping worker:'), error);
|
|
187
285
|
}
|
|
188
286
|
});
|
|
@@ -195,20 +293,37 @@ export function registerStartCommand(workerCommand) {
|
|
|
195
293
|
.command('start <nameOrId>')
|
|
196
294
|
.description('Start a worker')
|
|
197
295
|
.action(async (nameOrId) => {
|
|
296
|
+
const startTime = Date.now();
|
|
198
297
|
try {
|
|
298
|
+
trackCommand('worker-start', {
|
|
299
|
+
nameOrId,
|
|
300
|
+
});
|
|
199
301
|
// Create worker manager
|
|
200
302
|
const workerManager = new TonkWorkerManager();
|
|
201
303
|
// Get worker
|
|
202
304
|
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
203
305
|
if (!worker) {
|
|
204
306
|
console.error(chalk.red(`Worker with name or ID '${nameOrId}' not found.`));
|
|
307
|
+
const duration = Date.now() - startTime;
|
|
308
|
+
trackCommandError('worker-start', new Error('Worker not found'), duration, {
|
|
309
|
+
nameOrId,
|
|
310
|
+
});
|
|
205
311
|
return;
|
|
206
312
|
}
|
|
207
313
|
console.log(chalk.blue(`Starting worker '${worker.name}'...`));
|
|
208
314
|
await workerManager.start(worker.id);
|
|
209
315
|
console.log(chalk.green(`Worker '${worker.name}' started successfully!`));
|
|
316
|
+
const duration = Date.now() - startTime;
|
|
317
|
+
trackCommandSuccess('worker-start', duration, {
|
|
318
|
+
workerId: worker.id,
|
|
319
|
+
workerName: worker.name,
|
|
320
|
+
});
|
|
210
321
|
}
|
|
211
322
|
catch (error) {
|
|
323
|
+
const duration = Date.now() - startTime;
|
|
324
|
+
trackCommandError('worker-start', error, duration, {
|
|
325
|
+
nameOrId,
|
|
326
|
+
});
|
|
212
327
|
console.error(chalk.red('Failed to start worker:'), error);
|
|
213
328
|
}
|
|
214
329
|
});
|
|
@@ -221,20 +336,37 @@ export function registerStopCommand(workerCommand) {
|
|
|
221
336
|
.command('stop <nameOrId>')
|
|
222
337
|
.description('Stop a worker')
|
|
223
338
|
.action(async (nameOrId) => {
|
|
339
|
+
const startTime = Date.now();
|
|
224
340
|
try {
|
|
341
|
+
trackCommand('worker-stop', {
|
|
342
|
+
nameOrId,
|
|
343
|
+
});
|
|
225
344
|
// Create worker manager
|
|
226
345
|
const workerManager = new TonkWorkerManager();
|
|
227
346
|
// Get worker
|
|
228
347
|
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
229
348
|
if (!worker) {
|
|
230
349
|
console.error(chalk.red(`Worker with name or ID '${nameOrId}' not found.`));
|
|
350
|
+
const duration = Date.now() - startTime;
|
|
351
|
+
trackCommandError('worker-stop', new Error('Worker not found'), duration, {
|
|
352
|
+
nameOrId,
|
|
353
|
+
});
|
|
231
354
|
return;
|
|
232
355
|
}
|
|
233
356
|
console.log(chalk.blue(`Stopping worker '${worker.name}'...`));
|
|
234
357
|
await workerManager.stop(worker.id);
|
|
235
358
|
console.log(chalk.green(`Worker '${worker.name}' stopped successfully!`));
|
|
359
|
+
const duration = Date.now() - startTime;
|
|
360
|
+
trackCommandSuccess('worker-stop', duration, {
|
|
361
|
+
workerId: worker.id,
|
|
362
|
+
workerName: worker.name,
|
|
363
|
+
});
|
|
236
364
|
}
|
|
237
365
|
catch (error) {
|
|
366
|
+
const duration = Date.now() - startTime;
|
|
367
|
+
trackCommandError('worker-stop', error, duration, {
|
|
368
|
+
nameOrId,
|
|
369
|
+
});
|
|
238
370
|
console.error(chalk.red('Failed to stop worker:'), error);
|
|
239
371
|
}
|
|
240
372
|
});
|
|
@@ -251,13 +383,25 @@ export function registerLogsCommand(workerCommand) {
|
|
|
251
383
|
.option('-e, --error', 'Show only error logs')
|
|
252
384
|
.option('-o, --out', 'Show only standard output logs')
|
|
253
385
|
.action(async (nameOrId, options) => {
|
|
386
|
+
const startTime = Date.now();
|
|
254
387
|
try {
|
|
388
|
+
trackCommand('worker-logs', {
|
|
389
|
+
nameOrId,
|
|
390
|
+
follow: options.follow,
|
|
391
|
+
lines: options.lines,
|
|
392
|
+
error: options.error,
|
|
393
|
+
out: options.out,
|
|
394
|
+
});
|
|
255
395
|
// Create worker manager
|
|
256
396
|
const workerManager = new TonkWorkerManager();
|
|
257
397
|
// Get worker
|
|
258
398
|
const worker = await workerManager.findByNameOrId(nameOrId);
|
|
259
399
|
if (!worker) {
|
|
260
400
|
console.error(chalk.red(`Worker with name or ID '${nameOrId}' not found.`));
|
|
401
|
+
const duration = Date.now() - startTime;
|
|
402
|
+
trackCommandError('worker-logs', new Error('Worker not found'), duration, {
|
|
403
|
+
nameOrId,
|
|
404
|
+
});
|
|
261
405
|
return;
|
|
262
406
|
}
|
|
263
407
|
console.log(chalk.blue(`Fetching logs for worker '${worker.name}'...`));
|
|
@@ -309,12 +453,31 @@ export function registerLogsCommand(workerCommand) {
|
|
|
309
453
|
child.on('exit', resolve);
|
|
310
454
|
});
|
|
311
455
|
}
|
|
456
|
+
const duration = Date.now() - startTime;
|
|
457
|
+
trackCommandSuccess('worker-logs', duration, {
|
|
458
|
+
workerId: worker.id,
|
|
459
|
+
workerName: worker.name,
|
|
460
|
+
follow: options.follow,
|
|
461
|
+
lines: options.lines,
|
|
462
|
+
logType: options.error ? 'error' : options.out ? 'out' : 'all',
|
|
463
|
+
});
|
|
312
464
|
}
|
|
313
465
|
catch (error) {
|
|
466
|
+
const duration = Date.now() - startTime;
|
|
467
|
+
trackCommandError('worker-logs', error, duration, {
|
|
468
|
+
workerId: worker.id,
|
|
469
|
+
workerName: worker.name,
|
|
470
|
+
options,
|
|
471
|
+
});
|
|
314
472
|
console.error(chalk.red('Failed to fetch logs:'), error);
|
|
315
473
|
}
|
|
316
474
|
}
|
|
317
475
|
catch (error) {
|
|
476
|
+
const duration = Date.now() - startTime;
|
|
477
|
+
trackCommandError('worker-logs', error, duration, {
|
|
478
|
+
nameOrId,
|
|
479
|
+
options,
|
|
480
|
+
});
|
|
318
481
|
console.error(chalk.red('Failed to fetch worker logs:'), error);
|
|
319
482
|
}
|
|
320
483
|
});
|
|
@@ -332,7 +495,15 @@ export function registerRegisterCommand(workerCommand) {
|
|
|
332
495
|
.option('-p, --port <port>', 'Port number for the worker')
|
|
333
496
|
.option('-d, --description <description>', 'Description of the worker')
|
|
334
497
|
.action(async (dir = '.', options) => {
|
|
498
|
+
const startTime = Date.now();
|
|
335
499
|
try {
|
|
500
|
+
trackCommand('worker-register', {
|
|
501
|
+
hasDir: !!dir && dir !== '.',
|
|
502
|
+
hasName: !!options.name,
|
|
503
|
+
hasEndpoint: !!options.endpoint,
|
|
504
|
+
hasPort: !!options.port,
|
|
505
|
+
hasDescription: !!options.description,
|
|
506
|
+
});
|
|
336
507
|
// Create worker manager
|
|
337
508
|
const workerManager = new TonkWorkerManager();
|
|
338
509
|
// If options are provided, use them directly
|
|
@@ -358,6 +529,13 @@ export function registerRegisterCommand(workerCommand) {
|
|
|
358
529
|
console.log(` ${key}=${value}`);
|
|
359
530
|
});
|
|
360
531
|
}
|
|
532
|
+
const duration = Date.now() - startTime;
|
|
533
|
+
trackCommandSuccess('worker-register', duration, {
|
|
534
|
+
workerId: worker.id,
|
|
535
|
+
workerName: worker.name,
|
|
536
|
+
registrationType: 'direct',
|
|
537
|
+
hasCustomPort: !!options.port,
|
|
538
|
+
});
|
|
361
539
|
return;
|
|
362
540
|
}
|
|
363
541
|
// Look for package.json and worker.config.js files
|
|
@@ -365,6 +543,10 @@ export function registerRegisterCommand(workerCommand) {
|
|
|
365
543
|
if (!workerDir) {
|
|
366
544
|
console.error(chalk.red(`No package.json or worker.config.js found in ${path.resolve(dir)} or its parent directories.`));
|
|
367
545
|
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.'));
|
|
546
|
+
const duration = Date.now() - startTime;
|
|
547
|
+
trackCommandError('worker-register', new Error('Worker directory not found'), duration, {
|
|
548
|
+
dir: path.resolve(dir),
|
|
549
|
+
});
|
|
368
550
|
return;
|
|
369
551
|
}
|
|
370
552
|
console.log(chalk.blue(`Found worker directory at: ${workerDir}`));
|
|
@@ -373,6 +555,10 @@ export function registerRegisterCommand(workerCommand) {
|
|
|
373
555
|
const packageJson = await readPackageJson(packageJsonPath);
|
|
374
556
|
if (!packageJson) {
|
|
375
557
|
console.error(chalk.red(`Failed to parse package.json file at ${packageJsonPath}`));
|
|
558
|
+
const duration = Date.now() - startTime;
|
|
559
|
+
trackCommandError('worker-register', new Error('Failed to parse package.json'), duration, {
|
|
560
|
+
packageJsonPath,
|
|
561
|
+
});
|
|
376
562
|
return;
|
|
377
563
|
}
|
|
378
564
|
// Read worker.config.js for configuration
|
|
@@ -380,6 +566,10 @@ export function registerRegisterCommand(workerCommand) {
|
|
|
380
566
|
const workerConfig = await readWorkerConfigJs(workerConfigPath);
|
|
381
567
|
if (!workerConfig) {
|
|
382
568
|
console.error(chalk.red(`Failed to parse worker.config.js file at ${workerConfigPath}`));
|
|
569
|
+
const duration = Date.now() - startTime;
|
|
570
|
+
trackCommandError('worker-register', new Error('Failed to parse worker.config.js'), duration, {
|
|
571
|
+
workerConfigPath,
|
|
572
|
+
});
|
|
383
573
|
return;
|
|
384
574
|
}
|
|
385
575
|
// Determine port from config or use default
|
|
@@ -411,8 +601,22 @@ export function registerRegisterCommand(workerCommand) {
|
|
|
411
601
|
console.log(` ${key}=${value}`);
|
|
412
602
|
});
|
|
413
603
|
}
|
|
604
|
+
const duration = Date.now() - startTime;
|
|
605
|
+
trackCommandSuccess('worker-register', duration, {
|
|
606
|
+
workerId: worker.id,
|
|
607
|
+
workerName: worker.name,
|
|
608
|
+
registrationType: 'config-based',
|
|
609
|
+
workerDir,
|
|
610
|
+
port,
|
|
611
|
+
hasCustomEndpoint: !!options.endpoint,
|
|
612
|
+
});
|
|
414
613
|
}
|
|
415
614
|
catch (error) {
|
|
615
|
+
const duration = Date.now() - startTime;
|
|
616
|
+
trackCommandError('worker-register', error, duration, {
|
|
617
|
+
dir,
|
|
618
|
+
options,
|
|
619
|
+
});
|
|
416
620
|
console.error(chalk.red('Failed to register worker:'), error);
|
|
417
621
|
}
|
|
418
622
|
});
|
|
@@ -427,7 +631,13 @@ export function registerInstallCommand(workerCommand) {
|
|
|
427
631
|
.option('-p, --port <port>', 'Specify a port for the worker (default: auto-detect)')
|
|
428
632
|
.option('-n, --name <n>', 'Custom name for the worker (default: npm package name)')
|
|
429
633
|
.action(async (packageName, options) => {
|
|
634
|
+
const startTime = Date.now();
|
|
430
635
|
try {
|
|
636
|
+
trackCommand('worker-install', {
|
|
637
|
+
packageName,
|
|
638
|
+
hasCustomPort: !!options.port,
|
|
639
|
+
hasCustomName: !!options.name,
|
|
640
|
+
});
|
|
431
641
|
console.log(chalk.blue(`Installing worker from npm package: ${packageName}...`));
|
|
432
642
|
// Create worker manager
|
|
433
643
|
const workerManager = new TonkWorkerManager();
|
|
@@ -440,6 +650,11 @@ export function registerInstallCommand(workerCommand) {
|
|
|
440
650
|
}
|
|
441
651
|
catch (error) {
|
|
442
652
|
console.error(chalk.red('Failed to install package:'), error);
|
|
653
|
+
const duration = Date.now() - startTime;
|
|
654
|
+
trackCommandError('worker-install', error, duration, {
|
|
655
|
+
packageName,
|
|
656
|
+
stage: 'npm-install',
|
|
657
|
+
});
|
|
443
658
|
return;
|
|
444
659
|
}
|
|
445
660
|
// Find an available port starting from 5555
|
|
@@ -456,9 +671,57 @@ export function registerInstallCommand(workerCommand) {
|
|
|
456
671
|
}
|
|
457
672
|
catch (error) {
|
|
458
673
|
console.error(chalk.red('Failed to get package info:'), error);
|
|
674
|
+
const duration = Date.now() - startTime;
|
|
675
|
+
trackCommandError('worker-install', error, duration, {
|
|
676
|
+
packageName,
|
|
677
|
+
stage: 'package-info',
|
|
678
|
+
});
|
|
459
679
|
return;
|
|
460
680
|
}
|
|
461
|
-
//
|
|
681
|
+
// Strip scope from package name for display purposes (e.g., @tonk/worker -> worker)
|
|
682
|
+
const commandName = options.name || packageName.replace(/^@[^/]+\//, '');
|
|
683
|
+
// Verify the package can be executed directly
|
|
684
|
+
let setupCompleted = false;
|
|
685
|
+
try {
|
|
686
|
+
// Check if the command exists by running a simple help command
|
|
687
|
+
await execAsync(`${commandName} --help`);
|
|
688
|
+
console.log(chalk.green(`Verified that '${packageName}' is executable.`));
|
|
689
|
+
// Try running the setup command if it exists
|
|
690
|
+
try {
|
|
691
|
+
console.log(chalk.blue(`Running setup for '${packageName}'...`));
|
|
692
|
+
// Use spawn to allow user interaction during setup
|
|
693
|
+
const { spawn } = await import('node:child_process');
|
|
694
|
+
const setupProcess = spawn(commandName, ['setup'], {
|
|
695
|
+
stdio: 'inherit',
|
|
696
|
+
shell: true,
|
|
697
|
+
});
|
|
698
|
+
// Wait for the setup process to complete
|
|
699
|
+
setupCompleted = await new Promise((resolve, reject) => {
|
|
700
|
+
setupProcess.on('close', code => {
|
|
701
|
+
if (code === 0) {
|
|
702
|
+
console.log(chalk.green(`Setup completed successfully for '${packageName}'`));
|
|
703
|
+
resolve(true);
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
console.warn(chalk.yellow(`Setup command exited with code ${code}`));
|
|
707
|
+
resolve(false);
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
setupProcess.on('error', err => {
|
|
711
|
+
reject(err);
|
|
712
|
+
});
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
catch (setupError) {
|
|
716
|
+
console.log(chalk.yellow(`Setup command not available for '${packageName}', continuing with installation...`));
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
catch (error) {
|
|
720
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
721
|
+
console.warn(chalk.yellow(`Warning: Could not verify that '${packageName}' is executable. It may not be properly installed or may not provide a CLI.`));
|
|
722
|
+
console.warn(chalk.yellow(`Error: ${errorMessage}`));
|
|
723
|
+
}
|
|
724
|
+
// Register the worker with the npm package name
|
|
462
725
|
const worker = await workerManager.register({
|
|
463
726
|
name: packageName, // Use the actual package name for npm resolution
|
|
464
727
|
description: packageInfo.description || `Worker from npm package ${packageName}`,
|
|
@@ -467,20 +730,40 @@ export function registerInstallCommand(workerCommand) {
|
|
|
467
730
|
env: [`WORKER_PORT=${port}`],
|
|
468
731
|
type: 'npm',
|
|
469
732
|
});
|
|
470
|
-
console.log(chalk.green(`Worker '${
|
|
733
|
+
console.log(chalk.green(`Worker '${packageName}' registered successfully!`));
|
|
471
734
|
// Start the worker
|
|
472
|
-
console.log(chalk.blue(`Starting worker '${
|
|
735
|
+
console.log(chalk.blue(`Starting worker '${packageName}'...`));
|
|
473
736
|
const success = await workerManager.start(worker.id);
|
|
474
737
|
if (success) {
|
|
475
|
-
console.log(chalk.green(`Worker '${
|
|
738
|
+
console.log(chalk.green(`Worker '${packageName}' started successfully!`));
|
|
476
739
|
console.log(chalk.cyan('Worker ID:'), chalk.bold(worker.id));
|
|
477
740
|
console.log(chalk.cyan('Endpoint:'), chalk.bold(worker.endpoint));
|
|
741
|
+
const duration = Date.now() - startTime;
|
|
742
|
+
trackCommandSuccess('worker-install', duration, {
|
|
743
|
+
workerId: worker.id,
|
|
744
|
+
workerName: worker.name,
|
|
745
|
+
packageName,
|
|
746
|
+
port,
|
|
747
|
+
setupCompleted,
|
|
748
|
+
startedSuccessfully: true,
|
|
749
|
+
});
|
|
478
750
|
}
|
|
479
751
|
else {
|
|
480
|
-
console.error(chalk.red(`Failed to start worker '${
|
|
752
|
+
console.error(chalk.red(`Failed to start worker '${packageName}'.`));
|
|
753
|
+
const duration = Date.now() - startTime;
|
|
754
|
+
trackCommandError('worker-install', new Error('Failed to start worker'), duration, {
|
|
755
|
+
workerId: worker.id,
|
|
756
|
+
packageName,
|
|
757
|
+
stage: 'worker-start',
|
|
758
|
+
});
|
|
481
759
|
}
|
|
482
760
|
}
|
|
483
761
|
catch (error) {
|
|
762
|
+
const duration = Date.now() - startTime;
|
|
763
|
+
trackCommandError('worker-install', error, duration, {
|
|
764
|
+
packageName,
|
|
765
|
+
options,
|
|
766
|
+
});
|
|
484
767
|
console.error(chalk.red('Failed to install worker:'), error);
|
|
485
768
|
}
|
|
486
769
|
});
|
|
@@ -497,22 +780,33 @@ export function registerInitCommand(workerCommand) {
|
|
|
497
780
|
.option('-p, --port <port>', 'Port number for the worker', '5555')
|
|
498
781
|
.option('-D, --description <description>', 'Description of the worker')
|
|
499
782
|
.action(async (options) => {
|
|
783
|
+
const startTime = Date.now();
|
|
500
784
|
try {
|
|
785
|
+
trackCommand('worker-init', {
|
|
786
|
+
hasCustomDir: options.dir !== '.',
|
|
787
|
+
hasName: !!options.name,
|
|
788
|
+
hasCustomPort: options.port !== '5555',
|
|
789
|
+
hasDescription: !!options.description,
|
|
790
|
+
});
|
|
501
791
|
// Prompt for missing options
|
|
502
792
|
const answers = await promptForMissingOptions(options);
|
|
503
793
|
const mergedOptions = { ...options, ...answers };
|
|
504
794
|
// Create the directory if it doesn't exist
|
|
505
795
|
const targetDir = path.resolve(mergedOptions.dir);
|
|
796
|
+
let directoryCreated = false;
|
|
506
797
|
if (!fs.existsSync(targetDir)) {
|
|
507
798
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
508
799
|
console.log(chalk.blue(`Created directory: ${targetDir}`));
|
|
800
|
+
directoryCreated = true;
|
|
509
801
|
}
|
|
510
802
|
// Generate the package.json content if it doesn't exist
|
|
511
803
|
const packageJsonPath = path.join(targetDir, 'package.json');
|
|
804
|
+
let packageJsonCreated = false;
|
|
512
805
|
if (!fs.existsSync(packageJsonPath)) {
|
|
513
806
|
const packageJsonContent = generatePackageJsonContent(mergedOptions);
|
|
514
807
|
fs.writeFileSync(packageJsonPath, packageJsonContent);
|
|
515
808
|
console.log(chalk.green(`Created package.json at: ${packageJsonPath}`));
|
|
809
|
+
packageJsonCreated = true;
|
|
516
810
|
}
|
|
517
811
|
// Generate the worker.config.js content
|
|
518
812
|
const workerConfigContent = generateWorkerConfigJsContent();
|
|
@@ -520,13 +814,16 @@ export function registerInitCommand(workerCommand) {
|
|
|
520
814
|
fs.writeFileSync(workerConfigPath, workerConfigContent);
|
|
521
815
|
// Create src directory if it doesn't exist
|
|
522
816
|
const srcDir = path.join(targetDir, 'src');
|
|
817
|
+
let srcDirCreated = false;
|
|
523
818
|
if (!fs.existsSync(srcDir)) {
|
|
524
819
|
fs.mkdirSync(srcDir, { recursive: true });
|
|
525
820
|
console.log(chalk.blue(`Created src directory: ${srcDir}`));
|
|
821
|
+
srcDirCreated = true;
|
|
526
822
|
}
|
|
527
823
|
// Copy CLI template file
|
|
528
824
|
const cliTemplatePath = path.join(__dirname, 'templates', 'cli.ts.template');
|
|
529
825
|
const cliDestPath = path.join(srcDir, 'cli.ts');
|
|
826
|
+
let cliFileCreated = false;
|
|
530
827
|
if (fs.existsSync(cliTemplatePath)) {
|
|
531
828
|
let cliContent = fs.readFileSync(cliTemplatePath, 'utf-8');
|
|
532
829
|
// Replace template variables
|
|
@@ -536,6 +833,7 @@ export function registerInitCommand(workerCommand) {
|
|
|
536
833
|
.replace(/{{version}}/g, '1.0.0');
|
|
537
834
|
fs.writeFileSync(cliDestPath, cliContent);
|
|
538
835
|
console.log(chalk.green(`Created CLI file at: ${cliDestPath}`));
|
|
836
|
+
cliFileCreated = true;
|
|
539
837
|
}
|
|
540
838
|
else {
|
|
541
839
|
console.warn(chalk.yellow(`CLI template not found at: ${cliTemplatePath}`));
|
|
@@ -543,6 +841,7 @@ export function registerInitCommand(workerCommand) {
|
|
|
543
841
|
// Copy index.ts template file
|
|
544
842
|
const indexTemplatePath = path.join(__dirname, 'templates', 'index.ts.template');
|
|
545
843
|
const indexDestPath = path.join(srcDir, 'index.ts');
|
|
844
|
+
let indexFileCreated = false;
|
|
546
845
|
if (!fs.existsSync(indexDestPath) && fs.existsSync(indexTemplatePath)) {
|
|
547
846
|
let indexContent = fs.readFileSync(indexTemplatePath, 'utf-8');
|
|
548
847
|
// Replace template variables
|
|
@@ -552,6 +851,7 @@ export function registerInitCommand(workerCommand) {
|
|
|
552
851
|
.replace(/{{port}}/g, mergedOptions.port);
|
|
553
852
|
fs.writeFileSync(indexDestPath, indexContent);
|
|
554
853
|
console.log(chalk.green(`Created index.ts file at: ${indexDestPath}`));
|
|
854
|
+
indexFileCreated = true;
|
|
555
855
|
}
|
|
556
856
|
else if (!fs.existsSync(indexTemplatePath)) {
|
|
557
857
|
console.warn(chalk.yellow(`Index template not found at: ${indexTemplatePath}`));
|
|
@@ -559,11 +859,13 @@ export function registerInitCommand(workerCommand) {
|
|
|
559
859
|
// Copy tsconfig.json template file
|
|
560
860
|
const tsconfigTemplatePath = path.join(__dirname, 'templates', 'tsconfig.json.template');
|
|
561
861
|
const tsconfigDestPath = path.join(targetDir, 'tsconfig.json');
|
|
862
|
+
let tsconfigFileCreated = false;
|
|
562
863
|
if (!fs.existsSync(tsconfigDestPath) &&
|
|
563
864
|
fs.existsSync(tsconfigTemplatePath)) {
|
|
564
865
|
const tsconfigContent = fs.readFileSync(tsconfigTemplatePath, 'utf-8');
|
|
565
866
|
fs.writeFileSync(tsconfigDestPath, tsconfigContent);
|
|
566
867
|
console.log(chalk.green(`Created tsconfig.json file at: ${tsconfigDestPath}`));
|
|
868
|
+
tsconfigFileCreated = true;
|
|
567
869
|
}
|
|
568
870
|
else if (!fs.existsSync(tsconfigTemplatePath)) {
|
|
569
871
|
console.warn(chalk.yellow(`tsconfig.json template not found at: ${tsconfigTemplatePath}`));
|
|
@@ -571,8 +873,32 @@ export function registerInitCommand(workerCommand) {
|
|
|
571
873
|
console.log(chalk.green(`Worker configuration file created at: ${workerConfigPath}`));
|
|
572
874
|
console.log(chalk.blue(`\nYou can now register this worker with:`));
|
|
573
875
|
console.log(chalk.cyan(` tonk worker register ${targetDir}`));
|
|
876
|
+
const duration = Date.now() - startTime;
|
|
877
|
+
trackCommandSuccess('worker-init', duration, {
|
|
878
|
+
workerName: mergedOptions.name,
|
|
879
|
+
targetDir,
|
|
880
|
+
port: mergedOptions.port,
|
|
881
|
+
directoryCreated,
|
|
882
|
+
packageJsonCreated,
|
|
883
|
+
srcDirCreated,
|
|
884
|
+
cliFileCreated,
|
|
885
|
+
indexFileCreated,
|
|
886
|
+
tsconfigFileCreated,
|
|
887
|
+
filesCreated: [
|
|
888
|
+
packageJsonCreated && 'package.json',
|
|
889
|
+
'worker.config.js',
|
|
890
|
+
srcDirCreated && 'src/',
|
|
891
|
+
cliFileCreated && 'cli.ts',
|
|
892
|
+
indexFileCreated && 'index.ts',
|
|
893
|
+
tsconfigFileCreated && 'tsconfig.json',
|
|
894
|
+
].filter(Boolean).length,
|
|
895
|
+
});
|
|
574
896
|
}
|
|
575
897
|
catch (error) {
|
|
898
|
+
const duration = Date.now() - startTime;
|
|
899
|
+
trackCommandError('worker-init', error, duration, {
|
|
900
|
+
options,
|
|
901
|
+
});
|
|
576
902
|
console.error(chalk.red('Failed to initialise worker configuration:'), error);
|
|
577
903
|
}
|
|
578
904
|
});
|