export interface TemplateManifest {
    id: string;
    name: string;
    description: string;
    stack: {
        framework?: string;
        database?: string;
        auth?: string;
        billing?: string;
        styling?: string;
        deploy_target?: string;
    };
    required_env?: string[];
    post_install_steps?: string[];
    /** Files to NOT copy verbatim (templating tokens applied — handled by engine). */
    exclude?: string[];
    /** Optional minimum Node version. Surface as a warning if user is below. */
    required_node_version?: string;
    /** Set by registry at load time — not in the file itself. */
    source?: 'bundled' | 'user';
    /** Absolute path to template root. */
    rootDir?: string;
}
export declare class TemplateRegistry {
    /**
     * Discover all templates (user + bundled). User wins on id collision.
     * Returns templates with `source` + `rootDir` populated.
     */
    list(): TemplateManifest[];
    /** Resolve a single template by id. Returns null when not found. */
    get(id: string): TemplateManifest | null;
    /** Exposed for tests + scaffold engine to know the rootDir. */
    static _userTemplatesDir(): string;
    /** Exposed for tests. */
    static _bundledTemplatesCandidates(): string[];
    private collectFromDir;
}
