docs(pty): correct headless-path comments the #15172 rebase left stale

#15927 made `registerPtyHandlers` accept `BrowserWindow | null` so the headless
path could pass null instead of faking a window. #15172 reverted that signature
while splitting the PTY monolith, but the comments describing it survived, so
three of them now document an API that does not exist.

- orcad-entry.ts: the module docstring claimed orcad installs its controller via
  `registerPtyHandlers(null, …)`. It uses `registerHeadlessPtyRuntime`, and null
  is not accepted. It also claimed desktop surfaces are "declared rather than
  faked" — true except for the renderer window, which is still faked.
- register-headless-runtime.ts: record why the fake is safe rather than leaving
  `isDestroyed: () => true` looking arbitrary. It is load-bearing: every
  renderer-liveness guard reads it and skips, so no send is attempted.

Also gives the fake a `webContents.isDestroyed`. The real guards check both, and
a missing method reads as "alive" — the same gap this PR fixes in the test fake.
No behavior change: the window-level check already short-circuits.

Verified: 45 tests across the liveness-guard, startup-barrier, management and
kill/exit suites; pnpm typecheck clean; oxlint clean.
This commit is contained in:
Neil
2026-08-24 19:22:26 -07:00
parent 8ea0ed8d8a
commit 0276e913ba
2 changed files with 10 additions and 4 deletions
@@ -23,9 +23,13 @@ export function registerHeadlessPtyRuntime(
}
): void {
// Why: headless `orca serve` has no renderer window but still needs the same PTY handlers so remote clients can drive terminals.
// Why a fake rather than null: `registerPtyHandlers` takes a non-null BrowserWindow. `isDestroyed: () => true`
// is what makes that safe — every renderer-liveness guard reads it and skips, so no send is ever attempted.
// Keep `webContents.isDestroyed` in step with it: guards check both, and a missing method reads as "alive".
const headlessWindow = {
isDestroyed: () => true,
webContents: {
isDestroyed: () => true,
send: () => {},
on: () => {},
removeListener: () => {}
+6 -4
View File
@@ -2,12 +2,14 @@
* `orcad` — the Orca runtime served from plain Node, with no Electron.
*
* Installs the Node host adapters, constructs the same `OrcaRuntimeService` the
* desktop uses, installs a PTY controller via `registerPtyHandlers(null, …)`, and
* desktop uses, installs a PTY controller via `registerHeadlessPtyRuntime`, and
* serves runtime RPC. See docs/design/node-only-runtime-backend.html.
*
* The desktop-only surfaces are deliberately left uninstalled: no notifications, no
* renderer window, no browser panes. Those are declared rather than faked — see
* `runtime-desktop-surface.ts` and `pty-host-bindings.ts`.
* renderer window, no browser panes. Most are declared rather than faked — see
* `runtime-desktop-surface.ts` and `pty-host-bindings.ts`. The renderer window is the
* exception: `registerPtyHandlers` takes a non-null `BrowserWindow`, so the headless
* path still fakes one that reports itself destroyed.
*/
import { homedir, tmpdir } from 'node:os'
import { join } from 'node:path'
@@ -144,7 +146,7 @@ export async function startOrcad(options: OrcadOptions = {}): Promise<OrcadHandl
getDesktopWindowStatus: () => 'blocked'
})
// Why the headless entry point rather than registerPtyHandlers(null, …): this is the
// Why the headless entry point rather than registerPtyHandlers directly: this is the
// same call `--serve` makes, and it threads the store through. Without the store the
// handlers install fine and every terminal.create then fails at persistence time.
//