Skip to content

Commit 81fd53c

Browse files
committed
fix: pass system prompt via stdin for all platforms to fix Claude CLI compatibility
- Modified runProcess() to pass both system prompt and messages via stdin for all platforms - This fixes compatibility issues with Claude CLI versions newer than 1.0.58 - Avoids shell escaping issues and command-line length limits - Updated tests to reflect the new unified behavior Fixes #7145
1 parent 2a974e8 commit 81fd53c

File tree

2 files changed

+14
-26
lines changed

2 files changed

+14
-26
lines changed

src/integrations/claude-code/__tests__/run.spec.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ describe("runClaudeCode", () => {
141141
expect(typeof result[Symbol.asyncIterator]).toBe("function")
142142
})
143143

144-
test("should handle platform-specific stdin behavior", async () => {
144+
test("should pass system prompt via stdin for all platforms", async () => {
145145
const { runClaudeCode } = await import("../run")
146146
const messages = [{ role: "user" as const, content: "Hello world!" }]
147147
const systemPrompt = "You are a helpful assistant"
@@ -160,7 +160,7 @@ describe("runClaudeCode", () => {
160160
results.push(chunk)
161161
}
162162

163-
// On Windows, should NOT have --system-prompt in args
163+
// Should NOT have --system-prompt in args for any platform
164164
const [, args] = mockExeca.mock.calls[0]
165165
expect(args).not.toContain("--system-prompt")
166166

@@ -172,7 +172,7 @@ describe("runClaudeCode", () => {
172172
vi.clearAllMocks()
173173
mockExeca.mockReturnValue(createMockProcess())
174174

175-
// Test on non-Windows
175+
// Test on non-Windows (e.g., macOS/Linux)
176176
vi.mocked(os.platform).mockReturnValue("darwin")
177177

178178
const generator2 = runClaudeCode(options)
@@ -181,13 +181,12 @@ describe("runClaudeCode", () => {
181181
results2.push(chunk)
182182
}
183183

184-
// On non-Windows, should have --system-prompt in args
184+
// Should NOT have --system-prompt in args (same behavior as Windows now)
185185
const [, args2] = mockExeca.mock.calls[0]
186-
expect(args2).toContain("--system-prompt")
187-
expect(args2).toContain(systemPrompt)
186+
expect(args2).not.toContain("--system-prompt")
188187

189-
// Should only pass messages via stdin
190-
expect(mockStdin.write).toHaveBeenCalledWith(JSON.stringify(messages), "utf8", expect.any(Function))
188+
// Should pass both system prompt and messages via stdin (same as Windows)
189+
expect(mockStdin.write).toHaveBeenCalledWith(expectedStdinData, "utf8", expect.any(Function))
191190
})
192191

193192
test("should include model parameter when provided", async () => {

src/integrations/claude-code/run.ts

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,10 @@ function runProcess({
151151
maxOutputTokens,
152152
}: ClaudeCodeOptions & { maxOutputTokens?: number }) {
153153
const claudePath = path || "claude"
154-
const isWindows = os.platform() === "win32"
155154

156-
// Build args based on platform
155+
// Build args - no longer passing system prompt as flag for any platform
157156
const args = ["-p"]
158157

159-
// Pass system prompt as flag on non-Windows, via stdin on Windows (avoids cmd length limits)
160-
if (!isWindows) {
161-
args.push("--system-prompt", systemPrompt)
162-
}
163-
164158
args.push(
165159
"--verbose",
166160
"--output-format",
@@ -193,17 +187,12 @@ function runProcess({
193187
timeout: CLAUDE_CODE_TIMEOUT,
194188
})
195189

196-
// Prepare stdin data: Windows gets both system prompt & messages (avoids 8191 char limit),
197-
// other platforms get messages only (avoids Linux E2BIG error from ~128KiB execve limit)
198-
let stdinData: string
199-
if (isWindows) {
200-
stdinData = JSON.stringify({
201-
systemPrompt,
202-
messages,
203-
})
204-
} else {
205-
stdinData = JSON.stringify(messages)
206-
}
190+
// Pass both system prompt and messages via stdin for all platforms
191+
// This avoids shell escaping issues and command-line length limits
192+
const stdinData = JSON.stringify({
193+
systemPrompt,
194+
messages,
195+
})
207196

208197
// Use setImmediate to ensure process is spawned before writing (prevents stdin race conditions)
209198
setImmediate(() => {

0 commit comments

Comments
 (0)