Skip to content

fix: use UTF-8 encodings for module file read/write on Windows - #227

Closed
AshSgDe29071999 wants to merge 3 commits into
LobsterTrap:mainfrom
AshSgDe29071999:fix/windows-utf8-encoding
Closed

fix: use UTF-8 encodings for module file read/write on Windows#227
AshSgDe29071999 wants to merge 3 commits into
LobsterTrap:mainfrom
AshSgDe29071999:fix/windows-utf8-encoding

Conversation

@AshSgDe29071999

@AshSgDe29071999 AshSgDe29071999 commented Aug 5, 2026

Copy link
Copy Markdown

Summary

On Windows, Path.read_text() / write_text() without an explicit encoding use the locale codec (typically cp1252). Module files with emoji or other non-ASCII UTF-8 content then raise UnicodeDecodeError during lola mod info / lola install. A UTF-8 BOM also breaks the startswith("---") frontmatter check.

Changes

  • Read module/config text with encoding="utf-8-sig" (strips BOM when present).
  • Write with encoding="utf-8".
  • Cover emoji + BOM cases with unit tests on frontmatter validation.

Closes #224

Summary by CodeRabbit

  • Bug Fixes

    • Improved compatibility with UTF-8 files that include a byte-order mark.
    • Generated and updated configuration, skill, command, agent, and instruction files now consistently use UTF-8 encoding.
    • Preserved existing parsing, validation, sorting, and error-handling behavior.
    • Improved reliable reading and writing of configuration files across supported integrations.
  • Tests

    • Added coverage for UTF-8 content, including emoji and BOM-prefixed files.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The change standardizes module file encoding. Reads use BOM-aware UTF-8 decoding, and writes use explicit UTF-8 encoding across parsers, CLI commands, shared targets, and target integrations. Tests cover emoji content and BOM-prefixed frontmatter.

Changes

UTF-8 encoding support

Layer / File(s) Summary
Module parsing and input handling
src/lola/frontmatter.py, src/lola/models.py, src/lola/cli/install.py, src/lola/cli/mod.py, src/lola/targets/install.py, src/lola/targets/opencode.py, src/lola/targets/base.py
Module and MCP reads now use utf-8-sig. YAML reads use explicit UTF-8 decoding.
Shared target generation
src/lola/targets/base.py
Managed skills, instructions, commands, agents, and MCP configuration now use BOM-aware reads and explicit UTF-8 writes.
CLI, target integrations, and validation
src/lola/cli/mod.py, src/lola/targets/claude_code.py, src/lola/targets/copilot.py, src/lola/targets/cursor.py, src/lola/targets/gemini.py, src/lola/targets/openclaw.py, tests/test_utf8_encoding.py
Generated files use UTF-8, target-specific reads accept an optional BOM, and tests cover emoji content and BOM-prefixed frontmatter.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the primary change: explicit UTF-8 encoding for module file reads and writes on Windows.
Linked Issues check ✅ Passed The changes address issue #224 by adding UTF-8 and BOM-safe file I/O across the affected modules, targets, parsers, and CLI paths.
Out of Scope Changes check ✅ Passed All summarized code and test changes directly support the linked issue and PR objective.
Docstring Coverage ✅ Passed Docstring coverage is 82.35% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 71380d5711

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/lola/frontmatter.py Outdated
Comment thread src/lola/targets/claude_code.py Outdated
Comment thread src/lola/targets/cursor.py Outdated
Comment thread src/lola/targets/openclaw.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lola/frontmatter.py`:
- Line 50: Update the normal frontmatter file-loading path in frontmatter.load
to read markdown with UTF-8-SIG instead of the default UTF-8, ensuring a leading
BOM is stripped before frontmatter detection and parsing. Preserve the existing
return behavior and decoding for other paths.

In `@src/lola/models.py`:
- Line 234: Update the sibling lola.yaml read in Module.from_path to open
lola_yaml with encoding="utf-8-sig", matching the existing MCP configuration
read and supporting BOM-prefixed or non-ASCII values.

In `@src/lola/targets/claude_code.py`:
- Line 63: Update the SKILL.md destination writes to use explicit UTF-8 encoding
while preserving utf-8-sig reads: modify the write in
src/lola/targets/claude_code.py at lines 63-63, src/lola/targets/cursor.py at
lines 72-72, and src/lola/targets/openclaw.py at lines 73-73.

In `@tests/test_utf8_encoding.py`:
- Around line 8-15: Update test_parse_file_with_emoji to assert that body
contains the exact emoji content written by the fixture, including ⚠️, rather
than checking only the ASCII word “warning”.
- Around line 18-26: Extend test_parse_file_with_utf8_bom to call parse_file on
the BOM-prefixed skill and assert the parsed metadata contains the expected name
and description, along with the expected body content. Keep the existing
validate_skill assertion intact.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 228ab844-76ca-4dd2-99a4-c405240eb22c

📥 Commits

Reviewing files that changed from the base of the PR and between 853e936 and 71380d5.

📒 Files selected for processing (13)
  • src/lola/cli/install.py
  • src/lola/cli/mod.py
  • src/lola/frontmatter.py
  • src/lola/models.py
  • src/lola/targets/base.py
  • src/lola/targets/claude_code.py
  • src/lola/targets/copilot.py
  • src/lola/targets/cursor.py
  • src/lola/targets/gemini.py
  • src/lola/targets/install.py
  • src/lola/targets/openclaw.py
  • src/lola/targets/opencode.py
  • tests/test_utf8_encoding.py

Comment thread src/lola/frontmatter.py Outdated
Comment thread src/lola/models.py
Comment thread src/lola/targets/claude_code.py Outdated
Comment thread tests/test_utf8_encoding.py
Comment thread tests/test_utf8_encoding.py
@AshSgDe29071999

Copy link
Copy Markdown
Author

Addressed bot/review feedback:

  • Write skill files as UTF-8 in claude_code.py, cursor.py, and openclaw.py (write_text(..., encoding="utf-8"))
  • BOM-safe parse_file: read with utf-8-sig then frontmatter.loads (via parse()), so parse_file / get_metadata no longer miss name/description when a UTF-8 BOM is present
  • models.py: open lola.yaml / lola.yml with encoding="utf-8"
  • Tests: assert the emoji itself in the body; BOM case now also exercises parse_file and get_metadata

pytest tests/test_utf8_encoding.py green.

@SecKatie SecKatie left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — verified all review findings are fixed, the full test suite (1074 tests) passes, and ruff is clean.

@SecKatie

Copy link
Copy Markdown
Collaborator

@AshSgDe29071999 Thanks for the fix — review feedback is now all addressed and tests pass. Could you rebase onto the latest main and make sure the lint checks pass (ruff check src tests)? Once that's pushed I'll merge this.

AshSgDe29071999 and others added 3 commits August 10, 2026 23:43
Closes #224

Path.read_text()/write_text() without encoding use the locale codec on
Windows (often cp1252), which raises UnicodeDecodeError on emoji and
other non-ASCII module content. Read with utf-8-sig (strips BOM) and
write with utf-8 across the CLI and target install paths.
- Write skill files with encoding=utf-8 in claude_code/cursor/openclaw
- parse_file reads utf-8-sig then frontmatter.loads so BOM works
- Open lola.yaml as UTF-8
- Tests assert emoji content and exercise parse_file under BOM
@AshSgDe29071999

Copy link
Copy Markdown
Author

Rebased onto latest main and ran ruff format on the touched files so the format check is clean.

@AshSgDe29071999
AshSgDe29071999 force-pushed the fix/windows-utf8-encoding branch from 3693ff1 to a04c791 Compare August 10, 2026 18:14

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lola/targets/opencode.py (1)

34-60: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Use OpenCode’s native tool permission keys and deny unlisted tools.

_normalize_tool_name() converts webfetch to fetch, but OpenCode configuration uses webfetch/websearch, while todo tools use todowrite/todoread keys. KNOWN_OPENCODE_TOOLS also includes todoreplace, which is not a native OpenCode permission key. Keep exact supported keys, add missing native keys to the deny list, and cover web/todo/custom tools in OpenCode target tests so source allowlists do not get converted into broken access controls.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lola/targets/opencode.py` around lines 34 - 60, The OpenCode tool
normalization and allowlist deny set use incorrect native permission keys.
Update _normalize_tool_name and KNOWN_OPENCODE_TOOLS to preserve
webfetch/websearch and use todowrite/todoread, remove todoreplace, and ensure
unlisted tools remain denied; extend the OpenCode target tests to cover web,
todo, and custom tool mappings.

Source: MCP tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/lola/targets/opencode.py`:
- Around line 34-60: The OpenCode tool normalization and allowlist deny set use
incorrect native permission keys. Update _normalize_tool_name and
KNOWN_OPENCODE_TOOLS to preserve webfetch/websearch and use todowrite/todoread,
remove todoreplace, and ensure unlisted tools remain denied; extend the OpenCode
target tests to cover web, todo, and custom tool mappings.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 12d0792d-0cda-4d4d-8d59-55ef511be6fe

📥 Commits

Reviewing files that changed from the base of the PR and between 3693ff1 and a04c791.

📒 Files selected for processing (6)
  • src/lola/cli/mod.py
  • src/lola/targets/base.py
  • src/lola/targets/claude_code.py
  • src/lola/targets/copilot.py
  • src/lola/targets/cursor.py
  • src/lola/targets/opencode.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/lola/targets/cursor.py
  • src/lola/targets/claude_code.py
  • src/lola/cli/mod.py

@AshSgDe29071999 AshSgDe29071999 closed this by deleting the head repository Aug 11, 2026
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] Windows: UnicodeDecodeError (cp1252/charmap) reading UTF-8 module files with emoji/BOM

2 participants