coursmith 0.0.0-stage → 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.
@@ -0,0 +1,143 @@
1
+ # Animation presets
2
+
3
+ Animations are declared, not coded: you choose a preset and give it parameters, and the portal renders it
4
+ with consistent motion and styling (and shows a static version to learners who prefer reduced motion).
5
+ Use an animation block as a step's `visual` or among its `blocks`:
6
+
7
+ ```json
8
+ { "type": "animation", "caption": "Optional caption", "animation": { "preset": "…", "…": "…" } }
9
+ ```
10
+
11
+ Pick the preset that matches the idea, not the one that looks busiest:
12
+
13
+ | Preset | Shows | Use it for |
14
+ |---|---|---|
15
+ | `sequence` | Items appearing one after another | Lists of parts, ingredients, features, principles |
16
+ | `flow` | Nodes connected by arrows with moving particles | Causes and effects, data or energy flowing through a system |
17
+ | `timeline` | Dated events along a line | History, project phases, evolution of an idea |
18
+ | `process` | Numbered stages revealed in order | Procedures and pipelines with a clear order |
19
+ | `compare` | Before/after slider | Contrasting two states, a wrong vs right approach |
20
+ | `counter` | Numbers counting up to a value | Orders of magnitude, key statistics |
21
+ | `highlight-svg` | Your SVG with parts highlighted one by one | Anatomy of an object, parts of a diagram or interface |
22
+
23
+ All examples below pass `coursmith validate`.
24
+
25
+ ## sequence
26
+
27
+ - `layout`: `row` (default), `column` or `grid`.
28
+ - `items`: 2–12, each `label` (≤ 80 chars), optional `description` (≤ 240) and `icon` (a single emoji).
29
+
30
+ ```json animation
31
+ {
32
+ "preset": "sequence",
33
+ "layout": "grid",
34
+ "items": [
35
+ { "label": "Sun", "icon": "☀️", "description": "Solar panels convert light." },
36
+ { "label": "Wind", "icon": "🌬️", "description": "Turbines convert moving air." },
37
+ { "label": "Water", "icon": "💧", "description": "Dams convert falling water." }
38
+ ]
39
+ }
40
+ ```
41
+
42
+ ## flow
43
+
44
+ - `direction`: `LR` (left to right, default) or `TB` (top to bottom).
45
+ - `nodes`: 2–12, each with an `id` (lowercase-dash) and `label` (≤ 60).
46
+ - `edges`: 1–24, each `from` and `to` (node ids) and an optional short `label` (≤ 40).
47
+
48
+ ```json animation
49
+ {
50
+ "preset": "flow",
51
+ "direction": "LR",
52
+ "nodes": [
53
+ { "id": "sun", "label": "Sunlight" },
54
+ { "id": "panel", "label": "Solar panel" },
55
+ { "id": "inverter", "label": "Inverter" },
56
+ { "id": "home", "label": "Home" }
57
+ ],
58
+ "edges": [
59
+ { "from": "sun", "to": "panel" },
60
+ { "from": "panel", "to": "inverter", "label": "DC" },
61
+ { "from": "inverter", "to": "home", "label": "AC" }
62
+ ]
63
+ }
64
+ ```
65
+
66
+ ## timeline
67
+
68
+ - `events`: 2–16, each `date` (free text ≤ 40, e.g. `1882`, `Q3 2024`, `Day 1`), `title` (≤ 80), optional `description`.
69
+
70
+ ```json animation
71
+ {
72
+ "preset": "timeline",
73
+ "events": [
74
+ { "date": "1831", "title": "Faraday discovers induction" },
75
+ { "date": "1882", "title": "First public power station", "description": "Pearl Street, New York." },
76
+ { "date": "1990s", "title": "Grid interconnection across Europe" }
77
+ ]
78
+ }
79
+ ```
80
+
81
+ ## process
82
+
83
+ - `steps`: 2–10, each `title` (≤ 80) and optional `description` (≤ 240). Stages are numbered automatically.
84
+
85
+ ```json animation
86
+ {
87
+ "preset": "process",
88
+ "steps": [
89
+ { "title": "Measure", "description": "Read the meter at the start of the month." },
90
+ { "title": "Subtract", "description": "Subtract it from the reading at the end." },
91
+ { "title": "Multiply", "description": "Multiply the kWh by the price per kWh." }
92
+ ]
93
+ }
94
+ ```
95
+
96
+ ## compare
97
+
98
+ - `before` and `after`: each a `label` (≤ 60) plus `text` (≤ 400) and/or `asset` (an image or svg asset id).
99
+ At least one of `text` or `asset` is required on each side.
100
+
101
+ ```json animation
102
+ {
103
+ "preset": "compare",
104
+ "before": { "label": "Incandescent bulb", "text": "60 W for 800 lumens; most energy becomes heat." },
105
+ "after": { "label": "LED bulb", "text": "9 W for the same 800 lumens." }
106
+ }
107
+ ```
108
+
109
+ ## counter
110
+
111
+ - `items`: 1–6, each `label`, `to` (target number), optional `from` (default 0), `unit` (≤ 12 chars) and
112
+ `decimals` (0–4, default 0).
113
+
114
+ ```json animation
115
+ {
116
+ "preset": "counter",
117
+ "items": [
118
+ { "label": "Transmission line", "to": 380000, "unit": "V" },
119
+ { "label": "Home socket", "to": 230, "unit": "V" },
120
+ { "label": "Efficiency", "to": 93.5, "unit": "%", "decimals": 1 }
121
+ ]
122
+ }
123
+ ```
124
+
125
+ ## highlight-svg
126
+
127
+ - `asset`: an asset of kind `svg`.
128
+ - `highlights`: 1–12, each `elementId` (the `id` attribute of an element in the SVG; letters, digits, `_`
129
+ and `-`, starting with a letter), `label` and optional `description`. Elements are highlighted in order.
130
+ - Group each highlighted part in a `<g id="...">` so the whole part lights up. The portal removes scripts,
131
+ event handlers, `<foreignObject>`, `<image>`, `<use>` and external links, but keeps ids; if an id you
132
+ reference is missing after that cleanup, the submission is sent back with `animation.unknown_element`.
133
+
134
+ ```json animation
135
+ {
136
+ "preset": "highlight-svg",
137
+ "asset": "home-panel",
138
+ "highlights": [
139
+ { "elementId": "meter", "label": "Meter", "description": "Measures the energy you use." },
140
+ { "elementId": "breakers", "label": "Circuit breakers", "description": "Protect each circuit." }
141
+ ]
142
+ }
143
+ ```
@@ -0,0 +1,277 @@
1
+ # Block catalog
2
+
3
+ Every step has `blocks` (the text and media the learner reads, in order) and an optional `visual` (the
4
+ step's main illustration). The portal shows the visual pinned beside the text in scrollytelling, split
5
+ screen in the stepper and slides, and inline in document mode.
6
+
7
+ - `blocks` accepts: `markdown`, `callout`, `image`, `code`, `math`, `table`, `quote`, `chart`, `diagram`, `animation`.
8
+ - `visual` accepts: `chart`, `diagram`, `animation`, `image`.
9
+ - Unknown keys are rejected everywhere. Optional `caption` fields are shown under the element.
10
+
11
+ All examples below pass `coursmith validate`.
12
+
13
+ ## Step skeleton
14
+
15
+ ```json step
16
+ {
17
+ "id": "why-high-voltage",
18
+ "title": "Why high voltage?",
19
+ "visual": { "type": "diagram", "syntax": "mermaid", "code": "flowchart LR\n A[Plant] --> B[Lines] --> C[Homes]" },
20
+ "blocks": [
21
+ { "type": "markdown", "text": "Wires waste energy as heat, so the grid raises the [[voltage]]." }
22
+ ]
23
+ }
24
+ ```
25
+
26
+ ## Text blocks
27
+
28
+ ### markdown
29
+
30
+ Paragraphs, lists, **bold**, *italic*, `inline code` and links. Rules:
31
+
32
+ - No raw HTML (`<br>`, `<b>`, `<script>`…). No Markdown images: use an `image` block.
33
+ - Links must start with `https://`.
34
+ - Mark glossary terms as `[[term]]` or `[[term|text shown]]`. The term must be defined in the glossary of
35
+ this section or an earlier one (its `term` or one of its `aliases`, case-insensitive).
36
+ - Keep one idea per block; prefer several short blocks to one long one.
37
+
38
+ ```json block
39
+ {
40
+ "type": "markdown",
41
+ "text": "A [[transformer]] changes the [[voltage|voltage level]] of alternating current.\n\n- Step-up: raises it for transmission\n- Step-down: lowers it for homes\n\nMore on [Wikipedia](https://en.wikipedia.org/wiki/Transformer)."
42
+ }
43
+ ```
44
+
45
+ ### callout
46
+
47
+ `variant` is one of `info`, `tip`, `warning`, `example`. `title` is optional.
48
+
49
+ ```json block
50
+ { "type": "callout", "variant": "warning", "title": "Safety first", "text": "Never open an electrical panel yourself." }
51
+ ```
52
+
53
+ ### quote
54
+
55
+ ```json block
56
+ { "type": "quote", "text": "Nothing in life is to be feared, it is only to be understood.", "cite": "Marie Curie" }
57
+ ```
58
+
59
+ ### code
60
+
61
+ `language` is a lowercase highlighter name such as `python`, `ts`, `js`, `bash`, `sql`, `json`, `c++`, `c#`.
62
+
63
+ ```json block
64
+ { "type": "code", "language": "python", "code": "power_kw = 2\nhours = 1.5\nprint(power_kw * hours) # 3.0 kWh", "caption": "Energy = power × time" }
65
+ ```
66
+
67
+ ### math
68
+
69
+ LaTeX rendered with KaTeX. Escape backslashes in JSON (`\\frac`).
70
+
71
+ ```json block
72
+ { "type": "math", "tex": "E = P \\times t", "caption": "Energy equals power times time." }
73
+ ```
74
+
75
+ ### table
76
+
77
+ `headers` has 1–10 columns; every row must have exactly as many cells as `headers`. Up to 50 rows.
78
+
79
+ ```json block
80
+ {
81
+ "type": "table",
82
+ "headers": ["Device", "Power", "Energy in 2 h"],
83
+ "rows": [["Oven", "2 kW", "4 kWh"], ["LED bulb", "10 W", "0.02 kWh"]],
84
+ "caption": "Typical household devices"
85
+ }
86
+ ```
87
+
88
+ ## Media blocks and visuals
89
+
90
+ ### image
91
+
92
+ Refers to an entry of `assets` by id. Raster images (`png`, `jpg`, `webp`) and `svg` are accepted.
93
+
94
+ ```json visual
95
+ { "type": "image", "asset": "home-panel", "caption": "A typical home electrical panel" }
96
+ ```
97
+
98
+ The matching asset entry:
99
+
100
+ ```json asset
101
+ { "id": "home-panel", "kind": "svg", "file": "assets/home-panel.svg", "alt": "Electrical panel with meter, main switch and four breakers", "generatedBy": "hand-written SVG" }
102
+ ```
103
+
104
+ ### chart (Vega-Lite)
105
+
106
+ A [Vega-Lite v6](https://vega.github.io/vega-lite/) spec. Rules:
107
+
108
+ - Data must be inline in `data.values`. Any `url` (data or images) and any `href` are rejected.
109
+ - Keep it small (well under 200 KB): aggregate before charting.
110
+ - Give axes readable titles in the course language; label illustrative numbers as such in the `caption`.
111
+ - Leave size and colors to the portal's theme (light and dark) unless a color carries meaning.
112
+
113
+ ```json visual
114
+ {
115
+ "type": "chart",
116
+ "title": "Share of household consumption",
117
+ "caption": "Illustrative figures.",
118
+ "spec": {
119
+ "data": { "values": [
120
+ { "use": "Heating", "share": 45 },
121
+ { "use": "Appliances", "share": 30 },
122
+ { "use": "Lighting", "share": 10 },
123
+ { "use": "Other", "share": 15 }
124
+ ] },
125
+ "mark": { "type": "arc", "innerRadius": 50 },
126
+ "encoding": {
127
+ "theta": { "field": "share", "type": "quantitative" },
128
+ "color": { "field": "use", "type": "nominal", "title": "Use" }
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ Line and bar charts follow the usual Vega-Lite shape (`mark: "line"` / `"bar"`, `x` and `y` encodings).
135
+
136
+ ### diagram (Mermaid)
137
+
138
+ `syntax` is always `"mermaid"`. The first line must be one of these diagram types: `flowchart`, `graph`,
139
+ `sequenceDiagram`, `classDiagram`, `stateDiagram`, `stateDiagram-v2`, `erDiagram`, `gantt`, `pie`,
140
+ `journey`, `mindmap`, `timeline`, `quadrantChart`, `xychart-beta`.
141
+ Not allowed: `click` handlers, links (`href`) and `%%{init: ...}%%` directives.
142
+
143
+ ```json visual
144
+ {
145
+ "type": "diagram",
146
+ "syntax": "mermaid",
147
+ "code": "sequenceDiagram\n participant P as Plant\n participant G as Grid operator\n P->>G: Produces 500 MW\n G-->>P: Reduce output",
148
+ "caption": "The operator keeps supply and demand balanced."
149
+ }
150
+ ```
151
+
152
+ ### animation
153
+
154
+ An animation is a preset rendered by the portal from parameters. See `animation-presets.md` for all seven.
155
+
156
+ ```json visual
157
+ {
158
+ "type": "animation",
159
+ "caption": "From the plant to your home",
160
+ "animation": {
161
+ "preset": "process",
162
+ "steps": [
163
+ { "title": "Generation", "description": "A turbine spins a generator." },
164
+ { "title": "Transmission", "description": "High-voltage lines carry the power." },
165
+ { "title": "Distribution", "description": "Local lines deliver 230 V." }
166
+ ]
167
+ }
168
+ }
169
+ ```
170
+
171
+ ## Questions
172
+
173
+ ### check (end of a step, not scored)
174
+
175
+ Types `single`, `multiple`, `true_false`. Option ids are short lowercase strings such as `a`, `b`, `c`.
176
+
177
+ ```json check
178
+ {
179
+ "id": "check-transformer",
180
+ "type": "single",
181
+ "prompt": "What does a transformer change?",
182
+ "options": [
183
+ { "id": "a", "text": "The voltage" },
184
+ { "id": "b", "text": "The frequency" },
185
+ { "id": "c", "text": "The colour of the wires" }
186
+ ],
187
+ "correct": "a",
188
+ "explanation": "Transformers raise or lower voltage; frequency stays the same."
189
+ }
190
+ ```
191
+
192
+ ### final quiz questions
193
+
194
+ Same as checks plus `sectionRef` (the id of the section the question tests) and the `ordering` type.
195
+
196
+ ```json question
197
+ {
198
+ "id": "q-multiple-renewables",
199
+ "sectionRef": "generation",
200
+ "type": "multiple",
201
+ "prompt": "Which of these sources are renewable?",
202
+ "options": [
203
+ { "id": "a", "text": "Wind" },
204
+ { "id": "b", "text": "Coal" },
205
+ { "id": "c", "text": "Sunlight" }
206
+ ],
207
+ "correct": ["a", "c"],
208
+ "explanation": "Wind and sunlight replenish naturally; coal is a fossil fuel."
209
+ }
210
+ ```
211
+
212
+ ```json question
213
+ {
214
+ "id": "q-true-false-frequency",
215
+ "sectionRef": "generation",
216
+ "type": "true_false",
217
+ "prompt": "The European grid runs at 50 Hz.",
218
+ "correct": true,
219
+ "explanation": "European grids use 50 Hz; North America uses 60 Hz."
220
+ }
221
+ ```
222
+
223
+ ```json question
224
+ {
225
+ "id": "q-ordering-journey",
226
+ "sectionRef": "generation",
227
+ "type": "ordering",
228
+ "prompt": "Put the journey of electricity in order.",
229
+ "items": [
230
+ { "id": "plant", "text": "Power plant" },
231
+ { "id": "lines", "text": "Transmission lines" },
232
+ { "id": "home", "text": "Home" }
233
+ ],
234
+ "explanation": "Electricity is generated, transmitted at high voltage, then distributed to homes."
235
+ }
236
+ ```
237
+
238
+ ## Glossary entries
239
+
240
+ ```json glossary
241
+ { "term": "kilowatt-hour", "aliases": ["kilowatt-hours", "kWh"], "definition": "The energy used by a 1 kW device running for one hour; the unit on electricity bills." }
242
+ ```
243
+
244
+ ## Course metadata
245
+
246
+ `category` is one of: `technology`, `programming`, `data-ai`, `science`, `mathematics`, `engineering`,
247
+ `business`, `finance`, `marketing`, `design`, `arts-music`, `languages`, `history`, `humanities`,
248
+ `health-wellness`, `environment`, `law-policy`, `personal-development`, `education`, `other`.
249
+
250
+ ```json meta
251
+ {
252
+ "title": "Come arriva l'elettricità a casa tua",
253
+ "subtitle": "Dalla centrale alla presa, passo dopo passo",
254
+ "description": "Segui il viaggio dell'energia elettrica: produzione, trasmissione ad alta tensione, rete di distribuzione e quadro elettrico di casa.",
255
+ "language": "it",
256
+ "difficulty": "beginner",
257
+ "category": "engineering",
258
+ "tags": ["energia", "rete elettrica"],
259
+ "estimatedMinutes": 30,
260
+ "learningObjectives": ["Spiegare come funziona un generatore", "Descrivere il ruolo dei trasformatori"],
261
+ "prerequisites": [],
262
+ "coverImage": "cover",
263
+ "accentColor": "#2563eb"
264
+ }
265
+ ```
266
+
267
+ ## Limits
268
+
269
+ | Item | Limit |
270
+ |---|---|
271
+ | `course.json` | 2 MB |
272
+ | One asset file | 3 MB; all assets 25 MB |
273
+ | Sections | 1–12, each 1–15 steps, 80 steps in total |
274
+ | Blocks per step | 1–20 |
275
+ | Glossary per section | 1–40 entries |
276
+ | Final quiz | 10–40 questions |
277
+ | Markdown block | 20,000 characters |
@@ -0,0 +1,47 @@
1
+ # Coursmith content policy
2
+
3
+ Courses must be educational, accurate and respectful. The review agent applies these rules to all text,
4
+ charts, diagrams, animations and images in a course.
5
+
6
+ ## Not allowed (the course is rejected)
7
+
8
+ - **Hate and harassment**: content that demeans or attacks people for ethnicity, nationality, religion,
9
+ gender, sexual orientation, disability, age or similar traits; slurs; targeted harassment of real people.
10
+ - **Blasphemy and mockery of beliefs**: content meant to insult, ridicule or desecrate religions, their
11
+ figures, symbols or believers. Neutral, factual teaching about religions, their history and critiques
12
+ presented with respect is allowed.
13
+ - **Sexual content**: explicit sexual material, sexualization of anyone, any sexual content involving minors.
14
+ - **Graphic violence or gore** presented for shock value; glorification of violence, terrorism or extremism;
15
+ extremist propaganda or recruitment.
16
+ - **Dangerous instructions**: weapons, explosives or drug synthesis; malware or intrusion techniques aimed at
17
+ real systems; self-harm or suicide methods; dangerous challenges.
18
+ - **Illegal activity**: fraud, scams, evading law enforcement, piracy guides, trafficking.
19
+ - **Deception**: deliberate disinformation, conspiracy theories presented as fact, impersonation of real
20
+ people or organizations, plagiarism of copyrighted works.
21
+ - **Spam**: advertising, affiliate links, courses whose purpose is to sell something rather than to teach.
22
+
23
+ ## Sensitive topics (allowed with care; otherwise revision is required)
24
+
25
+ Health and medicine, mental health, law, personal finance and investing, politics, religion, history of
26
+ conflicts and atrocities, sexuality education, drugs and addiction (prevention and awareness).
27
+
28
+ Courses on these topics must:
29
+ - stay factual, balanced and neutral, presenting established consensus and noting where experts disagree;
30
+ - avoid giving individual medical, legal or financial advice, and include a short disclaimer pointing
31
+ learners to qualified professionals;
32
+ - describe difficult events without graphic detail and with respect for victims.
33
+
34
+ ## Quality requirements (revision is required when not met)
35
+
36
+ - **Accuracy**: no factual errors, outdated claims presented as current, or invented data. Example figures
37
+ must be labelled as illustrative.
38
+ - **Clarity**: each step explains one idea in plain language suited to the declared difficulty; no
39
+ unexplained jumps.
40
+ - **Language**: all learner-facing text is written in the course's declared language.
41
+ - **Difficulty**: content depth matches the declared level (beginner, intermediate, advanced).
42
+ - **Glossary**: every concept introduced and every technical or domain-specific term used in a section is
43
+ defined in that section's glossary (or an earlier one), with a correct, self-contained definition.
44
+ - **Quiz**: every question has exactly the declared correct answer, unambiguous wording, plausible
45
+ distractors, and an explanation consistent with the course content.
46
+ - **Visuals**: charts, diagrams, animations and images must be relevant, correctly labelled and consistent
47
+ with the text.