/**
 * Canonical graph query module. Per CLAUDE.md Rule 12, every consumer
 * (explore CLI subcommands, dashboard viz adapter, future 2.8 context
 * CLI, future 2.8 reachability) imports from here — never reimplements
 * graph traversal. Arch-check enforces.
 *
 * Sprint 1 ships the SKELETON: type signatures + empty implementations
 * so the canonical entry points exist for the arch rule to lock onto.
 * Sprint 2 fills the bodies as the explore CLI subcommands land.
 *
 * Every query is a pure function: takes a `Graph` (and optionally
 * other args), returns a typed result. No side effects, no I/O,
 * no caching — caching belongs at the loader level, not the query
 * level.
 */
import type { DetectedStack } from '../types';
import type { Graph, GraphNode } from './types';
/** Nodes that call into the given nodeId (predecessors via `calls` edges). */
export declare function callersOf(graph: Graph, nodeId: string): GraphNode[];
/** Nodes that the given nodeId calls into (successors via `calls` edges). */
export declare function calleesOf(graph: Graph, nodeId: string): GraphNode[];
/** All nodes declared in the given source file. */
export declare function nodesInFile(graph: Graph, sourceFile: string): GraphNode[];
/**
 * One row of `vyuh-dxkit explore hot-files` output. A "hot" file is
 * one many other files depend on (high total in-degree across all the
 * symbols it declares + inbound imports to the file's module node).
 *
 * - `callsIn`: count of `calls` edges terminating at any symbol in
 *   the file (summed across the file's function / class / method
 *   nodes)
 * - `importsIn`: count of `imports_from` edges terminating at the
 *   file's module node
 * - `callsOut`: count of `calls` edges originating from any symbol
 *   in the file
 * - `communityId` / `communityLabel`: the community the file's
 *   module node belongs to, when one exists; label is the
 *   community's dominantSourceDir for a quick visual anchor
 */
export interface HotFileResult {
    sourceFile: string;
    callsIn: number;
    importsIn: number;
    callsOut: number;
    communityId?: number;
    communityLabel?: string;
}
/**
 * Top-N files by total in-degree (callers + importers). The
 * "centrality" proxy — files many other files depend on. Useful as
 * a "what's the foundational layer of this repo?" answer.
 *
 * Files are derived from the union of `sourceFile` across all nodes;
 * the per-file aggregation traverses each node's inbound/outbound
 * edges. Limit defaults to 20 per the Sprint 0 spec.
 */
export declare function hotFilesQuery(graph: Graph, limit?: number): HotFileResult[];
/**
 * One row of `vyuh-dxkit explore communities` output. A community is
 * a Louvain-clustered grouping of nodes; the dominant source dir +
 * pack give the reader a visual anchor ("this is the auth stuff" /
 * "this is the bom layer").
 */
export interface CommunityResult {
    id: number;
    nodeCount: number;
    dominantSourceDir: string;
    dominantPack: string;
    cohesion: number;
    topHotFiles: string[];
}
/**
 * Top-N communities by node count, with each community's top-3 hot
 * files (by in-degree within the community). Gives a "what are the
 * natural modules in this repo?" answer that complements `hot-files`
 * (which is global).
 */
export declare function communitiesQuery(graph: Graph, limit?: number): CommunityResult[];
/**
 * One-symbol entry inside a file summary — a function / class /
 * method declared in the file plus its in/out call counts. Used by
 * the `explore file <path>` subcommand to show "here's what this
 * file declares + how it interconnects."
 */
export interface FileSymbolSummary {
    id: string;
    kind: 'function' | 'class' | 'method' | 'module';
    label: string;
    line?: number;
    exported?: boolean;
    callsIn: number;
    callsOut: number;
}
/**
 * Full summary for a single file: its symbols, its callers (deduped
 * to unique files for readability), its callees, its inbound and
 * outbound imports, and its community membership. Used by `explore
 * file <path>`.
 *
 * `callerFiles` / `calleeFiles` are deduped at the FILE level — if
 * 12 symbols from src/foo.ts call into this file's symbols, the
 * caller appears once in `callerFiles` with `count: 12`. The reader
 * usually wants "which files depend on me" not "every individual
 * call site" (which would scroll for pages on hot files).
 */
export interface FileSummary {
    sourceFile: string;
    found: boolean;
    symbols: FileSymbolSummary[];
    callerFiles: Array<{
        sourceFile: string;
        count: number;
    }>;
    calleeFiles: Array<{
        sourceFile: string;
        count: number;
    }>;
    importsIn: Array<{
        sourceFile: string;
    }>;
    importsOut: Array<{
        sourceFile: string;
    }>;
    communityId?: number;
    communityLabel?: string;
    communityPack?: string;
}
/**
 * Build the per-file summary. `found: false` when the file isn't in
 * the graph (excluded by minified detection / vendored / unsupported
 * extension); the consumer handles that case with an explanatory
 * note instead of an empty result.
 */
export declare function fileSummaryQuery(graph: Graph, sourceFile: string): FileSummary;
/**
 * One row of `vyuh-dxkit explore entry-points` output. An entry
 * point is a symbol declared in a source file whose path matches
 * one of the active packs' `architecturalShape.primaryComponentPaths`
 * or `routePaths` (per CLAUDE.md Rule 8 — these are pack-driven, no
 * hardcoded framework strings here).
 *
 * `componentType` carries the matched pattern label (e.g. `routes`,
 * `controllers`, `forms`) so the consumer can group by surface.
 * Sourced from the pack's `dominantVocabulary` when available, else
 * from the matched path segment.
 */
export interface EntryPointResult {
    sourceFile: string;
    line?: number;
    symbol: string;
    componentType: string;
    callsOut: number;
    pack: string;
}
/**
 * Discover entry-point symbols by intersecting graph nodes with the
 * union of active packs' `primaryComponentPaths` + `routePaths`. The
 * rank is by call out-degree — entry points typically fan OUT (they
 * receive a request, then call many downstream functions). A high
 * out-degree node in a primary-architecture path is almost certainly
 * a real entry point.
 *
 * `flags` is the per-pack boolean map from `DetectedStack.languages`;
 * only patterns from active packs contribute. This matches the
 * existing pack-driven analyzer pattern.
 */
export declare function entryPointsQuery(graph: Graph, primaryPaths: ReadonlyArray<string>, routePaths: ReadonlyArray<string>, limit?: number): EntryPointResult[];
export type LanguageFlags = DetectedStack['languages'];
/**
 * One row of `vyuh-dxkit explore api-surface` output. An "API surface"
 * symbol is one that the language pack identifies as exported AND has
 * zero internal callers (no other file in the graph calls into it).
 *
 * Typically this set falls into three buckets:
 *   - Genuine public API (library entry points, named exports)
 *   - CLI entry points (legitimately not internally imported)
 *   - Dead exports (false positives surfaced honestly)
 *
 * The consumer should verify before treating any as dead code.
 */
export interface ApiSurfaceResult {
    sourceFile: string;
    line?: number;
    symbol: string;
    kind: 'function' | 'class' | 'method' | 'module';
    pack: string;
}
/**
 * Find exported symbols with zero internal callers. `packsExcluded`
 * lists pack ids whose `exportDetection.reliability === 'unreliable'`
 * — those packs' nodes are skipped because we can't trust their
 * `exported` flag (today: ruby). The consumer surfaces the exclusion
 * as a note in its output.
 */
export declare function apiSurfaceQuery(graph: Graph, packsExcluded: ReadonlyArray<string>, limit?: number): ApiSurfaceResult[];
/**
 * Options for `featureQuery`. `substring` enables the noisier
 * keyword-substring expansion (off by default per Sprint 0 spec —
 * false-positive prone for short keywords).
 */
export interface FeatureQueryOpts {
    substring?: boolean;
    limit?: number;
}
/**
 * A clustering of symbols that look like they implement one feature.
 * The community membership is the structural backbone — symbols in
 * the same community are tightly coupled by definition. The role
 * label comes from the community's dominantPack/dominantSourceDir
 * + per-pack vocabulary when available.
 */
export interface FeatureCluster {
    clusterId: number;
    communityId?: number;
    role: string;
    dominantSourceDir: string;
    files: string[];
    keySymbols: string[];
    seedHits: number;
}
/**
 * Full result of a feature query. `results` is non-empty when at
 * least one symbol matched the keyword; `suggestions` is populated
 * only when `results` is empty (edit-distance ≤2 against the
 * symbolIndex keys, top-3). `centralEntryPoint` names the highest
 * call-in-degree node across all clusters when results were found
 * — the natural "if you only look at one file, look here" anchor.
 */
export interface FeatureResult {
    results: FeatureCluster[];
    suggestions: Array<{
        key: string;
        hits: number;
    }>;
    centralEntryPoint?: {
        sourceFile: string;
        line?: number;
        symbol: string;
        calledFrom: number;
    };
}
/**
 * The marquee query — "where is feature X implemented?" Three-stage
 * resolution:
 *
 *   1. Direct symbolIndex lookup (case-insensitive, exact match on
 *      the stripped name)
 *   2. Substring expansion (opt-in via opts.substring) — scans every
 *      node's label for substring match
 *   3. Structural expansion — for each seed, gather community
 *      membership + immediate callers + callees, group by community
 *
 * On zero hits, computes edit-distance suggestions against the
 * symbolIndex keys so the caller can prompt the user with "did you
 * mean..."
 */
export declare function featureQuery(graph: Graph, keyword: string, opts?: FeatureQueryOpts): FeatureResult;
/**
 * Options for `contextQuery`. `budget` is the soft token ceiling on
 * the rendered output (BFS stops adding nodes once the running
 * estimate would exceed it). `tokensPerNode` is the per-symbol render
 * cost estimate the budget math uses — tuned to roughly match one
 * markdown line like "- `foo()` src/a.ts:42 (5 in / 3 out)". `maxDepth`
 * is an optional HARD ceiling on BFS hops for power users; default is
 * budget-bounded only (adaptive depth).
 */
export interface ContextQueryOpts {
    substring?: boolean;
    budget?: number;
    tokensPerNode?: number;
    maxDepth?: number;
}
/** One symbol in the budget-bounded selection. */
export interface ContextNode {
    id: string;
    symbol: string;
    sourceFile: string;
    line?: number;
    kind: GraphNode['kind'];
    /** 0 = seed (matched the query), 1 = direct neighbor, 2 = … */
    hop: number;
    callsIn: number;
    callsOut: number;
}
/** Community grouping of the selection, for orientation. */
export interface ContextCommunityGroup {
    communityId?: number;
    role: string;
    files: string[];
    symbols: string[];
}
/**
 * Result of a context query — a slim, ranked, budget-bounded subgraph
 * built for injection into an LLM's context window (or a human's
 * terminal). The formatter (`src/explore/format.ts`) turns this into
 * markdown / JSON; this function owns only the graph work + budget
 * math (Rule 12).
 *
 * `selection` is BFS-ordered: seeds first (hop 0), then their direct
 * neighbors (hop 1), then hop 2, … — so the most relevant symbols
 * survive when the budget truncates the tail. `anchor` is the
 * highest call-in-degree seed ("if you read one thing, read this").
 * `blastRadius` counts unique callers of the SEEDS (the symbols a
 * change would touch). `suggestions` is populated only when nothing
 * matched (the did-you-mean path). `truncated` + `omittedCount`
 * drive the formatter's honest "+N more …" footer.
 */
export interface ContextResult {
    query: string;
    matched: boolean;
    anchor?: {
        sourceFile: string;
        line?: number;
        symbol: string;
        calledFrom: number;
    };
    selection: ContextNode[];
    byCommunity: ContextCommunityGroup[];
    blastRadius: {
        callers: number;
        callerFiles: number;
    };
    truncated: boolean;
    omittedCount: number;
    estimatedTokens: number;
    budget: number;
    suggestions: Array<{
        key: string;
        hits: number;
    }>;
}
/**
 * The marquee token-reduction primitive — "give me just the relevant
 * structural slice for this query." Resolves seeds the same way
 * `featureQuery` does (shared `findSeedIds`), then expands breadth-
 * first through `calls` edges, stopping when the running token
 * estimate fills the budget (or an optional `maxDepth` ceiling is
 * reached). Adaptive depth falls out for free: a hot symbol's
 * immediate neighbors fill the budget at hop 1, while a cold symbol's
 * sparse neighborhood leaves room to reach hop 2+.
 *
 * Pure: no I/O, no formatting. Same `Graph` in → same `ContextResult`
 * out.
 */
export declare function contextQuery(graph: Graph, keyword: string, opts?: ContextQueryOpts): ContextResult;
/**
 * Graph context for a single analyzer finding (a security vuln, a
 * test-gap source file, a quality offender) located at `sourceFile`
 * (+ an optional `line`). Built for the enrichment pass that decorates
 * detailed reports: a fixing agent reading a finding sees its
 * structural blast radius + module membership inline, without running
 * the `context` command itself.
 *
 * `found: false` when the file isn't in the graph (excluded as
 * vendored / autogenerated / minified, an unsupported extension, or
 * simply not parsed by graphify). Consumers degrade gracefully —
 * attach nothing.
 *
 * `blastRadius` is FILE-level: unique caller files / caller symbols
 * across every symbol the file declares — the surface a change to this
 * file would touch. File-level is the robust signal; graphify can
 * conflate same-name symbols across files, so per-symbol caller counts
 * are noisier. `enclosingSymbol` is a labeled best-effort for the
 * symbol the finding sits inside.
 */
export interface FindingContext {
    found: boolean;
    sourceFile: string;
    community?: {
        id?: number;
        role: string;
    };
    blastRadius: {
        callerFiles: number;
        callers: number;
        topCallerFiles: string[];
    };
    /**
     * Trust level of `blastRadius` for this file's language, stamped by
     * the enrichment adapter (not the pure query — `queries.ts` stays
     * independent of the language registry). `'unreliable'` means
     * graphify can't resolve this language's call edges (today: C#
     * cross-assembly `using`), so a 0 here is NOT evidence of "no callers"
     * and the renderer suppresses the number. Absent ⇒ treated as `'full'`.
     */
    callGraphReliability?: 'full' | 'partial' | 'unreliable';
    /**
     * Best-effort symbol the finding sits inside: the declaration
     * nearest at-or-above `line`. Absent when no `line` was given or the
     * file declares no symbol at-or-above the line. Graph nodes carry
     * only a declaration line (no end line), so this is a heuristic — a
     * finding can sit below the last symbol's declaration yet outside it.
     * Labeled as best-effort so consumers report it honestly.
     */
    enclosingSymbol?: {
        symbol: string;
        line?: number;
    };
}
/**
 * Graph context for one finding location. Reuses `fileSummaryQuery`
 * for the file-level caller aggregation + community lookup (Rule 2 —
 * one source of truth for "who depends on this file"), then maps an
 * optional `line` to the nearest enclosing declaration.
 *
 * Pure: same `Graph` + location in → same `FindingContext` out. The
 * enrichment adapter (`src/explore/finding-context.ts`) owns the
 * graph load, the per-finding loop, and the dedupe budget.
 */
export declare function findingContextQuery(graph: Graph, sourceFile: string, line?: number, opts?: {
    topCallerFiles?: number;
}): FindingContext;
/**
 * Structural context for one source location, resolved by POSITION
 * rather than by symbol name (the `context <file:line>` surface; its
 * sibling `contextQuery` resolves by keyword). The CLI pairs this with
 * the actual source slice read from disk — the graph carries no source
 * text — to hand a coding agent a focused chunk instead of a whole
 * file.
 *
 * `enclosingSymbol` is the declaration nearest at-or-above `line`;
 * `span` bounds that symbol's body as `[startLine, endLineExclusive)`
 * where `endLineExclusive` is the next declaration in the file (the
 * slice runs to EOF when the symbol is the last one). Both are
 * best-effort: graph nodes store only a declaration line, so a nested
 * or sibling boundary can be off — consumers label it as a heuristic.
 *
 * `found: false` when the file isn't in the graph (vendored /
 * autogenerated / unsupported / simply unparsed); the CLI still
 * delivers a centered raw-line window as a fallback.
 */
export interface FileLineContext {
    found: boolean;
    sourceFile: string;
    enclosingSymbol?: {
        id: string;
        symbol: string;
        line: number;
        kind: GraphNode['kind'];
        callsIn: number;
        callsOut: number;
    };
    span?: {
        startLine: number;
        endLineExclusive?: number;
    };
    callers: Array<{
        symbol: string;
        sourceFile: string;
        line?: number;
    }>;
    callees: Array<{
        symbol: string;
        sourceFile: string;
        line?: number;
    }>;
    community?: {
        id?: number;
        role: string;
    };
    blastRadius: {
        callerFiles: number;
        callers: number;
    };
    /**
     * Trust level of `blastRadius` for this file's language, stamped by
     * the CLI (not this pure query — `queries.ts` stays independent of the
     * language registry, Rule 6). `'unreliable'` ⇒ graphify can't resolve
     * the call edges (C# cross-assembly), so a 0 is NOT "no callers" and
     * the renderer suppresses the number. Absent ⇒ treated as `'full'`.
     */
    callGraphReliability?: 'full' | 'partial' | 'unreliable';
}
/**
 * Resolve the structural neighborhood of a `file:line` location. Reuses
 * `fileSummaryQuery` for the file-level blast radius + community (Rule 2
 * — one source of truth for "who depends on this file") and the
 * `callersOf` / `calleesOf` primitives for the enclosing symbol's direct
 * edges. Pure: same `Graph` + location in → same `FileLineContext` out.
 */
export declare function fileLineContextQuery(graph: Graph, sourceFile: string, line: number, opts?: {
    maxList?: number;
}): FileLineContext;
//# sourceMappingURL=queries.d.ts.map