@jaydenfyi/diffx 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-5FPIcmTx.mjs","names":["exitCode: ExitCode","cleanupRefs","fetchError: Error | null","mergeBase","mergeBase: string","hasActiveFilters","hasUnfilteredChanges","tokens: string[]","quote: \"'\" | '\"' | null","env: Record<string, string | undefined>","DIFFX_SHORT_FLAG_ALIASES: Record<string, DiffxOwnedFlag>","parseFlagName","diffxFlags: PartitionedArgs[\"diffxFlags\"]","gitArgs: string[]","pathspecs: string[]","inputRange: string | undefined","i","conflictingFlags: string[]","patterns: string[]","hasActiveFilters","color: \"always\" | \"never\"","cleanup: (() => Promise<void>) | undefined","parsed: ReturnType<typeof parseRangeInput> | undefined","gitDiffArgs: string[]","chunks: string[]","statLines: string[]","cleanNoIndexPath","map: StatusMap","filePath","rows: StatRow[]","summary: StatSummary","extraRows: StatRow[]","extraSummary: StatSummary","combinedSummary: StatSummary"],"sources":["../src/types.ts","../src/parsers/range/github-parser.ts","../src/parsers/range/git-url-parser.ts","../src/parsers/range/gitlab-parser.ts","../src/parsers/range/ref-range-parser.ts","../src/parsers/range-parser.ts","../src/git/git-client.ts","../src/git/utils.ts","../src/resolvers/local-ref-resolver.ts","../src/resolvers/remote-ref-resolver.ts","../src/resolvers/pr-url-resolver.ts","../src/resolvers/git-url-resolver.ts","../src/resolvers/gitlab-mr-resolver.ts","../src/resolvers/ref-resolver.ts","../src/resolvers/auto-base-resolver.ts","../src/output/patch-generator.ts","../src/output/output-factory.ts","../src/errors/error-handler.ts","../src/cli/pager.ts","../src/cli/arg-partitioner.ts","../src/filters/file-filter.ts","../src/cli/command-options.ts","../src/cli/git-pass-through.ts","../src/utils/overview-utils.ts","../src/cli/worktree-output.ts","../src/cli/command.ts"],"sourcesContent":["/**\n * Shared types for diffx\n */\n\n/** Output mode for diff/patch generation */\nexport type OutputMode =\n\t| \"diff\"\n\t| \"patch\"\n\t| \"stat\"\n\t| \"numstat\"\n\t| \"shortstat\"\n\t| \"name-only\"\n\t| \"name-status\"\n\t| \"summary\";\n\n/** Patch generation strategy */\nexport type PatchStyle = \"format-patch\" | \"diff\";\n\n/** Type of Git reference input */\nexport type RefType =\n\t| \"local-range\"\n\t| \"remote-range\"\n\t| \"pr-ref\"\n\t| \"github-url\"\n\t| \"pr-range\"\n\t| \"git-url-range\"\n\t| \"github-commit-url\"\n\t| \"github-pr-changes-url\"\n\t| \"github-compare-url\"\n\t| \"gitlab-mr-ref\";\n\n/** Parsed reference range */\nexport interface RefRange {\n\ttype: RefType;\n\tleft: string;\n\tright: string;\n\t/** Owner/repo for remote refs (e.g., \"octocat/Hello-World\") */\n\townerRepo?: string;\n\t/** PR/MR number for PR/MR refs */\n\tprNumber?: number;\n\t/** Left PR for PR range */\n\tleftPr?: GitHubPRUrl;\n\t/** Right PR for PR range */\n\trightPr?: GitHubPRUrl;\n\t/** Left MR for GitLab MR range */\n\tleftMr?: GitLabMRUrl;\n\t/** Right MR for GitLab MR range */\n\trightMr?: GitLabMRUrl;\n\t/** Left git URL for git-url-range */\n\tleftGitUrl?: string;\n\t/** Right git URL for git-url-range */\n\trightGitUrl?: string;\n\t/** Commit SHA for github-commit-url */\n\tcommitSha?: string;\n\t/** PR changes data for github-pr-changes-url */\n\tleftCommitSha?: string;\n\trightCommitSha?: string;\n\t/** Left ref for github-compare-url */\n\tleftRef?: string;\n\t/** Right ref for github-compare-url */\n\trightRef?: string;\n\t/** Right owner for cross-fork compare */\n\trightOwner?: string;\n\t/** Right repo for cross-fork compare */\n\trightRepo?: string;\n}\n\n/** Parsed GitHub PR URL */\nexport interface GitHubPRUrl {\n\towner: string;\n\trepo: string;\n\tprNumber: number;\n}\n\n/** Parsed GitLab MR URL */\nexport interface GitLabMRUrl {\n\towner: string;\n\trepo: string;\n\tmrNumber: number;\n}\n\n/** Parsed GitHub commit URL */\nexport interface GitHubCommitUrl {\n\towner: string;\n\trepo: string;\n\tcommitSha: string;\n}\n\n/** Parsed GitHub PR changes URL */\nexport interface GitHubPRChangesUrl {\n\towner: string;\n\trepo: string;\n\tprNumber: number;\n\tleftCommitSha: string;\n\trightCommitSha: string;\n}\n\n/** Parsed GitHub compare URL */\nexport interface GitHubCompareUrl {\n\towner: string;\n\trepo: string;\n\tleftRef: string;\n\trightRef: string;\n\trightOwner?: string; // For cross-fork comparisons\n\trightRepo?: string; // For cross-fork comparisons\n}\n\n/** File filter options */\nexport interface FilterOptions {\n\tinclude?: string[];\n\texclude?: string[];\n}\n\n/** CLI options */\nexport interface DiffxOptions {\n\tmode: OutputMode;\n\tinclude?: string | string[];\n\texclude?: string | string[];\n}\n\n/** Git operation result */\nexport interface GitResult {\n\tstdout: string;\n\texitCode: number;\n}\n\n/** Error types with exit codes */\nexport const ExitCode = {\n\tSUCCESS: 0,\n\tNO_FILES_MATCHED: 1,\n\tINVALID_INPUT: 2,\n\tGIT_ERROR: 3,\n} as const;\n\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];\n\n/** Custom error with exit code */\nexport class DiffxError extends Error {\n\t_tag = \"DiffxError\" as const;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly exitCode: ExitCode,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"DiffxError\";\n\t}\n}\n","import type {\n\tGitHubCommitUrl,\n\tGitHubCompareUrl,\n\tGitHubPRChangesUrl,\n\tGitHubPRUrl,\n} from \"../../types\";\n\nexport function parseGitHubPRUrl(input: string): GitHubPRUrl | null {\n\tconst match = input.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/pull\\/(\\d+)(\\/.*)?$/i);\n\tif (!match) return null;\n\n\treturn {\n\t\towner: match[1],\n\t\trepo: match[2],\n\t\tprNumber: parseInt(match[3], 10),\n\t};\n}\n\nexport function parseGitHubCommitUrl(input: string): GitHubCommitUrl | null {\n\tconst match = input.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/commit\\/([a-f0-9]+)$/i);\n\tif (!match) return null;\n\n\treturn {\n\t\towner: match[1],\n\t\trepo: match[2],\n\t\tcommitSha: match[3],\n\t};\n}\n\nexport function parseGitHubPRChangesUrl(input: string): GitHubPRChangesUrl | null {\n\tconst match = input.match(\n\t\t/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/pull\\/(\\d+)\\/changes\\/([a-f0-9]+)\\.\\.([a-f0-9]+)$/i,\n\t);\n\tif (!match) return null;\n\n\treturn {\n\t\towner: match[1],\n\t\trepo: match[2],\n\t\tprNumber: parseInt(match[3], 10),\n\t\tleftCommitSha: match[4],\n\t\trightCommitSha: match[5],\n\t};\n}\n\nexport function parseGitHubCompareUrl(input: string): GitHubCompareUrl | null {\n\tconst match = input.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/compare\\/(.+)\\.\\.\\.(.+)$/i);\n\tif (!match) return null;\n\n\tconst owner = match[1];\n\tconst repo = match[2];\n\tconst leftRef = match[3];\n\tconst rightRef = match[4];\n\n\tconst crossForkMatch = rightRef.match(/^([^:]+):([^:]+):(.+)$/);\n\tif (crossForkMatch) {\n\t\treturn {\n\t\t\towner,\n\t\t\trepo,\n\t\t\tleftRef,\n\t\t\trightRef: crossForkMatch[3],\n\t\t\trightOwner: crossForkMatch[1],\n\t\t\trightRepo: crossForkMatch[2],\n\t\t};\n\t}\n\n\tconst crossForkSlashMatch = rightRef.match(/^([^:]+):([^/]+)\\/(.+)$/);\n\tif (crossForkSlashMatch) {\n\t\treturn {\n\t\t\towner,\n\t\t\trepo,\n\t\t\tleftRef,\n\t\t\trightRef: crossForkSlashMatch[3],\n\t\t\trightOwner: crossForkSlashMatch[1],\n\t\t\trightRepo: crossForkSlashMatch[2],\n\t\t};\n\t}\n\n\treturn {\n\t\towner,\n\t\trepo,\n\t\tleftRef,\n\t\trightRef,\n\t};\n}\n\nexport function parsePRRef(input: string): GitHubPRUrl | null {\n\tconst match = /^github:([^/]+)\\/([^/]+)#(\\d+)$/i;\n\tconst result = input.match(match);\n\tif (!result) return null;\n\n\treturn {\n\t\towner: result[1],\n\t\trepo: result[2],\n\t\tprNumber: parseInt(result[3], 10),\n\t};\n}\n\nexport function parseGithubRefRange(\n\tinput: string,\n): { ownerRepo: string; left: string; right: string } | null {\n\tconst match = /^github:([^/]+)\\/([^@]+)@(.+)\\.\\.(.+)$/i;\n\tconst result = input.match(match);\n\tif (!result) return null;\n\n\tconst owner = result[1];\n\tconst repo = result[2];\n\tconst left = result[3].trim();\n\tconst right = result[4].trim();\n\n\tif (!owner || !repo || !left || !right) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\townerRepo: `${owner}/${repo}`,\n\t\tleft,\n\t\tright,\n\t};\n}\n\nexport function parsePRRange(input: string): { left: GitHubPRUrl; right: GitHubPRUrl } | null {\n\tif (!input.includes(\"..\")) return null;\n\tconst parts = input.split(\"..\");\n\tif (parts.length !== 2) return null;\n\tconst left = parseGitHubPRUrl(parts[0].trim()) ?? parsePRRef(parts[0].trim());\n\tconst right = parseGitHubPRUrl(parts[1].trim()) ?? parsePRRef(parts[1].trim());\n\tif (!left || !right) return null;\n\treturn { left, right };\n}\n","export function parseGitUrlRange(input: string): {\n\tleftUrl: string;\n\tleftRef: string;\n\trightUrl: string;\n\trightRef: string;\n} | null {\n\tconst isGitUrl = (s: string) => s.includes(\"://\") || (s.includes(\"@\") && s.includes(\":\"));\n\n\tconst doubleDotIndex = input.indexOf(\"..\");\n\tif (doubleDotIndex !== -1) {\n\t\tconst leftPart = input.slice(0, doubleDotIndex);\n\t\tconst rightPart = input.slice(doubleDotIndex + 2);\n\n\t\tconst lastAtLeft = leftPart.lastIndexOf(\"@\");\n\t\tconst lastAtRight = rightPart.lastIndexOf(\"@\");\n\n\t\tif (lastAtLeft !== -1 && lastAtRight !== -1) {\n\t\t\tconst leftUrl = leftPart.slice(0, lastAtLeft);\n\t\t\tconst leftRef = leftPart.slice(lastAtLeft + 1);\n\t\t\tconst rightUrl = rightPart.slice(0, lastAtRight);\n\t\t\tconst rightRef = rightPart.slice(lastAtRight + 1);\n\n\t\t\tif (isGitUrl(leftUrl) && isGitUrl(rightUrl)) {\n\t\t\t\treturn { leftUrl, leftRef, rightUrl, rightRef };\n\t\t\t}\n\t\t}\n\t}\n\n\tconst atBeforeDoubleDot = input.lastIndexOf(\"@\", input.indexOf(\"..\"));\n\tif (atBeforeDoubleDot !== -1 && input.includes(\"..\")) {\n\t\tconst url = input.slice(0, atBeforeDoubleDot);\n\t\tconst refPart = input.slice(atBeforeDoubleDot + 1);\n\t\tconst parts = refPart.split(\"..\");\n\t\tif (parts.length === 2 && isGitUrl(url)) {\n\t\t\treturn {\n\t\t\t\tleftUrl: url,\n\t\t\t\tleftRef: parts[0],\n\t\t\t\trightUrl: url,\n\t\t\t\trightRef: parts[1],\n\t\t\t};\n\t\t}\n\t}\n\n\treturn null;\n}\n","import type { GitLabMRUrl } from \"../../types\";\n\nexport function parseMRRef(input: string): GitLabMRUrl | null {\n\tconst match = /^gitlab:([^/]+)\\/([^/]+)!(\\d+)$/i;\n\tconst result = input.match(match);\n\tif (!result) return null;\n\n\treturn {\n\t\towner: result[1],\n\t\trepo: result[2],\n\t\tmrNumber: parseInt(result[3], 10),\n\t};\n}\n\nexport function parseGitlabRefRange(\n\tinput: string,\n): { ownerRepo: string; left: string; right: string } | null {\n\tconst match = /^gitlab:([^/]+)\\/([^@]+)@(.+)\\.\\.(.+)$/i;\n\tconst result = input.match(match);\n\tif (!result) return null;\n\n\tconst owner = result[1];\n\tconst repo = result[2];\n\tconst left = result[3].trim();\n\tconst right = result[4].trim();\n\n\tif (!owner || !repo || !left || !right) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\townerRepo: `${owner}/${repo}`,\n\t\tleft,\n\t\tright,\n\t};\n}\n","export function parseRemoteRefRange(input: string): {\n\tleft: string;\n\tright: string;\n\townerRepo: string;\n} | null {\n\tconst separatorIndex = input.indexOf(\"..\");\n\tif (separatorIndex === -1) {\n\t\treturn null;\n\t}\n\n\tconst leftPart = input.slice(0, separatorIndex).trim();\n\tconst rightPart = input.slice(separatorIndex + 2).trim();\n\n\tif (!leftPart || !rightPart) {\n\t\treturn null;\n\t}\n\n\tconst parseRemoteSide = (value: string): { owner: string; repo: string; ref: string } | null => {\n\t\tconst match = value.match(/^([^/]+)\\/([^@]+)@(.+)$/);\n\t\tif (!match) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst owner = match[1].trim();\n\t\tconst repo = match[2].trim();\n\t\tconst ref = match[3].trim();\n\t\tif (!owner || !repo || !ref) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn { owner, repo, ref };\n\t};\n\n\tconst left = parseRemoteSide(leftPart);\n\tif (!left) {\n\t\treturn null;\n\t}\n\n\tconst rightFull = parseRemoteSide(rightPart);\n\tif (rightFull) {\n\t\tif (rightFull.owner !== left.owner || rightFull.repo !== left.repo) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tleft: `${left.owner}/${left.repo}@${left.ref}`,\n\t\t\tright: `${rightFull.owner}/${rightFull.repo}@${rightFull.ref}`,\n\t\t\townerRepo: `${left.owner}/${left.repo}`,\n\t\t};\n\t}\n\n\treturn {\n\t\tleft: `${left.owner}/${left.repo}@${left.ref}`,\n\t\tright: `${left.owner}/${left.repo}@${rightPart}`,\n\t\townerRepo: `${left.owner}/${left.repo}`,\n\t};\n}\n\nexport function parseLocalRefRange(input: string): { left: string; right: string } | null {\n\tconst parts = input.split(\"..\");\n\tif (parts.length !== 2 || !parts[0] || !parts[1]) {\n\t\treturn null;\n\t}\n\treturn {\n\t\tleft: parts[0].trim(),\n\t\tright: parts[1].trim(),\n\t};\n}\n","/**\n * Range input parser for diffx\n * Parses various input formats into a RefRange\n */\n\nimport type { RefRange } from \"../types\";\nimport { DiffxError, ExitCode } from \"../types\";\nimport {\n\tparseGithubRefRange,\n\tparseGitHubCommitUrl,\n\tparseGitHubCompareUrl,\n\tparseGitHubPRChangesUrl,\n\tparseGitHubPRUrl,\n\tparsePRRange,\n\tparsePRRef,\n} from \"./range/github-parser\";\nimport { parseGitUrlRange } from \"./range/git-url-parser\";\nimport { parseGitlabRefRange, parseMRRef } from \"./range/gitlab-parser\";\nimport { parseLocalRefRange, parseRemoteRefRange } from \"./range/ref-range-parser\";\n\n/**\n * Parse a range input string into a RefRange\n */\nexport function parseRangeInput(input: string): RefRange {\n\tconst prRange = parsePRRange(input);\n\tif (prRange) {\n\t\treturn {\n\t\t\ttype: \"pr-range\",\n\t\t\tleft: \"\",\n\t\t\tright: \"\",\n\t\t\tleftPr: prRange.left,\n\t\t\trightPr: prRange.right,\n\t\t};\n\t}\n\n\tconst gitUrlRange = parseGitUrlRange(input);\n\tif (gitUrlRange) {\n\t\treturn {\n\t\t\ttype: \"git-url-range\",\n\t\t\tleft: gitUrlRange.leftRef,\n\t\t\tright: gitUrlRange.rightRef,\n\t\t\tleftGitUrl: gitUrlRange.leftUrl,\n\t\t\trightGitUrl: gitUrlRange.rightUrl,\n\t\t};\n\t}\n\n\tconst githubCompare = parseGitHubCompareUrl(input);\n\tif (githubCompare) {\n\t\treturn {\n\t\t\ttype: \"github-compare-url\",\n\t\t\tleft: \"\",\n\t\t\tright: \"\",\n\t\t\townerRepo: `${githubCompare.owner}/${githubCompare.repo}`,\n\t\t\tleftRef: githubCompare.leftRef,\n\t\t\trightRef: githubCompare.rightRef,\n\t\t\trightOwner: githubCompare.rightOwner,\n\t\t\trightRepo: githubCompare.rightRepo,\n\t\t};\n\t}\n\n\tconst githubPrChanges = parseGitHubPRChangesUrl(input);\n\tif (githubPrChanges) {\n\t\treturn {\n\t\t\ttype: \"github-pr-changes-url\",\n\t\t\tleft: \"\",\n\t\t\tright: \"\",\n\t\t\townerRepo: `${githubPrChanges.owner}/${githubPrChanges.repo}`,\n\t\t\tprNumber: githubPrChanges.prNumber,\n\t\t\tleftCommitSha: githubPrChanges.leftCommitSha,\n\t\t\trightCommitSha: githubPrChanges.rightCommitSha,\n\t\t};\n\t}\n\n\tconst githubPr = parseGitHubPRUrl(input);\n\tif (githubPr) {\n\t\treturn {\n\t\t\ttype: \"github-url\",\n\t\t\tleft: \"\", // Will be resolved later\n\t\t\tright: \"\",\n\t\t\townerRepo: `${githubPr.owner}/${githubPr.repo}`,\n\t\t\tprNumber: githubPr.prNumber,\n\t\t};\n\t}\n\n\tconst githubCommit = parseGitHubCommitUrl(input);\n\tif (githubCommit) {\n\t\treturn {\n\t\t\ttype: \"github-commit-url\",\n\t\t\tleft: \"\",\n\t\t\tright: \"\",\n\t\t\townerRepo: `${githubCommit.owner}/${githubCommit.repo}`,\n\t\t\tcommitSha: githubCommit.commitSha,\n\t\t};\n\t}\n\n\tconst githubRefRange = parseGithubRefRange(input);\n\tif (githubRefRange) {\n\t\tconst gitUrl = `git@github.com:${githubRefRange.ownerRepo}.git`;\n\t\treturn {\n\t\t\ttype: \"git-url-range\",\n\t\t\tleft: githubRefRange.left,\n\t\t\tright: githubRefRange.right,\n\t\t\tleftGitUrl: gitUrl,\n\t\t\trightGitUrl: gitUrl,\n\t\t};\n\t}\n\n\tconst gitlabRefRange = parseGitlabRefRange(input);\n\tif (gitlabRefRange) {\n\t\tconst gitUrl = `git@gitlab.com:${gitlabRefRange.ownerRepo}.git`;\n\t\treturn {\n\t\t\ttype: \"git-url-range\",\n\t\t\tleft: gitlabRefRange.left,\n\t\t\tright: gitlabRefRange.right,\n\t\t\tleftGitUrl: gitUrl,\n\t\t\trightGitUrl: gitUrl,\n\t\t};\n\t}\n\n\tconst prRef = parsePRRef(input);\n\tif (prRef) {\n\t\treturn {\n\t\t\ttype: \"pr-ref\",\n\t\t\tleft: \"\",\n\t\t\tright: \"\",\n\t\t\townerRepo: `${prRef.owner}/${prRef.repo}`,\n\t\t\tprNumber: prRef.prNumber,\n\t\t};\n\t}\n\n\tconst mrRef = parseMRRef(input);\n\tif (mrRef) {\n\t\treturn {\n\t\t\ttype: \"gitlab-mr-ref\",\n\t\t\tleft: \"\",\n\t\t\tright: \"\",\n\t\t\townerRepo: `${mrRef.owner}/${mrRef.repo}`,\n\t\t\tprNumber: mrRef.mrNumber,\n\t\t};\n\t}\n\n\tconst remoteRange = parseRemoteRefRange(input);\n\tif (remoteRange) {\n\t\treturn {\n\t\t\ttype: \"remote-range\",\n\t\t\tleft: remoteRange.left,\n\t\t\tright: remoteRange.right,\n\t\t\townerRepo: remoteRange.ownerRepo,\n\t\t};\n\t}\n\n\tconst localRange = parseLocalRefRange(input);\n\tif (localRange) {\n\t\treturn {\n\t\t\ttype: \"local-range\",\n\t\t\tleft: localRange.left,\n\t\t\tright: localRange.right,\n\t\t};\n\t}\n\n\tthrow new DiffxError(\n\t\t`Invalid range or URL: ${input}\\n\\nSupported formats:\\n - Local refs: main..feature, abc123..def456\\n - Remote refs: owner/repo@main..owner/repo@feature\\n - Git URL: git@github.com:owner/repo.git@main..feature\\n - Git URL (HTTPS): https://github.com/owner/repo.git@main..feature\\n - GitHub refs: github:owner/repo@main..feature\\n - GitHub PR ref: github:owner/repo#123\\n - GitHub PR range: github:owner/repo#123..github:owner/repo#456\\n - GitHub PR URL: https://github.com/owner/repo/pull/123\\n - PR URL range: https://github.com/owner/repo/pull/123..https://github.com/owner/repo/pull/456\\n - GitHub commit URL: https://github.com/owner/repo/commit/abc123\\n - GitHub PR changes URL: https://github.com/owner/repo/pull/123/changes/abc123..def456\\n - GitHub compare URL: https://github.com/owner/repo/compare/main...feature\\n - Cross-fork compare: https://github.com/owner/repo/compare/main...other:repo:feature\\n - GitLab refs: gitlab:owner/repo@main..feature\\n - GitLab MR ref: gitlab:owner/repo!123`,\n\t\tExitCode.INVALID_INPUT,\n\t);\n}\n","/**\n * Git client wrapper using simple-git\n */\n\nimport git from \"simple-git\";\nimport type { StatusResult } from \"simple-git\";\nimport type { GitDiffOptions, GitRemote } from \"./types\";\n\n/**\n * Git client wrapper for diffx operations\n */\nexport class GitClient {\n\tprivate readonly git = git();\n\n\tprivate buildColorFlag(color: \"always\" | \"never\" | \"auto\" | undefined): string[] {\n\t\treturn color ? [`--color=${color}`] : [];\n\t}\n\n\tprivate buildColorArgs(options: GitDiffOptions | undefined): string[] {\n\t\treturn options?.color ? [`--color=${options.color}`] : [];\n\t}\n\n\tprivate buildExtraArgs(options: GitDiffOptions | undefined): string[] {\n\t\treturn options?.extraArgs ?? [];\n\t}\n\n\t/**\n\t * Generate a unified diff between two refs\n\t */\n\tasync diff(left: string, right: string, options: GitDiffOptions | undefined): Promise<string> {\n\t\t// Use -- to separate refs from paths, and handle refs with special characters\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\tleft,\n\t\t\t`${right}`,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t} else {\n\t\t\targs.push(\"--\");\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate a unified diff between a ref and the working tree (includes staged + unstaged)\n\t */\n\tasync diffAgainstWorktree(ref: string, options: GitDiffOptions | undefined): Promise<string> {\n\t\tconst args = [...this.buildExtraArgs(options), ...this.buildColorArgs(options), ref];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t} else {\n\t\t\targs.push(\"--\");\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate a patch between two refs\n\t */\n\tasync formatPatch(\n\t\tleft: string,\n\t\tright: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\"format-patch\", \"--stdout\", `${left}..${right}`];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.raw(args);\n\t}\n\n\t/**\n\t * Generate diff statistics between two refs\n\t */\n\tasync diffStat(\n\t\tleft: string,\n\t\tright: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\t\"--stat\",\n\t\t\t`${left}..${right}`,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate diff statistics between a ref and the working tree\n\t */\n\tasync diffStatAgainstWorktree(ref: string, options: GitDiffOptions | undefined): Promise<string> {\n\t\tconst args = [...this.buildExtraArgs(options), ...this.buildColorArgs(options), \"--stat\", ref];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate per-file additions/deletions between two refs\n\t */\n\tasync diffNumStat(\n\t\tleft: string,\n\t\tright: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\t\"--numstat\",\n\t\t\t`${left}..${right}`,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate per-file additions/deletions between a ref and the working tree\n\t */\n\tasync diffNumStatAgainstWorktree(\n\t\tref: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\t\"--numstat\",\n\t\t\tref,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate summary statistics between two refs\n\t */\n\tasync diffShortStat(\n\t\tleft: string,\n\t\tright: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\t\"--shortstat\",\n\t\t\t`${left}..${right}`,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate name-only output between two refs\n\t */\n\tasync diffNameOnly(\n\t\tleft: string,\n\t\tright: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\t\"--name-only\",\n\t\t\t`${left}..${right}`,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate summary statistics between a ref and the working tree\n\t */\n\tasync diffShortStatAgainstWorktree(\n\t\tref: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\t\"--shortstat\",\n\t\t\tref,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate name-only output between a ref and the working tree\n\t */\n\tasync diffNameOnlyAgainstWorktree(\n\t\tref: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\t\"--name-only\",\n\t\t\tref,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate name-status output between a ref and the working tree\n\t */\n\tasync diffNameStatusAgainstWorktree(\n\t\tref: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\t\"--name-status\",\n\t\t\tref,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Check if a ref exists locally\n\t */\n\tasync refExists(ref: string): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this.git.revparse([\"--verify\", `refs/heads/${ref}`]);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Check if a ref exists (local or remote)\n\t */\n\tasync refExistsAny(ref: string): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this.git.revparse([\"--verify\", ref]);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Add a remote repository\n\t */\n\tasync addRemote(name: string, url: string): Promise<void> {\n\t\tawait this.git.remote([\"add\", name, url]);\n\t}\n\n\t/**\n\t * Get all remotes\n\t */\n\tasync getRemotes(): Promise<GitRemote[]> {\n\t\tconst remotes = await this.git.getRemotes(true);\n\t\treturn remotes.map((r) => ({\n\t\t\tname: r.name,\n\t\t\tfetchUrl: r.refs.fetch,\n\t\t\tpushUrl: r.refs.push,\n\t\t}));\n\t}\n\n\t/**\n\t * Fetch refs from a remote (shallow fetch)\n\t */\n\tasync fetch(remote: string, refs: string[] | undefined): Promise<void> {\n\t\tconst args = [\"fetch\", \"--no-tags\", \"--depth\", \"1\", remote];\n\t\tif (refs && refs.length > 0) {\n\t\t\targs.push(...refs);\n\t\t}\n\t\tawait this.git.raw(args);\n\t}\n\n\t/**\n\t * Fetch refs from a URL into explicit refspecs (shallow fetch)\n\t */\n\tasync fetchFromUrl(url: string, refspecs: string[], depth: number): Promise<void> {\n\t\tconst args = [\"fetch\", \"--no-tags\", \"--depth\", String(depth), url, ...refspecs];\n\t\tawait this.git.raw(args);\n\t}\n\n\t/**\n\t * Fetch a specific PR reference (without depth limit to get merge history)\n\t */\n\tasync fetchPR(remote: string, prNumber: number): Promise<void> {\n\t\t// Fetch PR refs into remote-tracking refs so they can be referenced later.\n\t\t// Use a small depth to include merge parents (merge^1, merge^2).\n\t\tconst headRef = `refs/pull/${prNumber}/head:refs/remotes/${remote}/pull/${prNumber}/head`;\n\t\tconst mergeRef = `refs/pull/${prNumber}/merge:refs/remotes/${remote}/pull/${prNumber}/merge`;\n\t\tawait this.git.raw([\"fetch\", \"--no-tags\", \"--depth\", \"2\", remote, headRef, mergeRef]);\n\t}\n\n\t/**\n\t * Delete refs if they exist\n\t */\n\tasync deleteRefs(refs: string[]): Promise<void> {\n\t\tawait Promise.all(\n\t\t\trefs.map(async (ref) => {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.git.raw([\"update-ref\", \"-d\", ref]);\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore missing refs\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Get the current branch name\n\t */\n\tasync getCurrentBranch(): Promise<string> {\n\t\tconst branch = await this.git.revparse([\"--abbrev-ref\", \"HEAD\"]);\n\t\treturn branch.trim();\n\t}\n\n\t/**\n\t * Get the HEAD commit hash\n\t */\n\tasync getHeadHash(): Promise<string> {\n\t\treturn this.git.revparse([\"HEAD\"]);\n\t}\n\n\t/**\n\t * Check if the working tree has staged or unstaged changes\n\t */\n\tasync hasWorktreeChanges(): Promise<boolean> {\n\t\tconst status = await this.git.status();\n\t\treturn status.files.length > 0 || status.not_added.length > 0;\n\t}\n\n\t/**\n\t * Get working tree status\n\t */\n\tasync getStatus(): Promise<StatusResult> {\n\t\treturn this.git.status();\n\t}\n\n\t/**\n\t * Get untracked files\n\t */\n\tasync getUntrackedFiles(): Promise<string[]> {\n\t\tconst status = await this.git.status();\n\t\treturn status.not_added;\n\t}\n\n\t/**\n\t * Generate a unified diff for an untracked file (vs /dev/null)\n\t */\n\tasync diffNoIndex(\n\t\tfilePath: string,\n\t\tcolor: \"always\" | \"never\" | \"auto\" | undefined,\n\t): Promise<string> {\n\t\tconst colorArgs = this.buildColorFlag(color);\n\t\treturn this.git.raw([\"diff\", ...colorArgs, \"--no-index\", \"--\", \"/dev/null\", filePath]);\n\t}\n\n\t/**\n\t * Generate diff statistics for an untracked file (vs /dev/null)\n\t */\n\tasync diffStatNoIndex(\n\t\tfilePath: string,\n\t\tcolor: \"always\" | \"never\" | \"auto\" | undefined,\n\t): Promise<string> {\n\t\tconst colorArgs = this.buildColorFlag(color);\n\t\treturn this.git.raw([\n\t\t\t\"diff\",\n\t\t\t...colorArgs,\n\t\t\t\"--no-index\",\n\t\t\t\"--stat\",\n\t\t\t\"--\",\n\t\t\t\"/dev/null\",\n\t\t\tfilePath,\n\t\t]);\n\t}\n\n\t/**\n\t * Generate per-file additions/deletions for an untracked file (vs /dev/null)\n\t */\n\tasync diffNumStatNoIndex(\n\t\tfilePath: string,\n\t\tcolor: \"always\" | \"never\" | \"auto\" | undefined,\n\t): Promise<string> {\n\t\tconst colorArgs = this.buildColorFlag(color);\n\t\treturn this.git.raw([\n\t\t\t\"diff\",\n\t\t\t...colorArgs,\n\t\t\t\"--no-index\",\n\t\t\t\"--numstat\",\n\t\t\t\"--\",\n\t\t\t\"/dev/null\",\n\t\t\tfilePath,\n\t\t]);\n\t}\n\n\t/**\n\t * Generate name-status diff between two refs\n\t */\n\tasync diffNameStatus(\n\t\tleft: string,\n\t\tright: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\t\"--name-status\",\n\t\t\t`${left}..${right}`,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate summary output between two refs\n\t */\n\tasync diffSummary(\n\t\tleft: string,\n\t\tright: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\t\"--summary\",\n\t\t\t`${left}..${right}`,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Generate summary output between a ref and the working tree\n\t */\n\tasync diffSummaryAgainstWorktree(\n\t\tref: string,\n\t\toptions: GitDiffOptions | undefined,\n\t): Promise<string> {\n\t\tconst args = [\n\t\t\t...this.buildExtraArgs(options),\n\t\t\t...this.buildColorArgs(options),\n\t\t\t\"--summary\",\n\t\t\tref,\n\t\t];\n\t\tif (options?.files && options.files.length > 0) {\n\t\t\targs.push(\"--\", ...options.files);\n\t\t}\n\t\treturn this.git.diff(args);\n\t}\n\n\t/**\n\t * Get the default branch ref for a remote (e.g., origin/main)\n\t */\n\tasync getRemoteHeadRef(remote: string): Promise<string | null> {\n\t\ttry {\n\t\t\tconst ref = await this.git.raw([\n\t\t\t\t\"symbolic-ref\",\n\t\t\t\t\"--quiet\",\n\t\t\t\t\"--short\",\n\t\t\t\t`refs/remotes/${remote}/HEAD`,\n\t\t\t]);\n\t\t\tconst trimmed = ref.trim();\n\t\t\treturn trimmed.length > 0 ? trimmed : null;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Get a best-effort default branch ref (remote or local)\n\t */\n\tasync getDefaultBranchRef(): Promise<string | null> {\n\t\tconst remotes = await this.getRemotes();\n\t\tconst remoteNames = remotes.map((r) => r.name);\n\t\tconst preferredRemotes = remoteNames.includes(\"origin\")\n\t\t\t? [\"origin\", ...remoteNames.filter((name) => name !== \"origin\")]\n\t\t\t: remoteNames;\n\n\t\tfor (const remote of preferredRemotes) {\n\t\t\tconst headRef = await this.getRemoteHeadRef(remote);\n\t\t\tif (headRef) return headRef;\n\t\t}\n\n\t\tconst fallbackBranchNames = [\"main\", \"master\", \"develop\", \"trunk\"];\n\t\tfor (const remote of preferredRemotes) {\n\t\t\tfor (const branch of fallbackBranchNames) {\n\t\t\t\tconst ref = `${remote}/${branch}`;\n\t\t\t\tif (await this.refExistsAny(ref)) return ref;\n\t\t\t}\n\t\t}\n\n\t\tfor (const branch of fallbackBranchNames) {\n\t\t\tif (await this.refExistsAny(branch)) return branch;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Get the merge-base between two refs\n\t */\n\tasync mergeBase(left: string, right: string): Promise<string> {\n\t\treturn this.git.raw([\"merge-base\", left, right]);\n\t}\n\n\t/**\n\t * Get a git config value\n\t */\n\tasync getConfigValue(\n\t\tkey: string,\n\t\tscope: \"all\" | \"local\" | \"global\" | \"system\" = \"all\",\n\t): Promise<string | null> {\n\t\ttry {\n\t\t\tconst scopeArgs = scope === \"all\" ? [] : [`--${scope}`];\n\t\t\tconst value = await this.git.raw([\"config\", ...scopeArgs, \"--get\", key]);\n\t\t\tconst trimmed = value.trim();\n\t\t\treturn trimmed.length > 0 ? trimmed : null;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Validate that two refs can be diffed\n\t */\n\tasync validateRefs(left: string, right: string): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this.git.diff([`${left}..${right}`]);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Run native git diff with raw arguments\n\t * This is the primary method for git diff pass-through compatibility\n\t *\n\t * @param args - Raw git diff arguments (e.g., [\"--stat\", \"HEAD\", \"--\", \"src/\"])\n\t * @param options - Execution options\n\t * @returns Git diff output and exit information\n\t */\n\tasync runGitDiffRaw(\n\t\targs: string[],\n\t\toptions: { capture?: boolean } = {},\n\t): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n\t\tconst { capture = true } = options;\n\n\t\t// Detect TTY for color output\n\t\tconst isTTY = process.stdout.isTTY;\n\t\tconst colorArgs = isTTY ? [\"--color=always\"] : [\"--color=never\"];\n\n\t\ttry {\n\t\t\t// Build the full command: git diff <color> <args>\n\t\t\tconst fullArgs = [\"diff\", ...colorArgs, ...args];\n\n\t\t\tif (capture) {\n\t\t\t\t// Capture mode: return output as string\n\t\t\t\tconst stdout = await this.git.raw(fullArgs);\n\t\t\t\treturn { stdout, stderr: \"\", exitCode: 0 };\n\t\t\t} else {\n\t\t\t\t// Streaming mode: for future TTY/pager support\n\t\t\t\t// For now, we still capture but this allows for future streaming implementation\n\t\t\t\tconst stdout = await this.git.raw(fullArgs);\n\t\t\t\treturn { stdout, stderr: \"\", exitCode: 0 };\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Handle git errors (e.g., bad refs, invalid options)\n\t\t\tif (error instanceof Error) {\n\t\t\t\t// simple-git throws with stderr in the message\n\t\t\t\treturn {\n\t\t\t\t\tstdout: \"\",\n\t\t\t\t\tstderr: error.message,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tstdout: \"\",\n\t\t\t\tstderr: String(error),\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t}\n}\n\n/**\n * Singleton Git client instance\n */\nexport const gitClient = new GitClient();\n","/**\n * Git utility functions\n */\n\nimport crypto from \"node:crypto\";\n\n/**\n * Build a GitHub HTTPS URL from owner/repo\n */\nexport function buildGitHubUrl(owner: string, repo: string): string {\n\treturn `https://github.com/${owner}/${repo}.git`;\n}\n\n/**\n * Parse owner/repo from a GitHub URL\n */\nexport function parseOwnerRepoFromUrl(url: string): { owner: string; repo: string } | null {\n\t// Match https://github.com/OWNER/REPO.git or https://github.com/OWNER/REPO\n\tconst match = url.match(/github\\.com[/:]([^/]+)\\/([^/]+?)(\\.git)?$/);\n\tif (!match) return null;\n\treturn { owner: match[1], repo: match[2] };\n}\n\n/**\n * Create a remote name from owner/repo\n */\nexport function createRemoteName(owner: string, repo: string): string {\n\t// Create a unique remote name like \"diffx-octocat-Hello-World\"\n\treturn `diffx-${owner}-${repo}`.replace(/[/_]/g, \"-\").toLowerCase();\n}\n\n/**\n * Check if a ref is a commit hash (40 hex chars or abbreviated)\n */\nexport function isCommitHash(ref: string): boolean {\n\treturn /^[a-f0-9]{4,40}$/i.test(ref);\n}\n\n/**\n * Normalize a ref for use with git commands\n */\nexport function normalizeRef(ref: string): string {\n\t// Remove refs/heads/ or refs/tags/ prefix if present\n\treturn ref.replace(/^refs\\/(heads|tags)\\//, \"\");\n}\n\n/**\n * Get PR ref name from PR number\n */\nexport function getPRRefName(prNumber: number): string {\n\treturn `refs/pull/${prNumber}/head`;\n}\n\n/**\n * Create a temporary ref prefix for one-off fetches\n */\nexport function createTempRefPrefix(): string {\n\tconst token = crypto.randomBytes(8).toString(\"hex\");\n\treturn `refs/diffx/tmp/${Date.now().toString(36)}-${token}`;\n}\n","/**\n * Local ref resolver\n * Handles resolution of local Git refs (branches, commits)\n */\n\nimport type { RefRange } from \"../types\";\nimport { gitClient } from \"../git/git-client\";\nimport { normalizeRef } from \"../git/utils\";\nimport { DiffxError, ExitCode } from \"../types\";\n\n/**\n * Resolve a local ref range to actual refs\n */\nexport async function resolveLocalRefs(range: RefRange): Promise<{\n\tleft: string;\n\tright: string;\n}> {\n\tif (range.type !== \"local-range\") {\n\t\tthrow new DiffxError(\"Invalid ref type for local resolver\", ExitCode.INVALID_INPUT);\n\t}\n\n\tconst left = normalizeRef(range.left);\n\tconst right = normalizeRef(range.right);\n\n\t// Validate that both refs exist (branches, tags, commits, and rev expressions)\n\tconst leftExists = await gitClient.refExistsAny(left);\n\tconst rightExists = await gitClient.refExistsAny(right);\n\n\tif (!leftExists) {\n\t\tthrow new DiffxError(`Left ref does not exist: ${range.left}`, ExitCode.INVALID_INPUT);\n\t}\n\tif (!rightExists) {\n\t\tthrow new DiffxError(`Right ref does not exist: ${range.right}`, ExitCode.INVALID_INPUT);\n\t}\n\n\treturn { left, right };\n}\n","/**\n * Remote ref resolver\n * Handles resolution of remote Git refs (OWNER/REPO@ref format)\n */\n\nimport type { RefRange } from \"../types\";\nimport { gitClient } from \"../git/git-client\";\nimport { buildGitHubUrl, createTempRefPrefix } from \"../git/utils\";\nimport { DiffxError, ExitCode } from \"../types\";\n\n/**\n * Resolve a remote ref range to local refs\n */\nexport async function resolveRemoteRefs(range: RefRange): Promise<{\n\tleft: string;\n\tright: string;\n\tcleanup?: () => Promise<void>;\n}> {\n\tif (range.type !== \"remote-range\" || !range.ownerRepo) {\n\t\tthrow new DiffxError(\"Invalid ref type for remote resolver\", ExitCode.INVALID_INPUT);\n\t}\n\n\tconst [owner, repo] = range.ownerRepo.split(\"/\");\n\tif (!owner || !repo) {\n\t\tthrow new DiffxError(`Invalid owner/repo: ${range.ownerRepo}`, ExitCode.INVALID_INPUT);\n\t}\n\n\t// Parse remote refs (format: OWNER/REPO@ref)\n\tconst leftMatch = range.left.match(/^[^/]+\\/[^@]+@(.+)$/);\n\tconst rightMatch = range.right.match(/^[^/]+\\/[^@]+@(.+)$/);\n\n\tif (!leftMatch || !rightMatch) {\n\t\tthrow new DiffxError(\"Invalid remote ref format\", ExitCode.INVALID_INPUT);\n\t}\n\n\tconst leftRemoteRef = leftMatch[1];\n\tconst rightRemoteRef = rightMatch[1];\n\n\tconst remoteUrl = buildGitHubUrl(owner, repo);\n\tconst tempPrefix = createTempRefPrefix();\n\tconst leftDestRef = `${tempPrefix}/left`;\n\tconst rightDestRef = `${tempPrefix}/right`;\n\n\ttry {\n\t\t// Fetch the refs (shallow fetch) without creating a remote\n\t\tawait gitClient.fetchFromUrl(\n\t\t\tremoteUrl,\n\t\t\t[`${leftRemoteRef}:${leftDestRef}`, `${rightRemoteRef}:${rightDestRef}`],\n\t\t\t1,\n\t\t);\n\n\t\t// Return as temp refs\n\t\treturn {\n\t\t\tleft: leftDestRef,\n\t\t\tright: rightDestRef,\n\t\t\tcleanup: async () => {\n\t\t\t\tawait gitClient.deleteRefs([leftDestRef, rightDestRef]);\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tthrow new DiffxError(\n\t\t\t`Failed to fetch remote refs: ${(error as Error).message}`,\n\t\t\tExitCode.GIT_ERROR,\n\t\t);\n\t}\n}\n","/**\n * GitHub PR URL resolver\n * Handles resolution of GitHub PR URLs and pr:OWNER/REPO#123 format\n */\n\nimport type { GitHubPRUrl, RefRange } from \"../types\";\nimport { gitClient } from \"../git/git-client\";\nimport { buildGitHubUrl, createTempRefPrefix } from \"../git/utils\";\nimport { DiffxError, ExitCode } from \"../types\";\n\ntype PRResolvedRefs = {\n\theadRef: string;\n\tmergeRef: string;\n\tcleanupRefs: string[];\n};\n\nasync function fetchPRRefs(pr: GitHubPRUrl, tempPrefix: string): Promise<PRResolvedRefs> {\n\tconst { owner, repo, prNumber } = pr;\n\tconst remoteUrl = buildGitHubUrl(owner, repo);\n\n\tconst headRef = `${tempPrefix}/pull/${prNumber}/head`;\n\tconst mergeRef = `${tempPrefix}/pull/${prNumber}/merge`;\n\n\tawait gitClient.fetchFromUrl(\n\t\tremoteUrl,\n\t\t[`refs/pull/${prNumber}/head:${headRef}`, `refs/pull/${prNumber}/merge:${mergeRef}`],\n\t\t2,\n\t);\n\n\treturn {\n\t\theadRef,\n\t\tmergeRef,\n\t\tcleanupRefs: [headRef, mergeRef],\n\t};\n}\n\n/**\n * Resolve a GitHub PR to local refs\n */\nexport async function resolvePRRefs(range: RefRange): Promise<{\n\tleft: string;\n\tright: string;\n\tcleanup?: () => Promise<void>;\n}> {\n\tif (!range.ownerRepo || range.prNumber === undefined) {\n\t\tthrow new DiffxError(\"Invalid PR ref\", ExitCode.INVALID_INPUT);\n\t}\n\n\ttry {\n\t\tconst [owner, repo] = range.ownerRepo.split(\"/\");\n\t\tif (!owner || !repo) {\n\t\t\tthrow new DiffxError(`Invalid owner/repo: ${range.ownerRepo}`, ExitCode.INVALID_INPUT);\n\t\t}\n\n\t\tconst tempPrefix = createTempRefPrefix();\n\t\tconst refs = await fetchPRRefs({ owner, repo, prNumber: range.prNumber }, tempPrefix);\n\n\t\t// The merge ref is the PR head merged into the base branch\n\t\t// Diffing merge^1..merge yields the PR changes (mirrors GitHub \"Files changed\")\n\t\treturn {\n\t\t\tleft: `${refs.mergeRef}^1`, // The first parent of the merge commit (the base branch)\n\t\t\tright: refs.mergeRef,\n\t\t\tcleanup: async () => {\n\t\t\t\tawait gitClient.deleteRefs(refs.cleanupRefs);\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tthrow new DiffxError(\n\t\t\t`Failed to fetch PR refs: ${(error as Error).message}`,\n\t\t\tExitCode.GIT_ERROR,\n\t\t);\n\t}\n}\n\n/**\n * Resolve a PR-to-PR range (compare PR heads)\n */\nexport async function resolvePRRangeRefs(range: RefRange): Promise<{\n\tleft: string;\n\tright: string;\n\tcleanup?: () => Promise<void>;\n}> {\n\tif (!range.leftPr || !range.rightPr) {\n\t\tthrow new DiffxError(\"Invalid PR range\", ExitCode.INVALID_INPUT);\n\t}\n\n\ttry {\n\t\tconst tempPrefix = createTempRefPrefix();\n\t\tconst leftRefs = await fetchPRRefs(range.leftPr, `${tempPrefix}/left`);\n\t\tconst rightRefs = await fetchPRRefs(range.rightPr, `${tempPrefix}/right`);\n\n\t\treturn {\n\t\t\tleft: leftRefs.headRef,\n\t\t\tright: rightRefs.headRef,\n\t\t\tcleanup: async () => {\n\t\t\t\tawait gitClient.deleteRefs([...leftRefs.cleanupRefs, ...rightRefs.cleanupRefs]);\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tthrow new DiffxError(\n\t\t\t`Failed to fetch PR range refs: ${(error as Error).message}`,\n\t\t\tExitCode.GIT_ERROR,\n\t\t);\n\t}\n}\n\n/**\n * Resolve a GitHub commit URL to local refs\n * Shows the changes in that commit (commit^..commit)\n */\nexport async function resolveGitHubCommitRefs(range: RefRange): Promise<{\n\tleft: string;\n\tright: string;\n\tcleanup?: () => Promise<void>;\n}> {\n\tif (!range.ownerRepo || !range.commitSha) {\n\t\tthrow new DiffxError(\"Invalid GitHub commit URL\", ExitCode.INVALID_INPUT);\n\t}\n\n\ttry {\n\t\tconst [owner, repo] = range.ownerRepo.split(\"/\");\n\t\tif (!owner || !repo) {\n\t\t\tthrow new DiffxError(`Invalid owner/repo: ${range.ownerRepo}`, ExitCode.INVALID_INPUT);\n\t\t}\n\n\t\tconst remoteUrl = buildGitHubUrl(owner, repo);\n\t\tconst tempPrefix = createTempRefPrefix();\n\t\tconst commitRef = `${tempPrefix}/commit/${range.commitSha}`;\n\n\t\t// Fetch with depth=2 to include the parent commit\n\t\tawait gitClient.fetchFromUrl(remoteUrl, [`${range.commitSha}:${commitRef}`], 2);\n\n\t\treturn {\n\t\t\tleft: `${commitRef}^`, // Parent of the commit\n\t\t\tright: commitRef,\n\t\t\tcleanup: async () => {\n\t\t\t\tawait gitClient.deleteRefs([commitRef]);\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tthrow new DiffxError(\n\t\t\t`Failed to fetch commit refs: ${(error as Error).message}`,\n\t\t\tExitCode.GIT_ERROR,\n\t\t);\n\t}\n}\n\n/**\n * Resolve a GitHub PR changes URL (compare two commits in a PR)\n */\nexport async function resolveGitHubPRChangesRefs(range: RefRange): Promise<{\n\tleft: string;\n\tright: string;\n\tcleanup?: () => Promise<void>;\n}> {\n\tif (!range.ownerRepo || !range.prNumber || !range.leftCommitSha || !range.rightCommitSha) {\n\t\tthrow new DiffxError(\"Invalid GitHub PR changes URL\", ExitCode.INVALID_INPUT);\n\t}\n\n\ttry {\n\t\tconst [owner, repo] = range.ownerRepo.split(\"/\");\n\t\tif (!owner || !repo) {\n\t\t\tthrow new DiffxError(`Invalid owner/repo: ${range.ownerRepo}`, ExitCode.INVALID_INPUT);\n\t\t}\n\n\t\tconst remoteUrl = buildGitHubUrl(owner, repo);\n\t\tconst tempPrefix = createTempRefPrefix();\n\t\tconst leftCommitRef = `${tempPrefix}/left-commit/${range.leftCommitSha}`;\n\t\tconst rightCommitRef = `${tempPrefix}/right-commit/${range.rightCommitSha}`;\n\n\t\t// Fetch both commits directly\n\t\tawait gitClient.fetchFromUrl(\n\t\t\tremoteUrl,\n\t\t\t[`${range.leftCommitSha}:${leftCommitRef}`, `${range.rightCommitSha}:${rightCommitRef}`],\n\t\t\t2,\n\t\t);\n\n\t\treturn {\n\t\t\tleft: leftCommitRef,\n\t\t\tright: rightCommitRef,\n\t\t\tcleanup: async () => {\n\t\t\t\tawait gitClient.deleteRefs([leftCommitRef, rightCommitRef]);\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tthrow new DiffxError(\n\t\t\t`Failed to fetch PR changes refs: ${(error as Error).message}`,\n\t\t\tExitCode.GIT_ERROR,\n\t\t);\n\t}\n}\n\n/**\n * Resolve a GitHub compare URL (compare two refs, possibly across forks)\n */\nexport async function resolveGitHubCompareRefs(range: RefRange): Promise<{\n\tleft: string;\n\tright: string;\n\tcleanup?: () => Promise<void>;\n}> {\n\tif (!range.ownerRepo || !range.leftRef || !range.rightRef) {\n\t\tthrow new DiffxError(\"Invalid GitHub compare URL\", ExitCode.INVALID_INPUT);\n\t}\n\n\ttry {\n\t\tconst [owner, repo] = range.ownerRepo.split(\"/\");\n\t\tif (!owner || !repo) {\n\t\t\tthrow new DiffxError(`Invalid owner/repo: ${range.ownerRepo}`, ExitCode.INVALID_INPUT);\n\t\t}\n\n\t\tconst tempPrefix = createTempRefPrefix();\n\t\tconst leftRef = `${tempPrefix}/left/${range.leftRef}`;\n\t\tconst rightRef = `${tempPrefix}/right/${range.rightRef}`;\n\t\tconst cleanupRefs = [leftRef, rightRef];\n\n\t\t// Fetch left ref from the base repo\n\t\tconst leftUrl = buildGitHubUrl(owner, repo);\n\n\t\t// Fetch right ref - may be from same repo or a different fork\n\t\tconst rightOwner = range.rightOwner || owner;\n\t\tconst rightRepo = range.rightRepo || repo;\n\t\tconst rightUrl = buildGitHubUrl(rightOwner, rightRepo);\n\n\t\t// Helper to determine if a ref looks like a commit SHA (hex only, reasonable length)\n\t\tconst isCommitSha = (ref: string) => /^[a-f0-9]{7,40}$/i.test(ref);\n\n\t\t// Helper to build refspec - try multiple possible locations\n\t\tconst buildRefspec = (ref: string, targetRef: string): string[] => {\n\t\t\t// If it looks like a commit SHA, fetch it directly\n\t\t\tif (isCommitSha(ref)) {\n\t\t\t\treturn [`${ref}:${targetRef}`];\n\t\t\t}\n\t\t\t// Otherwise try multiple ref types (heads, tags)\n\t\t\treturn [`refs/heads/${ref}:${targetRef}`, `refs/tags/${ref}:${targetRef}`];\n\t\t};\n\n\t\tconst fetchRef = async (url: string, ref: string, targetRef: string): Promise<string> => {\n\t\t\tlet fetchError: Error | null = null;\n\t\t\tfor (const refspec of buildRefspec(ref, targetRef)) {\n\t\t\t\ttry {\n\t\t\t\t\tawait gitClient.fetchFromUrl(url, [refspec], 1);\n\t\t\t\t\treturn refspec;\n\t\t\t\t} catch (e) {\n\t\t\t\t\tfetchError = e as Error;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow fetchError ?? new Error(`Failed to fetch ref: ${ref}`);\n\t\t};\n\n\t\t// Fetch left/right refs - try branches first, then tags, then direct SHA\n\t\tconst leftRefspec = await fetchRef(leftUrl, range.leftRef, leftRef);\n\t\tconst rightRefspec = await fetchRef(rightUrl, range.rightRef, rightRef);\n\n\t\t// GitHub compare URLs use three-dot semantics (merge-base..right)\n\t\tconst getMergeBase = async (): Promise<string | null> => {\n\t\t\ttry {\n\t\t\t\tconst mergeBase = (await gitClient.mergeBase(leftRef, rightRef)).trim();\n\t\t\t\treturn mergeBase.length > 0 ? mergeBase : null;\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t};\n\n\t\tlet mergeBase = await getMergeBase();\n\t\tif (!mergeBase) {\n\t\t\t// Shallow fetches may not include enough history to find a merge base.\n\t\t\tawait gitClient.fetchFromUrl(leftUrl, [leftRefspec], 200);\n\t\t\tawait gitClient.fetchFromUrl(rightUrl, [rightRefspec], 200);\n\t\t\tmergeBase = await getMergeBase();\n\t\t}\n\n\t\tif (!mergeBase) {\n\t\t\tthrow new Error(\"Failed to determine merge base for compare refs\");\n\t\t}\n\n\t\treturn {\n\t\t\tleft: mergeBase,\n\t\t\tright: rightRef,\n\t\t\tcleanup: async () => {\n\t\t\t\tawait gitClient.deleteRefs(cleanupRefs);\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tthrow new DiffxError(\n\t\t\t`Failed to fetch compare refs: ${(error as Error).message}`,\n\t\t\tExitCode.GIT_ERROR,\n\t\t);\n\t}\n}\n","/**\n * Git URL resolver\n * Handles resolution of arbitrary git URLs (git@host:path.git@ref format)\n */\n\nimport type { RefRange } from \"../types\";\nimport { gitClient } from \"../git/git-client\";\nimport { createTempRefPrefix } from \"../git/utils\";\nimport { DiffxError, ExitCode } from \"../types\";\n\n/**\n * Resolve a git URL range to local refs\n */\nexport async function resolveGitUrlRefs(range: RefRange): Promise<{\n\tleft: string;\n\tright: string;\n\tcleanup?: () => Promise<void>;\n}> {\n\tif (range.type !== \"git-url-range\" || !range.leftGitUrl || !range.rightGitUrl) {\n\t\tthrow new DiffxError(\"Invalid ref type for git URL resolver\", ExitCode.INVALID_INPUT);\n\t}\n\n\tconst leftUrl = range.leftGitUrl;\n\tconst rightUrl = range.rightGitUrl;\n\tconst leftRef = range.left;\n\tconst rightRef = range.right;\n\n\tconst tempPrefix = createTempRefPrefix();\n\tconst leftDestRef = `${tempPrefix}/left`;\n\tconst rightDestRef = `${tempPrefix}/right`;\n\n\ttry {\n\t\t// Fetch the refs (shallow fetch) without creating a remote\n\t\t// If both URLs are the same, fetch both refs in one call\n\t\tif (leftUrl === rightUrl) {\n\t\t\tawait gitClient.fetchFromUrl(\n\t\t\t\tleftUrl,\n\t\t\t\t[`${leftRef}:${leftDestRef}`, `${rightRef}:${rightDestRef}`],\n\t\t\t\t1,\n\t\t\t);\n\t\t} else {\n\t\t\t// Different URLs, fetch each separately\n\t\t\tawait gitClient.fetchFromUrl(leftUrl, [`${leftRef}:${leftDestRef}`], 1);\n\t\t\tawait gitClient.fetchFromUrl(rightUrl, [`${rightRef}:${rightDestRef}`], 1);\n\t\t}\n\n\t\t// Return as temp refs\n\t\treturn {\n\t\t\tleft: leftDestRef,\n\t\t\tright: rightDestRef,\n\t\t\tcleanup: async () => {\n\t\t\t\tawait gitClient.deleteRefs([leftDestRef, rightDestRef]);\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tthrow new DiffxError(\n\t\t\t`Failed to fetch refs from git URL: ${(error as Error).message}`,\n\t\t\tExitCode.GIT_ERROR,\n\t\t);\n\t}\n}\n","/**\n * GitLab MR resolver\n * Handles resolution of gitlab:OWNER/REPO!123 format\n */\n\nimport type { RefRange } from \"../types\";\nimport { gitClient } from \"../git/git-client\";\nimport { createTempRefPrefix } from \"../git/utils\";\nimport { DiffxError, ExitCode } from \"../types\";\n\ntype MRResolvedRefs = {\n\theadRef: string;\n\tmergeRef: string;\n\tcleanupRefs: string[];\n};\n\nasync function fetchMRRefs(range: RefRange, tempPrefix: string): Promise<MRResolvedRefs> {\n\tif (!range.ownerRepo || range.prNumber === undefined) {\n\t\tthrow new DiffxError(\"Invalid GitLab MR ref\", ExitCode.INVALID_INPUT);\n\t}\n\n\tconst [owner, repo] = range.ownerRepo.split(\"/\");\n\tif (!owner || !repo) {\n\t\tthrow new DiffxError(`Invalid owner/repo: ${range.ownerRepo}`, ExitCode.INVALID_INPUT);\n\t}\n\n\tconst remoteUrl = `git@gitlab.com:${owner}/${repo}.git`;\n\tconst mrNumber = range.prNumber;\n\n\tconst headRef = `${tempPrefix}/merge-requests/${mrNumber}/head`;\n\tconst mergeRef = `${tempPrefix}/merge-requests/${mrNumber}/merge`;\n\n\tawait gitClient.fetchFromUrl(\n\t\tremoteUrl,\n\t\t[\n\t\t\t`refs/merge-requests/${mrNumber}/head:${headRef}`,\n\t\t\t`refs/merge-requests/${mrNumber}/merge:${mergeRef}`,\n\t\t],\n\t\t2,\n\t);\n\n\treturn {\n\t\theadRef,\n\t\tmergeRef,\n\t\tcleanupRefs: [headRef, mergeRef],\n\t};\n}\n\n/**\n * Resolve a GitLab MR to local refs\n */\nexport async function resolveGitLabMRRefs(range: RefRange): Promise<{\n\tleft: string;\n\tright: string;\n\tcleanup?: () => Promise<void>;\n}> {\n\ttry {\n\t\tconst tempPrefix = createTempRefPrefix();\n\t\tconst refs = await fetchMRRefs(range, tempPrefix);\n\n\t\t// The merge ref is the MR head merged into the base branch\n\t\t// Diffing merge^1..merge yields the MR changes (similar to GitLab \"Changes\" tab)\n\t\treturn {\n\t\t\tleft: `${refs.mergeRef}^1`, // The first parent of the merge commit (the base branch)\n\t\t\tright: refs.mergeRef,\n\t\t\tcleanup: async () => {\n\t\t\t\tawait gitClient.deleteRefs(refs.cleanupRefs);\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tthrow new DiffxError(\n\t\t\t`Failed to fetch GitLab MR refs: ${(error as Error).message}`,\n\t\t\tExitCode.GIT_ERROR,\n\t\t);\n\t}\n}\n","/**\n * Ref resolver orchestrator\n * Routes to the appropriate resolver based on ref type\n */\n\nimport type { RefRange, RefType } from \"../types\";\nimport { resolveLocalRefs } from \"./local-ref-resolver\";\nimport { resolveRemoteRefs } from \"./remote-ref-resolver\";\nimport {\n\tresolvePRRangeRefs,\n\tresolvePRRefs,\n\tresolveGitHubCommitRefs,\n\tresolveGitHubPRChangesRefs,\n\tresolveGitHubCompareRefs,\n} from \"./pr-url-resolver\";\nimport { resolveGitUrlRefs } from \"./git-url-resolver\";\nimport { resolveGitLabMRRefs } from \"./gitlab-mr-resolver\";\n\nconst resolversByRefRangeType = {\n\t\"local-range\": resolveLocalRefs,\n\t\"remote-range\": resolveRemoteRefs,\n\t\"pr-ref\": resolvePRRefs,\n\t\"github-url\": resolvePRRefs,\n\t\"pr-range\": resolvePRRangeRefs,\n\t\"git-url-range\": resolveGitUrlRefs,\n\t\"github-commit-url\": resolveGitHubCommitRefs,\n\t\"github-pr-changes-url\": resolveGitHubPRChangesRefs,\n\t\"github-compare-url\": resolveGitHubCompareRefs,\n\t\"gitlab-mr-ref\": resolveGitLabMRRefs,\n} as const satisfies Record<\n\tRefType,\n\t(range: RefRange) => Promise<{\n\t\tleft: string;\n\t\tright: string;\n\t\tcleanup?: () => Promise<void>;\n\t}>\n>;\n/**\n * Resolve any ref range to concrete left/right refs\n */\nexport async function resolveRefs(range: RefRange): Promise<{\n\tleft: string;\n\tright: string;\n\tcleanup?: () => Promise<void>;\n}> {\n\tconst resolver = resolversByRefRangeType[range.type];\n\n\treturn resolver(range);\n}\n","/**\n * Auto base resolver\n * Resolves current branch diff against its inferred base branch\n */\n\nimport { gitClient } from \"../git/git-client\";\nimport { DiffxError, ExitCode } from \"../types\";\n\nexport interface AutoBaseRefs {\n\tleft: string;\n\tright: string;\n\tbaseRef: string;\n\tmergeBase: string;\n}\n\n/**\n * Resolve refs for auto base diff (merge-base..HEAD)\n */\nexport async function resolveAutoBaseRefs(): Promise<AutoBaseRefs> {\n\tconst baseRef = await gitClient.getDefaultBranchRef();\n\tif (!baseRef) {\n\t\tthrow new DiffxError(\n\t\t\t\"Could not determine a base branch automatically. Provide an explicit range (e.g., main..HEAD).\",\n\t\t\tExitCode.INVALID_INPUT,\n\t\t);\n\t}\n\n\tlet mergeBase: string;\n\ttry {\n\t\tmergeBase = (await gitClient.mergeBase(baseRef, \"HEAD\")).trim();\n\t} catch {\n\t\tthrow new DiffxError(\n\t\t\t`Could not find a merge base with ${baseRef}. Provide an explicit range (e.g., ${baseRef}..HEAD).`,\n\t\t\tExitCode.INVALID_INPUT,\n\t\t);\n\t}\n\n\tif (!mergeBase) {\n\t\tthrow new DiffxError(\n\t\t\t`Could not find a merge base with ${baseRef}. Provide an explicit range (e.g., ${baseRef}..HEAD).`,\n\t\t\tExitCode.INVALID_INPUT,\n\t\t);\n\t}\n\n\treturn {\n\t\tleft: mergeBase,\n\t\tright: \"HEAD\",\n\t\tbaseRef,\n\t\tmergeBase,\n\t};\n}\n","/**\n * Patch output generator\n * Generates patch output using git format-patch or git diff\n */\n\nimport type { GitDiffOptions } from \"../git/types\";\nimport { gitClient } from \"../git/git-client\";\nimport type { PatchStyle } from \"../types\";\n\n/**\n * Generate patch between two refs\n */\nexport async function generatePatch(\n\tleft: string,\n\tright: string,\n\toptions: GitDiffOptions | undefined,\n\tpatchStyle: PatchStyle = \"diff\",\n): Promise<string> {\n\tif (patchStyle === \"diff\") {\n\t\treturn gitClient.diff(left, right, options);\n\t}\n\n\treturn gitClient.formatPatch(left, right, options);\n}\n","/**\n * Output factory\n * Routes to the appropriate output generator based on mode\n */\n\nimport type { OutputMode, PatchStyle } from \"../types\";\nimport { gitClient } from \"../git/git-client\";\nimport { generatePatch } from \"./patch-generator\";\nimport { GitDiffOptions } from \"../git/types\";\n\ntype OutputGeneratorFn = (\n\tleft: string,\n\tright: string,\n\toptions: GitDiffOptions | undefined,\n\tpatchStyle?: PatchStyle,\n) => Promise<string>;\n\nconst outputGeneratorsByMode = {\n\tdiff: (left: string, right: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diff(left, right, options),\n\tpatch: generatePatch as OutputGeneratorFn,\n\tstat: (left: string, right: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffStat(left, right, options),\n\tnumstat: (left: string, right: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffNumStat(left, right, options),\n\tshortstat: (left: string, right: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffShortStat(left, right, options),\n\t\"name-only\": (left: string, right: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffNameOnly(left, right, options),\n\t\"name-status\": (left: string, right: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffNameStatus(left, right, options),\n\tsummary: (left: string, right: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffSummary(left, right, options),\n} as const satisfies Record<OutputMode, OutputGeneratorFn>;\n\ntype OutputGeneratorAgainstWorktreeFn = (\n\tref: string,\n\toptions: GitDiffOptions | undefined,\n) => Promise<string>;\n\nconst outputGeneratorsAgainstWorktreeByMode = {\n\tdiff: (ref: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffAgainstWorktree(ref, options),\n\tpatch: (ref: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffAgainstWorktree(ref, options),\n\tstat: (ref: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffStatAgainstWorktree(ref, options),\n\tnumstat: (ref: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffNumStatAgainstWorktree(ref, options),\n\tshortstat: (ref: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffShortStatAgainstWorktree(ref, options),\n\t\"name-only\": (ref: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffNameOnlyAgainstWorktree(ref, options),\n\t\"name-status\": (ref: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffNameStatusAgainstWorktree(ref, options),\n\tsummary: (ref: string, options: GitDiffOptions | undefined) =>\n\t\tgitClient.diffSummaryAgainstWorktree(ref, options),\n} as const satisfies Record<OutputMode, OutputGeneratorAgainstWorktreeFn>;\n\n/**\n * Generate output based on the specified mode\n */\nexport async function generateOutput(\n\tmode: OutputMode,\n\tleft: string,\n\tright: string,\n\toptions: GitDiffOptions | undefined,\n\tpatchStyle: PatchStyle | undefined,\n): Promise<string> {\n\tconst generator = outputGeneratorsByMode[mode];\n\treturn generator(left, right, options, patchStyle);\n}\n\n/**\n * Generate output between a ref and the working tree\n */\nexport async function generateOutputAgainstWorktree(\n\tmode: OutputMode,\n\tref: string,\n\toptions: GitDiffOptions | undefined,\n): Promise<string> {\n\tconst generator = outputGeneratorsAgainstWorktreeByMode[mode];\n\treturn generator(ref, options);\n}\n","/**\n * Error handler\n * Normalizes unknown errors into DiffxError instances\n */\n\nimport { DiffxError, ExitCode } from \"../types\";\n\n/**\n * Normalize an unknown error into a typed DiffxError\n */\nexport function handleError(error: unknown): DiffxError {\n\tif (error instanceof DiffxError) {\n\t\treturn error;\n\t}\n\n\tif (error instanceof Error) {\n\t\treturn new DiffxError(error.message, ExitCode.GIT_ERROR);\n\t}\n\n\treturn new DiffxError(String(error), ExitCode.GIT_ERROR);\n}\n\ntype EmptyOutputCheckInput = {\n\thasActiveFilters: boolean;\n\thasUnfilteredChanges: boolean;\n};\n\ntype EmptyOutputCheckResult = {\n\tisEmpty: boolean;\n\tisFilterMismatch: boolean;\n};\n\n/**\n * Check whether output is empty and whether that emptiness came from file filters\n */\nexport function checkEmptyOutput(\n\toutput: string,\n\t{ hasActiveFilters, hasUnfilteredChanges }: EmptyOutputCheckInput,\n): EmptyOutputCheckResult {\n\tconst isEmpty = !output || output.trim().length === 0;\n\tif (!isEmpty) {\n\t\treturn { isEmpty: false, isFilterMismatch: false };\n\t}\n\n\treturn {\n\t\tisEmpty: true,\n\t\tisFilterMismatch: hasActiveFilters && hasUnfilteredChanges,\n\t};\n}\n\n/**\n * Create a typed no-files-matched error\n */\nexport function createNoFilesMatchedError(): DiffxError {\n\treturn new DiffxError(\"No files matched the specified filters\", ExitCode.NO_FILES_MATCHED);\n}\n","/**\n * Pager utilities\n */\n\nimport { spawn } from \"node:child_process\";\nimport { gitClient } from \"../git/git-client\";\n\ntype PagerControl = {\n\tforce?: boolean;\n\tdisable?: boolean;\n\tpager?: string;\n};\n\nexport function shouldUsePager(control: PagerControl): boolean | Promise<boolean> {\n\tif (control.disable) return false;\n\tif (control.force) return true;\n\tif (!process.stdout.isTTY) return false;\n\n\t// Check if pager option is explicitly set to \"false\"\n\tif (control.pager === \"false\") return false;\n\n\t// If pager is explicitly provided (and not \"false\"), use it\n\tif (control.pager) return true;\n\n\t// Otherwise, check if there's a valid pager configured (async, no default)\n\treturn resolvePagerCommand().then((cmd) => cmd !== null && cmd !== \"\" && cmd !== \"false\");\n}\n\nasync function resolvePagerCommand(): Promise<string | null> {\n\tconst gitPager = process.env.GIT_PAGER;\n\tif (gitPager && gitPager.trim().length > 0) {\n\t\treturn gitPager.trim();\n\t}\n\n\t// Only trust user-level git config; do not execute repository-local core.pager.\n\tconst corePager =\n\t\t(await gitClient.getConfigValue(\"core.pager\", \"global\")) ??\n\t\t(await gitClient.getConfigValue(\"core.pager\", \"system\"));\n\tif (corePager && corePager.trim().length > 0) {\n\t\treturn corePager.trim();\n\t}\n\n\tconst pager = process.env.PAGER;\n\tif (pager && pager.trim().length > 0) {\n\t\treturn pager.trim();\n\t}\n\n\treturn null;\n}\n\nfunction parsePagerCommand(command: string): { file: string; args: string[] } | null {\n\tconst tokens: string[] = [];\n\tlet current = \"\";\n\tlet quote: \"'\" | '\"' | null = null;\n\tlet escaping = false;\n\n\tfor (let i = 0; i < command.length; i++) {\n\t\tconst char = command[i];\n\n\t\tif (escaping) {\n\t\t\tcurrent += char;\n\t\t\tescaping = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"\\\\\") {\n\t\t\tescaping = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote) {\n\t\t\tif (char === quote) {\n\t\t\t\tquote = null;\n\t\t\t} else {\n\t\t\t\tcurrent += char;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"'\" || char === '\"') {\n\t\t\tquote = char;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (/\\s/.test(char)) {\n\t\t\tif (current.length > 0) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += char;\n\t}\n\n\tif (escaping || quote) {\n\t\treturn null;\n\t}\n\n\tif (current.length > 0) {\n\t\ttokens.push(current);\n\t}\n\n\tif (tokens.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst [file, ...args] = tokens;\n\treturn { file, args };\n}\n\nasync function runPager(command: string, output: string): Promise<void> {\n\tconst parsed = parsePagerCommand(command);\n\tif (!parsed) {\n\t\tthrow new Error(\"Invalid pager command\");\n\t}\n\n\t// Determine args and environment based on pager type\n\tlet args = parsed.args;\n\tconst env: Record<string, string | undefined> = {};\n\n\t// Special handling for less pager\n\tconst isLess = parsed.file.endsWith(\"less\") || parsed.file === \"less\";\n\tif (isLess) {\n\t\t// Add -R flag for less if not already present\n\t\tif (!args.includes(\"-R\")) {\n\t\t\targs = [\"-R\", ...args];\n\t\t}\n\t\t// Set LESS environment variable\n\t\tenv.LESS = \"FRX\";\n\t} else {\n\t\t// Explicitly set LESS to undefined for non-less pagers\n\t\tenv.LESS = undefined;\n\t}\n\n\tawait new Promise<void>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst resolveOnce = () => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tresolve();\n\t\t};\n\t\tconst rejectOnce = (error: Error) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\treject(error);\n\t\t};\n\n\t\tconst child = spawn(parsed.file, args, {\n\t\t\tstdio: [\"pipe\", \"inherit\", \"inherit\"],\n\t\t\tenv: { ...process.env, ...env },\n\t\t});\n\n\t\tchild.on(\"error\", (error) => rejectOnce(error instanceof Error ? error : new Error(String(error))));\n\t\tchild.on(\"exit\", (code) => {\n\t\t\tif (code && code !== 0) {\n\t\t\t\trejectOnce(new Error(`Pager exited with code ${code}`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolveOnce();\n\t\t});\n\n\t\tif (child.stdin) {\n\t\t\tchild.stdin.on(\"error\", (error: NodeJS.ErrnoException) => {\n\t\t\t\t// Pager may exit before fully consuming stdin (e.g. user presses \"q\" in delta/less).\n\t\t\t\t// Treat broken pipe/closed stream as expected pager shutdown.\n\t\t\t\tif (error.code === \"EPIPE\" || error.code === \"ERR_STREAM_DESTROYED\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trejectOnce(error);\n\t\t\t});\n\t\t\tchild.stdin.write(output);\n\t\t\tchild.stdin.end();\n\t\t}\n\t});\n}\n\nexport async function pageOutput(output: string, control: PagerControl): Promise<boolean> {\n\tconst shouldPage = await shouldUsePager(control);\n\tif (!shouldPage) {\n\t\treturn false;\n\t}\n\n\t// Use explicit pager if provided, otherwise resolve from config\n\tlet pagerCommand = control.pager;\n\tif (!pagerCommand) {\n\t\tpagerCommand = (await resolvePagerCommand()) ?? \"less -R\";\n\t}\n\n\ttry {\n\t\tawait runPager(pagerCommand, output);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","/**\n * Argument partitioning for git diff pass-through\n *\n * This module handles the separation of diffx-owned flags from git pass-through flags.\n * The goal is to allow any git diff flag to work without diffx needing to know about it.\n */\n\n/**\n * Flags that are owned and processed by diffx\n * Everything else is passed through to git diff\n *\n * Note: Git output format flags (--stat, --numstat, etc.) are NOT owned by diffx\n * and are passed through to git for native git compatibility.\n * Use --overview to get diffx enhancements (e.g., including untracked files).\n */\nexport const DIFFX_OWNED_FLAGS = [\n\t\"--mode\",\n\t\"--include\",\n\t\"--exclude\",\n\t\"--pager\",\n\t\"--no-pager\",\n\t\"--overview\",\n\t\"--index\",\n] as const;\n\nconst DIFFX_SHORT_FLAG_ALIASES: Record<string, DiffxOwnedFlag> = {\n\t\"-i\": \"--include\",\n\t\"-e\": \"--exclude\",\n};\n\n/**\n * Note: --summary is no longer a diffx-owned flag as of Phase 2\n * It now passes through to native git diff --summary (structural summary)\n * The custom diffx table output is now only available via --overview\n */\n\n/**\n * Git output format flags that are mutually exclusive with --overview\n */\nexport const GIT_OUTPUT_FORMAT_FLAGS = [\n\t\"--stat\",\n\t\"--numstat\",\n\t\"--name-only\",\n\t\"--name-status\",\n\t\"--raw\",\n\t\"-p\",\n\t\"--patch\",\n\t\"--shortstat\",\n] as const;\n\n/**\n * Git diff flags that consume the next argv token as a value.\n * This prevents value tokens (e.g. regex patterns containing \"..\")\n * from being misclassified as diff ranges.\n */\nconst GIT_FLAGS_WITH_SEPARATE_VALUE = new Set([\n\t\"--abbrev\",\n\t\"--anchored\",\n\t\"--color\",\n\t\"--color-moved\",\n\t\"--color-moved-ws\",\n\t\"--diff-algorithm\",\n\t\"--dst-prefix\",\n\t\"--find-object\",\n\t\"--find-renames\",\n\t\"--find-copies\",\n\t\"--inter-hunk-context\",\n\t\"--line-prefix\",\n\t\"--output\",\n\t\"--output-indicator-context\",\n\t\"--output-indicator-new\",\n\t\"--output-indicator-old\",\n\t\"--relative\",\n\t\"--skip-to\",\n\t\"--rotate-to\",\n\t\"--src-prefix\",\n\t\"--stat-count\",\n\t\"--stat-graph-width\",\n\t\"--stat-name-width\",\n\t\"--stat-width\",\n\t\"--submodule\",\n\t\"--word-diff\",\n\t\"--word-diff-regex\",\n\t\"-G\",\n\t\"-O\",\n\t\"-S\",\n\t\"-U\",\n]);\n\nexport type DiffxOwnedFlag = (typeof DIFFX_OWNED_FLAGS)[number];\nexport type GitOutputFormatFlag = (typeof GIT_OUTPUT_FORMAT_FLAGS)[number];\n\n/**\n * Partitioned command-line arguments\n */\nexport interface PartitionedArgs {\n\t/** Flags owned by diffx with their values */\n\tdiffxFlags: Map<DiffxOwnedFlag, string | string[] | boolean>;\n\t/** Input range or URL (e.g., github:owner/repo#123, gitlab:owner/repo!123, https://github.com/.../pull/123) */\n\tinputRange: string | undefined;\n\t/** Git pass-through arguments (preserved order) */\n\tgitArgs: string[];\n\t/** Pathspecs (files after -- separator) */\n\tpathspecs: string[];\n}\n\n/**\n * Check if a flag is a diffx-owned flag\n */\nfunction isDiffxOwnedFlag(flag: string): flag is DiffxOwnedFlag {\n\treturn DIFFX_OWNED_FLAGS.includes(flag as DiffxOwnedFlag);\n}\n\nfunction normalizeDiffxFlag(flag: string): DiffxOwnedFlag | null {\n\tif (isDiffxOwnedFlag(flag)) {\n\t\treturn flag;\n\t}\n\treturn DIFFX_SHORT_FLAG_ALIASES[flag] ?? null;\n}\n\n/**\n * Check if a flag is a git output format flag\n */\nexport function isGitOutputFormatFlag(flag: string): flag is GitOutputFormatFlag {\n\treturn GIT_OUTPUT_FORMAT_FLAGS.includes(flag as GitOutputFormatFlag);\n}\n\n/**\n * Check if the flag is a negatable form (no-* version)\n */\nfunction isNegatedFlag(flag: string): boolean {\n\treturn flag.startsWith(\"--no-\");\n}\n\n/**\n * Get the base flag name from a negated flag\n * e.g., \"--no-pager\" => \"pager\"\n */\nfunction getBaseFlagName(flag: string): string {\n\tif (isNegatedFlag(flag)) {\n\t\treturn `--${flag.slice(5)}`; // Remove \"--no-\" prefix\n\t}\n\treturn flag;\n}\n\n/**\n * Parse a flag token to extract the flag name\n * Handles:\n * - --flag\n * - --flag=value\n * - --flag value\n * - -f\n * - -fvalue (combined short form)\n */\nfunction parseFlagName(arg: string): string {\n\tif (arg.startsWith(\"--\")) {\n\t\t// Long option: --flag or --flag=value\n\t\tconst idx = arg.indexOf(\"=\");\n\t\treturn idx >= 0 ? arg.slice(0, idx) : arg;\n\t} else if (arg.startsWith(\"-\") && arg.length > 1) {\n\t\t// Short option: -f or -fvalue\n\t\treturn arg.slice(0, 2);\n\t}\n\treturn arg;\n}\n\nfunction isGitFlagWithSeparateValue(arg: string): boolean {\n\tconst flagName = parseFlagName(arg);\n\treturn GIT_FLAGS_WITH_SEPARATE_VALUE.has(flagName);\n}\n\nfunction isValueForPreviousGitFlag(argv: string[], index: number): boolean {\n\tif (index <= 0) {\n\t\treturn false;\n\t}\n\tconst previousArg = argv[index - 1];\n\treturn (\n\t\t!previousArg.startsWith(\"--no-\") &&\n\t\t!normalizeDiffxFlag(parseFlagName(previousArg)) &&\n\t\tisGitFlagWithSeparateValue(previousArg)\n\t);\n}\n\n/**\n * Check if an argument takes a value\n * For diffx flags, we know which ones take values\n */\nfunction diffxFlagTakesValue(flag: string): boolean {\n\treturn flag === \"--mode\" || flag === \"--include\" || flag === \"--exclude\";\n}\n\nfunction appendDiffxFlagValue(\n\tdiffxFlags: Map<DiffxOwnedFlag, string | string[] | boolean>,\n\tflag: DiffxOwnedFlag,\n\tvalue: string,\n): void {\n\tconst existing = diffxFlags.get(flag);\n\tif (existing === undefined) {\n\t\tdiffxFlags.set(flag, value);\n\t\treturn;\n\t}\n\tif (Array.isArray(existing)) {\n\t\texisting.push(value);\n\t\tdiffxFlags.set(flag, existing);\n\t\treturn;\n\t}\n\tif (typeof existing === \"string\") {\n\t\tdiffxFlags.set(flag, [existing, value]);\n\t\treturn;\n\t}\n\tdiffxFlags.set(flag, value);\n}\n\n/**\n * Check if a token looks like a range/URL input\n * This is a heuristic to distinguish positionals from git revs\n */\nfunction looksLikeRangeOrUrl(arg: string): boolean {\n\t// GitHub PR ref format\n\tif (arg.startsWith(\"github:\")) return true;\n\n\t// GitLab MR ref format\n\tif (arg.startsWith(\"gitlab:\")) return true;\n\n\t// URL format\n\tif (arg.startsWith(\"http://\") || arg.startsWith(\"https://\")) return true;\n\n\t// Git URL format\n\tif (arg.startsWith(\"git@\") || arg.includes(\"://\")) return true;\n\n\t// Contains .. (range syntax like main..feature, main...feature)\n\tif (arg.includes(\"..\")) return true;\n\n\treturn false;\n}\n\n/**\n * Partition command-line arguments into diffx-owned and git pass-through\n *\n * @param argv - Raw command-line arguments (excluding program name)\n * @param tokens - Parsed tokens from gunshi CLI framework\n * @returns Partitioned arguments\n */\nexport function partitionArgs(\n\targv: string[],\n\ttokens: { kind: string; name?: string; rawName?: string }[],\n): PartitionedArgs {\n\tconst diffxFlags: PartitionedArgs[\"diffxFlags\"] = new Map();\n\tconst gitArgs: string[] = [];\n\tconst pathspecs: string[] = [];\n\n\tlet inputRange: string | undefined = undefined;\n\tlet seenDoubleDash = false;\n\tlet i = 0;\n\n\twhile (i < argv.length) {\n\t\tconst arg = argv[i];\n\n\t\t// Handle -- separator (option terminator)\n\t\tif (arg === \"--\" && !seenDoubleDash) {\n\t\t\tseenDoubleDash = true;\n\t\t\ti++;\n\n\t\t\t// Everything after -- is a pathspec\n\t\t\twhile (i < argv.length) {\n\t\t\t\tpathspecs.push(argv[i]);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t// If we've seen --, everything else is a pathspec\n\t\tif (seenDoubleDash) {\n\t\t\tpathspecs.push(arg);\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Parse the flag name\n\t\tconst flagName = parseFlagName(arg);\n\n\t\tconst normalizedFlag = normalizeDiffxFlag(flagName);\n\n\t\t// Check if this is a diffx-owned flag\n\t\tif (normalizedFlag) {\n\t\t\t// Extract the value if the flag takes one\n\t\t\tif (diffxFlagTakesValue(normalizedFlag)) {\n\t\t\t\t// Check if value is in the same arg (--flag=value)\n\t\t\t\tconst idx = arg.indexOf(\"=\");\n\t\t\t\tif (idx >= 0) {\n\t\t\t\t\tappendDiffxFlagValue(diffxFlags, normalizedFlag, arg.slice(idx + 1));\n\t\t\t\t} else if (arg.startsWith(flagName) && arg.length > flagName.length) {\n\t\t\t\t\t// Combined short form like -i*.ts\n\t\t\t\t\tappendDiffxFlagValue(diffxFlags, normalizedFlag, arg.slice(flagName.length));\n\t\t\t\t} else if (i + 1 < argv.length && !argv[i + 1].startsWith(\"-\")) {\n\t\t\t\t\t// Value is next arg\n\t\t\t\t\tappendDiffxFlagValue(diffxFlags, normalizedFlag, argv[i + 1]);\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\t// Flag without value (treat as boolean true)\n\t\t\t\t\tdiffxFlags.set(normalizedFlag, true);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Boolean flag\n\t\t\t\tconst baseFlag = getBaseFlagName(normalizedFlag);\n\t\t\t\tconst value = isNegatedFlag(flagName);\n\t\t\t\tdiffxFlags.set(baseFlag as DiffxOwnedFlag, !value);\n\t\t\t}\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Not a diffx flag - pass through to git\n\t\t// But check if it looks like a range/URL positional first\n\t\tif (\n\t\t\t!arg.startsWith(\"-\") &&\n\t\t\t!inputRange &&\n\t\t\t!isValueForPreviousGitFlag(argv, i) &&\n\t\t\tlooksLikeRangeOrUrl(arg)\n\t\t) {\n\t\t\tinputRange = arg;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Everything else is a git pass-through arg\n\t\tgitArgs.push(arg);\n\t\ti++;\n\t}\n\n\t// If no range found in argv, check positionals from tokens\n\t// The gunshi framework extracts positionals separately\n\tif (!inputRange) {\n\t\tconst positionals = tokens\n\t\t\t.filter((t) => t.kind === \"positional\")\n\t\t\t.map((t) => (t as { kind: string; value: string }).value)\n\t\t\t.filter((v) => v && v.trim().length > 0)\n\t\t\t.filter((v) => looksLikeRangeOrUrl(v))\n\t\t\t.filter((v) => {\n\t\t\t\tconst safeIdx = argv.findIndex(\n\t\t\t\t\t(arg, i) => arg === v && !isValueForPreviousGitFlag(argv, i),\n\t\t\t\t);\n\t\t\t\tif (safeIdx >= 0) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// If the value appears in argv only as an option value, do not treat it as a range.\n\t\t\t\tconst rawIdx = argv.indexOf(v);\n\t\t\t\tif (rawIdx >= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// Some CLI frameworks may surface positionals in tokens even when raw argv\n\t\t\t\t// has already been normalized. In that case, trust the token.\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\tif (positionals.length > 0) {\n\t\t\tinputRange = positionals[0];\n\t\t}\n\t}\n\n\treturn { diffxFlags, inputRange, gitArgs, pathspecs };\n}\n\n/**\n * Validate that --overview is not used with git output format flags\n */\nexport function validateOverviewMutualExclusivity(\n\tdiffxFlags: Map<string, unknown>,\n\tgitArgs: string[],\n): void {\n\tconst useOverview = diffxFlags.get(\"--overview\") === true;\n\n\tif (!useOverview) {\n\t\treturn;\n\t}\n\n\t// Check both diffxFlags and gitArgs for output format flags\n\tconst conflictingFlags: string[] = [];\n\n\t// Check diffxFlags for conflicting output format flags\n\tfor (const [flag] of diffxFlags) {\n\t\tif (isGitOutputFormatFlag(flag)) {\n\t\t\tconflictingFlags.push(flag);\n\t\t}\n\t}\n\n\t// Check gitArgs for output format flags\n\tfor (const arg of gitArgs) {\n\t\tconst flagName = parseFlagName(arg);\n\t\tif (isGitOutputFormatFlag(flagName)) {\n\t\t\tconflictingFlags.push(flagName);\n\t\t}\n\t}\n\n\tif (conflictingFlags.length > 0) {\n\t\tconst flags = conflictingFlags.join(\", \");\n\t\tthrow new Error(\n\t\t\t`Cannot use --overview with git output format flags: ${flags}\\n` +\n\t\t\t\t\"Use --overview for diffx custom output, or git flags for native output.\",\n\t\t);\n\t}\n}\n","/**\n * File filter\n * Handles include/exclude patterns for filtering diff output\n */\n\nimport type { FilterOptions } from \"../types\";\nimport { minimatch } from \"minimatch\";\n\n/**\n * Build file patterns array for git commands\n * Filters include patterns first, then excludes from those results\n */\nexport function buildFilePatterns(options: FilterOptions): string[] {\n\tconst patterns: string[] = [];\n\n\t// If no filters specified, return empty array (include all)\n\tif (!options.include && !options.exclude) {\n\t\treturn patterns;\n\t}\n\n\t// For now, we'll pass patterns directly to git\n\t// Git's pathspec behavior is complex, so we use a simplified approach:\n\t// 1. If includes specified, add them as positive patterns\n\t// 2. If excludes specified, add them as negative patterns\n\n\tif (options.include && options.include.length > 0) {\n\t\tpatterns.push(...options.include);\n\t}\n\n\tif (options.exclude && options.exclude.length > 0) {\n\t\t// Add as negative patterns (prefixed with :)\n\t\toptions.exclude.forEach((pattern) => {\n\t\t\tpatterns.push(`:!${pattern}`);\n\t\t});\n\t}\n\n\treturn patterns;\n}\n\n/**\n * Check if a file path matches the given patterns\n */\nexport function fileMatchesPattern(filePath: string, pattern: string): boolean {\n\t// Handle negative patterns\n\tif (pattern.startsWith(\":!\")) {\n\t\tconst negPattern = pattern.slice(2);\n\t\treturn !minimatch(filePath, negPattern, { dot: true });\n\t}\n\n\treturn minimatch(filePath, pattern, { dot: true });\n}\n\n/**\n * Check if a file should be included based on filter options\n */\nexport function shouldIncludeFile(filePath: string, options: FilterOptions): boolean {\n\t// If no filters, include everything\n\tif (!options.include && !options.exclude) {\n\t\treturn true;\n\t}\n\n\t// Check excludes first\n\tif (options.exclude && options.exclude.length > 0) {\n\t\tfor (const pattern of options.exclude) {\n\t\t\tif (minimatch(filePath, pattern, { dot: true })) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check includes\n\tif (options.include && options.include.length > 0) {\n\t\tfor (const pattern of options.include) {\n\t\t\tif (minimatch(filePath, pattern, { dot: true })) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\t// If includes specified but none matched, exclude the file\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n","import type { GitDiffOptions } from \"../git/types\";\nimport { buildFilePatterns } from \"../filters/file-filter\";\nimport { DiffxError, ExitCode, type OutputMode } from \"../types\";\nimport {\n\ttype PartitionedArgs,\n\tisGitOutputFormatFlag,\n\tvalidateOverviewMutualExclusivity,\n} from \"./arg-partitioner\";\nimport type { CliToken, FileFilterOptions } from \"./command-types\";\n\nconst MODES = new Set([\n\t\"diff\",\n\t\"patch\",\n\t\"stat\",\n\t\"numstat\",\n\t\"shortstat\",\n\t\"name-only\",\n\t\"name-status\",\n\t\"summary\",\n] as const);\n\nfunction parseFlagName(arg: string): string {\n\tif (arg.startsWith(\"--\")) {\n\t\tconst idx = arg.indexOf(\"=\");\n\t\treturn idx >= 0 ? arg.slice(0, idx) : arg;\n\t}\n\tif (arg.startsWith(\"-\") && arg.length > 1) {\n\t\treturn arg.slice(0, 2);\n\t}\n\treturn arg;\n}\n\nfunction parseMode(value: unknown): OutputMode | null {\n\tif (typeof value !== \"string\") {\n\t\treturn null;\n\t}\n\n\tif (!MODES.has(value as OutputMode)) {\n\t\treturn null;\n\t}\n\n\treturn value as OutputMode;\n}\n\nexport function validateNoConflictingFlags(\n\tdiffxFlags: Map<string, unknown>,\n\tgitArgs: string[],\n): void {\n\tconst pager = diffxFlags.get(\"--pager\");\n\tconst noPager = diffxFlags.get(\"--no-pager\");\n\tif (pager && noPager) {\n\t\tthrow new DiffxError(\"Cannot use both --pager and --no-pager\", ExitCode.INVALID_INPUT);\n\t}\n\n\tvalidateOverviewMutualExclusivity(diffxFlags, gitArgs);\n}\n\nexport function shouldUseGitPassThrough(\n\tpartitioned: Pick<PartitionedArgs, \"gitArgs\" | \"diffxFlags\" | \"pathspecs\">,\n\thasRange: boolean,\n\tuseGitCompat: boolean,\n\thasActiveFilters: boolean,\n): boolean {\n\tif (hasActiveFilters) {\n\t\treturn false;\n\t}\n\n\tif (partitioned.diffxFlags.get(\"--overview\") === true) {\n\t\treturn false;\n\t}\n\n\tif (partitioned.diffxFlags.get(\"--mode\")) {\n\t\treturn false;\n\t}\n\n\tfor (const arg of partitioned.gitArgs) {\n\t\tconst flagName = parseFlagName(arg);\n\t\tif (isGitOutputFormatFlag(flagName)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tif (useGitCompat) {\n\t\treturn true;\n\t}\n\n\tif (hasRange) {\n\t\treturn true;\n\t}\n\n\tif (partitioned.gitArgs.length > 0 || partitioned.pathspecs.length > 0) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nexport function getOutputMode({\n\toverview,\n\tstat,\n\tnumstat,\n\tshortstat,\n\trawMode,\n\thasStatFlag,\n\thasNumstatFlag,\n\thasShortstatFlag,\n\thasNameOnlyFlag,\n\thasNameStatusFlag,\n}: {\n\toverview: boolean | undefined;\n\tstat: boolean | undefined;\n\tnumstat: boolean | undefined;\n\tshortstat: boolean | undefined;\n\trawMode: string | undefined;\n\thasStatFlag: boolean;\n\thasNumstatFlag: boolean;\n\thasShortstatFlag: boolean;\n\thasNameOnlyFlag: boolean;\n\thasNameStatusFlag: boolean;\n}): OutputMode {\n\tconst mode = parseMode(rawMode);\n\n\tif (mode) {\n\t\treturn mode;\n\t}\n\n\tif (rawMode !== undefined) {\n\t\tthrow new DiffxError(\n\t\t\t`Invalid mode: ${rawMode}\\nSupported modes: diff, patch, stat, numstat, shortstat, name-only, name-status`,\n\t\t\tExitCode.INVALID_INPUT,\n\t\t);\n\t}\n\n\tif (overview) {\n\t\treturn \"numstat\";\n\t}\n\n\tif (stat || hasStatFlag) {\n\t\treturn \"stat\";\n\t}\n\n\tif (numstat || hasNumstatFlag) {\n\t\treturn \"numstat\";\n\t}\n\n\tif (shortstat || hasShortstatFlag) {\n\t\treturn \"shortstat\";\n\t}\n\n\tif (hasNameOnlyFlag) {\n\t\treturn \"name-only\";\n\t}\n\n\tif (hasNameStatusFlag) {\n\t\treturn \"name-status\";\n\t}\n\n\treturn \"diff\";\n}\n\nexport function getRangeOrUrl(\n\tpositionals: string[],\n\tpartitionedInputRange: string | undefined,\n): string | undefined {\n\tif (positionals.length <= 1) {\n\t\treturn partitionedInputRange;\n\t}\n\n\tthrow new DiffxError(\n\t\t`Unexpected arguments: ${positionals.slice(1).join(\" \")}`,\n\t\tExitCode.INVALID_INPUT,\n\t);\n}\n\nexport function validatePagerOptions(\n\tpager: boolean | undefined,\n\tnoPager: boolean | undefined,\n): void {\n\tif (pager && noPager) {\n\t\tthrow new DiffxError(\"Cannot use both --pager and --no-pager\", ExitCode.INVALID_INPUT);\n\t}\n}\n\nexport function hasLongOptionFlag(tokens: CliToken[], optionName: string): boolean {\n\tlet seenOptionTerminator = false;\n\tfor (const token of tokens) {\n\t\tif (token.kind === \"option-terminator\") {\n\t\t\tseenOptionTerminator = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (seenOptionTerminator || token.kind !== \"option\") {\n\t\t\tcontinue;\n\t\t}\n\t\tif (token.name === optionName) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function getFilterOptions({\n\tinclude,\n\texclude,\n}: {\n\tinclude: string | string[] | undefined;\n\texclude: string | string[] | undefined;\n}): FileFilterOptions {\n\tconst normalize = (value: string | string[] | undefined): string[] | undefined => {\n\t\tif (!value) return undefined;\n\t\treturn Array.isArray(value) ? value : [value];\n\t};\n\n\treturn {\n\t\tinclude: normalize(include),\n\t\texclude: normalize(exclude),\n\t};\n}\n\nexport function buildDiffOptions(\n\tfilterOptions: FileFilterOptions,\n\tpager: boolean | undefined,\n\tmode: OutputMode,\n\textraGitArgs: string[] = [],\n): { diffOptions: GitDiffOptions; color: \"always\" | \"never\" } {\n\tconst patterns = buildFilePatterns(filterOptions);\n\tconst supportsColorOutput = mode === \"diff\" || mode === \"patch\" || mode === \"stat\";\n\tconst wantsColor = supportsColorOutput && (Boolean(pager) || Boolean(process.stdout.isTTY));\n\tconst color: \"always\" | \"never\" = wantsColor ? \"always\" : \"never\";\n\n\treturn {\n\t\tdiffOptions: {\n\t\t\tfiles: patterns.length > 0 ? patterns : undefined,\n\t\t\tcolor,\n\t\t\textraArgs: extraGitArgs.length > 0 ? extraGitArgs : undefined,\n\t\t},\n\t\tcolor,\n\t};\n}\n\nexport function hasActiveFilters(filterOptions: FileFilterOptions): boolean {\n\treturn Boolean(filterOptions.include?.length || filterOptions.exclude?.length);\n}\n","import { gitClient } from \"../git/git-client\";\nimport { parseRangeInput } from \"../parsers/range-parser\";\nimport { resolveRefs } from \"../resolvers/ref-resolver\";\nimport { DiffxError, ExitCode } from \"../types\";\nimport type { PartitionedArgs } from \"./arg-partitioner\";\nimport { pageOutput } from \"./pager\";\n\nexport async function runGitPassThrough({\n\tpartitioned,\n\trangeOrUrl,\n\tuseGitCompat,\n\tpager,\n\tnoPager,\n}: {\n\tpartitioned: PartitionedArgs;\n\trangeOrUrl: string | undefined;\n\tuseGitCompat: boolean;\n\tpager: boolean | undefined;\n\tnoPager: boolean | undefined;\n}): Promise<void> {\n\tlet cleanup: (() => Promise<void>) | undefined;\n\n\tlet left = \"\";\n\tlet right = \"\";\n\n\tif (rangeOrUrl) {\n\t\tlet parsed: ReturnType<typeof parseRangeInput> | undefined;\n\t\ttry {\n\t\t\tparsed = parseRangeInput(rangeOrUrl);\n\t\t} catch (error) {\n\t\t\tif (error instanceof DiffxError && error.exitCode === ExitCode.INVALID_INPUT) {\n\t\t\t\tparsed = undefined;\n\t\t\t} else {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tif (!parsed) {\n\t\t\tif (!partitioned.gitArgs.includes(rangeOrUrl)) {\n\t\t\t\tleft = rangeOrUrl;\n\t\t\t}\n\t\t} else if (parsed.type === \"local-range\") {\n\t\t\tleft = parsed.left;\n\t\t\tright = parsed.right;\n\t\t} else {\n\t\t\tconst resolved = await resolveRefs(parsed);\n\t\t\tleft = resolved.left;\n\t\t\tright = resolved.right;\n\t\t\tcleanup = resolved.cleanup;\n\t\t}\n\t} else if (useGitCompat) {\n\t\tleft = \"\";\n\t\tright = \"\";\n\t}\n\n\tconst gitDiffArgs: string[] = [];\n\tif (left) gitDiffArgs.push(left);\n\tif (right) gitDiffArgs.push(right);\n\tif (partitioned.pathspecs.length > 0) {\n\t\tgitDiffArgs.push(\"--\");\n\t\tgitDiffArgs.push(...partitioned.pathspecs);\n\t}\n\n\tconst fullGitArgs = [...partitioned.gitArgs, ...gitDiffArgs];\n\n\ttry {\n\t\tconst result = await gitClient.runGitDiffRaw(fullGitArgs);\n\t\tif (result.exitCode !== 0) {\n\t\t\tconst message = result.stderr.trim().length > 0 ? result.stderr : \"git diff failed\";\n\t\t\tthrow new DiffxError(message, ExitCode.GIT_ERROR);\n\t\t}\n\n\t\tconst output = result.stdout;\n\t\tconst disablePager = Boolean(noPager);\n\t\tconst paged = await pageOutput(output, {\n\t\t\tforce: pager,\n\t\t\tdisable: disablePager,\n\t\t});\n\t\tif (!paged) {\n\t\t\tprocess.stdout.write(output);\n\t\t}\n\t} finally {\n\t\tif (cleanup) {\n\t\t\ttry {\n\t\t\t\tawait cleanup();\n\t\t\t} catch {\n\t\t\t\t// Ignore cleanup errors\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * Numstat output helpers\n */\n\nimport type { OutputMode } from \"../types\";\nimport { gitClient } from \"../git/git-client\";\nimport { shouldIncludeFile } from \"../filters/file-filter\";\n\ntype StatusMap = Map<string, string>;\n\nconst StatusCodeByName = {\n\tUNTRACKED: \"U\",\n\tUNMERGED: \"U\",\n\tDELETED: \"D\",\n\tADDED: \"A\",\n\tRENAMED: \"R\",\n\tCOPIED: \"C\",\n\tMODIFIED: \"M\",\n\tIGNORED: \"!\",\n\tUNKNOWN: \"?\",\n} as const;\n\nfunction hasStatusCode(file: { working_dir: string; index: string }, code: string): boolean {\n\treturn file.working_dir === code || file.index === code;\n}\n\nfunction resolveStatusCode(file: { working_dir: string; index: string }): string {\n\tif (hasStatusCode(file, \"?\")) return StatusCodeByName.UNTRACKED;\n\tif (hasStatusCode(file, \"U\")) return StatusCodeByName.UNMERGED;\n\tif (file.index === \"!\" && file.working_dir === \"!\") return StatusCodeByName.IGNORED;\n\tif (hasStatusCode(file, \"D\")) return StatusCodeByName.DELETED;\n\tif (hasStatusCode(file, \"A\")) return StatusCodeByName.ADDED;\n\tif (hasStatusCode(file, \"R\")) return StatusCodeByName.RENAMED;\n\tif (hasStatusCode(file, \"C\")) return StatusCodeByName.COPIED;\n\tif (hasStatusCode(file, \"M\")) return StatusCodeByName.MODIFIED;\n\treturn StatusCodeByName.UNKNOWN;\n}\n\nexport async function generateUntrackedOutput(\n\tmode: OutputMode,\n\tfiles: string[],\n\tcolor?: \"always\" | \"never\" | \"auto\",\n\tstatAlignWidth?: number,\n): Promise<string> {\n\tconst chunks: string[] = [];\n\tconst statLines: string[] = [];\n\tlet totalInsertions = 0;\n\tlet totalDeletions = 0;\n\tlet totalFiles = 0;\n\tfor (const filePath of files) {\n\t\tswitch (mode) {\n\t\t\tcase \"diff\":\n\t\t\tcase \"patch\":\n\t\t\t\tchunks.push(cleanNoIndexPath(await gitClient.diffNoIndex(filePath, color)));\n\t\t\t\tbreak;\n\t\t\tcase \"stat\":\n\t\t\t\t{\n\t\t\t\t\tconst statOutput = await gitClient.diffStatNoIndex(filePath, color);\n\t\t\t\t\tconst statLine = extractStatLine(statOutput);\n\t\t\t\t\tif (statLine) {\n\t\t\t\t\t\tstatLines.push(formatStatLine(statLine, statAlignWidth));\n\t\t\t\t\t}\n\n\t\t\t\t\tconst numstat = await gitClient.diffNumStatNoIndex(filePath, color);\n\t\t\t\t\tfor (const line of numstat.split(\"\\n\")) {\n\t\t\t\t\t\tconst trimmed = line.trim();\n\t\t\t\t\t\tif (!trimmed) continue;\n\t\t\t\t\t\tconst parts = trimmed.split(\"\\t\");\n\t\t\t\t\t\tif (parts.length < 2) continue;\n\t\t\t\t\t\tconst adds = Number(parts[0]);\n\t\t\t\t\t\tconst dels = Number(parts[1]);\n\t\t\t\t\t\ttotalInsertions += Number.isFinite(adds) ? adds : 0;\n\t\t\t\t\t\ttotalDeletions += Number.isFinite(dels) ? dels : 0;\n\t\t\t\t\t\ttotalFiles += 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"numstat\":\n\t\t\t\tchunks.push(cleanNoIndexPath(await gitClient.diffNumStatNoIndex(filePath, color)).trim());\n\t\t\t\tbreak;\n\t\t\tcase \"shortstat\":\n\t\t\t\t{\n\t\t\t\t\t// Accumulate totals for shortstat\n\t\t\t\t\tconst numstat = await gitClient.diffNumStatNoIndex(filePath, color);\n\t\t\t\t\tfor (const line of numstat.split(\"\\n\")) {\n\t\t\t\t\t\tconst trimmed = line.trim();\n\t\t\t\t\t\tif (!trimmed) continue;\n\t\t\t\t\t\tconst parts = trimmed.split(\"\\t\");\n\t\t\t\t\t\tif (parts.length < 2) continue;\n\t\t\t\t\t\tconst adds = Number(parts[0]);\n\t\t\t\t\t\tconst dels = Number(parts[1]);\n\t\t\t\t\t\ttotalInsertions += Number.isFinite(adds) ? adds : 0;\n\t\t\t\t\t\ttotalDeletions += Number.isFinite(dels) ? dels : 0;\n\t\t\t\t\t\ttotalFiles += 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"name-only\":\n\t\t\t\t// Just the filename, one per line\n\t\t\t\tchunks.push(filePath);\n\t\t\t\tbreak;\n\t\t\tcase \"name-status\":\n\t\t\t\t// Filename with status \"U\" for untracked\n\t\t\t\tchunks.push(`U\\t${filePath}`);\n\t\t\t\tbreak;\n\t\t\tcase \"summary\":\n\t\t\t\t// Summary shows create operations for untracked files\n\t\t\t\tchunks.push(`create mode 100644 ${filePath}`);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unknown output mode: ${mode}`);\n\t\t}\n\t}\n\tif (mode === \"stat\") {\n\t\tif (statLines.length === 0) return \"\";\n\t\tconst summary = formatSummaryLine(totalFiles, totalInsertions, totalDeletions);\n\t\treturn `${statLines.join(\"\\n\")}\\n ${summary}`;\n\t}\n\n\tif (mode === \"shortstat\") {\n\t\tif (totalFiles === 0) return \"\";\n\t\treturn formatSummaryLine(totalFiles, totalInsertions, totalDeletions);\n\t}\n\n\treturn chunks.filter((chunk) => chunk.trim().length > 0).join(\"\\n\");\n}\n\nexport function mergeOutputs(base: string, extra: string): string {\n\tif (!base) return extra;\n\tif (!extra) return base;\n\treturn `${base.trimEnd()}\\n${extra.trimStart()}`;\n}\n\nexport async function buildStatusMapForWorktree(filterOptions: {\n\tinclude?: string[];\n\texclude?: string[];\n}): Promise<StatusMap> {\n\tconst status = await gitClient.getStatus();\n\tconst map: StatusMap = new Map();\n\n\tfor (const filePath of status.not_added) {\n\t\tif (shouldIncludeFile(filePath, filterOptions)) {\n\t\t\tmap.set(filePath, \"U\");\n\t\t}\n\t}\n\n\tfor (const file of status.files) {\n\t\tif (!shouldIncludeFile(file.path, filterOptions)) continue;\n\t\tif (map.get(file.path) === StatusCodeByName.UNTRACKED) continue;\n\t\tmap.set(file.path, resolveStatusCode(file));\n\t}\n\n\treturn map;\n}\n\nexport async function buildStatusMapForRange(left: string, right: string): Promise<StatusMap> {\n\tconst output = await gitClient.diffNameStatus(left, right, undefined);\n\tconst map: StatusMap = new Map();\n\tfor (const line of output.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed) continue;\n\t\tconst parts = trimmed.split(\"\\t\");\n\t\tconst status = parts[0];\n\t\tif (status.startsWith(\"R\") || status.startsWith(\"C\")) {\n\t\t\tconst filePath = parts[2] ?? parts[1];\n\t\t\tif (filePath) map.set(filePath, status[0]);\n\t\t\tcontinue;\n\t\t}\n\t\tconst filePath = parts[1];\n\t\tif (filePath) map.set(filePath, status[0]);\n\t}\n\treturn map;\n}\n\nexport function formatNumstatOutput(output: string, statusMap: StatusMap): string {\n\tconst rows = output\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trim())\n\t\t.filter((line) => line.length > 0)\n\t\t.map((line) => {\n\t\t\tconst parts = line.split(\"\\t\");\n\t\t\tif (parts.length < 3) {\n\t\t\t\treturn { filePath: line, status: \"?\", adds: \"0\", dels: \"0\" };\n\t\t\t}\n\t\t\tconst adds = parts[0];\n\t\t\tconst dels = parts[1];\n\t\t\tconst filePath = parts.slice(2).join(\"\\t\").trim();\n\t\t\tconst status = statusMap.get(filePath) ?? \"?\";\n\t\t\treturn { filePath, status, adds, dels };\n\t\t});\n\n\tconst fileWidth = Math.max(4, ...rows.map((row) => row.filePath.length));\n\tconst statusWidth = 1;\n\tconst addsWidth = Math.max(1, ...rows.map((row) => row.adds.length));\n\tconst delsWidth = Math.max(1, ...rows.map((row) => row.dels.length));\n\n\tconst header = `${\"FILE\".padEnd(fileWidth)} ${\"S\".padEnd(statusWidth)} ${\"+\".padStart(addsWidth)} ${\"-\".padStart(delsWidth)}`;\n\tconst body = rows\n\t\t.map((row) => {\n\t\t\tconst fileCol = row.filePath.padEnd(fileWidth);\n\t\t\tconst statusCol = row.status.padEnd(statusWidth);\n\t\t\tconst addsCol = row.adds.padStart(addsWidth);\n\t\t\tconst delsCol = row.dels.padStart(delsWidth);\n\t\t\treturn `${fileCol} ${statusCol} ${addsCol} ${delsCol}`;\n\t\t})\n\t\t.join(\"\\n\");\n\treturn `${header}\\n${body}`;\n}\n\nfunction cleanNoIndexPath(output: string): string {\n\treturn output.replace(/\\/dev\\/null => /g, \"\");\n}\n\nfunction formatSummaryLine(files: number, insertions: number, deletions: number): string {\n\tconst fileLabel = files === 1 ? \"file changed\" : \"files changed\";\n\tconst insertLabel = insertions === 1 ? \"insertion(+)\" : \"insertions(+)\";\n\tconst deleteLabel = deletions === 1 ? \"deletion(-)\" : \"deletions(-)\";\n\treturn `${files} ${fileLabel}, ${insertions} ${insertLabel}, ${deletions} ${deleteLabel}`;\n}\n\nfunction extractStatLine(output: string): string | null {\n\tfor (const line of output.split(\"\\n\")) {\n\t\tif (line.includes(\"|\")) {\n\t\t\treturn line;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction formatStatLine(line: string, alignWidth?: number): string {\n\tconst [leftPart, rightPart = \"\"] = line.split(\"|\");\n\tconst rawFilePath = cleanNoIndexPath(leftPart).trim();\n\tconst fileWithLead = ` ${rawFilePath}`;\n\tconst width = Math.max(alignWidth ?? 0, fileWithLead.length);\n\tconst fileCol = fileWithLead.padEnd(width);\n\treturn `${fileCol} |${rightPart}`;\n}\n\nexport function formatStatOutput(output: string, alignWidth: number): string {\n\treturn output\n\t\t.split(\"\\n\")\n\t\t.map((line) => (line.includes(\"|\") ? formatStatLine(line, alignWidth) : line))\n\t\t.join(\"\\n\");\n}\n","import { buildFilePatterns, shouldIncludeFile } from \"../filters/file-filter\";\nimport { gitClient } from \"../git/git-client\";\nimport type { OutputMode } from \"../types\";\nimport {\n\tbuildStatusMapForRange,\n\tbuildStatusMapForWorktree,\n\tformatNumstatOutput,\n\tgenerateUntrackedOutput,\n\tmergeOutputs,\n} from \"../utils/overview-utils\";\nimport type { FileFilterOptions, ResolvedRefs } from \"./command-types\";\n\ntype StatRow = {\n\tfilePath: string;\n\tchangeCount: string;\n\tchangeBar: string;\n\tadditions: number;\n\tdeletions: number;\n};\n\ntype StatSummary = {\n\tfiles: number;\n\tinsertions: number;\n\tdeletions: number;\n};\n\nfunction cleanNoIndexPath(output: string): string {\n\treturn output.replace(/\\/dev\\/null => /g, \"\");\n}\n\nfunction parseStatOutput(output: string): { rows: StatRow[]; summary: StatSummary } {\n\tconst rows: StatRow[] = [];\n\tlet summary: StatSummary = { files: 0, insertions: 0, deletions: 0 };\n\n\tfor (const line of output.split(\"\\n\")) {\n\t\tconst idx = line.indexOf(\"|\");\n\t\tif (idx >= 0) {\n\t\t\tconst leftPart = line.slice(0, idx);\n\t\t\tconst rightPart = line.slice(idx + 1);\n\t\t\tconst filePath = cleanNoIndexPath(leftPart).trim();\n\t\t\tif (filePath.length > 0) {\n\t\t\t\tconst trimmedRight = rightPart.trim();\n\t\t\t\tconst match = trimmedRight.match(/^(\\d+)\\s+(.*)$/);\n\t\t\t\trows.push({\n\t\t\t\t\tfilePath,\n\t\t\t\t\tchangeCount: match ? match[1] : \"0\",\n\t\t\t\t\tchangeBar: match ? match[2] : trimmedRight,\n\t\t\t\t\tadditions: 0,\n\t\t\t\t\tdeletions: 0,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed.includes(\"file changed\") && !trimmed.includes(\"files changed\")) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst filesMatch = trimmed.match(/^(\\d+)\\s+files?\\s+changed/);\n\t\tconst insertionsMatch = trimmed.match(/(\\d+)\\s+insertions?\\(\\+\\)/);\n\t\tconst deletionsMatch = trimmed.match(/(\\d+)\\s+deletions?\\(-\\)/);\n\t\tif (filesMatch) {\n\t\t\tsummary = {\n\t\t\t\tfiles: Number.parseInt(filesMatch[1], 10) || 0,\n\t\t\t\tinsertions: insertionsMatch ? Number.parseInt(insertionsMatch[1], 10) || 0 : 0,\n\t\t\t\tdeletions: deletionsMatch ? Number.parseInt(deletionsMatch[1], 10) || 0 : 0,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { rows, summary };\n}\n\nfunction parseNumstatOutput(output: string): Map<string, { additions: number; deletions: number }> {\n\tconst map = new Map<string, { additions: number; deletions: number }>();\n\tfor (const line of output.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed) continue;\n\t\tconst parts = trimmed.split(\"\\t\");\n\t\tif (parts.length < 3) continue;\n\t\tconst filePath = cleanNoIndexPath(parts.slice(2).join(\"\\t\")).trim();\n\t\tif (!filePath) continue;\n\t\tconst additions = Number(parts[0]);\n\t\tconst deletions = Number(parts[1]);\n\t\tmap.set(filePath, {\n\t\t\tadditions: Number.isFinite(additions) ? additions : 0,\n\t\t\tdeletions: Number.isFinite(deletions) ? deletions : 0,\n\t\t});\n\t}\n\treturn map;\n}\n\nfunction buildStatBar(\n\tadditions: number,\n\tdeletions: number,\n\twidth: number,\n\tcolor: \"always\" | \"never\",\n): string {\n\tif (width <= 0) return \"\";\n\tconst total = additions + deletions;\n\tif (total <= 0) return \"\";\n\n\tconst effectiveWidth = additions > 0 && deletions > 0 ? Math.max(2, width) : width;\n\tlet plusWidth = additions > 0 ? Math.round((additions / total) * effectiveWidth) : 0;\n\tlet minusWidth = effectiveWidth - plusWidth;\n\n\tif (additions > 0 && plusWidth < 1) {\n\t\tplusWidth = 1;\n\t}\n\tif (deletions > 0 && minusWidth < 1) {\n\t\tminusWidth = 1;\n\t}\n\n\tif (plusWidth + minusWidth > effectiveWidth) {\n\t\tif (plusWidth > minusWidth && additions > 0) {\n\t\t\tplusWidth = Math.max(1, effectiveWidth - minusWidth);\n\t\t} else {\n\t\t\tminusWidth = Math.max(1, effectiveWidth - plusWidth);\n\t\t}\n\t}\n\tconst plus = \"+\".repeat(plusWidth);\n\tconst minus = \"-\".repeat(minusWidth);\n\tif (color === \"never\") {\n\t\treturn `${plus}${minus}`;\n\t}\n\tconst plusColored = plus ? `\\u001b[32m${plus}\\u001b[m` : \"\";\n\tconst minusColored = minus ? `\\u001b[31m${minus}\\u001b[m` : \"\";\n\treturn `${plusColored}${minusColored}`;\n}\n\nfunction formatStatSummary(summary: StatSummary): string {\n\tconst fileLabel = summary.files === 1 ? \"file changed\" : \"files changed\";\n\tconst insertionLabel = summary.insertions === 1 ? \"insertion(+)\" : \"insertions(+)\";\n\tconst deletionLabel = summary.deletions === 1 ? \"deletion(-)\" : \"deletions(-)\";\n\treturn `${summary.files} ${fileLabel}, ${summary.insertions} ${insertionLabel}, ${summary.deletions} ${deletionLabel}`;\n}\n\nfunction formatStatRows(rows: StatRow[]): string {\n\tif (rows.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst pathWidth = Math.max(...rows.map((row) => row.filePath.length));\n\tconst countWidth = Math.max(...rows.map((row) => row.changeCount.length));\n\treturn rows\n\t\t.map((row) => {\n\t\t\tconst fileCol = row.filePath.padEnd(pathWidth);\n\t\t\tconst countCol = row.changeCount.padStart(countWidth);\n\t\t\treturn ` ${fileCol} | ${countCol} ${row.changeBar}`;\n\t\t})\n\t\t.join(\"\\n\");\n}\n\nfunction parseShortStatOutput(output: string): {\n\tfiles: number;\n\tinsertions: number;\n\tdeletions: number;\n} {\n\tconst filesMatch = output.match(/(\\d+)\\s+files?\\s+changed/);\n\tconst insertionsMatch = output.match(/(\\d+)\\s+insertions?/);\n\tconst deletionsMatch = output.match(/(\\d+)\\s+deletions?/);\n\n\treturn {\n\t\tfiles: filesMatch ? Number.parseInt(filesMatch[1], 10) : 0,\n\t\tinsertions: insertionsMatch ? Number.parseInt(insertionsMatch[1], 10) : 0,\n\t\tdeletions: deletionsMatch ? Number.parseInt(deletionsMatch[1], 10) : 0,\n\t};\n}\n\nasync function appendUntrackedStatFiles(\n\toutput: string,\n\tleft: string,\n\tright: string | undefined,\n\tfilterOptions: FileFilterOptions,\n\tcolor: \"always\" | \"never\",\n): Promise<string> {\n\tif (right) {\n\t\treturn output;\n\t}\n\n\tconst untracked = await gitClient.getUntrackedFiles();\n\tconst filteredUntracked = untracked.filter((filePath) =>\n\t\tshouldIncludeFile(filePath, filterOptions),\n\t);\n\tif (filteredUntracked.length === 0) {\n\t\treturn output;\n\t}\n\n\tconst base = parseStatOutput(output);\n\tconst patterns = buildFilePatterns(filterOptions);\n\tconst trackedNumstatOutput = await gitClient.diffNumStatAgainstWorktree(left, {\n\t\tfiles: patterns.length > 0 ? patterns : undefined,\n\t});\n\tconst trackedNumstat = parseNumstatOutput(trackedNumstatOutput);\n\tconst baseRows = base.rows.map((row) => {\n\t\tconst counts = trackedNumstat.get(row.filePath);\n\t\tif (!counts) return row;\n\t\tconst total = counts.additions + counts.deletions;\n\t\treturn {\n\t\t\t...row,\n\t\t\tadditions: counts.additions,\n\t\t\tdeletions: counts.deletions,\n\t\t\tchangeCount: String(total),\n\t\t};\n\t});\n\n\tconst extraRows: StatRow[] = [];\n\tlet extraSummary: StatSummary = { files: 0, insertions: 0, deletions: 0 };\n\n\tfor (const filePath of filteredUntracked) {\n\t\tconst numstatOutput = await gitClient.diffNumStatNoIndex(filePath, color);\n\t\tconst parsedNumstat = parseNumstatOutput(numstatOutput);\n\t\tfor (const [parsedPath, counts] of parsedNumstat.entries()) {\n\t\t\tconst total = counts.additions + counts.deletions;\n\t\t\textraRows.push({\n\t\t\t\tfilePath: parsedPath,\n\t\t\t\tchangeCount: String(total),\n\t\t\t\tchangeBar: \"\",\n\t\t\t\tadditions: counts.additions,\n\t\t\t\tdeletions: counts.deletions,\n\t\t\t});\n\t\t\textraSummary.files += 1;\n\t\t\textraSummary.insertions += counts.additions;\n\t\t\textraSummary.deletions += counts.deletions;\n\t\t}\n\t}\n\n\tconst rows = [...baseRows, ...extraRows];\n\tif (rows.length === 0) {\n\t\treturn output;\n\t}\n\n\tconst maxTotalChanges = Math.max(1, ...rows.map((row) => row.additions + row.deletions));\n\tconst maxGraphWidth = 53;\n\tconst normalizedRows = rows.map((row) => {\n\t\tconst total = row.additions + row.deletions;\n\t\tconst graphWidth =\n\t\t\ttotal > 0 ? Math.max(1, Math.round((total / maxTotalChanges) * maxGraphWidth)) : 0;\n\t\treturn {\n\t\t\t...row,\n\t\t\tchangeCount: String(total),\n\t\t\tchangeBar: buildStatBar(row.additions, row.deletions, graphWidth, color),\n\t\t};\n\t});\n\n\tconst combinedSummary: StatSummary = {\n\t\tfiles: base.summary.files + extraSummary.files,\n\t\tinsertions: base.summary.insertions + extraSummary.insertions,\n\t\tdeletions: base.summary.deletions + extraSummary.deletions,\n\t};\n\n\treturn `${formatStatRows(normalizedRows)}\\n ${formatStatSummary(combinedSummary)}`;\n}\n\nasync function appendUntrackedShortStatFiles(\n\toutput: string,\n\tfilterOptions: FileFilterOptions,\n\tcolor: \"always\" | \"never\",\n): Promise<string> {\n\tconst untracked = await gitClient.getUntrackedFiles();\n\tconst filteredUntracked = untracked.filter((filePath) =>\n\t\tshouldIncludeFile(filePath, filterOptions),\n\t);\n\tif (filteredUntracked.length === 0) {\n\t\treturn output;\n\t}\n\n\tconst base = parseShortStatOutput(output);\n\n\tlet untrackedFiles = 0;\n\tlet untrackedInsertions = 0;\n\tlet untrackedDeletions = 0;\n\n\tfor (const filePath of filteredUntracked) {\n\t\tconst numstatOutput = await gitClient.diffNumStatNoIndex(filePath, color);\n\t\tfor (const line of numstatOutput.split(\"\\n\")) {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (!trimmed) continue;\n\t\t\tconst parts = trimmed.split(\"\\t\");\n\t\t\tif (parts.length < 2) continue;\n\t\t\tconst adds = Number(parts[0]);\n\t\t\tconst dels = Number(parts[1]);\n\t\t\tif (Number.isFinite(adds)) untrackedInsertions += adds;\n\t\t\tif (Number.isFinite(dels)) untrackedDeletions += dels;\n\t\t\tuntrackedFiles += 1;\n\t\t}\n\t}\n\n\tconst combined = {\n\t\tfiles: base.files + untrackedFiles,\n\t\tinsertions: base.insertions + untrackedInsertions,\n\t\tdeletions: base.deletions + untrackedDeletions,\n\t};\n\n\treturn ` ${combined.files} files changed, ${combined.insertions} insertions(+), ${combined.deletions} deletions(-)`;\n}\n\nasync function appendUntrackedFiles(\n\toutput: string,\n\tmode: OutputMode,\n\tleft: string,\n\tright: string | undefined,\n\tfilterOptions: FileFilterOptions,\n\tcolor: \"always\" | \"never\",\n): Promise<string> {\n\tif (right) {\n\t\treturn output;\n\t}\n\n\tif (mode === \"stat\") {\n\t\treturn appendUntrackedStatFiles(output, left, right, filterOptions, color);\n\t}\n\n\tif (mode === \"shortstat\") {\n\t\treturn appendUntrackedShortStatFiles(output, filterOptions, color);\n\t}\n\n\tconst untracked = await gitClient.getUntrackedFiles();\n\tconst filteredUntracked = untracked.filter((filePath) =>\n\t\tshouldIncludeFile(filePath, filterOptions),\n\t);\n\n\tif (filteredUntracked.length === 0) {\n\t\treturn output;\n\t}\n\n\tconst untrackedOutput = await generateUntrackedOutput(mode, filteredUntracked, color, undefined);\n\treturn mergeOutputs(output, untrackedOutput);\n}\n\nexport async function hasUnfilteredChanges(refs: ResolvedRefs): Promise<boolean> {\n\tif (!refs.right) {\n\t\treturn gitClient.hasWorktreeChanges();\n\t}\n\n\tconst shortstat = await gitClient.diffShortStat(refs.left, refs.right, undefined);\n\treturn shortstat.trim().length > 0;\n}\n\nexport async function processWorktreeOutput(\n\toutput: string,\n\tmode: OutputMode,\n\trefs: ResolvedRefs,\n\tfilterOptions: FileFilterOptions,\n\tcolor: \"always\" | \"never\",\n\tuseSummaryFormat: boolean,\n): Promise<string> {\n\tlet result = await appendUntrackedFiles(\n\t\toutput,\n\t\tmode,\n\t\trefs.left,\n\t\trefs.right || undefined,\n\t\tfilterOptions,\n\t\tcolor,\n\t);\n\n\tif (mode !== \"numstat\" || !useSummaryFormat) {\n\t\treturn result;\n\t}\n\n\tconst statusMap = refs.right\n\t\t? await buildStatusMapForRange(refs.left, refs.right)\n\t\t: await buildStatusMapForWorktree(filterOptions);\n\n\tresult = formatNumstatOutput(result, statusMap);\n\treturn result;\n}\n","/**\n * Gunshi CLI command definition for diffx\n */\n\nimport { define, type Args } from \"gunshi\";\nimport { parseRangeInput } from \"../parsers/range-parser\";\nimport { resolveRefs } from \"../resolvers/ref-resolver\";\nimport { resolveAutoBaseRefs } from \"../resolvers/auto-base-resolver\";\nimport { generateOutput, generateOutputAgainstWorktree } from \"../output/output-factory\";\nimport { checkEmptyOutput, createNoFilesMatchedError } from \"../errors/error-handler\";\nimport type { OutputMode } from \"../types\";\nimport type { GitDiffOptions } from \"../git/types\";\nimport { gitClient } from \"../git/git-client\";\nimport { pageOutput } from \"./pager\";\nimport { partitionArgs } from \"./arg-partitioner\";\nimport type { ResolvedRefs } from \"./command-types\";\nimport {\n\tbuildDiffOptions,\n\tgetFilterOptions,\n\tgetOutputMode,\n\tgetRangeOrUrl,\n\thasActiveFilters,\n\thasLongOptionFlag,\n\tshouldUseGitPassThrough,\n\tvalidateNoConflictingFlags,\n\tvalidatePagerOptions,\n} from \"./command-options\";\nimport { runGitPassThrough } from \"./git-pass-through\";\nimport { hasUnfilteredChanges, processWorktreeOutput } from \"./worktree-output\";\n\nconst RANGE_TYPES_USING_DIFF_PATCH_STYLE = new Set([\n\t\"pr-ref\",\n\t\"github-url\",\n\t\"pr-range\",\n\t\"github-commit-url\",\n\t\"github-pr-changes-url\",\n\t\"github-compare-url\",\n] as const);\n\ntype InferSetValue<T> = T extends Set<infer U> ? U : never;\ntype RangeTypeUsingDiffPatchStyle = InferSetValue<typeof RANGE_TYPES_USING_DIFF_PATCH_STYLE>;\n\nasync function resolveRefsForRange(rangeOrUrl: string, mode: OutputMode): Promise<ResolvedRefs> {\n\tconst range = parseRangeInput(rangeOrUrl);\n\n\tconst patchStyle =\n\t\tmode === \"patch\" &&\n\t\tRANGE_TYPES_USING_DIFF_PATCH_STYLE.has(range.type as RangeTypeUsingDiffPatchStyle)\n\t\t\t? \"diff\"\n\t\t\t: undefined;\n\n\tconst resolved = await resolveRefs(range);\n\treturn { ...resolved, patchStyle };\n}\n\nasync function resolveRefsForDefault(useGitCompat: boolean): Promise<ResolvedRefs> {\n\tif (useGitCompat) {\n\t\treturn { left: \"\", right: \"\" };\n\t}\n\n\tconst hasChanges = await gitClient.hasWorktreeChanges();\n\tif (hasChanges) {\n\t\treturn { left: \"HEAD\", right: \"\" };\n\t}\n\tconst auto = await resolveAutoBaseRefs();\n\treturn { left: auto.mergeBase, right: auto.right };\n}\n\nasync function generateDiffOutput(\n\tmode: OutputMode,\n\trefs: ResolvedRefs,\n\tdiffOptions: GitDiffOptions,\n): Promise<string> {\n\tconst { left, right, patchStyle } = refs;\n\tif (right) {\n\t\treturn generateOutput(mode, left, right, diffOptions, patchStyle);\n\t}\n\n\treturn generateOutputAgainstWorktree(mode, left, diffOptions);\n}\n\nasync function cleanupRefs(refs: ResolvedRefs): Promise<void> {\n\tif (!refs.cleanup) {\n\t\treturn;\n\t}\n\n\ttry {\n\t\tawait refs.cleanup();\n\t} catch {\n\t\t// Ignore cleanup errors\n\t}\n}\n\n/**\n * Main diffx command\n */\nexport const diffxCommand = define({\n\trendering: {\n\t\theader: null,\n\t},\n\targs: {\n\t\tmode: {\n\t\t\ttype: \"string\",\n\t\t\tdescription:\n\t\t\t\t\"Output mode: diff (default), patch (unified diff, same as git diff -p), stat, numstat, or shortstat\",\n\t\t},\n\t\tstat: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Show diff statistics (same as --mode stat)\",\n\t\t},\n\t\tnumstat: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Show per-file adds/removes (same as --mode numstat)\",\n\t\t},\n\t\tsummary: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription:\n\t\t\t\t\"Show structural summary (create/delete/rename mode). Equivalent to git diff --summary\",\n\t\t},\n\t\tshortstat: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Show summary line only (same as --mode shortstat)\",\n\t\t},\n\t\t\"name-only\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Show only filenames of changed files\",\n\t\t},\n\t\t\"name-status\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Show filenames with status (M/A/D/etc)\",\n\t\t},\n\t\toverview: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Show custom diffx table with status/additions/deletions (not a git flag)\",\n\t\t},\n\t\tpager: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Force output through a pager (overrides TTY detection)\",\n\t\t},\n\t\t\"no-pager\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Disable the pager\",\n\t\t},\n\t\tinclude: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Only include files matching this glob pattern\",\n\t\t\tshort: \"i\",\n\t\t},\n\t\texclude: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Exclude files matching this glob pattern\",\n\t\t\tshort: \"e\",\n\t\t},\n\t\tindex: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Strict git diff compatibility: show unstaged changes (index vs working tree)\",\n\t\t},\n\t} satisfies Args,\n\trun: async (ctx) => {\n\t\tconst rawArgv = process.argv.slice(2);\n\t\tconst partitioned = partitionArgs(rawArgv, ctx.tokens);\n\t\tvalidateNoConflictingFlags(partitioned.diffxFlags, partitioned.gitArgs);\n\n\t\tconst positionals = ctx.positionals ?? [];\n\t\tconst rangeOrUrl = getRangeOrUrl(positionals, partitioned.inputRange);\n\n\t\tconst {\n\t\t\tinclude,\n\t\t\texclude,\n\t\t\tmode: rawMode,\n\t\t\tstat,\n\t\t\tnumstat,\n\t\t\tshortstat,\n\t\t\toverview,\n\t\t\t\"name-only\": _nameOnly,\n\t\t\t\"name-status\": _nameStatus,\n\t\t\tpager,\n\t\t\t\"no-pager\": noPager,\n\t\t\tindex,\n\t\t} = ctx.values;\n\n\t\tconst toPatternList = (value: unknown): string | string[] | undefined => {\n\t\t\tif (typeof value === \"string\") return value;\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\tconst patterns = value.filter((item): item is string => typeof item === \"string\");\n\t\t\t\treturn patterns.length > 0 ? patterns : undefined;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t};\n\n\t\tvalidatePagerOptions(pager, noPager);\n\n\t\tconst hasRange = Boolean(rangeOrUrl);\n\t\tconst partitionedInclude = partitioned.diffxFlags.get(\"--include\");\n\t\tconst partitionedExclude = partitioned.diffxFlags.get(\"--exclude\");\n\t\tconst filterOptions = getFilterOptions({\n\t\t\tinclude: toPatternList(partitionedInclude) ?? toPatternList(include),\n\t\t\texclude: toPatternList(partitionedExclude) ?? toPatternList(exclude),\n\t\t});\n\t\tconst filtersAreActive = hasActiveFilters(filterOptions);\n\n\t\tif (shouldUseGitPassThrough(partitioned, hasRange, Boolean(index), filtersAreActive)) {\n\t\t\tawait runGitPassThrough({\n\t\t\t\tpartitioned,\n\t\t\t\trangeOrUrl,\n\t\t\t\tuseGitCompat: Boolean(index),\n\t\t\t\tpager,\n\t\t\t\tnoPager,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tconst hasStatFlag = hasLongOptionFlag(ctx.tokens, \"stat\");\n\t\tconst hasNumstatFlag = hasLongOptionFlag(ctx.tokens, \"numstat\");\n\t\tconst hasShortstatFlag = hasLongOptionFlag(ctx.tokens, \"shortstat\");\n\t\tconst hasNameOnlyFlag = hasLongOptionFlag(ctx.tokens, \"name-only\");\n\t\tconst hasNameStatusFlag = hasLongOptionFlag(ctx.tokens, \"name-status\");\n\n\t\tconst mode = getOutputMode({\n\t\t\trawMode,\n\t\t\tstat,\n\t\t\tnumstat,\n\t\t\tshortstat,\n\t\t\toverview,\n\t\t\thasStatFlag,\n\t\t\thasNumstatFlag,\n\t\t\thasShortstatFlag,\n\t\t\thasNameOnlyFlag,\n\t\t\thasNameStatusFlag,\n\t\t});\n\n\t\tconst useSummaryFormat = Boolean(overview);\n\t\tconst { diffOptions, color } = buildDiffOptions(\n\t\t\tfilterOptions,\n\t\t\tpager,\n\t\t\tmode,\n\t\t\tpartitioned.gitArgs,\n\t\t);\n\n\t\tconst refs = rangeOrUrl\n\t\t\t? await resolveRefsForRange(rangeOrUrl, mode)\n\t\t\t: await resolveRefsForDefault(Boolean(index));\n\n\t\ttry {\n\t\t\tlet output = await generateDiffOutput(mode, refs, diffOptions);\n\n\t\t\tif (!rangeOrUrl || useSummaryFormat) {\n\t\t\t\toutput = await processWorktreeOutput(\n\t\t\t\t\toutput,\n\t\t\t\t\tmode,\n\t\t\t\t\trefs,\n\t\t\t\t\tfilterOptions,\n\t\t\t\t\tcolor,\n\t\t\t\t\tuseSummaryFormat,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst emptyOutput = checkEmptyOutput(output, {\n\t\t\t\thasActiveFilters: filtersAreActive,\n\t\t\t\thasUnfilteredChanges: filtersAreActive ? await hasUnfilteredChanges(refs) : false,\n\t\t\t});\n\t\t\tif (emptyOutput.isEmpty) {\n\t\t\t\tif (emptyOutput.isFilterMismatch) {\n\t\t\t\t\tthrow createNoFilesMatchedError();\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst autoPagerMode = mode === \"diff\" || mode === \"patch\";\n\t\t\tconst disablePager = Boolean(noPager) || (!autoPagerMode && !pager);\n\t\t\tconst paged = await pageOutput(output, {\n\t\t\t\tforce: pager,\n\t\t\t\tdisable: disablePager,\n\t\t\t});\n\t\t\tif (!paged) {\n\t\t\t\tconsole.log(output);\n\t\t\t}\n\t\t} finally {\n\t\t\tawait cleanupRefs(refs);\n\t\t}\n\t},\n});\n"],"mappings":"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"}