From 63b0ccd0358a849259a2cc5ad31d7b91c1d7e94f Mon Sep 17 00:00:00 2001 From: Kacper Date: Mon, 29 Dec 2025 15:30:11 +0100 Subject: [PATCH 1/4] feat: enchance agent runner ui --- .../src/routes/running-agents/routes/index.ts | 3 +- apps/server/src/services/auto-mode-service.ts | 49 +++- .../tests/unit/routes/running-agents.test.ts | 196 ++++++++++++++ .../unit/services/auto-mode-service.test.ts | 249 ++++++++++++++++++ .../components/views/running-agents-view.tsx | 44 +++- apps/ui/src/lib/electron.ts | 4 + 6 files changed, 528 insertions(+), 17 deletions(-) create mode 100644 apps/server/tests/unit/routes/running-agents.test.ts diff --git a/apps/server/src/routes/running-agents/routes/index.ts b/apps/server/src/routes/running-agents/routes/index.ts index 72a3f838..693eba8b 100644 --- a/apps/server/src/routes/running-agents/routes/index.ts +++ b/apps/server/src/routes/running-agents/routes/index.ts @@ -9,8 +9,7 @@ import { getErrorMessage, logError } from '../common.js'; export function createIndexHandler(autoModeService: AutoModeService) { return async (_req: Request, res: Response): Promise => { try { - const runningAgents = autoModeService.getRunningAgents(); - const status = autoModeService.getStatus(); + const runningAgents = await autoModeService.getRunningAgents(); res.json({ success: true, diff --git a/apps/server/src/services/auto-mode-service.ts b/apps/server/src/services/auto-mode-service.ts index 9ba48361..491f9f61 100644 --- a/apps/server/src/services/auto-mode-service.ts +++ b/apps/server/src/services/auto-mode-service.ts @@ -1374,18 +1374,43 @@ Format your response as a structured markdown document.`; /** * Get detailed info about all running agents */ - getRunningAgents(): Array<{ - featureId: string; - projectPath: string; - projectName: string; - isAutoMode: boolean; - }> { - return Array.from(this.runningFeatures.values()).map((rf) => ({ - featureId: rf.featureId, - projectPath: rf.projectPath, - projectName: path.basename(rf.projectPath), - isAutoMode: rf.isAutoMode, - })); + async getRunningAgents(): Promise< + Array<{ + featureId: string; + projectPath: string; + projectName: string; + isAutoMode: boolean; + title?: string; + description?: string; + }> + > { + const agents = await Promise.all( + Array.from(this.runningFeatures.values()).map(async (rf) => { + // Try to fetch feature data to get title and description + let title: string | undefined; + let description: string | undefined; + + try { + const feature = await this.featureLoader.get(rf.projectPath, rf.featureId); + if (feature) { + title = feature.title; + description = feature.description; + } + } catch (error) { + // Silently ignore errors - title/description are optional + } + + return { + featureId: rf.featureId, + projectPath: rf.projectPath, + projectName: path.basename(rf.projectPath), + isAutoMode: rf.isAutoMode, + title, + description, + }; + }) + ); + return agents; } /** diff --git a/apps/server/tests/unit/routes/running-agents.test.ts b/apps/server/tests/unit/routes/running-agents.test.ts new file mode 100644 index 00000000..6071567f --- /dev/null +++ b/apps/server/tests/unit/routes/running-agents.test.ts @@ -0,0 +1,196 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import type { Request, Response } from 'express'; +import { createIndexHandler } from '@/routes/running-agents/routes/index.js'; +import type { AutoModeService } from '@/services/auto-mode-service.js'; +import { createMockExpressContext } from '../../utils/mocks.js'; + +describe('running-agents routes', () => { + let mockAutoModeService: Partial; + let req: Request; + let res: Response; + + beforeEach(() => { + vi.clearAllMocks(); + + mockAutoModeService = { + getRunningAgents: vi.fn(), + getStatus: vi.fn(), + }; + + const context = createMockExpressContext(); + req = context.req; + res = context.res; + }); + + describe('GET / (index handler)', () => { + it('should return empty array when no agents are running', async () => { + // Arrange + vi.mocked(mockAutoModeService.getRunningAgents!).mockResolvedValue([]); + + // Act + const handler = createIndexHandler(mockAutoModeService as AutoModeService); + await handler(req, res); + + // Assert + expect(mockAutoModeService.getRunningAgents).toHaveBeenCalled(); + expect(res.json).toHaveBeenCalledWith({ + success: true, + runningAgents: [], + totalCount: 0, + }); + }); + + it('should return running agents with all properties', async () => { + // Arrange + const runningAgents = [ + { + featureId: 'feature-123', + projectPath: '/home/user/project', + projectName: 'project', + isAutoMode: true, + title: 'Implement login feature', + description: 'Add user authentication with OAuth', + }, + { + featureId: 'feature-456', + projectPath: '/home/user/other-project', + projectName: 'other-project', + isAutoMode: false, + title: 'Fix navigation bug', + description: undefined, + }, + ]; + + vi.mocked(mockAutoModeService.getRunningAgents!).mockResolvedValue(runningAgents); + + // Act + const handler = createIndexHandler(mockAutoModeService as AutoModeService); + await handler(req, res); + + // Assert + expect(res.json).toHaveBeenCalledWith({ + success: true, + runningAgents, + totalCount: 2, + }); + }); + + it('should return agents without title/description (backward compatibility)', async () => { + // Arrange + const runningAgents = [ + { + featureId: 'legacy-feature', + projectPath: '/project', + projectName: 'project', + isAutoMode: true, + title: undefined, + description: undefined, + }, + ]; + + vi.mocked(mockAutoModeService.getRunningAgents!).mockResolvedValue(runningAgents); + + // Act + const handler = createIndexHandler(mockAutoModeService as AutoModeService); + await handler(req, res); + + // Assert + expect(res.json).toHaveBeenCalledWith({ + success: true, + runningAgents, + totalCount: 1, + }); + }); + + it('should handle errors gracefully and return 500', async () => { + // Arrange + const error = new Error('Database connection failed'); + vi.mocked(mockAutoModeService.getRunningAgents!).mockRejectedValue(error); + + // Act + const handler = createIndexHandler(mockAutoModeService as AutoModeService); + await handler(req, res); + + // Assert + expect(res.status).toHaveBeenCalledWith(500); + expect(res.json).toHaveBeenCalledWith({ + success: false, + error: 'Database connection failed', + }); + }); + + it('should handle non-Error exceptions', async () => { + // Arrange + vi.mocked(mockAutoModeService.getRunningAgents!).mockRejectedValue('String error'); + + // Act + const handler = createIndexHandler(mockAutoModeService as AutoModeService); + await handler(req, res); + + // Assert + expect(res.status).toHaveBeenCalledWith(500); + expect(res.json).toHaveBeenCalledWith({ + success: false, + error: expect.any(String), + }); + }); + + it('should correctly count multiple running agents', async () => { + // Arrange + const runningAgents = Array.from({ length: 10 }, (_, i) => ({ + featureId: `feature-${i}`, + projectPath: `/project-${i}`, + projectName: `project-${i}`, + isAutoMode: i % 2 === 0, + title: `Feature ${i}`, + description: `Description ${i}`, + })); + + vi.mocked(mockAutoModeService.getRunningAgents!).mockResolvedValue(runningAgents); + + // Act + const handler = createIndexHandler(mockAutoModeService as AutoModeService); + await handler(req, res); + + // Assert + expect(res.json).toHaveBeenCalledWith({ + success: true, + runningAgents, + totalCount: 10, + }); + }); + + it('should include agents from different projects', async () => { + // Arrange + const runningAgents = [ + { + featureId: 'feature-a', + projectPath: '/workspace/project-alpha', + projectName: 'project-alpha', + isAutoMode: true, + title: 'Feature A', + description: 'In project alpha', + }, + { + featureId: 'feature-b', + projectPath: '/workspace/project-beta', + projectName: 'project-beta', + isAutoMode: false, + title: 'Feature B', + description: 'In project beta', + }, + ]; + + vi.mocked(mockAutoModeService.getRunningAgents!).mockResolvedValue(runningAgents); + + // Act + const handler = createIndexHandler(mockAutoModeService as AutoModeService); + await handler(req, res); + + // Assert + const response = vi.mocked(res.json).mock.calls[0][0]; + expect(response.runningAgents[0].projectPath).toBe('/workspace/project-alpha'); + expect(response.runningAgents[1].projectPath).toBe('/workspace/project-beta'); + }); + }); +}); diff --git a/apps/server/tests/unit/services/auto-mode-service.test.ts b/apps/server/tests/unit/services/auto-mode-service.test.ts index ec0959d7..3dda13e2 100644 --- a/apps/server/tests/unit/services/auto-mode-service.test.ts +++ b/apps/server/tests/unit/services/auto-mode-service.test.ts @@ -1,5 +1,6 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; import { AutoModeService } from '@/services/auto-mode-service.js'; +import type { Feature } from '@automaker/types'; describe('auto-mode-service.ts', () => { let service: AutoModeService; @@ -66,4 +67,252 @@ describe('auto-mode-service.ts', () => { expect(runningCount).toBe(0); }); }); + + describe('getRunningAgents', () => { + // Helper to access private runningFeatures Map + const getRunningFeaturesMap = (svc: AutoModeService) => + (svc as any).runningFeatures as Map< + string, + { featureId: string; projectPath: string; isAutoMode: boolean } + >; + + // Helper to get the featureLoader and mock its get method + const mockFeatureLoaderGet = (svc: AutoModeService, mockFn: ReturnType) => { + (svc as any).featureLoader = { get: mockFn }; + }; + + it('should return empty array when no agents are running', async () => { + const result = await service.getRunningAgents(); + + expect(result).toEqual([]); + }); + + it('should return running agents with basic info when feature data is not available', async () => { + // Arrange: Add a running feature to the Map + const runningFeaturesMap = getRunningFeaturesMap(service); + runningFeaturesMap.set('feature-123', { + featureId: 'feature-123', + projectPath: '/test/project/path', + isAutoMode: true, + }); + + // Mock featureLoader.get to return null (feature not found) + const getMock = vi.fn().mockResolvedValue(null); + mockFeatureLoaderGet(service, getMock); + + // Act + const result = await service.getRunningAgents(); + + // Assert + expect(result).toHaveLength(1); + expect(result[0]).toEqual({ + featureId: 'feature-123', + projectPath: '/test/project/path', + projectName: 'path', + isAutoMode: true, + title: undefined, + description: undefined, + }); + }); + + it('should return running agents with title and description when feature data is available', async () => { + // Arrange + const runningFeaturesMap = getRunningFeaturesMap(service); + runningFeaturesMap.set('feature-456', { + featureId: 'feature-456', + projectPath: '/home/user/my-project', + isAutoMode: false, + }); + + const mockFeature: Partial = { + id: 'feature-456', + title: 'Implement user authentication', + description: 'Add login and signup functionality', + category: 'auth', + }; + + const getMock = vi.fn().mockResolvedValue(mockFeature); + mockFeatureLoaderGet(service, getMock); + + // Act + const result = await service.getRunningAgents(); + + // Assert + expect(result).toHaveLength(1); + expect(result[0]).toEqual({ + featureId: 'feature-456', + projectPath: '/home/user/my-project', + projectName: 'my-project', + isAutoMode: false, + title: 'Implement user authentication', + description: 'Add login and signup functionality', + }); + expect(getMock).toHaveBeenCalledWith('/home/user/my-project', 'feature-456'); + }); + + it('should handle multiple running agents', async () => { + // Arrange + const runningFeaturesMap = getRunningFeaturesMap(service); + runningFeaturesMap.set('feature-1', { + featureId: 'feature-1', + projectPath: '/project-a', + isAutoMode: true, + }); + runningFeaturesMap.set('feature-2', { + featureId: 'feature-2', + projectPath: '/project-b', + isAutoMode: false, + }); + + const getMock = vi + .fn() + .mockResolvedValueOnce({ + id: 'feature-1', + title: 'Feature One', + description: 'Description one', + }) + .mockResolvedValueOnce({ + id: 'feature-2', + title: 'Feature Two', + description: 'Description two', + }); + mockFeatureLoaderGet(service, getMock); + + // Act + const result = await service.getRunningAgents(); + + // Assert + expect(result).toHaveLength(2); + expect(getMock).toHaveBeenCalledTimes(2); + }); + + it('should silently handle errors when fetching feature data', async () => { + // Arrange + const runningFeaturesMap = getRunningFeaturesMap(service); + runningFeaturesMap.set('feature-error', { + featureId: 'feature-error', + projectPath: '/project-error', + isAutoMode: true, + }); + + const getMock = vi.fn().mockRejectedValue(new Error('Database connection failed')); + mockFeatureLoaderGet(service, getMock); + + // Act - should not throw + const result = await service.getRunningAgents(); + + // Assert + expect(result).toHaveLength(1); + expect(result[0]).toEqual({ + featureId: 'feature-error', + projectPath: '/project-error', + projectName: 'project-error', + isAutoMode: true, + title: undefined, + description: undefined, + }); + }); + + it('should handle feature with title but no description', async () => { + // Arrange + const runningFeaturesMap = getRunningFeaturesMap(service); + runningFeaturesMap.set('feature-title-only', { + featureId: 'feature-title-only', + projectPath: '/project', + isAutoMode: false, + }); + + const getMock = vi.fn().mockResolvedValue({ + id: 'feature-title-only', + title: 'Only Title', + // description is undefined + }); + mockFeatureLoaderGet(service, getMock); + + // Act + const result = await service.getRunningAgents(); + + // Assert + expect(result[0].title).toBe('Only Title'); + expect(result[0].description).toBeUndefined(); + }); + + it('should handle feature with description but no title', async () => { + // Arrange + const runningFeaturesMap = getRunningFeaturesMap(service); + runningFeaturesMap.set('feature-desc-only', { + featureId: 'feature-desc-only', + projectPath: '/project', + isAutoMode: false, + }); + + const getMock = vi.fn().mockResolvedValue({ + id: 'feature-desc-only', + description: 'Only description, no title', + // title is undefined + }); + mockFeatureLoaderGet(service, getMock); + + // Act + const result = await service.getRunningAgents(); + + // Assert + expect(result[0].title).toBeUndefined(); + expect(result[0].description).toBe('Only description, no title'); + }); + + it('should extract projectName from nested paths correctly', async () => { + // Arrange + const runningFeaturesMap = getRunningFeaturesMap(service); + runningFeaturesMap.set('feature-nested', { + featureId: 'feature-nested', + projectPath: '/home/user/workspace/projects/my-awesome-project', + isAutoMode: true, + }); + + const getMock = vi.fn().mockResolvedValue(null); + mockFeatureLoaderGet(service, getMock); + + // Act + const result = await service.getRunningAgents(); + + // Assert + expect(result[0].projectName).toBe('my-awesome-project'); + }); + + it('should fetch feature data in parallel for multiple agents', async () => { + // Arrange: Add multiple running features + const runningFeaturesMap = getRunningFeaturesMap(service); + for (let i = 1; i <= 5; i++) { + runningFeaturesMap.set(`feature-${i}`, { + featureId: `feature-${i}`, + projectPath: `/project-${i}`, + isAutoMode: i % 2 === 0, + }); + } + + // Track call order + const callOrder: string[] = []; + const getMock = vi.fn().mockImplementation(async (projectPath: string, featureId: string) => { + callOrder.push(featureId); + // Simulate async delay to verify parallel execution + await new Promise((resolve) => setTimeout(resolve, 10)); + return { id: featureId, title: `Title for ${featureId}` }; + }); + mockFeatureLoaderGet(service, getMock); + + // Act + const startTime = Date.now(); + const result = await service.getRunningAgents(); + const duration = Date.now() - startTime; + + // Assert + expect(result).toHaveLength(5); + expect(getMock).toHaveBeenCalledTimes(5); + // If executed in parallel, total time should be ~10ms (one batch) + // If sequential, it would be ~50ms (5 * 10ms) + // Allow some buffer for execution overhead + expect(duration).toBeLessThan(40); + }); + }); }); diff --git a/apps/ui/src/components/views/running-agents-view.tsx b/apps/ui/src/components/views/running-agents-view.tsx index 302ae777..804b5a19 100644 --- a/apps/ui/src/components/views/running-agents-view.tsx +++ b/apps/ui/src/components/views/running-agents-view.tsx @@ -1,15 +1,17 @@ import { useState, useEffect, useCallback } from 'react'; -import { Bot, Folder, Loader2, RefreshCw, Square, Activity } from 'lucide-react'; +import { Bot, Folder, Loader2, RefreshCw, Square, Activity, FileText } from 'lucide-react'; import { getElectronAPI, RunningAgent } from '@/lib/electron'; import { useAppStore } from '@/store/app-store'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; import { useNavigate } from '@tanstack/react-router'; +import { AgentOutputModal } from './board-view/dialogs/agent-output-modal'; export function RunningAgentsView() { const [runningAgents, setRunningAgents] = useState([]); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); + const [selectedAgent, setSelectedAgent] = useState(null); const { setCurrentProject, projects } = useAppStore(); const navigate = useNavigate(); @@ -94,6 +96,15 @@ export function RunningAgentsView() { [projects, setCurrentProject, navigate] ); + const handleViewLogs = useCallback((agent: RunningAgent) => { + // Set the current project context for the modal + const project = projects.find((p) => p.path === agent.projectPath); + if (project) { + (window as any).__currentProject = project; + } + setSelectedAgent(agent); + }, [projects]); + if (loading) { return (
@@ -156,15 +167,22 @@ export function RunningAgentsView() {
{/* Agent info */} -
+
- {agent.featureId} + + {agent.title || agent.featureId} + {agent.isAutoMode && ( AUTO )}
+ {agent.description && ( +

+ {agent.description} +

+ )}
)} + + {/* Agent Output Modal */} + {selectedAgent && ( + setSelectedAgent(null)} + featureDescription={selectedAgent.description || selectedAgent.title || selectedAgent.featureId} + featureId={selectedAgent.featureId} + featureStatus="running" + /> + )}
); } diff --git a/apps/ui/src/lib/electron.ts b/apps/ui/src/lib/electron.ts index bafa5cf3..82337f97 100644 --- a/apps/ui/src/lib/electron.ts +++ b/apps/ui/src/lib/electron.ts @@ -106,6 +106,8 @@ export interface RunningAgent { projectPath: string; projectName: string; isAutoMode: boolean; + title?: string; + description?: string; } export interface RunningAgentsResult { @@ -2687,6 +2689,8 @@ function createMockRunningAgentsAPI(): RunningAgentsAPI { projectPath: '/mock/project', projectName: 'Mock Project', isAutoMode: mockAutoModeRunning, + title: `Mock Feature Title for ${featureId}`, + description: 'This is a mock feature description for testing purposes.', })); return { success: true, From 0317dadcaf6a2b80bc2ab74c3bd74f046db43334 Mon Sep 17 00:00:00 2001 From: Kacper Date: Mon, 29 Dec 2025 16:03:27 +0100 Subject: [PATCH 2/4] feat: address pr comments --- .../tests/unit/routes/running-agents.test.ts | 1 - .../board-view/dialogs/agent-output-modal.tsx | 18 +++++++++++------- .../components/views/running-agents-view.tsx | 8 ++------ 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/apps/server/tests/unit/routes/running-agents.test.ts b/apps/server/tests/unit/routes/running-agents.test.ts index 6071567f..59279668 100644 --- a/apps/server/tests/unit/routes/running-agents.test.ts +++ b/apps/server/tests/unit/routes/running-agents.test.ts @@ -14,7 +14,6 @@ describe('running-agents routes', () => { mockAutoModeService = { getRunningAgents: vi.fn(), - getStatus: vi.fn(), }; const context = createMockExpressContext(); diff --git a/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx b/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx index 50a60291..9a1ebb75 100644 --- a/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx +++ b/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx @@ -23,6 +23,8 @@ interface AgentOutputModalProps { featureStatus?: string; /** Called when a number key (0-9) is pressed while the modal is open */ onNumberKeyPress?: (key: string) => void; + /** Project path - if not provided, falls back to window.__currentProject for backward compatibility */ + projectPath?: string; } type ViewMode = 'parsed' | 'raw' | 'changes'; @@ -34,6 +36,7 @@ export function AgentOutputModal({ featureId, featureStatus, onNumberKeyPress, + projectPath: projectPathProp, }: AgentOutputModalProps) { const [output, setOutput] = useState(''); const [isLoading, setIsLoading] = useState(true); @@ -62,19 +65,20 @@ export function AgentOutputModal({ setIsLoading(true); try { - // Get current project path from store (we'll need to pass this) - const currentProject = (window as any).__currentProject; - if (!currentProject?.path) { + // Use projectPath prop if provided, otherwise fall back to window.__currentProject for backward compatibility + const resolvedProjectPath = + projectPathProp || (window as any).__currentProject?.path; + if (!resolvedProjectPath) { setIsLoading(false); return; } - projectPathRef.current = currentProject.path; - setProjectPath(currentProject.path); + projectPathRef.current = resolvedProjectPath; + setProjectPath(resolvedProjectPath); // Use features API to get agent output if (api.features) { - const result = await api.features.getAgentOutput(currentProject.path, featureId); + const result = await api.features.getAgentOutput(resolvedProjectPath, featureId); if (result.success) { setOutput(result.content || ''); @@ -93,7 +97,7 @@ export function AgentOutputModal({ }; loadOutput(); - }, [open, featureId]); + }, [open, featureId, projectPathProp]); // Listen to auto mode events and update output useEffect(() => { diff --git a/apps/ui/src/components/views/running-agents-view.tsx b/apps/ui/src/components/views/running-agents-view.tsx index 804b5a19..53c621da 100644 --- a/apps/ui/src/components/views/running-agents-view.tsx +++ b/apps/ui/src/components/views/running-agents-view.tsx @@ -97,13 +97,8 @@ export function RunningAgentsView() { ); const handleViewLogs = useCallback((agent: RunningAgent) => { - // Set the current project context for the modal - const project = projects.find((p) => p.path === agent.projectPath); - if (project) { - (window as any).__currentProject = project; - } setSelectedAgent(agent); - }, [projects]); + }, []); if (loading) { return ( @@ -232,6 +227,7 @@ export function RunningAgentsView() { setSelectedAgent(null)} + projectPath={selectedAgent.projectPath} featureDescription={selectedAgent.description || selectedAgent.title || selectedAgent.featureId} featureId={selectedAgent.featureId} featureStatus="running" From 67a6c10edc30b369d56bcd7cd99fe4e72961c28c Mon Sep 17 00:00:00 2001 From: Shirone Date: Mon, 29 Dec 2025 16:10:33 +0100 Subject: [PATCH 3/4] refactor: improve code readability in RunningAgentsView component - Reformatted JSX for better clarity and consistency. - Enhanced the layout of the feature description prop for improved maintainability. --- apps/ui/src/components/views/running-agents-view.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/ui/src/components/views/running-agents-view.tsx b/apps/ui/src/components/views/running-agents-view.tsx index 53c621da..fb1ded96 100644 --- a/apps/ui/src/components/views/running-agents-view.tsx +++ b/apps/ui/src/components/views/running-agents-view.tsx @@ -174,7 +174,10 @@ export function RunningAgentsView() { )} {agent.description && ( -

+

{agent.description}

)} @@ -228,7 +231,9 @@ export function RunningAgentsView() { open={true} onClose={() => setSelectedAgent(null)} projectPath={selectedAgent.projectPath} - featureDescription={selectedAgent.description || selectedAgent.title || selectedAgent.featureId} + featureDescription={ + selectedAgent.description || selectedAgent.title || selectedAgent.featureId + } featureId={selectedAgent.featureId} featureStatus="running" /> From 7016985bf2c634710b034cded87fe0efba6d52d5 Mon Sep 17 00:00:00 2001 From: Shirone Date: Mon, 29 Dec 2025 16:16:24 +0100 Subject: [PATCH 4/4] chore: format --- .../components/views/board-view/dialogs/agent-output-modal.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx b/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx index 9a1ebb75..96bd158c 100644 --- a/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx +++ b/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx @@ -66,8 +66,7 @@ export function AgentOutputModal({ try { // Use projectPath prop if provided, otherwise fall back to window.__currentProject for backward compatibility - const resolvedProjectPath = - projectPathProp || (window as any).__currentProject?.path; + const resolvedProjectPath = projectPathProp || (window as any).__currentProject?.path; if (!resolvedProjectPath) { setIsLoading(false); return;