A spiffy ratatui TUI calendar — local SQLite with Google Calendar sync and DAG-linked events.
# Build and run cargo build --release ./target/release/solverforge-calendar # Or run directly cargo run- Multiple views - Month, week, day, and agenda views with vim-style navigation
- Google Calendar sync - Incremental two-way sync with OAuth (tokens in OS keyring)
- Event dependencies - DAG-linked events with cycle detection and topological ordering
- Recurring events - Full RFC 5545 RRULE support (daily, weekly, monthly, custom)
- Non-blocking I/O - Background workers for all DB and API operations
- Local SQLite database - Events, calendars, projects stored in
~/.local/share/solverforge/calendar.db - iCal import/export - Standard
.icssupport - Desktop notifications - Reminder alerts via libnotify
- SolverForge theme - Reads hackerman palette from
colors.toml
Ctrl+c/q- Quit1- Month view2- Week view3- Day view4- Agenda view?- HelpG/S- Google Calendar sync
h/j/k/l- Move left/down/up/rightH/L- Previous/next monthTab- Toggle sidebar focusSpace- Toggle calendar visibility
c- Create evente- Edit selected eventd- Delete selected eventEnter- Open event details
a- Quick add event (command-line style)
- Press
Gto open the Google Auth flow - Follow the OAuth browser prompt
- Tokens are stored in the OS keyring (
solverforge-calendarservice) - Press
Sto sync at any time — incremental sync via Google's sync tokens
- TEA pattern - The Elm Architecture (Model, Update, View)
- Async worker pool - Background threads for all DB and Google API calls
- Channel-based IPC - mpsc for worker result passing
- Event DAG - Directed acyclic graph for event dependencies with BFS cycle detection
- Theme support - Reads SolverForge
colors.toml
- 29 files, 5181 lines of Rust
- 11.6MB release binary
cargo build # debug cargo build --release # optimized cargo check # fast type check cargo clippy # lint cargo test # run testssolverforge-calendar/ └── src/ ├── main.rs # Entry point, terminal setup, event loop ├── app.rs # TEA state machine, all application state ├── keys.rs # (View, KeyEvent) → Action dispatch ├── worker.rs # Background thread pool, WorkerResult enum ├── event.rs # Crossterm event handling ├── models.rs # Calendar, Event, Project, EventDependency structs ├── db.rs # SQLite CRUD, schema migrations ├── dag.rs # EventDag — dependency graph with cycle detection ├── theme.rs # SolverForge color theme loader ├── recurrence.rs # RecurrencePreset, RFC 5545 RRULE helpers ├── notifications.rs # Background reminder task, libnotify ├── ical.rs # iCal import/export ├── google/ │ ├── auth.rs # OAuth via OS keyring │ ├── sync.rs # Incremental Google Calendar API sync │ └── types.rs # Google JSON → local Event conversion └── ui/ ├── month_view.rs # 5-week calendar grid ├── week_view.rs # Hourly time grid ├── day_view.rs # Single-day agenda ├── agenda_view.rs # Sorted upcoming events list ├── event_form.rs # Modal create/edit form ├── calendar_list.rs # Sidebar with visibility toggles ├── quick_add.rs # Command-line-style event entry ├── status_bar.rs # Keybinding hints + status messages ├── help.rs # Scrollable help overlay ├── google_auth.rs # OAuth flow UI └── util.rs # Shared rendering helpers 