diff --git a/apps/x/apps/main/src/ipc.ts b/apps/x/apps/main/src/ipc.ts index 607dc213..6c60ea63 100644 --- a/apps/x/apps/main/src/ipc.ts +++ b/apps/x/apps/main/src/ipc.ts @@ -1646,6 +1646,9 @@ export function setupIpcHandlers() { const preview = appInstallPreviews.get(args.name) ?? await appsInstaller.previewInstall(record); const result = await appsInstaller.installFromRegistry(record, preview); appInstallPreviews.delete(args.name); + // Materialize bundled agents NOW, not on the next apps:list poll — the + // renderer's post-install enable dialog patches these tasks immediately. + if (result.app) await appsAgents.syncAppAgents(result.app); capture('app_installed', { name: args.name }); return result; }, @@ -1654,6 +1657,7 @@ export function setupIpcHandlers() { return appsInstaller.previewUrlInstall(args.url); } const result = await appsInstaller.confirmUrlInstall(args.url); + if (result.app) await appsAgents.syncAppAgents(result.app); capture('app_installed', { name: result.app.manifest?.name ?? result.app.folder }); return result; }, diff --git a/apps/x/apps/renderer/src/components/apps/apps-view.tsx b/apps/x/apps/renderer/src/components/apps/apps-view.tsx index 44db99fa..9fdb89de 100644 --- a/apps/x/apps/renderer/src/components/apps/apps-view.tsx +++ b/apps/x/apps/renderer/src/components/apps/apps-view.tsx @@ -186,6 +186,11 @@ export function AppsView({ initialAppFolder, initialVersion, onNewApp }: { const r = await window.ipc.invoke('apps:list', {}) if (cancelled) return setApps(r.apps) + // Drop a selection whose app no longer exists (uninstalled while + // open). Left stale, a later reinstall makes this view yank the user + // into the app frame mid-flow — e.g. while they're in the catalog's + // post-install agent dialog. + setSelectedFolder((cur) => (cur && !r.apps.some((a) => a.folder === cur) ? null : cur)) setServerError(r.serverRunning ? null : (r.serverError ?? 'Apps server is not running.')) } catch (e) { if (!cancelled) setServerError(e instanceof Error ? e.message : String(e))