/**
 * Session-index warm service (RUSH-2682), migrated onto `ServiceSupervisor`
 * (RUSH-3193 P1) as the proof-of-concept periodic service.
 *
 * Incrementally scans this host's transcript dirs into the local index so a
 * locally-started session is discoverable within seconds, not on the next
 * unrelated `agents sessions*` call. Single-flight via the DB scan claim in
 * `scanSessionsIncremental` — a concurrent foreground scan is a skip, not a
 * failure. Previously a bare `setInterval` in `runDaemon()`
 * (daemon.ts:1118-1137); the supervisor now owns its timer, error boundary,
 * and deadline instead.
 */
import { BasePeriodicService } from './service.js';
import { runDeferredToolIndex, runSessionIndexWarmTick } from '../daemon-ticks.js';
/** Matches the historical inline interval (daemon.ts SESSION_INDEX_WARM_TICK_MS). */
const SESSION_INDEX_WARM_TICK_MS = 20_000;
/** Hard cap per tick — well above a healthy incremental scan, short enough that a hang never freezes the service for long. */
const SESSION_INDEX_WARM_DEADLINE_MS = 60_000;
export class SessionIndexService extends BasePeriodicService {
    id = 'session-index';
    intervalMs = SESSION_INDEX_WARM_TICK_MS;
    deadlineMs = SESSION_INDEX_WARM_DEADLINE_MS;
    async onStart(_ctx) {
        // No connections/handles to open — the scan claim itself is per-tick state.
    }
    async onStop() {
        // Nothing to release — the supervisor's timer teardown is the only cleanup needed.
    }
    async onTick(ctx) {
        const { indexed, claimed } = await runSessionIndexWarmTick();
        // Log only when the tick did something. A silent tick is what let it
        // report 0 forever unnoticed (RUSH-2691); a line on every idle 20s tick
        // would drown the log, so the steady state (claimed, nothing changed)
        // stays quiet and both interesting outcomes are visible.
        if (!claimed)
            ctx.log('INFO', 'session-index warm: skipped, another process holds the scan claim');
        else if (indexed > 0)
            ctx.log('INFO', `session-index warm: indexed ${indexed} transcript(s)`);
        // Deferred tool-index pass (PHNX-3411): fill tool_scan_ledger rows for
        // harnesses whose scanner produces no events. Runs only when the warm tick
        // claimed the scan lock (i.e. we are the active indexer this tick).
        if (claimed) {
            const { indexed: toolIndexed } = await runDeferredToolIndex();
            if (toolIndexed > 0)
                ctx.log('INFO', `session-index deferred: tool-indexed ${toolIndexed} transcript(s)`);
        }
    }
}
