import { mkdirSync } from 'node:fs'; import { join } from 'node:path'; import { homedir } from 'node:os'; import { DATA_PATH, ensureItemDirs } from './data-path'; import { ensureToolLoader } from './ensure-tool-loader'; // Queue is now owned by the sidecar process import { startDiscordBotIfConfigured } from './channels/discord/bot'; import { startTelegramBotIfConfigured } from './channels/telegram/bot'; import { startWhatsAppBotIfConfigured } from './channels/whatsapp/bot'; mkdirSync(DATA_PATH, { recursive: true }); ensureItemDirs(); /** Check common locations for the Pi package directory. */ async function findPiPackageDir(): Promise { const candidates = [ join(homedir(), '.npm-global', 'lib', 'node_modules', '@mariozechner', 'pi-coding-agent'), '/usr/local/lib/node_modules/@mariozechner/pi-coding-agent', ]; for (const dir of candidates) { if (await Bun.file(join(dir, 'package.json')).exists()) return dir; } return null; } async function ensurePiInstalled(): Promise { const dir = await findPiPackageDir(); if (!dir) return false; try { const pkg = await Bun.file(join(dir, 'package.json')).json(); if (pkg.version) { console.log(`[bootstrap] Pi found: ${pkg.version}`); return true; } } 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; } } (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; } } ensureToolLoader(); // Queue is initialized by the sidecar process await startDiscordBotIfConfigured().catch((err) => { console.error('[channels] Failed to start Discord bot:', err); }); await startTelegramBotIfConfigured().catch((err) => { console.error('[channels] Failed to start Telegram bot:', err); }); await startWhatsAppBotIfConfigured().catch((err) => { console.error('[channels] Failed to start WhatsApp bot:', err); }); })();