// tools/init-project/ancestor-data-detector.ts
//
// Detects existing `data/projects/<id>/` directories in ancestors of the
// projectPath and in ancestors of the current cwd. When such a dir exists,
// init_project would otherwise create a parallel, divergent data root in the
// new cwd-relative location — splitting the project state across two
// physical paths and confusing every downstream tool.
//
// This helper is read-only: it only reports findings. The handler decides
// whether to surface them as warnings or block.
import { stat } from 'node:fs/promises';
import { dirname, isAbsolute, join } from 'node:path';
const MAX_WALK_DEPTH = 8;
async function isExistingDir(p) {
    try {
        const s = await stat(p);
        return s.isDirectory();
    }
    catch {
        return false;
    }
}
async function walkUpForDir(startDir, relative) {
    if (!isAbsolute(startDir)) {
        return null;
    }
    let current = startDir;
    for (let i = 0; i < MAX_WALK_DEPTH; i++) {
        const candidate = join(current, relative);
        if (await isExistingDir(candidate)) {
            return candidate;
        }
        const parent = dirname(current);
        if (parent === current) {
            return null;
        }
        current = parent;
    }
    return null;
}
/**
 * Scan for ancestor `data/projects/<projectId>/` dirs above projectPath and cwd.
 * Returns deduplicated absolute paths (no double-counting when projectPath and
 * cwd share an ancestor).
 */
export async function detectAncestorDataDirs(projectPath, projectId, cwd = process.cwd()) {
    const subPath = join('data', 'projects', projectId);
    const seen = new Set();
    const fromProjectPath = [];
    const cursor = isAbsolute(projectPath) ? dirname(projectPath) : null;
    if (cursor !== null) {
        const hit = await walkUpForDir(cursor, subPath);
        if (hit !== null && !seen.has(hit)) {
            seen.add(hit);
            fromProjectPath.push(hit);
        }
    }
    const fromCwd = [];
    if (cwd !== projectPath) {
        const hit = await walkUpForDir(cwd, subPath);
        if (hit !== null && !seen.has(hit)) {
            seen.add(hit);
            fromCwd.push(hit);
        }
    }
    return { fromProjectPath, fromCwd };
}
/**
 * Build a single human-readable warning line summarizing every ancestor data
 * dir hit. Returns null when no warning is needed.
 */
export function buildAncestorDataWarning(report) {
    const all = [...report.fromProjectPath, ...report.fromCwd];
    if (all.length === 0) {
        return null;
    }
    const list = all.map((p) => `  • ${p}`).join('\n');
    return (`Existing Planu data found in ancestor directories — this project's state may be split across multiple locations:\n${list}\n` +
        `If specs go missing, copy the contents into <projectPath>/data/projects/<id>/ and reopen Claude Code from the project root.`);
}
//# sourceMappingURL=ancestor-data-detector.js.map