/**
 * @typedef {'wired' | 'stubbed' | 'unwired'} WiringBucket
 */
/**
 * @typedef {Object} SubFeature
 * @property {string} id
 * @property {string} name
 * @property {WiringBucket} wiring
 * @property {string} [component]
 * @property {string} [type]
 * @property {string} [handler]
 * @property {string} [test_hint]
 */
/**
 * @typedef {Object} FeatureGroup
 * @property {string} id
 * @property {string} name
 * @property {WiringBucket} wiring
 * @property {string} [component]
 * @property {string} [type]
 * @property {SubFeature[]} sub_features
 */
/**
 * @typedef {Object} FeatureArea
 * @property {string} area             kebab-case area id (e.g. "terminals")
 * @property {string} [route]
 * @property {string} [status]
 * @property {string} [last_scanned]
 * @property {FeatureGroup[]} features
 * @property {{ wired: number, stubbed: number, unwired: number, total: number }} counts
 * @property {string} source_path       absolute path the area was read from
 */
/**
 * @typedef {Object} InventoryResult
 * @property {'ok' | 'empty' | 'missing'} status
 * @property {string} registryDir
 * @property {FeatureArea[]} areas
 * @property {{ areas: number, features: number, sub_features: number, wired: number, stubbed: number, unwired: number }} totals
 * @property {Array<{ file: string, message: string }>} parse_errors
 */
/**
 * Normalize the wiring signal on a feature or sub-feature.
 *
 * @param {unknown} wired
 * @returns {WiringBucket}
 */
export function normalizeWiring(wired: unknown): WiringBucket;
/**
 * Read the features registry from `<projectDir>/.aperant/features/`.
 *
 * @param {string} projectDir
 * @returns {InventoryResult}
 */
export function readFeaturesRegistry(projectDir: string): InventoryResult;
/**
 * Best-effort extract the human-readable "last scanned" line from the
 * registry's REGISTRY.md. Returns null when the file is missing or does not
 * contain a matching line. Used by the nav renderer for the timestamp in
 * the generated README.
 *
 * @param {string} projectDir
 * @returns {string | null}
 */
export function readRegistryLastScanned(projectDir: string): string | null;
export type WiringBucket = "wired" | "stubbed" | "unwired";
export type SubFeature = {
    id: string;
    name: string;
    wiring: WiringBucket;
    component?: string | undefined;
    type?: string | undefined;
    handler?: string | undefined;
    test_hint?: string | undefined;
};
export type FeatureGroup = {
    id: string;
    name: string;
    wiring: WiringBucket;
    component?: string | undefined;
    type?: string | undefined;
    sub_features: SubFeature[];
};
export type FeatureArea = {
    /**
     * kebab-case area id (e.g. "terminals")
     */
    area: string;
    route?: string | undefined;
    status?: string | undefined;
    last_scanned?: string | undefined;
    features: FeatureGroup[];
    counts: {
        wired: number;
        stubbed: number;
        unwired: number;
        total: number;
    };
    /**
     * absolute path the area was read from
     */
    source_path: string;
};
export type InventoryResult = {
    status: "ok" | "empty" | "missing";
    registryDir: string;
    areas: FeatureArea[];
    totals: {
        areas: number;
        features: number;
        sub_features: number;
        wired: number;
        stubbed: number;
        unwired: number;
    };
    parse_errors: Array<{
        file: string;
        message: string;
    }>;
};
//# sourceMappingURL=features-reader.d.mts.map