TODO lists are a battle-hardened solution for productivity. There are countless applications available which span mobile apps, cloud-based solutions, etc. However, these tend to be far too heavy for my preference as I trend towards minimalist solutions, favoring simplicity over extensive functionality. The short list of requirements for a TODO list include functionality to:

  • Prioritize certain tasks over others
  • Manage separate lists for home and work
  • Attach free-form text to tasks

My solution has evolved from a simple text file to using kanban boards to better track my workflow. Kanban is a simple paradigm popularized in tech for tracking software development projects. Basically, a large physical board is partitioned into multiple lists (e.x., Backlog, TODO, In Progress, Under Review, and Done). Each issue / feature is added as a card, with a brief description, and placed within a single list. Cards are then moved between lists as work progresses. This is a great solution for tracking / prioritizing work within an engineering team.

I have incorporated the kanban philosophy into a script, namely due, within my scripts repository. It uses a collection of text-oriented lists and cards to track various tasks and enables use of multiple boards to segregate domains (e.x., home, work, etc). Internally, each element is stored as JSON enabling arbitrary features to facilitate extensibility. Below is the help menu for the due script:

hamersaw@ragnarok:~$ due help
USAGE: due COMMAND
COMMAND:
    add <ID> [FEATURE...] <DESC>    add an element at the desired location
    board                           list all initialized boards
    cat <ID>                        display note attached to the specified element
    help                            display this help menu
    list                            list all elements
    modify <ID> [FEATURE...]        update options on element
    move <SRCID> <DSTID>            move an element within the same level
    note <ID>                       edit the element note
    remove <ID>                     remove the specified element
    switch <BOARD>                  change the currently active board

FEATURE:
    <KEY>:<VALUE>                   generic key value pair

ID:
    (1-9)(.1-9)*                    dynamic element identifier

To print the entire kanban board we use the list command. Although the current board is empty, every element (i.e., list / card) is assign a dot seperated numerical ID. These are incremental, so they change as the board is modified, and hierarchical so IDs of cards begin with the resident list ID. The script uses these IDs for every functional operation.

hamersaw@ragnarok:~$ due list
LIST  CARD  NOTE  DESCRIPTION

Creating, Moving, and Removing Elements

Operations over lists and cards use the same commands with different IDs. We can add lists to a new board using the add commands below. Note that the ‘in-progress’ and ’todo’ lists are both added as ID 1, when ’todo’ is added there are 2 elements so it is inserted between them. Also descriptions can contain spaces as noted in the ‘under review’ example.

hamersaw@ragnarok:~$ due add 1 in-progress
hamersaw@ragnarok:~$ due add 1 todo
hamersaw@ragnarok:~$ due add 2 'under review'
hamersaw@ragnarok:~$ due list
LIST  CARD  NOTE  DESCRIPTION
1 todo
2 in-progress
3 under review

Now we can start creating cards to reflect our tasks with the add command. This command is used to add both lists and cards, the length of the ID determines which.

hamersaw@ragnarok:~$ due add 2.1 'implement a new feature'
hamersaw@ragnarok:~$ due add 1.1 'take over the world'
hamersaw@ragnarok:~$ due list
LIST  CARD  NOTE  DESCRIPTION
1 todo
      1.1         take over the world
2 in-progress
      2.1         implement a new feature
3 under review

As work progresses on a card we transition it through the kanban lists using the move command. Note that this command can be used to rearrange lists as well.

hamersaw@ragnarok:~$ due move 2.1 3.1
hamersaw@ragnarok:~$ due list
LIST  CARD  NOTE  DESCRIPTION
1 todo
      1.1         take over the world
2 in-progress
3 under review
      3.1         implement a new feature

And upon completion we use remove to remove the card from the board, which can also remove lists from the board.

hamersaw@ragnarok:~$ due remove 3.1
hamersaw@ragnarok:~$ due list
LIST  CARD  NOTE  DESCRIPTION
1 todo
      1.1         take over the world
2 in-progress
3 under review

Modifying Element Features

Internally, each element is stored using a JSON object to track metadata. We provide the modify command to arbitrarily change any field in the metadata. Below we change the description value on the remaining card. This functionality can be used to store arbitrary data as well, though I haven’t found that particularly useful.

hamersaw@ragnarok:~$ due modify 1.1 description:'try and take over the world'
hamersaw@ragnarok:~$ due list
LIST  CARD  NOTE  DESCRIPTION
1 todo
      1.1         try and take over the world
2 in-progress
3 under review

Attaching Notes to Each Card

The script allows each card to be associated with a single, text document of free-form notes in markdown format. I commonly use this to do things like track github issues and PR URLs, describe implementation details, or just brain dump. To create and modify a note we use the note command which spawns an editor (vim by default) and automatically saves the note when closed. An indicator that a note exists for this item is then present.

hamersaw@ragnarok:~$ due note 1.1
hamersaw@ragnarok:~$ due list
LIST  CARD  NOTE  DESCRIPTION
1 todo
      1.1   x     try and take over the world
2 in-progress
3 under review

To quickly view the note we can use cat on the card ID.

hamersaw@ragnarok:~$ due cat 1.1
hello world!

Using Multiple Boards

Due allows using multiple boards to segregate tracking tasks in different domains. I find this is very useful for a work / life balance to help partition my focus. The boards command lists all created boards and switch transitions to a different board, creating it if necessary.

hamersaw@ragnarok:~$ due boards
test
hamersaw@ragnarok:~$ due switch test2

This post is part 3 / 5 of the Script Series:

  1. Introduction
  2. A Script for Managing Dotfiles
  3. Due: A Kanban TODO List Script
  4. Scripting Your UI Color-Palette
  5. Password Management with Stash

5 day(s) offloaded in the 100DaysToOffload challenge.