/** * worker-launch.ts — How a worker is brought into existence, as a parameter. * * `startWorker()` used to spawn the child and build its transport inline, so * "there is a worker" and "a real process was spawned against the real iLink * account" were the same statement. Nothing could drive the worker lifecycle * from a test: every smoke test had to arrange for a spawn *never* to happen * (`faux-home.ts` writes `autoLogin: false`, `stub-pi.ts` says no stub may * cause one), which left the whole lifecycle — readiness gating, restart * backoff, the ownership gate around `startWorker()` — untested. * * This module is the seam. It answers only "how do I get a worker and a * transport bound to it"; every policy decision about what to do with one — * restart backoff, `intentional` exit classification, stale-exit detection, * the heartbeat, the `ownsChannel()` gate — stays in `index.ts`, which is why * a `WorkerLauncher` sees no channel state and cannot import any. * * It lives at the repository root, **not** under `channel/`, and that is * load-bearing: `packageDir` is passed in rather than derived here, and a * compiled copy at `dist/channel/worker-launch.js` would tempt a future * `import.meta.url` into missing both of `resolveWorkerCommand`'s probes — * falling back to tsx inside an npm package that ships only `dist/`, where * the channel then never comes up and says nothing about why. */ import type { Transport } from './ipc.js'; export interface WorkerLaunchOptions { /** * The directory the extension was loaded from (`index.ts`'s `__dirname`). * Always the caller's, never computed here — see the header. */ packageDir: string; /** * The interpreter that runs the compiled output: `process.execPath`, the * binary already running pi, not a bare `node`. PATH is not guaranteed to * hold one — a version manager, a desktop launcher or a launch agent can * leave it absent or older, and the channel then silently never starts. */ nodeExecPath: string; /** Environment overlaid on `process.env`. */ env: Record; /** * Where the worker's stderr goes — the extension's file logger. Never the * terminal: see the note on the spawn below. */ onStderr: (chunk: string) => void; /** Non-fatal notes from command resolution; the caller decides where they go. */ onWarning: (message: string) => void; } export interface WorkerHandle { /** The transport bound to *this* worker. */ readonly transport: Transport; /** `code === null` means a signal took it. Delivered asynchronously. */ onExit(handler: (code: number | null, signal: string | null) => void): void; onError(handler: (err: Error) => void): void; /** Let it go. Contract: **never throws** — an already-dead process is not an error. */ kill(signal?: NodeJS.Signals): void; } export type WorkerLauncher = (opts: WorkerLaunchOptions) => WorkerHandle; /** Spawn the real worker process and wire its stdio into a Transport. */ export declare const spawnWorker: WorkerLauncher; //# sourceMappingURL=worker-launch.d.ts.map