genbox 1.0.34 → 1.0.35

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.
@@ -187,56 +187,124 @@ exports.statusCommand = new commander_1.Command('status')
187
187
  console.error(chalk_1.default.red(error.message));
188
188
  return;
189
189
  }
190
- console.log(chalk_1.default.blue(`[INFO] Checking cloud-init progress on ${selectedName}...`));
190
+ console.log(chalk_1.default.blue(`[INFO] Checking status of ${selectedName}...`));
191
191
  console.log('');
192
- // 3. Check cloud-init status
193
- const status = sshExec(target.ipAddress, keyPath, 'cloud-init status 2>&1');
194
- if (!status) {
195
- console.log(chalk_1.default.yellow('[WARN] Unable to connect to server. It may still be booting.'));
196
- return;
197
- }
198
- // Check for SSH connection errors (timeout, refused, etc.)
199
- const sshErrors = [
200
- 'Operation timed out',
201
- 'Connection refused',
202
- 'Connection timed out',
203
- 'No route to host',
204
- 'Network is unreachable',
205
- 'ssh: connect to host',
206
- ];
207
- if (sshErrors.some(err => status.includes(err))) {
208
- console.log(chalk_1.default.yellow('[INFO] Server is still initializing - SSH is not yet available.'));
209
- console.log(chalk_1.default.dim(' This is normal for newly created servers.'));
210
- console.log(chalk_1.default.dim(' Please wait 1-2 minutes and try again.'));
192
+ // 3. Check status from DB first (more reliable than SSH)
193
+ const dbStatus = target.status; // 'provisioning' | 'running' | 'error' etc.
194
+ const setupDuration = target.setupDuration;
195
+ const setupCompletedAt = target.setupCompletedAt;
196
+ // If DB says RUNNING and we have setupCompletedAt, setup is complete
197
+ if (dbStatus === 'running' && setupCompletedAt) {
198
+ const durationStr = setupDuration ? formatDuration(setupDuration) : 'unknown';
199
+ console.log(chalk_1.default.green(`[SUCCESS] Setup completed! (took ${durationStr})`));
200
+ console.log('');
201
+ // Show Docker containers status
202
+ const dockerStatus = sshExec(target.ipAddress, keyPath, 'docker ps --format "{{.Names}}\\t{{.Status}}" 2>/dev/null', 10);
203
+ if (dockerStatus && dockerStatus.trim()) {
204
+ console.log(chalk_1.default.blue('[INFO] === Docker Services ==='));
205
+ console.log('NAMES\tSTATUS');
206
+ console.log(dockerStatus);
207
+ console.log('');
208
+ }
209
+ // Show PM2 processes
210
+ const pm2Status = sshExec(target.ipAddress, keyPath, 'source ~/.nvm/nvm.sh 2>/dev/null; pm2 list 2>/dev/null || echo ""', 10);
211
+ if (pm2Status && pm2Status.trim() && !pm2Status.includes('No process')) {
212
+ console.log(chalk_1.default.blue('[INFO] === PM2 Services ==='));
213
+ console.log(pm2Status);
214
+ console.log('');
215
+ }
216
+ // Show URLs if available
217
+ if (target.urls && Object.keys(target.urls).length > 0) {
218
+ console.log(chalk_1.default.blue('[INFO] === Service URLs ==='));
219
+ for (const [service, url] of Object.entries(target.urls)) {
220
+ console.log(` ${service}: ${chalk_1.default.cyan(url)}`);
221
+ }
222
+ }
211
223
  return;
212
224
  }
213
- if (status.includes('running')) {
214
- // Get timing breakdown
215
- const timing = getTimingBreakdown(target.ipAddress, keyPath);
216
- if (timing.total !== null) {
217
- console.log(chalk_1.default.yellow(`[WARN] Cloud-init is still running... (elapsed: ${formatDuration(timing.total)})`));
225
+ // If DB says PROVISIONING, check if we can SSH to get progress
226
+ if (dbStatus === 'provisioning') {
227
+ // Try to SSH and check cloud-init progress
228
+ let status = sshExec(target.ipAddress, keyPath, 'cloud-init status 2>&1');
229
+ if (!status) {
230
+ console.log(chalk_1.default.yellow('[WARN] Unable to connect to server. It may still be booting.'));
231
+ return;
218
232
  }
219
- else {
220
- console.log(chalk_1.default.yellow('[WARN] Cloud-init is still running...'));
233
+ // Check for SSH connection errors (timeout, refused, etc.)
234
+ const sshErrors = [
235
+ 'Operation timed out',
236
+ 'Connection refused',
237
+ 'Connection timed out',
238
+ 'No route to host',
239
+ 'Network is unreachable',
240
+ 'ssh: connect to host',
241
+ ];
242
+ if (sshErrors.some(err => status.includes(err))) {
243
+ console.log(chalk_1.default.yellow('[INFO] Server is still initializing - SSH is not yet available.'));
244
+ console.log(chalk_1.default.dim(' This is normal for newly created servers.'));
245
+ console.log(chalk_1.default.dim(' Please wait 1-2 minutes and try again.'));
246
+ return;
221
247
  }
222
- console.log('');
223
- // Show timing breakdown so far
224
- if (timing.sshReady !== null) {
225
- console.log(chalk_1.default.blue('[INFO] === Timing So Far ==='));
226
- console.log(` SSH Ready: ${formatDuration(timing.sshReady)}`);
248
+ // Cloud-init still running
249
+ if (status.includes('running')) {
250
+ // Get timing breakdown
251
+ const timing = getTimingBreakdown(target.ipAddress, keyPath);
227
252
  if (timing.total !== null) {
228
- console.log(` Elapsed: ${formatDuration(timing.total)}`);
253
+ console.log(chalk_1.default.yellow(`[INFO] Setup in progress... (elapsed: ${formatDuration(timing.total)})`));
254
+ }
255
+ else {
256
+ console.log(chalk_1.default.yellow('[INFO] Setup in progress...'));
229
257
  }
230
258
  console.log('');
259
+ // Show timing breakdown so far
260
+ if (timing.sshReady !== null) {
261
+ console.log(chalk_1.default.blue('[INFO] === Timing So Far ==='));
262
+ console.log(` SSH Ready: ${formatDuration(timing.sshReady)}`);
263
+ if (timing.total !== null) {
264
+ console.log(` Elapsed: ${formatDuration(timing.total)}`);
265
+ }
266
+ console.log('');
267
+ }
268
+ console.log(chalk_1.default.blue('[INFO] Latest setup progress:'));
269
+ // Tail cloud-init output log for progress
270
+ const logOutput = sshExec(target.ipAddress, keyPath, "sudo tail -30 /var/log/cloud-init-output.log 2>/dev/null | grep -E '^===|^#|Progress:|DONE|error|Error|failed|Failed' || sudo tail -20 /var/log/cloud-init-output.log", 15);
271
+ if (logOutput) {
272
+ console.log(logOutput);
273
+ }
274
+ return;
275
+ }
276
+ // Cloud-init done but callback might not have been received yet
277
+ if (status.includes('done')) {
278
+ console.log(chalk_1.default.green('[SUCCESS] Setup completed!'));
279
+ console.log(chalk_1.default.dim(' (Waiting for status update...)'));
280
+ return;
281
+ }
282
+ // Cloud-init not found (already cleaned up) - show generic status
283
+ if (status.includes('not found') || status.includes('command not found')) {
284
+ console.log(chalk_1.default.yellow('[INFO] Setup is finalizing...'));
285
+ return;
231
286
  }
232
- console.log(chalk_1.default.blue('[INFO] Latest setup progress:'));
233
- // Tail cloud-init output log for progress
234
- const logOutput = sshExec(target.ipAddress, keyPath, "sudo tail -30 /var/log/cloud-init-output.log 2>/dev/null | grep -E '^===|^#|Progress:|DONE|error|Error|failed|Failed' || sudo tail -20 /var/log/cloud-init-output.log", 15);
235
- if (logOutput) {
236
- console.log(logOutput);
287
+ // Other status
288
+ console.log(chalk_1.default.yellow(`[INFO] Status: ${status}`));
289
+ return;
290
+ }
291
+ // If DB says ERROR
292
+ if (dbStatus === 'error') {
293
+ console.log(chalk_1.default.red('[ERROR] Setup failed!'));
294
+ console.log(chalk_1.default.dim(' Run `genbox connect` to investigate.'));
295
+ return;
296
+ }
297
+ // Fallback: try legacy cloud-init check for backwards compatibility
298
+ let status = sshExec(target.ipAddress, keyPath, 'cloud-init status 2>&1');
299
+ if (!status || status.includes('not found')) {
300
+ // No cloud-init, check our status file
301
+ const genboxStatus = sshExec(target.ipAddress, keyPath, 'cat ~/.genbox-status 2>/dev/null');
302
+ if (genboxStatus && genboxStatus.includes('Setup Complete')) {
303
+ console.log(chalk_1.default.green('[SUCCESS] Setup completed!'));
304
+ return;
237
305
  }
238
306
  }
239
- else if (status.includes('done')) {
307
+ if (status && status.includes('done')) {
240
308
  // Get timing breakdown
241
309
  const timing = getTimingBreakdown(target.ipAddress, keyPath);
242
310
  console.log(chalk_1.default.green(`[SUCCESS] Cloud-init completed!${timing.total !== null ? ` (${formatDuration(timing.total)})` : ''}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genbox",
3
- "version": "1.0.34",
3
+ "version": "1.0.35",
4
4
  "description": "Genbox CLI - AI-Powered Development Environments",
5
5
  "main": "dist/index.js",
6
6
  "bin": {