Skip to content

fix(config): preserve non-ASCII paths in written JSON configs (#497)#682

Open
Chang-Jin-Lee wants to merge 1 commit into
tirth8205:mainfrom
Chang-Jin-Lee:fix/ensure-ascii-config-writes
Open

fix(config): preserve non-ASCII paths in written JSON configs (#497)#682
Chang-Jin-Lee wants to merge 1 commit into
tirth8205:mainfrom
Chang-Jin-Lee:fix/ensure-ascii-config-writes

Conversation

@Chang-Jin-Lee

Copy link
Copy Markdown

Linked issue

Closes #497 (remaining scope — see below)

What & why

json.dumps(existing, indent=2) defaults to ensure_ascii=True, so every config writer that round-trips a repo path or arbitrary pre-existing content through it serializes non-ASCII as literal \uXXXX escapes instead of native UTF-8. Six sites still had this:

  • skills.py: install_platform_configs (.mcp.json cwd field), the shared _merge_hooks_into_settings (Claude settings.json), install_codex_hooks (Codex hooks.json), install_gemini_cli_hooks (Gemini settings.json), install_cursor_hooks (Cursor hooks.json)
  • registry.py: Registry._save (registry.json)

Technically valid JSON either way, but as #497 documents, some MCP hosts / process launchers don't correctly decode \uXXXX when consuming these files directly.

One correction on scope: I believe #497's Bug 1 (json.dumps() abused for shell quoting, which is what actually produced the reported corrupted u57fa/u4e8e.../ desktop directory tree via double-encoding) is already fixed — the repo path is now substituted into hook scripts as a plain string, not JSON-encoded, so there's no longer a double-encode step for that specific flow. This PR closes out the remaining Bug 2 scope from the issue's "Affected locations" table: writing native UTF-8 in every config file this tool touches, which is still worth doing defensively (and is what a couple of those table rows asked for independent of Bug 1).

How it was tested

uv run pytest tests/ --tb=short -q   # 1967 passed, 5 skipped, 2 xpassed (pre-existing, unrelated)
uv run ruff check code_review_graph/ tests/test_skills.py tests/test_registry.py   # clean on touched files
uv run mypy code_review_graph/skills.py code_review_graph/registry.py --ignore-missing-imports --no-strict-optional   # no issues

Added one regression test per site (6 total, in TestNonAsciiConfigPreservation in test_skills.py and TestRegistryNonAscii in test_registry.py): seed non-ASCII content (a repo path or a pre-existing custom field), run the writer, assert the raw written file contains the literal UTF-8 characters and no \u escapes. Written first and watched fail (RED — every one failed with \uXXXX in the output) before adding ensure_ascii=False (GREEN).

Checklist

  • Tests added for new functionality
  • All tests pass: uv run pytest tests/ --tb=short -q
  • Linting passes: uv run ruff check code_review_graph/
  • Type checking passes: uv run mypy code_review_graph/ --ignore-missing-imports --no-strict-optional
  • Lines are at most 100 characters
  • Docs updated where behavior changed — N/A, internal serialization detail, no user-facing config/CLI surface changed

…205#497)

json.dumps(..., indent=2) defaults to ensure_ascii=True, so the 6 config
writers that round-trip a repo path or arbitrary pre-existing content
through it all serialize non-ASCII as literal \uXXXX escapes instead of
native UTF-8:

- skills.py: install_platform_configs (.mcp.json cwd field), the shared
  _merge_hooks_into_settings (Claude settings.json), install_codex_hooks
  (Codex hooks.json), install_gemini_cli_hooks (Gemini settings.json),
  install_cursor_hooks (Cursor hooks.json)
- registry.py: Registry._save (registry.json)

Technically valid JSON either way, but as tirth8205#497 documents, some MCP hosts
/ process launchers don't correctly decode \uXXXX when consuming these
files directly. The issue's Bug 1 (json.dumps() abused for shell
quoting, causing the reported corrupted-desktop-directory-tree symptom)
looks already fixed elsewhere — repo paths are now substituted into hook
scripts as plain strings, not JSON-encoded. This closes out the
remaining Bug 2 scope: writing native UTF-8 in every config file this
tool touches.

Added a regression test per site (6 total) seeding non-ASCII content and
asserting the raw written file contains literal UTF-8, not \u escapes.
Written first and watched fail (RED) before adding ensure_ascii=False
(GREEN).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

Bug: Double JSON encoding of non-ASCII paths corrupts directory structure on Windows

1 participant