@jokerized/decksmith 0.9.4 → 0.9.6

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 (50) hide show
  1. package/dist/cli.js +20775 -10046
  2. package/dist/deck-runtime.js +2 -2
  3. package/dist/index.js +11549 -1433
  4. package/dist/mcp.js +10824 -1086
  5. package/dist/types/bespoke/pipeline.d.ts +1 -1
  6. package/dist/types/bespoke/scene.d.ts +18 -2
  7. package/dist/types/emit/archetypes/index.d.ts +15 -0
  8. package/dist/types/emit/composition.d.ts +16 -1
  9. package/dist/types/emit/kit.d.ts +33 -0
  10. package/dist/types/emit/svg.d.ts +19 -0
  11. package/dist/types/emit/tex.d.ts +13 -0
  12. package/dist/types/literal/check.d.ts +45 -0
  13. package/dist/types/literal/formula.d.ts +78 -0
  14. package/dist/types/literal/index.d.ts +133 -0
  15. package/dist/types/literal/kind.d.ts +121 -0
  16. package/dist/types/literal/kinds/common.d.ts +280 -0
  17. package/dist/types/literal/kinds/evolve.d.ts +58 -0
  18. package/dist/types/literal/kinds/flow.d.ts +13 -0
  19. package/dist/types/literal/kinds/operate.d.ts +27 -0
  20. package/dist/types/literal/kinds/place-combos.d.ts +33 -0
  21. package/dist/types/literal/kinds/place-lengths.d.ts +36 -0
  22. package/dist/types/literal/kinds/place-margins.d.ts +44 -0
  23. package/dist/types/literal/kinds/place-sets.d.ts +31 -0
  24. package/dist/types/literal/kinds/place.d.ts +69 -0
  25. package/dist/types/literal/kinds/prior-work.d.ts +29 -0
  26. package/dist/types/literal/kinds/read.d.ts +33 -0
  27. package/dist/types/literal/kinds/recap.d.ts +16 -0
  28. package/dist/types/literal/kinds/region.d.ts +56 -0
  29. package/dist/types/literal/kinds/stage.d.ts +108 -0
  30. package/dist/types/literal/kinds/svg.d.ts +65 -0
  31. package/dist/types/literal/kinds/table.d.ts +19 -0
  32. package/dist/types/literal/kinds/tex.d.ts +6 -0
  33. package/dist/types/literal/kinds-shared.d.ts +15 -0
  34. package/dist/types/literal/kit.d.ts +86 -0
  35. package/dist/types/literal/ops.d.ts +56 -0
  36. package/dist/types/literal/registry.d.ts +20 -0
  37. package/dist/types/plan/codex.d.ts +28 -5
  38. package/dist/types/plan/coverage.d.ts +179 -0
  39. package/dist/types/plan/duration.d.ts +2 -0
  40. package/dist/types/plan/locate.d.ts +46 -0
  41. package/dist/types/plan/prompt.d.ts +14 -1
  42. package/dist/types/plan/variety.d.ts +23 -0
  43. package/dist/types/render/timing.d.ts +7 -1
  44. package/dist/types/source/harvest.d.ts +1 -0
  45. package/dist/types/types.d.ts +21451 -933
  46. package/dist/types/verify/fidelity.d.ts +7 -2
  47. package/dist/types/verify/fill.d.ts +70 -9
  48. package/dist/types/verify/overprint.d.ts +46 -0
  49. package/dist/types/verify/scenes.d.ts +61 -2
  50. package/package.json +1 -1
@@ -0,0 +1,179 @@
1
+ /**
2
+ * SECTION COVERAGE: a plan of an analysis covers every part the analysis has,
3
+ * in the order a talk covers them.
4
+ *
5
+ * The measured failure (2026-10-10, the EM-SNN ko deck): the source is a paper
6
+ * analysis with sections Q1 problem, Q2 related work, Q3 method, Q4 experiments,
7
+ * Q5 future directions, Q6 summary, Q8 limits. The plan opened on a title,
8
+ * spent twelve beats on the method and the numbers, and closed on one callout:
9
+ * the problem got the title slide only, and the related work, the future
10
+ * directions and the summary got nothing. Nothing checked, so nothing said.
11
+ *
12
+ * So the parts are DETECTED from the headings, generically — a lexicon over
13
+ * en/ko/ja/zh heading words, not this paper's Q-numbers — and the plan is held
14
+ * to them the way `variety.ts` holds it to its shapes: `codexPlanner` sends a
15
+ * plan that misses one back once, naming what is missing, and refuses the
16
+ * repair if it still does.
17
+ *
18
+ * WHAT IT DOES NOT DO. It never decides a document is a paper analysis from one
19
+ * lucky word: fewer than `MIN_PARTS` distinct parts and the check is off, and
20
+ * every deck planned before this is planned as it was (the same caution
21
+ * `prefs.genre` records about heading lexicons in general). A heading the
22
+ * lexicon does not know is not required; it is still in the source, and the
23
+ * planner may cover it where it fits.
24
+ *
25
+ * Also here, because they share the repair round: the literal-scene truth
26
+ * gate (a number on screen the source never states, an op parameter not
27
+ * stated IN ITS ROLE, a variant the source never names, example material
28
+ * without its tag, a formula its table does not bear out, a picture that
29
+ * names a beat with no picture).
30
+ */
31
+ import type { BeatPart, LiteralKindDoc, Source, Storyboard } from "../types.js";
32
+ /** The order a deck covers its parts in. */
33
+ export declare const PART_ORDER: readonly BeatPart[];
34
+ /** What each part is, for the prompt and the findings. */
35
+ export declare const PART_NAMES: Record<BeatPart, string>;
36
+ /** Fewer distinct parts than this and the source is not treated as an analysis. */
37
+ export declare const MIN_PARTS = 3;
38
+ /** The part a heading names, or undefined. */
39
+ export declare function partOfHeading(heading: string): BeatPart | undefined;
40
+ export interface SourcePart {
41
+ part: BeatPart;
42
+ /** Sections of this part that carry text, in source order: each must be cited. */
43
+ sections: Array<{
44
+ id: string;
45
+ heading: string;
46
+ }>;
47
+ }
48
+ /**
49
+ * The parts this source has, in deck order, or `[]` when it is not an analysis.
50
+ *
51
+ * A section takes its parent's part when the parent has one (the subsections of
52
+ * "Experiments" are experiments, whatever they are called), and its own
53
+ * heading's part otherwise. The document's title heading is not a section of
54
+ * any part. Only sections with text are listed: an empty parent is covered by
55
+ * covering its children.
56
+ *
57
+ * Back matter — an appendix, the references, the acknowledgements — and
58
+ * everything under or after the references is in no part: a talk is not held to its appendix. Two
59
+ * arXiv papers (FlashAttention, Chinchilla; 2026-10-14) each had 32 sections
60
+ * to cite for a 14-slide deck, about half of them appendix, and every plan was
61
+ * refused for missing one or for running long to cite them all.
62
+ */
63
+ export declare function sourceParts(source: Source): SourcePart[];
64
+ /**
65
+ * Where a plan departs from the source's parts, as sentences a repair can act
66
+ * on. Empty when the source has no detected parts.
67
+ */
68
+ export declare function coverageFindings(storyboard: Storyboard, source: Source): string[];
69
+ /**
70
+ * Advice for a plan whose source is about pictures: at least three of its own
71
+ * figures are captioned as views, frames or qualitative examples, and no beat
72
+ * runs `region` or `operate`. r1 drew a driving paper's only imagery at 55%
73
+ * width beside text, its panels unreadable, with neither verb used once. Sent
74
+ * back once with the other findings; a plan that still ignores it is kept.
75
+ */
76
+ export declare function pictureFindings(storyboard: Storyboard, source: Source): string[];
77
+ /**
78
+ * Advice for a plan that draws its MECHANISM as slideware, sent back once with
79
+ * the other findings (as `pictureFindings` is): r2 never chose \`operate\` or
80
+ * \`evolve\` on two papers and drew their method beats as two bullet columns, a
81
+ * chain of name cards and a 2×2 grid of numbers.
82
+ *
83
+ * - a beat of part "method" with no \`literal\`, drawn as words, is routed to
84
+ * the verb its evidence allows: a flow showing a figure it cites, place
85
+ * curves or evolve on an equation, else operate on example vectors or
86
+ * evolve (an update over steps, lanes of serial against parallel work);
87
+ * - a flow chain whose stages are mostly names (no count, figure or layer);
88
+ * - a beat whose claim states two or more of the source's numbers, drawn as
89
+ * words, is a place strip, plane or combos;
90
+ * - a split-compare with two lines or fewer a side is a setup detail: a
91
+ * caption of the result beat that uses it.
92
+ *
93
+ * Advice, not a refusal: whether a verb is honest for a beat depends on what the
94
+ * source prints, which a heuristic cannot settle; the planner gets one look.
95
+ */
96
+ export declare function slidewareFindings(storyboard: Storyboard, source: Source): string[];
97
+ /**
98
+ * Advice: an eyebrow or a scene's slot words left in English in a deck in another
99
+ * script (r3: "SPECULATIVE DECODING" over a Korean scene): two or more Latin
100
+ * words, no letter of another script, not all of them names (an acronym, a model
101
+ * with a digit). Names (items, rows, members) are the source's own and not checked.
102
+ */
103
+ export declare function latinWordFindings(storyboard: Storyboard): string[];
104
+ /** The most of a deck's spoken time text-only beats may take. */
105
+ export declare const TEXT_SHARE = 0.2;
106
+ /** The longest a kinetic statement may be spoken over, seconds. */
107
+ export declare const KINETIC_SECONDS = 8;
108
+ /**
109
+ * Advice against a deck that is mostly text: r3 opened one deck with 75s of
110
+ * bullet columns, held kinetic statements at 2–11% fill for 22–29s, and spent
111
+ * about a third of its runtime on split-compare, callout, kinetic and
112
+ * hero-number. Measured by the narration each beat speaks (its characters at the
113
+ * deck language's speaking rate): text-only beats at most `TEXT_SHARE` of it,
114
+ * never two in a row, and a kinetic beat at most `KINETIC_SECONDS`.
115
+ */
116
+ export declare function textShareFindings(storyboard: Storyboard): string[];
117
+ /**
118
+ * What breaks a kind's claim bans (src/types.ts `LiteralKindDoc.mustNotClaim`):
119
+ * a banned claim in `said` (the beat's takeaway and the scene's labels). Empty
120
+ * when it keeps them.
121
+ */
122
+ export declare function literalTruthProblems(rules: Pick<LiteralKindDoc, "mustNotClaim">, said: readonly string[]): string[];
123
+ /**
124
+ * The source's numbers in reading order, signs kept, references left out. A
125
+ * list "[0.5,0.25]" or "1,2,3" is its numbers one by one; "1,000" is one
126
+ * thousand; "1e-3" is one number.
127
+ */
128
+ export declare function numberSequence(source: string): number[];
129
+ /**
130
+ * Whether a number is grounded IN ITS ROLE: some occurrence of the value, as a
131
+ * whole token, either carries the symbol the source binds to it there (then
132
+ * the plan must give that symbol, and the symbol must stand within 40
133
+ * characters of the role's nouns somewhere), or is unbound and itself stands
134
+ * within 40 characters of them. `mustBind`: only a binding grounds it (a
135
+ * formula's own symbol). Returns why not, or undefined.
136
+ */
137
+ export declare function paramProblem(value: string, symbol: string | undefined, nouns: RegExp, role: string, text: string, mustBind?: boolean): string | undefined;
138
+ /**
139
+ * Why a formula is not grounded by its checks: each check passes under
140
+ * interval arithmetic (src/literal/formula.ts) with its numbers in order in
141
+ * one passage; every variable takes two values or more; and where two checks
142
+ * or more sit in one passage (a flattened table), EVERY row of it at their
143
+ * period, shaped like them, passes too — a plan cannot pick the rows that fit.
144
+ * When the checks' rows also print a fixed parameter, every row printing THAT
145
+ * value: the other rows are another curve's.
146
+ */
147
+ export declare function formulaProblems(expr: string, checks: ReadonlyArray<{
148
+ inputs: ReadonlyArray<{
149
+ name: string;
150
+ value: string;
151
+ }>;
152
+ output: string;
153
+ }>, fixed: ReadonlyArray<{
154
+ name: string;
155
+ value: string;
156
+ }>, _text: string, ps: readonly string[]): string[];
157
+ /**
158
+ * Fills the slots whose words the code knows (2026-10-15): the `example` tag on
159
+ * a scene running on example material, and an op chain's `input` and `output`
160
+ * titles. Left to the planner, FlashAttention's b02 (unseen-paper round 15) was
161
+ * refused for its missing tag alone, and its b11 first for a chain's `input`. A
162
+ * slot the planner did fill is kept as written.
163
+ */
164
+ export declare function withStockLabels(storyboard: Storyboard, source: Source): Storyboard;
165
+ /**
166
+ * The literal-scene checks no schema can express. Run on every plan; a plan
167
+ * with no `literal` has nothing to find.
168
+ *
169
+ * `takeaways` asks for a takeaway on every beat but the title, which is what a
170
+ * plan shown the field (src/plan/codex.ts) was asked for. `panels`, when the
171
+ * caller could read the figures, holds a `region`'s `panel` to the panels the
172
+ * build will find.
173
+ */
174
+ export declare function literalFindings(storyboard: Storyboard, source: Source,
175
+ /** `panels`: each source figure's panel count as the build finds it (`figurePanels`). */
176
+ opts?: {
177
+ takeaways?: boolean;
178
+ panels?: Readonly<Record<string, number>>;
179
+ }): string[];
@@ -626,3 +626,5 @@ export declare function playbackWarning(factor: number, p95: number): string | u
626
626
  * looked at the alternative and wants the fast video anyway.
627
627
  */
628
628
  export declare function playbackRefusal(actualSeconds: number, targetSeconds: number, p95: number): string | undefined;
629
+ /** CJK writes far more meaning per character, so it is read out far slower. */
630
+ export declare function charsPerSecond(lang: string): number;
@@ -0,0 +1,46 @@
1
+ import type { Source, Storyboard } from "../types.js";
2
+ import { type Runner } from "./codex.js";
3
+ type Box = {
4
+ x: number;
5
+ y: number;
6
+ w: number;
7
+ h: number;
8
+ };
9
+ /** The prompt for one panel: its things, numbered, one tight box each. */
10
+ export declare function locatePrompt(things: readonly string[]): string;
11
+ /** The boxes a reply gives, in order, or why it gives none. */
12
+ export declare function readBoxes(reply: unknown, n: number): Box[] | string;
13
+ interface PassOpts {
14
+ run?: Runner;
15
+ model?: string;
16
+ onBeat?: (id: string) => void;
17
+ /** Told a beat whose scene could not be read twice over; that beat loses its scene. Absent: refused. */
18
+ onDrop?: (id: string, why: string) => void;
19
+ }
20
+ /**
21
+ * The storyboard with every marked `region`'s boxes found (any box the planner
22
+ * wrote is a guess and is replaced). Fails loudly, naming the beat, when a
23
+ * panel's things cannot be found twice over.
24
+ */
25
+ export declare function locateMarks(storyboard: Storyboard, source: Source, assetsDir: string, opts?: PassOpts): Promise<Storyboard>;
26
+ type Step = {
27
+ lead?: string;
28
+ parts: Array<{
29
+ text: string;
30
+ tag: string;
31
+ }>;
32
+ };
33
+ /** The prompt for a trace: what to read, the tags, the rows exactly as printed. */
34
+ export declare function transcribePrompt(read: string, tags: ReadonlyArray<{
35
+ tag: string;
36
+ label: string;
37
+ }>): string;
38
+ /** The rows a reply gives, or why it gives none. */
39
+ export declare function readSteps(reply: unknown, tags: readonly string[]): Step[] | string;
40
+ /**
41
+ * The storyboard with every figure `trace`'s rows transcribed from its panel.
42
+ * The steps are the figure's, so the truth gate does not hold their numbers to
43
+ * the prose (src/plan/coverage.ts); what no gate sees is a misread glyph.
44
+ */
45
+ export declare function transcribeTraces(storyboard: Storyboard, source: Source, assetsDir: string, opts?: PassOpts): Promise<Storyboard>;
46
+ export {};
@@ -1,5 +1,5 @@
1
1
  import { type Prefs } from "../prefs.js";
2
- import { type Source } from "../types.js";
2
+ import { type LiteralKindDoc, type Source } from "../types.js";
3
3
  /**
4
4
  * How many sentences each archetype wants, because it is how many stops it has.
5
5
  *
@@ -20,6 +20,19 @@ import { type Source } from "../types.js";
20
20
  * and the only alternative to a checked table is prose nobody verifies.
21
21
  */
22
22
  export declare const REVEALS: Record<string, string>;
23
+ /**
24
+ * A kind's claim bans (src/types.ts `LiteralKindDoc`), under its slots:
25
+ * `literalFindings` checks the same entries, so the planner is told exactly
26
+ * what will be refused. Empty for a kind with none.
27
+ */
28
+ export declare function ruleDocs(d: Pick<LiteralKindDoc, "mustNotClaim">): string;
29
+ /**
30
+ * The prompt blocks that depend on the SOURCE, not just the preferences: the
31
+ * parts it must cover, when it has them, and the literal kinds, when the build
32
+ * draws scenes. Empty for a source with no parts and a classic plan, so those
33
+ * prompts are byte-for-byte what they were.
34
+ */
35
+ export declare function sourceBlocks(source: Source, prefs: Prefs): string;
23
36
  /**
24
37
  * The rules, then the preferences the person asking for the deck chose. They go
25
38
  * last because they are the part the model is most likely to drift from, and the
@@ -47,6 +47,29 @@ export declare const SCENE_SHARE = 0.6;
47
47
  export declare const PANEL_ARCHETYPES: ReadonlySet<Archetype>;
48
48
  /** At most this share of a picture deck's beats are panels: five of fourteen. */
49
49
  export declare const PANEL_SHARE = 0.36;
50
+ /**
51
+ * At most this many `kinetic` beats a deck. r1 of the literal verbs run had
52
+ * seven in one deck: two lines of type in the left third of a blank field, 75%
53
+ * empty and still for 13-15s each. One thesis is a kinetic; seven are a deck
54
+ * with nothing to show.
55
+ */
56
+ export declare const KINETIC_MAX = 1;
57
+ /** A plan may come back at most this many times the beats asked for. */
58
+ export declare const SLIDES_OVER = 1.5;
59
+ /**
60
+ * Where a plan is too LONG, as sentences — a separate group from the variety
61
+ * rules because its repair drops beats, which a variety repair may not.
62
+ *
63
+ * Over `SLIDES_OVER` × `slides`: r1 came back with 36 beats against 16, and
64
+ * 638s. 1.3 was the rule until Chinchilla (2026-10-15, 21 sections to cover)
65
+ * was refused at 19 and 20 beats against 14 in two of its last five rounds,
66
+ * three repairs each, never merged under 18. 1.5 still refuses r1's 2.25.
67
+ *
68
+ * And a setup beat whose next beat is its results — "navsim-metrics"
69
+ * then "navsim-results", seven times in one deck — is one point said twice:
70
+ * the metrics belong in the results' caption.
71
+ */
72
+ export declare function sizeFindings(storyboard: Storyboard, slides: number): string[];
50
73
  /** How many panel beats a deck of `beats` may carry, given whether it may ask for pictures. */
51
74
  export declare function panelsAllowed(beats: number, images: Prefs["images"]): number;
52
75
  /** How many stage beats a deck of `beats` must carry, given the picture cap. */
@@ -51,7 +51,7 @@ import type { z } from "zod";
51
51
  import type { BespokeMap } from "../bespoke/scene.js";
52
52
  import { type Cue } from "../deck/subtitles.js";
53
53
  import { type DeckNarration } from "../emit/composition.js";
54
- import type { Beat, Format, Source, Storyboard, segmentSchema } from "../types.js";
54
+ import type { Beat, Design, Format, Source, Storyboard, segmentSchema } from "../types.js";
55
55
  type Segment = z.infer<typeof segmentSchema>;
56
56
  /** Written beside `index.html` by `build`; read by `render`. */
57
57
  export declare const TIMING_FILE = "timing.json";
@@ -221,6 +221,12 @@ export interface TimingInput {
221
221
  theme?: string;
222
222
  /** `DeckOptions.bespoke`, exactly as `emitDeck` was given it. */
223
223
  bespoke?: BespokeMap;
224
+ /**
225
+ * The design the composition was emitted in (`emitDeck`'s, else the
226
+ * storyboard's). Holds DO depend on it: staged without it, a v2 hero number's
227
+ * hold was classic's reel roll, 0.04s off the island's (r3 C s16).
228
+ */
229
+ design?: Design;
224
230
  }
225
231
  /**
226
232
  * One pass over the built deck, producing the manifest `render` consumes.
@@ -170,6 +170,7 @@ export type Block = {
170
170
  kind: "table";
171
171
  columns: string[];
172
172
  rows: string[][];
173
+ caption?: string;
173
174
  } | {
174
175
  kind: "image";
175
176
  src: string;