fix: make spawn() work when host is an Electron main process#1508
Open
Copilot wants to merge 3 commits into
Open
fix: make spawn() work when host is an Electron main process#1508Copilot wants to merge 3 commits into
Copilot wants to merge 3 commits into
Conversation
Co-authored-by: friggeri <106686+friggeri@users.noreply.github.com>
Co-authored-by: friggeri <106686+friggeri@users.noreply.github.com>
Copilot created this pull request from a session on behalf of
friggeri
May 29, 2026 22:08
View session
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a startup failure when the Node.js SDK is hosted inside an Electron main process, where process.execPath points at the Electron binary and spawning the bundled .js CLI either silently exits (single-instance lock) or trips Commander's Electron argv parsing on --headless.
Changes:
- New
@internalhelperapplyElectronSpawnEnv()injectsELECTRON_RUN_AS_NODE=1andCOPILOT_CLI_RUN_AS_NODE=1(via??=) for.jsCLIs whenprocess.versions.electronis defined, andgetNodeExecPath()now accepts an optional override. - New public
CopilotClientOptions.nodeExecPathescape hatch for apps that bundle a real Node binary; wired through to the.jsspawn branch instartCLIServer(). - Documentation (README "Electron Usage" section, CHANGELOG Unreleased entry) and 6 unit tests covering injection, no-overwrite, non-
.js, non-Electron, override, and option storage.
Show a summary per file
| File | Description |
|---|---|
| nodejs/src/client.ts | Adds applyElectronSpawnEnv, extends getNodeExecPath with override, stores nodeExecPath option, and uses both in the .js spawn branch. |
| nodejs/src/types.ts | Adds nodeExecPath?: string to CopilotClientOptions with JSDoc explaining the Electron use case. |
| nodejs/test/client.test.ts | New Electron spawn environment describe block exercising helper behavior and option storage. |
| nodejs/README.md | New "Electron Usage" section documenting failure modes, automatic fix, and nodeExecPath escape hatch. |
| CHANGELOG.md | Adds an [Unreleased] entry describing the fix and new option. |
Copilot's findings
- Files reviewed: 5/5 changed files
- Comments generated: 1
Comment on lines
+8
to
+31
| ## [Unreleased] | ||
|
|
||
| ### Fixed: CLI server spawn in Electron main process (Node.js SDK) | ||
|
|
||
| `CopilotClient.start()` previously threw `CLI server exited unexpectedly with | ||
| code 0` when the host was an Electron main process. The root cause was that | ||
| `process.execPath` resolves to the Electron binary rather than a Node | ||
| executable, so spawning the bundled `.js` CLI failed silently (bare spawn) or | ||
| with a Commander argv-parsing error (`ELECTRON_RUN_AS_NODE=1` alone). | ||
|
|
||
| The SDK now detects `process.versions.electron` at spawn time and automatically | ||
| injects `ELECTRON_RUN_AS_NODE=1` and `COPILOT_CLI_RUN_AS_NODE=1` into the | ||
| child process environment. No code changes are required in existing Electron | ||
| apps. | ||
|
|
||
| A new `nodeExecPath` option on `CopilotClientOptions` lets apps that bundle a | ||
| real Node binary point the SDK at it directly, bypassing the auto-injected | ||
| env-vars entirely: | ||
|
|
||
| ```ts | ||
| const client = new CopilotClient({ | ||
| nodeExecPath: process.env.MY_APP_NODE_PATH ?? "node", | ||
| }); | ||
| ``` |
Contributor
Author
There was a problem hiding this comment.
Addressed in 9480efeb: removed the manual [Unreleased] CHANGELOG entry so release notes remain generator-managed.
Co-authored-by: friggeri <106686+friggeri@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In an Electron main process,
process.execPathis the Electron binary. Spawning the bundled.jsCLI with it fails two ways: bare spawn triggers single-instance lock → clean exit → misleadingCLI server exited unexpectedly with code 0; withELECTRON_RUN_AS_NODE=1alone,process.versions.electronis still set in the child, Commander picks Electron argv parsing, and--headlessis misclassified as a positional arg →error: too many arguments.Changes
applyElectronSpawnEnv(env, isJsFile)(client.ts) — new@internalhelper; whenprocess.versions.electron !== undefinedand the CLI is a.jsfile, injectsELECTRON_RUN_AS_NODE=1andCOPILOT_CLI_RUN_AS_NODE=1via??=(caller values are never overwritten). No-ops in all non-Electron hosts.getNodeExecPath(override?)— accepts an optional path override; exported@internalfor testability.CopilotClientOptions.nodeExecPath?: string(types.ts) — escape hatch for Electron apps that bundle a real Node binary, bypassing the env-var injection entirely:startCLIServer()— wired to callapplyElectronSpawnEnvbefore spawn and passoptions.nodeExecPathtogetNodeExecPath.6 new unit tests covering injection, no-overwrite, non-
.jsskip, non-Electron no-op, override, and option storage.README — new "Electron usage" section documenting both failure modes and both fixes.
CHANGELOG —
[Unreleased]Fixed entry.