Source. Requires Python but no additional dependencies.
There are lots of todo list/task tracking apps in the world. Probably too many. Unfortunately, they were apparently all written by people with much simpler lives and much more executive function than me, and so I was forced to write another one.
The insight I felt was missing from them was that, once you move past trivial cases, to-do lists aren't lists. Real-world tasks have dependencies. It's more of a todo directed graph.
For example, at the time of writing this page, I'm in the process of legally changing my name. At first glance, this looks like a list of distinct items:
But this is neither a list in the "must be done in this sequence" sense, nor a free-form unordered set of items that can be done in any order. The first three must be done first, in that order, then the rest are kind of mostly independent:
(This is probably wrong in several ways, because this is entirely too complicated. I've already corrected it once after discovering a non-obvious dependency.)
In the early stages, it's pointless to display these all in a list of "things you should do", because many of them are not yet possible. But they should still be tracked somehow, because otherwise you're missing the point of a todo list: to keep track of all the things that you need to do so you don't forget them.
Not all dependency chains are this big, but they still exist in a lot of places. Another pattern that comes up a lot for me is "get quotes for [some house thing I don't want to deal with myself]" followed by "have someone [do the thing]".
I also looked into misusing a ticket tracker as a todo list. To my surprise, many of those don't support dependencies either. Dependencies happen all the time in software development, but bugs having dependencies on each other is less common, and many ticket tracking systems focus on bugs. Regardless, I couldn't find anything that was both lightweight enough to use personally and could handle this use case.
So I wrote this thing. It's a command line tool, usage looks like this:
# add items # item text can be left unquoted; the command's arguments are concatenated together into one item title $ todo add buy ingredients for muffins $ todo add bake muffins $ todo add eat muffins # show items you can do right now $ todo ls t20220220165525 buy ingredients for muffins t20220220165535 bake muffins t20220220165542 eat muffins # add dependencies # anywhere an item is expected in any command, it may be shortened to a suffix of the id, or a # 'a after b' is equivalent to 'b before a' $ todo dep add buy before bake $ todo dep add eat after bake $ todo ls t20220220165525 buy ingredients for muffins # `todo edit` opens an existing task in $EDITOR # `todo add` without arguments does the same for a new task # the first line of the edited file is the title, the rest is a freeform description $ todo edit 5525 5525 => t20220220165525 # `todo ls` has two options, `verbose` (show dependencies and descriptions) and `all` (include tasks that are blocked by other tasks) $ todo ls verbose t20220220165525 buy ingredients for muffins flour, sugar, butter, eggs, milk # show all items $ todo ls all t20220220165525 buy ingredients for muffins t20220220165535 bake muffins t20220220165542 eat muffins # they can be combined: $ todo ls all verbose t20220220165525 buy ingredients for muffins flour, sugar, butter, eggs, milk t20220220165535 bake muffins (depends on t20220220165525 buy ingredients for muffins) t20220220165542 eat muffins (depends on t20220220165535 bake muffins)