import { spawnSync } from 'node:child_process'; import path from 'node:path'; export function sleepMs(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } export function readAgentRunWorkerQueueCounts(root, env) { const result = spawnSync( process.execPath, [path.join(root, 'scripts', 'agent-run-worker.mjs'), '--status'], { cwd: root, env, encoding: 'utf8' }, ); const combined = `${result.stdout ?? ''}\n${result.stderr ?? ''}`; const match = combined.match(/\{[\s\S]*\}/); if (!match) return null; try { const payload = JSON.parse(match[0]); const counts = payload?.queue?.statusCounts ?? {}; return { queued: Number(counts.queued ?? 0), running: Number(counts.running ?? 0), inFlight: Number(payload?.queue?.inFlight ?? 0), }; } catch { return null; } } export async function waitForAgentRunWorkerIdle(root, env, { timeoutMs = Number(process.env.GOOSE_V149_WORKER_IDLE_TIMEOUT_MS ?? 900_000), pollMs = Number(process.env.GOOSE_V149_WORKER_IDLE_POLL_MS ?? 5_000), logPrefix = '[goose-v149-worker-idle]', } = {}) { const deadline = Date.now() + timeoutMs; while (Date.now() < deadline) { const counts = readAgentRunWorkerQueueCounts(root, env); if (counts && counts.running === 0 && counts.queued === 0 && counts.inFlight === 0) { console.log(`${logPrefix} worker idle`); return; } console.log( `${logPrefix} waiting ` + `(running=${counts?.running ?? '?'} queued=${counts?.queued ?? '?'} inFlight=${counts?.inFlight ?? '?'})`, ); await sleepMs(pollMs); } const counts = readAgentRunWorkerQueueCounts(root, env); throw new Error( `worker not idle within ${timeoutMs}ms ` + `(running=${counts?.running ?? '?'} queued=${counts?.queued ?? '?'})`, ); } export const gooseV149PortalAgentEnv = { GOOSE_V149_PORTAL_RESUME_TIMEOUT_MS: process.env.GOOSE_V149_PORTAL_RESUME_TIMEOUT_MS ?? '900000', GOOSE_V149_PAGE_E2E_TIMEOUT_MS: process.env.GOOSE_V149_PAGE_E2E_TIMEOUT_MS ?? '900000', };