@@ -63,6 +63,14 @@ vi.mock("node:fs", async (importActual) => {
6363 return { ...actual , existsSync : vi . fn ( actual . existsSync ) } ;
6464} ) ;
6565
66+ // Default to no enabled tools, which matches how these tests run for real
67+ // (no cloud-run meta, no GH token gates passing). Individual tests opt in.
68+ vi . mock ( "../local-tools" , async ( importActual ) => {
69+ const actual = await importActual < typeof import ( "../local-tools" ) > ( ) ;
70+ return { ...actual , enabledLocalTools : vi . fn ( ( ) => [ ] ) } ;
71+ } ) ;
72+
73+ import { enabledLocalTools , LOCAL_TOOLS_MCP_NAME } from "../local-tools" ;
6674import { CodexAcpAgent } from "./codex-agent" ;
6775
6876describe ( "CodexAcpAgent" , ( ) => {
@@ -621,6 +629,44 @@ describe("CodexAcpAgent", () => {
621629 expect ( forwarded . _meta . systemPrompt ) . toContain ( "create_output" ) ;
622630 } ) ;
623631
632+ it ( "injects ELECTRON_RUN_AS_NODE on the local-tools MCP server env" , async ( ) => {
633+ vi . mocked ( enabledLocalTools ) . mockReturnValueOnce ( [
634+ { name : "create_pull_request" } ,
635+ ] as never ) ;
636+ const { agent } = createAgent ( ) ;
637+ mockCodexConnection . newSession . mockResolvedValue ( {
638+ sessionId : "session-1" ,
639+ modes : { currentModeId : "auto" , availableModes : [ ] } ,
640+ configOptions : [ ] ,
641+ } satisfies Partial < NewSessionResponse > ) ;
642+
643+ await agent . newSession ( {
644+ cwd : process . cwd ( ) ,
645+ mcpServers : [ ] ,
646+ } as never ) ;
647+
648+ const forwarded = mockCodexConnection . newSession . mock . calls [ 0 ] [ 0 ] as {
649+ mcpServers : Array < {
650+ name : string ;
651+ command : string ;
652+ env : Array < { name : string ; value : string } > ;
653+ } > ;
654+ } ;
655+
656+ const localToolsServer = forwarded . mcpServers . find (
657+ ( s ) => s . name === LOCAL_TOOLS_MCP_NAME ,
658+ ) ;
659+ expect ( localToolsServer ) . toBeDefined ( ) ;
660+ expect ( localToolsServer ?. command ) . toBe ( process . execPath ) ;
661+
662+ // Same invariant as the structured-output server: the script must run
663+ // as node even when process.execPath is the Electron app binary.
664+ const runAsNode = localToolsServer ?. env . find (
665+ ( e ) => e . name === "ELECTRON_RUN_AS_NODE" ,
666+ ) ;
667+ expect ( runAsNode ?. value ) . toBe ( "1" ) ;
668+ } ) ;
669+
624670 it ( "is a no-op when jsonSchema is absent" , async ( ) => {
625671 const { agent } = createAgent ( { } , { onStructuredOutput : vi . fn ( ) } ) ;
626672 mockCodexConnection . newSession . mockResolvedValue ( {
0 commit comments