// Planificateur de la découverte auto des repos : scan au démarrage + re-scan périodique. // Calqué sur DiscoveryService (sessions) — start()/stop() avec timer .unref(). Démarré depuis // runDaemon() UNIQUEMENT (jamais buildApp), ce qui isole naturellement les tests vitest du scan. // Lui-même sans état : il lit les racines/l'intervalle dans `settings` et délègue à WorktreeManager. import type { Db } from '../db/index.js'; import type { WorktreeManager } from './worktree-manager.js'; import { readScanIntervalMin, readScanRoots } from './scan-settings.js'; export class RepoDiscoveryService { private timer: NodeJS.Timeout | null = null; constructor( private readonly db: Db, private readonly worktrees: WorktreeManager, ) {} start(): void { if (this.timer) return; void this.refresh(); // scan initial asynchrone : ne bloque pas le boot const intervalMin = readScanIntervalMin(this.db); if (intervalMin > 0) { this.timer = setInterval(() => void this.refresh(), intervalMin * 60_000); this.timer.unref(); // ne maintient pas le process en vie } } stop(): void { if (this.timer) { clearInterval(this.timer); this.timer = null; } } /** Relit les racines (changement effectif sans redémarrage) et lance un scan. Ne lève jamais. */ private async refresh(): Promise { try { await this.worktrees.discoverRepos({ roots: readScanRoots(this.db) }); } catch { /* scan tolérant : une erreur ne doit pas tuer le timer */ } } }