Skip to content

Commit 0d2971c

Browse files
authored
fix: pass install.sh binary path explicitly to Agent SDK (#1235)
Agent SDK 0.2.113 dropped vendor/ripgrep and now ships native binaries via per-platform optionalDependencies. Two breakages: - action.yml chmod'd vendor/ripgrep which no longer exists, failing the Install Dependencies step with find exit 1. - The SDK auto-resolves its bundled binary by trying the -musl platform package before the glibc one. bun install does not respect the package.json libc field and installs both on glibc Linux, so the SDK picks the musl binary and spawn fails with ENOENT. Remove the obsolete ripgrep chmod. Make installClaudeCode() return the install.sh binary path and pass it explicitly as pathToClaudeCodeExecutable so the SDK skips auto-resolution entirely.
1 parent c68f82c commit 0d2971c

File tree

3 files changed

+18
-14
lines changed

3 files changed

+18
-14
lines changed

action.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,6 @@ runs:
194194
run: |
195195
cd ${GITHUB_ACTION_PATH}
196196
bun install --production
197-
# bun install --production strips execute bits from vendored binaries (bun issue #1140).
198-
# Restore +x on the ripgrep binaries so the Claude Agent SDK can exec them.
199-
find "${GITHUB_ACTION_PATH}/node_modules/@anthropic-ai/claude-agent-sdk/vendor/ripgrep" \
200-
-name "rg" -type f -exec chmod +x {} \;
201197
202198
- name: Install subprocess isolation dependencies
203199
# Install subprocess isolation dependencies when processing content from non-write users.

base-action/src/index.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ async function run() {
1111
try {
1212
validateEnvironmentVariables();
1313

14+
// The composite action's "Install Claude Code" step writes the binary to
15+
// ~/.local/bin/claude. Pass that path explicitly so the Agent SDK doesn't
16+
// fall back to its bundled platform package, which bun may resolve to the
17+
// wrong libc variant on Linux.
18+
const claudeExecutable =
19+
process.env.INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE ||
20+
`${process.env.HOME}/.local/bin/claude`;
21+
1422
await setupClaudeCodeSettings(
1523
process.env.INPUT_SETTINGS,
1624
undefined, // homeDir
@@ -20,7 +28,7 @@ async function run() {
2028
await installPlugins(
2129
process.env.INPUT_PLUGIN_MARKETPLACES,
2230
process.env.INPUT_PLUGINS,
23-
process.env.INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE,
31+
claudeExecutable,
2432
);
2533

2634
const promptConfig = await preparePrompt({
@@ -38,8 +46,7 @@ async function run() {
3846
appendSystemPrompt: process.env.INPUT_APPEND_SYSTEM_PROMPT,
3947
fallbackModel: process.env.INPUT_FALLBACK_MODEL,
4048
model: process.env.ANTHROPIC_MODEL,
41-
pathToClaudeCodeExecutable:
42-
process.env.INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE,
49+
pathToClaudeCodeExecutable: claudeExecutable,
4350
showFullOutput: process.env.INPUT_SHOW_FULL_OUTPUT,
4451
});
4552

src/entrypoints/run.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ import type { ClaudeRunResult } from "../../base-action/src/run-claude-sdk";
4343

4444
/**
4545
* Install Claude Code CLI, handling retry logic and custom executable paths.
46+
* Returns the absolute path to the claude executable.
4647
*/
47-
async function installClaudeCode(): Promise<void> {
48+
async function installClaudeCode(): Promise<string> {
4849
const customExecutable = process.env.PATH_TO_CLAUDE_CODE_EXECUTABLE;
4950
if (customExecutable) {
5051
if (/[\x00-\x1f\x7f]/.test(customExecutable)) {
@@ -61,7 +62,7 @@ async function installClaudeCode(): Promise<void> {
6162
}
6263
// Also add to current process PATH
6364
process.env.PATH = `${claudeDir}:${process.env.PATH}`;
64-
return;
65+
return customExecutable;
6566
}
6667

6768
const claudeCodeVersion = "2.1.113";
@@ -93,7 +94,7 @@ async function installClaudeCode(): Promise<void> {
9394
await appendFile(githubPath, `${homeBin}\n`);
9495
}
9596
process.env.PATH = `${homeBin}:${process.env.PATH}`;
96-
return;
97+
return `${homeBin}/claude`;
9798
} catch (error) {
9899
if (attempt === 3) {
99100
throw new Error(
@@ -104,6 +105,7 @@ async function installClaudeCode(): Promise<void> {
104105
await new Promise((resolve) => setTimeout(resolve, 5000));
105106
}
106107
}
108+
throw new Error("unreachable");
107109
}
108110

109111
/**
@@ -220,7 +222,7 @@ async function run() {
220222
prepareCompleted = true;
221223

222224
// Phase 2: Install Claude Code CLI
223-
await installClaudeCode();
225+
const claudeExecutable = await installClaudeCode();
224226

225227
// Phase 3: Run Claude (import base-action directly)
226228
// Set env vars needed by the base-action code
@@ -259,7 +261,7 @@ async function run() {
259261
await installPlugins(
260262
process.env.INPUT_PLUGIN_MARKETPLACES,
261263
process.env.INPUT_PLUGINS,
262-
process.env.INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE,
264+
claudeExecutable,
263265
);
264266

265267
const promptFile =
@@ -274,8 +276,7 @@ async function run() {
274276
claudeArgs: prepareResult.claudeArgs,
275277
appendSystemPrompt: process.env.APPEND_SYSTEM_PROMPT,
276278
model: process.env.ANTHROPIC_MODEL,
277-
pathToClaudeCodeExecutable:
278-
process.env.INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE,
279+
pathToClaudeCodeExecutable: claudeExecutable,
279280
showFullOutput: process.env.INPUT_SHOW_FULL_OUTPUT,
280281
});
281282

0 commit comments

Comments
 (0)