import type { LspClient, ServerConfig } from "./types.js";
/**
 * Configure the idle timeout for LSP clients.
 * @param ms - Timeout in milliseconds, or null/undefined to disable
 */
export declare function setIdleTimeout(ms: number | null | undefined): void;
/** LSP `FileChangeType` values for workspace/didChangeWatchedFiles notifications. */
export declare enum FileChangeType {
    Created = 1,
    Changed = 2,
    Deleted = 3
}
/** Filesystem change authored by the harness and announced to active LSP clients. */
export interface WatchedFileChange {
    filePath: string;
    type: FileChangeType;
}
/** Timeout for warmup initialize requests (5 seconds) */
export declare const WARMUP_TIMEOUT_MS = 5000;
/**
 * Get or create an LSP client for the given server configuration and working directory.
 * @param config - Server configuration
 * @param cwd - Working directory
 * @param initTimeoutMs - Optional hard deadline for the initialize handshake (warmup / other
 *   short-lived callers). When set it takes precedence over `signal` inside `sendRequest`.
 * @param signal - Optional caller abort signal. Threaded into the initialize `sendRequest`
 *   and the `initialized` notification so a wedged server surfaces the caller's
 *   timeout/cancel instead of falling back to the internal 30s default.
 */
export declare function getOrCreateClient(config: ServerConfig, cwd: string, initTimeoutMs?: number, signal?: AbortSignal): Promise<LspClient>;
/**
 * Ensure a file is opened in the LSP client.
 * Sends didOpen notification if the file is not already tracked.
 */
export declare function ensureFileOpen(client: LspClient, filePath: string, signal?: AbortSignal): Promise<void>;
/**
 * Wait for the server's initial project loading to complete.
 * Races the server's $/progress tracking against the abort signal.
 * Returns immediately if loading already completed or timed out.
 */
export declare function waitForProjectLoaded(client: LspClient, signal?: AbortSignal): Promise<void>;
/**
 * Sync in-memory content to the LSP client without reading from disk.
 * Use this to provide instant feedback during edits before the file is saved.
 */
export declare function syncContent(client: LspClient, filePath: string, content: string, signal?: AbortSignal): Promise<void>;
/**
 * Notify LSP that a file was saved.
 * Assumes content was already synced via syncContent - just sends didSave.
 */
export declare function notifySaved(client: LspClient, filePath: string, signal?: AbortSignal): Promise<void>;
/**
 * Announce harness-authored filesystem changes to active LSP clients for `cwd`.
 *
 * This covers sibling files that are not open text documents, such as generated
 * CSS modules or type files that another edited document imports immediately.
 *
 * The underlying stdin flush is self-bounded by
 * {@link WATCHED_FILES_NOTIFY_TIMEOUT_MS}; only an abort of the caller's
 * `signal` rejects.
 */
export declare function notifyWorkspaceWatchedFiles(cwd: string, changes: readonly WatchedFileChange[], signal?: AbortSignal): Promise<void>;
/**
 * Refresh a file in the LSP client.
 * Increments version, sends didChange and didSave notifications.
 */
export declare function refreshFile(client: LspClient, filePath: string, signal?: AbortSignal): Promise<void>;
/**
 * Shutdown a specific client by key.
 */
export declare function shutdownClient(key: string): Promise<void>;
/**
 * Send an LSP request and wait for response.
 *
 * Timeout policy:
 * - If `timeoutMs` is explicitly provided, that value is used.
 * - Else, if `signal` is provided, no internal timer is installed (the caller
 *   owns the deadline via the signal — typically a wall-clock `AbortSignal.timeout`
 *   from the LSP tool). Installing a second hard-coded 30s timer here used to
 *   cause "timed out after 30000ms" errors even when the caller had requested
 *   `timeout: 60`.
 * - Else (no signal, no explicit timeout), fall back to `DEFAULT_REQUEST_TIMEOUT_MS`
 *   to avoid leaking pending requests forever.
 */
export declare function sendRequest(client: LspClient, method: string, params: unknown, signal?: AbortSignal, timeoutMs?: number): Promise<unknown>;
/**
 * Send an LSP notification (no response expected).
 * `signal` bounds the underlying `sink.flush()` — without it a server that
 * stops draining stdin blocks every future write on the client's write queue.
 */
export declare function sendNotification(client: LspClient, method: string, params: unknown, signal?: AbortSignal): Promise<void>;
/**
 * Shutdown all LSP clients.
 */
export declare function shutdownAll(): Promise<void>;
/** Status of an LSP server */
export interface LspServerStatus {
    name: string;
    status: "connecting" | "ready" | "error";
    fileTypes: string[];
    error?: string;
}
/**
 * Get status of all active LSP clients.
 */
export declare function getActiveClients(): LspServerStatus[];
