// Daemon Client - High-level helpers used by cli.ts and index.ts to send // LSP work to the long-lived daemon. The first call autospawns the // daemon; subsequent calls reuse it. // // Why Not One Persistent Socket - For now we open a fresh connection per // request. The cost is negligible (Unix socket, same machine) compared to // the LSP request itself, and it keeps client code stateless. import { buildLaunchContext, sendOnce, type DaemonResponse, } from "./daemonProtocol.ts"; // Unwrap - Throws on { ok: false }, returns result on { ok: true }. All // callers want the result-or-throw shape, so we centralize it. function unwrap(resp: DaemonResponse): unknown { if (resp.ok) return resp.result; throw new Error(resp.error); } // Send LSP Request - Forwards an arbitrary LSP method to the daemon. The // daemon injects textDocument.uri from `file`, so callers omit it. export async function daemonRequest( file: string, method: string, params: Record, ): Promise { return unwrap( await sendOnce({ op: "request", file, method, params, launch: buildLaunchContext(), }), ); } // Wait For Diagnostics - Diagnostics arrive as a notification, not a // response, so the daemon has a dedicated op that awaits the next publish. export async function daemonDiagnostics( file: string, timeoutMs = 1500, ): Promise { return unwrap( await sendOnce({ op: "diagnostics", file, timeoutMs, launch: buildLaunchContext(), }), ); } // Status - Lists currently-cached LSP servers (id, root, opened files, // idle time). Useful for `pi-lsp daemon status`. export async function daemonStatus(): Promise { return unwrap(await sendOnce({ op: "status" })); } // Shutdown - Asks the daemon to dispose all LspClients and exit. export async function daemonShutdown(): Promise { return unwrap(await sendOnce({ op: "shutdown" })); } // Destroy Server - Kills running LspClient entries matching a server ID, // or all entries if no ID is given. Entries can respawn on next request. export async function daemonDestroyServer( serverId?: string, ): Promise { return unwrap(await sendOnce({ op: "destroy_server", serverId })); }