- Add AgentExecutor import to auto-mode-service.ts
- Add agentExecutor as constructor parameter (optional, with default)
- Initialize AgentExecutor with TypedEventBus, FeatureStateManager,
PlanApprovalService, and SettingsService dependencies
This enables constructor injection for testing and prepares for
incremental delegation of runAgent() logic to AgentExecutor.
The AgentExecutor contains the full execution pipeline;
runAgent() delegation will be done incrementally to ensure
stability.
- Test constructor injection with all dependencies
- Test interface exports (AgentExecutionOptions, AgentExecutionResult)
- Test callback type signatures (WaitForApprovalFn, SaveFeatureSummaryFn, etc.)
- Test dependency injection patterns with custom implementations
- Verify execute method signature
Note: Full integration tests for streaming/marker detection require
complex mocking of @automaker/utils module which has hoisting issues.
Integration testing covered in E2E and auto-mode-service tests.
- Extract parseTasksFromSpec for parsing tasks from spec content
- Extract marker detection functions (task start/complete, phase complete)
- Extract detectSpecFallback for non-Claude model support
- Extract extractSummary with multi-format support and last-match behavior
- Add 65 unit tests covering all functions and edge cases
- Extract plan approval workflow from AutoModeService
- Timeout-wrapped Promise creation via waitForApproval()
- Resolution handling (approve/reject) with needsRecovery flag
- Cancellation support for stopped features
- Per-project configurable timeout (default 30 minutes)
- Event emission through TypedEventBus for plan_rejected
- Add WorktreeResolver and FeatureStateManager as constructor parameters
- Remove top-level getCurrentBranch function (now in WorktreeResolver)
- Delegate loadFeature, updateFeatureStatus to FeatureStateManager
- Delegate markFeatureInterrupted, resetStuckFeatures to FeatureStateManager
- Delegate updateFeaturePlanSpec, saveFeatureSummary, updateTaskStatus
- Replace findExistingWorktreeForBranch calls with worktreeResolver
- Update tests to mock featureStateManager instead of internal methods
- All 89 tests passing across 3 service files
- Create FeatureStateManager class for feature status updates
- Extract updateFeatureStatus, markFeatureInterrupted, resetStuckFeatures
- Extract updateFeaturePlanSpec, saveFeatureSummary, updateTaskStatus
- Persist BEFORE emit pattern for data integrity (Pitfall 2)
- Handle corrupted JSON with readJsonWithRecovery backup support
- Preserve pipeline_* statuses in markFeatureInterrupted
- Fix bug: version increment now checks old content before applying updates
- Add 33 unit tests covering all state management operations
- Add TypedEventBus as wrapper around EventEmitter
- Implement emitAutoModeEvent method for auto-mode event format
- Add emit, subscribe, getUnderlyingEmitter methods
- Create comprehensive test suite (20 tests)
- Verify exact event format for frontend compatibility
- AutoModeService now delegates to ConcurrencyManager for all running feature tracking
- Constructor accepts optional ConcurrencyManager for dependency injection
- Remove local RunningFeature interface (imported from ConcurrencyManager)
- Migrate all this.runningFeatures usages to concurrencyManager methods
- Update tests to use concurrencyManager.acquire() instead of direct Map access
- ConcurrencyManager accepts getCurrentBranch function for testability
BREAKING: AutoModeService no longer exposes runningFeatures Map directly.
Tests must use concurrencyManager.acquire() to add running features.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Lease-based reference counting for nested execution support
- acquire() creates entry with leaseCount: 1 or increments existing
- release() decrements leaseCount, deletes at 0 or with force:true
- Project and worktree-level running counts
- RunningFeature interface exported for type sharing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Test lease counting basics (acquire/release semantics)
- Test running count queries (project and worktree level)
- Test feature state queries (isRunning, getRunningFeature, getAllRunning)
- Test edge cases (multiple features, multiple worktrees)
- 36 test cases documenting expected behavior
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix setProjectCustomIcon using wrong property name (customIcon -> customIconPath)
- Add currentProject state update to setProjectIcon and setProjectCustomIcon
- Fix data URL regex to handle all formats (e.g., charset=utf-8 in GIFs)
- Increase project icon size limit from 2MB to 5MB for animated GIFs
- Add toast notifications for upload validation errors
- Add image error fallback to folder icon in project switcher
- Make HttpApiClient get/put methods public for store access
- Fix TypeScript errors in app-store.ts (trashedAt type, font properties)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Updated the revision prompt generation to utilize a customizable template, allowing for dynamic insertion of plan version, previous plan content, user feedback, and task format examples.
- Added validation to ensure the presence of a tasks block in the revised specification, with clear instructions on the required format to prevent execution issues.
- Introduced logging for scenarios where no tasks are found in the revised plan, warning about potential fallback to single-agent execution.
Address CodeRabbit review comment - API keys stored in CLI credentials
file should also be detected as valid authentication.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated the error handling in the Claude Code CLI authentication check to log the specific error encountered. This enhancement provides better visibility into issues during the authentication process, ensuring users are informed of any problems that arise.
The startup warning "No Claude authentication configured" was shown
even when users have Claude Code CLI installed and authenticated
with a subscription. The Claude Agent SDK can reuse CLI authentication,
so this was a false positive.
Now checks for Claude Code CLI authentication indicators before
showing the warning:
- Recent CLI activity (stats cache)
- CLI setup indicators (settings + project sessions)
- OAuth credentials file
Also updated the warning message to list all authentication options.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolved conflict in auto-mode-service.ts by keeping the v0.14.0rc version
which uses isFeatureRunning() method and has more informative logging.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Simplified the graceful shutdown process by removing redundant error handling for marking features as interrupted, as it is now managed internally.
- Updated orphan detection logging to streamline the process and enhance clarity.
- Added logic to preserve specific pipeline statuses when marking features as interrupted, ensuring correct resumption of features after a server restart.
- Enhanced unit tests to cover new behavior for preserving pipeline statuses and handling various feature states.
- Add graceful shutdown handler that marks running features as 'interrupted'
before server exit (SIGTERM/SIGINT)
- Add 30-second shutdown timeout to prevent hanging on exit
- Add orphan detection to identify features with missing branches
- Add isFeatureRunning() for idempotent resume checks
- Improve resumeInterruptedFeatures() to handle features without saved context
- Add 'interrupted' status to FeatureStatusWithPipeline type
- Replace console.log with proper logger in auto-mode-service
- Add comprehensive unit tests for all new functionality (15 new tests)
Fixes#696🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Address CodeRabbit review comment: The reset logic was incorrectly
clearing feature.currentTaskId (which doesn't exist on Feature type)
instead of feature.planSpec.currentTaskId. This left planSpec.currentTaskId
stale, causing UI/recovery to still point at reverted tasks.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added functionality to extract and save the final summary from multi-task or single-agent execution in the auto mode service.
- Updated event types in the query invalidation hook to include 'auto_mode_task_started' and 'auto_mode_task_complete' for better event handling.
- Changed model references from `bareModel` to `effectiveBareModel` in multiple locations to ensure consistency.
- Removed redundant event emission for `auto_mode_summary` after saving feature summaries.
- Added checks to prevent resuming features that are already running, enhancing error handling.
- Introduced a new useEffect in various dialogs to clear `requirePlanApproval` when planning mode is set to 'skip' or 'lite'.
- Updated prompt templates to enforce a structured summary output format, ensuring critical information is captured after task completion.
Address PR #688 review feedback from CodeRabbit: When a GitHub PR fetch
fails and we return stale cached data, also update the fetchedAt timestamp.
This prevents the original TTL from expiring and causing every subsequent
poll to retry the failing request, which would still hammer GitHub during
API outages.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Address PR #688 review feedback: previously the cache was deleted before
fetch, causing repeated API calls if the fetch failed. Now the cache entry
is preserved and stale data is returned on failure, preventing unnecessary
API calls during GitHub API flakiness or temporary outages.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes#685
This commit addresses the GitHub API rate limit issue caused by excessive worktree PR status fetching.
## Changes
### Server-side PR caching (list.ts)
- Added `GitHubPRCacheEntry` interface and `githubPRCache` Map
- Implemented 2-minute TTL cache for GitHub PR data
- Modified `fetchGitHubPRs()` to check cache before making API calls
- Added `forceRefresh` parameter to bypass cache when explicitly requested
- Cache is properly cleared when force refresh is triggered
### Frontend polling reduction (worktree-panel.tsx)
- Increased worktree polling interval from 5 seconds to 30 seconds
- Reduces polling frequency by 6x while keeping UI reasonably fresh
- Updated comment to reflect new polling strategy
### Type improvements (use-worktrees.ts)
- Fixed `fetchWorktrees` callback signature to accept `silent` option
- Returns proper type for removed worktrees detection
## Impact
- Combined ~12x reduction in GitHub API calls
- 2-minute cache prevents repeated API hits during normal operation
- 30-second polling balances responsiveness with API conservation
- Force refresh option allows users to manually update when needed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Resolved conflict in apps/ui/src/hooks/use-query-invalidation.ts by:
- Keeping the refactored structure from v0.14.0rc (using constants and hasFeatureId() type guard)
- Adding the additional event types from the feature branch (auto_mode_task_status, auto_mode_summary) to SINGLE_FEATURE_INVALIDATION_EVENTS constant
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Introduced a dedicated 5-minute timeout for Codex models during feature generation to accommodate slower response times when generating 50+ features.
- Updated the CodexProvider to utilize this extended timeout based on the reasoning effort level.
- Enhanced the feature generation logic in generate-features-from-spec.ts to detect Codex models and apply the appropriate timeout.
- Modified the model resolver to include reasoning effort in the resolved phase model structure.
This change improves the reliability of feature generation for Codex models, ensuring they have sufficient time to process requests effectively.
- Throw error immediately when JSON extraction fails in
generate-features-from-spec.ts to avoid redundant parsing attempt
(feedback from Gemini Code Assist review)
- Emit spec_regeneration_error event before throwing for consistency
- Fix TypeScript cast in sync-spec.ts by using double cast through unknown
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This fixes the app spec generation failing for non-Claude models (Cursor, Gemini,
OpenCode, Copilot) that don't support structured output capabilities.
Changes:
- Add `supportsStructuredOutput()` utility function in @automaker/types to
centralize model capability detection
- Update generate-features-from-spec.ts:
- Add explicit JSON instructions for non-Claude/Codex models
- Define featuresOutputSchema for structured output
- Pre-extract JSON from text responses using extractJsonWithArray
- Handle both structured_output and text responses properly
- Update generate-spec.ts:
- Replace isCursorModel with supportsStructuredOutput for consistency
- Update sync-spec.ts:
- Add techStackOutputSchema for structured output
- Add JSON extraction fallback for text responses
- Handle both structured_output and text parsing
- Update validate-issue.ts:
- Use supportsStructuredOutput for cleaner capability detection
The fix follows the same pattern used in generate-spec.ts where non-Claude models
receive explicit JSON formatting instructions in the prompt and responses are
parsed using extractJson utilities.
Fixes#669🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Closes#671 (Complete fix for the plan mode system inside automaker)
Related: #619, #627, #531, #660
## Issues Fixed
### 1. Non-Claude Provider Support
- Removed Claude model restriction from planning mode UI selectors
- Added `detectSpecFallback()` function to detect specs without `[SPEC_GENERATED]` marker
- All providers (OpenAI, Gemini, Cursor, etc.) can now use spec and full planning modes
- Fallback detection looks for structural elements: tasks block, acceptance criteria,
problem statement, implementation plan, etc.
### 2. Crash/Restart Recovery
- Added `resetStuckFeatures()` to clean up transient states on auto-mode start
- Features stuck in `in_progress` are reset to `ready` or `backlog`
- Tasks stuck in `in_progress` are reset to `pending`
- Plan generation stuck in `generating` is reset to `pending`
- `loadPendingFeatures()` now includes recovery cases for interrupted executions
- Persisted task status in `planSpec.tasks` array allows resuming from last completed task
### 3. Spec Todo List UI Updates
- Added `ParsedTask` and `PlanSpec` types to `@automaker/types` for consistent typing
- New `auto_mode_task_status` event emitted when task status changes
- New `auto_mode_summary` event emitted when summary is extracted
- Query invalidation triggers on task status updates for real-time UI refresh
- Task markers (`[TASK_START]`, `[TASK_COMPLETE]`, `[PHASE_COMPLETE]`) are detected
and persisted to planSpec.tasks for UI display
### 4. Summary Extraction
- Added `extractSummary()` function to parse summaries from multiple formats:
- `<summary>` tags (explicit)
- `## Summary` sections (markdown)
- `**Goal**:` sections (lite mode)
- `**Problem**:` sections (spec/full modes)
- `**Solution**:` sections (fallback)
- Summary is saved to `feature.summary` field after execution
- Summary is extracted from plan content during spec generation
### 5. Worktree Mode Support (#619)
- Recovery logic properly handles branchName filtering
- Features in worktrees maintain correct association during recovery
## Files Changed
- libs/types/src/feature.ts - Added ParsedTask and PlanSpec interfaces
- libs/types/src/index.ts - Export new types
- apps/server/src/services/auto-mode-service.ts - Core fixes for all issues
- apps/server/tests/unit/services/auto-mode-task-parsing.test.ts - New tests
- apps/ui/src/store/app-store.ts - Import types from @automaker/types
- apps/ui/src/hooks/use-auto-mode.ts - Handle new events
- apps/ui/src/hooks/use-query-invalidation.ts - Invalidate on task updates
- apps/ui/src/types/electron.d.ts - New event type definitions
- apps/ui/src/components/views/board-view/dialogs/*.tsx - Enable planning for all models
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Removed the suggestionCount variable that was re-clamping the count parameter
- Removed default values from function parameters (count: number = 10 → count: number)
* feat: add GitHub Copilot SDK provider integration
Adds comprehensive GitHub Copilot SDK provider support including:
- CopilotProvider class with CLI detection and OAuth authentication check
- Copilot models definition with GPT-4o, Claude, and o1/o3 series models
- Settings UI integration with provider tab, model configuration, and navigation
- Onboarding flow integration with Copilot setup step
- Model selector integration for all phase-specific model dropdowns
- Persistence of enabled models and default model settings via API sync
- Server route for Copilot CLI status endpoint
https://claude.ai/code/session_01D26w7ZyEzP4H6Dor3ttk9d
* chore: update package-lock.json
https://claude.ai/code/session_01D26w7ZyEzP4H6Dor3ttk9d
* refactor: rename Copilot SDK to Copilot CLI and use GitHub icon
- Update all references from "GitHub Copilot SDK" to "GitHub Copilot CLI"
- Change install command from @github/copilot-sdk to @github/copilot
- Update CopilotIcon to use official GitHub Octocat logo
- Update error codes and comments throughout codebase
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: update Copilot model definitions and add dynamic model discovery
- Update COPILOT_MODEL_MAP with correct models from CLI (claude-sonnet-4.5,
claude-haiku-4.5, claude-opus-4.5, claude-sonnet-4, gpt-5.x series, gpt-4.1,
gemini-3-pro-preview)
- Change default Copilot model to copilot-claude-sonnet-4.5
- Add model caching methods to CopilotProvider (hasCachedModels,
clearModelCache, refreshModels)
- Add API routes for dynamic model discovery:
- GET /api/setup/copilot/models
- POST /api/setup/copilot/models/refresh
- POST /api/setup/copilot/cache/clear
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: use @github/copilot-sdk instead of direct CLI calls
- Install @github/copilot-sdk package for proper SDK integration
- Rewrite CopilotProvider to use SDK's CopilotClient API
- Use client.createSession() for session management
- Handle SDK events (assistant.message, tool.execution_*, session.idle)
- Auto-approve permissions for autonomous agent operation
- Remove incorrect CLI flags (--mode, --output-format)
- Update default model to claude-sonnet-4.5
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add Copilot and Gemini model support to model resolver
- Import isCopilotModel and isGeminiModel from types
- Add explicit checks for copilot- and gemini- prefixed models
- Pass through Copilot/Gemini models unchanged to their providers
- Update resolver documentation to list all supported providers
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: pass working directory to Copilot SDK and reduce event noise
- Create CopilotClient per execution with correct cwd from options.cwd
- This ensures the CLI operates in the correct project directory, not the
server's current directory
- Skip assistant.message_delta events (they create excessive noise)
- Only yield the final assistant.message event which has complete content
- Clean up client on completion and error paths
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: simplify Copilot SDK execution with sendAndWait
- Use sendAndWait() instead of manual event polling for more reliable
execution
- Disable streaming (streaming: false) to simplify response handling
- Increase timeout to 10 minutes for agentic operations
- Still capture tool execution events for UI display
- Add more debug logging for troubleshooting
- This should fix the "invalid_request_body" error on subsequent calls
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: allow Copilot model IDs with claude-, gemini-, gpt- prefixes
Copilot's bare model IDs legitimately contain prefixes like claude-,
gemini-, gpt- because those are the actual model names from the
Copilot CLI (e.g., claude-sonnet-4.5, gemini-3-pro-preview, gpt-5.1).
The generic validateBareModelId function was incorrectly rejecting
these valid model IDs. Now we only check that the copilot- prefix
has been stripped by the ProviderFactory.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: enable real-time streaming of tool events for Copilot
- Switch back to streaming mode (streaming: true) for real-time events
- Use async queue pattern to bridge SDK callbacks to async generator
- Events are now yielded as they happen, not batched at the end
- Tool calls (Read, Write, Edit, Bash, TodoWrite, etc.) show in real-time
- Better progress visibility during agentic operations
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: expand Copilot tool name and input normalization
Tool name mapping additions:
- view → Read (Copilot's file viewing tool)
- create_file → Write
- replace, patch → Edit
- run_shell_command, terminal → Bash
- search_file_content → Grep
- list_directory → Ls
- google_web_search → WebSearch
- report_intent → ReportIntent (Copilot-specific planning)
- think, plan → Think, Plan
Input normalization improvements:
- Read/Write/Edit: Map file, filename, filePath → file_path
- Bash: Map cmd, script → command
- Grep: Map query, search, regex → pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: convert git+ssh to git+https in package-lock.json
The @electron/node-gyp dependency was resolved with a git+ssh URL
which fails in CI environments without SSH keys. Convert to HTTPS.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address code review feedback for Copilot SDK provider
- Add guard for non-text prompts (vision not yet supported)
- Clear runtime model cache on fetch failure
- Fix race condition in async queue error handling
- Import CopilotAuthStatus from shared types
- Fix comment mismatch for default model constant
- Add auth-copilot and deauth-copilot routes
- Extract shared tool normalization utilities
- Create base model configuration UI component
- Add comprehensive unit tests for CopilotProvider
- Replace magic strings with constants
- Add debug logging for cleanup errors
* fix: address CodeRabbit review nitpicks
- Fix test mocks to include --version check for CLI detection
- Add aria-label for accessibility on refresh button
- Ensure default model checkbox always appears checked/enabled
* fix: address CodeRabbit review feedback
- Fix test mocks by creating fresh provider instances after mock setup
- Extract COPILOT_DISCONNECTED_MARKER_FILE constant to common.ts
- Add AUTONOMOUS MODE comment explaining auto-approval of permissions
- Improve tool-normalization with union types and null guards
- Handle 'canceled' (American spelling) status in todo normalization
* refactor: extract copilot connection logic to service and fix test mocks
- Create copilot-connection-service.ts with connect/disconnect logic
- Update auth-copilot and deauth-copilot routes to use service
- Fix test mocks for CLI detection:
- Mock fs.existsSync for CLI path validation
- Mock which/where command for CLI path detection
---------
Co-authored-by: Claude <noreply@anthropic.com>
- Change 'waiting_approval' status to 'in_progress' and add handling for 'waiting_approval' as pending.
- Introduce counting of live running features per project in the overview handler by fetching all running agents.
- Ensure accurate representation of project statuses in the overview.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>