fix(onboarding): actually probe shell PATH for node; stop returning Electron's bundled version

The `checkNodeInstalled` IPC handler was hardcoded to
`{ installed: true, version: process.version }`. That meant:

1. The NodeCheckStep in onboarding ALWAYS passed, regardless of what
   was actually on the user's machine.
2. The "Node.js vX.Y installed" success banner showed the **Electron
   runtime's** bundled Node version, not the one the agent's bash
   tool will invoke. A user with no shell Node saw "Node.js v22.x
   installed" and moved on, then every agent bash call that executed
   `node -e 'fetch(...)'` (the pattern the API prompt-builder strongly
   recommends in `api-docs/header.en.md`) crashed at runtime.

Replaced the stub with an `execFile("node", ["--version"])` probe that
runs in the same PATH the bash tool will later inherit. Added a 3s
timeout so a hung PATH entry doesn't stall onboarding. On failure the
handler returns `{ installed: false, version: null }` — the existing
NodeCheckStep already renders the platform-specific install
instructions (brew / winget / nvm) in that case.

No UI change; the fake-pass was the bug. Covers the onboarding audit
item about misleading health checks.
This commit is contained in:
ZacharyZhang-NY committed 2026-04-17 20:15:40 -04:00
1 parent e89fe043f7
commit ab731e64d2
1 file changed
+23 -1
+23 -1
View File
@@ -1,3 +1,4 @@
import { execFile } from "node:child_process";
import {
IPC_CHANNELS,
companyInputSchema,
@@ -11,6 +12,27 @@ import { validateConnectorConfigurationModel, validateConnectorModelSelection }
import { reconcileExecutionModeChange } from "./execution-mode-reconciler";
import { fail, ok, type RegisterCoreHandlersDependencies } from "./ipc-core-common";
/**
* Probe the user's shell PATH for a `node` binary. The onboarding Node
* check uses this to decide whether agents will be able to run the
* "Node.js fetch()" snippets the API prompt-builder emits. Returns the
* shell `node --version` output on success; never surfaces the raw
* `process.version` (that is Electron's bundled Node, not what the
* agent's bash tool will actually invoke).
*/
function probeShellNode(timeoutMs = 3000): Promise<{ installed: boolean; version: string | null }> {
return new Promise((resolve) => {
execFile("node", ["--version"], { timeout: timeoutMs }, (error, stdout) => {
if (error) {
resolve({ installed: false, version: null });
return;
}
const version = stdout.trim();
resolve({ installed: version.length > 0, version: version.length > 0 ? version : null });
});
});
}
export function registerCoreAdminHandlers({
registerHandle,
db,
@@ -108,7 +130,7 @@ export function registerCoreAdminHandlers({
});
registerHandle(IPC_CHANNELS.checkNodeInstalled, async () => {
return ok({ installed: true, version: process.version });
return ok(await probeShellNode());
});
registerHandle(IPC_CHANNELS.openTerminalCommand, async (_event, payload) => {