@@ -3,8 +3,7 @@ import { batch, createEffect, createMemo, onCleanup, onMount, type Accessor } fr
33import { createSimpleContext } from "@opencode-ai/ui/context"
44import { makeEventListener } from "@solid-primitives/event-listener"
55import { useGlobalSync } from "./global-sync"
6- import { useGlobalSDK } from "./global-sdk"
7- import { useServer } from "./server"
6+ import { useOpenedProjects } from "./opened-projects"
87import { usePlatform } from "./platform"
98import { Project } from "@opencode-ai/sdk/v2"
109import { Persist , persisted , removePersisted } from "@/utils/persist"
@@ -135,9 +134,8 @@ const normalizeStoredSessionTabs = (key: string, tabs: SessionTabs) => {
135134export const { use : useLayout , provider : LayoutProvider } = createSimpleContext ( {
136135 name : "Layout" ,
137136 init : ( ) => {
138- const globalSdk = useGlobalSDK ( )
139137 const globalSync = useGlobalSync ( )
140- const server = useServer ( )
138+ const openedProjects = useOpenedProjects ( )
141139 const platform = usePlatform ( )
142140
143141 const isRecord = ( value : unknown ) : value is Record < string , unknown > =>
@@ -384,21 +382,26 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
384382 return available [ Math . floor ( Math . random ( ) * available . length ) ]
385383 }
386384
387- function enrich ( project : { worktree : string ; expanded : boolean } ) {
385+ function enrich ( project : { worktree : string ; expanded : boolean ; name ?: string ; icon ?: { color ?: string ; override ?: string } } ) {
388386 const [ childStore ] = globalSync . child ( project . worktree , { bootstrap : false } )
389387 const projectID = childStore . project
390- const metadata = projectID
388+ const dbProject = projectID
391389 ? globalSync . data . project . find ( ( x ) => x . id === projectID )
392390 : globalSync . data . project . find ( ( x ) => x . worktree === project . worktree )
393391
394- // Preserve local icon override from per-workspace localStorage cache (childStore.icon).
395- // Without this, different subdirectories of the same git repo would share the same
396- // icon from the database instead of using their individual overrides.
397- const base = { ...metadata , ...project }
398- if ( childStore . icon ) {
399- return { ...base , icon : { ...base . icon , override : childStore . icon } }
400- }
401- return base
392+ // Config data (name, icon.color, icon.override) is authoritative for display.
393+ // Database data supplements with id, sandboxes, icon.url (auto-discovered favicon).
394+ return {
395+ ...dbProject ,
396+ worktree : project . worktree ,
397+ expanded : project . expanded ,
398+ name : project . name ?? dbProject ?. name ,
399+ icon : {
400+ url : dbProject ?. icon ?. url ,
401+ color : project . icon ?. color ,
402+ override : project . icon ?. override ?? childStore . icon ,
403+ } ,
404+ } as LocalProject
402405 }
403406
404407 const roots = createMemo ( ( ) => {
@@ -435,27 +438,27 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
435438 }
436439
437440 createEffect ( ( ) => {
438- const projects = server . projects . list ( )
441+ const projects = openedProjects . list ( )
439442 const seen = new Set ( projects . map ( ( project ) => project . worktree ) )
440443
441444 batch ( ( ) => {
442445 for ( const project of projects ) {
443446 const root = rootFor ( project . worktree )
444447 if ( root === project . worktree ) continue
445448
446- server . projects . close ( project . worktree )
449+ openedProjects . close ( project . worktree )
447450
448451 if ( ! seen . has ( root ) ) {
449- server . projects . open ( root )
452+ openedProjects . open ( root )
450453 seen . add ( root )
451454 }
452455
453- if ( project . expanded ) server . projects . expand ( root )
456+ if ( project . expanded ) openedProjects . expand ( root )
454457 }
455458 } )
456459 } )
457460
458- const enriched = createMemo ( ( ) => server . projects . list ( ) . map ( enrich ) )
461+ const enriched = createMemo ( ( ) => openedProjects . list ( ) . map ( enrich ) )
459462 const list = createMemo ( ( ) => {
460463 const projects = enriched ( )
461464 return projects . map ( ( project ) => {
@@ -501,22 +504,13 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
501504 used . add ( color )
502505 setColors ( worktree , color )
503506 }
504- if ( ! project . id ) continue
505507
506508 const requested = colorRequested . get ( worktree )
507509 if ( requested === color ) continue
508510 colorRequested . set ( worktree , color )
509511
510- if ( project . id === "global" ) {
511- globalSync . project . meta ( worktree , { icon : { color } } )
512- continue
513- }
514-
515- void globalSdk . client . project
516- . update ( { projectID : project . id , directory : worktree , icon : { color } } )
517- . catch ( ( ) => {
518- if ( colorRequested . get ( worktree ) === color ) colorRequested . delete ( worktree )
519- } )
512+ // Write color to config so all clients stay in sync
513+ openedProjects . updateMeta ( worktree , { icon : { color } } )
520514 }
521515 } )
522516
@@ -529,7 +523,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
529523 sessionTimer = window . setTimeout ( ( ) => {
530524 sessionTimer = undefined
531525 void Promise . all (
532- server . projects . list ( ) . map ( ( project ) => {
526+ openedProjects . list ( ) . map ( ( project ) => {
533527 return globalSync . project . loadSessions ( project . worktree )
534528 } ) ,
535529 )
@@ -558,21 +552,23 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
558552 list,
559553 open ( directory : string ) {
560554 const root = rootFor ( directory )
561- if ( server . projects . list ( ) . find ( ( x ) => x . worktree === root ) ) return
555+ if ( openedProjects . list ( ) . find ( ( x ) => x . worktree === root ) ) return
556+ // Bootstrap with bootstrap: true to trigger project discovery on the backend
557+ globalSync . child ( root , { bootstrap : true } )
562558 void globalSync . project . loadSessions ( root )
563- server . projects . open ( root )
559+ openedProjects . open ( root )
564560 } ,
565561 close ( directory : string ) {
566- server . projects . close ( directory )
562+ openedProjects . close ( directory )
567563 } ,
568564 expand ( directory : string ) {
569- server . projects . expand ( directory )
565+ openedProjects . expand ( directory )
570566 } ,
571567 collapse ( directory : string ) {
572- server . projects . collapse ( directory )
568+ openedProjects . collapse ( directory )
573569 } ,
574570 move ( directory : string , toIndex : number ) {
575- server . projects . move ( directory , toIndex )
571+ openedProjects . move ( directory , toIndex )
576572 } ,
577573 } ,
578574 sidebar : {
0 commit comments