Skip to content

Latest commit

 

History

History
103 lines (83 loc) · 4.25 KB

File metadata and controls

103 lines (83 loc) · 4.25 KB

Schema reference

The contract between the AI and the renderer is core/schema/analysis.schema.json (schemaVersion: 2). The AI emits a JSON object that validates against it; the tested shell renders it. The AI never writes HTML.

The core idea: a lesson is an ordered list of teaching blocks. There is no fixed page layout — structure emerges from which blocks the AI picks and in what order. A 3-block lesson and a 10-block lesson are both valid.

Top-level shape

{
  "schemaVersion": 2,                 // required — must be 2
  "meta":     { ... },                // required — title, mode, source, …
  "strategy": { ... },                // optional — the AI's teaching plan
  "blocks":   [ { "type": "",  } ]  // required — ordered teaching blocks (≥ 1)
}

meta (required)

field required notes
title lesson title, shown at the top
mode code | thinking | text
source what was analyzed, e.g. "src/lib/epr"
generatedAt ISO timestamp
audience beginner (default) | dev — the initial audience toggle state
skin aurora (default) | storybook | blueprint | terminal

strategy (optional)

The AI's teaching plan. It documents why the lesson is shaped the way it is and is useful for debugging; it does not dominate the page.

field notes
approach one-line description of the teaching approach
analogy the real-world metaphor, if one is used
why why this approach fits this subject

Blocks

blocks is an ordered array. Every block has a type and may carry a title and emoji. The remaining fields depend on the type — the renderer reads only the fields relevant to that type. Common convention: start with a hook, end with a quiz and/or recap.

type purpose key fields
hook opening line that grabs attention headline, body, kicker?
analogy map a real-world thing to the code realWorld, mapping[{from,to,note?}]
concept explain one idea, teacher voice body, technical?, code?, lang?
code show + explain a snippet code, explain, lang?
steps a narrated step-by-step walk steps[{title,body,code?,lang?}]
flow conceptual process diagram nodes[{id,label,kind?,note?}], edges[{from,to,label?}], rootId?
architecture real file map grouped into layers groups[{label,items[{id,file,role?}]}], edges[{from,to,label?}]
compare contrast two things left{label,body,code?,lang?}, right{…}
aha spotlight the key insight insight
quiz check understanding questions[{q,choices,answer,explain}]
recap the takeaways points[]
glossary define terms terms[{term,plain,technical?}]

Two-depth content

Anywhere a technical field exists, it is optional — when absent the renderer shows the plain/body text instead. This lets the audience toggle (Beginner ↔ Technical) swap depth, and lets the AI skip detail it doesn't have. Writing technical everywhere is never required.

Minimal valid example

{
  "schemaVersion": 2,
  "meta": {
    "title": "What this function does",
    "mode": "code",
    "source": "src/util/slugify.ts",
    "generatedAt": "2026-07-03T00:00:00Z"
  },
  "blocks": [
    { "type": "hook", "headline": "Turning titles into URLs", "body": "This one function makes any string safe for a web address." },
    { "type": "code", "title": "The whole thing", "lang": "ts", "code": "export const slugify = (s) => s.toLowerCase().replace(/\\s+/g, '-');", "explain": "Lowercase everything, then swap runs of spaces for hyphens." },
    { "type": "recap", "points": ["Lowercasing keeps URLs consistent.", "Hyphens replace spaces so the URL has no gaps."] }
  ]
}

For a full worked example, see the committed samples in examples/ alongside their .analysis.json sources.

Validation

core/build/inline.mjs validates the analysis against this schema before building and prints the exact failing path on error. Run it directly:

node core/build/inline.mjs analysis.json -o output.html