import type { GitBranchCompareResult, GitCommitCompareResult, GitDiffResult } from '../../shared/git-diff-compare-types' import { assertGitDiffWithinTransportBudget } from '../../shared/git-diff-transport-budget' import { getBranchDiff } from '../git/status' import type { GitAdmissionTier } from '../git/command-runner/git-exec-options' import { normalizeRuntimeRelativePath } from './runtime-relative-paths' import { localGitOptionsForTarget, normalizeRuntimeGitRelativePath, requireLocalRuntimeGitRoute, requireRuntimeGitProvider, type RuntimeGitCommandHost } from './runtime-git-command-target' export class RuntimeGitDiffCommands { constructor(private readonly host: RuntimeGitCommandHost) {} // Why: cap the payload after execution-host dispatch. async getRuntimeGitDiff( worktreeSelector: string, filePath: string, staged: boolean, compareAgainstHead?: boolean, maxContentBytes?: number ): Promise { const target = await this.host.resolveRuntimeGitTarget(worktreeSelector) const relativePath = normalizeRuntimeGitRelativePath(filePath) return assertGitDiffWithinTransportBudget( await requireRuntimeGitProvider(target).getDiff( target.worktree.path, relativePath, staged, compareAgainstHead ), maxContentBytes ) } async getRuntimeGitBranchCompare( worktreeSelector: string, baseRef: string, admissionTier: GitAdmissionTier = 'interactive' ): Promise { const target = await this.host.resolveRuntimeGitTarget(worktreeSelector) return requireRuntimeGitProvider(target).getBranchCompare(target.worktree.path, baseRef, { admissionTier }) } async getRuntimeGitCommitCompare( worktreeSelector: string, commitId: string ): Promise { const target = await this.host.resolveRuntimeGitTarget(worktreeSelector) return requireRuntimeGitProvider(target).getCommitCompare(target.worktree.path, commitId) } async getRuntimeGitBranchDiff( worktreeSelector: string, compare: { mergeBase: string; headOid: string }, filePath: string, oldPath?: string, maxContentBytes?: number ): Promise { const target = await this.host.resolveRuntimeGitTarget(worktreeSelector) const relativePath = normalizeRuntimeGitRelativePath(filePath) const oldRelativePath = oldPath ? normalizeRuntimeGitRelativePath(oldPath) : undefined requireLocalRuntimeGitRoute(target) return assertGitDiffWithinTransportBudget( await getBranchDiff( target.worktree.path, { mergeBase: compare.mergeBase, headOid: compare.headOid, filePath: relativePath, oldPath: oldRelativePath }, { ...localGitOptionsForTarget(target), admissionTier: 'interactive' } ), maxContentBytes ) } async getRuntimeGitCommitDiff( worktreeSelector: string, args: { commitOid: string; parentOid?: string | null; filePath: string; oldPath?: string }, maxContentBytes?: number ): Promise { const target = await this.host.resolveRuntimeGitTarget(worktreeSelector) const relativePath = normalizeRuntimeRelativePath(args.filePath) const oldRelativePath = args.oldPath ? normalizeRuntimeRelativePath(args.oldPath) : undefined return assertGitDiffWithinTransportBudget( await requireRuntimeGitProvider(target).getCommitDiff(target.worktree.path, { commitOid: args.commitOid, parentOid: args.parentOid, filePath: relativePath, oldPath: oldRelativePath }), maxContentBytes ) } async getRuntimeGitRemoteFileUrl( worktreeSelector: string, relativePath: string, line: number ): Promise { const target = await this.host.resolveRuntimeGitTarget(worktreeSelector) const normalizedRelativePath = normalizeRuntimeGitRelativePath(relativePath) return requireRuntimeGitProvider(target).getRemoteFileUrl( target.worktree.path, normalizedRelativePath, line ) } async getRuntimeGitRemoteCommitUrl( worktreeSelector: string, sha: string ): Promise { const target = await this.host.resolveRuntimeGitTarget(worktreeSelector) return requireRuntimeGitProvider(target).getRemoteCommitUrl(target.worktree.path, sha) } }