Add extra_args field to ClaudeCodeOptions for forward compatibility (#111)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled

## Summary
- Adds `extra_args` field to `ClaudeCodeOptions` to support passing
arbitrary CLI flags
- Enables forward compatibility with future CLI flags without requiring
SDK updates
- Supports both valued flags (`--flag value`) and boolean flags
(`--flag`)

## Changes
- Add `extra_args: dict[str, str | None]` field to `ClaudeCodeOptions`
- Implement logic in `SubprocessCLITransport` to handle extra args:
- `None` values create boolean flags (e.g., `{"verbose": None}` →
`--verbose`)
- String values create flags with arguments (e.g., `{"output": "json"}`
→ `--output json`)
- Add comprehensive tests for the new functionality

## Test plan
- [x] Added unit tests for settings file path handling
- [x] Added unit tests for settings JSON object handling  
- [x] Added unit tests for extra_args with both valued and boolean flags
- [x] All tests pass (`python -m pytest tests/`)
- [x] Type checking passes (`python -m mypy src/`)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Dickson Tsai 2025-08-04 22:47:24 -07:00 committed by GitHub
parent 8f4b7777b9
commit 9fc830028e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 65 additions and 0 deletions

View file

@ -134,6 +134,15 @@ class SubprocessCLITransport(Transport):
["--mcp-config", json.dumps({"mcpServers": self._options.mcp_servers})]
)
# Add extra args for future CLI flags
for flag, value in self._options.extra_args.items():
if value is None:
# Boolean flag without value
cmd.append(f"--{flag}")
else:
# Flag with value
cmd.extend([f"--{flag}", str(value)])
# Add prompt handling based on mode
if self._is_streaming:
# Streaming mode: use --input-format stream-json

View file

@ -128,3 +128,6 @@ class ClaudeCodeOptions:
cwd: str | Path | None = None
settings: str | None = None
add_dirs: list[str | Path] = field(default_factory=list)
extra_args: dict[str, str | None] = field(
default_factory=dict
) # Pass arbitrary CLI flags

View file

@ -174,3 +174,56 @@ class TestSubprocessCLITransport:
assert "/this/directory/does/not/exist" in str(exc_info.value)
anyio.run(_test)
def test_build_command_with_settings_file(self):
"""Test building CLI command with settings as file path."""
transport = SubprocessCLITransport(
prompt="test",
options=ClaudeCodeOptions(settings="/path/to/settings.json"),
cli_path="/usr/bin/claude",
)
cmd = transport._build_command()
assert "--settings" in cmd
assert "/path/to/settings.json" in cmd
def test_build_command_with_settings_json(self):
"""Test building CLI command with settings as JSON object."""
settings_json = '{"permissions": {"allow": ["Bash(ls:*)"]}}'
transport = SubprocessCLITransport(
prompt="test",
options=ClaudeCodeOptions(settings=settings_json),
cli_path="/usr/bin/claude",
)
cmd = transport._build_command()
assert "--settings" in cmd
assert settings_json in cmd
def test_build_command_with_extra_args(self):
"""Test building CLI command with extra_args for future flags."""
transport = SubprocessCLITransport(
prompt="test",
options=ClaudeCodeOptions(
extra_args={
"new-flag": "value",
"boolean-flag": None,
"another-option": "test-value",
}
),
cli_path="/usr/bin/claude",
)
cmd = transport._build_command()
cmd_str = " ".join(cmd)
# Check flags with values
assert "--new-flag value" in cmd_str
assert "--another-option test-value" in cmd_str
# Check boolean flag (no value)
assert "--boolean-flag" in cmd
# Make sure boolean flag doesn't have a value after it
boolean_idx = cmd.index("--boolean-flag")
# Either it's the last element or the next element is another flag
assert boolean_idx == len(cmd) - 1 or cmd[boolean_idx + 1].startswith("--")