Skip to content

fix: make health-check probes Windows-aware (.exe, .cmd, exec-bit, PATHEXT)#4

Open
zbolton36 wants to merge 1 commit into
robinslange:mainfrom
zbolton36:fix/windows-health-check
Open

fix: make health-check probes Windows-aware (.exe, .cmd, exec-bit, PATHEXT)#4
zbolton36 wants to merge 1 commit into
robinslange:mainfrom
zbolton36:fix/windows-health-check

Conversation

@zbolton36

Copy link
Copy Markdown

Fixes #3.

Problem

On Windows, /learning-loop:doctor reports four hard failures even when the binary, shims, and Claude Code are all installed and working. All four are false positives in the health-check probes (POSIX assumptions), not real install problems. The runtime path is unaffected: lib/binary.mjs already resolves ll-search.exe, so semantic search and indexing work while the checker reports the binary missing.

Verified before the fix that bin/ll-search.exe version returns 1.33.0, vault-search.mjs search returns ranked results, the .cmd shims exist, and claude --version works in the shell, while doctor still showed binary-exists, binary-runs, shims-exist, and claude-version as FAIL.

Changes

  1. .exe on the binary path (health-check.mjs, quick.mjs checkBinaryExists): the binary is ll-search.exe on Windows. Drives binary-exists and binary-runs.
  2. .cmd on the shim path (quick.mjs checkShimsExist): install-shims.mjs writes ll-watch.cmd / ll-search.cmd. Drives shims-exist.
  3. Skip the POSIX exec-bit test on win32 (binary + shims): stat.mode & 0o111 is always 0 for .exe/.cmd under Node statSync, so existence is the correct signal there.
  4. shell: true on win32 in safeExec: execFileSync does not honor PATHEXT, so bare claude/node miss their .cmd shims and read as "not found". Drives claude-version (and the misleading Linux install.sh fix it suggested).

All win32 behavior is guarded behind process.platform === 'win32', so POSIX behavior is byte-for-byte unchanged.

Tests

Added three win32-mocked cases to tests/health-check.test.mjs (mock process.platform so the branches run on the POSIX CI runner): .exe binary OK, .cmd shims OK, and extensionless-only shims FAIL on win32. The existing skipOnWindows exec-bit tests are untouched.

Local checks

  • npx prettier --check on changed files: clean.
  • npx eslint .: 0 errors (only pre-existing unused-disable warnings, including one on main).
  • node --test tests/health-check.test.mjs: 87 pass, 0 fail (3 skipOnWindows, 3 new win32 cases pass).

Result on a real Windows box: doctor goes from 19 pass / 1 warn / 4 fail to 23 pass / 1 warn / 0 fail (remaining warn is the legitimate local-bin-on-path).

Possibly related (not addressed here)

The session-start hook injects PLUGIN_DATA=...\data\learning-loop-inline, but resolve-paths.mjs / download-binary.mjs resolve ...\data\learning-loop-learning-loop-marketplace. Both bin/ dirs end up populated, so it is not breaking, but download-binary.mjs reporting "already installed" in one root while the checker probes the other is confusing. Flagging in case it points at a path-derivation inconsistency; happy to look if you want it in scope.

…THEXT)

On Windows the binary is ll-search.exe and the shims are .cmd, and Node
statSync reports no POSIX exec bit for either. The doctor reported four
false-positive failures (binary-exists, binary-runs, shims-exist,
claude-version) even with everything installed and working.

- health-check.mjs / quick.mjs: probe ll-search.exe on win32.
- quick.mjs: probe .cmd shims and skip the stat.mode & 0o111 exec-bit
  test on win32 (binary + shims).
- health-check.mjs safeExec: shell:true on win32 so execFileSync honors
  PATHEXT and resolves claude.cmd / node shims.
- tests: add win32-mocked coverage for the binary and shim checks.
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.

Windows: 4 false-positive health-check failures (.exe path, .cmd shims, POSIX exec-bit, PATHEXT)

1 participant