@jokerized/decksmith 0.6.0 → 0.8.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/README.md +29 -8
- package/dist/cli.js +619 -179
- package/dist/index.js +613 -176
- package/dist/mcp.js +554 -166
- package/dist/types/build/files.d.ts +2 -0
- package/dist/types/emit/archetypes/equation-morph.d.ts +40 -0
- package/dist/types/emit/archetypes/equation-walk.d.ts +60 -1
- package/dist/types/emit/composition.d.ts +3 -2
- package/dist/types/emit/tex.d.ts +39 -0
- package/dist/types/index.d.ts +4 -1
- package/dist/types/plan/prompt.d.ts +0 -12
- package/dist/types/render/capture.d.ts +24 -0
- package/dist/types/render/timing.d.ts +16 -0
- package/dist/types/source/fonts.d.ts +1 -1
- package/dist/types/verify/budget.d.ts +8 -1
- package/dist/types/verify/fidelity.d.ts +19 -0
- package/dist/types/verify/index.d.ts +17 -0
- package/package.json +2 -1
|
@@ -97,6 +97,8 @@ export declare function copyAudio(from: string, narration: DeckNarration, out: s
|
|
|
97
97
|
* Every glyph a document or plan can put on screen: serializing the whole object
|
|
98
98
|
* over-collects ids and TeX, but those are ASCII and the bundle only exists for
|
|
99
99
|
* CJK — over-collecting costs a few bytes, under-collecting costs a tofu box.
|
|
100
|
+
*
|
|
101
|
+
* A Latin deck gets `vendorInter` instead: nothing to subset, nothing to fetch.
|
|
100
102
|
*/
|
|
101
103
|
export declare function refreshFont(storyboard: Storyboard, source: Source, out: string, step: Step): Promise<string | undefined>;
|
|
102
104
|
export {};
|
|
@@ -1,2 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An equation becoming the next one.
|
|
3
|
+
*
|
|
4
|
+
* The keyed morph — the 3Blue1Brown move — and the one thing in the vocabulary
|
|
5
|
+
* that shows a DERIVATION rather than a statement: the terms the author keys
|
|
6
|
+
* travel from where they sit in the first line to where they sit in the second,
|
|
7
|
+
* as rigid bodies, and everything else dissolves. Which terms are keyed is the
|
|
8
|
+
* animation: `a^2+b^2=c^2` to `c^2-b^2=a^2` is a glyph riot unkeyed and a
|
|
9
|
+
* three-body exchange keyed, on the same two strings.
|
|
10
|
+
*
|
|
11
|
+
* The keying reuses `equation-walk`'s: a term is located in the TeX by normal
|
|
12
|
+
* form and wrapped in `\htmlClass{term t-<tone> ds-k-<tone>}{...}`, so KaTeX
|
|
13
|
+
* emits a real element the runtime can find. It must be found in BOTH lines
|
|
14
|
+
* to be a key at all — a term on one side only is dropped, with its legend
|
|
15
|
+
* row, exactly as the walk drops a term it cannot place.
|
|
16
|
+
*
|
|
17
|
+
* Geometry is measured in the browser, after fonts (Seam B), and the morph
|
|
18
|
+
* reaches the timeline as ONE typed `fromTo` on the host driving a GSAP plugin.
|
|
19
|
+
* See `src/emit/morph-runtime.ts` for why that, and not a callback.
|
|
20
|
+
*/
|
|
21
|
+
import type { BeatOf, Source, Term } from "../../types.js";
|
|
1
22
|
import type { Emitter } from "../kit.js";
|
|
23
|
+
/**
|
|
24
|
+
* Both lines and their keys, decided in Node — the morph's half of what
|
|
25
|
+
* `prepareWalk` is to the walk, so `plan` can report what `build` will do.
|
|
26
|
+
* Throws where the emitter would: a line KaTeX refuses even repaired, or no key.
|
|
27
|
+
*/
|
|
28
|
+
export declare function prepareMorph(beat: BeatOf<"equation-morph">, source: Source): {
|
|
29
|
+
a: {
|
|
30
|
+
id: string;
|
|
31
|
+
tex: string;
|
|
32
|
+
};
|
|
33
|
+
b: {
|
|
34
|
+
id: string;
|
|
35
|
+
tex: string;
|
|
36
|
+
};
|
|
37
|
+
wa: string;
|
|
38
|
+
wb: string;
|
|
39
|
+
both: Term[];
|
|
40
|
+
notes: string[];
|
|
41
|
+
};
|
|
2
42
|
export declare const equationMorph: Emitter<"equation-morph">;
|
|
@@ -10,7 +10,14 @@ import type { Term } from "../../types.js";
|
|
|
10
10
|
import type { Emitter, Theme } from "../kit.js";
|
|
11
11
|
export declare const OPTS = "{ displayMode: true, trust: function (c) { return c.command === \"\\\\htmlClass\"; }, strict: false, output: \"html\" }";
|
|
12
12
|
export declare const INLINE_OPTS = "{ displayMode: false, trust: function (c) { return c.command === \"\\\\htmlClass\"; }, strict: false, output: \"html\" }";
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Where `term` sits in `tex`, comparing normal forms. Null when it is absent.
|
|
15
|
+
*
|
|
16
|
+
* The span starts at the first matched character's token — with the `\left`
|
|
17
|
+
* that sizes it, when the term opens on a sized delimiter — and ends where the
|
|
18
|
+
* last matched character's token ends. Never further: whatever follows the term
|
|
19
|
+
* in the equation, a `\right` included, is not the term's.
|
|
20
|
+
*/
|
|
14
21
|
export declare function locate(tex: string, term: string): {
|
|
15
22
|
start: number;
|
|
16
23
|
end: number;
|
|
@@ -36,7 +43,47 @@ cls?: (t: Term) => string): {
|
|
|
36
43
|
tex: string;
|
|
37
44
|
used: Term[];
|
|
38
45
|
missing: Term[];
|
|
46
|
+
broken: Term[];
|
|
39
47
|
};
|
|
48
|
+
/** What `prepareWalk` decided about one equation and its terms. */
|
|
49
|
+
export interface PreparedWalk {
|
|
50
|
+
/** The TeX to render, repaired and term-wrapped. Absent when `plain`. */
|
|
51
|
+
tex?: string;
|
|
52
|
+
/** The repaired TeX without wrappers, for measuring. The source TeX when `plain`. */
|
|
53
|
+
raw: string;
|
|
54
|
+
/** Set when KaTeX refuses the equation even after repair. */
|
|
55
|
+
plain?: {
|
|
56
|
+
error: string;
|
|
57
|
+
};
|
|
58
|
+
used: Term[];
|
|
59
|
+
missing: Term[];
|
|
60
|
+
notes: string[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Everything the walk needs to draw one equation, decided in Node — so `plan`
|
|
64
|
+
* can report it and `build` cannot ship a `katex.render` call that throws.
|
|
65
|
+
*
|
|
66
|
+
* The equation is parsed and, if KaTeX refuses it, repaired (`repairTex`). Each
|
|
67
|
+
* term is repaired the same way, so a term spelled with the paper's own macro
|
|
68
|
+
* still finds it once both are drawn as names. Then the terms are wrapped, each
|
|
69
|
+
* wrapping parsed before it is kept.
|
|
70
|
+
*
|
|
71
|
+
* An equation no repair makes parseable is DEGRADED, not dropped and not
|
|
72
|
+
* shipped: `plain` is set and the slide shows the TeX source as text, with the
|
|
73
|
+
* terms still marked so the walk still walks. `notes` says, in words, every
|
|
74
|
+
* repair, degradation and dropped term — `plan` prints them and `build` reports
|
|
75
|
+
* them as the beat's warnings.
|
|
76
|
+
*/
|
|
77
|
+
export declare function prepareWalk(eq: {
|
|
78
|
+
id: string;
|
|
79
|
+
tex: string;
|
|
80
|
+
}, terms: readonly Term[], beatId: string): PreparedWalk;
|
|
81
|
+
/**
|
|
82
|
+
* A legend chip's contents: the term's TeX for KaTeX when it parses inline
|
|
83
|
+
* (repaired if it had to be), and its source as plain text when it does not —
|
|
84
|
+
* a chip is where a viewer reads WHICH symbol, so it is never left empty.
|
|
85
|
+
*/
|
|
86
|
+
export declare function chipSetup(sid: string, term: Term): string;
|
|
40
87
|
/**
|
|
41
88
|
* Display equations want to live between 68px and 108px.
|
|
42
89
|
*
|
|
@@ -58,6 +105,18 @@ cls?: (t: Term) => string): {
|
|
|
58
105
|
export declare function equationSize(tex: string): number;
|
|
59
106
|
/** Estimated rendered width of a display, in ems. */
|
|
60
107
|
export declare function texUnits(tex: string): number;
|
|
108
|
+
/**
|
|
109
|
+
* Grow each legend chip to hold the glyphs KaTeX set in it.
|
|
110
|
+
*
|
|
111
|
+
* A chip is a painted box with 2px of vertical padding, and the layout gate
|
|
112
|
+
* measures text against the nearest painted box. `x^{\text{gt}}_{<i}` or a
|
|
113
|
+
* `\frac` sets glyph boxes above and below the line box, so the chip failed
|
|
114
|
+
* `text_box_overflow` on its own superscript — measured on HypePaper deck
|
|
115
|
+
* 0ef77cae: the `gt` sat 10px above the chip's top edge. Padding is added only
|
|
116
|
+
* where a glyph box actually crosses an edge, so a chip that already held its
|
|
117
|
+
* term is untouched.
|
|
118
|
+
*/
|
|
119
|
+
export declare function chipFit(sid: string, terms: Term[]): string[];
|
|
61
120
|
/** One row per term: a chip KaTeX fills in `setup`, and the label. Shared with the morph. */
|
|
62
121
|
export declare function legendRows(sid: string, terms: Term[], theme: Theme): string;
|
|
63
122
|
export declare function legendCss(theme: Theme): string;
|
|
@@ -102,8 +102,9 @@ export interface DeckOptions {
|
|
|
102
102
|
* naming a family the bundle does not declare falls back silently.
|
|
103
103
|
*
|
|
104
104
|
* Passed in rather than read here because this function does no I/O. Absent,
|
|
105
|
-
* the link is emitted as before, so a caller that has no bundle is unchanged
|
|
106
|
-
*
|
|
105
|
+
* the link is emitted as before, so a caller that has no bundle is unchanged.
|
|
106
|
+
* `build` passes one for every deck: a Latin deck's is the vendored Inter
|
|
107
|
+
* (`vendorInter` in src/build/files.ts), for the same reason.
|
|
107
108
|
*/
|
|
108
109
|
fontCss?: string;
|
|
109
110
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The attribute `equation-walk`'s fit leaves on a display it could not fit,
|
|
3
|
+
* holding the formula. `fidelity` reads it and fails the deck naming that
|
|
4
|
+
* formula — the one statement the layout gate's `span.mord` cannot make.
|
|
5
|
+
*/
|
|
6
|
+
export declare const UNFIT_ATTR = "data-ds-unfit";
|
|
7
|
+
/** KaTeX's message for `tex`, or null when it parses. Same options the deck uses. */
|
|
8
|
+
export declare function texError(tex: string, display: boolean): string | null;
|
|
9
|
+
export interface Repaired {
|
|
10
|
+
/** The TeX to render: the input when it parsed, otherwise the repaired form. */
|
|
11
|
+
tex: string;
|
|
12
|
+
/** One sentence per repair made, in the order made. Empty when none was needed. */
|
|
13
|
+
repairs: string[];
|
|
14
|
+
/** KaTeX's message when even the repaired form does not parse; null otherwise. */
|
|
15
|
+
error: string | null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Parse `tex`; if KaTeX refuses it, apply the repairs that cannot change its
|
|
19
|
+
* meaning, one at a time, until it parses or none is left to try.
|
|
20
|
+
*
|
|
21
|
+
* THE REPAIRS, and why each is safe:
|
|
22
|
+
*
|
|
23
|
+
* - An UNBALANCED `\left`/`\right` is closed with the null delimiter `\right.`
|
|
24
|
+
* (or opened with `\left.`). The delimiter the author wrote is still drawn,
|
|
25
|
+
* at the size it was asked for; only the missing invisible partner is added.
|
|
26
|
+
* - An UNBALANCED brace group is closed at the end, or opened at the start.
|
|
27
|
+
* - `\label`, `\nonumber`, `\notag` are removed (see `NO_INK`).
|
|
28
|
+
* - An UNDEFINED macro — a paper's own `\newcommand`, which the source never
|
|
29
|
+
* carries — is drawn as its NAME in upright type: `\raydir` becomes
|
|
30
|
+
* `\operatorname{raydir}`, an operator rather than `\mathrm` so that two in a
|
|
31
|
+
* row keep a space between them (`\camerarot \cameraint` set as `\mathrm`
|
|
32
|
+
* read "camerarotcameraint"). A degradation, not a restoration, and the sentence
|
|
33
|
+
* it returns says so; but it keeps the symbol on the slide under the name the
|
|
34
|
+
* paper gave it, where the alternatives are to drop the symbol or the slide.
|
|
35
|
+
*
|
|
36
|
+
* Deterministic: the same input always produces the same output and sentences,
|
|
37
|
+
* which is what lets `plan` report a repair that `build` will then make.
|
|
38
|
+
*/
|
|
39
|
+
export declare function repairTex(input: string, display: boolean): Repaired;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -123,8 +123,11 @@ export { verify } from "./verify/index.js";
|
|
|
123
123
|
* `scanBeatCount` also fold into `verify`; that one needs the preferences the
|
|
124
124
|
* deck was asked for, which a built directory does not carry — and
|
|
125
125
|
* `scanUnusedFigures` folds in only where the source was passed alongside.
|
|
126
|
+
* `scanMath` does not fold into `verify`: by then the build has already said
|
|
127
|
+
* the same thing through `onBeatWarning`, and saying it twice trains people to
|
|
128
|
+
* stop reading it.
|
|
126
129
|
*/
|
|
127
|
-
export { scanBeatCount, scanNarrationDrift, scanPaperArc, scanHeadlines, scanNarrationLead, scanRepeatedObject, scanUnusedFigures, } from "./verify/index.js";
|
|
130
|
+
export { scanBeatCount, scanMath, scanNarrationDrift, scanPaperArc, scanHeadlines, scanNarrationLead, scanRepeatedObject, scanUnusedFigures, } from "./verify/index.js";
|
|
128
131
|
export { check, parseCheckReport, sampleTimes } from "./verify/check.js";
|
|
129
132
|
export type { CheckOptions } from "./verify/check.js";
|
|
130
133
|
/**
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* What the model is told, and what it is told about.
|
|
3
|
-
*
|
|
4
|
-
* Planning quality is the product, and this file is where it is won or lost —
|
|
5
|
-
* the schema only guarantees the storyboard is well-formed, never that it is a
|
|
6
|
-
* good explanation of this particular document.
|
|
7
|
-
*
|
|
8
|
-
* `renderSource` deliberately puts every citable id next to its caption. The
|
|
9
|
-
* model cannot cite an id it was never shown, so the inventory is the cheapest
|
|
10
|
-
* defence against the failure mode that actually happens: a plausible-looking
|
|
11
|
-
* `figureId` that exists in no source.
|
|
12
|
-
*/
|
|
13
1
|
import type { Prefs } from "../prefs.js";
|
|
14
2
|
import { type Source } from "../types.js";
|
|
15
3
|
/**
|
|
@@ -66,6 +66,30 @@ export interface ResolvedChrome {
|
|
|
66
66
|
export declare function resolveChrome(need?: string): Promise<ResolvedChrome>;
|
|
67
67
|
/** The path alone, for the callers that only ever wanted that. */
|
|
68
68
|
export declare function chromePath(need?: string): Promise<string>;
|
|
69
|
+
/**
|
|
70
|
+
* Whether Chrome died for want of a sandbox. Stock Ubuntu 24.04, GitHub's
|
|
71
|
+
* `ubuntu-latest` included, sets `kernel.apparmor_restrict_unprivileged_userns=1`.
|
|
72
|
+
* Chrome's sandbox needs exactly those namespaces, so it exits at launch with
|
|
73
|
+
* `FATAL:zygote_host_impl_linux.cc(…)] No usable sandbox!`, which puppeteer
|
|
74
|
+
* quotes in the error it throws.
|
|
75
|
+
*/
|
|
76
|
+
export declare function sandboxMissing(err: unknown): boolean;
|
|
77
|
+
/** How a person gets the sandbox back. */
|
|
78
|
+
export declare const SANDBOX_FIX = "`sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0`, or give Chrome an AppArmor profile";
|
|
79
|
+
/**
|
|
80
|
+
* Launch Chrome for a page DeckSmith wrote itself: a built deck, a caption band.
|
|
81
|
+
*
|
|
82
|
+
* On a host with no usable sandbox (`sandboxMissing`) every gate that opens the
|
|
83
|
+
* deck reported `not_measured`, a warning, so `build` PASSED having measured
|
|
84
|
+
* nothing (.planning/2026-09-18-linux-determinism.md §4). The sandbox stays on
|
|
85
|
+
* wherever Chrome can have one. Only when Chrome refuses to start without it is
|
|
86
|
+
* the launch retried with `--no-sandbox`, and stderr says so. That is no wider
|
|
87
|
+
* than the render already is: hyperframes launches its own capture with
|
|
88
|
+
* `--no-sandbox` every time, on this same deck.
|
|
89
|
+
*
|
|
90
|
+
* Pages from the web never come here: `harvest` refuses instead.
|
|
91
|
+
*/
|
|
92
|
+
export declare function launchOwnPage<T>(launch: (args: string[]) => Promise<T>, args: string[], what: string): Promise<T>;
|
|
69
93
|
type Browser = Awaited<ReturnType<typeof import("puppeteer-core").launch>>;
|
|
70
94
|
type Page = Awaited<ReturnType<Browser["newPage"]>>;
|
|
71
95
|
/** An open deck, seekable and photographable. Close it. */
|
|
@@ -111,6 +111,22 @@ export interface Timing {
|
|
|
111
111
|
* written without it, and those decks did reserve nothing.
|
|
112
112
|
*/
|
|
113
113
|
captionReserve?: number;
|
|
114
|
+
/**
|
|
115
|
+
* The format the deck was built for: its id and its duration budget.
|
|
116
|
+
*
|
|
117
|
+
* The composition records only pixels, and `verify` used to find the budget
|
|
118
|
+
* by looking those up among the presets. A custom canvas matches none, so
|
|
119
|
+
* every custom build read "no duration budget applies" — true of the pixels
|
|
120
|
+
* and false of the deck, which inherits the budget of the profile it was
|
|
121
|
+
* resized from (`resizeFormat`). Optional, and absent falls back to the pixel
|
|
122
|
+
* lookup: every `timing.json` written before this lacks it.
|
|
123
|
+
*/
|
|
124
|
+
format?: {
|
|
125
|
+
id: string;
|
|
126
|
+
minWeight: number;
|
|
127
|
+
maxSeconds?: number;
|
|
128
|
+
warnSeconds?: number;
|
|
129
|
+
};
|
|
114
130
|
scenes: TimedScene[];
|
|
115
131
|
segments: TimedSegment[];
|
|
116
132
|
}
|
|
@@ -6,7 +6,7 @@ export interface FontBundle {
|
|
|
6
6
|
/** The woff2 basenames written into `dir`, beside `fonts.css`. */
|
|
7
7
|
files: string[];
|
|
8
8
|
}
|
|
9
|
-
/** The family a language needs
|
|
9
|
+
/** The CJK family a language needs subset, or null: the deck ships Inter (`vendorInter`). */
|
|
10
10
|
export declare function familyFor(lang: string): string | null;
|
|
11
11
|
/**
|
|
12
12
|
* Write `dir/fonts.css` plus its woff2 for `lang`, covering `glyphs`. Returns
|
|
@@ -26,6 +26,13 @@ export declare function readCanvas(html: string): Canvas | undefined;
|
|
|
26
26
|
* be its own is a gate people learn to ignore. Today the two 16:9 profiles have
|
|
27
27
|
* the same (absent) budget, so the reading is exact as well as safe.
|
|
28
28
|
*/
|
|
29
|
+
/** What the budget gate reads off a format, whether a preset or the one `build` recorded. */
|
|
30
|
+
export type BudgetFormat = Pick<Format, "id" | "minWeight" | "maxSeconds" | "warnSeconds">;
|
|
31
|
+
/** `timing.json`'s record of the format, with the canvas it was recorded for. */
|
|
32
|
+
export interface RecordedFormat extends BudgetFormat {
|
|
33
|
+
width: number;
|
|
34
|
+
height: number;
|
|
35
|
+
}
|
|
29
36
|
export declare function profilesFor(width: number, height: number, formats?: Readonly<Record<string, Format>>): Format[];
|
|
30
37
|
/**
|
|
31
38
|
* The budget finding for one built composition, if there is one.
|
|
@@ -46,4 +53,4 @@ export declare function profilesFor(width: number, height: number, formats?: Rea
|
|
|
46
53
|
* a table that disagrees, rather than the rule being deleted and silently absent
|
|
47
54
|
* the next time a real destination is tighter than the rest.
|
|
48
55
|
*/
|
|
49
|
-
export declare function scanBudget(html: string, storyboard?: Storyboard, kept?: readonly Beat[], formats?: Readonly<Record<string, Format
|
|
56
|
+
export declare function scanBudget(html: string, storyboard?: Storyboard, kept?: readonly Beat[], formats?: Readonly<Record<string, Format>>, recorded?: RecordedFormat): Finding[];
|
|
@@ -291,6 +291,25 @@ export declare function gradeFidelity(rows: readonly Measured[], floor?: number)
|
|
|
291
291
|
* thing it was told to deliver, not a note about taste.
|
|
292
292
|
*/
|
|
293
293
|
export declare function gradeReserve(rows: readonly Measured[], tolerance?: number): Finding[];
|
|
294
|
+
/** An equation the deck's own fit gave up on: the scene, and the formula. */
|
|
295
|
+
export interface Unfit {
|
|
296
|
+
sid: string;
|
|
297
|
+
tex: string;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Run IN THE PAGE: every display `equation-walk`'s fit marked as not fitting.
|
|
301
|
+
*
|
|
302
|
+
* Read once, after the ready gate — the fit runs inside it, before any frame,
|
|
303
|
+
* so the marks are the same at every time the deck could be seeked to.
|
|
304
|
+
*/
|
|
305
|
+
export declare function collectUnfit(attr: string): Unfit[];
|
|
306
|
+
/**
|
|
307
|
+
* An error per equation that does not fit its box at the type floor even broken
|
|
308
|
+
* across lines, NAMING THE FORMULA. The layout gate sees the same overflow and
|
|
309
|
+
* can only say `span.mord`, which tells nobody which of a deck's equations to
|
|
310
|
+
* shorten.
|
|
311
|
+
*/
|
|
312
|
+
export declare function gradeUnfit(rows: readonly Unfit[]): Finding[];
|
|
294
313
|
/**
|
|
295
314
|
* Seek every declared stop and count the ink below its caption.
|
|
296
315
|
*
|
|
@@ -171,6 +171,23 @@ export declare function scanRepeatedObject(storyboard: Storyboard): Finding[];
|
|
|
171
171
|
* citing it in evidence is a different defect, and not this scan's to report.
|
|
172
172
|
*/
|
|
173
173
|
export declare function scanUnusedFigures(storyboard: Storyboard, source: Source): Finding[];
|
|
174
|
+
/**
|
|
175
|
+
* Every equation a walk or a morph will draw, parsed now by the KaTeX the deck
|
|
176
|
+
* vendors, with what `build` will do about each one said in words.
|
|
177
|
+
*
|
|
178
|
+
* Run at `plan` because that is when the storyboard is in front of the author
|
|
179
|
+
* and the cheapest moment to change a beat. Before this, a bad formula was first
|
|
180
|
+
* parsed by a browser at `verify`, after a deck had been built and narrated
|
|
181
|
+
* around it: 26 of 92 HypePaper build failures in the week to 2026-10-07.
|
|
182
|
+
*
|
|
183
|
+
* It calls the SAME preparation the emitters call (`prepareWalk`,
|
|
184
|
+
* `prepareMorph`), so what it reports is what `build` will do, not a second
|
|
185
|
+
* opinion that can drift from it. A WARNING throughout: a repaired formula, a
|
|
186
|
+
* formula shown as plain source and a dropped term are all drawn without
|
|
187
|
+
* throwing — and a beat that will be left out is reported again, by name, when
|
|
188
|
+
* `build` leaves it out.
|
|
189
|
+
*/
|
|
190
|
+
export declare function scanMath(storyboard: Storyboard, source: Source): Finding[];
|
|
174
191
|
/**
|
|
175
192
|
* Warn when the plan came back with fewer beats than were asked for.
|
|
176
193
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jokerized/decksmith",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Turn a source document into an animated explanation deck.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"demo": "node demo/build.mjs && node dist/cli.js build demo/storyboard.json --source demo/source.json -o demo/deck && python3 -m http.server 8080 --directory demo/deck --bind 127.0.0.1"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
+
"@fontsource-variable/inter": "5.3.0",
|
|
61
62
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
62
63
|
"@puppeteer/browsers": "^3.0.6",
|
|
63
64
|
"commander": "^14.0.1",
|