fix: pass claude binary path to Agent SDK for packaged app
The SDK's query() function also needs to find the claude binary. Added findClaudePath() in claude-client.ts and pass it via pathToClaudeCodeExecutable option, fixing "Failed to create session" in packaged builds where PATH is limited. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
2c5280cd77
commit
2e6fc2af7d
1 file changed
+53
@@ -14,6 +14,53 @@ import type {
|
||||
} from '@anthropic-ai/claude-agent-sdk';
|
||||
import type { ClaudeStreamOptions, SSEEvent, TokenUsage, MCPServerConfig, PermissionRequestEvent } from '@/types';
|
||||
import { registerPendingPermission } from './permission-registry';
|
||||
import { execFileSync } from 'child_process';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
|
||||
let cachedClaudePath: string | null | undefined;
|
||||
|
||||
function findClaudePath(): string | undefined {
|
||||
if (cachedClaudePath !== undefined) return cachedClaudePath || undefined;
|
||||
|
||||
const home = os.homedir();
|
||||
const candidates = [
|
||||
'/usr/local/bin/claude',
|
||||
'/opt/homebrew/bin/claude',
|
||||
path.join(home, '.npm-global', 'bin', 'claude'),
|
||||
path.join(home, '.local', 'bin', 'claude'),
|
||||
path.join(home, '.claude', 'bin', 'claude'),
|
||||
];
|
||||
|
||||
for (const p of candidates) {
|
||||
try {
|
||||
execFileSync(p, ['--version'], { timeout: 3000, stdio: 'pipe' });
|
||||
cachedClaudePath = p;
|
||||
return p;
|
||||
} catch {
|
||||
// not found
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: which claude
|
||||
const extra = ['/usr/local/bin', '/opt/homebrew/bin', '/usr/bin', '/bin',
|
||||
path.join(home, '.npm-global', 'bin'), path.join(home, '.nvm', 'current', 'bin'),
|
||||
path.join(home, '.local', 'bin'), path.join(home, '.claude', 'bin')];
|
||||
const current = (process.env.PATH || '').split(':');
|
||||
for (const p of extra) { if (!current.includes(p)) current.push(p); }
|
||||
|
||||
try {
|
||||
const result = execFileSync('/usr/bin/which', ['claude'], {
|
||||
timeout: 3000, stdio: 'pipe',
|
||||
env: { ...process.env, PATH: current.join(':') },
|
||||
});
|
||||
const found = result.toString().trim();
|
||||
if (found) { cachedClaudePath = found; return found; }
|
||||
} catch { /* not found */ }
|
||||
|
||||
cachedClaudePath = null;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert our MCPServerConfig to the SDK's McpStdioServerConfig format
|
||||
@@ -92,6 +139,12 @@ export function streamClaude(options: ClaudeStreamOptions): ReadableStream<strin
|
||||
permissionMode: (permissionMode as Options['permissionMode']) || 'acceptEdits',
|
||||
};
|
||||
|
||||
// Find claude binary for packaged app where PATH is limited
|
||||
const claudePath = findClaudePath();
|
||||
if (claudePath) {
|
||||
queryOptions.pathToClaudeCodeExecutable = claudePath;
|
||||
}
|
||||
|
||||
if (model) {
|
||||
queryOptions.model = model;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user