mirror of
https://github.com/stablyai/orca.git
synced 2026-10-24 08:03:58 +00:00
#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.
208 lines
5.8 KiB
TypeScript
208 lines
5.8 KiB
TypeScript
import type {
|
|
CheckStatus,
|
|
GitHubRepositoryIdentity,
|
|
PRConflictSummary,
|
|
PRMergeableState,
|
|
PRReviewDecision
|
|
} from './github/pull-request-types'
|
|
|
|
export type HostedReviewProvider =
|
|
| 'github'
|
|
| 'gitlab'
|
|
| 'bitbucket'
|
|
| 'azure-devops'
|
|
| 'gitea'
|
|
| 'unsupported'
|
|
|
|
export type HostedReviewState = 'open' | 'closed' | 'merged' | 'draft'
|
|
|
|
// Why: Bitbucket Cloud's API has no draft pull requests, so offering the toggle
|
|
// there would either publish a live PR or fail at submit.
|
|
export function hostedReviewProviderSupportsDraft(provider: HostedReviewProvider): boolean {
|
|
return provider !== 'bitbucket'
|
|
}
|
|
|
|
/** A linked review is identified by a positive integer PR/MR number. */
|
|
export function isPositiveHostedReviewNumber(value: unknown): value is number {
|
|
return typeof value === 'number' && Number.isInteger(value) && value > 0
|
|
}
|
|
|
|
export type HostedReviewInfo = {
|
|
provider: HostedReviewProvider
|
|
number: number
|
|
title: string
|
|
state: HostedReviewState
|
|
url: string
|
|
status: CheckStatus
|
|
updatedAt: string
|
|
mergeable: PRMergeableState
|
|
reviewDecision?: PRReviewDecision | null
|
|
autoMergeEnabled?: boolean
|
|
autoMergeAllowed?: boolean | null
|
|
mergeQueueRequired?: boolean | null
|
|
mergeStateStatus?: string | null
|
|
headSha?: string
|
|
/** GitHub repository that owns the PR; absent on older runtimes and other providers. */
|
|
githubRepository?: GitHubRepositoryIdentity
|
|
// Why: mirrors PRInfo.confirmedContainedHeadOid so merged-review staleness
|
|
// checks accept a worktree head confirmed to be part of the merged PR.
|
|
confirmedContainedHeadOid?: string
|
|
/** Target branch name for review-created worktree compare-base repair. */
|
|
baseRefName?: string
|
|
conflictSummary?: PRConflictSummary
|
|
}
|
|
|
|
export type HostedReviewForBranchArgs = {
|
|
repoPath: string
|
|
repoId?: string
|
|
branch: string
|
|
linkedGitHubPR?: number | null
|
|
fallbackGitHubPR?: number | null
|
|
linkedGitLabMR?: number | null
|
|
linkedBitbucketPR?: number | null
|
|
linkedAzureDevOpsPR?: number | null
|
|
linkedGiteaPR?: number | null
|
|
// The worktree's checked-out HEAD oid (GitHub merged-at-head visibility).
|
|
currentHeadOid?: string | null
|
|
/**
|
|
* Set only by surfaces scoped to the selected worktree. That tier is O(1), so
|
|
* the host re-checks it per minute; the worktree list is O(N) and is paced far
|
|
* more slowly to stay inside the shared API budget (#11532).
|
|
*/
|
|
active?: boolean
|
|
}
|
|
|
|
export type HostedReviewSummary = {
|
|
number?: number
|
|
url: string
|
|
}
|
|
|
|
export type CreateHostedReviewInput = {
|
|
provider: HostedReviewProvider
|
|
base: string
|
|
head?: string
|
|
title: string
|
|
body?: string
|
|
draft?: boolean
|
|
worktreePath?: string
|
|
useTemplate?: boolean
|
|
}
|
|
|
|
export type CreateHostedReviewArgs = CreateHostedReviewInput & {
|
|
repoPath: string
|
|
repoId?: string
|
|
connectionId?: string | null
|
|
}
|
|
|
|
export type CreateStackedHostedReviewInput = CreateHostedReviewInput
|
|
|
|
export type CreateStackedHostedReviewArgs = CreateStackedHostedReviewInput & {
|
|
repoPath: string
|
|
repoId?: string
|
|
connectionId?: string | null
|
|
}
|
|
|
|
export type CreateHostedReviewErrorCode =
|
|
| 'auth_required'
|
|
| 'unsupported_provider'
|
|
| 'already_exists'
|
|
| 'validation'
|
|
| 'timeout'
|
|
| 'unknown_completion'
|
|
| 'push_failed'
|
|
| 'unknown'
|
|
|
|
export type CreateHostedReviewResult =
|
|
| { ok: true; number: number; url: string }
|
|
| {
|
|
ok: false
|
|
code: CreateHostedReviewErrorCode
|
|
error: string
|
|
existingReview?: HostedReviewSummary
|
|
}
|
|
|
|
export type CreateStackedHostedReviewResult =
|
|
| {
|
|
ok: true
|
|
number: number
|
|
url: string
|
|
stackNumber: number
|
|
parentReview: HostedReviewSummary
|
|
}
|
|
| {
|
|
ok: false
|
|
code: CreateHostedReviewErrorCode
|
|
error: string
|
|
createdReview?: HostedReviewSummary
|
|
}
|
|
|
|
export type HostedReviewCreationBlockedReason =
|
|
| 'dirty'
|
|
| 'detached_head'
|
|
| 'default_branch'
|
|
| 'no_upstream'
|
|
| 'needs_push'
|
|
| 'needs_sync'
|
|
| 'auth_required'
|
|
| 'fork_head_unsupported'
|
|
| 'unsupported_provider'
|
|
| 'existing_review'
|
|
// Why: a stacked worktree's local-only parent base is unresolvable on the
|
|
// remote; blocked at create-time so the submit fails with actionable copy
|
|
// instead of the provider's opaque error.
|
|
| 'base_not_on_remote'
|
|
| null
|
|
|
|
export type HostedReviewCreationNextAction =
|
|
| 'commit'
|
|
| 'publish'
|
|
| 'push'
|
|
| 'sync'
|
|
| 'authenticate'
|
|
| 'open_existing_review'
|
|
| null
|
|
|
|
/**
|
|
* Records whether the eligibility result observed an authoritative existing-review
|
|
* lookup. `found` / `not_found` come only from an accepted provider lookup;
|
|
* `unavailable` marks a local-blocker fallback returned after a swallowed or
|
|
* skipped lookup, so it can never masquerade as authoritative no-review evidence.
|
|
*/
|
|
export type HostedReviewLookupOutcome = 'found' | 'not_found' | 'unavailable'
|
|
|
|
export type HostedReviewCreationEligibility = {
|
|
provider: HostedReviewProvider
|
|
review: HostedReviewSummary | null
|
|
canCreate: boolean
|
|
blockedReason: HostedReviewCreationBlockedReason
|
|
nextAction: HostedReviewCreationNextAction
|
|
reviewLookupOutcome: HostedReviewLookupOutcome
|
|
defaultBaseRef?: string | null
|
|
head?: string | null
|
|
title?: string | null
|
|
body?: string | null
|
|
/** Present only when the executing host supports GitHub stack creation. */
|
|
stackedCreationSupported?: boolean
|
|
}
|
|
|
|
export type HostedReviewCreationEligibilityArgs = {
|
|
repoPath: string
|
|
repoId?: string
|
|
worktreePath?: string
|
|
connectionId?: string | null
|
|
branch: string
|
|
base?: string | null
|
|
hasUncommittedChanges?: boolean
|
|
hasUpstream?: boolean
|
|
ahead?: number
|
|
behind?: number
|
|
linkedGitHubPR?: number | null
|
|
fallbackGitHubPR?: number | null
|
|
linkedGitLabMR?: number | null
|
|
linkedBitbucketPR?: number | null
|
|
linkedAzureDevOpsPR?: number | null
|
|
linkedGiteaPR?: number | null
|
|
}
|
|
|
|
export type HostedReviewDecision = 'approved' | 'changes_requested' | 'review_required' | null
|