Search

Todo CLI

A command-line todo manager with file persistence.

Todo CLI

A complete command-line todo application with JSON file persistence, argument parsing, and formatted output.

Code

use process
use fs
use json
use io
const DATA_FILE = "todos.json"
action loadTodos() -> list
if not fs#exists(DATA_FILE)
ret []
fin if
@raw = fs#read(DATA_FILE)
ret json#parse(raw)
.
action saveTodos(@items: list)
fs#write(DATA_FILE, json#stringify(items))
.
action addTodo(@text: str)
@items = loadTodos()
@newItem = {"text": text, "done": false, "created": time#now()}
items#push(newItem)
saveTodos(items)
io#println("Added: " + text)
.
action listTodos()
@items = loadTodos()
if items#length == 0
io#println("No todos yet.")
ret
fin if
for @i = 0 to items#length
@item = items[i]
@status = item#done ? "[x]" : "[ ]"
io#println(status + " " + (i + 1) + ". " + item#text)
fin for
.
action doneTodo(@index: int)
@items = loadTodos()
if index < 1 or index > items#length
io#println("Invalid index.")
ret
fin if
items[index - 1]#done = true
saveTodos(items)
io#println("Marked as done: " + items[index - 1]#text)
.
action main()
@args = process#args()
if args#length < 2
io#println("Usage: todo <add|list|done> [text|index]")
ret
fin if
@command = args[1]
if command == "add" and args#length > 2
addTodo(args[2])
elif command == "list"
listTodos()
elif command == "done" and args#length > 2
doneTodo(process#toInt(args[2]))
else
io#println("Usage: todo <add|list|done> [text|index]")
fin if
.

Usage

Terminal window
# Add a todo
draft run main.draft add "Write Draft tutorial"
# List todos
draft run main.draft list
# Mark as done
draft run main.draft done 1

Build a Binary

Terminal window
draft build -o todo
./todo add "Ship the release"
./todo list

Expected Output

$ ./todo add "Ship the release"
Added: Ship the release
$ ./todo list
[ ] 1. Ship the release