fix(install): windows install error (#233)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Haze <hazeone@users.noreply.github.com>
This commit is contained in:
Haze
2026-02-28 18:39:10 +08:00
committed by GitHub
Unverified
parent 3353de91b8
commit 9d07f611a3
4 changed files with 96 additions and 4 deletions

View File

@@ -14,6 +14,7 @@ import {
getOpenClawEntryPath,
isOpenClawBuilt,
isOpenClawPresent,
appendNodeRequireToNodeOptions,
quoteForCmd,
} from '../utils/paths';
import { getSetting } from '../utils/store';
@@ -870,9 +871,10 @@ export class GatewayManager extends EventEmitter {
try {
const preloadPath = ensureGatewayFetchPreload();
if (existsSync(preloadPath)) {
const quoted = `"${preloadPath}"`;
const opts = spawnEnv['NODE_OPTIONS'] ?? '';
spawnEnv['NODE_OPTIONS'] = `${opts} --require ${quoted}`.trim();
spawnEnv['NODE_OPTIONS'] = appendNodeRequireToNodeOptions(
spawnEnv['NODE_OPTIONS'],
preloadPath,
);
}
} catch (err) {
logger.warn('Failed to set up OpenRouter headers preload:', err);

View File

@@ -8,7 +8,13 @@ import { homedir } from 'os';
import { existsSync, mkdirSync, readFileSync, realpathSync } from 'fs';
import { logger } from './logger';
export { quoteForCmd, needsWinShell, prepareWinSpawn } from './win-shell';
export {
quoteForCmd,
needsWinShell,
prepareWinSpawn,
normalizeNodeRequirePathForNodeOptions,
appendNodeRequireToNodeOptions,
} from './win-shell';
/**
* Expand ~ to home directory

View File

@@ -63,3 +63,27 @@ export function prepareWinSpawn(
args: args.map(a => quoteForCmd(a)),
};
}
/**
* Normalize a module path for NODE_OPTIONS `--require` usage.
*
* Node parses NODE_OPTIONS using shell-like escaping rules. On Windows,
* a quoted path with backslashes (e.g. "C:\Users\...") loses separators
* because backslashes are interpreted as escapes. Using forward slashes
* keeps the absolute path intact while still being valid on Windows.
*/
export function normalizeNodeRequirePathForNodeOptions(modulePath: string): string {
if (process.platform !== 'win32') return modulePath;
return modulePath.replace(/\\/g, '/');
}
/**
* Append a `--require` preload module path to NODE_OPTIONS safely.
*/
export function appendNodeRequireToNodeOptions(
nodeOptions: string | undefined,
modulePath: string,
): string {
const normalized = normalizeNodeRequirePathForNodeOptions(modulePath);
return `${nodeOptions ?? ''} --require "${normalized}"`.trim();
}