From bde93b825ebbb163625e8326658adbf8e0b3efe3 Mon Sep 17 00:00:00 2001 From: Splash Date: Wed, 6 May 2026 11:53:10 +0800 Subject: [PATCH 1/2] Add proxy config patch script --- scripts/patch-all.js | 1 + scripts/patch-proxy-config.js | 263 ++++++++++++++++++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 scripts/patch-proxy-config.js diff --git a/scripts/patch-all.js b/scripts/patch-all.js index 91f47fb..b62ba8f 100644 --- a/scripts/patch-all.js +++ b/scripts/patch-all.js @@ -17,6 +17,7 @@ const PATCHES = [ "patch-devtools.js", "patch-fast-mode.js", "patch-plugin-auth.js", + "patch-proxy-config.js", ]; function main() { diff --git a/scripts/patch-proxy-config.js b/scripts/patch-proxy-config.js new file mode 100644 index 0000000..fd5170a --- /dev/null +++ b/scripts/patch-proxy-config.js @@ -0,0 +1,263 @@ +#!/usr/bin/env node +/** + * Post-build patch: read [proxy] from Codex config.toml and apply it app-wide. + * + * Supported config: + * [proxy] + * enabled = true + * server = "http://127.0.0.1:7890" + * bypass = "localhost,127.0.0.1," + * + * Optional env override: + * CODEX_PROXY_CONFIG_PATH=C:\path\to\config.toml + * + * The injected code runs in bootstrap.js before app.whenReady(), so + * Electron command-line proxy switches are applied early. It also exports + * HTTP_PROXY / HTTPS_PROXY / ALL_PROXY / NO_PROXY for Node and child + * processes that inherit process.env. + */ +const fs = require("fs"); +const path = require("path"); + +const { SRC_DIR, relPath } = require("./patch-util"); + +const MARKER = "Codex proxy config patch"; + +const INJECTED = String.raw` +/* Codex proxy config patch */ +(function(){ + function stripQuotes(v){ + v=String(v==null?"":v).trim(); + if((v.startsWith('"')&&v.endsWith('"'))||(v.startsWith("'")&&v.endsWith("'"))) return v.slice(1,-1); + return v; + } + function parseBool(v){ + v=stripQuotes(v).toLowerCase(); + return v==="true"||v==="1"||v==="yes"||v==="on"; + } + function stripTomlComment(raw){ + var quote=null, escaped=false; + for(var i=0;i + fs.existsSync(path.join(SRC_DIR, p)), + ); + + const dirs = []; + for (const plat of platforms) { + for (const rel of [ + [".vite", "build"], + ["src", ".vite", "build"], + ]) { + const dir = path.join(SRC_DIR, plat, ...rel); + if (fs.existsSync(dir)) dirs.push({ platform: plat, dir }); + } + } + + // Flat prepared src/ fallback. + for (const rel of [ + [".vite", "build"], + ["src", ".vite", "build"], + ]) { + const dir = path.join(SRC_DIR, ...rel); + if (fs.existsSync(dir)) dirs.push({ platform: "legacy", dir }); + } + + return dirs; +} + +function locateBootstraps(platform) { + const targets = []; + const seen = new Set(); + for (const { platform: plat, dir } of buildDirsForPlatform(platform)) { + const file = path.join(dir, "bootstrap.js"); + if (!fs.existsSync(file)) continue; + const real = path.resolve(file); + if (seen.has(real)) continue; + seen.add(real); + targets.push({ platform: plat, path: file }); + } + + // Fallback for upstream layout changes. Keep it conservative: + // bootstrap.js is the Electron entrypoint, and this patch is idempotent. + function walk(dir) { + if (!fs.existsSync(dir)) return; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + if (entry.name === "node_modules" || entry.name === "app.asar.unpacked") continue; + walk(full); + continue; + } + if (entry.isFile() && entry.name === "bootstrap.js") { + const real = path.resolve(full); + if (seen.has(real)) continue; + seen.add(real); + targets.push({ platform: platform || "auto", path: full }); + } + } + } + if (targets.length === 0) { + const fallbackRoot = platform ? path.join(SRC_DIR, platform) : SRC_DIR; + walk(fallbackRoot); + } + + return targets; +} + +function patchSource(source) { + if (source.includes(MARKER)) { + const start = source.indexOf("/* " + MARKER + " */"); + const end = source.indexOf("})();", start); + if (start !== -1 && end !== -1) { + const blockEnd = end + "})();".length; + const current = source.slice(start, blockEnd); + if (current === INJECTED) return { code: source, status: "already" }; + return { + code: `${source.slice(0, start)}${INJECTED}${source.slice(blockEnd)}`, + status: "updated", + }; + } + return { code: source, status: "already" }; + } + + const electronRequire = /require\((["'`])electron\1\)/.exec(source); + if (electronRequire) { + const semicolon = source.indexOf(";", electronRequire.index); + if (semicolon !== -1) { + const insertAt = semicolon + 1; + return { + code: `${source.slice(0, insertAt)}${INJECTED}\n${source.slice(insertAt)}`, + status: "patched", + }; + } + } + + const legacyNeedle = "var a=`desktop.intelLaunchWarning.message`"; + const legacyIdx = source.indexOf(legacyNeedle); + if (legacyIdx === -1) { + return { code: source, status: "no-match" }; + } + + return { + code: `${source.slice(0, legacyIdx)}${INJECTED}\n${source.slice(legacyIdx)}`, + status: "patched", + }; +} + +function main() { + const args = process.argv.slice(2); + const isCheck = args.includes("--check"); + const platform = args.find((a) => ["mac-arm64", "mac-x64", "win"].includes(a)); + + const targets = locateBootstraps(platform); + if (targets.length === 0) { + console.log("[ok] No bootstrap.js found; skipping proxy config patch"); + return; + } + + let patchedCount = 0; + for (const target of targets) { + console.log(`\n-- [${target.platform}] ${relPath(target.path)}`); + const source = fs.readFileSync(target.path, "utf8"); + const result = patchSource(source); + + if (result.status === "already") { + console.log(" [ok] Proxy config patch already injected"); + continue; + } + if (result.status === "no-match") { + console.log(" [!] bootstrap injection point not found"); + continue; + } + + patchedCount++; + if (isCheck) { + console.log(" [?] Would inject proxy config bootstrap"); + continue; + } + + fs.writeFileSync(target.path, result.code, "utf8"); + console.log(result.status === "updated" + ? " [ok] Proxy config bootstrap updated" + : " [ok] Proxy config bootstrap injected"); + } + + if (isCheck && patchedCount > 0) { + console.log(`\n=> Total: ${patchedCount} patchable bootstrap file(s)`); + } +} + +main(); From 7cff33d30e97817c5c490830424c77666d2d33e8 Mon Sep 17 00:00:00 2001 From: Splash Date: Wed, 6 May 2026 12:20:23 +0800 Subject: [PATCH 2/2] Update scripts/patch-proxy-config.js Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> --- scripts/patch-proxy-config.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/scripts/patch-proxy-config.js b/scripts/patch-proxy-config.js index fd5170a..06150ba 100644 --- a/scripts/patch-proxy-config.js +++ b/scripts/patch-proxy-config.js @@ -181,16 +181,24 @@ function patchSource(source) { if (source.includes(MARKER)) { const start = source.indexOf("/* " + MARKER + " */"); const end = source.indexOf("})();", start); - if (start !== -1 && end !== -1) { - const blockEnd = end + "})();".length; - const current = source.slice(start, blockEnd); - if (current === INJECTED) return { code: source, status: "already" }; - return { - code: `${source.slice(0, start)}${INJECTED}${source.slice(blockEnd)}`, - status: "updated", - }; + + // If we see the marker but can't find a well-formed injected block, + // treat this as a mismatch so callers can log/handle the anomaly. + if (start === -1 || end === -1) { + return { code: source, status: "no-match" }; } - return { code: source, status: "already" }; + + const blockEnd = end + "})();".length; + const current = source.slice(start, blockEnd); + + if (current === INJECTED) { + return { code: source, status: "already" }; + } + + return { + code: `${source.slice(0, start)}${INJECTED}${source.slice(blockEnd)}`, + status: "updated", + }; } const electronRequire = /require\((["'`])electron\1\)/.exec(source);