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>
- 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>
Trim the env var value and fall back to the default model when the
trimmed result is empty. This prevents invalid empty strings from
being appended to VALID_MODELS.
Addresses CodeRabbit review feedback on PR #147.
When ANTHROPIC_DEFAULT_OPUS_MODEL env var is set to a custom model ID,
that model was not present in VALID_MODELS (derived from AVAILABLE_MODELS),
causing potential validation failures in server/schemas.py validators.
This fix dynamically appends the env-provided DEFAULT_MODEL to VALID_MODELS
when set, ensuring validators accept the runtime default. The merge is
idempotent (only adds if missing) and doesn't alter AVAILABLE_MODELS semantics.
Addresses CodeRabbit review feedback on PR #147.
- Rename compute_mode -> convert_model_for_vertex for clarity
- Move `import re` to module top-level (stdlib convention)
- Use greedy regex quantifier for more readable pattern matching
- Restore PEP 8 double blank line between top-level definitions
- Add test_client.py with 10 unit tests covering:
- Vertex disabled (env unset, "0", empty)
- Standard conversions (Opus, Sonnet, Haiku)
- Edge cases (already-converted, non-Claude, no date suffix, empty)
Follow-up improvements from PR #129 review.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add comment on running_coding_agents explaining why feature_id keying
is safe (start_feature checks for duplicates before spawning), since
the sister dict running_testing_agents required PID keying to avoid
overwrites from concurrent same-feature testing
- Clear running_testing_agents dict in stop_all() after killing
processes so get_status() doesn't report stale agent counts while
_on_agent_complete callbacks are still in flight
Follow-up to PR #130 (runaway testing agent spawn fix).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
running_testing_agents was keyed by feature_id, so when multiple agents
tested the same feature, each spawn overwrote the previous dict entry.
The count stayed at 1 regardless of how many processes were actually
running, causing the maintain loop to spawn agents indefinitely (~130+).
Re-key the dict by PID so each agent gets a unique entry and the
existing max-agent guards work correctly. Also check the return value
of _spawn_testing_agent() to break the loop on failure.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update the documented test count in CLAUDE.md to reflect the current
state after merging PR #100 which added diagnostic warnings for config
loading failures. The test suite now includes additional tests for:
- Empty command name validation in project configs
- Config loading diagnostic warnings
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Follow-up to PR #89 - apply the same popen_kwargs pattern with
stdin=DEVNULL and CREATE_NO_WINDOW to _spawn_testing_agent() and
_run_initializer() for consistent Windows behavior.
Also fixes typo: _kill_process_tree -> kill_process_tree
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
Adds a test case to verify that empty command names are rejected
in project-level allowed_commands.yaml, matching the behavior already
tested for org-level config. Updates test count to 163.
Addresses review feedback from leonvanzyl.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Per CodeRabbit feedback, add logger.warning calls when pkill_processes
validation fails in both load_org_config and load_project_commands.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When config files have errors, users had no way to know why their
settings weren't being applied. Added logging.warning() calls to
diagnose:
- Empty config files
- Missing 'version' field
- Invalid structure (not a dict)
- Invalid command entries
- Exceeding 100 command limit
- YAML parse errors
- File read errors
Also added .resolve() to project path to handle symlinks correctly.
Fixes: leonvanzyl/autocoder#91
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add debug logging when shlex fallback extraction is used, capturing
both successful extractions and failures for security auditing
- Add test case for docker nested quotes that trigger fallback parser
- Remove redundant comment about re import (already at module level)
Follow-up improvements from PR #127 code review:
- Enables tracking of malformed command patterns in production logs
- Verifies fallback parser handles the exact docker exec case reported
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
- Create shared `isSubmitEnter()` utility in `ui/src/lib/keyboard.ts`
for IME-aware Enter key handling across all input components
- Extract magic number 48 to named constant `COLLAPSED_DEBUG_PANEL_CLEARANCE`
with explanatory comment (40px panel header + 8px margin)
- Update 5 components to use the new utility:
- AssistantChat.tsx
- ExpandProjectChat.tsx
- SpecCreationChat.tsx
- FolderBrowser.tsx
- TerminalTabs.tsx
This follows up on PR #121 which added IME composition checks. The
refactoring centralizes the logic for easier maintenance and documents
the padding value that prevents Kanban cards from being cut off when
the debug panel is collapsed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add sticky positioning and glassmorphism effect to the top navigation:
- sticky top-0 z-50 for fixed positioning above content
- bg-card/80 for 80% opacity background
- backdrop-blur-md for frosted glass effect
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change CSS import from bare module specifier to url() syntax to fix
Vite/Tailwind CSS resolution issues on some systems.
- Changed `@import "tw-animate-css"` to `@import url("tw-animate-css")`
- The url() wrapper ensures proper package resolution across platforms
- Fixes "Can't resolve 'tw-animate-css'" build error
The bare import syntax failed because Vite's CSS processing didn't
properly resolve the package exports. Using url() bypasses this issue
while still correctly resolving the npm package from node_modules.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add security controls to the EXTRA_READ_PATHS feature (PR #126) to prevent
path traversal attacks and accidental exposure of sensitive directories.
Changes:
- Add EXTRA_READ_PATHS_BLOCKLIST constant blocking credential directories
(.ssh, .aws, .azure, .kube, .gnupg, .docker, .npmrc, .pypirc, .netrc)
- Create get_extra_read_paths() function with comprehensive validation:
- Path canonicalization via Path.resolve() to prevent .. traversal
- Validates paths are absolute (rejects relative paths)
- Validates paths exist and are directories
- Blocks paths that are/contain sensitive directories
- Blocks paths that would expose sensitive dirs (e.g., home dir)
- Update create_client() to use validated getter function
- Improve logging to show validated paths instead of raw input
- Document security controls in CLAUDE.md under Security Model section
Security considerations:
- Addresses path traversal risk similar to CVE-2025-54794
- Prevents accidental exposure of SSH keys, cloud credentials, etc.
- All validation happens before permissions are granted to the agent
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace hardcoded violet/purple colors in OrchestratorStatusCard with
standard primary color CSS variables to ensure proper theming across
all theme variants (light/dark mode, Twitter, Claude, Neo Brutalism,
Aurora, Retro Arcade).
Changes:
- Card background: bg-primary/10 with border-primary/30
- Maestro title and state text: text-primary
- Activity button: text-primary hover:bg-primary/10
- Events border and timestamps: use primary color variants
Also includes:
- Enhanced review-pr command with vision alignment checks
- CLAUDE.md improvements: prerequisites, testing section, React 19 update
- Simplified parallel mode documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allow agents to read files from directories outside the project folder
via the EXTRA_READ_PATHS environment variable.
Changes:
- Add EXTRA_READ_PATHS_VAR constant in client.py
- Parse comma-separated paths and add Read/Glob/Grep permissions
- Log configured extra read paths on agent startup
- Document the feature in .env.example
Usage:
EXTRA_READ_PATHS=/path/to/docs,/path/to/libs
Security: External paths are read-only (no Write/Edit permissions)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
Add visited set to BFS algorithm to handle circular dependencies gracefully.
Previously, cycles in the dependency graph caused the orchestrator to hang
at 100% CPU indefinitely during startup.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace warm off-white with cool blue-gray concrete tone
- More corporate and industrial aesthetic
- Sidebar background adjusted to match
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change primary color to deep navy #000e4e
- Replace teal accent with gray monochrome scale
- Add warm off-white background
- Enhance card shadows for modern depth (2026 UI trend)
- Update chart colors to navy-gray gradient scale
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a new "Business" theme designed for corporate/professional use cases.
The theme features a sophisticated navy and gray color palette that conveys
trust and professionalism while maintaining excellent readability.
Key characteristics:
- Deep navy primary color for trust and professionalism
- Off-white/charcoal backgrounds (avoiding harsh pure white/black)
- Teal accent for CTAs and highlights
- Soft, professional shadows
- System fonts for native feel
- High contrast ratios (WCAG AA compliant)
Files changed:
- globals.css: Added .theme-business light and dark mode variables
- useTheme.ts: Added 'business' to ThemeId and THEMES array
- ThemeSelector.tsx: Added business theme class handling
The comment said "excluding test files" but the grep commands didn't
actually exclude them. Added common test file exclusion patterns.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add isComposing check to prevent Enter key from submitting messages
while Japanese (or other) IME input is in progress.
Affected components:
- AssistantChat
- ExpandProjectChat
- SpecCreationChat
- FolderBrowser
- TerminalTabs
Added 'text' language identifier to all fenced code blocks in the
Infrastructure Feature Descriptions section to satisfy MD040.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Addresses reviewer feedback:
1. Windows Compatibility: Added Windows alternative using netstat/taskkill
2. Safer Process Killing: Changed from `pkill -f "node"` to port-based
killing (`lsof -ti :$PORT`) to avoid killing unrelated Node processes
like VS Code, Claude Code, or other development tools
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>