Skip to content

provider-bridge가 Windows에서 ocx를 항상 error로 판정 — where 첫 줄(확장자 없는 shim) 선택 + shell 없이 .cmd spawn #131

Description

@lidge-jun

요약

Windows에서 cxc provider(및 SessionStart provider-bridge 훅)가 정상 동작 중인 opencodex를 항상 mode: "error"로 보고한다. ocx 프록시는 건강한데 detect 단계에서 실패한다.

환경

  • Windows 11 / PowerShell
  • Node v24.16.0
  • codex 0.135.0
  • codexclaw 0.2.24+codex.20260908031619 (dev, 9cd5276)
  • opencodex: npm 전역 설치 (C:\nvm4w\nodejs)

재현

$ cxc provider
{"provider":"ocx","mode":"error","ocxPath":"C:\\nvm4w\\nodejs\\ocx","reason":"ocx status exited null"}

$ ocx status
✅ Proxy: running (PID 11208)
   Health: http://127.0.0.1:10100/healthz ok (live)
   routing=opencodex-local, service=installed-but-unhealthy, shim=absent

원인

components/provider-bridge/src/cli.ts 두 군데가 겹친다.

1. whichOcx()where ocx 출력의 첫 줄을 그대로 쓴다.

npm 전역 설치는 확장자 없는 sh shim과 .cmd 런처를 같이 깔고, where는 확장자 없는 쪽을 먼저 내놓는다.

$ where.exe ocx
C:\nvm4w\nodejs\ocx
C:\nvm4w\nodejs\ocx.cmd

확장자 없는 파일은 Windows에서 실행 가능한 이미지가 아니라 spawnSync가 ENOENT로 실패한다.

2. .cmd를 골라도 그대로는 실패한다.

Node 18.20.2 / 20.12.2 이후(CVE-2024-27980) .cmd.batshell 옵션 없이 spawn하면 EINVAL이다.

두 경우 모두 res.status === null이 되어 detect.ts:82ocx status exited ${result.status ?? "null"} 분기로 떨어진다.

검증

node -e "spawnSync(p, ['status','--json'])"

C:\nvm4w\nodejs\ocx                  status=null   err=ENOENT     stdoutLen=0
C:\nvm4w\nodejs\ocx.cmd              status=null   err=EINVAL     stdoutLen=0
C:\nvm4w\nodejs\ocx.cmd (shell:true) status=0      err=undefined  stdoutLen=3931

.cmd + 셸 경유일 때만 status --json 페이로드가 정상적으로 돌아온다.

영향

  • Windows + npm 설치 opencodex 조합에서는 provider 모드로 진입할 수 없다. 항상 error.
  • SessionStart 훅의 provider 상태 줄과 이를 소비하는 카탈로그(L25) / GUI(L27)가 건강한 프록시를 error로 인식한다.
  • mode: "native" 폴백도 아니라서 "감지는 됐는데 읽지 못함"으로 잘못 보고된다. 사용자 입장에서는 원인 파악이 어렵다.

제안

  • whichOcx(): win32에서 where 출력의 여러 줄 중 PATHEXT에 포함된 확장자(.cmd, .exe, .bat)를 우선 선택한다.
  • runOcxStatus(): win32에서 대상이 .cmd/.bat이면 ComSpec을 경유해 실행한다. spawnSync(process.env.ComSpec, ["/d","/s","/c", quoted]) 형태가 안전하다. shell: true에 args를 넘기는 방식은 DEP0190 경고와 인용 문제가 따라온다.
  • 회귀 테스트: which가 확장자 없는 경로를 먼저 반환하는 케이스와 .cmd EINVAL 케이스를 detect deps 주입으로 커버한다.

detect-only 계약(Q-P2-2)은 그대로 유지된다. 실행 경로 해석만 고치면 된다.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions