/**
 * Structural pre-pass for analyse — orchestrator + public exports.
 *
 * Walks a source directory, extracts deterministic structural facts,
 * translates them into SpecVerse vocabulary via per-framework adapters,
 * and produces a `SpecVerseFacts` object suitable for injection into the
 * analyse prompt as a structural-context preamble.
 *
 * Design: see specverse-self/docs/proposals/STRUCTURAL-PREPASS-FOR-ANALYSE.md
 *
 * Usage:
 *   import { runPrepass } from '@specverse/engines/analyse-prepass';
 *   const facts = await runPrepass('/path/to/source');
 *   // facts.entities, facts.relationships, facts.lifecycles, ...
 */
export type { StructuralPrepass, Symbol, Import, Capabilities, FileFilter, ClassFilter, MethodFilter, InterfaceFilter, IndexResult, MethodFactSheet, } from './interface.js';
export { GrepOnlyBackend, CodeGraphBackend, GitNexusBackend, selectBackend, type BackendName, } from './backends/index.js';
export { extractTypeScriptPrisma, type PrismaFacts, type PrismaEntity, type PrismaField, type PrismaRelation, } from './adapters/index.js';
import { type BackendName } from './backends/index.js';
import type { StructuralPrepass, MethodFactSheet } from './interface.js';
import type { ComponentSuggestion } from './community-detection.js';
import type { NonLibraryImportHint } from './imports-graph.js';
export type { ComponentSuggestion } from './community-detection.js';
export type { NonLibraryImportHint, NonLibraryCategory, NonLibraryImportsByComponent, } from './imports-graph.js';
export { renderGitnexusignore, ANALYSE_IGNORE_DIRS, ANALYSE_IGNORE_EXTS, isIgnoredDir, hasIgnoredExt, isAnalyseConfigFile, } from './scope.js';
export { buildSourceVersion, readGitInfo } from './provenance.js';
export type { SourceVersion, SourceVersionGit } from './provenance.js';
export { hasExistingGitnexusIndex } from './backends/gitnexus.js';
export { walkMethodBodies, type MethodBodyFacts, type ThisAssignment, type ThisGuard, type MethodCall, type ThrowStmt, type ReturnStmt, } from './method-body-walker.js';
export { extractCandidateSteps, type CandidateStep, type CandidateStepKind, type MethodCandidates, } from './behavior-step-classifier.js';
/**
 * Normalised attribute shape — a per-adapter superset that consumers
 * can rely on regardless of which framework the source code uses. Each
 * adapter maps its own field type into this shape:
 *   - prisma's `PrismaField {name,type,required,unique,isId}` →
 *     {name, declaredType: type, isPrimary: isId, isUnique: unique, required}
 *   - decorators' `{name, declaredType?, isPrimary?, isUnique?}` →
 *     same shape directly
 *
 * `declaredType` is the source-language type (TS / Java / etc.) — kept
 * as-is rather than mapped to a SpecVerse vocabulary at this layer. The
 * downstream LLM analyse step is responsible for the WHAT-language
 * mapping (`string` → `String required`, `InvoiceStatus` → enum-typed
 * lifecycle field, etc.). Storing the raw type here keeps the prepass
 * loss-less.
 */
export interface FactAttribute {
    name: string;
    declaredType?: string;
    isPrimary?: boolean;
    isUnique?: boolean;
    required?: boolean;
    /**
     * Id-generation / default semantics recovered from the source, as a
     * SpecVerse `auto=` token: `uuid4` (Prisma `@default(uuid())` / Drizzle
     * uuid-with-default), `autoincrement` (Prisma `autoincrement()` / Drizzle
     * `serial`), `cuid`, `now`. Preserved through the skeleton so analyse →
     * realize reproduces the source's identity instead of guessing uuid
     * (Phase 2 of the identity proposal). Undefined when the source declares
     * no generation default.
     */
    auto?: string;
}
export interface SpecVerseFacts {
    /** Detected entities (model candidates). */
    entities: Array<{
        name: string;
        filePath: string;
        sourceFramework: string;
        /**
         * Per-attribute facts (column / field declarations on the entity).
         * Optional because not every adapter produces them yet — the
         * downstream analyse pipeline must tolerate missing attributes.
         * Populated by the prisma + typescript-decorators adapters; future
         * adapters (typescript-drizzle, python-django) will populate too.
         */
        attributes?: FactAttribute[];
    }>;
    /** Detected relationships between entities. */
    relationships: Array<{
        from: string;
        to: string;
        type: 'belongsTo' | 'hasMany' | 'hasOne' | 'manyToMany';
        cascade?: boolean;
    }>;
    /** Detected lifecycle declarations: states attached to a model's status field. */
    lifecycles: Array<{
        model: string;
        field: string;
        states: string[];
        /**
         * Inferred state-machine transitions — populated by the
         * typescript-decorators adapter via `method-body-walker.ts` when
         * instance methods follow the `if (this.field !== X) throw; this.field = Y;`
         * pattern. Each transition's `from` is the array of source states the
         * method allows (computed from the guard), `to` is the assignment
         * target, `action` is the method name. Empty when no methods match
         * the pattern. Cross-method composite transitions and complex flow
         * control (ternaries, switch statements) fall through to the LLM.
         */
        transitions?: Array<{
            action: string;
            from: string[];
            to: string;
        }>;
    }>;
    /** Provenance: which adapter(s) ran, what backend was used. */
    meta: {
        backend: string;
        backendCapabilities: Record<string, boolean>;
        adaptersRun: string[];
        sourceDir: string;
        durationMs: number;
        /**
         * Storage profile inferred from the detected ORM (Prisma datasource /
         * Drizzle dialect / …). Consumed by the deployment-emitter to emit a
         * faithful storage instance (`type: relational, provider: postgresql`)
         * instead of the blanket `document` default. Absent when no ORM with a
         * known dialect was detected.
         */
        storageProfile?: {
            type: 'relational' | 'document' | 'keyvalue';
            provider: string;
        };
    };
    /**
     * Optional component-boundary suggestions from Louvain on the entity graph.
     * Populated when the entity graph is large enough to benefit (≥5 entities)
     * and `suggestComponents !== false` in options. See
     * `specverse-self/docs/proposals/COMPONENT-SUGGESTION-FROM-MODEL-GRAPH.md`.
     */
    suggestedComponents?: ComponentSuggestion[];
    /**
     * Optional per-method fact sheets for entry-point methods (controllers,
     * services). Populated when `gatherMethodFacts !== false` in options.
     * Used by the verify-analyse prompt to cross-check analysed `behaviors[].steps`
     * against what source methods actually do (events emitted / dbWrites /
     * external calls / async boundaries). See TODO #32.
     */
    methodFactSheets?: MethodFactSheet[];
    /**
     * Optional pre-classified candidate-step timelines (#27-B). For every
     * detected entity class, the method-body walker + behavior-step
     * classifier extract a structured list of `CandidateStep`s per method
     * — kind ∈ {find, find-many, create, update, delete, transition, emit,
     * validate, call, return} ordered by source position. The analyse LLM
     * uses these as a structural anchor when emitting `behaviors[].steps[]`
     * blocks: instead of summarizing 200 lines of code, it refines a
     * 5-15 step pre-classified timeline into spec vocabulary.
     *
     * Populated when `extractCandidateSteps !== false` in options
     * AND at least one entity was detected by the typescript-decorators
     * adapter. Other adapters (typescript-prisma, future python/java)
     * don't yet run the classifier — they'd need their own walker
     * appropriate to the language.
     */
    candidateMethods?: Array<{
        /** Source file the methods came from. */
        filePath: string;
        /** Entity class containing the methods. */
        entityName: string;
        /** Per-method classified timelines. */
        methods: import('./behavior-step-classifier.js').MethodCandidates[];
    }>;
    /**
     * Detected React/JSX view declarations (engines 6.28.0+). Populated
     * by the `react-views` adapter when `*.tsx` / `*.jsx` files are
     * present and `runReactViewsAdapter !== false` in options. One entry
     * per uniquely-named view declaration (function components, arrow
     * components, class components, default exports). The skeleton
     * emitter consumes these to populate per-component `views:` blocks.
     */
    views?: Array<{
        name: string;
        filePath: string;
        sourceLineRange: [number, number];
        kind: 'function-component' | 'arrow-component' | 'class-component' | 'default-export';
        isScreen: boolean;
        /** Optional JSDoc / leading-comment text from above the declaration
         *  (engines 6.30.3+). Used by skeleton-emitter as the view's
         *  `description:` when present; falls back to humanized name otherwise. */
        docstring?: string;
        /** Engines 6.31.0+. Classified standard view type (`list`, `form`,
         *  `detail`, `dashboard`, `modal`, `provider`, `screen`, `layout`,
         *  `widget`, `page`, ...). Emitted into the spec as `type:`. */
        viewType?: string;
        /** Primary model the view is bound to. Set for inferred renderable views
         *  (e.g. a `timeline` view bound to its event model) so the skeleton emits
         *  `model:` and the runtime can render it. (#GUI-uplift part 2) */
        model?: string;
        /** Engines 6.31.0+. Sub-component names rendered inside this view's
         *  JSX. Skeleton-emitter cross-references against detected views to
         *  keep only known refs. */
        usesComponents?: string[];
        /** Engines 6.31.0+. Action handles extracted from button/link
         *  click handlers (handler name, optional label + variant). */
        actions?: Array<{
            name: string;
            label?: string;
            variant?: 'primary' | 'destructive' | 'secondary';
        }>;
        /** Engines 6.31.0+. True when the view has an explicit empty-state
         *  branch (zero-items / isEmpty). */
        emptyState?: boolean;
    }>;
    /**
     * HTTP routes detected via the backend's native route extraction
     * (engines 6.30.0+, TODO #51 phase 1). Populated when
     * `prepass.capabilities.routeExtraction === true`. GitNexus emits
     * Route nodes natively; walk-backend currently leaves this empty
     * (existing express-routes.ts adapter still fires for walk).
     */
    routes?: Array<{
        filePath: string;
        httpVerb: string;
        routePath: string;
        handlerName: string;
        sourceLineRange?: [number, number];
        responseKeys?: string[];
        errorKeys?: string[];
        middleware?: string[];
    }>;
    /**
     * Class → Interface IMPLEMENTS relationships (engines 6.30.0+, TODO #51
     * phase 2). Maps to spec `provides:` capability slots.
     */
    implementsRelationships?: Array<{
        className: string;
        interfaceName: string;
        classFilePath: string;
        interfaceFilePath?: string;
    }>;
    /**
     * Validation-schema declarations (engines 6.30.0+, TODO #51 phase 3).
     * Adapters parse `content` for library-specific shape (Zod field
     * declarations, etc.) and feed into entity attributes.
     */
    constSchemas?: Array<{
        name: string;
        filePath: string;
        content: string;
        sourceLineRange?: [number, number];
        library?: string;
    }>;
    /**
     * Pre-computed cross-method execution flows (engines 6.30.0+, TODO #51
     * phase 4). High-stepCount processes seed `behaviors:` action shells
     * with pre-grouped step sequences. GitNexus-only; walk-backend has no
     * equivalent.
     */
    processes?: Array<{
        id: string;
        label: string;
        entryPointId: string;
        terminalId: string;
        stepCount: number;
        processType: string;
        steps: Array<{
            symbolId: string;
            step: number;
        }>;
    }>;
    /**
     * Per-consumer cross-component import graph (engines 6.32.6+,
     * 2026-05-07 — Dom Williams shared-library / reference-or-implicit-
     * include feedback). Map shape: `{ [consumerComponent]: { [targetComponent]:
     * [...importedSymbols] } }`. Populated by walking each component's
     * source files for `import { ... } from '...'` statements and
     * resolving the path against the other components' sourceDirs.
     *
     * Skeleton-emitter uses this to emit per-component `import:` blocks
     * — a real cross-component dependency model that the schema has long
     * supported but our analyse pipeline never produced.
     */
    importsByComponent?: Record<string, Record<string, string[]>>;
    /**
     * V2 Phase 2 (Component Dependencies V2 — 2026-05-08) non-library
     * dependency hints. Map shape: `{ [consumerComponent]:
     * NonLibraryImportHint[] }`. Populated by walking each component's
     * source files for FOUR detection patterns:
     *   - subprocess executables (`spawnSync`, `execSync`, `Bun.spawn`)
     *   - HTTP/RPC service clients (`axios.create({ baseURL })`,
     *     `fetch(process.env.X + ...)`, gRPC stubs)
     *   - async messaging crossings (`rabbit.publish`, `kafka.consume`)
     *   - known managed-SaaS SDK init (`new Stripe(...)`, `new OpenAI(...)`)
     *
     * Each hint carries both consumer-side `import:` info (`from:`,
     * `version:`, `select:`) AND a deployment-side hint that the
     * deployment-emitter folds into the production-default deployment
     * (`category:` + `advertises:` + `config:`). See `imports-graph.ts`
     * Phase 2 for the detection rules.
     */
    nonLibraryImportsByComponent?: Record<string, NonLibraryImportHint[]>;
    /**
     * Audit-trail decision log — one entry per walker class, including
     * methods that were filtered out + their drop reason. Populated when
     * `recordAuditDecisions !== false` in options. Foundation for the
     * `extract-decisions.json` sidecar (see
     * specverse-self/docs/plans/2026-05-03-PIPELINE-AUDIT-TRAIL-INSTRUMENTATION.md).
     */
    auditDecisions?: ExtractAuditDecisions;
}
export interface ExtractAuditDecisions {
    schemaVersion: '1.0';
    classes: Array<{
        className: string;
        filePath: string;
        decision: {
            walked: boolean;
            reason: string;
        };
        methodCount: {
            raw: number;
            kept: number;
        };
        methods: Array<{
            methodName: string;
            isAsync: boolean;
            sourceLineRange: [number, number];
            candidateKindHistogram: Record<string, number>;
            filter: MethodFilterDecision;
        }>;
    }>;
    /** Aggregate counters across all classes. */
    stats: {
        classesWalked: number;
        methodsRaw: number;
        methodsKept: number;
        methodsByDropReason: Record<string, number>;
        candidateStepLines: number;
        candidateStepKindHistogram: Record<string, number>;
    };
}
export interface RunPrepassOptions {
    /** Backend to use; defaults to 'auto' (CodeGraph if available, else grep-only). */
    backend?: BackendName;
    /** Pre-built backend instance (advanced; bypasses selectBackend). */
    prepass?: StructuralPrepass;
    /** Skip adapter selection and run only the named ones. Default = all detected. */
    adapters?: Array<'typescript-prisma'>;
    /** Run model-graph community detection to suggest component boundaries. Default true. */
    suggestComponents?: boolean;
    /**
     * Gather per-method fact sheets for entry-point methods (heuristic:
     * methods on `*Controller` / `*Service` classes, capped at `methodFactsCap`
     * total to keep prompt context bounded). Default true. Set to false to
     * skip — backends that don't implement deep `getMethodDetails` (or
     * codebases with no class structure) just produce an empty list.
     */
    gatherMethodFacts?: boolean;
    /** Maximum number of method fact sheets to gather. Default 30. */
    methodFactsCap?: number;
    /**
     * Run the behavior-step classifier (#27-B) on every entity class
     * detected by the typescript-decorators adapter. Produces
     * `facts.candidateMethods[]` — pre-classified per-method timelines
     * the analyse LLM can refine into spec `behaviors[].steps[]`. Default
     * true. Set to false when the caller doesn't need the timelines
     * (e.g. structure-only analysis, or to save time on huge codebases).
     */
    extractCandidateSteps?: boolean;
    /**
     * When true (default), populates `facts.auditDecisions` with per-class
     * walked/skipped + per-method drop-reason data for downstream
     * `extract-decisions.json` emission. Add a small overhead during
     * extraction (proportional to walker output size). See
     * specverse-self/docs/plans/2026-05-03-PIPELINE-AUDIT-TRAIL-INSTRUMENTATION.md.
     */
    recordAuditDecisions?: boolean;
    /**
     * When true (default), runs the typescript-interfaces walker (Phase C).
     * Extracts entities from raw TS class/interface/type declarations for
     * adapter-free codebases. Adapter-detected entities take precedence;
     * TS walker fills the gap.
     */
    extractInterfaces?: boolean;
    /**
     * Entity-shape heuristic for the typescript-interfaces walker.
     * 'liberal' (default): a declared type with `id` field is an entity.
     * 'conservative': also requires `createdAt`/`updatedAt` field.
     */
    entityShapeHeuristic?: 'liberal' | 'conservative';
    /**
     * When true (default), runs the naming-convention FK inference pass
     * after all structural adapters. Lifts `*_id` / `*Id` attributes to
     * belongsTo + reverse hasMany relationships when the prefix resolves
     * to a known entity. Closes the gap surfaced by PowerSync / hand-rolled
     * Drizzle / convention-only-FK codebases (engines 6.47.0).
     */
    inferNamingConventionFks?: boolean;
    /**
     * When true (default), runs the #91b view-layer reachability gate after
     * entity extraction. Drops TSI-extracted entities reachable ONLY from
     * frontend-app subtrees (view/render/editor types). No-op unless the
     * source has a genuine multi-package frontend/backend split.
     */
    gateViewOnlyEntities?: boolean;
    /**
     * When true (default), upgrades String-typed date attributes to `DateTime`
     * using SQL DDL column types + `*_at`/`*_date` name conventions (GUI Tier 2
     * date-picker fidelity).
     */
    refineDateTypes?: boolean;
    /**
     * When true (default), runs the #GUI-uplift part-2 view-precision pass:
     * drop UI primitives / layout / sub-component views and emit a renderable
     * `timeline` view when the source warrants one. Opt out with `false`.
     */
    refineViews?: boolean;
    /**
     * Attach mode (coexistence): query a STANDARD index in the global
     * `~/.gitnexus` registry read-only instead of building a private isolated
     * one — threaded to the GitNexus backend. The caller decides the index
     * already exists (`hasExistingGitnexusIndex`). Default false (isolate).
     */
    attach?: boolean;
    /**
     * Restrict extracted facts to these top-level subdirs (the `--scope` flag).
     * Applied after extraction (facts-layer) so it works even when attaching to
     * a full index. Default: no filter.
     */
    scope?: string[];
}
/**
 * Run the structural pre-pass on a source directory.
 *
 * Pipeline:
 *   1. Select / receive a backend (`StructuralPrepass`)
 *   2. Initialize + index the source dir
 *   3. Detect which adapters apply (e.g. schema.prisma exists → TS+Prisma)
 *   4. Run each detected adapter to extract framework-specific facts
 *   5. Merge facts into a single SpecVerse-vocabulary `SpecVerseFacts` object
 */
export declare function runPrepass(sourceDir: string, options?: RunPrepassOptions): Promise<SpecVerseFacts>;
/**
 * Drop reasons. Aligns with the audit-trail decision log
 * (`extract-decisions.json` per the 2026-05-03 instrumentation plan).
 */
export type MethodFilterReason = 'no-candidates-classified' | 'level-0-accessor' | 'level-1-curved-retrieve' | 'level-1-curved-create-update-delete' | 'container-op-or-self-delegation-only' | 'kept-business-action-strong-signal' | 'kept-multi-step-composition' | 'kept-multiple-external-calls';
export interface MethodFilterDecision {
    kept: boolean;
    reason: MethodFilterReason;
}
/**
 * Format a `SpecVerseFacts` object as a markdown block suitable for
 * injection into the analyse prompt's user template (mirrors the format
 * from the existing manually-extracted facts files used in §5/§6
 * experiments).
 */
export declare function formatFactsAsMarkdown(facts: SpecVerseFacts): string;
/**
 * Format the per-method fact-sheet list as a markdown block suitable for
 * injection into the verify-analyse prompt as `methodFacts`. Each method
 * gets a compact entry showing its signature + the deterministic facts
 * (calls / emits / dbWrites / externalCalls / throws / asyncBoundaries /
 * branchPoints) that the LLM can cross-check the analysed `steps:`
 * against. Body text is excluded — keeps the block small enough to fit
 * inside one verify-analyse call without paginating.
 *
 * TODO #32 — surfaces what `runPrepass` already computes but didn't expose.
 */
export declare function formatMethodFactsAsMarkdown(sheets: MethodFactSheet[] | undefined): string;
/**
 * Format the per-method candidate-step timelines (#27-B/C) as a
 * markdown block suitable for prompt injection. Output shape:
 *
 *   # Pre-classified candidate behavior steps
 *   ## EntityName (path/to/file.ts)
 *   ### methodName  (5 candidate steps)
 *   1. [find]      Find Customer by { id }
 *   2. [validate]  Throw NotFoundException
 *   3. [create]    Create Invoice
 *   ...
 *
 * The analyse LLM uses this as a STRUCTURAL ANCHOR — refining the
 * pre-classified timeline into spec `behaviors[].steps[]` blocks
 * rather than summarizing raw method bodies.
 *
 * Returns the empty string when `candidateMethods` is undefined or
 * empty — caller should `if (md) prompt += md` rather than
 * unconditionally embed.
 */
export declare function formatCandidateMethodsAsMarkdown(candidateMethods: SpecVerseFacts['candidateMethods']): string;
//# sourceMappingURL=index.d.ts.map