mirror of
https://github.com/stablyai/orca.git
synced 2026-10-21 16:03:26 +00:00
* fix(github): align PR source and review head origin * fix(github): pin number-based work item open to the repo source preference Open-by-number and details still ran the upstream-first multi-candidate PR probe, so a fork and its upstream sharing a PR number opened different PRs than the list and start-point paths did once #10677 pinned those to origin. Thread repo.issueSourcePreference through dispatchWorkItem, getWorkItemDetails, getRepoWorkItem, and getRepoWorkItemDetails. getWorkItemByOwnerRepo is left alone: explicit owner/repo already pins identity. auto/upstream/undefined keep the multi-candidate probe. Co-authored-by: Orca <help@stably.ai> * test(github): enforce origin preference in review head origin resolution The explicit origin preference must short-circuit before any identity probe, so no remote queries should occur. Add validation to reject unexpected remotes and tighten the test assertion to verify no remote get-url calls happen at all. * fix(github): enforce origin preference in issue open-by-number lookup listWorkItems and getWorkItem must share preference so origin/upstream toggles cannot disagree. Explicit origin preference now fail-closes when origin identity is unresolved (no bare-lookup fallback), matching the PR candidate resolution rule. --------- Co-authored-by: Orca <help@stably.ai>
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import type { TaskSourceContext } from '../../shared/task-source-context'
|
|
import type { IssueSourcePreference } from '../../shared/types'
|
|
|
|
export type WorkItemArgs = {
|
|
repoPath: string
|
|
repoId?: string | null
|
|
sourceContext?: TaskSourceContext | null
|
|
number: number
|
|
type?: 'issue' | 'pr'
|
|
}
|
|
|
|
type RegisteredRepoContext = {
|
|
path: string
|
|
connectionId?: string | null
|
|
issueSourcePreference?: IssueSourcePreference
|
|
}
|
|
|
|
type LocalGitExecOptions = {
|
|
wslDistro?: string
|
|
}
|
|
|
|
// Why: renderer input crosses the IPC boundary and is untrusted. Reject
|
|
// non-integer or < 1 numbers, and coerce unrecognised `type` values to
|
|
// undefined so getWorkItem falls through to its issue-then-PR probe rather
|
|
// than silently dispatching to the wrong branch.
|
|
export function dispatchWorkItem<T>(
|
|
args: WorkItemArgs,
|
|
repo: RegisteredRepoContext,
|
|
fn: (
|
|
path: string,
|
|
n: number,
|
|
t?: 'issue' | 'pr',
|
|
connectionId?: string | null,
|
|
localGitOptions?: LocalGitExecOptions,
|
|
preference?: IssueSourcePreference
|
|
) => Promise<T | null>,
|
|
localGitOptions?: LocalGitExecOptions
|
|
): Promise<T | null> | null {
|
|
const { number, type } = args
|
|
if (typeof number !== 'number' || !Number.isInteger(number) || number < 1) {
|
|
return null
|
|
}
|
|
const safeType = type === 'issue' || type === 'pr' ? type : undefined
|
|
// Why: open-by-number must pin the same source the list and start-point use,
|
|
// else a fork and its upstream sharing a PR number resolve to different PRs.
|
|
return fn(
|
|
repo.path,
|
|
number,
|
|
safeType,
|
|
repo.connectionId ?? null,
|
|
localGitOptions,
|
|
repo.issueSourcePreference
|
|
)
|
|
}
|