// storage/session-state-store.ts — Persists session handoff state for SPEC-220.
// Persistence file: planu/session-state.json (gitignored — ephemeral per session).
import { readJson, writeJson } from './base-store.js';
import { join } from 'node:path';
import { execSync } from 'node:child_process';
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
const STATE_FILENAME = 'session-state.json';
const MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24 hours
// ---------------------------------------------------------------------------
// Internal helpers
// ---------------------------------------------------------------------------
function stateFile(projectPath) {
    return join(projectPath, 'planu', STATE_FILENAME);
}
function isExpired(savedAt) {
    const age = Date.now() - new Date(savedAt).getTime();
    return age > MAX_AGE_MS;
}
// ---------------------------------------------------------------------------
// Git staged files (best-effort, returns [] on failure)
// ---------------------------------------------------------------------------
export function getStagedFiles(projectPath) {
    try {
        const output = execSync('git diff --name-only --cached', {
            cwd: projectPath,
            encoding: 'utf-8',
            stdio: ['pipe', 'pipe', 'pipe'],
        });
        return output
            .split('\n')
            .map((f) => f.trim())
            .filter((f) => f.length > 0);
    }
    catch {
        return [];
    }
}
// ---------------------------------------------------------------------------
// Active specs (in-progress) — filesystem scan fallback
// ---------------------------------------------------------------------------
export async function getActiveSpecIds(projectPath) {
    try {
        const { glob } = await import('glob');
        const specFiles = await glob('planu/specs/*/spec.md', { cwd: projectPath });
        const active = [];
        for (const f of specFiles) {
            const { readFile } = await import('node:fs/promises');
            const content = await readFile(join(projectPath, f), 'utf-8');
            if (content.includes('status: implementing') || content.includes("status: 'implementing'")) {
                const match = /SPEC-\d+/.exec(f);
                if (match) {
                    active.push(match[0]);
                }
            }
        }
        return active;
    }
    catch {
        return [];
    }
}
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/** Persist session state to planu/session-state.json. */
export async function saveSessionState(projectPath, state) {
    const file = stateFile(projectPath);
    await writeJson(file, state);
}
/**
 * Load session state from planu/session-state.json.
 * Returns null if the file does not exist or timestamp is older than 24h.
 */
export async function loadSessionState(projectPath) {
    const file = stateFile(projectPath);
    const raw = await readJson(file, null);
    if (raw === null) {
        return null;
    }
    if (isExpired(raw.savedAt)) {
        return null;
    }
    return raw;
}
//# sourceMappingURL=session-state-store.js.map