Skip to content

Fix #44: Pass chat system prompts via --system-prompt-file (Windows command line too long) - #316

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

zwanski-start wants to merge 1 commit into
AutoForgeAI:masterfrom
zwanski-start:swarm/issue-44-guido

Conversation

@zwanski-start

Copy link
Copy Markdown

Closes #44

Problem

On Windows, claude is a .cmd shim, so the whole command goes through cmd.exe and its ~8191 character limit. Two separate problems came from how the chat sessions passed their system prompts:

  • Expand Project passed its system prompt (expand-project.md, about 6.6KB, plus the project path) inline as --system-prompt. With the other arguments (--mcp-config JSON, tool lists, settings path), that goes over the limit and fails with "The command line is too long."
  • Project Assistant / Spec creation worked around the limit (07c2010) by overwriting the project's CLAUDE.md with the chat prompt. That deletes whatever the user had in CLAUDE.md. It also leaks the chat-only instructions into the coding agents, which load CLAUDE.md via setting_sources=["project"] (for example, the assistant's "You must NEVER implement code").

Fix

  • New helpers in server/services/chat_constants.py:
    • write_system_prompt_file() writes the prompt to a per-session file, .autoforge/.system_prompt.<kind>.<uuid>.md.
    • remove_system_prompt_file() deletes it.
  • Assistant, spec and expand sessions now pass system_prompt={"type": "file", "path": ...}, which the SDK sends as --system-prompt-file <path>. Each session deletes its file in close().
  • None of the sessions write to CLAUDE.md any more. The assistant and spec sessions still use setting_sources, so the project's real CLAUDE.md is now read as context instead of being overwritten.
  • Added get_system_prompt_path() to autoforge_paths.py, and added .system_prompt.*.md to the .autoforge/.gitignore template.
  • Raised the minimum claude-agent-sdk to 0.1.51, the first release that supports the file system prompt option. I checked this by comparing the 0.1.50 and 0.1.51 wheels.

Verification

  • Captured the real CLI command each session builds, with SDK 0.1.81 and a long project path:
    • Assistant: about 1.9k characters
    • Expand: about 1.5k characters (before this change it carried the 6.6KB prompt inline)
    • Spec: about 0.8k characters
  • Confirmed the prompt files are created on start and deleted on close.
  • Confirmed an existing CLAUDE.md is left untouched.
  • End-to-end on Linux with the real claude CLI: started an AssistantChatSession and asked "what is your role / which project". It answered "I'm the project assistant and backlog manager for the "demo" project…", so the CLI reads the prompt from the file.
  • New test_chat_system_prompt.py (4 tests) passes. ruff check ., test_security.py, test_client.py and test_ws_security.py also pass.
  • mypy . shows no new errors. The diff against master is only line-number shifts of the existing unused-ignore warnings.
  • Not tested on an actual Windows machine. The fix relies on the argument length being well under 8191, which the measurements above show.

Assumptions / notes

  • I can't tell which CLAUDE.md files older versions already overwrote, so this PR doesn't try to restore them. Users who see an assistant or create-spec prompt in their project's CLAUDE.md should delete it or restore it from git.
  • Raising the SDK minimum changes the requirements hash, so npm installs will rebuild their venv once on the next start.

🤖 Generated with Claude Code

The expand-project session passed its ~6.6KB system prompt inline as a
CLI argument, pushing the command line past the Windows ~8191 char
limit ("The command line is too long."). The assistant and spec
sessions avoided this by overwriting the project's CLAUDE.md, which
clobbered user content and leaked chat-only instructions (e.g. the
assistant's "never implement code") into the coding agents, which load
CLAUDE.md via setting_sources=["project"].

All three chat sessions now write their prompt to a per-session file
in .autoforge/ (gitignored) and pass it with the SDK's file system
prompt option (--system-prompt-file), deleting it on close. 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: Ken (cubefarm agent, in a fresh session) · Round: 1 · Author: Guido

Assistant, spec and expand chat sessions now hand their system prompt to the Claude CLI via --system-prompt-file (ephemeral .autoforge/.system_prompt.<kind>.<uuid>.md) instead of passing it inline or overwriting the project's CLAUDE.md. With a stub claude CLI recording argv, all three commands contain no inline prompt and stay ~1.3k–2.4k chars (expand was ~10k inline on master, above cmd.exe's 8191 limit), a user CLAUDE.md is left untouched, and prompt files are removed on session close and server shutdown. ruff/mypy show no new problems, new tests and security tests pass, and the 21 pytest failures are identical on master. Not tested on a real Windows machine; the fix is proven by argv length measurement.

Check Details
✅ Code review of diff Small, focused change: write/remove helpers in chat_constants.py, a path helper plus a .gitignore pattern in autoforge_paths.py, and three sessions switched to system_prompt={'type':'file'}, with cleanup in close(). No debug leftovers, security.py and the localhost middleware are untouched, no secrets logged, and no new hardcoded OS paths (pathlib, UTF-8 writes).
✅ SDK support for file system prompt Installed SDK 0.1.81 maps {'type':'file'} to --system-prompt-file <path>, and the installed claude CLI help lists --system-prompt[-file]. Downloaded the 0.1.50 and 0.1.51 wheels: only 0.1.51 contains system-prompt-file, so the new >=0.1.51 floor is correct.
✅ Issue #44 repro: command length (stub claude CLI capturing argv) Long unicode project path. Assistant argv 2431 chars (prompt file 3813 B), Spec 1260 chars (24470 B file), Expand 2089 chars (7988 B file). No --system-prompt inline flag in any of them. On master, expand would carry the ~8KB prompt inline, about 10k chars total, which is over the 8191 limit.
✅ CLAUDE.md no longer overwritten Pre-existing CLAUDE.md content was byte-identical after running assistant, spec and expand sessions, both in a direct probe and through the live server's Assistant panel.
✅ Prompt file lifecycle / cleanup The file exists while the CLI runs (verified from inside the stub) and is deleted by close(), including on the client-init-failure path. In the live server the remaining assistant file persisted while the session was kept for resume (existing design) and was removed on graceful shutdown. No orphan processes left.
✅ Graceful degradation with no API key / failing CLI Assistant panel shows a 'Failed to initialize Claude' error message without crashing. The only console errors are the expected assistant error logs.
✅ UI smoke (project list, dashboard, kanban, assistant panel, phone width) Served SPA on :5345 loads, project selection works, Kanban renders, assistant panel works at 390px width. The PR does not touch the UI.
✅ Backend test suite 148 passed, 21 failed. All 21 failures are in test_devserver_security.py and fail identically on origin/master (diffed failure lists), so they predate this PR.
⏭️ UI e2e tests PR touches no UI code.
⏭️ Real Windows run No Windows machine available. Fix verified by argv length measurement on Linux.
🧪 Commands run
Command Result
venv/bin/ruff check . All checks passed
venv/bin/mypy . 24 errors in 9 files, identical set to origin/master (no new errors)
venv/bin/python -m pytest -q 148 passed, 21 failed (same 21 test_devserver_security failures on master)
venv/bin/python -m pytest -q test_chat_system_prompt.py 4 passed
venv/bin/python test_security.py ALL TESTS PASSED
venv/bin/python test_security_integration.py ALL INTEGRATION TESTS PASSED
npm --prefix ui run build success
npm --prefix ui run lint 0 errors, 6 warnings
pip download claude-agent-sdk==0.1.50 / 0.1.51 + grep system-prompt-file 0.1.50: absent, 0.1.51: present
probe.py with stub claude on PATH (assistant/spec/expand start+close) no inline prompt; argv 1260–2431 chars; files cleaned; CLAUDE.md intact
uvicorn server.main:app --port 5345 (isolated HOME, stub CLI) + Playwright assistant argv 1905 chars, graceful error, file removed on shutdown, no orphans

No browser screenshots were taken in this round.

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

cabana8471-arch pushed a commit to cabana8471-arch/autoforge that referenced this pull request Nov 7, 2026
… (Windows command line too long)

Adaptations: port remove_legacy_claude_md and its prompt-prefix list from AutoForgeAI#307 and call it from write_system_prompt_file, so a CLAUDE.md generated by older versions is removed while a user-authored one is never touched. Keep my-features' requirements pins (claude-agent-sdk>=0.1.81, mcp<2). New test_chat_claude_md.py starts the assistant and spec sessions against a fake SDK client: a pre-existing CLAUDE.md stays unchanged (it was overwritten before this change), none is created, and legacy generated files are removed.

Integrates AutoForgeAI#316

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeH26pcsqoxPb3CDs8g1VN
cabana8471-arch pushed a commit to cabana8471-arch/autoforge that referenced this pull request Nov 7, 2026
…l the model why

Adaptations: with AutoForgeAI#316 in place the spec and expand prompts reach the CLI through the session's ephemeral --system-prompt-file, so the 'no Bash/shell tool' note stays scoped to that conversation and never lands in a CLAUDE.md the coding agents read. The PR's tests now read the note from the system prompt file and assert that no CLAUDE.md is created (they asserted claude_md.endswith(NO_SHELL_PROMPT_NOTE)).

Integrates AutoForgeAI#298

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeH26pcsqoxPb3CDs8g1VN
cabana8471-arch pushed a commit to cabana8471-arch/autoforge that referenced this pull request Nov 8, 2026
…ct (AutoForgeAI#133)

Adaptation: kept my-features' _system_prompt_file (system prompt via --system-prompt-file, AutoForgeAI#316) next to the new query lock in AssistantChatSession.

Integrates AutoForgeAI#332

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeH26pcsqoxPb3CDs8g1VN
cabana8471-arch pushed a commit to cabana8471-arch/autoforge that referenced this pull request Nov 8, 2026
…features

Adaptations (plan Change 4.9, combined with my-features import): onboard mode and its spec-only write hook taken; 'passes': true is accepted by feature_create_bulk only when the feature MCP server runs with AUTOFORGE_ONBOARD_SESSION=1, which only the onboarding session sets (user decision 1A; initializer, assistant and expand sessions get an error). Onboarding refuses a symlinked app_spec.txt and the hook compares against the symlink-free path at write time. Kept my-features' features_created parsing (Phase 1) instead of the PR's second counter, the system-prompt file (AutoForgeAI#316) and web tools; onboard mode gets its own tools note. Not taken: NewProjectModal changes and the mcp requirement pin. Our import wizard offers 'Analyze with AI' for plain codebases: it registers the folder and opens the onboarding chat.

Integrates AutoForgeAI#303

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeH26pcsqoxPb3CDs8g1VN
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.

Windows: Project Assistant Opening Error,"Failed to initialize assistant" "The command line is too long."

1 participant