spindb 0.7.3 → 0.7.5

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.
@@ -15,18 +15,11 @@ import { createSpinner } from '../ui/spinner'
15
15
  import { success, error, warning, formatBytes } from '../ui/theme'
16
16
  import { getMissingDependencies } from '../../core/dependency-manager'
17
17
 
18
- /**
19
- * Generate a timestamp string for backup filenames
20
- * Format: YYYY-MM-DDTHHMMSS (ISO 8601 without colons for filesystem compatibility)
21
- */
22
18
  function generateTimestamp(): string {
23
19
  const now = new Date()
24
20
  return now.toISOString().replace(/:/g, '').split('.')[0]
25
21
  }
26
22
 
27
- /**
28
- * Generate default backup filename
29
- */
30
23
  function generateDefaultFilename(
31
24
  containerName: string,
32
25
  database: string,
@@ -35,9 +28,6 @@ function generateDefaultFilename(
35
28
  return `${containerName}-${database}-backup-${timestamp}`
36
29
  }
37
30
 
38
- /**
39
- * Get file extension for backup format
40
- */
41
31
  function getExtension(format: 'sql' | 'dump', engine: string): string {
42
32
  if (format === 'sql') {
43
33
  return '.sql'
@@ -73,7 +63,6 @@ export const backupCommand = new Command('backup')
73
63
  try {
74
64
  let containerName = containerArg
75
65
 
76
- // Interactive selection if no container provided
77
66
  if (!containerName) {
78
67
  const containers = await containerManager.list()
79
68
  const running = containers.filter((c) => c.status === 'running')
@@ -101,7 +90,6 @@ export const backupCommand = new Command('backup')
101
90
  containerName = selected
102
91
  }
103
92
 
104
- // Get container config
105
93
  const config = await containerManager.getConfig(containerName)
106
94
  if (!config) {
107
95
  console.error(error(`Container "${containerName}" not found`))
@@ -110,7 +98,6 @@ export const backupCommand = new Command('backup')
110
98
 
111
99
  const { engine: engineName } = config
112
100
 
113
- // Check if running
114
101
  const running = await processManager.isRunning(containerName, {
115
102
  engine: engineName,
116
103
  })
@@ -123,10 +110,8 @@ export const backupCommand = new Command('backup')
123
110
  process.exit(1)
124
111
  }
125
112
 
126
- // Get engine
127
113
  const engine = getEngine(engineName)
128
114
 
129
- // Check for required client tools
130
115
  const depsSpinner = createSpinner('Checking required tools...')
131
116
  depsSpinner.start()
132
117
 
@@ -136,7 +121,6 @@ export const backupCommand = new Command('backup')
136
121
  `Missing tools: ${missingDeps.map((d) => d.name).join(', ')}`,
137
122
  )
138
123
 
139
- // Offer to install
140
124
  const installed = await promptInstallDependencies(
141
125
  missingDeps[0].binary,
142
126
  config.engine,
@@ -146,7 +130,6 @@ export const backupCommand = new Command('backup')
146
130
  process.exit(1)
147
131
  }
148
132
 
149
- // Verify installation worked
150
133
  missingDeps = await getMissingDependencies(config.engine)
151
134
  if (missingDeps.length > 0) {
152
135
  console.error(
@@ -163,27 +146,22 @@ export const backupCommand = new Command('backup')
163
146
  depsSpinner.succeed('Required tools available')
164
147
  }
165
148
 
166
- // Determine which database to backup
167
149
  let databaseName = options.database
168
150
 
169
151
  if (!databaseName) {
170
- // Get list of databases in container
171
152
  const databases = config.databases || [config.database]
172
153
 
173
154
  if (databases.length > 1) {
174
- // Interactive mode: prompt for database selection
175
155
  databaseName = await promptDatabaseSelect(
176
156
  databases,
177
157
  'Select database to backup:',
178
158
  )
179
159
  } else {
180
- // Single database: use it
181
160
  databaseName = databases[0]
182
161
  }
183
162
  }
184
163
 
185
- // Determine format
186
- let format: 'sql' | 'dump' = 'sql' // Default to SQL
164
+ let format: 'sql' | 'dump' = 'sql'
187
165
 
188
166
  if (options.sql) {
189
167
  format = 'sql'
@@ -196,28 +174,23 @@ export const backupCommand = new Command('backup')
196
174
  }
197
175
  format = options.format as 'sql' | 'dump'
198
176
  } else if (!containerArg) {
199
- // Interactive mode: prompt for format
200
177
  format = await promptBackupFormat(engineName)
201
178
  }
202
179
 
203
- // Determine filename
204
180
  const defaultFilename = generateDefaultFilename(
205
181
  containerName,
206
182
  databaseName,
207
183
  )
208
184
  let filename = options.name || defaultFilename
209
185
 
210
- // In interactive mode with no name provided, optionally prompt for custom name
211
186
  if (!containerArg && !options.name) {
212
187
  filename = await promptBackupFilename(defaultFilename)
213
188
  }
214
189
 
215
- // Build full output path
216
190
  const extension = getExtension(format, engineName)
217
191
  const outputDir = options.output || process.cwd()
218
192
  const outputPath = join(outputDir, `${filename}${extension}`)
219
193
 
220
- // Create backup
221
194
  const backupSpinner = createSpinner(
222
195
  `Creating ${format === 'sql' ? 'SQL' : 'dump'} backup of "${databaseName}"...`,
223
196
  )
@@ -230,7 +203,6 @@ export const backupCommand = new Command('backup')
230
203
 
231
204
  backupSpinner.succeed('Backup created successfully')
232
205
 
233
- // Show result
234
206
  console.log()
235
207
  console.log(success('Backup complete'))
236
208
  console.log()
@@ -244,7 +216,6 @@ export const backupCommand = new Command('backup')
244
216
  } catch (err) {
245
217
  const e = err as Error
246
218
 
247
- // Check if this is a missing tool error
248
219
  const missingToolPatterns = ['pg_dump not found', 'mysqldump not found']
249
220
 
250
221
  const matchingPattern = missingToolPatterns.find((p) =>
@@ -16,7 +16,6 @@ export const cloneCommand = new Command('clone')
16
16
  let sourceName = source
17
17
  let targetName = target
18
18
 
19
- // Interactive selection if no source provided
20
19
  if (!sourceName) {
21
20
  const containers = await containerManager.list()
22
21
  const stopped = containers.filter((c) => c.status !== 'running')
@@ -50,14 +49,12 @@ export const cloneCommand = new Command('clone')
50
49
  sourceName = selected
51
50
  }
52
51
 
53
- // Check source exists
54
52
  const sourceConfig = await containerManager.getConfig(sourceName)
55
53
  if (!sourceConfig) {
56
54
  console.error(error(`Container "${sourceName}" not found`))
57
55
  process.exit(1)
58
56
  }
59
57
 
60
- // Check source is stopped
61
58
  const running = await processManager.isRunning(sourceName, {
62
59
  engine: sourceConfig.engine,
63
60
  })
@@ -70,12 +67,10 @@ export const cloneCommand = new Command('clone')
70
67
  process.exit(1)
71
68
  }
72
69
 
73
- // Get target name
74
70
  if (!targetName) {
75
71
  targetName = await promptContainerName(`${sourceName}-copy`)
76
72
  }
77
73
 
78
- // Clone the container
79
74
  const cloneSpinner = createSpinner(
80
75
  `Cloning ${sourceName} to ${targetName}...`,
81
76
  )
@@ -85,7 +80,6 @@ export const cloneCommand = new Command('clone')
85
80
 
86
81
  cloneSpinner.succeed(`Cloned "${sourceName}" to "${targetName}"`)
87
82
 
88
- // Get engine for connection string
89
83
  const engine = getEngine(newConfig.engine)
90
84
  const connectionString = engine.getConnectionString(newConfig)
91
85
 
@@ -53,7 +53,6 @@ export const connectCommand = new Command('connect')
53
53
  try {
54
54
  let containerName = name
55
55
 
56
- // Interactive selection if no name provided
57
56
  if (!containerName) {
58
57
  const containers = await containerManager.list()
59
58
  const running = containers.filter((c) => c.status === 'running')
@@ -81,7 +80,6 @@ export const connectCommand = new Command('connect')
81
80
  containerName = selected
82
81
  }
83
82
 
84
- // Get container config
85
83
  const config = await containerManager.getConfig(containerName)
86
84
  if (!config) {
87
85
  console.error(error(`Container "${containerName}" not found`))
@@ -91,11 +89,9 @@ export const connectCommand = new Command('connect')
91
89
  const { engine: engineName } = config
92
90
  const engineDefaults = getEngineDefaults(engineName)
93
91
 
94
- // Default database: container's database or superuser
95
92
  const database =
96
93
  options.database ?? config.database ?? engineDefaults.superuser
97
94
 
98
- // Check if running
99
95
  const running = await processManager.isRunning(containerName, {
100
96
  engine: engineName,
101
97
  })
@@ -108,18 +104,15 @@ export const connectCommand = new Command('connect')
108
104
  process.exit(1)
109
105
  }
110
106
 
111
- // Get engine
112
107
  const engine = getEngine(engineName)
113
108
  const connectionString = engine.getConnectionString(config, database)
114
109
 
115
- // Handle --tui and --install-tui flags (usql)
116
110
  const useUsql = options.tui || options.installTui
117
111
  if (useUsql) {
118
112
  const usqlInstalled = await isUsqlInstalled()
119
113
 
120
114
  if (!usqlInstalled) {
121
115
  if (options.installTui) {
122
- // Try to install usql
123
116
  console.log(
124
117
  info('Installing usql for enhanced shell experience...'),
125
118
  )
@@ -150,7 +143,6 @@ export const connectCommand = new Command('connect')
150
143
  process.exit(1)
151
144
  }
152
145
  } else {
153
- // --tui flag but usql not installed
154
146
  console.error(error('usql is not installed'))
155
147
  console.log()
156
148
  console.log(
@@ -167,7 +159,6 @@ export const connectCommand = new Command('connect')
167
159
  }
168
160
  }
169
161
 
170
- // Handle --pgcli and --install-pgcli flags
171
162
  const usePgcli = options.pgcli || options.installPgcli
172
163
  if (usePgcli) {
173
164
  if (engineName !== 'postgresql') {
@@ -228,7 +219,6 @@ export const connectCommand = new Command('connect')
228
219
  }
229
220
  }
230
221
 
231
- // Handle --mycli and --install-mycli flags
232
222
  const useMycli = options.mycli || options.installMycli
233
223
  if (useMycli) {
234
224
  if (engineName !== 'mysql') {
@@ -288,16 +278,13 @@ export const connectCommand = new Command('connect')
288
278
  console.log(info(`Connecting to ${containerName}:${database}...`))
289
279
  console.log()
290
280
 
291
- // Build client command based on engine and shell preference
292
281
  let clientCmd: string
293
282
  let clientArgs: string[]
294
283
 
295
284
  if (usePgcli) {
296
- // pgcli accepts connection strings
297
285
  clientCmd = 'pgcli'
298
286
  clientArgs = [connectionString]
299
287
  } else if (useMycli) {
300
- // mycli: mycli -h host -P port -u user database
301
288
  clientCmd = 'mycli'
302
289
  clientArgs = [
303
290
  '-h',
@@ -309,11 +296,9 @@ export const connectCommand = new Command('connect')
309
296
  database,
310
297
  ]
311
298
  } else if (useUsql) {
312
- // usql accepts connection strings directly for both PostgreSQL and MySQL
313
299
  clientCmd = 'usql'
314
300
  clientArgs = [connectionString]
315
301
  } else if (engineName === 'mysql') {
316
- // MySQL: mysql -h 127.0.0.1 -P port -u root database
317
302
  clientCmd = 'mysql'
318
303
  clientArgs = [
319
304
  '-h',
@@ -325,7 +310,6 @@ export const connectCommand = new Command('connect')
325
310
  database,
326
311
  ]
327
312
  } else {
328
- // PostgreSQL: psql connection_string
329
313
  clientCmd = 'psql'
330
314
  clientArgs = [connectionString]
331
315
  }
@@ -22,15 +22,10 @@ import { startWithRetry } from '../../core/start-with-retry'
22
22
  import { TransactionManager } from '../../core/transaction-manager'
23
23
  import { Engine } from '../../types'
24
24
 
25
- /**
26
- * Detect if a location string is a connection string or a file path
27
- * Also infers engine from connection string scheme
28
- */
29
25
  function detectLocationType(location: string): {
30
26
  type: 'connection' | 'file' | 'not_found'
31
27
  inferredEngine?: Engine
32
28
  } {
33
- // Check for PostgreSQL connection string
34
29
  if (
35
30
  location.startsWith('postgresql://') ||
36
31
  location.startsWith('postgres://')
@@ -38,12 +33,10 @@ function detectLocationType(location: string): {
38
33
  return { type: 'connection', inferredEngine: Engine.PostgreSQL }
39
34
  }
40
35
 
41
- // Check for MySQL connection string
42
36
  if (location.startsWith('mysql://')) {
43
37
  return { type: 'connection', inferredEngine: Engine.MySQL }
44
38
  }
45
39
 
46
- // Check if file exists
47
40
  if (existsSync(location)) {
48
41
  return { type: 'file' }
49
42
  }
@@ -83,7 +76,6 @@ export const createCommand = new Command('create')
83
76
  let version = options.version
84
77
  let database = options.database
85
78
 
86
- // Validate --from location if provided (before prompts so we can infer engine)
87
79
  let restoreLocation: string | null = null
88
80
  let restoreType: 'connection' | 'file' | null = null
89
81
 
@@ -103,7 +95,6 @@ export const createCommand = new Command('create')
103
95
  restoreLocation = options.from
104
96
  restoreType = locationInfo.type
105
97
 
106
- // Infer engine from connection string if not explicitly set
107
98
  if (!options.engine && locationInfo.inferredEngine) {
108
99
  engine = locationInfo.inferredEngine
109
100
  console.log(
@@ -113,7 +104,6 @@ export const createCommand = new Command('create')
113
104
  )
114
105
  }
115
106
 
116
- // If using --from, we must start the container
117
107
  if (options.start === false) {
118
108
  console.error(
119
109
  error(
@@ -124,15 +114,12 @@ export const createCommand = new Command('create')
124
114
  }
125
115
  }
126
116
 
127
- // Get engine defaults for port range and default version
128
117
  const engineDefaults = getEngineDefaults(engine)
129
118
 
130
- // Set version to engine default if not specified
131
119
  if (!version) {
132
120
  version = engineDefaults.defaultVersion
133
121
  }
134
122
 
135
- // Interactive mode if no name provided
136
123
  if (!containerName) {
137
124
  const answers = await promptCreateOptions()
138
125
  containerName = answers.name
@@ -141,16 +128,13 @@ export const createCommand = new Command('create')
141
128
  database = answers.database
142
129
  }
143
130
 
144
- // Default database name to container name if not specified
145
131
  database = database ?? containerName
146
132
 
147
133
  console.log(header('Creating Database Container'))
148
134
  console.log()
149
135
 
150
- // Get the engine
151
136
  const dbEngine = getEngine(engine)
152
137
 
153
- // Check for required client tools BEFORE creating anything
154
138
  const depsSpinner = createSpinner('Checking required tools...')
155
139
  depsSpinner.start()
156
140
 
@@ -160,7 +144,6 @@ export const createCommand = new Command('create')
160
144
  `Missing tools: ${missingDeps.map((d) => d.name).join(', ')}`,
161
145
  )
162
146
 
163
- // Offer to install
164
147
  const installed = await promptInstallDependencies(
165
148
  missingDeps[0].binary,
166
149
  engine,
@@ -170,7 +153,6 @@ export const createCommand = new Command('create')
170
153
  process.exit(1)
171
154
  }
172
155
 
173
- // Verify installation worked
174
156
  missingDeps = await getMissingDependencies(engine)
175
157
  if (missingDeps.length > 0) {
176
158
  console.error(
@@ -187,7 +169,6 @@ export const createCommand = new Command('create')
187
169
  depsSpinner.succeed('Required tools available')
188
170
  }
189
171
 
190
- // Find available port
191
172
  const portSpinner = createSpinner('Finding available port...')
192
173
  portSpinner.start()
193
174
 
@@ -216,7 +197,6 @@ export const createCommand = new Command('create')
216
197
  }
217
198
  }
218
199
 
219
- // Ensure binaries are available
220
200
  const binarySpinner = createSpinner(
221
201
  `Checking ${dbEngine.displayName} ${version} binaries...`,
222
202
  )
@@ -237,7 +217,6 @@ export const createCommand = new Command('create')
237
217
  )
238
218
  }
239
219
 
240
- // Check if container name already exists and prompt for new name if needed
241
220
  while (await containerManager.exists(containerName)) {
242
221
  console.log(
243
222
  chalk.yellow(` Container "${containerName}" already exists.`),
@@ -245,10 +224,8 @@ export const createCommand = new Command('create')
245
224
  containerName = await promptContainerName()
246
225
  }
247
226
 
248
- // Create transaction manager for rollback support
249
227
  const tx = new TransactionManager()
250
228
 
251
- // Create container
252
229
  const createSpinnerInstance = createSpinner('Creating container...')
253
230
  createSpinnerInstance.start()
254
231
 
@@ -260,7 +237,6 @@ export const createCommand = new Command('create')
260
237
  database,
261
238
  })
262
239
 
263
- // Register rollback action for container deletion
264
240
  tx.addRollback({
265
241
  description: `Delete container "${containerName}"`,
266
242
  execute: async () => {
@@ -274,7 +250,6 @@ export const createCommand = new Command('create')
274
250
  throw err
275
251
  }
276
252
 
277
- // Initialize database cluster
278
253
  const initSpinner = createSpinner('Initializing database cluster...')
279
254
  initSpinner.start()
280
255
 
@@ -282,7 +257,6 @@ export const createCommand = new Command('create')
282
257
  await dbEngine.initDataDir(containerName, version, {
283
258
  superuser: engineDefaults.superuser,
284
259
  })
285
- // Note: initDataDir is covered by the container delete rollback
286
260
  initSpinner.succeed('Database cluster initialized')
287
261
  } catch (err) {
288
262
  initSpinner.fail('Failed to initialize database cluster')
@@ -290,27 +264,19 @@ export const createCommand = new Command('create')
290
264
  throw err
291
265
  }
292
266
 
293
- // Determine if we should start the container
294
- // If --from is specified, we must start to restore
295
- // If --no-start is specified, don't start
296
- // Otherwise, ask the user
267
+ // --from requires start, --no-start skips, otherwise ask user
297
268
  let shouldStart = false
298
269
  if (restoreLocation) {
299
- // Must start to restore data
300
270
  shouldStart = true
301
271
  } else if (options.start === false) {
302
- // User explicitly requested no start
303
272
  shouldStart = false
304
273
  } else {
305
- // Ask the user
306
274
  console.log()
307
275
  shouldStart = await promptConfirm(`Start ${containerName} now?`, true)
308
276
  }
309
277
 
310
- // Get container config for starting and restoration
311
278
  const config = await containerManager.getConfig(containerName)
312
279
 
313
- // Start container if requested
314
280
  if (shouldStart && config) {
315
281
  const startSpinner = createSpinner(
316
282
  `Starting ${dbEngine.displayName}...`,
@@ -318,7 +284,6 @@ export const createCommand = new Command('create')
318
284
  startSpinner.start()
319
285
 
320
286
  try {
321
- // Use startWithRetry to handle port race conditions
322
287
  const result = await startWithRetry({
323
288
  engine: dbEngine,
324
289
  config,
@@ -337,7 +302,6 @@ export const createCommand = new Command('create')
337
302
  throw new Error('Failed to start container')
338
303
  }
339
304
 
340
- // Register rollback action for stopping the container
341
305
  tx.addRollback({
342
306
  description: `Stop container "${containerName}"`,
343
307
  execute: async () => {
@@ -370,8 +334,7 @@ export const createCommand = new Command('create')
370
334
  throw err
371
335
  }
372
336
 
373
- // Create the user's database (if different from default)
374
- const defaultDb = engineDefaults.superuser // postgres or root
337
+ const defaultDb = engineDefaults.superuser
375
338
  if (database !== defaultDb) {
376
339
  const dbSpinner = createSpinner(
377
340
  `Creating database "${database}"...`,
@@ -389,18 +352,16 @@ export const createCommand = new Command('create')
389
352
  }
390
353
  }
391
354
 
392
- // Handle --from restore if specified (only if started)
393
355
  if (restoreLocation && restoreType && config && shouldStart) {
394
356
  let backupPath = ''
395
357
 
396
358
  if (restoreType === 'connection') {
397
- // Create dump from remote database
398
359
  const timestamp = Date.now()
399
360
  tempDumpPath = join(tmpdir(), `spindb-dump-${timestamp}.dump`)
400
361
 
401
362
  let dumpSuccess = false
402
363
  let attempts = 0
403
- const maxAttempts = 2 // Allow one retry after installing deps
364
+ const maxAttempts = 2
404
365
 
405
366
  while (!dumpSuccess && attempts < maxAttempts) {
406
367
  attempts++
@@ -421,7 +382,6 @@ export const createCommand = new Command('create')
421
382
  const e = err as Error
422
383
  dumpSpinner.fail('Failed to create dump')
423
384
 
424
- // Check if this is a missing tool error
425
385
  if (
426
386
  e.message.includes('pg_dump not found') ||
427
387
  e.message.includes('ENOENT')
@@ -430,7 +390,6 @@ export const createCommand = new Command('create')
430
390
  if (!installed) {
431
391
  process.exit(1)
432
392
  }
433
- // Loop will retry
434
393
  continue
435
394
  }
436
395
 
@@ -441,7 +400,6 @@ export const createCommand = new Command('create')
441
400
  }
442
401
  }
443
402
 
444
- // Safety check - should never reach here without backupPath set
445
403
  if (!dumpSuccess) {
446
404
  console.error(error('Failed to create dump after retries'))
447
405
  process.exit(1)
@@ -450,20 +408,18 @@ export const createCommand = new Command('create')
450
408
  backupPath = restoreLocation
451
409
  }
452
410
 
453
- // Detect backup format
454
411
  const detectSpinner = createSpinner('Detecting backup format...')
455
412
  detectSpinner.start()
456
413
 
457
414
  const format = await dbEngine.detectBackupFormat(backupPath)
458
415
  detectSpinner.succeed(`Detected: ${format.description}`)
459
416
 
460
- // Restore backup
461
417
  const restoreSpinner = createSpinner('Restoring backup...')
462
418
  restoreSpinner.start()
463
419
 
464
420
  const result = await dbEngine.restore(config, backupPath, {
465
421
  database,
466
- createDatabase: false, // Already created above
422
+ createDatabase: false,
467
423
  })
468
424
 
469
425
  if (result.code === 0 || !result.stderr) {
@@ -485,10 +441,8 @@ export const createCommand = new Command('create')
485
441
  }
486
442
  }
487
443
 
488
- // Commit the transaction - all operations succeeded
489
444
  tx.commit()
490
445
 
491
- // Show success message
492
446
  const finalConfig = await containerManager.getConfig(containerName)
493
447
  if (finalConfig) {
494
448
  const connectionString = dbEngine.getConnectionString(finalConfig)
@@ -503,7 +457,6 @@ export const createCommand = new Command('create')
503
457
  console.log(chalk.gray(' Connect with:'))
504
458
  console.log(chalk.cyan(` spindb connect ${containerName}`))
505
459
 
506
- // Copy connection string to clipboard
507
460
  const copied =
508
461
  await platformService.copyToClipboard(connectionString)
509
462
  if (copied) {
@@ -519,13 +472,10 @@ export const createCommand = new Command('create')
519
472
  } catch (err) {
520
473
  const e = err as Error
521
474
 
522
- // Check if this is a missing tool error (PostgreSQL or MySQL)
523
475
  const missingToolPatterns = [
524
- // PostgreSQL
525
476
  'pg_restore not found',
526
477
  'psql not found',
527
478
  'pg_dump not found',
528
- // MySQL
529
479
  'mysql not found',
530
480
  'mysqldump not found',
531
481
  'mysqld not found',
@@ -549,7 +499,6 @@ export const createCommand = new Command('create')
549
499
  console.error(error(e.message))
550
500
  process.exit(1)
551
501
  } finally {
552
- // Clean up temp file if we created one
553
502
  if (tempDumpPath) {
554
503
  try {
555
504
  await rm(tempDumpPath, { force: true })
@@ -20,7 +20,6 @@ export const deleteCommand = new Command('delete')
20
20
  try {
21
21
  let containerName = name
22
22
 
23
- // Interactive selection if no name provided
24
23
  if (!containerName) {
25
24
  const containers = await containerManager.list()
26
25
 
@@ -37,14 +36,12 @@ export const deleteCommand = new Command('delete')
37
36
  containerName = selected
38
37
  }
39
38
 
40
- // Get container config
41
39
  const config = await containerManager.getConfig(containerName)
42
40
  if (!config) {
43
41
  console.error(error(`Container "${containerName}" not found`))
44
42
  process.exit(1)
45
43
  }
46
44
 
47
- // Confirm deletion
48
45
  if (!options.yes) {
49
46
  const confirmed = await promptConfirm(
50
47
  `Are you sure you want to delete "${containerName}"? This cannot be undone.`,
@@ -56,13 +53,11 @@ export const deleteCommand = new Command('delete')
56
53
  }
57
54
  }
58
55
 
59
- // Check if running
60
56
  const running = await processManager.isRunning(containerName, {
61
57
  engine: config.engine,
62
58
  })
63
59
  if (running) {
64
60
  if (options.force) {
65
- // Stop the container first
66
61
  const stopSpinner = createSpinner(`Stopping ${containerName}...`)
67
62
  stopSpinner.start()
68
63
 
@@ -80,7 +75,6 @@ export const deleteCommand = new Command('delete')
80
75
  }
81
76
  }
82
77
 
83
- // Delete the container
84
78
  const deleteSpinner = createSpinner(`Deleting ${containerName}...`)
85
79
  deleteSpinner.start()
86
80