diff --git a/docs/specs/claude-version-management/installation-and-versioning.md b/docs/specs/claude-version-management/installation-and-versioning.md index 4da7adf0..ee894ad2 100644 --- a/docs/specs/claude-version-management/installation-and-versioning.md +++ b/docs/specs/claude-version-management/installation-and-versioning.md @@ -106,37 +106,72 @@ Claude Code has deprecated npm installation and now requires native installation 3. **Version Checking on Agent Execution**: - Before `claude.run()`: Check installed version vs supported version + **Scenario 0: Below Minimum Version** (user version < minimum supported version — hard block): + ``` + ✗ Claude Code v2.0.10 is no longer supported + Minimum required version: v2.0.30 + Recommended version: v2.1.25 (recommended) + + This version is known to be incompatible with CodeMie and must be upgraded. + + ? What would you like to do? (Use arrow keys) + ❯ Install v2.1.25 now and continue + Exit + ``` + - If **Install**: Installs the supported version and proceeds with agent execution + - If **Exit**: Prints manual update command and exits with code 0: + ``` + If you want to update manually, run: + codemie update claude + ``` + **Scenario 1: Newer Untested Version** (user version > supported version): ``` ⚠️ WARNING: You are running Claude Code v2.0.45 - CodeMie has only tested and verified Claude Code v2.0.30 + CodeMie has only tested and verified Claude Code v2.0.30 - Running a newer version may cause compatibility issues with the CodeMie backend proxy. + Running a newer version may cause compatibility issues with the CodeMie backend proxy. - To install the supported version, run: - codemie install claude --supported + To install the supported version, run: + codemie install claude --supported - Or install a specific version: - codemie install claude 2.0.30 + Or install a specific version: + codemie install claude 2.0.30 - Continue anyway? [y/N]: + ? What would you like to do? (Use arrow keys) + ❯ Install v2.0.30 now and continue + Continue with current version + Exit ``` - - Exit code 1 if user declines (non-zero exit) - - Proceed if user confirms - + - If **Install**: Installs the supported version and proceeds + - If **Continue**: Proceeds with the currently installed (newer) version + - If **Exit**: Prints install commands and exits with code 0: + ``` + To install the supported version, run: + codemie install claude --supported + + Or install a specific version: + codemie install claude 2.0.30 + ``` + **Scenario 2: Update Available** (newer supported version exists, current version compatible): ``` ℹ️ A new supported version of Claude Code is available! Current version: v2.1.20 Latest version: v2.1.22 (recommended) - To update, run: + ? What would you like to do? (Use arrow keys) + ❯ Install v2.1.22 now and continue + Continue with current version + Exit + ``` + - If **Install**: Installs the supported version and proceeds + - If **Continue**: Proceeds with the currently installed version + - If **Exit**: Prints manual update command and exits with code 0: + ``` + If you want to update manually, run: codemie update claude - - Continue with current version? [Y/n]: ``` - - Exit code 1 if user declines (non-zero exit) - - Proceed if user confirms (default: yes) **User-Facing Output**: - Success: "Claude Code v2.0.30 installed successfully ✓" @@ -273,11 +308,13 @@ export class ClaudePlugin extends BaseAgentAdapter { } interface VersionCompatibilityResult { - compatible: boolean; // true if versions match or installed <= supported - installedVersion: string | null; // null if not installed - supportedVersion: string; // from metadata - isNewer: boolean; // true if installed > supported (warning case) - hasUpdate: boolean; // true if newer supported version available (info prompt) + compatible: boolean; // true if versions match or installed <= supported + installedVersion: string | null; // null if not installed + supportedVersion: string; // from metadata + isNewer: boolean; // true if installed > supported (warning case) + hasUpdate: boolean; // true if newer supported version available (info prompt) + isBelowMinimum: boolean; // true if installed < minimumSupportedVersion (hard block) + minimumSupportedVersion?: string; // from metadata, minimum version still compatible } ``` @@ -299,10 +336,10 @@ Claude Code includes a built-in auto-updater that can automatically update to ne When a newer supported version is available (installed < supported), users receive an informational prompt: - **Message Type**: ℹ️ Info (cyan, non-threatening) -- **Default Action**: Continue with current version (Y is default) -- **Command**: `codemie update claude` -- **Behavior**: Non-blocking - allows user to proceed with current version or cancel to update -- **Purpose**: Keep users informed of newer tested versions without forcing immediate updates +- **Default Action**: Install supported version now (first option in list) +- **Options**: Install now and continue / Continue with current version / Exit +- **Behavior**: Non-blocking — user can install immediately, continue with current version, or exit and update manually +- **Purpose**: Keep users informed of newer tested versions and offer a frictionless upgrade path **Installation Logic**: @@ -368,11 +405,13 @@ export interface AgentMetadata { * Result of version compatibility check */ export interface VersionCompatibilityResult { - compatible: boolean; // true if installed version is compatible - installedVersion: string | null; // null if not installed - supportedVersion: string; // version from metadata - isNewer: boolean; // true if installed > supported (requires warning) - hasUpdate: boolean; // true if newer supported version available (info prompt) + compatible: boolean; // true if installed version is compatible + installedVersion: string | null; // null if not installed + supportedVersion: string; // version from metadata + isNewer: boolean; // true if installed > supported (requires warning) + hasUpdate: boolean; // true if newer supported version available (info prompt) + isBelowMinimum: boolean; // true if installed < minimumSupportedVersion (hard block) + minimumSupportedVersion?: string; // from metadata, minimum version still compatible } ``` diff --git a/src/agents/core/BaseAgentAdapter.ts b/src/agents/core/BaseAgentAdapter.ts index e0cd50ca..59ac3ec3 100644 --- a/src/agents/core/BaseAgentAdapter.ts +++ b/src/agents/core/BaseAgentAdapter.ts @@ -349,16 +349,34 @@ export abstract class BaseAgentAdapter implements AgentAdapter { console.log(); console.log(chalk.red(`✗ ${this.displayName} v${installedDisplay} is no longer supported`)); console.log(chalk.red(` Minimum required version: v${minimumDisplay}`)); + console.log(chalk.white(` Recommended version: v${compat.supportedVersion} `) + chalk.green('(recommended)')); console.log(); console.log(chalk.white(' This version is known to be incompatible with CodeMie and must be upgraded.')); console.log(); - console.log(chalk.white(' To upgrade, run:')); - console.log(chalk.blueBright(` codemie install ${this.name}`)); - console.log(); - process.exit(1); - } - if (compat.isNewer && !this.metadata.silentMode) { + const { belowMinChoice } = await inquirer.prompt([ + { + type: 'list', + name: 'belowMinChoice', + message: 'What would you like to do?', + choices: [ + { name: `Install v${compat.supportedVersion} now and continue`, value: 'install' }, + { name: 'Exit', value: 'exit' }, + ], + default: 'install', + }, + ]); + + if (belowMinChoice === 'install') { + console.log(chalk.blue(`\n Installing ${this.displayName} v${compat.supportedVersion}...`)); + await this.installVersion('supported'); + console.log(); // Add spacing before agent starts + } else { + console.log(chalk.white('\n If you want to update manually, run:')); + console.log(chalk.blueBright(` codemie update ${this.name}`)); + process.exit(0); + } + } else if (compat.isNewer && !this.metadata.silentMode) { // User is running a newer (untested) version console.log(); console.log(chalk.yellow(`⚠️ WARNING: You are running ${this.displayName} v${compat.installedVersion}`)); @@ -373,18 +391,30 @@ export abstract class BaseAgentAdapter implements AgentAdapter { console.log(chalk.blueBright(` codemie install ${this.name} ${compat.supportedVersion}`)); console.log(); - const { continueAnyway } = await inquirer.prompt([ + const { newerChoice } = await inquirer.prompt([ { - type: 'confirm', - name: 'continueAnyway', - message: 'Continue anyway?', - default: false, + type: 'list', + name: 'newerChoice', + message: 'What would you like to do?', + choices: [ + { name: `Install v${compat.supportedVersion} now and continue`, value: 'install' }, + { name: 'Continue with current version', value: 'continue' }, + { name: 'Exit', value: 'exit' }, + ], + default: 'install', }, ]); - if (!continueAnyway) { - console.log(chalk.gray('\nExecution cancelled\n')); - process.exit(1); + if (newerChoice === 'install') { + console.log(chalk.blue(`\n Installing ${this.displayName} v${compat.supportedVersion}...`)); + await this.installVersion('supported'); + } else if (newerChoice === 'exit') { + console.log(chalk.white('\n To install the supported version, run:')); + console.log(chalk.blueBright(` codemie install ${this.name} --supported`)); + console.log(); + console.log(chalk.white(' Or install a specific version:')); + console.log(chalk.blueBright(` codemie install ${this.name} ${compat.supportedVersion}`)); + process.exit(0); } console.log(); // Add spacing before agent starts @@ -396,22 +426,28 @@ export abstract class BaseAgentAdapter implements AgentAdapter { console.log(chalk.white(` Current version: v${compat.installedVersion}`)); console.log(chalk.white(` Latest version: v${compat.supportedVersion} `) + chalk.green('(recommended)')); console.log(); - console.log(chalk.white(' To update, run:')); - console.log(chalk.blueBright(` codemie update ${this.name}`)); - console.log(); - const { continueWithCurrent } = await inquirer.prompt([ + const { updateChoice } = await inquirer.prompt([ { - type: 'confirm', - name: 'continueWithCurrent', - message: 'Continue with current version?', - default: true, + type: 'list', + name: 'updateChoice', + message: `What would you like to do?`, + choices: [ + { name: `Install v${compat.supportedVersion} now and continue`, value: 'install' }, + { name: 'Continue with current version', value: 'continue' }, + { name: 'Exit', value: 'exit' }, + ], + default: 'install', }, ]); - if (!continueWithCurrent) { - console.log(chalk.gray('\nExecution cancelled. Please run the update command above.\n')); - process.exit(1); + if (updateChoice === 'install') { + console.log(chalk.blue(`\n Installing ${this.displayName} v${compat.supportedVersion}...`)); + await this.installVersion('supported'); + } else if (updateChoice === 'exit') { + console.log(chalk.white('\n If you want to update manually, run:')); + console.log(chalk.blueBright(` codemie update ${this.name}`)); + process.exit(0); } console.log(); // Add spacing before agent starts