Files
autocoder/client.py
Auto 05607b310a feat: Add YOLO mode for rapid prototyping without browser testing
Add a new YOLO (You Only Live Once) mode that skips all browser testing
and regression tests for faster feature iteration during prototyping.

Changes made:

**Core YOLO Mode Implementation:**
- Add --yolo CLI flag to autonomous_agent_demo.py
- Update agent.py to accept yolo_mode parameter and select appropriate prompt
- Modify client.py to conditionally include Playwright MCP server (excluded in YOLO mode)
- Add coding_prompt_yolo.template.md with static analysis only verification
- Add get_coding_prompt_yolo() to prompts.py

**Server/API Updates:**
- Add AgentStartRequest schema with yolo_mode field
- Update AgentStatus to include yolo_mode
- Modify process_manager.py to pass --yolo flag to subprocess
- Update agent router to accept yolo_mode in start request

**UI Updates:**
- Add YOLO toggle button (lightning bolt icon) in AgentControl
- Show YOLO mode indicator when agent is running in YOLO mode
- Add useAgentStatus hook to track current mode
- Update startAgent API to accept yoloMode parameter
- Add YOLO toggle in SpecCreationChat completion flow

**Spec Creation Improvements:**
- Fix create-spec.md to properly replace [FEATURE_COUNT] placeholder
- Add REQUIRED FEATURE COUNT section to initializer_prompt.template.md
- Fix spec_chat_session.py to create security settings file for Claude SDK
- Delete app_spec.txt before spec creation to allow fresh creation

**Documentation:**
- Add YOLO mode section to CLAUDE.md with usage examples
- Add checkpoint.md slash command for creating detailed commits

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 08:36:58 +02:00

197 lines
6.9 KiB
Python

"""
Claude SDK Client Configuration
===============================
Functions for creating and configuring the Claude Agent SDK client.
"""
import json
import os
import shutil
import sys
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
from claude_agent_sdk.types import HookMatcher
from security import bash_security_hook
# Feature MCP tools for feature/test management
FEATURE_MCP_TOOLS = [
"mcp__features__feature_get_stats",
"mcp__features__feature_get_next",
"mcp__features__feature_get_for_regression",
"mcp__features__feature_mark_in_progress",
"mcp__features__feature_mark_passing",
"mcp__features__feature_skip",
"mcp__features__feature_create_bulk",
]
# Playwright MCP tools for browser automation
PLAYWRIGHT_TOOLS = [
# Core navigation & screenshots
"mcp__playwright__browser_navigate",
"mcp__playwright__browser_navigate_back",
"mcp__playwright__browser_take_screenshot",
"mcp__playwright__browser_snapshot",
# Element interaction
"mcp__playwright__browser_click",
"mcp__playwright__browser_type",
"mcp__playwright__browser_fill_form",
"mcp__playwright__browser_select_option",
"mcp__playwright__browser_hover",
"mcp__playwright__browser_drag",
"mcp__playwright__browser_press_key",
# JavaScript & debugging
"mcp__playwright__browser_evaluate",
# "mcp__playwright__browser_run_code", # REMOVED - causes Playwright MCP server crash
"mcp__playwright__browser_console_messages",
"mcp__playwright__browser_network_requests",
# Browser management
"mcp__playwright__browser_close",
"mcp__playwright__browser_resize",
"mcp__playwright__browser_tabs",
"mcp__playwright__browser_wait_for",
"mcp__playwright__browser_handle_dialog",
"mcp__playwright__browser_file_upload",
"mcp__playwright__browser_install",
]
# Built-in tools
BUILTIN_TOOLS = [
"Read",
"Write",
"Edit",
"Glob",
"Grep",
"Bash",
]
def create_client(project_dir: Path, model: str, yolo_mode: bool = False):
"""
Create a Claude Agent SDK client with multi-layered security.
Args:
project_dir: Directory for the project
model: Claude model to use
yolo_mode: If True, skip Playwright MCP server for rapid prototyping
Returns:
Configured ClaudeSDKClient (from claude_agent_sdk)
Security layers (defense in depth):
1. Sandbox - OS-level bash command isolation prevents filesystem escape
2. Permissions - File operations restricted to project_dir only
3. Security hooks - Bash commands validated against an allowlist
(see security.py for ALLOWED_COMMANDS)
Note: Authentication is handled by start.bat/start.sh before this runs.
The Claude SDK auto-detects credentials from ~/.claude/.credentials.json
"""
# Build allowed tools list based on mode
# In YOLO mode, exclude Playwright tools for faster prototyping
allowed_tools = [*BUILTIN_TOOLS, *FEATURE_MCP_TOOLS]
if not yolo_mode:
allowed_tools.extend(PLAYWRIGHT_TOOLS)
# Build permissions list
permissions_list = [
# Allow all file operations within the project directory
"Read(./**)",
"Write(./**)",
"Edit(./**)",
"Glob(./**)",
"Grep(./**)",
# Bash permission granted here, but actual commands are validated
# by the bash_security_hook (see security.py for allowed commands)
"Bash(*)",
# Allow Feature MCP tools for feature management
*FEATURE_MCP_TOOLS,
]
if not yolo_mode:
# Allow Playwright MCP tools for browser automation (standard mode only)
permissions_list.extend(PLAYWRIGHT_TOOLS)
# Create comprehensive security settings
# Note: Using relative paths ("./**") restricts access to project directory
# since cwd is set to project_dir
security_settings = {
"sandbox": {"enabled": True, "autoAllowBashIfSandboxed": True},
"permissions": {
"defaultMode": "acceptEdits", # Auto-approve edits within allowed directories
"allow": permissions_list,
},
}
# Ensure project directory exists before creating settings file
project_dir.mkdir(parents=True, exist_ok=True)
# Write settings to a file in the project directory
settings_file = project_dir / ".claude_settings.json"
with open(settings_file, "w") as f:
json.dump(security_settings, f, indent=2)
print(f"Created security settings at {settings_file}")
print(" - Sandbox enabled (OS-level bash isolation)")
print(f" - Filesystem restricted to: {project_dir.resolve()}")
print(" - Bash commands restricted to allowlist (see security.py)")
if yolo_mode:
print(" - MCP servers: features (database) - YOLO MODE (no Playwright)")
else:
print(" - MCP servers: playwright (browser), features (database)")
print(" - Project settings enabled (skills, commands, CLAUDE.md)")
print()
# Use system Claude CLI instead of bundled one (avoids Bun runtime crash on Windows)
system_cli = shutil.which("claude")
if system_cli:
print(f" - Using system CLI: {system_cli}")
else:
print(" - Warning: System Claude CLI not found, using bundled CLI")
# Build MCP servers config - features is always included, playwright only in standard mode
mcp_servers = {
"features": {
"command": sys.executable, # Use the same Python that's running this script
"args": ["-m", "mcp_server.feature_mcp"],
"env": {
# Inherit parent environment (PATH, ANTHROPIC_API_KEY, etc.)
**os.environ,
# Add custom variables
"PROJECT_DIR": str(project_dir.resolve()),
"PYTHONPATH": str(Path(__file__).parent.resolve()),
},
},
}
if not yolo_mode:
# Include Playwright MCP server for browser automation (standard mode only)
mcp_servers["playwright"] = {
"command": "npx",
"args": ["@playwright/mcp@latest", "--viewport-size", "1280x720"],
}
return ClaudeSDKClient(
options=ClaudeAgentOptions(
model=model,
cli_path=system_cli, # Use system CLI to avoid bundled Bun crash (exit code 3)
system_prompt="You are an expert full-stack developer building a production-quality web application.",
setting_sources=["project"], # Enable skills, commands, and CLAUDE.md from project dir
max_buffer_size=10 * 1024 * 1024, # 10MB for large Playwright screenshots
allowed_tools=allowed_tools,
mcp_servers=mcp_servers,
hooks={
"PreToolUse": [
HookMatcher(matcher="Bash", hooks=[bash_security_hook]),
],
},
max_turns=1000,
cwd=str(project_dir.resolve()),
settings=str(settings_file.resolve()), # Use absolute path
)
)