/**
 * Vertical detection from filesystem signals.
 *
 * Pure scoring function consumed by Stage 0.5 of the agent activation flow.
 * Performs no filesystem IO; the caller is responsible for shallow-scanning the
 * install directory and passing the resulting metadata in. This keeps detection
 * deterministic, testable, and host-independent (the same function runs in the
 * MCP server, the CLI, and any future browser-side prototype).
 *
 * The signal table mirrors the per-vertical heuristics documented in
 * `docs/foundation/file_ranking_heuristic.md` so the human-readable reference
 * and the machine implementation can never silently drift.
 *
 * Notes:
 *   - Matching is case-insensitive on filenames AND folder paths.
 *   - Folder signals are matched against any segment of the relative path.
 *   - Glob-style filename hints are translated into anchored regexes.
 *   - `personal-agent` is intentionally absent from the signal table because
 *     it is the meta-fallback returned when no other vertical scores.
 */
const FOLDER_WEIGHT = 2;
const FILENAME_WEIGHT = 1;
const VERTICAL_SIGNALS = [
    {
        slug: "compliance",
        folderSignals: ["vendors", "risk", "soc2", "audits", "compliance"],
        filenamePatterns: ["vendor-*", "*-soc2*", "risk-register*", "*assessment*"],
    },
    {
        slug: "crm",
        folderSignals: ["contacts", "pipeline", "deals", "accounts", "crm"],
        filenamePatterns: ["*-contacts.csv", "*-deals.csv", "account-*"],
    },
    {
        slug: "contracts",
        folderSignals: ["contracts", "agreements", "counterparty"],
        filenamePatterns: ["*-msa*", "*-sow*", "amendment-*", "*signed*"],
    },
    {
        slug: "diligence",
        folderSignals: ["due diligence", "data room", "ic memos", "diligence"],
        filenamePatterns: ["dd-*", "*-memo.md", "ic-deck-*"],
    },
    {
        slug: "portfolio",
        folderSignals: ["portfolio", "holdings", "lp reports"],
        filenamePatterns: ["kpi-*", "*-quarterly*", "lp-report-*"],
    },
    {
        slug: "cases",
        folderSignals: ["cases", "matters", "investigations"],
        filenamePatterns: ["case-*", "matter-*", "evidence-*"],
    },
    {
        slug: "financial-ops",
        folderSignals: ["statements", "accounting", "ap", "ar", "finance"],
        filenamePatterns: ["*-statement*", "*-transactions.csv", "ap-run-*"],
    },
    {
        slug: "procurement",
        folderSignals: ["rfp", "suppliers", "pos", "procurement"],
        filenamePatterns: ["rfp-*", "po-*", "supplier-*"],
    },
    {
        slug: "agent-auth",
        folderSignals: ["auth", "policies", "agents", "oauth"],
        filenamePatterns: ["policy-*", "auth-decision-*", "agent-*.json"],
    },
    {
        slug: "healthcare",
        folderSignals: ["patients", "encounters", "care", "clinical"],
        filenamePatterns: ["encounter-*", "note-*", "careplan-*"],
    },
    {
        slug: "government",
        folderSignals: ["constituents", "permits", "foia"],
        filenamePatterns: ["case-*", "foia-*", "permit-*"],
    },
    {
        slug: "customer-ops",
        folderSignals: ["tickets", "support", "escalations"],
        filenamePatterns: ["ticket-*", "escalation-*"],
    },
    {
        slug: "logistics",
        folderSignals: ["shipments", "routes", "inventory", "logistics"],
        filenamePatterns: ["shipment-*", "route-*", "inventory-*"],
    },
    {
        slug: "personal-data",
        folderSignals: [
            "receipts",
            "travel",
            "health",
            "subscriptions",
            "personal",
        ],
        filenamePatterns: ["receipt-*", "flight-*", "subscription-*"],
    },
    {
        slug: "trading",
        folderSignals: ["trades", "strategies", "backtests"],
        filenamePatterns: ["trade-log-*", "strategy-*", "backtest-*"],
    },
    {
        slug: "crypto-engineering",
        folderSignals: ["audits", "runbooks"],
        filenamePatterns: ["*.sol", "audit-*.md", "incident-*.md"],
    },
    {
        slug: "engineering",
        folderSignals: ["runbooks", "incidents", "rfcs", "architecture"],
        filenamePatterns: ["rfc-*.md", "incident-*.md", "runbook-*", "*.arch.md"],
    },
    {
        slug: "customer-development",
        folderSignals: ["interviews", "user research", "discovery"],
        filenamePatterns: ["interview-*", "*-transcript.md", "*-research.md"],
    },
    {
        slug: "content-ops",
        folderSignals: ["posts", "newsletters", "drafts", "content"],
        filenamePatterns: ["*-draft.md", "post-*.md", "newsletter-*"],
    },
    {
        slug: "meetings",
        folderSignals: ["meetings", "notes", "transcripts"],
        filenamePatterns: ["transcript-*", "*-meeting-notes.md"],
    },
];
function globToRegExp(pattern) {
    // Escape regex metacharacters except * and ?, then translate the wildcards.
    const escaped = pattern
        .replace(/[.+^${}()|[\]\\]/g, "\\$&")
        .replace(/\*/g, ".*")
        .replace(/\?/g, ".");
    return new RegExp(`^${escaped}$`, "i");
}
const VERTICAL_REGEX_CACHE = new Map();
function regexesFor(slug, patterns) {
    const cached = VERTICAL_REGEX_CACHE.get(slug);
    if (cached)
        return cached;
    const built = patterns.map(globToRegExp);
    VERTICAL_REGEX_CACHE.set(slug, built);
    return built;
}
function basename(path) {
    const i = path.lastIndexOf("/");
    return i >= 0 ? path.slice(i + 1) : path;
}
function pathSegments(path) {
    return path.split("/").filter(Boolean);
}
/**
 * Score the supplied filesystem entries against the vertical signal table.
 * Returns the full sorted result; the caller decides how to act on it
 * (auto-confirm, ask, or fall back to `personal-agent`).
 */
export function detectVerticalFromSignals(entries, options = {}) {
    const ambiguityMargin = options.ambiguityMargin ?? 0.15;
    const matchesByVertical = new Map();
    const scoresByVertical = new Map();
    for (const entry of entries) {
        const segments = pathSegments(entry.relativePath).map((s) => s.toLowerCase());
        const file = entry.isDirectory ? null : basename(entry.relativePath);
        for (const sig of VERTICAL_SIGNALS) {
            let matched = false;
            const matches = matchesByVertical.get(sig.slug) ?? new Set();
            for (const folder of sig.folderSignals) {
                const needle = folder.toLowerCase();
                if (segments.some((seg) => seg === needle || seg.includes(needle))) {
                    scoresByVertical.set(sig.slug, (scoresByVertical.get(sig.slug) ?? 0) + FOLDER_WEIGHT);
                    matches.add(`folder:${folder}`);
                    matched = true;
                    break;
                }
            }
            if (file) {
                const regexes = regexesFor(sig.slug, sig.filenamePatterns);
                for (let i = 0; i < regexes.length; i++) {
                    if (regexes[i].test(file)) {
                        scoresByVertical.set(sig.slug, (scoresByVertical.get(sig.slug) ?? 0) + FILENAME_WEIGHT);
                        matches.add(`file:${sig.filenamePatterns[i]}`);
                        matched = true;
                        break;
                    }
                }
            }
            if (matched)
                matchesByVertical.set(sig.slug, matches);
        }
    }
    const scores = Array.from(scoresByVertical.entries())
        .map(([slug, score]) => ({
        slug,
        score,
        matched: Array.from(matchesByVertical.get(slug) ?? []).sort(),
    }))
        .sort((a, b) => b.score - a.score);
    if (scores.length === 0) {
        return {
            topVertical: null,
            ambiguous: false,
            scores: [],
            recommendFallback: true,
        };
    }
    const top = scores[0];
    const runnerUp = scores[1]?.score ?? 0;
    const ambiguous = top.score > 0 && runnerUp > 0 && runnerUp / top.score >= 1 - ambiguityMargin;
    return {
        topVertical: top.slug,
        ambiguous,
        scores,
        recommendFallback: false,
    };
}
//# sourceMappingURL=vertical_detection.js.map