@plusonelabs/cue 0.0.90 → 0.0.96-e2e-bench-windows.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.txt +7 -0
- package/bin/cue.js +550 -0
- package/bin/windows-bootstrap.ps1 +1113 -0
- package/bin/windows-runtime-artifact.json +6 -0
- package/dist/cli.mjs +1414 -1820
- package/package.json +2 -2
- package/.eslintignore +0 -6
- package/cue-v0.0.90.tar.gz +0 -0
- package/install.sh +0 -63
package/README.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Flat npm package artifact for local install testing.
|
|
2
|
+
|
|
3
|
+
Install examples:
|
|
4
|
+
npm install -g ./plusonelabs-cue-<version>.tgz
|
|
5
|
+
|
|
6
|
+
On Windows (supported path), the host wrapper forwards into WSL.
|
|
7
|
+
Install Cue inside WSL as well (or use a separate local WSL runtime artifact) before testing wrapper commands.
|
package/bin/cue.js
ADDED
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* global console, process */
|
|
3
|
+
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import { spawn, spawnSync } from 'child_process';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
8
|
+
|
|
9
|
+
const FORCE_WINDOWS_WRAPPER = process.env.CUE_FORCE_WINDOWS_HOST_WRAPPER === '1';
|
|
10
|
+
const isWindowsHost = process.platform === 'win32' || FORCE_WINDOWS_WRAPPER;
|
|
11
|
+
const WRAPPER_DEBUG = process.env.CUE_WINDOWS_WRAPPER_DEBUG === '1';
|
|
12
|
+
|
|
13
|
+
async function main() {
|
|
14
|
+
if (!isWindowsHost) {
|
|
15
|
+
await runCliEntrypoint();
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const normalizedArgv = normalizeWindowsWrapperArgv(process.argv);
|
|
20
|
+
const args = normalizedArgv.slice(2);
|
|
21
|
+
if (args.includes('--windows-bootstrap')) {
|
|
22
|
+
const rawBootstrapArgs = args.filter((arg) => arg !== '--windows-bootstrap');
|
|
23
|
+
const code = runWindowsBootstrap(normalizeWindowsBootstrapArgs(rawBootstrapArgs));
|
|
24
|
+
process.exit(code);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (isWindowsHost && args[0] === 'update') {
|
|
28
|
+
const code = runWindowsHostUpdateFlow(args.slice(1));
|
|
29
|
+
process.exit(code);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const exitCode = await runCueInWsl(args);
|
|
33
|
+
process.exit(exitCode);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function runCliEntrypoint() {
|
|
37
|
+
const baseDir = path.dirname(fileURLToPath(import.meta.url));
|
|
38
|
+
const candidates = [
|
|
39
|
+
path.join(baseDir, '..', 'dist', 'cli.mjs'),
|
|
40
|
+
path.join(baseDir, '..', 'dist', 'src', 'cli.js'),
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
for (const candidate of candidates) {
|
|
44
|
+
if (!fs.existsSync(candidate)) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
await import(pathToFileURL(candidate).href);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.error('Cue CLI entrypoint not found in package.');
|
|
52
|
+
console.error('Expected one of:');
|
|
53
|
+
for (const candidate of candidates) {
|
|
54
|
+
console.error(` - ${candidate}`);
|
|
55
|
+
}
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function runWindowsBootstrap(extraArgs) {
|
|
60
|
+
const powershellCommand = resolvePowerShellCommand();
|
|
61
|
+
if (!powershellCommand) {
|
|
62
|
+
console.error('PowerShell was not found. Run bootstrap manually from PowerShell.');
|
|
63
|
+
return 1;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const scriptPath = path.join(
|
|
67
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
68
|
+
'windows-bootstrap.ps1'
|
|
69
|
+
);
|
|
70
|
+
if (!fs.existsSync(scriptPath)) {
|
|
71
|
+
console.error(`Windows bootstrap script not found: ${scriptPath}`);
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const psArgs = [
|
|
76
|
+
'-NoProfile',
|
|
77
|
+
'-ExecutionPolicy',
|
|
78
|
+
'Bypass',
|
|
79
|
+
'-File',
|
|
80
|
+
scriptPath,
|
|
81
|
+
...extraArgs,
|
|
82
|
+
];
|
|
83
|
+
const result = spawnSync(powershellCommand, psArgs, { stdio: 'inherit' });
|
|
84
|
+
if (result.error) {
|
|
85
|
+
console.error(`Failed to run PowerShell bootstrap: ${result.error.message}`);
|
|
86
|
+
return 1;
|
|
87
|
+
}
|
|
88
|
+
return typeof result.status === 'number' ? result.status : 1;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function normalizeWindowsBootstrapArgs(args) {
|
|
92
|
+
const normalized = [];
|
|
93
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
94
|
+
const arg = args[i];
|
|
95
|
+
|
|
96
|
+
if (arg === '--install' || arg === '--install-cue') {
|
|
97
|
+
normalized.push('-InstallCue');
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (arg === '--no-systemd' || arg === '--skip-systemd-check') {
|
|
102
|
+
normalized.push('-RequireSystemd:$false');
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (arg === '--distro') {
|
|
107
|
+
const value = args[i + 1];
|
|
108
|
+
if (value) {
|
|
109
|
+
normalized.push('-Distro', value);
|
|
110
|
+
i += 1;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (arg === '--json') {
|
|
116
|
+
normalized.push('-Json');
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (arg === '--runtime-url') {
|
|
121
|
+
const value = args[i + 1];
|
|
122
|
+
if (value) {
|
|
123
|
+
normalized.push('-RuntimeUrl', value);
|
|
124
|
+
i += 1;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (arg === '--runtime-sha256') {
|
|
130
|
+
const value = args[i + 1];
|
|
131
|
+
if (value) {
|
|
132
|
+
normalized.push('-RuntimeSha256', value);
|
|
133
|
+
i += 1;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
normalized.push(arg);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return normalized;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function resolvePowerShellCommand() {
|
|
145
|
+
const candidates = process.env.CUE_POWERSHELL_EXE
|
|
146
|
+
? [process.env.CUE_POWERSHELL_EXE]
|
|
147
|
+
: ['powershell.exe', 'pwsh.exe'];
|
|
148
|
+
|
|
149
|
+
for (const candidate of candidates) {
|
|
150
|
+
const result = spawnSync(candidate, ['-NoProfile', '-Command', '$PSVersionTable.PSVersion.Major'], {
|
|
151
|
+
stdio: 'ignore',
|
|
152
|
+
});
|
|
153
|
+
if (!result.error) {
|
|
154
|
+
return candidate;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function resolveWindowsUpdateCommand() {
|
|
162
|
+
const nodeDir = path.dirname(process.execPath);
|
|
163
|
+
const commandCandidates = [
|
|
164
|
+
{
|
|
165
|
+
name: 'bun',
|
|
166
|
+
checks: ['bun', 'bun.exe'],
|
|
167
|
+
args: ['add', '-g', '@plusonelabs/cue@latest'],
|
|
168
|
+
label: 'bun add -g @plusonelabs/cue@latest',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: 'npm',
|
|
172
|
+
checks: ['npm', 'npm.cmd', 'npm.exe', path.join(nodeDir, 'npm.cmd'), path.join(nodeDir, 'npm.exe')],
|
|
173
|
+
args: ['install', '-g', '@plusonelabs/cue@latest'],
|
|
174
|
+
label: 'npm install -g @plusonelabs/cue@latest',
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
for (const candidate of commandCandidates) {
|
|
179
|
+
for (const checkCmd of candidate.checks) {
|
|
180
|
+
const check = runWindowsTool(checkCmd, ['--version'], 'ignore');
|
|
181
|
+
if (!check.error && check.status === 0) {
|
|
182
|
+
return {
|
|
183
|
+
name: candidate.name,
|
|
184
|
+
cmd: checkCmd,
|
|
185
|
+
args: candidate.args,
|
|
186
|
+
label: candidate.label,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function runWindowsHostUpdateFlow(extraArgs) {
|
|
196
|
+
if (extraArgs.length > 0) {
|
|
197
|
+
console.error('cue update on Windows does not support additional arguments yet.');
|
|
198
|
+
console.error('Run `cue --windows-bootstrap --install-cue` directly if you need custom bootstrap flags.');
|
|
199
|
+
return 1;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const updateCommand = resolveWindowsUpdateCommand();
|
|
203
|
+
if (!updateCommand) {
|
|
204
|
+
console.error('No supported host package manager found for Windows update (need bun or npm).');
|
|
205
|
+
return 1;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
console.log('Windows host detected (WSL2-supported mode).');
|
|
209
|
+
console.log(`Updating host package with: ${updateCommand.label}`);
|
|
210
|
+
console.log('');
|
|
211
|
+
|
|
212
|
+
const hostUpdate = runWindowsTool(updateCommand.cmd, updateCommand.args, 'inherit');
|
|
213
|
+
if (hostUpdate.error) {
|
|
214
|
+
console.error(`Host package update failed: ${hostUpdate.error.message}`);
|
|
215
|
+
return 1;
|
|
216
|
+
}
|
|
217
|
+
if (typeof hostUpdate.status === 'number' && hostUpdate.status !== 0) {
|
|
218
|
+
console.error(`Host package update failed (exit ${hostUpdate.status}).`);
|
|
219
|
+
return hostUpdate.status;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
console.log('');
|
|
223
|
+
console.log('Refreshing WSL runtime with bootstrap (--install-cue)...');
|
|
224
|
+
console.log('');
|
|
225
|
+
|
|
226
|
+
const bootstrapCode = runWindowsBootstrap(['-InstallCue']);
|
|
227
|
+
if (bootstrapCode !== 0) {
|
|
228
|
+
console.error('WSL runtime refresh failed during Windows update flow.');
|
|
229
|
+
return bootstrapCode;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
console.log('');
|
|
233
|
+
console.log('Windows host and WSL runtime update flow completed.');
|
|
234
|
+
return 0;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function quoteCmdArg(value) {
|
|
238
|
+
const text = String(value ?? '');
|
|
239
|
+
if (text.length === 0) {
|
|
240
|
+
return '""';
|
|
241
|
+
}
|
|
242
|
+
if (!/[ \t"&()<>^|]/.test(text)) {
|
|
243
|
+
return text;
|
|
244
|
+
}
|
|
245
|
+
return `"${text.replace(/"/g, '""')}"`;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function runWindowsTool(command, args, stdio) {
|
|
249
|
+
const cmdLine = [command, ...args].map(quoteCmdArg).join(' ');
|
|
250
|
+
return spawnSync('cmd.exe', ['/d', '/s', '/c', cmdLine], {
|
|
251
|
+
stdio,
|
|
252
|
+
windowsHide: false,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async function runCueInWsl(userArgs) {
|
|
257
|
+
const wslExe = process.env.CUE_WSL_EXE || 'wsl.exe';
|
|
258
|
+
const statusCheck = spawnSync(wslExe, ['--status'], { stdio: 'ignore' });
|
|
259
|
+
if (statusCheck.error) {
|
|
260
|
+
printWslMissingHelp(statusCheck.error);
|
|
261
|
+
return 1;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const mappedCwd = windowsPathToWslPath(process.cwd());
|
|
265
|
+
if (!mappedCwd) {
|
|
266
|
+
console.error(`Warning: could not map Windows cwd to WSL path: ${process.cwd()}`);
|
|
267
|
+
console.error('Cue will start in the default WSL working directory.');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const distro = (process.env.CUE_WSL_DISTRO || '').trim();
|
|
271
|
+
if (distro && !validateRequestedWslDistro(wslExe, distro)) {
|
|
272
|
+
return 1;
|
|
273
|
+
}
|
|
274
|
+
const wslArgs = [];
|
|
275
|
+
if (distro) {
|
|
276
|
+
wslArgs.push('-d', distro);
|
|
277
|
+
}
|
|
278
|
+
wslArgs.push(
|
|
279
|
+
'-e',
|
|
280
|
+
'bash',
|
|
281
|
+
'-lc',
|
|
282
|
+
WSL_LAUNCH_SCRIPT,
|
|
283
|
+
'cue-wsl-wrapper',
|
|
284
|
+
mappedCwd || '__CUE_NO_CWD__',
|
|
285
|
+
...userArgs
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
const child = spawn(wslExe, wslArgs, {
|
|
289
|
+
stdio: 'inherit',
|
|
290
|
+
windowsHide: false,
|
|
291
|
+
env: {
|
|
292
|
+
...process.env,
|
|
293
|
+
CUE_WINDOWS_HOST_WRAPPER: '1',
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
debugLog('Launching WSL wrapper', {
|
|
298
|
+
wslExe,
|
|
299
|
+
distro: distro || '(default)',
|
|
300
|
+
mappedCwd: mappedCwd || null,
|
|
301
|
+
args: userArgs,
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
return await new Promise((resolve) => {
|
|
305
|
+
let settled = false;
|
|
306
|
+
const settle = (code) => {
|
|
307
|
+
if (settled) return;
|
|
308
|
+
settled = true;
|
|
309
|
+
resolve(code);
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
child.on('error', (error) => {
|
|
313
|
+
console.error(`Failed to launch WSL: ${error.message}`);
|
|
314
|
+
settle(1);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
child.on('exit', (code, signal) => {
|
|
318
|
+
if (typeof code === 'number') {
|
|
319
|
+
settle(code);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
if (signal) {
|
|
323
|
+
console.error(`WSL process exited due to signal: ${signal}`);
|
|
324
|
+
}
|
|
325
|
+
settle(1);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
process.on('SIGINT', () => child.kill('SIGINT'));
|
|
329
|
+
process.on('SIGTERM', () => child.kill('SIGTERM'));
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function validateRequestedWslDistro(wslExe, distro) {
|
|
334
|
+
const listed = listWslDistros(wslExe);
|
|
335
|
+
if (!listed.ok) {
|
|
336
|
+
debugLog('WSL distro listing unavailable; skipping CUE_WSL_DISTRO validation', {
|
|
337
|
+
error: listed.error,
|
|
338
|
+
});
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const requested = distro.trim().toLowerCase();
|
|
343
|
+
const matched = listed.names.some((name) => name.toLowerCase() === requested);
|
|
344
|
+
if (matched) {
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
console.error(`WSL distro not found: ${distro}`);
|
|
349
|
+
if (listed.names.length > 0) {
|
|
350
|
+
console.error('Available distros:');
|
|
351
|
+
for (const name of listed.names) {
|
|
352
|
+
console.error(` - ${name}`);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
console.error('Update CUE_WSL_DISTRO or unset it to use the default WSL distro.');
|
|
356
|
+
console.error('Tip: Run `cue --windows-bootstrap` from PowerShell to validate your WSL setup.');
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function listWslDistros(wslExe) {
|
|
361
|
+
const attempts = [
|
|
362
|
+
['--list', '--quiet'],
|
|
363
|
+
['-l', '-q'],
|
|
364
|
+
];
|
|
365
|
+
|
|
366
|
+
let lastError = null;
|
|
367
|
+
for (const args of attempts) {
|
|
368
|
+
const result = spawnSync(wslExe, args, {
|
|
369
|
+
encoding: 'utf8',
|
|
370
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
371
|
+
windowsHide: true,
|
|
372
|
+
});
|
|
373
|
+
if (result.error) {
|
|
374
|
+
lastError = result.error.message;
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
if (typeof result.status === 'number' && result.status !== 0) {
|
|
378
|
+
const detail = String(result.stderr || result.stdout || '').trim();
|
|
379
|
+
lastError = detail || `wsl exited with code ${result.status}`;
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return { ok: true, names: parseWslDistroList(String(result.stdout || '')) };
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return { ok: false, names: [], error: lastError || 'unknown error' };
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function parseWslDistroList(output) {
|
|
390
|
+
const nullChar = String.fromCharCode(0);
|
|
391
|
+
return output
|
|
392
|
+
.split(/\r?\n/)
|
|
393
|
+
.map((line) =>
|
|
394
|
+
line
|
|
395
|
+
.replaceAll(nullChar, '')
|
|
396
|
+
.replace(/^\s*\*?\s*/, '')
|
|
397
|
+
.trim()
|
|
398
|
+
)
|
|
399
|
+
.filter(Boolean);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function debugLog(message, payload) {
|
|
403
|
+
if (!WRAPPER_DEBUG) return;
|
|
404
|
+
const suffix =
|
|
405
|
+
payload && typeof payload === 'object'
|
|
406
|
+
? ` ${JSON.stringify(payload)}`
|
|
407
|
+
: payload !== undefined
|
|
408
|
+
? ` ${String(payload)}`
|
|
409
|
+
: '';
|
|
410
|
+
console.error(`[cue windows-wrapper] ${message}${suffix}`);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function normalizeWindowsWrapperArgv(argv) {
|
|
414
|
+
if (!isWindowsHost || !Array.isArray(argv) || argv.length < 2) {
|
|
415
|
+
return argv;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const stripControlChars = (value) => {
|
|
419
|
+
let out = '';
|
|
420
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
421
|
+
const code = value.charCodeAt(i);
|
|
422
|
+
if (code >= 32 && code !== 127) {
|
|
423
|
+
out += value[i];
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return out;
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
const normalizeArg = (value) =>
|
|
430
|
+
stripControlChars(String(value ?? ''))
|
|
431
|
+
.replace(/^['"]+|['"]+$/g, '')
|
|
432
|
+
.trim();
|
|
433
|
+
|
|
434
|
+
const normalizeCandidate = (value) => normalizeArg(value).replace(/^\\\\\?\\/, '');
|
|
435
|
+
|
|
436
|
+
const execPath = normalizeCandidate(process.execPath);
|
|
437
|
+
const execPathLower = execPath.toLowerCase();
|
|
438
|
+
const execBase = path.basename(execPathLower);
|
|
439
|
+
|
|
440
|
+
const looksLikeExecPath = (value) => {
|
|
441
|
+
if (value === undefined) return false;
|
|
442
|
+
const normalized = normalizeCandidate(value);
|
|
443
|
+
if (!normalized) return false;
|
|
444
|
+
const lower = normalized.toLowerCase();
|
|
445
|
+
const base = path.basename(lower);
|
|
446
|
+
return (
|
|
447
|
+
lower === execPathLower ||
|
|
448
|
+
base === execBase ||
|
|
449
|
+
lower.endsWith('\\node.exe') ||
|
|
450
|
+
lower.endsWith('/node.exe') ||
|
|
451
|
+
(base === 'node.exe' && fs.existsSync(normalized))
|
|
452
|
+
);
|
|
453
|
+
};
|
|
454
|
+
|
|
455
|
+
const next = [...argv];
|
|
456
|
+
|
|
457
|
+
// Windows shims can inject duplicate node.exe tokens near the front of argv.
|
|
458
|
+
for (let i = 1; i <= 4 && i < next.length; ) {
|
|
459
|
+
if (looksLikeExecPath(next[i])) {
|
|
460
|
+
next.splice(i, 1);
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
i += 1;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (WRAPPER_DEBUG && next.length !== argv.length) {
|
|
467
|
+
debugLog('Normalized Windows argv', {
|
|
468
|
+
before: argv,
|
|
469
|
+
after: next,
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
return next;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function printWslMissingHelp(error) {
|
|
477
|
+
console.error('WSL2 is required for Cue on Windows (supported path).');
|
|
478
|
+
console.error(`WSL launch failed: ${error.message}`);
|
|
479
|
+
console.error('');
|
|
480
|
+
console.error('Next steps:');
|
|
481
|
+
console.error(' 1) Install WSL2 and Ubuntu LTS');
|
|
482
|
+
console.error(' 2) Run `cue --windows-bootstrap` from PowerShell');
|
|
483
|
+
console.error(' 3) Install Cue inside WSL (Ubuntu): bun add -g @plusonelabs/cue');
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function windowsPathToWslPath(inputPath) {
|
|
487
|
+
if (!inputPath) return null;
|
|
488
|
+
const normalized = inputPath.replaceAll('/', '\\');
|
|
489
|
+
|
|
490
|
+
const driveMatch = normalized.match(/^([A-Za-z]):\\(.*)$/);
|
|
491
|
+
if (driveMatch) {
|
|
492
|
+
const drive = driveMatch[1].toLowerCase();
|
|
493
|
+
const rest = driveMatch[2].replaceAll('\\', '/');
|
|
494
|
+
return `/mnt/${drive}/${rest}`;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
const wslUncMatch = normalized.match(/^\\\\wsl(?:\\.localhost)?\\[^\\]+\\(.*)$/i);
|
|
498
|
+
if (wslUncMatch) {
|
|
499
|
+
return `/${wslUncMatch[1].replaceAll('\\', '/')}`;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return null;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
const WSL_LAUNCH_SCRIPT = `
|
|
506
|
+
set -e
|
|
507
|
+
cwd="$1"
|
|
508
|
+
shift
|
|
509
|
+
if [ "$cwd" != "__CUE_NO_CWD__" ]; then
|
|
510
|
+
cd "$cwd"
|
|
511
|
+
fi
|
|
512
|
+
if [ -d "$HOME/.cue/bin" ]; then
|
|
513
|
+
PATH="$HOME/.cue/bin:$PATH"
|
|
514
|
+
fi
|
|
515
|
+
cue_path="$(command -v cue || true)"
|
|
516
|
+
if [ -z "$cue_path" ]; then
|
|
517
|
+
echo "Cue is not installed inside WSL." >&2
|
|
518
|
+
echo "Install inside Ubuntu: bun add -g @plusonelabs/cue" >&2
|
|
519
|
+
echo "Or install via bootstrap runtime artifact and ensure ~/.cue/bin is on PATH." >&2
|
|
520
|
+
exit 127
|
|
521
|
+
fi
|
|
522
|
+
case "$cue_path" in
|
|
523
|
+
/mnt/*|*.exe|*.cmd)
|
|
524
|
+
echo "Cue inside WSL resolves to a Windows command: $cue_path" >&2
|
|
525
|
+
echo "A Linux cue runtime should be installed in ~/.cue/bin or via Bun/npm inside WSL." >&2
|
|
526
|
+
echo "If you used bootstrap artifact install, add ~/.cue/bin to PATH or restart your shell." >&2
|
|
527
|
+
exit 126
|
|
528
|
+
;;
|
|
529
|
+
esac
|
|
530
|
+
node_path="$(command -v node || true)"
|
|
531
|
+
if [ -z "$node_path" ]; then
|
|
532
|
+
echo "Linux Node.js runtime is not installed inside WSL." >&2
|
|
533
|
+
echo "Cue requires a Linux node binary in Ubuntu (not only Windows npm/node)." >&2
|
|
534
|
+
echo "Example: sudo apt update && sudo apt install -y nodejs npm" >&2
|
|
535
|
+
exit 125
|
|
536
|
+
fi
|
|
537
|
+
case "$node_path" in
|
|
538
|
+
/mnt/*|*.exe|*.cmd)
|
|
539
|
+
echo "WSL node resolves to a Windows executable: $node_path" >&2
|
|
540
|
+
echo "Install a Linux Node.js runtime in Ubuntu (example: sudo apt install -y nodejs npm)." >&2
|
|
541
|
+
exit 125
|
|
542
|
+
;;
|
|
543
|
+
esac
|
|
544
|
+
exec "$cue_path" "$@"
|
|
545
|
+
`;
|
|
546
|
+
|
|
547
|
+
main().catch((error) => {
|
|
548
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
549
|
+
process.exit(1);
|
|
550
|
+
});
|