From 4e90b4561a6fcee8bb5335bccf86799a722cb406 Mon Sep 17 00:00:00 2001 From: shivammittal274 <56757235+shivammittal274@users.noreply.github.com> Date: Sat, 21 Mar 2026 22:12:52 +0530 Subject: [PATCH] feat(eval): weekly eval pipeline with R2 uploads and trend dashboard (#516) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(eval): weekly eval pipeline with R2 uploads and trend dashboard Add infrastructure for running weekly evaluations and tracking score trends over time: - Auto-generated output dirs: results/{config-name}/{timestamp}/ Each eval run gets its own timestamped folder, nothing is overwritten. - upload-run.ts: uploads eval results to Cloudflare R2. Supports uploading a specific run or all un-uploaded runs for a config. - weekly-report.ts: generates an interactive HTML dashboard from R2 data. Config dropdown, trend chart with hover tooltips, searchable runs table. Groups runs by config name. - viewer.html: client-facing 3-column run viewer (task list, screenshots with autoplay, agent stream with messages.jsonl). Shows performance grader axis breakdown with per-axis scores. - browseros-agent-weekly.json: weekly benchmark config (kimi-k2p5, webbench-2of4-50, 10 workers, performance grader, headless). - eval-weekly.yml: GitHub Actions workflow with cron (Saturday 6am) and manual trigger. Runs on self-hosted Mac Studio runner. Concurrency group ensures only one eval runs at a time. - Dashboard updates: load previous runs, messages.jsonl viewer, grade badges show percentages, async stream loading. - Grader updates: timeout 30min, max turns 100, DOM content verification guidance for performance grader. * fix(eval): address Greptile review — injection, nested dirs, escaping - Fix script injection in eval-weekly.yml: pass github.event.inputs through env var instead of interpolating into shell - Fix /api/runs to enumerate nested results/{config}/{timestamp}/ dirs - Fix /api/load-run to allow single-slash run names (config/timestamp) - Add HTML escaping for R2-sourced values in weekly-report.ts - Escape axis names in viewer.html renderAxesBreakdown * fix(eval): fix biome lint — non-null assertion, template literals * fix(eval): fix biome errors — replace var with let, fix inner function declaration * fix(eval): address Greptile P2 issues - isRunDir: check all subdirs for metadata.json, not just first 3 - eval-runner: guard configPath for dashboard-driven runs (fallback to 'eval') - load-run: default unknown termination_reason to 'failed' not 'completed' * feat(eval): make BROWSEROS_BINARY configurable via env var --- .github/workflows/eval-weekly.yml | 82 ++ .../eval/configs/browseros-agent-weekly.json | 26 + .../browseros-agent/apps/eval/package.json | 3 +- .../apps/eval/scripts/upload-run.ts | 349 +++++ .../apps/eval/scripts/weekly-report.ts | 590 ++++++++ .../apps/eval/src/constants.ts | 2 +- .../apps/eval/src/dashboard/index.html | 93 +- .../apps/eval/src/dashboard/server.ts | 129 +- .../apps/eval/src/dashboard/viewer.html | 1270 +++++++++++++++++ .../apps/eval/src/graders/performance/axes.ts | 11 +- .../graders/performance/performance-grader.ts | 4 +- .../eval/src/runner/browseros-app-manager.ts | 4 +- .../apps/eval/src/runner/eval-runner.ts | 31 +- packages/browseros-agent/bun.lock | 185 ++- 14 files changed, 2755 insertions(+), 24 deletions(-) create mode 100644 .github/workflows/eval-weekly.yml create mode 100644 packages/browseros-agent/apps/eval/configs/browseros-agent-weekly.json create mode 100644 packages/browseros-agent/apps/eval/scripts/upload-run.ts create mode 100644 packages/browseros-agent/apps/eval/scripts/weekly-report.ts create mode 100644 packages/browseros-agent/apps/eval/src/dashboard/viewer.html diff --git a/.github/workflows/eval-weekly.yml b/.github/workflows/eval-weekly.yml new file mode 100644 index 000000000..4271cd3b4 --- /dev/null +++ b/.github/workflows/eval-weekly.yml @@ -0,0 +1,82 @@ +name: Weekly Eval + +on: + schedule: + # Every Saturday at 06:00 UTC + - cron: '0 6 * * 6' + workflow_dispatch: + inputs: + config: + description: 'Eval config file (relative to apps/eval/)' + required: false + default: 'configs/browseros-agent-weekly.json' + +concurrency: + group: eval-runner + cancel-in-progress: false + +permissions: + contents: read + +jobs: + eval: + runs-on: self-hosted + timeout-minutes: 360 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + working-directory: packages/browseros-agent + run: bun install + + - name: Run eval + working-directory: packages/browseros-agent/apps/eval + env: + FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_API_KEY }} + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + BROWSEROS_BINARY: ${{ secrets.BROWSEROS_BINARY }} + EVAL_CONFIG: ${{ github.event.inputs.config || 'configs/browseros-agent-weekly.json' }} + run: | + echo "Running eval with config: $EVAL_CONFIG" + bun run src/index.ts -c "$EVAL_CONFIG" + + - name: Upload runs to R2 + if: success() + working-directory: packages/browseros-agent/apps/eval + env: + EVAL_R2_ACCOUNT_ID: ${{ secrets.EVAL_R2_ACCOUNT_ID }} + EVAL_R2_ACCESS_KEY_ID: ${{ secrets.EVAL_R2_ACCESS_KEY_ID }} + EVAL_R2_SECRET_ACCESS_KEY: ${{ secrets.EVAL_R2_SECRET_ACCESS_KEY }} + EVAL_R2_BUCKET: ${{ secrets.EVAL_R2_BUCKET }} + EVAL_R2_CDN_BASE_URL: ${{ secrets.EVAL_R2_CDN_BASE_URL }} + EVAL_CONFIG: ${{ github.event.inputs.config || 'configs/browseros-agent-weekly.json' }} + run: | + CONFIG_NAME=$(basename "$EVAL_CONFIG" .json) + bun scripts/upload-run.ts "results/$CONFIG_NAME" + + - name: Generate trend report + if: success() + working-directory: packages/browseros-agent + env: + EVAL_R2_ACCOUNT_ID: ${{ secrets.EVAL_R2_ACCOUNT_ID }} + EVAL_R2_ACCESS_KEY_ID: ${{ secrets.EVAL_R2_ACCESS_KEY_ID }} + EVAL_R2_SECRET_ACCESS_KEY: ${{ secrets.EVAL_R2_SECRET_ACCESS_KEY }} + EVAL_R2_BUCKET: ${{ secrets.EVAL_R2_BUCKET }} + EVAL_R2_CDN_BASE_URL: ${{ secrets.EVAL_R2_CDN_BASE_URL }} + run: bun apps/eval/scripts/weekly-report.ts /tmp/eval-report.html + + - name: Upload report as artifact + if: success() + uses: actions/upload-artifact@v4 + with: + name: eval-report-${{ github.run_id }} + path: /tmp/eval-report.html diff --git a/packages/browseros-agent/apps/eval/configs/browseros-agent-weekly.json b/packages/browseros-agent/apps/eval/configs/browseros-agent-weekly.json new file mode 100644 index 000000000..9e605e6a2 --- /dev/null +++ b/packages/browseros-agent/apps/eval/configs/browseros-agent-weekly.json @@ -0,0 +1,26 @@ +{ + "agent": { + "type": "single", + "provider": "openai-compatible", + "model": "accounts/fireworks/models/kimi-k2p5", + "apiKey": "FIREWORKS_API_KEY", + "baseUrl": "https://api.fireworks.ai/inference/v1", + "supportsImages": true + }, + "dataset": "../data/webbench-2of4-50.jsonl", + "num_workers": 10, + "restart_server_per_task": true, + "browseros": { + "server_url": "http://127.0.0.1:9110", + "base_cdp_port": 9010, + "base_server_port": 9110, + "base_extension_port": 9310, + "load_extensions": false, + "headless": true + }, + "graders": ["performance_grader"], + "grader_api_key_env": "OPENROUTER_API_KEY", + "grader_base_url": "https://openrouter.ai/api/v1", + "grader_model": "openai/gpt-4.1", + "timeout_ms": 1800000 +} diff --git a/packages/browseros-agent/apps/eval/package.json b/packages/browseros-agent/apps/eval/package.json index 161370682..b7abbfe34 100644 --- a/packages/browseros-agent/apps/eval/package.json +++ b/packages/browseros-agent/apps/eval/package.json @@ -9,12 +9,13 @@ }, "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.2.63", + "@aws-sdk/client-s3": "^3.1014.0", "@browseros/server": "workspace:*", "@browseros/shared": "workspace:*", "@google/gemini-cli-core": "^0.16.0", - "ai": "^6.0.94", "@google/genai": "1.30.0", "@modelcontextprotocol/sdk": "^1.25.2", + "ai": "^6.0.94", "hono": "^4.6.0", "openai": "^4.0.0", "sharp": "^0.34.5", diff --git a/packages/browseros-agent/apps/eval/scripts/upload-run.ts b/packages/browseros-agent/apps/eval/scripts/upload-run.ts new file mode 100644 index 000000000..f641eda32 --- /dev/null +++ b/packages/browseros-agent/apps/eval/scripts/upload-run.ts @@ -0,0 +1,349 @@ +/** + * Upload eval runs to R2. + * + * Two modes: + * bun scripts/upload-run.ts results/browseros-agent-weekly/2026-03-21-1730 + * → uploads that specific run + * + * bun scripts/upload-run.ts results/browseros-agent-weekly + * → finds all timestamped subfolders, uploads any not yet in R2 + * + * Env vars: EVAL_R2_ACCOUNT_ID, EVAL_R2_ACCESS_KEY_ID, EVAL_R2_SECRET_ACCESS_KEY + * EVAL_R2_BUCKET (default: browseros-eval) + * EVAL_R2_CDN_BASE_URL (default: https://eval.browseros.com) + */ + +import { readdir, readFile, stat } from 'node:fs/promises' +import { basename, dirname, extname, join } from 'node:path' +import { + GetObjectCommand, + PutObjectCommand, + S3Client, +} from '@aws-sdk/client-s3' + +const CONCURRENCY = 20 + +const CONTENT_TYPES: Record = { + '.json': 'application/json', + '.jsonl': 'application/x-ndjson', + '.png': 'image/png', +} + +interface R2Config { + accountId: string + accessKeyId: string + secretAccessKey: string + bucket: string + cdnBaseUrl: string +} + +function loadConfig(): R2Config { + const accountId = process.env.EVAL_R2_ACCOUNT_ID + const accessKeyId = process.env.EVAL_R2_ACCESS_KEY_ID + const secretAccessKey = process.env.EVAL_R2_SECRET_ACCESS_KEY + + if (!accountId || !accessKeyId || !secretAccessKey) { + console.error( + 'Missing required env vars: EVAL_R2_ACCOUNT_ID, EVAL_R2_ACCESS_KEY_ID, EVAL_R2_SECRET_ACCESS_KEY', + ) + process.exit(1) + } + + return { + accountId, + accessKeyId, + secretAccessKey, + bucket: process.env.EVAL_R2_BUCKET || 'browseros-eval', + cdnBaseUrl: ( + process.env.EVAL_R2_CDN_BASE_URL || 'https://eval.browseros.com' + ).replace(/\/+$/, ''), + } +} + +function createClient(config: R2Config): S3Client { + return new S3Client({ + region: 'auto', + endpoint: `https://${config.accountId}.r2.cloudflarestorage.com`, + credentials: { + accessKeyId: config.accessKeyId, + secretAccessKey: config.secretAccessKey, + }, + }) +} + +async function upload( + client: S3Client, + bucket: string, + key: string, + body: Buffer, + contentType: string, +) { + await client.send( + new PutObjectCommand({ + Bucket: bucket, + Key: key, + Body: body, + ContentType: contentType, + }), + ) +} + +async function collectFiles(dir: string): Promise { + const files: string[] = [] + const entries = await readdir(dir, { withFileTypes: true }) + for (const entry of entries) { + const full = join(dir, entry.name) + if (entry.isDirectory()) { + files.push(...(await collectFiles(full))) + } else { + files.push(full) + } + } + return files +} + +async function runPool( + items: T[], + concurrency: number, + fn: (item: T) => Promise, +) { + let i = 0 + const workers = Array.from({ length: concurrency }, async () => { + while (i < items.length) { + const idx = i++ + await fn(items[idx]) + } + }) + await Promise.all(workers) +} + +// Check if a run has already been uploaded to R2 +async function isUploaded( + client: S3Client, + bucket: string, + runId: string, +): Promise { + try { + await client.send( + new GetObjectCommand({ + Bucket: bucket, + Key: `runs/${runId}/manifest.json`, + }), + ) + return true + } catch { + return false + } +} + +// Detect if a directory is a run dir (has task subdirs with metadata.json) +// vs a config dir (has timestamped subdirs like 2026-03-21-1730/) +async function isRunDir(dir: string): Promise { + const entries = await readdir(dir, { withFileTypes: true }) + const subdirs = entries.filter((e) => e.isDirectory()) + for (const subdir of subdirs) { + const metaPath = join(dir, subdir.name, 'metadata.json') + const metaStat = await stat(metaPath).catch(() => null) + if (metaStat?.isFile()) return true + } + return false +} + +async function uploadSingleRun( + runDir: string, + runId: string, + r2Config: R2Config, + client: S3Client, +): Promise { + const taskDirs = await readdir(runDir, { withFileTypes: true }) + const taskEntries = taskDirs.filter((d) => d.isDirectory()) + + if (taskEntries.length === 0) { + console.warn(` No task subdirectories in ${runId}, skipping`) + return + } + + const manifestTasks: Record[] = [] + const jobs: { key: string; filePath: string; contentType: string }[] = [] + + // Extract agent config from first task + let agentConfig: Record | undefined + let dataset: string | undefined + + for (const taskDir of taskEntries) { + const taskId = taskDir.name + const taskPath = join(runDir, taskId) + const metaPath = join(taskPath, 'metadata.json') + + let meta: Record = {} + try { + meta = JSON.parse(await readFile(metaPath, 'utf-8')) + } catch { + continue + } + + if (!agentConfig && meta.agent_config) + agentConfig = meta.agent_config as Record + if (!dataset && meta.dataset) dataset = meta.dataset as string + + const files = await collectFiles(taskPath) + let screenshotCount = 0 + + for (const file of files) { + const relative = file.slice(taskPath.length + 1) + const ext = extname(file) + if (relative.startsWith('screenshots/') && ext === '.png') + screenshotCount++ + + jobs.push({ + key: `runs/${runId}/${taskId}/${relative}`, + filePath: file, + contentType: CONTENT_TYPES[ext] || 'application/octet-stream', + }) + } + + manifestTasks.push({ + queryId: meta.query_id || taskId, + query: meta.query || '', + startUrl: meta.start_url || '', + status: + meta.termination_reason === 'completed' + ? 'completed' + : meta.termination_reason || 'unknown', + durationMs: meta.total_duration_ms || 0, + screenshotCount: (meta.screenshot_count as number) || screenshotCount, + graderResults: meta.grader_results || {}, + }) + } + + if (manifestTasks.length === 0) { + console.warn(` No completed tasks in ${runId}, skipping`) + return + } + + console.log( + ` Uploading ${jobs.length} files across ${manifestTasks.length} tasks...`, + ) + + let uploaded = 0 + await runPool(jobs, CONCURRENCY, async (job) => { + const body = await readFile(job.filePath) + await upload(client, r2Config.bucket, job.key, body, job.contentType) + uploaded++ + if (uploaded % 50 === 0 || uploaded === jobs.length) { + console.log(` ${uploaded}/${jobs.length}`) + } + }) + + // Read summary.json if it exists + let summaryData: Record | undefined + try { + summaryData = JSON.parse( + await readFile(join(runDir, 'summary.json'), 'utf-8'), + ) + } catch {} + + // Upload manifest + const manifest = { + runId, + uploadedAt: new Date().toISOString(), + agentConfig, + dataset, + summary: summaryData + ? { + passRate: summaryData.passRate, + avgDurationMs: summaryData.avgDurationMs, + } + : undefined, + tasks: manifestTasks, + } + const manifestBody = Buffer.from(JSON.stringify(manifest, null, 2)) + await upload( + client, + r2Config.bucket, + `runs/${runId}/manifest.json`, + manifestBody, + 'application/json', + ) + + // Upload viewer.html to bucket root + const viewerPath = join( + import.meta.dir, + '..', + 'src', + 'dashboard', + 'viewer.html', + ) + const viewerBody = await readFile(viewerPath) + await upload(client, r2Config.bucket, 'viewer.html', viewerBody, 'text/html') + + console.log(` Uploaded ${uploaded + 2} files`) + console.log(` ${r2Config.cdnBaseUrl}/viewer.html?run=${runId}`) +} + +async function main() { + const inputDir = process.argv[2] + if (!inputDir) { + console.error( + 'Usage:\n' + + ' bun scripts/upload-run.ts results/config-name/2026-03-21-1730 (specific run)\n' + + ' bun scripts/upload-run.ts results/config-name (all un-uploaded runs)', + ) + process.exit(1) + } + + const dirStat = await stat(inputDir).catch(() => null) + if (!dirStat?.isDirectory()) { + console.error(`Not a directory: ${inputDir}`) + process.exit(1) + } + + const r2Config = loadConfig() + const client = createClient(r2Config) + + if (await isRunDir(inputDir)) { + // Single run: results/config-name/2026-03-21-1730 + const timestamp = basename(inputDir) + const configName = basename(dirname(inputDir)) + const runId = `${configName}-${timestamp}` + console.log(`Uploading run: ${runId}`) + await uploadSingleRun(inputDir, runId, r2Config, client) + } else { + // Config dir: results/config-name/ — upload all un-uploaded runs + const configName = basename(inputDir) + const entries = await readdir(inputDir, { withFileTypes: true }) + const runDirs = entries + .filter((e) => e.isDirectory()) + .map((e) => e.name) + .sort() + + if (runDirs.length === 0) { + console.error('No run subdirectories found') + process.exit(1) + } + + console.log( + `Found ${runDirs.length} runs for config "${configName}", checking R2...`, + ) + + let uploadedCount = 0 + for (const dir of runDirs) { + const runId = `${configName}-${dir}` + const alreadyUploaded = await isUploaded(client, r2Config.bucket, runId) + if (alreadyUploaded) { + console.log(` ${runId}: already uploaded, skipping`) + continue + } + + console.log(` ${runId}: uploading...`) + await uploadSingleRun(join(inputDir, dir), runId, r2Config, client) + uploadedCount++ + } + + console.log( + `\nDone. Uploaded ${uploadedCount} new run(s), ${runDirs.length - uploadedCount} already in R2.`, + ) + } +} + +main() diff --git a/packages/browseros-agent/apps/eval/scripts/weekly-report.ts b/packages/browseros-agent/apps/eval/scripts/weekly-report.ts new file mode 100644 index 000000000..97b196989 --- /dev/null +++ b/packages/browseros-agent/apps/eval/scripts/weekly-report.ts @@ -0,0 +1,590 @@ +/** + * Weekly Report Generator + * + * Reads all uploaded eval runs from R2, builds cumulative score history, + * and generates an HTML dashboard with: + * - Config selector dropdown (groups runs by config/runId pattern) + * - Config details card (architecture, model, dataset, grader) + * - Interactive trend chart (filtered by selected config) + * - Stat cards (latest, trend, best, duration) + * - Searchable table of all runs + * + * Usage: + * bun apps/eval/scripts/weekly-report.ts [local-output-path] + * + * Env vars required: + * EVAL_R2_ACCOUNT_ID, EVAL_R2_ACCESS_KEY_ID, EVAL_R2_SECRET_ACCESS_KEY + * EVAL_R2_BUCKET (default: browseros-eval) + */ + +import { writeFile } from 'node:fs/promises' +import { + GetObjectCommand, + ListObjectsV2Command, + PutObjectCommand, + S3Client, +} from '@aws-sdk/client-s3' + +interface ManifestTask { + queryId: string + query: string + status: string + durationMs: number + screenshotCount: number + graderResults: Record +} + +interface Manifest { + runId: string + uploadedAt: string + agentConfig?: { type?: string; model?: string } + dataset?: string + summary?: { passRate?: number; avgDurationMs?: number } + tasks: ManifestTask[] +} + +interface RunSummary { + runId: string + configName: string + date: string + passRate: number + total: number + completed: number + failed: number + timeout: number + avgDurationMs: number + model: string + dataset: string + agentType: string +} + +const PASS_FAIL_GRADER_ORDER = [ + 'performance_grader', + 'webvoyager_grader', + 'fara_combined', + 'fara_grader', +] + +function requireEnv(name: string): string { + const value = process.env[name] + if (!value) { + console.error(`Missing required env var: ${name}`) + process.exit(1) + } + return value +} + +const accountId = requireEnv('EVAL_R2_ACCOUNT_ID') +const accessKeyId = requireEnv('EVAL_R2_ACCESS_KEY_ID') +const secretAccessKey = requireEnv('EVAL_R2_SECRET_ACCESS_KEY') +const bucket = process.env.EVAL_R2_BUCKET || 'browseros-eval' + +const client = new S3Client({ + region: 'auto', + endpoint: `https://${accountId}.r2.cloudflarestorage.com`, + credentials: { accessKeyId, secretAccessKey }, +}) + +// Step 1: List all manifest.json files in runs/ +console.log('Scanning R2 for eval runs...') + +const manifests: Manifest[] = [] +let continuationToken: string | undefined + +do { + const listRes = await client.send( + new ListObjectsV2Command({ + Bucket: bucket, + Prefix: 'runs/', + ContinuationToken: continuationToken, + }), + ) + + const manifestKeys = + listRes.Contents?.filter((obj) => obj.Key?.endsWith('/manifest.json')).map( + (obj) => obj.Key as string, + ) ?? [] + + for (const key of manifestKeys) { + try { + const res = await client.send( + new GetObjectCommand({ Bucket: bucket, Key: key }), + ) + const body = await res.Body?.transformToString() + if (body) manifests.push(JSON.parse(body)) + } catch { + console.warn(` Failed to read ${key}, skipping`) + } + } + + continuationToken = listRes.NextContinuationToken +} while (continuationToken) + +console.log(`Found ${manifests.length} runs`) + +if (manifests.length === 0) { + console.log('No runs found. Nothing to report.') + process.exit(0) +} + +// Step 2: Build run summaries +const runs: RunSummary[] = manifests + .map((m) => { + const total = m.tasks.length + const completed = m.tasks.filter((t) => t.status === 'completed').length + const failed = m.tasks.filter((t) => t.status === 'failed').length + const timeout = m.tasks.filter((t) => t.status === 'timeout').length + + let graded = 0 + let passed = 0 + for (const task of m.tasks) { + if (!task.graderResults) continue + for (const name of PASS_FAIL_GRADER_ORDER) { + if (task.graderResults[name]) { + graded++ + if (task.graderResults[name].pass) passed++ + break + } + } + } + + const passRate = graded > 0 ? passed / graded : 0 + const durations = m.tasks + .filter((t) => t.durationMs > 0) + .map((t) => t.durationMs) + const avgDurationMs = + durations.length > 0 + ? durations.reduce((a, b) => a + b, 0) / durations.length + : 0 + + const date = m.uploadedAt + ? m.uploadedAt.split('T')[0] + : m.runId.slice(0, 10) + + const model = m.agentConfig?.model || 'unknown' + const dataset = m.dataset || m.runId + const agentType = m.agentConfig?.type || 'unknown' + + const configName = extractConfigName(m.runId) + return { + runId: m.runId, + configName, + date, + passRate, + total, + completed, + failed, + timeout, + avgDurationMs, + model, + dataset, + agentType, + } + }) + .sort((a, b) => a.date.localeCompare(b.date)) + +// Step 3: Identify unique config groups +// runId can be "ci-weekly" (old) or "ci-weekly-2026-03-21-1730" (timestamped) +// Extract config name by stripping the date-time suffix pattern +function escHtml(s: string): string { + return s + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') +} + +function extractConfigName(runId: string): string { + // "browseros-agent-weekly-2026-03-21-1730" → "browseros-agent-weekly" + // "ci-weekly" → "ci-weekly" (no timestamp, old format) + return runId.replace(/-\d{4}-\d{2}-\d{2}-\d{4}$/, '') +} + +const configGroups = [...new Set(runs.map((r) => r.configName))] +const defaultConfig = configGroups.includes('ci-weekly') + ? 'ci-weekly' + : configGroups[0] + +// Step 4: Generate HTML report +const html = ` + + + + + BrowserOS Eval Dashboard + + + + + + + +
+ + +
+ + +
+ + +
+ + +
+ +
+
+
+
+
+
+ + +
+

All Runs

+ +
+ + + + + + + + + + + + + + + + + ${runs + .slice() + .reverse() + .map((r) => { + const viewerUrl = `viewer.html?run=${encodeURIComponent(r.runId)}` + const passed = Math.round(r.passRate * r.total) + const archLabel = + r.agentType === 'orchestrator-executor' + ? 'Orch-Exec' + : r.agentType === 'single' + ? 'Tool Loop' + : r.agentType === 'gemini-computer-use' + ? 'Gemini CU' + : r.agentType || '—' + return ` + + + + + + + + + + + ` + }) + .join('\n')} + +
DateConfigModelDatasetArchitecturePass RateTasksTimeoutAvg DurationView
${escHtml(r.date)}${escHtml(r.runId)}${escHtml(r.model)}${escHtml(r.dataset)}${escHtml(archLabel)}${(r.passRate * 100).toFixed(1)}% (${passed}/${r.total})${r.total}${r.timeout}${(r.avgDurationMs / 1000).toFixed(0)}sView →
+ + + + +` + +// Step 5: Save locally and upload to R2 +const localPath = process.argv[2] || '/tmp/eval-report.html' +await writeFile(localPath, html) +console.log(`Report saved locally: ${localPath}`) + +await client.send( + new PutObjectCommand({ + Bucket: bucket, + Key: 'report.html', + Body: html, + ContentType: 'text/html', + CacheControl: 'public, max-age=300', + }), +) + +const cdnBaseUrl = ( + process.env.EVAL_R2_CDN_BASE_URL || 'https://eval.browseros.com' +).replace(/\/+$/, '') + +console.log(`Report uploaded to R2: ${bucket}/report.html`) +console.log(` View at: ${cdnBaseUrl}/report.html`) + +// Print summary +console.log('\nScore trend:') +for (const run of runs.slice(-10)) { + const bar = '\u2588'.repeat(Math.round(run.passRate * 20)) + const pct = (run.passRate * 100).toFixed(0).padStart(3) + console.log(` ${run.date} ${pct}% ${bar}`) +} diff --git a/packages/browseros-agent/apps/eval/src/constants.ts b/packages/browseros-agent/apps/eval/src/constants.ts index 285d7ef2a..1db4d1d1b 100644 --- a/packages/browseros-agent/apps/eval/src/constants.ts +++ b/packages/browseros-agent/apps/eval/src/constants.ts @@ -2,7 +2,7 @@ * Eval-specific constants shared across agents, runners, and capture modules. */ -export const DEFAULT_TIMEOUT_MS = 15 * 60 * 1000 // 15 minutes +export const DEFAULT_TIMEOUT_MS = 30 * 60 * 1000 // 30 minutes export const SCREENSHOT_TIMEOUT_MS = 65_000 // 65s — ensures we get extension's error (60s) export const MAX_ACTIONS_PER_DELEGATION = 15 export const CLADO_REQUEST_TIMEOUT_MS = 120_000 diff --git a/packages/browseros-agent/apps/eval/src/dashboard/index.html b/packages/browseros-agent/apps/eval/src/dashboard/index.html index d0e65d95b..4b120f5e8 100644 --- a/packages/browseros-agent/apps/eval/src/dashboard/index.html +++ b/packages/browseros-agent/apps/eval/src/dashboard/index.html @@ -354,7 +354,7 @@
- +
@@ -454,6 +454,17 @@
+ +
+
+ + +
+ +
+ @@ -529,6 +540,7 @@ async function init() { // Load saved configs into dropdown loadConfigList(); + loadRunList(); if (mode.configMode) { // Config mode — show panel expanded @@ -656,6 +668,53 @@ async function loadConfigList() { } catch {} } +async function loadRunList() { + try { + const res = await fetch('/api/runs'); + const runs = await res.json(); + const sel = document.getElementById('cfg-run-select'); + sel.innerHTML = ''; + runs.forEach(r => { + const opt = document.createElement('option'); + opt.value = r; + opt.textContent = r; + sel.appendChild(opt); + }); + } catch {} +} + +async function loadPreviousRun() { + const runName = document.getElementById('cfg-run-select').value; + if (!runName) return; + const errEl = document.getElementById('config-error'); + errEl.textContent = ''; + try { + const res = await fetch('/api/load-run', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ runName }), + }); + const result = await res.json(); + if (!res.ok) { + errEl.textContent = result.error || 'Failed to load run'; + return; + } + const stateRes = await fetch('/api/state'); + const state = await stateRes.json(); + document.getElementById('config-name').textContent = + state.configName ? `${state.configName} \u00B7 ${state.agentType}` : ''; + tasks = state.tasks; + setConfigPanelOpen(false); + updateConfigSummary(state.configName, state.agentType); + selectedTaskId = null; + renderTaskList(); + updateProgress(); + if (tasks.length > 0) selectTask(tasks[0].queryId); + } catch (e) { + errEl.textContent = `Network error: ${e.message}`; + } +} + async function loadSavedConfig(name) { if (!name) return; try { @@ -1055,7 +1114,8 @@ function renderTaskList() { if (t.graderResults) { const primary = getPrimaryGrader(t.graderResults); if (primary) { - graderBadge = `${primary.pass ? 'PASS' : 'FAIL'}`; + const pct = typeof primary.score === 'number' ? `${(primary.score * 100).toFixed(0)}%` : (primary.pass ? 'PASS' : 'FAIL'); + graderBadge = `${pct}`; } } @@ -1144,12 +1204,35 @@ function toggleAutoplay() { // ============================================================================ // Agent Stream // ============================================================================ -function renderStreamForTask(taskId) { +async function renderStreamForTask(taskId) { const body = document.getElementById('stream-body'); body.innerHTML = ''; const events = streamEvents[taskId] || []; - events.forEach(e => appendStreamEntry(e, false)); - body.scrollTop = body.scrollHeight; + if (events.length > 0) { + events.forEach(e => appendStreamEntry(e, false)); + body.scrollTop = body.scrollHeight; + return; + } + const task = tasks.find(t => t.queryId === taskId); + if (!task || task.status === 'pending' || task.status === 'running') return; + body.innerHTML = '
Loading events...
'; + try { + const res = await fetch(`/api/messages/${taskId}`); + if (!res.ok) { + body.innerHTML = '
No event log available
'; + return; + } + const text = await res.text(); + const parsed = text.trim().split('\n').filter(Boolean).map(line => { + try { return JSON.parse(line); } catch { return null; } + }).filter(Boolean); + streamEvents[taskId] = parsed; + body.innerHTML = ''; + parsed.forEach(e => appendStreamEntry(e, false)); + body.scrollTop = body.scrollHeight; + } catch { + body.innerHTML = '
Failed to load events
'; + } } function appendStreamEntry(event, scroll = true) { diff --git a/packages/browseros-agent/apps/eval/src/dashboard/server.ts b/packages/browseros-agent/apps/eval/src/dashboard/server.ts index f346f2c8c..6f1ff4c14 100644 --- a/packages/browseros-agent/apps/eval/src/dashboard/server.ts +++ b/packages/browseros-agent/apps/eval/src/dashboard/server.ts @@ -1,4 +1,4 @@ -import { mkdir, readdir, readFile } from 'node:fs/promises' +import { mkdir, readdir, readFile, stat } from 'node:fs/promises' import { join, resolve } from 'node:path' import { Hono } from 'hono' import { streamSSE } from 'hono/streaming' @@ -199,6 +199,133 @@ app.get('/api/screenshots/:taskId/:index', async (c) => { } }) +app.get('/api/messages/:taskId', async (c) => { + const { taskId } = c.req.param() + if (taskId.includes('..') || taskId.includes('/')) { + return c.json({ error: 'Invalid parameters' }, 400) + } + const filepath = join(dashboardState.outputDir, taskId, 'messages.jsonl') + const resolved = resolve(filepath) + if (!resolved.startsWith(resolve(dashboardState.outputDir))) { + return c.json({ error: 'Invalid path' }, 400) + } + try { + const file = Bun.file(filepath) + if (!(await file.exists())) return c.notFound() + const data = await file.arrayBuffer() + return c.body(data, 200, { + 'Content-Type': 'application/x-ndjson', + 'Cache-Control': 'no-cache', + }) + } catch { + return c.notFound() + } +}) + +const resultsDir = join(import.meta.dir, '..', '..', 'results') + +app.get('/api/runs', async (c) => { + try { + const runs: string[] = [] + const entries = await readdir(resultsDir, { withFileTypes: true }) + for (const entry of entries.filter((e) => e.isDirectory())) { + const subEntries = await readdir(join(resultsDir, entry.name), { + withFileTypes: true, + }).catch(() => [] as import('node:fs').Dirent[]) + const hasTimestampDirs = subEntries.some( + (s) => s.isDirectory() && /^\d{4}-\d{2}-\d{2}-\d{4}$/.test(s.name), + ) + if (hasTimestampDirs) { + for (const sub of subEntries.filter((s) => s.isDirectory())) { + runs.push(`${entry.name}/${sub.name}`) + } + } else { + runs.push(entry.name) + } + } + runs.sort().reverse() + return c.json(runs) + } catch { + return c.json([]) + } +}) + +app.post('/api/load-run', async (c) => { + if (evalRunning) + return c.json({ error: 'Cannot load while eval is running' }, 409) + let body: { runName: string } + try { + body = await c.req.json() + } catch { + return c.json({ error: 'Invalid JSON body' }, 400) + } + const runName = body.runName + if (!runName || runName.includes('..')) { + return c.json({ error: 'Invalid run name' }, 400) + } + if ((runName.match(/\//g) || []).length > 1) { + return c.json({ error: 'Invalid run name' }, 400) + } + const outputDir = resolve(resultsDir, runName) + if (!outputDir.startsWith(resolve(resultsDir))) { + return c.json({ error: 'Invalid path' }, 400) + } + const dirStat = await stat(outputDir).catch(() => null) + if (!dirStat?.isDirectory()) { + return c.json({ error: 'Run directory not found' }, 404) + } + const entries = await readdir(outputDir, { withFileTypes: true }) + const taskDirs = entries.filter((e) => e.isDirectory()) + const loadedTasks: DashboardTask[] = [] + let agentType = '' + for (const taskDir of taskDirs) { + const metaPath = join(outputDir, taskDir.name, 'metadata.json') + try { + const raw = JSON.parse(await readFile(metaPath, 'utf-8')) + if (!agentType && raw.agent_config?.type) { + agentType = raw.agent_config.type + } + const screenshotDir = join(outputDir, taskDir.name, 'screenshots') + let screenshotCount = raw.screenshot_count ?? 0 + if (!screenshotCount) { + try { + const files = await readdir(screenshotDir) + screenshotCount = files.filter((f: string) => + f.endsWith('.png'), + ).length + } catch {} + } + loadedTasks.push({ + queryId: raw.query_id || taskDir.name, + query: raw.query || '', + startUrl: raw.start_url, + status: + raw.termination_reason === 'completed' + ? 'completed' + : raw.termination_reason === 'timeout' + ? 'timeout' + : 'failed', + durationMs: raw.total_duration_ms, + graderResults: raw.grader_results, + screenshotCount, + }) + } catch {} + } + if (loadedTasks.length === 0) { + return c.json({ error: 'No completed tasks found in this run' }, 404) + } + dashboardState.configName = runName + dashboardState.agentType = agentType + dashboardState.outputDir = outputDir + dashboardState.tasks = loadedTasks + return c.json({ + status: 'loaded', + configName: runName, + agentType, + taskCount: loadedTasks.length, + }) +}) + // ============================================================================ // Config & Run API // ============================================================================ diff --git a/packages/browseros-agent/apps/eval/src/dashboard/viewer.html b/packages/browseros-agent/apps/eval/src/dashboard/viewer.html new file mode 100644 index 000000000..efdbb00e5 --- /dev/null +++ b/packages/browseros-agent/apps/eval/src/dashboard/viewer.html @@ -0,0 +1,1270 @@ + + + + + +BrowserOS Eval Viewer + + + + + + +
+ + + + +
+
+
🔎
+
Select a task from the sidebar to view screenshots and agent activity
+
+
+ + + +
+ + + + + + + + diff --git a/packages/browseros-agent/apps/eval/src/graders/performance/axes.ts b/packages/browseros-agent/apps/eval/src/graders/performance/axes.ts index ca0b92809..ea32042dc 100644 --- a/packages/browseros-agent/apps/eval/src/graders/performance/axes.ts +++ b/packages/browseros-agent/apps/eval/src/graders/performance/axes.ts @@ -53,8 +53,8 @@ The raw event stream — one JSON object per line with a "type" field. - "tool-output-error" / "tool-input-error" — Tool call failed. Fields: toolCallId, error. - "text-delta" — Agent's reasoning text. Field: delta (small text chunk). -**Event types to AVOID reading:** -- "tool-output-available" — Tool output. The "output" field contains FULL PAGE DOM CONTENT — hundreds of interactive elements, entire page text, etc. These lines are 5-50KB each. NEVER read them. The tool-input-available lines already tell you what the agent did. Screenshots show you the visual result. +**Event types to handle carefully:** +- "tool-output-available" — Tool output. The "output" field contains FULL PAGE DOM CONTENT — hundreds of interactive elements, entire page text, etc. These lines are 5-50KB each. NEVER read them in bulk. However, you CAN and SHOULD use Grep to search within these lines for specific keywords when screenshots alone can't verify a claim. For example, if the task asks "find the price of X" and the screenshot is unclear, grep messages.jsonl for the product name or price value to confirm the agent actually saw it in the DOM. ### 2. screenshots/ directory Numbered PNG screenshots (1.png, 2.png, ...) captured after each tool execution. @@ -95,6 +95,13 @@ Grep for "tool-output-error" or "tool-input-error". If none found, zero errors. **Step 3: Sample reasoning (only if needed for reasoning_quality)** Grep for "text-delta" but LIMIT to the first 10 and last 10 results. Don't read all reasoning text. +**Step 4: Verify claims from DOM content (critical for task_completion)** +When the agent's final answer contains specific data (prices, names, dates, counts, etc.) that you can't confirm from screenshots alone, use Grep to search messages.jsonl for those specific values or keywords. This searches the tool-output-available lines which contain DOM content the agent actually saw. For example: +- Task asks "find cheapest flight price" → grep for the dollar amount from the final answer +- Task asks "list the top 3 articles" → grep for the article titles mentioned in the answer +- Task asks "extract the email address" → grep for the email pattern +This is the most reliable way to verify whether the agent actually found the data it claims, since screenshots may be blurry, truncated, or missing the relevant section. + ## How to View Screenshots You have {screenshot_count} screenshots. View 3-5 strategically: diff --git a/packages/browseros-agent/apps/eval/src/graders/performance/performance-grader.ts b/packages/browseros-agent/apps/eval/src/graders/performance/performance-grader.ts index 1706ba5f0..127bafd7c 100644 --- a/packages/browseros-agent/apps/eval/src/graders/performance/performance-grader.ts +++ b/packages/browseros-agent/apps/eval/src/graders/performance/performance-grader.ts @@ -16,8 +16,8 @@ import { type PerformanceGraderOptions, } from './types' -export const DEFAULT_MAX_TURNS = 15 -export const DEFAULT_MAX_BUDGET_USD = 0.5 +export const DEFAULT_MAX_TURNS = 100 +export const DEFAULT_MAX_BUDGET_USD = 100 export const DEFAULT_PASS_THRESHOLD = 75 const DEFAULT_MODEL = 'claude-opus-4-5-20251101' const GRADER_TIMEOUT_MS = 300_000 diff --git a/packages/browseros-agent/apps/eval/src/runner/browseros-app-manager.ts b/packages/browseros-agent/apps/eval/src/runner/browseros-app-manager.ts index 6a2b05854..3a4a6c318 100644 --- a/packages/browseros-agent/apps/eval/src/runner/browseros-app-manager.ts +++ b/packages/browseros-agent/apps/eval/src/runner/browseros-app-manager.ts @@ -30,7 +30,9 @@ const MONOREPO_ROOT = join( '../../../..', ) -const BROWSEROS_BINARY = '/Applications/BrowserOS.app/Contents/MacOS/BrowserOS' +const BROWSEROS_BINARY = + process.env.BROWSEROS_BINARY || + '/Applications/BrowserOS.app/Contents/MacOS/BrowserOS' const CONTROLLER_EXT_DIR = join(MONOREPO_ROOT, 'apps/controller-ext/dist') diff --git a/packages/browseros-agent/apps/eval/src/runner/eval-runner.ts b/packages/browseros-agent/apps/eval/src/runner/eval-runner.ts index f36c2bbc1..859195231 100644 --- a/packages/browseros-agent/apps/eval/src/runner/eval-runner.ts +++ b/packages/browseros-agent/apps/eval/src/runner/eval-runner.ts @@ -1,5 +1,5 @@ import { mkdir, writeFile } from 'node:fs/promises' -import { dirname, join, resolve } from 'node:path' +import { basename, dirname, join, resolve } from 'node:path' import { dashboardState, setActiveExecutor, @@ -120,18 +120,31 @@ function resolvePaths( ? config.dataset : resolve(configDir, config.dataset) - // Resolve output directory: use options.outputDir if provided, otherwise resolve from config - const outputDir = options.outputDir - ? options.outputDir - : config.output_dir - ? config.output_dir.startsWith('/') - ? config.output_dir - : resolve(configDir, config.output_dir) - : resolve(configDir, 'results') + // Resolve output directory: results/{config-name}/{timestamp}/ + // Config name derived from config filename (e.g., "browseros-agent-weekly.json" → "browseros-agent-weekly") + const configName = options.configPath + ? basename(resolve(options.configPath), '.json') + : 'eval' + const timestamp = formatTimestamp(new Date()) + const resultsBase = config.output_dir + ? config.output_dir.startsWith('/') + ? config.output_dir + : resolve(configDir, config.output_dir) + : resolve(configDir, '..', 'results') + const outputDir = join(resultsBase, configName, timestamp) return { dataPath, outputDir } } +function formatTimestamp(date: Date): string { + const y = date.getFullYear() + const m = String(date.getMonth() + 1).padStart(2, '0') + const d = String(date.getDate()).padStart(2, '0') + const h = String(date.getHours()).padStart(2, '0') + const min = String(date.getMinutes()).padStart(2, '0') + return `${y}-${m}-${d}-${h}${min}` +} + // ============================================================================ // Task Loading // ============================================================================ diff --git a/packages/browseros-agent/bun.lock b/packages/browseros-agent/bun.lock index 003528756..d966042d4 100644 --- a/packages/browseros-agent/bun.lock +++ b/packages/browseros-agent/bun.lock @@ -149,6 +149,7 @@ "version": "0.1.0", "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.2.63", + "@aws-sdk/client-s3": "^3.1014.0", "@browseros/server": "workspace:*", "@browseros/shared": "workspace:*", "@google/gemini-cli-core": "^0.16.0", @@ -3627,6 +3628,8 @@ "path-exists": ["path-exists@5.0.0", "", {}, "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ=="], + "path-expression-matcher": ["path-expression-matcher@1.2.0", "", {}, "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ=="], + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], @@ -4553,7 +4556,9 @@ "@browseros/agent/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], - "@browseros/eval/@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="], + "@browseros/eval/@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.1014.0", "", { "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.23", "@aws-sdk/credential-provider-node": "^3.972.24", "@aws-sdk/middleware-bucket-endpoint": "^3.972.8", "@aws-sdk/middleware-expect-continue": "^3.972.8", "@aws-sdk/middleware-flexible-checksums": "^3.974.3", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-location-constraint": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-sdk-s3": "^3.972.23", "@aws-sdk/middleware-ssec": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.24", "@aws-sdk/region-config-resolver": "^3.972.9", "@aws-sdk/signature-v4-multi-region": "^3.996.11", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.10", "@smithy/config-resolver": "^4.4.13", "@smithy/core": "^3.23.12", "@smithy/eventstream-serde-browser": "^4.2.12", "@smithy/eventstream-serde-config-resolver": "^4.3.12", "@smithy/eventstream-serde-node": "^4.2.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-blob-browser": "^4.2.13", "@smithy/hash-node": "^4.2.12", "@smithy/hash-stream-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/md5-js": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.27", "@smithy/middleware-retry": "^4.4.44", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.43", "@smithy/util-defaults-mode-node": "^4.2.47", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "@smithy/util-waiter": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-0XLrOT4Cm3NEhhiME7l/8LbTXS4KdsbR4dSrY207KNKTcHLLTZ9EXt4ZpgnTfLvWQF3pGP2us4Zi1fYLo0N+Ow=="], + + "@browseros/eval/@types/bun": ["@types/bun@1.3.11", "", { "dependencies": { "bun-types": "1.3.11" } }, "sha512-5vPne5QvtpjGpsGYXiFyycfpDF2ECyPcTSsFBMa0fraoxiQyMJ3SmuQIGhzPg2WJuWxVBoxWJ2kClYTcw/4fAg=="], "@browseros/server/@types/bun": ["@types/bun@1.3.5", "", { "dependencies": { "bun-types": "1.3.5" } }, "sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w=="], @@ -5303,7 +5308,101 @@ "@browseros/agent/@types/bun/bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="], - "@browseros/eval/@types/bun/bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="], + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/core": ["@aws-sdk/core@3.973.23", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws-sdk/xml-builder": "^3.972.15", "@smithy/core": "^3.23.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-aoJncvD1XvloZ9JLnKqTRL9dBy+Szkryoag9VT+V1TqsuUgIxV9cnBVM/hrDi2vE8bDqLiDR8nirdRcCdtJu0w=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.24", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.21", "@aws-sdk/credential-provider-http": "^3.972.23", "@aws-sdk/credential-provider-ini": "^3.972.23", "@aws-sdk/credential-provider-process": "^3.972.21", "@aws-sdk/credential-provider-sso": "^3.972.23", "@aws-sdk/credential-provider-web-identity": "^3.972.23", "@aws-sdk/types": "^3.973.6", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-9Jwi7aps3AfUicJyF5udYadPypPpCwUZ6BSKr/QjRbVCpRVS1wc+1Q6AEZ/qz8J4JraeRd247pSzyMQSIHVebw=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-bucket-endpoint": ["@aws-sdk/middleware-bucket-endpoint@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-arn-parser": "^3.972.3", "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-WR525Rr2QJSETa9a050isktyWi/4yIGcmY3BQ1kpHqb0LqUglQHCS8R27dTJxxWNZvQ0RVGtEZjTCbZJpyF3Aw=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-expect-continue": ["@aws-sdk/middleware-expect-continue@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-5DTBTiotEES1e2jOHAq//zyzCjeMB78lEHd35u15qnrid4Nxm7diqIf9fQQ3Ov0ChH1V3Vvt13thOnrACmfGVQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-flexible-checksums": ["@aws-sdk/middleware-flexible-checksums@3.974.3", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", "@aws-sdk/core": "^3.973.23", "@aws-sdk/crc64-nvme": "^3.972.5", "@aws-sdk/types": "^3.973.6", "@smithy/is-array-buffer": "^4.2.2", "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-middleware": "^4.2.12", "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-fB7FNLH1+VPUs0QL3PLrHW+DD4gKu6daFgWtyq3R0Y0Lx8DLZPvyGAxCZNFBxH+M2xt9KvBJX6USwjuqvitmCQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-location-constraint": ["@aws-sdk/middleware-location-constraint@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-KaUoFuoFPziIa98DSQsTPeke1gvGXlc5ZGMhy+b+nLxZ4A7jmJgLzjEF95l8aOQN2T/qlPP3MrAyELm8ExXucw=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-BnnvYs2ZEpdlmZ2PNlV2ZyQ8j8AEkMTjN79y/YA475ER1ByFYrkVR85qmhni8oeTaJcDqbx364wDpitDAA/wCA=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.972.23", "", { "dependencies": { "@aws-sdk/core": "^3.973.23", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-arn-parser": "^3.972.3", "@smithy/core": "^3.23.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-50QgHGPQAb2veqFOmTF1A3GsAklLHZXL47KbY35khIkfbXH5PLvqpEc/gOAEBPj/yFxrlgxz/8mqWcWTNxBkwQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-ssec": ["@aws-sdk/middleware-ssec@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-wqlK0yO/TxEC2UsY9wIlqeeutF6jjLe0f96Pbm40XscTo57nImUk9lBcw0dPgsm0sppFtAkSlDrfpK+pC30Wqw=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.24", "", { "dependencies": { "@aws-sdk/core": "^3.973.23", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@smithy/core": "^3.23.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-retry": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-dLTWy6IfAMhNiSEvMr07g/qZ54be6pLqlxVblbF6AzafmmGAzMMj8qMoY9B4+YgT+gY9IcuxZslNh03L6PyMCQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.9", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/config-resolver": "^4.4.13", "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-eQ+dFU05ZRC/lC2XpYlYSPlXtX3VT8sn5toxN2Fv7EXlMoA2p9V7vUBKqHunfD4TRLpxUq8Y8Ol/nCqiv327Ng=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.11", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "^3.972.23", "@aws-sdk/types": "^3.973.6", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-SKgZY7x6AloLUXO20FJGnkKJ3a6CXzNDt6PYs2yqoPzgU0xKWcUoGGJGEBTsfM5eihKW42lbwp+sXzACLbSsaA=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/types": ["@aws-sdk/types@3.973.6", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.5", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-endpoints": "^3.3.3", "tslib": "^2.6.2" } }, "sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.10", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.24", "@aws-sdk/types": "^3.973.6", "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-E99zeTscCc+pTMfsvnfi6foPpKmdD1cZfOC7/P8UUrjsoQdg9VEWPRD+xdFduKnfPXwcvby58AlO9jwwF6U96g=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/config-resolver": ["@smithy/config-resolver@4.4.13", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-iIzMC5NmOUP6WL6o8iPBjFhUhBZ9pPjpUpQYWMUFQqKyXXzOftbfK8zcQCz/jFV1Psmf05BK5ypx4K2r4Tnwdg=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/core": ["@smithy/core@3.23.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-o9VycsYNtgC+Dy3I0yrwCqv9CWicDnke0L7EVOrZtJpjb2t0EjaEofmMrYc0T1Kn3yk32zm6cspxF9u9Bj7e5w=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.12", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-XUSuMxlTxV5pp4VpqZf6Sa3vT/Q75FVkLSpSSE3KkWBvAQWeuWt1msTv8fJfgA4/jcJhrbrbMzN1AC/hvPmm5A=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-7epsAZ3QvfHkngz6RXQYseyZYHlmWXSTPOfPmXkiS+zA6TBNo1awUaMFL9vxyXlGdoELmCZyZe1nQE+imbmV+Q=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.12", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-D1pFuExo31854eAvg89KMn9Oab/wEeJR6Buy32B49A9Ogdtx5fwZPqBHUlDzaCDpycTFk2+fSQgX689Qsk7UGA=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.15", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-T4jFU5N/yiIfrtrsb9uOQn7RdELdM/7HbyLNr6uO/mpkj1ctiVs7CihVr51w4LyQlXWDpXFn4BElf1WmQvZu/A=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/hash-blob-browser": ["@smithy/hash-blob-browser@4.2.13", "", { "dependencies": { "@smithy/chunked-blob-reader": "^5.2.2", "@smithy/chunked-blob-reader-native": "^4.2.3", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-YrF4zWKh+ghLuquldj6e/RzE3xZYL8wIPfkt0MqCRphVICjyyjH8OwKD7LLlKpVEbk4FLizFfC1+gwK6XQdR3g=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/hash-node": ["@smithy/hash-node@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/hash-stream-node": ["@smithy/hash-stream-node@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-O3YbmGExeafuM/kP7Y8r6+1y0hIh3/zn6GROx0uNlB54K9oihAL75Qtc+jFfLNliTi6pxOAYZrRKD9A7iA6UFw=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-/4F1zb7Z8LOu1PalTdESFHR0RbPwHd3FcaG1sI3UEIriQTWakysgJr65lc1jj6QY5ye7aFsisajotH6UhWfm/g=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/md5-js": ["@smithy/md5-js@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-W/oIpHCpWU2+iAkfZYyGWE+qkpuf3vEXHLxQQDx9FPNZTTdnul0dZ2d/gUFrtQ5je1G2kp4cjG0/24YueG2LbQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-YE58Yz+cvFInWI/wOTrB+DbvUVz/pLn5mC5MvOV4fdRUc6qGwygyngcucRQjAhiCEbmfLOXX0gntSIcgMvAjmA=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.27", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/middleware-serde": "^4.2.15", "@smithy/node-config-provider": "^4.3.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-middleware": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-T3TFfUgXQlpcg+UdzcAISdZpj4Z+XECZ/cefgA6wLBd6V4lRi0svN2hBouN/be9dXQ31X4sLWz3fAQDf+nt6BA=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.44", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/service-error-classification": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-Y1Rav7m5CFRPQyM4CI0koD/bXjyjJu3EQxZZhtLGD88WIrBrQ7kqXM96ncd6rYnojwOo/u9MXu57JrEvu/nLrA=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.15", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-ExYhcltZSli0pgAKOpQQe1DLFBLryeZ22605y/YS+mQpdNWekum9Ujb/jMKfJKgjtz1AZldtwA/wCYuKJgjjlg=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-kruC5gRHwsCOuyCd4ouQxYjgRAym2uDlCvQ5acuMtRrcdfg7mFBg6blaxcJ09STpt3ziEkis6bhg1uwrWU7txw=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.12", "", { "dependencies": { "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-tr2oKX2xMcO+rBOjobSwVAkV05SIfUKz8iI53rzxEmgW3GOOPOv0UioSDk+J8OpRQnpnhsO3Af6IEBabQBVmiw=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/node-http-handler": ["@smithy/node-http-handler@4.5.0", "", { "dependencies": { "@smithy/abort-controller": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Rnq9vQWiR1+/I6NZZMNzJHV6pZYyEHt2ZnuV3MG8z2NNenC4i/8Kzttz7CjZiHSmsN5frhXhg17z3Zqjjhmz1A=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/protocol-http": ["@smithy/protocol-http@5.3.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/smithy-client": ["@smithy/smithy-client@4.12.7", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/middleware-endpoint": "^4.4.27", "@smithy/middleware-stack": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-stream": "^4.5.20", "tslib": "^2.6.2" } }, "sha512-q3gqnwml60G44FECaEEsdQMplYhDMZYCtYhMCzadCnRnnHIobZJjegmdoUo6ieLQlPUzvrMdIJUpx6DoPmzANQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/types": ["@smithy/types@4.13.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/url-parser": ["@smithy/url-parser@4.2.12", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-wOPKPEpso+doCZGIlr+e1lVI6+9VAKfL4kZWFgzVgGWY2hZxshNKod4l2LXS3PRC9otH/JRSjtEHqQ/7eLciRA=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.43", "", { "dependencies": { "@smithy/property-provider": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Qd/0wCKMaXxev/z00TvNzGCH2jlKKKxXP1aDxB6oKwSQthe3Og2dMhSayGCnsma1bK/kQX1+X7SMP99t6FgiiQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.47", "", { "dependencies": { "@smithy/config-resolver": "^4.4.13", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-qSRbYp1EQ7th+sPFuVcVO05AE0QH635hycdEXlpzIahqHHf2Fyd/Zl+8v0XYMJ3cgDVPa0lkMefU7oNUjAP+DQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-endpoints": ["@smithy/util-endpoints@3.3.3", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-VACQVe50j0HZPjpwWcjyT51KUQ4AnsvEaQ2lKHOSL4mNLD0G9BjEniQ+yCt1qqfKfiAHRAts26ud7hBjamrwig=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-middleware": ["@smithy/util-middleware@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Er805uFUOvgc0l8nv0e0su0VFISoxhJ/AwOn3gL2NWNY2LUEldP5WtVcRYSQBcjg0y9NfG8JYrCJaYDpupBHJQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-retry": ["@smithy/util-retry@4.2.12", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-1zopLDUEOwumjcHdJ1mwBHddubYF8GMQvstVCLC54Y46rqoHwlIU+8ZzUeaBcD+WCJHyDGSeZ2ml9YSe9aqcoQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-stream": ["@smithy/util-stream@4.5.20", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.15", "@smithy/node-http-handler": "^4.5.0", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-4yXLm5n/B5SRBR2p8cZ90Sbv4zL4NKsgxdzCzp/83cXw2KxLEumt5p+GAVyRNZgQOSrzXn9ARpO0lUe8XSlSDw=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-waiter": ["@smithy/util-waiter@4.2.13", "", { "dependencies": { "@smithy/abort-controller": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-2zdZ9DTHngRtcYxJK1GUDxruNr53kv5W2Lupe0LMU+Imr6ohQg8M2T14MNkj1Y0wS3FFwpgpGQyvuaMF7CiTmQ=="], + + "@browseros/eval/@types/bun/bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="], "@browseros/server/@types/bun/bun-types": ["bun-types@1.3.5", "", { "dependencies": { "@types/node": "*" } }, "sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw=="], @@ -5617,6 +5716,70 @@ "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.15", "", { "dependencies": { "@smithy/types": "^4.13.1", "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" } }, "sha512-PxMRlCFNiQnke9YR29vjFQwz4jq+6Q04rOVFeTDR2K7Qpv9h9FOWOxG+zJjageimYbWqE3bTuLjmryWHAWbvaA=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.12", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.21", "", { "dependencies": { "@aws-sdk/core": "^3.973.23", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-BkAfKq8Bd4shCtec1usNz//urPJF/SZy14qJyxkSaRJQ/Vv1gVh0VZSTmS7aE6aLMELkFV5wHHrS9ZcdG8Kxsg=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.23", "", { "dependencies": { "@aws-sdk/core": "^3.973.23", "@aws-sdk/types": "^3.973.6", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/node-http-handler": "^4.5.0", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/util-stream": "^4.5.20", "tslib": "^2.6.2" } }, "sha512-4XZ3+Gu5DY8/n8zQFHBgcKTF7hWQl42G6CY9xfXVo2d25FM/lYkpmuzhYopYoPL1ITWkJ2OSBQfYEu5JRfHOhA=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.23", "", { "dependencies": { "@aws-sdk/core": "^3.973.23", "@aws-sdk/credential-provider-env": "^3.972.21", "@aws-sdk/credential-provider-http": "^3.972.23", "@aws-sdk/credential-provider-login": "^3.972.23", "@aws-sdk/credential-provider-process": "^3.972.21", "@aws-sdk/credential-provider-sso": "^3.972.23", "@aws-sdk/credential-provider-web-identity": "^3.972.23", "@aws-sdk/nested-clients": "^3.996.13", "@aws-sdk/types": "^3.973.6", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-PZLSmU0JFpNCDFReidBezsgL5ji9jOBry8CnZdw4Jj6d0K2z3Ftnp44NXgADqYx5BLMu/ZHujfeJReaDoV+IwQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.21", "", { "dependencies": { "@aws-sdk/core": "^3.973.23", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-nRxbeOJ1E1gVA0lNQezuMVndx+ZcuyaW/RB05pUsznN5BxykSlH6KkZ/7Ca/ubJf3i5N3p0gwNO5zgPSCzj+ww=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.23", "", { "dependencies": { "@aws-sdk/core": "^3.973.23", "@aws-sdk/nested-clients": "^3.996.13", "@aws-sdk/token-providers": "3.1014.0", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-APUccADuYPLL0f2htpM8Z4czabSmHOdo4r41W6lKEZdy++cNJ42Radqy6x4TopENzr3hR6WYMyhiuiqtbf/nAA=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.23", "", { "dependencies": { "@aws-sdk/core": "^3.973.23", "@aws-sdk/nested-clients": "^3.996.13", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-H5JNqtIwOu/feInmMMWcK0dL5r897ReEn7n2m16Dd0DPD9gA2Hg8Cq4UDzZ/9OzaLh/uqBM6seixz0U6Fi2Eag=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.12", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.7", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-bucket-endpoint/@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.972.3", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-flexible-checksums/@aws-sdk/crc64-nvme": ["@aws-sdk/crc64-nvme@3.972.5", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-2VbTstbjKdT+yKi8m7b3a9CiVac+pL/IY2PHJwsaGkkHmuuqkJZIErPck1h6P3T9ghQMLSdMPyW6Qp7Di5swFg=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-sdk-s3/@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.972.3", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/middleware-sdk-s3/@smithy/signature-v4": ["@smithy/signature-v4@5.3.12", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4": ["@smithy/signature-v4@5.3.12", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.12", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.12", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.7", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1" } }, "sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.7", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-P2OdvrgiAKpkPNKlKUtWbNZKB1XjPxM086NeVhK+W+wI46pIKdWBe5QyXvhUm3MEcyS/rkLvY8rZzyUdmyDZBw=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.12", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1" } }, "sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/util-waiter/@smithy/abort-controller": ["@smithy/abort-controller@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q=="], + "@google/gemini-cli-core/@opentelemetry/exporter-logs-otlp-http/@opentelemetry/otlp-transformer/@opentelemetry/resources": ["@opentelemetry/resources@2.0.1", "", { "dependencies": { "@opentelemetry/core": "2.0.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw=="], "@google/gemini-cli-core/@opentelemetry/exporter-logs-otlp-http/@opentelemetry/otlp-transformer/@opentelemetry/sdk-metrics": ["@opentelemetry/sdk-metrics@2.0.1", "", { "dependencies": { "@opentelemetry/core": "2.0.1", "@opentelemetry/resources": "2.0.1" }, "peerDependencies": { "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, "sha512-wf8OaJoSnujMAHWR3g+/hGvNcsC16rf9s1So4JlMiFaFHiE4HpIA3oUh+uWZQ7CNuK8gVW/pQSkgoa5HkkOl0g=="], @@ -5661,6 +5824,22 @@ "wxt/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.23", "", { "dependencies": { "@aws-sdk/core": "^3.973.23", "@aws-sdk/nested-clients": "^3.996.13", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-OmE/pSkbMM3dCj1HdOnZ5kXnKK+R/Yz+kbBugraBecp0pGAs21eEURfQRz+1N2gzIHLVyGIP1MEjk/uSrFsngg=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.13", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.23", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.24", "@aws-sdk/region-config-resolver": "^3.972.9", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.10", "@smithy/config-resolver": "^4.4.13", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.27", "@smithy/middleware-retry": "^4.4.44", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.43", "@smithy/util-defaults-mode-node": "^4.2.47", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-ptZ1HF4yYHNJX8cgFF+8NdYO69XJKZn7ft0/ynV3c0hCbN+89fAbrLS+fqniU2tW8o9Kfqhj8FUh+IPXb2Qsuw=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.13", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.23", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.24", "@aws-sdk/region-config-resolver": "^3.972.9", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.10", "@smithy/config-resolver": "^4.4.13", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.27", "@smithy/middleware-retry": "^4.4.44", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.43", "@smithy/util-defaults-mode-node": "^4.2.47", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-ptZ1HF4yYHNJX8cgFF+8NdYO69XJKZn7ft0/ynV3c0hCbN+89fAbrLS+fqniU2tW8o9Kfqhj8FUh+IPXb2Qsuw=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1014.0", "", { "dependencies": { "@aws-sdk/core": "^3.973.23", "@aws-sdk/nested-clients": "^3.996.13", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-gHTHNUoaOGNrSWkl32A7wFsU78jlNTlqMccLu0byUk5CysYYXaxNMIonIVr4YcykC7vgtDS5ABuz83giy6fzJA=="], + + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.13", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.23", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.24", "@aws-sdk/region-config-resolver": "^3.972.9", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.10", "@smithy/config-resolver": "^4.4.13", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.27", "@smithy/middleware-retry": "^4.4.44", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.43", "@smithy/util-defaults-mode-node": "^4.2.47", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-ptZ1HF4yYHNJX8cgFF+8NdYO69XJKZn7ft0/ynV3c0hCbN+89fAbrLS+fqniU2tW8o9Kfqhj8FUh+IPXb2Qsuw=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.12", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FE3bZdEl62ojmy8x4FHqxq2+BuOHlcxiH5vaZ6aqHJr3AIZzwF5jfx8dEiU/X0a8RboyNDjmXjlbr8AdEyLgiA=="], + + "@browseros/eval/@aws-sdk/client-s3/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.12", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FE3bZdEl62ojmy8x4FHqxq2+BuOHlcxiH5vaZ6aqHJr3AIZzwF5jfx8dEiU/X0a8RboyNDjmXjlbr8AdEyLgiA=="], + "@google/genai/google-auth-library/gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], "@google/genai/google-auth-library/gaxios/rimraf/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], @@ -5675,6 +5854,8 @@ "publish-browser-extension/listr2/cli-truncate/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + "@browseros/eval/@aws-sdk/client-s3/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/fast-xml-builder": ["fast-xml-builder@1.1.4", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg=="], + "@google/genai/google-auth-library/gaxios/rimraf/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], "@google/genai/google-auth-library/gaxios/rimraf/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],