()
| 236 | * the second run (with fresh cache) shows it — zero startup delay. |
| 237 | */ |
| 238 | export async function checkForUpdatesInteractive(): Promise<void> { |
| 239 | if (!process.stdin.isTTY || process.env.CI || isDevEnvironment()) return |
| 240 | |
| 241 | const currentVersion = getVersion() |
| 242 | const cache = readCache() |
| 243 | |
| 244 | // Kick off background refresh if cache is missing or stale |
| 245 | if (!cache || Date.now() - cache.lastCheckTime >= CACHE_STALE_MS) { |
| 246 | refreshCacheInBackground(cache) |
| 247 | } |
| 248 | |
| 249 | // Prompt is based on cached data only — no network wait |
| 250 | const latestVersion = cache?.latestVersion |
| 251 | if (!latestVersion || !isNewerVersion(latestVersion, currentVersion)) return |
| 252 | if (cache?.skippedVersion === latestVersion) return |
| 253 | |
| 254 | const choice = await promptUser(` ✨ Update available! ${currentVersion} → ${latestVersion}`, [ |
| 255 | `Update now (runs \`npm install -g ${PACKAGE_NAME}\`)`, |
| 256 | 'Skip', |
| 257 | 'Skip until next version', |
| 258 | ]) |
| 259 | |
| 260 | if (choice === 1) { |
| 261 | const result = await performCliSelfUpdate() |
| 262 | if (result.success) { |
| 263 | process.stderr.write( |
| 264 | ` \x1b[32m🎉 Updated successfully! Please restart chatlab to use the new version.\x1b[0m\n\n` |
| 265 | ) |
| 266 | process.exit(0) |
| 267 | } else { |
| 268 | process.stderr.write(` ❌ Update failed: ${result.error}\n\n`) |
| 269 | } |
| 270 | } else if (choice === 3) { |
| 271 | writeCache({ |
| 272 | lastCheckTime: Date.now(), |
| 273 | latestVersion, |
| 274 | skippedVersion: latestVersion, |
| 275 | }) |
| 276 | } |
| 277 | } |
no test coverage detected