Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions src/integrations/claude-code/__tests__/run.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 and messages 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"
Expand All @@ -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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment references Windows-specific behavior that no longer exists. Could we update it to reflect the unified behavior?

const [, args] = mockExeca.mock.calls[0]
expect(args).not.toContain("--system-prompt")

Expand All @@ -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 for all platforms now)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here - this comment still mentions platform differences that we've eliminated. Consider:

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 () => {
Expand Down
25 changes: 7 additions & 18 deletions src/integrations/claude-code/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 command line argument
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment could be more descriptive about why we're making this change. Consider:

This would help future maintainers understand the reasoning behind this architectural decision.

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",
Expand Down Expand Up @@ -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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two comment lines could be consolidated for brevity:

// This avoids command line argument issues with --system-prompt flag
const stdinData = JSON.stringify({
systemPrompt,
messages,
})

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