@mulmoclaude/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/helps/billing-clients-worklog.md +215 -0
- package/assets/helps/billing-invoice.md +458 -0
- package/assets/helps/business.md +104 -0
- package/assets/helps/collection-skills.md +810 -0
- package/assets/helps/custom-view.md +433 -0
- package/assets/helps/feeds.md +114 -0
- package/assets/helps/gemini.md +57 -0
- package/assets/helps/github.md +23 -0
- package/assets/helps/guide.md +61 -0
- package/assets/helps/index.md +89 -0
- package/assets/helps/lessons-collection.md +400 -0
- package/assets/helps/mulmoscript.md +249 -0
- package/assets/helps/portfolio-tracker.md +211 -0
- package/assets/helps/presentation-deck.md +828 -0
- package/assets/helps/presenthtml.md +89 -0
- package/assets/helps/sandbox.md +97 -0
- package/assets/helps/spreadsheet.md +43 -0
- package/assets/helps/storyteller.md +101 -0
- package/assets/helps/telegram.md +136 -0
- package/assets/helps/todo-collection.md +140 -0
- package/assets/helps/vocabulary.md +109 -0
- package/assets/helps/wiki.md +168 -0
- package/assets/skills-preset/mc-cooking-coach/SKILL.md +217 -0
- package/assets/skills-preset/mc-library/SKILL.md +188 -0
- package/assets/skills-preset/mc-manage-automations/SKILL.md +119 -0
- package/assets/skills-preset/mc-manage-skills/SKILL.md +141 -0
- package/assets/skills-preset/mc-wiki-deep-lint/SKILL.md +108 -0
- package/assets/skills-preset/mc-wiki-health-check/SKILL.md +61 -0
- package/assets/skills-preset/mc-wiki-ingest/SKILL.md +182 -0
- package/assets/skills-preset/mc-wiki-promote/SKILL.md +175 -0
- package/assets/skills-preset/mc-zenn/SKILL.md +136 -0
- package/dist/chunk-CKQMccvm.cjs +28 -0
- package/dist/collection/core/actionVisible.d.ts +34 -0
- package/dist/collection/core/calendarGrid.d.ts +120 -0
- package/dist/collection/core/deriveAll.d.ts +38 -0
- package/dist/collection/core/derivedFormula.d.ts +18 -0
- package/dist/collection/core/draft.d.ts +18 -0
- package/dist/collection/core/enumColors.d.ts +33 -0
- package/dist/collection/core/errorMessage.d.ts +4 -0
- package/dist/collection/core/itemLabel.d.ts +12 -0
- package/dist/collection/core/presentCollection.d.ts +13 -0
- package/dist/collection/core/promptSafety.d.ts +1 -0
- package/dist/collection/core/schema.d.ts +355 -0
- package/dist/collection/core/shortHexId.d.ts +8 -0
- package/dist/collection/core/sortItems.d.ts +29 -0
- package/dist/collection/core/uiTypes.d.ts +106 -0
- package/dist/collection/index.cjs +793 -0
- package/dist/collection/index.cjs.map +1 -0
- package/dist/collection/index.d.ts +14 -0
- package/dist/collection/index.js +740 -0
- package/dist/collection/index.js.map +1 -0
- package/dist/collection/paths.cjs +44 -0
- package/dist/collection/paths.cjs.map +1 -0
- package/dist/collection/paths.js +41 -0
- package/dist/collection/paths.js.map +1 -0
- package/dist/collection/server/atomic.d.ts +1 -0
- package/dist/collection/server/delete.d.ts +38 -0
- package/dist/collection/server/derive.d.ts +8 -0
- package/dist/collection/server/discoveredCollection.d.ts +18 -0
- package/dist/collection/server/discovery.d.ts +227 -0
- package/dist/collection/server/host.d.ts +77 -0
- package/dist/collection/server/index.cjs +1721 -0
- package/dist/collection/server/index.cjs.map +1 -0
- package/dist/collection/server/index.d.ts +11 -0
- package/dist/collection/server/index.js +1671 -0
- package/dist/collection/server/index.js.map +1 -0
- package/dist/collection/server/io.d.ts +114 -0
- package/dist/collection/server/paths.d.ts +52 -0
- package/dist/collection/server/spawn.d.ts +55 -0
- package/dist/collection/server/templatePath.d.ts +25 -0
- package/dist/collection/server/util.d.ts +3 -0
- package/dist/collection/server/validate.d.ts +19 -0
- package/dist/collection/server/views.d.ts +20 -0
- package/dist/deriveAll-C15OpM3K.cjs +399 -0
- package/dist/deriveAll-C15OpM3K.cjs.map +1 -0
- package/dist/deriveAll-C6BYnpBL.js +364 -0
- package/dist/deriveAll-C6BYnpBL.js.map +1 -0
- package/dist/file-change/index.cjs +72 -0
- package/dist/file-change/index.cjs.map +1 -0
- package/dist/file-change/index.d.ts +43 -0
- package/dist/file-change/index.js +66 -0
- package/dist/file-change/index.js.map +1 -0
- package/dist/notifier/engine.d.ts +72 -0
- package/dist/notifier/index.cjs +484 -0
- package/dist/notifier/index.cjs.map +1 -0
- package/dist/notifier/index.d.ts +3 -0
- package/dist/notifier/index.js +464 -0
- package/dist/notifier/index.js.map +1 -0
- package/dist/notifier/store.d.ts +18 -0
- package/dist/notifier/types.d.ts +118 -0
- package/dist/notifier/validate.d.ts +17 -0
- package/dist/scheduler/adapter.d.ts +48 -0
- package/dist/scheduler/index.cjs +352 -0
- package/dist/scheduler/index.cjs.map +1 -0
- package/dist/scheduler/index.d.ts +2 -0
- package/dist/scheduler/index.js +343 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/task-manager.d.ts +51 -0
- package/dist/whisper/client.cjs +241 -0
- package/dist/whisper/client.cjs.map +1 -0
- package/dist/whisper/client.d.ts +35 -0
- package/dist/whisper/client.js +239 -0
- package/dist/whisper/client.js.map +1 -0
- package/dist/whisper/ffmpeg.d.ts +6 -0
- package/dist/whisper/index.cjs +433 -0
- package/dist/whisper/index.cjs.map +1 -0
- package/dist/whisper/index.d.ts +5 -0
- package/dist/whisper/index.js +425 -0
- package/dist/whisper/index.js.map +1 -0
- package/dist/whisper/internal.d.ts +11 -0
- package/dist/whisper/models.d.ts +49 -0
- package/dist/whisper/sidecar.d.ts +8 -0
- package/dist/whisper/whisper.d.ts +28 -0
- package/dist/workspace-setup/assets.d.ts +10 -0
- package/dist/workspace-setup/index.d.ts +3 -0
- package/dist/workspace-setup/index.js +556 -0
- package/dist/workspace-setup/index.js.map +1 -0
- package/dist/workspace-setup/slug.d.ts +6 -0
- package/dist/workspace-setup/slug.js +13 -0
- package/dist/workspace-setup/slug.js.map +1 -0
- package/dist/workspace-setup/sync.d.ts +94 -0
- package/package.json +95 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Guide & Planner Templates
|
|
2
|
+
|
|
3
|
+
Reference templates for the Guide & Planner role. Use these structures when authoring documents with `presentDocument` for any of the supported guide types.
|
|
4
|
+
|
|
5
|
+
## Document Conventions (all types)
|
|
6
|
+
|
|
7
|
+
Every guide should:
|
|
8
|
+
|
|
9
|
+
- **Overview**: open with a summary of the key parameters (servings, days, level, budget, etc.)
|
|
10
|
+
- **Numbered steps OR structured sections**: use one or the other consistently across the document
|
|
11
|
+
- **Anchors**: add `<a id="step-1"></a>` (or `step-N`, `day-N`, `section-name`) to each major heading for `scrollToAnchor` navigation
|
|
12
|
+
- **Images**: embed via `` — make the alt-text prompt specific enough to generate a useful illustration on its own
|
|
13
|
+
- **Close**: end with tips, variations, troubleshooting, or follow-up recommendations
|
|
14
|
+
- **Tone**: warm and encouraging; adapt vocabulary to the user's stated experience level
|
|
15
|
+
|
|
16
|
+
## Form-First Workflow
|
|
17
|
+
|
|
18
|
+
Always call `presentForm` before producing the document. Tailor fields to the request type:
|
|
19
|
+
|
|
20
|
+
- **Recipe**: servings, dietary restrictions, skill level, available time, equipment
|
|
21
|
+
- **Travel**: destination, dates, traveler count, interests, budget tier, accommodation type
|
|
22
|
+
- **Fitness**: goal (weight loss / strength / endurance), starting level, days per week, equipment access
|
|
23
|
+
- **Event**: occasion, guest count, budget, venue type, dietary needs
|
|
24
|
+
- **Study guide**: topic, current level, time available, learning goal
|
|
25
|
+
- **DIY / home project**: project type, skill level, tools available, budget
|
|
26
|
+
|
|
27
|
+
Pre-fill any field the user already provided via `defaultValue`. Mark fields the user must answer as `required: true`. Keep forms concise — ask only for what is needed to produce a great result.
|
|
28
|
+
|
|
29
|
+
## Per-Type Document Structures
|
|
30
|
+
|
|
31
|
+
### Recipe
|
|
32
|
+
|
|
33
|
+
overview → ingredients (scaled to the chosen servings) → equipment → prep work → numbered cooking steps (each with an image) → chef's tips → storage notes
|
|
34
|
+
|
|
35
|
+
### Travel
|
|
36
|
+
|
|
37
|
+
overview → day-by-day itinerary (morning / afternoon / evening) → accommodation & dining → transport between stops → budget breakdown → packing tips → local culture tips
|
|
38
|
+
|
|
39
|
+
### Fitness
|
|
40
|
+
|
|
41
|
+
overview → weekly schedule → per-workout breakdown (warm-up, main exercises with sets / reps / form notes, cool-down) → progression plan over weeks → nutrition tips
|
|
42
|
+
|
|
43
|
+
### Event
|
|
44
|
+
|
|
45
|
+
overview → timeline & checklist (T-minus weeks) → venue & catering → guest list & invitations → décor & entertainment → budget tracker
|
|
46
|
+
|
|
47
|
+
### Study Guide
|
|
48
|
+
|
|
49
|
+
overview → topic breakdown → key concepts per section → worked examples → practice questions → resources & references
|
|
50
|
+
|
|
51
|
+
### DIY / Home Project
|
|
52
|
+
|
|
53
|
+
overview → required tools & materials → safety notes → numbered steps (each with an image) → finishing & cleanup → maintenance & care
|
|
54
|
+
|
|
55
|
+
## Follow-up Pattern
|
|
56
|
+
|
|
57
|
+
After presenting the document:
|
|
58
|
+
|
|
59
|
+
- Offer to read any step aloud (scroll to it first with `scrollToAnchor`, then narrate the step)
|
|
60
|
+
- Invite follow-up questions
|
|
61
|
+
- Offer to adjust the plan based on feedback (regenerate the form, add steps, change scope)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# About MulmoClaude
|
|
2
|
+
|
|
3
|
+
MulmoClaude is a GUI front-end for Claude Code. It lets you talk to Claude Code through a chat interface with rich visual output, powered by the **GUI Chat Protocol** — a plugin layer that allows Claude to render structured results (documents, spreadsheets, mind maps, images, and more) directly in the canvas alongside the conversation.
|
|
4
|
+
|
|
5
|
+
Under the hood it uses the Claude Code Agent SDK as its LLM core. Claude has full access to your workspace files and can use built-in tools (read, write, bash, search) as well as GUI Chat Protocol plugins registered as MCP servers.
|
|
6
|
+
|
|
7
|
+
**Core philosophy**: The workspace is the database. Files are the source of truth. Claude is the intelligent interface.
|
|
8
|
+
|
|
9
|
+
## Roles
|
|
10
|
+
|
|
11
|
+
- **General** — Everyday assistant: task management, scheduling, wiki, mind maps, and general Q&A.
|
|
12
|
+
- **Office** — Creates documents, spreadsheets, presentations, and MulmoScript slideshows.
|
|
13
|
+
- **Guide & Planner** — Collects your needs via a form, then produces a rich illustrated guide or plan. Works for recipes, travel itineraries, fitness programs, event planning, study guides, DIY projects, and more.
|
|
14
|
+
- **Artist** — Generates and edits images, opens a drawing canvas, and creates 3D scenes.
|
|
15
|
+
- **Tutor** — Assesses your knowledge level, then teaches any topic with structured documents and visuals.
|
|
16
|
+
- **Storyteller** — Crafts illustrated narrative stories as a MulmoScript storyboard.
|
|
17
|
+
- **Storyteller Plus** — Like Storyteller, with consistent character images across beats.
|
|
18
|
+
- **Settings** — Manages information sources, skills, and scheduled automations for the workspace.
|
|
19
|
+
- _(Additional roles may be defined by the user in the workspace.)_
|
|
20
|
+
|
|
21
|
+
## Key Capabilities
|
|
22
|
+
|
|
23
|
+
- Build **collections** — schema-driven data apps (todo lists, trackers, ledgers, decks) with table / calendar / kanban / dashboard views, plus LLM-authored **custom views**; manage a calendar scheduler
|
|
24
|
+
- Present documents and spreadsheets with rich formatting
|
|
25
|
+
- Generate and edit images
|
|
26
|
+
- Create interactive mind maps
|
|
27
|
+
- Generate and edit HTML pages / 3D scenes
|
|
28
|
+
- Present MulmoScript multimedia stories
|
|
29
|
+
- Manage a personal knowledge wiki
|
|
30
|
+
- Switch between roles mid-conversation
|
|
31
|
+
- Ask clarifying questions via interactive forms
|
|
32
|
+
- Play browser games
|
|
33
|
+
|
|
34
|
+
## Collections — Apps from Data
|
|
35
|
+
|
|
36
|
+
Collections are MulmoClaude's most distinctive capability: a **schema-driven data app declared in a single small JSON file**, with no database, ORM, or migration tool. You describe a data model, cross-record relations, computed fields, and per-record action buttons in a `schema.json`; the host reads that DSL and renders a full app — table, calendar, kanban board, and dashboard views — over a folder of plain `<id>.json` records. The same primitives power todo lists, recipe boxes, stock portfolios, invoice ledgers, vocabulary decks, and curricula, all without any app-specific host code. This is the core philosophy made concrete: a `schema.json` plus a folder of records **is** the app.
|
|
37
|
+
|
|
38
|
+
Because Claude authors and edits the schema for you in conversation, you build and reshape these apps just by talking — "add a priority field," "track this as a kanban," "make rent recur monthly" — and the collection updates live. We call this **vibe crafting**: the end-user counterpart of a developer's "vibe coding" — you describe the app you want and Claude builds it, with the schema validated and custom views sandboxed so you get the power without the pitfalls. Records stay validated, computed fields (totals, cross-collection lookups) recompute on every render, and completion bells / recurring obligations are declared in the same schema.
|
|
39
|
+
|
|
40
|
+
See [Collection skills](config/helps/collection-skills.md) for the full schema DSL.
|
|
41
|
+
|
|
42
|
+
## Custom Views — Views the Built-ins Don't Cover
|
|
43
|
+
|
|
44
|
+
When the built-in table / calendar / kanban / dashboard views don't fit what you want to _see_ — a year-at-a-glance planner, a Gantt bar, a heat-map, a printable report — Claude authors a **custom view**: a single HTML file rendered in a sandboxed iframe over the collection's records. It reads (and optionally writes) records through a scoped token, stays live as the data changes, and can hand work back to a chat — all without any view-specific host code. The view is data, just like the rest of the collection, so you can ask for an entirely new way to look at your data in plain language and get it.
|
|
45
|
+
|
|
46
|
+
See [Custom views](config/helps/custom-view.md) for the authoring contract.
|
|
47
|
+
|
|
48
|
+
## Wiki — Long-Term Memory
|
|
49
|
+
|
|
50
|
+
The wiki (`wiki/` in the workspace) acts as Claude's long-term memory. Unlike the conversation history which resets each session, the wiki is a persistent, compounding knowledge base that Claude builds and maintains over time. You feed it sources — articles, URLs, notes — and Claude ingests them into structured, interlinked Markdown pages. The more you add, the smarter it gets.
|
|
51
|
+
|
|
52
|
+
See [Wiki](config/helps/wiki.md) for details on how it works.
|
|
53
|
+
|
|
54
|
+
## Help Pages
|
|
55
|
+
|
|
56
|
+
- [Wiki](config/helps/wiki.md) — how the personal knowledge wiki works, its folder layout, page format, and operations
|
|
57
|
+
- [Gemini API Key](config/helps/gemini.md) — why `GEMINI_API_KEY` is strongly recommended (images, audio, video) and how to get one from Google AI Studio
|
|
58
|
+
- [MulmoScript](config/helps/mulmoscript.md) — format reference for authoring multimedia stories: beats, image types, speech, audio, and a minimal example
|
|
59
|
+
- [Business Presentation Template](config/helps/business.md) — MulmoScript template and rules for business presentations in the Office role
|
|
60
|
+
- [Presentation Deck](config/helps/presentation-deck.md) — authoring business decks two ways: structured `slide` layouts (title/stats/table/timeline/…) or animated `html_tailwind` + `animation: true`, with full worked samples
|
|
61
|
+
- [Storyteller Template](config/helps/storyteller.md) — MulmoScript template and rules for character-driven narrated stories in the Storyteller role
|
|
62
|
+
- [Guide & Planner Templates](config/helps/guide.md) — document structures and form-field hints per guide type for the Guide & Planner role
|
|
63
|
+
- [Spreadsheet](config/helps/spreadsheet.md) — cell format, formulas, date handling, and format codes for the presentSpreadsheet plugin
|
|
64
|
+
- [presentHtml](config/helps/presenthtml.md) — self-contained HTML rules and the three-`../` relative-path convention used by the presentHtml plugin to keep generated files portable under `file://`
|
|
65
|
+
- [Sandbox](config/helps/sandbox.md) — how the Docker sandbox isolates the agent, what it can access, and how to disable it
|
|
66
|
+
- [Telegram Bridge](config/helps/telegram.md) — how to talk to MulmoClaude from the Telegram app: creating a bot, starting the bridge, allowlisting chat IDs, commands, and troubleshooting
|
|
67
|
+
- [Feeds](config/helps/feeds.md) — register a self-refreshing data feed (RSS/Atom/JSON) by authoring `feeds/<slug>/schema.json`: schema shape, the `ingest` block, raw-item field mapping, and `maxItems` retention
|
|
68
|
+
- [GitHub repositories in the workspace](config/helps/github.md) — clone-destination rules under `github/<name>/` and how to handle existing directories with matching or different remotes
|
|
69
|
+
- [Collection skills](config/helps/collection-skills.md) — build a data app (model + UI + relations + computed fields + action buttons) by authoring a `schema.json` collection skill: the DSL, field types, derived formulas, actions, records
|
|
70
|
+
- [Custom views](config/helps/custom-view.md) — give a collection a view the built-ins don't cover (year/quarter overview, Gantt): an HTML file under `views/`, registered in `schema.json`, rendered in a sandboxed iframe over the records
|
|
71
|
+
- [Todo list collection](config/helps/todo-collection.md) — the canonical recipe for building or migrating a todo / task list: full schema (status enum + `done` toggle + priority bells), `SKILL.md`, and legacy `todo-plugin` migration steps
|
|
72
|
+
- [Vocabulary collection](config/helps/vocabulary.md) — recipe for a language-learning word deck (any language): `proficiency` enum + `mastered` toggle + `meaning`/`example` fields, a kanban for drag-to-promote review, and bulk-add / quiz workflows
|
|
73
|
+
- [Lessons collection](config/helps/lessons-collection.md) — recipe for a multi-session **curriculum** (any topic): one lesson per record, a `status` kanban, a `file` link to each lesson's HTML, and per-lesson + course-level **Learn** actions run by the Tutor
|
|
74
|
+
- [Clients + Worklog](config/helps/billing-clients-worklog.md) — recipe for a client database and a per-client timesheet (Bundle A of the billing suite); set this up before invoicing
|
|
75
|
+
- [Invoicing](config/helps/billing-invoice.md) — recipe for an invoice ledger + business profile with line items, host-computed totals, and PDF / bookkeeping action buttons (Bundle B; references the clients + worklog from Bundle A)
|
|
76
|
+
- [Portfolio tracker](config/helps/portfolio-tracker.md) — recipe for a paired stock-quotes watchlist + holdings portfolio whose price/value are computed live from the quotes via a cross-collection derived ref
|
|
77
|
+
|
|
78
|
+
## Workspace Layout
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
~/mulmoclaude/
|
|
82
|
+
chat/ ← session tool results (.jsonl per session)
|
|
83
|
+
todos/ ← todo items
|
|
84
|
+
calendar/ ← calendar events
|
|
85
|
+
contacts/ ← address book
|
|
86
|
+
wiki/ ← personal knowledge wiki (long-term memory)
|
|
87
|
+
config/helps/ ← help pages (synced from app on every start)
|
|
88
|
+
memory.md ← distilled facts loaded into every session
|
|
89
|
+
```
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
# Lessons — a stateful-curriculum collection recipe
|
|
2
|
+
|
|
3
|
+
Read this whenever the user wants to **learn a topic over multiple sessions** and
|
|
4
|
+
have their **course tracked** — a sequence of lessons, where each lesson is taught
|
|
5
|
+
once, practiced, and revisited, with progress that survives across conversations.
|
|
6
|
+
It is the authoritative template for a lessons collection — copy it rather than
|
|
7
|
+
reinventing one from the generic DSL fragments in
|
|
8
|
+
`config/helps/collection-skills.md`. Read that file first for the general schema
|
|
9
|
+
rules; this one is the lessons-specific specialization. For a **flashcard / word
|
|
10
|
+
deck** (single-item drilling rather than a structured curriculum) use
|
|
11
|
+
`config/helps/vocabulary.md` instead.
|
|
12
|
+
|
|
13
|
+
The design in one line: **each lesson is one record, the `status` enum is the
|
|
14
|
+
single source of truth for where the learner is in the curriculum, and a kanban
|
|
15
|
+
board turns the whole course into a visible progress pipeline.** The lesson's
|
|
16
|
+
actual content lives as a self-contained HTML artifact that a `file` field links
|
|
17
|
+
to — so the collection is the *table of contents + progress board* over the
|
|
18
|
+
self-contained HTML lessons you author.
|
|
19
|
+
|
|
20
|
+
> **The `lesson` field points at a real HTML file on disk.** Each lesson's body
|
|
21
|
+
> is a self-contained HTML page saved under `artifacts/html/…`; the `file` field
|
|
22
|
+
> stores its **workspace-relative path**, and the row becomes a clickable link
|
|
23
|
+
> that re-opens the rendered page. The collection never stores the lesson body —
|
|
24
|
+
> it points at it. One concept per lesson, one HTML file per lesson, one record
|
|
25
|
+
> per lesson. **How and *when* that file gets written matters — see "Authoring the
|
|
26
|
+
> lesson HTML" and "Pre-generating lessons in the background" below: author ahead of
|
|
27
|
+
> time in a hidden background session so the learner never waits; `presentHtml`
|
|
28
|
+
> renders a single lesson to the learner but don't loop it to batch-create files.**
|
|
29
|
+
|
|
30
|
+
## Ground it in the learner's goal first
|
|
31
|
+
|
|
32
|
+
A curriculum is only good if it serves a real goal. **Before** authoring lessons,
|
|
33
|
+
establish *why* the learner wants this and *where they already are* — the Tutor
|
|
34
|
+
role does this with `putQuestions`. Capture the answer (their goal + current
|
|
35
|
+
level) so later sessions can resume without re-asking: either in the SKILL.md, or
|
|
36
|
+
as a `singleton` companion collection (see "Extending it"). Then pitch each
|
|
37
|
+
lesson at the learner's **zone of proximal development** — challenging but
|
|
38
|
+
reachable — and prefer cited, external sources over unverified recall.
|
|
39
|
+
|
|
40
|
+
## schema.json
|
|
41
|
+
|
|
42
|
+
Author it at `data/skills/lessons-<topic>/schema.json` — one collection per
|
|
43
|
+
course, so the slug carries the topic (`lessons-french-cooking`,
|
|
44
|
+
`lessons-linear-algebra`). The bridge mirrors it to `.claude/skills/<slug>/`; the
|
|
45
|
+
user opens it at `/collections/lessons-<topic>`:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"title": "Linear Algebra",
|
|
50
|
+
"icon": "school",
|
|
51
|
+
"dataPath": "data/lessons-linear-algebra/items",
|
|
52
|
+
"primaryKey": "id",
|
|
53
|
+
"fields": {
|
|
54
|
+
"id": { "type": "string", "label": "ID", "primary": true, "required": true },
|
|
55
|
+
"order": { "type": "number", "label": "#", "required": true },
|
|
56
|
+
"title": { "type": "string", "label": "Lesson", "required": true },
|
|
57
|
+
"status": { "type": "enum", "label": "Status", "values": ["planned", "learning", "practiced", "mastered"], "required": true },
|
|
58
|
+
"objective": { "type": "text", "label": "What this lesson teaches" },
|
|
59
|
+
"lesson": { "type": "file", "label": "Lesson" },
|
|
60
|
+
"resources": { "type": "markdown", "label": "Cited sources" },
|
|
61
|
+
"notes": { "type": "text", "label": "Where the learner is" }
|
|
62
|
+
},
|
|
63
|
+
"displayField": "title",
|
|
64
|
+
"kanbanField": "status",
|
|
65
|
+
"actions": [
|
|
66
|
+
{ "id": "learn", "label": "Learn", "icon": "school", "kind": "chat", "role": "tutor", "template": "templates/learn.md" }
|
|
67
|
+
],
|
|
68
|
+
"collectionActions": [
|
|
69
|
+
{ "id": "continue", "label": "Learn", "icon": "play_arrow", "kind": "chat", "role": "tutor", "template": "templates/continue.md" }
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Every key earns its place:
|
|
75
|
+
|
|
76
|
+
| Key | What it gives the user |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `order` (`number`) | The curriculum sequence. Sort the table by it to read the course top-to-bottom. Cheap to renumber, unlike renaming files. |
|
|
79
|
+
| `title` (`string`) | The lesson name. It is the `displayField`, so it labels every table row and kanban card. |
|
|
80
|
+
| `status` (`enum`) | The four stages of mastery and the single source of truth for "where the learner is". Drives the kanban columns: `planned` → `learning` → `practiced` → `mastered`. |
|
|
81
|
+
| `objective` (`text`) | The **prompt the lesson's HTML page is generated from** (see the callout below). A paragraph covering the one concept this lesson teaches, the key points, and the takeaway — keep it to **one concept** (the cardinal rule of good lessons), but describe it *fully*. Not a one-line title. |
|
|
82
|
+
| `lesson` (`file`) | The clickable link to the lesson's HTML page on disk. Stores the bare workspace-relative path (`artifacts/html/lessons-<topic>/<id>.html`) — never an `/api/files/raw?...` URL. Written directly to disk when pre-authored, or set from the path `presentHtml` returns when taught live. Empty until the page exists. |
|
|
83
|
+
| `resources` (`markdown`) | Cited external sources for the lesson — links the learner can return to. Grounds teaching in verifiable material, not unverified recall. |
|
|
84
|
+
| `notes` (`text`) | Learner-specific observations: what they struggled with, what to revisit next time. The continuity that makes multi-session teaching work. |
|
|
85
|
+
| `kanbanField` | Pins the board to `status` (drag a card → writes `status`). |
|
|
86
|
+
| `displayField` | Card / table label (the lesson title, not the opaque id). |
|
|
87
|
+
|
|
88
|
+
> **`objective` is the lesson's generation prompt — write it like one.** Because
|
|
89
|
+
> lessons are authored just-in-time, when the page is finally written the LLM sees
|
|
90
|
+
> only this record: `title` + `objective` are the entire spec it generates the
|
|
91
|
+
> HTML from. So don't write a label — write a brief. Spell out the angle to take,
|
|
92
|
+
> the points that must be covered, a worked example or analogy to use, what to
|
|
93
|
+
> defer to other lessons, and the takeaway the learner should leave with. The
|
|
94
|
+
> richer the `objective`, the better the page and the less it drifts from the
|
|
95
|
+
> course you planned. Think of it as the prompt you're handing your future self.
|
|
96
|
+
>
|
|
97
|
+
> **Because it's a long prose field, mind the JSON:** an unescaped ASCII quote
|
|
98
|
+
> inside `objective` (e.g. `…もう"中心"ではなく…`) breaks the file, and a broken
|
|
99
|
+
> record is **silently skipped** — you'll quietly end up with fewer lessons than
|
|
100
|
+
> you wrote. In prose, use `「」`/`『』` (or escape as `\"`), never a raw `"`.
|
|
101
|
+
|
|
102
|
+
**Labels are localizable.** `title`, every `label`, and the enum `values` are free
|
|
103
|
+
text — translate them into the learner's language. Product/role names stay in
|
|
104
|
+
English. Keep the `status` `values` in lockstep with anything that references them
|
|
105
|
+
(`kanbanField`, action `when` predicates).
|
|
106
|
+
|
|
107
|
+
## Action templates
|
|
108
|
+
|
|
109
|
+
There are just **two actions, both labeled "Learn"** — each picks the right mode
|
|
110
|
+
automatically, so the learner never has to choose "teach vs. review vs. extend".
|
|
111
|
+
Each needs a plain-English template inside the skill dir; the host starts a new
|
|
112
|
+
chat in the `tutor` role seeded with it.
|
|
113
|
+
|
|
114
|
+
- **Per-record action** (`actions`) — the **Learn** button on a lesson's detail
|
|
115
|
+
panel. The host prepends **that lesson's record JSON** as passive data; the
|
|
116
|
+
`learn` template teaches or reviews it depending on its `status` (the gating
|
|
117
|
+
that used to need a `when` predicate now lives inside the template).
|
|
118
|
+
- **Collection-level action** (`collectionActions`) — the **Learn** button in the
|
|
119
|
+
collection header. There's no single record, so the host prepends a **compact
|
|
120
|
+
progress summary of every lesson** (each one's `id`, `title`, and `status`); the
|
|
121
|
+
`continue` template reads how far the learner has got and picks the next lesson
|
|
122
|
+
to run. `when` predicates are not evaluated on collection-level actions.
|
|
123
|
+
|
|
124
|
+
Keep templates short — the role prompt already knows how to teach.
|
|
125
|
+
|
|
126
|
+
`data/skills/lessons-<topic>/templates/learn.md` (per-record):
|
|
127
|
+
|
|
128
|
+
```markdown
|
|
129
|
+
Learn this lesson. The record above gives the lesson's `title`, its `objective`
|
|
130
|
+
(a paragraph describing what to teach — your authoring brief), `status`, and — if
|
|
131
|
+
already authored — its `lesson` HTML path. Pick the mode from `status`, and never
|
|
132
|
+
jump straight to a quiz — the HTML page IS the lesson, so deliver it first.
|
|
133
|
+
|
|
134
|
+
Deliver the page with `presentHtml`:
|
|
135
|
+
- `lesson` already set (often pre-authored in the background — see below) → present
|
|
136
|
+
it by passing its **path** to `presentHtml` (no duplicate save). Instant.
|
|
137
|
+
- `lesson` empty (the prefetch worker hasn't finished, or never ran) → author the
|
|
138
|
+
page **from the `objective` brief** and present it with `presentHtml` (passing the
|
|
139
|
+
`html`), then write the returned `data.filePath` into the record's `lesson` field.
|
|
140
|
+
This is the graceful fallback.
|
|
141
|
+
|
|
142
|
+
**The moment the page is on screen — _before_ you teach or quiz — prefetch the next
|
|
143
|
+
lesson** so its generation overlaps the whole time the learner spends here: call
|
|
144
|
+
`spawnBackgroundChat` (`hidden: true`, `role: "tutor"`) to author the next-by-`order`
|
|
145
|
+
lesson's HTML in the background (a self-contained message that reads that record and
|
|
146
|
+
`Write`s the page to `artifacts/html/lessons-<topic>/<id>.html`, sets its `lesson`
|
|
147
|
+
field, and presents nothing). Skip if it's already authored or this is the last
|
|
148
|
+
lesson. **Do this now, not at the end** — the learner often advances the instant they
|
|
149
|
+
finish, and a prefetch fired during the wrap-up is too late to hide the wait.
|
|
150
|
+
|
|
151
|
+
Then branch on `status`:
|
|
152
|
+
- `planned` / `learning` → teach the page, check understanding with a question or a
|
|
153
|
+
`presentForm` quiz, and set `status` to `learning` (or `practiced` if they nailed
|
|
154
|
+
it).
|
|
155
|
+
- `practiced` / `mastered` → run a short review quiz on the `objective` (include an
|
|
156
|
+
"explain it in your own words" item); set `status` to `mastered`, or back to
|
|
157
|
+
`learning` if they're shaky.
|
|
158
|
+
|
|
159
|
+
Cite real sources in the page and in `resources`, and record anything to revisit in
|
|
160
|
+
`notes`. Don't re-show the collection card after a single lesson — just keep the
|
|
161
|
+
conversation going; the board reflects the new `status` next time it's opened. (The
|
|
162
|
+
next lesson was already prefetched right after you showed this page — see above.)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`data/skills/lessons-<topic>/templates/continue.md` (collection-level):
|
|
166
|
+
|
|
167
|
+
```markdown
|
|
168
|
+
Continue the course. The summary above lists every lesson's `id`, `title`, and
|
|
169
|
+
`status`. Pick the next move, in order:
|
|
170
|
+
|
|
171
|
+
1. a lesson with `status: learning` → resume it
|
|
172
|
+
2. else the lowest-`order` `status: planned` lesson → start it
|
|
173
|
+
3. else a `practiced` (not yet `mastered`) lesson → review it
|
|
174
|
+
|
|
175
|
+
In cases 1–3, run that one lesson exactly like the per-lesson Learn button: present
|
|
176
|
+
by `path` if `lesson` is set (else author from `objective`), and **immediately
|
|
177
|
+
prefetch the next lesson** with a hidden `spawnBackgroundChat` worker — _before_ you
|
|
178
|
+
teach or quiz, so it generates while the learner works. Then deliver the lesson, check
|
|
179
|
+
understanding, and update `status` + `notes`. Don't re-show the collection card
|
|
180
|
+
afterwards — just continue the conversation.
|
|
181
|
+
|
|
182
|
+
4. only if **every** lesson is `mastered` → append the next batch as `planned`
|
|
183
|
+
records (a **paragraph `objective`** each — the authoring brief — continuing the
|
|
184
|
+
`order`), pitched at the learner's now-higher level; do NOT author the HTML yet.
|
|
185
|
+
When you write these records, use the language's quotation marks (`「」`/`『』`,
|
|
186
|
+
or `'…'`/`“…”`) — or escape as `\"` — in string values, never a raw `"`, or the
|
|
187
|
+
file breaks and the record is silently skipped. Then call
|
|
188
|
+
`presentCollection` once to show the expanded roadmap.
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Authoring the lesson HTML — two ways
|
|
192
|
+
|
|
193
|
+
`presentHtml` does two things: it saves the HTML *and* **renders it in the
|
|
194
|
+
learner's canvas**. The `Write` tool only saves. Choose by whether the learner
|
|
195
|
+
should see the page right now.
|
|
196
|
+
|
|
197
|
+
**Batch / scaffolding (no user involvement) — Write the file directly.** If you
|
|
198
|
+
pre-author several lessons at once, do NOT loop `presentHtml` over them — that
|
|
199
|
+
would flash every page into the canvas one after another, hijacking the
|
|
200
|
+
conversation. Instead:
|
|
201
|
+
|
|
202
|
+
1. Author the self-contained HTML (see `config/helps/presenthtml.md` for the
|
|
203
|
+
document rules — full `<!DOCTYPE html>`, inline CSS/JS or an allowed CDN).
|
|
204
|
+
2. **Write it straight to disk** at a stable, course-scoped path:
|
|
205
|
+
`artifacts/html/lessons-<topic>/<id>.html` (filename = the record id, so the
|
|
206
|
+
link is meaningful and stable). Use the `Write` tool — not `presentHtml`.
|
|
207
|
+
3. Set that path as the lesson record's `lesson` field.
|
|
208
|
+
|
|
209
|
+
**Teaching one lesson live — use `presentHtml`.** This is the common case: most
|
|
210
|
+
lessons are authored **just-in-time**, the moment the learner reaches them (you
|
|
211
|
+
don't pre-generate the whole course up front). When you teach one and want it in
|
|
212
|
+
the canvas:
|
|
213
|
+
|
|
214
|
+
- **New lesson** (empty `lesson`): call `presentHtml` with the `html` — it saves
|
|
215
|
+
and renders in one step and returns the saved path in `data.filePath`. Write
|
|
216
|
+
*that* returned path into the record's `lesson` field (don't also `Write` it
|
|
217
|
+
yourself, or you'll create two copies).
|
|
218
|
+
- **Pre-authored lesson** (`lesson` already set): call `presentHtml` with the
|
|
219
|
+
**`path`** (the existing `lesson` value) instead of `html` — it presents the
|
|
220
|
+
file in place without saving a duplicate.
|
|
221
|
+
|
|
222
|
+
Either way, **`presentHtml` must actually run** — delivering the page is the heart
|
|
223
|
+
of teaching, not an optional step before the quiz.
|
|
224
|
+
|
|
225
|
+
Keep lesson pages **self-contained** (inline everything or an allowed CDN) so
|
|
226
|
+
they render correctly regardless of the directory they were saved in.
|
|
227
|
+
|
|
228
|
+
## Pre-generating lessons in the background — no wait
|
|
229
|
+
|
|
230
|
+
Authoring a full HTML page takes the model tens of seconds, and `presentHtml` only
|
|
231
|
+
renders **after** the page is fully generated. So a lesson authored at the moment
|
|
232
|
+
the learner asks for it makes them **stare at a blank canvas** — worst of all on the
|
|
233
|
+
very first lesson of a brand-new course. The fix: author **ahead of time, in a
|
|
234
|
+
parallel background session**, so the page is already on disk (and the record's
|
|
235
|
+
`lesson` field set) by the time the learner opens it. Then you just present it by
|
|
236
|
+
`path`, instantly.
|
|
237
|
+
|
|
238
|
+
The tool is **`spawnBackgroundChat({ message, role, hidden })`** — it launches a
|
|
239
|
+
second, independent agent session that runs **concurrently** with this conversation
|
|
240
|
+
and returns immediately. To pre-author one lesson:
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
spawnBackgroundChat({
|
|
244
|
+
role: "tutor",
|
|
245
|
+
hidden: true,
|
|
246
|
+
message: "<a fully self-contained instruction — see the rules below>"
|
|
247
|
+
})
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Rules for the worker:
|
|
251
|
+
|
|
252
|
+
- **`hidden: true`, always.** These are plumbing, not conversations — a visible
|
|
253
|
+
worker would clutter the learner's chat history. (`hidden: false` exists for other
|
|
254
|
+
uses where the user *should* see the spawned chat; a lesson worker is never that.)
|
|
255
|
+
- **The `message` must be fully self-contained** — the worker shares NONE of this
|
|
256
|
+
chat's context. Spell out: read the record at
|
|
257
|
+
`data/lessons-<topic>/items/<id>.json`; author a self-contained HTML page **from
|
|
258
|
+
its `objective`** (full `<!DOCTYPE html>`, inline CSS/JS or an allowed CDN — see
|
|
259
|
+
`config/helps/presenthtml.md`); **`Write`** it to
|
|
260
|
+
`artifacts/html/lessons-<topic>/<id>.html`; set that path as the record's `lesson`
|
|
261
|
+
field with `manageCollection` putItems `mode: "merge"` (`{ id, lesson }` — merge
|
|
262
|
+
keeps every other field); do **NOT** call `presentHtml` and do **NOT** present
|
|
263
|
+
anything — just write the files and stop. (No one is viewing the worker's canvas,
|
|
264
|
+
so presenting there is wasted.)
|
|
265
|
+
- **One lesson per call**, and don't spawn a fleet — the host caps concurrent hidden
|
|
266
|
+
workers and a worker can't spawn further workers.
|
|
267
|
+
|
|
268
|
+
**When to pre-author:**
|
|
269
|
+
|
|
270
|
+
1. **At course creation — pre-author lesson 1 (optionally 2).** Right after
|
|
271
|
+
`presentCollection` shows the roadmap, fire a worker for lesson 1 and tell the
|
|
272
|
+
learner it's being prepared (e.g. "コースができました!最初のレッスンを準備中です。
|
|
273
|
+
準備ができたら『始めて』と言ってください"). The learner reads the roadmap while the
|
|
274
|
+
page generates — the wait now **overlaps** with something useful instead of being
|
|
275
|
+
dead air. Do **not** also author lesson 1 inline in the same turn.
|
|
276
|
+
2. **Prefetch the next lesson the moment you present the current one — not at the
|
|
277
|
+
end.** As soon as lesson N's page is on screen (*before* you teach or quiz it),
|
|
278
|
+
fire a worker for the next-by-`order` lesson, so its generation overlaps the
|
|
279
|
+
*whole* time the learner spends on N. Waiting until you update `status`/`notes` is
|
|
280
|
+
too late — the learner often advances the instant they finish, and the wait
|
|
281
|
+
reappears. By the time they reach N+1, it's already authored → instant.
|
|
282
|
+
|
|
283
|
+
**Presenting, and the fallback.** When the learner opens a lesson, check its `lesson`
|
|
284
|
+
field: **set** → `presentHtml` by `path` (instant); **still empty** (the worker
|
|
285
|
+
hasn't finished, or never ran) → author it inline from `objective` as usual. The
|
|
286
|
+
inline path is the graceful fallback — background pre-generation is a pure
|
|
287
|
+
optimization, never a dependency. Because workers write to the **stable**
|
|
288
|
+
`artifacts/html/lessons-<topic>/<id>.html` path, a rare double-author (learner races
|
|
289
|
+
ahead of the worker) just overwrites in place — never a duplicate.
|
|
290
|
+
|
|
291
|
+
## SKILL.md
|
|
292
|
+
|
|
293
|
+
`data/skills/lessons-<topic>/SKILL.md` tells the agent when and how to operate the
|
|
294
|
+
collection. Keep it short — the schema and templates do the heavy lifting. Cover:
|
|
295
|
+
|
|
296
|
+
- **Trigger phrases** — "teach me <topic>", "what's my next lesson", "continue my
|
|
297
|
+
course", "I'm ready for the next one", plus the equivalents in the learner's
|
|
298
|
+
language.
|
|
299
|
+
- **Record shape** — point at the schema; note `id` is the filename
|
|
300
|
+
(`lesson-<order3>-<slug>`, e.g. `lesson-001-eigenvalues`), new lessons start at
|
|
301
|
+
`status: "planned"` with an empty `lesson`, `order` is the reading sequence, and
|
|
302
|
+
`objective` is a **full paragraph** (the authoring brief), not a one-liner.
|
|
303
|
+
- **The teaching loop** —
|
|
304
|
+
- **Plan the course**: once the goal/level is known, draft the full sequence of
|
|
305
|
+
lessons as `planned` records, in `order`, so the learner can see the road
|
|
306
|
+
ahead. Give each one a **paragraph `objective`** — what that lesson must teach,
|
|
307
|
+
its key points, the intended takeaway — not just a title. That paragraph is
|
|
308
|
+
what makes deferred authoring work: when you write the page later, the record's
|
|
309
|
+
`objective` is the prompt you generate it from, so write it that way. Once the
|
|
310
|
+
records are written, call `presentCollection` **once** to show the roadmap (this
|
|
311
|
+
also surfaces any malformed records right away). **Then immediately fire a hidden
|
|
312
|
+
`spawnBackgroundChat` worker to pre-author lesson 1** and tell the learner it's
|
|
313
|
+
being prepared — do NOT author lesson 1 inline in the same turn (see
|
|
314
|
+
"Pre-generating lessons in the background"). The learner reads the roadmap while
|
|
315
|
+
it generates.
|
|
316
|
+
- **Pre-author lesson 1 in the background** (then the rest just-in-time): the
|
|
317
|
+
worker above writes lesson 1's HTML to disk and sets its `lesson` path, so the
|
|
318
|
+
first open never waits. You *may* fire a second worker for lesson 2 as well.
|
|
319
|
+
Leaving the rest `planned` with an empty `lesson` and prefetching each next
|
|
320
|
+
lesson as you open the current one is the default — never pre-generate the
|
|
321
|
+
whole course up front.
|
|
322
|
+
- **Learn a lesson** (the per-lesson **Learn** button): always **deliver the page
|
|
323
|
+
with `presentHtml` first** — never jump straight to a quiz. Present by `path` if
|
|
324
|
+
`lesson` is set (usually it was pre-authored in the background), else author from
|
|
325
|
+
`objective` inline (store the returned `data.filePath`) as the fallback. **The
|
|
326
|
+
moment the page is shown — before teaching or quizzing — prefetch the next lesson**
|
|
327
|
+
with a hidden `spawnBackgroundChat` worker, so its generation overlaps this whole
|
|
328
|
+
lesson rather than starting at the end. Then branch on `status`:
|
|
329
|
+
`planned`/`learning` → teach + quiz (→ `learning`/`practiced`);
|
|
330
|
+
`practiced`/`mastered` → review quiz (→ `mastered`, or back to `learning` if
|
|
331
|
+
shaky). Record gaps in `notes`.
|
|
332
|
+
- **Continue the course** (the header **Learn** button, `continue` action): from
|
|
333
|
+
the progress summary, resume a `learning` lesson, else start the lowest-`order`
|
|
334
|
+
`planned` one, else review a `practiced` lesson; **prefetch the next lesson the
|
|
335
|
+
moment you present the current one** (not after running it) — and only once
|
|
336
|
+
everything is `mastered`, append the next batch of `planned` lessons (paragraph
|
|
337
|
+
`objective` each, HTML authored lazily later).
|
|
338
|
+
- **Operations** — record I/O via `manageCollection` (`getItems` to read;
|
|
339
|
+
`putItems` for schema-validated writes — `mode: "create"` for new lessons,
|
|
340
|
+
`mode: "merge"` with a partial row for status/notes/lesson updates so the
|
|
341
|
+
fields you omit survive; Delete removes the file at
|
|
342
|
+
`data/lessons-<topic>/items/<id>.json`; raw Read / Write / Edit is the
|
|
343
|
+
escape hatch). Rather than dumping the whole course into chat,
|
|
344
|
+
point the user at `/collections/lessons-<topic>`.
|
|
345
|
+
- **When to call `presentCollection`** — when the **course itself** changes: after
|
|
346
|
+
creating the collection or adding/extending lessons (it also surfaces malformed
|
|
347
|
+
records). Do **not** call it after each individual lesson's teach/review — a
|
|
348
|
+
single `status` update doesn't need the whole board re-rendered; that's just
|
|
349
|
+
noise mid-lesson.
|
|
350
|
+
|
|
351
|
+
## A record on disk
|
|
352
|
+
|
|
353
|
+
One JSON per lesson — `lesson` is empty until the lesson is taught. Note the
|
|
354
|
+
`objective` is a full paragraph (the brief the page will be authored from), not a
|
|
355
|
+
one-liner:
|
|
356
|
+
|
|
357
|
+
```json
|
|
358
|
+
{ "id": "lesson-001-eigenvalues", "order": 1, "title": "What an eigenvalue is", "status": "planned", "objective": "Teach that an eigenvector is a direction a matrix only scales (never rotates), and its eigenvalue is the scale factor. Cover the geometric picture first (a transformation acting on a few vectors, most changing direction, a special one not), then the equation Av = λv. The takeaway: the learner can look at a 2x2 transformation and point to which directions are eigenvectors. Keep it geometric — defer the characteristic-polynomial algebra to a later lesson." }
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
After teaching, the same record gains its artifact link:
|
|
362
|
+
|
|
363
|
+
```json
|
|
364
|
+
{ "id": "lesson-001-eigenvalues", "order": 1, "title": "What an eigenvalue is", "status": "learning", "objective": "Teach that an eigenvector is a direction a matrix only scales (never rotates), and its eigenvalue is the scale factor. Cover the geometric picture first, then Av = λv. Takeaway: spot eigenvectors of a 2x2 transformation by eye. Keep it geometric.", "lesson": "artifacts/html/lessons-linear-algebra/lesson-001-eigenvalues.html", "resources": "- [3Blue1Brown](https://www.3blue1brown.com/)", "notes": "Solid on the geometry; revisit the algebra next time." }
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## What the learner gets, with zero host code
|
|
368
|
+
|
|
369
|
+
- **Table** — the whole course in `order`, each row showing its `status` and a
|
|
370
|
+
clickable link to the rendered lesson. The `status` dropdown edits inline.
|
|
371
|
+
- **Kanban** — columns from `status`; the course as a progress pipeline. Drag a
|
|
372
|
+
card to promote/demote a lesson, or run an entire review pass by dragging.
|
|
373
|
+
- **Learn button (per lesson)** — one tap starts a fresh Tutor chat seeded with
|
|
374
|
+
that lesson; it teaches or reviews based on the lesson's `status`, so there's
|
|
375
|
+
nothing to decide.
|
|
376
|
+
- **Learn button (header)** — seeds a Tutor chat with the whole course's progress
|
|
377
|
+
and resumes where you left off — picking the next lesson, or growing the course
|
|
378
|
+
once everything's mastered.
|
|
379
|
+
- Because each lesson is its own file, the course is fully diffable and portable;
|
|
380
|
+
the learner owns it as plain JSON plus the HTML artifacts.
|
|
381
|
+
|
|
382
|
+
## Extending it
|
|
383
|
+
|
|
384
|
+
- **Spaced review reminders.** Add a `reviewBy` (`date`) field plus
|
|
385
|
+
`"completionField": "status"`, `"completionDoneValues": ["mastered"]`,
|
|
386
|
+
`"triggerField": "reviewBy"`, and a `"notifyWhen": { "field": "status", "in":
|
|
387
|
+
["practiced", "mastered"] }`. The bell then nudges the learner to review a
|
|
388
|
+
taught lesson on its `reviewBy` date — without belling every `planned` lesson.
|
|
389
|
+
- **The mission / goal.** For a durable record of *why* the learner is studying,
|
|
390
|
+
add a `singleton` companion collection (`lessons-<topic>-goal`, `singleton:
|
|
391
|
+
"goal"`) with `goal`, `level`, and `target` fields — read it at the start of
|
|
392
|
+
every session to resume without re-interviewing.
|
|
393
|
+
- **A "mastered" checkbox.** Add a `toggle` projecting `status`
|
|
394
|
+
(`"field": "status", "onValue": "mastered", "offValue": "practiced"`) for a
|
|
395
|
+
one-click way to mark a reviewed lesson done.
|
|
396
|
+
- **Prerequisites.** Add a `ref` field pointing back into the same collection to
|
|
397
|
+
record which lesson must come first — useful for non-linear curricula.
|
|
398
|
+
|
|
399
|
+
Keep additions minimal — the core fields (`order`, `title`, `status`,
|
|
400
|
+
`objective`, `lesson`) are enough to start teaching a tracked course today.
|