Skip to content

hydrobiont/gcal_cli

Repository files navigation

gcal_cli

A keyboard-driven terminal app (TUI) for viewing Google Calendar. Launch it, leave it open, and read your week at a glance — a week grid with per-calendar colors and RSVP status, a free-slot finder that copies shareable availability to your clipboard, multiple Google accounts, and a multi-timezone gutter. It is read-only: it never modifies your calendars.

Repository: github.com/hydrobiont/gcal_cli

Features

  • Week grid with per-calendar colors and per-event RSVP status (accepted / tentative / declined / needs-action). Today's column and day are marked (today), and t jumps back to the current week from anywhere.
  • Free-slot finder — scans your "mine" calendars within working hours and lists open slots. Mark slots across as many weeks as you like (scroll with /); the selection persists, and y copies a grouped-by-day, timezone-labelled availability block ("when can we meet") to the clipboard.
  • Multiple accounts — connect several Google accounts; events merge into one view.
  • Multi-timezone gutter — show the time column in several IANA zones side by side.
  • Calendar toggles — flip a calendar's grid visibility, and mark which calendars are "mine" (count toward your free/busy) vs. colleagues' (shown but not blocking).
  • Duplicate-event collapsing — the same meeting on several calendars collapses to one block, with participants listed.
  • Local cache — last-fetched events load instantly on start, refreshing in the background.
  • Live view — while open, the app follows the wall clock: it refreshes events in the background every sync_interval, and when left open across a week boundary it automatically advances to the new current week — keeping any free slots you'd marked.
  • Read-only scopescalendar.readonly + tasks.readonly only.

Key bindings

Key Action
tab Cycle panes: free slots → week grid → calendars
/ (j / k) Move cursor (slot list / grid slot-row / calendar list)
space Select / unselect a free slot — accumulates across weeks (slots pane) · show/hide calendar (calendars pane)
enter / space Expand a grid slot to all that week's meetings (grid pane)
esc Collapse an expanded grid slot
m Mark a calendar mine / not-mine (calendars pane)
y Copy the free-slot selection — all weeks, kept after copy (slots pane)
c Clear the whole free-slot selection (slots pane)
/ (h / l) Previous / next week — moves both panes; selection persists
t Jump back to the current week
r Refresh both panes
? Toggle the expanded help
q Quit

Requirements

  • macOS (v1 only): clipboard copy uses pbcopy, OAuth tokens are stored in the macOS Keychain.
  • Go 1.25+ to build.
  • A Google account (Workspace or personal Gmail).

Installation

git clone https://github.com/hydrobiont/gcal_cli.git
cd gcal_cli
make build            # produces ./bin/gcal_cli
cp bin/gcal_cli /usr/local/bin/   # or anywhere on your PATH

Or with the Go toolchain:

go install github.com/hydrobiont/gcal_cli@latest

Google Cloud setup (bring your own OAuth client)

gcal_cli does not ship a shared OAuth client — you create your own in the Google Cloud console and point the app at it. This keeps your data flowing only between your machine and Google. Steps below are accurate as of 2026.

  1. Create a project at https://console.cloud.google.com/ (or reuse one).

  2. Enable APIs — in APIs & Services → Library, enable both:

    • Google Calendar API
    • Google Tasks API
  3. Configure the OAuth consent screen (APIs & Services → OAuth consent screen):

    • Workspace users: choose Internal. No app verification is required, and refresh tokens do not expire after 7 days.
    • Personal Gmail: you can only choose External. Leave the app in Testing and add your address as a test user. Caveat: in Testing mode a personal-account refresh token expires after 7 days, so you will need to re-run gcal_cli auth add about once a week.
  4. Add scopes — request exactly:

    • https://www.googleapis.com/auth/calendar.readonly
    • https://www.googleapis.com/auth/tasks.readonly
  5. Create the OAuth client (APIs & Services → Credentials → Create credentials → OAuth client ID): application type Desktop app.

  6. Download the client JSON and install it:

    mkdir -p ~/.config/gcal_cli
    mv ~/Downloads/client_secret_*.json ~/.config/gcal_cli/oauth_client.json
    chmod 600 ~/.config/gcal_cli/oauth_client.json

    gcal_cli reads this file and never writes to it.

First run

gcal_cli auth add        # opens the browser for consent; token → Keychain
gcal_cli calendars sync  # discovers your calendars into config.toml
gcal_cli                 # launches the TUI

In the TUI, tab to the calendars pane, then:

  • space to toggle a calendar's visibility in the grid,
  • m to mark a calendar as mine (so its events count toward free/busy).

Run gcal_cli auth add again for each additional account.

Configuration

Config lives at ~/.config/gcal_cli/config.toml (or $XDG_CONFIG_HOME/gcal_cli/config.toml). gcal_cli calendars sync populates the [[calendars]] entries; you can hand-edit everything. Built-in defaults: 09:00–18:00 working hours Mon–Fri, 30-minute minimum free slot, 5-minute background sync, a 30-days-back / 90-days-forward window.

Precedence: an explicit per-weekday working_hours override beats the default; absent any config file, the built-in defaults apply.

[[accounts]]
email = "you@example.com"
label = "Work"

[[calendars]]
account = "you@example.com"
id      = "you@example.com"
summary = "You"
visible = true
mine    = true
color   = "#4285F4"

[[calendars]]
account = "you@example.com"
id      = "team@example.com"
summary = "Team"
visible = true
mine    = false          # shown in the grid, but does not block your free/busy

[working_hours]
  [working_hours.default]
  start = "09:00"
  end   = "18:00"
  [working_hours.fri]      # per-weekday override
  start = "09:00"
  end   = "14:00"

min_slot_length = "30m"
sync_interval   = "5m"

[window]
back_days    = 30
forward_days = 90

[[timezones]]
name = "Europe/Berlin"

[[timezones]]
name = "America/New_York"

Free-slots workflow ("when can we meet")

  1. With the free-slots pane focused, the app lists open slots within your working hours across your visible "mine" calendars.
  2. space marks slots. To pick across multiple weeks, scroll with / and keep marking — the selection accumulates across every week you visit. c clears the whole selection; t jumps back to the current week.
  3. y copies your selection (across all weeks) as a grouped-by-day, timezone-labelled text block — paste it straight into chat or email. The selection is kept after copying, so you can refine and copy again.

Privacy & security

  • Read-only OAuth scopes (calendar.readonly, tasks.readonly); the app cannot change your calendars.
  • OAuth tokens are stored in the macOS Keychain (service gcal_cli), never in plaintext config or the cache.
  • Your OAuth client JSON and the local event cache stay under ~/.config/gcal_cli/. No data leaves your machine except the API calls to Google.

License

Released under the PostgreSQL License — a liberal open-source license similar to MIT.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors