@agent-foundry/replay-server 1.0.0 → 1.0.1

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 +153 -12
  6. package/dist/cli/render.js +14 -4
  7. package/dist/cli/render.js.map +1 -1
  8. package/dist/renderer/PuppeteerRenderer.d.ts +12 -2
  9. package/dist/renderer/PuppeteerRenderer.d.ts.map +1 -1
  10. package/dist/renderer/PuppeteerRenderer.js +23 -16
  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 +8 -0
  33. package/env.example +30 -0
  34. package/package.json +7 -3
  35. package/restart.sh +5 -0
  36. package/samples/jump_arena_0_ja-mks5um2x-nksbmz.json +1907 -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 +41 -21
  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
@@ -0,0 +1,410 @@
1
+ /**
2
+ * Bundle Manager
3
+ *
4
+ * Manages bundle lifecycle: download, extraction, caching, and cleanup.
5
+ * Uses LRU eviction to manage cache size.
6
+ */
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import { createGunzip } from 'zlib';
10
+ import { extract } from 'tar-stream';
11
+ /**
12
+ * Error thrown by bundle manager operations
13
+ */
14
+ export class BundleManagerError extends Error {
15
+ code;
16
+ bundleId;
17
+ constructor(message, code, bundleId) {
18
+ super(message);
19
+ this.code = code;
20
+ this.bundleId = bundleId;
21
+ this.name = 'BundleManagerError';
22
+ }
23
+ }
24
+ /**
25
+ * Bundle Manager for downloading, caching, and serving game bundles
26
+ */
27
+ export class BundleManager {
28
+ bundlesDir;
29
+ maxCacheSize;
30
+ ossClient;
31
+ bundles = new Map();
32
+ downloadPromises = new Map();
33
+ bundlesInUse = new Set();
34
+ downloadStats = {
35
+ active: 0,
36
+ completed: 0,
37
+ failed: 0,
38
+ };
39
+ constructor(config) {
40
+ this.bundlesDir = config.bundlesDir;
41
+ this.maxCacheSize = config.maxCacheSize;
42
+ this.ossClient = config.ossClient;
43
+ // Ensure bundles directory exists
44
+ fs.mkdirSync(this.bundlesDir, { recursive: true });
45
+ // Load existing bundles from disk
46
+ this.loadCachedBundles();
47
+ }
48
+ /**
49
+ * Ensure a bundle is available (download if needed)
50
+ * Returns the path to the bundle directory
51
+ */
52
+ async ensureBundle(bundleId, bundleUrl) {
53
+ const bundlePath = path.join(this.bundlesDir, bundleId);
54
+ // Check if already cached
55
+ if (this.isCached(bundleId)) {
56
+ // Update last accessed time
57
+ const info = this.bundles.get(bundleId);
58
+ if (info) {
59
+ info.lastAccessedAt = new Date();
60
+ }
61
+ return bundlePath;
62
+ }
63
+ // Check if already downloading
64
+ if (this.downloadPromises.has(bundleId)) {
65
+ console.log(`[BundleManager] Waiting for existing download: ${bundleId}`);
66
+ return this.downloadPromises.get(bundleId);
67
+ }
68
+ // Need to download
69
+ if (!bundleUrl) {
70
+ throw new BundleManagerError(`Bundle ${bundleId} not cached and no bundleUrl provided`, 'BUNDLE_URL_REQUIRED', bundleId);
71
+ }
72
+ // Start download
73
+ const downloadPromise = this.downloadBundle(bundleId, bundleUrl);
74
+ this.downloadPromises.set(bundleId, downloadPromise);
75
+ try {
76
+ const result = await downloadPromise;
77
+ return result;
78
+ }
79
+ finally {
80
+ this.downloadPromises.delete(bundleId);
81
+ }
82
+ }
83
+ /**
84
+ * Check if a bundle is cached and ready
85
+ */
86
+ isCached(bundleId) {
87
+ const bundlePath = path.join(this.bundlesDir, bundleId);
88
+ const indexPath = path.join(bundlePath, 'index.html');
89
+ return fs.existsSync(bundlePath) && fs.existsSync(indexPath);
90
+ }
91
+ /**
92
+ * Mark bundle as in use (prevents eviction during rendering)
93
+ */
94
+ markInUse(bundleId) {
95
+ this.bundlesInUse.add(bundleId);
96
+ }
97
+ /**
98
+ * Mark bundle as no longer in use
99
+ */
100
+ markNotInUse(bundleId) {
101
+ this.bundlesInUse.delete(bundleId);
102
+ }
103
+ /**
104
+ * Download and extract a bundle
105
+ */
106
+ async downloadBundle(bundleId, bundleUrl) {
107
+ const bundlePath = path.join(this.bundlesDir, bundleId);
108
+ const tempPath = `${bundlePath}.downloading`;
109
+ const archivePath = `${bundlePath}.tar.gz`;
110
+ // Initialize bundle info
111
+ this.bundles.set(bundleId, {
112
+ bundleId,
113
+ bundleUrl,
114
+ status: 'downloading',
115
+ progress: 0,
116
+ });
117
+ this.downloadStats.active++;
118
+ try {
119
+ console.log(`[BundleManager] Downloading bundle ${bundleId} from ${bundleUrl}`);
120
+ // Ensure cache has space
121
+ await this.ensureCacheSpace(100 * 1024 * 1024); // Reserve 100MB
122
+ // Download archive
123
+ await this.ossClient.downloadFile(bundleUrl, archivePath, (percent) => {
124
+ const info = this.bundles.get(bundleId);
125
+ if (info) {
126
+ info.progress = percent;
127
+ }
128
+ });
129
+ console.log(`[BundleManager] Extracting bundle ${bundleId}...`);
130
+ // Create temp directory for extraction
131
+ fs.mkdirSync(tempPath, { recursive: true });
132
+ // Extract TAR.GZ
133
+ await this.extractTarGz(archivePath, tempPath);
134
+ // Clean up archive
135
+ fs.unlinkSync(archivePath);
136
+ // Move temp to final location
137
+ if (fs.existsSync(bundlePath)) {
138
+ fs.rmSync(bundlePath, { recursive: true });
139
+ }
140
+ fs.renameSync(tempPath, bundlePath);
141
+ // Verify extraction
142
+ const indexPath = path.join(bundlePath, 'index.html');
143
+ if (!fs.existsSync(indexPath)) {
144
+ throw new BundleManagerError(`Bundle extraction failed: index.html not found`, 'EXTRACTION_INVALID', bundleId);
145
+ }
146
+ // Calculate bundle size
147
+ const size = this.getDirectorySize(bundlePath);
148
+ // Update bundle info
149
+ this.bundles.set(bundleId, {
150
+ bundleId,
151
+ bundleUrl,
152
+ status: 'ready',
153
+ size,
154
+ cachedAt: new Date(),
155
+ lastAccessedAt: new Date(),
156
+ });
157
+ this.downloadStats.active--;
158
+ this.downloadStats.completed++;
159
+ console.log(`[BundleManager] Bundle ${bundleId} ready (${(size / 1024 / 1024).toFixed(2)} MB)`);
160
+ return bundlePath;
161
+ }
162
+ catch (error) {
163
+ // Cleanup on error
164
+ for (const p of [tempPath, archivePath, bundlePath]) {
165
+ if (fs.existsSync(p)) {
166
+ try {
167
+ fs.rmSync(p, { recursive: true });
168
+ }
169
+ catch {
170
+ // Ignore cleanup errors
171
+ }
172
+ }
173
+ }
174
+ const errorMessage = error instanceof Error ? error.message : String(error);
175
+ this.bundles.set(bundleId, {
176
+ bundleId,
177
+ bundleUrl,
178
+ status: 'error',
179
+ error: errorMessage,
180
+ });
181
+ this.downloadStats.active--;
182
+ this.downloadStats.failed++;
183
+ throw new BundleManagerError(`Failed to download bundle ${bundleId}: ${errorMessage}`, 'DOWNLOAD_FAILED', bundleId);
184
+ }
185
+ }
186
+ /**
187
+ * Extract TAR.GZ archive to destination directory
188
+ */
189
+ async extractTarGz(archivePath, destPath) {
190
+ return new Promise((resolve, reject) => {
191
+ const extractStream = extract();
192
+ const entries = [];
193
+ extractStream.on('entry', (header, stream, next) => {
194
+ let filePath = path.join(destPath, header.name);
195
+ // Handle case where archive has a single root directory
196
+ // (common with GitHub releases: bundle-v1.0.0/index.html)
197
+ entries.push(header.name);
198
+ if (header.type === 'directory') {
199
+ fs.mkdirSync(filePath, { recursive: true });
200
+ stream.resume();
201
+ next();
202
+ }
203
+ else if (header.type === 'file') {
204
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
205
+ const writeStream = fs.createWriteStream(filePath);
206
+ stream.pipe(writeStream);
207
+ stream.on('end', () => {
208
+ writeStream.end();
209
+ next();
210
+ });
211
+ stream.on('error', reject);
212
+ writeStream.on('error', reject);
213
+ }
214
+ else {
215
+ // Skip other types (symlinks, etc.)
216
+ stream.resume();
217
+ next();
218
+ }
219
+ });
220
+ extractStream.on('finish', () => {
221
+ // Check if all files are in a subdirectory
222
+ // If so, move them up one level
223
+ const subdirs = fs.readdirSync(destPath);
224
+ if (subdirs.length === 1) {
225
+ const subdir = path.join(destPath, subdirs[0]);
226
+ if (fs.statSync(subdir).isDirectory()) {
227
+ // Check if index.html is in subdirectory
228
+ if (fs.existsSync(path.join(subdir, 'index.html'))) {
229
+ // Move all files up
230
+ const files = fs.readdirSync(subdir);
231
+ for (const file of files) {
232
+ fs.renameSync(path.join(subdir, file), path.join(destPath, file));
233
+ }
234
+ fs.rmdirSync(subdir);
235
+ }
236
+ }
237
+ }
238
+ resolve();
239
+ });
240
+ extractStream.on('error', reject);
241
+ const gunzip = createGunzip();
242
+ gunzip.on('error', reject);
243
+ const readStream = fs.createReadStream(archivePath);
244
+ readStream.on('error', reject);
245
+ readStream.pipe(gunzip).pipe(extractStream);
246
+ });
247
+ }
248
+ /**
249
+ * Ensure cache has enough space by evicting old bundles
250
+ */
251
+ async ensureCacheSpace(requiredBytes) {
252
+ const stats = this.getCacheStats();
253
+ const availableBytes = this.maxCacheSize - stats.used;
254
+ if (availableBytes >= requiredBytes) {
255
+ return;
256
+ }
257
+ const bytesToFree = requiredBytes - availableBytes;
258
+ let freedBytes = 0;
259
+ // Get bundles sorted by last accessed time (oldest first)
260
+ const evictionCandidates = Array.from(this.bundles.entries())
261
+ .filter(([id, info]) => {
262
+ return (info.status === 'ready' &&
263
+ !this.bundlesInUse.has(id) &&
264
+ !this.downloadPromises.has(id));
265
+ })
266
+ .sort(([, a], [, b]) => {
267
+ const aTime = a.lastAccessedAt?.getTime() || 0;
268
+ const bTime = b.lastAccessedAt?.getTime() || 0;
269
+ return aTime - bTime;
270
+ });
271
+ for (const [bundleId, info] of evictionCandidates) {
272
+ if (freedBytes >= bytesToFree) {
273
+ break;
274
+ }
275
+ console.log(`[BundleManager] Evicting bundle ${bundleId} to free space`);
276
+ this.removeBundle(bundleId);
277
+ freedBytes += info.size || 0;
278
+ }
279
+ if (freedBytes < bytesToFree) {
280
+ throw new BundleManagerError(`Unable to free enough cache space (needed: ${bytesToFree}, freed: ${freedBytes})`, 'CACHE_FULL');
281
+ }
282
+ }
283
+ /**
284
+ * Load existing bundles from disk
285
+ */
286
+ loadCachedBundles() {
287
+ if (!fs.existsSync(this.bundlesDir)) {
288
+ return;
289
+ }
290
+ const entries = fs.readdirSync(this.bundlesDir, { withFileTypes: true });
291
+ for (const entry of entries) {
292
+ if (!entry.isDirectory()) {
293
+ continue;
294
+ }
295
+ // Skip temp directories
296
+ if (entry.name.endsWith('.downloading') || entry.name.endsWith('.tar.gz')) {
297
+ // Clean up orphaned temp files
298
+ try {
299
+ fs.rmSync(path.join(this.bundlesDir, entry.name), { recursive: true });
300
+ }
301
+ catch {
302
+ // Ignore
303
+ }
304
+ continue;
305
+ }
306
+ const bundlePath = path.join(this.bundlesDir, entry.name);
307
+ const indexPath = path.join(bundlePath, 'index.html');
308
+ if (fs.existsSync(indexPath)) {
309
+ const stats = fs.statSync(bundlePath);
310
+ const size = this.getDirectorySize(bundlePath);
311
+ this.bundles.set(entry.name, {
312
+ bundleId: entry.name,
313
+ status: 'ready',
314
+ size,
315
+ cachedAt: stats.mtime,
316
+ lastAccessedAt: stats.mtime,
317
+ });
318
+ }
319
+ }
320
+ console.log(`[BundleManager] Loaded ${this.bundles.size} cached bundles`);
321
+ }
322
+ /**
323
+ * Get directory size recursively
324
+ */
325
+ getDirectorySize(dirPath) {
326
+ let size = 0;
327
+ try {
328
+ const files = fs.readdirSync(dirPath);
329
+ for (const file of files) {
330
+ const filePath = path.join(dirPath, file);
331
+ const stats = fs.statSync(filePath);
332
+ if (stats.isDirectory()) {
333
+ size += this.getDirectorySize(filePath);
334
+ }
335
+ else {
336
+ size += stats.size;
337
+ }
338
+ }
339
+ }
340
+ catch {
341
+ // Ignore errors
342
+ }
343
+ return size;
344
+ }
345
+ /**
346
+ * List all bundles
347
+ */
348
+ listBundles() {
349
+ return Array.from(this.bundles.values());
350
+ }
351
+ /**
352
+ * Get bundle info
353
+ */
354
+ getBundleInfo(bundleId) {
355
+ return this.bundles.get(bundleId);
356
+ }
357
+ /**
358
+ * Remove bundle from cache
359
+ */
360
+ removeBundle(bundleId) {
361
+ const bundlePath = path.join(this.bundlesDir, bundleId);
362
+ if (fs.existsSync(bundlePath)) {
363
+ try {
364
+ fs.rmSync(bundlePath, { recursive: true });
365
+ }
366
+ catch (error) {
367
+ console.error(`[BundleManager] Failed to remove bundle ${bundleId}:`, error);
368
+ }
369
+ }
370
+ this.bundles.delete(bundleId);
371
+ }
372
+ /**
373
+ * Get cache statistics
374
+ */
375
+ getCacheStats() {
376
+ let used = 0;
377
+ let count = 0;
378
+ for (const info of this.bundles.values()) {
379
+ if (info.status === 'ready' && info.size) {
380
+ used += info.size;
381
+ count++;
382
+ }
383
+ }
384
+ return {
385
+ used,
386
+ max: this.maxCacheSize,
387
+ usedPercent: Math.round((used / this.maxCacheSize) * 100),
388
+ bundleCount: count,
389
+ };
390
+ }
391
+ /**
392
+ * Get download statistics
393
+ */
394
+ getDownloadStats() {
395
+ return { ...this.downloadStats };
396
+ }
397
+ /**
398
+ * Get bundles directory path
399
+ */
400
+ getBundlesDir() {
401
+ return this.bundlesDir;
402
+ }
403
+ }
404
+ /**
405
+ * Create a bundle manager instance
406
+ */
407
+ export function createBundleManager(config) {
408
+ return new BundleManager(config);
409
+ }
410
+ //# sourceMappingURL=BundleManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BundleManager.js","sourceRoot":"","sources":["../../src/services/BundleManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * OSS Client
3
+ *
4
+ * Handles authenticated downloads from Alibaba Cloud OSS using STS credentials
5
+ * obtained from the BFF API.
6
+ */
7
+ import type { STSCredentials, OSSClientConfig } from './types.js';
8
+ /**
9
+ * Error thrown by OSS client operations
10
+ */
11
+ export declare class OSSClientError extends Error {
12
+ readonly code: string;
13
+ readonly statusCode?: number | undefined;
14
+ constructor(message: string, code: string, statusCode?: number | undefined);
15
+ }
16
+ /**
17
+ * OSS Client for downloading bundles with STS authentication
18
+ */
19
+ export declare class OSSClient {
20
+ private readonly bffBaseUrl;
21
+ private readonly serviceToken?;
22
+ private readonly timeout;
23
+ private cachedCredentials;
24
+ private credentialsExpiresAt;
25
+ constructor(config: OSSClientConfig);
26
+ /**
27
+ * Get STS credentials from BFF API
28
+ * Caches credentials until they expire (with 5 minute buffer)
29
+ *
30
+ * Uses the /studio/service/sts endpoint which requires BFF_SERVICE_TOKEN
31
+ * (set to SUPABASE_JWT_SECRET) for service-to-service authentication.
32
+ */
33
+ getSTSCredentials(): Promise<STSCredentials>;
34
+ /**
35
+ * Download file from OSS URL with STS authentication
36
+ *
37
+ * @param url - OSS URL to download from
38
+ * @param destPath - Local destination path
39
+ * @param onProgress - Optional progress callback (0-100)
40
+ */
41
+ downloadFile(url: string, destPath: string, onProgress?: (percent: number) => void): Promise<void>;
42
+ /**
43
+ * Clear cached credentials
44
+ */
45
+ clearCredentialsCache(): void;
46
+ }
47
+ /**
48
+ * Create an OSS client instance
49
+ */
50
+ export declare function createOSSClient(config: OSSClientConfig): OSSClient;
51
+ //# sourceMappingURL=OSSClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OSSClient.d.ts","sourceRoot":"","sources":["../../src/services/OSSClient.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElE;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;aAGjB,IAAI,EAAE,MAAM;aACZ,UAAU,CAAC,EAAE,MAAM;gBAFnC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,YAAA;CAK1C;AAED;;GAEG;AACH,qBAAa,SAAS;IAClB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,oBAAoB,CAAqB;gBAErC,MAAM,EAAE,eAAe;IAMnC;;;;;;OAMG;IACG,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC;IA8GlD;;;;;;OAMG;IACG,YAAY,CACd,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACvC,OAAO,CAAC,IAAI,CAAC;IAoGhB;;OAEG;IACH,qBAAqB,IAAI,IAAI;CAIhC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAElE"}