Skip to content

Commit 78240c0

Browse files
committed
feat: allow claude code process to run as a custom user (#133)
1 parent f794e17 commit 78240c0

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

src/claude_code_sdk/_internal/transport/subprocess_cli.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ async def connect(self) -> None:
189189
stderr=self._stderr_file,
190190
cwd=self._cwd,
191191
env=process_env,
192+
user=self._options.user,
192193
)
193194

194195
if self._process.stdout:

src/claude_code_sdk/types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,4 @@ class ClaudeCodeOptions:
141141
extra_args: dict[str, str | None] = field(
142142
default_factory=dict
143143
) # Pass arbitrary CLI flags
144+
user: str | None = None

tests/test_transport.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,42 @@ async def _test():
352352
assert env_passed["PATH"] == os.environ["PATH"]
353353

354354
anyio.run(_test)
355+
356+
def test_connect_as_different_user(self):
357+
"""Test connect as different user."""
358+
359+
async def _test():
360+
361+
custom_user = "claude"
362+
options = ClaudeCodeOptions(user=custom_user)
363+
364+
# Mock the subprocess to capture the env argument
365+
with patch(
366+
"anyio.open_process", new_callable=AsyncMock
367+
) as mock_open_process:
368+
mock_process = MagicMock()
369+
mock_process.stdout = MagicMock()
370+
mock_stdin = MagicMock()
371+
mock_stdin.aclose = AsyncMock() # Add async aclose method
372+
mock_process.stdin = mock_stdin
373+
mock_process.returncode = None
374+
mock_open_process.return_value = mock_process
375+
376+
transport = SubprocessCLITransport(
377+
prompt="test",
378+
options=options,
379+
cli_path="/usr/bin/claude",
380+
)
381+
382+
await transport.connect()
383+
384+
# Verify open_process was called with correct user
385+
mock_open_process.assert_called_once()
386+
call_kwargs = mock_open_process.call_args.kwargs
387+
assert "user" in call_kwargs
388+
user_passed = call_kwargs["user"]
389+
390+
# Check that user was passed
391+
assert user_passed == "claude"
392+
393+
anyio.run(_test)

0 commit comments

Comments
 (0)