mirror of
https://github.com/stablyai/orca.git
synced 2026-10-17 16:02:55 +00:00
Carry the worktree head on PR-refresh candidates so fallback preservation is head-gated
Live validation caught a self-sustaining loop the unit seams missed: the Checks panel passes its displayed PR number as the refresh fallback, and the candidate path carried no worktree head, so main preserved a merged branch PR head-blind — the merged view survived new local commits instead of yielding to 'No pull request found'. Thread currentHeadOid through GitHubPRRefreshCandidate, both renderer candidate builders, the gh:prForBranch IPC, and the runtime RPC method — the same shape the hosted-review path already used. Main's explicit-head gate (equality or confirmed commit membership) now applies to every renderer-driven lookup; true no-context callers keep the designed deleted-head preservation. Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -94,6 +94,28 @@ describe('pr-refresh-coordinator', () => {
|
||||
vi.useRealTimers()
|
||||
})
|
||||
|
||||
it('forwards the candidate worktree head into the branch lookup options', async () => {
|
||||
const { reportVisiblePRRefreshCandidates } = await import('./pr-refresh-coordinator')
|
||||
getPRForBranchOutcomeMock.mockResolvedValueOnce({
|
||||
kind: 'no-pr',
|
||||
fetchedAt: Date.now()
|
||||
})
|
||||
|
||||
reportVisiblePRRefreshCandidates([makeCandidate({ currentHeadOid: 'worktree-head-oid' })], 1, 1)
|
||||
await vi.runOnlyPendingTimersAsync()
|
||||
|
||||
// Why: without the head, a panel-supplied fallback number preserves a
|
||||
// merged PR head-blind after the branch moves on to new work.
|
||||
expect(getPRForBranchOutcomeMock).toHaveBeenCalledWith(
|
||||
'/repo',
|
||||
'feature/test',
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
expect.objectContaining({ currentHeadOid: 'worktree-head-oid' })
|
||||
)
|
||||
})
|
||||
|
||||
it('does not show visible background refreshes as queued', async () => {
|
||||
const { reportVisiblePRRefreshCandidates } = await import('./pr-refresh-coordinator')
|
||||
getPRForBranchOutcomeMock.mockResolvedValueOnce({
|
||||
|
||||
@@ -34,7 +34,7 @@ type PRRefreshOutcomeObserver = (
|
||||
|
||||
type PRBranchLookupCandidate = Pick<
|
||||
GitHubPRRefreshCandidate,
|
||||
'localGitOptions' | 'linkedPRNumber' | 'fallbackPRNumber' | 'fallbackPRSource'
|
||||
'localGitOptions' | 'linkedPRNumber' | 'fallbackPRNumber' | 'fallbackPRSource' | 'currentHeadOid'
|
||||
>
|
||||
|
||||
function shouldAcceptMergedFallbackPR(candidate: PRBranchLookupCandidate): boolean {
|
||||
@@ -55,6 +55,9 @@ function hostedReviewOptionArgs(
|
||||
if (shouldAcceptMergedFallbackPR(candidate)) {
|
||||
options.acceptMergedFallbackPR = true
|
||||
}
|
||||
if (typeof candidate.currentHeadOid === 'string' && candidate.currentHeadOid.trim().length > 0) {
|
||||
options.currentHeadOid = candidate.currentHeadOid
|
||||
}
|
||||
return Object.keys(options).length > 0 ? [options] : []
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user