/** * Bridges WS ⇄ a language server's stdio. Server command from `LSP_CMD`, port `LSP_PORT`, and a per-session * **auth token** `LSP_TOKEN` (the endpoint is a public `wss://-.e2b.app` URL — the runner connects with * `?token=`; without it, anyone with the URL could read the workspace via LSP, council #4). Frame parsing * uses the unit-tested {@link FRAME_DECODER_JS} (council #1/#2/#5). * * redesign⑤ (#96 §DESIGN-V2 F4): the WS server now rides an explicit `http.createServer` instead of binding its * own socket (`new WebSocketServer({host,port})`) — the same port also answers `GET /healthz` (host-side liveness * probe, §DESIGN-V2 F2/C6) without a second port or dependency. The EADDRINUSE loud-exit handler MOVES with the * bind onto the http server (`server.on('error', …)`, same `lsp-bridge wss error` text + `exit 1` — test/lsp-e2b.test.ts * :256-269 pins this exact text/code); `ws` still forwards its underlying server's `'error'` to `wss`, so nothing * downstream (per-connection handling) changes. */ export declare const BRIDGE_SOURCE: string; /** Bridge dir inside the sandbox(声明提前:tsserver 定值路径引用它)。 */ export declare const BRIDGE_DIR = "/home/user/.lsp-bridge"; /** tls 的 tsserver.js 定值路径(#96 真机门):install 腿保证在场,connect 腿经 * `initializationOptions.tsserver.path` 告知 tls(v4 起无 CLI 旗可用)。 */ export declare const TSSERVER_JS_PATH = "/home/user/.lsp-bridge/node_modules/typescript/lib/tsserver.js"; /** Language server command per languageId. P1 = typescript/javascript; dart/kotlin land with their template servers. * `--stdio` only where the server needs it to pick stdio over its other transports (the node-based servers); * gopls/jdtls/kotlin-language-server/sourcekit-lsp/`dart language-server` speak LSP over stdio by default. * #96 真机门发现(E2B 真沙箱逐帧取证,test/lsp-e2b-bridge-live.test.ts):typescript-language-server * **不自动发现全局 typescript**(只认 workspace 内 node_modules/typescript 或显式 tsserver 路径), * `npm i -g … typescript` 装成之后 initialize 仍答 "Could not find a valid TypeScript installation"; * 且 v4 起 `--tsserver-path` CLI 旗已移除(未知参数=进程退 1,第二轮真机实测)——路径只能走 LSP * `initializationOptions.tsserver.path`(TSSERVER_JS_PATH,connectE2bLspBridge 对 ts/js 传入), * typescript 本体由 lspInstallCommand 落进 BRIDGE_DIR 定值路径(烤好模板文件在场则秒过)。 */ export declare const SERVER_CMD: Readonly>; /** npm packages a non-baked sandbox needs (on-the-fly install). Languages absent here (go) REQUIRE a baked template. */ export declare const SERVER_NPM: Readonly>; /** One bridge process per language → distinct ports.(BRIDGE_DIR 声明已提前至 SERVER_CMD 上方。) */ export declare function portForLanguage(language: string): number; /** FOREGROUND install (run via `env.exec` — must finish before the start). A baked template makes both checks * skip instantly; a non-baked sandbox npm-installs the server + ws here (slow once per sandbox). */ export declare function lspInstallCommand(language: string): string; /** Start the bridge — run as a TRUE background command (`env.startBackground`), NOT `&`-backgrounded inside a * foreground run: E2B reaps the foreground process group on completion, killing an in-shell `&`/nohup child. * So node is the FOREGROUND here and E2B keeps the background command alive. */ export declare function lspStartCommand(language: string, port: number, token: string): string; /** Where the on-the-fly `npm i` output from {@link lspInstallCommand} lands — previously had zero readers * (§DESIGN-V2 F7 bonus fix); an install failure now tails this for the `lastError`/event snippet. */ export declare const LSP_SETUP_LOG = "/tmp/lsp-setup.log"; /** BRIDGE_DIR-relative log the bridge process itself appends to (fatal errors, child exits) — §DESIGN-V2 C4. */ export declare function bridgeLogFile(): string; /** Per-port pidfile the bridge writes ONLY after a confirmed bind (BRIDGE_SOURCE's `listen` callback) — see its * header comment for why a losing (EADDRINUSE) second bridge must never clobber this. */ export declare function bridgePidFile(port: number): string; /** §DESIGN-V2 F3: verify a prior bridge generation ACTUALLY stopped before the host mints a replacement. * Exit 0 = confirmed dead (or the pidfile never existed — nothing was ever listening) → safe to start a new * generation on this port. Exit 1 = still alive after the bound wait — the caller MUST NOT start a new bridge: * an unconfirmed kill risks EADDRINUSE (the new generation's fresh token would then be permanently rejected by * the still-listening old process, the token check in BRIDGE_SOURCE) — better to stay `dead` than double-burn * the restart budget on a doomed attempt. POSIX `sh` only (no `seq`/bashisms — sandboxes vary in shell). * Bound: 20 × 0.1s = 2s. */ export declare function terminateBridgeCommand(port: number): string; //# sourceMappingURL=e2b-bridge.d.ts.map