A BMad-Method-powered, multi-agent AI assistant for structured course development with LiaScript
Teaching-Agent helps educators design, structure, and author complete courses through guided, iterative workflows — from initial concept to published, interactive materials. It coordinates four specialized agents (teaching, visual design, learner review, and publishing) around a single project file, journal.md, that holds the entire course state.
It is editor-agnostic: the same specs build into configurations for Claude Code, GitHub Copilot, OpenAI Codex, Cursor, Windsurf, and any web chat.
Read this before the technical details below. This repository is a worked example: it shows the LiaScript toolchain in practice, using a NIS2 compliance course as the concrete case.
The repository has two layers:
- A sample course — "NIS2 Ready." A complete, self-paced course (six units) on the EU NIS2 Directive that works as a real training resource on its own. NIS2 was chosen as a fitting example because it concerns public administration and critical infrastructure, so the subject matter is directly relevant to the sectors LiaScript courses are often written for.
- The tooling behind it. A separate LiaScript document —
about-liascript.md("Behind the Scenes") — walks through the tools used to build the course — LiaScript itself, the Teaching-Agent multi-agent system, and theliaexexporter — and refers to concrete features in the course as examples. Written from scratch for readers new to all three, it documents how an interactive, accessible, standards-based Open Educational Resource is produced.
In short: the course is the example, and the tooling document explains how it was made — with open, standards-based, vendor-independent tools.
Taken verbatim from the course definition (journal.md → ## Outline → Target Audience):
Employees across ministries, public administrations, and critical-infrastructure organizations (energy, health, digital infrastructure, transport, etc.) that fall under the EU NIS2 Directive — a mixed audience of decision-makers, IT/security staff, and general employees, with no deep technical or legal background assumed.
Accordingly, the material is written at a beginner level: every legal or technical term is paraphrased in plain language before it is named, and no prior technical or legal background is assumed.
Note
The rest of this README describes the generic Teaching-Agent tooling that produced the course. For the current state and contents of the NIS2 course itself, see journal.md. For a gentle, from-scratch tour of the tools — best opened in the LiaScript viewer rather than read as raw text, since it is itself interactive — see about-liascript.md.
- How It Works
- The Four Agents
journal.md— the Single Source of Truth- The Workflow
- Installation
- Usage
- Commands Reference
- Project Structure
- Example Session
- License
Teaching-Agent follows Spec-Driven Development: you define what the course should achieve before writing any content.
- Define first, write later — start with learning objectives, audience, and scope
- Design didactics deliberately — choose teaching methods, style, and persona before materials
- Plan the structure — build a complete agenda with clear per-session goals
- Create iteratively — develop materials session-by-session, with validation gates at each step
The result is consistency, traceability, and quality across the whole course. This implements the BMad Method (Behavior-Model-Agnostic Design): defined personas, task-driven workflows, template-based outputs, and built-in validation.
Learn more:
- BMad-Method Framework — the core methodology
specs/— the complete technical specification (agents, tasks, templates, workflow)
The Teaching-Agent is the coordinator. It knows when to hand off to the other three via :agent {name}. Each agent has its own persona and command set, but they all read and write the same journal.md.
| Agent | Icon | Role | Activate with |
|---|---|---|---|
| Teaching | 🎓 | Pedagogical structure & content (default) | active on start |
| Artist | 🎨 | Visual identity, logos, image prompts | :agent artist |
| Learner | 🧑🎓 | Persona-based, learner-perspective review | :agent learner |
| Development | 🛠️ | Git, publishing, GitHub Pages | :agent development |
The Teaching-Agent proactively suggests a handoff at the right moments — e.g. :agent artist after didactics are done, :agent learner after a session is validated, or :agent development once the course passes validation.
All planning, state, reviews, and notes live in one file: journal.md. It is itself a valid LiaScript document, so the project state is also a viewable course outline. Only final teaching materials (materials/), visual assets (assets/), and publishing files (project.yaml, .github/workflows/) stay separate.
journal.md is divided into fixed sections, each owned by a task:
| Section | Filled by | Contents |
|---|---|---|
## Dashboard |
:update-dashboard (auto) |
Derived progress overview |
## Course Context |
:init-course |
Course type, terminology, conventions |
## Outline |
:create-outline |
Title, audience, learning objectives |
## Didactics |
:create-didactics |
Teaching concept, persona, difficulty |
## Visual Identity |
:create-visuals |
Colors, logo & image style |
## Templates |
:manage-templates |
LiaScript template imports & usage |
## Agenda |
:create-agenda |
Session structure |
## Sessions |
:create-session … |
Per-session skeletons, validation & persona reviews |
## Agents |
:configure-agent, :create-learner-persona |
Agent customizations, learner personas |
## Validation |
:validate-course |
Latest validation summary (publishing gate) |
## Analysis Status |
:analyze-existing |
Gap analysis for existing courses |
## Notes Backup |
:save-notes, :save-decision |
Summaries, research, decision records |
flowchart TD
INIT["**INIT** · :init-course<br/>→ Course Context"]
OUTLINE["**FOUNDATION** · :create-outline<br/>→ Outline"]
DID["**DIDACTICS** · :create-didactics<br/>→ Didactics"]
PERSONA["🧑🎓 :create-learner-persona<br/>(optional)"]
VIS["🎨 :create-visuals · :create-logo<br/>→ Visual Identity"]
AGENDA["**PLANNING** · :create-agenda<br/>→ Agenda"]
DEV["**SESSIONS** (iterative or batch)<br/>:create-session → :promote-session<br/>:coauthor-materials → :validate-course<br/>🧑🎓 :review-as-persona (optional)"]
VAL["**VALIDATION** · :validate-course<br/>→ Validation (PASS / FAIL gate)"]
PUB["🛠️ :create-project · :manage-git<br/>(optional, gated on PASS)"]
BUNDLE["**BUNDLE** · :assemble-bundle<br/>→ course-bundle/"]
INIT --> OUTLINE --> DID --> VIS --> AGENDA --> DEV --> VAL
DID -.->|optional| PERSONA -.-> VIS
VAL -->|PASS| PUB
VAL -->|PASS| BUNDLE
INIT -.->|improve-existing| ANALYZE[":analyze-existing"] -.-> DEV
style INIT fill:#0B6E75,color:#fff
style BUNDLE fill:#FF8C42,color:#fff
style VIS fill:#6B4E9B,color:#fff
style PERSONA fill:#6B4E9B,color:#fff
style PUB fill:#2E7D32,color:#fff
:init-course first asks for a course type, which sets terminology, persona, pacing, and whether an agenda is required:
| Type | Terminology | Persona | Agenda |
|---|---|---|---|
lecture-series |
session / lecture | professor | required |
self-paced |
unit / module | coach | optional |
workshop |
block / activity | facilitator | required |
single-lesson |
lesson | tutor | optional |
improve-existing |
(from existing) | (from existing) | runs :analyze-existing |
- Iterative — fully develop one session (create → promote → coauthor → validate → review), then move to the next. Focused.
- Batch — create all skeletons, then promote all, then coauthor all. Overview-first.
If you already know what you want, :scaffold replaces :init-course → :create-outline → :create-didactics → :create-agenda → :create-session with a single intake interview followed by automatic generation of the whole structure. Co-authoring stays interactive afterward.
Publishing (:create-project, :update-project) and bundling (:assemble-bundle) are blocked until :validate-course records Mode: course + Result: PASS in ## Validation. This keeps half-finished courses from being shipped.
git clone <your-repo-url> teaching-agent
cd teaching-agentThe source of truth lives in specs/. The build script renders it into the right format for each environment:
# Requires Python 3 (+ PyYAML for the navigation targets)
pip install pyyaml
python specs/build.py # build all targets
python specs/build.py claude # only Claude Code → CLAUDE.md
python specs/build.py copilot # only Copilot → .github/copilot-instructions.md
python specs/build.py nav # all "navigation" editors (claude, codex, cursor, windsurf)
python specs/build.py bundle # all "bundle" targets (copilot, web)| Target | Output file | Environment |
|---|---|---|
claude |
CLAUDE.md |
Claude Code CLI |
copilot |
.github/copilot-instructions.md |
GitHub Copilot (VS Code / Web) |
codex |
.codex/AGENTS.md |
OpenAI Codex CLI |
cursor |
.cursor/rules/agent.md |
Cursor IDE |
windsurf |
.windsurfrules |
Windsurf IDE |
web |
dist/web-bundle.md |
Web chat (paste manually) |
There are two build modes:
- Navigation (
claude,codex,cursor,windsurf): a lightweight pointer file. The agent reads each task file fromspecs/on demand — keeps context small. - Bundle (
copilot,web): one self-contained Markdown with all specs inlined, for environments without filesystem access. Pastedist/web-bundle.mdinto any chat.
The generated files are committed, so for the supported editors you can often skip the build and just open the project.
Open the project — CLAUDE.md is picked up automatically. Then issue commands directly:
:help
:init-course
.github/copilot-instructions.md is loaded automatically. In Copilot Chat:
:help
:scaffold
Open the project; the respective rules file (.cursor/rules/agent.md, .windsurfrules, .codex/AGENTS.md) is read at startup. Issue the same : commands.
Paste the contents of dist/web-bundle.md as the first message, then start with :help.
In every environment the agent introduces itself, reads journal.md if it exists, and tells you which step comes next.
| Command | Purpose |
|---|---|
:init-course |
Initialize project; choose course type; create Course Context |
:scaffold {course-type?} |
Fast-track: one interview → full structure |
:analyze-existing |
Scan an existing course and fill gaps (improve-existing) |
:create-outline |
Title, audience, 3–5 learning objectives |
:create-didactics |
Teaching concept, instructor persona, difficulty |
:create-learner-persona {name?} |
Build an evidence-based learner persona |
:create-agenda |
Structure sessions / modules |
:manage-templates {name?} |
Add & document LiaScript template imports |
:update-dashboard |
Regenerate the derived ## Dashboard |
:create-session {n} {type} {title?} |
Create a session skeleton |
:promote-session {n} {type} |
Expand skeleton into a material document (materials/{n}-{slug}/README.md in multi-file mode, or a ## chapter in root README.md in single-file mode — see specs/data/file-structure-modes.md) |
:coauthor-materials |
Interactive content co-authoring in persona |
:quick-fix {n} {type} {description} |
Targeted single-issue correction |
:validate-course [{n} {type}] |
Full course check, or single-session check |
:assemble-bundle |
Package everything into course-bundle/ |
:save-notes {type?} {title?} |
Save a summary / research / decision note |
:save-decision {title} |
Save a structured decision record (ADR) |
:configure-agent {agent} |
Customize an agent's behavior in journal.md |
:agent {character} · :list-agents |
Switch persona · list available agents |
:help · :exit |
Show actions · leave persona |
| Command | Purpose |
|---|---|
:create-visuals |
Define colors, logo & image style → Visual Identity |
:create-logo |
Generate a detailed logo prompt |
:create-image {description} |
Create an image prompt on demand |
| Command | Purpose |
|---|---|
:review-as-persona {name} {n} {type} |
Review a material as a specific learner persona |
:list-learners |
List defined learner personas |
| Command | Purpose |
|---|---|
:manage-git |
Stage, commit, push, diff, resolve conflicts |
:create-project |
Multi-file: generate project.yaml + GitHub Pages workflow. Single-file: push to GitHub, hand back the LiaScript viewer link (no project.yaml/Pages) |
:update-project |
Multi-file: update publishing config & redeploy. Single-file: push the update (viewer link stays the same) |
specs/
main.md ← web-bundle header
build.py ← config generator (run this to (re)build)
project.yaml ← example LiaScript publishing config
agents/ ← agent personas (teaching, artist, learner, development)
tasks/ ← one task definition per command
templates/ ← YAML templates for journal.md sections
checklists/ ← quality checks (used by :validate-course)
data/ ← LiaScript cheat-sheet & workflow reference
workflows/ ← course-development.yaml (the master workflow)
journal.md ← project state (single source of truth)
materials/ ← generated LiaScript course materials (multi-file mode only)
assets/ ← generated visual assets & prompts (single-file mode; nested per session under materials/ in multi-file mode)
CLAUDE.md ← generated: Claude Code config
.github/copilot-instructions.md ← generated: Copilot config
.codex/AGENTS.md ← generated: Codex config
.cursor/rules/agent.md ← generated: Cursor config
.windsurfrules ← generated: Windsurf config
dist/web-bundle.md ← generated: paste-anywhere bundle
:init-course
→ Choose "lecture-series", title "Databases Unlocked",
audience "CS undergraduates (3rd–5th semester)", language de, Sie-form
:create-outline
→ 5 learning objectives, abstract on database paradigms
:create-didactics
→ Persona: "practical professor, hands-on, browser-based examples"
:agent artist → :create-visuals
→ Teal/orange palette, consistent course image style
:agent teaching → :create-agenda
→ Blocks: file formats → key-value → document → relational SQL
:create-session 1 lecture "Data & Serialization"
:promote-session 1 lecture
:coauthor-materials
→ Add interactive DuckDB-Wasm examples and a quiz
:validate-course 1 lecture
:agent learner → :review-as-persona alex 1 lecture
→ Check cognitive load and assumed prior knowledge
:agent teaching → :validate-course # full course → PASS
:agent development → :create-project # publish to GitHub Pages
:assemble-bundle # distributable package
Boost Software License 1.0 — a permissive license allowing free use, modification, and distribution.
Ready to build your course? Start with:
:help