/** * Whether canvases can run here, and how to fork one. * * Design: `docs/canvas-extensions-design.md` §11.1. A canvas child must run under * **Node ≥ 20.6** — the version that introduced `module.register`, which * `resolver.ts` uses to make the SDK specifier resolvable inside the child without * writing into the extension directory. * * The requirement is on the *child*, not on hoocode. An earlier version of this * module conflated the two and refused to run canvases at all under the * self-contained build; but a Bun-compiled parent forking a Node child is fine, so * the question is "is a usable Node reachable?", not "are we Node?". That makes * canvases available on every install path where Node exists — npm, bun, or the * standalone binary with Node on PATH. * * Two traps found by running it rather than reasoning about it, both of which fail * *silently* if you get them wrong: * * 1. **Bun exports `module.register` but ignores resolve hooks.** The call * succeeds, nothing warns, and the child then resolves the real * `@github/copilot-sdk` out of Bun's global install cache instead of the shim. * So the child may never be Bun, however the parent was launched. * 2. **`process.versions.node` does not identify Node.** Bun reports * `process.versions.node = "24.3.0"` next to `process.versions.bun`. Deciding * "we can fork ourselves" must therefore require `process.versions.bun` to be * absent, never just a satisfying Node version. * * Resolution is not cached here. It can spawn `node --version`, so the caller should * resolve once per session and hold the result rather than asking per open. */ import type { CanvasRuntime } from "./runner.js"; /** Minimum Node that supports `module.register`, which `resolver.ts` depends on. */ export declare const CANVAS_MIN_NODE_MAJOR = 20; /** Minimum minor within {@link CANVAS_MIN_NODE_MAJOR}. */ export declare const CANVAS_MIN_NODE_MINOR = 6; /** How long to wait for `node --version` before giving up on PATH discovery. */ export declare const CANVAS_NODE_PROBE_TIMEOUT_MS = 5000; /** Either a runtime that can fork canvases, or the reason none is available. */ export type CanvasAvailability = { available: true; runtime: CanvasRuntime; } | { available: false; reason: string; }; /** * A shim the child could import, paired with whatever argv it needs to do so. * * The pairing is the point: the built `.js` needs nothing, while the TypeScript source * needs a loader. Offering a shim without its prerequisite is how you get an * "available" that fails at fork time. */ export interface CanvasShimCandidate { /** `file:` URL of the shim module. */ url: string; /** Extra argv prepended for the child, e.g. a TypeScript loader. */ execArgv: string[]; } /** A Node executable found on PATH. */ export interface DiscoveredNode { /** Passed straight to `spawn`, so a bare name is fine — it resolves via PATH. */ execPath: string; /** Version without the leading `v`. */ version: string; } /** Host facts {@link resolveCanvasRuntime} reads. Injectable so tests need no subprocess. */ export interface CanvasHostProbe { /** `process.versions.bun`, or undefined on Node. */ bunVersion: string | undefined; /** `process.versions.node` — meaningless as a Node check; see the module header. */ nodeVersion: string; /** `process.execPath`. */ execPath: string; /** Candidate shims, highest precedence first. */ shimCandidates: CanvasShimCandidate[]; /** Whether a `file:` URL exists on disk. */ exists: (fileUrl: string) => boolean; /** Locate a Node on PATH. Resolves undefined when there is none. */ probePathNode: () => Promise; } /** Read the current process. */ export declare function currentCanvasHostProbe(): CanvasHostProbe; /** * Decide whether canvases can run, and produce the runtime if so. * * Never throws and never guesses: an unavailable result carries a sentence a person * can act on, because "no Node here" is a legitimate state rather than a failure. */ export declare function resolveCanvasRuntime(probe?: CanvasHostProbe): Promise; //# sourceMappingURL=launch.d.ts.map