claude-agent-sdk 0.1.3__tar.gz → 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of claude-agent-sdk might be problematic. Click here for more details.

Files changed (30) hide show
  1. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/PKG-INFO +11 -1
  2. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/README.md +10 -0
  3. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/pyproject.toml +1 -1
  4. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/__init__.py +10 -2
  5. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/_internal/client.py +2 -1
  6. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/_internal/transport/subprocess_cli.py +7 -5
  7. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/_version.py +1 -1
  8. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/types.py +1 -0
  9. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/test_sdk_mcp_integration.py +72 -0
  10. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/test_subprocess_buffering.py +17 -23
  11. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/test_transport.py +29 -44
  12. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/.gitignore +0 -0
  13. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/LICENSE +0 -0
  14. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/_errors.py +0 -0
  15. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/_internal/__init__.py +0 -0
  16. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/_internal/message_parser.py +0 -0
  17. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/_internal/query.py +0 -0
  18. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/_internal/transport/__init__.py +0 -0
  19. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/client.py +0 -0
  20. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/py.typed +0 -0
  21. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/src/claude_agent_sdk/query.py +0 -0
  22. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/conftest.py +0 -0
  23. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/test_changelog.py +0 -0
  24. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/test_client.py +0 -0
  25. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/test_errors.py +0 -0
  26. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/test_integration.py +0 -0
  27. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/test_message_parser.py +0 -0
  28. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/test_streaming_client.py +0 -0
  29. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/test_tool_callbacks.py +0 -0
  30. {claude_agent_sdk-0.1.3 → claude_agent_sdk-0.1.4}/tests/test_types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-agent-sdk
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Python SDK for Claude Code
5
5
  Project-URL: Homepage, https://github.com/anthropics/claude-agent-sdk-python
6
6
  Project-URL: Documentation, https://docs.anthropic.com/en/docs/claude-code/sdk
@@ -313,6 +313,16 @@ If you're upgrading from the Claude Code SDK (versions < 0.1.0), please see the
313
313
  - Settings isolation and explicit control
314
314
  - New programmatic subagents and session forking features
315
315
 
316
+ ## Development
317
+
318
+ If you're contributing to this project, run the initial setup script to install git hooks:
319
+
320
+ ```bash
321
+ ./scripts/initial-setup.sh
322
+ ```
323
+
324
+ This installs a pre-push hook that runs lint checks before pushing, matching the CI workflow. To skip the hook temporarily, use `git push --no-verify`.
325
+
316
326
  ## License
317
327
 
318
328
  MIT
@@ -280,6 +280,16 @@ If you're upgrading from the Claude Code SDK (versions < 0.1.0), please see the
280
280
  - Settings isolation and explicit control
281
281
  - New programmatic subagents and session forking features
282
282
 
283
+ ## Development
284
+
285
+ If you're contributing to this project, run the initial setup script to install git hooks:
286
+
287
+ ```bash
288
+ ./scripts/initial-setup.sh
289
+ ```
290
+
291
+ This installs a pre-push hook that runs lint checks before pushing, matching the CI workflow. To skip the hook temporarily, use `git push --no-verify`.
292
+
283
293
  ## License
284
294
 
285
295
  MIT
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "claude-agent-sdk"
7
- version = "0.1.3"
7
+ version = "0.1.4"
8
8
  description = "Python SDK for Claude Code"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -203,7 +203,7 @@ def create_sdk_mcp_server(
203
203
  - ClaudeAgentOptions: Configuration for using servers with query()
204
204
  """
205
205
  from mcp.server import Server
206
- from mcp.types import TextContent, Tool
206
+ from mcp.types import ImageContent, TextContent, Tool
207
207
 
208
208
  # Create MCP server instance
209
209
  server = Server(name, version=version)
@@ -273,11 +273,19 @@ def create_sdk_mcp_server(
273
273
  # Convert result to MCP format
274
274
  # The decorator expects us to return the content, not a CallToolResult
275
275
  # It will wrap our return value in CallToolResult
276
- content = []
276
+ content: list[TextContent | ImageContent] = []
277
277
  if "content" in result:
278
278
  for item in result["content"]:
279
279
  if item.get("type") == "text":
280
280
  content.append(TextContent(type="text", text=item["text"]))
281
+ if item.get("type") == "image":
282
+ content.append(
283
+ ImageContent(
284
+ type="image",
285
+ data=item["data"],
286
+ mimeType=item["mimeType"],
287
+ )
288
+ )
281
289
 
282
290
  # Return just the content list - the decorator wraps it
283
291
  return content
@@ -71,7 +71,8 @@ class InternalClient:
71
71
  chosen_transport = transport
72
72
  else:
73
73
  chosen_transport = SubprocessCLITransport(
74
- prompt=prompt, options=configured_options
74
+ prompt=prompt,
75
+ options=configured_options,
75
76
  )
76
77
 
77
78
  # Connect transport
@@ -37,12 +37,13 @@ class SubprocessCLITransport(Transport):
37
37
  self,
38
38
  prompt: str | AsyncIterable[dict[str, Any]],
39
39
  options: ClaudeAgentOptions,
40
- cli_path: str | Path | None = None,
41
40
  ):
42
41
  self._prompt = prompt
43
42
  self._is_streaming = not isinstance(prompt, str)
44
43
  self._options = options
45
- self._cli_path = str(cli_path) if cli_path else self._find_cli()
44
+ self._cli_path = (
45
+ str(options.cli_path) if options.cli_path is not None else self._find_cli()
46
+ )
46
47
  self._cwd = str(options.cwd) if options.cwd else None
47
48
  self._process: Process | None = None
48
49
  self._stdout_stream: TextReceiveStream | None = None
@@ -79,8 +80,8 @@ class SubprocessCLITransport(Transport):
79
80
  " npm install -g @anthropic-ai/claude-code\n"
80
81
  "\nIf already installed locally, try:\n"
81
82
  ' export PATH="$HOME/node_modules/.bin:$PATH"\n'
82
- "\nOr specify the path when creating transport:\n"
83
- " SubprocessCLITransport(..., cli_path='/path/to/claude')"
83
+ "\nOr provide the path via ClaudeAgentOptions:\n"
84
+ " ClaudeAgentOptions(cli_path='/path/to/claude')"
84
85
  )
85
86
 
86
87
  def _build_command(self) -> list[str]:
@@ -205,7 +206,8 @@ class SubprocessCLITransport(Transport):
205
206
  if self._process:
206
207
  return
207
208
 
208
- await self._check_claude_version()
209
+ if not os.environ.get("CLAUDE_AGENT_SDK_SKIP_VERSION_CHECK"):
210
+ await self._check_claude_version()
209
211
 
210
212
  cmd = self._build_command()
211
213
  try:
@@ -1,3 +1,3 @@
1
1
  """Version information for claude-agent-sdk."""
2
2
 
3
- __version__ = "0.1.3"
3
+ __version__ = "0.1.4"
@@ -512,6 +512,7 @@ class ClaudeAgentOptions:
512
512
  model: str | None = None
513
513
  permission_prompt_tool_name: str | None = None
514
514
  cwd: str | Path | None = None
515
+ cli_path: str | Path | None = None
515
516
  settings: str | None = None
516
517
  add_dirs: list[str | Path] = field(default_factory=list)
517
518
  env: dict[str, str] = field(default_factory=dict)
@@ -4,9 +4,11 @@ This test file verifies that SDK MCP servers work correctly through the full sta
4
4
  matching the TypeScript SDK test/sdk.test.ts pattern.
5
5
  """
6
6
 
7
+ import base64
7
8
  from typing import Any
8
9
 
9
10
  import pytest
11
+ from mcp.types import CallToolRequest, CallToolRequestParams
10
12
 
11
13
  from claude_agent_sdk import (
12
14
  ClaudeAgentOptions,
@@ -191,3 +193,73 @@ async def test_server_creation():
191
193
 
192
194
  # When no tools are provided, the handlers are not registered
193
195
  assert ListToolsRequest not in instance.request_handlers
196
+
197
+
198
+ @pytest.mark.asyncio
199
+ async def test_image_content_support():
200
+ """Test that tools can return image content with base64 data."""
201
+
202
+ # Create sample base64 image data (a simple 1x1 pixel PNG)
203
+ png_data = base64.b64encode(
204
+ b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01"
205
+ b"\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\tpHYs\x00\x00\x0b\x13"
206
+ b"\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x0cIDATx\x9cc```"
207
+ b"\x00\x00\x00\x04\x00\x01]U!\x1c\x00\x00\x00\x00IEND\xaeB`\x82"
208
+ ).decode("utf-8")
209
+
210
+ # Track tool executions
211
+ tool_executions: list[dict[str, Any]] = []
212
+
213
+ # Create a tool that returns both text and image content
214
+ @tool(
215
+ "generate_chart", "Generates a chart and returns it as an image", {"title": str}
216
+ )
217
+ async def generate_chart(args: dict[str, Any]) -> dict[str, Any]:
218
+ tool_executions.append({"name": "generate_chart", "args": args})
219
+ return {
220
+ "content": [
221
+ {"type": "text", "text": f"Generated chart: {args['title']}"},
222
+ {
223
+ "type": "image",
224
+ "data": png_data,
225
+ "mimeType": "image/png",
226
+ },
227
+ ]
228
+ }
229
+
230
+ server_config = create_sdk_mcp_server(
231
+ name="image-test-server", version="1.0.0", tools=[generate_chart]
232
+ )
233
+
234
+ # Get the server instance
235
+ server = server_config["instance"]
236
+
237
+ call_handler = server.request_handlers[CallToolRequest]
238
+
239
+ # Call the chart generation tool
240
+ chart_request = CallToolRequest(
241
+ method="tools/call",
242
+ params=CallToolRequestParams(
243
+ name="generate_chart", arguments={"title": "Sales Report"}
244
+ ),
245
+ )
246
+ result = await call_handler(chart_request)
247
+
248
+ # Verify the result contains both text and image content
249
+ assert len(result.root.content) == 2
250
+
251
+ # Check text content
252
+ text_content = result.root.content[0]
253
+ assert text_content.type == "text"
254
+ assert text_content.text == "Generated chart: Sales Report"
255
+
256
+ # Check image content
257
+ image_content = result.root.content[1]
258
+ assert image_content.type == "image"
259
+ assert image_content.data == png_data
260
+ assert image_content.mimeType == "image/png"
261
+
262
+ # Verify the tool was executed correctly
263
+ assert len(tool_executions) == 1
264
+ assert tool_executions[0]["name"] == "generate_chart"
265
+ assert tool_executions[0]["args"]["title"] == "Sales Report"
@@ -15,6 +15,15 @@ from claude_agent_sdk._internal.transport.subprocess_cli import (
15
15
  )
16
16
  from claude_agent_sdk.types import ClaudeAgentOptions
17
17
 
18
+ DEFAULT_CLI_PATH = "/usr/bin/claude"
19
+
20
+
21
+ def make_options(**kwargs: object) -> ClaudeAgentOptions:
22
+ """Construct ClaudeAgentOptions with a default CLI path for tests."""
23
+
24
+ cli_path = kwargs.pop("cli_path", DEFAULT_CLI_PATH)
25
+ return ClaudeAgentOptions(cli_path=cli_path, **kwargs)
26
+
18
27
 
19
28
  class MockTextReceiveStream:
20
29
  """Mock TextReceiveStream for testing."""
@@ -50,9 +59,7 @@ class TestSubprocessBuffering:
50
59
 
51
60
  buffered_line = json.dumps(json_obj1) + "\n" + json.dumps(json_obj2)
52
61
 
53
- transport = SubprocessCLITransport(
54
- prompt="test", options=ClaudeAgentOptions(), cli_path="/usr/bin/claude"
55
- )
62
+ transport = SubprocessCLITransport(prompt="test", options=make_options())
56
63
 
57
64
  mock_process = MagicMock()
58
65
  mock_process.returncode = None
@@ -85,9 +92,7 @@ class TestSubprocessBuffering:
85
92
 
86
93
  buffered_line = json.dumps(json_obj1) + "\n" + json.dumps(json_obj2)
87
94
 
88
- transport = SubprocessCLITransport(
89
- prompt="test", options=ClaudeAgentOptions(), cli_path="/usr/bin/claude"
90
- )
95
+ transport = SubprocessCLITransport(prompt="test", options=make_options())
91
96
 
92
97
  mock_process = MagicMock()
93
98
  mock_process.returncode = None
@@ -115,9 +120,7 @@ class TestSubprocessBuffering:
115
120
 
116
121
  buffered_line = json.dumps(json_obj1) + "\n\n\n" + json.dumps(json_obj2)
117
122
 
118
- transport = SubprocessCLITransport(
119
- prompt="test", options=ClaudeAgentOptions(), cli_path="/usr/bin/claude"
120
- )
123
+ transport = SubprocessCLITransport(prompt="test", options=make_options())
121
124
 
122
125
  mock_process = MagicMock()
123
126
  mock_process.returncode = None
@@ -161,9 +164,7 @@ class TestSubprocessBuffering:
161
164
  part2 = complete_json[100:250]
162
165
  part3 = complete_json[250:]
163
166
 
164
- transport = SubprocessCLITransport(
165
- prompt="test", options=ClaudeAgentOptions(), cli_path="/usr/bin/claude"
166
- )
167
+ transport = SubprocessCLITransport(prompt="test", options=make_options())
167
168
 
168
169
  mock_process = MagicMock()
169
170
  mock_process.returncode = None
@@ -209,9 +210,7 @@ class TestSubprocessBuffering:
209
210
  for i in range(0, len(complete_json), chunk_size)
210
211
  ]
211
212
 
212
- transport = SubprocessCLITransport(
213
- prompt="test", options=ClaudeAgentOptions(), cli_path="/usr/bin/claude"
214
- )
213
+ transport = SubprocessCLITransport(prompt="test", options=make_options())
215
214
 
216
215
  mock_process = MagicMock()
217
216
  mock_process.returncode = None
@@ -239,9 +238,7 @@ class TestSubprocessBuffering:
239
238
  async def _test() -> None:
240
239
  huge_incomplete = '{"data": "' + "x" * (_DEFAULT_MAX_BUFFER_SIZE + 1000)
241
240
 
242
- transport = SubprocessCLITransport(
243
- prompt="test", options=ClaudeAgentOptions(), cli_path="/usr/bin/claude"
244
- )
241
+ transport = SubprocessCLITransport(prompt="test", options=make_options())
245
242
 
246
243
  mock_process = MagicMock()
247
244
  mock_process.returncode = None
@@ -269,8 +266,7 @@ class TestSubprocessBuffering:
269
266
 
270
267
  transport = SubprocessCLITransport(
271
268
  prompt="test",
272
- options=ClaudeAgentOptions(max_buffer_size=custom_limit),
273
- cli_path="/usr/bin/claude",
269
+ options=make_options(max_buffer_size=custom_limit),
274
270
  )
275
271
 
276
272
  mock_process = MagicMock()
@@ -309,9 +305,7 @@ class TestSubprocessBuffering:
309
305
  large_json[3000:] + "\n" + msg3,
310
306
  ]
311
307
 
312
- transport = SubprocessCLITransport(
313
- prompt="test", options=ClaudeAgentOptions(), cli_path="/usr/bin/claude"
314
- )
308
+ transport = SubprocessCLITransport(prompt="test", options=make_options())
315
309
 
316
310
  mock_process = MagicMock()
317
311
  mock_process.returncode = None
@@ -10,6 +10,15 @@ import pytest
10
10
  from claude_agent_sdk._internal.transport.subprocess_cli import SubprocessCLITransport
11
11
  from claude_agent_sdk.types import ClaudeAgentOptions
12
12
 
13
+ DEFAULT_CLI_PATH = "/usr/bin/claude"
14
+
15
+
16
+ def make_options(**kwargs: object) -> ClaudeAgentOptions:
17
+ """Construct options using the standard CLI path unless overridden."""
18
+
19
+ cli_path = kwargs.pop("cli_path", DEFAULT_CLI_PATH)
20
+ return ClaudeAgentOptions(cli_path=cli_path, **kwargs)
21
+
13
22
 
14
23
  class TestSubprocessCLITransport:
15
24
  """Test subprocess transport implementation."""
@@ -29,9 +38,7 @@ class TestSubprocessCLITransport:
29
38
 
30
39
  def test_build_command_basic(self):
31
40
  """Test building basic CLI command."""
32
- transport = SubprocessCLITransport(
33
- prompt="Hello", options=ClaudeAgentOptions(), cli_path="/usr/bin/claude"
34
- )
41
+ transport = SubprocessCLITransport(prompt="Hello", options=make_options())
35
42
 
36
43
  cmd = transport._build_command()
37
44
  assert cmd[0] == "/usr/bin/claude"
@@ -47,8 +54,7 @@ class TestSubprocessCLITransport:
47
54
  path = Path("/usr/bin/claude")
48
55
  transport = SubprocessCLITransport(
49
56
  prompt="Hello",
50
- options=ClaudeAgentOptions(),
51
- cli_path=path,
57
+ options=ClaudeAgentOptions(cli_path=path),
52
58
  )
53
59
 
54
60
  # Path object is converted to string, compare with str(path)
@@ -58,10 +64,9 @@ class TestSubprocessCLITransport:
58
64
  """Test building CLI command with system prompt as string."""
59
65
  transport = SubprocessCLITransport(
60
66
  prompt="test",
61
- options=ClaudeAgentOptions(
67
+ options=make_options(
62
68
  system_prompt="Be helpful",
63
69
  ),
64
- cli_path="/usr/bin/claude",
65
70
  )
66
71
 
67
72
  cmd = transport._build_command()
@@ -72,10 +77,9 @@ class TestSubprocessCLITransport:
72
77
  """Test building CLI command with system prompt preset."""
73
78
  transport = SubprocessCLITransport(
74
79
  prompt="test",
75
- options=ClaudeAgentOptions(
80
+ options=make_options(
76
81
  system_prompt={"type": "preset", "preset": "claude_code"},
77
82
  ),
78
- cli_path="/usr/bin/claude",
79
83
  )
80
84
 
81
85
  cmd = transport._build_command()
@@ -86,14 +90,13 @@ class TestSubprocessCLITransport:
86
90
  """Test building CLI command with system prompt preset and append."""
87
91
  transport = SubprocessCLITransport(
88
92
  prompt="test",
89
- options=ClaudeAgentOptions(
93
+ options=make_options(
90
94
  system_prompt={
91
95
  "type": "preset",
92
96
  "preset": "claude_code",
93
97
  "append": "Be concise.",
94
98
  },
95
99
  ),
96
- cli_path="/usr/bin/claude",
97
100
  )
98
101
 
99
102
  cmd = transport._build_command()
@@ -105,14 +108,13 @@ class TestSubprocessCLITransport:
105
108
  """Test building CLI command with options."""
106
109
  transport = SubprocessCLITransport(
107
110
  prompt="test",
108
- options=ClaudeAgentOptions(
111
+ options=make_options(
109
112
  allowed_tools=["Read", "Write"],
110
113
  disallowed_tools=["Bash"],
111
114
  model="claude-sonnet-4-5",
112
115
  permission_mode="acceptEdits",
113
116
  max_turns=5,
114
117
  ),
115
- cli_path="/usr/bin/claude",
116
118
  )
117
119
 
118
120
  cmd = transport._build_command()
@@ -135,8 +137,7 @@ class TestSubprocessCLITransport:
135
137
  dir2 = Path("/path/to/dir2")
136
138
  transport = SubprocessCLITransport(
137
139
  prompt="test",
138
- options=ClaudeAgentOptions(add_dirs=[dir1, dir2]),
139
- cli_path="/usr/bin/claude",
140
+ options=make_options(add_dirs=[dir1, dir2]),
140
141
  )
141
142
 
142
143
  cmd = transport._build_command()
@@ -155,10 +156,7 @@ class TestSubprocessCLITransport:
155
156
  """Test session continuation options."""
156
157
  transport = SubprocessCLITransport(
157
158
  prompt="Continue from before",
158
- options=ClaudeAgentOptions(
159
- continue_conversation=True, resume="session-123"
160
- ),
161
- cli_path="/usr/bin/claude",
159
+ options=make_options(continue_conversation=True, resume="session-123"),
162
160
  )
163
161
 
164
162
  cmd = transport._build_command()
@@ -198,8 +196,7 @@ class TestSubprocessCLITransport:
198
196
 
199
197
  transport = SubprocessCLITransport(
200
198
  prompt="test",
201
- options=ClaudeAgentOptions(),
202
- cli_path="/usr/bin/claude",
199
+ options=make_options(),
203
200
  )
204
201
 
205
202
  await transport.connect()
@@ -215,9 +212,7 @@ class TestSubprocessCLITransport:
215
212
  """Test reading messages from CLI output."""
216
213
  # This test is simplified to just test the transport creation
217
214
  # The full async stream handling is tested in integration tests
218
- transport = SubprocessCLITransport(
219
- prompt="test", options=ClaudeAgentOptions(), cli_path="/usr/bin/claude"
220
- )
215
+ transport = SubprocessCLITransport(prompt="test", options=make_options())
221
216
 
222
217
  # The transport now just provides raw message reading via read_messages()
223
218
  # So we just verify the transport can be created and basic structure is correct
@@ -231,8 +226,7 @@ class TestSubprocessCLITransport:
231
226
  async def _test():
232
227
  transport = SubprocessCLITransport(
233
228
  prompt="test",
234
- options=ClaudeAgentOptions(cwd="/this/directory/does/not/exist"),
235
- cli_path="/usr/bin/claude",
229
+ options=make_options(cwd="/this/directory/does/not/exist"),
236
230
  )
237
231
 
238
232
  with pytest.raises(CLIConnectionError) as exc_info:
@@ -246,8 +240,7 @@ class TestSubprocessCLITransport:
246
240
  """Test building CLI command with settings as file path."""
247
241
  transport = SubprocessCLITransport(
248
242
  prompt="test",
249
- options=ClaudeAgentOptions(settings="/path/to/settings.json"),
250
- cli_path="/usr/bin/claude",
243
+ options=make_options(settings="/path/to/settings.json"),
251
244
  )
252
245
 
253
246
  cmd = transport._build_command()
@@ -259,8 +252,7 @@ class TestSubprocessCLITransport:
259
252
  settings_json = '{"permissions": {"allow": ["Bash(ls:*)"]}}'
260
253
  transport = SubprocessCLITransport(
261
254
  prompt="test",
262
- options=ClaudeAgentOptions(settings=settings_json),
263
- cli_path="/usr/bin/claude",
255
+ options=make_options(settings=settings_json),
264
256
  )
265
257
 
266
258
  cmd = transport._build_command()
@@ -271,14 +263,13 @@ class TestSubprocessCLITransport:
271
263
  """Test building CLI command with extra_args for future flags."""
272
264
  transport = SubprocessCLITransport(
273
265
  prompt="test",
274
- options=ClaudeAgentOptions(
266
+ options=make_options(
275
267
  extra_args={
276
268
  "new-flag": "value",
277
269
  "boolean-flag": None,
278
270
  "another-option": "test-value",
279
271
  }
280
272
  ),
281
- cli_path="/usr/bin/claude",
282
273
  )
283
274
 
284
275
  cmd = transport._build_command()
@@ -309,8 +300,7 @@ class TestSubprocessCLITransport:
309
300
 
310
301
  transport = SubprocessCLITransport(
311
302
  prompt="test",
312
- options=ClaudeAgentOptions(mcp_servers=mcp_servers),
313
- cli_path="/usr/bin/claude",
303
+ options=make_options(mcp_servers=mcp_servers),
314
304
  )
315
305
 
316
306
  cmd = transport._build_command()
@@ -333,8 +323,7 @@ class TestSubprocessCLITransport:
333
323
  string_path = "/path/to/mcp-config.json"
334
324
  transport = SubprocessCLITransport(
335
325
  prompt="test",
336
- options=ClaudeAgentOptions(mcp_servers=string_path),
337
- cli_path="/usr/bin/claude",
326
+ options=make_options(mcp_servers=string_path),
338
327
  )
339
328
 
340
329
  cmd = transport._build_command()
@@ -346,8 +335,7 @@ class TestSubprocessCLITransport:
346
335
  path_obj = Path("/path/to/mcp-config.json")
347
336
  transport = SubprocessCLITransport(
348
337
  prompt="test",
349
- options=ClaudeAgentOptions(mcp_servers=path_obj),
350
- cli_path="/usr/bin/claude",
338
+ options=make_options(mcp_servers=path_obj),
351
339
  )
352
340
 
353
341
  cmd = transport._build_command()
@@ -361,8 +349,7 @@ class TestSubprocessCLITransport:
361
349
  json_config = '{"mcpServers": {"server": {"type": "stdio", "command": "test"}}}'
362
350
  transport = SubprocessCLITransport(
363
351
  prompt="test",
364
- options=ClaudeAgentOptions(mcp_servers=json_config),
365
- cli_path="/usr/bin/claude",
352
+ options=make_options(mcp_servers=json_config),
366
353
  )
367
354
 
368
355
  cmd = transport._build_command()
@@ -379,7 +366,7 @@ class TestSubprocessCLITransport:
379
366
  "MY_TEST_VAR": test_value,
380
367
  }
381
368
 
382
- options = ClaudeAgentOptions(env=custom_env)
369
+ options = make_options(env=custom_env)
383
370
 
384
371
  # Mock the subprocess to capture the env argument
385
372
  with patch(
@@ -408,7 +395,6 @@ class TestSubprocessCLITransport:
408
395
  transport = SubprocessCLITransport(
409
396
  prompt="test",
410
397
  options=options,
411
- cli_path="/usr/bin/claude",
412
398
  )
413
399
 
414
400
  await transport.connect()
@@ -440,7 +426,7 @@ class TestSubprocessCLITransport:
440
426
 
441
427
  async def _test():
442
428
  custom_user = "claude"
443
- options = ClaudeAgentOptions(user=custom_user)
429
+ options = make_options(user=custom_user)
444
430
 
445
431
  # Mock the subprocess to capture the env argument
446
432
  with patch(
@@ -469,7 +455,6 @@ class TestSubprocessCLITransport:
469
455
  transport = SubprocessCLITransport(
470
456
  prompt="test",
471
457
  options=options,
472
- cli_path="/usr/bin/claude",
473
458
  )
474
459
 
475
460
  await transport.connect()