import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext, ReadonlyFooterDataProvider, SessionInfoChangedEvent, Theme, } from "@earendil-works/pi-coding-agent"; import type { TUI } from "@earendil-works/pi-tui"; import type { DashboardData } from "./discovery.js"; type DashboardLayout = typeof import("./layout.js"); type DashboardFooter = typeof import("./footer.js"); type DashboardDiscovery = typeof import("./discovery.js"); export default function startupDashboard(pi: ExtensionAPI) { let data: DashboardData = { contexts: [], skills: [], extensions: [], themes: [], }; let headerEnabled = true; let footerEnabled = true; let sessionTitle: string | undefined; let requestFooterRender: (() => void) | undefined; let layout: DashboardLayout | undefined; let footer: DashboardFooter | undefined; let discovery: DashboardDiscovery | undefined; async function loadDashboardModules(): Promise<{ layout: DashboardLayout; footer: DashboardFooter; discovery: DashboardDiscovery; }> { layout ??= await import("./layout.js"); footer ??= await import("./footer.js"); discovery ??= await import("./discovery.js"); return { layout, footer, discovery }; } const installHeader = (ctx: ExtensionContext): void => { if (!headerEnabled) { ctx.ui.setHeader(undefined); return; } const renderDashboard = layout?.renderDashboard; if (!renderDashboard) return; ctx.ui.setHeader((_tui: TUI, theme: Theme) => { return { render: (width: number) => renderDashboard(width, data, theme), invalidate() {}, }; }); }; const installFooter = (ctx: ExtensionContext): void => { if (!footerEnabled) { ctx.ui.setFooter(undefined); requestFooterRender = undefined; return; } const renderFooter = footer?.renderFooter; const createFooterSnapshot = footer?.createFooterSnapshot; if (!renderFooter || !createFooterSnapshot) return; ctx.ui.setFooter( (tui: TUI, theme: Theme, footerData: ReadonlyFooterDataProvider) => { const requestRender = () => tui.requestRender(); requestFooterRender = requestRender; const unsubscribeBranch = footerData.onBranchChange(requestRender); return { render: (width: number) => renderFooter( width, createFooterSnapshot( ctx, footerData.getGitBranch(), sessionTitle, footerData.getExtensionStatuses(), ), theme, ), invalidate() {}, dispose: () => { unsubscribeBranch(); if (requestFooterRender === requestRender) { requestFooterRender = undefined; } }, }; }, ); }; pi.on("session_start", async (_event: unknown, ctx: ExtensionContext) => { if (ctx.mode !== "tui") return; sessionTitle = pi.getSessionName(); const modules = await loadDashboardModules(); data = await modules.discovery.discoverDashboardData( ctx.cwd, ctx.isProjectTrusted(), ); installHeader(ctx); installFooter(ctx); }); const refreshFooter = (ctx: ExtensionContext): void => { if (ctx.mode !== "tui") return; requestFooterRender?.(); }; pi.on("model_select", (_event: unknown, ctx: ExtensionContext) => refreshFooter(ctx), ); pi.on("thinking_level_select", (_event: unknown, ctx: ExtensionContext) => refreshFooter(ctx), ); pi.on( "session_info_changed", (event: SessionInfoChangedEvent, ctx: ExtensionContext) => { sessionTitle = event.name; refreshFooter(ctx); }, ); pi.on("message_start", (_event: unknown, ctx: ExtensionContext) => refreshFooter(ctx), ); pi.on("message_end", (_event: unknown, ctx: ExtensionContext) => refreshFooter(ctx), ); pi.on("session_compact", (_event: unknown, ctx: ExtensionContext) => refreshFooter(ctx), ); pi.on("session_shutdown", (_event: unknown, ctx: ExtensionContext) => { sessionTitle = undefined; requestFooterRender = undefined; if (ctx.mode !== "tui") return; ctx.ui.setFooter(undefined); ctx.ui.setHeader(undefined); }); pi.registerCommand("dashboard-header", { description: "Toggle the custom startup dashboard header", handler: async (_args: string, ctx: ExtensionCommandContext) => { if (ctx.mode !== "tui") return; headerEnabled = !headerEnabled; const modules = await loadDashboardModules(); if (headerEnabled) { data = await modules.discovery.discoverDashboardData( ctx.cwd, ctx.isProjectTrusted(), ); } installHeader(ctx); ctx.ui.notify( `Dashboard header ${headerEnabled ? "enabled" : "disabled"}`, "info", ); }, }); pi.registerCommand("dashboard-footer", { description: "Toggle the custom dashboard footer", handler: async (_args: string, ctx: ExtensionCommandContext) => { if (ctx.mode !== "tui") return; footerEnabled = !footerEnabled; await loadDashboardModules(); installFooter(ctx); ctx.ui.notify( `Dashboard footer ${footerEnabled ? "enabled" : "disabled"}`, "info", ); }, }); }