Skip to content

Fix Windows compatibility: atomic rename and explicit UTF-8 I/O - #5

Open
mutoharohfiqhiabcd-source wants to merge 1 commit into
ChipFlow:mainfrom
mutoharohfiqhiabcd-source:fix/windows-compat
Open

mutoharohfiqhiabcd-source wants to merge 1 commit into
ChipFlow:mainfrom
mutoharohfiqhiabcd-source:fix/windows-compat

Conversation

@mutoharohfiqhiabcd-source

Copy link
Copy Markdown

Problem

map.py cannot complete a run on Windows. Indexing aborts before repo-map.db is ever written, so the skill is unusable there out of the box.

Three independent issues, all POSIX assumptions.

1. Path.rename() does not overwrite on Windows

map.py used Path.rename() in two places — Cache.save() and the progress-file finalisation in main():

On POSIX, rename(2) silently replaces an existing destination. On Windows, os.rename raises FileExistsError (WinError 183) when the target exists. The cache file exists on every run after the first, so indexing always died at the first checkpoint:

FileExistsError: [WinError 183] Cannot create a file when that file already exists:
  '...\.claude\repo-map-cache.tmp' -> '...\.claude\repo-map-cache.json'

os.replace() is the portable equivalent: atomic on both platforms, and it overwrites.

Worth noting — scripts/goals.py and scripts/context_saver.py already use os.replace(). map.py was the only outlier, so this also brings it in line with the rest of the codebase.

2. Missing encoding= on write_text() / read_text()

Without an explicit encoding these fall back to the locale codec, which is GBK on zh-CN Windows and cannot encode the 📝 (U+1F4DD) used in the generated map:

UnicodeEncodeError: 'gbk' codec can't encode character '\U0001f4dd' in position 193

Fixed 63 call sites across scripts/ and servers/.

3. Console codec

The final print(repo_map) hit the same wall on stdout. map.py now reconfigures sys.stdout / sys.stderr to UTF-8 with errors="replace".

Verification

Windows 11 (zh-CN), Python 3.12 via uv, on a 600-file C++ project:

$ uv run --script scripts/map.py D:\PvZ-Portable
Files: 600 (17 Python, 583 C/C++/ObjC++/Metal)
Symbols found: 7597
Repo map saved to: D:\PvZ-Portable\.claude\repo-map.md
real    0m17.292s

Symbol queries against the resulting DB behave as expected:

TeleportZombies             src\Lawn\BlinkSystem.cpp:131
Board::AddZombie            src\Lawn\Board.cpp:2690
Board::FindLawnMowerInRow   src\Lawn\Board.cpp:9566

Scope

This PR only unblocks indexing on Windows. The FTS5 table stays unpopulated, which matches docs/development.md ("The FTS5 table schema exists but is not yet populated or exposed via MCP tools").

I'm happy to split this up or drop any part of it if you'd prefer a narrower change.

The scripts could not complete a run on Windows at all. Three independent
issues, all stemming from POSIX assumptions:

1. Path.rename() overwrites an existing destination on POSIX, but raises
   FileExistsError (WinError 183) on Windows when the target exists.
   map.py used it on both cache and progress-file save paths, so indexing
   aborted before repo-map.db was ever written. Replaced with os.replace(),
   which atomically overwrites on both platforms. goals.py and
   context_saver.py already used os.replace(); map.py was the outlier.

2. write_text()/read_text() without an explicit encoding fall back to the
   locale codec -- GBK on zh-CN Windows -- which cannot encode characters
   such as U+1F4DD in the generated repo map. Added encoding="utf-8" to all
   63 call sites across scripts/ and servers/.

3. sys.stdout/stderr also default to the locale codec, so the final
   print(repo_map) crashed with UnicodeEncodeError. map.py now reconfigures
   both streams to UTF-8.

Verified on Windows 11 (zh-CN), Python 3.12 via uv:

    uv run --script scripts/map.py <project-dir>

On a 600-file C++ project this now completes in ~17s and writes
repo-map.db (7597 symbols), repo-map.md and repo-map-cache.json.

This only unblocks indexing. The FTS5 table remains intentionally
unpopulated, per docs/development.md.
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.

1 participant