Conversation
- Check latest version from npm registry - Show current vs. latest version comparison - Prompt to update if newer version available - Auto-detect package manager (npm/yarn/pnpm) - Support --check flag for check-only mode - Graceful handling of offline/unreachable registry - Works across npm, yarn, pnpm global installs Closes #55
There was a problem hiding this comment.
Pull request overview
Adds a new clawatch update command to the CLI to check the npm registry for newer releases and (optionally) perform a global upgrade via the detected package manager.
Changes:
- Introduces an
updatecommand with a--checkmode. - Fetches the latest published version and prompts before running a global update/install command.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| // 1. Fetch latest version from npm registry | ||
| console.log(chalk.gray(' Checking npm registry...')); | ||
| let latestVersion: string; | ||
| try { | ||
| latestVersion = execSync('npm view clawatch version 2>/dev/null', { encoding: 'utf-8' }).trim(); | ||
| } catch { | ||
| console.log(chalk.red('\n ❌ Could not reach npm registry.')); | ||
| console.log(chalk.yellow(' Check your internet connection and try again.\n')); | ||
| process.exit(1); | ||
| } |
There was a problem hiding this comment.
The update check shells out to npm before any package-manager detection. If npm isn't installed/available (but pnpm/yarn is), clawatch update will always exit with “Could not reach npm registry”. Consider detecting an available package manager first and then querying the registry with that tool (or do a direct HTTPS registry request) so the command works in non-npm setups.
| try { | ||
| latestVersion = execSync('npm view clawatch version 2>/dev/null', { encoding: 'utf-8' }).trim(); |
There was a problem hiding this comment.
Using shell redirection (2>/dev/null) inside execSync(...) is not portable (e.g., Windows uses 2>nul) and also implicitly relies on a shell. Prefer passing stdio options (e.g., ignore stderr) or using execFileSync with arguments to avoid shell-specific syntax.
| // 2. Compare versions | ||
| if (currentVersion === latestVersion) { | ||
| console.log(chalk.green('\n ✅ Already on the latest version!\n')); | ||
| process.exit(0); | ||
| } | ||
|
|
||
| console.log(chalk.yellow(`\n ⬆️ Update available: ${currentVersion} → ${latestVersion}`)); | ||
|
|
There was a problem hiding this comment.
The version comparison only checks string equality. If the user is on a newer pre-release/dev build (or a different tag), this will still report an “update available” and potentially trigger a downgrade when running the install step. Consider doing a proper semver comparison (and handling non-semver strings) so you only offer an update when latest > current, and show a separate message when the current version is ahead.
| const npmGlobalPrefix = execSync('npm prefix -g 2>/dev/null', { encoding: 'utf-8' }).trim(); | ||
| const npmGlobalModules = path.join(npmGlobalPrefix, 'lib', 'node_modules', 'clawatch'); | ||
| if (fs.existsSync(npmGlobalModules)) { | ||
| return { manager: 'npm', command: 'npm update -g clawatch' }; | ||
| } |
There was a problem hiding this comment.
These execSync calls include shell redirection (2>/dev/null) which isn’t portable and can break detection depending on the user’s shell/OS (same pattern appears in the yarn/pnpm checks below). Prefer suppressing stderr via execSync stdio options or using execFileSync rather than embedding redirects in the command string.
| try { | ||
| const yarnGlobalDir = execSync('yarn global dir 2>/dev/null', { encoding: 'utf-8' }).trim(); | ||
| if (yarnGlobalDir && fs.existsSync(path.join(yarnGlobalDir, 'node_modules', 'clawatch'))) { | ||
| return { manager: 'yarn', command: 'yarn global upgrade clawatch' }; | ||
| } |
There was a problem hiding this comment.
The yarn probe uses shell redirection (2>/dev/null) in the execSync command string. This isn’t portable across platforms/shells; prefer suppressing stderr via execSync stdio options or switching to execFileSync with args.
| try { | ||
| const pnpmGlobalDir = execSync('pnpm root -g 2>/dev/null', { encoding: 'utf-8' }).trim(); | ||
| if (pnpmGlobalDir && fs.existsSync(path.join(pnpmGlobalDir, 'clawatch'))) { | ||
| return { manager: 'pnpm', command: 'pnpm update -g clawatch' }; |
There was a problem hiding this comment.
The pnpm probe uses 2>/dev/null in the command string, which is Unix-shell specific and can break detection depending on OS/shell. Prefer suppressing stderr via execSync stdio options or use execFileSync with args.
| // Fallback: try npm if it exists | ||
| try { | ||
| execSync('npm --version 2>/dev/null', { encoding: 'utf-8' }); | ||
| return { manager: 'npm', command: 'npm install -g clawatch@latest' }; |
There was a problem hiding this comment.
This probe also uses shell redirection (2>/dev/null). To keep the fallback detection cross-platform, prefer configuring stdio to ignore stderr (or use execFileSync('npm', ['--version'])) instead of relying on shell-specific redirect syntax.
Summary
Adds a
clawatch updateCLI command that lets users self-update without leaving the tool.What it does
--checkflag: Check-only mode — shows if an update is available without installingUsage
Acceptance Criteria from #55
clawatch updateexistsCloses #55