diff --git a/packages/desktop/scripts/verify.mjs b/packages/desktop/scripts/verify.mjs index 84a1158e..7fe10526 100644 --- a/packages/desktop/scripts/verify.mjs +++ b/packages/desktop/scripts/verify.mjs @@ -47,25 +47,6 @@ console.log('Screenshot (Agent mode):', shot1) const bodyText = await page.evaluate(() => document.body.innerText) console.log('Page text:', bodyText.slice(0, 200)) -// Click the mode switch button -const switchResult = await page.evaluate(() => { - const btns = [...document.querySelectorAll('button')] - const btn = btns.find(b => b.textContent?.includes('IDE')) - if (!btn) return 'NOT_FOUND' - btn.click() - return 'CLICKED: ' + btn.textContent?.trim() -}) -console.log('Switch button:', switchResult) - -await new Promise(r => setTimeout(r, 500)) -const shot2 = path.join(SHOT_DIR, '02-ide-mode.png') -await page.screenshot({ path: shot2 }) -console.log('Screenshot (IDE mode):', shot2) - -// Verify mode switched -const bodyText2 = await page.evaluate(() => document.body.innerText) -console.log('Page text after switch:', bodyText2.slice(0, 200)) - // Test IPC ping const pingResult = await page.evaluate(() => { return window.electronAPI?.ping?.() diff --git a/packages/desktop/src/App.tsx b/packages/desktop/src/App.tsx index ee442651..cfcac6a0 100644 --- a/packages/desktop/src/App.tsx +++ b/packages/desktop/src/App.tsx @@ -1,14 +1,20 @@ import { useEffect } from 'react'; +import { useAgentCore } from './hooks/useAgent'; import { useUIStore } from './stores/ui.store'; import { useWorkspaceStore } from './stores/workspace.store'; -import AgentLayout from './layouts/AgentLayout'; -import IDELayout from './layouts/IDELayout'; +import ProjectStrip from './agent/ProjectStrip'; +import AgentSidebar from './agent/AgentSidebar'; +import AgentWorkspace from './agent/AgentWorkspace'; +import { AutomationPanel } from './agent/AutomationPanel'; +import GlobalSettingsPage from './settings/GlobalSettingsPage'; +import ProjectSettingsPage from './settings/ProjectSettingsPage'; import TitleBar from './TitleBar'; import ErrorBoundary from './shared/ErrorBoundary'; export default function App() { - const mode = useUIStore((s) => s.mode); + const { sendMessage, abort } = useAgentCore(); const theme = useUIStore((s) => s.theme); + const view = useUIStore((s) => s.view); const rootPath = useWorkspaceStore((s) => s.rootPath); // Sync workspace cwd to main process for git polling @@ -31,16 +37,29 @@ export default function App() { }; }, []); + let content; + if (view === 'global-settings') { + content = ; + } else if (view === 'project-settings') { + content = ; + } else if (view === 'automation') { + content = ; + } else { + content = ( +
+ + + +
+ ); + } + return (
- {/* Both layouts stay mounted; visibility toggled via display to preserve Monaco + PTY state */} -
- -
-
- +
+ {content}
diff --git a/packages/desktop/src/TitleBar.tsx b/packages/desktop/src/TitleBar.tsx index ae686c7a..6867e1ae 100644 --- a/packages/desktop/src/TitleBar.tsx +++ b/packages/desktop/src/TitleBar.tsx @@ -1,12 +1,5 @@ -import { useUIStore } from './stores/ui.store'; - -const isWindows = window.electronAPI?.platform === 'win32'; - export default function TitleBar() { - const mode = useUIStore((s) => s.mode); - const setMode = useUIStore((s) => s.setMode); - - if (!isWindows) return null; + if (window.electronAPI?.platform !== 'win32') return null; return (
Coding Code -
- - -
); } diff --git a/packages/desktop/src/layouts/AgentLayout.tsx b/packages/desktop/src/layouts/AgentLayout.tsx deleted file mode 100644 index 06d4910a..00000000 --- a/packages/desktop/src/layouts/AgentLayout.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { useAgentCore } from '../hooks/useAgent'; -import { useUIStore } from '../stores/ui.store'; -import ProjectStrip from '../agent/ProjectStrip'; -import AgentSidebar from '../agent/AgentSidebar'; -import AgentWorkspace from '../agent/AgentWorkspace'; -import { AutomationPanel } from '../agent/AutomationPanel'; -import GlobalSettingsPage from '../settings/GlobalSettingsPage'; -import ProjectSettingsPage from '../settings/ProjectSettingsPage'; - -export default function AgentLayout() { - const { sendMessage, abort } = useAgentCore(); - const view = useUIStore((s) => s.view); - - if (view === 'global-settings') { - return ; - } - - if (view === 'project-settings') { - return ; - } - - if (view === 'automation') { - return ; - } - - return ( -
- - - -
- ); -} diff --git a/packages/desktop/src/layouts/IDELayout.tsx b/packages/desktop/src/layouts/IDELayout.tsx deleted file mode 100644 index 0c6d4f4d..00000000 --- a/packages/desktop/src/layouts/IDELayout.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { useUIStore } from '../stores/ui.store'; - -export default function IDELayout() { - const setMode = useUIStore((s) => s.setMode); - - return ( -
-

IDE 模式

-

Phase 3 中实现完整 IDE 布局

- -
- ); -} diff --git a/packages/desktop/src/stores/ui.store.ts b/packages/desktop/src/stores/ui.store.ts index 4e4206c2..752da47c 100644 --- a/packages/desktop/src/stores/ui.store.ts +++ b/packages/desktop/src/stores/ui.store.ts @@ -4,43 +4,33 @@ import { immer } from 'zustand/middleware/immer'; import { createDebouncedStorage } from './storage'; interface UIState { - mode: 'agent' | 'ide'; view: 'agent' | 'global-settings' | 'project-settings' | 'automation'; sidebarCollapsed: boolean; sidebarWidth: number; rightPanelWidth: number; bottomPanelHeight: number; - ideSidebarView: 'explorer' | 'search' | 'git' | 'extensions'; theme: 'dark' | 'light' | 'paper'; } interface UIActions { - setMode: (mode: 'agent' | 'ide') => void; setView: (view: UIState['view']) => void; toggleSidebar: () => void; setSidebarWidth: (w: number) => void; setRightPanelWidth: (w: number) => void; setBottomPanelHeight: (h: number) => void; - setIdeSidebarView: (view: UIState['ideSidebarView']) => void; setTheme: (theme: UIState['theme']) => void; } export const useUIStore = create()( persist( immer((set) => ({ - mode: 'agent', view: 'agent', sidebarCollapsed: false, sidebarWidth: 220, rightPanelWidth: 320, bottomPanelHeight: 200, - ideSidebarView: 'explorer', theme: 'dark', - setMode: (mode) => - set((s) => { - s.mode = mode; - }), setView: (view) => set((s) => { s.view = view; @@ -61,10 +51,6 @@ export const useUIStore = create()( set((s) => { s.bottomPanelHeight = h; }), - setIdeSidebarView: (view) => - set((s) => { - s.ideSidebarView = view; - }), setTheme: (theme) => set((s) => { s.theme = theme; diff --git a/packages/desktop/test/app-agent-layout-inline.test.ts b/packages/desktop/test/app-agent-layout-inline.test.ts new file mode 100644 index 00000000..4101b70a --- /dev/null +++ b/packages/desktop/test/app-agent-layout-inline.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from 'vitest'; +import { existsSync, readFileSync } from 'fs'; +import { resolve } from 'path'; + +const srcRoot = resolve(__dirname, '..', 'src'); +const appSource = readFileSync(resolve(srcRoot, 'App.tsx'), 'utf8'); + +describe('App agent layout', () => { + it('owns the agent view routing after removing AgentLayout', () => { + expect(existsSync(resolve(srcRoot, 'layouts', 'AgentLayout.tsx'))).toBe(false); + expect(appSource).not.toContain('AgentLayout'); + expect(appSource).toContain('useAgentCore()'); + expect(appSource).toContain(''); + expect(appSource).toContain(''); + expect(appSource).toContain(''); + }); +});