@calltelemetry/cli 0.3.6 → 0.3.8

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 (128) hide show
  1. package/dist/commands/config.d.ts.map +1 -1
  2. package/dist/commands/config.js +10 -16
  3. package/dist/commands/config.js.map +1 -1
  4. package/dist/commands/offline.d.ts.map +1 -1
  5. package/dist/commands/offline.js +78 -105
  6. package/dist/commands/offline.js.map +1 -1
  7. package/dist/commands/self-update.d.ts +2 -3
  8. package/dist/commands/self-update.d.ts.map +1 -1
  9. package/dist/commands/self-update.js +4 -49
  10. package/dist/commands/self-update.js.map +1 -1
  11. package/dist/commands/update.d.ts.map +1 -1
  12. package/dist/commands/update.js +25 -82
  13. package/dist/commands/update.js.map +1 -1
  14. package/dist/index.js +16 -6
  15. package/dist/index.js.map +1 -1
  16. package/dist/lib/auto-update.d.ts +15 -5
  17. package/dist/lib/auto-update.d.ts.map +1 -1
  18. package/dist/lib/auto-update.js +61 -25
  19. package/dist/lib/auto-update.js.map +1 -1
  20. package/dist/lib/bundle.d.ts.map +1 -1
  21. package/dist/lib/bundle.js +2 -9
  22. package/dist/lib/bundle.js.map +1 -1
  23. package/dist/lib/compose.d.ts +4 -0
  24. package/dist/lib/compose.d.ts.map +1 -1
  25. package/dist/lib/compose.js +35 -9
  26. package/dist/lib/compose.js.map +1 -1
  27. package/dist/lib/ipv6.d.ts +15 -0
  28. package/dist/lib/ipv6.d.ts.map +1 -0
  29. package/dist/lib/ipv6.js +36 -0
  30. package/dist/lib/ipv6.js.map +1 -0
  31. package/dist/lib/log.d.ts +6 -0
  32. package/dist/lib/log.d.ts.map +1 -1
  33. package/dist/lib/log.js +30 -0
  34. package/dist/lib/log.js.map +1 -1
  35. package/dist/lib/network.d.ts.map +1 -1
  36. package/dist/lib/network.js +47 -4
  37. package/dist/lib/network.js.map +1 -1
  38. package/dist/lib/offline-steps.d.ts +33 -0
  39. package/dist/lib/offline-steps.d.ts.map +1 -0
  40. package/dist/lib/offline-steps.js +350 -0
  41. package/dist/lib/offline-steps.js.map +1 -0
  42. package/dist/lib/prefs.d.ts +1 -0
  43. package/dist/lib/prefs.d.ts.map +1 -1
  44. package/dist/lib/prefs.js +1 -1
  45. package/dist/lib/prefs.js.map +1 -1
  46. package/dist/lib/rpc.d.ts +3 -0
  47. package/dist/lib/rpc.d.ts.map +1 -1
  48. package/dist/lib/rpc.js +26 -4
  49. package/dist/lib/rpc.js.map +1 -1
  50. package/dist/lib/services.d.ts +5 -0
  51. package/dist/lib/services.d.ts.map +1 -1
  52. package/dist/lib/services.js +24 -0
  53. package/dist/lib/services.js.map +1 -1
  54. package/dist/lib/update-steps.d.ts +17 -0
  55. package/dist/lib/update-steps.d.ts.map +1 -0
  56. package/dist/lib/update-steps.js +169 -0
  57. package/dist/lib/update-steps.js.map +1 -0
  58. package/dist/lib/update.d.ts +2 -0
  59. package/dist/lib/update.d.ts.map +1 -1
  60. package/dist/lib/update.js +11 -0
  61. package/dist/lib/update.js.map +1 -1
  62. package/dist/ui/components/ErrorBoundary.d.ts +14 -0
  63. package/dist/ui/components/ErrorBoundary.d.ts.map +1 -0
  64. package/dist/ui/components/ErrorBoundary.js +19 -0
  65. package/dist/ui/components/ErrorBoundary.js.map +1 -0
  66. package/dist/ui/components/ShellOutput.d.ts.map +1 -1
  67. package/dist/ui/components/ShellOutput.js +8 -5
  68. package/dist/ui/components/ShellOutput.js.map +1 -1
  69. package/dist/ui/components/index.d.ts +1 -0
  70. package/dist/ui/components/index.d.ts.map +1 -1
  71. package/dist/ui/components/index.js +1 -0
  72. package/dist/ui/components/index.js.map +1 -1
  73. package/dist/ui/views/CertsStatusView.d.ts.map +1 -1
  74. package/dist/ui/views/CertsStatusView.js +19 -10
  75. package/dist/ui/views/CertsStatusView.js.map +1 -1
  76. package/dist/ui/views/DbBackupView.d.ts.map +1 -1
  77. package/dist/ui/views/DbBackupView.js +4 -2
  78. package/dist/ui/views/DbBackupView.js.map +1 -1
  79. package/dist/ui/views/DbStatusView.d.ts.map +1 -1
  80. package/dist/ui/views/DbStatusView.js +3 -2
  81. package/dist/ui/views/DbStatusView.js.map +1 -1
  82. package/dist/ui/views/DiagDatabaseView.d.ts.map +1 -1
  83. package/dist/ui/views/DiagDatabaseView.js +12 -10
  84. package/dist/ui/views/DiagDatabaseView.js.map +1 -1
  85. package/dist/ui/views/DiagNetworkView.d.ts.map +1 -1
  86. package/dist/ui/views/DiagNetworkView.js +23 -14
  87. package/dist/ui/views/DiagNetworkView.js.map +1 -1
  88. package/dist/ui/views/DiagServiceView.d.ts.map +1 -1
  89. package/dist/ui/views/DiagServiceView.js +6 -5
  90. package/dist/ui/views/DiagServiceView.js.map +1 -1
  91. package/dist/ui/views/DockerStatusView.d.ts.map +1 -1
  92. package/dist/ui/views/DockerStatusView.js +5 -4
  93. package/dist/ui/views/DockerStatusView.js.map +1 -1
  94. package/dist/ui/views/MainMenu.d.ts.map +1 -1
  95. package/dist/ui/views/MainMenu.js +50 -4
  96. package/dist/ui/views/MainMenu.js.map +1 -1
  97. package/dist/ui/views/MigrateRunView.js +1 -1
  98. package/dist/ui/views/MigrateRunView.js.map +1 -1
  99. package/dist/ui/views/MigrateWatchView.d.ts.map +1 -1
  100. package/dist/ui/views/MigrateWatchView.js +2 -2
  101. package/dist/ui/views/MigrateWatchView.js.map +1 -1
  102. package/dist/ui/views/OfflineApplyView.d.ts +6 -0
  103. package/dist/ui/views/OfflineApplyView.d.ts.map +1 -0
  104. package/dist/ui/views/OfflineApplyView.js +109 -0
  105. package/dist/ui/views/OfflineApplyView.js.map +1 -0
  106. package/dist/ui/views/OfflineDownloadView.d.ts +6 -0
  107. package/dist/ui/views/OfflineDownloadView.d.ts.map +1 -0
  108. package/dist/ui/views/OfflineDownloadView.js +67 -0
  109. package/dist/ui/views/OfflineDownloadView.js.map +1 -0
  110. package/dist/ui/views/OfflineFetchView.d.ts +6 -0
  111. package/dist/ui/views/OfflineFetchView.d.ts.map +1 -0
  112. package/dist/ui/views/OfflineFetchView.js +64 -0
  113. package/dist/ui/views/OfflineFetchView.js.map +1 -0
  114. package/dist/ui/views/OfflineInspectView.d.ts +6 -0
  115. package/dist/ui/views/OfflineInspectView.d.ts.map +1 -0
  116. package/dist/ui/views/OfflineInspectView.js +65 -0
  117. package/dist/ui/views/OfflineInspectView.js.map +1 -0
  118. package/dist/ui/views/OfflineListView.d.ts.map +1 -1
  119. package/dist/ui/views/OfflineListView.js +2 -6
  120. package/dist/ui/views/OfflineListView.js.map +1 -1
  121. package/dist/ui/views/SettingsView.d.ts +6 -0
  122. package/dist/ui/views/SettingsView.d.ts.map +1 -0
  123. package/dist/ui/views/SettingsView.js +68 -0
  124. package/dist/ui/views/SettingsView.js.map +1 -0
  125. package/dist/ui/views/UpdateView.d.ts.map +1 -1
  126. package/dist/ui/views/UpdateView.js +20 -134
  127. package/dist/ui/views/UpdateView.js.map +1 -1
  128. package/package.json +4 -2
@@ -0,0 +1,350 @@
1
+ /**
2
+ * Shared offline pipeline steps consumed by both the CLI (`commands/offline.ts`)
3
+ * and the TUI offline views. Keeps all offline logic in one place.
4
+ */
5
+ import { existsSync, readFileSync, statSync } from 'node:fs';
6
+ import { copyFile, mkdir, rm } from 'node:fs/promises';
7
+ import { join } from 'node:path';
8
+ import { getPaths } from './paths.js';
9
+ import { exec, execRetry } from './exec.js';
10
+ import { composeUp } from './compose.js';
11
+ import { downloadBundle } from './bundle.js';
12
+ import { checkDiskSpace } from './system.js';
13
+ import { debug } from './log.js';
14
+ import { formatBytes } from './system.js';
15
+ // ─── Canonical Image Regex ──────────────────────────────────────────────────
16
+ /**
17
+ * Extract image names from docker-compose.yml content.
18
+ * Single canonical regex — replaces 3 duplicated patterns across the codebase.
19
+ *
20
+ * @param filter - 'all' returns every image, 'calltelemetry' only calltelemetry images
21
+ */
22
+ export function extractImageNames(content, filter = 'all') {
23
+ const images = [];
24
+ for (const line of content.split('\n')) {
25
+ const match = line.match(/image:\s*["']?([^\s"']+)["']?/);
26
+ if (match) {
27
+ if (filter === 'calltelemetry' && !line.includes('calltelemetry'))
28
+ continue;
29
+ images.push(match[1]);
30
+ }
31
+ }
32
+ return images;
33
+ }
34
+ /**
35
+ * Validate a bundle file without extracting.
36
+ * Checks: file exists, is a valid tar.gz, disk space for extraction.
37
+ */
38
+ export async function validateBundle(bundlePath) {
39
+ if (!existsSync(bundlePath)) {
40
+ return { valid: false, error: `Bundle file not found: ${bundlePath}` };
41
+ }
42
+ // Check it's a valid tar.gz
43
+ try {
44
+ await exec('tar', ['-tzf', bundlePath], { stdout: 'pipe', stderr: 'pipe' });
45
+ }
46
+ catch {
47
+ return { valid: false, error: 'Bundle is not a valid tar.gz archive' };
48
+ }
49
+ // Check disk space (need at least 2x bundle size for extraction)
50
+ const bundleSize = statSync(bundlePath).size;
51
+ const { installDir } = getPaths();
52
+ const disk = await checkDiskSpace(installDir);
53
+ if (!disk.ok) {
54
+ return { valid: false, error: `Low disk space: ${disk.freePercent}% free (need 10%+)` };
55
+ }
56
+ return { valid: true };
57
+ }
58
+ /**
59
+ * Inspect a bundle's contents without fully extracting.
60
+ * Uses tar listing + selective extract of docker-compose.yml only.
61
+ */
62
+ export async function inspectBundle(bundlePath) {
63
+ const sizeBytes = statSync(bundlePath).size;
64
+ // List tar contents
65
+ const result = await exec('tar', ['-tzf', bundlePath], {
66
+ stdout: 'pipe',
67
+ stderr: 'pipe',
68
+ });
69
+ const entries = String(result.stdout ?? '').split('\n').filter(Boolean);
70
+ // Normalize paths (strip leading directory component to match --strip-components=1)
71
+ const normalized = entries.map((e) => {
72
+ const parts = e.split('/');
73
+ return parts.length > 1 ? parts.slice(1).join('/') : e;
74
+ }).filter(Boolean);
75
+ // Identify config files
76
+ const knownConfigs = ['docker-compose.yml', 'Caddyfile', 'cli.sh', 'nats.conf'];
77
+ const configFiles = knownConfigs.filter(f => normalized.some((n) => n === f || n.endsWith(`/${f}`)));
78
+ // Check for images.tar
79
+ const hasImages = normalized.some((n) => n === 'images.tar');
80
+ // Extract version from bundle filename
81
+ const versionMatch = bundlePath.match(/calltelemetry-(?:bundle|offline)-([^\s/]+?)\.tar\.gz$/);
82
+ const version = versionMatch ? versionMatch[1] : null;
83
+ // Try to extract docker-compose.yml to parse image names
84
+ let imageNames = [];
85
+ if (configFiles.includes('docker-compose.yml')) {
86
+ const tmpDir = `/tmp/ct-inspect-${process.pid}`;
87
+ try {
88
+ await mkdir(tmpDir, { recursive: true });
89
+ // Extract just docker-compose.yml
90
+ await exec('tar', ['-xzf', bundlePath, '-C', tmpDir, '--strip-components=1',
91
+ '--include=*/docker-compose.yml', '--include=docker-compose.yml'], {
92
+ stdout: 'pipe',
93
+ stderr: 'pipe',
94
+ });
95
+ const composePath = join(tmpDir, 'docker-compose.yml');
96
+ if (existsSync(composePath)) {
97
+ const content = readFileSync(composePath, 'utf-8');
98
+ imageNames = extractImageNames(content, 'all');
99
+ }
100
+ }
101
+ catch {
102
+ debug('Could not extract docker-compose.yml for inspection');
103
+ }
104
+ finally {
105
+ await rm(tmpDir, { recursive: true, force: true });
106
+ }
107
+ }
108
+ // Check for prometheus/grafana dirs
109
+ if (normalized.some((n) => n.startsWith('prometheus/')))
110
+ configFiles.push('prometheus/');
111
+ if (normalized.some((n) => n.startsWith('grafana/')))
112
+ configFiles.push('grafana/');
113
+ return {
114
+ version,
115
+ configFiles,
116
+ hasImages,
117
+ imageNames,
118
+ sizeBytes,
119
+ sizeLabel: formatBytes(sizeBytes),
120
+ };
121
+ }
122
+ // ─── Fetch Steps (config-only bundle) ───────────────────────────────────────
123
+ export function fetchSteps(version) {
124
+ return [
125
+ {
126
+ label: 'Download config bundle',
127
+ run: async (ctx) => {
128
+ const { gcsBundleBaseUrl } = getPaths();
129
+ ctx?.log(`Downloading from ${gcsBundleBaseUrl}/${version}/`);
130
+ await downloadBundle(version, { quiet: true });
131
+ ctx?.log('Extracted docker-compose.yml, configs, and supporting files');
132
+ return version;
133
+ },
134
+ },
135
+ {
136
+ label: 'Verify checksum',
137
+ run: async (ctx) => {
138
+ const { gcsBundleBaseUrl, installDir } = getPaths();
139
+ const bundleFile = `calltelemetry-bundle-${version}.tar.gz`;
140
+ const checksumUrl = `${gcsBundleBaseUrl}/${version}/${bundleFile}.sha256`;
141
+ try {
142
+ await execRetry('curl', ['-sfL', checksumUrl, '-o', `${bundleFile}.sha256`], {
143
+ cwd: installDir,
144
+ });
145
+ await exec('sha256sum', ['-c', `${bundleFile}.sha256`], { cwd: installDir });
146
+ ctx?.log('SHA256 checksum verified');
147
+ await rm(join(installDir, `${bundleFile}.sha256`), { force: true });
148
+ return 'verified';
149
+ }
150
+ catch {
151
+ ctx?.log('Checksum not available — skipped');
152
+ return 'skipped';
153
+ }
154
+ },
155
+ },
156
+ ];
157
+ }
158
+ // ─── Download Steps (full offline bundle with Docker images) ────────────────
159
+ export function downloadSteps(version) {
160
+ const configBundle = `calltelemetry-bundle-${version}.tar.gz`;
161
+ const bundleDir = `calltelemetry-offline-${version}`;
162
+ const bundleName = `calltelemetry-offline-${version}.tar.gz`;
163
+ return [
164
+ {
165
+ label: 'Download config bundle',
166
+ run: async (ctx) => {
167
+ const { gcsBundleBaseUrl } = getPaths();
168
+ const bundleUrl = `${gcsBundleBaseUrl}/${version}/${configBundle}`;
169
+ ctx?.log(`Downloading from ${bundleUrl}`);
170
+ await execRetry('curl', ['-fsSL', bundleUrl, '-o', configBundle], {
171
+ retries: 2,
172
+ retryDelay: 3000,
173
+ });
174
+ return 'downloaded';
175
+ },
176
+ },
177
+ {
178
+ label: 'Extract config bundle',
179
+ run: async (ctx) => {
180
+ await rm(bundleDir, { recursive: true, force: true });
181
+ await mkdir(bundleDir, { recursive: true });
182
+ await exec('tar', ['-xzf', configBundle, '-C', bundleDir, '--strip-components=1']);
183
+ await rm(configBundle, { force: true });
184
+ ctx?.log(`Extracted to ${bundleDir}/`);
185
+ return 'extracted';
186
+ },
187
+ },
188
+ {
189
+ label: 'Pull Docker images',
190
+ run: async (ctx) => {
191
+ const composePath = join(bundleDir, 'docker-compose.yml');
192
+ if (!existsSync(composePath)) {
193
+ throw new Error('docker-compose.yml not found in bundle');
194
+ }
195
+ const content = readFileSync(composePath, 'utf-8');
196
+ const images = extractImageNames(content, 'all');
197
+ ctx?.log(`Found ${images.length} images to pull`);
198
+ let pulled = 0;
199
+ for (const img of images) {
200
+ ctx?.log(`Pulling ${img} (${pulled + 1}/${images.length})...`);
201
+ try {
202
+ await exec('docker', ['pull', img]);
203
+ pulled++;
204
+ }
205
+ catch {
206
+ ctx?.log(`Warning: Failed to pull ${img}`);
207
+ }
208
+ }
209
+ return `${pulled}/${images.length} images pulled`;
210
+ },
211
+ },
212
+ {
213
+ label: 'Save Docker images',
214
+ run: async (ctx) => {
215
+ const composePath = join(bundleDir, 'docker-compose.yml');
216
+ const content = readFileSync(composePath, 'utf-8');
217
+ const images = extractImageNames(content, 'all');
218
+ ctx?.log(`Saving ${images.length} images to images.tar...`);
219
+ await exec('docker', ['save', ...images, '-o', join(bundleDir, 'images.tar')]);
220
+ const size = statSync(join(bundleDir, 'images.tar')).size;
221
+ return formatBytes(size);
222
+ },
223
+ },
224
+ {
225
+ label: 'Create offline archive',
226
+ run: async (ctx) => {
227
+ ctx?.log(`Archiving ${bundleDir}/ → ${bundleName}`);
228
+ await exec('tar', ['-czf', bundleName, bundleDir]);
229
+ await rm(bundleDir, { recursive: true, force: true });
230
+ const size = statSync(bundleName).size;
231
+ ctx?.log(`Archive size: ${formatBytes(size)}`);
232
+ return bundleName;
233
+ },
234
+ },
235
+ ];
236
+ }
237
+ // ─── Apply Steps (install offline bundle) ───────────────────────────────────
238
+ export function applySteps(bundlePath) {
239
+ const extractDir = `offline-extract-${process.pid}`;
240
+ return [
241
+ {
242
+ label: 'Validate bundle',
243
+ run: async (ctx) => {
244
+ const result = await validateBundle(bundlePath);
245
+ if (!result.valid)
246
+ throw new Error(result.error);
247
+ const size = statSync(bundlePath).size;
248
+ ctx?.log(`Bundle valid: ${formatBytes(size)}`);
249
+ return 'valid';
250
+ },
251
+ },
252
+ {
253
+ label: 'Extract bundle',
254
+ run: async (ctx) => {
255
+ await mkdir(extractDir, { recursive: true });
256
+ ctx?.log(`Extracting to ${extractDir}/`);
257
+ await exec('tar', ['-xzf', bundlePath, '-C', extractDir, '--strip-components=1']);
258
+ return 'extracted';
259
+ },
260
+ },
261
+ {
262
+ label: 'Load Docker images',
263
+ run: async (ctx) => {
264
+ const imagesFile = join(extractDir, 'images.tar');
265
+ if (!existsSync(imagesFile)) {
266
+ ctx?.log('No images.tar found — config-only bundle');
267
+ return 'skipped';
268
+ }
269
+ const size = statSync(imagesFile).size;
270
+ ctx?.log(`Loading images (${formatBytes(size)})...`);
271
+ await exec('docker', ['load', '-i', imagesFile]);
272
+ return 'loaded';
273
+ },
274
+ },
275
+ {
276
+ label: 'Install configuration',
277
+ run: async (ctx) => {
278
+ const { installDir, backupDir } = getPaths();
279
+ await mkdir(backupDir, { recursive: true });
280
+ const configFiles = ['docker-compose.yml', 'Caddyfile', 'cli.sh', 'nats.conf'];
281
+ let installed = 0;
282
+ for (const file of configFiles) {
283
+ const src = join(extractDir, file);
284
+ if (!existsSync(src))
285
+ continue;
286
+ const dest = join(installDir, file);
287
+ if (existsSync(dest)) {
288
+ await copyFile(dest, join(backupDir, `${file}.backup`));
289
+ ctx?.log(`Backed up ${file}`);
290
+ }
291
+ await copyFile(src, dest);
292
+ ctx?.log(`Installed ${file}`);
293
+ installed++;
294
+ }
295
+ // Copy prometheus/grafana directories if present
296
+ const promSrc = join(extractDir, 'prometheus');
297
+ if (existsSync(promSrc)) {
298
+ const promDest = join(installDir, 'prometheus');
299
+ await mkdir(promDest, { recursive: true });
300
+ try {
301
+ await exec('cp', ['-r', `${promSrc}/.`, promDest]);
302
+ }
303
+ catch {
304
+ try {
305
+ await exec('sudo', ['cp', '-r', `${promSrc}/.`, promDest]);
306
+ }
307
+ catch { /* skip */ }
308
+ }
309
+ ctx?.log('Installed prometheus/');
310
+ installed++;
311
+ }
312
+ const grafanaSrc = join(extractDir, 'grafana');
313
+ if (existsSync(grafanaSrc)) {
314
+ const grafanaDest = join(installDir, 'grafana');
315
+ await mkdir(grafanaDest, { recursive: true });
316
+ try {
317
+ await exec('cp', ['-r', `${grafanaSrc}/.`, grafanaDest]);
318
+ }
319
+ catch {
320
+ try {
321
+ await exec('sudo', ['cp', '-r', `${grafanaSrc}/.`, grafanaDest]);
322
+ }
323
+ catch { /* skip */ }
324
+ }
325
+ ctx?.log('Installed grafana/');
326
+ installed++;
327
+ }
328
+ return `${installed} files installed`;
329
+ },
330
+ },
331
+ {
332
+ label: 'Restart services',
333
+ run: async (ctx) => {
334
+ ctx?.log('Restarting services...');
335
+ try {
336
+ await exec('systemctl', ['restart', 'docker-compose-app.service']);
337
+ ctx?.log('Restarted via systemctl');
338
+ }
339
+ catch {
340
+ ctx?.log('systemctl failed, using docker-compose up');
341
+ await composeUp(['-d']);
342
+ }
343
+ // Cleanup extract dir
344
+ await rm(extractDir, { recursive: true, force: true });
345
+ return 'done';
346
+ },
347
+ },
348
+ ];
349
+ }
350
+ //# sourceMappingURL=offline-steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline-steps.js","sourceRoot":"","sources":["../../src/lib/offline-steps.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  export interface Preferences {
2
2
  autoUpdate: boolean;
3
+ ipv6: boolean;
3
4
  }
4
5
  /**
5
6
  * Load preferences from ~/.ct/preferences.json.
@@ -1 +1 @@
1
- {"version":3,"file":"prefs.d.ts","sourceRoot":"","sources":["../../src/lib/prefs.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAOD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,WAAW,GAAG,IAAI,CAU9C;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAQlD;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,WAAW,CAEtC"}
1
+ {"version":3,"file":"prefs.d.ts","sourceRoot":"","sources":["../../src/lib/prefs.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;CACf;AAOD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,WAAW,GAAG,IAAI,CAU9C;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAQlD;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,WAAW,CAEtC"}
package/dist/lib/prefs.js CHANGED
@@ -4,7 +4,7 @@ import { homedir } from 'node:os';
4
4
  import { debug } from './log.js';
5
5
  const PREFS_DIR = join(homedir(), '.ct');
6
6
  const PREFS_FILE = join(PREFS_DIR, 'preferences.json');
7
- const DEFAULTS = { autoUpdate: false };
7
+ const DEFAULTS = { autoUpdate: false, ipv6: false };
8
8
  /**
9
9
  * Load preferences from ~/.ct/preferences.json.
10
10
  * Returns null if the file doesn't exist (first run).
@@ -1 +1 @@
1
- {"version":3,"file":"prefs.js","sourceRoot":"","sources":["../../src/lib/prefs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAMjC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;AACzC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;AAEvD,MAAM,QAAQ,GAAgB,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAEpD;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;IACpC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC1C,IAAI,CAAC;QACH,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1E,KAAK,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,SAAS,EAAE,IAAI,QAAQ,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"prefs.js","sourceRoot":"","sources":["../../src/lib/prefs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAOjC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;AACzC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;AAEvD,MAAM,QAAQ,GAAgB,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAEjE;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;IACpC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC1C,IAAI,CAAC;QACH,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1E,KAAK,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,SAAS,EAAE,IAAI,QAAQ,CAAC;AACjC,CAAC"}
package/dist/lib/rpc.d.ts CHANGED
@@ -6,6 +6,9 @@ export interface AppHealthDetail {
6
6
  rpc: boolean;
7
7
  dbConnected: boolean;
8
8
  overall: 'healthy' | 'degraded' | 'down';
9
+ apiError?: string;
10
+ rpcError?: string;
11
+ dbError?: string;
9
12
  }
10
13
  export declare function getAppHealth(): Promise<AppHealthDetail>;
11
14
  export declare function getReleaseBin(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../src/lib/rpc.ts"],"names":[],"mappings":"AAIA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGvD;AAED,wBAAsB,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9C;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAOpD;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;CAC1C;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC,CAmB7D;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../src/lib/rpc.ts"],"names":[],"mappings":"AAIA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGvD;AAED,wBAAsB,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9C;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAOpD;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC,CAwC7D;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
package/dist/lib/rpc.js CHANGED
@@ -23,15 +23,37 @@ export async function healthCheck() {
23
23
  }
24
24
  }
25
25
  export async function getAppHealth() {
26
+ let apiError;
27
+ let rpcError;
28
+ let dbError;
26
29
  const [api, rpc_ok, db] = await Promise.all([
27
- healthCheck(),
28
- rpcOk(),
30
+ (async () => {
31
+ try {
32
+ const result = await composeExec('web', ['curl', '-sf', 'http://127.0.0.1:4080/healthz'], { pipe: true });
33
+ return result.exitCode === 0;
34
+ }
35
+ catch (err) {
36
+ apiError = err.stderr?.trim() || err.message || 'Health check failed';
37
+ return false;
38
+ }
39
+ })(),
40
+ (async () => {
41
+ try {
42
+ const output = await rpc('IO.puts("ok")');
43
+ return output.includes('ok');
44
+ }
45
+ catch (err) {
46
+ rpcError = err.stderr?.trim() || err.message || 'RPC connection failed';
47
+ return false;
48
+ }
49
+ })(),
29
50
  (async () => {
30
51
  try {
31
52
  const out = await rpc(':ok = Ecto.Adapters.SQL.query!(Cdrcisco.Repo, "SELECT 1") |> elem(0) |> IO.inspect()');
32
53
  return out.includes('ok');
33
54
  }
34
- catch {
55
+ catch (err) {
56
+ dbError = err.stderr?.trim() || err.message || 'Database query failed';
35
57
  return false;
36
58
  }
37
59
  })(),
@@ -41,7 +63,7 @@ export async function getAppHealth() {
41
63
  overall = 'healthy';
42
64
  else if (api || rpc_ok)
43
65
  overall = 'degraded';
44
- return { api, rpc: rpc_ok, dbConnected: db, overall };
66
+ return { api, rpc: rpc_ok, dbConnected: db, overall, apiError, rpcError, dbError };
45
67
  }
46
68
  export function getReleaseBin() {
47
69
  return RELEASE_BIN;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../src/lib/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,GAAG,6BAA6B,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAY;IACpC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACpF,OAAO,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,+BAA+B,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1G,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC1C,WAAW,EAAE;QACb,KAAK,EAAE;QACP,CAAC,KAAK,IAAI,EAAE;YACV,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,sFAAsF,CAAC,CAAC;gBAC9G,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC,CAAC,EAAE;KACL,CAAC,CAAC;IAEH,IAAI,OAAO,GAA+B,MAAM,CAAC;IACjD,IAAI,GAAG,IAAI,MAAM,IAAI,EAAE;QAAE,OAAO,GAAG,SAAS,CAAC;SACxC,IAAI,GAAG,IAAI,MAAM;QAAE,OAAO,GAAG,UAAU,CAAC;IAE7C,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../src/lib/rpc.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,11 @@ export interface ServiceInfo {
7
7
  status: string;
8
8
  }
9
9
  export declare function getServiceList(): Promise<ServiceInfo[]>;
10
+ export interface ServiceListResult {
11
+ services: ServiceInfo[];
12
+ error?: string;
13
+ }
14
+ export declare function getServiceListSafe(): Promise<ServiceListResult>;
10
15
  export declare function startService(name: string): Promise<import("execa").Result<{
11
16
  cwd: string;
12
17
  stdin: "pipe" | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/lib/services.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAkB7D;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM;;;;;IAE9C;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM;;;;;IAE7C;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM;;;;;IAEhD;AAED,wBAAsB,gBAAgB;;;;IAErC;AAED,wBAAsB,eAAe;;;;;IAEpC"}
1
+ {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/lib/services.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAkB7D;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAqBrE;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM;;;;;IAE9C;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM;;;;;IAE7C;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM;;;;;IAEhD;AAED,wBAAsB,gBAAgB;;;;IAErC;AAED,wBAAsB,eAAe;;;;;IAEpC"}
@@ -18,6 +18,30 @@ export async function getServiceList() {
18
18
  };
19
19
  });
20
20
  }
21
+ export async function getServiceListSafe() {
22
+ try {
23
+ const services = await getServiceList();
24
+ return { services };
25
+ }
26
+ catch (err) {
27
+ const stderr = err.stderr?.trim() ?? '';
28
+ const msg = err.message ?? 'Unknown error';
29
+ let error;
30
+ if (stderr.includes('Cannot connect to the Docker daemon') || msg.includes('Cannot connect to the Docker daemon')) {
31
+ error = 'Docker daemon is not running';
32
+ }
33
+ else if (stderr.includes('no configuration file provided') || stderr.includes('no such file or directory')) {
34
+ error = 'Docker Compose file not found';
35
+ }
36
+ else if (stderr.includes('permission denied') || msg.includes('permission denied')) {
37
+ error = 'Permission denied accessing Docker';
38
+ }
39
+ else {
40
+ error = stderr || msg;
41
+ }
42
+ return { services: [], error };
43
+ }
44
+ }
21
45
  export async function startService(name) {
22
46
  return compose(['start', name], { pipe: true });
23
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/lib/services.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAWlD,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IAEpB,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;SACnB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC3B,GAAG,CAAC,IAAI,CAAC,EAAE;QACV,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,OAAO;YACL,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE;YAC1B,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE;YACtB,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;YACxB,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE;YACtB,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE;YACtB,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;SACzB,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,OAAO,OAAO,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,OAAO,OAAO,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,OAAO,OAAO,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,OAAO,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC"}
1
+ {"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/lib/services.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /** Minimal step context — compatible with the TUI's StepContext. */
2
+ export interface StepContext {
3
+ log: (line: string) => void;
4
+ }
5
+ /** A single pipeline step. Same shape as the TUI's Step interface. */
6
+ export interface UpdateStep {
7
+ label: string;
8
+ run: (ctx?: StepContext) => Promise<string | void>;
9
+ }
10
+ export declare function preflightSteps(targetVersion: string): UpdateStep[];
11
+ export declare function executeSteps(targetVersion: string): UpdateStep[];
12
+ /**
13
+ * Run a list of steps sequentially with console output.
14
+ * Used by `commands/update.ts` to run the same pipeline as the TUI.
15
+ */
16
+ export declare function runStepsCli(steps: UpdateStep[]): Promise<void>;
17
+ //# sourceMappingURL=update-steps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-steps.d.ts","sourceRoot":"","sources":["../../src/lib/update-steps.ts"],"names":[],"mappings":"AAYA,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,sEAAsE;AACtE,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACpD;AAID,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,EAAE,CA8BlE;AAID,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,EAAE,CAgGhE;AAID;;;GAGG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAepE"}