@@ -28,19 +28,74 @@ const AgentPanel = dynamic(
2828
2929const PANEL_SPRING = { type : 'spring' as const , stiffness : 500 , damping : 35 }
3030
31+ function NoCodebasePane ( {
32+ isDesktop,
33+ onOpenFolder,
34+ } : {
35+ isDesktop : boolean
36+ onOpenFolder : ( ) => void
37+ } ) {
38+ return (
39+ < div className = "flex flex-1 flex-col items-center justify-center gap-6 bg-[var(--bg)] px-6 select-none" >
40+ < div className = "flex flex-col items-center gap-4 max-w-[320px]" >
41+ < div className = "w-16 h-16 rounded-2xl bg-[color-mix(in_srgb,var(--brand)_8%,transparent)] border border-[color-mix(in_srgb,var(--brand)_20%,var(--border))] flex items-center justify-center" >
42+ < Icon
43+ icon = "lucide:folder-search"
44+ width = { 28 }
45+ height = { 28 }
46+ className = "text-[var(--brand)]"
47+ />
48+ </ div >
49+ < div className = "text-center" >
50+ < p className = "text-[15px] font-semibold text-[var(--text-primary)] mb-1.5" >
51+ No codebase selected
52+ </ p >
53+ < p className = "text-[13px] text-[var(--text-tertiary)] leading-relaxed" >
54+ Open a folder{ ! isDesktop ? ' or connect a GitHub repo' : '' } to start editing, browsing files, and using the agent.
55+ </ p >
56+ </ div >
57+ < div className = "flex flex-col items-center gap-2 w-full mt-1" >
58+ < button
59+ onClick = { onOpenFolder }
60+ className = "flex items-center justify-center gap-2 w-full max-w-[220px] px-4 py-2.5 rounded-xl text-[13px] font-medium bg-[var(--brand)] text-[var(--brand-contrast)] hover:brightness-110 transition-all cursor-pointer shadow-[0_2px_8px_color-mix(in_srgb,var(--brand)_25%,transparent)]"
61+ >
62+ < Icon icon = "lucide:folder-open" width = { 15 } height = { 15 } />
63+ Open Folder
64+ </ button >
65+ < div className = "flex items-center gap-3 text-[11px] text-[var(--text-disabled)] mt-1" >
66+ < span className = "flex items-center gap-1" >
67+ < Icon icon = "lucide:command" width = { 10 } height = { 10 } />
68+ < Icon icon = "lucide:letter-text" width = { 10 } height = { 10 } className = "opacity-60" />
69+ P for commands
70+ </ span >
71+ </ div >
72+ </ div >
73+ </ div >
74+ </ div >
75+ )
76+ }
77+
3178function MainEditorPane ( {
3279 hasFiles,
80+ hasCodebase,
3381 isDesktop,
3482 isNarrow,
3583 branchName,
3684 onBrowse,
85+ onOpenFolder,
3786} : {
3887 hasFiles : boolean
88+ hasCodebase : boolean
3989 isDesktop : boolean
4090 isNarrow : boolean
4191 branchName : string | null
4292 onBrowse : ( ) => void
93+ onOpenFolder : ( ) => void
4394} ) {
95+ if ( ! hasCodebase && ! hasFiles ) {
96+ return < NoCodebasePane isDesktop = { isDesktop } onOpenFolder = { onOpenFolder } />
97+ }
98+
4499 return hasFiles ? (
45100 < div className = "flex flex-1 min-h-0 min-w-0 flex-col bg-[var(--bg)]" >
46101 < EditorTabs />
@@ -118,6 +173,7 @@ export function EditorView() {
118173 const chatPanelResize = usePanelResize ( 'chat' )
119174
120175 const hasFiles = files . length > 0 || ! ! activeFile
176+ const hasCodebase = ! ! repo || ! ! local . rootPath
121177 const branchName = repo ?. branch ?? local . gitInfo ?. branch ?? null
122178
123179 useEffect ( ( ) => {
@@ -150,12 +206,24 @@ export function EditorView() {
150206 className = "shrink-0 overflow-hidden border-r border-[var(--border)] bg-[var(--sidebar-bg)] flex flex-col"
151207 >
152208 < div className = "flex items-center justify-between h-10 px-3 border-b border-[var(--border)] shrink-0" >
153- < span className = "text-[11px] font-bold uppercase tracking-wider text-[var(--text-disabled)]" >
154- Explorer
155- </ span >
209+ < button
210+ onClick = { ( ) => local . openFolder ( ) }
211+ className = "flex items-center gap-1.5 min-w-0 rounded-md px-1 py-0.5 -mx-1 hover:bg-[color-mix(in_srgb,var(--text-primary)_8%,transparent)] transition-colors cursor-pointer group"
212+ title = { local . rootPath ?? 'Open folder' }
213+ >
214+ < Icon
215+ icon = "lucide:folder-open"
216+ width = { 13 }
217+ height = { 13 }
218+ className = "text-[var(--brand)] shrink-0 group-hover:scale-110 transition-transform"
219+ />
220+ < span className = "text-[11px] font-bold text-[var(--text-disabled)] group-hover:text-[var(--text-secondary)] truncate uppercase tracking-wider transition-colors" >
221+ { local . rootPath ?. split ( '/' ) . pop ( ) || ( repo ? repo . repo . split ( '/' ) . pop ( ) : 'Explorer' ) }
222+ </ span >
223+ </ button >
156224 < button
157225 onClick = { ( ) => layout . hide ( 'tree' ) }
158- className = "p-1.5 rounded-lg hover:bg-[color-mix(in_srgb,var(--text-primary)_8%,transparent)] text-[var(--text-disabled)] hover:text-[var(--text-tertiary)] cursor-pointer"
226+ className = "p-1.5 rounded-lg hover:bg-[color-mix(in_srgb,var(--text-primary)_8%,transparent)] text-[var(--text-disabled)] hover:text-[var(--text-tertiary)] cursor-pointer shrink-0 "
159227 title = "Hide (⌘B)"
160228 >
161229 < Icon icon = "lucide:panel-left-close" width = { 15 } height = { 15 } />
@@ -199,18 +267,20 @@ export function EditorView() {
199267 </ button >
200268 ) }
201269
202- { /* Mobile: show file explorer full-width when no files are open */ }
203- { isMobile && ! hasFiles ? (
270+ { /* Mobile: show file explorer when no files are open (but codebase is selected) */ }
271+ { isMobile && ! hasFiles && hasCodebase ? (
204272 < div className = "flex-1 overflow-y-auto" >
205273 < FileExplorer />
206274 </ div >
207275 ) : (
208276 < MainEditorPane
209277 hasFiles = { hasFiles }
278+ hasCodebase = { hasCodebase }
210279 isDesktop = { isDesktop }
211280 isNarrow = { isNarrow }
212281 branchName = { branchName }
213282 onBrowse = { ( ) => layout . show ( 'tree' ) }
283+ onOpenFolder = { ( ) => local . openFolder ( ) }
214284 />
215285 ) }
216286 </ div >
@@ -272,12 +342,24 @@ export function EditorView() {
272342 className = "absolute inset-y-0 left-0 z-50 w-[min(92vw,360px)] bg-[var(--sidebar-bg)] border-r border-[var(--border)] flex flex-col"
273343 >
274344 < div className = "flex items-center justify-between h-10 px-3 border-b border-[var(--border)] shrink-0 bg-[var(--bg-elevated)]" >
275- < span className = "text-[11px] font-bold uppercase tracking-wider text-[var(--text-disabled)]" >
276- Explorer
277- </ span >
345+ < button
346+ onClick = { ( ) => local . openFolder ( ) }
347+ className = "flex items-center gap-1.5 min-w-0 rounded-md px-1 py-0.5 -mx-1 hover:bg-[var(--bg-subtle)] transition-colors cursor-pointer group"
348+ title = { local . rootPath ?? 'Open folder' }
349+ >
350+ < Icon
351+ icon = "lucide:folder-open"
352+ width = { 13 }
353+ height = { 13 }
354+ className = "text-[var(--brand)] shrink-0 group-hover:scale-110 transition-transform"
355+ />
356+ < span className = "text-[11px] font-bold text-[var(--text-disabled)] group-hover:text-[var(--text-secondary)] truncate uppercase tracking-wider transition-colors" >
357+ { local . rootPath ?. split ( '/' ) . pop ( ) || ( repo ? repo . repo . split ( '/' ) . pop ( ) : 'Explorer' ) }
358+ </ span >
359+ </ button >
278360 < button
279361 onClick = { ( ) => layout . hide ( 'tree' ) }
280- className = "p-2 rounded-lg hover:bg-[var(--bg-subtle)] text-[var(--text-tertiary)] cursor-pointer"
362+ className = "p-2 rounded-lg hover:bg-[var(--bg-subtle)] text-[var(--text-tertiary)] cursor-pointer shrink-0 "
281363 >
282364 < Icon icon = "lucide:x" width = { 14 } height = { 14 } />
283365 </ button >
0 commit comments