/** * Canonical shared types for the SuPi code-understanding stack. * * These types are package-agnostic and used across supi-lsp, supi-tree-sitter, * and supi-code-intelligence for communicating code analysis results, * capability availability, and structural data shapes. */ // ── Position and location types ──────────────────────────────────────── /** 0-based LSP position. */ export interface CodePosition { line: number; character: number; } /** A source range spanning two CodePositions. */ export interface SourceRange { start: CodePosition; end: CodePosition; } /** A code location (file URI + range). */ export interface CodeLocation { uri: string; range: SourceRange; } // ── Symbol types ─────────────────────────────────────────────────────── /** A 1-based source position used as a symbol anchor. */ export interface SymbolAnchor { line: number; character: number; } /** Provider-backed nesting evidence for a declaration reported within one document. */ export type DeclarationNesting = "top-level" | "nested" | "unknown"; /** * A discovered symbol / declaration. * * Per ADR 0003, anchors are split so position-strict substrates * (structural callee lookup, LSP `rename`) cannot silently consume a * declaration anchor (the `export` keyword) as if it were the identifier. * - `declarationAnchor` is always present (the defining node start). * - `nameAnchor` is best-effort (the identifier token), present when the * provider can derive it (LSP `selectionRange`, or a tree-sitter snap). * Strict consumers must prefer it and hard-fail when it is absent. */ export interface CodeSymbol { name: string; kind: string; file: string; declarationAnchor: SymbolAnchor; nameAnchor?: SymbolAnchor; /** Named symbolic container when reported; absence does not prove top-level nesting. */ container?: string | null; } /** * A document-scoped declaration with explicit hierarchy evidence. * * `unknown` means the provider returned a flat observation without an actual * hierarchy. A reported container name remains metadata and does not promote * a flat observation to known nesting. */ export interface DocumentCodeSymbol extends CodeSymbol { nesting: DeclarationNesting; } // ── Result types ─────────────────────────────────────────────────────── /** * Discriminated result union for provider operations. * * Used primarily by structural (tree-sitter-backed) operations that * have explicit error and unsupported-language states. Semantic operations * use `null` to signal absence. */ export type CodeResult = | { kind: "success"; data: T } | { kind: "unsupported-language"; file: string; message: string } | { kind: "file-access-error"; file: string; message: string } | { kind: "validation-error"; message: string } | { kind: "runtime-error"; message: string } | { kind: "unavailable"; message: string }; /** Result confidence classification. */ export type ConfidenceMode = "semantic" | "structural" | "heuristic" | "unavailable"; // ── Structural data shapes (value types, range-flattened) ────────────── export interface OutlineData { name: string; kind: string; startLine: number; startCharacter: number; endLine: number; endCharacter: number; children?: OutlineData[]; } export interface ExportData { name: string; kind: string; startLine: number; startCharacter: number; endLine: number; endCharacter: number; moduleSpecifier?: string; } export interface ImportData { moduleSpecifier: string; startLine: number; startCharacter: number; endLine: number; endCharacter: number; } export interface NodeAtData { type: string; startLine: number; startCharacter: number; endLine: number; endCharacter: number; text: string; ancestry: Array<{ type: string; startLine: number; startCharacter: number; endLine: number; endCharacter: number; }>; } // ── Refactor types ─────────────────────────────────────────────────── /** * A single file edit within a workspace edit. */ export interface FileEdit { /** Absolute file path */ file: string; /** The source range to replace */ range: SourceRange; /** The new text to insert */ newText: string; } /** A document-state precondition established when semantic edits are normalized. */ export type DocumentEditPrecondition = | { file: string; kind: "open-document-version"; version: number } | { file: string; kind: "disk-content" }; /** * A precise workspace edit — one or more file edits to apply atomically. */ export interface WorkspaceEdit { edits: FileEdit[]; /** Document state that the semantic provider validated before it made this plan. */ documentPreconditions?: DocumentEditPrecondition[]; } /** * Supported refactor operation names for the current semantic planning path. */ export type RefactorOperation = | "rename_symbol" | "extract_function" | "extract_variable" | "rename_file" | "move_file" | "update_imports" | "delete_dead_code"; /** * Operation-aware refactor planning request. * * Consumers provide a target file/position plus operation-specific options. * File/resource operations remain requestable so providers can reject them * explicitly and honestly until shared workspace-edit resource ops exist. */ export interface RefactorRequest { operation: RefactorOperation; file: string; position: CodePosition; range?: SourceRange; newName?: string; destination?: string; } /** * A disambiguation candidate when a refactor target is ambiguous. */ export interface DisambiguationCandidate { description: string; file?: string; line?: number; character?: number; } /** * Result of a refactor operation. * * - `precise`: exact edits available for safe direct apply * - `ambiguous`: multiple candidates, caller must disambiguate * - `unavailable`: refactoring not possible */ export type RefactorResult = | { kind: "precise"; edits: WorkspaceEdit; /** Provider roots authorized by the semantic route. Consumers canonicalize before storage. */ authorizedMutationRoots: string[]; } | { kind: "ambiguous"; candidates: DisambiguationCandidate[] } | { kind: "unavailable"; reason: string }; // ── Structural data shapes (value types, range-flattened) ────────────── /** Callee collection depth. */ export type CalleeDepth = "direct" | "deep"; /** * Structural outgoing calls from the enclosing executable scope at a * position. Callee names are source-shape facts, not resolved symbol * identities. * * In `direct` depth, nested function/callback scopes are excluded from the * outer scope. In `deep` depth, all callees within the enclosing scope are * included, including those inside nested scopes. */ export interface CalleesData { enclosingScope: { name: string; startLine: number; endLine: number }; /** Distinct call sites with 1-based UTF-16 start coordinates. */ callees: Array<{ name: string; /** Optional syntax-shortened label for presentation; does not replace `name`. */ displayName?: string; startLine: number; startCharacter: number; }>; depth: CalleeDepth; } /** A single call-site match with name and start line. */ export interface CallSite { name: string; startLine: number; }