A TODO juggler TUI application built with Ratatui that displays and manages TODO items from TOML files. Features a terminal user interface for managing tasks with due dates, comments, and Google Tasks synchronization.
- Terminal User Interface: Navigate and manage TODOs with keyboard shortcuts
- TOML Storage: TODOs stored in human-readable TOML format with metadata, stable IDs, comments, and due dates
- Due Date Support: Automatic sorting with overdue items highlighted
- External Editor Integration: Edit TODOs in your preferred editor (via
$VISUAL/$EDITOR) - Google Tasks Sync (Bare Bones): Manual setup flow; see
docs/google-tasks-sync.md - Completion Tracking: Mark items as done/undone
- Snooze/Prepone: Quickly adjust due dates by ±1 day or ±7 days, plus custom delays
brew install scode/dist-tap/juggler- Install Rust using rustup.
- From the repository root, run:
cargo install --path .-
Run the TUI:
juggler
-
Optional: Google Tasks sync is currently very bare bones and requires manual setup. See
docs/google-tasks-sync.md.
Launch the interactive TUI (default behavior):
cargo run
# or
./target/release/jugglerKeyboard Shortcuts:
j/k- Move cursor down/upo- Toggle expand/collapse on the cursored itemx- Select/deselect the cursored iteme- Toggle done on selected items; if none selected, acts on the cursored itemE- Edit the cursored item in external editor ($VISUAL/$EDITOR, supports args)s- Snooze selected items by 1 day; if none selected, snooze the cursored itemS- Unsnooze (minus 1 day) for selected items; if none selected, unsnooze the cursored itemp- Snooze by 7 days for selected items; if none selected, snooze the cursored itemP- Prepone by 7 days for selected items; if none selected, prepone the cursored itemt- Custom delay prompt (e.g., 5d, -2h)q- Quit and saveQ- Quit, save, and sync to Google Tasks (sync is skipped if local save fails or sync preconditions are missing)
Note: Actions operate on all selected items. If no items are selected, they apply to the item under the cursor.
View available commands:
juggler --help
juggler login --help
juggler logout --help
juggler sync google-tasks --helpAvailable commands:
juggler- Launch interactive TUI modejuggler login- Browser-based OAuth authenticationjuggler sync google-tasks- Sync TODOs with Google Tasksjuggler logout- Remove the stored refresh token (idempotent if no token is stored)
Login options:
--port <PORT>: Local callback port (default: 8080)
Sync options:
--dry-run: Log actions without executing them (safe testing mode)--debug-auth: Print keychain diagnostics for authentication
Global options:
--juggler-dir <DIR>: Override the juggler data directory for this invocation--google-oauth-client-id <ID>: Google OAuth desktop client id (required forloginandsyncunlessGOOGLE_OAUTH_CLIENT_IDis set; ignored bylogout)--google-oauth-client-secret <SECRET>: Google OAuth desktop client secret (required forloginandsyncunlessGOOGLE_OAUTH_CLIENT_SECRETis set; ignored bylogout)
Environment variables:
JUGGLER_DIR: Override the juggler data directory when--juggler-diris not providedGOOGLE_OAUTH_CLIENT_ID: Fallback for--google-oauth-client-idinlogin/sync/TUI sync-on-exit flowsGOOGLE_OAUTH_CLIENT_SECRET: Fallback for--google-oauth-client-secretinlogin/sync/TUI sync-on-exit flows- Precedence:
--juggler-dirtakes precedence overJUGGLER_DIR - Precedence:
--google-oauth-client-idand--google-oauth-client-secrettake precedence over their environment-variable fallbacks
Synchronization to Google Tasks is currently very bare bones and requires manual setup. See docs/google-tasks-sync.md.
By default, TODOs are stored at ~/.juggler/TODOs.toml. You can override the directory with --juggler-dir <DIR> or JUGGLER_DIR (with --juggler-dir taking precedence). Each save creates a timestamped backup of the previous file in the same directory (e.g., TODOs_2025-01-07T09-00-00.toml).
[metadata]
format_version = 1
juggler_edition = 1
[todos.T1]
title = "Buy groceries"
comment = """- Milk
- Bread
- Eggs"""
done = false
due_date = "2025-01-07T09:00:00Z" # ISO 8601 format
google_task_id = "task_abc123" # Set after sync
[todos.T2]
title = "Completed task"
done = trueCopyright (c) Peter Schuller peter.schuller@infidyne.com
This project is licensed under the MIT license (LICENSE or http://opensource.org/licenses/MIT)
