Mario Miletta300 downloadsCalendar for your vault: daily and periodic notes, tasks, and dated notes in one place.
Calendar for your Obsidian vault: daily and periodic notes, tasks, and dated notes in one place.
Part of the marioverse Obsidian plugin suite.
The month grid, with daily notes and open, done and overdue tasks shown right on their date.
Horizon: Apri il calendario) with three modes:-) are hiddendate frontmatter property (periodic notes are excluded to avoid duplicates)Horizon reads your Google calendars and shows their events in every view. It never writes to Google.
Setup (once, on desktop):
The refresh token lives in Obsidian's secret storage on that device, never in the vault. Calendars follow your Google Calendar selection; switch single ones off in settings. Events refresh every 5 minutes, or with Refresh Google Calendar.
Click an event for: Join call (Meet, Zoom or Teams link), Open/Create meeting note, Open daily note, Open in Google Calendar. A meeting note gets date, gcal_event and a daily link; a Granola note with the same title on the same day is reused instead of creating a new one. On phones events show only after connecting there, which needs the desktop sign-in flow, so mobile stays without events for now.
Notes in Agenda, Week, the day popover, and Bases views render as mini-cards: title (with time), a clean two-line excerpt, and the note's cover image (frontmatter cover/image/thumbnail → first embed → first external image). Hydration is async and LRU-cached. In the compact Month grid, hovering a note chip shows a floating hover-card with image and a longer excerpt. Settings: card length slider and a richCards toggle to fall back to compact chips.
Open overdue tasks roll up to a pinned "In ritardo" section on today in the Agenda (with a batch "Porta tutto a oggi"), and today's cell shows a red ↩ N badge in every view. Right-click any task chip for snooze presets (Oggi / Domani / Lunedì prossimo / +1 settimana). Every reschedule Notice carries a 10-second Annulla that re-applies the old date through the same guarded writes.
Horizon registers as a Bases view: any .base gains a month calendar. The Base decides which notes (filters); the view option dateProperty decides when (default date — set it to created for Granola meeting notes). Timestamps with an explicit offset (Granola writes UTC Z) are converted to the local day and time.
Beyond {{title}} / {{date:FMT}} / {{time:FMT}}, periodic-note templates can use:
{{agenda}} — the target day's calendar events and meetings (with times) and open tasks, as plain bullets with source links (never - [ ] lines: no task duplication){{week-digest}} — pre-compiled weekly review: Fatto (done per day), Meeting e note, In arrivo (due next week).(app.plugins.getPlugin('horizon') as HorizonPlugin).api exposes: getAgenda(from, to), getOverdue(), rescheduleTask(ref, kind, day), toggleTaskDone(ref), exportAgenda(), propose(proposal). Reads come from the live index; writes go through the guarded line-edit path.
.horizon/agenda.json path at most every 5 minutes of activity..horizon/proposals.json path (kind: 'reschedule' | 'new-task', targetKey, optional reason). Horizon renders dashed ✦ ghost chips on the target days; ✓ accepts, ✕ dismisses.✅ date, Tasks-plugin compatible. Recurring (🔁) tasks open at the line instead — completing them needs the Tasks rrule enginedaily-notes.json)Verified — isDesktopOnly: false in manifest.json; styles.css ships a pointer: coarse media query with 44px hit areas plus a max-width: 480px responsive rule for compact layouts.
pnpm i
pnpm dev # esbuild watch
pnpm build # typecheck + production build
pnpm test # node native test runner (74+ unit tests, no Obsidian needed)
pnpm lint
Architecture: a pure per-day index (src/index/) fed by metadataCache events, consumed by two ItemViews (src/ui/). All date math is UTC-immune (src/dates.ts); file writes go through guarded line edits (src/edits/). Pure modules never import the Obsidian runtime, so the whole read/write logic tests headless.
See it running in the Obsidianverse sample vault, a small, fictional vault with the whole plugin suite pre-configured.