Lifelong Calendar is an Obsidian plugin for keeping a date-based timeline of your life inside your vault.
It is designed for people who want to record what they read, learned, built, visited, or experienced on specific dates, while keeping the actual data in Markdown files they control.
The plugin supports:
- timeline entries stored in your vault as Markdown
- internal Obsidian note links and external URLs
- a dedicated timeline view with search and filtering
- reminder emails for incomplete days
- grounded AI questions over timeline entries and linked notes
The plugin creates and manages dated timeline entries under a folder in your vault, which defaults to:
Lifelong Calendar/Entries
Each entry is stored as a normal Markdown file with frontmatter and note content. This means:
- your timeline data remains portable
- you can inspect and edit entries manually
- your data is not locked into a proprietary backend
The plugin also offers optional cloud-based reminder support. That part uses a small Cloudflare Worker and D1 database so reminders can still function when Obsidian is closed.
- Dedicated
Lifelong Calendarview inside Obsidian - Create and edit entries with date, title, category, links, and note
- Attach internal Obsidian links or external URLs
- Preview-first workflow from the detail pane
- Search entries by text
- Filter by year and category
- Open a random memory
- Sync today's completion state to a reminder backend
- Send reminder emails through Resend
- Ask grounded AI questions over entries and linked notes
Each entry is stored as one Markdown file. Filenames are generated from the date and a slug of the title.
Example:
---
lc_id: 123e4567-e89b-12d3-a456-426614174000
date: 2026-03-06
title: Read chapter 1
type: reading
links:
- "[[Book Notes]]"
- "https://example.com/article"
created_at: 2026-03-06T20:00:00.000Z
updated_at: 2026-03-06T20:00:00.000Z
---
Short note about the day.Important behavior:
- one file per entry
- unknown frontmatter fields are preserved
- links may be plain internal paths, wikilinks, Markdown links, or external URLs
- for reminder purposes, a day is considered complete if at least one timeline entry exists for that date
This repository contains the plugin source and build output.
To install manually into Obsidian:
- Run:
npm install
npm run build- Copy these files into your vault plugin folder:
manifest.jsonmain.jsstyles.css
Target path:
<your-vault>/.obsidian/plugins/lifelong-calendar/
- In Obsidian, open
Settings -> Community plugins. - Enable
Lifelong Calendar.
If you plan to submit this plugin to the official Obsidian Community Plugins directory, use this checklist:
- Keep these files in the root of your GitHub repository:
README.mdLICENSEmanifest.jsonversions.json
- Keep your source code in the repository.
- Do not commit
main.jsto the repository. Generate it only for releases. - Update
manifest.jsonwith the release version. - Create a GitHub release whose tag exactly matches the plugin version in
manifest.json. - Upload these release assets:
main.jsmanifest.jsonstyles.css
- Submit the repository to
community-plugins.jsoninobsidianmd/obsidian-releases.
Notes:
versions.jsononly needs updates whenminAppVersionchanges.- Obsidian Community Plugins currently does not support a custom listing icon through
manifest.json. - The icon in
assets/lifelong-calendar-icon.svgis for repository branding, README display, and other external use.
To generate the exact release assets locally, run:
powershell -ExecutionPolicy Bypass -File .\scripts\prepare-release.ps1This creates a versioned folder and zip file under release/ containing only:
main.jsmanifest.jsonstyles.css
Typical usage flow:
- Open the command palette.
- Run
Open Lifelong Calendar. - Create entries for today or any past date.
- Attach relevant notes or external links.
- Search or filter the timeline later.
You can create entries with:
Add Timeline EntryAdd Current Note to TimelineAdd External Link to Timeline
The entry modal requires:
- a valid
YYYY-MM-DDdate - a title
- at least one link or a note
The plugin currently provides these commands:
Open Lifelong CalendarAdd Timeline EntryAdd Current Note to TimelineAdd External Link to TimelineOpen Random MemoryAsk Lifelong CalendarSync Today's Reminder StatusSend Test Reminder Email
Entries folder: folder where timeline entry Markdown files are storedDefault categories: comma-separated category suggestions in the entry modalOpen internal links in new tab: open internal note links in a new leaf
Backend URL: deployed Cloudflare Worker URLBackend token: shared bearer token used by the pluginReminder email: address that receives reminder emailsReminder timezone: timezone used to determine the current dayReminder time: daily reminder time inHH:MMformatEnable reminders: enables completion sync
Reminder action buttons:
Save config: sends reminder settings to the backendSync today: sends today's completion state to the backendTest email: sends a test reminder email
Provider:OpenAI,Groq,Gemini,Ollama, orCustom OpenAI-compatibleAPI key: required for cloud providersBase URL: optional override, required for custom endpointsModel: model nameMax retrieved chunks: number of local sources sent to the model
The reminder system is optional.
When configured, the plugin syncs whether today is complete to a small backend. That backend can send reminder emails even when Obsidian is closed.
The backend stores:
- reminder email
- reminder time
- reminder timezone
- reminder completion state
- reminder delivery records
The backend does not store:
- your vault
- your Markdown files
- the full contents of your timeline entries for reminder purposes
- your AI chat answers
Reminder behavior:
- a day is complete if your timeline contains at least one entry for that date
- the plugin syncs today's completion automatically when relevant entry files change
- completion from Obsidian and web check-in is merged per source instead of blindly overwriting
- email links do not mutate reminder state on
GET - the email check-in flow requires an explicit confirmation
POST
The reminder system is optional and sends daily emails when you haven't logged an entry.
-
Get a Resend API key at resend.com/api-keys
-
Run the setup script:
npm run setup-reminder
-
Copy the Worker URL shown at the end of the script
-
Configure in Obsidian:
- Settings → Lifelong Calendar → Reminder Cloud
- Set
Backend URLto your Worker URL - Set
Backend tokento the AUTH_TOKEN shown - Set
Reminder email,Reminder timezone,Reminder time - Enable
Enable reminders - Click
Save config→Sync today→Test email
See backend/README.md for detailed instructions.
If you prefer to set up manually, see backend/README.md.
The AI feature is optional.
Ask Lifelong Calendar searches your timeline entries and linked internal notes, then sends the top retrieved chunks to the configured model.
Provider:OpenAIAPI key: your OpenAI API keyBase URL: leave blankModel: a valid model such asgpt-4.1-mini
If you use the built-in Gemini provider:
Provider:GeminiAPI key: your Gemini API keyBase URL: leave blankModel: use a valid Gemini model
Important:
- do not set the Gemini
Base URLto the OpenAI-compatible Gemini endpoint when usingProvider = Gemini - the built-in Gemini provider in this plugin uses the native
generateContentAPI
If you specifically want the OpenAI-compatible Gemini endpoint:
- set
ProvidertoCustom OpenAI-compatible - set
Base URLto the Gemini OpenAI-compatible root URL - use a valid Gemini-compatible model name
Provider:OllamaBase URL:http://localhost:11434Model: a locally available Ollama model
- retrieval is currently lexical, not embedding-based
- citations are shown only when the model returns valid grounded citation IDs
- if a model returns malformed JSON or plain text, the answer may still display without citations
If Ask Lifelong Calendar says Failed to fetch, the most common reasons are:
- wrong provider selected
- wrong base URL
- local Ollama server not running
- invalid endpoint path
- network or firewall issue
For example:
- if
Provider = Gemini, leaveBase URLblank - if using a custom OpenAI-compatible endpoint, set
Base URLto the API root, not/chat/completions
Your actual timeline data stays in your vault as Markdown files.
That means:
- you can inspect entries manually
- you can back them up normally with your vault
- the plugin can rebuild its index from stored files
- reminder emails require your own Cloudflare and Resend setup
- AI chat requires your own provider configuration
- retrieval is lexical only for now
- reminder completeness is currently based on whether at least one entry exists for that date
Install dependencies:
npm installType-check the plugin:
npm run checkBuild the plugin:
npm run buildValidate the Worker syntax:
node --check backend/worker.mjs- src/: plugin source code
- main.js: built plugin bundle used by Obsidian
- styles.css: plugin styles
- manifest.json: Obsidian plugin manifest
- assets/lifelong-calendar-icon.svg: repository branding icon
- backend/worker.mjs: Cloudflare Worker reminder service
- backend/schema.sql: D1 schema
- backend/wrangler.jsonc: Cloudflare Worker configuration
The project currently includes:
- a working Obsidian timeline plugin
- Markdown-backed entry storage
- a deployable reminder backend
- AI retrieval and grounded-answer foundation
The remaining work is mostly product polish, deployment testing, and retrieval improvements.