Commit Graph

112 Commits

Author SHA1 Message Date
Auto
4f102e7bc2 fix: resolve false-positive rate limit and one-message-behind in chat sessions
The Claude Code CLI v2.1.45+ emits a `rate_limit_event` message type that
the Python SDK v0.1.19 cannot parse, raising MessageParseError. Two bugs
resulted:

1. **False-positive rate limit**: check_rate_limit_error() matched
   "rate_limit" in the exception string "Unknown message type:
   rate_limit_event" via both an explicit type check and a regex fallback,
   triggering 15-19s backoff + query re-send on every session.

2. **One-message-behind**: The MessageParseError killed the
   receive_response() async generator, but the CLI subprocess was still
   alive with buffered response data. Catching and returning meant the
   response was never consumed. The next send_message() would read the
   previous response first, creating a one-behind offset.

Changes:

- chat_constants.py: check_rate_limit_error() now returns (False, None)
  for any MessageParseError, blocking both false-positive paths. Added
  safe_receive_response() helper that retries receive_response() on
  MessageParseError — the SDK's decoupled producer/consumer architecture
  (anyio memory channel) allows the new generator to continue reading
  remaining messages without data loss. Removed calculate_rate_limit_backoff
  re-export and MAX_CHAT_RATE_LIMIT_RETRIES constant.

- spec_chat_session.py, assistant_chat_session.py, expand_chat_session.py:
  Replaced retry-with-backoff loops with safe_receive_response() wrapper.
  Removed asyncio.sleep backoff, query re-send, and rate_limited yield.
  Cleaned up unused imports (asyncio, calculate_rate_limit_backoff,
  MAX_CHAT_RATE_LIMIT_RETRIES).

- agent.py: Added inner retry loop around receive_response() with same
  MessageParseError skip-and-restart pattern. Removed early-return that
  truncated responses.

- types.ts: Removed SpecChatRateLimitedMessage,
  AssistantChatRateLimitedMessage, and their union entries.

- useSpecChat.ts, useAssistantChat.ts, useExpandChat.ts: Removed dead
  'rate_limited' case handlers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 13:00:16 +02:00
Auto
dcdd06e02e fix: handle rate_limit_event crash in chat sessions
The Claude CLI sends `rate_limit_event` messages that the SDK's
`parse_message()` doesn't recognize, raising `MessageParseError` and
crashing all three chat session types (spec, assistant, expand).

Changes:
- Bump claude-agent-sdk minimum from 0.1.0 to 0.1.39
- Add `check_rate_limit_error()` helper in chat_constants.py that
  detects rate limits from both MessageParseError data payloads and
  error message text patterns
- Wrap `receive_response()` loops in all three `_query_claude()` methods
  with retry-on-rate-limit logic (up to 3 retries with backoff)
- Gracefully log and skip non-rate-limit MessageParseError instead of
  crashing the session
- Add `rate_limited` message type to frontend TypeScript types and
  handle it in useSpecChat, useAssistantChat, useExpandChat hooks to
  show "Rate limited. Retrying in Xs..." system messages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 12:21:49 +02:00
Auto
819ebcd112 Merge remote-tracking branch 'origin/master' into feature/blocked-for-human-input
# Conflicts:
#	server/services/process_manager.py
2026-02-12 07:36:11 +02:00
Auto
f4636fdfd5 fix: handle pausing/draining states in UI guards and process cleanup
Follow-up fixes after merging PR #183 (graceful pause/drain mode):

- process_manager: _stream_output finally block now transitions from
  pausing/paused_graceful to crashed/stopped (not just running), and
  cleans up the drain signal file on process exit
- App.tsx: block Reset button and R shortcut during pausing/paused_graceful
- AgentThought/ProgressDashboard: keep thought bubble visible while pausing
- OrchestratorAvatar: add draining/paused cases to animation, glow, and
  description switch statements
- AgentMissionControl: show Draining/Paused badge text for new states
- registry.py: remove redundant type annotation to fix mypy no-redef
- process_manager.py: add type:ignore for SQLAlchemy Column assignment
- websocket.py: reclassify test-pass lines as 'testing' not 'success'
- review-pr.md: add post-review recommended action guidance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 07:28:37 +02:00
Leon van Zyl
c114248b09 Merge pull request #183 from CaitlynByrne/feat/pause-drain
feat: add graceful pause (drain mode) for running agents
2026-02-12 07:22:01 +02:00
Auto
e9873a2642 feat: migrate browser automation from Playwright MCP to CLI, fix headless setting
Major changes across 21 files (755 additions, 196 deletions):

Browser Automation Migration:
- Add versioned project migration system (prompts.py) with content-based
  detection and section-level regex replacement for coding/testing prompts
- Migrate STEP 5 (browser verification) and BROWSER AUTOMATION sections
  in coding prompt template to use playwright-cli commands
- Migrate STEP 2 and AVAILABLE TOOLS sections in testing prompt template
- Migration auto-runs at agent startup (autonomous_agent_demo.py), copies
  playwright-cli skill, scaffolds .playwright/cli.config.json, updates
  .gitignore, and stamps .migration_version file
- Add playwright-cli command validation to security allowlist (security.py)
  with tests for allowed subcommands and blocked eval/run-code

Headless Browser Setting Fix:
- Add _apply_playwright_headless() to process_manager.py that reads/updates
  .playwright/cli.config.json before agent subprocess launch
- Remove dead PLAYWRIGHT_HEADLESS env var that was never consumed
- Settings UI toggle now correctly controls visible browser window

Playwright CLI Auto-Install:
- Add ensurePlaywrightCli() to lib/cli.js for npm global entry point
- Add playwright-cli detection + npm install to start.bat, start.sh,
  start_ui.bat, start_ui.sh for all startup paths

Other Improvements:
- Add project folder path tooltip to ProjectSelector.tsx dropdown items
- Remove legacy Playwright MCP server configuration from client.py
- Update CLAUDE.md with playwright-cli skill documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 13:37:03 +02:00
Auto
f87970daca fix: prevent temp file accumulation during long agent runs
Address three issues reported after overnight AutoForge runs:
1. ~193GB of .node files in %TEMP% from V8 compile caching
2. Stale npm artifact folders on drive root when %TEMP% fills up
3. PNG screenshot files left in project root by Playwright

Changes:
- Widen .node cleanup glob from ".78912*.node" to ".[0-9a-f]*.node"
  to match all V8 compile cache hex prefixes
- Add "node-compile-cache" directory to temp cleanup patterns
- Set NODE_COMPILE_CACHE="" in all subprocess environments (client.py,
  parallel_orchestrator.py, process_manager.py) to disable V8 compile
  caching at the source
- Add cleanup_project_screenshots() to remove stale .png files from
  project directories (feature*-*.png, screenshot-*.png, step-*.png)
- Run cleanup_stale_temp() at server startup in lifespan()
- Add _run_inter_session_cleanup() to orchestrator, called after each
  agent completes (both coding and testing paths)
- Update coding and testing prompt templates to instruct agents to use
  inline (base64) screenshots only, never saving files to disk

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 08:54:52 +02:00
Caitlyn Byrne
656df0fd9a feat: add "blocked for human input" feature across full stack
Agents can now request structured human input when they encounter
genuine blockers (API keys, design choices, external configs). The
request is displayed in the UI with a dynamic form, and the human's
response is stored and made available when the agent resumes.

Changes span 21 files + 1 new component:
- Database: 3 new columns (needs_human_input, human_input_request,
  human_input_response) with migration
- MCP: new feature_request_human_input tool + guards on existing tools
- API: new resolve-human-input endpoint, 4th feature bucket
- Orchestrator: skip needs_human_input features in scheduling
- Progress: 4-tuple return from count_passing_tests
- WebSocket: needs_human_input count in progress messages
- UI: conditional 4th Kanban column, HumanInputForm component,
  amber status indicators, dependency graph support

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 14:11:35 -05:00
Caitlyn Byrne
9721368188 feat: add graceful pause (drain mode) for running agents
File-based signal (.pause_drain) lets the orchestrator finish current
work before pausing instead of hard-freezing the process tree.  New
status states pausing/paused_graceful flow through WebSocket to the UI
where a Pause button, draining indicator, and Resume button are shown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:37:22 -05:00
Auto
71f17c73c2 feat: add structured questions (AskUserQuestion) to assistant chat
Add interactive multiple-choice question support to the project assistant,
allowing it to present clickable options when clarification is needed.

Backend changes:
- Add ask_user MCP tool to feature_mcp.py with input validation
- Add mcp__features__ask_user to assistant allowed tools list
- Intercept ask_user tool calls in _query_claude() to yield question messages
- Add answer WebSocket message handler in assistant_chat router
- Document ask_user tool in assistant system prompt

Frontend changes:
- Add AssistantChatQuestionMessage type and update server message union
- Add currentQuestions state and sendAnswer() to useAssistantChat hook
- Handle question WebSocket messages by attaching to last assistant message
- Render QuestionOptions component between messages and input area
- Disable text input while structured questions are active

Flow: Claude calls ask_user → backend intercepts → WebSocket question message →
frontend renders QuestionOptions → user clicks options → answer sent back →
Claude receives formatted answer and continues conversation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:26:36 +02:00
Auto
9259a799e3 fix: propagate alternative API provider settings to agent subprocesses
When users configured GLM/Ollama/Kimi via the Settings UI, agents still
used Claude because conflicting env vars leaked through subprocess env.

Root cause: get_effective_sdk_env() set ANTHROPIC_AUTH_TOKEN for GLM but
didn't clear ANTHROPIC_API_KEY, which leaked from os.environ. The CLI
prioritized the wrong credential.

Changes:
- registry.py: Clear conflicting auth vars (API_KEY vs AUTH_TOKEN) and
  Vertex AI vars when building env for alternative providers
- client.py: Replace manual os.getenv() loop with get_effective_sdk_env()
  so agent SDK reads provider settings from the database
- autonomous_agent_demo.py: Apply UI-configured provider settings to
  process env so CLI-launched agents also respect Settings UI config
- start.py: Pass --model from settings when launching agent subprocess
- server/schemas.py: Allow non-Claude model names when an alternative
  provider is configured (prevents 422 errors for glm-4.7, etc.)
- .env.example: Document env vars for GLM, Ollama, and Kimi providers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 13:38:36 +02:00
Auto
a52f191a54 refactor: make Settings UI the single source of truth for API provider
Remove legacy env-var-based provider/mode detection that caused misleading
UI badges (e.g., GLM badge showing when Settings was set to Claude).

Key changes:
- Remove _is_glm_mode() and _is_ollama_mode() env-var sniffing functions
  from server/routers/settings.py; derive glm_mode/ollama_mode purely from
  the api_provider setting
- Remove `import os` from settings router (no longer needed)
- Update schema comments to reflect settings-based derivation
- Remove "(configured via .env)" from badge tooltips in App.tsx
- Remove Kimi/GLM/Ollama/Playwright-headless sections from .env.example;
  add note pointing to Settings UI
- Update CLAUDE.md and README.md documentation to reference Settings UI
  for alternative provider configuration
- Update model IDs from claude-opus-4-5-20251101 to claude-opus-4-6
  across registry, client, chat sessions, tests, and UI defaults
- Add LEGACY_MODEL_MAP with auto-migration in get_all_settings()
- Show model ID subtitle in SettingsModal model selector
- Add Vertex passthrough test for claude-opus-4-6 (no date suffix)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 09:23:06 +02:00
Auto
73d6cfcd36 fix: address PR #163 review findings
- Fix model selection regression: _get_settings_defaults() now checks
  api_model (set by new provider UI) before falling back to legacy
  model setting, ensuring Claude model selection works end-to-end
- Add input validation for provider settings: api_base_url must start
  with http:// or https:// (max 500 chars), api_auth_token max 500
  chars, api_model max 200 chars
- Fix terminal.py misleading import alias: replace
  is_valid_project_name aliased as validate_project_name with direct
  is_valid_project_name import across all 5 call sites

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 08:10:18 +02:00
nioasoft
a752ece70c fix: wrong import alias overwrote project_name with bool
assistant_chat.py and spec_creation.py imported is_valid_project_name
(returns bool) aliased as validate_project_name. When used as
`project_name = validate_project_name(project_name)`, the project name
was replaced with True, causing "Project not found in registry" errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 06:20:03 +02:00
nioasoft
3c61496021 fix: clean up stuck features on agent start
Ensures features stuck from a previous crash are reset before
launching a new agent, not just on stop/crash going forward.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 06:02:30 +02:00
nioasoft
6d4a198380 fix: remove unused API_ENV_VARS imports from chat sessions
The provider refactor moved env building to get_effective_sdk_env(),
making these imports unused. Fixes ruff F401 lint errors in CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 05:57:47 +02:00
nioasoft
13785325d7 feat: add API provider selection UI and fix stuck features on agent crash
API Provider Selection:
- Add provider switcher in Settings modal (Claude, Kimi, GLM, Ollama, Custom)
- Auth tokens stored locally only (registry.db), never returned by API
- get_effective_sdk_env() builds provider-specific env vars for agent subprocess
- All chat sessions (spec, expand, assistant) use provider settings
- Backward compatible: defaults to Claude, env vars still work as override

Fix Stuck Features:
- Add _cleanup_stale_features() to process_manager.py
- Reset in_progress features when agent stops, crashes, or fails healthcheck
- Prevents features from being permanently stuck after rate limit crashes
- Uses separate SQLAlchemy engine to avoid session conflicts with subprocess

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 05:55:51 +02:00
nioasoft
70131f2271 fix: accept WebSocket before validation to prevent opaque 403 errors
All WebSocket endpoints now call websocket.accept() before any
validation checks. Previously, closing the connection before accepting
caused Starlette to return an opaque HTTP 403 instead of a meaningful
error message.

Changes:
- Server: Accept WebSocket first, then send JSON error + close with
  4xxx code if validation fails (expand, spec, assistant, terminal,
  main project WS)
- Server: ConnectionManager.connect() no longer calls accept() to
  avoid double-accept
- UI: Gate expand button and keyboard shortcut on hasSpec
- UI: Skip WebSocket reconnection on application error codes (4000-4999)
- UI: Update keyboard shortcuts help text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 05:46:24 +02:00
nioasoft
035e8fdfca fix: accept WebSocket before validation to prevent opaque 403 errors
All 5 WebSocket endpoints (expand, spec, assistant, terminal, project)
were closing the connection before calling accept() when validation
failed. Starlette converts pre-accept close into an HTTP 403, giving
clients no meaningful error information.

Server changes:
- Move websocket.accept() before all validation checks in every WS handler
- Send JSON error message before closing so clients get actionable errors
- Fix validate_project_name usage (raises HTTPException, not returns bool)
- ConnectionManager.connect() no longer calls accept() (caller's job)

Client changes:
- All 3 WS hooks (useWebSocket, useExpandChat, useSpecChat) skip
  reconnection on 4xxx close codes (application errors won't self-resolve)
- Gate expand button, keyboard shortcut, and modal on hasSpec
- Add hasSpec to useEffect dependency array to prevent stale closure
- Update keyboard shortcuts help text for E key context

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 21:08:46 +02:00
Auto
c55a1a0182 fix: harden dev server RCE mitigations from PR #153
Address security gaps and improve validation in the dev server command
execution path introduced by PR #153:

Security fixes (critical):
- Add missing shell metacharacters to dangerous_ops blocklist: single &
  (Windows cmd.exe command separator), >, <, ^, %, \n, \r
- The single & gap was a confirmed RCE bypass on Windows where .cmd
  files are always executed via cmd.exe even with shell=False (CPython
  limitation documented in issue #77696)
- Apply validate_custom_command_strict at /start endpoint for
  defense-in-depth against config file tampering

Validation improvements:
- Fix uvicorn --flag=value syntax (split on = before comparing)
- Expand Python support: Django (manage.py), Flask, custom .py scripts
- Add runners: flask, poetry, cargo, go, npx
- Expand npm script allowlist: serve, develop, server, preview
- Reorder PATCH /config validation to run strict check first (fail fast)
- Extract constants: ALLOWED_NPM_SCRIPTS, ALLOWED_PYTHON_MODULES,
  BLOCKED_SHELLS for reuse and testability

Cleanup:
- Remove unused security.py imports from dev_server_manager.py
- Fix deprecated datetime.utcnow() -> datetime.now(timezone.utc)
- Remove unnecessary _remove_lock() in exception handlers where lock
  was never created (Popen failure path)

Tests:
- Add test_devserver_security.py with 78 tests covering valid commands,
  blocked shells, blocked commands, injection attempts, dangerous_ops
  blocking, and constant verification

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 08:52:47 +02:00
Leon van Zyl
75766a433a Merge pull request #153 from syphonetic/master
Implemented RCE mitigation measures
2026-02-05 08:31:28 +02:00
Auto
c2ad993e75 rebrand: rename AutoCoder to AutoForge across entire codebase
Complete project rebrand from AutoCoder to AutoForge, touching 62 files
across Python backend, FastAPI server, React UI, documentation, config,
and CI/CD.

Key changes:
- Rename autocoder_paths.py -> autoforge_paths.py with backward-compat
  migration from .autocoder/ -> .autoforge/ directories
- Update registry.py to migrate ~/.autocoder/ -> ~/.autoforge/ global
  config directory with fallback support
- Update security.py with fallback reads from legacy .autocoder/ paths
- Rename .claude/commands and skills from gsd-to-autocoder-spec to
  gsd-to-autoforge-spec
- Update all Python modules: client, prompts, progress, agent,
  orchestrator, server routers and services
- Update React UI: package.json name, index.html title, localStorage
  keys, all documentation sections, component references
- Update start scripts (bat/sh/py), examples, and .env.example
- Update CLAUDE.md and README.md with new branding and paths
- Update test files for new .autoforge/ directory structure
- Transfer git remote from leonvanzyl/autocoder to
  AutoForgeAI/autoforge

Backward compatibility preserved: legacy .autocoder/ directories are
auto-detected and migrated on next agent start. Config fallback chain
checks both new and old paths.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 12:02:06 +02:00
syphonetic
81d2f0cbe0 Merge branch 'master' into master 2026-02-04 05:50:35 +08:00
syphonetic
c7c88449ad Remove unused dev server management functions
Removed unused functions and endpoints related to dev server management, including command validation and configuration updates.
2026-02-04 02:34:29 +08:00
syphonetic
9622da9561 Remove unnecessary blank line in dev_server_manager.py 2026-02-04 02:34:06 +08:00
syphonetic
83d2182107 Refactor dev server API for security and validation
Refactor dev server API to enhance security and command validation. Added logging and improved command handling.
2026-02-04 02:19:19 +08:00
syphonetic
7651436c27 Refactor dev server command execution and locking
Refactor dev server management to improve command execution and security checks. Introduce lock file handling and command validation enhancements.
2026-02-04 02:18:55 +08:00
Auto
1607fc8175 feat: add multi-feature batching for coding agents
Enable the orchestrator to assign 1-3 features per coding agent subprocess,
selected via dependency chain extension + same-category fill. This reduces
cold-start overhead and leverages shared context across related features.

Orchestrator (parallel_orchestrator.py):
- Add batch tracking: _batch_features and _feature_to_primary data structures
- Add build_feature_batches() with dependency chain + category fill algorithm
- Add start_feature_batch() and _spawn_coding_agent_batch() methods
- Update _on_agent_complete() for batch cleanup across all features
- Update stop_feature() with _feature_to_primary lookup
- Update get_ready_features() to exclude all batch feature IDs
- Update main loop to build batches then spawn per available slot

CLI and agent layer:
- Add --feature-ids (comma-separated) and --batch-size CLI args
- Add feature_ids parameter to run_autonomous_agent() with batch prompt selection
- Add get_batch_feature_prompt() with sequential workflow instructions

WebSocket layer (server/websocket.py):
- Add BATCH_CODING_AGENT_START_PATTERN and BATCH_FEATURES_COMPLETE_PATTERN
- Add _handle_batch_agent_start() and _handle_batch_agent_complete() methods
- Add featureIds field to all agent_update messages
- Track current_feature_id updates as agent moves through batch

Frontend (React UI):
- Add featureIds to ActiveAgent and WSAgentUpdateMessage types
- Update KanbanColumn and DependencyGraph agent-feature maps for batch
- Update AgentCard to show "Batch: #X, #Y, #Z" with active feature highlight
- Add "Features per Agent" segmented control (1-3) in SettingsModal

Settings integration (full stack):
- Add batch_size to schemas, settings router, agent router, process manager
- Default batch_size=3, user-configurable 1-3 via settings UI
- batch_size=1 is functionally identical to pre-batching behavior

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 16:35:07 +02:00
Auto
24481d474d feat: add headless browser toggle to settings UI
Replace the PLAYWRIGHT_HEADLESS environment variable with a global
setting toggle in the Settings modal. The setting is persisted in the
registry DB and injected as an env var into agent subprocesses, so
client.py reads it unchanged.

Backend:
- Add playwright_headless field to SettingsResponse/SettingsUpdate schemas
- Read/write the setting in settings router via existing _parse_bool helper
- Pass playwright_headless from agent router through to process manager
- Inject PLAYWRIGHT_HEADLESS env var into subprocess environment

Frontend:
- Add playwright_headless to Settings/SettingsUpdate TypeScript types
- Add "Headless Browser" Switch toggle below YOLO mode in SettingsModal
- Add default value to DEFAULT_SETTINGS in useProjects

Also fix CSS build warning: change @import url("tw-animate-css") to bare
@import "tw-animate-css" so Tailwind v4 inlines it during compilation
instead of leaving it for Vite/Lightning CSS post-processing.

Remove stale summary.md from previous refactoring session.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 13:40:46 +02:00
Auto
94e0b05cb1 refactor: optimize token usage, deduplicate code, fix bugs across agents
Token reduction (~40% per session, ~2.3M fewer tokens per 200-feature project):
- Agent-type-specific tool lists: coding 9, testing 5, init 5 (was 19 for all)
- Right-sized max_turns: coding 300, testing 100 (was 1000 for all)
- Trimmed coding prompt template (~150 lines removed)
- Streamlined testing prompt with batch support
- YOLO mode now strips browser testing instructions from prompt
- Added Grep, WebFetch, WebSearch to expand project session

Performance improvements:
- Rate limit retries start at ~15s with jitter (was fixed 60s)
- Post-spawn delay reduced to 0.5s (was 2s)
- Orchestrator consolidated to 1 DB query per loop (was 5-7)
- Testing agents batch 3 features per session (was 1)
- Smart context compaction preserves critical state, discards noise

Bug fixes:
- Removed ghost feature_release_testing MCP tool (wasted tokens every test session)
- Forward all 9 Vertex AI env vars to chat sessions (was missing 3)
- Fix DetachedInstanceError risk in test batch ORM access
- Prevent duplicate testing of same features in parallel mode

Code deduplication:
- _get_project_path(): 9 copies -> 1 shared utility (project_helpers.py)
- validate_project_name(): 9 copies -> 2 variants in 1 file (validation.py)
- ROOT_DIR: 10 copies -> 1 definition (chat_constants.py)
- API_ENV_VARS: 4 copies -> 1 source of truth (env_constants.py)

Security hardening:
- Unified sensitive directory blocklist (14 dirs, was two divergent lists)
- Cached get_blocked_paths() for O(1) directory listing checks
- Terminal security warning when ALLOW_REMOTE=1 exposes WebSocket
- 20 new security tests for EXTRA_READ_PATHS blocking
- Extracted _validate_command_list() and _validate_pkill_processes() helpers

Type safety:
- 87 mypy errors -> 0 across 58 source files
- Installed types-PyYAML for proper yaml stub types
- Fixed SQLAlchemy Column[T] coercions across all routers

Dead code removed:
- 13 files deleted (~2,679 lines): unused UI components, debug logs, outdated docs
- 7 unused npm packages removed (Radix UI components with 0 imports)
- AgentAvatar.tsx reduced from 615 -> 119 lines (SVGs extracted to mascotData.tsx)

New CLI options:
- --testing-batch-size (1-5) for parallel mode test batching
- --testing-feature-ids for direct multi-feature testing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 13:16:24 +02:00
Auto
dc5bcc4ae9 feat: move autocoder runtime files into .autocoder/ subdirectory
Add centralized path resolution module (autocoder_paths.py) that
consolidates all autocoder-generated file paths behind a dual-path
strategy: check .autocoder/X first, fall back to root-level X for
backward compatibility, default to .autocoder/X for new projects.

Key changes:
- New autocoder_paths.py with dual-path resolution for features.db,
  assistant.db, lock files, settings, prompts dir, and progress cache
- migrate_project_layout() safely moves old-layout projects to new
  layout with SQLite WAL flush and integrity verification
- Updated 22 files to delegate path construction to autocoder_paths
- Reset/delete logic cleans both old and new file locations
- Orphan lock cleanup checks both locations per project
- Migration called automatically at agent start in autonomous_agent_demo.py
- Updated markdown commands/skills to reference .autocoder/prompts/
- CLAUDE.md documentation updated with new project structure

Files at project root that remain unchanged:
- CLAUDE.md (Claude SDK reads from cwd via setting_sources=["project"])
- app_spec.txt root copy (agent templates reference it via cat)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 11:32:06 +02:00
Auto
d8a8c83447 fix: prevent SQLite corruption in parallel mode with atomic operations
Replace ineffective threading.Lock() with atomic SQL operations for
cross-process safety. Key changes:

- Add SQLAlchemy event hooks (do_connect/do_begin) for BEGIN IMMEDIATE
  transactions in api/database.py
- Add atomic_transaction() context manager for multi-statement ops
- Convert all feature MCP write operations to atomic UPDATE...WHERE
  with compare-and-swap patterns (feature_claim, mark_passing, etc.)
- Add WHERE passes=0 state guard to feature_mark_passing
- Add WAL checkpoint on shutdown and idempotent cleanup() in
  parallel_orchestrator.py with async-safe signal handling
- Wrap SQLite connections with contextlib.closing() in progress.py
- Add thread-safe engine cache with double-checked locking in
  assistant_database.py
- Migrate to SQLAlchemy 2.0 DeclarativeBase across all modules

Inspired by PR #108 (cabana8471-arch), with fixes for nested
BEGIN EXCLUSIVE bug and missing state guards.

Closes #106

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 09:45:20 +02:00
Auto
6609a0f7d6 fix: prevent PendingRollbackError and add MCP tool support for sessions
- Add explicit session.rollback() in exception handlers for database
  context managers in features.py, schedules.py, and database.py get_db()
  to prevent SQLAlchemy PendingRollbackError on failed transactions
- Add EXPAND_FEATURE_TOOLS to expand session security settings allow list
  so the expand skill can use the MCP tools it references
- Update assistant session prompt to direct the LLM to call MCP tools
  directly for feature creation instead of suggesting CLI commands

Cherry-picked fixes from PR #92 (closed) with cleaner implementation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 09:15:24 +02:00
Leon van Zyl
a4a33e612e Merge pull request #89 from mmereu/master
fix: prevent agent subprocess blocking on Windows
2026-01-29 10:54:12 +02:00
Auto
cf62885e83 feat: add project reset functionality with quick and full reset options
Add the ability to reset a project to its initial state with two options:
- Quick Reset: Clears features.db, assistant.db, and settings files while
  preserving app spec and prompts
- Full Reset: Deletes everything including prompts directory, triggering
  the setup wizard for project reconfiguration

Backend changes:
- Add POST /{name}/reset endpoint to projects router with full_reset query param
- Validate agent lock file to prevent reset while agent is running (409 Conflict)
- Dispose database engines before deleting files to release Windows file locks
- Add engine caching to api/database.py for better connection management
- Add dispose_engine() functions to both database modules
- Delete WAL mode journal files (*.db-wal, *.db-shm) during reset

Frontend changes:
- Add ResetProjectModal component with toggle between Quick/Full reset modes
- Add ProjectSetupRequired component shown when has_spec is false
- Add resetProject API function and useResetProject React Query hook
- Integrate reset button in header (disabled when agent running)
- Add 'R' keyboard shortcut to open reset modal
- Show ProjectSetupRequired when project needs setup after full reset

This implements the feature from PR #4 directly on master to avoid merge
conflicts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 10:42:05 +02:00
Auto
f6ddffa6e2 feat: persist concurrent agents slider at project level
Add `default_concurrency` column to the projects table in the registry
database, allowing each project to remember its preferred concurrency
setting (1-5 agents). The value persists across page refreshes and
app restarts.

Backend changes:
- Add `default_concurrency` column to Project model in registry.py
- Add database migration for existing databases (ALTER TABLE)
- Add get/set_project_concurrency() CRUD functions
- Add ProjectSettingsUpdate schema with validation
- Add PATCH /{name}/settings endpoint in projects router
- Include default_concurrency in ProjectSummary/ProjectDetail responses

Frontend changes:
- Add default_concurrency to ProjectSummary TypeScript interface
- Add ProjectSettingsUpdate type and updateProjectSettings API function
- Add useUpdateProjectSettings React Query mutation hook
- Update AgentControl to accept defaultConcurrency prop
- Sync local state when project changes via useEffect
- Debounce slider changes (500ms) before saving to backend
- Pass defaultConcurrency from selectedProjectData in App.tsx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 09:08:17 +02:00
Auto
7a6b7f8f9c fix: align security_settings with permission_mode + add dependency tests
- Fix settings inconsistency in ExpandChatSession: security_settings
  now uses "bypassPermissions" to match permission_mode parameter
- Add comprehensive tests for dependency resolver (12 tests):
  - Cycle detection in compute_scheduling_scores (critical fix from PR #124)
  - Self-reference handling
  - Diamond dependency patterns
  - would_create_circular_dependency validation
  - Dependency satisfaction checks

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 08:04:01 +02:00
rudiheydra
3161c1260a fix: wire MCP server into ExpandChatSession for feature creation
Replace direct-DB feature creation with MCP tool path. The expand
session now configures the feature MCP server and allows
feature_create_bulk tool calls, matching how AssistantChatSession
already works. Removes duplicated _create_features_bulk() method
and <features_to_create> regex parsing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 10:09:40 +11:00
Leon van Zyl
ccfd1aa73e Merge pull request #97 from cabana8471-arch/fix/pydantic-datetime-serialization
fix: Pydantic datetime serialization for API endpoints
2026-01-26 16:07:03 +02:00
Leon van Zyl
d5e423b805 Merge pull request #98 from cabana8471-arch/fix/skip-priority-consistency
fix: use consistent priority increment when skipping features
2026-01-26 15:59:00 +02:00
Leon van Zyl
a437af7f96 Merge pull request #102 from cabana8471-arch/fix/websocket-project-isolation
fix: prevent cross-project UI contamination
2026-01-26 10:32:06 +02:00
Leon van Zyl
0ef6cf7d62 Merge pull request #103 from cabana8471-arch/feat/webui-remote-access
feat: add --host argument for WebUI remote access
2026-01-26 10:27:05 +02:00
Auto
095d248a66 add ollama support 2026-01-26 09:42:01 +02:00
cabana8471
d6ba075ac4 style: align priority calculation pattern with rest of file
Address CodeRabbit feedback - use consistent conditional pattern:
`(max_priority.priority + 1) if max_priority else 1`

This matches the pattern used in create_feature and create_features_bulk.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 12:36:54 +01:00
cabana8471
be20c8a3ef feat: add --host argument for WebUI remote access (#81)
Users can now access the WebUI remotely (e.g., via VS Code tunnels,
remote servers) by specifying a host address:

    python start_ui.py --host 0.0.0.0
    python start_ui.py --host 0.0.0.0 --port 8888

Changes:
- Added --host and --port CLI arguments to start_ui.py
- Security warning displayed when remote access is enabled
- AUTOCODER_ALLOW_REMOTE env var passed to server
- server/main.py conditionally disables localhost middleware
- CORS updated to allow all origins when remote access is enabled
- Browser auto-open disabled for remote hosts

Security considerations documented in warning:
- File system access to project directories
- API can start/stop agents and modify files
- Recommend firewall or VPN for protection

Fixes: leonvanzyl/autocoder#81

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 12:14:23 +01:00
cabana8471
32c7778ee5 fix: prevent cross-project UI contamination (#71)
When running multiple projects simultaneously, UI would show mixed data
because the manager registry used only project_name as key. Projects with
the same name but different paths shared the same manager instance.

Changed manager registries to use composite key (project_name, resolved_path):
- server/services/process_manager.py: AgentProcessManager registry
- server/services/dev_server_manager.py: DevServerProcessManager registry

This ensures that:
- /old/my-app and /new/my-app get separate managers
- Multiple browser tabs viewing different projects stay isolated
- Project renames don't cause callback contamination

Fixes: leonvanzyl/autocoder#71
Also fixes: leonvanzyl/autocoder#62 (progress bar sync)
Also fixes: leonvanzyl/autocoder#61 (features missing in kanban)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 12:12:38 +01:00
cabana8471
6731ef44ea fix: use consistent priority increment when skipping features (#65)
The REST API skip endpoint was using max_priority + 1000, while the
MCP server used max_priority + 1. This caused priority inflation where
values could reach 10,000+ after multiple skips.

Changed to use + 1 for consistency with mcp_server/feature_mcp.py:345.

Fixes: leonvanzyl/autocoder#65

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 12:07:36 +01:00
cabana8471
43c37c52fe fix: Pydantic datetime serialization for API endpoints
Problem:
Several API endpoints return 500 Internal Server Error because datetime
objects are not serializable by Pydantic. The error occurs when:
- GET /agent/{project}/status
- GET /devserver/{project}/status
- GET /schedules/{project}/next

Root cause:
Pydantic models expect strings for Optional datetime fields, but the code
was passing raw datetime objects.

Solution:
Convert datetime objects to ISO 8601 strings using .isoformat() before
returning in Pydantic response models.

Changes:
- server/routers/agent.py: Fix started_at serialization
- server/routers/devserver.py: Fix started_at serialization
- server/routers/schedules.py: Fix next_start/next_end serialization

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 08:04:14 +01:00
mmereu
45289ef0d2 Merge remote-tracking branch 'origin/master'
Resolved conflicts by combining:
- stdin=DEVNULL and CREATE_NO_WINDOW (blocking fix)
- PYTHONUNBUFFERED env var (output buffering fix)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 10:43:38 +01:00
mmereu
d48fb0a6fc fix: prevent agent subprocess blocking on Windows
- Add stdin=subprocess.DEVNULL to prevent blocking on stdin reads
- Add CREATE_NO_WINDOW flag on Windows to prevent console pop-ups
- Remove trailing pause from start_ui.bat

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 10:40:47 +01:00