genbox 1.0.106 → 1.0.108
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/init.js +17 -22
- package/dist/commands/list.js +6 -0
- package/dist/commands/status.js +42 -47
- package/package.json +1 -1
package/dist/commands/init.js
CHANGED
|
@@ -1164,35 +1164,30 @@ async function setupProfiles(detected, environments) {
|
|
|
1164
1164
|
}
|
|
1165
1165
|
// Start with default profiles
|
|
1166
1166
|
let profiles = { ...defaultProfiles };
|
|
1167
|
-
// If there are
|
|
1168
|
-
if (Object.keys(
|
|
1169
|
-
console.log(chalk_1.default.dim('Found
|
|
1167
|
+
// If there are user-created profiles, offer to retain them
|
|
1168
|
+
if (Object.keys(userCreatedProfiles).length > 0) {
|
|
1169
|
+
console.log(chalk_1.default.dim('Found user-created profiles in genbox.yaml:'));
|
|
1170
1170
|
console.log('');
|
|
1171
|
-
// Display
|
|
1172
|
-
for (const [name, profile] of Object.entries(
|
|
1173
|
-
|
|
1174
|
-
const label = isUserCreated ? chalk_1.default.yellow(' (user-created)') : chalk_1.default.dim(' (auto-generated)');
|
|
1175
|
-
console.log(` ${chalk_1.default.cyan(name)}${label}`);
|
|
1171
|
+
// Display user-created profiles
|
|
1172
|
+
for (const [name, profile] of Object.entries(userCreatedProfiles)) {
|
|
1173
|
+
console.log(` ${chalk_1.default.cyan(name)}`);
|
|
1176
1174
|
console.log(chalk_1.default.dim(` ${profile.description || 'No description'}`));
|
|
1177
1175
|
console.log(chalk_1.default.dim(` Apps: ${profile.apps?.join(', ') || 'all'}`));
|
|
1178
1176
|
console.log('');
|
|
1179
1177
|
}
|
|
1180
|
-
// Let user select which
|
|
1181
|
-
const retainChoices = Object.entries(
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
checked: isUserCreated, // User-created profiles are checked by default
|
|
1187
|
-
};
|
|
1188
|
-
});
|
|
1178
|
+
// Let user select which user-created profiles to retain
|
|
1179
|
+
const retainChoices = Object.entries(userCreatedProfiles).map(([name, profile]) => ({
|
|
1180
|
+
name: `${name} - ${profile.description || 'No description'}`,
|
|
1181
|
+
value: name,
|
|
1182
|
+
checked: true, // All user-created profiles are checked by default
|
|
1183
|
+
}));
|
|
1189
1184
|
const retainedNames = await prompts.checkbox({
|
|
1190
|
-
message: 'Select
|
|
1185
|
+
message: 'Select user-created profiles to retain:',
|
|
1191
1186
|
choices: retainChoices,
|
|
1192
1187
|
});
|
|
1193
|
-
// Add retained profiles
|
|
1188
|
+
// Add retained user-created profiles
|
|
1194
1189
|
for (const name of retainedNames) {
|
|
1195
|
-
profiles[name] =
|
|
1190
|
+
profiles[name] = userCreatedProfiles[name];
|
|
1196
1191
|
}
|
|
1197
1192
|
}
|
|
1198
1193
|
if (Object.keys(profiles).length === 0) {
|
|
@@ -1204,8 +1199,8 @@ async function setupProfiles(detected, environments) {
|
|
|
1204
1199
|
console.log(chalk_1.default.dim('Final profiles:'));
|
|
1205
1200
|
console.log('');
|
|
1206
1201
|
for (const [name, profile] of Object.entries(profiles)) {
|
|
1207
|
-
const
|
|
1208
|
-
const label =
|
|
1202
|
+
const isUserCreated = userCreatedProfiles[name] !== undefined;
|
|
1203
|
+
const label = isUserCreated ? chalk_1.default.yellow(' (user-created)') : '';
|
|
1209
1204
|
console.log(` ${chalk_1.default.cyan(name)}${label}`);
|
|
1210
1205
|
console.log(chalk_1.default.dim(` ${profile.description || 'No description'}`));
|
|
1211
1206
|
console.log(chalk_1.default.dim(` Apps: ${profile.apps?.join(', ') || 'all'}`));
|
package/dist/commands/list.js
CHANGED
|
@@ -49,6 +49,12 @@ exports.listCommand = new commander_1.Command('list')
|
|
|
49
49
|
}
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
|
+
// Sort by createdAt (newest first)
|
|
53
|
+
genboxes.sort((a, b) => {
|
|
54
|
+
const dateA = a.createdAt ? new Date(a.createdAt).getTime() : 0;
|
|
55
|
+
const dateB = b.createdAt ? new Date(b.createdAt).getTime() : 0;
|
|
56
|
+
return dateB - dateA;
|
|
57
|
+
});
|
|
52
58
|
// Calculate column widths
|
|
53
59
|
const nameWidth = Math.max(12, ...genboxes.map(g => g.name.length + (options.all && g.project ? g.project.length + 3 : 0)));
|
|
54
60
|
const statusWidth = 12;
|
package/dist/commands/status.js
CHANGED
|
@@ -398,80 +398,75 @@ exports.statusCommand = new commander_1.Command('status')
|
|
|
398
398
|
console.log(chalk_1.default.dim(` (updated ${statsAge < 60 ? 'just now' : Math.floor(statsAge / 60) + 'm ago'})`));
|
|
399
399
|
console.log('');
|
|
400
400
|
}
|
|
401
|
-
// Show Docker containers status
|
|
402
|
-
const
|
|
403
|
-
const hasDockerServices =
|
|
401
|
+
// Show Docker containers status from DB (updated by heartbeat)
|
|
402
|
+
const dockerServices = systemStats?.dockerServices || [];
|
|
403
|
+
const hasDockerServices = dockerServices.length > 0;
|
|
404
404
|
if (hasDockerServices) {
|
|
405
405
|
console.log(chalk_1.default.blue('[INFO] === Docker Services ==='));
|
|
406
|
-
console.log('
|
|
407
|
-
|
|
406
|
+
console.log('NAME\t\t\tSTATUS');
|
|
407
|
+
for (const svc of dockerServices) {
|
|
408
|
+
const healthBadge = svc.health
|
|
409
|
+
? (svc.health === 'healthy' ? chalk_1.default.green(' ✓') : chalk_1.default.red(` (${svc.health})`))
|
|
410
|
+
: '';
|
|
411
|
+
console.log(`${svc.name}\t${svc.status}${healthBadge}`);
|
|
412
|
+
}
|
|
408
413
|
console.log('');
|
|
409
414
|
}
|
|
410
|
-
// Show PM2 processes
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
const hasPm2Apps = pm2Status && pm2Status.trim() &&
|
|
414
|
-
!pm2Status.includes('No process') &&
|
|
415
|
-
(pm2Status.includes('online') || pm2Status.includes('stopped') ||
|
|
416
|
-
pm2Status.includes('errored') || pm2Status.includes('launching'));
|
|
415
|
+
// Show PM2 processes from DB (updated by heartbeat)
|
|
416
|
+
const pm2Services = systemStats?.pm2Services || [];
|
|
417
|
+
const hasPm2Apps = pm2Services.length > 0;
|
|
417
418
|
if (hasPm2Apps) {
|
|
418
419
|
console.log(chalk_1.default.blue('[INFO] === PM2 Services ==='));
|
|
419
|
-
console.log(
|
|
420
|
+
console.log('NAME\t\tSTATUS\t\tCPU\tMEM');
|
|
421
|
+
for (const app of pm2Services) {
|
|
422
|
+
const statusColor = app.status === 'online' ? chalk_1.default.green :
|
|
423
|
+
app.status === 'stopped' ? chalk_1.default.yellow : chalk_1.default.red;
|
|
424
|
+
console.log(`${app.name}\t\t${statusColor(app.status)}\t\t${app.cpu || 0}%\t${app.memory || 0}MB`);
|
|
425
|
+
}
|
|
420
426
|
console.log('');
|
|
421
427
|
}
|
|
422
|
-
// Warn if no services are running and
|
|
428
|
+
// Warn if no services are running and show setup errors from DB (no SSH needed)
|
|
423
429
|
if (!hasDockerServices && !hasPm2Apps) {
|
|
424
430
|
console.log(chalk_1.default.yellow('[WARN] No Docker or PM2 services are running!'));
|
|
425
|
-
//
|
|
426
|
-
const
|
|
427
|
-
if (
|
|
428
|
-
// Found
|
|
431
|
+
// Check for setup errors stored in DB (sent by setup callback)
|
|
432
|
+
const setupErrors = target.setupErrors;
|
|
433
|
+
if (setupErrors && setupErrors.trim()) {
|
|
434
|
+
// Found errors from setup - display them
|
|
429
435
|
console.log(chalk_1.default.red('[ERROR] Build failed during setup:'));
|
|
430
|
-
console.log(
|
|
436
|
+
console.log(setupErrors);
|
|
431
437
|
console.log('');
|
|
432
438
|
console.log(chalk_1.default.dim(' Fix the error and run: cd ~/goodpass/api && docker compose up -d'));
|
|
433
439
|
}
|
|
434
440
|
else {
|
|
435
|
-
// No
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
441
|
+
// No errors in DB - try SSH fallback for older genboxes
|
|
442
|
+
// First check ~/.genbox-errors file (fast)
|
|
443
|
+
const savedErrors = sshExec(target.ipAddress, keyPath, 'cat ~/.genbox-errors 2>/dev/null || echo ""', 10);
|
|
444
|
+
if (savedErrors && savedErrors.trim()) {
|
|
445
|
+
console.log(chalk_1.default.red('[ERROR] Build failed during setup:'));
|
|
446
|
+
console.log(savedErrors);
|
|
447
|
+
console.log('');
|
|
448
|
+
console.log(chalk_1.default.dim(' Fix the error and run: cd ~/goodpass/api && docker compose up -d'));
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
// No saved errors - check if there's a docker compose error
|
|
452
|
+
console.log(chalk_1.default.dim(' Checking for build errors...'));
|
|
453
|
+
const buildResult = sshExec(target.ipAddress, keyPath, 'cd ~/goodpass/api 2>/dev/null && docker compose build 2>&1 | tail -60 || echo ""', 120);
|
|
454
|
+
if (buildResult && (buildResult.includes('ERROR') || buildResult.includes('TS2') ||
|
|
455
|
+
buildResult.includes('failed') || buildResult.includes('ELIFECYCLE'))) {
|
|
444
456
|
console.log(chalk_1.default.red('[ERROR] Docker build failed:'));
|
|
445
|
-
// Extract just the error portion
|
|
446
457
|
const lines = buildResult.split('\n');
|
|
447
458
|
const errorLines = lines.filter(line => line.includes('ERROR') || line.includes('TS2') || line.includes('TS1') ||
|
|
448
459
|
line.includes('failed') || line.includes('exit code') ||
|
|
449
460
|
line.includes('>') || line.includes('^') ||
|
|
450
|
-
line.match(/^\s*\d+\s*\|/)
|
|
451
|
-
).slice(-
|
|
452
|
-
if (errorLines.length > 0) {
|
|
453
|
-
console.log(errorLines.join('\n'));
|
|
454
|
-
}
|
|
455
|
-
else {
|
|
456
|
-
// Show last 25 lines if no specific error pattern found
|
|
457
|
-
console.log(lines.slice(-25).join('\n'));
|
|
458
|
-
}
|
|
461
|
+
line.match(/^\s*\d+\s*\|/)).slice(-20);
|
|
462
|
+
console.log(errorLines.length > 0 ? errorLines.join('\n') : lines.slice(-25).join('\n'));
|
|
459
463
|
console.log('');
|
|
460
464
|
console.log(chalk_1.default.dim(' Fix the error and run: cd ~/goodpass/api && docker compose up -d'));
|
|
461
465
|
}
|
|
462
|
-
else if (buildResult.includes('Built') || buildResult.includes('FINISHED')) {
|
|
463
|
-
// Build succeeded, services just need to start
|
|
464
|
-
console.log(chalk_1.default.dim(' Build OK. Start services with: cd ~/goodpass/api && docker compose up -d'));
|
|
465
|
-
}
|
|
466
466
|
else {
|
|
467
|
-
console.log(chalk_1.default.dim(buildResult));
|
|
468
|
-
console.log('');
|
|
469
467
|
console.log(chalk_1.default.dim(' Try: cd ~/goodpass/api && docker compose up -d'));
|
|
470
468
|
}
|
|
471
469
|
}
|
|
472
|
-
else {
|
|
473
|
-
console.log(chalk_1.default.dim(' Try: cd ~/goodpass/api && docker compose up -d'));
|
|
474
|
-
}
|
|
475
470
|
}
|
|
476
471
|
console.log('');
|
|
477
472
|
}
|