spindb 0.9.1 → 0.9.3

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.
Files changed (55) hide show
  1. package/README.md +5 -8
  2. package/cli/commands/attach.ts +108 -0
  3. package/cli/commands/backup.ts +13 -11
  4. package/cli/commands/clone.ts +14 -10
  5. package/cli/commands/config.ts +29 -29
  6. package/cli/commands/connect.ts +51 -39
  7. package/cli/commands/create.ts +65 -32
  8. package/cli/commands/delete.ts +8 -8
  9. package/cli/commands/deps.ts +17 -15
  10. package/cli/commands/detach.ts +100 -0
  11. package/cli/commands/doctor.ts +27 -13
  12. package/cli/commands/edit.ts +120 -57
  13. package/cli/commands/engines.ts +17 -15
  14. package/cli/commands/info.ts +8 -6
  15. package/cli/commands/list.ts +127 -18
  16. package/cli/commands/logs.ts +15 -11
  17. package/cli/commands/menu/backup-handlers.ts +52 -47
  18. package/cli/commands/menu/container-handlers.ts +164 -79
  19. package/cli/commands/menu/engine-handlers.ts +21 -11
  20. package/cli/commands/menu/index.ts +4 -4
  21. package/cli/commands/menu/shell-handlers.ts +34 -31
  22. package/cli/commands/menu/sql-handlers.ts +22 -16
  23. package/cli/commands/menu/update-handlers.ts +19 -17
  24. package/cli/commands/restore.ts +22 -20
  25. package/cli/commands/run.ts +20 -18
  26. package/cli/commands/self-update.ts +5 -5
  27. package/cli/commands/sqlite.ts +247 -0
  28. package/cli/commands/start.ts +11 -9
  29. package/cli/commands/stop.ts +9 -9
  30. package/cli/commands/url.ts +12 -9
  31. package/cli/helpers.ts +9 -4
  32. package/cli/index.ts +6 -0
  33. package/cli/ui/prompts.ts +12 -5
  34. package/cli/ui/spinner.ts +4 -4
  35. package/cli/ui/theme.ts +4 -4
  36. package/config/paths.ts +0 -8
  37. package/core/binary-manager.ts +5 -1
  38. package/core/config-manager.ts +32 -0
  39. package/core/container-manager.ts +5 -5
  40. package/core/platform-service.ts +3 -3
  41. package/core/start-with-retry.ts +6 -6
  42. package/core/transaction-manager.ts +6 -6
  43. package/engines/mysql/backup.ts +37 -13
  44. package/engines/mysql/index.ts +11 -11
  45. package/engines/mysql/restore.ts +4 -4
  46. package/engines/mysql/version-validator.ts +2 -2
  47. package/engines/postgresql/binary-manager.ts +17 -17
  48. package/engines/postgresql/index.ts +7 -2
  49. package/engines/postgresql/restore.ts +2 -2
  50. package/engines/postgresql/version-validator.ts +2 -2
  51. package/engines/sqlite/index.ts +30 -15
  52. package/engines/sqlite/registry.ts +64 -33
  53. package/engines/sqlite/scanner.ts +99 -0
  54. package/package.json +4 -3
  55. package/types/index.ts +21 -1
@@ -4,7 +4,7 @@ import { rm } from 'fs/promises'
4
4
  import { containerManager } from '../../../core/container-manager'
5
5
  import { processManager } from '../../../core/process-manager'
6
6
  import { createSpinner } from '../../ui/spinner'
7
- import { header, error, warning, info, formatBytes } from '../../ui/theme'
7
+ import { header, uiError, uiWarning, uiInfo, formatBytes } from '../../ui/theme'
8
8
  import { promptConfirm } from '../../ui/prompts'
9
9
  import { getEngineIcon, ENGINE_ICONS } from '../../constants'
10
10
  import {
@@ -37,7 +37,7 @@ export async function handleEngines(): Promise<void> {
37
37
  const engines = await getInstalledEngines()
38
38
 
39
39
  if (engines.length === 0) {
40
- console.log(info('No engines installed yet.'))
40
+ console.log(uiInfo('No engines installed yet.'))
41
41
  console.log(
42
42
  chalk.gray(
43
43
  ' PostgreSQL engines are downloaded automatically when you create a container.',
@@ -128,7 +128,9 @@ export async function handleEngines(): Promise<void> {
128
128
  console.log(chalk.gray(` MySQL: system-installed at ${mysqlEngine.path}`))
129
129
  }
130
130
  if (sqliteEngine) {
131
- console.log(chalk.gray(` SQLite: system-installed at ${sqliteEngine.path}`))
131
+ console.log(
132
+ chalk.gray(` SQLite: system-installed at ${sqliteEngine.path}`),
133
+ )
132
134
  }
133
135
  console.log()
134
136
 
@@ -212,7 +214,7 @@ async function handleDeleteEngine(
212
214
  if (usingContainers.length > 0) {
213
215
  console.log()
214
216
  console.log(
215
- error(
217
+ uiError(
216
218
  `Cannot delete: ${usingContainers.length} container(s) are using ${engineName} ${engineVersion}`,
217
219
  ),
218
220
  )
@@ -238,7 +240,7 @@ async function handleDeleteEngine(
238
240
  )
239
241
 
240
242
  if (!confirmed) {
241
- console.log(warning('Deletion cancelled'))
243
+ console.log(uiWarning('Deletion cancelled'))
242
244
  return
243
245
  }
244
246
 
@@ -248,8 +250,8 @@ async function handleDeleteEngine(
248
250
  try {
249
251
  await rm(enginePath, { recursive: true, force: true })
250
252
  spinner.succeed(`Deleted ${engineName} ${engineVersion}`)
251
- } catch (err) {
252
- const e = err as Error
253
+ } catch (error) {
254
+ const e = error as Error
253
255
  spinner.fail(`Failed to delete: ${e.message}`)
254
256
  }
255
257
  }
@@ -272,7 +274,7 @@ async function handleMysqlInfo(mysqldPath: string): Promise<void> {
272
274
 
273
275
  if (mysqlContainers.length > 0) {
274
276
  console.log(
275
- warning(
277
+ uiWarning(
276
278
  `${mysqlContainers.length} container(s) are using ${displayName}:`,
277
279
  ),
278
280
  )
@@ -438,7 +440,9 @@ async function handleSqliteInfo(sqlitePath: string): Promise<void> {
438
440
  const sqliteContainers = containers.filter((c) => c.engine === 'sqlite')
439
441
 
440
442
  if (sqliteContainers.length > 0) {
441
- console.log(info(`${sqliteContainers.length} SQLite database(s) registered:`))
443
+ console.log(
444
+ uiInfo(`${sqliteContainers.length} SQLite database(s) registered:`),
445
+ )
442
446
  console.log()
443
447
  for (const c of sqliteContainers) {
444
448
  const status =
@@ -471,9 +475,15 @@ async function handleSqliteInfo(sqlitePath: string): Promise<void> {
471
475
 
472
476
  console.log(chalk.white(' Notes:'))
473
477
  console.log(chalk.gray(' ' + '─'.repeat(50)))
474
- console.log(chalk.gray(' • SQLite is typically pre-installed on macOS and most Linux distributions'))
478
+ console.log(
479
+ chalk.gray(
480
+ ' • SQLite is typically pre-installed on macOS and most Linux distributions',
481
+ ),
482
+ )
475
483
  console.log(chalk.gray(' • No server process - databases are just files'))
476
- console.log(chalk.gray(' • Use "spindb delete <name>" to unregister a database'))
484
+ console.log(
485
+ chalk.gray(' • Use "spindb delete <name>" to unregister a database'),
486
+ )
477
487
  console.log()
478
488
 
479
489
  await inquirer.prompt([
@@ -3,7 +3,7 @@ import chalk from 'chalk'
3
3
  import inquirer from 'inquirer'
4
4
  import { containerManager } from '../../../core/container-manager'
5
5
  import { promptInstallDependencies } from '../../ui/prompts'
6
- import { header, error } from '../../ui/theme'
6
+ import { header, uiError } from '../../ui/theme'
7
7
  import { getInstalledEngines } from '../../helpers'
8
8
  import {
9
9
  handleCreate,
@@ -156,8 +156,8 @@ export const menuCommand = new Command('menu')
156
156
  .action(async () => {
157
157
  try {
158
158
  await showMainMenu()
159
- } catch (err) {
160
- const e = err as Error
159
+ } catch (error) {
160
+ const e = error as Error
161
161
 
162
162
  // Check if this is a missing tool error
163
163
  if (
@@ -177,7 +177,7 @@ export const menuCommand = new Command('menu')
177
177
  process.exit(1)
178
178
  }
179
179
 
180
- console.error(error(e.message))
180
+ console.error(uiError(e.message))
181
181
  process.exit(1)
182
182
  }
183
183
  })
@@ -20,7 +20,7 @@ import {
20
20
  import { platformService } from '../../../core/platform-service'
21
21
  import { getEngine } from '../../../engines'
22
22
  import { createSpinner } from '../../ui/spinner'
23
- import { error, warning, info, success } from '../../ui/theme'
23
+ import { uiError, uiWarning, uiInfo, uiSuccess } from '../../ui/theme'
24
24
  import { pressEnterToContinue } from './shared'
25
25
 
26
26
  export async function handleCopyConnectionString(
@@ -28,7 +28,7 @@ export async function handleCopyConnectionString(
28
28
  ): Promise<void> {
29
29
  const config = await containerManager.getConfig(containerName)
30
30
  if (!config) {
31
- console.error(error(`Container "${containerName}" not found`))
31
+ console.error(uiError(`Container "${containerName}" not found`))
32
32
  return
33
33
  }
34
34
 
@@ -39,10 +39,10 @@ export async function handleCopyConnectionString(
39
39
 
40
40
  console.log()
41
41
  if (copied) {
42
- console.log(success('Connection string copied to clipboard'))
42
+ console.log(uiSuccess('Connection string copied to clipboard'))
43
43
  console.log(chalk.gray(` ${connectionString}`))
44
44
  } else {
45
- console.log(warning('Could not copy to clipboard. Connection string:'))
45
+ console.log(uiWarning('Could not copy to clipboard. Connection string:'))
46
46
  console.log(chalk.cyan(` ${connectionString}`))
47
47
  }
48
48
  console.log()
@@ -59,7 +59,7 @@ export async function handleCopyConnectionString(
59
59
  export async function handleOpenShell(containerName: string): Promise<void> {
60
60
  const config = await containerManager.getConfig(containerName)
61
61
  if (!config) {
62
- console.error(error(`Container "${containerName}" not found`))
62
+ console.error(uiError(`Container "${containerName}" not found`))
63
63
  return
64
64
  }
65
65
 
@@ -69,12 +69,13 @@ export async function handleOpenShell(containerName: string): Promise<void> {
69
69
  const shellCheckSpinner = createSpinner('Checking available shells...')
70
70
  shellCheckSpinner.start()
71
71
 
72
- const [usqlInstalled, pgcliInstalled, mycliInstalled, litecliInstalled] = await Promise.all([
73
- isUsqlInstalled(),
74
- isPgcliInstalled(),
75
- isMycliInstalled(),
76
- isLitecliInstalled(),
77
- ])
72
+ const [usqlInstalled, pgcliInstalled, mycliInstalled, litecliInstalled] =
73
+ await Promise.all([
74
+ isUsqlInstalled(),
75
+ isPgcliInstalled(),
76
+ isMycliInstalled(),
77
+ isLitecliInstalled(),
78
+ ])
78
79
 
79
80
  shellCheckSpinner.stop()
80
81
  // Clear the spinner line
@@ -119,7 +120,9 @@ export async function handleOpenShell(containerName: string): Promise<void> {
119
120
  engineSpecificInstallValue = 'install-pgcli'
120
121
  }
121
122
 
122
- const choices: Array<{ name: string; value: ShellChoice } | inquirer.Separator> = [
123
+ const choices: Array<
124
+ { name: string; value: ShellChoice } | inquirer.Separator
125
+ > = [
123
126
  {
124
127
  name: `>_ Use default shell (${defaultShellName})`,
125
128
  value: 'default',
@@ -173,16 +176,16 @@ export async function handleOpenShell(containerName: string): Promise<void> {
173
176
 
174
177
  if (shellChoice === 'install-pgcli') {
175
178
  console.log()
176
- console.log(info('Installing pgcli for enhanced PostgreSQL shell...'))
179
+ console.log(uiInfo('Installing pgcli for enhanced PostgreSQL shell...'))
177
180
  const pm = await detectPackageManager()
178
181
  if (pm) {
179
182
  const result = await installPgcli(pm)
180
183
  if (result.success) {
181
- console.log(success('pgcli installed successfully!'))
184
+ console.log(uiSuccess('pgcli installed successfully!'))
182
185
  console.log()
183
186
  await launchShell(containerName, config, connectionString, 'pgcli')
184
187
  } else {
185
- console.error(error(`Failed to install pgcli: ${result.error}`))
188
+ console.error(uiError(`Failed to install pgcli: ${result.error}`))
186
189
  console.log()
187
190
  console.log(chalk.gray('Manual installation:'))
188
191
  for (const instruction of getPgcliManualInstructions()) {
@@ -192,7 +195,7 @@ export async function handleOpenShell(containerName: string): Promise<void> {
192
195
  await pressEnterToContinue()
193
196
  }
194
197
  } else {
195
- console.error(error('No supported package manager found'))
198
+ console.error(uiError('No supported package manager found'))
196
199
  console.log()
197
200
  console.log(chalk.gray('Manual installation:'))
198
201
  for (const instruction of getPgcliManualInstructions()) {
@@ -206,16 +209,16 @@ export async function handleOpenShell(containerName: string): Promise<void> {
206
209
 
207
210
  if (shellChoice === 'install-mycli') {
208
211
  console.log()
209
- console.log(info('Installing mycli for enhanced MySQL shell...'))
212
+ console.log(uiInfo('Installing mycli for enhanced MySQL shell...'))
210
213
  const pm = await detectPackageManager()
211
214
  if (pm) {
212
215
  const result = await installMycli(pm)
213
216
  if (result.success) {
214
- console.log(success('mycli installed successfully!'))
217
+ console.log(uiSuccess('mycli installed successfully!'))
215
218
  console.log()
216
219
  await launchShell(containerName, config, connectionString, 'mycli')
217
220
  } else {
218
- console.error(error(`Failed to install mycli: ${result.error}`))
221
+ console.error(uiError(`Failed to install mycli: ${result.error}`))
219
222
  console.log()
220
223
  console.log(chalk.gray('Manual installation:'))
221
224
  for (const instruction of getMycliManualInstructions()) {
@@ -225,7 +228,7 @@ export async function handleOpenShell(containerName: string): Promise<void> {
225
228
  await pressEnterToContinue()
226
229
  }
227
230
  } else {
228
- console.error(error('No supported package manager found'))
231
+ console.error(uiError('No supported package manager found'))
229
232
  console.log()
230
233
  console.log(chalk.gray('Manual installation:'))
231
234
  for (const instruction of getMycliManualInstructions()) {
@@ -239,16 +242,16 @@ export async function handleOpenShell(containerName: string): Promise<void> {
239
242
 
240
243
  if (shellChoice === 'install-usql') {
241
244
  console.log()
242
- console.log(info('Installing usql for enhanced shell experience...'))
245
+ console.log(uiInfo('Installing usql for enhanced shell experience...'))
243
246
  const pm = await detectPackageManager()
244
247
  if (pm) {
245
248
  const result = await installUsql(pm)
246
249
  if (result.success) {
247
- console.log(success('usql installed successfully!'))
250
+ console.log(uiSuccess('usql installed successfully!'))
248
251
  console.log()
249
252
  await launchShell(containerName, config, connectionString, 'usql')
250
253
  } else {
251
- console.error(error(`Failed to install usql: ${result.error}`))
254
+ console.error(uiError(`Failed to install usql: ${result.error}`))
252
255
  console.log()
253
256
  console.log(chalk.gray('Manual installation:'))
254
257
  for (const instruction of getUsqlManualInstructions()) {
@@ -258,7 +261,7 @@ export async function handleOpenShell(containerName: string): Promise<void> {
258
261
  await pressEnterToContinue()
259
262
  }
260
263
  } else {
261
- console.error(error('No supported package manager found'))
264
+ console.error(uiError('No supported package manager found'))
262
265
  console.log()
263
266
  console.log(chalk.gray('Manual installation:'))
264
267
  for (const instruction of getUsqlManualInstructions()) {
@@ -272,16 +275,16 @@ export async function handleOpenShell(containerName: string): Promise<void> {
272
275
 
273
276
  if (shellChoice === 'install-litecli') {
274
277
  console.log()
275
- console.log(info('Installing litecli for enhanced SQLite shell...'))
278
+ console.log(uiInfo('Installing litecli for enhanced SQLite shell...'))
276
279
  const pm = await detectPackageManager()
277
280
  if (pm) {
278
281
  const result = await installLitecli(pm)
279
282
  if (result.success) {
280
- console.log(success('litecli installed successfully!'))
283
+ console.log(uiSuccess('litecli installed successfully!'))
281
284
  console.log()
282
285
  await launchShell(containerName, config, connectionString, 'litecli')
283
286
  } else {
284
- console.error(error(`Failed to install litecli: ${result.error}`))
287
+ console.error(uiError(`Failed to install litecli: ${result.error}`))
285
288
  console.log()
286
289
  console.log(chalk.gray('Manual installation:'))
287
290
  for (const instruction of getLitecliManualInstructions()) {
@@ -291,7 +294,7 @@ export async function handleOpenShell(containerName: string): Promise<void> {
291
294
  await pressEnterToContinue()
292
295
  }
293
296
  } else {
294
- console.error(error('No supported package manager found'))
297
+ console.error(uiError('No supported package manager found'))
295
298
  console.log()
296
299
  console.log(chalk.gray('Manual installation:'))
297
300
  for (const instruction of getLitecliManualInstructions()) {
@@ -312,7 +315,7 @@ async function launchShell(
312
315
  connectionString: string,
313
316
  shellType: 'default' | 'usql' | 'pgcli' | 'mycli' | 'litecli',
314
317
  ): Promise<void> {
315
- console.log(info(`Connecting to ${containerName}...`))
318
+ console.log(uiInfo(`Connecting to ${containerName}...`))
316
319
  console.log()
317
320
 
318
321
  let shellCmd: string
@@ -386,7 +389,7 @@ async function launchShell(
386
389
 
387
390
  shellProcess.on('error', (err: NodeJS.ErrnoException) => {
388
391
  if (err.code === 'ENOENT') {
389
- console.log(warning(`${shellCmd} not found on your system.`))
392
+ console.log(uiWarning(`${shellCmd} not found on your system.`))
390
393
  console.log()
391
394
  console.log(chalk.gray(' Connect manually with:'))
392
395
  console.log(chalk.cyan(` ${connectionString}`))
@@ -394,7 +397,7 @@ async function launchShell(
394
397
  console.log(chalk.gray(` Install ${shellCmd}:`))
395
398
  console.log(chalk.cyan(` ${installHint}`))
396
399
  } else {
397
- console.log(error(`Failed to start ${shellCmd}: ${err.message}`))
400
+ console.log(uiError(`Failed to start ${shellCmd}: ${err.message}`))
398
401
  }
399
402
  settle()
400
403
  })
@@ -7,14 +7,17 @@ import { containerManager } from '../../../core/container-manager'
7
7
  import { getMissingDependencies } from '../../../core/dependency-manager'
8
8
  import { getEngine } from '../../../engines'
9
9
  import { paths } from '../../../config/paths'
10
- import { promptInstallDependencies, promptDatabaseSelect } from '../../ui/prompts'
11
- import { error, warning, info, success } from '../../ui/theme'
10
+ import {
11
+ promptInstallDependencies,
12
+ promptDatabaseSelect,
13
+ } from '../../ui/prompts'
14
+ import { uiError, uiWarning, uiInfo, uiSuccess } from '../../ui/theme'
12
15
  import { pressEnterToContinue } from './shared'
13
16
 
14
17
  export async function handleRunSql(containerName: string): Promise<void> {
15
18
  const config = await containerManager.getConfig(containerName)
16
19
  if (!config) {
17
- console.error(error(`Container "${containerName}" not found`))
20
+ console.error(uiError(`Container "${containerName}" not found`))
18
21
  return
19
22
  }
20
23
 
@@ -23,7 +26,7 @@ export async function handleRunSql(containerName: string): Promise<void> {
23
26
  let missingDeps = await getMissingDependencies(config.engine)
24
27
  if (missingDeps.length > 0) {
25
28
  console.log(
26
- warning(`Missing tools: ${missingDeps.map((d) => d.name).join(', ')}`),
29
+ uiWarning(`Missing tools: ${missingDeps.map((d) => d.name).join(', ')}`),
27
30
  )
28
31
 
29
32
  const installed = await promptInstallDependencies(
@@ -38,7 +41,7 @@ export async function handleRunSql(containerName: string): Promise<void> {
38
41
  missingDeps = await getMissingDependencies(config.engine)
39
42
  if (missingDeps.length > 0) {
40
43
  console.log(
41
- error(
44
+ uiError(
42
45
  `Still missing tools: ${missingDeps.map((d) => d.name).join(', ')}`,
43
46
  ),
44
47
  )
@@ -50,11 +53,14 @@ export async function handleRunSql(containerName: string): Promise<void> {
50
53
  }
51
54
 
52
55
  // Strip quotes that terminals add when drag-and-dropping files
53
- const stripQuotes = (path: string) =>
54
- path.replace(/^['"]|['"]$/g, '').trim()
56
+ const stripQuotes = (path: string) => path.replace(/^['"]|['"]$/g, '').trim()
55
57
 
56
58
  // Prompt for file path (empty input = go back)
57
- console.log(chalk.gray(' Drag & drop, enter path (abs or rel), or press Enter to go back'))
59
+ console.log(
60
+ chalk.gray(
61
+ ' Drag & drop, enter path (abs or rel), or press Enter to go back',
62
+ ),
63
+ )
58
64
  const { filePath: rawFilePath } = await inquirer.prompt<{
59
65
  filePath: string
60
66
  }>([
@@ -90,7 +96,7 @@ export async function handleRunSql(containerName: string): Promise<void> {
90
96
  }
91
97
 
92
98
  console.log()
93
- console.log(info(`Running SQL file against "${databaseName}"...`))
99
+ console.log(uiInfo(`Running SQL file against "${databaseName}"...`))
94
100
  console.log()
95
101
 
96
102
  try {
@@ -99,11 +105,11 @@ export async function handleRunSql(containerName: string): Promise<void> {
99
105
  database: databaseName,
100
106
  })
101
107
  console.log()
102
- console.log(success('SQL file executed successfully'))
103
- } catch (err) {
104
- const e = err as Error
108
+ console.log(uiSuccess('SQL file executed successfully'))
109
+ } catch (error) {
110
+ const e = error as Error
105
111
  console.log()
106
- console.log(error(`SQL execution failed: ${e.message}`))
112
+ console.log(uiError(`SQL execution failed: ${e.message}`))
107
113
  }
108
114
 
109
115
  console.log()
@@ -116,7 +122,7 @@ export async function handleRunSql(containerName: string): Promise<void> {
116
122
  export async function handleViewLogs(containerName: string): Promise<void> {
117
123
  const config = await containerManager.getConfig(containerName)
118
124
  if (!config) {
119
- console.error(error(`Container "${containerName}" not found`))
125
+ console.error(uiError(`Container "${containerName}" not found`))
120
126
  return
121
127
  }
122
128
 
@@ -126,7 +132,7 @@ export async function handleViewLogs(containerName: string): Promise<void> {
126
132
 
127
133
  if (!existsSync(logPath)) {
128
134
  console.log(
129
- info(
135
+ uiInfo(
130
136
  `No log file found for "${containerName}". The container may not have been started yet.`,
131
137
  ),
132
138
  )
@@ -194,7 +200,7 @@ export async function handleViewLogs(containerName: string): Promise<void> {
194
200
  const lineCount = action === 'tail-100' ? 100 : 50
195
201
  const content = await readFile(logPath, 'utf-8')
196
202
  if (content.trim() === '') {
197
- console.log(info('Log file is empty'))
203
+ console.log(uiInfo('Log file is empty'))
198
204
  } else {
199
205
  const lines = content.split('\n')
200
206
  const nonEmptyLines =
@@ -9,7 +9,7 @@ import { paths } from '../../../config/paths'
9
9
  import { getSupportedEngines } from '../../../config/engine-defaults'
10
10
  import { checkEngineDependencies } from '../../../core/dependency-manager'
11
11
  import { createSpinner } from '../../ui/spinner'
12
- import { header, success, error, warning, info } from '../../ui/theme'
12
+ import { header, uiSuccess, uiError, uiWarning, uiInfo } from '../../ui/theme'
13
13
  import { pressEnterToContinue } from './shared'
14
14
  import { Engine } from '../../../types'
15
15
 
@@ -26,7 +26,7 @@ export async function handleCheckUpdate(): Promise<void> {
26
26
  if (!result) {
27
27
  spinner.fail('Could not reach npm registry')
28
28
  console.log()
29
- console.log(info('Check your internet connection and try again.'))
29
+ console.log(uiInfo('Check your internet connection and try again.'))
30
30
  console.log(chalk.gray(' Manual update: npm install -g spindb@latest'))
31
31
  console.log()
32
32
  await pressEnterToContinue()
@@ -66,27 +66,29 @@ export async function handleCheckUpdate(): Promise<void> {
66
66
  updateSpinner.succeed('Update complete')
67
67
  console.log()
68
68
  console.log(
69
- success(
69
+ uiSuccess(
70
70
  `Updated from ${updateResult.previousVersion} to ${updateResult.newVersion}`,
71
71
  ),
72
72
  )
73
73
  console.log()
74
74
  if (updateResult.previousVersion !== updateResult.newVersion) {
75
- console.log(warning('Please restart spindb to use the new version.'))
75
+ console.log(
76
+ uiWarning('Please restart spindb to use the new version.'),
77
+ )
76
78
  console.log()
77
79
  }
78
80
  } else {
79
81
  updateSpinner.fail('Update failed')
80
82
  console.log()
81
- console.log(error(updateResult.error || 'Unknown error'))
83
+ console.log(uiError(updateResult.error || 'Unknown error'))
82
84
  console.log()
83
- console.log(info('Manual update: npm install -g spindb@latest'))
85
+ console.log(uiInfo('Manual update: npm install -g spindb@latest'))
84
86
  }
85
87
  await pressEnterToContinue()
86
88
  } else if (action === 'disable') {
87
89
  await updateManager.setAutoCheckEnabled(false)
88
90
  console.log()
89
- console.log(info('Update checks disabled on startup.'))
91
+ console.log(uiInfo('Update checks disabled on startup.'))
90
92
  console.log(chalk.gray(' Re-enable with: spindb config update-check on'))
91
93
  console.log()
92
94
  await pressEnterToContinue()
@@ -138,7 +140,7 @@ async function checkConfiguration(): Promise<HealthCheckResult> {
138
140
  label: 'Refresh binary cache',
139
141
  handler: async () => {
140
142
  await configManager.refreshAllBinaries()
141
- console.log(success('Binary cache refreshed'))
143
+ console.log(uiSuccess('Binary cache refreshed'))
142
144
  },
143
145
  },
144
146
  }
@@ -150,12 +152,12 @@ async function checkConfiguration(): Promise<HealthCheckResult> {
150
152
  message: 'Configuration valid',
151
153
  details: [`Binary tools cached: ${binaryCount}`],
152
154
  }
153
- } catch (err) {
155
+ } catch (error) {
154
156
  return {
155
157
  name: 'Configuration',
156
158
  status: 'error',
157
159
  message: 'Configuration file is corrupted',
158
- details: [(err as Error).message],
160
+ details: [(error as Error).message],
159
161
  }
160
162
  }
161
163
  }
@@ -199,12 +201,12 @@ async function checkContainers(): Promise<HealthCheckResult> {
199
201
  message: `${containers.length} container(s)`,
200
202
  details,
201
203
  }
202
- } catch (err) {
204
+ } catch (error) {
203
205
  return {
204
206
  name: 'Containers',
205
207
  status: 'error',
206
208
  message: 'Failed to list containers',
207
- details: [(err as Error).message],
209
+ details: [(error as Error).message],
208
210
  }
209
211
  }
210
212
  }
@@ -233,7 +235,7 @@ async function checkSqliteRegistry(): Promise<HealthCheckResult> {
233
235
  label: 'Remove orphaned entries from registry',
234
236
  handler: async () => {
235
237
  const count = await sqliteRegistry.removeOrphans()
236
- console.log(success(`Removed ${count} orphaned entries`))
238
+ console.log(uiSuccess(`Removed ${count} orphaned entries`))
237
239
  },
238
240
  },
239
241
  }
@@ -244,12 +246,12 @@ async function checkSqliteRegistry(): Promise<HealthCheckResult> {
244
246
  status: 'ok',
245
247
  message: `${entries.length} database(s) registered, all files exist`,
246
248
  }
247
- } catch (err) {
249
+ } catch (error) {
248
250
  return {
249
251
  name: 'SQLite Registry',
250
252
  status: 'warning',
251
253
  message: 'Could not check registry',
252
- details: [(err as Error).message],
254
+ details: [(error as Error).message],
253
255
  }
254
256
  }
255
257
  }
@@ -279,12 +281,12 @@ async function checkBinaries(): Promise<HealthCheckResult> {
279
281
  message: hasWarning ? 'Some tools missing' : 'All tools available',
280
282
  details: results,
281
283
  }
282
- } catch (err) {
284
+ } catch (error) {
283
285
  return {
284
286
  name: 'Database Tools',
285
287
  status: 'error',
286
288
  message: 'Failed to check tools',
287
- details: [(err as Error).message],
289
+ details: [(error as Error).message],
288
290
  }
289
291
  }
290
292
  }