/** * Per-orchestrator-process registry of `EpicEventBus` instances, keyed by * epic-ref string (`"owner/repo#number"`). * * Each bus is driven by a private poller — mirrors `watch.ts` but emits into * the bus instead of stdout NDJSON. Multiple concurrent `cockpit_await_events` * callers against the same epic share the subscriber; refcounted via * `acquire` / `release`. * * Bus lifetime is decoupled from call lifetime (#924): `release()` at * refcount 0 pauses the poller and arms an idle-TTL timer instead of tearing * down the bus. The next `acquire()` disarms the timer, resumes the poller, * and runs a synchronous catch-up poll so between-call events are captured. * A soft cap on live buses evicts the least-recently-active on overflow. * * Env knobs: * `COCKPIT_MCP_BUS_IDLE_TTL_MS` — idle-TTL for refcount-0 buses (default 7_200_000, sourced from the shared `DEFAULT_QUIET_HORIZON_MS` constant in `event-bus.ts`). * `COCKPIT_MCP_BUS_MAX` — soft cap on live buses (default 100). */ import { type CommandRunner, type GhWrapper, type RateLimitScheduler } from '@generacy-ai/cockpit'; import { EpicEventBus } from './event-bus.js'; export interface AcquireOptions { epicRef: string; runner?: CommandRunner; gh?: GhWrapper; intervalMs?: number; rateLimitScheduler?: RateLimitScheduler; logger?: { warn: (msg: string) => void; info?: (msg: string) => void; }; /** * Injection seam for tests: build an event bus without starting a poll * loop. Callers use the returned bus's `emit()` directly. */ noPoll?: boolean; /** Test seam: wall-clock provider (drives `lastActiveAt`). */ now?: () => number; /** Test seam: override the idle-TTL for this and subsequent acquires. */ idleTtlMs?: number; /** Test seam: override the LRU soft cap for this and subsequent acquires. */ maxBuses?: number; /** * Test seam: replace the entire poll cycle (resolveEpic + runOnePoll + * computeAggregateEvents). Called from both the poll loop and * `catchUpPoll()`. Used to drive between-call event emission * deterministically in unit tests. */ runCycle?: (bus: EpicEventBus) => Promise; } export interface Acquired { bus: EpicEventBus; release: () => void; } export declare function acquireEpicBus(options: AcquireOptions): Promise; /** * Test-only: forcibly release all subscriptions. Use in test `afterEach`. */ export declare function _resetRegistryForTests(): void; //# sourceMappingURL=event-bus-registry.d.ts.map