Chronote is an Obsidian plugin that combines spaced repetition (SRS), Google Calendar integration, and AI-powered study planning into a single command center — all running locally inside your vault.
┌─────────────────────────────────────────────────────────────┐
│ Obsidian Plugin Host │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────────┐ │
│ │ main.ts │ │ settings.ts │ │ ChronoteDashboardView │ │
│ │ (lifecycle)│ │ (config) │ │ (UI / data hub) │ │
│ └──────┬──────┘ └──────────────┘ └─────────────────────┘ │
│ │ │
│ ┌──────▼──────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Commands │ │ TestService │ │ GoogleCalendarService│ │
│ │ (review, │ │ (tests) │ │ (OAuth / REST) │ │
│ │ tests) │ └─────────────┘ └─────────────────────┘ │
│ └────────────┘ │ │
│ ▼ │
│ ┌──────────────────────────────┐ ┌─────────────────────┐ │
│ │ AI Service Registry │ │ Vector Index │ │
│ │ (Gemini / OpenAI-compat / │ │ (local embeddings, │ │
│ │ Anthropic / Chronote Cloud) │ │ RAG search) │ │
│ └──────────────────────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Entry point: src/main.ts
onload()
this.loadData() (merges with DEFAULT_SETTINGS from src/settings.ts).chronote-dashboard (src/views/ChronoteDashboardView.ts).chronote-auth to receive Google OAuth tokens after the browser flow.open-chronote-dashboard, plus the SRS and test commands).Commands (src/commands.ts).ChronoteSettingTab).onunload()
Core logic: src/utils/srsLogic.ts
Frontmatter writer: src/commands.ts (applyReviewToFrontmatter)
Spaced repetition data lives in each note’s YAML frontmatter:
confidence — last review score (1–5)interval — days until next reviewnext_review — ISO date (YYYY-MM-DD)exam_date — optional exam date, synced from linked testsAlgorithm (calculateNextReview):
exam_date is today or past, set interval to 9999 and date to 9999-12-31 (archived).maxReviewIntervalDays and dailyLimitMax (overflows to next day if daily cap exceeded).The dashboard and chat modals read this data via app.metadataCache.getFileCache() — no separate database.
Owner: src/services/testService.ts
Tests are stored in plugin settings (ChronoteSettings.tests) as an array of:
{ id: string; name: string; date: string; filePaths: string[]; done?: boolean }
TestService provides CRUD + toggleDone.exam_date frontmatter is synced to the test date.exam_date.confidence scores of linked notes (excluding notes with exclude_from_exam: true).Owner: src/services/googleCalendarService.ts
https://cortex-proxy.vercel.app/api/auth.chronote-auth:// protocol handler.data.json via saveData().GoogleCalendarService maintains a preemptive refresh timer (every 60 s) and refreshes 5 minutes before expiry via the proxy (POST /api/refresh).Owner: src/services/ai/* (GeminiAdapter, OpenAICompatAdapter, AnthropicAdapter, createAdapter)
metadataCache frontmatter)TestService)notes, tests, flashcards, quizzes) on top.ChronoteChatModal (src/modals/ChronoteChatModal.ts) provides an interactive chat UI; scheduling queries may render an “Approve Schedule” button to bulk-create events.Chronote Cloud is wired through the same adapter interface as a fixed-base-url OpenAI-compatible endpoint. It is not available yet — the option is reserved in the catalog and settings, and will activate when the managed service goes live.Owner: src/agent/vectorIndex/*
chunker.ts) and embedded (embeddings.ts) into a local index.knowledge-index.bin in the plugin folder.knowledgeBase.ts is the single owner of the local index.File: src/views/ChronoteDashboardView.ts
The dashboard is a single custom ItemView rendered into the workspace. It has three main panels:
Re-rendering is debounced: metadata changes from typing trigger a 2-second delay so the dashboard does not refetch the calendar on every keystroke.
User edits a note
│
▼
Obsidian metadataCache updates frontmatter (confidence, interval, next_review, exam_date)
│
├──► Dashboard reads metadataCache → renders due reviews + test progress
│
├──► AI service reads metadataCache (via chat modal) → builds study plan context
│
├──► GoogleCalendarService reads free/busy time → AI uses it for planning
│
▼
AI returns suggested events → user approves in chat modal
│
▼
GoogleCalendarService.createEvent() → POST to Google Calendar API
│
▼
Dashboard re-fetches calendar → shows new events in schedule panel
Key conventions:
metadataCache is the single source of truth for SRS state.settings.tests is the single source of truth for tests.GoogleCalendarService instances are created per-consumer (Dashboard, Chat Modal) but share the same underlying settings object.