From c07ec46a8bf419adeec9fbf241e43183a96fe524 Mon Sep 17 00:00:00 2001 From: cluic Date: Wed, 20 May 2026 13:24:21 +0800 Subject: [PATCH] Fix Windows debug startup detection --- node/.changeset/fix-windows-debug-start.md | 5 +++ node/src/server.mjs | 41 +++++++++++++++++++++- node/test/server.test.mjs | 21 ++++++++++- 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 node/.changeset/fix-windows-debug-start.md diff --git a/node/.changeset/fix-windows-debug-start.md b/node/.changeset/fix-windows-debug-start.md new file mode 100644 index 0000000..7580c49 --- /dev/null +++ b/node/.changeset/fix-windows-debug-start.md @@ -0,0 +1,5 @@ +--- +"@cluic/codex-remote-proxy": patch +--- + +Fix Windows startup detection so `crp start --debug` keeps the proxy process running. diff --git a/node/src/server.mjs b/node/src/server.mjs index afb3aa0..6ae6e20 100644 --- a/node/src/server.mjs +++ b/node/src/server.mjs @@ -1,5 +1,7 @@ import http from "node:http"; import https from "node:https"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; import { readFileSync } from "node:fs"; import { resolve, dirname } from "node:path"; import { URL } from "node:url"; @@ -560,6 +562,43 @@ export function startServer(settings = loadConfig()) { return app; } -if (import.meta.url === `file://${process.argv[1]}`) { +function isWindowsStylePath(filePath) { + return /^[A-Za-z]:[\\/]/.test(filePath); +} + +function modulePathFromMetaUrl(metaUrl) { + const url = new URL(metaUrl); + if (url.protocol !== "file:") { + return null; + } + const pathname = decodeURIComponent(url.pathname); + if (/^\/[A-Za-z]:\//.test(pathname)) { + return path.win32.normalize(pathname.slice(1)); + } + return fileURLToPath(metaUrl); +} + +function normalizeExecutionPath(filePath) { + if (!filePath) { + return ""; + } + if (isWindowsStylePath(filePath)) { + return path.win32.normalize(filePath).toLowerCase(); + } + return resolve(filePath); +} + +export function isDirectExecution(metaUrl = import.meta.url, argv1 = process.argv[1]) { + if (!argv1) { + return false; + } + const modulePath = modulePathFromMetaUrl(metaUrl); + if (!modulePath) { + return false; + } + return normalizeExecutionPath(modulePath) === normalizeExecutionPath(argv1); +} + +if (isDirectExecution()) { startServer(); } diff --git a/node/test/server.test.mjs b/node/test/server.test.mjs index 35f5206..82147cf 100644 --- a/node/test/server.test.mjs +++ b/node/test/server.test.mjs @@ -7,7 +7,7 @@ import { join } from "node:path"; import { once } from "node:events"; import { DatabaseSync } from "node:sqlite"; -import { createApp } from "../src/server.mjs"; +import { createApp, isDirectExecution } from "../src/server.mjs"; function makeTempDir(prefix) { return join(os.tmpdir(), `${prefix}-${Date.now()}-${Math.random().toString(16).slice(2)}`); @@ -133,3 +133,22 @@ test("server writes proxied request and response to sqlite", async () => { rmSync(dir, { recursive: true, force: true }); }); + +test("isDirectExecution handles both POSIX and Windows paths", () => { + assert.equal( + isDirectExecution("file:///Users/example/project/node/src/server.mjs", "/Users/example/project/node/src/server.mjs"), + true + ); + assert.equal( + isDirectExecution("file:///C:/Users/Xingh/project/node/src/server.mjs", "C:\\Users\\Xingh\\project\\node\\src\\server.mjs"), + true + ); + assert.equal( + isDirectExecution("file:///c:/Users/Xingh/project/node/src/server.mjs", "C:/Users/Xingh/project/node/src/server.mjs"), + true + ); + assert.equal( + isDirectExecution("file:///C:/Users/Xingh/project/node/src/server.mjs", "C:\\Users\\Xingh\\project\\node\\src\\other.mjs"), + false + ); +});