import { ChildProcess } from "node:child_process"; import { IncomingMessage, Server, ServerResponse } from "node:http"; import { EventEmitter } from "node:events"; import { Duplex } from "node:stream"; /** * Options for `createServer()` from VS Code server * (`code-server/lib/vscode/out/server-main.js`). * * Scope: only options that are actually consumed when the server is embedded * via `createServer(null, opts)` — i.e. reached through `zF`/`jF`/`uM`/`AF` * directly, or read from `environmentService.args` during request handling, * workbench construction, or extension host setup. * * Options that only fire through the `spawnCli`/`YH` argv-parsing entry * (license prompt, extension install/list/uninstall, host/port listen, * `--folder-uri`, `--locate-shell-integration-path`, etc.) are intentionally * omitted — passing them to `createServer()` has no effect. */ interface VSCodeServerOptions { /** The path under which the web UI and the code server is provided. Defaults to `'/'`. */ "server-base-path"?: string; /** The path to a socket file for the server to listen to. Also toggles Windows management-connection socket transfer. */ "socket-path"?: string; /** Print startup timing breakdown to stdout once the server is ready. */ "print-startup-performance"?: boolean; /** A secret that must be included with all requests. */ "connection-token"?: string; /** Path to a file that contains the connection token. */ "connection-token-file"?: string; /** Run without a connection token. Only use this if the connection is secured by other means. */ "without-connection-token"?: boolean; auth?: string; "github-auth"?: string; /** Specifies the directory that server data is kept in. */ "server-data-dir"?: string; "user-data-dir"?: string; "extensions-dir"?: string; "extensions-download-dir"?: string; "builtin-extensions-dir"?: string; /** The path to the directory where agent plugins are located. */ "agent-plugins-dir"?: string; /** The workspace folder to open when no input is specified in the browser URL. A relative or absolute path resolved against the current working directory. */ "default-folder"?: string; /** The workspace to open when no input is specified in the browser URL. A relative or absolute path resolved against the current working directory. */ "default-workspace"?: string; locale?: string; log?: string[]; logsPath?: string; "disable-websocket-compression"?: boolean; "use-host-proxy"?: boolean; "disable-file-downloads"?: boolean; "disable-file-uploads"?: boolean; "file-watcher-polling"?: string; /** Sets the initial telemetry level. Valid levels are: `'off'`, `'crash'`, `'error'` and `'all'`. */ "telemetry-level"?: string; "disable-telemetry"?: boolean; "disable-update-check"?: boolean; "disable-experiments"?: boolean; "enable-sync"?: boolean; "enable-proposed-api"?: string[]; "disable-workspace-trust"?: boolean; "disable-getting-started-override"?: boolean; "link-protection-trusted-domains"?: string[]; "enable-remote-auto-shutdown"?: boolean; "remote-auto-shutdown-without-delay"?: boolean; "without-browser-env-var"?: boolean; /** Override the reconnection grace time window in seconds. Defaults to `10800` (3 hours). */ "reconnection-grace-time"?: string; /** The path to a socket file for the agent host WebSocket server to listen on. */ "agent-host-path"?: string; /** The port the agent host WebSocket server should listen on. */ "agent-host-port"?: string; "inspect-ptyhost"?: string; "inspect-brk-ptyhost"?: string; "inspect-agenthost"?: string; "inspect-brk-agenthost"?: string; "enable-smoke-test-driver"?: boolean; "crash-reporter-directory"?: string; "crash-reporter-id"?: string; "force-disable-user-env"?: boolean; "force-user-env"?: boolean; } interface CreateCodeServerOptions { /** Workspace folder opened when no input is given in the URL. */ defaultFolder?: string; /** * Customize the URL returned by the server. Called with the base URL after * auth params are applied. Return a modified URL, a string, or `undefined` * to keep the original. */ formatURL?: (url: URL) => string | URL | undefined; /** Connection token (shared auth secret). Auto-generated if omitted. */ connectionToken?: string; /** Host/interface to bind (used to infer local-only access for token default). */ host?: string; /** * Base URL the server is mounted under (e.g. `/code`). Defaults to `/`. * Forwarded to VS Code as `server-base-path` and honored by coderaft's own * routes (`/healthz`, `/_static/*`, `/proxy/*`, `/login`, …). */ baseURL?: string; /** * URI template for proxied ports. `{{port}}` is replaced with the port number. * * Path-based (default): `baseURL + "/proxy/{{port}}/"` (e.g. `/code/proxy/3000/`) * Subdomain-based: `https://{{port}}.proxy.example.com/` * * Passed to VS Code as `VSCODE_PROXY_URI`. */ proxyURI?: string; /** * Extensions to preinstall before the server boots. Each entry is anything * VS Code's CLI accepts: a gallery id (`esbenp.prettier-vscode`), an id pinned * to a version (`esbenp.prettier-vscode@12.4.0`), or a path to a local * `.vsix`. Gallery ids resolve from Open VSX (https://open-vsx.org) by * default. * * Installation is idempotent — already-installed extensions are skipped, so * warm restarts pay no cost. Failures (bad id, gallery outage) are logged and * never block startup. */ extensions?: string[]; /** Extra options forwarded to VS Code's `createServer()`. */ vscode?: VSCodeServerOptions; } interface StartCodeServerOptions extends CreateCodeServerOptions { /** TCP port to listen on. Defaults to `$PORT` or `6063`. Ignored when `socketPath` is set. */ port?: number; /** Unix socket path to listen on. When set, `port` and `host` are ignored. */ socketPath?: string; } interface CodeServerHandler { /** Node-style HTTP request handler (middleware). */ handleRequest(req: IncomingMessage, res: ServerResponse): void; /** Handle WebSocket upgrade. */ handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer): void; connectionToken: string; dispose(): Promise; } interface CodeServerHandle { server: Server; /** TCP port the server is bound to, or `undefined` when listening on a unix socket. */ port?: number; /** Unix socket path the server is bound to, or `undefined` when listening on TCP. */ socketPath?: string; url: string; connectionToken: string; close(): Promise; } declare function createCodeServer(opts?: CreateCodeServerOptions): Promise; declare function startCodeServer(opts?: StartCodeServerOptions): Promise; interface SpawnProcessOptions { /** Extra environment variables merged into the worker's `process.env`. */ env?: NodeJS.ProcessEnv; /** Node.js exec argv forwarded to the worker (e.g. `["--inspect"]`). */ execArgv?: string[]; /** * stdio for the forked worker. Defaults to `"inherit"` for stdout/stderr and * `"ignore"` for stdin. Pass `"pipe"` to capture output via `handle.proc`. */ stdio?: "inherit" | "pipe" | "ignore"; /** * Max ms to wait for the worker to report `ready`. Defaults to 60000. * On timeout, the worker is killed and the promise rejects. */ startupTimeout?: number; } interface SpawnCodeServerOptions extends StartCodeServerOptions { /** Options for the forked worker process. */ spawn?: SpawnProcessOptions; } interface SpawnedCodeServer { /** * Emitted when the handle loses its worker: crash, explicit kill, or a * `reload()` whose respawn failed (the old worker is already gone; the * failure also rejects the `reload()` promise). Not emitted for `close()` * or the successful half of `reload()`. */ on(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): this; /** * Emitted for worker `error` events (spawn failure, IPC send failure) and * for post-ready fatal errors forwarded by the worker (uncaughtException, * unhandledRejection). */ on(event: "error", listener: (err: Error) => void): this; on(event: string, listener: (...args: unknown[]) => void): this; } declare class SpawnedCodeServer extends EventEmitter { #private; /** The forked worker process (changes after `reload`). */ proc: ChildProcess; url: string; /** TCP port the server is bound to, or `undefined` when listening on a unix socket. */ port?: number; /** Unix socket path the server is bound to, or `undefined` when listening on TCP. */ socketPath?: string; connectionToken: string; private constructor(); /** Spawn a new worker and resolve with a handle once it reports ready. */ static spawn(opts?: SpawnCodeServerOptions): Promise; /** Terminate the worker process. Sends SIGTERM, then SIGKILL after 5s. Idempotent. */ close(): Promise; /** Kill the current worker and spawn a new one with the original options. */ reload(): Promise; } declare function spawnCodeServer(opts?: SpawnCodeServerOptions): Promise; interface EnsureExtensionsOptions { /** Directory extensions are installed into (must match the running server). */ extensionsDir: string; /** VS Code user data directory. */ userDataDir: string; /** VS Code server data directory. */ serverDataDir?: string; /** Reinstall even if an extension with the same id is already present. */ force?: boolean; /** Install pre-release versions when available. */ preRelease?: boolean; } /** * Read the ids of already-installed extensions (lowercased) from the * `extensions.json` manifest VS Code maintains in the extensions directory. * Returns an empty set when the directory or manifest doesn't exist yet. */ declare function readInstalledExtensions(extensionsDir: string): Set; /** * Ensure the given extensions are installed before the server boots. Missing * extensions are installed from the gallery (Open VSX by default) in a forked * child process — `spawnCli` calls `process.exit()` when done, so it cannot run * in the server process. Best-effort: install failures are logged, not thrown, * so a bad id or a gallery outage never blocks startup. */ declare function ensureExtensions(specs: string[], opts: EnsureExtensionsOptions): Promise; export { type CodeServerHandle, type CodeServerHandler, type CreateCodeServerOptions, type EnsureExtensionsOptions, type SpawnCodeServerOptions, type SpawnProcessOptions, SpawnedCodeServer, type StartCodeServerOptions, createCodeServer, ensureExtensions, readInstalledExtensions, spawnCodeServer, startCodeServer };