Skip to content

fix(providers): detect npm-installed CLI versions on Windows - #228

Merged
j35dev merged 1 commit into
j35dev:mainfrom
aryamthecodebreaker:fix/windows-cli-detection
Sep 14, 2026
Merged

j35dev merged 1 commit into
j35dev:mainfrom
aryamthecodebreaker:fix/windows-cli-detection

Conversation

@aryamthecodebreaker

@aryamthecodebreaker aryamthecodebreaker commented Sep 13, 2026 •

Copy link
Copy Markdown

The detector half of #223, on its own against main as you asked. #223 now carries only the background work.

What

detectDriver returned version: null for npm-installed CLIs on Windows. On this machine opencode and codex both registered as version: null while claude did not, which made it look like an opencode problem. Two independent causes, both in packages/providers/src/detector.ts:

1. findBinary could only return a file Windows cannot execute. npm writes an extensionless sh shim (opencode) beside opencode.cmd in %APPDATA%\npm, and BINARY_NAMES lists the bare name first, so detection returned the shim. Spawning it fails with ENOENT — needsWindowsShell is false for an extensionless path, so it is spawned directly rather than through the cmd.exe wrapper.

Windows candidates are now filtered to .exe/.cmd, not merely reordered. Reordering alone is not enough, as Devin Review pointed out on the first revision: the scan is directory-first, so a bare shim in an earlier PATH entry still beats a runnable .cmd in a later one. Nothing is lost by dropping them, since a Windows executable needs its extension. POSIX lookup order is untouched.

2. The version probe timed out. probeVersion allowed 5000ms. opencode.exe is a ~180MB single-file binary: measured here at 2.9s–5.1s for --version while all six providers are probed concurrently at startup, so it was killed just before answering. Raised to 15000ms.

Why it matters

With version: null the provider still registers, but that version is what the update checks and the provider UI read, so an installed, working CLI reports as version-less purely because of how npm lays out its global bin directory on Windows.

How verified

Windows 11, Node 24.19, pnpm 10.33, opencode 1.18.30 installed through npm.

Before: driver registered { kind: 'opencode', version: null }, same for codex.
After: { kind: 'opencode', version: '1.18.30' } and { kind: 'codex', version: 'codex-cli 0.154.0' }.

Four cases in detector.test.ts cover the lookup: .exe/.cmd preferred within one directory, a bare shim in an earlier PATH entry losing to a runnable one later, win32 finding nothing when only the bare shim exists, and posix still resolving the bare name. The pre-existing "extension priority" case is now pinned to posix explicitly — it passed on Linux CI regardless of platform behaviour, which hid exactly this bug.

pnpm --filter @ari/providers test       # 38 files, 415 tests passed
pnpm --filter @ari/providers typecheck  # clean

Note this touches findBinary, which #222 also edits (rejecting a directory named like the CLI). The two changes are independent — npm's shim is a regular file, so it passes isRegularFile and still wins the lookup without the filter here — but whichever lands second wants a trivial rebase.

🤖 Generated with Claude Code


Devin Review

detectDriver returned `version: null` for npm-installed CLIs on Windows.
Here opencode and codex both registered as null while claude did not, which
made it look like an opencode problem. Two independent causes:

- findBinary could only return a file Windows cannot execute. npm writes an
  extensionless sh shim beside the .cmd in %APPDATA%\npm, and spawning it
  fails with ENOENT (needsWindowsShell is false for an extensionless path,
  so it is spawned directly). Windows candidates are now filtered to
  .exe/.cmd rather than merely reordered: the scan is directory-first, so a
  bare shim in an earlier PATH entry would still beat a runnable .cmd in a
  later one. Nothing is lost, since a Windows executable needs its
  extension. POSIX lookup is unchanged.

- probeVersion allowed 5000ms. opencode.exe is a ~180MB single-file binary
  that answers --version in 2.9-5.1s here while all six providers are probed
  concurrently at startup, so it was killed just before replying.

Before: driver registered { kind: 'opencode', version: null }, same for codex.
After:  { kind: 'opencode', version: '1.18.30' } and
        { kind: 'codex', version: 'codex-cli 0.154.0' }.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

Devin Review

Comment thread packages/providers/src/detector.ts
@j35dev
j35dev merged commit dc166af into j35dev:main Sep 14, 2026
2 checks passed
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.

2 participants