mirror of
https://github.com/SuperClaude-Org/SuperClaude_Framework.git
synced 2025-12-29 16:16:08 +00:00
🚀 v4.0.4 - Enhanced installation with pipx support
- Added automatic detection of PEP 668 environments - Implemented pipx as preferred installation method for Linux/macOS - Added fallback to pip --user for externally managed environments - Improved error messages with clear installation alternatives - Added --break-system-packages as last resort option - Updated NPM wrapper to handle all installation scenarios - Enhanced update mechanism to detect and use correct tool
This commit is contained in:
@@ -28,9 +28,33 @@ function detectPip() {
|
||||
return null;
|
||||
}
|
||||
|
||||
function detectPipx() {
|
||||
if (checkCommand("pipx")) return "pipx";
|
||||
return null;
|
||||
}
|
||||
|
||||
function isSuperClaudeInstalled(pipCmd) {
|
||||
const result = run(pipCmd, ["show", "SuperClaude"]);
|
||||
return result.status === 0;
|
||||
}
|
||||
|
||||
module.exports = { run, detectPython, detectPip, isSuperClaudeInstalled };
|
||||
function isSuperClaudeInstalledPipx() {
|
||||
const result = run("pipx", ["list"]);
|
||||
if (result.status === 0 && result.stdout) {
|
||||
return result.stdout.toString().includes("SuperClaude");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkPythonEnvironment() {
|
||||
// Check if we're in an externally managed environment (PEP 668)
|
||||
const result = run("python3", ["-c", "import sysconfig; print(sysconfig.get_path('stdlib'))"]);
|
||||
if (result.status === 0 && result.stdout) {
|
||||
const stdlibPath = result.stdout.toString().trim();
|
||||
const checkPep668 = run("test", ["-f", `${stdlibPath}/EXTERNALLY-MANAGED`]);
|
||||
return checkPep668.status === 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
module.exports = { run, detectPython, detectPip, detectPipx, isSuperClaudeInstalled, isSuperClaudeInstalledPipx, checkPythonEnvironment };
|
||||
|
||||
105
bin/install.js
105
bin/install.js
@@ -1,31 +1,114 @@
|
||||
#!/usr/bin/env node
|
||||
const { run, detectPython, detectPip, isSuperClaudeInstalled } = require("./checkEnv");
|
||||
const { run, detectPython, detectPip, detectPipx, isSuperClaudeInstalled, isSuperClaudeInstalledPipx, checkPythonEnvironment } = require("./checkEnv");
|
||||
|
||||
console.log("🔍 Checking environment...");
|
||||
|
||||
let pythonCmd = detectPython();
|
||||
if (!pythonCmd) {
|
||||
console.error("❌ Python 3 is required but not found.");
|
||||
console.error(" Please install Python 3.8 or later from https://python.org");
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(`✅ Found Python: ${pythonCmd}`);
|
||||
|
||||
let pipCmd = detectPip();
|
||||
if (!pipCmd) {
|
||||
console.error("❌ pip is required but not found.");
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(`✅ Found Pip: ${pipCmd}`);
|
||||
// Check if we're in an externally managed environment (PEP 668)
|
||||
const isExternallyManaged = checkPythonEnvironment();
|
||||
let installMethod = null;
|
||||
let isInstalled = false;
|
||||
|
||||
// Check installation
|
||||
if (!isSuperClaudeInstalled(pipCmd)) {
|
||||
if (isExternallyManaged) {
|
||||
console.log("📦 Detected externally managed Python environment (PEP 668)");
|
||||
|
||||
// Try pipx first for externally managed environments
|
||||
let pipxCmd = detectPipx();
|
||||
if (pipxCmd) {
|
||||
console.log(`✅ Found pipx: ${pipxCmd}`);
|
||||
installMethod = "pipx";
|
||||
isInstalled = isSuperClaudeInstalledPipx();
|
||||
} else {
|
||||
console.log("⚠️ pipx is recommended for this system but not found.");
|
||||
console.log(" You can install pipx with: apt install pipx (Ubuntu/Debian) or brew install pipx (macOS)");
|
||||
console.log(" Alternatively, use one of these:");
|
||||
console.log(" pip install --user SuperClaude # Recommended");
|
||||
console.log(" pip install --break-system-packages SuperClaude # Force (use with caution)");
|
||||
|
||||
// Fall back to pip with --user flag
|
||||
let pipCmd = detectPip();
|
||||
if (pipCmd) {
|
||||
console.log(`✅ Found pip: ${pipCmd}`);
|
||||
console.log(" Will attempt installation with --user flag");
|
||||
installMethod = "pip-user";
|
||||
isInstalled = isSuperClaudeInstalled(pipCmd);
|
||||
} else {
|
||||
console.error("❌ Neither pipx nor pip found. Please install one of them.");
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Standard environment - use pip normally
|
||||
let pipCmd = detectPip();
|
||||
if (!pipCmd) {
|
||||
console.error("❌ pip is required but not found.");
|
||||
console.error(" Please install pip or use your system's package manager");
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(`✅ Found pip: ${pipCmd}`);
|
||||
installMethod = "pip";
|
||||
isInstalled = isSuperClaudeInstalled(pipCmd);
|
||||
}
|
||||
|
||||
// Perform installation based on detected method
|
||||
if (!isInstalled) {
|
||||
console.log("📦 Installing SuperClaude from PyPI...");
|
||||
const result = run(pipCmd, ["install", "SuperClaude"], { stdio: "inherit" });
|
||||
|
||||
let result;
|
||||
switch(installMethod) {
|
||||
case "pipx":
|
||||
result = run("pipx", ["install", "SuperClaude"], { stdio: "inherit" });
|
||||
break;
|
||||
case "pip-user":
|
||||
result = run(detectPip(), ["install", "--user", "SuperClaude"], { stdio: "inherit" });
|
||||
break;
|
||||
case "pip":
|
||||
result = run(detectPip(), ["install", "SuperClaude"], { stdio: "inherit" });
|
||||
break;
|
||||
}
|
||||
|
||||
if (result.status !== 0) {
|
||||
console.error("❌ Installation failed.");
|
||||
if (installMethod === "pip" && isExternallyManaged) {
|
||||
console.error(" Your system requires pipx or --user flag for pip installations.");
|
||||
console.error(" Try: pipx install SuperClaude");
|
||||
console.error(" Or: pip install --user SuperClaude");
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
console.log("✅ SuperClaude installed successfully!");
|
||||
|
||||
// For pipx installations, ensure it's in PATH
|
||||
if (installMethod === "pipx") {
|
||||
console.log("\n📌 Note: If 'SuperClaude' command is not found, run:");
|
||||
console.log(" pipx ensurepath");
|
||||
console.log(" Then restart your terminal or run: source ~/.bashrc");
|
||||
}
|
||||
} else {
|
||||
console.log("✅ SuperClaude already installed.");
|
||||
}
|
||||
}
|
||||
|
||||
// Try to run SuperClaude install
|
||||
console.log("\n🚀 Running SuperClaude installation...");
|
||||
const installResult = run("SuperClaude", ["install"], { stdio: "inherit" });
|
||||
|
||||
if (installResult.status !== 0) {
|
||||
console.log("\n⚠️ Could not run 'SuperClaude install' automatically.");
|
||||
console.log(" Please run it manually after ensuring SuperClaude is in your PATH:");
|
||||
console.log(" SuperClaude install");
|
||||
|
||||
if (installMethod === "pipx") {
|
||||
console.log("\n If command not found, try:");
|
||||
console.log(" pipx ensurepath && source ~/.bashrc");
|
||||
} else if (installMethod === "pip-user") {
|
||||
console.log("\n If command not found, add Python user bin to PATH:");
|
||||
console.log(" export PATH=\"$HOME/.local/bin:$PATH\"");
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,71 @@
|
||||
#!/usr/bin/env node
|
||||
const { run, detectPip } = require("./checkEnv");
|
||||
const { run, detectPip, detectPipx, isSuperClaudeInstalledPipx, checkPythonEnvironment } = require("./checkEnv");
|
||||
|
||||
let pipCmd = detectPip();
|
||||
if (!pipCmd) {
|
||||
console.error("❌ pip not found, cannot update.");
|
||||
process.exit(1);
|
||||
console.log("🔄 Checking for SuperClaude updates...");
|
||||
|
||||
// Detect installation method
|
||||
const isExternallyManaged = checkPythonEnvironment();
|
||||
let updateMethod = null;
|
||||
|
||||
// Check if installed via pipx
|
||||
if (detectPipx() && isSuperClaudeInstalledPipx()) {
|
||||
updateMethod = "pipx";
|
||||
console.log("✅ Detected pipx installation");
|
||||
} else {
|
||||
// Check for pip installation
|
||||
let pipCmd = detectPip();
|
||||
if (!pipCmd) {
|
||||
console.error("❌ Neither pipx nor pip found, cannot update.");
|
||||
console.error(" Please install SuperClaude first using:");
|
||||
console.error(" pipx install SuperClaude");
|
||||
console.error(" or");
|
||||
console.error(" pip install SuperClaude");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (isExternallyManaged) {
|
||||
updateMethod = "pip-user";
|
||||
console.log("✅ Detected pip installation with --user flag");
|
||||
} else {
|
||||
updateMethod = "pip";
|
||||
console.log("✅ Detected standard pip installation");
|
||||
}
|
||||
}
|
||||
|
||||
// Perform update based on detected method
|
||||
console.log("🔄 Updating SuperClaude from PyPI...");
|
||||
const result = run(pipCmd, ["install", "--upgrade", "SuperClaude"], { stdio: "inherit" });
|
||||
|
||||
let result;
|
||||
switch(updateMethod) {
|
||||
case "pipx":
|
||||
result = run("pipx", ["upgrade", "SuperClaude"], { stdio: "inherit" });
|
||||
break;
|
||||
case "pip-user":
|
||||
result = run(detectPip(), ["install", "--upgrade", "--user", "SuperClaude"], { stdio: "inherit" });
|
||||
break;
|
||||
case "pip":
|
||||
result = run(detectPip(), ["install", "--upgrade", "SuperClaude"], { stdio: "inherit" });
|
||||
break;
|
||||
}
|
||||
|
||||
if (result.status !== 0) {
|
||||
console.error("❌ Update failed.");
|
||||
if (updateMethod === "pip" && isExternallyManaged) {
|
||||
console.error(" Your system requires pipx or --user flag for pip operations.");
|
||||
console.error(" Try: pipx upgrade SuperClaude");
|
||||
console.error(" Or: pip install --upgrade --user SuperClaude");
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("✅ SuperClaude updated successfully!");
|
||||
|
||||
|
||||
// Run SuperClaude update command
|
||||
console.log("\n🚀 Running SuperClaude update...");
|
||||
const updateResult = run("SuperClaude", ["update"], { stdio: "inherit" });
|
||||
|
||||
if (updateResult.status !== 0) {
|
||||
console.log("\n⚠️ Could not run 'SuperClaude update' automatically.");
|
||||
console.log(" Please run it manually:");
|
||||
console.log(" SuperClaude update");
|
||||
}
|
||||
Reference in New Issue
Block a user