@@ -616,13 +616,26 @@ function readProcessManagerLogs( siteId: string ): { stdout?: string[]; stderr?:
616616export async function getSiteDetails ( _event : IpcMainInvokeEvent ) : Promise < SiteDetails [ ] > {
617617 const sites = SiteServer . getAllDetails ( ) ;
618618 const userData = await loadUserData ( ) ;
619- for ( const site of sites ) {
620- const appdataSite = userData . siteMetadata [ site . id ] ;
621- if ( appdataSite ) {
619+ await Promise . all (
620+ sites . map ( async ( site ) => {
621+ const appdataSite = userData . siteMetadata [ site . id ] ;
622+ if ( ! appdataSite ) {
623+ return ;
624+ }
622625 site . sortOrder = appdataSite . sortOrder ;
623626 site . themeDetails = appdataSite . themeDetails ;
624- }
625- }
627+ site . siteIconPath = appdataSite . siteIconPath ;
628+
629+ // Read the icon file from disk and hand the renderer a data URL.
630+ // Keeping the base64 out of the persisted appdata avoids bloating
631+ // app.json with image bytes.
632+ if ( appdataSite . siteIconPath ) {
633+ site . siteIcon = await getImageData ( appdataSite . siteIconPath ) ;
634+ } else if ( appdataSite . siteIconPath === null ) {
635+ site . siteIcon = null ;
636+ }
637+ } )
638+ ) ;
626639
627640 return sites ;
628641}
@@ -694,6 +707,7 @@ export async function createSite(
694707 // If the site is running after creation, fetch theme details and update thumbnail
695708 if ( server . details . running ) {
696709 void loadThemeDetails ( event , server . details . id ) ;
710+ void loadSiteIcon ( event , server . details . id ) ;
697711 }
698712
699713 return server . details ;
@@ -878,6 +892,7 @@ export async function startServer( event: IpcMainInvokeEvent, id: string ): Prom
878892
879893 if ( server . details . running ) {
880894 void loadThemeDetails ( event , id ) ;
895+ void loadSiteIcon ( event , id ) ;
881896 }
882897
883898 // Keep managed instruction files (STUDIO.md, CLAUDE.md) up-to-date
@@ -1264,6 +1279,29 @@ export async function loadThemeDetails(
12641279 return themeDetails ;
12651280}
12661281
1282+ // Mirror of loadThemeDetails for the Site Icon: fetch from the running
1283+ // site's mu-plugin command and persist the resolved path so the renderer
1284+ // can read it back from appdata via getSiteDetails.
1285+ export async function loadSiteIcon (
1286+ _event : IpcMainInvokeEvent ,
1287+ id : string
1288+ ) : Promise < StartedSiteDetails [ 'siteIconPath' ] > {
1289+ const server = SiteServer . get ( id ) ;
1290+ if ( ! server ) {
1291+ throw new Error ( 'Site not found.' ) ;
1292+ }
1293+
1294+ const oldIconPath = server . details . siteIconPath ;
1295+ const iconPath = await server . getSiteIcon ( ) ;
1296+ const hasIconChanged = iconPath !== oldIconPath ;
1297+
1298+ if ( hasIconChanged ) {
1299+ await server . persistSiteIcon ( ) ;
1300+ }
1301+
1302+ return iconPath ;
1303+ }
1304+
12671305export async function getOnboardingData ( _event : IpcMainInvokeEvent ) : Promise < boolean > {
12681306 const userData = await loadUserData ( ) ;
12691307 const { onboardingCompleted = false } = userData ;
0 commit comments