import type { ptree } from "@oh-my-pi/pi-utils"; import * as z from "zod/v4"; export declare const lspSchema: z.ZodObject<{ action: z.ZodEnum<{ capabilities: "capabilities"; code_actions: "code_actions"; definition: "definition"; diagnostics: "diagnostics"; hover: "hover"; implementation: "implementation"; references: "references"; reload: "reload"; rename: "rename"; rename_file: "rename_file"; request: "request"; status: "status"; symbols: "symbols"; type_definition: "type_definition"; }>; file: z.ZodOptional; line: z.ZodOptional; symbol: z.ZodOptional; query: z.ZodOptional; new_name: z.ZodOptional; apply: z.ZodOptional; timeout: z.ZodOptional; payload: z.ZodOptional; }, z.core.$strip>; export type LspParams = z.infer; export interface LspToolDetails { serverName?: string; action: string; success: boolean; request?: LspParams; } export interface Position { line: number; character: number; } export interface Range { start: Position; end: Position; } export interface Location { uri: string; range: Range; } export interface LocationLink { originSelectionRange?: Range; targetUri: string; targetRange: Range; targetSelectionRange: Range; } export type DiagnosticSeverity = 1 | 2 | 3 | 4; export interface DiagnosticRelatedInformation { location: Location; message: string; } export interface Diagnostic { range: Range; severity?: DiagnosticSeverity; code?: string | number; codeDescription?: { href: string; }; source?: string; message: string; tags?: number[]; relatedInformation?: DiagnosticRelatedInformation[]; data?: unknown; } export interface PublishedDiagnostics { diagnostics: Diagnostic[]; version: number | null; } export interface PublishDiagnosticsParams { uri: string; diagnostics: Diagnostic[]; version?: number | null; } export interface TextEdit { range: Range; newText: string; } export interface AnnotatedTextEdit extends TextEdit { annotationId?: string; } export interface TextDocumentIdentifier { uri: string; } export interface VersionedTextDocumentIdentifier extends TextDocumentIdentifier { version: number | null; } export interface OptionalVersionedTextDocumentIdentifier extends TextDocumentIdentifier { version?: number | null; } export interface TextDocumentEdit { textDocument: OptionalVersionedTextDocumentIdentifier; edits: (TextEdit | AnnotatedTextEdit)[]; } export interface CreateFileOptions { overwrite?: boolean; ignoreIfExists?: boolean; } export interface CreateFile { kind: "create"; uri: string; options?: CreateFileOptions; } export interface RenameFileOptions { overwrite?: boolean; ignoreIfExists?: boolean; } export interface RenameFile { kind: "rename"; oldUri: string; newUri: string; options?: RenameFileOptions; } export interface DeleteFileOptions { recursive?: boolean; ignoreIfNotExists?: boolean; } export interface DeleteFile { kind: "delete"; uri: string; options?: DeleteFileOptions; } export type DocumentChange = TextDocumentEdit | CreateFile | RenameFile | DeleteFile; export interface WorkspaceEdit { changes?: Record; documentChanges?: DocumentChange[]; changeAnnotations?: Record; } export type CodeActionKind = "quickfix" | "refactor" | "refactor.extract" | "refactor.inline" | "refactor.rewrite" | "source" | "source.organizeImports" | "source.fixAll" | string; export interface Command { title: string; command: string; arguments?: unknown[]; } export interface CodeAction { title: string; kind?: CodeActionKind; diagnostics?: Diagnostic[]; isPreferred?: boolean; disabled?: { reason: string; }; edit?: WorkspaceEdit; command?: Command; data?: unknown; } export interface CodeActionContext { diagnostics: Diagnostic[]; only?: CodeActionKind[]; triggerKind?: 1 | 2; } export type SymbolKind = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26; export declare const SYMBOL_KIND_NAMES: Record; export interface DocumentSymbol { name: string; detail?: string; kind: SymbolKind; tags?: number[]; deprecated?: boolean; range: Range; selectionRange: Range; children?: DocumentSymbol[]; } export interface SymbolInformation { name: string; kind: SymbolKind; tags?: number[]; deprecated?: boolean; location: Location; containerName?: string; } export interface MarkupContent { kind: "plaintext" | "markdown"; value: string; } export type MarkedString = string | { language: string; value: string; }; export interface Hover { contents: MarkupContent | MarkedString | MarkedString[]; range?: Range; } /** * Interface for linter/formatter clients. * Can be implemented using LSP protocol or CLI tools. */ export interface LinterClient { /** Format file content. Returns formatted content. */ format(filePath: string, content: string): Promise; /** Get diagnostics for a file. Content should already be written to disk. */ lint(filePath: string): Promise; /** Dispose of any resources (e.g., LSP connection) */ dispose?(): void; } /** Factory function to create a LinterClient */ export type LinterClientFactory = (config: ServerConfig, cwd: string) => LinterClient; export interface ServerCapabilities { flycheck?: boolean; ssr?: boolean; expandMacro?: boolean; runnables?: boolean; relatedTests?: boolean; } export interface ServerConfig { command: string; args?: string[]; fileTypes: string[]; rootMarkers: string[]; initOptions?: Record; settings?: Record; disabled?: boolean; /** Per-server warmup timeout in milliseconds. Overrides the global WARMUP_TIMEOUT_MS for this server during startup. */ warmupTimeoutMs?: number; capabilities?: ServerCapabilities; /** If true, this is a linter/formatter server (e.g., Biome) - used only for diagnostics/actions, not type intelligence */ isLinter?: boolean; /** Resolved absolute path to the command binary (set during config loading) */ resolvedCommand?: string; /** * Custom linter client factory. If provided, creates a custom client instead of using LSP. * The client handles format/lint operations. Useful for tools with buggy LSP implementations. */ createClient?: LinterClientFactory; } export interface OpenFile { version: number; languageId: string; } export interface PendingRequest { resolve: (result: unknown) => void; reject: (error: Error) => void; method: string; } export interface LspServerCapabilities { renameProvider?: boolean | { prepareProvider?: boolean; }; codeActionProvider?: boolean | { resolveProvider?: boolean; }; hoverProvider?: boolean; definitionProvider?: boolean; referencesProvider?: boolean; documentSymbolProvider?: boolean; workspaceSymbolProvider?: boolean; [key: string]: unknown; } export interface LspClient { name: string; cwd: string; config: ServerConfig; proc: ptree.ChildProcess<"pipe">; requestId: number; diagnostics: Map; diagnosticsVersion: number; openFiles: Map; pendingRequests: Map; messageBuffer: Uint8Array; isReading: boolean; serverCapabilities?: LspServerCapabilities; lastActivity: number; /** Serializes outbound JSON-RPC writes to the server process. */ writeQueue: Promise; /** Tracks active work-done progress tokens from the server */ activeProgressTokens: Set; /** Resolves when the server's initial project loading completes (or after timeout) */ projectLoaded: Promise; /** Call to signal that project loading has completed */ resolveProjectLoaded: () => void; } export interface LspJsonRpcRequest { jsonrpc: "2.0"; id: number; method: string; params: unknown; } export interface LspJsonRpcResponse { jsonrpc: "2.0"; id?: number; result?: unknown; error?: { code: number; message: string; data?: unknown; }; } export interface LspJsonRpcNotification { jsonrpc: "2.0"; method: string; params?: unknown; }