diff --git a/action.yml b/action.yml index b6e909a..1079534 100644 --- a/action.yml +++ b/action.yml @@ -194,10 +194,6 @@ runs: run: | cd ${GITHUB_ACTION_PATH} bun install --production - # bun install --production strips execute bits from vendored binaries (bun issue #1140). - # Restore +x on the ripgrep binaries so the Claude Agent SDK can exec them. - find "${GITHUB_ACTION_PATH}/node_modules/@anthropic-ai/claude-agent-sdk/vendor/ripgrep" \ - -name "rg" -type f -exec chmod +x {} \; - name: Install subprocess isolation dependencies # Install subprocess isolation dependencies when processing content from non-write users. diff --git a/base-action/src/index.ts b/base-action/src/index.ts index 970e79d..160e641 100644 --- a/base-action/src/index.ts +++ b/base-action/src/index.ts @@ -11,6 +11,14 @@ async function run() { try { validateEnvironmentVariables(); + // The composite action's "Install Claude Code" step writes the binary to + // ~/.local/bin/claude. Pass that path explicitly so the Agent SDK doesn't + // fall back to its bundled platform package, which bun may resolve to the + // wrong libc variant on Linux. + const claudeExecutable = + process.env.INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE || + `${process.env.HOME}/.local/bin/claude`; + await setupClaudeCodeSettings( process.env.INPUT_SETTINGS, undefined, // homeDir @@ -20,7 +28,7 @@ async function run() { await installPlugins( process.env.INPUT_PLUGIN_MARKETPLACES, process.env.INPUT_PLUGINS, - process.env.INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE, + claudeExecutable, ); const promptConfig = await preparePrompt({ @@ -38,8 +46,7 @@ async function run() { appendSystemPrompt: process.env.INPUT_APPEND_SYSTEM_PROMPT, fallbackModel: process.env.INPUT_FALLBACK_MODEL, model: process.env.ANTHROPIC_MODEL, - pathToClaudeCodeExecutable: - process.env.INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE, + pathToClaudeCodeExecutable: claudeExecutable, showFullOutput: process.env.INPUT_SHOW_FULL_OUTPUT, }); diff --git a/src/entrypoints/run.ts b/src/entrypoints/run.ts index f7578c0..3cae5f2 100644 --- a/src/entrypoints/run.ts +++ b/src/entrypoints/run.ts @@ -43,8 +43,9 @@ import type { ClaudeRunResult } from "../../base-action/src/run-claude-sdk"; /** * Install Claude Code CLI, handling retry logic and custom executable paths. + * Returns the absolute path to the claude executable. */ -async function installClaudeCode(): Promise { +async function installClaudeCode(): Promise { const customExecutable = process.env.PATH_TO_CLAUDE_CODE_EXECUTABLE; if (customExecutable) { if (/[\x00-\x1f\x7f]/.test(customExecutable)) { @@ -61,7 +62,7 @@ async function installClaudeCode(): Promise { } // Also add to current process PATH process.env.PATH = `${claudeDir}:${process.env.PATH}`; - return; + return customExecutable; } const claudeCodeVersion = "2.1.113"; @@ -93,7 +94,7 @@ async function installClaudeCode(): Promise { await appendFile(githubPath, `${homeBin}\n`); } process.env.PATH = `${homeBin}:${process.env.PATH}`; - return; + return `${homeBin}/claude`; } catch (error) { if (attempt === 3) { throw new Error( @@ -104,6 +105,7 @@ async function installClaudeCode(): Promise { await new Promise((resolve) => setTimeout(resolve, 5000)); } } + throw new Error("unreachable"); } /** @@ -220,7 +222,7 @@ async function run() { prepareCompleted = true; // Phase 2: Install Claude Code CLI - await installClaudeCode(); + const claudeExecutable = await installClaudeCode(); // Phase 3: Run Claude (import base-action directly) // Set env vars needed by the base-action code @@ -259,7 +261,7 @@ async function run() { await installPlugins( process.env.INPUT_PLUGIN_MARKETPLACES, process.env.INPUT_PLUGINS, - process.env.INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE, + claudeExecutable, ); const promptFile = @@ -274,8 +276,7 @@ async function run() { claudeArgs: prepareResult.claudeArgs, appendSystemPrompt: process.env.APPEND_SYSTEM_PROMPT, model: process.env.ANTHROPIC_MODEL, - pathToClaudeCodeExecutable: - process.env.INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE, + pathToClaudeCodeExecutable: claudeExecutable, showFullOutput: process.env.INPUT_SHOW_FULL_OUTPUT, });