Skip to content

fix(core): P87 — Windows .cmd 래퍼 CLI spawn 실패 (#92)#96

Merged
hang-in merged 2 commits into
mainfrom
fix/p87-windows-cmd-spawn
May 28, 2026
Merged

fix(core): P87 — Windows .cmd 래퍼 CLI spawn 실패 (#92)#96
hang-in merged 2 commits into
mainfrom
fix/p87-windows-cmd-spawn

Conversation

@hang-in
Copy link
Copy Markdown
Owner

@hang-in hang-in commented May 28, 2026

Summary

Issue #92 (cakel, Windows 10): secall wiki update --backend codexError: program not found 로 실패. where codexcodex.cmd 를 찾고 codex 자체도 동작하는데 secall 만 실패.

원인

  • codex 는 npm 설치라 C:\Users\User\AppData\Roaming\npm\codex.cmd (배치 래퍼).
  • std::process::Command::new("codex") 는 Windows 에서 PATHEXT 미적용codex.exe 만 시도, .cmd 못 찾음.
  • command_existswhere.exe 외부 호출이라 .cmd 를 찾아 통과 → "존재하는데 spawn 실패" 불일치.

Fix

  • which crate (workspace dep) 도입 — Windows PATHEXT (.CMD/.EXE/.BAT) 적용.
  • lib.rs: resolve_program(cmd) -> PathBuf 추가 + command_exists 를 which 기반 재구현 (외부 프로세스 호출 제거, spawn 과 동일 탐색 규칙).
  • spawn 5곳을 Command::new(resolve_program(X)) 로 변경. Rust 1.77+ 가 .cmd 풀경로를 cmd.exe 경유로 안전 실행.
파일 명령
wiki/codex.rs codex
wiki/claude.rs claude
wiki/reviewers/codex.rs codex
wiki/reviewers/claude.rs (run_review_cli) bin
search/query_expand.rs claude

Test plan

  • cargo fmt --all -- --check clean
  • cargo clippy --workspace --all-targets -- -D warnings clean
  • cargo test -p secall-core --lib 426 passed (command_exists 회귀 3건 포함)
  • ⚠️ Windows 실제 spawn 검증 필요 — 개발 환경(macOS)에서 불가. @cakel 님 Windows 빌드 검증 요청드립니다. macOS/Linux 는 which 가 확장자 없는 실행파일 그대로 resolve → 회귀 없음.

Risk

  • which resolve 실패 시 입력 문자열 그대로 fallback → 기존 동작 유지.

Closes #92

🤖 Generated with Claude Code

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the which crate to resolve command paths on Windows, fixing an issue where npm-installed CLI wrappers (like codex.cmd and claude.cmd) fail to spawn due to missing PATHEXT resolution. It adds a resolve_program helper and updates command execution sites to use it. The reviewer suggested optimizing performance in wiki/reviewers/codex.rs and wiki/reviewers/claude.rs by moving the resolve_program calls outside of the for strict in [false, true] loops to avoid redundant disk I/O operations.

let output_path = output_file.path().to_path_buf();

let mut child = tokio::process::Command::new("codex");
let mut child = tokio::process::Command::new(crate::resolve_program("codex"));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

for strict in [false, true] 루프 내부에서 crate::resolve_program("codex")를 매번 호출하고 있습니다.

resolve_program 내부의 which::whichPATH 환경 변수에 등록된 디렉토리들을 순회하며 디스크 I/O 작업을 수행하므로, 루프가 돌 때마다 동일한 경로 탐색을 반복하는 것은 비효율적입니다.

루프 실행 전에 한 번만 경로를 찾아 변수에 저장한 뒤, 루프 내부에서는 해당 변수를 참조하도록 변경하는 것을 권장합니다.

예시:

let program = crate::resolve_program("codex");
for strict in [false, true] {
    // ...
    let mut child = tokio::process::Command::new(&program);
    // ...
}

);

let mut child = tokio::process::Command::new(bin);
let mut child = tokio::process::Command::new(crate::resolve_program(bin));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

for strict in [false, true] 루프 내부에서 crate::resolve_program(bin)을 매번 호출하고 있습니다.

resolve_programPATH 환경 변수의 디렉토리들을 검색하는 디스크 I/O 작업을 수반하므로, 루프 내부에서 반복 호출하는 것은 비효율적입니다.

루프 외부에서 미리 경로를 resolve한 뒤 루프 내부에서 재사용하도록 개선하는 것을 권장합니다.

예시:

let program = crate::resolve_program(bin);
for strict in [false, true] {
    // ...
    let mut child = tokio::process::Command::new(&program);
    // ...
}

@hang-in
Copy link
Copy Markdown
Owner Author

hang-in commented May 28, 2026

Gemini 리뷰 2건 반영 (commit fe17704). reviewers/{codex,claude}.rs 의 resolve_program 호출을 for strict 루프 밖으로 빼서 PATH 탐색 (disk I/O) 1회만 수행하고 루프 안에서는 &program 재사용. fmt + clippy clean.

hang-in pushed a commit that referenced this pull request May 28, 2026
PR #96 Gemini 리뷰 2건 (medium): reviewers/{codex,claude}.rs 의
`for strict in [false, true]` 루프 안에서 `resolve_program` 을 매번 호출
(PATH 디스크 I/O 반복). 루프 밖에서 1회 resolve 후 `&program` 재사용.

검증: cargo fmt --check + clippy -D warnings clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d9ng and others added 2 commits May 29, 2026 07:39
Issue #92 (cakel, Windows 10): `secall wiki update --backend codex` 가
"program not found" 로 실패. `where codex` 는 codex.cmd 를 찾는데도 spawn 실패.

원인: codex 는 npm 설치라 `codex.cmd` 배치 래퍼. `Command::new("codex")` 는
Windows 에서 PATHEXT 미적용 → `codex.exe` 만 찾고 `.cmd` 못 찾음. 반면
`command_exists` 는 `where.exe` 외부 호출이라 통과 → "존재하는데 spawn 실패" 불일치.

Fix:
- `which` crate (workspace dep) 도입.
- `lib.rs`: `resolve_program(cmd) -> PathBuf` 추가 (PATHEXT 적용 경로 resolve).
  `command_exists` 도 which 기반 재구현 (where.exe/which 외부 호출 제거 →
  spawn 과 동일 탐색 규칙).
- spawn 5곳 (`wiki/{codex,claude}`, `wiki/reviewers/{codex,claude}`,
  `search/query_expand`) 을 `Command::new(resolve_program(X))` 로.
  Rust 1.77+ 가 .cmd 풀경로를 cmd.exe 경유로 안전 실행.

검증:
- cargo fmt --check / clippy -D warnings: clean
- cargo test -p secall-core --lib: 426 passed (command_exists 회귀 3건 포함)
- ⚠️ Windows 실제 spawn 은 개발 환경(macOS) 에서 검증 불가 — cakel 검증 요청 예정.
  macOS/Linux 는 which 가 확장자 없는 실행파일 그대로 resolve → 회귀 없음.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PR #96 Gemini 리뷰 2건 (medium): reviewers/{codex,claude}.rs 의
`for strict in [false, true]` 루프 안에서 `resolve_program` 을 매번 호출
(PATH 디스크 I/O 반복). 루프 밖에서 1회 resolve 후 `&program` 재사용.

검증: cargo fmt --check + clippy -D warnings clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hang-in hang-in force-pushed the fix/p87-windows-cmd-spawn branch from fe17704 to b0d2cff Compare May 28, 2026 22:40
@hang-in hang-in merged commit af385c7 into main May 28, 2026
3 checks passed
@hang-in hang-in deleted the fix/p87-windows-cmd-spawn branch May 28, 2026 22:52
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.

secall wiki update --backend codex 에서 codex 가 실행되지 않음

1 participant