screenci 0.0.10 → 0.0.12

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 +56 -56
  2. package/dist/Dockerfile +1 -2
  3. package/dist/cli.d.ts +22 -1
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +1164 -423
  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 +35 -5
  53. package/skills/playwright-cli/SKILL.md +348 -0
  54. package/skills/screenci/SKILL.md +56 -0
  55. package/skills/screenci/references/init.md +46 -0
  56. package/skills/screenci/references/record.md +43 -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
package/README.md CHANGED
@@ -82,79 +82,79 @@ export default defineConfig({
82
82
 
83
83
  screenci enforces `workers: 1`, `retries: 0`, and `fullyParallel: false` — FFmpeg records one screen at a time. Don't fight it.
84
84
 
85
- ## Captions & AI voiceovers
85
+ ## AI voiceovers
86
86
 
87
- `createCaptions()` maps caption keys to text. At render time screenci sends the text through ElevenLabs and lines up the audio with your recording.
87
+ `createVoiceOvers()` maps keys to narration text (or audio files). Define it once near the top of the file, then `await voiceOvers.key` inside `video()` wherever that spoken line should begin. The audio keeps playing while your next actions run. Use `await voiceOvers.waitEnd()` only when an action must wait for the current line to finish.
88
88
 
89
89
  ```ts
90
- import { video, createCaptions } from 'screenci'
91
-
92
- const captions = createCaptions({
93
- intro: 'Welcome to the dashboard.',
94
- addButton: 'Click here to create a new project.',
90
+ import { video, createVoiceOvers, voices } from 'screenci'
91
+
92
+ const voiceOvers = createVoiceOvers({
93
+ voice: { name: voices.Aria },
94
+ languages: {
95
+ en: {
96
+ captions: {
97
+ intro: 'Welcome to the dashboard.',
98
+ addButton: 'Click here to create a new project.',
99
+ },
100
+ },
101
+ },
95
102
  })
96
103
 
97
104
  video('Dashboard walkthrough', async ({ page }) => {
98
105
  await page.goto('/dashboard')
99
106
 
100
- await captions.intro.start()
101
- // ...anything you do here plays over the voiceover...
102
- await captions.intro.end()
103
-
107
+ await voiceOvers.intro
108
+ await page.locator('#reports').click()
104
109
  await page.locator('#new-project').click()
105
- await captions.addButton.start()
106
- await captions.addButton.end()
110
+
111
+ await voiceOvers.addButton
112
+ await voiceOvers.waitEnd()
107
113
  })
108
114
  ```
109
115
 
110
- ### With a voice
116
+ Use this pattern:
111
117
 
112
118
  ```ts
113
- import { createCaptions, voices } from 'screenci'
114
-
115
- const captions = createCaptions(
116
- { voice: voices.en.Jude },
117
- {
118
- intro: 'Welcome to the dashboard.',
119
- addButton: 'Click here to create a new project.',
120
- }
121
- )
119
+ const voiceOvers = createVoiceOvers({ ... })
120
+
121
+ video('Example', async ({ page }) => {
122
+ await voiceOvers.intro // starts narration now
123
+ await page.click('#next') // runs while intro audio is still playing
124
+
125
+ await voiceOvers.details // auto-ends intro, then starts details
126
+ await voiceOvers.waitEnd() // only if the next action must wait
127
+ await page.click('#confirm')
128
+ })
122
129
  ```
123
130
 
124
131
  ### Multi-language (type-safe)
125
132
 
126
- TypeScript will yell at you if any language is missing a key. That's a feature.
133
+ TypeScript enforces that every language has the same keys. Missing a translation is a compile error.
127
134
 
128
135
  ```ts
129
- import { createCaptions, voices } from 'screenci'
130
-
131
- const captions = createCaptions({
132
- en: {
133
- voice: voices.en.Jude,
134
- captions: {
135
- intro: 'Welcome to the dashboard.',
136
- addButton: 'Click here to create a new project.',
136
+ import { createVoiceOvers, voices } from 'screenci'
137
+
138
+ const voiceOvers = createVoiceOvers({
139
+ voice: { name: voices.Ava },
140
+ languages: {
141
+ en: {
142
+ captions: {
143
+ intro: 'Welcome to the dashboard.',
144
+ addButton: 'Click here to create a new project.',
145
+ },
137
146
  },
138
- },
139
- fi: {
140
- voice: voices.fi.Martti,
141
- captions: {
142
- intro: 'Tervetuloa hallintapaneeliin.',
143
- addButton: 'Klikkaa tästä luodaksesi uuden projektin.',
147
+ fi: {
148
+ voice: { name: voices.Nora },
149
+ captions: {
150
+ intro: 'Tervetuloa hallintapaneeliin.',
151
+ addButton: 'Klikkaa tästä luodaksesi uuden projektin.',
152
+ },
144
153
  },
145
154
  },
146
155
  })
147
156
  ```
148
157
 
149
- ### Sync actions to audio
150
-
151
- ```ts
152
- // Wait until the voiceover is 60% done, then perform the action
153
- await captions.intro.waitUntil('60%')
154
- await page.locator('#cta').click()
155
- await captions.intro.end()
156
- ```
157
-
158
158
  ## Hide the boring parts
159
159
 
160
160
  `hide()` cuts a section from the final video. Perfect for logins, page loads, and test setup.
@@ -200,14 +200,14 @@ video('Profile settings', async ({ page }) => {
200
200
 
201
201
  ## API
202
202
 
203
- | Export | What it does |
204
- | ---------------- | ---------------------------------------------------- |
205
- | `defineConfig` | Wraps Playwright config with screenci defaults |
206
- | `video` | Declares a video recording test |
207
- | `createCaptions` | Creates typed caption controllers with AI voiceovers |
208
- | `hide` | Cuts a section from the final video |
209
- | `autoZoom` | Smooth camera pan that follows interactions |
210
- | `voices` | Available voice constants (`voices.en.Jude`, etc.) |
203
+ | Export | What it does |
204
+ | ------------------ | ------------------------------------------------------------------ |
205
+ | `defineConfig` | Wraps Playwright config with screenci defaults |
206
+ | `video` | Declares a video recording test |
207
+ | `createVoiceOvers` | Creates typed voiceover controllers with AI-generated audio |
208
+ | `hide` | Cuts a section from the final video |
209
+ | `autoZoom` | Smooth camera pan that follows interactions |
210
+ | `voices` | Available voice constants (`voices.Ava`, `voices.elevenlabs(...)`) |
211
211
 
212
212
  The `page` fixture inside `video()` is a `ScreenCIPage` — a Playwright `Page` with animated cursor support wired in on all locator methods.
213
213
 
@@ -223,5 +223,5 @@ The `page` fixture inside `video()` is a `ScreenCIPage` — a Playwright `Page`
223
223
  Upload to screenci.com for rendering, voiceover generation, and the permanent embed link:
224
224
 
225
225
  ```bash
226
- npm run upload-latest
226
+ npm run retry
227
227
  ```
package/dist/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- # Recording runtime ───────────────────────────────────────────────────────────
1
+ # ── Runtime image ─────────────────────────────────────────────────────────────
2
2
  FROM docker.io/library/node:25.2.1-slim
3
3
 
4
4
  WORKDIR /app
@@ -18,7 +18,6 @@ RUN printf '{"private":true,"workspaces":["screenci"]}' > package.json && npm in
18
18
  RUN npx playwright install chromium --with-deps
19
19
 
20
20
  # ── screenci build output ─────────────────────────────────────────────────────
21
- # Copy pre-built dist directly from the screenci package directory.
22
21
  COPY dist ./screenci/dist/
23
22
 
24
23
  # Explicit bin wrapper — no npm bin-linking magic needed.
package/dist/cli.d.ts CHANGED
@@ -1,4 +1,25 @@
1
1
  #!/usr/bin/env -S npx tsx
2
+ import type { RecordingCustomVoiceRef, RecordingData } from './src/events.js';
3
+ import type { VoiceKey } from './src/voices.js';
4
+ type PreparedUploadAsset = {
5
+ fileHash: string;
6
+ path: string;
7
+ size: number;
8
+ name?: string;
9
+ fileBuffer?: Buffer;
10
+ contentType?: string;
11
+ };
12
+ export declare function attachUploadAbortStdinListener(input: Pick<NodeJS.ReadStream, 'on' | 'off' | 'pause'>, onAbort: (signal: NodeJS.Signals) => void): () => void;
13
+ declare const MIN_CONTAINER_RUNTIME_MAJOR_VERSION: {
14
+ readonly podman: 5;
15
+ readonly docker: 28;
16
+ };
17
+ type ContainerRuntimeName = keyof typeof MIN_CONTAINER_RUNTIME_MAJOR_VERSION;
18
+ export declare function stripVoicePath(voice: VoiceKey | RecordingCustomVoiceRef): VoiceKey | RecordingCustomVoiceRef;
19
+ export declare function annotateRecordingDataWithAssetHashes(data: RecordingData, assets: PreparedUploadAsset[]): RecordingData;
20
+ export declare function getDevBackendUrl(): string;
21
+ export declare function getDevFrontendUrl(): string;
2
22
  export declare function main(): Promise<void>;
3
- export declare function detectContainerRuntime(): string;
23
+ export declare function detectContainerRuntime(forcedRuntime?: ContainerRuntimeName): string;
24
+ export {};
4
25
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":";AAgzBA,wBAAsB,IAAI,kBA2JzB;AAqED,wBAAgB,sBAAsB,IAAI,MAAM,CAc/C"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":";AAwBA,OAAO,KAAK,EACV,uBAAuB,EACvB,aAAa,EAEd,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AA4D/C,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAiBD,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,GAAG,KAAK,GAAG,OAAO,CAAC,EACtD,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,GACxC,MAAM,IAAI,CAiBZ;AAuED,QAAA,MAAM,mCAAmC;;;CAG/B,CAAA;AAEV,KAAK,oBAAoB,GAAG,MAAM,OAAO,mCAAmC,CAAA;AAyhB5E,wBAAgB,cAAc,CAC5B,KAAK,EAAE,QAAQ,GAAG,uBAAuB,GACxC,QAAQ,GAAG,uBAAuB,CAKpC;AAED,wBAAgB,oCAAoC,CAClD,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,mBAAmB,EAAE,GAC5B,aAAa,CAqEf;AAmQD,wBAAgB,gBAAgB,IAAI,MAAM,CAKzC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAK1C;AA8gBD,wBAAsB,IAAI,kBAsQzB;AAyJD,wBAAgB,sBAAsB,CACpC,aAAa,CAAC,EAAE,oBAAoB,GACnC,MAAM,CAoBR"}