Repository navigation
Windows fixes, agent-friendly MCP replies, simpler README - #9
Merged
Merged
Conversation
wikifier.bat read %ERRORLEVEL% inside a parenthesized block. cmd expands it when the block is parsed, before the binary runs, so every failure exited 0 (e.g. `wikifier.bat no-such-command` printed UnknownCommand and returned 0). The launcher now picks the binary first and runs it outside any block. .gitattributes keeps *.sh LF (bash on WSL/Linux rejects CRLF) and *.bat/*.ps1 CRLF (cmd misparses labels in LF-only batch files) whatever core.autocrlf says. tests/cli_surface.rs runs wikifier.bat on Windows and wikifier.sh elsewhere against the built binary and checks exit codes 0 and 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
file_health.json stores a sha256 of each Green file. Git for Windows checks files out with CRLF (core.autocrlf=true), so on a Windows clone every baseline hashed from LF elsewhere mismatched: check-changes on this repo flagged 51 untouched files dirty and rewrote health and pending. content_sha256_prefixed drops the CR of each CRLF pair before hashing. LF-only content hashes exactly as before, so existing baselines stay valid. update-maps uses the same hash for its cache entries. Unit test in src/sha256.rs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found by driving `wikifier mcp` the way an agent does, on copies of real repos (a 17-file crate and a 587-file Cargo workspace): - prepare_edit / get_dependencies / get_dependents / get_file_wiki with a guessed argument name (`file_path`) or an unknown path answered success:true with every field empty. MCP now returns InvalidArguments naming the missing field, the accepted fields and the received ones; the lookups return FileNotFound with a list_paths hint. - `src\a.rs` and absolute paths (which skills/run.md already promised) returned empty lookups, and record-change on `src\a.rs` created a second health row. scope::rel_arg turns every file argument into the project-relative `/` key. - MCP update_maps returned the whole edge list (~280 KB on the workspace) and health ignored its advertised `limit` (~145 KB). The edge list is now opt-in (`edges: true`, count still in edges_persisted); health honors `limit` (adds entries_total) and `summary`. The update_maps schema now lists full, max_files and edges. - init always seeded `src/`, so a workspace with crates/ hit ScopeError on the first map. It now seeds src/ when present, else the top-level directories that hold source. tests/agent_args.rs covers each case, plus a Green file surviving a CRLF checkout. skills/run.md and CHANGELOG (Unreleased) describe the changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What it is, install, connecting an agent over MCP (Claude Code command and .mcp.json), a short quick start of the edit loop, and how it works (pipeline, artifacts, language table). The Performance and Benchmarks sections, tables and measurement notes are unchanged byte for byte. Detail moves to links: skills/run.md, AGENTS.md, CONTRIBUTING.md, docs/spec.md. README.md.wiki.md describes the new layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
record-change / mark-green for the edited sources, tests and docs; update-maps refreshed library.md (it listed 25 of the 34 mapped files). Generated by the wikifier binary, not edited by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measured on a 587-file Cargo workspace (Specula) on Windows 11, same copy before and after. Cache files, library.md, folder cards, health hashes and the update-maps / cycles / dependencies --full / dependents / check-changes / session-bootstrap output are byte-identical (timestamps aside). Warm MCP calls, median of 5: check_changes 353 -> 53 ms, update_maps 708 -> 50 ms, get_cycles 317 -> 39 ms, session_bootstrap 33 -> 16 ms. Cold update-maps, interleaved runs: 18.7 s -> 6.4 s. - Cache commits write files on several threads and flush each directory once instead of once per file. Every file is still synced and renamed into place; forward files still land before by_dst. - A full map scans each file once (the second resolution pass reuses the scans). Import lines come from one substring search per distinct spec, not a per-line loop per import. JS/TS barrel follow-through builds its sorted scan table once, not once per imported name. - cycles and dependencies --full read edges from index.tsv instead of one by_src file per mapped file; cycles loads edge flags only for files in a cycle. library.md no longer reads the notes files. - update-maps keeps library.md and the folder cards when the cache commit changed nothing. - check-changes and health seeding use a mapped file's cache hash when size and mtime match (the rule update-maps already skips by) and read the file otherwise, or when that hash is not the baseline. - The walk takes file types from the directory entry. - session-bootstrap --limit caps `files` (files_total gives the count); over MCP the default cap is 100 (21.7 KB -> 4.7 KB here). tests/speed_paths.rs checks each fast path against the slow one; unit tests cover line_of and the batched writer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CMYkogM3QWVjMLzWKGyjuJ
…t closes an item. pending_updates.md kept "(no pending items — run check-changes after making edits)" above the items once any were added (this repo's own file showed it). The note now goes when the first item arrives and comes back when mark-green removes the last one. A record-change item read `LLM/agent edit — <reason>`, wording carried over from the Python package. It now reads `<reason> — refresh the wiki, then mark-green`, the step that clears it. tests/parity_fixes.rs covers both. CHANGELOG and skills/run.md updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CMYkogM3QWVjMLzWKGyjuJ
record-change / mark-green for the edited files, then update-maps. Generated by the wikifier binary, not edited by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CMYkogM3QWVjMLzWKGyjuJ
The wk_cache files are derived and can be rebuilt from the sources, so by_src, by_dst, payload, notes and barrel records are now written through a temp file and a rename (a reader never sees a torn file) but not synced. To make that safe, every commit records each file's length in wk_cache/sizes.tsv. Session::open compares those lengths with one directory listing per kind and reads a file only when no length is recorded (an older cache, or a lost sizes.tsv). A missing, resized or malformed file is a miss: update-maps parses that source again, or rewrites the by_dst record from the index. Lookups that meet a bad record answer from index.tsv in the meantime. Health (json and md), the journal and pending_updates.md were plain overwrites with no sync; they now go through a synced temp file and a rename (artifacts::write_durable). Cold update-maps on the same Specula copy, interleaved runs, machine at ~80% load: median 11.9 s with batched syncs, 12.5 s without. No measurable change on this Windows box, where creating ~2,000 small files (antivirus on create) dominates; the sync cost matters more on Linux and macOS. tests/speed_paths.rs corrupts and truncates cache records, checks the lookups still answer, then checks the next update-maps rebuilds every cache file byte for byte (and catches same-size damage once sizes.tsv is gone). Another test covers the durable user-state writes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CMYkogM3QWVjMLzWKGyjuJ
Bump Cargo.toml/Cargo.lock to 5.1.0 and the docs that name the package version (AGENTS.md, CLAUDE.md, skills/run.md, README install snippet). The README benchmark section keeps its 5.0.0 measurement note. CHANGELOG: Unreleased becomes "5.1.0 - 2026-11-05", with a note for MCP clients that session_bootstrap now caps `files` at 100 unless `limit` is passed and update_maps leaves out the edge list unless `edges: true`. README says the same. skills/run.md and CLAUDE.md describe the unsynced derived cache and the durable user state. tests/cli_surface.rs checks those docs name CARGO_PKG_VERSION, so the next bump cannot leave one behind. The binary, tests and release workflow already read the version from Cargo.toml. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CMYkogM3QWVjMLzWKGyjuJ
Generated by the wikifier binary (record-change, mark-green, update-maps), not edited by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CMYkogM3QWVjMLzWKGyjuJ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Verified wikifier 5.0.0 on Windows 11 and made it work better for agents on the first try.
Fixes
wikifier.batnow returns the real exit code. It used to exit 0 every time because%ERRORLEVEL%was read inside a parenthesized block..gitattributesnow pins line endings for the launchers.check-changesused to flag 51 untouched files as dirty.src\a.rsand absolute paths now resolve to the same health row assrc/a.rs, instead of creating a duplicate row or returning nothing.Agent improvements
update_mapsleaves out the edge list unless you ask for it (277 KB → 0.5 KB).healthhonourslimit/summary(145 KB → 1 KB).initfinds source folders in Cargo workspaces and other layouts withoutsrc/.Docs
README shortened from 247 to 173 lines. The Performance and Benchmarks sections are unchanged byte for byte.
Each fix has a test that fails without it. 74 tests pass locally. This PR is the first CI run for the branch.
🤖 Generated with Claude Code
https://claude.ai/code/session_01CMYkogM3QWVjMLzWKGyjuJ