Skip to content

Commit 52d5b74

Browse files
fix: inherit process.env when spawning agent subprocess (agentclientprotocol#374)
In 0.20.0, the env option was introduced with an explicit object spread, but without including process.env. This caused the subprocess to receive an empty environment, stripping HOME, PATH and other inherited variables when spawned from an external editor such as Zed. Add ...process.env as the base so user-provided and gateway env vars still override it, while preserving the parent process environment. Add tests to verify HOME/PATH are inherited and that user-provided vars are merged on top correctly. Fixes agentclientprotocol#373 --------- Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
1 parent edf6486 commit 52d5b74

7 files changed

Lines changed: 59 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.20.1
4+
5+
- fix: inherit process.env when spawning agent subprocess
6+
37
## 0.20.0
48

59
- Update to @anthropic-ai/claude-agent-sdk@0.2.63

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"publishConfig": {
44
"access": "public"
55
},
6-
"version": "0.20.0",
6+
"version": "0.20.1",
77
"description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
88
"main": "dist/lib.js",
99
"types": "dist/lib.d.ts",

src/acp-agent.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,7 @@ export class ClaudeAcpAgent implements Agent {
12401240
...(maxThinkingTokens !== undefined && { maxThinkingTokens }),
12411241
...userProvidedOptions,
12421242
env: {
1243+
...process.env,
12431244
...userProvidedOptions?.env,
12441245
...createEnvForGateway(this.gatewayAuthMeta),
12451246
},

src/tests/acp-agent.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ describe.skipIf(!process.env.RUN_INTEGRATION_TESTS)("ACP subprocess integration"
227227
sessionId: newSessionResponse.sessionId,
228228
});
229229

230-
expect(client.takeReceivedText()).toBe("");
230+
expect(client.takeReceivedText()).toBe("Error: No messages to compact");
231231

232232
// Send something
233233
await connection.prompt({

src/tests/authorization.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ describe("authorization", () => {
101101
expect(mockQuery).toHaveBeenCalledWith(
102102
expect.objectContaining({
103103
options: expect.objectContaining({
104-
env: {
104+
env: expect.objectContaining({
105105
ANTHROPIC_AUTH_TOKEN: "",
106106
ANTHROPIC_BASE_URL: "https://gateway.example",
107107
ANTHROPIC_CUSTOM_HEADERS: "x-api-key: test",
108108
userEnv: "userEnv",
109-
},
109+
}),
110110
}),
111111
}),
112112
);

src/tests/create-session-options.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,54 @@ describe("createSession options merging", () => {
151151
expect(capturedOptions!.hooks?.PostToolUse).toHaveLength(2);
152152
});
153153

154+
it("inherits HOME and PATH from process.env when no env is provided", async () => {
155+
await agent.newSession({
156+
cwd: "/test",
157+
mcpServers: [],
158+
});
159+
160+
expect(capturedOptions?.env?.HOME).toBe(process.env.HOME);
161+
expect(capturedOptions?.env?.PATH).toBe(process.env.PATH);
162+
});
163+
164+
it("merges user-provided env vars on top of process.env", async () => {
165+
await agent.newSession({
166+
cwd: "/test",
167+
mcpServers: [],
168+
_meta: {
169+
claudeCode: {
170+
options: {
171+
env: {
172+
CUSTOM_VAR: "custom-value",
173+
},
174+
},
175+
},
176+
},
177+
});
178+
179+
expect(capturedOptions?.env?.HOME).toBe(process.env.HOME);
180+
expect(capturedOptions?.env?.PATH).toBe(process.env.PATH);
181+
expect(capturedOptions?.env?.CUSTOM_VAR).toBe("custom-value");
182+
});
183+
184+
it("allows user-provided env vars to override process.env entries", async () => {
185+
await agent.newSession({
186+
cwd: "/test",
187+
mcpServers: [],
188+
_meta: {
189+
claudeCode: {
190+
options: {
191+
env: {
192+
HOME: "/custom/home",
193+
},
194+
},
195+
},
196+
},
197+
});
198+
199+
expect(capturedOptions?.env?.HOME).toBe("/custom/home");
200+
});
201+
154202
it("merges user-provided mcpServers with ACP mcpServers", async () => {
155203
await agent.newSession({
156204
cwd: "/test",

0 commit comments

Comments
 (0)