Python developer. I build small tools that fix everyday annoyances,
and send fixes upstream to the open-source projects I rely on.
I'm self-taught and I learn by shipping: break it, read the traceback, fix it, repeat. Most of what I write starts as an irritation of my own β a downloads folder that nobody has ever seen twice the same way, a rename that took far too many clicks, a clipboard that forgets everything the moment I close it.
Everything here is MIT licensed. Where there is code there are tests, and a README that says what it does and what it doesn't.
- Building β small Python tools, one annoyance at a time
- Maintaining β bug fixes upstream where the software I use has a gap
- Exploring β HTML and CSS next to Python, and Git beyond
push/pull
| Project | What it is |
|---|---|
| EzSort | Sorts a messy folder into categories β CLI and desktop app, zero dependencies, preview first, undo everything. |
| EzRename | Batch-renames files with a live preview and one-click undo. GUI and CLI for Windows. |
| Easy Clipboard Manager | A local-first clipboard history for Windows. Search, snippets, global hotkey β nothing ever leaves your machine. |
| TreeMark | Prints any project as a tree: plain, Markdown or emoji. Standard library only. pip install treemark |
| awesome-tools | A directory of 1,026 genuinely free, open-source and free-tier tools, with a searchable static web app. |
| AI Prompt Vault | 162 prompt enhancers across 14 categories. Copy, paste, refine. |
- Never surprise the user. Preview before you act, and make every action undoable. A file mover that deletes something once never earns that trust back.
- Ship the test with the fix. A bug report is a test that hasn't been written down yet.
- Write down the limits. A README that only lists strengths is an advertisement, so the limitations get their own section.
- Small surface, no dependencies where I can manage it β a tool that installs in one line is a tool people actually try.
I'd rather send the fix than file a complaint. Three have been merged, and five more are waiting on review:
| Pull request | Status | Fix |
|---|---|---|
| osmose-qa/osmose-backend#2839 | Merged | TagRemove_Incompatibles rejected aeroway=jet_bridge with highway=footway, a pairing used by about half of those objects |
| osmose-qa/osmose-backend#2838 | Merged | The unexpected-symbol check flagged emoji in free-text tags like description, not just in names |
| petercorke/bdsim#121 | Merged | oodebug wrappers hid the real operator signatures from the generated API docs |
| numpy/numpy-financial#167 | Open | fv sized its output buffer from rate alone, so an integer rate truncated the result and made ipmt/ppmt raise on a 0% loan |
| arsenetar/dupeguru#1431 | Open | Scanning a directory loop (Windows junction / symlink) blew the recursion limit β now walked iteratively with cycle detection |
| mgedmin/dozer#22 | Open | Debug pages were served unauthenticated β added optional HTTP Basic auth with constant-time comparison |
| PyCQA/docformatter#397 | Open | Splitting a multi-sentence summary stranded the rest of it under a stray blank line, glued to the description |
| kuzmoyev/google-calendar-simple-api#212 | Open | A timezone passed alongside timezone-aware datetimes was written into the TZID label without converting them |
# kritagya.py
projects = 6 # the six listed above
merged_upstream = 3 # pull requests other maintainers have accepted
open_upstream = 5 # waiting on review
status = "still learning"
Still learning. If you're stuck on the same thing, say hi.


