@@ -17,17 +17,12 @@ import { buildSortedWorkspacesByProject } from "./utils/ui/workspaceFiltering";
1717import { useResumeManager } from "./hooks/useResumeManager" ;
1818import { useUnreadTracking } from "./hooks/useUnreadTracking" ;
1919import { useWorkspaceStoreRaw , useWorkspaceRecency } from "./stores/WorkspaceStore" ;
20- import { ChatInput } from "./components/ChatInput/index" ;
21- import type { ChatInputAPI } from "./components/ChatInput/types" ;
2220
2321import { useStableReference , compareMaps } from "./hooks/useStableReference" ;
2422import { CommandRegistryProvider , useCommandRegistry } from "./contexts/CommandRegistryContext" ;
2523import { useOpenTerminal } from "./hooks/useOpenTerminal" ;
2624import type { CommandAction } from "./contexts/CommandRegistryContext" ;
27- import { ModeProvider } from "./contexts/ModeContext" ;
28- import { ProviderOptionsProvider } from "./contexts/ProviderOptionsContext" ;
2925import { ThemeProvider , useTheme , type ThemeMode } from "./contexts/ThemeContext" ;
30- import { ThinkingProvider } from "./contexts/ThinkingContext" ;
3126import { CommandPalette } from "./components/CommandPalette" ;
3227import { buildCoreSources , type BuildSourcesParams } from "./utils/commands/sources" ;
3328
@@ -48,12 +43,12 @@ import { getRuntimeTypeForTelemetry } from "@/common/telemetry";
4843import { useStartWorkspaceCreation , getFirstProjectPath } from "./hooks/useStartWorkspaceCreation" ;
4944import { useAPI } from "@/browser/contexts/API" ;
5045import { AuthTokenModal } from "@/browser/components/AuthTokenModal" ;
46+ import { ProjectPage } from "@/browser/components/ProjectPage" ;
5147
5248import { SettingsProvider , useSettings } from "./contexts/SettingsContext" ;
5349import { SettingsModal } from "./components/Settings/SettingsModal" ;
5450import { SplashScreenProvider } from "./components/splashScreens/SplashScreenProvider" ;
5551import { TutorialProvider } from "./contexts/TutorialContext" ;
56- import { ConnectionStatusIndicator } from "./components/ConnectionStatusIndicator" ;
5752import { TooltipProvider } from "./components/ui/tooltip" ;
5853import { useFeatureFlags } from "./contexts/FeatureFlagsContext" ;
5954import { FeatureFlagsProvider } from "./contexts/FeatureFlagsContext" ;
@@ -102,25 +97,16 @@ function AppInner() {
10297 const isMobile = typeof window !== "undefined" && window . innerWidth <= 768 ;
10398 const [ sidebarCollapsed , setSidebarCollapsed ] = usePersistedState ( "sidebarCollapsed" , isMobile ) ;
10499 const defaultProjectPath = getFirstProjectPath ( projects ) ;
105- const creationChatInputRef = useRef < ChatInputAPI | null > ( null ) ;
106100 const creationProjectPath = ! selectedWorkspace
107101 ? ( pendingNewWorkspaceProject ?? ( projects . size === 1 ? defaultProjectPath : null ) )
108102 : null ;
109- const handleCreationChatReady = useCallback ( ( api : ChatInputAPI ) => {
110- creationChatInputRef . current = api ;
111- api . focus ( ) ;
112- } , [ ] ) ;
113103
114104 const startWorkspaceCreation = useStartWorkspaceCreation ( {
115105 projects,
116106 beginWorkspaceCreation,
117107 } ) ;
118108
119- useEffect ( ( ) => {
120- if ( creationProjectPath ) {
121- creationChatInputRef . current ?. focus ( ) ;
122- }
123- } , [ creationProjectPath ] ) ;
109+ // ProjectPage handles its own focus when mounted
124110
125111 const handleToggleSidebar = useCallback ( ( ) => {
126112 setSidebarCollapsed ( ( prev ) => ! prev ) ;
@@ -502,12 +488,6 @@ function AppInner() {
502488 } else if ( matchesKeybind ( e , KEYBINDS . OPEN_SETTINGS ) ) {
503489 e . preventDefault ( ) ;
504490 openSettings ( ) ;
505- } else if ( matchesKeybind ( e , KEYBINDS . FOCUS_CHAT ) ) {
506- // Focus creation chat when on new chat page (no workspace selected)
507- if ( creationProjectPath && creationChatInputRef . current ) {
508- e . preventDefault ( ) ;
509- creationChatInputRef . current . focus ( ) ;
510- }
511491 }
512492 } ;
513493
@@ -661,51 +641,40 @@ function AppInner() {
661641 const projectName =
662642 projectPath . split ( "/" ) . pop ( ) ?? projectPath . split ( "\\" ) . pop ( ) ?? "Project" ;
663643 return (
664- < ModeProvider projectPath = { projectPath } >
665- < ProviderOptionsProvider >
666- < ThinkingProvider projectPath = { projectPath } >
667- < ConnectionStatusIndicator />
668- < ChatInput
669- variant = "creation"
670- projectPath = { projectPath }
671- projectName = { projectName }
672- onProviderConfig = { handleProviderConfig }
673- onReady = { handleCreationChatReady }
674- onWorkspaceCreated = { ( metadata ) => {
675- // IMPORTANT: Add workspace to store FIRST (synchronous) to ensure
676- // the store knows about it before React processes the state updates.
677- // This prevents race conditions where the UI tries to access the
678- // workspace before the store has created its aggregator.
679- workspaceStore . addWorkspace ( metadata ) ;
680-
681- // Add to workspace metadata map (triggers React state update)
682- setWorkspaceMetadata ( ( prev ) =>
683- new Map ( prev ) . set ( metadata . id , metadata )
684- ) ;
685-
686- // Only switch to new workspace if user hasn't selected another one
687- // during the creation process (selectedWorkspace was null when creation started)
688- setSelectedWorkspace ( ( current ) => {
689- if ( current !== null ) {
690- // User has already selected another workspace - don't override
691- return current ;
692- }
693- return toWorkspaceSelection ( metadata ) ;
694- } ) ;
695-
696- // Track telemetry
697- telemetry . workspaceCreated (
698- metadata . id ,
699- getRuntimeTypeForTelemetry ( metadata . runtimeConfig )
700- ) ;
701-
702- // Clear pending state
703- clearPendingWorkspaceCreation ( ) ;
704- } }
705- />
706- </ ThinkingProvider >
707- </ ProviderOptionsProvider >
708- </ ModeProvider >
644+ < ProjectPage
645+ projectPath = { projectPath }
646+ projectName = { projectName }
647+ onProviderConfig = { handleProviderConfig }
648+ onWorkspaceCreated = { ( metadata ) => {
649+ // IMPORTANT: Add workspace to store FIRST (synchronous) to ensure
650+ // the store knows about it before React processes the state updates.
651+ // This prevents race conditions where the UI tries to access the
652+ // workspace before the store has created its aggregator.
653+ workspaceStore . addWorkspace ( metadata ) ;
654+
655+ // Add to workspace metadata map (triggers React state update)
656+ setWorkspaceMetadata ( ( prev ) => new Map ( prev ) . set ( metadata . id , metadata ) ) ;
657+
658+ // Only switch to new workspace if user hasn't selected another one
659+ // during the creation process (selectedWorkspace was null when creation started)
660+ setSelectedWorkspace ( ( current ) => {
661+ if ( current !== null ) {
662+ // User has already selected another workspace - don't override
663+ return current ;
664+ }
665+ return toWorkspaceSelection ( metadata ) ;
666+ } ) ;
667+
668+ // Track telemetry
669+ telemetry . workspaceCreated (
670+ metadata . id ,
671+ getRuntimeTypeForTelemetry ( metadata . runtimeConfig )
672+ ) ;
673+
674+ // Clear pending state
675+ clearPendingWorkspaceCreation ( ) ;
676+ } }
677+ />
709678 ) ;
710679 } ) ( )
711680 ) : (
0 commit comments