Skip to content

Add CODEX_HOME .env support; patch Electron bundle; ignore .env#2

Open
JKamsker wants to merge 3 commits intoaidanqm:mainfrom
JKamsker:feat/custom-env
Open

Add CODEX_HOME .env support; patch Electron bundle; ignore .env#2
JKamsker wants to merge 3 commits intoaidanqm:mainfrom
JKamsker:feat/custom-env

Conversation

@JKamsker
Copy link

@JKamsker JKamsker commented Feb 4, 2026

Summary by Sourcery

Add support for configuring and persisting CODEX_HOME via .env and environment variables and patch the Electron bundle for improved behavior and diagnostics.

New Features:

  • Support configuring CODEX_HOME via a new run script parameter, environment variables, and a persisted .env file with precedence rules.

Enhancements:

  • Introduce utilities to read and write .env files without BOM and normalize paths for CODEX_HOME resolution.
  • Patch the Electron main bundle to implement the open-config-toml action on desktop and to transparently resolve a real codex.exe when Windows npm shims are used.
  • Improve Electron renderer logging to emit more informative error payloads instead of opaque object representations.
  • Automatically patch the Electron app bundle as part of the run script workflow.

@sourcery-ai
Copy link

sourcery-ai bot commented Feb 4, 2026

Reviewer's Guide

.env-based CODEX_HOME configuration is added to the run script, Electron app bundles are post-processed to patch main/renderer behavior, and .env is now ignored in version control.

Flow diagram for Electron bundle patching via Patch-AppMainJs

flowchart TD
  Start([Start Patch-AppMainJs]) --> MainPath[Compute mainJs = AppDir/.vite/build/main.js]
  MainPath --> CheckMain{main.js exists?}
  CheckMain -->|no| EndNoMain([Return without changes])
  CheckMain -->|yes| ReadMain[Read main.js content as text]

  ReadMain --> InitInsertions[Initialize empty insertions list]

  InitInsertions --> CheckConfigPatch{text not matching Failed to open config.toml?}
  CheckConfigPatch -->|yes| AddConfigPatch[Append open-config-toml patch snippet to insertions]
  CheckConfigPatch -->|no| SkipConfigPatch[Do not modify config handler]

  AddConfigPatch --> CheckSpawnPatch
  SkipConfigPatch --> CheckSpawnPatch

  CheckSpawnPatch{text not matching __codexWindowsPatched?}
  CheckSpawnPatch -->|yes| AddSpawnPatch[Append Windows spawn patch snippet to insertions]
  CheckSpawnPatch -->|no| SkipSpawnPatch[Do not modify spawn]

  AddSpawnPatch --> AnyInsertions
  SkipSpawnPatch --> AnyInsertions

  AnyInsertions{insertions list is empty?} -->|yes| EndNoInsert([Return without changes])
  AnyInsertions -->|no| BuildInsertionText[Join insertions with newlines into insertionText]

  BuildInsertionText --> FindSourceMap{text matches //# sourceMappingURL line?}
  FindSourceMap -->|yes| InsertBeforeMap[Replace sourceMappingURL line with insertionText then source map comment]
  FindSourceMap -->|no| AppendInsertion[Append insertionText to end of file]

  InsertBeforeMap --> WriteMain[Write updated main.js with UTF-8 no BOM]
  AppendInsertion --> WriteMain

  WriteMain --> AssetsPath[Compute assetsDir = AppDir/webview/assets]
  AssetsPath --> CheckAssets{assetsDir exists?}
  CheckAssets -->|no| EndNoAssets([Done patching main only])
  CheckAssets -->|yes| ListIndexFiles[Get index-*.js files]

  ListIndexFiles --> ForEachIndex[For each index-*.js file]
  ForEachIndex --> ReadIndex[Read file content rt]
  ReadIndex --> StoreOrig[Store orig = rt]

  StoreOrig --> ReplaceErrors[Replace error log patterns with more verbose interpolation]
  ReplaceErrors --> ReplaceCleanup[Replace automation cleanup logs to use sanitizeLogValue where desired]

  ReplaceCleanup --> CompareChanges{rt differs from orig?}
  CompareChanges -->|no| NextFile[Skip write for this file]
  CompareChanges -->|yes| WriteIndex[Write updated file with UTF-8 no BOM]

  WriteIndex --> NextFile
  NextFile --> MoreFiles{More index-*.js files?}
  MoreFiles -->|yes| ForEachIndex
  MoreFiles -->|no| EndDone([Finished patching Electron bundle])
Loading

File-Level Changes

Change Details Files
Add dotenv helpers and CODEX_HOME resolution/persistence logic to the run script.
  • Introduce Parse-DotEnvValue, Read-DotEnv, and Set-DotEnvVar helpers for reading and writing .env files without BOMs.
  • Compute CODEX_HOME from CLI argument, environment variables, and .env with explicit-override rules and path normalization.
  • Create and export the resolved CODEX_HOME directory, and persist it back to .env only when explicitly changed.
scripts/run.ps1
Patch the Electron bundle at runtime to improve config handling and logging.
  • Add Patch-AppMainJs to inject support for the open-config-toml message in Electron main.js so it opens/creates CODEX_HOME/config.toml.
  • Within Patch-AppMainJs, on Windows patch child_process.spawn so npm shim-based 'codex' invocations resolve to a real codex.exe if available.
  • Rewrite source-mapped main.js safely, and post-process renderer index-*.js assets to improve error log serialization and specific automation log messages.
  • Invoke Patch-AppMainJs after syncing app.asar.unpacked, ensuring patches are applied on each run unless Reuse is set.
scripts/run.ps1
Ignore local .env configuration from version control.
  • Update .gitignore to exclude the .env file so local CODEX_HOME and other env config are not committed.
.gitignore

Possibly linked issues

  • #extra help for install: The PR patches Electron/CLI resolution to better find codex.exe on Windows, directly addressing the issue’s detection problem.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The bundle patching in Patch-AppMainJs relies on exact string/regex matches in minified JS; consider centralizing the patterns/constants or adding some basic validation/logging so that silent mismatches or future upstream changes are easier to detect and debug.
  • Several try { ... } catch {} blocks in Patch-AppMainJs and the asset-rewriting loop swallow all exceptions; it would be safer to at least log failures (or scope the try blocks more narrowly) so unexpected issues with file IO or pattern replacements don’t silently fail.
  • The .env parsing/writing helpers implement a custom subset of dotenv behavior (e.g., no inline comments or export support); if this script is expected to coexist with other dotenv tooling, consider documenting or slightly extending the parser to handle the most common variations to avoid surprising users.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The bundle patching in `Patch-AppMainJs` relies on exact string/regex matches in minified JS; consider centralizing the patterns/constants or adding some basic validation/logging so that silent mismatches or future upstream changes are easier to detect and debug.
- Several `try { ... } catch {}` blocks in `Patch-AppMainJs` and the asset-rewriting loop swallow all exceptions; it would be safer to at least log failures (or scope the `try` blocks more narrowly) so unexpected issues with file IO or pattern replacements don’t silently fail.
- The `.env` parsing/writing helpers implement a custom subset of dotenv behavior (e.g., no inline comments or `export` support); if this script is expected to coexist with other dotenv tooling, consider documenting or slightly extending the parser to handle the most common variations to avoid surprising users.

## Individual Comments

### Comment 1
<location> `scripts/run.ps1:283-284` </location>
<code_context>
+  $p = [Environment]::ExpandEnvironmentVariables($Path).Trim().Trim('"').Trim("'")
+  $p = $p -replace "/", "\"
+  try {
+    $full = [System.IO.Path]::GetFullPath($p)
+    return $full.TrimEnd("\")
+  } catch {
+    return $p.TrimEnd("\")
</code_context>

<issue_to_address>
**issue:** Normalize-PathString can strip the trailing backslash from root paths like `C:\` or UNC shares.

`TrimEnd("\")` turns `C:\` into `C:`, and similarly alters UNC roots like `\\server\share\`, which is not equivalent and can change behavior. Consider only trimming a trailing separator when the path is longer than the minimum root (or after `Path.GetFullPath`, only when there is more than a root component).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant