mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 18:37:24 +00:00
* Keep opened GitHub work items bound to their exact repository * Bind GitHub work item ownership through consumers and dispatch * Keep empty mention lists from consuming selection keys * Preserve GitHub action and consumer ownership across resource changes * Exercise repository account updates through their production store action * Exercise account publication and cache settlement through GitHub consumers * Simplify fork PR contract verification * Make contract verification imports and clocks deterministic * Correct mobile task test fixtures and model types * Correct task recording fixtures and CI types * Correct task fixture types and static checks * Consolidate replay test RPC imports * Separate GitHub metadata imports from Linear hooks * Scope mobile PR sidebar reads to the selected resource * Separate desktop GitHub changes from phone updates * Fix relay authority probe census across topology cases * Repair repository owner proof fixtures and compiler allocation * Preserve repository row observation in host lookup * Seed metadata fixture before server-side store acquisition * Preserve nullable fixture settings and discover mixed test types * Preserve GitHub detail argument types and optional capabilities * Let keyed details queries own pending read replacement * Repair GitHub RPC and relay test fixture boundaries * Verify expected GitHub account at repository execution capture * Preserve captured GitHub account expectations through client dispatch * Retain observed runtime status after switching environments * Fix account contract fixture types and RPC setup timing * Restore the negative-capability switch probe assertion * Align account fixtures with runtime identity and configured origin * Consolidate details test imports * Drop duplicate fork pull request identity tests
128 lines
3.3 KiB
TypeScript
128 lines
3.3 KiB
TypeScript
import type { GhAccountBinding } from '../../shared/github/account-binding'
|
|
import type { GitHubAssignableUser, GitHubOwnerRepo } from '../../shared/github/pull-request-types'
|
|
import type { IssueSourcePreference } from '../../shared/repo-types'
|
|
import type { LocalGitExecOptions } from './gh-utils'
|
|
import {
|
|
resolveGitHubRepoExecution,
|
|
resolveIssueGitHubApiRepositorySource
|
|
} from './github-api-repository'
|
|
import { acquire, ghExecFileAsync, release } from './gh-utils'
|
|
|
|
export async function listLabels(
|
|
repoPath: string,
|
|
preference?: IssueSourcePreference,
|
|
connectionId?: string | null,
|
|
localGitOptions: LocalGitExecOptions = {},
|
|
repositoryOverride?: GitHubOwnerRepo | null,
|
|
expectedGhAccount?: GhAccountBinding | null
|
|
): Promise<string[]> {
|
|
const { ownerRepo, ghOptions } = await resolveGitHubRepoExecution(
|
|
repoPath,
|
|
repositoryOverride ??
|
|
(async () =>
|
|
(
|
|
await resolveIssueGitHubApiRepositorySource(
|
|
repoPath,
|
|
preference,
|
|
connectionId,
|
|
localGitOptions
|
|
)
|
|
).source),
|
|
connectionId,
|
|
localGitOptions,
|
|
expectedGhAccount
|
|
)
|
|
if (!ownerRepo) {
|
|
return []
|
|
}
|
|
await acquire()
|
|
try {
|
|
const { stdout } = await ghExecFileAsync(
|
|
[
|
|
'api',
|
|
'--paginate',
|
|
`repos/${ownerRepo.owner}/${ownerRepo.repo}/labels`,
|
|
'--jq',
|
|
'.[].name'
|
|
],
|
|
ghOptions
|
|
)
|
|
return stdout
|
|
.trim()
|
|
.split('\n')
|
|
.filter((l) => l.length > 0)
|
|
} catch {
|
|
return []
|
|
} finally {
|
|
release()
|
|
}
|
|
}
|
|
|
|
export async function listAssignableUsers(
|
|
repoPath: string,
|
|
preference?: IssueSourcePreference,
|
|
connectionId?: string | null,
|
|
localGitOptions: LocalGitExecOptions = {},
|
|
repositoryOverride?: GitHubOwnerRepo | null,
|
|
expectedGhAccount?: GhAccountBinding | null
|
|
): Promise<GitHubAssignableUser[]> {
|
|
const { ownerRepo, ghOptions } = await resolveGitHubRepoExecution(
|
|
repoPath,
|
|
repositoryOverride ??
|
|
(async () =>
|
|
(
|
|
await resolveIssueGitHubApiRepositorySource(
|
|
repoPath,
|
|
preference,
|
|
connectionId,
|
|
localGitOptions
|
|
)
|
|
).source),
|
|
connectionId,
|
|
localGitOptions,
|
|
expectedGhAccount
|
|
)
|
|
if (!ownerRepo) {
|
|
return []
|
|
}
|
|
await acquire()
|
|
try {
|
|
// REST pagination covers all assignees; jq emits NDJSON instead of concatenated page arrays.
|
|
const { stdout } = await ghExecFileAsync(
|
|
[
|
|
'api',
|
|
'--paginate',
|
|
`repos/${ownerRepo.owner}/${ownerRepo.repo}/assignees?per_page=100`,
|
|
'--jq',
|
|
'.[] | {login, avatar_url}'
|
|
],
|
|
ghOptions
|
|
)
|
|
type RESTAssignee = { login?: string; avatar_url?: string | null }
|
|
const users: GitHubAssignableUser[] = []
|
|
for (const line of stdout.split('\n')) {
|
|
const trimmed = line.trim()
|
|
if (!trimmed) {
|
|
continue
|
|
}
|
|
try {
|
|
const user = JSON.parse(trimmed) as RESTAssignee
|
|
if (user.login) {
|
|
users.push({
|
|
login: user.login,
|
|
name: null,
|
|
avatarUrl: user.avatar_url ?? ''
|
|
})
|
|
}
|
|
} catch {
|
|
// Skip malformed NDJSON lines defensively.
|
|
}
|
|
}
|
|
return users
|
|
} catch {
|
|
return []
|
|
} finally {
|
|
release()
|
|
}
|
|
}
|