@graphlearning/shell 0.7.0 → 0.10.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 CHANGED
@@ -88,6 +88,23 @@ The recorder (`scripts/record-course.mjs` in each content repo) drives these, so
88
88
  - `?capture=1` — suppress every interactive control, leaving a clean frame
89
89
  - `window.__scene.plan()` — the active course's sections, for the recorder to walk
90
90
 
91
+ ## Keyboard
92
+
93
+ Interactive only — `?capture=1` suppresses nothing here because none of it fires without a reader.
94
+
95
+ | Key | What it does |
96
+ | --- | --- |
97
+ | `←` / `→` | seek the narration −10s / +10s **when the section has a clip** (exactly when the scrub bar is on screen); otherwise page to the previous/next section |
98
+ | `Shift`+`←` / `→` | always page, clip or no clip |
99
+ | `Space` | play/pause the narration |
100
+ | `Esc` | back to the catalog (and from the catalog, up to graphl.in) |
101
+ | `←` / `→` / `Home` / `End` | with the scrub bar focused: seek ∓10s / to the start / to the end |
102
+
103
+ The arrows seek rather than page because the footer's `‹` `›` buttons are the pager's real home and
104
+ `Esc` still leaves — while the only thing a *listening* reader has no control for is a 10s jump.
105
+ Where there is no clip to seek (the catalog, a bare scene view, a repo whose wavs are not generated
106
+ yet) the old paging meaning stands, so the keyboard never goes dead.
107
+
91
108
  ## Develop
92
109
 
93
110
  `npm run dev` serves a fixture harness on :5176 — two throwaway courses with a diagram scene, a code
@@ -113,12 +130,27 @@ They are `bin` entries, wired through each repo's `npm run`:
113
130
  | command | what it does |
114
131
  |---|---|
115
132
  | `npm run record` | one course → a 3840×2160 MP4 |
133
+ | `npm run record:all` | every course in syllabus order, waiting for narration to land |
116
134
  | `npm run record:reels` | one course → portrait reels |
117
135
  | `npm run shots:4k` | one PNG per section, no ffmpeg |
118
136
  | `npm run thumb` | a branded YouTube thumbnail |
119
137
  | `npm run gen:desc` | video descriptions + chapters |
120
138
  | `npm run gen:audio` | the narration manifest |
121
139
 
140
+ `record:all` is the only one whose repo script is not just the bin: it needs a sleep wrapper, because
141
+ a full concept is a multi-hour batch and the machine going idle mid-run kills it.
142
+
143
+ ```json
144
+ "record:all": "caffeinate -ims graphl-record-all"
145
+ ```
146
+
147
+ It exists because narration arrives DURING a batch — the Colab + Chatterbox pass commits wavs one
148
+ section at a time — so before each course it pulls the repo's branch and counts that course's wavs
149
+ against `scripts/audio-manifest.json`, waiting (`--wait`, default 240 min) for the missing ones.
150
+ A course is recorded only when it is complete; an incomplete one is skipped and named in the summary
151
+ rather than half-recorded into `record`'s 3s-silence fallback. Re-running is cheap — finished courses
152
+ are segment-cache hits.
153
+
122
154
  **Capture is not realtime.** `record` and `record:reels` screencast one short window per section and
123
155
  loop it over the narration (`-stream_loop`), because the only moving thing in a frame is the engine's
124
156
  edge pulse and that pulse has a 2.4s period — and a pulse crosses its whole edge in exactly one
@@ -1,3 +1,4 @@
1
+ export declare const SEEK_S = 10;
1
2
  export declare function NarrationBar({ audio }: {
2
3
  audio: HTMLAudioElement | null;
3
4
  }): import("react").JSX.Element | null;