feat: add configurable CLI command and UI improvements

Add support for alternative CLI commands via CLI_COMMAND environment
variable, allowing users to use CLIs other than 'claude' (e.g., 'glm').
This change affects all server services and the main CLI launcher.

Key changes:

- Configurable CLI command via CLI_COMMAND env var (defaults to 'claude')
- Configurable Playwright headless mode via PLAYWRIGHT_HEADLESS env var
- Pin claude-agent-sdk version to <0.2.0 for stability
- Use tail -500 for progress notes to avoid context overflow
- Add project delete functionality with confirmation dialog
- Replace single-line input with resizable textarea in spec chat
- Add coder agent configuration for code implementation tasks
- Ignore issues/ directory in git

Files modified:
- client.py: CLI command and Playwright headless configuration
- server/main.py, server/services/*: CLI command configuration
- start.py: CLI command configuration and error messages
- .env.example: Document new environment variables
- .gitignore: Ignore issues/ directory
- requirements.txt: Pin SDK version
- .claude/templates/*: Use tail -500 for progress notes
- ui/src/components/ProjectSelector.tsx: Add delete button
- ui/src/components/SpecCreationChat.tsx: Auto-resizing textarea
- ui/src/components/ConfirmDialog.tsx: New reusable dialog
- .claude/agents/coder.md: New coder agent configuration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Auto
2026-01-10 13:19:49 +02:00
parent a0f7e72361
commit 117ca89f08
16 changed files with 496 additions and 49 deletions

View File

@@ -6,10 +6,26 @@ Main entry point for the Autonomous Coding UI server.
Provides REST API, WebSocket, and static file serving.
"""
import os
import shutil
from contextlib import asynccontextmanager
from pathlib import Path
from dotenv import load_dotenv
# Load environment variables from .env file if present
load_dotenv()
def get_cli_command() -> str:
"""
Get the CLI command to use for the agent.
Reads from CLI_COMMAND environment variable, defaults to 'claude'.
This allows users to use alternative CLIs like 'glm'.
"""
return os.getenv("CLI_COMMAND", "claude")
from fastapi import FastAPI, HTTPException, Request, WebSocket
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
@@ -124,11 +140,12 @@ async def health_check():
@app.get("/api/setup/status", response_model=SetupStatus)
async def setup_status():
"""Check system setup status."""
# Check for Claude CLI
claude_cli = shutil.which("claude") is not None
# Check for CLI (configurable via CLI_COMMAND environment variable)
cli_command = get_cli_command()
claude_cli = shutil.which(cli_command) is not None
# Check for Claude CLI configuration directory
# Note: Claude CLI no longer stores credentials in ~/.claude/.credentials.json
# Check for CLI configuration directory
# Note: CLI no longer stores credentials in ~/.claude/.credentials.json
# The existence of ~/.claude indicates the CLI has been configured
claude_dir = Path.home() / ".claude"
credentials = claude_dir.exists() and claude_dir.is_dir()

View File

@@ -18,12 +18,27 @@ from pathlib import Path
from typing import AsyncGenerator, Optional
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
from dotenv import load_dotenv
from .assistant_database import (
add_message,
create_conversation,
)
# Load environment variables from .env file if present
load_dotenv()
def get_cli_command() -> str:
"""
Get the CLI command to use for the agent.
Reads from CLI_COMMAND environment variable, defaults to 'claude'.
This allows users to use alternative CLIs like 'glm'.
"""
return os.getenv("CLI_COMMAND", "claude")
logger = logging.getLogger(__name__)
# Root directory of the project
@@ -227,8 +242,9 @@ class AssistantChatSession:
# Get system prompt with project context
system_prompt = get_system_prompt(self.project_name, self.project_dir)
# Use system Claude CLI
system_cli = shutil.which("claude")
# Use system CLI (configurable via CLI_COMMAND environment variable)
cli_command = get_cli_command()
system_cli = shutil.which(cli_command)
try:
self.client = ClaudeSDKClient(

View File

@@ -9,6 +9,7 @@ Uses the expand-project.md skill to help users add features to existing projects
import asyncio
import json
import logging
import os
import re
import shutil
import threading
@@ -18,9 +19,23 @@ from pathlib import Path
from typing import AsyncGenerator, Optional
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
from dotenv import load_dotenv
from ..schemas import ImageAttachment
# Load environment variables from .env file if present
load_dotenv()
def get_cli_command() -> str:
"""
Get the CLI command to use for the agent.
Reads from CLI_COMMAND environment variable, defaults to 'claude'.
This allows users to use alternative CLIs like 'glm'.
"""
return os.getenv("CLI_COMMAND", "claude")
logger = logging.getLogger(__name__)
@@ -120,12 +135,14 @@ class ExpandChatSession:
except UnicodeDecodeError:
skill_content = skill_path.read_text(encoding="utf-8", errors="replace")
# Find and validate Claude CLI before creating temp files
system_cli = shutil.which("claude")
# Find and validate CLI before creating temp files
# CLI command is configurable via CLI_COMMAND environment variable
cli_command = get_cli_command()
system_cli = shutil.which(cli_command)
if not system_cli:
yield {
"type": "error",
"content": "Claude CLI not found. Please install Claude Code."
"content": f"CLI '{cli_command}' not found. Please install it or check your CLI_COMMAND setting."
}
return

View File

@@ -8,6 +8,7 @@ Uses the create-spec.md skill to guide users through app spec creation.
import json
import logging
import os
import shutil
import threading
from datetime import datetime
@@ -15,9 +16,23 @@ from pathlib import Path
from typing import AsyncGenerator, Optional
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
from dotenv import load_dotenv
from ..schemas import ImageAttachment
# Load environment variables from .env file if present
load_dotenv()
def get_cli_command() -> str:
"""
Get the CLI command to use for the agent.
Reads from CLI_COMMAND environment variable, defaults to 'claude'.
This allows users to use alternative CLIs like 'glm'.
"""
return os.getenv("CLI_COMMAND", "claude")
logger = logging.getLogger(__name__)
@@ -142,7 +157,9 @@ class SpecChatSession:
# Create Claude SDK client with limited tools for spec creation
# Use Opus for best quality spec generation
# Use system CLI to avoid bundled Bun runtime crash (exit code 3) on Windows
system_cli = shutil.which("claude")
# CLI command is configurable via CLI_COMMAND environment variable
cli_command = get_cli_command()
system_cli = shutil.which(cli_command)
try:
self.client = ClaudeSDKClient(
options=ClaudeAgentOptions(