Files
orca/src/preload/api/github-pull-request-api.ts
T
Neil 77f23b013f refactor(shared): drop the shared/types barrel and import from the real modules (#14447)
#14397 split `shared/types.ts` into 46 per-domain modules but kept the path as
a re-export barrel so the import sites did not have to change. This removes
the barrel: every consumer now imports from the module that actually declares
the type, and `src/shared/types.ts` is deleted.

Barrels hide where a type lives, make every consumer look like it depends on
the whole domain, and let an unrelated edit invalidate a module that ~2,000
files transitively import.

2,323 import declarations across 2,321 files. Rewritten mechanically: each
specifier was resolved to an absolute path via the TypeScript AST and
recomputed, rather than string-substituted, so alias forms (`@/../../shared/
types`) and per-specifier `type` modifiers survive.

Four cases the mechanical pass had to handle, each found by a gate rather than
by reading the diff:

- Modules inside `src/shared` import the barrel as `./types`, not
  `shared/types`. A pre-filter on the latter string skipped 176 of them and
  left imports dangling at a deleted file, which surfaced as confusing
  `Property 'x' is optional in type 'Repo' but required in Pick<Repo, ...>`
  errors rather than "module not found".
- The barrel RENAMED one type on the way through
  (`WorkspaceSource as WorkspaceCreateTelemetrySource`), so the original name
  in the owning module has to be re-aliased at each consumer.
- Three test files put `;(globalThis as ...)` on the line after the import.
  TypeScript parses that `;` as the import statement's terminator, so
  replacing through `statement.getEnd()` deletes it and breaks ASI. The
  rewrite now stops at the module specifier.
- A file that already imported directly from a module got a SECOND import
  from it, because the barrel re-exported those same names — which trips
  `import/no-duplicates` under `--deny-warnings`. A post-pass merges
  declarations sharing a specifier and type-only-ness; the `import type` plus
  `import` pair from one module is left alone, since that form is allowed.

Splitting one barrel import into several genuinely adds lines, which pushed
`terminal-layout-pty-ownership.ts` to 301 counted lines: its 107-character
import must wrap, and neither local type collapses onto one line (101 and 116
characters). Rather than contort a type declaration to fit a line budget,
`collectLeafIds` and `pruneLeaves` move to `terminal-pane-layout-tree.ts` —
they are pure structural operations on the layout tree and independent of PTY
ownership. `visible-worktrees.ts` similarly loses its own mini-barrel
re-export of `isDefaultBranchWorkspace`, with the four real consumers
repointed at the declaring module. No `max-lines` bypass added.

Verified: cold `tsc --noEmit` green on node, cli, and web (buildinfo deleted
first — these projects are `composite: true` and reuse stale caches); the full
`pnpm lint` green, not just bare oxlint — the narrower local check is what let
the duplicate imports reach CI; max-lines ratchet OK at 344.
2026-08-13 22:48:24 -07:00

200 lines
6.2 KiB
TypeScript

import type { AppStarSource } from '../../shared/gh-star-source'
import type { GhAuthDiagnostic } from '../../shared/github/auth-types'
import type { TaskSourceContext } from '../../shared/task-source-context'
import type { PRCheckDetail, PRCheckRunDetails } from '../../shared/github/check-types'
import type {
GitHubCommentResult,
GitHubPRReviewCommentInput,
GitHubReactionContent,
PRComment
} from '../../shared/github/comment-types'
import type {
GitHubPRRefreshCandidate,
GitHubPRRefreshEnqueueResult,
GitHubPRRefreshEvent,
GitHubPRRefreshReason,
PRRefreshOutcome
} from '../../shared/github/pull-request-refresh-types'
import type {
GitHubOwnerRepo,
GitHubPRFile,
GitHubPRFileContents,
GitHubViewer,
PRInfo
} from '../../shared/github/pull-request-types'
import type { GetRateLimitResult } from '../../shared/github/rate-limit-types'
import type { GitHubRepoSelectorArgs } from './github-work-item-api'
export type GithubPullRequestApi = {
viewer: () => Promise<GitHubViewer | null>
repoSlug: (args: {
repoPath: string
repoId?: string
}) => Promise<{ owner: string; repo: string; host?: string } | null>
repoUpstream: (args: {
repoPath: string
repoId?: string
}) => Promise<{ owner: string; repo: string; host?: string } | null>
prForBranch: (args: {
repoPath: string
repoId?: string
branch: string
linkedPRNumber?: number | null
fallbackPRNumber?: number | null
acceptMergedFallbackPR?: boolean
currentHeadOid?: string | null
}) => Promise<PRInfo | null>
refreshPRNow: (args: { candidate: GitHubPRRefreshCandidate }) => Promise<PRRefreshOutcome>
enqueuePRRefresh: (args: {
candidate: GitHubPRRefreshCandidate
reason: GitHubPRRefreshReason
priority?: number
}) => Promise<GitHubPRRefreshEnqueueResult | false>
reportVisiblePRRefreshCandidates: (args: {
candidates: GitHubPRRefreshCandidate[]
generation: number
}) => Promise<boolean>
onPRRefreshEvent: (callback: (event: GitHubPRRefreshEvent) => void) => () => void
prFileContents: (
args: GitHubRepoSelectorArgs & {
prNumber: number
prRepo?: GitHubOwnerRepo | null
path: string
oldPath?: string
status: GitHubPRFile['status']
headSha: string
baseSha: string
}
) => Promise<GitHubPRFileContents>
prChecks: (
args: GitHubRepoSelectorArgs & {
prNumber: number
headSha?: string
prRepo?: GitHubOwnerRepo | null
noCache?: boolean
}
) => Promise<PRCheckDetail[]>
prCheckDetails: (args: {
repoPath: string
repoId?: string
sourceContext?: TaskSourceContext | null
checkRunId?: number
workflowRunId?: number
checkName?: string
url?: string | null
prRepo?: GitHubOwnerRepo | null
}) => Promise<PRCheckRunDetails | null>
rerunPRChecks: (
args: GitHubRepoSelectorArgs & {
prNumber: number
headSha?: string
failedOnly?: boolean
prRepo?: GitHubOwnerRepo | null
}
) => Promise<{ ok: true; count: number } | { ok: false; error: string }>
prComments: (args: {
repoPath: string
repoId?: string
sourceContext?: TaskSourceContext | null
prNumber: number
prRepo?: GitHubOwnerRepo | null
noCache?: boolean
}) => Promise<PRComment[]>
setPRCommentReaction: (args: {
repoPath: string
repoId?: string
sourceContext?: TaskSourceContext | null
reactionSubjectId: string
content: GitHubReactionContent
reacted: boolean
prRepo?: GitHubOwnerRepo | null
}) => Promise<boolean>
resolveReviewThread: (args: {
repoPath: string
repoId?: string
sourceContext?: TaskSourceContext | null
threadId: string
resolve: boolean
prRepo?: GitHubOwnerRepo | null
}) => Promise<boolean>
setPRFileViewed: (
args: GitHubRepoSelectorArgs & {
prNumber: number
prRepo?: GitHubOwnerRepo | null
pullRequestId: string
path: string
viewed: boolean
}
) => Promise<boolean>
updatePRTitle: (args: {
repoPath: string
repoId?: string
prNumber: number
title: string
prRepo?: GitHubOwnerRepo | null
}) => Promise<boolean>
mergePR: (
args: GitHubRepoSelectorArgs & {
prNumber: number
method?: 'merge' | 'squash' | 'rebase'
prRepo?: GitHubOwnerRepo | null
}
) => Promise<{ ok: true } | { ok: false; error: string }>
setPRAutoMerge: (
args: GitHubRepoSelectorArgs & {
prNumber: number
enabled: boolean
method?: 'merge' | 'squash' | 'rebase'
prRepo?: GitHubOwnerRepo | null
}
) => Promise<{ ok: true } | { ok: false; error: string }>
updatePRState: (
args: GitHubRepoSelectorArgs & {
prNumber: number
updates: { state: 'open' | 'closed' }
prRepo?: GitHubOwnerRepo | null
}
) => Promise<{ ok: true } | { ok: false; error: string }>
requestPRReviewers: (
args: GitHubRepoSelectorArgs & {
prNumber: number
reviewers: string[]
prRepo?: GitHubOwnerRepo | null
}
) => Promise<{ ok: true } | { ok: false; error: string }>
removePRReviewers: (
args: GitHubRepoSelectorArgs & {
prNumber: number
reviewers: string[]
prRepo?: GitHubOwnerRepo | null
}
) => Promise<{ ok: true } | { ok: false; error: string }>
addPRReviewCommentReply: (
args: GitHubRepoSelectorArgs & {
prNumber: number
commentId: number
body: string
threadId?: string
path?: string
line?: number
prRepo?: GitHubOwnerRepo | null
}
) => Promise<GitHubCommentResult>
addPRReviewComment: (
args: GitHubPRReviewCommentInput & {
repoId?: string
sourceContext?: TaskSourceContext | null
}
) => Promise<GitHubCommentResult>
checkOrcaStarred: () => Promise<boolean | null>
starOrca: (source: AppStarSource) => Promise<boolean>
/**
* GitHub API rate-limit snapshot. Does NOT consume quota (the
* `rate_limit` endpoint is exempt). Cached 30s server-side — pass
* `force: true` to bust after a known-expensive op.
*/
rateLimit: (args?: { force?: boolean }) => Promise<GetRateLimitResult>
/** Explains scope_missing ProjectV2 failures — notably a shell `GITHUB_TOKEN` shadowing the keyring credential, where `gh auth refresh` is a no-op. */
diagnoseAuth: (args?: { host?: string }) => Promise<GhAuthDiagnostic>
}