diff --git a/src/integrations/claude-code/__tests__/run.spec.ts b/src/integrations/claude-code/__tests__/run.spec.ts index fa5aedcd36..17108dd93a 100644 --- a/src/integrations/claude-code/__tests__/run.spec.ts +++ b/src/integrations/claude-code/__tests__/run.spec.ts @@ -141,7 +141,7 @@ describe("runClaudeCode", () => { expect(typeof result[Symbol.asyncIterator]).toBe("function") }) - test("should handle platform-specific stdin behavior", async () => { + test("should pass system prompt via stdin for all platforms", async () => { const { runClaudeCode } = await import("../run") const messages = [{ role: "user" as const, content: "Hello world!" }] const systemPrompt = "You are a helpful assistant" @@ -160,7 +160,7 @@ describe("runClaudeCode", () => { results.push(chunk) } - // On Windows, should NOT have --system-prompt in args + // Should NOT have --system-prompt in args for any platform const [, args] = mockExeca.mock.calls[0] expect(args).not.toContain("--system-prompt") @@ -172,7 +172,7 @@ describe("runClaudeCode", () => { vi.clearAllMocks() mockExeca.mockReturnValue(createMockProcess()) - // Test on non-Windows + // Test on non-Windows (e.g., macOS/Linux) vi.mocked(os.platform).mockReturnValue("darwin") const generator2 = runClaudeCode(options) @@ -181,13 +181,12 @@ describe("runClaudeCode", () => { results2.push(chunk) } - // On non-Windows, should have --system-prompt in args + // Should NOT have --system-prompt in args (same behavior as Windows now) const [, args2] = mockExeca.mock.calls[0] - expect(args2).toContain("--system-prompt") - expect(args2).toContain(systemPrompt) + expect(args2).not.toContain("--system-prompt") - // Should only pass messages via stdin - expect(mockStdin.write).toHaveBeenCalledWith(JSON.stringify(messages), "utf8", expect.any(Function)) + // Should pass both system prompt and messages via stdin (same as Windows) + expect(mockStdin.write).toHaveBeenCalledWith(expectedStdinData, "utf8", expect.any(Function)) }) test("should include model parameter when provided", async () => { diff --git a/src/integrations/claude-code/run.ts b/src/integrations/claude-code/run.ts index 3f438df0fc..71ed232133 100644 --- a/src/integrations/claude-code/run.ts +++ b/src/integrations/claude-code/run.ts @@ -151,16 +151,10 @@ function runProcess({ maxOutputTokens, }: ClaudeCodeOptions & { maxOutputTokens?: number }) { const claudePath = path || "claude" - const isWindows = os.platform() === "win32" - // Build args based on platform + // Build args - no longer passing system prompt as flag for any platform const args = ["-p"] - // Pass system prompt as flag on non-Windows, via stdin on Windows (avoids cmd length limits) - if (!isWindows) { - args.push("--system-prompt", systemPrompt) - } - args.push( "--verbose", "--output-format", @@ -193,17 +187,12 @@ function runProcess({ timeout: CLAUDE_CODE_TIMEOUT, }) - // Prepare stdin data: Windows gets both system prompt & messages (avoids 8191 char limit), - // other platforms get messages only (avoids Linux E2BIG error from ~128KiB execve limit) - let stdinData: string - if (isWindows) { - stdinData = JSON.stringify({ - systemPrompt, - messages, - }) - } else { - stdinData = JSON.stringify(messages) - } + // Pass both system prompt and messages via stdin for all platforms + // This avoids shell escaping issues and command-line length limits + const stdinData = JSON.stringify({ + systemPrompt, + messages, + }) // Use setImmediate to ensure process is spawned before writing (prevents stdin race conditions) setImmediate(() => {