At a glance: that function is way too long and deeply nested. Three levels of loop/branch nesting is, in my experience, the most that any function should have; and the more nested it is the shorter it should be. 

Consider extracting branch and loop bodies to separate named functions.

----------

Your code structure also seems to be “determine what command to execute” (add / list / etc), then “execute said command”. I’d make this explicit, have the regexp parsing of an input line in a separate function that returns the command type and parameters. Dispatching this would be a natural use for `match` over your own Command type. (That said, in a realistic CLI you might need the commands available to be extensible so don’t get too married to this pattern.)