import { z } from 'zod';
import { GitRangeModeSchema } from '../../git/types.js';
import { EntityDiagnosticSchema, EntityKindSchema } from './types.js';
/**
 * The public entity-intelligence contract.
 *
 * Inputs are Zod schemas because they arrive from a CLI parser or an MCP client
 * and must be validated at the boundary. Results are plain types: OCC
 * constructs them itself, so a schema there would only re-check its own work.
 */
export const OccEntityQuerySchema = z.object({
    name: z.string().min(1),
    relativePath: z.string().optional(),
    kind: EntityKindSchema.optional(),
    ref: z.string().optional(),
});
/**
 * A durable lineage handle as an *input*.
 *
 * The version prefix is part of the pattern so a handle minted under a future
 * `ENTITY_LINEAGE_ID_VERSION` still parses here and can be refused with a
 * precise `lineage-version-mismatch` instead of a generic validation error —
 * staleness is detectable from the string alone, and the resolver must get the
 * chance to say so.
 */
export const OccEntityLineageHandleSchema = z.object({
    lineageId: z.string().regex(/^ent\d+:[0-9a-f]{32}$/),
    ref: z.string().optional(),
});
export const OccEntityErrorCodeSchema = z.enum([
    'invalid-ref',
    'invalid-input',
    'invalid-path',
    'path-escape',
    'not-a-repo',
    'git-failed',
    'unsupported-language',
    'aborted',
    'budget-exceeded',
]);
// ---------------------------------------------------------------------------
// search
// ---------------------------------------------------------------------------
export const OccEntitySearchOptionsSchema = z.object({
    limit: z.number().int().positive().optional(),
    kind: EntityKindSchema.optional(),
    relativePath: z.string().optional(),
    /** Include entities extracted from data formats (JSON, YAML, TOML, CSV, Markdown). */
    formats: z.boolean().optional(),
    includeTests: z.boolean().optional(),
    /**
     * Subsequence-match the query (camelCase-aware) instead of substring
     * matching. Exact-name precedence is preserved; within the fuzzy tier,
     * results order by match quality instead of name length.
     */
    fuzzy: z.boolean().optional(),
});
// ---------------------------------------------------------------------------
// diff
// ---------------------------------------------------------------------------
export const OccEntityDiffOptionsSchema = z.object({
    base: z.string().optional(),
    head: z.string().optional(),
    staged: z.boolean().optional(),
    relativePath: z.string().optional(),
    maxEntities: z.number().int().positive().optional(),
    /**
     * How `base` and `head` are compared.
     *
     * `merge-base` (the default) reports what `head` added since it diverged from
     * `base` — the review-shaped question. `exact` reports what differs between
     * exactly those two revisions, including changes unique to `base`. A bare
     * tree endpoint is always exact, because a tree has no ancestry. When two
     * commit endpoints have no merge base, OCC also falls back to their exact
     * trees and reports a two-dot range rather than requiring shared ancestry.
     */
    rangeMode: GitRangeModeSchema.optional(),
    /**
     * Include data-format entities (JSON, YAML, TOML, CSV, Markdown).
     *
     * Defaults to whatever the session was built with, or `true` standalone. On a
     * docs-heavy range the heading churn of a rewritten changelog can bury every
     * code change, and this is the only way to say so on the cache-free path.
     */
    formats: z.boolean().optional(),
});
// ---------------------------------------------------------------------------
// authoritative whole-diff semantics
// ---------------------------------------------------------------------------
/**
 * Decoder for current and persisted whole-diff proof receipts. V1 is unsafe
 * for positive semantic-no-op decisions; V1-V3 remain decodable so consumers
 * can reject or migrate them explicitly instead of losing their provenance.
 */
export const OccWholeDiffProofSchema = z.enum([
    'whole-file-cst-v1',
    'whole-file-cst-v2',
    'whole-file-cst-v3',
    'whole-file-cst-v4',
]);
// ---------------------------------------------------------------------------
// impact
// ---------------------------------------------------------------------------
export const OccEntityImpactScopeSchema = z.enum(['deps', 'dependents', 'tests', 'all']);
export const OccEntityImpactOptionsSchema = z.object({
    scope: OccEntityImpactScopeSchema.optional(),
    /** Graph hops to follow; `0` means unbounded. */
    depth: z.number().int().nonnegative().optional(),
    maxEntities: z.number().int().positive().optional(),
    /** Verified source lines on either side of each returned entity reference. */
    inlineContext: z.number().int().nonnegative().optional(),
});
// ---------------------------------------------------------------------------
// blame
// ---------------------------------------------------------------------------
export const OccEntityBlameOptionsSchema = z.object({
    relativePath: z.string().min(1),
    ref: z.string().optional(),
    /**
     * Look outside the indexed commit window for entities it does not cover.
     *
     * Default true. One bounded `git log --follow` per file, so a whole file's
     * blame pays for it once; pass `false` for the cheapest possible answer at the
     * cost of reporting `outside-window` where attribution exists.
     */
    walkBack: z.boolean().optional(),
});
export const OccEntityBlameStateSchema = z.enum([
    'committed',
    'working-tree-modified',
    'uncommitted',
    'untracked',
    'no-history',
    /**
     * The entity has history, and it is further back than OCC looked.
     *
     * Distinct from `no-history`, which claims there is nothing to find. Reporting
     * a bound as an absence is the same class of error as reporting it as a dirty
     * working tree.
     */
    'outside-window',
    'shallow-history',
]);
// ---------------------------------------------------------------------------
// history
// ---------------------------------------------------------------------------
export const ENTITY_HISTORY_DEFAULT_LIMIT = 20;
export const ENTITY_HISTORY_MAX_LIMIT = 100;
export const OccEntityHistoryOptionsSchema = z.object({
    limit: z.number().int().positive().max(ENTITY_HISTORY_MAX_LIMIT).optional(),
    ref: z.string().optional(),
    /** Look outside the indexed commit window when it holds no events. Default true. */
    walkBack: z.boolean().optional(),
});
// ---------------------------------------------------------------------------
// context
// ---------------------------------------------------------------------------
export const ENTITY_CONTEXT_DEFAULT_BUDGET = 8000;
export const OccEntityContextRoleSchema = z.enum([
    'target',
    'direct_dependency',
    'transitive_dependency',
    'direct_dependent',
    'transitive_dependent',
]);
export const OccEntityContextDirectionSchema = z.enum(['deps', 'dependents']);
export const OccEntityContextOptionsSchema = z.object({
    tokenBudget: z.number().int().positive().optional(),
    /** Graph hops to follow; `0` means unbounded. */
    hops: z.number().int().nonnegative().optional(),
    tokenizer: z.string().optional(),
    /**
     * Which directions to traverse. Defaults to both.
     *
     * What a reader needs before changing an entity is usually mostly callees —
     * the constant it reads, the helper it delegates to — so both are included by
     * default and dependencies win the first hop when the budget is tight.
     */
    include: z.array(OccEntityContextDirectionSchema).nonempty().optional(),
    /** Verified source lines on either side of each bundled entity. */
    inlineContext: z.number().int().nonnegative().optional(),
});
/** Why a session no longer describes the repository in front of it. */
export const OccEntityStalenessReasonSchema = z.enum(['head-moved', 'working-tree-changed']);
export const EntityDiagnosticsSchema = z.array(EntityDiagnosticSchema);
/**
 * Re-exported because `OccEntityDiffOptions.rangeMode` embeds it.
 *
 * A consumer validating a diff request needs the enum, and reaching past this
 * module into the git layer for one member of a contract stated here would make
 * the entity API only nearly self-describing.
 */
export { GitRangeModeSchema };
//# sourceMappingURL=api-types.js.map