|
| 1 | +--- |
| 2 | +name: memento-flashcards |
| 3 | +description: >- |
| 4 | + Spaced-repetition flashcard system. Create cards from facts or text, |
| 5 | + chat with flashcards using free-text answers graded by the agent, |
| 6 | + generate quizzes from YouTube transcripts, review due cards with |
| 7 | + adaptive scheduling, and export/import decks as CSV. |
| 8 | +version: 1.0.0 |
| 9 | +author: Memento AI |
| 10 | +license: MIT |
| 11 | +platforms: [macos, linux] |
| 12 | +metadata: |
| 13 | + hermes: |
| 14 | + tags: [Education, Flashcards, Spaced Repetition, Learning, Quiz, YouTube] |
| 15 | + requires_toolsets: [terminal] |
| 16 | + category: productivity |
| 17 | +--- |
| 18 | + |
| 19 | +# Memento Flashcards — Spaced-Repetition Flashcard Skill |
| 20 | + |
| 21 | +## Overview |
| 22 | + |
| 23 | +Memento gives you a local, file-based flashcard system with spaced-repetition scheduling. |
| 24 | +Users can chat with their flashcards by answering in free text and having the agent grade the response before scheduling the next review. |
| 25 | +Use it whenever the user wants to: |
| 26 | + |
| 27 | +- **Remember a fact** — turn any statement into a Q/A flashcard |
| 28 | +- **Study with spaced repetition** — review due cards with adaptive intervals and agent-graded free-text answers |
| 29 | +- **Quiz from a YouTube video** — fetch a transcript and generate a 5-question quiz |
| 30 | +- **Manage decks** — organise cards into collections, export/import CSV |
| 31 | + |
| 32 | +All card data lives in a single JSON file. No external API keys are required — you (the agent) generate flashcard content and quiz questions directly. |
| 33 | + |
| 34 | +User-facing response style for Memento Flashcards: |
| 35 | +- Use plain text only. Do not use Markdown formatting in replies to the user. |
| 36 | +- Keep review and quiz feedback brief and neutral. Avoid extra praise, pep, or long explanations. |
| 37 | + |
| 38 | +## When to Use |
| 39 | + |
| 40 | +Use this skill when the user wants to: |
| 41 | +- Save facts as flashcards for later review |
| 42 | +- Review due cards with spaced repetition |
| 43 | +- Generate a quiz from a YouTube video transcript |
| 44 | +- Import, export, inspect, or delete flashcard data |
| 45 | + |
| 46 | +Do not use this skill for general Q&A, coding help, or non-memory tasks. |
| 47 | + |
| 48 | +## Quick Reference |
| 49 | + |
| 50 | +| User intent | Action | |
| 51 | +|---|---| |
| 52 | +| "Remember that X" / "save this as a flashcard" | Generate a Q/A card, call `memento_cards.py add` | |
| 53 | +| Sends a fact without mentioning flashcards | Ask "Want me to save this as a Memento flashcard?" — only create if confirmed | |
| 54 | +| "Create a flashcard" | Ask for Q, A, collection; call `memento_cards.py add` | |
| 55 | +| "Review my cards" | Call `memento_cards.py due`, present cards one-by-one | |
| 56 | +| "Quiz me on [YouTube URL]" | Call `youtube_quiz.py fetch VIDEO_ID`, generate 5 questions, call `memento_cards.py add-quiz` | |
| 57 | +| "Export my cards" | Call `memento_cards.py export --output PATH` | |
| 58 | +| "Import cards from CSV" | Call `memento_cards.py import --file PATH --collection NAME` | |
| 59 | +| "Show my stats" | Call `memento_cards.py stats` | |
| 60 | +| "Delete a card" | Call `memento_cards.py delete --id ID` | |
| 61 | +| "Delete a collection" | Call `memento_cards.py delete-collection --collection NAME` | |
| 62 | + |
| 63 | +## Card Storage |
| 64 | + |
| 65 | +Cards are stored in a JSON file at: |
| 66 | + |
| 67 | +``` |
| 68 | +~/.hermes/skills/productivity/memento-flashcards/data/cards.json |
| 69 | +``` |
| 70 | + |
| 71 | +**Never edit this file directly.** Always use `memento_cards.py` subcommands. The script handles atomic writes (write to temp file, then rename) to prevent corruption. |
| 72 | + |
| 73 | +The file is created automatically on first use. |
| 74 | + |
| 75 | +## Procedure |
| 76 | + |
| 77 | +### Creating Cards from Facts |
| 78 | + |
| 79 | +### Activation Rules |
| 80 | + |
| 81 | +Not every factual statement should become a flashcard. Use this three-tier check: |
| 82 | + |
| 83 | +1. **Explicit intent** — the user mentions "memento", "flashcard", "remember this", "save this card", "add a card", or similar phrasing that clearly requests a flashcard → **create the card directly**, no confirmation needed. |
| 84 | +2. **Implicit intent** — the user sends a factual statement without mentioning flashcards (e.g. "The speed of light is 299,792 km/s") → **ask first**: "Want me to save this as a Memento flashcard?" Only create the card if the user confirms. |
| 85 | +3. **No intent** — the message is a coding task, a question, instructions, normal conversation, or anything that is clearly not a fact to memorize → **do NOT activate this skill at all**. Let other skills or default behavior handle it. |
| 86 | + |
| 87 | +When activation is confirmed (tier 1 directly, tier 2 after confirmation), generate a flashcard: |
| 88 | + |
| 89 | +**Step 1:** Turn the statement into a Q/A pair. Use this format internally: |
| 90 | + |
| 91 | +``` |
| 92 | +Turn the factual statement into a front-back pair. |
| 93 | +Return exactly two lines: |
| 94 | +Q: <question text> |
| 95 | +A: <answer text> |
| 96 | +
|
| 97 | +Statement: "{statement}" |
| 98 | +``` |
| 99 | + |
| 100 | +Rules: |
| 101 | +- The question should test recall of the key fact |
| 102 | +- The answer should be concise and direct |
| 103 | + |
| 104 | +**Step 2:** Call the script to store the card: |
| 105 | + |
| 106 | +```bash |
| 107 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py add \ |
| 108 | + --question "What year did World War 2 end?" \ |
| 109 | + --answer "1945" \ |
| 110 | + --collection "History" |
| 111 | +``` |
| 112 | + |
| 113 | +If the user doesn't specify a collection, use `"General"` as the default. |
| 114 | + |
| 115 | +The script outputs JSON confirming the created card. |
| 116 | + |
| 117 | +### Manual Card Creation |
| 118 | + |
| 119 | +When the user explicitly asks to create a flashcard, ask them for: |
| 120 | +1. The question (front of card) |
| 121 | +2. The answer (back of card) |
| 122 | +3. The collection name (optional — default to `"General"`) |
| 123 | + |
| 124 | +Then call `memento_cards.py add` as above. |
| 125 | + |
| 126 | +### Reviewing Due Cards |
| 127 | + |
| 128 | +When the user wants to review, fetch all due cards: |
| 129 | + |
| 130 | +```bash |
| 131 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py due |
| 132 | +``` |
| 133 | + |
| 134 | +This returns a JSON array of cards where `next_review_at <= now`. If a collection filter is needed: |
| 135 | + |
| 136 | +```bash |
| 137 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py due --collection "History" |
| 138 | +``` |
| 139 | + |
| 140 | +**Review flow (free-text grading):** |
| 141 | + |
| 142 | +Here is an example of the EXACT interaction pattern you must follow. The user answers, you grade them, tell them the correct answer, then rate the card. |
| 143 | + |
| 144 | +**Example interaction:** |
| 145 | + |
| 146 | +> **Agent:** What year did the Berlin Wall fall? |
| 147 | +> |
| 148 | +> **User:** 1991 |
| 149 | +> |
| 150 | +> **Agent:** Not quite. The Berlin Wall fell in 1989. Next review is tomorrow. |
| 151 | +> *(agent calls: memento_cards.py rate --id ABC --rating hard --user-answer "1991")* |
| 152 | +> |
| 153 | +> Next question: Who was the first person to walk on the moon? |
| 154 | +
|
| 155 | +**The rules:** |
| 156 | + |
| 157 | +1. Show only the question. Wait for the user to answer. |
| 158 | +2. After receiving their answer, compare it to the expected answer and grade it: |
| 159 | + - **correct** → user got the key fact right (even if worded differently) |
| 160 | + - **partial** → right track but missing the core detail |
| 161 | + - **incorrect** → wrong or off-topic |
| 162 | +3. **You MUST tell the user the correct answer and how they did.** Keep it short and plain-text. Use this format: |
| 163 | + - correct: "Correct. Answer: {answer}. Next review in 7 days." |
| 164 | + - partial: "Close. Answer: {answer}. {what they missed}. Next review in 3 days." |
| 165 | + - incorrect: "Not quite. Answer: {answer}. Next review tomorrow." |
| 166 | +4. Then call the rate command: correct→easy, partial→good, incorrect→hard. |
| 167 | +5. Then show the next question. |
| 168 | + |
| 169 | +```bash |
| 170 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py rate \ |
| 171 | + --id CARD_ID --rating easy --user-answer "what the user said" |
| 172 | +``` |
| 173 | + |
| 174 | +**Never skip step 3.** The user must always see the correct answer and feedback before you move on. |
| 175 | + |
| 176 | +If no cards are due, tell the user: "No cards due for review right now. Check back later!" |
| 177 | + |
| 178 | +**Retire override:** At any point the user can say "retire this card" to permanently remove it from reviews. Use `--rating retire` for this. |
| 179 | + |
| 180 | +### Spaced Repetition Algorithm |
| 181 | + |
| 182 | +The rating determines the next review interval: |
| 183 | + |
| 184 | +| Rating | Interval | ease_streak | Status change | |
| 185 | +|---|---|---|---| |
| 186 | +| **hard** | +1 day | reset to 0 | stays learning | |
| 187 | +| **good** | +3 days | reset to 0 | stays learning | |
| 188 | +| **easy** | +7 days | +1 | if ease_streak >= 3 → retired | |
| 189 | +| **retire** | permanent | reset to 0 | → retired | |
| 190 | + |
| 191 | +- **learning**: card is actively in rotation |
| 192 | +- **retired**: card won't appear in reviews (user has mastered it or manually retired it) |
| 193 | +- Three consecutive "easy" ratings automatically retire a card |
| 194 | + |
| 195 | +### YouTube Quiz Generation |
| 196 | + |
| 197 | +When the user sends a YouTube URL and wants a quiz: |
| 198 | + |
| 199 | +**Step 1:** Extract the video ID from the URL (e.g. `dQw4w9WgXcQ` from `https://www.youtube.com/watch?v=dQw4w9WgXcQ`). |
| 200 | + |
| 201 | +**Step 2:** Fetch the transcript: |
| 202 | + |
| 203 | +```bash |
| 204 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/youtube_quiz.py fetch VIDEO_ID |
| 205 | +``` |
| 206 | + |
| 207 | +This returns `{"title": "...", "transcript": "..."}` or an error. |
| 208 | + |
| 209 | +If the script reports `missing_dependency`, tell the user to install it: |
| 210 | +```bash |
| 211 | +pip install youtube-transcript-api |
| 212 | +``` |
| 213 | + |
| 214 | +**Step 3:** Generate 5 quiz questions from the transcript. Use these rules: |
| 215 | + |
| 216 | +``` |
| 217 | +You are creating a 5-question quiz for a podcast episode. |
| 218 | +Return ONLY a JSON array with exactly 5 objects. |
| 219 | +Each object must contain keys 'question' and 'answer'. |
| 220 | +
|
| 221 | +Selection criteria: |
| 222 | +- Prioritize important, surprising, or foundational facts. |
| 223 | +- Skip filler, obvious details, and facts that require heavy context. |
| 224 | +- Never return true/false questions. |
| 225 | +- Never ask only for a date. |
| 226 | +
|
| 227 | +Question rules: |
| 228 | +- Each question must test exactly one discrete fact. |
| 229 | +- Use clear, unambiguous wording. |
| 230 | +- Prefer What, Who, How many, Which. |
| 231 | +- Avoid open-ended Describe or Explain prompts. |
| 232 | +
|
| 233 | +Answer rules: |
| 234 | +- Each answer must be under 240 characters. |
| 235 | +- Lead with the answer itself, not preamble. |
| 236 | +- Add only minimal clarifying detail if needed. |
| 237 | +``` |
| 238 | + |
| 239 | +Use the first 15,000 characters of the transcript as context. Generate the questions yourself (you are the LLM). |
| 240 | + |
| 241 | +**Step 4:** Validate the output is valid JSON with exactly 5 items, each having non-empty `question` and `answer` strings. If validation fails, retry once. |
| 242 | + |
| 243 | +**Step 5:** Store quiz cards: |
| 244 | + |
| 245 | +```bash |
| 246 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py add-quiz \ |
| 247 | + --video-id "VIDEO_ID" \ |
| 248 | + --questions '[{"question":"...","answer":"..."},...]' \ |
| 249 | + --collection "Quiz - Episode Title" |
| 250 | +``` |
| 251 | + |
| 252 | +The script deduplicates by `video_id` — if cards for that video already exist, it skips creation and reports the existing cards. |
| 253 | + |
| 254 | +**Step 6:** Present questions one-by-one using the same free-text grading flow: |
| 255 | +1. Show "Question 1/5: ..." and wait for the user's answer. Never include the answer or any hint about revealing it. |
| 256 | +2. Wait for the user to answer in their own words |
| 257 | +3. Grade their answer using the grading prompt (see "Reviewing Due Cards" section) |
| 258 | +4. **IMPORTANT: You MUST reply to the user with feedback before doing anything else.** Show the grade, the correct answer, and when the card is next due. Do NOT silently skip to the next question. Keep it short and plain-text. Example: "Not quite. Answer: {answer}. Next review tomorrow." |
| 259 | +5. **After showing feedback**, call the rate command and then show the next question in the same message: |
| 260 | +```bash |
| 261 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py rate \ |
| 262 | + --id CARD_ID --rating easy --user-answer "what the user said" |
| 263 | +``` |
| 264 | +6. Repeat. Every answer MUST receive visible feedback before the next question. |
| 265 | + |
| 266 | +### Export/Import CSV |
| 267 | + |
| 268 | +**Export:** |
| 269 | +```bash |
| 270 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py export \ |
| 271 | + --output ~/flashcards.csv |
| 272 | +``` |
| 273 | + |
| 274 | +Produces a 3-column CSV: `question,answer,collection` (no header row). |
| 275 | + |
| 276 | +**Import:** |
| 277 | +```bash |
| 278 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py import \ |
| 279 | + --file ~/flashcards.csv \ |
| 280 | + --collection "Imported" |
| 281 | +``` |
| 282 | + |
| 283 | +Reads a CSV with columns: question, answer, and optionally collection (column 3). If the collection column is missing, uses the `--collection` argument. |
| 284 | + |
| 285 | +### Statistics |
| 286 | + |
| 287 | +```bash |
| 288 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py stats |
| 289 | +``` |
| 290 | + |
| 291 | +Returns JSON with: |
| 292 | +- `total`: total card count |
| 293 | +- `learning`: cards in active rotation |
| 294 | +- `retired`: mastered cards |
| 295 | +- `due_now`: cards due for review right now |
| 296 | +- `collections`: breakdown by collection name |
| 297 | + |
| 298 | +## Pitfalls |
| 299 | + |
| 300 | +- **Never edit `cards.json` directly** — always use the script subcommands to avoid corruption |
| 301 | +- **Transcript failures** — some YouTube videos have no English transcript or have transcripts disabled; inform the user and suggest another video |
| 302 | +- **Optional dependency** — `youtube_quiz.py` needs `youtube-transcript-api`; if missing, tell the user to run `pip install youtube-transcript-api` |
| 303 | +- **Large imports** — CSV imports with thousands of rows work fine but the JSON output may be verbose; summarize the result for the user |
| 304 | +- **Video ID extraction** — support both `youtube.com/watch?v=ID` and `youtu.be/ID` URL formats |
| 305 | + |
| 306 | +## Verification |
| 307 | + |
| 308 | +Verify the helper scripts directly: |
| 309 | + |
| 310 | +```bash |
| 311 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py stats |
| 312 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py add --question "Capital of France?" --answer "Paris" --collection "General" |
| 313 | +python3 ~/.hermes/skills/productivity/memento-flashcards/scripts/memento_cards.py due |
| 314 | +``` |
| 315 | + |
| 316 | +If you are testing from the repo checkout, run: |
| 317 | + |
| 318 | +```bash |
| 319 | +pytest tests/skills/test_memento_cards.py tests/skills/test_youtube_quiz.py -q |
| 320 | +``` |
| 321 | + |
| 322 | +Agent-level verification: |
| 323 | +- Start a review and confirm feedback is plain text, brief, and always includes the correct answer before the next card |
| 324 | +- Run a YouTube quiz flow and confirm each answer receives visible feedback before the next question |
0 commit comments