mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-22 02:56:52 +03:00
Fix Windows question browser opening (#510)
AI assistance: Codex reproduced the issue, implemented the fix, and ran the validation described in the pull request.
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import { spawn } from 'node:child_process';
|
||||
|
||||
export function browserOpenCommand(url, {
|
||||
platform = process.platform,
|
||||
comspec = process.env.ComSpec || process.env.COMSPEC || 'cmd.exe',
|
||||
} = {}) {
|
||||
if (platform === 'darwin') return { command: 'open', args: [url] };
|
||||
if (platform === 'win32') return { command: comspec, args: ['/c', 'start', '', url] };
|
||||
return { command: 'xdg-open', args: [url] };
|
||||
}
|
||||
|
||||
export function openSystemBrowser(url, {
|
||||
platform = process.platform,
|
||||
comspec = process.env.ComSpec || process.env.COMSPEC || 'cmd.exe',
|
||||
spawnImpl = spawn,
|
||||
} = {}) {
|
||||
const { command, args } = browserOpenCommand(url, { platform, comspec });
|
||||
try {
|
||||
const child = spawnImpl(command, args, { stdio: 'ignore', detached: true });
|
||||
child.on('error', () => {});
|
||||
child.unref();
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,7 @@ import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { openSystemBrowser } from './lib/open-system-browser.mjs';
|
||||
|
||||
function arg(name, fallback = null) {
|
||||
const i = process.argv.indexOf(`--${name}`);
|
||||
@@ -976,8 +977,7 @@ server.listen(portArg, '127.0.0.1', () => {
|
||||
console.log('Waiting for the user to choose in the browser (Ctrl-C aborts)...');
|
||||
}
|
||||
if (!hasFlag('no-open')) {
|
||||
const opener = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
|
||||
try { spawn(opener, [url], { stdio: 'ignore', detached: true }).unref(); } catch { /* URL printed anyway */ }
|
||||
openSystemBrowser(url);
|
||||
}
|
||||
if (timeoutSec > 0) {
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -5,6 +5,9 @@ import { writeFileSync, mkdtempSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { EventEmitter } from 'node:events';
|
||||
|
||||
import { browserOpenCommand, openSystemBrowser } from '../skill/scripts/lib/open-system-browser.mjs';
|
||||
|
||||
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const SCRIPT = path.join(ROOT, 'skill', 'scripts', 'serve-question.mjs');
|
||||
@@ -39,6 +42,24 @@ const PAYLOAD = {
|
||||
};
|
||||
|
||||
describe('serve-question', () => {
|
||||
it('opens Windows URLs through cmd.exe and reserves the start title argument', () => {
|
||||
assert.deepEqual(
|
||||
browserOpenCommand('http://127.0.0.1:1234/', { platform: 'win32', comspec: 'cmd.exe' }),
|
||||
{ command: 'cmd.exe', args: ['/c', 'start', '', 'http://127.0.0.1:1234/'] },
|
||||
);
|
||||
});
|
||||
|
||||
it('absorbs asynchronous system-opener failures after printing the URL', () => {
|
||||
const child = new EventEmitter();
|
||||
child.unref = () => {};
|
||||
assert.equal(openSystemBrowser('http://127.0.0.1:1234/', {
|
||||
platform: 'linux',
|
||||
spawnImpl: () => child,
|
||||
}), true);
|
||||
assert.equal(child.listenerCount('error'), 1);
|
||||
assert.doesNotThrow(() => child.emit('error', Object.assign(new Error('missing opener'), { code: 'ENOENT' })));
|
||||
});
|
||||
|
||||
it('serves the page, records the answer, prints ANSWER, exits 0', async () => {
|
||||
const { child, url, read } = await startServer(PAYLOAD);
|
||||
const html = await (await fetch(url)).text();
|
||||
|
||||
Reference in New Issue
Block a user