Todo MD puts a plain markdown checkbox file in the panel menu, so the list stays readable in any editor and on any device. Tasks live in a single file — ~/todo.md by default, or any path set in the preferences. Features: * ## Category sections become colored tabs; each category header has a ⋮ action menu (also on right-click) offering add task, change color, rename and delete * Check, uncheck, edit inline and delete tasks; reorder them inside their category by dragging the handle at the end of a row, or with Alt+Up / Alt+Down on a focused row * Fixed menu width and a configurable maximum height; the tab bar and the list keep their scroll position * Edits made outside the shell are picked up live by a file monitor * Preferences: todo file path, menu width, maximum menu height, category colors Compatibility: GNOME Shell 46, 47, 48, 49 and 50, each verified by a manual regression run (Ubuntu 24.04, 24.10, 25.04, 25.10 and 26.04). File access: the extension only reads and writes the markdown todo file you configure (~/todo.md by default), plus its own GSettings. No network requests, no subprocesses, no clipboard use. Shell integration: like most panel extensions, this one builds on GNOME Shell's own internal JavaScript modules (panel menu, popup menu, drag-and-drop) and on St/Clutter — they are not a stable public API, which is why shell-version lists only the releases this code has actually been tested on.
Note: Binary files aren't shown on the web site. To see all files, please download the extension zipfile.
EGO-X-004 warning
extensions should avoid synchronous file IO in shell code
Shell code should avoid synchronous file IO APIs like `GLib.file_get_contents()` and `Gio.File.load_contents()`.
storage.js:434
file.load_contents(null)
EGO-L-002 warning
objects created by extension should be destroyed in disable()
Objects assigned in `enable()` are missing matching `.destroy()` calls in `disable()` or its helper methods.
extension.js:309
this._contentSection = new PopupMenu.PopupMenuSection()
EGO-L-003 warning
signals connected by extension should be disconnected in disable()
Signals assigned in `enable()` are missing matching disconnect calls in `disable()` or its helper methods.
extension.js:400
this._tabBar.newCategoryButton.connect('clicked', () => {
this._cancelEditing();
this._addingNewCategory = !this._addingNewCategory;
this._refreshTodoMenu();
})
| Version | Status |
|---|---|
| 0.20.1 (2) | Unreviewed |
| 0.15.0 (1) | Unreviewed |
Version 0.20.1 supersedes 0.15.0 — please review this one instead. It contains the fixes for everything reported so far, plus drag-and-drop reordering. The notes on this upload describe what changed.