mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 09:13:08 +00:00
fix: add Windows support for Claude CLI detection
Previously, the Claude CLI detection failed on Windows due to:
1. Shell command incompatibility
- Used 'which claude || where claude 2>/dev/null' which fails on Windows
- 'which' doesn't exist on Windows
- '2>/dev/null' is Unix syntax (Windows uses '2>nul')
- Now uses platform-specific commands: 'where' on Windows, 'which' on Unix
2. Missing Windows fallback paths
- Only checked Unix paths like ~/.local/bin/claude
- Added Windows-specific paths:
* %USERPROFILE%\.local\bin\claude.exe
* %APPDATA%\npm\claude.cmd
* %USERPROFILE%\.npm-global\bin\claude.cmd
3. Credentials file detection
- Only checked for 'credentials.json'
- Claude CLI on Windows uses '.credentials.json' (hidden file)
- Now checks both '.credentials.json' and 'credentials.json'
Additional improvements:
- Handle 'where' command returning multiple paths (takes first match)
- Maintains full backward compatibility with Linux and macOS
This commit is contained in:
@@ -17,12 +17,15 @@ export async function getClaudeStatus() {
|
|||||||
let cliPath = "";
|
let cliPath = "";
|
||||||
let method = "none";
|
let method = "none";
|
||||||
|
|
||||||
// Try to find Claude CLI
|
const isWindows = process.platform === "win32";
|
||||||
|
|
||||||
|
// Try to find Claude CLI using platform-specific command
|
||||||
try {
|
try {
|
||||||
const { stdout } = await execAsync(
|
// Use 'where' on Windows, 'which' on Unix-like systems
|
||||||
"which claude || where claude 2>/dev/null"
|
const findCommand = isWindows ? "where claude" : "which claude";
|
||||||
);
|
const { stdout } = await execAsync(findCommand);
|
||||||
cliPath = stdout.trim();
|
// 'where' on Windows can return multiple paths - take the first one
|
||||||
|
cliPath = stdout.trim().split(/\r?\n/)[0];
|
||||||
installed = true;
|
installed = true;
|
||||||
method = "path";
|
method = "path";
|
||||||
|
|
||||||
@@ -34,13 +37,23 @@ export async function getClaudeStatus() {
|
|||||||
// Version command might not be available
|
// Version command might not be available
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Not in PATH, try common locations
|
// Not in PATH, try common locations based on platform
|
||||||
const commonPaths = [
|
const commonPaths = isWindows
|
||||||
path.join(os.homedir(), ".local", "bin", "claude"),
|
? [
|
||||||
path.join(os.homedir(), ".claude", "local", "claude"),
|
// Windows-specific paths
|
||||||
"/usr/local/bin/claude",
|
path.join(os.homedir(), ".local", "bin", "claude.exe"),
|
||||||
path.join(os.homedir(), ".npm-global", "bin", "claude"),
|
path.join(os.homedir(), "AppData", "Roaming", "npm", "claude.cmd"),
|
||||||
];
|
path.join(os.homedir(), "AppData", "Roaming", "npm", "claude"),
|
||||||
|
path.join(os.homedir(), ".npm-global", "bin", "claude.cmd"),
|
||||||
|
path.join(os.homedir(), ".npm-global", "bin", "claude"),
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
// Unix (Linux/macOS) paths
|
||||||
|
path.join(os.homedir(), ".local", "bin", "claude"),
|
||||||
|
path.join(os.homedir(), ".claude", "local", "claude"),
|
||||||
|
"/usr/local/bin/claude",
|
||||||
|
path.join(os.homedir(), ".npm-global", "bin", "claude"),
|
||||||
|
];
|
||||||
|
|
||||||
for (const p of commonPaths) {
|
for (const p of commonPaths) {
|
||||||
try {
|
try {
|
||||||
@@ -124,26 +137,34 @@ export async function getClaudeStatus() {
|
|||||||
// Settings file doesn't exist
|
// Settings file doesn't exist
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for credentials file (OAuth tokens from claude login) - legacy/alternative auth
|
// Check for credentials file (OAuth tokens from claude login)
|
||||||
const credentialsPath = path.join(claudeDir, "credentials.json");
|
// Note: Claude CLI may use ".credentials.json" (hidden) or "credentials.json" depending on version/platform
|
||||||
try {
|
const credentialsPaths = [
|
||||||
const credentialsContent = await fs.readFile(credentialsPath, "utf-8");
|
path.join(claudeDir, ".credentials.json"),
|
||||||
const credentials = JSON.parse(credentialsContent);
|
path.join(claudeDir, "credentials.json"),
|
||||||
auth.hasCredentialsFile = true;
|
];
|
||||||
|
|
||||||
// Check what type of token is in credentials
|
for (const credentialsPath of credentialsPaths) {
|
||||||
if (credentials.oauth_token || credentials.access_token) {
|
try {
|
||||||
auth.hasStoredOAuthToken = true;
|
const credentialsContent = await fs.readFile(credentialsPath, "utf-8");
|
||||||
auth.oauthTokenValid = true;
|
const credentials = JSON.parse(credentialsContent);
|
||||||
auth.authenticated = true;
|
auth.hasCredentialsFile = true;
|
||||||
auth.method = "oauth_token"; // Stored OAuth token from credentials file
|
|
||||||
} else if (credentials.api_key) {
|
// Check what type of token is in credentials
|
||||||
auth.apiKeyValid = true;
|
if (credentials.oauth_token || credentials.access_token) {
|
||||||
auth.authenticated = true;
|
auth.hasStoredOAuthToken = true;
|
||||||
auth.method = "api_key"; // Stored API key in credentials file
|
auth.oauthTokenValid = true;
|
||||||
|
auth.authenticated = true;
|
||||||
|
auth.method = "oauth_token"; // Stored OAuth token from credentials file
|
||||||
|
} else if (credentials.api_key) {
|
||||||
|
auth.apiKeyValid = true;
|
||||||
|
auth.authenticated = true;
|
||||||
|
auth.method = "api_key"; // Stored API key in credentials file
|
||||||
|
}
|
||||||
|
break; // Found and processed credentials file
|
||||||
|
} catch {
|
||||||
|
// No credentials file at this path or invalid format
|
||||||
}
|
}
|
||||||
} catch {
|
|
||||||
// No credentials file or invalid format
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Environment variables override stored credentials (higher priority)
|
// Environment variables override stored credentials (higher priority)
|
||||||
|
|||||||
Reference in New Issue
Block a user