From aed9fb7c9544a27e067573e3d77f031c212e5736 Mon Sep 17 00:00:00 2001 From: Pedram Amini Date: Wed, 28 Jan 2026 20:35:13 -0500 Subject: [PATCH] dropped Aider across the code base and documentation --- CLAUDE-AGENTS.md | 3 +- README.md | 4 +- docs/features.md | 2 +- docs/index.md | 2 +- docs/installation.md | 3 +- docs/slash-commands.md | 2 +- .../cli/commands/list-agents.test.ts | 4 +- src/__tests__/cli/output/jsonl.test.ts | 4 +- src/__tests__/cli/services/storage.test.ts | 4 +- src/__tests__/main/agent-detector.test.ts | 4 +- .../main/parsers/agent-output-parser.test.ts | 2 +- .../main/parsers/error-patterns.test.ts | 4 +- .../main/parsers/usage-aggregator.test.ts | 2 +- .../components/TransferErrorModal.test.tsx | 2 +- .../components/TransferProgressModal.test.tsx | 2 +- .../AgentComparisonChart.test.tsx | 4 +- .../UsageDashboard/chart-performance.test.tsx | 2 +- .../renderer/hooks/useSendToAgent.test.ts | 2 +- .../renderer/services/contextGroomer.test.ts | 39 +++----- .../renderer/utils/contextUsage.test.ts | 9 +- .../renderer/utils/sessionValidation.test.ts | 14 +-- .../shared/templateVariables.test.ts | 2 +- src/main/agent-capabilities.ts | 29 ------ src/main/agent-detector.ts | 25 +---- .../collectors/windows-diagnostics.ts | 20 ++-- src/main/parsers/agent-output-parser.ts | 1 - src/main/parsers/error-patterns.ts | 1 - src/main/parsers/usage-aggregator.ts | 1 - src/renderer/components/NewInstanceModal.tsx | 2 +- .../UsageDashboard/SessionStats.tsx | 3 +- .../Wizard/screens/AgentSelectionScreen.tsx | 94 +++++++++++-------- src/renderer/constants/agentIcons.ts | 1 - .../hooks/agent/useAvailableAgents.ts | 4 +- src/renderer/services/contextGroomer.ts | 29 ------ src/renderer/types/index.ts | 4 +- src/renderer/utils/contextUsage.ts | 1 - src/renderer/utils/sessionValidation.ts | 1 - src/shared/templateVariables.ts | 2 +- src/shared/types.ts | 2 +- 39 files changed, 131 insertions(+), 205 deletions(-) diff --git a/CLAUDE-AGENTS.md b/CLAUDE-AGENTS.md index d70092e8..8098ea60 100644 --- a/CLAUDE-AGENTS.md +++ b/CLAUDE-AGENTS.md @@ -9,10 +9,9 @@ Agent support documentation for the Maestro codebase. For the main guide, see [[ | `claude-code` | Claude Code | **Active** | Primary agent, `--print --verbose --output-format stream-json` | | `codex` | OpenAI Codex | **Active** | Full support, `--json`, YOLO mode default | | `opencode` | OpenCode | **Active** | Multi-provider support (75+ LLMs), stub session storage | +| `factory-droid` | Factory Droid | **Active** | Factory's AI coding assistant, `-o stream-json` | | `terminal` | Terminal | Internal | Hidden from UI, used for shell sessions | -Additional `ToolType` values (`aider`, `claude`) are defined in types but not yet implemented in `agent-detector.ts`. - ## Agent Capabilities Each agent declares capabilities that control UI feature availability. See `src/main/agent-capabilities.ts` for the full interface. diff --git a/README.md b/README.md index 85ff0897..2b08cbe1 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Maestro is a cross-platform desktop app for orchestrating your fleet of AI agent Collaborate with AI to create detailed specification documents, then let Auto Run execute them automatically, each task in a fresh session with clean context. Allowing for long-running unattended sessions, my current record is nearly 24 hours of continuous runtime. -Run multiple agents in parallel with a Linear/Superhuman-level responsive interface. Currently supporting **Claude Code**, **OpenAI Codex**, and **OpenCode** with plans for additional agentic coding tools (Aider, Gemini CLI, Qwen3 Coder) based on user demand. +Run multiple agents in parallel with a Linear/Superhuman-level responsive interface. Currently supporting **Claude Code**, **OpenAI Codex**, **OpenCode**, and **Factory Droid** with plans for additional agentic coding tools (Gemini CLI, Qwen3 Coder) based on user demand.
@@ -79,7 +79,7 @@ Run multiple agents in parallel with a Linear/Superhuman-level responsive interf Additional interactions: Drag nodes to reposition, scroll to zoom, use mini-map for overview. -> **Note**: Maestro supports Claude Code, OpenAI Codex, and OpenCode. Support for additional agents (Aider, Gemini CLI, Qwen3 Coder) may be added in future releases based on community demand. +> **Note**: Maestro supports Claude Code, OpenAI Codex, OpenCode, and Factory Droid. Support for additional agents (Gemini CLI, Qwen3 Coder) may be added in future releases based on community demand. ## Quick Start diff --git a/docs/features.md b/docs/features.md index fffeda50..2844a366 100644 --- a/docs/features.md +++ b/docs/features.md @@ -34,4 +34,4 @@ icon: sparkles - 📊 **[Usage Dashboard](./usage-dashboard)** - Comprehensive analytics for tracking AI usage patterns. View aggregated statistics, compare agent performance, analyze activity heatmaps, and export data to CSV. Access via `Opt+Cmd+U` / `Alt+Ctrl+U`. - 🏆 **[Achievements](./achievements)** - Level up from Apprentice to Titan of the Baton based on cumulative Auto Run time. 11 conductor-themed ranks to unlock. -> **Note**: Maestro currently supports Claude Code, Codex (OpenAI), and OpenCode as fully-integrated providers. Support for additional providers (Aider, Gemini CLI, Qwen3 Coder) is planned for future releases based on community demand. +> **Note**: Maestro currently supports Claude Code, Codex (OpenAI), OpenCode, and Factory Droid as fully-integrated providers. Support for additional providers (Gemini CLI, Qwen3 Coder) is planned for future releases based on community demand. diff --git a/docs/index.md b/docs/index.md index 419d2e3f..a4da2cab 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,7 +10,7 @@ Maestro is a cross-platform desktop app for orchestrating your fleet of AI agent Collaborate with AI to create detailed specification documents, then let Auto Run execute them automatically, each task in a fresh session with clean context. Allowing for long-running unattended sessions, my current record is nearly 24 hours of continuous runtime. -Run multiple agents in parallel with a Linear/Superhuman-level responsive interface. Currently supporting **Claude Code**, **Codex** (OpenAI), and **OpenCode** with plans for additional agentic coding tools (Aider, Gemini CLI, Qwen3 Coder) based on user demand. +Run multiple agents in parallel with a Linear/Superhuman-level responsive interface. Currently supporting **Claude Code**, **Codex** (OpenAI), **OpenCode**, and **Factory Droid** with plans for additional agentic coding tools (Gemini CLI, Qwen3 Coder) based on user demand. ![Main screen](./screenshots/main-screen.png) diff --git a/docs/installation.md b/docs/installation.md index 028de0df..39b151e7 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -19,7 +19,8 @@ Download the latest release for your platform from the [Releases](https://github - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) — Anthropic's AI coding assistant (fully integrated) - [Codex](https://github.com/openai/codex) — OpenAI's coding agent (fully integrated) - [OpenCode](https://github.com/sst/opencode) — Open-source AI coding assistant (fully integrated) - - [Aider](https://github.com/paul-gauthier/aider), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [Qwen3 Coder](https://github.com/QwenLM/Qwen-Agent) — Planned support + - [Factory Droid](https://docs.factory.ai/cli) — Factory's AI coding assistant (fully integrated) + - [Gemini CLI](https://github.com/google-gemini/gemini-cli), [Qwen3 Coder](https://github.com/QwenLM/Qwen-Agent) — Planned support - Git (optional, for git-aware features) ## WSL2 Users (Windows Subsystem for Linux) diff --git a/docs/slash-commands.md b/docs/slash-commands.md index 63d31a00..ade63f29 100644 --- a/docs/slash-commands.md +++ b/docs/slash-commands.md @@ -34,7 +34,7 @@ Commands support **template variables** that are automatically substituted at ru | `{{AGENT_GROUP}}` | Agent's group name (if grouped) | | `{{AGENT_SESSION_ID}}` | Agent session ID (for conversation continuity) | | `{{TAB_NAME}}` | Custom tab name (alias: `SESSION_NAME`) | -| `{{TOOL_TYPE}}` | Agent type (claude-code, codex, opencode, aider) | +| `{{TOOL_TYPE}}` | Agent type (claude-code, codex, opencode, factory-droid) | ### Path Variables diff --git a/src/__tests__/cli/commands/list-agents.test.ts b/src/__tests__/cli/commands/list-agents.test.ts index 9175f516..4bf40900 100644 --- a/src/__tests__/cli/commands/list-agents.test.ts +++ b/src/__tests__/cli/commands/list-agents.test.ts @@ -78,7 +78,7 @@ describe('list-agents command', () => { it('should display agents in human-readable format', () => { const mockSessions: SessionInfo[] = [ mockSession({ id: 'a1', name: 'Agent One', toolType: 'claude-code' }), - mockSession({ id: 'a2', name: 'Agent Two', toolType: 'aider' }), + mockSession({ id: 'a2', name: 'Agent Two', toolType: 'factory-droid' }), ]; vi.mocked(readSessions).mockReturnValue(mockSessions); @@ -423,7 +423,7 @@ describe('list-agents command', () => { }); it('should handle all tool types', () => { - const toolTypes = ['claude-code', 'aider', 'terminal', 'gemini-cli', 'qwen3-coder']; + const toolTypes = ['claude-code', 'factory-droid', 'terminal', 'gemini-cli', 'qwen3-coder']; const mockSessions: SessionInfo[] = toolTypes.map((toolType, i) => mockSession({ id: `agent-${i}`, name: `Agent ${i}`, toolType: toolType as any }) ); diff --git a/src/__tests__/cli/output/jsonl.test.ts b/src/__tests__/cli/output/jsonl.test.ts index f161d65c..b2d2844f 100644 --- a/src/__tests__/cli/output/jsonl.test.ts +++ b/src/__tests__/cli/output/jsonl.test.ts @@ -526,7 +526,7 @@ describe('jsonl output', () => { const agent = { id: 'agent-456', name: 'Grouped Agent', - toolType: 'aider', + toolType: 'factory-droid', cwd: '/path', groupId: 'group-123', }; @@ -576,7 +576,7 @@ describe('jsonl output', () => { }); it('should handle different tool types', () => { - const toolTypes = ['claude-code', 'aider', 'terminal', 'gemini-cli', 'qwen3-coder']; + const toolTypes = ['claude-code', 'factory-droid', 'terminal', 'gemini-cli', 'qwen3-coder']; toolTypes.forEach((toolType, index) => { consoleSpy.mockClear(); diff --git a/src/__tests__/cli/services/storage.test.ts b/src/__tests__/cli/services/storage.test.ts index 0454736c..53b735ff 100644 --- a/src/__tests__/cli/services/storage.test.ts +++ b/src/__tests__/cli/services/storage.test.ts @@ -341,7 +341,7 @@ describe('storage service', () => { const result = readAgentConfigs(); expect(result['claude-code']).toEqual({ customPath: '/custom/path' }); - expect(result['aider']).toEqual({ setting: 'value' }); + expect(result['factory-droid']).toEqual({ setting: 'value' }); }); it('should return empty object when file does not exist', () => { @@ -389,7 +389,7 @@ describe('storage service', () => { }) ); - const result = getAgentCustomPath('aider'); + const result = getAgentCustomPath('factory-droid'); expect(result).toBeUndefined(); }); diff --git a/src/__tests__/main/agent-detector.test.ts b/src/__tests__/main/agent-detector.test.ts index 8ebc0ae8..5ba586eb 100644 --- a/src/__tests__/main/agent-detector.test.ts +++ b/src/__tests__/main/agent-detector.test.ts @@ -277,7 +277,7 @@ describe('agent-detector', () => { const agents = await detector.detectAgents(); - // Should have all 7 agents (terminal, claude-code, codex, gemini-cli, qwen3-coder, opencode, aider) + // Should have all 7 agents (terminal, claude-code, codex, gemini-cli, qwen3-coder, opencode, factory-droid) expect(agents.length).toBe(7); const agentIds = agents.map((a) => a.id); @@ -287,7 +287,7 @@ describe('agent-detector', () => { expect(agentIds).toContain('gemini-cli'); expect(agentIds).toContain('qwen3-coder'); expect(agentIds).toContain('opencode'); - expect(agentIds).toContain('aider'); + expect(agentIds).toContain('factory-droid'); }); it('should mark agents as available when binary is found', async () => { diff --git a/src/__tests__/main/parsers/agent-output-parser.test.ts b/src/__tests__/main/parsers/agent-output-parser.test.ts index b3320951..4def6d03 100644 --- a/src/__tests__/main/parsers/agent-output-parser.test.ts +++ b/src/__tests__/main/parsers/agent-output-parser.test.ts @@ -316,7 +316,7 @@ describe('agent-output-parser', () => { expect(isValidToolType('codex')).toBe(true); expect(isValidToolType('terminal')).toBe(true); expect(isValidToolType('claude')).toBe(true); - expect(isValidToolType('aider')).toBe(true); + expect(isValidToolType('factory-droid')).toBe(true); }); it('should return false for invalid agent IDs', () => { diff --git a/src/__tests__/main/parsers/error-patterns.test.ts b/src/__tests__/main/parsers/error-patterns.test.ts index 202d9192..940c634b 100644 --- a/src/__tests__/main/parsers/error-patterns.test.ts +++ b/src/__tests__/main/parsers/error-patterns.test.ts @@ -825,8 +825,8 @@ describe('error-patterns', () => { ], }; - registerErrorPatterns('aider', customPatterns); - const patterns = getErrorPatterns('aider'); + registerErrorPatterns('factory-droid', customPatterns); + const patterns = getErrorPatterns('factory-droid'); expect(patterns).toBe(customPatterns); }); diff --git a/src/__tests__/main/parsers/usage-aggregator.test.ts b/src/__tests__/main/parsers/usage-aggregator.test.ts index dfc284cd..ff2e7ded 100644 --- a/src/__tests__/main/parsers/usage-aggregator.test.ts +++ b/src/__tests__/main/parsers/usage-aggregator.test.ts @@ -207,7 +207,7 @@ describe('DEFAULT_CONTEXT_WINDOWS', () => { expect(DEFAULT_CONTEXT_WINDOWS['claude']).toBe(200000); expect(DEFAULT_CONTEXT_WINDOWS['codex']).toBe(200000); expect(DEFAULT_CONTEXT_WINDOWS['opencode']).toBe(128000); - expect(DEFAULT_CONTEXT_WINDOWS['aider']).toBe(128000); + expect(DEFAULT_CONTEXT_WINDOWS['factory-droid']).toBe(200000); expect(DEFAULT_CONTEXT_WINDOWS['terminal']).toBe(0); }); }); diff --git a/src/__tests__/renderer/components/TransferErrorModal.test.tsx b/src/__tests__/renderer/components/TransferErrorModal.test.tsx index aac3bb39..a536a2fe 100644 --- a/src/__tests__/renderer/components/TransferErrorModal.test.tsx +++ b/src/__tests__/renderer/components/TransferErrorModal.test.tsx @@ -43,7 +43,7 @@ vi.mock('../../../renderer/services/contextGroomer', () => ({ 'claude-code': 'Claude Code', opencode: 'OpenCode', codex: 'OpenAI Codex', - aider: 'Aider', + factory-droid: 'Factory Droid', terminal: 'Terminal', }; return names[toolType] || toolType; diff --git a/src/__tests__/renderer/components/TransferProgressModal.test.tsx b/src/__tests__/renderer/components/TransferProgressModal.test.tsx index 7a03e8cb..e3c68393 100644 --- a/src/__tests__/renderer/components/TransferProgressModal.test.tsx +++ b/src/__tests__/renderer/components/TransferProgressModal.test.tsx @@ -37,7 +37,7 @@ vi.mock('../../../renderer/services/contextGroomer', () => ({ 'claude-code': 'Claude Code', opencode: 'OpenCode', codex: 'OpenAI Codex', - aider: 'Aider', + factory-droid: 'Factory Droid', terminal: 'Terminal', }; return names[toolType] || toolType; diff --git a/src/__tests__/renderer/components/UsageDashboard/AgentComparisonChart.test.tsx b/src/__tests__/renderer/components/UsageDashboard/AgentComparisonChart.test.tsx index c90e6952..cd408d79 100644 --- a/src/__tests__/renderer/components/UsageDashboard/AgentComparisonChart.test.tsx +++ b/src/__tests__/renderer/components/UsageDashboard/AgentComparisonChart.test.tsx @@ -103,7 +103,7 @@ describe('AgentComparisonChart', () => { // Use getAllByText since agent names appear in both bar labels and legend expect(screen.getAllByText('claude-code').length).toBeGreaterThanOrEqual(1); - expect(screen.getAllByText('aider').length).toBeGreaterThanOrEqual(1); + expect(screen.getAllByText('factory-droid').length).toBeGreaterThanOrEqual(1); expect(screen.getAllByText('terminal').length).toBeGreaterThanOrEqual(1); }); @@ -167,7 +167,7 @@ describe('AgentComparisonChart', () => { // In duration mode, claude-code has highest duration (2000000), then aider (1600000), then terminal (500000) expect(agentNames[0]).toBe('claude-code'); - expect(agentNames[1]).toBe('aider'); + expect(agentNames[1]).toBe('factory-droid'); expect(agentNames[2]).toBe('terminal'); }); }); diff --git a/src/__tests__/renderer/components/UsageDashboard/chart-performance.test.tsx b/src/__tests__/renderer/components/UsageDashboard/chart-performance.test.tsx index dc1a21fb..d51cd94a 100644 --- a/src/__tests__/renderer/components/UsageDashboard/chart-performance.test.tsx +++ b/src/__tests__/renderer/components/UsageDashboard/chart-performance.test.tsx @@ -76,7 +76,7 @@ function generateManyAgentsData(numAgents: number): StatsAggregation { const byAgent: Record = {}; const agentNames = [ 'claude-code', - 'aider', + 'factory-droid', 'opencode', 'gpt-engineer', 'cursor', diff --git a/src/__tests__/renderer/hooks/useSendToAgent.test.ts b/src/__tests__/renderer/hooks/useSendToAgent.test.ts index b0f9bb53..b47da4e9 100644 --- a/src/__tests__/renderer/hooks/useSendToAgent.test.ts +++ b/src/__tests__/renderer/hooks/useSendToAgent.test.ts @@ -885,7 +885,7 @@ describe('transfer edge cases', () => { }); it('handles all supported agent types as targets', async () => { - const targetAgents: ToolType[] = ['opencode', 'aider', 'codex', 'claude']; + const targetAgents: ToolType[] = ['opencode', 'factory-droid', 'codex', 'claude']; for (const targetAgent of targetAgents) { vi.clearAllMocks(); diff --git a/src/__tests__/renderer/services/contextGroomer.test.ts b/src/__tests__/renderer/services/contextGroomer.test.ts index 273ee856..a1fea4aa 100644 --- a/src/__tests__/renderer/services/contextGroomer.test.ts +++ b/src/__tests__/renderer/services/contextGroomer.test.ts @@ -466,7 +466,6 @@ describe('AGENT_ARTIFACTS', () => { it('should define artifacts for all agent types', () => { const expectedAgents: ToolType[] = [ 'claude-code', - 'aider', 'opencode', 'codex', 'factory-droid', @@ -496,14 +495,6 @@ describe('AGENT_ARTIFACTS', () => { expect(artifacts).toContain('opus'); }); - it('should include aider-specific commands', () => { - const artifacts = AGENT_ARTIFACTS['aider']; - expect(artifacts).toContain('/add'); - expect(artifacts).toContain('/drop'); - expect(artifacts).toContain('/commit'); - expect(artifacts).toContain('Aider'); - }); - it('should include codex-specific references', () => { const artifacts = AGENT_ARTIFACTS['codex']; expect(artifacts).toContain('Codex'); @@ -521,9 +512,9 @@ describe('AGENT_TARGET_NOTES', () => { it('should define notes for all agent types', () => { const expectedAgents: ToolType[] = [ 'claude-code', - 'aider', 'opencode', 'codex', + 'factory-droid', 'claude', 'terminal', ]; @@ -542,11 +533,10 @@ describe('AGENT_TARGET_NOTES', () => { expect(notes).toContain('edit files'); }); - it('should mention git workflow in aider notes', () => { - const notes = AGENT_TARGET_NOTES['aider']; - expect(notes).toContain('git'); - expect(notes).toContain('/add'); - expect(notes).toContain('/drop'); + it('should mention Factory in factory-droid notes', () => { + const notes = AGENT_TARGET_NOTES['factory-droid']; + expect(notes).toContain('Factory'); + expect(notes).toContain('AI coding assistant'); }); it('should mention reasoning models in codex notes', () => { @@ -564,9 +554,9 @@ describe('AGENT_TARGET_NOTES', () => { describe('getAgentDisplayName', () => { it('should return correct display names for all agents', () => { expect(getAgentDisplayName('claude-code')).toBe('Claude Code'); - expect(getAgentDisplayName('aider')).toBe('Aider'); expect(getAgentDisplayName('opencode')).toBe('OpenCode'); expect(getAgentDisplayName('codex')).toBe('OpenAI Codex'); + expect(getAgentDisplayName('factory-droid')).toBe('Factory Droid'); expect(getAgentDisplayName('claude')).toBe('Claude'); expect(getAgentDisplayName('terminal')).toBe('Terminal'); }); @@ -580,14 +570,14 @@ describe('getAgentDisplayName', () => { describe('buildContextTransferPrompt', () => { it('should include source and target agent names', () => { - const prompt = buildContextTransferPrompt('claude-code', 'aider'); + const prompt = buildContextTransferPrompt('claude-code', 'opencode'); expect(prompt).toContain('Claude Code'); - expect(prompt).toContain('Aider'); + expect(prompt).toContain('OpenCode'); }); it('should include source agent artifacts', () => { - const prompt = buildContextTransferPrompt('claude-code', 'aider'); + const prompt = buildContextTransferPrompt('claude-code', 'opencode'); // Should include Claude Code artifacts as bullet points expect(prompt).toContain('"/clear"'); @@ -597,12 +587,11 @@ describe('buildContextTransferPrompt', () => { }); it('should include target agent notes', () => { - const prompt = buildContextTransferPrompt('claude-code', 'aider'); + const prompt = buildContextTransferPrompt('claude-code', 'opencode'); - // Should include Aider target notes - expect(prompt).toContain('git repositories'); - expect(prompt).toContain('/add'); - expect(prompt).toContain('/drop'); + // Should include OpenCode target notes + expect(prompt).toContain('multi-model'); + expect(prompt).toContain('AI coding assistant'); }); it('should handle agents with no artifacts', () => { @@ -623,7 +612,7 @@ describe('buildContextTransferPrompt', () => { }); it('should work for all agent type combinations', () => { - const agents: ToolType[] = ['claude-code', 'aider', 'opencode', 'codex', 'factory-droid', 'claude', 'terminal']; + const agents: ToolType[] = ['claude-code', 'opencode', 'codex', 'factory-droid', 'claude', 'terminal']; for (const source of agents) { for (const target of agents) { diff --git a/src/__tests__/renderer/utils/contextUsage.test.ts b/src/__tests__/renderer/utils/contextUsage.test.ts index 6e3d9ba4..71dfe578 100644 --- a/src/__tests__/renderer/utils/contextUsage.test.ts +++ b/src/__tests__/renderer/utils/contextUsage.test.ts @@ -95,10 +95,11 @@ describe('estimateContextUsage', () => { expect(result).toBe(8); }); - it('should use aider default context window (128k)', () => { + it('should use factory-droid default context window (200k)', () => { const stats = createStats({ contextWindow: 0 }); - const result = estimateContextUsage(stats, 'aider'); - expect(result).toBe(8); + const result = estimateContextUsage(stats, 'factory-droid'); + // (10000 + 0 + 0) / 200000 = 5% + expect(result).toBe(5); }); it('should return null for terminal agent', () => { @@ -289,7 +290,7 @@ describe('DEFAULT_CONTEXT_WINDOWS', () => { expect(DEFAULT_CONTEXT_WINDOWS['claude']).toBe(200000); expect(DEFAULT_CONTEXT_WINDOWS['codex']).toBe(200000); expect(DEFAULT_CONTEXT_WINDOWS['opencode']).toBe(128000); - expect(DEFAULT_CONTEXT_WINDOWS['aider']).toBe(128000); + expect(DEFAULT_CONTEXT_WINDOWS['factory-droid']).toBe(200000); expect(DEFAULT_CONTEXT_WINDOWS['terminal']).toBe(0); }); }); diff --git a/src/__tests__/renderer/utils/sessionValidation.test.ts b/src/__tests__/renderer/utils/sessionValidation.test.ts index 04bceb4b..dd6f8170 100644 --- a/src/__tests__/renderer/utils/sessionValidation.test.ts +++ b/src/__tests__/renderer/utils/sessionValidation.test.ts @@ -171,9 +171,9 @@ describe('sessionValidation', () => { ]; // Different provider (aider) also gets a warning now const result = validateNewSession( - 'Aider Agent', + 'Factory Droid Agent', '/Users/test/project', - 'aider', + 'factory-droid', existingSessions ); expect(result.valid).toBe(true); @@ -269,7 +269,7 @@ describe('sessionValidation', () => { createMockSession({ name: 'Agent 2', projectRoot: '/Users/test/project', - toolType: 'aider', + toolType: 'factory-droid', }), ]; const result = validateNewSession( @@ -299,7 +299,7 @@ describe('sessionValidation', () => { projectRoot: '/path/two', toolType: 'claude-code', }), - createMockSession({ name: 'Session 3', projectRoot: '/path/three', toolType: 'aider' }), + createMockSession({ name: 'Session 3', projectRoot: '/path/three', toolType: 'factory-droid' }), ]; // Unique name and directory - no warning @@ -331,7 +331,7 @@ describe('sessionValidation', () => { const diffProviderResult = validateNewSession( 'Session 4', '/path/two', - 'aider', + 'factory-droid', existingSessions ); expect(diffProviderResult.valid).toBe(true); @@ -372,10 +372,10 @@ describe('sessionValidation', () => { createMockSession({ name: 'Existing', projectRoot: '/path', - toolType: 'aider', + toolType: 'factory-droid', }), ]; - const result = validateNewSession('New', '/path', 'aider', existingSessions); + const result = validateNewSession('New', '/path', 'factory-droid', existingSessions); expect(result.valid).toBe(true); expect(result.warning).toBeDefined(); expect(result.warning).toContain('Existing'); diff --git a/src/__tests__/shared/templateVariables.test.ts b/src/__tests__/shared/templateVariables.test.ts index 975deef5..d807067b 100644 --- a/src/__tests__/shared/templateVariables.test.ts +++ b/src/__tests__/shared/templateVariables.test.ts @@ -183,7 +183,7 @@ describe('substituteTemplateVariables', () => { it('should replace {{TOOL_TYPE}} with session.toolType', () => { const context = createTestContext({ - session: createTestSession({ toolType: 'aider' }), + session: createTestSession({ toolType: 'factory-droid' }), }); const result = substituteTemplateVariables('Tool: {{TOOL_TYPE}}', context); expect(result).toBe('Tool: aider'); diff --git a/src/main/agent-capabilities.ts b/src/main/agent-capabilities.ts index aaa99d8b..30790b4f 100644 --- a/src/main/agent-capabilities.ts +++ b/src/main/agent-capabilities.ts @@ -246,35 +246,6 @@ export const AGENT_CAPABILITIES: Record = { supportsContextExport: false, // Not yet investigated - PLACEHOLDER }, - /** - * Aider - AI pair programming in your terminal - * https://github.com/paul-gauthier/aider - * - * PLACEHOLDER: Most capabilities set to false until Aider integration is - * implemented. Update this configuration when integrating the agent. - */ - aider: { - supportsResume: false, // Not yet investigated - supportsReadOnlyMode: false, // Not yet investigated - supportsJsonOutput: false, // Not yet investigated - supportsSessionId: false, // Not yet investigated - supportsImageInput: true, // Aider supports vision models - supportsImageInputOnResume: false, // Not yet investigated - supportsSlashCommands: true, // Aider has /commands - supportsSessionStorage: false, // Not yet investigated - supportsCostTracking: true, // Aider tracks costs - supportsUsageStats: true, // Aider shows token usage - supportsBatchMode: false, // Not yet investigated - requiresPromptToStart: false, // Not yet investigated - supportsStreaming: true, // Likely streams - supportsResultMessages: false, // Not yet investigated - supportsModelSelection: true, // --model flag - supportsStreamJsonInput: false, - supportsThinkingDisplay: false, // Not yet investigated - supportsContextMerge: false, // Not yet investigated - PLACEHOLDER - supportsContextExport: false, // Not yet investigated - PLACEHOLDER - }, - /** * OpenCode - Open source coding assistant * https://github.com/opencode-ai/opencode diff --git a/src/main/agent-detector.ts b/src/main/agent-detector.ts index fe5ec087..cf9114d0 100644 --- a/src/main/agent-detector.ts +++ b/src/main/agent-detector.ts @@ -172,13 +172,6 @@ export const AGENT_DEFINITIONS: Omit path.join(p, 'gemini')), ], - aider: [ - // pip installation - path.join(home, '.local', 'bin', 'aider'), - // Homebrew paths - '/opt/homebrew/bin/aider', - '/usr/local/bin/aider', - // Add paths from Node version managers (in case installed via npm) - ...versionManagerPaths.map((p) => path.join(p, 'aider')), - ], droid: [ // Factory Droid installation paths path.join(home, '.factory', 'bin', 'droid'), diff --git a/src/main/debug-package/collectors/windows-diagnostics.ts b/src/main/debug-package/collectors/windows-diagnostics.ts index ed0fb2fc..5e52163f 100644 --- a/src/main/debug-package/collectors/windows-diagnostics.ts +++ b/src/main/debug-package/collectors/windows-diagnostics.ts @@ -31,7 +31,7 @@ export interface WindowsDiagnosticsInfo { codex: AgentProbeResult; opencode: AgentProbeResult; gemini: AgentProbeResult; - aider: AgentProbeResult; + droid: AgentProbeResult; }; whereResults?: { // Results from 'where' command for each agent @@ -39,7 +39,7 @@ export interface WindowsDiagnosticsInfo { codex: WhereResult; opencode: WhereResult; gemini: WhereResult; - aider: WhereResult; + droid: WhereResult; }; npmInfo?: { npmGlobalPrefix: string | null; // npm config get prefix (sanitized) @@ -105,7 +105,7 @@ export async function collectWindowsDiagnostics(): Promise { path.join(appData, 'npm', 'opencode.cmd'), ], gemini: [path.join(appData, 'npm', 'gemini.cmd'), path.join(localAppData, 'npm', 'gemini.cmd')], - aider: [ - path.join(appData, 'Python', 'Scripts', 'aider.exe'), - path.join(localAppData, 'Programs', 'Python', 'Python312', 'Scripts', 'aider.exe'), - path.join(localAppData, 'Programs', 'Python', 'Python311', 'Scripts', 'aider.exe'), - path.join(localAppData, 'Programs', 'Python', 'Python310', 'Scripts', 'aider.exe'), + droid: [ + path.join(home, '.factory', 'bin', 'droid.exe'), + path.join(localAppData, 'Factory', 'droid.exe'), + path.join(appData, 'Factory', 'droid.exe'), + path.join(home, '.local', 'bin', 'droid.exe'), + path.join(appData, 'npm', 'droid.cmd'), + path.join(localAppData, 'npm', 'droid.cmd'), ], }; diff --git a/src/main/parsers/agent-output-parser.ts b/src/main/parsers/agent-output-parser.ts index 3144003d..c9e40646 100644 --- a/src/main/parsers/agent-output-parser.ts +++ b/src/main/parsers/agent-output-parser.ts @@ -41,7 +41,6 @@ const VALID_TOOL_TYPES: ToolType[] = [ 'codex', 'terminal', 'claude', - 'aider', 'factory-droid', ]; diff --git a/src/main/parsers/error-patterns.ts b/src/main/parsers/error-patterns.ts index c0ca3ce2..afa4d476 100644 --- a/src/main/parsers/error-patterns.ts +++ b/src/main/parsers/error-patterns.ts @@ -26,7 +26,6 @@ import { logger } from '../utils/logger'; const VALID_TOOL_TYPES = new Set([ 'claude', 'claude-code', - 'aider', 'opencode', 'codex', 'terminal', diff --git a/src/main/parsers/usage-aggregator.ts b/src/main/parsers/usage-aggregator.ts index e94c6701..6d5d667f 100644 --- a/src/main/parsers/usage-aggregator.ts +++ b/src/main/parsers/usage-aggregator.ts @@ -46,7 +46,6 @@ export const DEFAULT_CONTEXT_WINDOWS: Record = { claude: 200000, // Legacy Claude codex: 200000, // OpenAI o3/o4-mini context window opencode: 128000, // OpenCode (depends on model, 128k is conservative default) - aider: 128000, // Aider (varies by model, 128k is conservative default) terminal: 0, // Terminal has no context window 'factory-droid': 200000, // Factory Droid (Claude Opus 4.5 default context) }; diff --git a/src/renderer/components/NewInstanceModal.tsx b/src/renderer/components/NewInstanceModal.tsx index e1ad838b..5c673156 100644 --- a/src/renderer/components/NewInstanceModal.tsx +++ b/src/renderer/components/NewInstanceModal.tsx @@ -1490,7 +1490,7 @@ export function EditAgentModal({ 'claude-code': 'Claude Code', codex: 'Codex', opencode: 'OpenCode', - aider: 'Aider', + 'factory-droid': 'Factory Droid', }; const agentName = agentNameMap[session.toolType] || session.toolType; diff --git a/src/renderer/components/UsageDashboard/SessionStats.tsx b/src/renderer/components/UsageDashboard/SessionStats.tsx index a3c6042e..1eeb7c29 100644 --- a/src/renderer/components/UsageDashboard/SessionStats.tsx +++ b/src/renderer/components/UsageDashboard/SessionStats.tsx @@ -90,9 +90,10 @@ function formatAgentName(toolType: ToolType): string { 'claude-code': 'Claude Code', opencode: 'OpenCode', 'openai-codex': 'OpenAI Codex', + codex: 'Codex', 'gemini-cli': 'Gemini CLI', 'qwen3-coder': 'Qwen3 Coder', - aider: 'Aider', + 'factory-droid': 'Factory Droid', terminal: 'Terminal', }; return names[toolType] || toolType; diff --git a/src/renderer/components/Wizard/screens/AgentSelectionScreen.tsx b/src/renderer/components/Wizard/screens/AgentSelectionScreen.tsx index b7ccb3e2..6bc4d09d 100644 --- a/src/renderer/components/Wizard/screens/AgentSelectionScreen.tsx +++ b/src/renderer/components/Wizard/screens/AgentSelectionScreen.tsx @@ -68,16 +68,9 @@ export const AGENT_TILES: AgentTile[] = [ name: 'Factory Droid', supported: true, description: "Factory's AI coding assistant", - brandColor: '#8B5CF6', // Purple/violet + brandColor: '#3B82F6', // Factory blue }, // Coming soon agents at the bottom - { - id: 'aider', - name: 'Aider', - supported: false, - description: 'Coming soon', - brandColor: '#14B8A6', // Teal - }, { id: 'gemini-cli', name: 'Gemini CLI', @@ -94,9 +87,9 @@ export const AGENT_TILES: AgentTile[] = [ }, ]; -// Grid dimensions for keyboard navigation (3 cols for 7 items) +// Grid dimensions for keyboard navigation (3 cols for 6 items) const GRID_COLS = 3; -const GRID_ROWS = 3; +const GRID_ROWS = 2; /** * Get SVG logo for an agent with brand colors @@ -155,33 +148,6 @@ export function AgentLogo({ ); - case 'aider': - // Aider - chat bubble with code brackets - return ( - - {/* Chat bubble with code brackets */} - - - - ); - case 'gemini-cli': // Gemini - Google's sparkle/star logo return ( @@ -254,6 +220,60 @@ export function AgentLogo({ ); + case 'factory-droid': + // Factory Droid - pinwheel/flower logo + return ( + + {/* Factory Droid pinwheel logo - 6 petals radiating from center */} + + {/* Petals - elliptical shapes radiating outward */} + + + + + + + + ); + default: return (
diff --git a/src/renderer/constants/agentIcons.ts b/src/renderer/constants/agentIcons.ts index 2e976f85..e84a0344 100644 --- a/src/renderer/constants/agentIcons.ts +++ b/src/renderer/constants/agentIcons.ts @@ -41,7 +41,6 @@ export const AGENT_ICONS: Record = { // Open-source alternatives opencode: '📟', - aider: '🛠️', // Enterprise 'factory-droid': '🏭', diff --git a/src/renderer/hooks/agent/useAvailableAgents.ts b/src/renderer/hooks/agent/useAvailableAgents.ts index 399bf49e..180bfe08 100644 --- a/src/renderer/hooks/agent/useAvailableAgents.ts +++ b/src/renderer/hooks/agent/useAvailableAgents.ts @@ -74,8 +74,8 @@ function getAgentIcon(agentId: string): string { return '⬡'; case 'opencode': return '📟'; - case 'aider': - return '🛠️'; + case 'factory-droid': + return '🏭'; default: return '🔧'; } diff --git a/src/renderer/services/contextGroomer.ts b/src/renderer/services/contextGroomer.ts index 13570939..fd801592 100644 --- a/src/renderer/services/contextGroomer.ts +++ b/src/renderer/services/contextGroomer.ts @@ -59,28 +59,6 @@ export const AGENT_ARTIFACTS: Record = { 'Claude Code', 'CLAUDE.md', ], - aider: [ - // Slash commands - '/add', - '/drop', - '/commit', - '/diff', - '/undo', - '/clear', - '/run', - '/voice', - '/help', - '/quit', - '/ls', - '/map', - // Brand references - 'Aider', - 'aider', - // Model references - 'gpt-4', - 'gpt-3.5', - 'GPT', - ], opencode: [ // Slash commands '/help', @@ -145,12 +123,6 @@ export const AGENT_TARGET_NOTES: Record = { It can read and edit files, run terminal commands, search code, and interact with git. It uses slash commands like /compact, /clear, /cost for session management. It can handle large codebases and multi-file changes. - `, - aider: ` - Aider is an AI pair programming tool. - It works with git repositories and can make commits. - It uses /add to include files in context and /drop to remove them. - It focuses on code changes and git workflow. `, opencode: ` OpenCode is a multi-model AI coding assistant. @@ -186,7 +158,6 @@ export const AGENT_TARGET_NOTES: Record = { export function getAgentDisplayName(agentType: ToolType): string { const names: Record = { 'claude-code': 'Claude Code', - aider: 'Aider', opencode: 'OpenCode', codex: 'OpenAI Codex', 'factory-droid': 'Factory Droid', diff --git a/src/renderer/types/index.ts b/src/renderer/types/index.ts index d583040e..c56ca5de 100644 --- a/src/renderer/types/index.ts +++ b/src/renderer/types/index.ts @@ -457,8 +457,8 @@ export interface Session { // Usage statistics from AI responses usageStats?: UsageStats; inputMode: 'terminal' | 'ai'; - // AI process PID (for non-batch agents like Aider) - // For Claude batch mode, this is 0 since processes spawn per-message + // AI process PID (for agents with persistent processes) + // For batch mode agents, this is 0 since processes spawn per-message aiPid: number; // Terminal uses runCommand() which spawns fresh shells per command // This field is kept for backwards compatibility but is always 0 diff --git a/src/renderer/utils/contextUsage.ts b/src/renderer/utils/contextUsage.ts index 49e65084..9866328f 100644 --- a/src/renderer/utils/contextUsage.ts +++ b/src/renderer/utils/contextUsage.ts @@ -17,7 +17,6 @@ export const DEFAULT_CONTEXT_WINDOWS: Record = { claude: 200000, // Legacy Claude codex: 200000, // OpenAI o3/o4-mini context window opencode: 128000, // OpenCode (depends on model, 128k is conservative default) - aider: 128000, // Aider (varies by model, 128k is conservative default) 'factory-droid': 200000, // Factory Droid (varies by model, defaults to Claude Opus) terminal: 0, // Terminal has no context window }; diff --git a/src/renderer/utils/sessionValidation.ts b/src/renderer/utils/sessionValidation.ts index 978f73f6..d7cab847 100644 --- a/src/renderer/utils/sessionValidation.ts +++ b/src/renderer/utils/sessionValidation.ts @@ -111,7 +111,6 @@ export function getProviderDisplayName(toolType: ToolType): string { const displayNames: Record = { 'claude-code': 'Claude Code', claude: 'Claude', - aider: 'Aider', opencode: 'OpenCode', codex: 'Codex', 'factory-droid': 'Factory Droid', diff --git a/src/shared/templateVariables.ts b/src/shared/templateVariables.ts index 836f764b..04e9695a 100644 --- a/src/shared/templateVariables.ts +++ b/src/shared/templateVariables.ts @@ -10,7 +10,7 @@ * {{AGENT_SESSION_ID}} - Agent session ID (for conversation continuity) * {{AGENT_HISTORY_PATH}} - Path to agent's history JSON file (for task recall) * {{TAB_NAME}} - Custom tab name (alias: SESSION_NAME) - * {{TOOL_TYPE}} - Agent type (claude-code, aider, etc.) + * {{TOOL_TYPE}} - Agent type (claude-code, codex, opencode, factory-droid) * * Path Variables: * {{CWD}} - Current working directory diff --git a/src/shared/types.ts b/src/shared/types.ts index 18ace442..fbc3cff6 100644 --- a/src/shared/types.ts +++ b/src/shared/types.ts @@ -1,7 +1,7 @@ // Shared type definitions for Maestro CLI and Electron app // These types are used by both the CLI tool and the renderer process -export type ToolType = 'claude' | 'claude-code' | 'aider' | 'opencode' | 'codex' | 'terminal' | 'factory-droid'; +export type ToolType = 'claude' | 'claude-code' | 'opencode' | 'codex' | 'terminal' | 'factory-droid'; /** * ThinkingMode controls how AI reasoning/thinking content is displayed.