devrel-toolkit 0.1.2 → 0.1.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"BrowserFrame.d.ts","sourceRoot":"","sources":["../../../src/compositor/components/BrowserFrame.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAW1B,UAAU,iBAAiB;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QACL,IAAI,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QAC9D,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAiJpD,CAAC"}
1
+ {"version":3,"file":"BrowserFrame.d.ts","sourceRoot":"","sources":["../../../src/compositor/components/BrowserFrame.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAW1B,UAAU,iBAAiB;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QACL,IAAI,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QAC9D,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAoJpD,CAAC"}
@@ -3,8 +3,8 @@ import { AbsoluteFill, Img, staticFile, interpolate, spring, useCurrentFrame, us
3
3
  export const BrowserFrame = ({ screenshotPath, url, zoom, durationFrames, }) => {
4
4
  const frame = useCurrentFrame();
5
5
  const { fps, width, height } = useVideoConfig();
6
- // Chrome bar height
7
- const chromeHeight = 40;
6
+ // Chrome bar height (0 when chrome is hidden)
7
+ const chromeHeight = 0;
8
8
  // Calculate zoom animation
9
9
  let scale = 1;
10
10
  let translateX = 0;
@@ -44,7 +44,9 @@ export const BrowserFrame = ({ screenshotPath, url, zoom, durationFrames, }) =>
44
44
  extrapolateRight: "clamp",
45
45
  });
46
46
  }
47
- return (_jsxs(AbsoluteFill, { children: [_jsxs("div", { style: {
47
+ // Skip browser chrome it wastes vertical space and causes black bars
48
+ const showChrome = false;
49
+ return (_jsxs(AbsoluteFill, { style: { backgroundColor: "#0a0a0a" }, children: [showChrome && _jsxs("div", { style: {
48
50
  height: chromeHeight,
49
51
  backgroundColor: "#e8e8e8",
50
52
  display: "flex",
@@ -91,7 +93,7 @@ export const BrowserFrame = ({ screenshotPath, url, zoom, durationFrames, }) =>
91
93
  }, children: _jsx(Img, { src: staticFile(screenshotPath), style: {
92
94
  width: "100%",
93
95
  height: "100%",
94
- objectFit: "cover",
96
+ objectFit: "contain",
95
97
  } }) }) })] }));
96
98
  };
97
99
  //# sourceMappingURL=BrowserFrame.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BrowserFrame.js","sourceRoot":"","sources":["../../../src/compositor/components/BrowserFrame.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BrowserFrame.js","sourceRoot":"","sources":["../../../src/compositor/components/BrowserFrame.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devrel-toolkit",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Toolkit for automated product demo video creation with AI avatars and Remotion compositing",
5
5
  "type": "module",
6
6
  "bin": {
@@ -40,7 +40,19 @@ npx devrel-toolkit doctor
40
40
 
41
41
  If any checks fail, run `npx devrel-toolkit setup`.
42
42
 
43
- **Browser automation**: You MUST use `browser-use` CLI for all browser interactions (screenshots, clicks, element detection). Do NOT use Playwright, Puppeteer, or write custom browser scripts. browser-use CLI is the required tool. Only fall back to Playwright if browser-use is genuinely not installed and cannot be installed.
43
+ **Browser automation**: You MUST use `browser-use` CLI for all browser interactions. It is a standalone Python CLI binary, NOT an npm package. Try running `browser-use` first. If not found in PATH, use the full path `~/.browser-use-env/bin/browser-use`. Never use `npx browser-use`.
44
+
45
+ If browser-use is not installed at all, install it:
46
+ ```bash
47
+ curl -fsSL https://browser-use.com/cli/install.sh | bash
48
+ ```
49
+ Then use `~/.browser-use-env/bin/browser-use` for all commands.
50
+
51
+ If browser-use fails with timeout errors on `open` (even after 120s), the machine likely has an enterprise policy blocking Chrome DevTools remote debugging (CDP). Browser-use depends on CDP and cannot work in this environment. Use Playwright instead — it ships its own Chromium binary that bypasses enterprise policies:
52
+ ```bash
53
+ npx playwright install chromium # one-time setup
54
+ ```
55
+ Then use Playwright's Node.js API — write a small `.mjs` script for each capture task using `chromium.launch()`, `page.goto()`, `page.screenshot()`, `page.locator().boundingBox()`.
44
56
 
45
57
  **D-ID API key**: Check if `DID_API_KEY` is set (in `.env.local` or environment). If it is NOT set and the user did NOT pass `--no-avatar`:
46
58
  - Ask the user: "I need a D-ID API key to generate the avatar presenter. You can get one at https://studio.d-id.com. Would you like to provide your key, or should I skip the avatar and create a video without a presenter?"
@@ -103,28 +115,38 @@ mkdir -p ./demo-work-$(date +%s)/screenshots
103
115
  mkdir -p ./demo-work-$(date +%s)/avatars
104
116
  ```
105
117
 
106
- **Always use `--headed` mode** so both you and the user can see what's happening:
118
+ Use `~/.browser-use-env/bin/browser-use` (full path) if `browser-use` is not in PATH.
107
119
 
120
+ **First command — open the URL** (use a long timeout, the first browser launch is slow):
108
121
  ```bash
109
- browser-use --headed open <url>
122
+ ~/.browser-use-env/bin/browser-use open <url>
123
+ ```
110
124
 
111
- # For each scene, execute navigation steps:
112
- browser-use state # See available elements
125
+ Do NOT use `--headed` or `--profile` flags — headed mode times out in Claude Code's bash, and `--profile` causes macOS permission errors on Chrome cookies. Use plain headless mode. The built-in Chromium works fine for screenshots.
126
+
127
+ After the first `open`, subsequent commands are fast (~50ms) because the daemon stays alive:
128
+
129
+ ```bash
130
+ browser-use state # See available elements with indices
113
131
  browser-use click <index> # Click elements
114
132
  browser-use input <index> "text" # Fill forms
115
133
  browser-use scroll down # Scroll
116
134
  browser-use wait text "loaded" # Wait for content
117
135
 
118
- # Take screenshot — use viewport for above-the-fold, --full for long pages
136
+ # Take screenshot — viewport only, NOT full page
119
137
  browser-use screenshot ./demo-work/screenshots/scene-<id>.png
120
- browser-use screenshot --full ./demo-work/screenshots/scene-<id>.png # full page
121
138
 
122
- # Get bounding boxes for highlights/zoom targets
139
+ # Get bounding boxes for zoom targets
123
140
  browser-use get bbox <index> # Returns { x, y, width, height }
141
+
142
+ # When done
143
+ browser-use close
124
144
  ```
125
145
 
126
146
  Save all screenshots and record bounding box data for zoom targets.
127
147
 
148
+ **Screenshots must show content, not empty space.** Before taking each screenshot, scroll to the section you want to capture so it fills the viewport. If the page has a hero at the top, take the screenshot there. If you need to show a section further down, `browser-use scroll down` first until that section is visible, then screenshot. Never capture black/empty space above or below the content — the video frame should be filled with the actual UI.
149
+
128
150
  **CRITICAL — Bounding boxes**: You MUST use `browser-use get bbox <index>` to get exact bounding box coordinates for every zoom target. NEVER guess or estimate bbox values. Wrong coordinates cause the zoom to frame empty space or cut off content. Run `browser-use state` to find the element index, then `browser-use get bbox <index>` to get the precise `{ x, y, width, height }`.
129
151
 
130
152
  **Zoom framing**: The zoom bbox should include some padding around the target element (add ~50px on each side) so content isn't clipped at the edges. The zoom `level` controls magnification — use 1.3-1.5 for sections, 1.8-2.0 for small elements.
@@ -146,31 +168,60 @@ For scenes that need animated explainers, flow diagrams, or motion graphics inst
146
168
  cd custom-animations && npm install
147
169
  ```
148
170
 
149
- 2. Write a React component for each animation scene. You have the Remotion best-practices skill use it. Example for a flow diagram:
171
+ 2. Write a React component for each animation scene. **Animations MUST have motion** elements appearing one by one, arrows drawing in, labels fading in sequentially. A static diagram rendered as a video is NOT an animation. Every element should animate in using `spring()` or `interpolate()` with staggered delays.
172
+
173
+ Example — a flow diagram where each step appears one after another:
150
174
  ```tsx
151
- // src/FlowDiagram.tsx
152
- import { AbsoluteFill, useCurrentFrame, useVideoConfig, interpolate, spring } from "remotion";
175
+ import { AbsoluteFill, useCurrentFrame, useVideoConfig, spring, interpolate } from "remotion";
153
176
 
154
177
  export const FlowDiagram: React.FC = () => {
155
178
  const frame = useCurrentFrame();
156
179
  const { fps } = useVideoConfig();
157
- // Animate arrows, labels, flow steps using interpolate/spring
158
- // ...
180
+
181
+ // Each step appears sequentially with spring animation
182
+ const step1 = spring({ frame, fps, config: { damping: 200 } });
183
+ const step2 = spring({ frame: frame - 20, fps, config: { damping: 200 } });
184
+ const step3 = spring({ frame: frame - 40, fps, config: { damping: 200 } });
185
+ const step4 = spring({ frame: frame - 60, fps, config: { damping: 200 } });
186
+
187
+ // Arrow draws in between steps
188
+ const arrow1Width = interpolate(step2, [0, 1], [0, 300]);
189
+ const arrow2Width = interpolate(step3, [0, 1], [0, 300]);
190
+
191
+ return (
192
+ <AbsoluteFill style={{ backgroundColor: "#0a0a0a", padding: 80 }}>
193
+ {/* Step 1 fades/scales in */}
194
+ <div style={{ opacity: step1, transform: `scale(${step1})` }}>
195
+ Client → GET /api/random
196
+ </div>
197
+ {/* Arrow draws from left to right */}
198
+ <div style={{ width: arrow1Width, height: 2, backgroundColor: "#4A90D9" }} />
199
+ {/* Step 2 appears after arrow */}
200
+ <div style={{ opacity: step2, transform: `translateY(${(1-step2)*20}px)` }}>
201
+ Server → 402 + config
202
+ </div>
203
+ {/* etc. — each step has a staggered delay */}
204
+ </AbsoluteFill>
205
+ );
159
206
  };
160
207
  ```
161
208
 
209
+ The key pattern: `spring({ frame: frame - DELAY, fps })` where DELAY increases for each element. This creates the sequential reveal effect.
210
+
162
211
  3. Register it as a composition in `src/Root.tsx` and render to MP4:
163
212
  ```bash
164
213
  npx remotion render FlowDiagram ./demo-work/screenshots/scene-flow-diagram.mp4
165
214
  ```
166
215
 
167
- 4. Use the rendered MP4 as the `screenshotPath` for that scene in render-props.json. The toolkit will include it in the final video alongside the app screenshot scenes.
216
+ 4. Use the rendered MP4 as the `screenshotPath` for that scene in render-props.json.
168
217
 
169
- **Tips for custom animations**:
170
- - Match the resolution (1920x1080) and dark background (#0a0a0a) for consistency
171
- - Keep animations 3-8 seconds they should complement the narration, not replace it
218
+ **Animation rules**:
219
+ - **Every element must animate in** nothing should just "be there" from frame 1
220
+ - Use staggered delays (20-30 frames apart) so elements appear one by one
221
+ - Arrows should draw in (width/height animating from 0 to full)
222
+ - Labels should fade + slide in (opacity 0→1 + translateY)
223
+ - Match the resolution (1920x1080) and dark background (#0a0a0a)
172
224
  - Use the app's color scheme for visual consistency
173
- - Prefer simple, clean motion graphics over complex 3D or particle effects
174
225
 
175
226
  ### Step 4: Generate Avatar Video
176
227
 
@@ -178,29 +229,71 @@ Skip this step if `--no-avatar` or `--preview` was specified.
178
229
 
179
230
  Generate **one single continuous avatar video** with all the narration combined. Do NOT generate separate clips per scene — separate clips create jarring cuts between sentences. One continuous video gives natural speech flow.
180
231
 
181
- 1. Check available avatars:
182
- ```bash
183
- npx devrel-toolkit d-id avatars
184
- ```
232
+ **D-ID has two APIs — try Expressives first, fall back to Talks:**
233
+
234
+ **Option A: Expressives API (V4 avatars — via toolkit) preferred**
185
235
 
186
- 2. Concatenate ALL scene narrations into one text, in order, with natural pauses between sections. Use `npx devrel-toolkit d-id generate` with a single-scene script:
236
+ 1. Use this avatar by default: `public_oliver_sport_elegant@avt_VVIQYg` (Oliver professional male presenter). Concatenate all narrations into one script:
187
237
  ```json
188
238
  [
189
239
  {
190
240
  "id": "full-narration",
191
- "narration": "Welcome to our platform. Let me show you how easy it is to get started. ... Signing up is simple. Just click the button and fill in your details. ... And that's it — you're ready to go.",
192
- "avatarId": "<chosen-avatar-id>"
241
+ "narration": "Welcome to our platform. ... And that's it — you're ready to go.",
242
+ "avatarId": "public_oliver_sport_elegant@avt_VVIQYg"
193
243
  }
194
244
  ]
195
245
  ```
196
-
197
- 3. Generate:
246
+ 2. Generate:
198
247
  ```bash
199
248
  npx devrel-toolkit d-id generate \
200
249
  --script ./demo-work/avatar-script.json \
201
250
  --output ./demo-work/avatars/ \
202
- --avatar "<avatar-id>"
251
+ --avatar "public_oliver_sport_elegant@avt_VVIQYg"
203
252
  ```
253
+ 3. If that avatar fails, list available ones with `npx devrel-toolkit d-id avatars` and pick another.
254
+
255
+ **Option B: Talks API (works on all plans including free — via curl)**
256
+
257
+ If Expressives fails (subscription error, no avatars available), use the Talks API directly. It takes a source photo URL instead of an avatar ID:
258
+
259
+ ```bash
260
+ DID_KEY=$(grep DID_API_KEY .env.local | cut -d= -f2)
261
+
262
+ # Concatenate all narration into one string
263
+ NARRATION="Welcome to our platform. ... And that's it."
264
+
265
+ # Create the talk
266
+ RESPONSE=$(curl -s -X POST "https://api.d-id.com/talks" \
267
+ -H "Authorization: Basic $DID_KEY" \
268
+ -H "Content-Type: application/json" \
269
+ -d "{
270
+ \"source_url\": \"https://d-id-public-bucket.s3.us-west-2.amazonaws.com/alice.jpg\",
271
+ \"script\": {
272
+ \"type\": \"text\",
273
+ \"input\": \"$NARRATION\",
274
+ \"provider\": { \"type\": \"microsoft\", \"voice_id\": \"en-US-JennyNeural\" }
275
+ }
276
+ }")
277
+
278
+ TALK_ID=$(echo "$RESPONSE" | python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
279
+
280
+ # Poll until done, then download
281
+ for i in $(seq 1 60); do
282
+ RESULT=$(curl -s "https://api.d-id.com/talks/$TALK_ID" -H "Authorization: Basic $DID_KEY")
283
+ STATUS=$(echo "$RESULT" | python3 -c "import json,sys; print(json.load(sys.stdin).get('status','unknown'))")
284
+ if [ "$STATUS" = "done" ]; then
285
+ RESULT_URL=$(echo "$RESULT" | python3 -c "import json,sys; print(json.load(sys.stdin).get('result_url',''))")
286
+ curl -sL "$RESULT_URL" -o ./demo-work/avatars/full-narration.mp4
287
+ echo "Downloaded avatar video!"
288
+ break
289
+ fi
290
+ if [ "$STATUS" = "error" ] || [ "$STATUS" = "rejected" ]; then
291
+ echo "FAILED: $RESULT"
292
+ break
293
+ fi
294
+ sleep 5
295
+ done
296
+ ```
204
297
 
205
298
  4. This takes 1–5 minutes. The output includes a `manifest.json` with the clip path and total duration. Use this single avatar clip as `avatarClipPath` for the **first scene only** — the PiP will play continuously across all scenes.
206
299
 
@@ -282,9 +375,10 @@ Wait for the render to complete. This may take a few minutes.
282
375
  ## Error Handling
283
376
 
284
377
  **browser-use not found:**
285
- - Run `npx devrel-toolkit setup` or install manually: `curl -fsSL https://browser-use.com/cli/install.sh | bash`
378
+ - Install it: `curl -fsSL https://browser-use.com/cli/install.sh | bash`
379
+ - Or run `npx devrel-toolkit setup` which handles the installation
286
380
  - Do NOT use `pip install browser-use` — that installs the Python SDK, not the CLI
287
- - If browser-use cannot be installed, fall back to Playwright
381
+ - Do NOT fall back to Playwright — install browser-use
288
382
 
289
383
  **Browser navigation fails:**
290
384
  - Retry the action once