1- import { spawn , spawnSync , type SpawnSyncReturns } from "node:child_process" ;
2- import { copyFileSync , mkdirSync , mkdtempSync , readFileSync , rmSync , writeFileSync } from "node:fs" ;
1+ import { type SpawnSyncReturns , spawn , spawnSync } from "node:child_process" ;
2+ import {
3+ copyFileSync ,
4+ mkdirSync ,
5+ mkdtempSync ,
6+ readFileSync ,
7+ rmSync ,
8+ writeFileSync ,
9+ } from "node:fs" ;
310import { tmpdir } from "node:os" ;
411import { delimiter , dirname , join } from "node:path" ;
512import process from "node:process" ;
@@ -42,8 +49,14 @@ function createWrapperFixture(): string {
4249 createdDirs . push ( fixtureRoot ) ;
4350 const scriptDir = join ( fixtureRoot , "scripts" ) ;
4451 mkdirSync ( scriptDir , { recursive : true } ) ;
45- copyFileSync ( join ( repoRootDir , "scripts" , "codex.js" ) , join ( scriptDir , "codex.js" ) ) ;
46- copyFileSync ( join ( repoRootDir , "scripts" , "codex-routing.js" ) , join ( scriptDir , "codex-routing.js" ) ) ;
52+ copyFileSync (
53+ join ( repoRootDir , "scripts" , "codex.js" ) ,
54+ join ( scriptDir , "codex.js" ) ,
55+ ) ;
56+ copyFileSync (
57+ join ( repoRootDir , "scripts" , "codex-routing.js" ) ,
58+ join ( scriptDir , "codex-routing.js" ) ,
59+ ) ;
4760 return fixtureRoot ;
4861}
4962
@@ -149,7 +162,9 @@ function runWrapperAsync(
149162 } ) ;
150163}
151164
152- function combinedOutput ( result : SpawnSyncReturns < string > | WrapperAsyncResult ) : string {
165+ function combinedOutput (
166+ result : SpawnSyncReturns < string > | WrapperAsyncResult ,
167+ ) : string {
153168 return `${ result . stdout ?? "" } \n${ result . stderr ?? "" } ` ;
154169}
155170
@@ -185,6 +200,32 @@ describe("codex bin wrapper", () => {
185200 expect ( result . stdout ) . toContain ( "FORWARDED:--version" ) ;
186201 } ) ;
187202
203+ it ( "injects file auth store forwarding for wrapped real cli invocations by default" , ( ) => {
204+ const fixtureRoot = createWrapperFixture ( ) ;
205+ const fakeBin = createFakeCodexBin ( fixtureRoot ) ;
206+ const result = runWrapper ( fixtureRoot , [ "exec" , "status" ] , {
207+ CODEX_MULTI_AUTH_REAL_CODEX_BIN : fakeBin ,
208+ } ) ;
209+
210+ expect ( result . status ) . toBe ( 0 ) ;
211+ expect ( result . stdout ) . toContain (
212+ 'FORWARDED:exec status -c cli_auth_credentials_store="file"' ,
213+ ) ;
214+ } ) ;
215+
216+ it ( "skips file auth store forwarding when the opt-out env var is disabled" , ( ) => {
217+ const fixtureRoot = createWrapperFixture ( ) ;
218+ const fakeBin = createFakeCodexBin ( fixtureRoot ) ;
219+ const result = runWrapper ( fixtureRoot , [ "exec" , "status" ] , {
220+ CODEX_MULTI_AUTH_REAL_CODEX_BIN : fakeBin ,
221+ CODEX_MULTI_AUTH_FORCE_FILE_AUTH_STORE : "0" ,
222+ } ) ;
223+
224+ expect ( result . status ) . toBe ( 0 ) ;
225+ expect ( result . stdout ) . toContain ( "FORWARDED:exec status" ) ;
226+ expect ( result . stdout ) . not . toContain ( 'cli_auth_credentials_store="file"' ) ;
227+ } ) ;
228+
188229 it ( "installs Windows codex shell guards to survive shim takeover" , ( ) => {
189230 if ( process . platform !== "win32" ) {
190231 return ;
@@ -206,7 +247,8 @@ describe("codex bin wrapper", () => {
206247 ) ;
207248 writeFileSync (
208249 join ( shimDir , "codex.ps1" ) ,
209- 'Write-Output "$basedir/node_modules/@openai/codex/bin/codex.js"' + "\r\n" ,
250+ 'Write-Output "$basedir/node_modules/@openai/codex/bin/codex.js"' +
251+ "\r\n" ,
210252 "utf8" ,
211253 ) ;
212254
@@ -246,21 +288,36 @@ describe("codex bin wrapper", () => {
246288 expect ( readFileSync ( pwshProfilePath , "utf8" ) ) . toContain (
247289 "# >>> codex-multi-auth shell guard >>>" ,
248290 ) ;
249- expect ( readFileSync ( pwshProfilePath , "utf8" ) ) . toContain ( "CodexMultiAuthShim" ) ;
291+ expect ( readFileSync ( pwshProfilePath , "utf8" ) ) . toContain (
292+ "CodexMultiAuthShim" ,
293+ ) ;
250294 } ) ;
251295
252296 it ( "prefers invocation-derived shim directory over PATH-decoy shim entries" , ( ) => {
253297 if ( process . platform !== "win32" ) {
254298 return ;
255299 }
256300
257- const fixtureRoot = mkdtempSync ( join ( tmpdir ( ) , "codex-wrapper-invoke-fixture-" ) ) ;
301+ const fixtureRoot = mkdtempSync (
302+ join ( tmpdir ( ) , "codex-wrapper-invoke-fixture-" ) ,
303+ ) ;
258304 createdDirs . push ( fixtureRoot ) ;
259305 const globalShimDir = join ( fixtureRoot , "global-bin" ) ;
260- const scriptDir = join ( globalShimDir , "node_modules" , "codex-multi-auth" , "scripts" ) ;
306+ const scriptDir = join (
307+ globalShimDir ,
308+ "node_modules" ,
309+ "codex-multi-auth" ,
310+ "scripts" ,
311+ ) ;
261312 mkdirSync ( scriptDir , { recursive : true } ) ;
262- copyFileSync ( join ( repoRootDir , "scripts" , "codex.js" ) , join ( scriptDir , "codex.js" ) ) ;
263- copyFileSync ( join ( repoRootDir , "scripts" , "codex-routing.js" ) , join ( scriptDir , "codex-routing.js" ) ) ;
313+ copyFileSync (
314+ join ( repoRootDir , "scripts" , "codex.js" ) ,
315+ join ( scriptDir , "codex.js" ) ,
316+ ) ;
317+ copyFileSync (
318+ join ( repoRootDir , "scripts" , "codex-routing.js" ) ,
319+ join ( scriptDir , "codex-routing.js" ) ,
320+ ) ;
264321 writeFileSync (
265322 join ( globalShimDir , "codex-multi-auth.cmd" ) ,
266323 "@ECHO OFF\r\nREM real shim\r\n" ,
@@ -285,7 +342,9 @@ describe("codex bin wrapper", () => {
285342 expect ( readFileSync ( join ( globalShimDir , "codex.bat" ) , "utf8" ) ) . toContain (
286343 "codex-multi-auth windows shim guardian v1" ,
287344 ) ;
288- expect ( ( ) => readFileSync ( join ( decoyShimDir , "codex.bat" ) , "utf8" ) ) . toThrow ( ) ;
345+ expect ( ( ) =>
346+ readFileSync ( join ( decoyShimDir , "codex.bat" ) , "utf8" ) ,
347+ ) . toThrow ( ) ;
289348 } ) ;
290349
291350 it ( "honors bypass for auth commands and forwards to the real CLI" , ( ) => {
@@ -369,20 +428,20 @@ describe("codex bin wrapper", () => {
369428 it ( "prints actionable guidance when real codex bin cannot be found" , ( ) => {
370429 const fixtureRoot = createWrapperFixture ( ) ;
371430 const missingOverride = join ( fixtureRoot , "missing" , "codex.js" ) ;
372- const result = runWrapper (
373- fixtureRoot ,
374- [ "--version" ] ,
375- {
376- CODEX_MULTI_AUTH_BYPASS : "" ,
377- CODEX_MULTI_AUTH_REAL_CODEX_BIN : missingOverride ,
378- } ,
379- ) ;
431+ const result = runWrapper ( fixtureRoot , [ "--version" ] , {
432+ CODEX_MULTI_AUTH_BYPASS : "" ,
433+ CODEX_MULTI_AUTH_REAL_CODEX_BIN : missingOverride ,
434+ } ) ;
380435 const output = combinedOutput ( result ) ;
381436
382437 expect ( result . status ) . toBe ( 1 ) ;
383- expect ( output ) . toContain ( `CODEX_MULTI_AUTH_REAL_CODEX_BIN is set but missing: ${ missingOverride } ` ) ;
438+ expect ( output ) . toContain (
439+ `CODEX_MULTI_AUTH_REAL_CODEX_BIN is set but missing: ${ missingOverride } ` ,
440+ ) ;
384441 expect ( output ) . toContain ( "Could not locate the official Codex CLI binary" ) ;
385- expect ( output ) . toContain ( "Install it globally: npm install -g @openai/codex" ) ;
442+ expect ( output ) . toContain (
443+ "Install it globally: npm install -g @openai/codex" ,
444+ ) ;
386445 } ) ;
387446
388447 it ( "handles concurrent wrapper invocations without module-load regressions" , async ( ) => {
0 commit comments