Observed on a real graphify install (0.9.64, Windows 11, Python 3.12, installed via uv tool install graphifyy). The install itself worked — skill and references copied correctly. Two problems in _register_always_on_block (graphify/install.py:754-774), both affecting the claude / windows / codebuddy paths only.
1. The whole of CLAUDE.md is rewritten to CRLF on Windows
target.write_text(content.rstrip() + registration, encoding="utf-8")
Path.write_text opens in text mode, so on Windows every \n becomes \r\n — including the user's pre-existing content, which is read back with read_text and rewritten wholesale. Measured on my ~/.claude/CLAUDE.md:
|
bytes |
CRLF |
bare LF |
| before install |
3,365 |
0 |
82 |
| after install |
3,678 |
85 |
0 |
Three lines were added; 85 lines changed. For anyone keeping ~/.claude/CLAUDE.md in a dotfiles repo — or syncing it between a Windows box and a Linux one, which is a common Claude Code setup — a one-line registration lands as a whole-file diff. Same class as #2655 (export sized for NAME_MAX, ignoring Windows MAX_PATH).
Fix: target.write_bytes((content.rstrip() + registration).encode("utf-8")), or pass newline="" via an explicit open(). Worth auditing the other write_text call sites on this path — gemini_install writes GEMINI.md the same way.
2. The idempotency guard is a bare substring match, and _CLAUDE_MD_MARKER is dead code on this path
_CLAUDE_MD_MARKER = "## graphify" # install.py:745
...
if "graphify" in content: # install.py:765
print(f"{prefix}already registered (no change)")
Three things don't line up:
- The guard tests for the bare word
"graphify" anywhere in the file, not for the marker.
_CLAUDE_MD_MARKER is never referenced on this path. _replace_or_append_section — which does use a marker, correctly — is only wired to gemini_install.
- What actually gets written by
_skill_registration is # graphify (H1), so even if the marker were used it wouldn't match ## graphify (H2).
Failure modes:
- Silent non-registration. A user whose
CLAUDE.md mentions graphify for any other reason — a note to self, a project instruction, a link to this repo — gets already registered (no change) and no registration block, with no way to tell the difference from a real skip.
- No refresh path. If the block is edited, truncated, or the skill path changes, re-running
install cannot repair it — the word is still present, so it no-ops. _replace_or_append_section exists precisely for this and is right there.
- Heading level is inconsistent with the other three
*_MD_MARKER constants, which all specify ## graphify.
Fix: use the existing _replace_or_append_section(content, _CLAUDE_MD_MARKER, ...) helper here as gemini_install already does, and make _skill_registration emit ## graphify so the written heading and the marker agree.
3. Cosmetic: no blank line before the heading
content.rstrip() + registration where registration opens with a single "\n# graphify\n" leaves the heading flush against the user's last paragraph:
or two things that actually block on me get lost in progress narration.
# graphify
Renders fine under CommonMark, but reads as glued to the preceding section in an editor. rstrip() + "\n\n" would settle it.
Happy to send a PR — all three are a handful of lines and item 2 is mostly deleting code in favour of the helper you already have. Equally happy to leave it if you'd rather do it yourself.
Reproduced on graphifyy 0.9.64, Windows 11, uv tool install; line references against site-packages/graphify/install.py from that build. AI-assisted review, all figures measured on the actual install.
Observed on a real
graphify install(0.9.64, Windows 11, Python 3.12, installed viauv tool install graphifyy). The install itself worked — skill and references copied correctly. Two problems in_register_always_on_block(graphify/install.py:754-774), both affecting theclaude/windows/codebuddypaths only.1. The whole of
CLAUDE.mdis rewritten to CRLF on WindowsPath.write_textopens in text mode, so on Windows every\nbecomes\r\n— including the user's pre-existing content, which is read back withread_textand rewritten wholesale. Measured on my~/.claude/CLAUDE.md:Three lines were added; 85 lines changed. For anyone keeping
~/.claude/CLAUDE.mdin a dotfiles repo — or syncing it between a Windows box and a Linux one, which is a common Claude Code setup — a one-line registration lands as a whole-file diff. Same class as #2655 (export sized forNAME_MAX, ignoring WindowsMAX_PATH).Fix:
target.write_bytes((content.rstrip() + registration).encode("utf-8")), or passnewline=""via an explicitopen(). Worth auditing the otherwrite_textcall sites on this path —gemini_installwritesGEMINI.mdthe same way.2. The idempotency guard is a bare substring match, and
_CLAUDE_MD_MARKERis dead code on this pathThree things don't line up:
"graphify"anywhere in the file, not for the marker._CLAUDE_MD_MARKERis never referenced on this path._replace_or_append_section— which does use a marker, correctly — is only wired togemini_install._skill_registrationis# graphify(H1), so even if the marker were used it wouldn't match## graphify(H2).Failure modes:
CLAUDE.mdmentions graphify for any other reason — a note to self, a project instruction, a link to this repo — getsalready registered (no change)and no registration block, with no way to tell the difference from a real skip.installcannot repair it — the word is still present, so it no-ops._replace_or_append_sectionexists precisely for this and is right there.*_MD_MARKERconstants, which all specify## graphify.Fix: use the existing
_replace_or_append_section(content, _CLAUDE_MD_MARKER, ...)helper here asgemini_installalready does, and make_skill_registrationemit## graphifyso the written heading and the marker agree.3. Cosmetic: no blank line before the heading
content.rstrip() + registrationwhereregistrationopens with a single"\n# graphify\n"leaves the heading flush against the user's last paragraph:Renders fine under CommonMark, but reads as glued to the preceding section in an editor.
rstrip() + "\n\n"would settle it.Happy to send a PR — all three are a handful of lines and item 2 is mostly deleting code in favour of the helper you already have. Equally happy to leave it if you'd rather do it yourself.
Reproduced on graphifyy 0.9.64, Windows 11,
uv toolinstall; line references againstsite-packages/graphify/install.pyfrom that build. AI-assisted review, all figures measured on the actual install.