/** * The runtime check that runs BEFORE anything native is imported. * * The sandbox this server executes `call_tool_chain` in is `isolated-vm`, a * native addon reached through `@utcp/code-mode`. A native addon binds to one * V8 ABI, so it only loads on a Node major it was built for — and building it * on the user's machine (the `node-gyp rebuild` half of its install script) is * a C++ compile most people running `npx` neither expect nor have a toolchain * for. So the supported range is not a preference: it is exactly the majors * `isolated-vm` ships a prebuilt binary for. * * `@utcp/code-mode` imports `isolated-vm` at MODULE level, so on a wrong Node * the failure lands while `server.ts` is being imported — before a single line * of ours runs, as a `ERR_DLOPEN_FAILED` stack trace under whatever the MCP * client shows for "the server died". This module exists so the check happens * first and says one sentence instead. That is also why `cli.ts` imports * `server.js` DYNAMICALLY: a static import would be evaluated (and would * crash) before `preflight()` could run. */ /** * The Node versions `isolated-vm@6.1.2` publishes prebuilt binaries for, each * with the lowest version of that major this repo supports. * * The MAJORS are read off the published tarball's `prebuilds/` folder, which * carries exactly two ABIs — `abi127` (Node 22) and `abi137` (Node 24) — for * linux-x64, linux-arm64 (glibc and musl), darwin-arm64 and win32-x64. Node 23 * has no binary there, which is why this is a list rather than a range: * `>=22 <25` would promise a version that compiles instead of downloading. * * The FLOOR inside a major is a second, independent constraint: 22.13 is what * the repo's `.nvmrc` pins and what `pdfjs-dist` requires, and it is what both * published packages' `engines` says. A runtime that satisfies the major but * not the floor is outside the range we publish, so it gets the same sentence * rather than starting on a version nobody tests. * * Bumping `isolated-vm` means re-reading that folder and editing this list, * the `engines` fields and the CI matrix together — `supported-node.test.ts` * fails while they disagree. */ export interface SupportedNode { readonly major: number; /** The lowest supported version of this major, as `engines` spells it: `22.13`, `24`. */ readonly floor: string; } export declare const SUPPORTED_NODE: readonly SupportedNode[]; /** Just the majors — the ABI list, without the floors. */ export declare const SUPPORTED_NODE_MAJORS: readonly number[]; /** * `>=22.13 <23 || >=24 <25` — the `engines` range that says EXACTLY these * versions. One `>=floor 'loaded' | 'unresolved'; /** * Load `isolated-vm` the way `@utcp/code-mode` will. * * Under pnpm's isolated `node_modules` it is NOT resolvable from this package * — it is code-mode's peer dependency, not ours — so the resolution walks * from code-mode's own entry point. Both are tried, because a hoisted install * (npm, yarn, `--shamefully-hoist`) puts it in reach directly. */ export declare const loadNativeSandbox: NativeSandboxProbe; /** * Is `@utcp/code-mode` — the module whose module-level import pulls the * sandbox in — installed here at all? * * This is what separates the two ways `isolated-vm` can be missing. With * code-mode PRESENT, an absent sandbox is a broken install for every caller: * importing `server.js` imports code-mode, which imports `isolated-vm` and * dies. With code-mode ABSENT, nothing here reaches for the sandbox, and an * embedding host that installed this package without the extras is not broken * — refusing there would be inventing a problem. */ export declare const codeModeInstalled: () => boolean; export interface PreflightOptions { /** Defaults to `process.versions.node`; injected so a test can be Node 26. */ nodeVersion?: string; /** Defaults to {@link loadNativeSandbox}; injected so a test can fail it. */ probeNativeSandbox?: NativeSandboxProbe; /** Defaults to {@link codeModeInstalled}; injected so a test can be either install. */ probeCodeMode?: () => boolean; /** * Refuse a sandbox that cannot even be RESOLVED, whatever else is installed. * The CLI says yes: its very next statement imports `server.js`, so an * unresolved module is a crash one line away rather than a hypothetical. * Leaving it unset does NOT mean "never refuse" — an install carrying * code-mode WITHOUT its sandbox is refused either way, because that one is * broken for every caller (see {@link codeModeInstalled}). */ requireNativeSandbox?: boolean; } /** * The one sentence to print before exiting non-zero, or `null` to carry on. * * Synchronous on purpose: it must complete before `server.js` is imported, * and `require` of a native addon is synchronous anyway. */ export declare function preflight(options?: PreflightOptions): string | null; //# sourceMappingURL=preflight.d.ts.map