Repository navigation
Releases: Lyellr88/sidenote
Release list
Sidenote 1.4.1
Sidenote 1.4.0
A way to make the text bigger.
Text zoom
Ctrl+ (or Ctrl+=) grows the list and entry text, Ctrl- shrinks it, one point at a time between 7pt and 20pt. Works whether the entry field or the list has focus. It resets to the default next time you start it, the same way a width you drag stays for the session but not beyond it.
Upgrade
sidenote upgradeSidenote 1.3.2
Internal only - no user-facing changes.
Lint
The project had no ruff configuration, so it ran with essentially every rule category ruff ships, including ones aimed at async libraries and web-security auditing that don't fit a synchronous Windows desktop app. pyproject.toml now selects a standard baseline for this codebase, and every finding under it was checked by hand rather than pattern-matched away: broad except Exception clauses were narrowed to the real exception type where one exists, and left broad with an explanation where they're deliberately catching arbitrary callback code on a background thread.
CI now runs ruff check . before the test suite on every push to master, so a regression here fails the build.
Upgrade
sidenote upgradeSidenote 1.3.1
Internal only - no user-facing changes.
Refactor
terminal_overlay.py held the whole overlay in one ~1050-line class. It's now split into overlay_ui.py, overlay_positioning.py, overlay_tabs.py, overlay_todos.py, and overlay_theme.py, with terminal_overlay.py down to 206 lines of setup and lifecycle code. Every method moved verbatim into a mixin class - none were rewritten to make the split.
This release also doubles as the first real test of the project's new CI pipeline: both the test and publish jobs ran and passed on a genuinely new version, publishing this to PyPI on their own.
Upgrade
sidenote upgradeSidenote 1.3.0
Edit a todo without retyping it, and the project now ships with real test coverage for the overlay and a CI pipeline behind it.
Edit a todo
Select a todo and press Enter. Change the text and press Enter again to save, or Escape to leave it as it was. It reuses the same entry field tab naming already does, so nothing new to learn.
Test coverage and CI
The tkinter overlay had no automated coverage until now - every check during development was a one-off script. tests/test_overlay_smoke.py instantiates the real overlay headlessly and drives its actual methods: tabs, drag-reorder, undo, editing, and the header-overlap regression that a 5-tab switcher can cause next to the title.
A GitHub Actions workflow runs that suite on every push to master and publishes to PyPI on success.
Upgrade
sidenote upgradeSidenote 1.2.2
A fix for sidenote upgrade itself, and a keyboard shortcut for the tab-delete confirmation added in 1.2.1.
Upgrade fix
sidenote upgrade could report success without installing anything. Its pip call trusted a stale local cache instead of checking PyPI, so right after a release it would print "Requirement already satisfied" for every package and call that a completed upgrade. It now runs with --no-cache-dir, and so do the manual commands it prints when something goes wrong.
Tab deletion
The confirmation popup's keyboard Delete key now confirms the deletion, the same as clicking its Delete button. Escape already cancelled it; this makes Delete the matching shortcut.
Upgrade
sidenote upgradeSidenote 1.2.1
A way to delete a tab, with a confirmation step so a stray click can't take one out.
Deleting a tab
A small × shows up next to the tab name in the footer once you have a second tab. Clicking it opens a small popup naming the tab and how many todos go with it, with Cancel and Delete buttons; Escape also cancels. The popup matches the overlay's own dark styling and sits next to the button rather than opening a separate OS dialog. You can't delete the last tab that's left.
Upgrade
sidenote upgradeSidenote 1.2.0
Tabs, drag to reorder, and undo for deletes.
Tabs
Up to 5 separate lists. Click + in the top-left to add one; the entry field switches to naming mode, so type a name and press Enter. Numbered buttons next to + switch between them once a second tab exists. Double-click a tab's name in the footer to rename it.
Existing todos become the first tab automatically. Nothing to migrate by hand.
Reordering and undo
Press and drag a todo to move it up or down. Ctrl+Z restores the list to how it looked before your last delete, whether that was a single todo or everything Ctrl+Delete just cleared.
Header and footer
- takes the header's top-left spot; ? moves to sit next to the lock button on the right. The footer now shows the current tab's name on the left and the open/done count on the right, instead of a single centred line. Locking and unlocking no longer print text to the footer; the lock icon already shows the state.
Upgrade
sidenote upgradeYour todos file gains a tabs structure the first time it loads under this version, and the old flat list becomes tab one. If you ever downgrade, older versions read the file's todos list directly, which no longer exists at the top level, so they won't see any of your todos. Back up ~/.terminal_todos.json first if that matters to you.
Sidenote 1.1.2
Everything since the v1.0.0 tag, which carried version 1.0.1. This is one round of interface work plus the bugs it turned up.
Copying and resizing
Right-click a todo to put its text on the clipboard. The row fades from teal back to its normal colour to confirm. You get the text by itself, without the checkbox and timestamp that the list draws in front of it.
Drag the overlay's edge to widen it for longer notes. Earlier versions recalculated the width on every terminal focus, move, and resize event, so a widened overlay snapped back to 280px almost immediately. It now keeps the width you set until you restart it. Height still tracks your terminal so the two stay flush.
Quieter interface
The header centres the name Sidenote between the help and lock buttons. Both buttons work as before.
The window title is empty, so the taskbar and Alt+Tab no longer read "Quick Todos".
The list has no scrollbar. The wheel and arrow keys scroll it as before.
The white border around the list is gone. It was a one pixel focus ring drawn in SystemButtonFace, and it appeared whenever the list lost focus.
Selection is a dark grey one shade off the list background, replacing the bright blue that filled the entire row.
Fixes
The copy fade did not appear on a row that was already selected, and completed todos lost their grey while selected. Tk draws the selected row from selectforeground and ignores the per-item foreground, so both colours now set each.
The PATH repair snippet in DOCS.md had three PowerShell statements on one line. PowerShell read the last two as arguments to python, so SetEnvironmentVariable never ran and nothing reported an error. Anyone who ran it to fix a missing sidenote command would have seen no output and assumed it worked.
The FAQ said the overlay could not be resized. It can.
Upgrade
sidenote upgradeYour todos live outside the package at ~/.terminal_todos.json, and pip does not touch them.
Sidenote v1.0.0 - Zero-Friction Todo for Your Terminal
Sidenote v1.0.0 – Zero-Friction Todo for Your Terminal
I kept losing tasks in the 3 seconds it took to open Notepad. That's why this exists.
The Problem
You're coding. A task pops into your head. You Alt+Tab to write it down. By the time you find Notepad, it's gone.
If you have ADHD, you know exactly what I'm talking about. That 2-second context switch is long enough for your working memory to dump everything. I tried every solution: Notepad (too many clicks), terminal todo apps (have to run a command first), PowerShell scratchpad (switch focus, lose context). They all added friction. Friction kills capture.
The Solution
A todo list that's already on screen, attached to your terminal window. Press Shift+Tab, type, press Enter. Three seconds, zero context loss. Done.
What It Does
Terminal integration. The overlay sits flush against the right edge of your terminal, pixel-aligned. It follows when you move the window and hides while you drag.
Smart z-order. Click the terminal and the todo comes forward with it automatically. No need to click twice.
Global hotkey. Shift+Tab toggles it from anywhere: your terminal, VS Code, a browser, whatever.
Check things off. Double-click a todo to mark it done. It grays out with a [x]. Press Ctrl+Delete to clear everything you've finished.
Lock button. Working with multiple terminals? Lock the overlay to one specific window so it stops following the others.
Built-in help. The ? button shows every keyboard shortcut. Nothing to memorize, nothing to look up.
Persistent storage. Todos save atomically (temp file + rename), so crashes can't corrupt your data. Everything survives reboots.
Event-driven. Uses Windows event hooks instead of polling. It reacts instantly and costs ~0% CPU when idle.
Dark theme. Minimal black interface that matches your terminal. No visual clutter.
Technical Details (For the Curious)
This started as a working prototype, then got a serious polish pass to fix the rough edges:
Thread safety. The original version called Tkinter widgets directly from background threads, which caused random hangs. Now all UI updates go through a work queue. The background threads compute state, the main thread applies it. No more crashes.
PID-based termination. The first version killed every Python process on your machine when you ran sidenote stop. Bad idea if you had a Flask server or Jupyter notebook running. Now it reads the PID from the lockfile and kills only that process.
Real terminal detection. The prototype matched window titles, so a Chrome tab called "PowerShell docs" would trigger it. Now it uses GetWindowThreadProcessId() to check the actual executable name (powershell.exe, WindowsTerminal.exe, etc.).
Stale lock recovery. If the process crashed, the old version left a lockfile behind and refused to start again. Now it checks whether the PID in the lockfile is alive and reclaims it if not.
DPI awareness. The overlay calculates frame extents correctly on multi-monitor setups with different DPI scaling. It matches the terminal's height exactly, no gaps or misalignment.
Atomic saves. Writes go to a temp file first, then rename over the real file. An interrupted save can't corrupt your todo list.
Test coverage. The package includes tests for storage (atomic writes, migration, corruption handling), lockfile behavior (PID liveness, reuse safety), terminal detection, and CLI commands.
Install
pip install sidenote
sidenote init # Optional: adds start-note/stop-note shortcuts
sidenote # StartPress Shift+Tab to toggle. You're done.
Commands
sidenote # Start the overlay
sidenote stop # Stop it (kills only this process)
sidenote status # Check if running, show PID
sidenote version # Show version, Python version, install path
sidenote upgrade # Update to the latest releaseWhy This Exists
Most todo apps are built for organized people who want better organization. This is for ADHD brains that need to catch thoughts before they evaporate. The 3-second working memory window is real. By the time you open an app, switch a tab, or run a command, the thought is already gone.
This tool exists because I got tired of losing tasks to context switches. Sometimes the best tools are the ones you build yourself.
Repo: https://github.com/Lyellr88/sidenote
License: MIT
Platform: Windows 10/11, Python 3.7+