/** * Candidate resolution — the one step every import entry point funnels through. * * `auden import` (no arguments), `auden import ` and the MCP `import` * tool all answer the same two questions about a file before anything is sent: * *is this adoptable*, and *does the dashboard already own it*. This module is * where both are answered, once. * * **Why a shape rather than a rule.** Until slice 4 this job was done by a * bulk-scan pre-filter (`filterSidecarMappedFiles`, deleted in PR #643) that * each caller applied, so "remember to call the filter" was a rule a fourth * entry point could forget — and forgetting it forks a guide into a second row * with no error (`guide-versioned-identity-plan.md` → slice 3's third live * reproduction, PR #627). Here `managed` is a *field on every candidate*, * produced by the only function that can produce a candidate, so a caller has * no way to reach the importer with an unannotated file. * `importDiscoveredGuides` refuses a managed candidate on top of that, which is * what makes retiring the sweep filter a deletion rather than a leap * (`auden-import-plan.md` → *Where the check lives*). * * **Membership is decided by the placement record, exactly as it was before.** * `readPlacement` is the authority — the same call, over the same file, that * the deleted pre-filter was handed. The bundle *name* is decoration read * separately and best-effort: a managed file with no recoverable bundle name is * still managed, and says so without naming one. */ import type { DiscoveredGuideFile } from './discover.js'; /** * Why a file cannot be adopted, or `null` when it can. * * A record rather than a boolean so the refusal can name the bundle; `bundle` * is `null` when the placement file claims the path but no mapping recovered a * name for it. */ export type ManagedBy = { bundle: string | null; }; export type ImportCandidate = { file: DiscoveredGuideFile; /** Non-null when the dashboard already owns this file — never adoptable. */ managed: ManagedBy | null; }; export type ImportCandidateDeps = { /** Injected by tests so resolution runs without a repo on disk. */ readPlacementFn?: (root: string) => Promise>; /** Injected by tests; failure here degrades to an unnamed bundle, never to unmanaged. */ readBundleNamesFn?: (root: string) => Promise>; }; /** * Annotate discovered files with whether the dashboard already owns them. * * Order is preserved and nothing is dropped: a managed file is a candidate that * cannot be selected, not a candidate that disappears. Hiding it is how a user * ends up wondering why their file never appears (`auden-import-plan.md`). */ export declare function resolveImportCandidates(files: ReadonlyArray, root: string, deps?: ImportCandidateDeps): Promise; /** The candidates a user or agent may actually adopt. */ export declare function adoptable(candidates: ReadonlyArray): ImportCandidate[]; /** The candidates that are shown but not selectable. */ export declare function managed(candidates: ReadonlyArray): ImportCandidate[]; /** * The refusal shown when someone points at a file the dashboard owns. * * One sentence, and it names the next action — a skip that says nothing is how * the user concludes Auden is broken rather than that the file is already in. */ export declare function managedRefusal(candidate: ImportCandidate): string; //# sourceMappingURL=import-candidates.d.ts.map