fix(cli): make uipro update upgrade CLI via npm

Approved by github-maintain cron-safe review. Supersedes #326.
This commit is contained in:
Alexander 2026-06-25 05:18:09 -04:00 committed by GitHub
parent 3a12b63bd8
commit 4ab70389b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 7 deletions

View File

@ -33,7 +33,7 @@ uipro init --force # Overwrite existing files
# Other commands
uipro versions # List available versions
uipro update # Refresh skill files from installed CLI package
uipro update # Update the global CLI to the latest release
```
## GitHub Authentication
@ -63,13 +63,15 @@ uipro init
## How It Works
`uipro init` generates assistant-specific files from the templates bundled with the installed CLI package. To get newer templates and data, update the package first:
`uipro init` generates assistant-specific files from the templates bundled with the installed CLI package. To get newer templates and data, update the package, then regenerate:
```bash
npm install -g uipro-cli@latest
uipro init --ai codex
uipro update # updates the global CLI to the latest release
uipro init --ai codex --force # regenerate skill files from the new package
```
`uipro update` runs `npm install -g uipro-cli@latest` for you (it shells out to `npm` only on Windows, where `npm` is a `.cmd`). You can still run that command manually if you prefer. When the CLI is already current, `uipro update` just refreshes the installed skill files.
## Development
```bash

View File

@ -1,3 +1,4 @@
import { execFileSync } from 'node:child_process';
import { readFile } from 'node:fs/promises';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
@ -38,9 +39,38 @@ export async function updateCommand(options: UpdateOptions): Promise<void> {
if (currentVersion !== latestVersion) {
console.log();
logger.warn(`Installed CLI package is ${chalk.cyan(currentVersion)}, but latest release is ${chalk.cyan(release.tag_name)}.`);
logger.info(`Update the CLI package first: ${chalk.cyan(`npm install -g uipro-cli@${latestVersion}`)}`);
logger.info('Then rerun: uipro init --ai <platform>');
// Only auto-run with a well-formed semver, so nothing unexpected can
// reach the shell that npm.cmd requires on Windows.
if (!/^\d+\.\d+\.\d+([.-][0-9A-Za-z.-]+)?$/.test(latestVersion)) {
logger.warn(`Installed CLI is ${chalk.cyan(currentVersion)}; latest release is ${chalk.cyan(release.tag_name)}.`);
logger.info(`Update the CLI package: ${chalk.cyan(`npm install -g uipro-cli@${latestVersion}`)}`);
logger.info('Then rerun: uipro init --ai <platform> --force');
return;
}
logger.info(`Updating CLI from ${chalk.cyan(currentVersion)} to ${chalk.cyan(latestVersion)}...`);
console.log();
const isWindows = process.platform === 'win32';
try {
// execFileSync with an explicit args array — no shell string to expand.
// On Windows npm is npm.cmd, which Node only spawns via a shell.
execFileSync(
isWindows ? 'npm.cmd' : 'npm',
['install', '-g', `uipro-cli@${latestVersion}`],
{ stdio: 'inherit', shell: isWindows }
);
} catch {
console.log();
logger.error('Automatic update failed (you may need elevated/admin permissions).');
logger.info(`Update manually: ${chalk.cyan(`npm install -g uipro-cli@${latestVersion}`)}`);
process.exit(1);
}
console.log();
logger.success(`Updated to ${chalk.cyan(latestVersion)}.`);
logger.info(`Now rerun ${chalk.cyan('uipro init --ai <platform> --force')} to refresh your skill files.`);
return;
}