Skip to content

Fix #8: Pass chat session system prompts via --system-prompt-file (Windows cmdline limit) - #295

Open
zwanski-start wants to merge 1 commit into
AutoForgeAI:masterfrom
zwanski-start:swarm/issue-8-ada
Open

zwanski-start wants to merge 1 commit into
AutoForgeAI:masterfrom
zwanski-start:swarm/issue-8-ada

Conversation

@zwanski-start

Copy link
Copy Markdown

Closes #8

Problem

On Windows, creating a project failed with Failed to initialize Claude: Command failed with exit code 1 / The command line is too long. The chat sessions built long system prompts (create-spec.md alone is ~20 KB) that ended up on the Claude CLI command line, which Windows caps at about 8191 characters.

Current master had partly worked around this for spec creation and the assistant by writing the prompt into the project's CLAUDE.md. That overwrote the user's own CLAUDE.md, which the coding agents load. The expand-project session still passed its prompt inline with --system-prompt.

Change

This follows the fix suggested in the issue: pass the prompt to Claude as a file.

  • chat_constants.write_system_prompt_file() writes each session's prompt to its own .autoforge/.system_prompt.<kind>.<uuid>.md. remove_system_prompt_file() deletes it when the session closes.
  • The spec, expand and assistant sessions now pass system_prompt={"type": "file", "path": ...}. The SDK turns this into --system-prompt-file, so the command line stays short however long the prompt is.
  • The spec and assistant sessions no longer write to the project's CLAUDE.md.
  • autoforge_paths.get_system_prompt_path() builds the file path, and .system_prompt.*.md is added to the generated .autoforge/.gitignore.
  • Raised the minimum claude-agent-sdk to >=0.1.51, the first version with SystemPromptFile (per the SDK changelog). Installed environments already pick up 0.1.81 under the existing <0.2.0 cap.

Verification

  • New test_system_prompt_file.py (2 tests, both pass). It runs the spec and expand sessions with a stubbed SDK client, builds the real CLI command with the SDK's SubprocessCLITransport, and checks that:
    • --system-prompt-file is used and --system-prompt is not
    • the full command line is under 8191 characters
    • the file holds the full skill with $ARGUMENTS replaced
    • CLAUDE.md is not written
    • the file is removed on close()
  • Manually ran claude -p --system-prompt-file <18 KB file> --output-format stream-json --verbose (the mode the SDK uses) with CLI 2.1.303. The prompt was applied.
  • ruff check . is clean. mypy shows the same errors before and after this change. test_security.py, test_client.py, test_dependency_resolver.py, test_rate_limit_utils.py and test_ws_security.py pass.
  • test_devserver_security.py has 21 failures, and the same 21 fail on unmodified master, so they are unrelated to this change.
  • Not tested on a real Windows machine; none was available.

Assumptions / notes

  • Projects whose CLAUDE.md was already overwritten by an older spec or assistant session keep that file. The assistant still uses setting_sources=["project"], so it may see that old prompt as project context next to the real system prompt. That duplication is harmless, and this PR does not delete user files.
  • The assistant UI was not changed, so I skipped a browser check.

🤖 Generated with Claude Code

…pt-file

Spec creation, project expansion and the assistant built long system
prompts (create-spec.md alone is ~20KB). Passing them inline exceeded
the Windows ~8191 character command line limit ("The command line is
too long"); the spec/assistant workaround of writing the prompt to the
project's CLAUDE.md clobbered the user's CLAUDE.md, and expand still
passed its prompt inline.

Write each prompt to a per-session .autoforge/.system_prompt.<kind>.<uuid>.md
file, hand it to the CLI via SystemPromptFile (--system-prompt-file),
and delete it when the session closes. Requires claude-agent-sdk>=0.1.51.

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

Copy link
Copy Markdown
Author

🔍 QA report: ✅ Passed

Tester: Dennis (cubefarm agent, in a fresh session) · Round: 1 · Author: Ada

Spec, expand and assistant chat sessions now write their system prompt to a per-session .autoforge/.system_prompt...md file and pass it via --system-prompt-file, so the CLI command line stays far below the ~8191-char Windows limit (1.4 KB measured) and the project's CLAUDE.md is no longer overwritten. Verified with the new tests plus an independent probe of the assistant session, confirmed --system-prompt-file first ships in SDK 0.1.51 (justifying the bumped minimum) and that the installed Claude CLI supports it. ruff, mypy and pytest show no regressions against master (the 21 test_devserver_security failures are identical on master), and the server and UI still boot and render cleanly. Not verified on a real Windows machine.

Check Details
✅ Spec/expand sessions use --system-prompt-file, cmdline < 8191, CLAUDE.md untouched, file cleaned on close test_system_prompt_file.py renders the real CLI command with the SDK's SubprocessCLITransport; 2/2 pass.
✅ Assistant session (not covered by PR tests) Throwaway probe with a stubbed ClaudeSDKClient: command 1372 chars with only --system-prompt-file; a user-authored CLAUDE.md is unchanged; re-start replaces the old prompt file (only one left); close() removes it.
✅ SDK minimum version claim Downloaded claude-agent-sdk 0.1.50 and 0.1.51 sdists: 'system-prompt-file' is present only in 0.1.51. Installed venv has 0.1.81. claude CLI 2.1.303 --help lists --system-prompt[-file].
✅ Prompt files ignored by git ensure_autoforge_dir writes .gitignore containing .system_prompt.*.md (rewritten on every call, so existing projects pick it up); git status --ignored shows a prompt file as ignored.
✅ Session lifecycle / stale file cleanup create_session/remove_session in all three services close the old session, which now calls remove_system_prompt_file; unlink errors are logged, not raised.
✅ Backend regressions (ruff/mypy/pytest) ruff clean; mypy 24 errors identical to master (unchanged files); pytest 146 passed/21 failed vs master 144 passed/21 failed, same test_devserver_security failures.
✅ Security tests test_security.py and test_security_integration.py all pass; security.py untouched.
✅ Server boot and REST routes uvicorn on 127.0.0.1:5247; /api/health, /api/projects and /api/settings return 200, an unknown project 404, an invalid name 400; no errors in the server log.
✅ UI smoke in browser Welcome page, project dashboard (live WebSocket indicator) and Kanban board render with 0 console errors. Phone width (390px) works but is cramped by the fixed sidebar; the PR doesn't change the UI, so this was not counted against it.
⏭️ Real Windows run / live chat session No Windows machine available; live chat skipped to avoid paid API calls. Covered by command rendering and length checks.
🧪 Commands run
Command Result
venv/bin/python -m pytest test_system_prompt_file.py -v 2 passed
venv/bin/python -m ruff check . All checks passed
venv/bin/python -m mypy . (PR vs origin/master) 24 errors on both, identical set
venv/bin/python -m pytest -q (PR) 146 passed, 21 failed (test_devserver_security, same as master)
venv/bin/python -m pytest -q (origin/master worktree) 144 passed, 21 failed
venv/bin/python test_security.py && venv/bin/python test_security_integration.py all passed
pip download claude-agent-sdk==0.1.50 / 0.1.51 + grep system-prompt-file present only in 0.1.51
venv/bin/python probe_assistant.py (throwaway) assistant uses the prompt file, CLAUDE.md intact, file removed on close
npm --prefix ui run lint 0 errors, 6 warnings
npm --prefix ui run build success
uvicorn server.main:app --port 5247 + curl key routes health/projects/settings 200, unknown project 404, invalid name 400

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

1 participant