import type { StructuralPrepass, Symbol, Import, FileFilter, ClassFilter, MethodFilter, InterfaceFilter, IndexResult, MethodFactSheet } from '../interface.js';
export interface GitNexusBackendOptions {
    /** Path to the gitnexus binary. Auto-detected via PATH if omitted. */
    gitnexusPath?: string;
    /** Skip running `gitnexus analyze` if .gitnexus/ already exists. */
    reuseExistingIndex?: boolean;
    /**
     * Override `GITNEXUS_HOME` — the directory gitnexus uses for its
     * global registry (`<dir>/registry.json`). By default we create a
     * per-invocation temp dir under `os.tmpdir()` so concurrent
     * `spv ai analyse` invocations don't race on `~/.gitnexus/registry.json`
     * (the 2026-05-14 9-cell matrix surfaced this race —
     * `docs/proposals/2026-05-14-GITNEXUS-PREPASS-CONCURRENCY.md`).
     *
     * NOTE: the env var gitnexus actually honours is `GITNEXUS_HOME`
     * (`process.env.GITNEXUS_HOME || ~/.gitnexus`); `GITNEXUS_DIR` is only
     * a hardcoded constant inside gitnexus for the per-repo `.gitnexus`
     * subdir name and is NOT read from the environment. Setting the wrong
     * one (the pre-2026-05-26 bug) made this isolation a no-op and leaked
     * every run into the real `~/.gitnexus/registry.json`.
     *
     * Pass an explicit path to share state across invocations (e.g.
     * tests, or callers that want to inspect the registry afterwards).
     * Pass `'inherit'` to fall back to gitnexus's default
     * (`~/.gitnexus/`) — useful when you explicitly want the global
     * registry, accepting the concurrency risk.
     *
     * Ignored in `attach` mode, which always uses the global registry.
     */
    gitnexusHome?: string;
    /**
     * Attach mode (coexistence): operate against a STANDARD index in the
     * **global** `~/.gitnexus` registry rather than a private isolated one —
     * so SpecVerse shares the same index the user's own gitnexus / MCP / IDE
     * use, instead of colliding with or duplicating it.
     *
     * In attach mode `init()` resolves the repo's *registered* name (not the
     * `<parent>-<basename>-<hash>` isolation name), registers an unregistered
     * on-disk `.gitnexus/` via `gitnexus index` (no re-analysis), and SKIPS
     * `analyze` (read-only). The caller is responsible for deciding the index
     * already exists (or for creating a standard one first — P2b). Default
     * `false` = the isolated per-run flow (batch / concurrent-safe).
     */
    attach?: boolean;
}
export declare class GitNexusBackend implements StructuralPrepass {
    private sourceDir;
    /**
     * Canonical repo name as registered in `~/.gitnexus/registry.json`.
     * Resolved by `init()` from the registry; passed as `--repo <name>`
     * to every `gitnexus cypher` call so multi-repo registries don't
     * cross-contaminate query results.
     */
    private repoName;
    private gitnexusPath;
    private reuseExistingIndex;
    /** Attach mode — share the global standard index instead of isolating. */
    private readonly attach;
    /**
     * Per-invocation `GITNEXUS_HOME`. Threaded into every `gitnexus`
     * subprocess via `env:` so this backend's registry-state is isolated
     * from concurrent invocations. `null` means "don't set GITNEXUS_HOME"
     * (inherit gitnexus's default).
     */
    private readonly gitnexusHome;
    capabilities: {
        callGraph: boolean;
        crossFileResolution: boolean;
        componentClustering: boolean;
        fullTextSearch: boolean;
        fileWatching: boolean;
        routeExtraction: boolean;
        implementsExtraction: boolean;
        validationSchemaExtraction: boolean;
        processExtraction: boolean;
    };
    constructor(options?: GitNexusBackendOptions);
    /**
     * Build the env to thread into every `gitnexus` subprocess. Sets
     * `GITNEXUS_HOME` to the per-invocation dir (registry isolation);
     * otherwise inherits. `GITNEXUS_HOME` is the var gitnexus reads for its
     * global-registry location — NOT `GITNEXUS_DIR` (a no-op env name).
     */
    private execEnv;
    static isAvailable(): boolean;
    init(sourceDir: string): Promise<void>;
    /**
     * Resolve a sourceDir to its canonical gitnexus repo name by reading
     * `~/.gitnexus/registry.json`. Falls back to the dir's basename if the
     * registry isn't readable or has no matching entry — but a basename
     * fallback is unsafe in multi-repo registries (it can collide with
     * another project that happens to have the same dir name), so we log
     * a warning to stderr in that case.
     */
    private resolveRepoName;
    index(): Promise<IndexResult>;
    listFiles(filter?: FileFilter): Promise<string[]>;
    listClasses(filter?: ClassFilter): Promise<Symbol[]>;
    listMethods(filter?: MethodFilter): Promise<Symbol[]>;
    listInterfaces(filter?: InterfaceFilter): Promise<Symbol[]>;
    listImports(file: string): Promise<Import[]>;
    fileSourceText(file: string): Promise<string>;
    callers(symbol: string): Promise<Symbol[]>;
    callees(symbol: string): Promise<Symbol[]>;
    /**
     * Cluster files via GitNexus's Leiden community detection.
     * This is the distinguishing feature vs CodeGraph — surfaces natural
     * component boundaries for SpecVerse `components:` inference.
     *
     * GitNexus's edge model: a single `CodeRelation` table with a `type`
     * property — relationship discrimination happens via WHERE on that
     * property, not by edge label. Community membership is `MEMBER_OF`.
     *
     * Note: GitNexus's MEMBER_OF connects symbols (not files directly) to
     * communities. We aggregate per-community by filePath of the member symbols.
     */
    clusterFiles(): Promise<Array<{
        id: string;
        files: string[];
    }>>;
    /**
     * Engines 6.30.0+ — TODO #51 phase 1.
     * Native query against GitNexus's Route nodes + HANDLES_ROUTE edges.
     * Each Route has filePath + httpVerb + path properties; the handler is
     * resolved via the HANDLES_ROUTE edge. responseKeys / errorKeys /
     * middleware are populated when GitNexus's handler-shape detector fires.
     */
    listRoutes(): Promise<NonNullable<StructuralPrepass['listRoutes']> extends () => Promise<infer T> ? T : never>;
    /**
     * Engines 6.30.0+ — TODO #51 phase 2.
     * Native query against GitNexus's IMPLEMENTS edges (Class → Interface).
     */
    listImplementsRelationships(): Promise<NonNullable<StructuralPrepass['listImplementsRelationships']> extends () => Promise<infer T> ? T : never>;
    /**
     * Engines 6.30.0+ — TODO #51 phase 3.
     * Native query against GitNexus's Const nodes whose name suggests a
     * validation schema (Zod/Yup/Joi). The adapter parses `content` for
     * library-specific shape extraction.
     */
    listConstSchemas(): Promise<NonNullable<StructuralPrepass['listConstSchemas']> extends () => Promise<infer T> ? T : never>;
    /**
     * Engines 6.30.0+ — TODO #51 phase 4.
     * Native query against GitNexus's Process nodes + STEP_IN_PROCESS edges.
     * Each process is a heuristic-labelled execution flow. We return them
     * with steps in order; adapters filter by stepCount and processType.
     */
    listProcesses(): Promise<NonNullable<StructuralPrepass['listProcesses']> extends () => Promise<infer T> ? T : never>;
    /**
     * GitNexus's call graph traversal — same `CodeRelation` table pattern
     * as MEMBER_OF, with `type='CALLS'` as the discriminating property.
     * (Override the default callers/callees from the parent class above
     * because the relation type isn't `:CALLS` — it's `:CodeRelation` with
     * a property filter.)
     */
    getMethodDetails(qualifiedName: string): Promise<MethodFactSheet | null>;
    /**
     * Run a Cypher query via the `gitnexus cypher` CLI and parse the
     * markdown-table output into a row array. Each row is a map of
     * column name → value (string, number, or array depending on Cypher).
     *
     * Passes `--repo <name>` to disambiguate when multiple repos are
     * registered globally. The name comes from `~/.gitnexus/registry.json`
     * (resolved by `init()`), NOT the basename of sourceDir — the basename
     * is unsafe because gitnexus derives the registered name from the git
     * remote / package.json, which usually differs from the dir name
     * (e.g. clones into `./source/` register as `nestjs-realworld-example-app`).
     */
    private cypher;
    private rowToSymbol;
    private mapLabel;
    private toRelativePath;
    private escape;
    private detectBinary;
}
/**
 * Extract the basename of a sourceDir for fallback-naming. `/foo/bar/source/`
 * → `source`. Empty path → `source` (the gitnexus default for unnamed dirs).
 */
export declare function basenameOrSource(sourceDir: string): string;
/**
 * True if `sourceDir` already has a STANDARD gitnexus index — either a
 * `.gitnexus/` store on disk OR a matching entry in the global
 * `~/.gitnexus/registry.json`. Lets the analyse front-end decide whether to
 * ATTACH read-only (coexistence) vs create/isolate a fresh index.
 */
export declare function hasExistingGitnexusIndex(sourceDir: string): boolean;
/**
 * Pure-function version of the registry-lookup logic — takes the registry
 * file content + the sourceDir and returns the canonical name (or null if
 * not found, plus an optional warning). Exported for unit testing without
 * needing gitnexus installed or a real ~/.gitnexus directory.
 *
 * Match order:
 *   1. Exact `path === sourceDir`
 *   2. `storagePath` is inside sourceDir (handles symlink-resolved paths)
 */
export declare function resolveRepoNameFromRegistry(registryContent: string, sourceDir: string): {
    name: string | null;
    warning: string | null;
};
//# sourceMappingURL=gitnexus.d.ts.map