diff --git a/VERSION b/VERSION index ee74734a..627a3f43 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.1.0 +4.1.1 diff --git a/bin/ccs.js b/bin/ccs.js index 163110ff..a88cc491 100755 --- a/bin/ccs.js +++ b/bin/ccs.js @@ -255,6 +255,12 @@ async function handleDoctorCommand() { } async function handleUpdateCommand() { + // First, copy .claude/ directory from package to ~/.ccs/.claude/ + const ClaudeDirInstaller = require('./utils/claude-dir-installer'); + const installer = new ClaudeDirInstaller(); + installer.install(); + + // Then, create symlinks from ~/.ccs/.claude/ to ~/.claude/ const ClaudeSymlinkManager = require('./utils/claude-symlink-manager'); const manager = new ClaudeSymlinkManager(); diff --git a/bin/utils/claude-dir-installer.js b/bin/utils/claude-dir-installer.js new file mode 100644 index 00000000..7d57a1ef --- /dev/null +++ b/bin/utils/claude-dir-installer.js @@ -0,0 +1,102 @@ +#!/usr/bin/env node +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const os = require('os'); + +/** + * ClaudeDirInstaller - Manages copying .claude/ directory from package to ~/.ccs/.claude/ + * v4.1.1: Fix for npm install not copying .claude/ directory + */ +class ClaudeDirInstaller { + constructor() { + this.homeDir = os.homedir(); + this.ccsClaudeDir = path.join(this.homeDir, '.ccs', '.claude'); + } + + /** + * Copy .claude/ directory from package to ~/.ccs/.claude/ + * @param {string} packageDir - Package installation directory (default: auto-detect) + */ + install(packageDir) { + try { + // Auto-detect package directory if not provided + if (!packageDir) { + // Try to find package root by going up from this file + packageDir = path.join(__dirname, '..', '..'); + } + + const packageClaudeDir = path.join(packageDir, '.claude'); + + if (!fs.existsSync(packageClaudeDir)) { + console.log('[!] Package .claude/ directory not found'); + console.log(` Searched in: ${packageClaudeDir}`); + console.log(' This may be a development installation'); + return false; + } + + console.log('[i] Installing CCS .claude/ items...'); + + // Remove old version before copying new one + if (fs.existsSync(this.ccsClaudeDir)) { + fs.rmSync(this.ccsClaudeDir, { recursive: true, force: true }); + } + + // Use fs.cpSync for recursive copy (Node.js 16.7.0+) + // Fallback to manual copy for older Node.js versions + if (fs.cpSync) { + fs.cpSync(packageClaudeDir, this.ccsClaudeDir, { recursive: true }); + } else { + // Fallback for Node.js < 16.7.0 + this._copyDirRecursive(packageClaudeDir, this.ccsClaudeDir); + } + + console.log('[OK] Copied .claude/ items to ~/.ccs/.claude/'); + return true; + } catch (err) { + console.warn('[!] Failed to copy .claude/ directory:', err.message); + console.warn(' CCS items may not be available'); + return false; + } + } + + /** + * Recursively copy directory (fallback for Node.js < 16.7.0) + * @param {string} src - Source directory + * @param {string} dest - Destination directory + * @private + */ + _copyDirRecursive(src, dest) { + // Create destination directory + if (!fs.existsSync(dest)) { + fs.mkdirSync(dest, { recursive: true }); + } + + // Read source directory + const entries = fs.readdirSync(src, { withFileTypes: true }); + + for (const entry of entries) { + const srcPath = path.join(src, entry.name); + const destPath = path.join(dest, entry.name); + + if (entry.isDirectory()) { + // Recursively copy subdirectory + this._copyDirRecursive(srcPath, destPath); + } else { + // Copy file + fs.copyFileSync(srcPath, destPath); + } + } + } + + /** + * Check if ~/.ccs/.claude/ exists and is valid + * @returns {boolean} True if directory exists + */ + isInstalled() { + return fs.existsSync(this.ccsClaudeDir); + } +} + +module.exports = ClaudeDirInstaller; diff --git a/installers/install.ps1 b/installers/install.ps1 index 2272b732..cfda70fa 100644 --- a/installers/install.ps1 +++ b/installers/install.ps1 @@ -31,7 +31,7 @@ $InstallMethod = if ($ScriptDir -and ((Test-Path "$ScriptDir\lib\ccs.ps1") -or ( # IMPORTANT: Update this version when releasing new versions! # This hardcoded version is used for standalone installations (irm | iex) # For git installations, VERSION file is read if available -$CcsVersion = "4.1.0" +$CcsVersion = "4.1.1" # Try to read VERSION file for git installations if ($ScriptDir) { diff --git a/installers/install.sh b/installers/install.sh index cf482eb5..8f23ca38 100755 --- a/installers/install.sh +++ b/installers/install.sh @@ -32,7 +32,7 @@ fi # IMPORTANT: Update this version when releasing new versions! # This hardcoded version is used for standalone installations (curl | bash) # For git installations, VERSION file is read if available -CCS_VERSION="4.1.0" +CCS_VERSION="4.1.1" # Try to read VERSION file for git installations if [[ -f "$SCRIPT_DIR/VERSION" ]]; then diff --git a/lib/ccs b/lib/ccs index 01c4b040..f177d438 100755 --- a/lib/ccs +++ b/lib/ccs @@ -2,7 +2,7 @@ set -euo pipefail # Version (updated by scripts/bump-version.sh) -CCS_VERSION="4.1.0" +CCS_VERSION="4.1.1" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" readonly CONFIG_FILE="${CCS_CONFIG:-$HOME/.ccs/config.json}" readonly PROFILES_JSON="$HOME/.ccs/profiles.json" diff --git a/lib/ccs.ps1 b/lib/ccs.ps1 index 4880ec1f..0798f1c4 100644 --- a/lib/ccs.ps1 +++ b/lib/ccs.ps1 @@ -12,7 +12,7 @@ param( $ErrorActionPreference = "Stop" # Version (updated by scripts/bump-version.sh) -$CcsVersion = "4.1.0" +$CcsVersion = "4.1.1" $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $ConfigFile = if ($env:CCS_CONFIG) { $env:CCS_CONFIG } else { "$env:USERPROFILE\.ccs\config.json" } $ProfilesJson = "$env:USERPROFILE\.ccs\profiles.json" diff --git a/package.json b/package.json index ff5ddc80..a1eff3c3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kaitranntt/ccs", - "version": "4.1.0", + "version": "4.1.1", "description": "Claude Code Switch - Instant profile switching between Claude Sonnet 4.5 and GLM 4.6", "keywords": [ "cli", diff --git a/scripts/postinstall.js b/scripts/postinstall.js index 6301f39e..ab19055c 100755 --- a/scripts/postinstall.js +++ b/scripts/postinstall.js @@ -103,6 +103,17 @@ function createConfigFiles() { } console.log(''); + // Copy .claude/ directory from package to ~/.ccs/.claude/ (v4.1.1) + try { + const ClaudeDirInstaller = require('../bin/utils/claude-dir-installer'); + const installer = new ClaudeDirInstaller(); + const packageDir = path.join(__dirname, '..'); + installer.install(packageDir); + } catch (err) { + console.warn('[!] Failed to install .claude/ directory:', err.message); + console.warn(' CCS items may not be available'); + } + // Install CCS items to ~/.claude/ (v4.1.0) try { const ClaudeSymlinkManager = require('../bin/utils/claude-symlink-manager');