Skip to content

Fix #8: Pass chat-session system prompts via file to avoid Windows command-line limit - #243

Open
arkaccess wants to merge 1 commit into
AutoForgeAI:masterfrom
arkaccess:swarm/issue-8-barbara
Open

arkaccess wants to merge 1 commit into
AutoForgeAI:masterfrom
arkaccess:swarm/issue-8-barbara

Conversation

@arkaccess

Copy link
Copy Markdown

Closes #8

Problem

On Windows, creating a new project failed with Failed to initialize Claude: Command failed with exit code 1. The console showed The command line is too long. A plain-string system_prompt is passed to the Claude CLI as a --system-prompt <text> argument. Windows caps command lines at about 8191 characters, and create-spec.md alone is about 20 KB.

There was a partial workaround in master: spec and assistant chats wrote their prompt into the project's CLAUDE.md and loaded it via setting_sources. That overwrote any real project CLAUDE.md the coding agent relies on. The expand-project chat still passed its about 6.6 KB prompt on the command line, and the extra MCP, tools and settings arguments push it close to the limit.

Fix

As the issue suggests, the prompt is now passed through a file:

  • New helpers write_system_prompt_file() / remove_system_prompt_file() in server/services/chat_constants.py. They write the prompt to a unique .autoforge/.system_prompt.<kind>.<uuid>.md file. The path comes from the new autoforge_paths.get_system_prompt_path(), and the pattern is added to the generated .autoforge/.gitignore.
  • Spec, expand and assistant chat sessions pass system_prompt={"type": "file", "path": ...}. The SDK turns that into --system-prompt-file <path>, so the command line stays short no matter how long the prompt is. Each session deletes its file in close().
  • Spec and assistant sessions no longer overwrite the project's CLAUDE.md. They keep setting_sources, so a real project CLAUDE.md is still loaded as extra context.
  • Minimum claude-agent-sdk raised from 0.1.39 to 0.1.51 in requirements.txt and requirements-prod.txt. I checked the wheels: 0.1.51 is the first release with SystemPromptFile and --system-prompt-file; 0.1.50 does not have it.

Verification

  • New test_system_prompt_file.py (3 tests). It checks that the file is written to .autoforge/, is gitignored, is unique per session and is removed on close, and that CLAUDE.md is not touched. It also builds the real SDK CLI command with a 20 KB prompt: the command contains --system-prompt-file, does not contain the prompt text, and is shorter than 8191 characters.
  • End-to-end smoke test on Linux with the real Claude CLI (2.1.303) and SDK 0.1.81: SpecChatSession.start() on a fresh project dir. Claude replied with the create-spec Phase 1 greeting, which shows it read the prompt from the file. No CLAUDE.md was created, and the temp file was gone after close().
  • I checked that the CLI accepts --system-prompt-file; a missing file gives System prompt file not found.
  • ruff check . passes. mypy . shows the same 25 errors as master, none new. test_security.py and test_security_integration.py pass. test_client.py passes.
  • test_devserver_security.py has 21 failures, and master has the same 21, so they are not caused by this change.
  • No UI changes, so I did not run a browser check.

Assumptions / notes

  • I could not test on Windows. The fix removes the long argument altogether, which is the root cause in the issue.
  • Existing projects whose CLAUDE.md was already overwritten by the old workaround keep that file. I did not auto-delete it, because I can't reliably tell it apart from a file the user wrote.
  • The CLI reads --system-prompt-file as a full replacement prompt. Before, the spec prompt was loaded as CLAUDE.md context on top of an empty system prompt, so the effective behaviour is the same.
  • The branch was pushed to the arkaccess/autoforge fork, because the bot account only has read access to upstream.

🤖 Generated with Claude Code

…pt-file

Windows limits command lines to ~8191 characters, so passing the
create-spec/expand-project skills as a --system-prompt argument fails
with "The command line is too long." and surfaces in the UI as
"Failed to initialize Claude: Command failed with exit code 1".

Spec, expand and assistant chat sessions now write their system prompt
to a unique, gitignored .autoforge/.system_prompt.<kind>.<uuid>.md file
and pass it as system_prompt={"type": "file", ...}, which the SDK
forwards as --system-prompt-file. The file is removed when the session
closes.

This also replaces the previous workaround of overwriting the project's
CLAUDE.md with the spec/assistant prompt, which clobbered any real
project CLAUDE.md the coding agent relies on.

Bumps claude-agent-sdk to >=0.1.51 (first release with SystemPromptFile).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@arkaccess

Copy link
Copy Markdown
Author

🔍 QA report: ✅ Passed

Tester: Ken (cubefarm agent, in a fresh session) · Round: 1 · Author: Barbara

The PR fixes issue #8: spec, expand and assistant chat sessions now write their system prompt to a gitignored .autoforge/.system_prompt...md file and pass it with --system-prompt-file, and no longer overwrite the project's CLAUDE.md. I built the real SDK command for each session (no API calls). It contains --system-prompt-file, no long prompt argument, and is 545 to 1411 characters long (prompts up to 21 KB), well below Windows' 8191 limit. Each prompt file is deleted on close(), and a user's own CLAUDE.md is left unchanged. ruff, mypy (same 24 errors as master), pytest (only the 21 test_devserver_security failures master already has), UI lint and build, server boot, REST and WebSocket checks, and a browser smoke test all pass.

Check Details
✅ Issue #8: long system prompt not on the command line I replaced ClaudeSDKClient with a fake (no API calls) and built the real CLI command with SubprocessCLITransport for each session. Spec: 21203-char prompt, 545-char command. Expand: 6800-char prompt, 1069-char command. Assistant: 3778-char prompt, 1411-char command. Each command has --system-prompt-file and no argument longer than 2000 chars. Not tested on Windows itself.
✅ Project CLAUDE.md not overwritten A user-written CLAUDE.md was unchanged after starting each of the three sessions.
✅ Temp prompt file lifecycle and gitignore The file exists while the client starts and is removed on close(); nothing is left in .autoforge/. The .system_prompt.*.md pattern is in the generated .autoforge/.gitignore of a project created through the API. Minor: if the client fails to start, the file stays until close() or server shutdown (gitignored, harmless).
✅ SDK minimum version 0.1.51 is correct Downloaded the wheels: the 0.1.50 subprocess_cli.py has no --system-prompt-file, 0.1.51 has it. The venv runs 0.1.81.
✅ Python lint, types, tests ruff clean. mypy shows the same 24 errors on master and on the branch. pytest: 147 passed, 21 failed; master gives 144 passed with the same 21 test_devserver_security failures. The 3 new tests pass. The security tests pass.
✅ Server boot, REST and WebSocket uvicorn on 127.0.0.1:5345: /api/health 200, GET/POST /api/projects 200, invalid name 422, features 200. /ws/projects/qa243 connects and streams messages.
✅ UI smoke test in browser Dashboard, Kanban and Graph views render with 0 console errors or warnings, also at 390x844. No UI files changed, so e2e was not needed.
✅ Security and process cleanup security.py and the localhost middleware are untouched, and no secrets are logged. The server was stopped and the port is free afterwards.
🧪 Commands run
Command Result
venv/bin/ruff check . All checks passed
venv/bin/mypy . (PR vs origin/master) 24 errors on both, identical sets, none new
venv/bin/python -m pytest -q (PR) 147 passed, 21 failed (all in test_devserver_security.py, same failures on master)
venv/bin/python -m pytest -q (origin/master) 144 passed, 21 failed
venv/bin/python -m pytest test_system_prompt_file.py test_client.py 24 passed
venv/bin/python test_security.py && venv/bin/python test_security_integration.py All tests passed
pip download claude-agent-sdk==0.1.50 / 0.1.51 and grep for system-prompt-file 0.1.50: 0 matches, 0.1.51: 1 match
probe.py (fake ClaudeSDKClient, real _build_command for spec, expand and assistant sessions) All use --system-prompt-file; commands are 545, 1069 and 1411 chars; CLAUDE.md unchanged; prompt files removed on close
npm --prefix ui run lint 0 errors, 6 warnings
npm --prefix ui run build built successfully
uvicorn server.main:app --port 5345 + curl REST routes + websocket client 200 and 422 as expected; WebSocket streams

No browser screenshots were taken in this round.

Posted by cubefarm · merges automatically once GitHub's checks pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Creating a new Project in Windows under DOS results in Failed to intialize Claude Error

2 participants