Skip to content

1.0.0 - #81

Open
rtuszik wants to merge 20 commits into
mainfrom
organize
Open

rtuszik wants to merge 20 commits into
mainfrom
organize

Conversation

@rtuszik

@rtuszik rtuszik commented May 28, 2026 •

Copy link
Copy Markdown
Owner

TODO:

  • update readme to reflect new package structure
  • allow invocation with uv run koalakeys

@socket-security

socket-security Bot commented May 28, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedpytest@​9.1.1 ⏵ 9.0.387100100100100
Updatedvulture@​2.14 ⏵ 2.16100100100100100
Updatedruamel-yaml@​0.18.16 ⏵ 0.19.1100100100100100
Updatedpytest-cov@​7.0.0 ⏵ 7.1.0100100100100100
Addedprek@​0.3.6100100100100100
Updatedty@​0.0.11 ⏵ 0.0.40100 +1100100100100
Updatedruff@​0.14.14 ⏵ 0.15.14100 +1100100100100
Addedpytest-playwright@​0.7.1100100100100100
Addedpytest-playwright@​0.8.0100100100100100

View full report

@socket-security

socket-security Bot commented May 28, 2026 •

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Priority Alert  (click "▶" to expand/collapse) Action
Critical priority
Critical CVE: pypi certifi bundles emSign root CAs with compromised intermediate CA keys

CVE: GHSA-6q48-6c7w-9gw2 certifi bundles emSign root CAs with compromised intermediate CA keys (CRITICAL)

Affected versions: >= 2019.03.09 < 2026.10.19

Patched version: 2026.10.19

From: uv.lock → pypi/pytest-playwright@0.8.0 → pypi/pytest-playwright@0.7.1 → pypi/certifi@2026.5.20

ℹ Read more on: This package | This alert | What is a critical CVE?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Remove or replace dependencies that include known critical CVEs. Consumers can use dependency overrides or npm audit fix --force to remove vulnerable dependencies.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore pypi/certifi@2026.5.20. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn

View full report

@github-actions

github-actions Bot commented May 28, 2026 •

Copy link
Copy Markdown

Coverage

Coverage Report
FileStmtsMissCoverMissing
src/koalakeys
   cli.py60297%51, 100
   generate_cheatsheet.py2182987%56–57, 109–111, 126–127, 151–153, 197–199, 208–210, 220–221, 225, 229, 235–236, 267–268, 272–273, 277–278, 295
   logger.py35391%21, 42–43
   template_renderer.py16288%20–21
   theming.py1751591%111, 134, 165–168, 170, 176, 179, 183, 213, 236, 261, 284, 293
TOTAL6895193% 

Tests Skipped Failures Errors Time
187 0 💤 0 ❌ 0 🔥 3.063s ⏱️

@rtuszik rtuszik changed the title Organize 1.0.0 Jun 9, 2026
@rtuszik

rtuszik commented Jun 22, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai

@coderabbitai

coderabbitai Bot commented Jun 22, 2026 •

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get PR details
gh pr view 81 --repo rtuszik/KoalaKeys

echo "---FILES CHANGED---"
gh pr diff 81 --repo rtuszik/KoalaKeys --name-only

echo "---PR COMMENTS---"
gh pr view 81 --repo rtuszik/KoalaKeys --comments

Length of output: 31529


🏁 Script executed:

#!/bin/bash
# Check pyproject.toml for scripts/entry points
cat pyproject.toml

echo "---README---"
cat README.md | head -100

Length of output: 5139



@rtuszik, happy to help! I noticed a few things worth addressing before this is ready to merge:

Outstanding TODOs

  1. README not updated – The README still references the old invocation path (uv run src/generate_cheatsheet.py) and the old src/ structure. It needs to be updated to reflect the new src/koalakeys/ package layout.

  2. uv run koalakeys not yet wired up – pyproject.toml is missing a [project.scripts] entry. You'll need something like:

    [project.scripts]
    koalakeys = "koalakeys:main"

    (adjust the entry point to match your actual main() function location in src/koalakeys/__init__.py or generate_cheatsheet.py).

Other things to check

  • Version mismatch: pyproject.toml has version = "0.6.0" but the PR is titled 1.0.0. Was the bump forgotten?
  • prek dependency: Socket Security flagged prek@0.3.6 as 90% likely containing obfuscated code. It's only a dev dependency, but worth verifying it's intentional/safe before merging.

Would you like me to do a full review of all the changes now?

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026 •

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
Walkthrough

The package adds theme-aware cheatsheet generation with six built-in themes and user-theme inheritance. It adds koalakeys commands for project initialisation, generation, and validation. The changes also update templates, tests, packaging, documentation, and CI workflows.

Changes: KoalaKeys theming and CLI workflow

Layer / File(s) Summary
Theme definitions and styling validation
src/koalakeys/theming.py, src/koalakeys/themes/*, src/koalakeys/validate_yaml.py, docs/schema/cheatsheet.schema.json, yaml_cheatsheet_spec.md, tests/test_theming.py, tests/test_validate_yaml.py
Adds theme resolution, inheritance, token validation, CSS sanitisation, and validation for theme and custom CSS fields. Adds built-in theme definitions and documents theme and CSS options.
Theme-aware generation and templates
src/koalakeys/generate_cheatsheet.py, src/koalakeys/templates/*, src/koalakeys/layouts/*, src/koalakeys/logger.py, src/koalakeys/template_renderer.py, tests/test_generate_cheatsheet.py, tests/test_integration.py, tests/test_browser.py, tests/conftest.py
Generation resolves theme and custom CSS data for rendering. Templates apply the styling and conditionally render the dark-mode controls. The package includes layout mappings and updated template assets.
CLI commands and project scaffolding
src/koalakeys/cli.py, src/koalakeys/scaffold/*, tests/test_cli.py, tests/test_scaffold.py, README.md
Adds init, generate, and validate commands. The init command creates a starter cheatsheet and supports skipping or replacing an existing example.
Packaging, development, and CI configuration
pyproject.toml, .pre-commit-config.yml, pytest.ini, .github/actions/setup-python/action.yml, .github/workflows/*
Declares the koalakeys executable and build backend, updates development tooling, pins action references, restricts workflow permissions, disables persisted checkout credentials, and runs browser tests on pull requests.

Priority: Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Merge Risk: Moderate · up to 89898

Fix theme-key injection and malformed-theme handling before merging: generated pages can contain injected content, and one bad theme can stop generation of later sheets. The CLI and documentation also need small corrections.

Pre-merge checks: Passed 3 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Title check Inconclusive The title is related to the version change, but "1.0.0" does not describe the package restructure, CLI, theming, or workflow changes. Use a descriptive title such as "Prepare the 1.0.0 package release and CLI".
Passed Passed checks: 3 passed
Check name Status Explanation
Description check Passed The description identifies README updates and support for invoking the package with uv run koalakeys. Both topics relate to the changeset.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

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.

@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: 7

Caution

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

⚠️ Outside diff range comments (2)
pyproject.toml (2)

3-3: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Align package version with the 1.0.0 release intent.

Line 3 still declares 0.6.0, which conflicts with the stated release target and can break release automation and artefact labelling.

Proposed change
-version = "0.6.0"
+version = "1.0.0"

1-8: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add a CLI script entry for uv run koalakeys.

[project.scripts] is missing, so the uv run koalakeys objective will not work.

Proposed change
 [project]
 name = "koalakeys"
 version = "0.6.0"
 description = "Build interactive, portable cheatsheets from YAML."
 readme = "README.md"
 requires-python = ">=3.9"
 dependencies = ["jinja2>=3.1.6", "python-dotenv>=1.1.1", "ruamel-yaml>=0.18.14"]
+
+[project.scripts]
+koalakeys = "koalakeys.<module_with_main>:main"
🧹 Nitpick comments (2)
.github/workflows/pytest.yml (1)

18-20: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Remove the duplicated non-browser test run.

Line 18-Line 20 already runs pytest, then Line 32-Line 38 runs it again with coverage. Keeping only the coverage run avoids duplicate CI time.

Proposed change
-            - run: |
-                uv run pytest
-
             # Browser/Playwright tests are excluded by default (pytest.ini) and run
             # only on pull requests, where we install Chromium for them.
             - name: Install Playwright browser
               if: github.event_name == 'pull_request'
               run: |
                 uv run playwright install --with-deps chromium

Also applies to: 32-38

tests/conftest.py (1)

9-16: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Consolidate isolated_output into one fixture definition.

Line 9 introduces a shared fixture, but there is also an isolated_output fixture in tests/test_generate_cheatsheet.py (Lines 10-16 in graph context). Keeping both increases drift risk and can create subtle shadowing differences; prefer using only the conftest.py fixture.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f15c7b39-fc7a-4cef-ac6b-5dc0bba20052

📥 Commits

Reviewing files that changed from the base of the PR and between 7ccb4b1 and 3c140bb.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (45)
  • .github/actions/setup-python/action.yml
  • .github/workflows/lint.yml
  • .github/workflows/pytest.yml
  • .pre-commit-config.yml
  • docs/schema/cheatsheet.schema.json
  • pyproject.toml
  • pytest.ini
  • src/koalakeys/__init__.py
  • src/koalakeys/generate_cheatsheet.py
  • src/koalakeys/layouts/keyboard_layouts.yaml
  • src/koalakeys/layouts/system_mappings.yaml
  • src/koalakeys/logger.py
  • src/koalakeys/template_renderer.py
  • src/koalakeys/templates/base.html
  • src/koalakeys/templates/cheatsheets/assets/cheatsheets.css
  • src/koalakeys/templates/cheatsheets/cheatsheet-template.html
  • src/koalakeys/templates/cheatsheets/components/body.html
  • src/koalakeys/templates/cheatsheets/scripts/main.js
  • src/koalakeys/templates/index/assets/index.css
  • src/koalakeys/templates/index/components/body.html
  • src/koalakeys/templates/index/components/footer.html
  • src/koalakeys/templates/index/index_template.html
  • src/koalakeys/templates/index/scripts/main.js
  • src/koalakeys/themes/catppuccin.yaml
  • src/koalakeys/themes/dracula.yaml
  • src/koalakeys/themes/gruvbox.yaml
  • src/koalakeys/themes/nord.yaml
  • src/koalakeys/themes/rose-pine.yaml
  • src/koalakeys/themes/solarized.yaml
  • src/koalakeys/theming.py
  • src/koalakeys/validate_yaml.py
  • src/layouts/keyboard_layouts.yaml
  • src/layouts/system_mappings.yaml
  • src/templates/cheatsheets/assets/cheatsheets.css
  • src/templates/cheatsheets/cheatsheet-template.html
  • src/templates/index/assets/index.css
  • tests/__init__.py
  • tests/conftest.py
  • tests/test_browser.py
  • tests/test_generate_cheatsheet.py
  • tests/test_integration.py
  • tests/test_replace_shortcut_names.py
  • tests/test_template_renderer.py
  • tests/test_theming.py
  • tests/test_validate_yaml.py
💤 Files with no reviewable changes (6)
  • src/templates/index/assets/index.css
  • tests/init.py
  • src/layouts/keyboard_layouts.yaml
  • src/templates/cheatsheets/cheatsheet-template.html
  • src/layouts/system_mappings.yaml
  • src/templates/cheatsheets/assets/cheatsheets.css

Comment on lines +29 to +31
THEMES_DIR = PROJECT_ROOT / "themes"
STYLES_DIR = PROJECT_ROOT / "styles"
LAYOUTS_DIR = PACKAGE_DIR / "layouts"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Theme lookup path is inconsistent with the relocated package assets.

Line 29 points to PROJECT_ROOT / "themes", but this PR moves themes into the package namespace. That can cause resolve_theme(...) to miss theme files and make generate_html(...) return None on otherwise valid input.

💡 Proposed fix
-THEMES_DIR = PROJECT_ROOT / "themes"
+THEMES_DIR = PACKAGE_DIR / "themes"

Comment thread src/koalakeys/templates/cheatsheets/assets/cheatsheets.css Outdated
Comment thread src/koalakeys/templates/index/assets/index.css
Comment thread src/koalakeys/theming.py
Comment thread src/koalakeys/theming.py
Comment thread src/koalakeys/validate_yaml.py
Comment thread tests/test_browser.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: 3

Caution

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

⚠️ Outside diff range comments (2)

🟠 Major · Align the package version with the 1.0.0 release target. · pyproject.toml:3

pyproject.toml:3
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Align the package version with the 1.0.0 release target.

A build from this PR will declare version 0.6.0 in its package metadata. Set version to 1.0.0, or align the release target with 0.6.0, before publishing.

🟠 Major · Confine custom_css to STYLES_DIR. · generate_cheatsheet.py:142

src/koalakeys/generate_cheatsheet.py:142
🔒 Security & Privacy | 🛡️ Detected with Advanced Tier | 🟠 Major | ⚡ Quick win

Path Traversal

Exploitability: Moderate
CWE: CWE-22 — Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Confine custom_css to STYLES_DIR.

If an attacker can supply a cheatsheet, custom_css can contain an absolute path or .. segments. STYLES_DIR / filename can then read any readable file outside styles/, and the content is inserted into the generated HTML. Resolve the root and candidate paths, then reject candidates outside the resolved STYLES_DIR before calling read_text.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: c1f8a17f-2c12-4f4f-a227-b9c9220a260a

📥 Commits

Reviewing files that changed from the base of the PR and between 3c140bb and 96f3c40.

⛔ Files ignored due to path filters (1)
  • assets/images/KoalaKeys_Example.png is excluded by !**/*.png
📒 Files selected for processing (12)
  • README.md
  • pyproject.toml
  • src/koalakeys/cli.py
  • src/koalakeys/generate_cheatsheet.py
  • src/koalakeys/scaffold/__init__.py
  • src/koalakeys/scaffold/example.yaml
  • src/koalakeys/theming.py
  • src/koalakeys/validate_yaml.py
  • tests/test_cli.py
  • tests/test_generate_cheatsheet.py
  • tests/test_scaffold.py
  • yaml_cheatsheet_spec.md
💤 Files with no reviewable changes (1)
  • src/koalakeys/validate_yaml.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/koalakeys/theming.py

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.

Comment thread README.md Outdated
Comment thread src/koalakeys/generate_cheatsheet.py

@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 GitHub limitations.

⚠️ Outside diff range comments (2)

Major · Replace the flagged prek release before merge. · pyproject.toml:14

pyproject.toml:14
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Replace the flagged prek release before merge.

uv.lock resolves the development dependency to prek==0.3.6 and records PyPI distribution URLs and hashes. This is the release flagged by Socket Security. Replace it with a vetted release and regenerate uv.lock, or remove the dependency.

Minor · Correct the current-directory statement. · README.md:95

README.md:95
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the current-directory statement.

init [path] can scaffold a directory other than the current directory. State that generate and validate use the current directory, while init uses its path argument.

🔇 Additional comments: 2
pyproject.toml: 1

3-10: LGTM!

Also applies to: 13-13, 15-20, 23-29, 34-37, 64-81

README.md-15-15: 1

15-15: Minor · Maintainability & Code Quality · Quick win

⚠️ Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Split the quick-start instruction into separate steps.

The punctuation makes the command sequence unclear. LanguageTool also reports DOUBLE_PUNCTUATION on this line. Use separate sentences or an ordered list.

Source: Linters/SAST tools


Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b7a4da03-740a-43b1-bfd0-f945d6ed974f
Commits

Reviewing files that changed from the base of the PR and between 3b31401 and fb76c1a.

Files ignored due to path filters: 1
  • uv.lock is excluded by !**/*.lock
Files selected for processing: 2
  • README.md
  • pyproject.toml

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

@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: 7


Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8b36972f-54a1-4187-bcbc-3cb9199432c0
Commits

Reviewing files that changed from the base of the PR and between fb76c1a and 8989865.

Files ignored due to path filters: 2
  • assets/images/KoalaKeys_Example.png is excluded by !**/*.png
  • uv.lock is excluded by !**/*.lock
Files selected for processing: 52
  • .github/actions/setup-python/action.yml
  • .github/workflows/lint.yml
  • .github/workflows/pytest.yml
  • .pre-commit-config.yml
  • README.md
  • docs/schema/cheatsheet.schema.json
  • pyproject.toml
  • pytest.ini
  • src/koalakeys/__init__.py
  • src/koalakeys/cli.py
  • src/koalakeys/generate_cheatsheet.py
  • src/koalakeys/layouts/keyboard_layouts.yaml
  • src/koalakeys/layouts/system_mappings.yaml
  • src/koalakeys/logger.py
  • src/koalakeys/scaffold/__init__.py
  • src/koalakeys/scaffold/example.yaml
  • src/koalakeys/template_renderer.py
  • src/koalakeys/templates/base.html
  • src/koalakeys/templates/cheatsheets/assets/cheatsheets.css
  • src/koalakeys/templates/cheatsheets/cheatsheet-template.html
  • src/koalakeys/templates/cheatsheets/components/body.html
  • src/koalakeys/templates/cheatsheets/scripts/main.js
  • src/koalakeys/templates/index/assets/index.css
  • src/koalakeys/templates/index/components/body.html
  • src/koalakeys/templates/index/components/footer.html
  • src/koalakeys/templates/index/index_template.html
  • src/koalakeys/templates/index/scripts/main.js
  • src/koalakeys/themes/catppuccin.yaml
  • src/koalakeys/themes/dracula.yaml
  • src/koalakeys/themes/gruvbox.yaml
  • src/koalakeys/themes/nord.yaml
  • src/koalakeys/themes/rose-pine.yaml
  • src/koalakeys/themes/solarized.yaml
  • src/koalakeys/theming.py
  • src/koalakeys/validate_yaml.py
  • src/layouts/keyboard_layouts.yaml
  • src/layouts/system_mappings.yaml
  • src/templates/cheatsheets/assets/cheatsheets.css
  • src/templates/cheatsheets/cheatsheet-template.html
  • src/templates/index/assets/index.css
  • tests/__init__.py
  • tests/conftest.py
  • tests/test_browser.py
  • tests/test_cli.py
  • tests/test_generate_cheatsheet.py
  • tests/test_integration.py
  • tests/test_replace_shortcut_names.py
  • tests/test_scaffold.py
  • tests/test_template_renderer.py
  • tests/test_theming.py
  • tests/test_validate_yaml.py
  • yaml_cheatsheet_spec.md
Files with no reviewable changes: 11
  • src/koalakeys/templates/index/components/body.html
  • tests/init.py
  • src/koalakeys/init.py
  • src/layouts/system_mappings.yaml
  • src/koalakeys/templates/index/components/footer.html
  • src/koalakeys/templates/index/scripts/main.js
  • src/templates/index/assets/index.css
  • src/templates/cheatsheets/assets/cheatsheets.css
  • src/templates/cheatsheets/cheatsheet-template.html
  • src/layouts/keyboard_layouts.yaml
  • src/koalakeys/templates/index/index_template.html
Files skipped from review as they are similar to previous changes: 1
  • src/koalakeys/templates/index/assets/index.css

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.

Comment thread README.md

- Generate HTML cheat sheets from YAML files
- Interactive keyboard layout with real-time highlighting
- Six built-in themes (catppuccin, dracula, gruvbox, nord, rosé-pine, solarized) plus user themes and custom CSS

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor · Functional Correctness · Quick win

🔎 Supported by static analysis

Script executed:

#!/bin/bash
# Check the built-in identifier and any normalisation in theme resolution.
rg -n -C 5 'rose-pine|rosé-pine|def resolve_theme|BUILTIN' \
  src/koalakeys/theming.py src/koalakeys/themes/rose-pine.yaml yaml_cheatsheet_spec.md

Repository: rtuszik/KoalaKeys

Length of output: 2261


Script executed:

#!/bin/bash
printf '%s\n' '--- resolver ---'
nl -ba src/koalakeys/theming.py | sed -n '186,225p'
printf '%s\n' '--- README ---'
nl -ba README.md | sed -n '24,32p'

Repository: rtuszik/KoalaKeys

Length of output: 2485


Use the accepted theme identifier.

The built-in identifier is rose-pine. Replace rosé-pine in the README.

Suggested fix
--- "a/README.md"
+++ "b/README.md"
@@ -25,7 +25,7 @@
 
 - Generate HTML cheat sheets from YAML files
 - Interactive keyboard layout with real-time highlighting
-- Six built-in themes (catppuccin, dracula, gruvbox, nord, rosé-pine, solarized) plus user themes and custom CSS
+- Six built-in themes (catppuccin, dracula, gruvbox, nord, rose-pine, solarized) plus user themes and custom CSS
 - Categorized shortcuts with descriptions
 - Index page for quick access to all cheat sheets
 - Search functionality
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Six built-in themes (catppuccin, dracula, gruvbox, nord, rosé-pine, solarized) plus user themes and custom CSS
- Six built-in themes (catppuccin, dracula, gruvbox, nord, rose-pine, solarized) plus user themes and custom CSS

Comment thread src/koalakeys/cli.py
if in_place:
print(" koalakeys generate")
else:
print(f" cd {args.path or DEFAULT_PROJECT_DIRNAME} && koalakeys generate")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor · Functional Correctness · Quick win

Make the printed command work for paths with spaces.

If a user runs koalakeys init "my project", the next step prints cd my project && koalakeys generate. That command does not enter the new directory. Quote or escape the path in the printed command.

Comment thread src/koalakeys/cli.py
all_valid = False
if not path.is_file():
continue
for warning in lint_yaml(path):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor · Stability & Availability · Quick win

Handle lint read errors after validation fails.

If a .yaml file contains invalid UTF-8, validate_yaml() returns False, but path.is_file() remains true. lint_yaml() then raises UnicodeDecodeError, so validate prints a traceback instead of completing its file checks. Catch read and decoding errors around the lint call, and retain the non-zero result.

Comment thread src/koalakeys/theming.py
Comment on lines +109 to +111
def _validate_token_value(name: str, value: object) -> str:
if not isinstance(value, (str, int, float)):
raise ThemeError(f"Token '{name}' must be a scalar, got {type(value).__name__}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor · Security & Privacy · Quick win

🔎 Supported by static analysis

Script executed:

sed -n '35,155p' src/koalakeys/theming.py

Repository: rtuszik/KoalaKeys

Length of output: 3829


Script executed:

sed -n '156,260p' src/koalakeys/theming.py
echo '--- spec sanitisation mentions ---'
rg -n -i -- 'sanitis|sanitiz' --glob '*.md' . || test "$?" -eq 1

Repository: rtuszik/KoalaKeys

Length of output: 5594


Script executed:

sed -n '260,330p' src/koalakeys/theming.py
echo '--- spec context ---'
sed -n '190,205p' yaml_cheatsheet_spec.md

Repository: rtuszik/KoalaKeys

Length of output: 2270


Validate token names before emitting them as CSS custom properties.

_validate_token_value checks only the value. The token name is never checked. _split_theme_doc stores each non-reserved key in shared without validating it. _resolve_user_theme merges these keys without filtering, and render_token_css writes --kk-{k}: {v}; for each one. The token CSS does not pass through sanitize_css.

A user theme can use the key "a: red; } body {display:none} .x {--b" with the value red. The value red passes _COLOR_RE. The key is not matched against _COLOR_RE. The output then contains --kk-a: red; } body {display:none} .x {--b: red;, which adds a body rule. A key such as </style><script> can also end the <style> block, because the template emits the token CSS with | safe.

yaml_cheatsheet_spec.md states that theme values are validated and custom CSS is sanitised before emission. It does not mention token names, so token names are emitted without a check.

Restrict token names to a safe pattern. Alternatively, accept only names in COLOR_TOKENS and SHARED_TOKENS.

🛡️ Proposed fix
--- "a/src/koalakeys/theming.py"
+++ "b/src/koalakeys/theming.py"
@@ -106,8 +106,13 @@
         return "\n".join(lines)
 
 
+_TOKEN_NAME_RE = re.compile(r"^[a-z0-9][a-z0-9-]*$")
+
+
 def _validate_token_value(name: str, value: object) -> str:
+    if not isinstance(name, str) or not _TOKEN_NAME_RE.match(name):
+        raise ThemeError(f"Invalid token name: {name!r}")
     if not isinstance(value, (str, int, float)):
         raise ThemeError(f"Token '{name}' must be a scalar, got {type(value).__name__}")
     text = str(value).strip()
     if name == "font":

Place _TOKEN_NAME_RE with the other regular expressions. Check that existing theme files use only lowercase letters, digits and hyphens in token names.

Comment thread src/koalakeys/theming.py
parent = data.get("extends")
if not parent:
raise ThemeError(f"User theme '{name}' must declare 'extends: <built-in>'")
if parent not in builtin_names:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor · Stability & Availability · Quick win

Reject non-string extends values with ThemeError.

parent not in builtin_names raises TypeError for an unhashable value, for example extends: [catppuccin]. apply_styling catches only ThemeError. The exception therefore escapes generate_html and aborts generate_all. The same problem applies to an unhashable default_mode at Line 285 (default_mode not in modes).

Check isinstance(parent, str) first. Apply the same check to default_mode.

🛡️ Proposed fix
--- "a/src/koalakeys/theming.py"
+++ "b/src/koalakeys/theming.py"
@@ -247,7 +247,7 @@
     parent = data.get("extends")
     if not parent:
         raise ThemeError(f"User theme '{name}' must declare 'extends: <built-in>'")
-    if parent not in builtin_names:
+    if not isinstance(parent, str) or parent not in builtin_names:
         raise ThemeError(f"User theme '{name}' extends unknown built-in '{parent}'. Available: {sorted(builtin_names)}")
 
     base = _resolve_builtin(parent, builtins_dir)
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if parent not in builtin_names:
if not isinstance(parent, str) or parent not in builtin_names:

Comment thread src/koalakeys/theming.py
Comment on lines +257 to +262
merged_modes: dict[str, dict[str, str]] = {}
for mode in MODES:
base_tokens = getattr(base, mode)
if base_tokens is None and mode not in user_modes:
continue
merged_modes[mode] = {**(base_tokens or {}), **user_modes.get(mode, {})}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor · Functional Correctness · Quick win

Check that merged user-theme modes define every colour token.

_assert_complete runs only for built-in themes. A user theme can extend a dark-only built-in (for example nord) and declare a partial light: block. The merge then creates a light mode that holds only the user's tokens. both_modes becomes true, so the toggle appears. Switching to light mode leaves most --kk-* variables undefined.

After merging, check each mode against COLOR_TOKENS and raise ThemeError when tokens are missing.

🐛 Proposed fix
         merged_modes[mode] = {**(base_tokens or {}), **user_modes.get(mode, {})}
+        missing = [t for t in COLOR_TOKENS if t not in merged_modes[mode]]
+        if missing:
+            raise ThemeError(f"User theme '{name}' mode '{mode}' missing tokens: {missing}")
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
merged_modes: dict[str, dict[str, str]] = {}
for mode in MODES:
base_tokens = getattr(base, mode)
if base_tokens is None and mode not in user_modes:
continue
merged_modes[mode] = {**(base_tokens or {}), **user_modes.get(mode, {})}
merged_modes: dict[str, dict[str, str]] = {}
for mode in MODES:
base_tokens = getattr(base, mode)
if base_tokens is None and mode not in user_modes:
continue
merged_modes[mode] = {**(base_tokens or {}), **user_modes.get(mode, {})}
missing = [t for t in COLOR_TOKENS if t not in merged_modes[mode]]
if missing:
raise ThemeError(f"User theme '{name}' mode '{mode}' missing tokens: {missing}")

Comment thread yaml_cheatsheet_spec.md
sheet exactly like a built-in: `theme: my-dracula`.

The full token list (all color, typography, and spacing tokens a theme can set)
is documented in [docs/themes/tokens.md](docs/themes/tokens.md).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor · Maintainability & Code Quality · Quick win

🔎 Supported by static analysis

Script executed:

#!/bin/bash
fd -i 'tokens.md' docs
rg -n 'docs/themes/tokens.md' --glob '*.md' --glob '*.yaml' --glob '*.css'

Repository: rtuszik/KoalaKeys

Length of output: 453


Script executed:

test -e docs/themes/tokens.md && echo "target: present" || echo "target: absent"
test -d docs && echo "docs dir: present" || echo "docs dir: absent"
ls -la docs 2>&1 || true
git ls-files | rg -i 'tokens' || test "$?" -eq 1
git ls-files | rg -i '^docs/' || test "$?" -eq 1

Repository: rtuszik/KoalaKeys

Length of output: 379


Add the missing token reference or fix the broken link.

The link in yaml_cheatsheet_spec.md points to docs/themes/tokens.md, and that file does not exist in the checkout. The docs/ directory contains only docs/schema/cheatsheet.schema.json. Readers who follow the link reach a missing page. They cannot find the token list that the Theming section says is documented there.

Either add docs/themes/tokens.md or change the link to a document that exists. Also update the other references to the same path in src/koalakeys/themes/catppuccin.yaml:5 and src/koalakeys/templates/cheatsheets/assets/cheatsheets.css:5, so that they do not point to a missing file.

This branch has not been deployed

No deployments
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