clipwise 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clipwise",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Scriptable cinematic screen recorder for product demos — YAML in, polished MP4 out",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -10,6 +10,7 @@
10
10
  },
11
11
  "files": [
12
12
  "dist",
13
+ "skills",
13
14
  "README.md",
14
15
  "LICENSE"
15
16
  ],
@@ -0,0 +1,373 @@
1
+ # Clipwise — Cinematic Screen Recorder
2
+
3
+ You are an expert at creating Clipwise YAML scenarios. Clipwise is a Playwright + CDP-based scriptable screen recorder that turns YAML scenarios into polished MP4/GIF demo videos with cinematic effects (zoom, cursor trail, device frame, keystroke HUD, etc.).
4
+
5
+ TRIGGER: when the user wants to record a demo video, create a screen recording scenario, generate a product demo, or mentions "clipwise".
6
+
7
+ ## Setup Check
8
+
9
+ Before creating a scenario, verify clipwise is installed:
10
+
11
+ ```bash
12
+ npx clipwise --version
13
+ ```
14
+
15
+ If not installed:
16
+ ```bash
17
+ npm install -D clipwise
18
+ ```
19
+
20
+ ffmpeg is required for MP4 output:
21
+ ```bash
22
+ # macOS
23
+ brew install ffmpeg
24
+ # Ubuntu
25
+ sudo apt install ffmpeg
26
+ ```
27
+
28
+ ## YAML Schema Reference
29
+
30
+ ### Top-Level Structure
31
+
32
+ ```yaml
33
+ name: string # Scenario name (required)
34
+ description: string # Optional description
35
+
36
+ viewport:
37
+ width: 1280 # Browser width (100-3840, default: 1280)
38
+ height: 800 # Browser height (100-3840, default: 800)
39
+
40
+ effects: # All optional, sensible defaults
41
+ zoom: ...
42
+ cursor: ...
43
+ background: ...
44
+ deviceFrame: ...
45
+ keystroke: ...
46
+ watermark: ...
47
+ speedRamp: ...
48
+
49
+ output:
50
+ format: mp4 # mp4 | gif | png-sequence
51
+ width: 1280 # Output width
52
+ height: 800 # Output height
53
+ fps: 30 # 1-60
54
+ preset: balanced # social | balanced | archive
55
+ outputDir: "./output"
56
+ filename: "my-recording"
57
+
58
+ steps: [] # Array of steps (min 1, first must have navigate)
59
+ ```
60
+
61
+ ### Step Structure
62
+
63
+ ```yaml
64
+ - name: "Step name" # Optional label
65
+ captureDelay: 50 # ms to wait after actions before capturing (50-100 for snappy)
66
+ holdDuration: 700 # ms to hold on result (500-800 for snappy)
67
+ transition: none # none | fade
68
+ actions: [] # Array of actions
69
+ ```
70
+
71
+ ### Actions (12 types)
72
+
73
+ #### Basic Actions
74
+
75
+ 1. **navigate** — Open a URL (MUST be the first action in step 1)
76
+ ```yaml
77
+ - action: navigate
78
+ url: "https://example.com"
79
+ waitUntil: load # load | domcontentloaded | networkidle (default)
80
+ ```
81
+
82
+ 2. **click** — Click an element
83
+ ```yaml
84
+ - action: click
85
+ selector: "#my-button"
86
+ delay: 0 # Optional click delay (ms)
87
+ timeout: 15000 # Optional element wait timeout
88
+ ```
89
+
90
+ 3. **type** — Type text character-by-character (auto-focuses the element)
91
+ ```yaml
92
+ - action: type
93
+ selector: "#email-input"
94
+ text: "user@example.com"
95
+ delay: 18 # ms per character (15-25 recommended, default: 50)
96
+ timeout: 15000 # Optional
97
+ ```
98
+
99
+ 4. **hover** — Hover over an element
100
+ ```yaml
101
+ - action: hover
102
+ selector: ".card"
103
+ timeout: 15000 # Optional
104
+ ```
105
+
106
+ 5. **scroll** — Scroll the page
107
+ ```yaml
108
+ - action: scroll
109
+ y: 400 # Vertical px (positive=down, negative=up)
110
+ x: 0 # Horizontal px
111
+ selector: ".container" # Optional: scroll within element
112
+ smooth: true # Default: true
113
+ timeout: 15000 # Optional
114
+ ```
115
+
116
+ 6. **wait** — Pause for a fixed duration
117
+ ```yaml
118
+ - action: wait
119
+ duration: 1000 # ms
120
+ ```
121
+
122
+ 7. **screenshot** — Capture marker (for png-sequence)
123
+ ```yaml
124
+ - action: screenshot
125
+ name: "result" # Optional label
126
+ fullPage: false # Default: false
127
+ ```
128
+
129
+ #### Async Wait Actions (for dynamic/API content)
130
+
131
+ 8. **waitForSelector** — Wait for element state
132
+ ```yaml
133
+ - action: waitForSelector
134
+ selector: ".result-panel"
135
+ state: visible # visible (default) | attached | hidden
136
+ timeout: 15000
137
+ ```
138
+
139
+ 9. **waitForNavigation** — Wait for page load
140
+ ```yaml
141
+ - action: waitForNavigation
142
+ waitUntil: networkidle # load | domcontentloaded | networkidle
143
+ timeout: 15000
144
+ ```
145
+
146
+ 10. **waitForURL** — Wait for URL match
147
+ ```yaml
148
+ - action: waitForURL
149
+ url: "https://example.com/dashboard"
150
+ timeout: 15000
151
+ ```
152
+
153
+ 11. **waitForFunction** — Wait for JS expression to be truthy
154
+ ```yaml
155
+ - action: waitForFunction
156
+ expression: "document.querySelector('.done') !== null"
157
+ polling: raf # raf (default) | number in ms (e.g. 500)
158
+ timeout: 30000
159
+ ```
160
+
161
+ 12. **waitForResponse** — Wait for network response (URL substring match)
162
+ ```yaml
163
+ - action: waitForResponse
164
+ url: "/api/chat/completions"
165
+ status: 200 # Optional HTTP status filter
166
+ timeout: 30000
167
+ ```
168
+
169
+ ### Effects Configuration
170
+
171
+ #### Zoom — Adaptive zoom follows cursor on clicks
172
+ ```yaml
173
+ zoom:
174
+ enabled: true
175
+ intensity: moderate # subtle(1.15x) | light(1.25x) | moderate(1.35x) | strong(1.5x) | dramatic(1.8x)
176
+ # scale: 1.35 # Or use numeric value (overridden by intensity)
177
+ duration: 500 # Zoom animation ms
178
+ easing: ease-in-out # ease-in-out | ease-in | ease-out | linear
179
+ autoZoom:
180
+ followCursor: true
181
+ transitionDuration: 300
182
+ padding: 200
183
+ ```
184
+
185
+ #### Cursor — Custom cursor with click effect, trail, highlight
186
+ ```yaml
187
+ cursor:
188
+ enabled: true
189
+ size: 20
190
+ color: "#000000"
191
+ speed: fast # fast (~72ms) | normal (~144ms) | slow (~288ms)
192
+ smoothing: true
193
+ clickEffect: true
194
+ clickColor: "rgba(59, 130, 246, 0.3)"
195
+ clickRadius: 30
196
+ trail: true
197
+ trailLength: 8
198
+ trailColor: "rgba(59, 130, 246, 0.2)"
199
+ highlight: true
200
+ highlightRadius: 40
201
+ highlightColor: "rgba(255, 215, 0, 0.18)"
202
+ ```
203
+
204
+ #### Background — Gradient/solid padding with corners and shadow
205
+ ```yaml
206
+ background:
207
+ type: gradient # gradient | solid | image
208
+ value: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
209
+ padding: 48
210
+ borderRadius: 14
211
+ shadow: true
212
+ ```
213
+
214
+ #### Device Frame — Wraps recording in a device mockup
215
+ ```yaml
216
+ deviceFrame:
217
+ enabled: true
218
+ type: browser # browser | macbook | iphone | ipad | android | none
219
+ darkMode: true
220
+ ```
221
+
222
+ | Type | Description |
223
+ |------|-------------|
224
+ | browser | macOS browser chrome with traffic lights |
225
+ | macbook | MacBook Pro frame |
226
+ | iphone | iPhone 15 Pro with Dynamic Island |
227
+ | ipad | iPad Pro with camera dot |
228
+ | android | Android with punch-hole camera |
229
+
230
+ #### Keystroke HUD — Shows typed keys on screen
231
+ ```yaml
232
+ keystroke:
233
+ enabled: true
234
+ showTyping: false # true = show regular typing; false = shortcuts only (industry default)
235
+ position: bottom-center # bottom-center | bottom-left | bottom-right
236
+ fontSize: 16
237
+ backgroundColor: "rgba(0, 0, 0, 0.75)"
238
+ textColor: "#ffffff"
239
+ padding: 8
240
+ fadeAfter: 1500
241
+ ```
242
+
243
+ #### Watermark — Text overlay at corner
244
+ ```yaml
245
+ watermark:
246
+ enabled: true
247
+ text: "My App"
248
+ position: bottom-right # top-left | top-right | bottom-left | bottom-right
249
+ opacity: 0.5
250
+ fontSize: 14
251
+ color: "#ffffff"
252
+ ```
253
+
254
+ #### Speed Ramp — Auto-adjusts speed near actions
255
+ ```yaml
256
+ speedRamp:
257
+ enabled: true
258
+ idleSpeed: 3.0 # Skip factor for idle frames (0.5-8)
259
+ actionSpeed: 0.8 # Slow factor near clicks (0.25-2)
260
+ transitionFrames: 15
261
+ ```
262
+
263
+ ### Output Presets
264
+
265
+ | Preset | Use case | Approx size (30s) |
266
+ |--------|----------|--------------------|
267
+ | social | Twitter, LinkedIn, Loom | ~2-4 MB |
268
+ | balanced | General purpose, portfolio | ~4-6 MB |
269
+ | archive | High-fidelity storage | larger |
270
+
271
+ ## Critical Rules
272
+
273
+ 1. **First step MUST contain a `navigate` action** — the browser needs a page to start
274
+ 2. **Selectors**: use CSS selectors (`#id`, `.class`, `[data-testid="..."]`). No control chars, semicolons, backticks, or backslashes
275
+ 3. **Type needs focus**: the `type` action auto-focuses, but the element must exist and be visible
276
+ 4. **Scroll before interact**: if an element is below the fold, `scroll` to it first
277
+ 5. **Prefer async waits over fixed `wait`**: use `waitForSelector`, `waitForFunction`, `waitForResponse` instead of guessing durations
278
+ 6. **Viewport = output**: if viewport and output dimensions differ, output will be scaled (a warning is shown)
279
+ 7. **Mobile scenarios**: use `viewport: {width: 390, height: 844}` with `deviceFrame.type: iphone` and `output: {width: 540, height: 1080}`
280
+
281
+ ## Timing Presets
282
+
283
+ ### Snappy demo (~30s)
284
+ - `captureDelay: 50-100`
285
+ - `holdDuration: 500-800`
286
+ - `type.delay: 15-25`
287
+
288
+ ### Cinematic demo (~60s)
289
+ - `captureDelay: 200-400`
290
+ - `holdDuration: 1500-2500`
291
+ - `type.delay: 40-60`
292
+
293
+ ## CLI Commands
294
+
295
+ ```bash
296
+ # Record from YAML scenario
297
+ npx clipwise record <scenario.yaml> -f mp4 -o ./output
298
+
299
+ # Instant demo with built-in dashboard
300
+ npx clipwise demo
301
+ npx clipwise demo --device iphone
302
+ npx clipwise demo --url https://my-app.com
303
+
304
+ # Create template YAML
305
+ npx clipwise init
306
+
307
+ # Validate scenario without recording
308
+ npx clipwise validate <scenario.yaml>
309
+ ```
310
+
311
+ ## Workflow
312
+
313
+ 1. Ask the user for: target URL, what actions to demo, and preferred style (snappy/cinematic)
314
+ 2. Generate a complete `clipwise.yaml` scenario
315
+ 3. Run `npx clipwise validate clipwise.yaml` to check for errors
316
+ 4. If valid, run `npx clipwise record clipwise.yaml -f mp4 -o ./output`
317
+ 5. If the user has specific selectors, use them. Otherwise suggest inspecting the page first
318
+
319
+ ## Selector Discovery
320
+
321
+ If the user doesn't know selectors, help them find them:
322
+ ```bash
323
+ # Open the target URL in a browser and inspect elements
324
+ npx playwright open <url>
325
+ ```
326
+
327
+ Or read the page HTML to find appropriate selectors:
328
+ ```bash
329
+ curl -s <url> | head -200
330
+ ```
331
+
332
+ ## Example: Minimal Scenario
333
+
334
+ ```yaml
335
+ name: "My App Demo"
336
+ viewport:
337
+ width: 1280
338
+ height: 800
339
+
340
+ effects:
341
+ deviceFrame:
342
+ enabled: true
343
+ type: browser
344
+ cursor:
345
+ enabled: true
346
+ clickEffect: true
347
+ highlight: true
348
+ background:
349
+ padding: 48
350
+ borderRadius: 14
351
+ shadow: true
352
+
353
+ output:
354
+ format: mp4
355
+ fps: 30
356
+ preset: balanced
357
+
358
+ steps:
359
+ - name: "Open app"
360
+ captureDelay: 100
361
+ holdDuration: 1000
362
+ actions:
363
+ - action: navigate
364
+ url: "http://localhost:3000"
365
+ waitUntil: load
366
+
367
+ - name: "Click CTA"
368
+ captureDelay: 50
369
+ holdDuration: 800
370
+ actions:
371
+ - action: click
372
+ selector: "#cta-button"
373
+ ```