I want to create a "keyboard cleaning application" for Linux, MacOS and Windows. The basic idea is to grab the keyboard and allow the user to press any key or combination (as much as possible) without any effect while wiping and pressing randomly.
A special keyboard sequence ("keys are clean") or mouse click on a button to end the "cleaning". The screen should display an extended keyboad (F1 to F12, arrow keys, numpad) in the middle showing which key is currently pressed and a counter of total number of keys pressed so far. Instructions and a "Done" button to exit the application should be shown on the bottom.
The project must use:
- Python (3.9 and newer) and the
pygamefor multiplatform compatability. - The extremely fast Python package manager
uvshould be used. - The tools
autopep8,pylint,pytestandtoxshould be used for formatting and testing.
The source files should be under a src directory.
The project will be uploaded to https://test.pypi.org/ and https://pypi.org/ using twine.
The license will be the Unlicense.
A sample Makefile is provided and must be updated.
An .editorconfig file is provided and should be respected.
Type hints should be added where possible.
Is it possible? Concerns? Ask questions.
Prepare a plan for implementation and let me review it.
Role: Lead Software Architect / Developer
Create a cross-platform keyboard cleaning utility for Linux, macOS, and Windows. The app must "lock" the keyboard, visually reflecting keypresses on a virtual UI while suppressing their effect on the OS, allowing users to wipe their physical keyboard without triggering commands.
- Input Handling: - Capture all keyboard events. Use
pygamefor the UI, but acknowledge that native OS hooks ( e.g.,pynputor platform-specific APIs) might be needed to achieve a "Global Hook" that suppresses system shortcuts.- Requirement: The app must prevent accidental "destructive" key combos (like Alt+F4 or Cmd+Q) while in cleaning mode.
- Visual Feedback:
- A 100% (Full/Extended) keyboard layout visualization (F-keys, arrows, numpad).
- Real-time highlighting of keys currently held down.
- A persistent counter showing total key strikes during the session.
- Exit Mechanics:
- A specific "Safety Sequence" (e.g., typing 'keys are clean') or a prominent "Done" button clickable via mouse to release the lock and exit.
- Language: Python 3.9+ with strict Type Hinting.
- UI:
pygame. - Environment: Use
uvfor dependency management (provide apyproject.toml). - DevOps/QA:
- Formatting:
autopep8. - Linting:
pylint. - Testing:
pytest(withpytest-mockfor input simulation) andtoxfor cross-version testing.
- Formatting:
- Structure:
src/layout. - Deployment: Ready for PyPI/TestPyPI via
twine. - Licensing: Unlicense.
- Artifacts: Update the existing
Makefileand respect the.editorconfig.
- Analyze the feasibility of "Global Input Suppression" across Linux (X11/Wayland), macOS (Accessibility Permissions), and Windows (LowLevelHooks).
- Detail how you will handle high-frequency random inputs (keyboard mashing) without crashing the event queue.
- Provide a directory structure and a step-by-step implementation plan.
- DO NOT write all the code yet. Present the plan and the proposed
pyproject.tomlfor review first. - Ask questions to clarify unclear points.
These are the prompts used in the Claude Sonnet 4.6 vibe-coding session.
-
"0. My name is 'Doncho Nikolaev Gunchev', not 'Dimitar'. 1. Yes, use 'keys are clean' exactly. 2. ISO 105 key. 3. Full screen application. 4. Use pygame-ce. 5. Yes, update the Makefile accordingly, this is just a sample/skeleton. 6. Use
pynput. And write the plan to PLAN.md." -
"Excellent, I added minor detail with date/time display. Please proceed with the plan." (after manually editing the renderer line in PLAN.md)
-
"Write this summary after all done to CHANGELOG.md."
-
"I added all files to git, please commit."
-
"The command
uv sync --group devdoes not seem to do anything." -
"Add this info to README, development section."
-
"commit please"
-
"On Linux (KDE, Wayland) the Super (windows) key is showing the start menu. Is there a way to capture it. Is some dependency missing?"
-
"Yes please, implement option A and commit." (during implementation) "Please add a notice to
sudo usermod -aG input $USERto the user, if the access is not granted on /dev/*..." -
"The
Enterkey overlaps withDel. Please shorten the# ~key and fit theEnterthere." (with screenshot) -
"Please add a
Makefiletarged that creates new release. Something likemake V=0.2.0 releasethat updates the version everywhere, tags it in git and adds the changes (from git log) to @CHANGELOG.md." -
"If /dev/input/event* isn't readable, in addition to logging: sudo usermod -aG input $USER for stronger evdev-level suppression, add it below the "keys are clean" hint."
-
"Before the clock on the top add the application title and short description as a header. Make the milliseconds from the clock optional, it is too "busy"."
-
"Nice. Append the prompts I used to PROMPT.md in the project root. Make release 0.9.0, tag it and commit (without PROMPT.md)."
-
For some reason the Super key gets captured by KeyClean, but shortly after KDE's application launcher picks it up too.
-
Nope, same story. Maybe take a look how @../kbdclean/ does it, there is no problem with Super.
-
Put the release part in a separate python script
release.py, clean the Makefile. -
Clean and fix the "clean" target in the @Makefile.
-
"Add a
runmake target, that does all the uv sync steps and then uv runs the app. Development mode." -
"Hey, won't that only work on Linux?"
-
"When I run it locally, everything works, the Super key is captured. When I upload to pypi and run it with
uvx keycleanthe Super key leaks to KDE. What could be wrong, missing dependency?" -
"Nice, make new release and upload."
-
"Add the version to the first line."
-
"Add
-devto the version if there are uncommitted changes or commits after the last tag." (interrupted after proposal — see next) -
"Yes please. And do a release."
-
"
__init__.pyin the release shows0.9.5-devinstead of0.9.4." -
"Add all prompts missing from @PROMPT.md, this one included, commit, then
make release V=0.9.5please." -
"On MacOS I noticed a warning that some dependency is missing. I used
uv tool install keyclean. Is it also missing/optional, likeevdevwas on Linux?" -
"On MacOS I also noticed that the arrow keys have boxes instead of arrows (missing font glyphs?)."
-
"Next to the left Shift there is an extra
\|button, remove it and enlarge the shift key." -
"Move the first line of keys,
Esc...F12...Pausea bit up, doubling the distance they have from the second line. AlignPrint ScreenwithInsandDelhorizontally. Align the right side of theEnterkey withBackspaceand the rightShift." -
"Add more spacing to the first row (
Esc..F12) so thatF12aligns withBackspaceon the right. Remove the#~key on the bottom left of theEnterkey and join the space to theEnterkey. Expand the\|key on the left top of theEnterkey to normal width, taking the space fromEnter. Move theEnterlabel down to use the newly joined space." -
"Auch, make the
Enterkey only use the second line. Shift\|right to not overlap with]}and extend it right to align withBackspace." -
"Perfection. Now, you mentioned something about handling negative rows. Won't shifting everything a bit down solve that problem?"
-
"Nice. Add all prompts to @PROMPT.md and create a new release please."
-
"Interesting, on MacOS 0.9.5 was working, but 0.9.6 is crashing and I am getting a prompt to reopen it (which does not work). Also, I get
keycleanandkeyclean-gui, what is the use of the second script?" -
"Let's test that. You know the drill, @PROMPT.md, release and I will test."
-
"Nope, keeps crashing. I get "pygame-ce 2.5.7 (SDL 2.32.10, Python 3.14.3)" and "Trace/BPT trap: 5 keyclean" on Mac."
-
"You know the drill, @PROMPT.md, release and I will test."
-
"Interesting, now it shows a crash dialog, which I can close, and then the app shows up. If I grant the accessibility permission to iterm it just crashes, nothing works. And the arrow keys are still just empty squares."
-
"Why are the files in
src/keyclean/input_grabber/named with underscore at the start?" -
"OK, what does
pygame-ceprovide here, besides the obvious full screen scene? I am thinking can it be done using TUI?" -
"Add RPM packaging, desktop entry and icon please."
-
"Will python3-pygame.x86_64 work?"
-
"Nope, still broken. Drop
pygame-ceand replace it with justpygame." -
"Same error." (after switching to plain pygame — pygame 2.6.1 from PyPI has a broken font module with Python 3.14)
-
"Figure out what the Font problem is. There are games that rely on pygame and work fine."
-
"Looks like pygame and pygame-ce are both quite problematic to package, for Fedora at least. Can python3-pysdl2 replace it for the purpose of KeyClean?"
-
"But
make rpmstill fails with:python3dist(pygame-ce) >= 2.4 is needed by keyclean-..." (fix: sed-replace pygame-ce→pygame in pyproject.toml during %prep so %pyproject_buildrequires generates python3dist(pygame) instead) -
"Add a changelog to the rpm spec file for the initial package."
-
"Nice,
make rpm RPM_VER=0.9.10 RPM_REV=0works. Can you make RPM_VER default to the latest release and RPM_REV default to 0?" -
"Please update the prompts. No need for new release this time."