@agent-foundry/replay-server 1.0.0 → 1.0.2

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 (46) hide show
  1. package/.cursor/dev.mdc +941 -0
  2. package/.cursor/project.mdc +17 -2
  3. package/.env +30 -0
  4. package/Dockerfile +6 -0
  5. package/README.md +297 -27
  6. package/dist/cli/render.js +14 -4
  7. package/dist/cli/render.js.map +1 -1
  8. package/dist/renderer/PuppeteerRenderer.d.ts +28 -2
  9. package/dist/renderer/PuppeteerRenderer.d.ts.map +1 -1
  10. package/dist/renderer/PuppeteerRenderer.js +134 -36
  11. package/dist/renderer/PuppeteerRenderer.js.map +1 -1
  12. package/dist/server/index.d.ts +4 -0
  13. package/dist/server/index.d.ts.map +1 -1
  14. package/dist/server/index.js +200 -46
  15. package/dist/server/index.js.map +1 -1
  16. package/dist/services/BundleManager.d.ts +99 -0
  17. package/dist/services/BundleManager.d.ts.map +1 -0
  18. package/dist/services/BundleManager.js +410 -0
  19. package/dist/services/BundleManager.js.map +1 -0
  20. package/dist/services/OSSClient.d.ts +51 -0
  21. package/dist/services/OSSClient.d.ts.map +1 -0
  22. package/dist/services/OSSClient.js +207 -0
  23. package/dist/services/OSSClient.js.map +1 -0
  24. package/dist/services/index.d.ts +7 -0
  25. package/dist/services/index.d.ts.map +1 -0
  26. package/dist/services/index.js +7 -0
  27. package/dist/services/index.js.map +1 -0
  28. package/dist/services/types.d.ts +73 -0
  29. package/dist/services/types.d.ts.map +1 -0
  30. package/dist/services/types.js +5 -0
  31. package/dist/services/types.js.map +1 -0
  32. package/docker-compose.local.yml +10 -0
  33. package/env.example +30 -0
  34. package/package.json +7 -3
  35. package/restart.sh +5 -0
  36. package/samples/jump_arena_5_ja-mksi5fku-qgk5iq.json +1952 -0
  37. package/scripts/render-pipeline.sh +657 -0
  38. package/scripts/test-bundle-preload.sh +20 -0
  39. package/scripts/test-service-sts.sh +176 -0
  40. package/src/cli/render.ts +18 -7
  41. package/src/renderer/PuppeteerRenderer.ts +192 -39
  42. package/src/server/index.ts +249 -68
  43. package/src/services/BundleManager.ts +503 -0
  44. package/src/services/OSSClient.ts +286 -0
  45. package/src/services/index.ts +7 -0
  46. package/src/services/types.ts +78 -0
@@ -151,8 +151,20 @@ sequenceDiagram
151
151
  #### 4. Game URL Resolution Priority
152
152
 
153
153
  1. `config.gameUrl` (explicit URL in render request)
154
- 2. `manifest.bundleId` → `/bundles/<bundleId>/` (bundle hosting)
155
- 3. `GAME_URL` environment variable (fallback)
154
+ 2. `manifest.bundleId` + `manifest.bundleUrl` download from OSS, cache, and serve
155
+ 3. `manifest.bundleId` `/bundles/<bundleId>/` (from cache)
156
+ 4. `GAME_URL` environment variable (fallback)
157
+
158
+ #### 5. Dynamic Bundle Downloads
159
+
160
+ **Why**: Support multiple games without rebuilding Docker image. Bundles downloaded on-demand from OSS.
161
+
162
+ **How**:
163
+ - Client provides `bundleUrl` in manifest pointing to TAR.GZ archive on OSS
164
+ - Server gets STS credentials from BFF API
165
+ - Downloads and extracts bundle to cache directory
166
+ - LRU eviction when cache exceeds `MAX_CACHE_SIZE`
167
+ - Bundles marked "in use" during rendering are protected from eviction
156
168
 
157
169
  ---
158
170
 
@@ -558,6 +570,9 @@ ACR_NAMESPACE=your-namespace ./scripts/deploy-aliyun.sh
558
570
  | `BUNDLES_DIR` | `./bundles` | Directory containing game bundles |
559
571
  | `OUTPUT_DIR` | `./output` | Directory for rendered videos |
560
572
  | `PUPPETEER_EXECUTABLE_PATH` | `/usr/bin/chromium` | Chromium executable path |
573
+ | `BFF_BASE_URL` | `http://localhost:11001` | BFF API URL for STS credentials |
574
+ | `BFF_SERVICE_TOKEN` | - | Optional service-to-service auth token |
575
+ | `MAX_CACHE_SIZE` | `10737418240` | Max bundle cache size in bytes (10GB) |
561
576
 
562
577
  ### Render Configuration
563
578
 
package/.env ADDED
@@ -0,0 +1,30 @@
1
+ # Replay Server Environment Variables
2
+
3
+ # Server port
4
+ PORT=3001
5
+
6
+ # Default game URL (fallback when no bundleId specified)
7
+ GAME_URL=http://localhost:3000
8
+
9
+ # Directory containing game bundles
10
+ BUNDLES_DIR=./bundles
11
+
12
+ # Directory for rendered video output
13
+ OUTPUT_DIR=./output
14
+
15
+ # Puppeteer executable path (for containerized environments)
16
+ PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
17
+
18
+ # =============================================================================
19
+ # Bundle Download Configuration
20
+ # =============================================================================
21
+
22
+ # BFF API URL for STS credentials (required for dynamic bundle downloads)
23
+ BFF_BASE_URL=http://localhost:11001
24
+
25
+ # Service-to-service auth token for BFF (REQUIRED for bundle downloads)
26
+ # Set this to the value of SUPABASE_JWT_SECRET from BFF's .env file
27
+ BFF_SERVICE_TOKEN=ijwt8jbx3Kkf2XDE8bR3AViGJchA5VppbOwpBFTF
28
+
29
+ # Maximum bundle cache size in bytes (default: 10GB = 10737418240)
30
+ MAX_CACHE_SIZE=10737418240
package/Dockerfile CHANGED
@@ -144,6 +144,12 @@ WORKDIR /app/packages/replay-server
144
144
  ENV PORT=9000
145
145
  ENV BUNDLES_DIR=/app/packages/replay-server/bundles
146
146
  ENV OUTPUT_DIR=/app/packages/replay-server/output
147
+ # BFF API URL for STS credentials (required for dynamic bundle downloads)
148
+ ENV BFF_BASE_URL=http://localhost:11001
149
+ # Optional: Service-to-service auth token for BFF
150
+ # ENV BFF_SERVICE_TOKEN=
151
+ # Maximum cache size in bytes (default: 10GB)
152
+ ENV MAX_CACHE_SIZE=10737418240
147
153
 
148
154
  # Expose port
149
155
  EXPOSE 9000
package/README.md CHANGED
@@ -20,11 +20,11 @@ The replay-server can host game bundles internally, eliminating the need for a s
20
20
 
21
21
  ```
22
22
  ┌──────────────────────────────────────────────────────────────┐
23
- │ replay-server
24
- │ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐
25
- │ │ Bundle Host │ │ Puppeteer │ │ HTTP API │
26
- │ │ /bundles/* │◄──│ Renderer │◄──│ POST /render │
27
- │ └─────────────┘ └──────────────┘ └─────────────────┘
23
+ │ replay-server
24
+ │ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐
25
+ │ │ Bundle Host │ │ Puppeteer │ │ HTTP API │
26
+ │ │ /bundles/* │◄──│ Renderer │◄──│ POST /render │
27
+ │ └─────────────┘ └──────────────┘ └─────────────────┘
28
28
  │ │ ▲ │
29
29
  │ ▼ │ │
30
30
  │ bundles/game-life-restart/ manifest.json │
@@ -84,7 +84,59 @@ cd packages/replay-server
84
84
  pnpm install
85
85
  ```
86
86
 
87
- ### CLI Tool
87
+ ### Render Pipeline Script (Recommended)
88
+
89
+ The **render-pipeline.sh** script provides a complete end-to-end workflow that automates:
90
+ - Server health checking (with auto-start option)
91
+ - Bundle verification and preloading
92
+ - Job submission via HTTP API
93
+ - Status polling with progress display
94
+ - Automatic video download
95
+
96
+ ```bash
97
+ cd packages/replay-server
98
+
99
+ # Basic usage (server must be running)
100
+ ./scripts/render-pipeline.sh -m samples/life-replay-lr-mkcdfzc2-u8cqbs.json
101
+
102
+ # With custom output and settings
103
+ ./scripts/render-pipeline.sh \
104
+ -m samples/life-replay-lr-mkcdfzc2-u8cqbs.json \
105
+ -o videos/my-replay.mp4 \
106
+ --width 720 \
107
+ --height 1280 \
108
+ --fps 30
109
+
110
+ # Auto-start server if needed
111
+ ./scripts/render-pipeline.sh -m samples/replay.json --start-server
112
+
113
+ # Build bundle locally if missing
114
+ ./scripts/render-pipeline.sh -m samples/replay.json --build-bundle
115
+
116
+ # Verbose output for debugging
117
+ ./scripts/render-pipeline.sh -m samples/replay.json --verbose
118
+
119
+ # Show help
120
+ ./scripts/render-pipeline.sh --help
121
+ ```
122
+
123
+ **Prerequisites:**
124
+ - `curl` - HTTP requests (pre-installed on most systems)
125
+ - `jq` - JSON parsing (`brew install jq` on macOS, `apt install jq` on Linux)
126
+
127
+ **Features:**
128
+ - ✅ Idempotent - safe to run multiple times
129
+ - ✅ Automatic bundle downloading from OSS if `bundleUrl` provided
130
+ - ✅ Real-time progress display with status updates
131
+ - ✅ Colored output for better readability
132
+ - ✅ Robust error handling with clear messages
133
+ - ✅ Uses `/api/bundles` API endpoints (separated from static file serving at `/bundles`)
134
+
135
+ **Note:** Bundle management APIs are under `/api/bundles/*` prefix, while static bundle files are served at `/bundles/<bundleId>/`. This separation prevents route conflicts between API endpoints and static file serving.
136
+
137
+ ### CLI Tool (Direct Rendering)
138
+
139
+ For direct rendering without the HTTP server:
88
140
 
89
141
  ```bash
90
142
  # From project root (recommended)
@@ -177,9 +229,9 @@ Response:
177
229
  }
178
230
  ```
179
231
 
180
- **GET /bundles** - List available game bundles
232
+ **GET /api/bundles** - List available game bundles
181
233
  ```bash
182
- curl http://localhost:3001/bundles
234
+ curl http://localhost:3001/api/bundles
183
235
  ```
184
236
 
185
237
  Response:
@@ -229,22 +281,83 @@ curl http://localhost:3001/status/5eaee18f-48a7-4193-b594-86756ac76ce2
229
281
  curl -o video.mp4 http://localhost:3001/download/5eaee18f-48a7-4193-b594-86756ac76ce2
230
282
  ```
231
283
 
284
+ ## Replay Modes
285
+
286
+ The renderer supports two replay modes, detected automatically based on manifest fields:
287
+
288
+ | Mode | Detection | Use Case | Example |
289
+ |------|-----------|----------|---------|
290
+ | **Continuous** | `summary.durationSeconds` present | Real-time games with continuous animation | JumpArena |
291
+ | **Age-based** | `timeline[]` array present | Turn-based or discrete-state games | LifeRestart |
292
+
293
+ ### Mode Detection Priority
294
+
295
+ 1. If `manifest.summary.durationSeconds` exists and is > 0 → **Continuous mode**
296
+ 2. If `manifest.timeline[]` exists and has items → **Age-based mode**
297
+ 3. Fallback: Continuous mode with 10s default duration
298
+
299
+ ### Continuous Mode
300
+
301
+ For games that animate in real-time (like JumpArena):
302
+
303
+ - Renderer captures frames at regular intervals (e.g., 16 FPS = every 62.5ms)
304
+ - Game runs its own simulation based on elapsed time
305
+ - No external events dispatched during capture
306
+ - Duration determined by `manifest.summary.durationSeconds`
307
+
308
+ **Manifest structure:**
309
+ ```json
310
+ {
311
+ "schema": "jumpArena.replay.v1",
312
+ "bundleId": "game-jump-arena",
313
+ "gameId": "ja-abc123",
314
+ "gameRun": { "seed": 1234, "inputs": [...], "events": [...] },
315
+ "summary": {
316
+ "durationSeconds": 8.5,
317
+ "totalScore": 10
318
+ }
319
+ }
320
+ ```
321
+
322
+ ### Age-based Mode
323
+
324
+ For games with discrete states (like LifeRestart):
325
+
326
+ - Renderer dispatches `replay-next-age` events to advance the game
327
+ - Each "age" is displayed for `secondsPerAge` seconds (default: 1.2s)
328
+ - Frames captured while displaying each age
329
+ - Duration = `timeline.length × secondsPerAge`
330
+
331
+ **Manifest structure:**
332
+ ```json
333
+ {
334
+ "schema": "lifeRestart.replay.v1",
335
+ "bundleId": "game-life-restart",
336
+ "gameId": "lr-abc123",
337
+ "timeline": [
338
+ { "age": 0, "eventId": 1, "description": "..." },
339
+ { "age": 1, "eventId": 2, "description": "..." }
340
+ ],
341
+ "summary": { "finalAge": 80 }
342
+ }
343
+ ```
344
+
232
345
  ## Game Integration
233
346
 
234
- For the renderer to work, the game must support replay mode:
347
+ For the renderer to work, the game must support replay mode. The requirements differ slightly based on replay mode.
235
348
 
236
- ### 1. Listen for replay manifest
349
+ ### Common Requirements (Both Modes)
350
+
351
+ #### 1. Listen for replay manifest
237
352
 
238
353
  ```typescript
239
- // In your game's main component
354
+ // In your game's main component or hook
240
355
  useEffect(() => {
241
- // Check for manifest from URL or window
242
356
  const urlParams = new URLSearchParams(window.location.search);
243
357
  if (urlParams.get('mode') === 'replay') {
244
358
  // Wait for manifest injection
245
359
  const handleManifest = (e: CustomEvent) => {
246
- const manifest = e.detail;
247
- enterReplayMode(manifest);
360
+ enterReplayMode(e.detail);
248
361
  };
249
362
 
250
363
  window.addEventListener('replay-manifest-loaded', handleManifest);
@@ -253,26 +366,94 @@ useEffect(() => {
253
366
  if ((window as any).__REPLAY_MANIFEST__) {
254
367
  enterReplayMode((window as any).__REPLAY_MANIFEST__);
255
368
  }
369
+
370
+ return () => {
371
+ window.removeEventListener('replay-manifest-loaded', handleManifest);
372
+ };
256
373
  }
257
374
  }, []);
258
375
  ```
259
376
 
260
- ### 2. Handle replay-next-age event
377
+ #### 2. Signal when ready for capture
378
+
379
+ ```tsx
380
+ // Add data attribute when replay is ready
381
+ <div data-replay-ready={isReplayReady ? "true" : "false"}>
382
+ {/* game content */}
383
+ </div>
384
+ ```
385
+
386
+ ### Continuous Mode Requirements
387
+
388
+ For real-time games like JumpArena:
389
+
390
+ #### 1. Start simulation from time zero
391
+
392
+ ```typescript
393
+ function enterReplayMode(manifest: ReplayManifest) {
394
+ // Load the game state from manifest
395
+ loadGameRun(manifest.gameRun);
396
+
397
+ // CRITICAL: Reset simulation time to 0
398
+ simulationTime = 0;
399
+
400
+ // Mark as replay mode
401
+ setIsReplayMode(true);
402
+ setIsReplayReady(true);
403
+ }
404
+ ```
405
+
406
+ #### 2. Use elapsed time for simulation (not wall clock)
407
+
408
+ ```typescript
409
+ // In your animation loop
410
+ function gameLoop() {
411
+ const now = performance.now();
412
+ const dt = (now - lastFrameTime) / 1000;
413
+ lastFrameTime = now;
414
+
415
+ // Advance simulation time
416
+ if (isReplayMode) {
417
+ simulationTime += dt;
418
+ }
419
+
420
+ // Render game state at simulationTime
421
+ const state = simulateAtTime(gameRun, simulationTime);
422
+ render(state);
423
+
424
+ requestAnimationFrame(gameLoop);
425
+ }
426
+ ```
427
+
428
+ #### 3. Key implementation notes
429
+
430
+ - **Do NOT skip to final state**: Even if `gameRun.result` exists, animate from the beginning
431
+ - **simulateAtTime must be deterministic**: Given the same inputs and time, return the same state
432
+ - **Include summary.durationSeconds**: Calculate total replay duration when exporting manifest
433
+
434
+ ### Age-based Mode Requirements
435
+
436
+ For discrete-state games like LifeRestart:
437
+
438
+ #### 1. Handle replay-next-age event
261
439
 
262
440
  ```typescript
263
441
  window.addEventListener('replay-next-age', () => {
264
- // Advance to next age in replay
265
- replayNextAge();
442
+ // Advance to next age/state in timeline
443
+ currentAgeIndex++;
444
+ displayAge(timeline[currentAgeIndex]);
266
445
  });
267
446
  ```
268
447
 
269
- ### 3. Signal when ready
448
+ #### 2. Start from first age
270
449
 
271
- ```tsx
272
- // Add data attribute when ready for capture
273
- <div data-replay-ready="true">
274
- {/* game content */}
275
- </div>
450
+ ```typescript
451
+ function enterReplayMode(manifest: ReplayManifest) {
452
+ timeline = manifest.timeline;
453
+ currentAgeIndex = -1; // Will be incremented on first replay-next-age
454
+ setIsReplayMode(true);
455
+ setIsReplayReady(true);
456
+ }
276
457
  ```
277
458
 
278
459
  ## Configuration
@@ -285,13 +466,102 @@ Environment variables:
285
466
  | `GAME_URL` | http://localhost:5173 | Fallback URL when no bundleId specified |
286
467
  | `BUNDLES_DIR` | ./bundles | Directory containing game bundles |
287
468
  | `OUTPUT_DIR` | ./output | Directory for rendered videos |
469
+ | `BFF_BASE_URL` | http://localhost:11001 | BFF API URL for STS credentials |
470
+ | `BFF_SERVICE_TOKEN` | - | **Required** for bundle downloads. Set to BFF's `SUPABASE_JWT_SECRET` |
471
+ | `MAX_CACHE_SIZE` | 10737418240 | Max bundle cache size in bytes (10GB) |
472
+
473
+ ### Service-to-Service Authentication
474
+
475
+ For dynamic bundle downloads from OSS, the replay-server needs to authenticate with the BFF service. This uses a service-to-service authentication mechanism:
476
+
477
+ 1. **Get `SUPABASE_JWT_SECRET` from BFF**: Copy the value of `SUPABASE_JWT_SECRET` from the BFF service's `.env` file
478
+ 2. **Set `BFF_SERVICE_TOKEN`**: Configure this value in replay-server's `.env`:
479
+ ```env
480
+ BFF_SERVICE_TOKEN=your-supabase-jwt-secret-from-bff
481
+ ```
482
+ 3. **How it works**: The replay-server calls `POST /studio/service/sts` on the BFF with this token as a Bearer token. BFF validates the token matches its `SUPABASE_JWT_SECRET` and returns STS credentials for OSS access.
483
+
484
+ **Note:** This endpoint does not require user authentication - it's designed for internal service communication only.
288
485
 
289
486
  ### Game URL Resolution Order
290
487
 
291
488
  When rendering a video, the game URL is resolved in this order:
292
489
  1. `config.gameUrl` (explicit URL in render request)
293
- 2. `manifest.bundleId` (serves from `/bundles/<bundleId>/`)
294
- 3. `GAME_URL` environment variable (fallback)
490
+ 2. `manifest.bundleId` + `manifest.bundleUrl` (downloads from OSS if not cached)
491
+ 3. `manifest.bundleId` (serves from cached `/bundles/<bundleId>/`)
492
+ 4. `GAME_URL` environment variable (fallback)
493
+
494
+ ## Dynamic Bundle Downloads
495
+
496
+ The replay-server supports downloading game bundles on-demand from Alibaba Cloud OSS.
497
+
498
+ ### How It Works
499
+
500
+ 1. Client includes `bundleId` and `bundleUrl` in the render request manifest
501
+ 2. Server checks if bundle is cached locally
502
+ 3. If not cached, server gets STS credentials from BFF API
503
+ 4. Server downloads and extracts the TAR.GZ bundle from OSS
504
+ 5. Bundle is cached for future requests (LRU eviction when cache is full)
505
+
506
+ ### Bundle Management Endpoints
507
+
508
+ **POST /api/bundles/preload** - Preload a bundle (async download)
509
+ ```bash
510
+ curl -X POST http://localhost:3001/api/bundles/preload \
511
+ -H "Content-Type: application/json" \
512
+ -d '{
513
+ "bundleId": "game-vocab-master",
514
+ "bundleUrl": "https://oss-bucket.oss-cn-beijing.aliyuncs.com/bundles/game-vocab-master.tar.gz"
515
+ }'
516
+ ```
517
+
518
+ **GET /api/bundles/stats** - Get cache and download statistics
519
+ ```bash
520
+ curl http://localhost:3001/api/bundles/stats
521
+ ```
522
+
523
+ Response:
524
+ ```json
525
+ {
526
+ "cache": {
527
+ "used": 15728640,
528
+ "max": 10737418240,
529
+ "usedPercent": 0.15,
530
+ "bundleCount": 2
531
+ },
532
+ "downloads": {
533
+ "active": 1,
534
+ "completed": 15,
535
+ "failed": 0
536
+ }
537
+ }
538
+ ```
539
+
540
+ **DELETE /api/bundles/:bundleId** - Remove bundle from cache
541
+ ```bash
542
+ curl -X DELETE http://localhost:3001/api/bundles/game-vocab-master
543
+ ```
544
+
545
+ ### Render Request with bundleUrl
546
+
547
+ ```bash
548
+ curl -X POST http://localhost:3001/render \
549
+ -H "Content-Type: application/json" \
550
+ -d '{
551
+ "manifest": {
552
+ "schema": "lifeRestart.replay.v1",
553
+ "bundleId": "game-vocab-master",
554
+ "bundleUrl": "https://oss-bucket.oss-cn-beijing.aliyuncs.com/bundles/game-vocab-master.tar.gz",
555
+ "gameId": "vm-abc123",
556
+ "timeline": [...],
557
+ "highlights": []
558
+ },
559
+ "config": {
560
+ "width": 1080,
561
+ "height": 1920
562
+ }
563
+ }'
564
+ ```
295
565
 
296
566
  ## Output
297
567
 
@@ -439,7 +709,7 @@ curl http://localhost:3001/health
439
709
  # }
440
710
 
441
711
  # List available bundles
442
- curl http://localhost:3001/bundles
712
+ curl http://localhost:3001/api/bundles
443
713
  ```
444
714
 
445
715
  ##### 3.4 Test Render API with bundleId
@@ -600,7 +870,7 @@ docker buildx imagetools inspect ${ACR_REGISTRY}/${ACR_NAMESPACE}/${IMAGE_NAME}:
600
870
  curl https://<your-function-url>/health
601
871
 
602
872
  # Check available bundles
603
- curl https://<your-function-url>/bundles
873
+ curl https://<your-function-url>/api/bundles
604
874
 
605
875
  # **NEW: Debug Chromium installation**
606
876
  curl https://<your-function-url>/debug/chrome
@@ -151,11 +151,21 @@ async function main() {
151
151
  console.log('📄 Loading manifest...');
152
152
  const manifest = await loadManifest(args);
153
153
  console.log(` Game ID: ${manifest.gameId}`);
154
- console.log(` Timeline: ${manifest.timeline.length} ages`);
155
- console.log(` Highlights: ${manifest.highlights.length}`);
154
+ // Handle optional timeline
155
+ const timelineLength = Array.isArray(manifest.timeline) ? manifest.timeline.length : 0;
156
+ if (timelineLength > 0) {
157
+ console.log(` Timeline: ${timelineLength} ages`);
158
+ }
159
+ // Handle optional highlights
160
+ const highlightsLength = Array.isArray(manifest.highlights) ? manifest.highlights.length : 0;
161
+ if (highlightsLength > 0) {
162
+ console.log(` Highlights: ${highlightsLength}`);
163
+ }
156
164
  // Estimate duration
157
- const estimatedDuration = manifest.timeline.length * args.secondsPerAge;
158
- console.log(` Estimated video duration: ${estimatedDuration}s`);
165
+ const estimatedDuration = timelineLength * args.secondsPerAge;
166
+ if (estimatedDuration > 0) {
167
+ console.log(` Estimated video duration: ${estimatedDuration}s`);
168
+ }
159
169
  console.log('');
160
170
  // Create output directory
161
171
  const outputDir = path.dirname(path.resolve(args.output));
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/cli/render.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/cli/render.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,21 @@
8
8
  * 4. Captures screenshots as JPEG buffers and streams directly to FFmpeg via stdin
9
9
  * 5. Encodes video using libx264 (CPU) by default, or h264_nvenc if explicitly enabled
10
10
  */
11
- import type { ReplayManifestV1 } from '@agent-foundry/replay';
11
+ /**
12
+ * Generic replay manifest interface
13
+ * Supports any game type - games interpret their own schemas
14
+ */
15
+ export interface GenericReplayManifest {
16
+ schema: string;
17
+ bundleId?: string;
18
+ gameId: string;
19
+ timeline?: unknown[];
20
+ summary?: {
21
+ durationSeconds?: number;
22
+ [key: string]: unknown;
23
+ };
24
+ [key: string]: unknown;
25
+ }
12
26
  export interface RenderConfig {
13
27
  /** URL of the game (can be local file:// or http://) */
14
28
  gameUrl: string;
@@ -47,10 +61,22 @@ export declare class PuppeteerRenderer {
47
61
  private page;
48
62
  private pageErrors;
49
63
  private failedRequests;
64
+ /**
65
+ * Calculate replay timing based on manifest fields
66
+ *
67
+ * Detection priority (field-based, not schema-name based):
68
+ * 1. If manifest.summary.durationSeconds exists → continuous mode
69
+ * 2. If manifest.timeline[] exists → age-based mode
70
+ * 3. Fallback to 10s continuous mode
71
+ *
72
+ * Continuous mode: Real-time simulation, frames captured at regular intervals
73
+ * Age-based mode: Discrete ages with replay-next-age events
74
+ */
75
+ private calculateReplayTiming;
50
76
  /**
51
77
  * Render a replay manifest to video
52
78
  */
53
- render(manifest: ReplayManifestV1, config: RenderConfig): Promise<RenderResult>;
79
+ render(manifest: GenericReplayManifest, config: RenderConfig): Promise<RenderResult>;
54
80
  private initBrowser;
55
81
  private loadGame;
56
82
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"PuppeteerRenderer.d.ts","sourceRoot":"","sources":["../../src/renderer/PuppeteerRenderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,WAAW,YAAY;IACzB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAEhB,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IAEnB,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,kCAAkC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,8EAA8E;IAC9E,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,oCAAoC;IACpC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAWD,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,cAAc,CAAkD;IAExE;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;YAiDvE,WAAW;YAqDX,QAAQ;IA4FtB;;;OAGG;YACW,sBAAsB;IAYpC;;OAEG;YACW,iCAAiC;IA0K/C;;OAEG;IACH,OAAO,CAAC,YAAY;YA4BN,YAAY;IAQ1B,OAAO,CAAC,cAAc;CAWzB"}
1
+ {"version":3,"file":"PuppeteerRenderer.d.ts","sourceRoot":"","sources":["../../src/renderer/PuppeteerRenderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE;QACN,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KAC1B,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAkBD,MAAM,WAAW,YAAY;IACzB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAEhB,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IAEnB,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,kCAAkC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,8EAA8E;IAC9E,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,oCAAoC;IACpC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAWD,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,cAAc,CAAkD;IAExE;;;;;;;;;;OAUG;IACH,OAAO,CAAC,qBAAqB;IAsC7B;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,qBAAqB,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;YAsD5E,WAAW;YAqDX,QAAQ;IAiGtB;;;OAGG;YACW,sBAAsB;IAapC;;OAEG;YACW,iCAAiC;IAwO/C;;OAEG;IACH,OAAO,CAAC,YAAY;YA4BN,YAAY;IAQ1B,OAAO,CAAC,cAAc;CAWzB"}