PrPoller
Defined in: src/pr-poller.ts:106
Polls PR status for active sessions and caches it in memory. One gh process
runs at a time (sequential awaits) to bound the synchronous execFileSync
blocking in the forge runner and avoid GitHub rate spikes.
Two cadences. The full tick sweep (every intervalMs, default 120s) covers
every active session and prunes the cache. A faster fastTick (every
fastIntervalMs, default 15s) re-polls only sessions with an open PR — the
in-flight ones whose CI/merge/review state can still move. Without it the list
overview lagged the detail view (GitRail, which polls its open PR every 15s):
checks: "pending" is short-lived and the 120s sweep routinely sampled none
then success two sweeps later, never recording the running state, so the
list jumped straight to green and never showed the pulsing “CI running” dot.
The fast sweep is capped at fastBatch open PRs per tick (round-robin beyond
it) so it never fans out one blocking gh per PR over an unbounded backlog.
Implements
Section titled “Implements”Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new PrPoller(
store,resolveForge,onChange,intervalMs?,pollDelayMs?,reconcileBranch?,fastIntervalMs?,fastBatch?,ownsPr?):PrPoller
Defined in: src/pr-poller.ts:136
Parameters
Section titled “Parameters”Pick<SessionStore, "list" | "get">
resolveForge
Section titled “resolveForge”(repoPath) => GitForge | null
onChange
Section titled “onChange”(id, git) => void
intervalMs?
Section titled “intervalMs?”number = 120_000
pollDelayMs?
Section titled “pollDelayMs?”number = 1000
Coalescing window for pollSession — bursts of status flips near a
turn’s end collapse into one gh call.
reconcileBranch?
Section titled “reconcileBranch?”(s) => string | null
Called when the stored branch yields no PR: re-resolves the session’s live worktree branch (an agent may have renamed it), persists the adoption, and returns the new branch to retry against — or null when nothing changed.
fastIntervalMs?
Section titled “fastIntervalMs?”number = 15_000
Fast cadence for re-polling open PRs (in-flight CI/merge state).
fastBatch?
Section titled “fastBatch?”number = 8
Max open PRs polled per fast tick; the rest rotate in on later ticks.
ownsPr?
Section titled “ownsPr?”(s, headSha) => boolean | null
Whether a name-matched terminal (merged/closed) PR’s head commit actually
belongs to the session’s branch. Guards against gh pr list --head <name>
returning a prior, already-merged PR that merely reused this branch name.
false → discard the stale PR; true/null → trust it.
Returns
Section titled “Returns”PrPoller
Methods
Section titled “Methods”drop()
Section titled “drop()”drop(
id):void
Defined in: src/pr-poller.ts:299
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”void
Implementation of
Section titled “Implementation of”fastTick()
Section titled “fastTick()”fastTick():
Promise<void>
Defined in: src/pr-poller.ts:180
Accelerated re-poll of in-flight PRs (cached state === "open") so the list
overview tracks CI running/transition as live as the detail view, without the
120s sweep’s lag. Capped at fastBatch per tick, rotating so every open PR is
covered across a few ticks rather than fanning out one gh per PR each time.
Returns
Section titled “Returns”Promise<void>
get(
id):GitState|undefined
Defined in: src/pr-poller.ts:293
Read one session’s cached state without materializing the whole map — O(1) for per-request callers (e.g. GET /git) that only need a single key.
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”GitState | undefined
Implementation of
Section titled “Implementation of”pollSession()
Section titled “pollSession()”pollSession(
id):void
Defined in: src/pr-poller.ts:266
Targeted poll triggered by an external signal — chiefly an agent finishing
a turn, which is when it has most likely just run gh pr create. Surfaces
the PR badge within seconds instead of waiting up to intervalMs for the
next full sweep. Debounced per session (so a burst of status flips makes at
most one gh call); de-duped per session via inFlight, and serialized
behind any in-flight sweep through withGh so it never runs gh
concurrently with one (queued, not dropped).
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”void
set(
id,git):void
Defined in: src/pr-poller.ts:296
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”void
Implementation of
Section titled “Implementation of”snapshot()
Section titled “snapshot()”snapshot():
Record<string,GitState>
Defined in: src/pr-poller.ts:290
Returns
Section titled “Returns”Record<string, GitState>
Implementation of
Section titled “Implementation of”start()
Section titled “start()”start():
void
Defined in: src/pr-poller.ts:303
Returns
Section titled “Returns”void
stop()
Section titled “stop()”stop():
void
Defined in: src/pr-poller.ts:307
Returns
Section titled “Returns”void
tick()
Section titled “tick()”tick():
Promise<void>
Defined in: src/pr-poller.ts:159
Returns
Section titled “Returns”Promise<void>