Skip to content

Commit b0ba188

Browse files
committed
fix: use shell command substitution instead of unsupported @filepath syntax
The CLI does not support @filepath syntax for the --agents argument. When command line length exceeds platform limits, the SDK now uses shell command substitution $(cat filepath) on Unix systems instead of the non-functional @filepath notation. Fixes #337
1 parent 27575ae commit b0ba188

File tree

1 file changed

+42
-11
lines changed

1 file changed

+42
-11
lines changed

src/claude_agent_sdk/_internal/transport/subprocess_cli.py

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import os
66
import platform
77
import re
8+
import shlex
89
import shutil
910
import sys
1011
import tempfile
@@ -169,8 +170,13 @@ def _build_settings_value(self) -> str | None:
169170

170171
return json.dumps(settings_obj)
171172

172-
def _build_command(self) -> list[str]:
173-
"""Build CLI command with arguments."""
173+
def _build_command(self) -> list[str] | str:
174+
"""Build CLI command with arguments.
175+
176+
Returns either a list of command arguments (for direct execution)
177+
or a shell command string (when command line is too long and
178+
shell command substitution is needed on Unix systems).
179+
"""
174180
cmd = [self._cli_path, "--output-format", "stream-json", "--verbose"]
175181

176182
if self._options.system_prompt is None:
@@ -333,11 +339,12 @@ def _build_command(self) -> list[str]:
333339
# String mode: use --print with the prompt
334340
cmd.extend(["--print", "--", str(self._prompt)])
335341

336-
# Check if command line is too long (Windows limitation)
342+
# Check if command line is too long (platform-specific limits)
337343
cmd_str = " ".join(cmd)
338344
if len(cmd_str) > _CMD_LENGTH_LIMIT and self._options.agents:
339-
# Command is too long - use temp file for agents
340-
# Find the --agents argument and replace its value with @filepath
345+
# Command is too long - use temp file for agents with shell command substitution
346+
# Note: The @filepath syntax is not supported by the CLI, so we use
347+
# shell command substitution $(cat filepath) on Unix systems instead.
341348
try:
342349
agents_idx = cmd.index("--agents")
343350
agents_json_value = cmd[agents_idx + 1]
@@ -353,13 +360,37 @@ def _build_command(self) -> list[str]:
353360
# Track for cleanup
354361
self._temp_files.append(temp_file.name)
355362

356-
# Replace agents JSON with @filepath reference
357-
cmd[agents_idx + 1] = f"@{temp_file.name}"
363+
if platform.system() != "Windows":
364+
# Unix: use shell command substitution $(cat filepath)
365+
# Build shell command with proper quoting
366+
quoted_parts = []
367+
for i, arg in enumerate(cmd):
368+
if i == agents_idx + 1:
369+
# Replace agents JSON with cat command substitution
370+
# Use double quotes around $(...) to preserve JSON whitespace
371+
quoted_parts.append(
372+
f'"$(cat {shlex.quote(temp_file.name)})"'
373+
)
374+
else:
375+
quoted_parts.append(shlex.quote(arg))
358376

359-
logger.info(
360-
f"Command line length ({len(cmd_str)}) exceeds limit ({_CMD_LENGTH_LIMIT}). "
361-
f"Using temp file for --agents: {temp_file.name}"
362-
)
377+
shell_cmd = " ".join(quoted_parts)
378+
379+
logger.info(
380+
f"Command line length ({len(cmd_str)}) exceeds limit "
381+
f"({_CMD_LENGTH_LIMIT}). Using shell command substitution "
382+
f"for --agents: {temp_file.name}"
383+
)
384+
385+
return shell_cmd
386+
else:
387+
# Windows: command line limits are stricter and shell substitution
388+
# is not as straightforward. Log a warning.
389+
logger.warning(
390+
f"Command line length ({len(cmd_str)}) exceeds Windows limit "
391+
f"({_CMD_LENGTH_LIMIT}). Large agent configurations may not "
392+
f"work correctly on Windows."
393+
)
363394
except (ValueError, IndexError) as e:
364395
# This shouldn't happen, but log it just in case
365396
logger.warning(f"Failed to optimize command line length: {e}")

0 commit comments

Comments
 (0)