Tony Peonio22 downloadsTurn a course folder and an exam date into a day-by-day study plan, daily quizzes from your own notes with a local model, and flashcards.
An Obsidian plugin for students: give it a course folder and an exam date and it writes a day-by-day study plan from your own notes, asks you a daily quiz generated by a local model (via Ollama) from those notes, and turns the questions into flashcards. Everything runs on your machine; nothing leaves it.
Exam Companion is part of the Companion suite of local-first Obsidian plugins by Tony Peonio for students and researchers: your machine does the work, every change is a diff you approve, and the numbers are published. The others are Local Vault Agent (local Ollama agent that searches, compiles, edits notes), Lecture Companion (live local lecture transcription, Canvas slides, Ollama summaries), Canvas Companion (Canvas LMS assignments, grades and announcements as notes), Paper Companion (Zotero search by meaning, page-cited reading notes), Research Log Companion (append-only lab notebook with git, parameters, data hashes), Job Hunt Companion (job applications as notes, resume tailoring, interview questions), Fellowship Companion (grants and fellowships: deadlines, materials, letters, eligibility), Code Companion (commits in the daily note, weekly report, TODOs), Teaching Companion (local-model rubric grading with verbatim evidence) and Branching Table of Contents (parent/child properties as a rooted family tree). All at github.com/TonyPeonio.
## section of the notes in the course folder
is a topic, weighted by how much you wrote (a Lecture Companion lecture note is one topic). Each topic gets a first pass and a review three to
five days later; the last two days are mixed review of the weakest and heaviest topics. Minutes
per day are respected. The plan is an ordinary checklist note you can edit.Question::Answer lines in the format the
Spaced Repetition plugin reads, in a
note tagged #flashcards/<Course> so that plugin shows them as a deck.## Summary, ## Transcript, ## My notes) are one topic each, quizzed from the
Summary; its other layout (## YYYY-MM-DD sections with a ### Summary) is one topic per
section.ollama pull qwen3.5:9b (default; fits a 12 GB GPU). qwen3.5:4b for smaller
cards; any Ollama chat model works.Exams/<Course> – <Exam> <date>.md.## Quiz YYYY-MM-DD; open the answer callouts to check yourself and tick what you got right.Flashcards/<Course>.md, tagged for the
Spaced Repetition plugin. Running it again adds only new questions; cards you have already
reviewed keep their scheduling.| Command | What it does |
|---|---|
| Plan an exam | Asks for folder, exam, dates and minutes; writes the plan note |
| Today's quiz | Adds model-written questions on today's topics to the plan note |
| Record quiz results | Reads the latest quiz's ticks, adds weak topics, rebuilds the remaining days |
| Export flashcards | Writes Question::Answer lines for the Spaced Repetition plugin |
Topics. For each note in the course folder, every ## heading section is one topic; a ### Summary
under it is used as the quiz text, the whole section's word count as the weight. A dated section
with a **Topic:** … line is titled by that line. A Lecture Companion lecture note (## Slides,
## Summary, ## Transcript, ## My notes) is one topic titled by its title property and date,
quizzed from the Summary and weighted by the whole note. Notes without ## headings are one topic
each. Topics are ordered by date when one is found in the heading, the file name or a date:
property.
Schedule. Days run from the start date to the day before the exam (the exam date must be a real calendar day after today). Half the total time goes to first passes, split in proportion to topic weight (10 minutes minimum, one day's budget maximum); a topic that does not fit the remaining minutes of a day moves to the next, and when the runway is too short for everything the overflow is spread over the least loaded days. Each topic is reviewed at half its first-pass time three to five days later (or in the final days when the runway is short). Weak topics get one more review as early as there is room and come first in the final mixed review. Weekends are ordinary days. The result is deterministic for the same notes and inputs.
Plan note. Frontmatter holds exam, date, course_folder, minutes_per_day and
weak_topics; ## Plan has one ### YYYY-MM-DD (Day) section per day with task lines
- [ ] Topic — 25 min — [[Note#Heading]]; ## Topics lists every topic with its weight. Quiz
sections are appended after that. Record quiz results rewrites only ## Plan from today on.
Quiz. The system prompt asks for exactly N Q: / A: pairs supported by the given text, in
explain/compare/compute style; the user message carries today's topics' text, trimmed to the
context window (3.2 characters per token, 1,500 tokens reserved for the reply). The parser accepts
numbering, bold labels, "Question/Answer", Q and A on one line, code in answers, and ignores
headings and closing remarks; if the model writes more pairs than asked, the first N are kept.
Questions are attached to the topic they mention, else in turn. Each question is a checkbox
followed by a collapsed [!answer] callout and its source link. npm run quiz:live runs this
path against a real Ollama model with three lecture notes and checks the questions (see
scripts/quiz-live.ts).
flashcards by default. A new flashcards note starts with
#flashcards/<Course>, which is what the Spaced Repetition plugin scans for (and names the
deck). Change it if you changed the tag in that plugin's settings.The plugin talks only to the Ollama URL you set (localhost by default), and only when you run Today's quiz. It reads the notes in the course folder you choose and writes under the exams and flashcards folders. No telemetry, no accounts.
npm install
npm run dev # watch build → main.js
npm test # unit tests (vitest), no Ollama needed
npm run build # type-check + Obsidian review lint + production bundle
To release: bump version in manifest.json and package.json, add the version to
versions.json, write release-notes/<version>.md, commit, then push a tag named exactly
<version>. The release workflow builds, tests, attests and publishes the GitHub release.
src/core/ (topics, planner, quiz, dates, frontmatter, Ollama client) has no Obsidian dependency
and is tested against an in-memory vault; src/main.ts, the modal and the settings tab are the
thin Obsidian layer.
MIT