- Rust 99.9%
|
Opal Raava
f1d1febc7e
New crate cloned from promptlib with markdown preview support (edit/view toggle via egui_commonmark). DB: always ./projnotes.db in current directory. Includes View menu with font size controls. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| crates | projnotes: add hierarchical project notes egui app | |
| md | bugfixes | |
| .gitignore | projnotes: add hierarchical project notes egui app | |
| Cargo.lock | projnotes: add hierarchical project notes egui app | |
| Cargo.toml | projnotes: add hierarchical project notes egui app | |
| Makefile | projnotes: add hierarchical project notes egui app | |
| README.md | Implement v0.3.0: files, diary, meetings, orgs, data portability | |
todo
A command-line task manager built for people with executive dysfunction.
The core problem: you know what needs doing, but lose track of what you're currently doing and what comes next. todo solves this with explicit focus tracking — you consciously decide what you're working on, and the app helps you stay on track.
How It Helps
statuson startup — immediately shows what you were doing, no decision neededfocusis explicit — you consciously decide what you're working on; prevents driftnextsuggests — when you finish something, the app suggests what to do next based on priority and age- Elapsed time on focus — gentle awareness of time passing, no alarms
focus swap— legitimizes context-switching instead of feeling guilty about it- Notes on tasks and projects — capture thoughts and progress inline so you can resume later
- Routines combat analysis paralysis — break multi-step tasks into a checklist and just do the current step
- Hierarchical projects — break large projects into manageable sub-projects;
task lsshows only the current level, not everything at once - People and organisations — remember who's involved, track meetings, log communication history
- Files and diary — attach documents, store binary files, keep a narrative diary per project or person
- Planned meetings — schedule meetings with attendees, prep files, and done-lifecycle that auto-logs meatspace encounters
- Data portability — export your entire database to JSON, import it back
- Low friction input — tab completion and aliases mean less typing, less friction
Install
Requires a Rust toolchain (1.85+ for edition 2024).
git clone https://codeberg.org/your-user/todo.git
cd todo
cargo build --release
cp target/release/todo ~/.local/bin/
No other system dependencies — SQLite is bundled.
Quick Start
# Add some tasks
todo task add "buy groceries" --priority high
todo task add "clean kitchen"
# Create a project hierarchy
todo project new "work" --parent /
todo project new "backend" --parent /work
todo task add "review PR #42" -p /work/backend
# See what's open
todo task ls
# Start working on something
todo focus add 1
# Or add a task and focus on it in one step
todo start "fix the auth bug" --priority high
# Drop everything else, focus on one thing
todo one "deploy hotfix"
# Check your focus
todo focus
# Done!
todo focus done 1
# What should I do next?
todo next
# Track people and organisations
todo person new "Alice" --last "Johnson" --link
todo org new "Acme Corp" --purpose "Client"
todo person meatspace alice "Had coffee, discussed API redesign"
todo person contact alice phone "Quick call about deploy"
# Schedule a meeting
todo meeting new "Sprint planning" --date 2026年03月01日
todo meeting add "Sprint planning" alice
# Attach files and keep a diary
todo file import notes.md --name "design-notes"
todo diary add "Decided to go with approach B after discussion"
# Export your data
todo export > backup.json
# See the full project tree
todo tree
Two Modes
Direct mode — pass commands as arguments:
todo task add "fix the bug"
todo focus add 3
todo status
todo task ls -p /work/backend
todo person new "Alice" --link
In direct mode, commands default to the inbox project. Use -p <path> to target other projects.
Interactive mode — launch the REPL with no arguments:
$ todo
╭───────────────────────────────────────╮
│ todo v0.3.0 │
│ Tasks: 12 Active: 3 Done today: 2 │
╰───────────────────────────────────────╯
inbox > cd /work/backend
work/backend > task ls
work/backend > person ls
work/backend > cd ..
work > ls
work > quit
The REPL tracks your current project (shown in the prompt), provides tab completion, command history, and shorthand aliases.
Data Storage
By default, data lives at ~/.local/share/todo/todo.db (SQLite). If a ./todo.db exists in the current directory, that one is used instead — useful for per-project task lists.
todo create # creates ./todo.db in current directory
REPL history is saved at ~/.local/share/todo/history.txt.
Commands
Project Management
| Command | Description |
|---|---|
project new "name" |
Create a project under the current project |
project new "name" --parent "/path" |
Create under a specific parent |
project ls [--all] |
List sub-projects, tasks, routines, and people |
project show <name|id|path> |
Show project details, notes, children |
project rename <name|id> "new name" |
Rename a project |
project archive <name|id|path> |
Archive a project and all descendants |
project rm <name|id|path> |
Delete a project (cascades to children/tasks) |
project mv <path> <new-parent-path> |
Move a project subtree to a new parent |
project note <name|id|path> "text" |
Add a timestamped note to a project |
project cd <path> |
Change current project (REPL only) |
Tasks without an explicit --project go into the current project (REPL) or inbox (direct mode). The inbox project cannot be deleted, archived, or renamed.
Path resolution follows filesystem conventions:
/work/backend absolute path (from root)
backend relative path (from current project)
.. parent project
../frontend parent, then into sibling
/ root level
cd (no args) go to inbox
Task Management
| Command | Description |
|---|---|
task add "description" [options] |
Add a new task |
task ls [--all] |
List tasks in current project |
task show <id> |
Show task detail including notes |
task edit <id> ["new description"] |
Edit task description |
task note <id> ["text"] |
Add a note to a task |
task done <id> |
Mark task as complete |
task rm <id> |
Delete a task |
task mv <id> <project-path> |
Move task to a different project |
task priority <id> <high|med|low> |
Set task priority |
Options for task add:
-p, --project "path" Assign to a project (default: current/inbox)
--priority high Set priority: high, med, low (default: med)
--note "details" Attach a note immediately
In the REPL, task edit and task note without inline text enter multiline mode — type your text, then press Enter on a blank line to submit.
Focus Tracking
The focus system tracks what you're actively working on — the heart of the app. Focus is global and works across all projects.
| Command | Description |
|---|---|
focus |
Show currently focused tasks with elapsed time |
focus add <id> |
Start working on a task |
focus drop <id> |
Stop working on a task (back to backlog) |
focus done <id> |
Complete a focused task |
focus clear |
Drop all focused tasks back to backlog |
focus swap <old-id> <new-id> |
Replace one focus item with another |
start "description" [options] |
Add a task and immediately focus on it |
one "description" [options] |
Clear all focus, add a task, focus only on it |
Routines
A routine is an ordered checklist of steps attached to a project. Routines track linear progress — what step you're on, what's been done, what was skipped.
| Command | Description |
|---|---|
routine new "name" |
Create a routine in the current project |
routine ls |
List routines in the current project |
routine show <name|id> |
Show all steps with status |
routine rename <name|id> "new name" |
Rename a routine |
routine rm <name|id> |
Delete a routine |
routine add <name|id> "step text" |
Append a step |
routine add <name|id> "step" --at <pos> |
Insert a step at position |
routine edit <routine> <step-num> "text" |
Edit a step's text |
routine rmstep <routine> <step-num> |
Remove a step |
routine move <routine> <from> <to> |
Move a step to a different position |
routine now <name|id> |
Show the current step |
routine done <name|id> |
Mark current step done and auto-advance |
routine skip <name|id> |
Skip current step and advance |
routine skipped <name|id> |
List all skipped steps |
routine reset <name|id> |
Reset routine to step 1 |
Routines require being inside a project (not at root /).
People
People are global contacts that can be linked to multiple projects. Track who's involved, what they look like, and your communication history.
| Command | Description |
|---|---|
person new <"first"> [options] |
Create a new person |
person ls |
List people linked to current project |
person ls --all |
List all people globally |
person show <name|id> |
Full profile with phones, URLs, diary, meetings |
person edit <name|id> [options] |
Edit person details |
person rm <name|id> |
Delete a person and all their links/logs |
person ln <name|id> [project-path] |
Link person to a project (default: current) |
person unln <name|id> [project-path] |
Unlink person from a project |
person met <name|id> |
Toggle the "met in meatspace" flag |
person meatspace <names> ["notes"] [opts] |
Log an IRL meeting (comma-separated names for groups) |
person contact <names> <type> ["notes"] [opts] |
Log a digital contact (comma-separated for groups) |
person phone add <name|id> "number" [--label] |
Add a phone number |
person phone rm <name|id> <phone-ident> |
Remove a phone number |
person url add <name|id> "url" [--description] |
Add a web URL |
person url rm <name|id> <url-ident> |
Remove a URL |
Options for person new:
--last "name" Last name
--birthday YYYY-MM-DD Birthday
--email "email" Email address
--phone "phone" Phone number
--appearance "description" Physical description
--relationship "desc" Relationship description
--link Auto-link to current project (direct mode)
-p, --project "path" Target project for --link
Options for person edit (in addition to the above):
--function "role" Job function / role
--purpose "why" Why you know them
--address "addr" Physical address
--is-org Mark as organisation
Options for person meatspace / person contact:
--date YYYY-MM-DD Backdate the log entry (default: today)
--location "place" Meeting location (meatspace only)
-p, --project "path" Target project context
Contact types: phone, whatsapp, email, social, game
Group logging: Use comma-separated names to log a meeting or contact with multiple people at once. A shared group ID links the entries.
person meatspace alice,bob,charlie "Team lunch at the cafe"
person contact alice,bob email "Sent project update"
Organisations
Organisations are a filtered view over people with is_organisation set. They share the same underlying data but have dedicated commands.
| Command | Description |
|---|---|
org new "name" [options] |
Create an organisation |
org ls |
List organisations linked to current project |
org show <name|id> |
Show organisation details |
org edit <name|id> [options] |
Edit organisation (--purpose, --address, etc.) |
org rm <name|id> |
Delete an organisation |
org ln <name|id> [project-path] |
Link org to a project |
org unln <name|id> [project-path] |
Unlink org from a project |
Meetings
Planned meetings with attendees, prep files, and a lifecycle that auto-logs meatspace encounters when marked done.
| Command | Description |
|---|---|
meeting new "title" --date YYYY-MM-DD |
Schedule a meeting |
meeting ls [--all] |
List upcoming meetings (--all includes past) |
meeting show <title|id> |
Show meeting details, attendees, files |
meeting edit <title|id> [options] |
Edit meeting title, date, or notes |
meeting rm <title|id> |
Delete a meeting |
meeting add <meeting> <person> |
Add an attendee |
meeting drop <meeting> <person> |
Remove an attendee |
meeting done <meeting> ["notes"] |
Mark done: logs meatspace for all attendees |
meeting file import <meeting> "name" --path file |
Attach a file to a meeting |
meeting file ls <meeting> |
List meeting files |
meeting file cat <meeting> <file> |
View a meeting file |
meeting file rm <meeting> <file> |
Remove a meeting file |
When you mark a meeting done, it automatically creates meatspace log entries for every attendee and sets their met_meatspace flag.
Files
Text files (.md, .json) stored in the database, scoped to projects or people.
| Command | Description |
|---|---|
file ls |
List files in the current project |
file cat <name|id> |
View file contents |
file import "name" --path file.md |
Import a file from disk |
file export <name|id> [--path out.md] |
Export to disk or stdout |
file rm <name|id> |
Delete a file |
file mv <name|id> "new-name" |
Rename a file |
Use --person <name> to scope file commands to a person instead of a project.
Binary Files
Arbitrary files stored as BLOBs in the database. Same scoping as text files.
| Command | Description |
|---|---|
binary ls |
List binary files in the current project |
binary import "name" --path file.pdf |
Import any file from disk |
binary export <name|id> --path out.pdf |
Export to disk |
binary rm <name|id> |
Delete a binary file |
binary mv <name|id> "new-name" |
Rename a binary file |
Use --person <name> to scope binary commands to a person.
Diary
Timestamped narrative entries scoped to projects or people.
| Command | Description |
|---|---|
diary |
Show recent diary entries |
diary add ["text"] [--date YYYY-MM-DD] |
Add a diary entry (multiline in REPL) |
diary ls [--limit N] |
List diary entries |
diary show <id> |
Show a diary entry |
diary rm <id> |
Delete a diary entry |
Use --person <name> to scope diary commands to a person.
Data Portability
| Command | Description |
|---|---|
export [--pretty] [--quiet] |
Export entire database to JSON on stdout |
import [--force] [--quiet] |
Import JSON from stdin (replaces all data) |
# Backup
todo export --pretty > backup.json
# Restore (destructive — replaces everything)
todo import --force < backup.json
Overview
| Command | Description |
|---|---|
status |
Dashboard: focused tasks + open tasks by project |
today |
Meetings today + tasks completed today |
next [n] |
Suggest next tasks to work on (default: 5) |
search "term" |
Search across tasks, people, files, diary, and meetings |
tree |
Show full project hierarchy with task/people counts |
ppl |
Show project tree with linked people names |
create |
Create a local ./todo.db in the current directory |
REPL Aliases
In interactive mode, these shortcuts save keystrokes:
| Alias | Expands to |
|---|---|
p |
project |
t |
task |
f |
focus |
r |
routine |
pp |
person |
o |
org |
mt |
meeting |
fi |
file |
bin |
binary |
di |
diary |
s |
status |
n |
next |
d <id> |
task done <id> |
a "desc" |
task add "desc" |
ls / l / dir |
project ls |
cd <path> |
project cd <path> |
mkdir "name" |
project new "name" |
rmdir "name" |
project rm "name" |
rm <id> |
task rm <id> |
cat <id> |
task show <id> |
mv <id> <prj> |
task mv <id> <project> |
ps |
status |
q |
quit |
REPL-only commands: help, clear, quit/exit/q.
Example Session
$ todo
╭───────────────────────────────────────╮
│ todo v0.3.0 │
│ Tasks: 12 Active: 3 Done today: 2 │
╰───────────────────────────────────────╯
inbox > ls
Sub-projects
(none)
Tasks (4 open)
#1 buy groceries priority: med age: 1d
#2 call dentist priority: high age: 3d
#6 look up train times priority: low age: 2h
#9 file tax return priority: high age: 5d
inbox > cd /work
work > ls
Sub-projects
backend 3 tasks
frontend 1 task
Tasks (2 open)
#14 write quarterly report priority: med age: 1d
#15 book meeting room priority: low age: 4h
Routines
deploy-checklist 8 steps (at step 3)
People (1)
Alice Johnson
work > org new "Acme Corp" --purpose "Client"
Created organisation: Acme Corp (#3)
work > meeting new "Sprint planning" --date 2026年03月01日
Created meeting: Sprint planning (#1)
work > meeting add "Sprint planning" alice
Added Alice to meeting: Sprint planning
work > diary add "Kicked off Q1 planning with the team"
Added diary entry #1
work > person meatspace alice,bob "Sprint planning, discussed API redesign"
Logged meatspace meeting with Alice [work]
Logged meatspace meeting with Bob [work]
work > cd backend
work/backend > a "fix auth bug" --priority high
Added task #19: fix auth bug [work/backend]
work/backend > cd /
/ > tree
Project Tree
inbox 4 tasks
work 2 tasks 2 people
+-- backend 3 tasks
| +-- api 1 task
+-- frontend 1 task
+-- infra 0 tasks
home 5 tasks
+-- garden 2 tasks
hobby 0 tasks
/ > f
Currently Working On
#4 clean fridge home 25m
#7 fix SSH config work/backend 1h 12m
2 active tasks
/ > q
License
MIT