explico 0.14.0 → 0.15.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +112 -1
  2. package/dist/compiler/cli-main.d.ts +61 -4
  3. package/dist/compiler/cli-main.js +77 -36
  4. package/dist/compiler/cli-reference.d.ts +50 -0
  5. package/dist/compiler/cli-reference.js +213 -0
  6. package/dist/compiler/cli-verbs.d.ts +45 -0
  7. package/dist/compiler/cli-verbs.js +224 -0
  8. package/dist/compiler/cli-verify.d.ts +51 -0
  9. package/dist/compiler/cli-verify.js +151 -0
  10. package/dist/compiler/cli.d.ts +19 -50
  11. package/dist/compiler/cli.js +45 -6
  12. package/dist/compiler/content-release.d.ts +49 -0
  13. package/dist/compiler/content-release.js +63 -0
  14. package/dist/compiler/content-schemas.d.ts +2 -2
  15. package/dist/compiler/manifest.js +29 -24
  16. package/dist/compiler/page-versions.d.ts +25 -1
  17. package/dist/compiler/page-versions.js +19 -0
  18. package/dist/compiler/validate-content.js +2 -2
  19. package/dist/reference/consistency.js +7 -1
  20. package/dist/reference/diagram-fit.d.ts +5 -1
  21. package/dist/reference/diagram-fit.js +5 -1
  22. package/dist/rules/catalog.js +16 -0
  23. package/dist/rules/in-effect.d.ts +1 -1
  24. package/dist/rules/in-effect.js +5 -4
  25. package/dist/rules/rules.schema.json +21 -0
  26. package/docs/authoring/README.md +2 -0
  27. package/docs/authoring/agents.md +18 -11
  28. package/docs/authoring/cli-reference.json +2172 -0
  29. package/docs/authoring/cli.md +887 -0
  30. package/docs/authoring/deck.md +24 -0
  31. package/docs/authoring/migrating.md +168 -18
  32. package/docs/authoring/versioning.md +2 -1
  33. package/docs/course-agent/AGENTS.md +10 -7
  34. package/docs/course-agent/agents/rules-reviewer.md +2 -2
  35. package/docs/course-agent/skills/draft-lesson/SKILL.md +7 -6
  36. package/docs/course-agent/skills/migrate-course/SKILL.md +5 -4
  37. package/docs/course-agent/skills/release-content/SKILL.md +5 -3
  38. package/docs/diagram-scaling.md +2 -2
  39. package/package.json +1 -1
  40. package/src/compiler/cli-main.ts +135 -47
  41. package/src/compiler/cli-reference.ts +285 -0
  42. package/src/compiler/cli-verbs.ts +270 -0
  43. package/src/compiler/cli-verify.ts +241 -0
  44. package/src/compiler/cli.ts +77 -17
  45. package/src/compiler/content-release.ts +91 -0
  46. package/src/compiler/manifest.ts +34 -24
  47. package/src/compiler/page-versions.ts +42 -0
  48. package/src/compiler/validate-content.ts +5 -2
  49. package/src/reference/consistency.ts +13 -2
  50. package/src/reference/diagram-fit.ts +18 -4
  51. package/src/rules/catalog.ts +17 -0
  52. package/src/rules/in-effect.ts +5 -4
@@ -0,0 +1,887 @@
1
+ <!-- generated by scripts/agent/gen-cli.mjs from src/compiler/cli-verbs.ts and the report types — do not edit; `node scripts/agent/gen-cli.mjs` rewrites it, `--check` gates it -->
2
+
3
+ # The `content` CLI
4
+
5
+ Every verb of `pnpm content`, what it writes, when it exits 1, and the shape
6
+ of its `--json`. The same data, with a JSON Schema per type, is
7
+ [`cli-reference.json`](cli-reference.json); `pnpm content help <verb> [--json]`
8
+ prints one verb of it. Every verb takes `--json`: data only on stdout, and on
9
+ a failure `{ "ok": false, "error": { "code", "message" } }` ([`ErrorJson`](#errorjson)).
10
+
11
+ | Verb | You want to know or do | Writes |
12
+ | --- | --- | --- |
13
+ | [`status`](#content-status) | how the course stands | nothing |
14
+ | [`diagnostics`](#content-diagnostics) | what is wrong, where | nothing |
15
+ | [`warnings`](#content-warnings) | the warnings alone | nothing |
16
+ | [`context`](#content-context) | what a lesson draws on | nothing |
17
+ | [`equation`](#content-equation) | will this expression build | nothing |
18
+ | [`bindings`](#content-bindings) | what a lesson's math binds | nothing |
19
+ | [`symbol`](#content-symbol) | is this symbol defined already | nothing |
20
+ | [`check`](#content-check) | does it render | nothing |
21
+ | [`rule`](#content-rule) | one rule, whole | nothing |
22
+ | [`migrate`](#content-migrate) | what an upgrade needs | nothing |
23
+ | [`rules`](#content-rules) | which rules apply | nothing |
24
+ | [`move`](#content-move) | a local entry becomes shared | only with --write |
25
+ | [`rename`](#content-rename) | rename a shared card | only with --write |
26
+ | [`fix`](#content-fix) | the mechanical repairs | only with --write |
27
+ | [`new lesson`](#content-new-lesson) | a chapter to start from | new files; never overwrites |
28
+ | [`new deck`](#content-new-deck) | slides to start from | new files; never overwrites |
29
+ | [`new term`](#content-new-term) | a shared notation card to start from | new files; never overwrites |
30
+ | [`init-agent`](#content-init-agent) | install the agent procedures | only with --write |
31
+ | [`release`](#content-release) | cut a content release (rule C3) | only with --write |
32
+ | [`verify`](#content-verify) | is it ready to hand back | what validate:content and astro build write; logs and the pass record under node_modules/.cache/explico/verify/ |
33
+ | [`help`](#content-help) | a verb's flags and its --json shape | nothing |
34
+
35
+ ## content status
36
+
37
+ ```text
38
+ pnpm content status [--json]
39
+ ```
40
+
41
+ - **For:** how the course stands
42
+ - **Prints:** counts, diagnostic totals, the knowledge and page versions, the agent surfaces' sizes, whether the course's AGENTS.md points at the engine's guide and the procedures are installed
43
+ - **Writes:** nothing
44
+ - **Exits 1:** on a usage error
45
+
46
+ `--json`: [`StatusReport`](#statusreport)
47
+
48
+ ## content diagnostics
49
+
50
+ ```text
51
+ pnpm content diagnostics [info|warning|error] [--all | --code <c> | --lesson <id> | --changed] [--json]
52
+ ```
53
+
54
+ - **For:** what is wrong, where
55
+ - **Prints:** counts by code (with each code's rule) and by file, at the given severity or higher (info by default); a filter or --all lists the lines instead. --json always prints the lines
56
+ - **Writes:** nothing
57
+ - **Exits 1:** on a usage error
58
+
59
+ | Flag | Effect |
60
+ | --- | --- |
61
+ | `--all` | list every diagnostic instead of the counts |
62
+ | `--code <c>` | only that diagnostic code |
63
+ | `--lesson <id>` | only that lesson's file |
64
+ | `--changed` | only lessons whose .mdx or .checks.yml differs from git HEAD, tracked or not |
65
+
66
+ `--json`: [`DiagnosticsReport`](#diagnosticsreport)
67
+
68
+ ## content warnings
69
+
70
+ ```text
71
+ pnpm content warnings [--json]
72
+ ```
73
+
74
+ - **For:** the warnings alone
75
+ - **Prints:** every warning, one line each with its rule, then the count
76
+ - **Writes:** nothing
77
+ - **Exits 1:** on a usage error
78
+
79
+ `--json`: [`WarningsReport`](#warningsreport)
80
+
81
+ ## content context
82
+
83
+ ```text
84
+ pnpm content context <lesson> [--json]
85
+ ```
86
+
87
+ - **For:** what a lesson draws on
88
+ - **Prints:** its outcomes, notation, sources, diagnostics and token counts; --json adds the body, the floats it can reference, its sections and domain signatures
89
+ - **Writes:** nothing
90
+ - **Exits 1:** on a usage error
91
+
92
+ `--json`: [`ContextReport`](#contextreport)
93
+
94
+ ## content equation
95
+
96
+ ```text
97
+ pnpm content equation "<latex>" [--lesson <id>] [--json]
98
+ ```
99
+
100
+ - **For:** will this expression build
101
+ - **Prints:** each glyph's card, unresolved glyphs with where they are defined
102
+ - **Writes:** nothing
103
+ - **Exits 1:** on a usage error, and when the build would refuse the expression
104
+
105
+ | Flag | Effect |
106
+ | --- | --- |
107
+ | `--lesson <id>` | resolve against that lesson's local notation as well as the shared cards |
108
+
109
+ `--json`: [`EquationReport`](#equationreport)
110
+
111
+ ## content bindings
112
+
113
+ ```text
114
+ pnpm content bindings <lesson> [--json]
115
+ ```
116
+
117
+ - **For:** what a lesson's math binds
118
+ - **Prints:** every math span: its bindings, unresolved glyphs, redundant `\explain` wraps
119
+ - **Writes:** nothing
120
+ - **Exits 1:** on a usage error
121
+
122
+ `--json`: [`BindingsReport`](#bindingsreport)
123
+
124
+ ## content symbol
125
+
126
+ ```text
127
+ pnpm content symbol <latex | key> [--json]
128
+ ```
129
+
130
+ - **For:** is this symbol defined already
131
+ - **Prints:** the shared card, each local entry with its lesson, each gloss with its card, near misses
132
+ - **Writes:** nothing
133
+ - **Exits 1:** on a usage error
134
+
135
+ `--json`: [`SymbolReport`](#symbolreport)
136
+
137
+ ## content check
138
+
139
+ ```text
140
+ pnpm content check <lesson | deck>… [--changed] [--json]
141
+ ```
142
+
143
+ - **For:** does it render
144
+ - **Prints:** ok or FAIL per lesson: schema, references, MDX → KaTeX; each error and warning with its rule, the info counted by code
145
+ - **Writes:** nothing
146
+ - **Exits 1:** on a usage error, and when a lesson has an error
147
+
148
+ | Flag | Effect |
149
+ | --- | --- |
150
+ | `--changed` | the lessons whose .mdx or .checks.yml differs from git HEAD, tracked or not |
151
+
152
+ `--json`: [`CheckReport`](#checkreport)
153
+
154
+ ## content rule
155
+
156
+ ```text
157
+ pnpm content rule <ID> [--json]
158
+ ```
159
+
160
+ - **For:** one rule, whole
161
+ - **Prints:** the entry as this course has it (enforcement, codes, settings in effect) and the rule page's section, example included
162
+ - **Writes:** nothing
163
+ - **Exits 1:** on a usage error, and for an ID the catalog and the course rules do not know
164
+
165
+ `--json`: [`RuleReport`](#rulereport)
166
+
167
+ ## content migrate
168
+
169
+ ```text
170
+ pnpm content migrate [--from <version>] [--to <version>] [--json]
171
+ ```
172
+
173
+ - **For:** what an upgrade needs
174
+ - **Prints:** the migration guide's sections between the version package.json pins at git HEAD and the one installed, oldest first
175
+ - **Writes:** nothing
176
+ - **Exits 1:** on a usage error, and when a section between the two versions is missing
177
+
178
+ | Flag | Effect |
179
+ | --- | --- |
180
+ | `--from <version>` | start here instead of the version pinned at HEAD |
181
+ | `--to <version>` | stop here instead of the installed version |
182
+
183
+ `--json`: [`MigrateReport`](#migratereport)
184
+
185
+ ## content rules
186
+
187
+ ```text
188
+ pnpm content rules [--element <e>[,<e>]] [--enforcement script|partial|guide|locked] [--edition chapter|deck] [--json]
189
+ ```
190
+
191
+ - **For:** which rules apply
192
+ - **Prints:** the rules this course has on, by element, with enforcement, codes, settings in effect and a one-line summary
193
+ - **Writes:** nothing
194
+ - **Exits 1:** on a usage error
195
+
196
+ | Flag | Effect |
197
+ | --- | --- |
198
+ | `--element <e>[,<e>]` | only rules about these elements (prose, table, notation, …) |
199
+ | `--enforcement <kind>` | only script, partial, guide or locked rules |
200
+ | `--edition <edition>` | chapter (the default) or deck: the rules for that edition's pages |
201
+
202
+ `--json`: [`RulesJson`](#rulesjson)
203
+
204
+ ## content move
205
+
206
+ ```text
207
+ pnpm content move <lesson>:<key> [--to <key>] [--write] [--json]
208
+ ```
209
+
210
+ - **For:** a local entry becomes shared
211
+ - **Prints:** the new card and every copy and reference that changes, as a diff
212
+ - **Writes:** only with --write
213
+ - **Exits 1:** on a usage error
214
+
215
+ | Flag | Effect |
216
+ | --- | --- |
217
+ | `--to <key>` | the shared card's key, when it differs from the local one |
218
+ | `--write` | apply the edits; without it the diff is printed and nothing changes |
219
+
220
+ `--json`: [`EditPlanJson`](#editplanjson)
221
+
222
+ ## content rename
223
+
224
+ ```text
225
+ pnpm content rename <old> <new> [--write] [--json]
226
+ ```
227
+
228
+ - **For:** rename a shared card
229
+ - **Prints:** the card file and every reference, as a diff
230
+ - **Writes:** only with --write
231
+ - **Exits 1:** on a usage error
232
+
233
+ | Flag | Effect |
234
+ | --- | --- |
235
+ | `--write` | apply the edits; without it the diff is printed and nothing changes |
236
+
237
+ `--json`: [`EditPlanJson`](#editplanjson)
238
+
239
+ ## content fix
240
+
241
+ ```text
242
+ pnpm content fix <lesson>… | --all [--write] [--json]
243
+ ```
244
+
245
+ - **For:** the mechanical repairs
246
+ - **Prints:** redundant `\explain` wraps unwrapped, as a diff
247
+ - **Writes:** only with --write
248
+ - **Exits 1:** on a usage error
249
+
250
+ | Flag | Effect |
251
+ | --- | --- |
252
+ | `--all` | every lesson; the ones with nothing to fix are counted |
253
+ | `--write` | apply the edits; without it the diff is printed and nothing changes |
254
+
255
+ `--json`: [`EditPlanJson`](#editplanjson)
256
+
257
+ ## content new lesson
258
+
259
+ ```text
260
+ pnpm content new lesson <id> [--json]
261
+ ```
262
+
263
+ - **For:** a chapter to start from
264
+ - **Prints:** the files it created: the .mdx and its .checks.yml
265
+ - **Writes:** new files; never overwrites
266
+ - **Exits 1:** on a usage error
267
+
268
+ `--json`: [`NewJson`](#newjson)
269
+
270
+ ## content new deck
271
+
272
+ ```text
273
+ pnpm content new deck <lesson | part> [--json]
274
+ ```
275
+
276
+ - **For:** slides to start from
277
+ - **Prints:** the deck it drafted from the chapter (or the part's chapters)
278
+ - **Writes:** new files; never overwrites
279
+ - **Exits 1:** on a usage error
280
+
281
+ `--json`: [`NewJson`](#newjson)
282
+
283
+ ## content new term
284
+
285
+ ```text
286
+ pnpm content new term <key> [--json]
287
+ ```
288
+
289
+ - **For:** a shared notation card to start from
290
+ - **Prints:** the card file it created
291
+ - **Writes:** new files; never overwrites
292
+ - **Exits 1:** on a usage error
293
+
294
+ `--json`: [`NewJson`](#newjson)
295
+
296
+ ## content init-agent
297
+
298
+ ```text
299
+ pnpm content init-agent [--write] [--json]
300
+ ```
301
+
302
+ - **For:** install the agent procedures
303
+ - **Prints:** the skills and the rules-reviewer agent it would copy into .claude/, and a baseline AGENTS.md when the course has none; rerun after an upgrade
304
+ - **Writes:** only with --write
305
+ - **Exits 1:** on a usage error
306
+
307
+ | Flag | Effect |
308
+ | --- | --- |
309
+ | `--write` | apply the edits; without it the diff is printed and nothing changes |
310
+
311
+ `--json`: [`EditPlanJson`](#editplanjson)
312
+
313
+ ## content release
314
+
315
+ ```text
316
+ pnpm content release [major|minor|patch] [--write] [--json]
317
+ ```
318
+
319
+ - **For:** cut a content release (rule C3)
320
+ - **Prints:** ## [Unreleased] in content/CHANGELOG.md becoming a dated ## [x.y.z] heading and about.version becoming x.y.z, as a diff; the bump defaults to what the section's headings imply (Breaking or Removed → major, Added → minor, else patch)
321
+ - **Writes:** only with --write
322
+ - **Exits 1:** on a usage error
323
+
324
+ | Flag | Effect |
325
+ | --- | --- |
326
+ | `--write` | apply the edits; without it the diff is printed and nothing changes |
327
+
328
+ `--json`: [`EditPlanJson`](#editplanjson)
329
+
330
+ ## content verify
331
+
332
+ ```text
333
+ pnpm content verify [--e2e] [--force] [--json]
334
+ ```
335
+
336
+ - **For:** is it ready to hand back
337
+ - **Prints:** one line per step — validate:content, check --changed, astro check, the course's tests, astro build, and with --e2e the browser tests — and the tail of each failed step's log; a rerun on an unchanged tree answers from the last pass
338
+ - **Writes:** what validate:content and astro build write; logs and the pass record under node_modules/.cache/explico/verify/
339
+ - **Exits 1:** on a usage error, and when a step fails
340
+
341
+ | Flag | Effect |
342
+ | --- | --- |
343
+ | `--e2e` | also run the browser tests (the course's test:e2e script, or playwright test when it has a config) |
344
+ | `--force` | run even when nothing changed since the last pass |
345
+
346
+ `--json`: [`VerifyReport`](#verifyreport)
347
+
348
+ ## content help
349
+
350
+ ```text
351
+ pnpm content help [<verb>] [--json]
352
+ ```
353
+
354
+ - **For:** a verb's flags and its --json shape
355
+ - **Prints:** the usage; with a verb, its flags, what it writes, its exit code and the shape of its --json
356
+ - **Writes:** nothing
357
+ - **Exits 1:** on a usage error, and for an unknown verb
358
+
359
+ `--json`: [`HelpJson`](#helpjson)
360
+
361
+ ## The `--json` types
362
+
363
+ A `?` marks a property that may be absent.
364
+
365
+ ### BindingsReport
366
+
367
+ ```ts
368
+ BindingsReport
369
+ lesson: string
370
+ file: string
371
+ scope: {…}[]
372
+ key: string
373
+ notation: string
374
+ scope: "shared" | "local"
375
+ spans: BindingsSpan[]
376
+ counts: {…}
377
+ spans: number
378
+ bindings: number
379
+ unresolved: number
380
+ wraps: number
381
+ redundantWraps: number
382
+ errors: number
383
+ ```
384
+
385
+ ### BindingsSpan
386
+
387
+ ```ts
388
+ BindingsSpan
389
+ line: number
390
+ column: number
391
+ display: boolean
392
+ latex: string
393
+ unresolved: UnresolvedGlyph[]
394
+ error?: string — The resolver rejected the span (a KaTeX parse error or a rule it enforces, N13 say); its message.
395
+ bindings: SpanBinding[]
396
+ wraps: ExplicitWrap[]
397
+ ```
398
+
399
+ ### CheckLessonResult
400
+
401
+ ```ts
402
+ CheckLessonResult
403
+ lesson: string
404
+ file: string
405
+ ok: boolean
406
+ rendered: boolean
407
+ diagnostics: CliDiagnostic[]
408
+ ```
409
+
410
+ ### CheckReport
411
+
412
+ ```ts
413
+ CheckReport
414
+ ok: boolean
415
+ lessons: CheckLessonResult[]
416
+ ```
417
+
418
+ ### CliDiagnostic
419
+
420
+ ```ts
421
+ CliDiagnostic — One normalized diagnostic. `code` is `<source>:<kind>` and always stable.
422
+ code: string
423
+ rule?: string — The catalog entry that owns the code — a rule ID (`N9`) or an invariant slug (`keyed-floats`). Absent only for a code the catalog does not know, which `tests/rules/catalog.test.ts` treats as a bug.
424
+ doc?: string — The owner's page and anchor under `docs/authoring/`, `notation.md#n4`.
425
+ severity: DiagnosticSeverity
426
+ message: string
427
+ file?: string
428
+ line?: number
429
+ column?: number
430
+ equation?: EquationLink — The keyed equation the finding sits in, when the math carries a `\label{eq:…}` — `{ key, href }`, the href being the anchor on the rendered page. A size-only finding inside a long `aligned` block is otherwise anonymous.
431
+ ```
432
+
433
+ ### CliReference
434
+
435
+ ```ts
436
+ CliReference — `docs/authoring/cli-reference.json`, whole: what `content help --json` prints.
437
+ generatedBy: string — Where it came from, and that it is generated.
438
+ verbs: ContentVerb[]
439
+ error: string — The type every verb's `--json` prints when the run fails: a stable code and a message, never a stack.
440
+ $defs: Record<string, Record<string, unknown>> — A JSON Schema of every type a verb's `--json` prints, and of every named type inside one, by name.
441
+ ```
442
+
443
+ ### ContentVerb
444
+
445
+ ```ts
446
+ ContentVerb — One verb's row.
447
+ verb: string — The command word(s): `symbol`, `new lesson`.
448
+ args: string — What follows the verb on the usage line, `--json` left out (every verb takes it).
449
+ when: string — What you want to know or do when you reach for it.
450
+ prints: string — What it prints as text.
451
+ flags: ContentVerbFlag[] — The flags, each once; a positional argument is described in `prints` or `when`.
452
+ writes: string — What it changes on disk.
453
+ exit?: string — When it exits 1, beyond a usage error.
454
+ json: string — The type its `--json` prints, by its exported name in `explico/compiler/cli`, `cli-main` or `cli-verify`.
455
+ ```
456
+
457
+ ### ContentVerbFlag
458
+
459
+ ```ts
460
+ ContentVerbFlag — One flag a verb takes.
461
+ flag: string — As typed: `--lesson <id>`, `--write`.
462
+ description: string
463
+ ```
464
+
465
+ ### ContextReport
466
+
467
+ ```ts
468
+ ContextReport
469
+ lesson: {…}
470
+ id: string
471
+ slug: string
472
+ file: string
473
+ title: string
474
+ description: string
475
+ teaches: string[]
476
+ requires: string[]
477
+ assumptions: string[]
478
+ since: null | string — The version the page's content last changed in; `null` for a change not yet released (rule C5).
479
+ notationLocal: unknown
480
+ body: string
481
+ taughtOutcomes: {…}[]
482
+ id: string
483
+ outcome: string
484
+ prerequisiteOutcomes: {…}[]
485
+ id: string
486
+ outcome: string
487
+ notation: {…}[]
488
+ key: string
489
+ latex: string
490
+ meaning: string
491
+ scope: string
492
+ units?: string
493
+ formula?: string
494
+ equations: ManifestLessonFloat[]
495
+ tables: ManifestLessonFloat[]
496
+ figures: ManifestLessonFloat[]
497
+ diagrams: ManifestLessonFloat[]
498
+ examples: {…}[] — Worked-example sets: `short` is the title `[[ex-key]]` names.
499
+ key: string
500
+ number: string
501
+ short?: string
502
+ knowledgeChecks: {…}[]
503
+ key: string
504
+ number: string
505
+ title?: string
506
+ sections: {…}[] — The top-level headings: `slug` is what `[[sec-slug]]` names.
507
+ slug: string
508
+ text: string
509
+ level: number
510
+ number?: string
511
+ sources: {…}[]
512
+ id: string
513
+ title: string
514
+ type: string
515
+ recordLocator?: string
516
+ citedLocators: string[]
517
+ domainSignatures: DomainFileSignatures[]
518
+ diagnostics: CliDiagnostic[]
519
+ tokens: TokenCounts
520
+ ```
521
+
522
+ ### DiagnosticSeverity
523
+
524
+ ```ts
525
+ DiagnosticSeverity = "error" | "warning" | "info"
526
+ ```
527
+
528
+ ### DiagnosticsReport
529
+
530
+ ```ts
531
+ DiagnosticsReport
532
+ minimumSeverity: DiagnosticSeverity
533
+ count: number
534
+ diagnostics: CliDiagnostic[]
535
+ ```
536
+
537
+ ### DomainFileSignatures
538
+
539
+ ```ts
540
+ DomainFileSignatures
541
+ file: string
542
+ signatures: string[]
543
+ ```
544
+
545
+ ### EditPlanJson
546
+
547
+ ```ts
548
+ EditPlanJson — `--json` of `move`, `rename`, `fix` and `init-agent`: the plan, and whether `--write` applied it.
549
+ summary: string[]
550
+ edits: FileEdit[]
551
+ next: string[] — What to run after writing.
552
+ written: boolean — True when `--write` applied the edits; false for a dry run.
553
+ ```
554
+
555
+ ### Editions
556
+
557
+ ```ts
558
+ Editions = "chapter" | "deck" | "both"
559
+ ```
560
+
561
+ ### Element
562
+
563
+ ```ts
564
+ Element = "slide" | "prose" | "math" | "equation" | "notation" | "heading" | "part-page" | "plot" | "diagram" | "table" | "assessment" | "source" | "changelog" — The part of a page a rule is about. The first tag on an entry is primary.
565
+ ```
566
+
567
+ ### EquationLink
568
+
569
+ ```ts
570
+ EquationLink — The equation a finding sits in, when its math carries a `\label{eq:…}`. A location tells you where to edit; this tells you *what you are looking at*. A size-only N17 finding inside a six-line `aligned` block is otherwise anonymous — the message names delimiters, not the result they belong to — so the key and the rendered page's anchor both travel with the diagnostic.
571
+ key: string — The label's key, without the `eq:` prefix.
572
+ href: string — Where the reader sees it, e.g. `/l1-ar/ar1-basics/#eq-ar1-variance`.
573
+ ```
574
+
575
+ ### EquationReport
576
+
577
+ ```ts
578
+ EquationReport — One LaTeX string, resolved the way the gate will: against a lesson's scope, or against every shared card when no lesson is named (the table a notation entry's body and formula use). The inner loop while drafting: a few lines out, non-zero exit when the build would refuse the span.
579
+ latex: string
580
+ against: {…} | {…}
581
+ unresolved: UnresolvedGlyph[]
582
+ ok: boolean
583
+ error?: string — The resolver rejected the span (a KaTeX parse error or a rule it enforces, N13 say); its message.
584
+ bindings: SpanBinding[]
585
+ wraps: ExplicitWrap[]
586
+ ```
587
+
588
+ ### ErrorJson
589
+
590
+ ```ts
591
+ ErrorJson — `--json` of any verb whose run failed: a stable code and a message, never a stack.
592
+ ok: false
593
+ error: {…}
594
+ code: "unknown-command" | "usage" | "unknown-lesson" | "unknown-kind" | "invalid-id" | "exists" | "not-a-lesson" | "no-git" | "unknown-version" | "migration-gap" | "unknown-key" | "no-changelog" | "internal" — `internal` for an unexpected throw; every other code is stable.
595
+ message: string
596
+ ```
597
+
598
+ ### ExplicitWrap
599
+
600
+ ```ts
601
+ ExplicitWrap
602
+ key: string
603
+ inner: string
604
+ redundant: boolean — The bare `inner` resolves to exactly this card: the wrap costs tokens and binds nothing new.
605
+ ```
606
+
607
+ ### FileEdit
608
+
609
+ ```ts
610
+ FileEdit
611
+ file: string — Course-relative path.
612
+ before: null | string — `null` when the file is created.
613
+ after: null | string — `null` when the file is deleted.
614
+ ```
615
+
616
+ ### HelpJson
617
+
618
+ ```ts
619
+ HelpJson = CliReference | VerbHelpJson — `content help --json` prints the whole reference; `content help <verb> --json` that verb's rows.
620
+ ```
621
+
622
+ ### ManifestLessonFloat
623
+
624
+ ```ts
625
+ ManifestLessonFloat — One keyed float of a lesson (v21): its key and number, and its caption pair — `short` (an equation's `\caption{…}`, or the `short` prop) and, for a `<Table>` / `<Figure>` / `<Diagram>`, the long `caption`. Each is present only when the source states it as a literal.
626
+ key: string
627
+ number: string
628
+ short?: string
629
+ caption?: string
630
+ ```
631
+
632
+ ### MigrateReport
633
+
634
+ ```ts
635
+ MigrateReport
636
+ from: string
637
+ to: string
638
+ file: string
639
+ sections: MigrationSection[]
640
+ tokens: number
641
+ ```
642
+
643
+ ### MigrationSection
644
+
645
+ ```ts
646
+ MigrationSection
647
+ from: string
648
+ to: string
649
+ heading: string
650
+ markdown: string
651
+ tokens: number
652
+ ```
653
+
654
+ ### NewJson
655
+
656
+ ```ts
657
+ NewJson — `--json` of `new lesson`, `new deck` and `new term`.
658
+ ok: true
659
+ created: string[] — Course-relative paths of the files it created.
660
+ ```
661
+
662
+ ### RetiredRule
663
+
664
+ ```ts
665
+ RetiredRule — A rule that is no longer in force. It keeps its ID forever — an old commit message, review comment or waiver naming `N3` must stay unambiguous — but it is deliberately *not* a {@link RuleEntry}: nothing iterates it as a rule, it has no page in `docs/authoring/`, it is absent from the settings schema and from `build/rules-in-effect.md`, and an agent never reads it while drafting. The one place it is written out is the generated table in `docs/authoring/retired.md`, which is where a migration guide links.
666
+ id: unknown | unknown | unknown | unknown | unknown | unknown | unknown
667
+ title: string — The sentence the rule had, so an old reference to it still resolves.
668
+ date: string — `YYYY-MM-DD`.
669
+ into?: unknown | unknown | unknown | unknown | unknown | unknown | unknown — The rule it was folded into, when it was folded into one.
670
+ why: string — Why, and what changed for an author — one or two sentences.
671
+ ```
672
+
673
+ ### RuleInEffect
674
+
675
+ ```ts
676
+ RuleInEffect — One rule as `content rules --json` reports it.
677
+ id: string
678
+ kind: "rule" | "invariant"
679
+ source: "engine" | "course" — `course` for one of this course's own `X` rules; `engine` for the rest.
680
+ title: string
681
+ elements: Element[]
682
+ enforcement: "script" | "partial" | "guide" | "locked"
683
+ enabled: boolean
684
+ waivable: boolean — May be waived at one place with `{/* explico-allow <ID>: reason *\/}`.
685
+ codes: string[]
686
+ settings: Record<string, unknown>
687
+ summary: string
688
+ doc: string
689
+ editions: Editions — The edition it is about: `chapter`, `deck`, or `both`.
690
+ ```
691
+
692
+ ### RuleReport
693
+
694
+ ```ts
695
+ RuleReport — One rule, whole: the catalog entry as this course has it (enforcement, codes, settings in effect, whether it is on) and the rule page's own section, example included. About half a thousand tokens where opening the page costs twenty thousand.
696
+ id: string
697
+ status: "in-effect" | "retired" | "unknown"
698
+ rule?: RuleInEffect
699
+ retired?: RetiredRule
700
+ section?: {…} — The rule page's section for this rule, when the page is at hand.
701
+ file: string
702
+ markdown: string
703
+ tokens: number
704
+ known: string[] — For `unknown`: the IDs this course has, so the caller can pick one.
705
+ ```
706
+
707
+ ### RulesFilter
708
+
709
+ ```ts
710
+ RulesFilter
711
+ elements?: Element[] — Keep a rule whose elements (any, not just primary) include one of these.
712
+ enforcement?: "script" | "partial" | "guide" | "locked"
713
+ edition?: "chapter" | "deck" — The edition the page is for: `chapter` (the default) or `deck`.
714
+ ```
715
+
716
+ ### RulesJson
717
+
718
+ ```ts
719
+ RulesJson — `--json` of `rules`: the report without its Markdown page.
720
+ filter: RulesFilter
721
+ count: number
722
+ rules: RuleInEffect[]
723
+ ```
724
+
725
+ ### SpanBinding
726
+
727
+ ```ts
728
+ SpanBinding
729
+ token: string
730
+ key: string
731
+ how: string — The resolver's match kind; `explicit` for an `\explain` wrap.
732
+ ```
733
+
734
+ ### StatusReport
735
+
736
+ ```ts
737
+ StatusReport
738
+ knowledgeVersion: string — The course's published knowledge version (`about.version`).
739
+ agentSurfaces: {…}[] — What an agent is told to read before working, in estimated tokens: the course's `AGENTS.md`, the repository's one level up when the course is a workspace package, and the rules-in-effect page. A budget to watch; the estimate is bytes over four.
740
+ name: string
741
+ tokens: number
742
+ agentGuide: {…} — Whether the course's own `AGENTS.md` points an agent at the engine's guide (`docs/authoring/agents.md`), and whether the procedures `content init-agent` installs are in `.claude/`.
743
+ agentsFile: null | string
744
+ linksGuide: boolean
745
+ skillsInstalled: boolean
746
+ pageVersions: {…} — Rule C5: how many chapters and part pages carry a version of their own, and the slugs of those with a change `## [Unreleased]` has not released.
747
+ tracked: number
748
+ unreleased: string[]
749
+ counts: {…}
750
+ lessons: number
751
+ competencies: number
752
+ assessments: number
753
+ sources: number
754
+ tracks: number
755
+ notationDefinitions: number
756
+ keyedEquations: number
757
+ keyedTables: number
758
+ keyedFigures: number
759
+ keyedDiagrams: number
760
+ keyedExamples: number
761
+ orphans: CliDiagnostic[]
762
+ diagnostics: {…}
763
+ errors: number
764
+ warnings: number
765
+ infos: number
766
+ ```
767
+
768
+ ### SymbolHit
769
+
770
+ ```ts
771
+ SymbolHit
772
+ tier: SymbolTier
773
+ key: string
774
+ latex: string
775
+ label: string
776
+ meaning?: string
777
+ units?: string
778
+ matchedBy: "latex" | "alias" | "key" — How the query matched: the latex as written, an alias, or the key.
779
+ where: string — shared: the entry file; local: the lesson id; gloss: the owning card.
780
+ boundIn?: string[] — shared only: the pages (lessons and overview pages) whose bundle binds the card.
781
+ ```
782
+
783
+ ### SymbolReport
784
+
785
+ ```ts
786
+ SymbolReport
787
+ query: string
788
+ shared: SymbolHit[]
789
+ local: SymbolHit[]
790
+ glosses: SymbolHit[]
791
+ contains: SymbolHit[] — Entries whose latex contains the query as a glyph, not matched above.
792
+ containsTotal: number — How many `contains` candidates there were before the list was capped.
793
+ ```
794
+
795
+ ### SymbolTier
796
+
797
+ ```ts
798
+ SymbolTier = "shared" | "local" | "gloss" — Where a hit is defined: a shared card, a lesson's `notation.local`, or a card's gloss.
799
+ ```
800
+
801
+ ### TokenCounts
802
+
803
+ ```ts
804
+ TokenCounts
805
+ context: number — Tokens in the serialized `content context` payload.
806
+ docSet: number — `README.md` + `AGENTS.md` + `docs/architecture.md`.
807
+ corpus: number — Every file under `content/`.
808
+ ratio: number — `context / (docSet + corpus)`, rounded to 4 dp.
809
+ ```
810
+
811
+ ### UnresolvedGlyph
812
+
813
+ ```ts
814
+ UnresolvedGlyph
815
+ token: string
816
+ suspended?: string
817
+ lenders?: string[] — Rule N23: indexed entries whose base this bare letter is; none lends it a card.
818
+ defined: {…}[] — Where `content symbol` finds the token defined: exact hits, then near misses.
819
+ tier: SymbolTier
820
+ key: string
821
+ where: string
822
+ near: {…}[]
823
+ latex: string
824
+ key: string
825
+ ```
826
+
827
+ ### VerbHelp
828
+
829
+ ```ts
830
+ VerbHelp — One verb's row, its usage line, and a self-contained JSON Schema of its `--json`.
831
+ usage: string
832
+ schema: Record<string, unknown>
833
+ verb: string — The command word(s): `symbol`, `new lesson`.
834
+ args: string — What follows the verb on the usage line, `--json` left out (every verb takes it).
835
+ when: string — What you want to know or do when you reach for it.
836
+ prints: string — What it prints as text.
837
+ flags: ContentVerbFlag[] — The flags, each once; a positional argument is described in `prints` or `when`.
838
+ writes: string — What it changes on disk.
839
+ exit?: string — When it exits 1, beyond a usage error.
840
+ json: string — The type its `--json` prints, by its exported name in `explico/compiler/cli`, `cli-main` or `cli-verify`.
841
+ ```
842
+
843
+ ### VerbHelpJson
844
+
845
+ ```ts
846
+ VerbHelpJson — What `content help <verb> --json` prints: every verb the word names (`new` names three).
847
+ verbs: VerbHelp[]
848
+ ```
849
+
850
+ ### VerifyReport
851
+
852
+ ```ts
853
+ VerifyReport
854
+ ok: boolean
855
+ cached: boolean — True when the tree is unchanged since a pass that covered as much: nothing ran, `steps` are that pass's.
856
+ since?: string — When the recorded pass ran, for a cached answer (ISO 8601).
857
+ tree: null | string — The hash of the tree the run left, or `null` outside a git repository (then nothing is recorded).
858
+ e2e: boolean — Whether the browser tests were part of the run.
859
+ steps: VerifyStep[]
860
+ ```
861
+
862
+ ### VerifyStep
863
+
864
+ ```ts
865
+ VerifyStep
866
+ name: VerifyStepName
867
+ status: "pass" | "fail" | "skipped"
868
+ command?: string — The command it ran, as it would be typed; absent for a skipped step.
869
+ reason?: string — Why it was skipped, or why it could not start.
870
+ seconds?: number
871
+ log?: string — Course-relative path of its whole output.
872
+ tail?: string[] — The last lines of the output of a failed step.
873
+ ```
874
+
875
+ ### VerifyStepName
876
+
877
+ ```ts
878
+ VerifyStepName = "validate:content" | "check --changed" | "astro check" | "tests" | "astro build" | "e2e"
879
+ ```
880
+
881
+ ### WarningsReport
882
+
883
+ ```ts
884
+ WarningsReport
885
+ count: number
886
+ warnings: CliDiagnostic[]
887
+ ```