screenci 0.0.10 → 0.0.11

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 (68) hide show
  1. package/README.md +44 -58
  2. package/dist/Dockerfile +16 -2
  3. package/dist/cli.d.ts +21 -1
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +1199 -420
  6. package/dist/cli.js.map +1 -1
  7. package/dist/e2e/instrument.e2e.js +12 -0
  8. package/dist/e2e/instrument.e2e.js.map +1 -1
  9. package/dist/index.d.ts +7 -7
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -2
  12. package/dist/index.js.map +1 -1
  13. package/dist/playwright.config.d.ts +1 -1
  14. package/dist/src/asset.d.ts +27 -67
  15. package/dist/src/asset.d.ts.map +1 -1
  16. package/dist/src/asset.js +44 -45
  17. package/dist/src/asset.js.map +1 -1
  18. package/dist/src/caption.d.ts +164 -54
  19. package/dist/src/caption.d.ts.map +1 -1
  20. package/dist/src/caption.js +304 -131
  21. package/dist/src/caption.js.map +1 -1
  22. package/dist/src/events.d.ts +67 -25
  23. package/dist/src/events.d.ts.map +1 -1
  24. package/dist/src/events.js +34 -18
  25. package/dist/src/events.js.map +1 -1
  26. package/dist/src/instrument.d.ts.map +1 -1
  27. package/dist/src/instrument.js +142 -35
  28. package/dist/src/instrument.js.map +1 -1
  29. package/dist/src/logger.d.ts.map +1 -1
  30. package/dist/src/logger.js +2 -1
  31. package/dist/src/logger.js.map +1 -1
  32. package/dist/src/recording.d.ts +1 -1
  33. package/dist/src/recording.d.ts.map +1 -1
  34. package/dist/src/recordingData.d.ts +145 -0
  35. package/dist/src/recordingData.d.ts.map +1 -0
  36. package/dist/src/recordingData.js +2 -0
  37. package/dist/src/recordingData.js.map +1 -0
  38. package/dist/src/types.d.ts +133 -66
  39. package/dist/src/types.d.ts.map +1 -1
  40. package/dist/src/video.d.ts.map +1 -1
  41. package/dist/src/video.js +28 -20
  42. package/dist/src/video.js.map +1 -1
  43. package/dist/src/voices.d.ts +344 -41
  44. package/dist/src/voices.d.ts.map +1 -1
  45. package/dist/src/voices.js +261 -30
  46. package/dist/src/voices.js.map +1 -1
  47. package/dist/test-fixtures/screenci.config.d.ts +5 -0
  48. package/dist/test-fixtures/screenci.config.d.ts.map +1 -0
  49. package/dist/test-fixtures/screenci.config.js +4 -0
  50. package/dist/test-fixtures/screenci.config.js.map +1 -0
  51. package/dist/tsconfig.tsbuildinfo +1 -1
  52. package/package.json +34 -4
  53. package/skills/playwright-cli/SKILL.md +348 -0
  54. package/skills/screenci/SKILL.md +55 -0
  55. package/skills/screenci/references/init.md +47 -0
  56. package/skills/screenci/references/record.md +41 -0
  57. package/dist/reporter.d.ts +0 -9
  58. package/dist/reporter.d.ts.map +0 -1
  59. package/dist/reporter.js +0 -49
  60. package/dist/reporter.js.map +0 -1
  61. package/dist/src/caption.test-d.d.ts +0 -2
  62. package/dist/src/caption.test-d.d.ts.map +0 -1
  63. package/dist/src/caption.test-d.js +0 -50
  64. package/dist/src/caption.test-d.js.map +0 -1
  65. package/dist/src/captionHash.d.ts +0 -12
  66. package/dist/src/captionHash.d.ts.map +0 -1
  67. package/dist/src/captionHash.js +0 -17
  68. package/dist/src/captionHash.js.map +0 -1
@@ -0,0 +1,348 @@
1
+ ---
2
+ name: playwright-cli
3
+ description: Automate browser interactions, test web pages and work with Playwright tests.
4
+ allowed-tools:
5
+ - Bash(playwright-cli:*)
6
+ - Bash(npx:*)
7
+ - Bash(npm:*)
8
+ ---
9
+
10
+ # Browser Automation with playwright-cli
11
+
12
+ ## Quick start
13
+
14
+ ```bash
15
+ # open new browser
16
+ playwright-cli open
17
+ # navigate to a page
18
+ playwright-cli goto https://playwright.dev
19
+ # interact with the page using refs from the snapshot
20
+ playwright-cli click e15
21
+ playwright-cli type "page.click"
22
+ playwright-cli press Enter
23
+ # take a screenshot (rarely used, as snapshot is more common)
24
+ playwright-cli screenshot
25
+ # close the browser
26
+ playwright-cli close
27
+ ```
28
+
29
+ ## Commands
30
+
31
+ ### Core
32
+
33
+ ```bash
34
+ playwright-cli open
35
+ # open and navigate right away
36
+ playwright-cli open https://example.com/
37
+ playwright-cli goto https://playwright.dev
38
+ playwright-cli type "search query"
39
+ playwright-cli click e3
40
+ playwright-cli dblclick e7
41
+ # --submit presses Enter after filling the element
42
+ playwright-cli fill e5 "user@example.com" --submit
43
+ playwright-cli drag e2 e8
44
+ playwright-cli hover e4
45
+ playwright-cli select e9 "option-value"
46
+ playwright-cli upload ./document.pdf
47
+ playwright-cli check e12
48
+ playwright-cli uncheck e12
49
+ playwright-cli snapshot
50
+ playwright-cli eval "document.title"
51
+ playwright-cli eval "el => el.textContent" e5
52
+ # get element id, class, or any attribute not visible in the snapshot
53
+ playwright-cli eval "el => el.id" e5
54
+ playwright-cli eval "el => el.getAttribute('data-testid')" e5
55
+ playwright-cli dialog-accept
56
+ playwright-cli dialog-accept "confirmation text"
57
+ playwright-cli dialog-dismiss
58
+ playwright-cli resize 1920 1080
59
+ playwright-cli close
60
+ ```
61
+
62
+ ### Navigation
63
+
64
+ ```bash
65
+ playwright-cli go-back
66
+ playwright-cli go-forward
67
+ playwright-cli reload
68
+ ```
69
+
70
+ ### Keyboard
71
+
72
+ ```bash
73
+ playwright-cli press Enter
74
+ playwright-cli press ArrowDown
75
+ playwright-cli keydown Shift
76
+ playwright-cli keyup Shift
77
+ ```
78
+
79
+ ### Mouse
80
+
81
+ ```bash
82
+ playwright-cli mousemove 150 300
83
+ playwright-cli mousedown
84
+ playwright-cli mousedown right
85
+ playwright-cli mouseup
86
+ playwright-cli mouseup right
87
+ playwright-cli mousewheel 0 100
88
+ ```
89
+
90
+ ### Save as
91
+
92
+ ```bash
93
+ playwright-cli screenshot
94
+ playwright-cli screenshot e5
95
+ playwright-cli screenshot --filename=page.png
96
+ playwright-cli pdf --filename=page.pdf
97
+ ```
98
+
99
+ ### Tabs
100
+
101
+ ```bash
102
+ playwright-cli tab-list
103
+ playwright-cli tab-new
104
+ playwright-cli tab-new https://example.com/page
105
+ playwright-cli tab-close
106
+ playwright-cli tab-close 2
107
+ playwright-cli tab-select 0
108
+ ```
109
+
110
+ ### Storage
111
+
112
+ ```bash
113
+ playwright-cli state-save
114
+ playwright-cli state-save auth.json
115
+ playwright-cli state-load auth.json
116
+
117
+ # Cookies
118
+ playwright-cli cookie-list
119
+ playwright-cli cookie-list --domain=example.com
120
+ playwright-cli cookie-get session_id
121
+ playwright-cli cookie-set session_id abc123
122
+ playwright-cli cookie-set session_id abc123 --domain=example.com --httpOnly --secure
123
+ playwright-cli cookie-delete session_id
124
+ playwright-cli cookie-clear
125
+
126
+ # LocalStorage
127
+ playwright-cli localstorage-list
128
+ playwright-cli localstorage-get theme
129
+ playwright-cli localstorage-set theme dark
130
+ playwright-cli localstorage-delete theme
131
+ playwright-cli localstorage-clear
132
+
133
+ # SessionStorage
134
+ playwright-cli sessionstorage-list
135
+ playwright-cli sessionstorage-get step
136
+ playwright-cli sessionstorage-set step 3
137
+ playwright-cli sessionstorage-delete step
138
+ playwright-cli sessionstorage-clear
139
+ ```
140
+
141
+ ### Network
142
+
143
+ ```bash
144
+ playwright-cli route "**/*.jpg" --status=404
145
+ playwright-cli route "https://api.example.com/**" --body='{"mock": true}'
146
+ playwright-cli route-list
147
+ playwright-cli unroute "**/*.jpg"
148
+ playwright-cli unroute
149
+ ```
150
+
151
+ ### DevTools
152
+
153
+ ```bash
154
+ playwright-cli console
155
+ playwright-cli console warning
156
+ playwright-cli network
157
+ playwright-cli run-code "async page => await page.context().grantPermissions(['geolocation'])"
158
+ playwright-cli run-code --filename=script.js
159
+ playwright-cli tracing-start
160
+ playwright-cli tracing-stop
161
+ playwright-cli video-start video.webm
162
+ playwright-cli video-chapter "Chapter Title" --description="Details" --duration=2000
163
+ playwright-cli video-stop
164
+ ```
165
+
166
+ ## Raw output
167
+
168
+ The global `--raw` option strips page status, generated code, and snapshot sections from the output, returning only the result value.
169
+ Use it to pipe command output into other tools. Commands that don't produce output return nothing.
170
+
171
+ ```bash
172
+ playwright-cli --raw eval "JSON.stringify(performance.timing)" | jq '.loadEventEnd - .navigationStart'
173
+ playwright-cli --raw eval "JSON.stringify([...document.querySelectorAll('a')].map(a => a.href))" > links.json
174
+ playwright-cli --raw snapshot > before.yml
175
+ playwright-cli click e5
176
+ playwright-cli --raw snapshot > after.yml
177
+ diff before.yml after.yml
178
+ TOKEN=$(playwright-cli --raw cookie-get session_id)
179
+ playwright-cli --raw localstorage-get theme
180
+ ```
181
+
182
+ ## Open parameters
183
+
184
+ ```bash
185
+ # Use specific browser when creating session
186
+ playwright-cli open --browser=chrome
187
+ playwright-cli open --browser=firefox
188
+ playwright-cli open --browser=webkit
189
+ playwright-cli open --browser=msedge
190
+
191
+ # Use persistent profile (by default profile is in-memory)
192
+ playwright-cli open --persistent
193
+
194
+ # Use persistent profile with custom directory
195
+ playwright-cli open --profile=/path/to/profile
196
+
197
+ # Connect to browser via extension
198
+ playwright-cli attach --extension
199
+
200
+ # Start with config file
201
+ playwright-cli open --config=my-config.json
202
+
203
+ # Close the browser
204
+ playwright-cli close
205
+
206
+ # Delete user data for the default session
207
+ playwright-cli delete-data
208
+ ```
209
+
210
+ ## Snapshots
211
+
212
+ After each command, playwright-cli provides a snapshot of the current browser state.
213
+
214
+ ```bash
215
+ > playwright-cli goto https://example.com
216
+ ### Page
217
+ - Page URL: https://example.com/
218
+ - Page Title: Example Domain
219
+ ### Snapshot
220
+ [Snapshot](.playwright-cli/page-2026-02-14T19-22-42-679Z.yml)
221
+ ```
222
+
223
+ You can also take a snapshot on demand using `playwright-cli snapshot` command. All the options below can be combined as needed.
224
+
225
+ ```bash
226
+ # default - save to a file with timestamp-based name
227
+ playwright-cli snapshot
228
+
229
+ # save to file, use when snapshot is a part of the workflow result
230
+ playwright-cli snapshot --filename=after-click.yaml
231
+
232
+ # snapshot an element instead of the whole page
233
+ playwright-cli snapshot "#main"
234
+
235
+ # limit snapshot depth for efficiency, take a partial snapshot afterwards
236
+ playwright-cli snapshot --depth=4
237
+ playwright-cli snapshot e34
238
+ ```
239
+
240
+ ## Targeting elements
241
+
242
+ By default, use refs from the snapshot to interact with page elements.
243
+
244
+ ```bash
245
+ # get snapshot with refs
246
+ playwright-cli snapshot
247
+
248
+ # interact using a ref
249
+ playwright-cli click e15
250
+ ```
251
+
252
+ You can also use css selectors or Playwright locators.
253
+
254
+ ```bash
255
+ # css selector
256
+ playwright-cli click "#main > button.submit"
257
+
258
+ # role locator
259
+ playwright-cli click "getByRole('button', { name: 'Submit' })"
260
+
261
+ # test id
262
+ playwright-cli click "getByTestId('submit-button')"
263
+ ```
264
+
265
+ ## Browser Sessions
266
+
267
+ ```bash
268
+ # create new browser session named "mysession" with persistent profile
269
+ playwright-cli -s=mysession open example.com --persistent
270
+
271
+ # same with manually specified profile directory (use when requested explicitly)
272
+ playwright-cli -s=mysession open example.com --profile=/path/to/profile
273
+ playwright-cli -s=mysession click e6
274
+ playwright-cli -s=mysession close
275
+
276
+ # stop a named browser
277
+ playwright-cli -s=mysession delete-data
278
+
279
+ # delete user data for persistent session
280
+ playwright-cli list
281
+
282
+ # Close all browsers
283
+ playwright-cli close-all
284
+
285
+ # Forcefully kill all browser processes
286
+ playwright-cli kill-all
287
+ ```
288
+
289
+ ## Installation
290
+
291
+ If global `playwright-cli` command is not available, try a local version via `npx playwright-cli`:
292
+
293
+ ```bash
294
+ npx --no-install playwright-cli --version
295
+ ```
296
+
297
+ Otherwise, install `playwright-cli` as a global command:
298
+
299
+ ```bash
300
+ npm install -g @playwright/cli@latest
301
+ ```
302
+
303
+ ## Example: Form submission
304
+
305
+ ```bash
306
+ playwright-cli open https://example.com/form
307
+ playwright-cli snapshot
308
+ playwright-cli fill e1 "user@example.com"
309
+ playwright-cli fill e2 "password123"
310
+ playwright-cli click e3
311
+ playwright-cli snapshot
312
+ playwright-cli close
313
+ ```
314
+
315
+ ## Example: Multi-tab workflow
316
+
317
+ ```bash
318
+ playwright-cli open https://example.com
319
+ playwright-cli tab-new https://example.com/other
320
+ playwright-cli tab-list
321
+ playwright-cli tab-select 0
322
+ playwright-cli snapshot
323
+ playwright-cli close
324
+ ```
325
+
326
+ ## Example: Debugging with DevTools
327
+
328
+ ```bash
329
+ playwright-cli open https://example.com
330
+ playwright-cli click e4
331
+ playwright-cli fill e7 "test"
332
+ playwright-cli console
333
+ playwright-cli network
334
+ playwright-cli close
335
+ ```
336
+
337
+ ```bash
338
+ playwright-cli open https://example.com
339
+ playwright-cli tracing-start
340
+ playwright-cli click e4
341
+ playwright-cli fill e7 "test"
342
+ playwright-cli tracing-stop
343
+ playwright-cli close
344
+ ```
345
+
346
+ ## Specific tasks
347
+
348
+ Later revisions can add the upstream `references/` files here as needed.
@@ -0,0 +1,55 @@
1
+ ---
2
+ name: screenci
3
+ description: Scaffold and record ScreenCI video projects. Use when creating a new screenci project, running screenci recordings, or editing screenci video scripts and config.
4
+ allowed-tools:
5
+ - Bash(screenci:*)
6
+ - Bash(npx:*)
7
+ - Bash(npm:*)
8
+ ---
9
+
10
+ # ScreenCI
11
+
12
+ Use this skill when the task is about ScreenCI project setup, video recording workflows, or updating `.video.ts` files and `screenci.config.ts`.
13
+
14
+ ## Quick Start
15
+
16
+ ```bash
17
+ # scaffold a new project
18
+ npx screenci init my-project
19
+ cd my-project
20
+ npm install
21
+
22
+ # iterate locally without recording
23
+ npx screenci dev
24
+
25
+ # capture recordings
26
+ npx screenci record
27
+ ```
28
+
29
+ ## What ScreenCI Adds
30
+
31
+ ScreenCI uses Playwright-style `.video.ts` files and adds recording-specific helpers:
32
+
33
+ - `video()` declares one output video per test.
34
+ - `hide()` removes setup and loading sections from the final recording.
35
+ - `autoZoom()` follows a form or page section with smooth camera motion.
36
+ - `createVoiceOvers()` creates typed narration and caption markers.
37
+
38
+ ## Command Notes
39
+
40
+ - `screenci init` scaffolds a project with `screenci.config.ts`, a starter `videos/example.video.ts`, `Dockerfile`, and `package.json`.
41
+ - `screenci record` runs the recording flow. By default it uses Podman or Docker unless `--no-container` is used.
42
+ - `screenci dev` runs Playwright in UI mode for fast iteration without screen capture.
43
+ - `screenci retry` uploads the latest `.screenci` output when API configuration is available.
44
+
45
+ ## Recording Workflow
46
+
47
+ 1. Start from a generated project or an existing package using ScreenCI.
48
+ 2. Edit `.video.ts` files like Playwright tests.
49
+ 3. Run `npx screenci dev` to validate selectors and flow.
50
+ 4. Run `npx screenci record` to produce `.screenci/<video-name>/recording.mp4` and `data.json`.
51
+
52
+ ## Specific Tasks
53
+
54
+ - **Project scaffolding** [references/init.md](references/init.md)
55
+ - **Recording videos** [references/record.md](references/record.md)
@@ -0,0 +1,47 @@
1
+ # `screenci init`
2
+
3
+ Use `screenci init` to scaffold a new ScreenCI project.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ npx screenci init
9
+ npx screenci init my-project
10
+ npx screenci init my-project --verbose
11
+ ```
12
+
13
+ ## What It Creates
14
+
15
+ `screenci init` creates a ready-to-run project containing:
16
+
17
+ ```text
18
+ my-project/
19
+ screenci.config.ts
20
+ videos/
21
+ example.video.ts
22
+ Dockerfile
23
+ package.json
24
+ .gitignore
25
+ .github/workflows/record.yml
26
+ ```
27
+
28
+ ## Requirements
29
+
30
+ - Node.js 20+ recommended
31
+ - Podman 5+ recommended, or Docker 28+
32
+
33
+ ## Notes
34
+
35
+ - If no name is passed, the command prompts for one.
36
+ - `--verbose` shows more setup output.
37
+ - `--local` uses the local package path for development workflows.
38
+ - After scaffolding, run `npm install`.
39
+
40
+ ## Typical Flow
41
+
42
+ ```bash
43
+ npx screenci init my-project
44
+ cd my-project
45
+ npm install
46
+ npx screenci dev
47
+ ```
@@ -0,0 +1,41 @@
1
+ # `screenci record`
2
+
3
+ Use `screenci record` to capture ScreenCI videos from `.video.ts` scripts.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ npx screenci record
9
+ npx screenci record --no-container
10
+ npx screenci record -c screenci.config.ts
11
+ ```
12
+
13
+ ## What It Does
14
+
15
+ - Runs ScreenCI video tests
16
+ - Starts the recording pipeline
17
+ - Saves output under `.screenci/<video-name>/`
18
+ - Produces at least `recording.mp4` and `data.json`
19
+
20
+ ## Runtime Behavior
21
+
22
+ - By default, recording runs in Podman or Docker.
23
+ - `--no-container` runs directly on the host.
24
+ - Playwright arguments can be passed through after the command.
25
+ - When API configuration and `SCREENCI_SECRET` are available, uploads may run after recording.
26
+
27
+ ## Recommended Workflow
28
+
29
+ ```bash
30
+ # first verify the flow
31
+ npx screenci dev
32
+
33
+ # then record
34
+ npx screenci record
35
+ ```
36
+
37
+ ## Constraints
38
+
39
+ - ScreenCI enforces single-worker recording behavior.
40
+ - Use `hide()` for login and loading sections.
41
+ - Use one `autoZoom()` block per form or page section rather than per click.
@@ -1,9 +0,0 @@
1
- import type { Reporter, FullConfig, Suite } from '@playwright/test/reporter';
2
- /**
3
- * Custom reporter that validates video names are unique after sanitization
4
- */
5
- declare class VideoNameValidator implements Reporter {
6
- onBegin(config: FullConfig, suite: Suite): void;
7
- }
8
- export default VideoNameValidator;
9
- //# sourceMappingURL=reporter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,KAAK,EAEN,MAAM,2BAA2B,CAAA;AAGlC;;GAEG;AACH,cAAM,kBAAmB,YAAW,QAAQ;IAC1C,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK;CAgDzC;AAED,eAAe,kBAAkB,CAAA"}
package/dist/reporter.js DELETED
@@ -1,49 +0,0 @@
1
- import { sanitizeVideoName } from './src/sanitize.js';
2
- /**
3
- * Custom reporter that validates video names are unique after sanitization
4
- */
5
- class VideoNameValidator {
6
- onBegin(config, suite) {
7
- const videoNames = new Map();
8
- // Collect all test titles
9
- const collectTests = (suite) => {
10
- for (const test of suite.tests) {
11
- const sanitized = sanitizeVideoName(test.title);
12
- const existing = videoNames.get(sanitized);
13
- if (existing) {
14
- existing.push(test.title);
15
- }
16
- else {
17
- videoNames.set(sanitized, [test.title]);
18
- }
19
- }
20
- for (const child of suite.suites) {
21
- collectTests(child);
22
- }
23
- };
24
- collectTests(suite);
25
- // Check for duplicates
26
- const duplicates = [];
27
- for (const [sanitized, titles] of videoNames.entries()) {
28
- if (titles.length > 1) {
29
- duplicates.push({ sanitized, titles });
30
- }
31
- }
32
- if (duplicates.length > 0) {
33
- console.error('\n❌ Duplicate video names detected after sanitization:\n');
34
- for (const { sanitized, titles } of duplicates) {
35
- console.error(` Sanitized name: "${sanitized}"`);
36
- console.error(` Conflicts between:`);
37
- for (const title of titles) {
38
- console.error(` - "${title}"`);
39
- }
40
- console.error('');
41
- }
42
- console.error('Please ensure all video titles result in unique sanitized names.');
43
- console.error('Sanitization rules: Converted to lowercase kebab-case (alphanumeric and dashes only).\n');
44
- process.exit(1);
45
- }
46
- }
47
- }
48
- export default VideoNameValidator;
49
- //# sourceMappingURL=reporter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../reporter.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD;;GAEG;AACH,MAAM,kBAAkB;IACtB,OAAO,CAAC,MAAkB,EAAE,KAAY;QACtC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAA;QAE9C,0BAA0B;QAC1B,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE;YACpC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC/B,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAC/C,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;gBAC1C,IAAI,QAAQ,EAAE,CAAC;oBACb,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAC3B,CAAC;qBAAM,CAAC;oBACN,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;gBACzC,CAAC;YACH,CAAC;YACD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjC,YAAY,CAAC,KAAK,CAAC,CAAA;YACrB,CAAC;QACH,CAAC,CAAA;QAED,YAAY,CAAC,KAAK,CAAC,CAAA;QAEnB,uBAAuB;QACvB,MAAM,UAAU,GAAmD,EAAE,CAAA;QACrE,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;YACvD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAA;YACxC,CAAC;QACH,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAA;YACzE,KAAK,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;gBAC/C,OAAO,CAAC,KAAK,CAAC,sBAAsB,SAAS,GAAG,CAAC,CAAA;gBACjD,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAA;gBACrC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oBAC3B,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,GAAG,CAAC,CAAA;gBACnC,CAAC;gBACD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACnB,CAAC;YACD,OAAO,CAAC,KAAK,CACX,kEAAkE,CACnE,CAAA;YACD,OAAO,CAAC,KAAK,CACX,yFAAyF,CAC1F,CAAA;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;CACF;AAED,eAAe,kBAAkB,CAAA"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=caption.test-d.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"caption.test-d.d.ts","sourceRoot":"","sources":["../../src/caption.test-d.ts"],"names":[],"mappings":""}
@@ -1,50 +0,0 @@
1
- import { describe, it, assertType } from 'vitest';
2
- import { createCaptions } from './caption.js';
3
- import { voices } from './voices.js';
4
- describe('createCaptions type constraints', () => {
5
- it('accepts matching keys across all languages', () => {
6
- createCaptions({
7
- en: {
8
- voice: voices.en.Jude,
9
- captions: { intro: 'Hello', outro: 'Bye' },
10
- },
11
- fi: {
12
- voice: voices.fi.Martti,
13
- captions: { intro: 'Hei', outro: 'Näkemiin' },
14
- },
15
- });
16
- });
17
- it('accepts mixed value types (string vs file object) for the same key', () => {
18
- createCaptions({
19
- en: {
20
- voice: voices.en.Jude,
21
- captions: {
22
- intro: 'Hello',
23
- clip: { path: '/clip.mp4', subtitle: 'Watch' },
24
- },
25
- },
26
- fi: {
27
- voice: voices.fi.Martti,
28
- captions: { intro: 'Hei', clip: 'Katso' },
29
- },
30
- });
31
- });
32
- it('rejects a language with a missing caption key', () => {
33
- createCaptions({
34
- en: {
35
- voice: voices.en.Jude,
36
- captions: { intro: 'Hello', outro: 'Bye' },
37
- },
38
- fi: {
39
- voice: voices.fi.Martti,
40
- // @ts-expect-error — 'outro' is missing
41
- captions: { intro: 'Hei' },
42
- },
43
- });
44
- });
45
- it('rejects a wrong-language voice', () => {
46
- // @ts-expect-error — fi voice is not assignable to VoiceForLang<'en'>
47
- assertType(voices.fi.Martti);
48
- });
49
- });
50
- //# sourceMappingURL=caption.test-d.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"caption.test-d.js","sourceRoot":"","sources":["../../src/caption.test-d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGpC,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,cAAc,CAAC;YACb,EAAE,EAAE;gBACF,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI;gBACrB,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE;aAC3C;YACD,EAAE,EAAE;gBACF,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM;gBACvB,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE;aAC9C;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,cAAc,CAAC;YACb,EAAE,EAAE;gBACF,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI;gBACrB,QAAQ,EAAE;oBACR,KAAK,EAAE,OAAO;oBACd,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE;iBAC/C;aACF;YACD,EAAE,EAAE;gBACF,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM;gBACvB,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;aAC1C;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,cAAc,CAAC;YACb,EAAE,EAAE;gBACF,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI;gBACrB,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE;aAC3C;YACD,EAAE,EAAE;gBACF,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM;gBACvB,wCAAwC;gBACxC,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;aAC3B;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,sEAAsE;QACtE,UAAU,CAAqB,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -1,12 +0,0 @@
1
- export interface CaptionOptions {
2
- voiceId: string;
3
- language: string;
4
- text: string;
5
- }
6
- /**
7
- * Compute a deterministic SHA-256 hash from caption options.
8
- * All fields that affect audio generation should be included here.
9
- * Returns a hex string.
10
- */
11
- export declare function computeCaptionHash(options: CaptionOptions): Promise<string>;
12
- //# sourceMappingURL=captionHash.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"captionHash.d.ts","sourceRoot":"","sources":["../../src/captionHash.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC,CAUjB"}
@@ -1,17 +0,0 @@
1
- /**
2
- * Compute a deterministic SHA-256 hash from caption options.
3
- * All fields that affect audio generation should be included here.
4
- * Returns a hex string.
5
- */
6
- export async function computeCaptionHash(options) {
7
- const sorted = {};
8
- for (const key of Object.keys(options).sort()) {
9
- sorted[key] = options[key];
10
- }
11
- const encoded = new TextEncoder().encode(JSON.stringify(sorted));
12
- const hashBuffer = await crypto.subtle.digest('SHA-256', encoded);
13
- return Array.from(new Uint8Array(hashBuffer))
14
- .map((b) => b.toString(16).padStart(2, '0'))
15
- .join('');
16
- }
17
- //# sourceMappingURL=captionHash.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"captionHash.js","sourceRoot":"","sources":["../../src/captionHash.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAuB;IAEvB,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,MAAM,GAAG,IAAK,MAAM,CAAC,IAAI,CAAC,OAAO,CAA8B,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5E,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;IAChE,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IACjE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;SAC1C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAA;AACb,CAAC"}