screenci 0.0.9 → 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 +48 -0
  3. package/dist/cli.d.ts +21 -1
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +1346 -384
  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 +9 -8
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +3 -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 +69 -27
  23. package/dist/src/events.d.ts.map +1 -1
  24. package/dist/src/events.js +64 -40
  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 +4 -0
  33. package/dist/src/recording.d.ts.map +1 -0
  34. package/dist/src/recording.js +2 -0
  35. package/dist/src/recording.js.map +1 -0
  36. package/dist/src/recordingData.d.ts +145 -0
  37. package/dist/src/recordingData.d.ts.map +1 -0
  38. package/dist/src/recordingData.js +2 -0
  39. package/dist/src/recordingData.js.map +1 -0
  40. package/dist/src/types.d.ts +201 -71
  41. package/dist/src/types.d.ts.map +1 -1
  42. package/dist/src/types.js +31 -1
  43. package/dist/src/types.js.map +1 -1
  44. package/dist/src/video.d.ts.map +1 -1
  45. package/dist/src/video.js +29 -24
  46. package/dist/src/video.js.map +1 -1
  47. package/dist/src/voices.d.ts +344 -41
  48. package/dist/src/voices.d.ts.map +1 -1
  49. package/dist/src/voices.js +261 -30
  50. package/dist/src/voices.js.map +1 -1
  51. package/dist/test-fixtures/screenci.config.d.ts +5 -0
  52. package/dist/test-fixtures/screenci.config.d.ts.map +1 -0
  53. package/dist/test-fixtures/screenci.config.js +4 -0
  54. package/dist/test-fixtures/screenci.config.js.map +1 -0
  55. package/dist/tsconfig.tsbuildinfo +1 -1
  56. package/package.json +39 -3
  57. package/skills/playwright-cli/SKILL.md +348 -0
  58. package/skills/screenci/SKILL.md +55 -0
  59. package/skills/screenci/references/init.md +47 -0
  60. package/skills/screenci/references/record.md +41 -0
  61. package/dist/reporter.d.ts +0 -9
  62. package/dist/reporter.d.ts.map +0 -1
  63. package/dist/reporter.js +0 -49
  64. package/dist/reporter.js.map +0 -1
  65. package/dist/src/caption.test-d.d.ts +0 -2
  66. package/dist/src/caption.test-d.d.ts.map +0 -1
  67. package/dist/src/caption.test-d.js +0 -50
  68. package/dist/src/caption.test-d.js.map +0 -1
package/README.md CHANGED
@@ -82,79 +82,65 @@ 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 text (or audio files). At render time screenci generates voiceover audio and syncs it to your recording.
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()
107
+ await voiceOvers.intro.start()
101
108
  // ...anything you do here plays over the voiceover...
102
- await captions.intro.end()
109
+ await voiceOvers.intro.end()
103
110
 
104
111
  await page.locator('#new-project').click()
105
- await captions.addButton.start()
106
- await captions.addButton.end()
112
+ await voiceOvers.addButton.start()
113
+ await voiceOvers.addButton.end()
107
114
  })
108
115
  ```
109
116
 
110
- ### With a voice
111
-
112
- ```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
- )
122
- ```
123
-
124
117
  ### Multi-language (type-safe)
125
118
 
126
- TypeScript will yell at you if any language is missing a key. That's a feature.
119
+ TypeScript enforces that every language has the same keys. Missing a translation is a compile error.
127
120
 
128
121
  ```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.',
122
+ import { createVoiceOvers, voices } from 'screenci'
123
+
124
+ const voiceOvers = createVoiceOvers({
125
+ voice: { name: voices.Ava },
126
+ languages: {
127
+ en: {
128
+ captions: {
129
+ intro: 'Welcome to the dashboard.',
130
+ addButton: 'Click here to create a new project.',
131
+ },
137
132
  },
138
- },
139
- fi: {
140
- voice: voices.fi.Martti,
141
- captions: {
142
- intro: 'Tervetuloa hallintapaneeliin.',
143
- addButton: 'Klikkaa tästä luodaksesi uuden projektin.',
133
+ fi: {
134
+ voice: { name: voices.Nora },
135
+ captions: {
136
+ intro: 'Tervetuloa hallintapaneeliin.',
137
+ addButton: 'Klikkaa tästä luodaksesi uuden projektin.',
138
+ },
144
139
  },
145
140
  },
146
141
  })
147
142
  ```
148
143
 
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
144
  ## Hide the boring parts
159
145
 
160
146
  `hide()` cuts a section from the final video. Perfect for logins, page loads, and test setup.
@@ -200,14 +186,14 @@ video('Profile settings', async ({ page }) => {
200
186
 
201
187
  ## API
202
188
 
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.) |
189
+ | Export | What it does |
190
+ | ------------------ | ------------------------------------------------------------------ |
191
+ | `defineConfig` | Wraps Playwright config with screenci defaults |
192
+ | `video` | Declares a video recording test |
193
+ | `createVoiceOvers` | Creates typed voiceover controllers with AI-generated audio |
194
+ | `hide` | Cuts a section from the final video |
195
+ | `autoZoom` | Smooth camera pan that follows interactions |
196
+ | `voices` | Available voice constants (`voices.Ava`, `voices.elevenlabs(...)`) |
211
197
 
212
198
  The `page` fixture inside `video()` is a `ScreenCIPage` — a Playwright `Page` with animated cursor support wired in on all locator methods.
213
199
 
@@ -223,5 +209,5 @@ The `page` fixture inside `video()` is a `ScreenCIPage` — a Playwright `Page`
223
209
  Upload to screenci.com for rendering, voiceover generation, and the permanent embed link:
224
210
 
225
211
  ```bash
226
- npm run upload-latest
212
+ npm run retry
227
213
  ```
@@ -0,0 +1,48 @@
1
+ # Recording runtime ───────────────────────────────────────────────────────────
2
+ FROM docker.io/library/node:25.2.1-slim AS builder
3
+
4
+ WORKDIR /build
5
+
6
+ COPY package.json package.json
7
+ RUN npm install --include=dev --ignore-scripts
8
+
9
+ COPY tsconfig.json tsconfig.json
10
+ COPY Dockerfile Dockerfile
11
+ COPY index.ts index.ts
12
+ COPY cli.ts cli.ts
13
+ COPY src src
14
+ RUN npm run build
15
+
16
+ # ── Runtime image ─────────────────────────────────────────────────────────────
17
+ FROM docker.io/library/node:25.2.1-slim
18
+
19
+ WORKDIR /app
20
+
21
+ RUN apt-get update && apt-get install -y --no-install-recommends \
22
+ xvfb \
23
+ ffmpeg \
24
+ x11-utils \
25
+ && rm -rf /var/lib/apt/lists/*
26
+
27
+ # ── Dependency layer (cached until package.json changes) ──────────────────────
28
+ # Install screenci as a workspace package so npm creates the bin link.
29
+ COPY package.json ./screenci/
30
+ RUN printf '{"private":true,"workspaces":["screenci"]}' > package.json && npm install
31
+
32
+ # Playwright browser download: only re-runs when the playwright version changes.
33
+ RUN npx playwright install chromium --with-deps
34
+
35
+ # ── screenci build output ─────────────────────────────────────────────────────
36
+ COPY --from=builder /build/dist ./screenci/dist/
37
+
38
+ # Explicit bin wrapper — no npm bin-linking magic needed.
39
+ RUN printf '#!/bin/sh\nexec node /app/screenci/dist/cli.js "$@"\n' > /app/node_modules/.bin/screenci && \
40
+ chmod +x /app/node_modules/.bin/screenci
41
+
42
+ # Create .screenci directory for recordings
43
+ RUN mkdir -p .screenci
44
+
45
+ # Add node_modules/.bin to PATH
46
+ ENV PATH="/app/node_modules/.bin:${PATH}"
47
+
48
+ CMD ["echo", "Container ready"]
package/dist/cli.d.ts CHANGED
@@ -1,4 +1,24 @@
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
+ declare const MIN_CONTAINER_RUNTIME_MAJOR_VERSION: {
13
+ readonly podman: 5;
14
+ readonly docker: 28;
15
+ };
16
+ type ContainerRuntimeName = keyof typeof MIN_CONTAINER_RUNTIME_MAJOR_VERSION;
17
+ export declare function stripVoicePath(voice: VoiceKey | RecordingCustomVoiceRef): VoiceKey | RecordingCustomVoiceRef;
18
+ export declare function annotateRecordingDataWithAssetHashes(data: RecordingData, assets: PreparedUploadAsset[]): RecordingData;
19
+ export declare function getDevBackendUrl(): string;
20
+ export declare function getDevFrontendUrl(): string;
2
21
  export declare function main(): Promise<void>;
3
- export declare function detectContainerRuntime(): string;
22
+ export declare function detectContainerRuntime(forcedRuntime?: ContainerRuntimeName): string;
23
+ export {};
4
24
  //# 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":";AAurBA,wBAAsB,IAAI,kBAoJzB;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;AA6FD,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;AAukBD,wBAAsB,IAAI,kBAgRzB;AAyJD,wBAAgB,sBAAsB,CACpC,aAAa,CAAC,EAAE,oBAAoB,GACnC,MAAM,CAoBR"}