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:
@@ -14,6 +14,7 @@ import {
|
|||||||
getOpenClawEntryPath,
|
getOpenClawEntryPath,
|
||||||
isOpenClawBuilt,
|
isOpenClawBuilt,
|
||||||
isOpenClawPresent,
|
isOpenClawPresent,
|
||||||
|
appendNodeRequireToNodeOptions,
|
||||||
quoteForCmd,
|
quoteForCmd,
|
||||||
} from '../utils/paths';
|
} from '../utils/paths';
|
||||||
import { getSetting } from '../utils/store';
|
import { getSetting } from '../utils/store';
|
||||||
@@ -870,9 +871,10 @@ export class GatewayManager extends EventEmitter {
|
|||||||
try {
|
try {
|
||||||
const preloadPath = ensureGatewayFetchPreload();
|
const preloadPath = ensureGatewayFetchPreload();
|
||||||
if (existsSync(preloadPath)) {
|
if (existsSync(preloadPath)) {
|
||||||
const quoted = `"${preloadPath}"`;
|
spawnEnv['NODE_OPTIONS'] = appendNodeRequireToNodeOptions(
|
||||||
const opts = spawnEnv['NODE_OPTIONS'] ?? '';
|
spawnEnv['NODE_OPTIONS'],
|
||||||
spawnEnv['NODE_OPTIONS'] = `${opts} --require ${quoted}`.trim();
|
preloadPath,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.warn('Failed to set up OpenRouter headers preload:', err);
|
logger.warn('Failed to set up OpenRouter headers preload:', err);
|
||||||
|
|||||||
@@ -8,7 +8,13 @@ import { homedir } from 'os';
|
|||||||
import { existsSync, mkdirSync, readFileSync, realpathSync } from 'fs';
|
import { existsSync, mkdirSync, readFileSync, realpathSync } from 'fs';
|
||||||
import { logger } from './logger';
|
import { logger } from './logger';
|
||||||
|
|
||||||
export { quoteForCmd, needsWinShell, prepareWinSpawn } from './win-shell';
|
export {
|
||||||
|
quoteForCmd,
|
||||||
|
needsWinShell,
|
||||||
|
prepareWinSpawn,
|
||||||
|
normalizeNodeRequirePathForNodeOptions,
|
||||||
|
appendNodeRequireToNodeOptions,
|
||||||
|
} from './win-shell';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand ~ to home directory
|
* Expand ~ to home directory
|
||||||
|
|||||||
@@ -63,3 +63,27 @@ export function prepareWinSpawn(
|
|||||||
args: args.map(a => quoteForCmd(a)),
|
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();
|
||||||
|
}
|
||||||
|
|||||||
@@ -160,3 +160,63 @@ describe('prepareWinSpawn', () => {
|
|||||||
expect(relResult.shell).toBe(true);
|
expect(relResult.shell).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('normalizeNodeRequirePathForNodeOptions', () => {
|
||||||
|
let normalizeNodeRequirePathForNodeOptions: (modulePath: string) => string;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const mod = await import('@electron/utils/win-shell');
|
||||||
|
normalizeNodeRequirePathForNodeOptions = mod.normalizeNodeRequirePathForNodeOptions;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns path unchanged on non-Windows', () => {
|
||||||
|
setPlatform('linux');
|
||||||
|
expect(normalizeNodeRequirePathForNodeOptions('/home/user/.config/app/preload.cjs'))
|
||||||
|
.toBe('/home/user/.config/app/preload.cjs');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts backslashes to forward slashes on Windows', () => {
|
||||||
|
setPlatform('win32');
|
||||||
|
expect(normalizeNodeRequirePathForNodeOptions('C:\\Users\\70954\\AppData\\Roaming\\clawx\\gateway-fetch-preload.cjs'))
|
||||||
|
.toBe('C:/Users/70954/AppData/Roaming/clawx/gateway-fetch-preload.cjs');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('leaves forward slashes intact on Windows', () => {
|
||||||
|
setPlatform('win32');
|
||||||
|
expect(normalizeNodeRequirePathForNodeOptions('C:/already/forward/slashes.cjs'))
|
||||||
|
.toBe('C:/already/forward/slashes.cjs');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('appendNodeRequireToNodeOptions', () => {
|
||||||
|
let appendNodeRequireToNodeOptions: (nodeOptions: string | undefined, modulePath: string) => string;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const mod = await import('@electron/utils/win-shell');
|
||||||
|
appendNodeRequireToNodeOptions = mod.appendNodeRequireToNodeOptions;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('creates NODE_OPTIONS from undefined', () => {
|
||||||
|
setPlatform('linux');
|
||||||
|
expect(appendNodeRequireToNodeOptions(undefined, '/tmp/preload.cjs'))
|
||||||
|
.toBe('--require "/tmp/preload.cjs"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('appends to existing NODE_OPTIONS', () => {
|
||||||
|
setPlatform('linux');
|
||||||
|
expect(appendNodeRequireToNodeOptions('--disable-warning=ExperimentalWarning', '/tmp/preload.cjs'))
|
||||||
|
.toBe('--disable-warning=ExperimentalWarning --require "/tmp/preload.cjs"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('normalizes Windows backslashes in the module path', () => {
|
||||||
|
setPlatform('win32');
|
||||||
|
expect(appendNodeRequireToNodeOptions(undefined, 'C:\\Users\\test\\preload.cjs'))
|
||||||
|
.toBe('--require "C:/Users/test/preload.cjs"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('appends to existing NODE_OPTIONS on Windows with normalized path', () => {
|
||||||
|
setPlatform('win32');
|
||||||
|
expect(appendNodeRequireToNodeOptions('--max-old-space-size=4096', 'D:\\app\\data\\preload.cjs'))
|
||||||
|
.toBe('--max-old-space-size=4096 --require "D:/app/data/preload.cjs"');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user