import { mkdirSync, existsSync, copyFileSync } from 'node:fs'; import { join } from 'node:path'; import { homedir } from 'node:os'; import { DATA_PATH, PI_CONFIG_DIR } from './data-path'; import { syncLocalProvidersToPiConfig } from './api/server-settings/sync-pi-config'; import { syncAllUserPiConfigs } from './api/server-settings/sync-user-pi-config'; import { syncSeedSkills } from './sync-skills'; import { syncSeedTools } from './sync-tools'; import { syncSeedExtensions } from './sync-extensions'; import { syncSeedResources } from './sync-resources'; import { migrateSettingsToResources } from './migrate-resources'; import { generateResourceSkill } from './api/pi/pi-bridge'; import { initQueue } from './queue'; mkdirSync(DATA_PATH, { recursive: true }); mkdirSync(PI_CONFIG_DIR, { recursive: true }); async function ensurePiInstalled(): Promise { try { const proc = Bun.spawn(['pi', '--version'], { stdout: 'pipe', stderr: 'pipe' }); await proc.exited; return proc.exitCode === 0; } catch { return false; } } async function installPi(): Promise { console.log('[bootstrap] Pi not found, installing...'); try { const proc = Bun.spawn(['npm', 'install', '-g', '@mariozechner/pi-coding-agent'], { stdout: 'pipe', stderr: 'pipe', }); const stderr = await new Response(proc.stderr).text(); await proc.exited; if (proc.exitCode !== 0) { console.error('[bootstrap] Pi installation failed:', stderr.trim()); return false; } console.log('[bootstrap] Pi installed successfully'); return true; } catch (err) { console.error('[bootstrap] Pi installation error:', err); return false; } } function seedPiConfig(): void { const hostPiDir = join(homedir(), '.pi', 'agent'); const filesToCopy = ['models.json', 'settings.json']; for (const file of filesToCopy) { const target = join(PI_CONFIG_DIR, file); if (existsSync(target)) continue; const source = join(hostPiDir, file); if (existsSync(source)) { copyFileSync(source, target); console.log(`[bootstrap] Seeded ${file} from host Pi config`); } } } (async () => { const installed = await ensurePiInstalled(); if (!installed) { const ok = await installPi(); if (!ok) { console.error('[bootstrap] Could not install Pi — model discovery will not work'); return; } } seedPiConfig(); syncSeedSkills(); syncSeedTools(); syncSeedExtensions(); syncSeedResources(); await migrateSettingsToResources(); generateResourceSkill(DATA_PATH); await syncLocalProvidersToPiConfig().catch(err => { console.error('[bootstrap] Failed to sync local providers to Pi config:', err); }); await syncAllUserPiConfigs().catch(err => { console.error('[bootstrap] Failed to sync user Pi configs:', err); }); await initQueue().catch(err => { console.error('[bootstrap] Failed to initialize queue:', err); }); })();