feat: install.sh + auto-update checker for CLI
- tools/install.sh: standalone installer/upgrader, curl-pipe safe (main() wrapper, process.argv instead of stdin, mkdir -p prefix) - packages/mosaic/src/runtime/update-checker.ts: version check module with 1h cache at ~/.cache/mosaic/update-check.json - CLI startup: non-blocking background update check on every invocation - 'mosaic update' command: explicit check + install (--check for CI) - session-start.sh: warns agents when CLI is outdated - Proper semver comparison including pre-release precedence - eslint: allow __tests__ in packages/mosaic for projectService
This commit is contained in:
@@ -10,6 +10,14 @@ import { registerPrdyCommand } from './commands/prdy.js';
|
||||
const _require = createRequire(import.meta.url);
|
||||
const CLI_VERSION: string = (_require('../package.json') as { version: string }).version;
|
||||
|
||||
// Fire-and-forget update check at startup (non-blocking, cached 1h)
|
||||
try {
|
||||
const { backgroundUpdateCheck } = await import('@mosaic/mosaic');
|
||||
backgroundUpdateCheck();
|
||||
} catch {
|
||||
// Silently ignore — update check is best-effort
|
||||
}
|
||||
|
||||
const program = new Command();
|
||||
|
||||
program.name('mosaic').description('Mosaic Stack CLI').version(CLI_VERSION);
|
||||
@@ -297,6 +305,52 @@ if (qrCmd !== undefined) {
|
||||
program.addCommand(qrCmd as unknown as Command);
|
||||
}
|
||||
|
||||
// ─── update ─────────────────────────────────────────────────────────────
|
||||
|
||||
program
|
||||
.command('update')
|
||||
.description('Check for and install Mosaic CLI updates')
|
||||
.option('--check', 'Check only, do not install')
|
||||
.action(async (opts: { check?: boolean }) => {
|
||||
const { checkForUpdate, formatUpdateNotice } = await import('@mosaic/mosaic');
|
||||
const { execSync } = await import('node:child_process');
|
||||
|
||||
console.log('Checking for updates…');
|
||||
const result = checkForUpdate({ skipCache: true });
|
||||
|
||||
if (!result.latest) {
|
||||
console.error('Could not reach the Mosaic registry.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(` Installed: ${result.current || '(none)'}`);
|
||||
console.log(` Latest: ${result.latest}`);
|
||||
|
||||
if (!result.updateAvailable) {
|
||||
console.log('\n✔ Up to date.');
|
||||
return;
|
||||
}
|
||||
|
||||
const notice = formatUpdateNotice(result);
|
||||
if (notice) console.log(notice);
|
||||
|
||||
if (opts.check) {
|
||||
process.exit(2); // Signal to callers that an update exists
|
||||
}
|
||||
|
||||
console.log('Installing update…');
|
||||
try {
|
||||
execSync(
|
||||
'npm install -g @mosaic/cli@latest --registry=https://git.mosaicstack.dev/api/packages/mosaic/npm/',
|
||||
{ stdio: 'inherit', timeout: 60_000 },
|
||||
);
|
||||
console.log('\n✔ Updated successfully.');
|
||||
} catch {
|
||||
console.error('\nUpdate failed. Try manually: bash tools/install.sh');
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
// ─── wizard ─────────────────────────────────────────────────────────────
|
||||
|
||||
program
|
||||
|
||||
Reference in New Issue
Block a user