Blocker pulls your macOS calendar into a beautiful terminal UI. Create work blocks, dismiss noise, resize and move tasks — plan your entire day without leaving the keyboard.
◆ blocker [ Monday, February 17 ] 10:15 AM ALL DAY Presidents' Day 08:00 · · · · · · · · · · · · · · · · · 08:15 · · · · · · · · · · · · · · · · · 08:30 · · · · · · · · · · · · · · · · · 08:45 · · · · · · · · · · · · · · · · · 09:00 Write API proposal 9:00 – 10:00am 09:15 09:30 09:45 › 10:00 Team standup 10:00 – 10:30am 10:15 10:30 · · · · · · · · · · · · · · · · · 10:45 · · · · · · · · · · · · · · · · · 11:00 ✓ Draft release notes 11:00 – 11:30am 11:15 j/k navigate · [ ] day · enter block · d dismiss · c complete · m move · q quit
Pulls events from macOS Calendar via icalBuddy. See your real schedule — meetings, all-day events, and time blocks — right in the terminal.
Vim-style navigation, single-key actions, and modal editing. Create, move, resize, complete, and dismiss blocks without touching the mouse.
Work blocks and dismissed events are saved to ~/.blocker/ as simple JSON files, one per day. No database, no cloud, no accounts.
Install icalBuddy, build the binary, and run. No config files, no setup wizard. Blocker works out of the box with sensible defaults.
Everything you need to turn a wall of calendar events into a focused plan of attack.
Your day is rendered as 15-minute slots from 8 AM to 6 PM. Calendar events and work blocks fill the grid, while empty slots show dot leaders for clean visual texture. Day bounds automatically expand to fit early or late events.
08:00 · · · · · · · · · 08:15 · · · · · · · · · 08:30 Deep work session 08:45 09:00 09:15 09:30 Design review 09:45
Press enter on an empty slot to create a work block. Type a label and confirm. Blocks start at one slot and can be extended with J/K to resize.
Press d to dismiss noisy calendar events you don't need to see. Press c to mark work blocks as completed. Both states persist across sessions.
Press m to enter move mode. Use j/k to slide the block up or down. Collision detection prevents overlaps. Press enter to confirm or esc to cancel.
Press [ and ] to move between days. State is automatically saved when you leave a day and loaded when you arrive. Press g to jump back to today.
Calendar events refresh every 5 minutes when viewing today. Your work blocks and dismissals are preserved across refreshes. Press r to refresh manually.
A yellow arrow in the gutter marks the current time slot. On launch, the cursor jumps directly to "now" so you always start where you are in the day.
All-day calendar events are displayed in a purple banner above the time grid. Holidays, PTO, and multi-day events stay visible without cluttering the timeline.
Moving or resizing blocks into occupied slots is blocked automatically. No accidental overlaps, no broken layouts. The grid stays clean.
Calendar events and work blocks live side by side. Each has its own color and behavior.
Fetched from macOS Calendar via icalBuddy. Displayed in cyan. Can be dismissed but not edited or moved — they reflect your real calendar.
10:00 Team standup 10:00 – 10:30am 10:15
Created by you to plan focused work. Displayed in green. Fully editable — move, resize, complete, or delete them freely.
09:00 Write API proposal 9:00 – 10:00am 09:15 09:30 09:45
Vim-style bindings with modal editing. Normal, Creating, and Moving modes keep context clear.
Blocker reads your calendar through icalBuddy, a macOS CLI tool. Install it with brew install ical-buddy and grant Calendar access in System Settings.
Clone the repo and build with make build. The compiled binary has zero runtime dependencies beyond icalBuddy. Run ./blocker to launch.
Navigate to empty slots and press enter to create work blocks. Dismiss calendar noise with d. Resize blocks with J/K until your day is mapped out.
As you work through the day, press c to mark blocks complete. Navigate between days with [ / ]. Everything saves automatically.
Built on Bubbletea's Model-Update-View pattern. Every keypress produces a message, the model updates, and the view re-renders. State is predictable and easy to reason about.
Three clean modes — Normal, Creating, and Moving — keep keybindings context-aware. Each mode has its own update function and help bar. No accidental actions.
Each day's state is a single JSON file in ~/.blocker/. Work blocks, completion status, and dismissed events are all captured. No database, no migrations.
Calendar events are fetched via icalBuddy shell commands, parsed into blocks, and merged with persisted work blocks. Auto-refresh keeps things current without polling aggressively.
Fast compilation, single binary output, excellent concurrency.
Elm-architecture TUI framework from Charmbracelet. Clean, testable, composable.
Declarative terminal styling. Colors, borders, padding — CSS-like API for the terminal.
macOS CLI for reading Calendar.app events. Lightweight bridge to native calendar data.
One file per day in ~/.blocker/. Human-readable, git-friendly, zero setup.
Leverages macOS Calendar and privacy permissions. Designed for the Mac terminal workflow.
Blocker is open source and free. Build from source in seconds.
# Install icalBuddy (macOS Calendar bridge) $ brew install ical-buddy # Clone and build $ git clone https://github.com/cochranjd/blocker.git $ cd blocker && make build # Run it $ ./blocker