@jokerized/decksmith 0.3.0 → 0.3.1

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.
@@ -26,6 +26,10 @@ export declare const settingsSchema: z.ZodObject<{
26
26
  normal: "normal";
27
27
  dense: "dense";
28
28
  }>>;
29
+ genre: z.ZodOptional<z.ZodEnum<{
30
+ general: "general";
31
+ paper: "paper";
32
+ }>>;
29
33
  duration: z.ZodOptional<z.ZodNumber>;
30
34
  slides: z.ZodOptional<z.ZodInt>;
31
35
  animation_speed: z.ZodOptional<z.ZodNumber>;
@@ -63,6 +67,10 @@ export declare const estimateSchema: z.ZodObject<{
63
67
  normal: "normal";
64
68
  dense: "dense";
65
69
  }>>;
70
+ genre: z.ZodOptional<z.ZodEnum<{
71
+ general: "general";
72
+ paper: "paper";
73
+ }>>;
66
74
  duration: z.ZodOptional<z.ZodNumber>;
67
75
  slides: z.ZodOptional<z.ZodInt>;
68
76
  animation_speed: z.ZodOptional<z.ZodNumber>;
@@ -101,6 +109,10 @@ export declare const createSchema: z.ZodObject<{
101
109
  normal: "normal";
102
110
  dense: "dense";
103
111
  }>>;
112
+ genre: z.ZodOptional<z.ZodEnum<{
113
+ general: "general";
114
+ paper: "paper";
115
+ }>>;
104
116
  duration: z.ZodOptional<z.ZodNumber>;
105
117
  slides: z.ZodOptional<z.ZodInt>;
106
118
  animation_speed: z.ZodOptional<z.ZodNumber>;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * The paper arc: what a research-talk deck must open and close with.
3
+ *
4
+ * A research talk has a shape a general explainer does not. It opens on the
5
+ * problem and on the ground the work stands on, and it closes on what the work
6
+ * does NOT do and then on what to take away. DeckSmith's planner writes the
7
+ * opening well already — 13 of 15 committed full-deck runs open with a `title` —
8
+ * and the ending badly: 10 of 15 close with a `callout`, but ZERO of 15 carry
9
+ * two, because the limitation arrives as a subordinate clause inside the
10
+ * conclusion ("The idea works, but the strongest lightweight models remain
11
+ * ahead") rather than as its own slide. Splitting that clause into a slide is
12
+ * the actual behaviour change this module asks for.
13
+ *
14
+ * WHY THIS FILE EXISTS AT ALL, rather than the rule living where it is enforced:
15
+ * three directories read this definition and none of them can own it — the
16
+ * prompt (src/plan/prompt.ts) asks the model for the arc, the scan
17
+ * (src/verify/index.ts) reports where a plan missed it, and the cut
18
+ * (src/plan/select.ts) refuses to delete a beat that carries a role. Restating
19
+ * the rule three times is how the three fall out of step; deriving it from one
20
+ * table is how they cannot.
21
+ *
22
+ * WHAT THIS MODULE DELIBERATELY DOES NOT DO. It never decides that a document is
23
+ * a research paper. `prefs.genre` is declared by the author and nothing here
24
+ * sniffs it — see the field's own note in src/types.ts for the measurement that
25
+ * settled that. And it never requires a beat the source cannot support: RULE 3
26
+ * forbids inventing a baseline or a result, so a source that says nothing about
27
+ * prior work honestly yields no `background` beat, and this file's job is then
28
+ * to report the gap rather than to have manufactured one.
29
+ */
30
+ import type { Prefs } from "../prefs.js";
31
+ import type { Beat, BeatRole, Storyboard } from "../types.js";
32
+ /** Every structural job, in the order a deck performs them. */
33
+ export declare const ARC_ROLES: readonly BeatRole[];
34
+ /**
35
+ * Roles required at a given deck length, and why the list shortens.
36
+ *
37
+ * Four reserved slides out of five is not a deck, it is a table of contents. At
38
+ * `--duration 60` a deck is about five beats, so asking for the full arc there
39
+ * is asking for something nobody could deliver, and a gate that fires on the
40
+ * impossible is one people learn to ignore. The thresholds:
41
+ *
42
+ * n >= 8 the full arc. 8 is this project's own definition of a full-deck
43
+ * run — the corpus count of "15 committed full-deck plans" is beats
44
+ * >= 8 — not a number chosen here.
45
+ * 5..7 the ending only. An `intro` is what the planner already writes
46
+ * unprompted 13 times in 15, and `background` is the beat most likely
47
+ * to have no source material behind it, so those two are the ones to
48
+ * give up first when the budget is short.
49
+ * n < 5 nothing. There is no room for a shape.
50
+ *
51
+ * Read off the beat count the plan actually came back with, not off
52
+ * `prefs.slides`: the floor the author asked for and the deck the planner
53
+ * returned are different numbers, and `scanBeatCount` already owns the gap
54
+ * between them.
55
+ */
56
+ export declare function requiredRoles(beatCount: number): readonly BeatRole[];
57
+ /** Whether the paper arc was asked for at all. Declared, never sniffed. */
58
+ export declare function paperArcRequested(prefs: Pick<Prefs, "genre">): boolean;
59
+ /** The beats carrying a structural role, by role. Later duplicates are reported, not kept. */
60
+ export declare function arcBeats(storyboard: Storyboard): Map<BeatRole, Beat[]>;
61
+ /**
62
+ * Ids of every beat carrying a role — what the cut refuses to release.
63
+ *
64
+ * Takes a beat list rather than a Storyboard because the cut works over the
65
+ * surviving beats, not over the plan.
66
+ */
67
+ export declare function arcIds(beats: readonly Beat[]): Set<string>;
68
+ /**
69
+ * Where a plan departs from the arc it was asked for, as sentences.
70
+ *
71
+ * ORDER IS CHECKED, NOT JUST PRESENCE, and only where order is the point. The
72
+ * user's requirement is specifically that the deck END on the conclusion with
73
+ * limitations immediately before it — an ending is a position, not a topic — so
74
+ * those two are checked against the last two slots. The opening pair is checked
75
+ * for presence and for being early, because "the first couple of slides" is a
76
+ * region rather than an index, and a deck that opens title, problem, background
77
+ * is not wrong.
78
+ *
79
+ * Returns an empty array when the arc was not requested, when the deck is too
80
+ * short to carry it, or when the plan satisfied it.
81
+ */
82
+ export declare function arcProblems(storyboard: Storyboard, prefs: Pick<Prefs, "genre" | "slides">): string[];
@@ -1,5 +1,11 @@
1
1
  import type { Prefs } from "../prefs.js";
2
2
  import { type Source, type Storyboard } from "../types.js";
3
+ /** The schema for one run. `role` is present only when the paper arc was asked for. */
4
+ export declare function schemaFor(prefs: Pick<Prefs, "genre">): unknown;
5
+ /**
6
+ * The default-preferences schema, unchanged and still exported: `general` hides
7
+ * `role`, so these bytes are what they have always been.
8
+ */
3
9
  export declare const SCHEMA: unknown;
4
10
  export interface CodexOptions {
5
11
  /** Left unset by default: use whatever model the user's Codex is configured for. */
@@ -39,6 +39,7 @@ export interface PrefFlags {
39
39
  lang?: string;
40
40
  tone?: string;
41
41
  density?: string;
42
+ genre?: string;
42
43
  duration?: string | number;
43
44
  theme?: string;
44
45
  speed?: string | number;
@@ -60,20 +60,6 @@ export interface AudioInput {
60
60
  file: string;
61
61
  delayMs: number;
62
62
  }
63
- /**
64
- * Delay every segment onto one track and sum them.
65
- *
66
- * `amix` with `normalize=0` sums rather than averaging: the default divides by
67
- * the input count, which on a 37-segment deck would render the narration 31 dB
68
- * down and sound exactly like a bug in the TTS. The segments never overlap — the
69
- * timing model gives each one the video's undivided attention — so summing is
70
- * safe. `dropout_transition=0` stops amix ramping the gain as inputs end.
71
- *
72
- * Every input is resampled and laid out identically first, because amix refuses
73
- * a mismatch and edge-tts emits 24 kHz mono while the video wants 48 kHz.
74
- * `apad` runs the track out to the video's length so the mux does not have to
75
- * choose between a short audio stream and `-shortest` truncating the picture.
76
- */
77
63
  export declare function audioGraph(inputs: readonly AudioInput[], seconds: number,
78
64
  /**
79
65
  * ffmpeg input index of the first mp3. 1 when the video is the only other