---
name: engram-lesson-academy
description: >
  Build interactive HTML lesson courses for the EngramQuest plugin's Lesson Academy
  (the "Lessons" / "教材" tab). Given any topic — programming, marketing, medicine, yoga,
  anything — this skill designs a course matched to the user's background and goal, then
  generates beautiful self-contained HTML lessons the user studies inside Obsidian.
  Trigger this skill whenever the user says they want to learn something, asks to be taught
  a topic, mentions "teach", "教我", "我想學", "課程", "教材", "lesson", "course",
  or asks to add / extend / regenerate lessons in an existing course — even if they
  don't name the skill. Also trigger when the user wants study material generated from
  their own vault notes.
---

# Lesson Academy Skill

Create **courses** of interactive HTML **lessons** for the EngramQuest plugin. A course is a
folder holding a `meta.json` (course info + lesson list + completion tracking) and one
self-contained HTML file per lesson. The plugin's **Learn → Lessons** tab renders courses as
cards with progress bars; the user opens each lesson in an in-app viewer and marks it done.

**Which root folder to use.** The plugin scans every folder listed in its "Lesson storage
folders" setting (default: just `engram-quest/lessons/`) — see `Lesson storage folders` under
Settings → EngramQuest → Lesson Academy in the app. Pick the root **before** Step 1:
- If this course is part of an active curriculum — i.e. `8.TRACK/Learning/<domain>/curriculum-<domain>.md`
  exists for the topic being taught — write the course under
  `8.TRACK/Learning/<domain>/lessons/{courseSlug}/`, alongside that domain's curriculum,
  progress tracking, and diagrams, so the whole domain's study material stays in one place.
- Otherwise (a standalone course with no curriculum context), use the default
  `engram-quest/lessons/{courseSlug}/`.
- If unsure which applies, ask the user rather than guessing.

Everywhere below, `{lessonsRoot}` means whichever of the two you picked for this course.

Your lessons are the user's actual study material — quality matters more than quantity.
One excellent, tightly-scoped lesson beats three shallow ones.

## Output language

Lesson content and course metadata (title, description, tags) match the language of the user's
prompt and source notes. If the user writes in Traditional Chinese, teach in Traditional Chinese.

## Core principles

1. **One lesson teaches ONE thing.** Completable in 10–20 minutes, ending with a tangible win.
2. **Ground in the user's mission.** Knowing *why* they want to learn shapes every lesson.
   If the goal is unclear, ask before designing the course.
3. **Zone of proximal development.** Each lesson should challenge "just enough" — build on what
   the previous lessons established, never re-explain what's already mastered.
4. **Never trust parametric knowledge alone for fast-moving topics.** For current
   frameworks/tools/APIs, verify key claims with web search and cite sources in the lesson.
5. **Knowledge first, then practice.** Teach the concept, then end the lesson with an
   interactive quiz or exercise so the user gets an immediate feedback loop.
6. **Use visuals only when they materially improve understanding.** Lessons do not need visuals
   by default. Add a visual when the topic is spatial, procedural, comparative, abstract, or
   easier to understand through a realistic scene. Prefer one primary visual; use two only when
   one sets context and the other explains the mechanism.

### Visual teaching decision

Before writing lesson HTML, decide whether a visual would clarify the one thing this lesson
teaches. If yes, choose the medium by the learning job:

- **First classify the knowledge shape** (see `references/visual-teaching.md`). Complex concepts
  — multi-actor flows, layered architectures, abstract mechanisms — are strong candidates for a
  teaching image. A well-crafted visual compresses what would take three paragraphs into one
  memorable picture.
- Use **AI image generation capability** for polished educational infographics and teaching
  images that make a complex concept click — e.g. a step-by-step flow diagram with numbered
  actors and arrows, a layered architecture overview, a before/after comparison. Prompt for a
  *clean technical teaching image*, not a generic decorative scene. A good teaching image is
  immediately informative on its own; a bad one is atmospheric but explains nothing.
- Use **SVG/HTML diagrams** for exact labels, arrows, comparisons, flows, decision trees,
  overlays, or interactive controls where precision matters, or when an AI-generated image fails
  the quality gate.
- Use a **hybrid** when a generated image teaches the big picture but needs exact explanatory
  labels: generated image for the teaching visual, HTML/SVG for labels, arrows, captions, checks,
  or interactive overlays.

If the lesson needs visual strategy, read `references/visual-teaching.md` before generating the
HTML. Do not add decorative images.

---

## Step 1: Understand the request

Parse what the user wants:

| Request | Action |
|---|---|
| "I want to learn X" (new topic) | New course → Step 2 |
| "Add a lesson about Y to my Z course" | Extend existing course → Step 4 (read meta.json first) |
| "Continue my course" / "next lesson" | Read meta.json + completion, generate the next lesson in the outline |
| "Generate my course" / "把課綱生成內容" | Course has planned (`file: null`) lessons — generate HTML for each, keeping their ids (see `references/lesson-format.md` § Planned lessons) |
| "Just build me an outline first" | Create the course with all lessons as `file: null` so the user can edit the plan in the plugin UI before generation |
| "Make lessons from my notes on X" | Search vault for source notes, then Step 2 |

The user can also create courses and outline entries directly in the plugin ("建立新課程" /
"新增課綱") — those appear as lessons with `"file": null`. Generating their content is the
most common follow-up request this skill receives.

Before asking the user anything, check what already exists — across every configured root, not
just the default one:

```bash
ls engram-quest/lessons/ 2>/dev/null
ls 8.TRACK/Learning/*/lessons/ 2>/dev/null
```

If a matching course exists (in either location), read its `meta.json` to see the outline and
which lessons are completed — extend it in place, at the root it already lives in, rather than
starting over or duplicating it under a different root.

When the request builds on the user's own notes, find them with Obsidian CLI
(see `references/obsidian-cli.md` for syntax):

```bash
obsidian search query="<topic>" format=json
```

## Step 2: Establish the mission (new course only)

Ask the user (briefly, 2–3 questions max, skip what's already clear from the prompt):

1. **Why** do they want to learn this? (project, exam, career, curiosity)
2. **Current level** — total beginner, some exposure, or experienced in an adjacent area?
3. **Depth** — quick overview (3–4 lessons) or thorough path (6–10 lessons)?

The answers shape the outline. A .NET backend developer learning React needs a completely
different course than a designer learning React.

## Step 3: Design the course outline

Produce an outline of N lessons, each one line:

```
1. <lesson title> — <the ONE thing it teaches>
2. ...
```

Order matters: each lesson should rely only on earlier lessons. Show the outline to the user
for approval before generating (generation is expensive; outline changes are cheap).

Pick the course metadata now:
- `courseSlug` — short kebab-case ASCII (e.g. `dotnet-basics`, `marketing-seo`)
- `icon` — one emoji that captures the topic (🔷 💊 📈 🧘 …)
- `colorScheme` — one of `indigo | green | amber | rose | cyan` (pick what fits the topic mood)
- `tags` — **reuse existing tags first; only add a new one if nothing fits:**
  1. Scan the existing tag pool before deciding:
     ```bash
     python3 -c "
     import json, glob
     tags = set()
     for f in glob.glob('engram-quest/lessons/*/meta.json') + glob.glob('8.TRACK/Learning/*/lessons/*/meta.json'):
         tags.update(json.load(open(f, encoding='utf-8')).get('tags', []))
     print(sorted(tags))
     "
     ```
  2. Pick 1–2 tags from the pool that best match this course's topic.
  3. Only add a brand-new tag when the pool has nothing suitable. Maximum **2 tags total**.
  4. Exception: if the user explicitly specifies tags, use those exactly.
- `description` — one sentence, shown on the course card (≤ 40 chars in zh, ≤ 80 in en)

## Step 4: Generate lessons

For each lesson, write a single self-contained HTML file following the hard rules in
`references/html-recipe.md` (read it before generating the first lesson — Obsidian's CSP
silently breaks externally-loaded resources, so violations look fine to you but broken to
the user).

When a visual would materially improve learning, also read `references/visual-teaching.md` and
choose the visual type and production method before writing the lesson. Keep the visual count
tight: usually one, rarely two.

Lesson ID and filename:
- `id` = `lsn-<current unix ms timestamp>` (e.g. `lsn-1717977600000`); when generating several
  lessons in one run, make each timestamp distinct (increment by 1 if needed)
- filename = `<id>-<short-ascii-slug>.html` (e.g. `lsn-1717977600000-seo-basics.html`)

Write the file to:

```
{lessonsRoot}/{courseSlug}/{filename}
```

## Step 5: Write / update meta.json

`{lessonsRoot}/{courseSlug}/meta.json` is the contract with the plugin — its exact
shape is specified in `references/lesson-format.md` (read it the first time you write one).

Critical rules:
- **Never overwrite an existing meta.json blindly.** Read → merge → write. Existing `lessons`
  entries and the whole `completion` map must survive (they hold the user's progress).
- New lessons append to the `lessons` array with `"source": "skill"`.
- Initialize `completion[id] = { "viewed": false, "completed": false, "starred": false }`
  for each new lesson.

## Step 6: Tell the user

After generating, summarize:

```
✅ Course "{title}" — {N} lessons created

Open EngramQuest → 學習 (Learn) → 教材 (Lessons) to start.
Lessons:
1. <title>
2. ...
```

Remind them they can ask you follow-up questions about any lesson, ask for the next lesson,
or ask to regenerate one that didn't land.

---

## Lesson HTML quality bar

A lesson is a **beautiful, readable document** the user will revisit. Follow the visual and
structural guidance in `references/html-recipe.md`, and:

- Open with what the lesson teaches and why it matters for the user's mission.
- Readable on a phone: multi-column layouts must collapse at narrow widths — see the
  responsive hard rules in `references/html-recipe.md`.
- Use concrete examples over abstract definitions. Code topics get runnable-looking snippets;
  physical skills get step sequences; concept topics get diagrams built from styled divs.
- Litter factual claims with citations (`<a href>` links to sources) when the topic is
  technical or fast-moving.
- End with a short interactive quiz (3–5 questions, inline JS, immediate feedback) plus a
  "next steps" pointer.
- Close with a reminder that the user can ask their AI teacher (you) follow-up questions.

## Converting lessons to other EngramQuest formats

When the user finishes a course (or asks), offer to:
- **Generate review-deck flashcards** from the lessons' key facts — create an
  `engram-review/ai-cards/{course-title}.md` per the review-deck skill's card format
  (`question :: answer` lines, if that skill is installed).
- **Build a quest map** from the course — hand off to the quest-map skill if installed.

Don't auto-generate these; lessons alone are the deliverable unless asked.

## What NOT to do

- Don't write into the user's own notes — only the configured lesson roots (`engram-quest/lessons/`
  and, when a course belongs to a curriculum, that domain's `8.TRACK/Learning/<domain>/lessons/`)
  are yours.
- Don't delete or rename existing lesson files; the plugin tracks them by `meta.json`.
- Don't generate the whole course's HTML before the outline is approved.
- Don't pad lessons to look longer; density and clarity beat length.
