⚠️ Work in Progress: Cloodoo is under active development. Features and APIs may change.
A personal TODO system with a terminal UI, real-time multi-device sync, an Android companion app, a browser extension for capturing tasks from email, and a GNOME Shell extension for screenshot-based TODOs.
Written in Common Lisp. Built on SQLite with temporal versioning, gRPC bidirectional streaming with mTLS, and optional LLM enrichment.
- Terminal UI with vim-style navigation, mouse support, inline editing, tag sidebar, and calendar date picker
- Real-time sync across devices via gRPC bidirectional streaming with mutual TLS authentication
- Android app (Jetpack Compose, Material 3) with offline sync queue, QR code pairing, and background reconnect
- Browser extension (Manifest V3) that extracts TODO context from Gmail, Outlook, Yahoo Mail, ProtonMail, and Zoho Mail
- GNOME Shell extension for capturing screenshots as TODOs with
Super+Shift+T-- uses content-addressed storage for deduplication - AI enrichment via Gemini, OpenAI, Anthropic, or local Ollama -- auto-fills descriptions, tags, priorities, and time estimates
- REST API for programmatic access and the browser extension
- Certificate management with a built-in CA, device pairing via QR codes, and certificate revocation
- Temporal database -- every change creates a new version; nothing is overwritten
- Org-mode import -- bring tasks in from Emacs
- Org-agenda export -- export to text or PDF in org-mode agenda format with priority markers, overdue indicators, and statistics
Requires SBCL and ocicl for Common Lisp dependencies.
git clone https://github.com/atgreen/cloodoo.git
cd cloodoo
ocicl install
makeThis produces a cloodoo executable in the project root.
Launch the TUI:
./cloodooAdd a task from the command line:
./cloodoo add "Buy groceries" --priority high --due 2026-02-01 --tag errandsList tasks:
./cloodoo list
./cloodoo list --status pending --priority highMark a task done:
./cloodoo done groceriesCloodoo can run in two ways: standalone on a single machine, or with a sync server that keeps multiple devices in sync.
Just run ./cloodoo. It stores your tasks in a local SQLite database
and that's it -- no server, no network, no setup. The TUI, the CLI
commands, and the browser extension all read and write the same local
database.
This is the default. If you only use one computer and don't need your tasks on your phone, standalone mode is all you need.
If you want your tasks on more than one device, you run a sync server.
The sync server is just another cloodoo command:
./cloodoo cert init # create a certificate authority (once)
./cloodoo sync-server # start the sync serverThe sync server uses gRPC with mutual TLS, so every device needs a
certificate. You issue one with ./cloodoo cert issue my-phone,
which prints a QR code the other device can scan.
Once the sync server is running:
- The TUI on other machines can connect to it. If a machine has been paired, the TUI connects automatically on startup.
- The Android app connects to the sync server after scanning the QR code. It keeps a local copy of your tasks and syncs changes in real time. If you're offline, changes queue up and sync when you reconnect.
- Changes made on any device are broadcast to all other connected devices immediately.
The browser extension works by talking to the cloodoo executable on
your machine through the browser's native messaging protocol -- it
does not make network connections to any server. When you capture a
task from an email, the extension sends it to the local cloodoo
process, which writes it to your local database.
This means the extension works the same way regardless of whether you are running a sync server or not:
- Without a sync server: the task goes into your local database and shows up in your TUI.
- With a sync server: the task goes into your local database and is pushed directly to the sync server, so it reaches your other devices immediately.
If native messaging isn't set up yet (you haven't run
./cloodoo setup-extension), the extension queues tasks locally in
the browser and retries periodically until the native host is
available.
Press ? in the TUI for the full help overlay.
| Key | Action |
|---|---|
j / k / Arrow keys |
Move down / up |
g / G |
Jump to first / last item |
PgUp / PgDn |
Page up / down |
Enter |
View details |
Esc |
Go back / cancel |
| Key | Action |
|---|---|
a |
Add task |
e |
Edit task |
Space |
Cycle status (pending / in-progress / completed / waiting / cancelled) |
Del / d |
Delete task |
D |
Delete all completed |
| Key | Action |
|---|---|
Shift+Up / Shift+Down |
Increase / decrease priority |
B / C |
Set priority to medium / low |
S |
Set scheduled date |
L |
Set due date |
t |
Edit tags |
| Key | Action |
|---|---|
/ |
Search |
f |
Cycle status filter |
s |
Cycle sort order (priority / due date / created / title) |
c |
Clear filters |
l |
Toggle tag sidebar |
r |
Refresh from database |
| Key | Action |
|---|---|
h / j / k / l |
Navigate calendar |
[ / ] |
Previous / next month |
{ / } |
Previous / next year |
Home |
Jump to today |
Del |
Clear date |
Enter |
Confirm |
| Key | Action |
|---|---|
Tab |
Focus sidebar |
j / k |
Navigate tags |
Space |
Toggle tag filter |
a |
Select all tags |
1-9, 0 |
Preset tag combinations |
| Key | Action |
|---|---|
& |
Re-run AI enrichment |
u |
Edit user context ($EDITOR) |
i |
Import org-mode file |
? |
Help |
q |
Quit |
cloodoo Launch the TUI
cloodoo add TITLE Add a task (--priority, --due, --schedule, --tag, --note, --attachment)
cloodoo list List tasks (--status, --priority, --all)
cloodoo done SEARCH Mark a task completed
cloodoo stats Show counts and overdue tasks
cloodoo export Export tasks in org-agenda format (text or PDF)
cloodoo sync-server Start gRPC sync server (default 0.0.0.0:50051)
cloodoo sync-connect Connect TUI to a remote sync server
cloodoo sync-reset Force a full resync across all connected devices
cloodoo sync-upload-attachments Upload all local attachments to the sync server
cloodoo cert init Initialize certificate authority
cloodoo cert issue NAME Issue client certificate (shows QR code)
cloodoo cert list List issued certificates
cloodoo cert revoke NAME Revoke a certificate
cloodoo enrich-pending Process tasks awaiting AI enrichment
cloodoo dump Export database as SQL
cloodoo compact Remove old row versions
cloodoo native-host Handle browser native messaging
cloodoo setup-extension Set up browser extension (Chrome, Chromium, Firefox)
Cloodoo syncs in real time over gRPC with mutual TLS.
./cloodoo cert init./cloodoo sync-serverListens on port 50051 with mTLS by default.
On the server, issue a certificate and show a QR code:
./cloodoo cert issue my-phoneOn the Android app, scan the QR code or enter the pairing URL and passphrase. The app stores the client certificate and connects automatically on future launches.
The TUI also auto-connects on startup if a paired config exists.
./cloodoo cert list
./cloodoo cert revoke my-old-laptopThe companion app lives in android/. Standard Gradle project using
Jetpack Compose, Room, and gRPC.
cd android
./gradlew assembleDebug- Material Design 3 UI with todo list, priority badges, and due dates
- Speed dial FAB with voice input (on-device speech-to-text) and form-based task creation
- QR code scanning for device pairing (ML Kit)
- Offline sync queue -- changes made while disconnected are sent on reconnect
- Minimum SDK 26 (Android 8.0)
The extension lives in browser-extension/. Supports Chrome and Firefox
(Manifest V3).
- Load as an unpacked extension from the
browser-extension/directory - Install the native messaging host:
./cloodoo setup-extension
- Gmail -- including a toolbar quick-add button
- Outlook (live.com, office.com, office365.com)
- Yahoo Mail
- ProtonMail
- Zoho Mail
The extension extracts email subject, sender, date, and body snippet to pre-fill the TODO form. Tasks can be created even when offline and will sync when the native host becomes available.
The GNOME extension lives in gnome-extension/. Allows capturing
screenshots as TODOs with attached images.
make install-gnome-extensionOr manually:
cd gnome-extension
glib-compile-schemas schemas/
mkdir -p ~/.local/share/gnome-shell/extensions/cloodoo-screenshot@moxielogic.com
cp -r * ~/.local/share/gnome-shell/extensions/cloodoo-screenshot@moxielogic.com/
gnome-extensions enable cloodoo-screenshot@moxielogic.comThen restart GNOME Shell (Alt+F2, type r, Enter on X11; log out/in on
Wayland).
- Press
Super+Shift+T - Select an area with the crosshair cursor
- Enter title, priority, and tags in the dialog
- The TODO is created with the screenshot attached
Screenshots are stored using content-addressed storage (SHA256 hashing)
and deduplicated automatically. Requires gnome-screenshot and
zenity.
Set one of these environment variables (or add to .env):
| Provider | Variable | Default model |
|---|---|---|
| Gemini | GEMINI_API_KEY |
gemini-2.0-flash |
| OpenAI | OPENAI_API_KEY |
gpt-4o-mini |
| Anthropic | ANTHROPIC_API_KEY |
claude-sonnet-4-20250514 |
| Ollama | (none -- local) | llama3.2:latest |
Enrichment runs automatically for new tasks or on demand with & in
the TUI. You can also process the queue from the CLI:
./cloodoo enrich-pendingPress u in the TUI to edit a user context file
(~/.config/cloodoo/user-context.md) that gives the LLM background
about you -- location, work context, preferences -- so enrichment
results are more relevant.
Cloodoo can export your tasks in org-agenda style (similar to Emacs org-mode agenda views), either as formatted text or PDF:
# Export to text file
./cloodoo export -o agenda.txt
# Export to PDF (requires pandoc, wkhtmltopdf, or enscript)
./cloodoo export --pdf -o agenda.pdf
# Group by tags instead of by date
./cloodoo export --by-tag -o by-tag.txt
# Filter by status or priority
./cloodoo export --status pending --priority high -o urgent.txt
# Include completed tasks (hidden by default)
./cloodoo export --all -o full-agenda.txtThe output format includes:
- Week header with ISO week numbers (e.g.,
Week-agenda (W05-W06):) - Tasks grouped by scheduled/due date or by tags
- Overdue indicators showing days late (e.g.,
Sched.232x:means 232 days overdue) - Priority markers:
[#A](high),[#B](medium),[#C](low) - Status keywords: TODO, DOING, DONE, WAITING, CANCELLED
- Footer statistics: total count, completed count, overdue count
PDF generation requires one of:
pandocwithpdflatex(most common)wkhtmltopdf(produces formatted HTML-style PDFs)enscriptwithps2pdf(plain text to PostScript to PDF)
If no PDF converter is available, the command falls back to text export automatically.
Cloodoo follows the XDG Base Directory spec:
| Directory | Contents |
|---|---|
~/.local/share/cloodoo/ |
SQLite database, certificates, blobs |
~/.config/cloodoo/ |
config.lisp, user-context.md, sync pairing |
~/.cache/cloodoo/ |
Temporary files |
SQLite with temporal versioning. Every update creates a new row with a
valid_from timestamp; the previous row gets a valid_to. Current
state is always WHERE valid_to IS NULL.
./cloodoo dump # Export as SQL
./cloodoo compact # Remove old versions to reclaim space
./cloodoo stats # Counts, overdue tasks, prioritiesMIT -- Copyright (C) 2026 Anthony Green