Files
codebase-memory-mcp/tests
Martin VogelandClaude Fable 5.1 8135be28a7 fix(cli): remove the install dir from the Windows user PATH on uninstall (#2117)
On Windows, install registers the install directory in the persistent
HKCU\Environment\Path, but uninstall never removed it — so every
install/uninstall cycle left its entry behind and the user PATH grew
without bound (a real test host reached ~8000 chars, emptying the
effective PATH and breaking tooling).

The reported non-ASCII "mojibake" is historical, not a current-code bug.
Both install paths already write the value through the UTF-16 registry
API: install.ps1 (shipped in each release archive) runs `cbm install`,
which calls RegSetValueExW(L"Path", ...) — git history shows no ANSI
(RegSetValueExA / SetEnvironmentVariableA) predecessor — and
setup-windows.ps1 writes via .NET [Environment]::SetEnvironmentVariable
(Unicode) with an ASCII-only install dir. The only path that handles a
non-ASCII directory is the wide-correct C path, so current code cannot
produce a garbled entry; the garbage the reporter saw was left by an
older binary. No code change is needed for the encoding itself.

The real defect is the missing uninstall-side removal. This adds
cli_remove_windows_user_path(), the counterpart to
cli_ensure_windows_user_path(): it opens the same key, walks the
';'-separated segments, and drops exactly the ones equal to the install
dir using the same case- and trailing-separator-insensitive comparison
the install `present` scan uses, so it removes precisely what install
would have de-duplicated. Every other segment is preserved
byte-for-byte, the value kind (REG_SZ / REG_EXPAND_SZ) is preserved, and
a registry error is a warning rather than a hard failure so a user is
never blocked from finishing an uninstall over a cosmetic PATH edit.
Removing the entry on uninstall also stops accumulation on reinstall: a
garbled historical entry defeats the install de-dup and gets re-added,
so taking our own entry back out keeps the value bounded.

Testing:
- tests/test_cli.c: a hermetic Windows unit test drives the append and
  remove logic against a GUID-scoped scratch key via the existing
  CBM_TEST_WINDOWS_USER_PATH_RUN_ID seam, never the developer's live
  HKCU\Environment\Path. A non-ASCII install dir doubles as a mojibake
  guard (a broken UTF-8->UTF-16 round-trip would fail the match and leak
  a duplicate). It asserts append, idempotent reinstall, exact removal
  from the tail and the middle, idempotent removal, and byte-for-byte
  survival of unrelated entries.
- tests/test_smoke_fixture_contract.sh: a macOS-runnable source contract
  that fails when the removal is absent and passes with it, proving the
  wiring binds (verified RED-on-revert).

The Windows-only registry code is #ifdef _WIN32; its compile and the
behavioral unit test are verified by CI's Windows leg (the local Windows
VM is down). Pre-existing mojibaked entries from old binaries are a
separate one-time cleanup, out of scope here, and setup-windows.ps1's
own lack of an uninstall mode is noted as a possible follow-up.

Fixes #2117

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-09-08 22:08:39 +02:00
..