@kvman/kvvideo 0.1.0 → 0.1.2

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 (258) hide show
  1. package/README.md +1 -1
  2. package/dist/api.d.ts +31 -0
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/brand/brand.d.ts +17 -0
  5. package/dist/brand/brand.d.ts.map +1 -0
  6. package/dist/brand/brand.js +44 -0
  7. package/dist/brand/brand.js.map +1 -0
  8. package/dist/browser/launch.d.ts +2 -0
  9. package/dist/browser/launch.d.ts.map +1 -1
  10. package/dist/browser/launch.js +7 -1
  11. package/dist/browser/launch.js.map +1 -1
  12. package/dist/compose/ass-file.d.ts +5 -0
  13. package/dist/compose/ass-file.d.ts.map +1 -1
  14. package/dist/compose/ass-file.js +32 -3
  15. package/dist/compose/ass-file.js.map +1 -1
  16. package/dist/compose/background.d.ts +23 -0
  17. package/dist/compose/background.d.ts.map +1 -0
  18. package/dist/compose/background.js +31 -0
  19. package/dist/compose/background.js.map +1 -0
  20. package/dist/compose/camera.d.ts +32 -0
  21. package/dist/compose/camera.d.ts.map +1 -0
  22. package/dist/compose/camera.js +98 -0
  23. package/dist/compose/camera.js.map +1 -0
  24. package/dist/compose/caption-font.d.ts +2 -0
  25. package/dist/compose/caption-font.d.ts.map +1 -1
  26. package/dist/compose/caption-font.js +2 -1
  27. package/dist/compose/caption-font.js.map +1 -1
  28. package/dist/compose/compose-drawing.d.ts +19 -0
  29. package/dist/compose/compose-drawing.d.ts.map +1 -0
  30. package/dist/compose/compose-drawing.js +38 -0
  31. package/dist/compose/compose-drawing.js.map +1 -0
  32. package/dist/compose/compose-input.d.ts +139 -0
  33. package/dist/compose/compose-input.d.ts.map +1 -1
  34. package/dist/compose/compose-input.js +48 -9
  35. package/dist/compose/compose-input.js.map +1 -1
  36. package/dist/compose/compose-plan.d.ts +36 -0
  37. package/dist/compose/compose-plan.d.ts.map +1 -0
  38. package/dist/compose/compose-plan.js +55 -0
  39. package/dist/compose/compose-plan.js.map +1 -0
  40. package/dist/compose/compose-size.d.ts +49 -0
  41. package/dist/compose/compose-size.d.ts.map +1 -0
  42. package/dist/compose/compose-size.js +67 -0
  43. package/dist/compose/compose-size.js.map +1 -0
  44. package/dist/compose/drawn-images.d.ts +19 -0
  45. package/dist/compose/drawn-images.d.ts.map +1 -0
  46. package/dist/compose/drawn-images.js +75 -0
  47. package/dist/compose/drawn-images.js.map +1 -0
  48. package/dist/compose/final-pass.d.ts +34 -0
  49. package/dist/compose/final-pass.d.ts.map +1 -0
  50. package/dist/compose/final-pass.js +106 -0
  51. package/dist/compose/final-pass.js.map +1 -0
  52. package/dist/compose/frame-layout.d.ts +30 -0
  53. package/dist/compose/frame-layout.d.ts.map +1 -0
  54. package/dist/compose/frame-layout.js +33 -0
  55. package/dist/compose/frame-layout.js.map +1 -0
  56. package/dist/compose/overlays.d.ts +20 -0
  57. package/dist/compose/overlays.d.ts.map +1 -0
  58. package/dist/compose/overlays.js +30 -0
  59. package/dist/compose/overlays.js.map +1 -0
  60. package/dist/compose/page-again.d.ts +26 -0
  61. package/dist/compose/page-again.d.ts.map +1 -0
  62. package/dist/compose/page-again.js +50 -0
  63. package/dist/compose/page-again.js.map +1 -0
  64. package/dist/compose/player-copies.d.ts +5 -1
  65. package/dist/compose/player-copies.d.ts.map +1 -1
  66. package/dist/compose/player-copies.js +19 -16
  67. package/dist/compose/player-copies.js.map +1 -1
  68. package/dist/compose/register-compose.d.ts.map +1 -1
  69. package/dist/compose/register-compose.js +104 -20
  70. package/dist/compose/register-compose.js.map +1 -1
  71. package/dist/compose/render.d.ts +13 -4
  72. package/dist/compose/render.d.ts.map +1 -1
  73. package/dist/compose/render.js +48 -22
  74. package/dist/compose/render.js.map +1 -1
  75. package/dist/compose/scene-args.d.ts +32 -7
  76. package/dist/compose/scene-args.d.ts.map +1 -1
  77. package/dist/compose/scene-args.js +77 -16
  78. package/dist/compose/scene-args.js.map +1 -1
  79. package/dist/compose/scene-look.d.ts +31 -0
  80. package/dist/compose/scene-look.d.ts.map +1 -0
  81. package/dist/compose/scene-look.js +46 -0
  82. package/dist/compose/scene-look.js.map +1 -0
  83. package/dist/compose/scene-plan.d.ts +0 -2
  84. package/dist/compose/scene-plan.d.ts.map +1 -1
  85. package/dist/compose/scene-plan.js +7 -5
  86. package/dist/compose/scene-plan.js.map +1 -1
  87. package/dist/compose/sound-effects.d.ts +23 -0
  88. package/dist/compose/sound-effects.d.ts.map +1 -0
  89. package/dist/compose/sound-effects.js +40 -0
  90. package/dist/compose/sound-effects.js.map +1 -0
  91. package/dist/compose/transitions.d.ts +16 -0
  92. package/dist/compose/transitions.d.ts.map +1 -0
  93. package/dist/compose/transitions.js +38 -0
  94. package/dist/compose/transitions.js.map +1 -0
  95. package/dist/connector.d.ts +79 -14
  96. package/dist/connector.d.ts.map +1 -1
  97. package/dist/connector.js +33 -8
  98. package/dist/connector.js.map +1 -1
  99. package/dist/files/sidecar.d.ts +209 -0
  100. package/dist/files/sidecar.d.ts.map +1 -0
  101. package/dist/files/sidecar.js +66 -0
  102. package/dist/files/sidecar.js.map +1 -0
  103. package/dist/index.d.ts.map +1 -1
  104. package/dist/index.js +9 -1
  105. package/dist/index.js.map +1 -1
  106. package/dist/look/look-at.d.ts +15 -0
  107. package/dist/look/look-at.d.ts.map +1 -0
  108. package/dist/look/look-at.js +20 -0
  109. package/dist/look/look-at.js.map +1 -0
  110. package/dist/look/look-input.d.ts +22 -0
  111. package/dist/look/look-input.d.ts.map +1 -0
  112. package/dist/look/look-input.js +25 -0
  113. package/dist/look/look-input.js.map +1 -0
  114. package/dist/look/register-look.d.ts +3 -0
  115. package/dist/look/register-look.d.ts.map +1 -0
  116. package/dist/look/register-look.js +52 -0
  117. package/dist/look/register-look.js.map +1 -0
  118. package/dist/narration/alignment.d.ts +15 -0
  119. package/dist/narration/alignment.d.ts.map +1 -0
  120. package/dist/narration/alignment.js +21 -0
  121. package/dist/narration/alignment.js.map +1 -0
  122. package/dist/narration/captions.d.ts +22 -4
  123. package/dist/narration/captions.d.ts.map +1 -1
  124. package/dist/narration/captions.js +44 -16
  125. package/dist/narration/captions.js.map +1 -1
  126. package/dist/narration/join-args.d.ts +3 -0
  127. package/dist/narration/join-args.d.ts.map +1 -0
  128. package/dist/narration/join-args.js +19 -0
  129. package/dist/narration/join-args.js.map +1 -0
  130. package/dist/narration/narration-cache.d.ts +25 -0
  131. package/dist/narration/narration-cache.d.ts.map +1 -0
  132. package/dist/narration/narration-cache.js +36 -0
  133. package/dist/narration/narration-cache.js.map +1 -0
  134. package/dist/narration/piper.d.ts +2 -6
  135. package/dist/narration/piper.d.ts.map +1 -1
  136. package/dist/narration/piper.js +9 -15
  137. package/dist/narration/piper.js.map +1 -1
  138. package/dist/narration/pronunciations.d.ts +11 -0
  139. package/dist/narration/pronunciations.d.ts.map +1 -0
  140. package/dist/narration/pronunciations.js +40 -0
  141. package/dist/narration/pronunciations.js.map +1 -0
  142. package/dist/narration/register-narration.d.ts +8 -0
  143. package/dist/narration/register-narration.d.ts.map +1 -1
  144. package/dist/narration/register-narration.js +54 -26
  145. package/dist/narration/register-narration.js.map +1 -1
  146. package/dist/narration/register-voice.d.ts +27 -0
  147. package/dist/narration/register-voice.d.ts.map +1 -0
  148. package/dist/narration/register-voice.js +82 -0
  149. package/dist/narration/register-voice.js.map +1 -0
  150. package/dist/narration/sentence-speaker.d.ts +35 -0
  151. package/dist/narration/sentence-speaker.d.ts.map +1 -0
  152. package/dist/narration/sentence-speaker.js +44 -0
  153. package/dist/narration/sentence-speaker.js.map +1 -0
  154. package/dist/narration/speech-services.d.ts +23 -3
  155. package/dist/narration/speech-services.d.ts.map +1 -1
  156. package/dist/narration/speech-services.js +27 -10
  157. package/dist/narration/speech-services.js.map +1 -1
  158. package/dist/narration/voice-args.d.ts +3 -0
  159. package/dist/narration/voice-args.d.ts.map +1 -0
  160. package/dist/narration/voice-args.js +10 -0
  161. package/dist/narration/voice-args.js.map +1 -0
  162. package/dist/programs/media-duration.d.ts +12 -0
  163. package/dist/programs/media-duration.d.ts.map +1 -1
  164. package/dist/programs/media-duration.js +13 -0
  165. package/dist/programs/media-duration.js.map +1 -1
  166. package/dist/programs/run-program.d.ts +1 -0
  167. package/dist/programs/run-program.d.ts.map +1 -1
  168. package/dist/programs/run-program.js +1 -0
  169. package/dist/programs/run-program.js.map +1 -1
  170. package/dist/record/address.d.ts +1 -1
  171. package/dist/record/address.d.ts.map +1 -1
  172. package/dist/record/address.js +5 -7
  173. package/dist/record/address.js.map +1 -1
  174. package/dist/record/cursor-script.d.ts +2 -1
  175. package/dist/record/cursor-script.d.ts.map +1 -1
  176. package/dist/record/cursor-script.js +52 -14
  177. package/dist/record/cursor-script.js.map +1 -1
  178. package/dist/record/encoder-args.js +1 -1
  179. package/dist/record/motion.d.ts +19 -0
  180. package/dist/record/motion.d.ts.map +1 -0
  181. package/dist/record/motion.js +59 -0
  182. package/dist/record/motion.js.map +1 -0
  183. package/dist/record/narration-cues.d.ts +14 -0
  184. package/dist/record/narration-cues.d.ts.map +1 -0
  185. package/dist/record/narration-cues.js +12 -0
  186. package/dist/record/narration-cues.js.map +1 -0
  187. package/dist/record/page-clock.d.ts +7 -0
  188. package/dist/record/page-clock.d.ts.map +1 -0
  189. package/dist/record/page-clock.js +13 -0
  190. package/dist/record/page-clock.js.map +1 -0
  191. package/dist/record/page-ready.d.ts +4 -0
  192. package/dist/record/page-ready.d.ts.map +1 -0
  193. package/dist/record/page-ready.js +15 -0
  194. package/dist/record/page-ready.js.map +1 -0
  195. package/dist/record/page-route.d.ts +13 -0
  196. package/dist/record/page-route.d.ts.map +1 -0
  197. package/dist/record/page-route.js +64 -0
  198. package/dist/record/page-route.js.map +1 -0
  199. package/dist/record/pointer.d.ts +6 -7
  200. package/dist/record/pointer.d.ts.map +1 -1
  201. package/dist/record/pointer.js +11 -10
  202. package/dist/record/pointer.js.map +1 -1
  203. package/dist/record/record-source.d.ts +16 -0
  204. package/dist/record/record-source.d.ts.map +1 -0
  205. package/dist/record/record-source.js +11 -0
  206. package/dist/record/record-source.js.map +1 -0
  207. package/dist/record/recorder.d.ts +19 -7
  208. package/dist/record/recorder.d.ts.map +1 -1
  209. package/dist/record/recorder.js +52 -18
  210. package/dist/record/recorder.js.map +1 -1
  211. package/dist/record/register-record.d.ts.map +1 -1
  212. package/dist/record/register-record.js +45 -13
  213. package/dist/record/register-record.js.map +1 -1
  214. package/dist/record/run-step.d.ts +16 -3
  215. package/dist/record/run-step.d.ts.map +1 -1
  216. package/dist/record/run-step.js +43 -23
  217. package/dist/record/run-step.js.map +1 -1
  218. package/dist/record/screencast.js +1 -1
  219. package/dist/record/steps.d.ts +56 -1
  220. package/dist/record/steps.d.ts.map +1 -1
  221. package/dist/record/steps.js +36 -18
  222. package/dist/record/steps.js.map +1 -1
  223. package/dist/review/analysis.d.ts +19 -0
  224. package/dist/review/analysis.d.ts.map +1 -0
  225. package/dist/review/analysis.js +36 -0
  226. package/dist/review/analysis.js.map +1 -0
  227. package/dist/review/frames.d.ts +9 -0
  228. package/dist/review/frames.d.ts.map +1 -0
  229. package/dist/review/frames.js +28 -0
  230. package/dist/review/frames.js.map +1 -0
  231. package/dist/review/register-review.d.ts +24 -0
  232. package/dist/review/register-review.d.ts.map +1 -0
  233. package/dist/review/register-review.js +81 -0
  234. package/dist/review/register-review.js.map +1 -0
  235. package/dist/review/sheet-args.d.ts +11 -0
  236. package/dist/review/sheet-args.d.ts.map +1 -0
  237. package/dist/review/sheet-args.js +24 -0
  238. package/dist/review/sheet-args.js.map +1 -0
  239. package/dist/settings.d.ts +4 -0
  240. package/dist/settings.d.ts.map +1 -1
  241. package/dist/settings.js +4 -2
  242. package/dist/settings.js.map +1 -1
  243. package/dist/setup/ffmpeg-readiness.js +1 -1
  244. package/dist/setup/ffmpeg-readiness.js.map +1 -1
  245. package/dist/ui.d.ts.map +1 -1
  246. package/dist/ui.js +3 -2
  247. package/dist/ui.js.map +1 -1
  248. package/dist/web/components/player.css +1 -1
  249. package/dist/web/components/player.js +33 -21
  250. package/docs/guide.md +39 -10
  251. package/locales/ar.json +12 -1
  252. package/locales/en.json +12 -1
  253. package/package.json +11 -5
  254. package/sounds/SOURCES.md +13 -0
  255. package/sounds/click.wav +0 -0
  256. package/sounds/keys.wav +0 -0
  257. package/sounds/pop.wav +0 -0
  258. package/sounds/whoosh.wav +0 -0
@@ -0,0 +1,209 @@
1
+ import { z } from '@kvman/sdk';
2
+ export declare const sidecarCaptionSchema: z.ZodObject<{
3
+ text: z.ZodString;
4
+ startMs: z.ZodNumber;
5
+ endMs: z.ZodNumber;
6
+ words: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
7
+ text: z.ZodString;
8
+ startMs: z.ZodNumber;
9
+ endMs: z.ZodNumber;
10
+ }, z.core.$strip>>>;
11
+ }, z.core.$strip>;
12
+ export declare const recordingSidecarSchema: z.ZodObject<{
13
+ kind: z.ZodEnum<{
14
+ page: "page";
15
+ site: "site";
16
+ }>;
17
+ source: z.ZodString;
18
+ width: z.ZodNumber;
19
+ height: z.ZodNumber;
20
+ device: z.ZodEnum<{
21
+ phone: "phone";
22
+ desktop: "desktop";
23
+ }>;
24
+ scale: z.ZodLiteral<2>;
25
+ durationMs: z.ZodNumber;
26
+ steps: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
27
+ do: z.ZodLiteral<"goto">;
28
+ url: z.ZodString;
29
+ atLine: z.ZodExactOptional<z.ZodNumber>;
30
+ }, z.core.$strict>, z.ZodObject<{
31
+ do: z.ZodLiteral<"click">;
32
+ target: z.ZodString;
33
+ atLine: z.ZodExactOptional<z.ZodNumber>;
34
+ }, z.core.$strict>, z.ZodObject<{
35
+ do: z.ZodLiteral<"type">;
36
+ target: z.ZodString;
37
+ text: z.ZodString;
38
+ atLine: z.ZodExactOptional<z.ZodNumber>;
39
+ }, z.core.$strict>, z.ZodObject<{
40
+ do: z.ZodLiteral<"press">;
41
+ key: z.ZodString;
42
+ atLine: z.ZodExactOptional<z.ZodNumber>;
43
+ }, z.core.$strict>, z.ZodObject<{
44
+ do: z.ZodLiteral<"hover">;
45
+ target: z.ZodString;
46
+ atLine: z.ZodExactOptional<z.ZodNumber>;
47
+ }, z.core.$strict>, z.ZodObject<{
48
+ do: z.ZodLiteral<"scroll">;
49
+ pixels: z.ZodNumber;
50
+ atLine: z.ZodExactOptional<z.ZodNumber>;
51
+ }, z.core.$strict>, z.ZodObject<{
52
+ do: z.ZodLiteral<"wait">;
53
+ ms: z.ZodNumber;
54
+ }, z.core.$strict>, z.ZodObject<{
55
+ do: z.ZodLiteral<"waitFor">;
56
+ target: z.ZodString;
57
+ atLine: z.ZodExactOptional<z.ZodNumber>;
58
+ }, z.core.$strict>], "do">>;
59
+ actions: z.ZodArray<z.ZodObject<{
60
+ do: z.ZodString;
61
+ atMs: z.ZodNumber;
62
+ actMs: z.ZodOptional<z.ZodNumber>;
63
+ endMs: z.ZodNumber;
64
+ box: z.ZodOptional<z.ZodObject<{
65
+ x: z.ZodNumber;
66
+ y: z.ZodNumber;
67
+ width: z.ZodNumber;
68
+ height: z.ZodNumber;
69
+ }, z.core.$strip>>;
70
+ }, z.core.$strip>>;
71
+ }, z.core.$strip>;
72
+ export declare const narrationSidecarSchema: z.ZodObject<{
73
+ kind: z.ZodLiteral<"narration">;
74
+ durationMs: z.ZodNumber;
75
+ captions: z.ZodArray<z.ZodObject<{
76
+ text: z.ZodString;
77
+ startMs: z.ZodNumber;
78
+ endMs: z.ZodNumber;
79
+ words: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
80
+ text: z.ZodString;
81
+ startMs: z.ZodNumber;
82
+ endMs: z.ZodNumber;
83
+ }, z.core.$strip>>>;
84
+ }, z.core.$strip>>;
85
+ }, z.core.$strip>;
86
+ export declare const videoSidecarSchema: z.ZodObject<{
87
+ kind: z.ZodLiteral<"video">;
88
+ durationMs: z.ZodNumber;
89
+ width: z.ZodNumber;
90
+ height: z.ZodNumber;
91
+ scenes: z.ZodArray<z.ZodObject<{
92
+ startMs: z.ZodNumber;
93
+ endMs: z.ZodNumber;
94
+ }, z.core.$strip>>;
95
+ captions: z.ZodArray<z.ZodObject<{
96
+ text: z.ZodString;
97
+ startMs: z.ZodNumber;
98
+ endMs: z.ZodNumber;
99
+ words: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
100
+ text: z.ZodString;
101
+ startMs: z.ZodNumber;
102
+ endMs: z.ZodNumber;
103
+ }, z.core.$strip>>>;
104
+ }, z.core.$strip>>;
105
+ }, z.core.$strip>;
106
+ declare const sidecarSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
107
+ kind: z.ZodEnum<{
108
+ page: "page";
109
+ site: "site";
110
+ }>;
111
+ source: z.ZodString;
112
+ width: z.ZodNumber;
113
+ height: z.ZodNumber;
114
+ device: z.ZodEnum<{
115
+ phone: "phone";
116
+ desktop: "desktop";
117
+ }>;
118
+ scale: z.ZodLiteral<2>;
119
+ durationMs: z.ZodNumber;
120
+ steps: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
121
+ do: z.ZodLiteral<"goto">;
122
+ url: z.ZodString;
123
+ atLine: z.ZodExactOptional<z.ZodNumber>;
124
+ }, z.core.$strict>, z.ZodObject<{
125
+ do: z.ZodLiteral<"click">;
126
+ target: z.ZodString;
127
+ atLine: z.ZodExactOptional<z.ZodNumber>;
128
+ }, z.core.$strict>, z.ZodObject<{
129
+ do: z.ZodLiteral<"type">;
130
+ target: z.ZodString;
131
+ text: z.ZodString;
132
+ atLine: z.ZodExactOptional<z.ZodNumber>;
133
+ }, z.core.$strict>, z.ZodObject<{
134
+ do: z.ZodLiteral<"press">;
135
+ key: z.ZodString;
136
+ atLine: z.ZodExactOptional<z.ZodNumber>;
137
+ }, z.core.$strict>, z.ZodObject<{
138
+ do: z.ZodLiteral<"hover">;
139
+ target: z.ZodString;
140
+ atLine: z.ZodExactOptional<z.ZodNumber>;
141
+ }, z.core.$strict>, z.ZodObject<{
142
+ do: z.ZodLiteral<"scroll">;
143
+ pixels: z.ZodNumber;
144
+ atLine: z.ZodExactOptional<z.ZodNumber>;
145
+ }, z.core.$strict>, z.ZodObject<{
146
+ do: z.ZodLiteral<"wait">;
147
+ ms: z.ZodNumber;
148
+ }, z.core.$strict>, z.ZodObject<{
149
+ do: z.ZodLiteral<"waitFor">;
150
+ target: z.ZodString;
151
+ atLine: z.ZodExactOptional<z.ZodNumber>;
152
+ }, z.core.$strict>], "do">>;
153
+ actions: z.ZodArray<z.ZodObject<{
154
+ do: z.ZodString;
155
+ atMs: z.ZodNumber;
156
+ actMs: z.ZodOptional<z.ZodNumber>;
157
+ endMs: z.ZodNumber;
158
+ box: z.ZodOptional<z.ZodObject<{
159
+ x: z.ZodNumber;
160
+ y: z.ZodNumber;
161
+ width: z.ZodNumber;
162
+ height: z.ZodNumber;
163
+ }, z.core.$strip>>;
164
+ }, z.core.$strip>>;
165
+ }, z.core.$strip>, z.ZodObject<{
166
+ kind: z.ZodLiteral<"narration">;
167
+ durationMs: z.ZodNumber;
168
+ captions: z.ZodArray<z.ZodObject<{
169
+ text: z.ZodString;
170
+ startMs: z.ZodNumber;
171
+ endMs: z.ZodNumber;
172
+ words: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
173
+ text: z.ZodString;
174
+ startMs: z.ZodNumber;
175
+ endMs: z.ZodNumber;
176
+ }, z.core.$strip>>>;
177
+ }, z.core.$strip>>;
178
+ }, z.core.$strip>, z.ZodObject<{
179
+ kind: z.ZodLiteral<"video">;
180
+ durationMs: z.ZodNumber;
181
+ width: z.ZodNumber;
182
+ height: z.ZodNumber;
183
+ scenes: z.ZodArray<z.ZodObject<{
184
+ startMs: z.ZodNumber;
185
+ endMs: z.ZodNumber;
186
+ }, z.core.$strip>>;
187
+ captions: z.ZodArray<z.ZodObject<{
188
+ text: z.ZodString;
189
+ startMs: z.ZodNumber;
190
+ endMs: z.ZodNumber;
191
+ words: z.ZodExactOptional<z.ZodArray<z.ZodObject<{
192
+ text: z.ZodString;
193
+ startMs: z.ZodNumber;
194
+ endMs: z.ZodNumber;
195
+ }, z.core.$strip>>>;
196
+ }, z.core.$strip>>;
197
+ }, z.core.$strip>], "kind">;
198
+ /** What a sidecar holds. */
199
+ export type Sidecar = z.output<typeof sidecarSchema>;
200
+ /** The sidecar's path beside a file. */
201
+ export declare function sidecarPath(file: string): string;
202
+ /** The sidecar beside an output; an existing one is replaced only with `replace` (plan 16 §16.3). */
203
+ export declare function sidecarOutputPath(output: string, replace: boolean, shown: string): string;
204
+ /** The sidecar beside `file`, or `undefined` when it is missing or invalid. */
205
+ export declare function readSidecar(file: string): Sidecar | undefined;
206
+ /** Writes a sidecar into a work folder, to be placed beside its output; answers its path there. */
207
+ export declare function writeSidecar(folder: string, sidecar: Sidecar): string;
208
+ export {};
209
+ //# sourceMappingURL=sidecar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidecar.d.ts","sourceRoot":"","sources":["../../src/files/sidecar.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAS/B,eAAO,MAAM,oBAAoB;;;;;;;;;iBAA6J,CAAC;AAE/L,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAUjC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;iBAAkI,CAAC;AAEtK,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;iBAO7B,CAAC;AAEH,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAAqG,CAAC;AAEzH,4BAA4B;AAC5B,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAErD,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,qGAAqG;AACrG,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzF;AAWD,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAK7D;AAED,mGAAmG;AACnG,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAIrE"}
@@ -0,0 +1,66 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { z } from '@kvman/sdk';
4
+ import { invalid } from "../problems.js";
5
+ import { actionSchema, stepSchema } from "../record/steps.js";
6
+ // The sidecar beside an output, `<file>.kvvideo.json` (plan 16 §16.3; ADR 0115, 31): what a later command needs from
7
+ // it, so the agent copies no numbers between calls. It is validated when read; a missing or invalid one is absent.
8
+ const wordSchema = z.object({ text: z.string(), startMs: z.number().int().nonnegative(), endMs: z.number().int().nonnegative() });
9
+ export const sidecarCaptionSchema = z.object({ text: z.string(), startMs: z.number().int().nonnegative(), endMs: z.number().int().nonnegative(), words: z.array(wordSchema).exactOptional() });
10
+ export const recordingSidecarSchema = z.object({
11
+ kind: z.enum(['site', 'page']),
12
+ source: z.string(),
13
+ width: z.number().int().positive(),
14
+ height: z.number().int().positive(),
15
+ device: z.enum(['desktop', 'phone']),
16
+ scale: z.literal(2),
17
+ durationMs: z.number().int().nonnegative(),
18
+ steps: z.array(stepSchema),
19
+ actions: z.array(actionSchema),
20
+ });
21
+ export const narrationSidecarSchema = z.object({ kind: z.literal('narration'), durationMs: z.number().int().nonnegative(), captions: z.array(sidecarCaptionSchema) });
22
+ export const videoSidecarSchema = z.object({
23
+ kind: z.literal('video'),
24
+ durationMs: z.number().int().nonnegative(),
25
+ width: z.number().int().positive(),
26
+ height: z.number().int().positive(),
27
+ scenes: z.array(z.object({ startMs: z.number().int().nonnegative(), endMs: z.number().int().nonnegative() })),
28
+ captions: z.array(sidecarCaptionSchema),
29
+ });
30
+ const sidecarSchema = z.discriminatedUnion('kind', [recordingSidecarSchema, narrationSidecarSchema, videoSidecarSchema]);
31
+ /** The sidecar's path beside a file. */
32
+ export function sidecarPath(file) {
33
+ return `${file}.kvvideo.json`;
34
+ }
35
+ /** The sidecar beside an output; an existing one is replaced only with `replace` (plan 16 §16.3). */
36
+ export function sidecarOutputPath(output, replace, shown) {
37
+ const beside = sidecarPath(output);
38
+ if (existsSync(beside) && !replace)
39
+ throw invalid(`${sidecarPath(shown)} exists; set replace to true to write over it.`, { path: sidecarPath(shown) });
40
+ return beside;
41
+ }
42
+ function parsed(text) {
43
+ try {
44
+ return JSON.parse(text);
45
+ }
46
+ catch (error) {
47
+ if (error instanceof SyntaxError)
48
+ return undefined;
49
+ throw error;
50
+ }
51
+ }
52
+ /** The sidecar beside `file`, or `undefined` when it is missing or invalid. */
53
+ export function readSidecar(file) {
54
+ const beside = sidecarPath(file);
55
+ if (!existsSync(beside))
56
+ return undefined;
57
+ const result = sidecarSchema.safeParse(parsed(readFileSync(beside, 'utf8')));
58
+ return result.success ? result.data : undefined;
59
+ }
60
+ /** Writes a sidecar into a work folder, to be placed beside its output; answers its path there. */
61
+ export function writeSidecar(folder, sidecar) {
62
+ const made = path.join(folder, 'sidecar.json');
63
+ writeFileSync(made, `${JSON.stringify(sidecar, null, 2)}\n`);
64
+ return made;
65
+ }
66
+ //# sourceMappingURL=sidecar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../../src/files/sidecar.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAWtC,YAAY,EAAE,MAAM,UAAU,CAAC;yBAKf,KAAK,GAAG,KAAG,IAAI;AAA/B,wBAUE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAetC,YAAY,EAAE,MAAM,UAAU,CAAC;yBAKf,KAAK,GAAG,KAAG,IAAI;AAA/B,wBAcE"}
package/dist/index.js CHANGED
@@ -1,23 +1,31 @@
1
+ import { registerBrand } from "./brand/brand.js";
1
2
  import { registerCompose } from "./compose/register-compose.js";
2
3
  import { registerFonts } from "./fonts/register-fonts.js";
4
+ import { registerLook } from "./look/register-look.js";
3
5
  import { registerNarration } from "./narration/register-narration.js";
6
+ import { registerVoice } from "./narration/register-voice.js";
4
7
  import { registerRecord } from "./record/register-record.js";
8
+ import { registerReview } from "./review/register-review.js";
5
9
  import { registerWithKvcoder } from "./register-with-kvcoder.js";
6
10
  import { registerSettings } from "./settings.js";
7
11
  import { registerSetup } from "./setup/register-setup.js";
8
12
  import { registerUi } from "./ui.js";
9
13
  import { registerVideoStart } from "./video-start.js";
10
- // kvvideo (plan 16): makes videos of the person's app, recorded in the installed browser, narrated, and captioned. It
14
+ // kvvideo (plan 16): makes any kind of video, recorded in the installed browser, narrated, and captioned. It
11
15
  // has no loop of its own; it extends kvcoder with the `video` connector and its guide, which a chat has once the
12
16
  // person runs `/video` in it (ADR 0107).
13
17
  export default (ctx) => {
14
18
  registerSettings(ctx);
19
+ registerBrand(ctx);
15
20
  registerUi(ctx);
16
21
  registerSetup(ctx);
17
22
  registerFonts(ctx);
18
23
  registerRecord(ctx);
24
+ registerLook(ctx);
19
25
  registerNarration(ctx);
26
+ registerVoice(ctx);
20
27
  registerCompose(ctx);
28
+ registerReview(ctx);
21
29
  registerVideoStart(ctx);
22
30
  registerWithKvcoder(ctx);
23
31
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAItD,sHAAsH;AACtH,iHAAiH;AACjH,yCAAyC;AACzC,eAAe,CAAC,GAAQ,EAAQ,EAAE;IAChC,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACtB,UAAU,CAAC,GAAG,CAAC,CAAC;IAChB,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,cAAc,CAAC,GAAG,CAAC,CAAC;IACpB,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACvB,eAAe,CAAC,GAAG,CAAC,CAAC;IACrB,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACxB,mBAAmB,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAItD,6GAA6G;AAC7G,iHAAiH;AACjH,yCAAyC;AACzC,eAAe,CAAC,GAAQ,EAAQ,EAAE;IAChC,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACtB,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,UAAU,CAAC,GAAG,CAAC,CAAC;IAChB,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,cAAc,CAAC,GAAG,CAAC,CAAC;IACpB,YAAY,CAAC,GAAG,CAAC,CAAC;IAClB,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACvB,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,eAAe,CAAC,GAAG,CAAC,CAAC;IACrB,cAAc,CAAC,GAAG,CAAC,CAAC;IACpB,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACxB,mBAAmB,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { Browser } from 'playwright-core';
2
+ import { type RecordSource } from '../record/recorder.ts';
3
+ export type LookPlan = {
4
+ source: RecordSource;
5
+ width: number;
6
+ height: number;
7
+ device: 'desktop' | 'phone';
8
+ ownPort: number | null;
9
+ moments: readonly number[];
10
+ };
11
+ export declare function lookAt(browser: Browser, plan: LookPlan): Promise<{
12
+ atMs: number;
13
+ image: Buffer;
14
+ }[]>;
15
+ //# sourceMappingURL=look-at.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"look-at.d.ts","sourceRoot":"","sources":["../../src/look/look-at.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAKxF,MAAM,MAAM,QAAQ,GAAG;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAEhK,wBAAsB,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAezG"}
@@ -0,0 +1,20 @@
1
+ import { holdPageClock } from "../record/page-clock.js";
2
+ import { openSource, recordingContext } from "../record/recorder.js";
3
+ export async function lookAt(browser, plan) {
4
+ const context = await recordingContext(browser, plan);
5
+ try {
6
+ const page = await context.newPage();
7
+ const clock = await holdPageClock(page);
8
+ await openSource(page, plan.source);
9
+ const frames = [];
10
+ for (const atMs of [...plan.moments].sort((first, second) => first - second)) {
11
+ await clock.seek(atMs);
12
+ frames.push({ atMs, image: await page.screenshot({ type: 'jpeg', quality: 85, scale: 'css' }) });
13
+ }
14
+ return frames;
15
+ }
16
+ finally {
17
+ await context.close();
18
+ }
19
+ }
20
+ //# sourceMappingURL=look-at.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"look-at.js","sourceRoot":"","sources":["../../src/look/look-at.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAqB,MAAM,uBAAuB,CAAC;AAOxF,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAgB,EAAE,IAAc;IAC3D,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;YAC7E,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACnG,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { z } from '@kvman/sdk';
2
+ export declare const lookInputSchema: z.ZodObject<{
3
+ url: z.ZodExactOptional<z.ZodString>;
4
+ page: z.ZodExactOptional<z.ZodString>;
5
+ atMs: z.ZodExactOptional<z.ZodArray<z.ZodNumber>>;
6
+ width: z.ZodExactOptional<z.ZodNumber>;
7
+ height: z.ZodExactOptional<z.ZodNumber>;
8
+ device: z.ZodExactOptional<z.ZodEnum<{
9
+ phone: "phone";
10
+ desktop: "desktop";
11
+ }>>;
12
+ }, z.core.$strict>;
13
+ /** `look`'s input. */
14
+ export type LookInput = z.output<typeof lookInputSchema>;
15
+ export declare const lookOutputSchema: z.ZodObject<{
16
+ images: z.ZodArray<z.ZodObject<{
17
+ fileId: z.ZodString;
18
+ name: z.ZodString;
19
+ atMs: z.ZodNumber;
20
+ }, z.core.$strip>>;
21
+ }, z.core.$strip>;
22
+ //# sourceMappingURL=look-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"look-input.d.ts","sourceRoot":"","sources":["../../src/look/look-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAuB/B,eAAO,MAAM,eAAe;;;;;;;;;;kBAE1B,CAAC;AAEH,sBAAsB;AACtB,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAEzD,eAAO,MAAM,gBAAgB;;;;;;iBAAkG,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { z } from '@kvman/sdk';
2
+ import { address, side } from "../record/steps.js";
3
+ // `look`'s input and answer (plan 16 §16.5 Looking; ADR 0117, 19): a website or a page as `record` opens it, and 1 to 6
4
+ // distinct moments of its clock, `[1000]` when left out.
5
+ const moment = z.number().int().min(0).max(60_000);
6
+ const lookFields = z.strictObject({
7
+ url: address.describe('A website to look at: any http or https address.').exactOptional(),
8
+ page: z.string().min(1).max(1000).describe('An .html file of the workspace to look at, with the files beside it.').exactOptional(),
9
+ atMs: z
10
+ .array(moment)
11
+ .min(1)
12
+ .max(6)
13
+ .refine((moments) => new Set(moments).size === moments.length, 'Each moment is given once.')
14
+ .describe("The moments to show, in ms from the page's clock start (0 to 60000); 1000 when left out.")
15
+ .exactOptional(),
16
+ width: side.describe('The page width in CSS pixels: 1280 by default, 390 on a phone.').exactOptional(),
17
+ height: side.describe('The page height in CSS pixels: 720 by default, 844 on a phone.').exactOptional(),
18
+ device: z.enum(['desktop', 'phone']).describe('desktop (the default), or phone.').exactOptional(),
19
+ });
20
+ export const lookInputSchema = lookFields.superRefine((input, context) => {
21
+ if ((input.url === undefined) === (input.page === undefined))
22
+ context.addIssue({ code: 'custom', path: ['url'], message: 'Give exactly one of url and page.' });
23
+ });
24
+ export const lookOutputSchema = z.object({ images: z.array(z.object({ fileId: z.string(), name: z.string(), atMs: moment })) });
25
+ //# sourceMappingURL=look-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"look-input.js","sourceRoot":"","sources":["../../src/look/look-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAEnD,wHAAwH;AACxH,yDAAyD;AAEzD,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAEnD,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC;IAChC,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,kDAAkD,CAAC,CAAC,aAAa,EAAE;IACzF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,sEAAsE,CAAC,CAAC,aAAa,EAAE;IAClI,IAAI,EAAE,CAAC;SACJ,KAAK,CAAC,MAAM,CAAC;SACb,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,CAAC,CAAC;SACN,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,EAAE,4BAA4B,CAAC;SAC3F,QAAQ,CAAC,0FAA0F,CAAC;SACpG,aAAa,EAAE;IAClB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,gEAAgE,CAAC,CAAC,aAAa,EAAE;IACtG,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,gEAAgE,CAAC,CAAC,aAAa,EAAE;IACvG,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC,CAAC,aAAa,EAAE;CAClG,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACvE,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC;QAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC,CAAC;AAClK,CAAC,CAAC,CAAC;AAKH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type Ctx } from '@kvman/sdk';
2
+ export declare function registerLook(ctx: Ctx): void;
3
+ //# sourceMappingURL=register-look.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-look.d.ts","sourceRoot":"","sources":["../../src/look/register-look.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAkBzC,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAkC3C"}
@@ -0,0 +1,52 @@
1
+ import { z } from '@kvman/sdk';
2
+ import { launchChannel } from "../browser/launch.js";
3
+ import { startBrowser } from "../browser/start-browser.js";
4
+ import { trimOldest } from "../narration/narration-cache.js";
5
+ import { ownPortOf } from "../record/own-port.js";
6
+ import { defaultSize, sourceOf } from "../record/record-source.js";
7
+ import { lookAt } from "./look-at.js";
8
+ import { lookInputSchema, lookOutputSchema } from "./look-input.js";
9
+ // `video look` (plan 16 §16.5 Looking; ADR 0117, 4 and 19): a page's or a website's frames at chosen moments, which the
10
+ // model sees through kvcoder (`images: true`), to check a scene before it is narrated and recorded. The source is
11
+ // checked before a browser starts; the browser is closed when the call ends, fails, or is cancelled. The newest 24
12
+ // frames of the workspace are kept in the kernel's files.
13
+ const keptFrames = 24;
14
+ const frameRowSchema = z.object({ fileId: z.string(), createdAt: z.string() });
15
+ export function registerLook(ctx) {
16
+ ctx.registerCommand('kvvideo.frame.capture', {
17
+ description: "Shows a website's or an HTML page's frames at chosen moments of its clock, to look at a scene before it is recorded.",
18
+ input: lookInputSchema,
19
+ output: lookOutputSchema,
20
+ public: true,
21
+ retries: 0,
22
+ timeoutMs: 120_000,
23
+ handle: async (input) => {
24
+ const ownPort = ownPortOf(process.env['KVMAN_HOME']);
25
+ const source = sourceOf(ctx.job.workspace.path, input, ownPort);
26
+ const device = input.device ?? 'desktop';
27
+ const size = { width: input.width ?? defaultSize[device].width, height: input.height ?? defaultSize[device].height };
28
+ const browser = await startBrowser(await ctx.settings.get('kvvideo.browser'), launchChannel);
29
+ const stop = () => void browser.close();
30
+ ctx.job.signal.addEventListener('abort', stop, { once: true });
31
+ try {
32
+ const frames = await lookAt(browser, { source, ...size, device, ownPort, moments: input.atMs ?? [1000] });
33
+ const images = [];
34
+ for (const [index, frame] of frames.entries()) {
35
+ const name = `look-${String(index + 1)}.jpg`;
36
+ const stored = await ctx.files.write(name, frame.image, 'image/jpeg');
37
+ images.push({ fileId: stored.id, name, atMs: frame.atMs });
38
+ }
39
+ const rows = ctx.store.collection('lookFrames', frameRowSchema);
40
+ for (const image of images)
41
+ await rows.insert({ fileId: image.fileId, createdAt: new Date().toISOString() });
42
+ await trimOldest(rows, ctx.files, keptFrames);
43
+ return { images };
44
+ }
45
+ finally {
46
+ ctx.job.signal.removeEventListener('abort', stop);
47
+ await browser.close();
48
+ }
49
+ },
50
+ });
51
+ }
52
+ //# sourceMappingURL=register-look.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-look.js","sourceRoot":"","sources":["../../src/look/register-look.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { z } from '@kvman/sdk';
2
+ export declare const alignmentSchema: z.ZodObject<{
3
+ startsMs: z.ZodArray<z.ZodNumber>;
4
+ endsMs: z.ZodArray<z.ZodNumber>;
5
+ }, z.core.$strip>;
6
+ /** When each spoken character starts and ends, in ms from the sentence's start. */
7
+ export type Alignment = z.output<typeof alignmentSchema>;
8
+ export declare const elevenLabsAlignmentSchema: z.ZodObject<{
9
+ characters: z.ZodArray<z.ZodString>;
10
+ character_start_times_seconds: z.ZodArray<z.ZodNumber>;
11
+ character_end_times_seconds: z.ZodArray<z.ZodNumber>;
12
+ }, z.core.$strip>;
13
+ /** The alignment of `spoken`; one whose characters aren't the text fails `kvvideo/NARRATION_FAILED`. */
14
+ export declare function alignmentOf(answer: z.output<typeof elevenLabsAlignmentSchema>, spoken: string): Alignment;
15
+ //# sourceMappingURL=alignment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alignment.d.ts","sourceRoot":"","sources":["../../src/narration/alignment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAM/B,eAAO,MAAM,eAAe;;;iBAAmH,CAAC;AAEhJ,mFAAmF;AACnF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAEzD,eAAO,MAAM,yBAAyB;;;;iBAIpC,CAAC;AAIH,wGAAwG;AACxG,wBAAgB,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,yBAAyB,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAOzG"}
@@ -0,0 +1,21 @@
1
+ import { z } from '@kvman/sdk';
2
+ import { kvvideoProblem } from "../problems.js";
3
+ // ElevenLabs's character times (plan 16 §16.6; ADR 0115, 17): each character of the text it was sent, by code point,
4
+ // with when it starts and ends, kept in whole milliseconds.
5
+ export const alignmentSchema = z.object({ startsMs: z.array(z.number().int().nonnegative()), endsMs: z.array(z.number().int().nonnegative()) });
6
+ export const elevenLabsAlignmentSchema = z.object({
7
+ characters: z.array(z.string()),
8
+ character_start_times_seconds: z.array(z.number()),
9
+ character_end_times_seconds: z.array(z.number()),
10
+ });
11
+ const ms = (seconds) => Math.max(0, Math.round(seconds * 1000));
12
+ /** The alignment of `spoken`; one whose characters aren't the text fails `kvvideo/NARRATION_FAILED`. */
13
+ export function alignmentOf(answer, spoken) {
14
+ const { characters, character_start_times_seconds: starts, character_end_times_seconds: ends } = answer;
15
+ if (characters.join('') !== spoken || [...spoken].length !== characters.length || starts.length !== characters.length || ends.length !== characters.length) {
16
+ const reason = "ElevenLabs's character times don't match the text it was sent";
17
+ throw kvvideoProblem('NARRATION_FAILED', reason, { service: 'elevenlabs', reason });
18
+ }
19
+ return { startsMs: starts.map(ms), endsMs: ends.map(ms) };
20
+ }
21
+ //# sourceMappingURL=alignment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alignment.js","sourceRoot":"","sources":["../../src/narration/alignment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,qHAAqH;AACrH,4DAA4D;AAE5D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;AAKhJ,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC/B,6BAA6B,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAClD,2BAA2B,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CACjD,CAAC,CAAC;AAEH,MAAM,EAAE,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC;AAEhF,wGAAwG;AACxG,MAAM,UAAU,WAAW,CAAC,MAAkD,EAAE,MAAc;IAC5F,MAAM,EAAE,UAAU,EAAE,6BAA6B,EAAE,MAAM,EAAE,2BAA2B,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;IACxG,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,MAAM,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;QAC3J,MAAM,MAAM,GAAG,+DAA+D,CAAC;QAC/E,MAAM,cAAc,CAAC,kBAAkB,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;AAC5D,CAAC"}
@@ -1,10 +1,28 @@
1
+ import type { Alignment } from './alignment.ts';
2
+ import type { Spoken } from './pronunciations.ts';
3
+ export type Word = {
4
+ text: string;
5
+ startMs: number;
6
+ endMs: number;
7
+ };
1
8
  export type Caption = {
2
9
  text: string;
3
10
  startMs: number;
4
11
  endMs: number;
12
+ words?: Word[];
13
+ };
14
+ /** The text's sentences, in order: cut at line breaks and after `.`, `!`, `?`, `؟`, and `…` followed by a space. */
15
+ export declare function sentencesOf(text: string): string[];
16
+ /** A sentence's caption lines: whole words, each line as long as it can be up to 42 characters. */
17
+ export declare function linesOf(sentence: string): string[];
18
+ /** One sentence's place in the narration: its audio from `startMs` for `durationMs`, and its character times. */
19
+ export type PlacedSentence = {
20
+ text: string;
21
+ spoken: Spoken;
22
+ startMs: number;
23
+ durationMs: number;
24
+ alignment: Alignment | null;
5
25
  };
6
- /** The caption lines of a text, in order. */
7
- export declare function captionLines(text: string): string[];
8
- /** The text's captions over a narration of `durationMs`. */
9
- export declare function timedCaptions(text: string, durationMs: number): Caption[];
26
+ /** The captions of placed sentences over a narration of `durationMs`: each line ends where the next starts. */
27
+ export declare function captionsOf(sentences: readonly PlacedSentence[], durationMs: number): Caption[];
10
28
  //# sourceMappingURL=captions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"captions.d.ts","sourceRoot":"","sources":["../../src/narration/captions.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AA0BvE,6CAA6C;AAC7C,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAGnD;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,EAAE,CAUzE"}
1
+ {"version":3,"file":"captions.d.ts","sourceRoot":"","sources":["../../src/narration/captions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAMlD,MAAM,MAAM,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpE,MAAM,MAAM,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC;AAMvF,oHAAoH;AACpH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAMlD;AAED,mGAAmG;AACnG,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAclD;AAED,iHAAiH;AACjH,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAA;CAAE,CAAC;AAwChI,+GAA+G;AAC/G,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,EAAE,CAG9F"}