@g-abhishek/gitx 0.1.4 → 0.1.6

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.
Files changed (48) hide show
  1. package/README.md +82 -13
  2. package/dist/ai/claudeAi.d.ts.map +1 -1
  3. package/dist/ai/claudeAi.js +4 -30
  4. package/dist/ai/claudeAi.js.map +1 -1
  5. package/dist/ai/claudeCliAi.d.ts.map +1 -1
  6. package/dist/ai/claudeCliAi.js +4 -21
  7. package/dist/ai/claudeCliAi.js.map +1 -1
  8. package/dist/ai/openAiAi.d.ts.map +1 -1
  9. package/dist/ai/openAiAi.js +4 -30
  10. package/dist/ai/openAiAi.js.map +1 -1
  11. package/dist/ai/reviewHelpers.d.ts +24 -0
  12. package/dist/ai/reviewHelpers.d.ts.map +1 -1
  13. package/dist/ai/reviewHelpers.js +123 -39
  14. package/dist/ai/reviewHelpers.js.map +1 -1
  15. package/dist/cli/commands/pr/cherryPick.d.ts +25 -0
  16. package/dist/cli/commands/pr/cherryPick.d.ts.map +1 -0
  17. package/dist/cli/commands/pr/cherryPick.js +317 -0
  18. package/dist/cli/commands/pr/cherryPick.js.map +1 -0
  19. package/dist/cli/commands/pr/fixComments.d.ts +5 -2
  20. package/dist/cli/commands/pr/fixComments.d.ts.map +1 -1
  21. package/dist/cli/commands/pr/fixComments.js +5 -82
  22. package/dist/cli/commands/pr/fixComments.js.map +1 -1
  23. package/dist/cli/commands/pr/index.d.ts.map +1 -1
  24. package/dist/cli/commands/pr/index.js +6 -2
  25. package/dist/cli/commands/pr/index.js.map +1 -1
  26. package/dist/cli/commands/pr/port.d.ts +34 -0
  27. package/dist/cli/commands/pr/port.d.ts.map +1 -0
  28. package/dist/cli/commands/pr/port.js +453 -0
  29. package/dist/cli/commands/pr/port.js.map +1 -0
  30. package/dist/cli/commands/pr/resolve.d.ts +3 -0
  31. package/dist/cli/commands/pr/resolve.d.ts.map +1 -0
  32. package/dist/cli/commands/pr/resolve.js +92 -0
  33. package/dist/cli/commands/pr/resolve.js.map +1 -0
  34. package/dist/cli/commands/pr/review.js +1 -1
  35. package/dist/cli/commands/pr/review.js.map +1 -1
  36. package/dist/cli/commands/sync.d.ts +12 -11
  37. package/dist/cli/commands/sync.d.ts.map +1 -1
  38. package/dist/cli/commands/sync.js +13 -101
  39. package/dist/cli/commands/sync.js.map +1 -1
  40. package/dist/utils/gitOps.d.ts +11 -4
  41. package/dist/utils/gitOps.d.ts.map +1 -1
  42. package/dist/utils/gitOps.js +53 -37
  43. package/dist/utils/gitOps.js.map +1 -1
  44. package/dist/workflows/pr.d.ts +1 -1
  45. package/dist/workflows/pr.d.ts.map +1 -1
  46. package/dist/workflows/pr.js +82 -19
  47. package/dist/workflows/pr.js.map +1 -1
  48. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"gitOps.js","sourceRoot":"","sources":["../../src/utils/gitOps.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extended git operations for the implement workflow.\n * All functions execute native git commands via child_process.\n */\n\nimport { execFile, exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { dirname, resolve, join } from \"node:path\";\nimport { GitxError } from \"./errors.js\";\n\nconst execFileAsync = promisify(execFile);\nconst execAsync = promisify(exec);\n\n// ─── Internal helper ──────────────────────────────────────────────────────────\n\nasync function git(args: string[], cwd: string): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\"git\", args, { cwd });\n return String(stdout ?? \"\").trim();\n } catch (err: unknown) {\n const stderr =\n (err as { stderr?: string }).stderr ??\n (err as Error).message ??\n String(err);\n throw new GitxError(`git ${args[0]} failed: ${stderr.trim()}`, {\n exitCode: 1,\n cause: err,\n });\n }\n}\n\n// ─── Branch operations ────────────────────────────────────────────────────────\n\nexport async function getCurrentBranch(cwd = process.cwd()): Promise<string> {\n return git([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], cwd);\n}\n\n/**\n * Resolve the default branch (main/master/develop) by inspecting the remote.\n * Falls back to \"main\" if nothing can be determined.\n */\nexport async function getDefaultBranchFromGit(\n cwd = process.cwd(),\n configuredDefault?: string\n): Promise<string> {\n if (configuredDefault) return configuredDefault;\n\n try {\n // Try to read from remote HEAD reference\n const out = await git(\n [\"rev-parse\", \"--abbrev-ref\", \"origin/HEAD\"],\n cwd\n );\n // \"origin/main\" → \"main\"\n return out.replace(/^origin\\//, \"\") || \"main\";\n } catch {\n // Fall back to checking common branch names\n try {\n const branches = await git(\n [\"branch\", \"-r\", \"--format=%(refname:short)\"],\n cwd\n );\n const candidates = [\"origin/main\", \"origin/master\", \"origin/develop\"];\n for (const candidate of candidates) {\n if (branches.split(\"\\n\").some((b) => b.trim() === candidate)) {\n return candidate.replace(\"origin/\", \"\");\n }\n }\n } catch {\n /* ignore */\n }\n return \"main\";\n }\n}\n\n/**\n * Create and checkout a new branch.\n * If the branch already exists, just check it out.\n */\nexport async function createAndCheckoutBranch(\n branchName: string,\n cwd = process.cwd()\n): Promise<void> {\n try {\n await git([\"checkout\", \"-b\", branchName], cwd);\n } catch {\n // Branch might already exist – try checking it out\n await git([\"checkout\", branchName], cwd);\n }\n}\n\n/** Sanitise a free-form task string into a valid branch name */\nexport function slugifyBranchName(task: string, prefix = \"gitx\"): string {\n const slug = task\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 50);\n const ts = Date.now().toString(36);\n return `${prefix}/${slug}-${ts}`;\n}\n\n// ─── File operations ──────────────────────────────────────────────────────────\n\n/**\n * Write content to a file inside the repo, creating parent directories as needed.\n * Paths should be relative to `cwd`.\n */\nexport async function writeRepoFile(\n relativePath: string,\n content: string,\n cwd = process.cwd()\n): Promise<void> {\n const abs = resolve(join(cwd, relativePath));\n await mkdir(dirname(abs), { recursive: true });\n await writeFile(abs, content, \"utf-8\");\n}\n\n// ─── Diff application ─────────────────────────────────────────────────────────\n\n/**\n * Apply a unified diff string using `git apply`.\n * Returns `true` if applied cleanly, `false` if it failed (caller decides how\n * to handle partial failures).\n */\nexport async function applyUnifiedDiff(\n unifiedDiff: string,\n cwd = process.cwd()\n): Promise<{ ok: boolean; error?: string }> {\n try {\n // Use --3way to handle minor conflicts gracefully\n const { stdout, stderr } = await execAsync(\n `echo ${JSON.stringify(unifiedDiff)} | git apply --3way --whitespace=fix -`,\n { cwd }\n );\n return { ok: true, error: stderr || stdout || undefined };\n } catch (err: unknown) {\n const stderr =\n (err as { stderr?: string }).stderr ??\n (err as Error).message ??\n String(err);\n return { ok: false, error: stderr.trim() };\n }\n}\n\n// ─── Staging & committing ─────────────────────────────────────────────────────\n\nexport async function stageAll(cwd = process.cwd()): Promise<void> {\n await git([\"add\", \"-A\"], cwd);\n}\n\nexport async function hasStagedChanges(cwd = process.cwd()): Promise<boolean> {\n try {\n const out = await git([\"diff\", \"--cached\", \"--name-only\"], cwd);\n return out.trim().length > 0;\n } catch {\n return false;\n }\n}\n\nexport async function commitChanges(\n message: string,\n cwd = process.cwd()\n): Promise<string> {\n await git([\"commit\", \"-m\", message], cwd);\n return git([\"rev-parse\", \"HEAD\"], cwd);\n}\n\n// ─── Push ─────────────────────────────────────────────────────────────────────\n\nexport async function pushBranch(\n branchName: string,\n cwd = process.cwd()\n): Promise<void> {\n await git([\"push\", \"--set-upstream\", \"origin\", branchName], cwd);\n}\n\n// ─── Repo inspection ──────────────────────────────────────────────────────────\n\n/**\n * List all tracked files in the repo (respects .gitignore).\n * Returns paths relative to `cwd`.\n */\nexport async function listTrackedFiles(cwd = process.cwd()): Promise<string[]> {\n try {\n const out = await git([\"ls-files\"], cwd);\n return out\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Get the unified diff of only staged changes (`git diff --cached`).\n * Use this when the caller wants to commit only what's already in the index.\n */\nexport async function getStagedDiff(cwd = process.cwd()): Promise<string> {\n try {\n return await git([\"diff\", \"--cached\"], cwd);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Get a compact stat summary of only staged changes (`git diff --cached --stat`).\n */\nexport async function getStagedDiffStat(cwd = process.cwd()): Promise<string> {\n try {\n return await git([\"diff\", \"--cached\", \"--stat\"], cwd);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Get the unified diff of all uncommitted changes (staged + unstaged).\n */\nexport async function getWorkingDiff(cwd = process.cwd()): Promise<string> {\n try {\n const staged = await git([\"diff\", \"--cached\"], cwd);\n const unstaged = await git([\"diff\"], cwd);\n return [staged, unstaged].filter(Boolean).join(\"\\n\");\n } catch {\n return \"\";\n }\n}\n\n/**\n * Get a compact summary of staged changes (--stat format):\n * lists every changed file with insertion/deletion counts.\n * Always small regardless of diff size — used to give the AI the\n * complete picture of what changed even when the full diff is truncated.\n */\nexport async function getWorkingDiffStat(cwd = process.cwd()): Promise<string> {\n try {\n const staged = await git([\"diff\", \"--cached\", \"--stat\"], cwd);\n const unstaged = await git([\"diff\", \"--stat\"], cwd);\n return [staged, unstaged].filter(Boolean).join(\"\\n\");\n } catch {\n return \"\";\n }\n}\n\n/**\n * Auto-detect the most likely base branch for the current feature branch.\n *\n * Strategy:\n * 1. Check if the current branch has a configured upstream tracking branch.\n * 2. Otherwise, try common default branch names (main, master, develop, dev).\n * 3. For each candidate, count commits on HEAD that are NOT in that branch.\n * The candidate with the fewest such commits is the likely origin.\n *\n * Falls back to \"main\" if nothing can be determined.\n */\nexport async function detectBaseBranch(cwd = process.cwd()): Promise<string> {\n // Get current branch name upfront — used for all checks below\n const current = await git([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], cwd).catch(() => \"\");\n\n // 1. Try upstream tracking branch — only useful if it points to a DIFFERENT\n // branch (e.g. origin/main), not the branch's own remote tracking ref.\n // e.g. \"origin/gitx/test\" → \"gitx/test\" == current → skip\n // \"origin/main\" → \"main\" != current → use it\n try {\n const upstream = await git([\"rev-parse\", \"--abbrev-ref\", \"@{upstream}\"], cwd);\n const branch = upstream.replace(/^[^/]+\\//, \"\").trim();\n if (branch && branch !== current) return branch;\n } catch {\n // No upstream configured — fall through\n }\n\n // 2. Check remote HEAD (origin's default branch)\n try {\n const remoteHead = await git([\"rev-parse\", \"--abbrev-ref\", \"origin/HEAD\"], cwd);\n const branch = remoteHead.replace(/^origin\\//, \"\").trim();\n if (branch && branch !== current) return branch;\n } catch {\n // Not available — fall through\n }\n\n // 3. Count commits ahead of each common default branch name\n const candidates = [\"main\", \"master\", \"develop\", \"dev\", \"staging\"];\n const counts: Array<{ branch: string; ahead: number }> = [];\n for (const candidate of candidates) {\n if (candidate === current) continue;\n try {\n // Count commits on HEAD not in candidate\n const out = await git([\"rev-list\", \"--count\", `${candidate}..HEAD`], cwd);\n counts.push({ branch: candidate, ahead: parseInt(out.trim(), 10) || 0 });\n } catch {\n // Branch doesn't exist locally — skip\n }\n }\n\n if (counts.length > 0) {\n // Pick the branch with the fewest commits ahead (closest ancestor)\n counts.sort((a, b) => a.ahead - b.ahead);\n return counts[0]!.branch;\n }\n\n return \"main\";\n}\n\n/**\n * Get the one-line commit log for commits on HEAD that are not in baseBranch.\n * Used to give AI context about what this branch adds.\n */\nexport async function getBranchCommits(\n cwd = process.cwd(),\n baseBranch = \"main\"\n): Promise<string[]> {\n try {\n const out = await git(\n [\"log\", \"--oneline\", \"--no-decorate\", `${baseBranch}..HEAD`],\n cwd\n );\n return out.split(\"\\n\").map((l) => l.trim()).filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Get the unified diff of all changes between baseBranch and HEAD.\n * This is what the PR reviewer would see — all additions across all commits.\n */\nexport async function getBranchDiff(\n cwd = process.cwd(),\n baseBranch = \"main\"\n): Promise<string> {\n try {\n // Three-dot diff: all changes introduced by this branch vs. the merge base\n return await git([\"diff\", `${baseBranch}...HEAD`], cwd);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Get the --stat summary of all changes between baseBranch and HEAD.\n * Lists every file changed with insertion/deletion counts.\n * Used alongside a truncated diff so the AI sees the full file list even\n * when the detailed patch is cut off.\n */\nexport async function getBranchStat(\n cwd = process.cwd(),\n baseBranch = \"main\"\n): Promise<string> {\n try {\n return await git([\"diff\", \"--stat\", `${baseBranch}...HEAD`], cwd);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Read file content as a string. Returns empty string if file doesn't exist.\n */\nexport async function readRepoFile(\n relativePath: string,\n cwd = process.cwd()\n): Promise<string | undefined> {\n try {\n const abs = resolve(join(cwd, relativePath));\n const { readFile } = await import(\"node:fs/promises\");\n return await readFile(abs, \"utf-8\");\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check whether a branch exists on the remote (origin).\n * Uses git ls-remote which does not require a full fetch.\n */\nexport async function branchExistsOnRemote(\n branchName: string,\n cwd = process.cwd()\n): Promise<boolean> {\n try {\n const out = await git(\n [\"ls-remote\", \"--heads\", \"origin\", `refs/heads/${branchName}`],\n cwd\n );\n return out.trim().length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Returns true if the working tree has uncommitted changes (staged or unstaged).\n */\nexport async function isWorkingTreeDirty(cwd = process.cwd()): Promise<boolean> {\n try {\n const out = await git([\"status\", \"--porcelain\"], cwd);\n return out.trim().length > 0;\n } catch {\n return false;\n }\n}\n\n// ─── Context helpers for `gitx ask` ──────────────────────────────────────────\n\n/**\n * Returns `git status --short` output for use in AI context.\n * Returns an empty string when the working tree is clean or git fails.\n */\nexport async function getGitStatus(cwd = process.cwd()): Promise<string> {\n try {\n return await git([\"status\", \"--short\"], cwd);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Returns the last `count` commits as one-line summaries (hash + subject).\n * Defaults to the last 10 commits.\n */\nexport async function getRecentCommits(cwd = process.cwd(), count = 10): Promise<string[]> {\n try {\n const out = await git([\"log\", \"--oneline\", \"--no-decorate\", `-${count}`], cwd);\n return out.split(\"\\n\").map((l) => l.trim()).filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Returns the list of git stashes as `stash@{0}: ...` strings.\n * Returns an empty array when there are no stashes or git fails.\n */\nexport async function getStashList(cwd = process.cwd()): Promise<string[]> {\n try {\n const out = await git([\"stash\", \"list\"], cwd);\n return out.split(\"\\n\").map((l) => l.trim()).filter(Boolean);\n } catch {\n return [];\n }\n}\n"]}
1
+ {"version":3,"file":"gitOps.js","sourceRoot":"","sources":["../../src/utils/gitOps.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extended git operations for the implement workflow.\n * All functions execute native git commands via child_process.\n */\n\nimport { execFile, exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { dirname, resolve, join } from \"node:path\";\nimport { GitxError } from \"./errors.js\";\n\nconst execFileAsync = promisify(execFile);\nconst execAsync = promisify(exec);\n\n// ─── Internal helper ──────────────────────────────────────────────────────────\n\nasync function git(args: string[], cwd: string): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\"git\", args, { cwd });\n return String(stdout ?? \"\").trim();\n } catch (err: unknown) {\n const stderr =\n (err as { stderr?: string }).stderr ??\n (err as Error).message ??\n String(err);\n throw new GitxError(`git ${args[0]} failed: ${stderr.trim()}`, {\n exitCode: 1,\n cause: err,\n });\n }\n}\n\n// ─── Branch operations ────────────────────────────────────────────────────────\n\nexport async function getCurrentBranch(cwd = process.cwd()): Promise<string> {\n return git([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], cwd);\n}\n\n/**\n * Resolve the default branch (main/master/develop) by inspecting the remote.\n * Falls back to \"main\" if nothing can be determined.\n */\nexport async function getDefaultBranchFromGit(\n cwd = process.cwd(),\n configuredDefault?: string\n): Promise<string> {\n if (configuredDefault) return configuredDefault;\n\n try {\n // Try to read from remote HEAD reference\n const out = await git(\n [\"rev-parse\", \"--abbrev-ref\", \"origin/HEAD\"],\n cwd\n );\n // \"origin/main\" → \"main\"\n return out.replace(/^origin\\//, \"\") || \"main\";\n } catch {\n // Fall back to checking common branch names\n try {\n const branches = await git(\n [\"branch\", \"-r\", \"--format=%(refname:short)\"],\n cwd\n );\n const candidates = [\"origin/main\", \"origin/master\", \"origin/develop\"];\n for (const candidate of candidates) {\n if (branches.split(\"\\n\").some((b) => b.trim() === candidate)) {\n return candidate.replace(\"origin/\", \"\");\n }\n }\n } catch {\n /* ignore */\n }\n return \"main\";\n }\n}\n\n/**\n * Create and checkout a new branch.\n * If the branch already exists, just check it out.\n */\nexport async function createAndCheckoutBranch(\n branchName: string,\n cwd = process.cwd()\n): Promise<void> {\n try {\n await git([\"checkout\", \"-b\", branchName], cwd);\n } catch {\n // Branch might already exist – try checking it out\n await git([\"checkout\", branchName], cwd);\n }\n}\n\n/** Sanitise a free-form task string into a valid branch name */\nexport function slugifyBranchName(task: string, prefix = \"gitx\"): string {\n const slug = task\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 50);\n const ts = Date.now().toString(36);\n return `${prefix}/${slug}-${ts}`;\n}\n\n// ─── File operations ──────────────────────────────────────────────────────────\n\n/**\n * Write content to a file inside the repo, creating parent directories as needed.\n * Paths should be relative to `cwd`.\n */\nexport async function writeRepoFile(\n relativePath: string,\n content: string,\n cwd = process.cwd()\n): Promise<void> {\n const abs = resolve(join(cwd, relativePath));\n await mkdir(dirname(abs), { recursive: true });\n await writeFile(abs, content, \"utf-8\");\n}\n\n// ─── Diff application ─────────────────────────────────────────────────────────\n\n/**\n * Apply a unified diff string using `git apply`.\n * Returns `true` if applied cleanly, `false` if it failed (caller decides how\n * to handle partial failures).\n */\nexport async function applyUnifiedDiff(\n unifiedDiff: string,\n cwd = process.cwd()\n): Promise<{ ok: boolean; error?: string }> {\n try {\n // Use --3way to handle minor conflicts gracefully\n const { stdout, stderr } = await execAsync(\n `echo ${JSON.stringify(unifiedDiff)} | git apply --3way --whitespace=fix -`,\n { cwd }\n );\n return { ok: true, error: stderr || stdout || undefined };\n } catch (err: unknown) {\n const stderr =\n (err as { stderr?: string }).stderr ??\n (err as Error).message ??\n String(err);\n return { ok: false, error: stderr.trim() };\n }\n}\n\n// ─── Staging & committing ─────────────────────────────────────────────────────\n\nexport async function stageAll(cwd = process.cwd()): Promise<void> {\n await git([\"add\", \"-A\"], cwd);\n}\n\nexport async function hasStagedChanges(cwd = process.cwd()): Promise<boolean> {\n try {\n const out = await git([\"diff\", \"--cached\", \"--name-only\"], cwd);\n return out.trim().length > 0;\n } catch {\n return false;\n }\n}\n\nexport async function commitChanges(\n message: string,\n cwd = process.cwd()\n): Promise<string> {\n await git([\"commit\", \"-m\", message], cwd);\n return git([\"rev-parse\", \"HEAD\"], cwd);\n}\n\n// ─── Push ─────────────────────────────────────────────────────────────────────\n\nexport async function pushBranch(\n branchName: string,\n cwd = process.cwd()\n): Promise<void> {\n await git([\"push\", \"--set-upstream\", \"origin\", branchName], cwd);\n}\n\n// ─── Repo inspection ──────────────────────────────────────────────────────────\n\n/**\n * List all tracked files in the repo (respects .gitignore).\n * Returns paths relative to `cwd`.\n */\nexport async function listTrackedFiles(cwd = process.cwd()): Promise<string[]> {\n try {\n const out = await git([\"ls-files\"], cwd);\n return out\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Get the unified diff of only staged changes (`git diff --cached`).\n * Use this when the caller wants to commit only what's already in the index.\n */\nexport async function getStagedDiff(cwd = process.cwd()): Promise<string> {\n try {\n return await git([\"diff\", \"--cached\"], cwd);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Get a compact stat summary of only staged changes (`git diff --cached --stat`).\n */\nexport async function getStagedDiffStat(cwd = process.cwd()): Promise<string> {\n try {\n return await git([\"diff\", \"--cached\", \"--stat\"], cwd);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Get the unified diff of all uncommitted changes (staged + unstaged).\n */\nexport async function getWorkingDiff(cwd = process.cwd()): Promise<string> {\n try {\n const staged = await git([\"diff\", \"--cached\"], cwd);\n const unstaged = await git([\"diff\"], cwd);\n return [staged, unstaged].filter(Boolean).join(\"\\n\");\n } catch {\n return \"\";\n }\n}\n\n/**\n * Get a compact summary of staged changes (--stat format):\n * lists every changed file with insertion/deletion counts.\n * Always small regardless of diff size — used to give the AI the\n * complete picture of what changed even when the full diff is truncated.\n */\nexport async function getWorkingDiffStat(cwd = process.cwd()): Promise<string> {\n try {\n const staged = await git([\"diff\", \"--cached\", \"--stat\"], cwd);\n const unstaged = await git([\"diff\", \"--stat\"], cwd);\n return [staged, unstaged].filter(Boolean).join(\"\\n\");\n } catch {\n return \"\";\n }\n}\n\n/**\n * Auto-detect the most likely base branch for the current feature branch.\n *\n * Strategy:\n * 1. Upstream tracking branch set via `git push -u` — strongest signal.\n * Ignored if it points to the branch's own remote ref (origin/current).\n * 2. Scan ALL remote tracking branches and count how many commits HEAD has\n * that each candidate doesn't (`git rev-list --count <ref>..HEAD`).\n * The branch with the FEWEST such commits is the closest ancestor —\n * i.e. the branch this one was forked from.\n *\n * Example: main → feature1 (3 commits) → feature2 (2 commits)\n * - origin/main..HEAD = 5 (feature1's 3 + feature2's 2)\n * - origin/feature1..HEAD = 2 (just feature2's commits)\n * → feature1 wins ✓\n *\n * Falls back to \"main\" if nothing can be determined.\n */\nexport async function detectBaseBranch(cwd = process.cwd()): Promise<string> {\n const current = await git([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], cwd).catch(() => \"\");\n\n // 1. Explicit upstream tracking branch — only trust it if it differs from\n // the current branch (guards against \"origin/feature2\" → \"feature2\").\n try {\n const upstream = await git([\"rev-parse\", \"--abbrev-ref\", \"@{upstream}\"], cwd);\n const branch = upstream.replace(/^[^/]+\\//, \"\").trim();\n if (branch && branch !== current) return branch;\n } catch {\n // No upstream set — fall through\n }\n\n // 2. Scan all remote tracking branches (origin/*), compute how many commits\n // HEAD has that each remote ref doesn't. Closest ancestor wins.\n try {\n const remoteOut = await git(\n [\"branch\", \"-r\", \"--format=%(refname:short)\"],\n cwd\n );\n\n const remoteRefs = remoteOut\n .split(\"\\n\")\n .map((b) => b.trim())\n .filter((b) => b && !b.endsWith(\"/HEAD\")); // skip \"origin/HEAD\" pointer\n\n if (remoteRefs.length === 0) return \"main\";\n\n // Count commits ahead of every remote ref in parallel for speed\n const results = await Promise.all(\n remoteRefs.map(async (ref) => {\n const name = ref.replace(/^[^/]+\\//, \"\"); // \"origin/feature1\" → \"feature1\"\n if (name === current) return null; // skip own remote tracking ref\n try {\n const out = await git([\"rev-list\", \"--count\", `${ref}..HEAD`], cwd);\n return { branch: name, ahead: parseInt(out.trim(), 10) || 0 };\n } catch {\n return null;\n }\n })\n );\n\n const counts = results.filter((r): r is { branch: string; ahead: number } => r !== null);\n if (counts.length === 0) return \"main\";\n\n // Sort by fewest commits ahead — that's the closest ancestor.\n // Tiebreak: prefer default branch names so \"main\" beats an equally-close\n // unrelated branch that happens to have 0 commits.\n const defaults = new Set([\"main\", \"master\", \"develop\", \"dev\", \"staging\"]);\n counts.sort((a, b) => {\n if (a.ahead !== b.ahead) return a.ahead - b.ahead;\n // Same distance — prefer default branches\n const aDefault = defaults.has(a.branch) ? 0 : 1;\n const bDefault = defaults.has(b.branch) ? 0 : 1;\n return aDefault - bDefault;\n });\n\n return counts[0]!.branch;\n } catch {\n return \"main\";\n }\n}\n\n/**\n * Get the one-line commit log for commits on HEAD that are not in baseBranch.\n * Used to give AI context about what this branch adds.\n */\nexport async function getBranchCommits(\n cwd = process.cwd(),\n baseBranch = \"main\"\n): Promise<string[]> {\n try {\n const out = await git(\n [\"log\", \"--oneline\", \"--no-decorate\", `${baseBranch}..HEAD`],\n cwd\n );\n return out.split(\"\\n\").map((l) => l.trim()).filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Get the unified diff of all changes between baseBranch and HEAD.\n * This is what the PR reviewer would see — all additions across all commits.\n */\nexport async function getBranchDiff(\n cwd = process.cwd(),\n baseBranch = \"main\"\n): Promise<string> {\n try {\n // Three-dot diff: all changes introduced by this branch vs. the merge base\n return await git([\"diff\", `${baseBranch}...HEAD`], cwd);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Get the --stat summary of all changes between baseBranch and HEAD.\n * Lists every file changed with insertion/deletion counts.\n * Used alongside a truncated diff so the AI sees the full file list even\n * when the detailed patch is cut off.\n */\nexport async function getBranchStat(\n cwd = process.cwd(),\n baseBranch = \"main\"\n): Promise<string> {\n try {\n return await git([\"diff\", \"--stat\", `${baseBranch}...HEAD`], cwd);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Read file content as a string. Returns empty string if file doesn't exist.\n */\nexport async function readRepoFile(\n relativePath: string,\n cwd = process.cwd()\n): Promise<string | undefined> {\n try {\n const abs = resolve(join(cwd, relativePath));\n const { readFile } = await import(\"node:fs/promises\");\n return await readFile(abs, \"utf-8\");\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check whether a branch exists on the remote (origin).\n * Uses git ls-remote which does not require a full fetch.\n */\nexport async function branchExistsOnRemote(\n branchName: string,\n cwd = process.cwd()\n): Promise<boolean> {\n try {\n const out = await git(\n [\"ls-remote\", \"--heads\", \"origin\", `refs/heads/${branchName}`],\n cwd\n );\n return out.trim().length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Returns true if the working tree has uncommitted changes (staged or unstaged).\n */\nexport async function isWorkingTreeDirty(cwd = process.cwd()): Promise<boolean> {\n try {\n const out = await git([\"status\", \"--porcelain\"], cwd);\n return out.trim().length > 0;\n } catch {\n return false;\n }\n}\n\n// ─── Context helpers for `gitx ask` ──────────────────────────────────────────\n\n/**\n * Returns `git status --short` output for use in AI context.\n * Returns an empty string when the working tree is clean or git fails.\n */\nexport async function getGitStatus(cwd = process.cwd()): Promise<string> {\n try {\n return await git([\"status\", \"--short\"], cwd);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Returns the last `count` commits as one-line summaries (hash + subject).\n * Defaults to the last 10 commits.\n */\nexport async function getRecentCommits(cwd = process.cwd(), count = 10): Promise<string[]> {\n try {\n const out = await git([\"log\", \"--oneline\", \"--no-decorate\", `-${count}`], cwd);\n return out.split(\"\\n\").map((l) => l.trim()).filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Returns the list of git stashes as `stash@{0}: ...` strings.\n * Returns an empty array when there are no stashes or git fails.\n */\nexport async function getStashList(cwd = process.cwd()): Promise<string[]> {\n try {\n const out = await git([\"stash\", \"list\"], cwd);\n return out.split(\"\\n\").map((l) => l.trim()).filter(Boolean);\n } catch {\n return [];\n }\n}\n"]}
@@ -37,5 +37,5 @@ export interface FixCommentsResult {
37
37
  * Fetch PR review comments, ask AI to suggest fixes, apply them, and
38
38
  * commit + push the changes.
39
39
  */
40
- export declare function runFixCommentsWorkflow(gitx: Gitx, prNumber: number, dryRun?: boolean): Promise<FixCommentsResult>;
40
+ export declare function runFixCommentsWorkflow(gitx: Gitx, prNumber: number, dryRun?: boolean, noCommit?: boolean): Promise<FixCommentsResult>;
41
41
  //# sourceMappingURL=pr.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../src/workflows/pr.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AA4B5E,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,WAAW,CAAC;IAChB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,gBAAgB,EAAE,wBAAwB,CAAC;IAC3D,gEAAgE;IAChE,YAAY,EAAE,OAAO,CAAC;IACtB,uFAAuF;IACvF,cAAc,EAAE,QAAQ,GAAG,gBAAgB,GAAG,MAAM,CAAC;CACtD;AA6DD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,WAAW,UAAO,GACjB,OAAO,CAAC,YAAY,CAAC,CAiJvB;AAID,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,WAAW,CAAC;IAChB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,MAAM,UAAQ,GACb,OAAO,CAAC,iBAAiB,CAAC,CA0F5B"}
1
+ {"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../src/workflows/pr.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AA4B5E,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,WAAW,CAAC;IAChB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,gBAAgB,EAAE,wBAAwB,CAAC;IAC3D,gEAAgE;IAChE,YAAY,EAAE,OAAO,CAAC;IACtB,uFAAuF;IACvF,cAAc,EAAE,QAAQ,GAAG,gBAAgB,GAAG,MAAM,CAAC;CACtD;AA6DD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,WAAW,UAAO,GACjB,OAAO,CAAC,YAAY,CAAC,CAoJvB;AAID,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,WAAW,CAAC;IAChB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,MAAM,UAAQ,EACd,QAAQ,UAAQ,GACf,OAAO,CAAC,iBAAiB,CAAC,CA0J5B"}
@@ -96,8 +96,10 @@ export async function runReviewWorkflow(gitx, prNumber, postComment = true) {
96
96
  const ctxSpinner = ora("Building codebase context from changed files…").start();
97
97
  const allTracked = await listTrackedFiles(cwd);
98
98
  const allChangedPaths = parseChangedPathsFromDiff(diff);
99
- // Filter out lockfiles / generated files — they waste tokens and add no review value
100
- const changedPaths = allChangedPaths.filter(isReviewableFile).slice(0, 8);
99
+ // Filter out lockfiles / generated files — they waste tokens and add no review value.
100
+ // No file count cap — per-file budgets in buildSeniorReviewPrompt already control
101
+ // total size. Dropping files arbitrarily is worse than sending all of them.
102
+ const changedPaths = allChangedPaths.filter(isReviewableFile);
101
103
  const skippedCount = allChangedPaths.length - changedPaths.length;
102
104
  // Read full content of changed files
103
105
  const changedFiles = {};
@@ -107,7 +109,8 @@ export async function runReviewWorkflow(gitx, prNumber, postComment = true) {
107
109
  changedFiles[p] = content;
108
110
  }
109
111
  // Read supporting context files (imported by the changed files)
110
- const ctxPaths = await findContextFiles(changedPaths, allTracked, cwd, 5);
112
+ // 10 context files gives the AI a solid picture of the codebase structure
113
+ const ctxPaths = await findContextFiles(changedPaths, allTracked, cwd, 10);
111
114
  const contextFiles = {};
112
115
  for (const p of ctxPaths) {
113
116
  const content = await readRepoFile(p, cwd);
@@ -208,34 +211,89 @@ export async function runReviewWorkflow(gitx, prNumber, postComment = true) {
208
211
  * Fetch PR review comments, ask AI to suggest fixes, apply them, and
209
212
  * commit + push the changes.
210
213
  */
211
- export async function runFixCommentsWorkflow(gitx, prNumber, dryRun = false) {
214
+ export async function runFixCommentsWorkflow(gitx, prNumber, dryRun = false, noCommit = false) {
212
215
  const { applyUnifiedDiff, stageAll, hasStagedChanges, commitChanges } = await import("../utils/gitOps.js");
213
216
  const cwd = gitx.cwd;
214
217
  const ctx = await gitx.getRepoContext();
215
218
  const provider = createProvider(ctx);
216
- logger.info(`🔍 Fetching PR #${prNumber}…`);
219
+ const fetchSpinner = ora("Fetching PR, comments and diff…").start();
217
220
  const pr = await provider.getPR(ctx.repoSlug, prNumber);
218
- logger.info("💬 Fetching review comments…");
219
- const comments = await provider.getPRComments(ctx.repoSlug, prNumber);
221
+ const [comments, diff] = await Promise.all([
222
+ provider.getPRComments(ctx.repoSlug, prNumber),
223
+ provider.getPRDiff(ctx.repoSlug, prNumber),
224
+ ]);
225
+ fetchSpinner.succeed(`PR #${prNumber}: "${pr.title}" — ${comments.length} comment(s)`);
220
226
  if (comments.length === 0) {
221
227
  logger.info("No review comments found.");
222
228
  return { pr, comments, appliedFixes: [], skippedFixes: [] };
223
229
  }
224
- // Gather file contents for files mentioned in comments
230
+ // ── Build file context ────────────────────────────────────────────────────
231
+ // Only load files directly mentioned in comments + their close imports.
232
+ // Random repo source files are irrelevant — the AI is fixing specific lines.
233
+ const ctxSpinner = ora("Building file context for commented files…").start();
225
234
  const mentionedPaths = [...new Set(comments.map((c) => c.path).filter(Boolean))];
226
235
  const trackedFiles = await listTrackedFiles(cwd);
227
- // Also include files mentioned in the PR body / title
228
- const allSourceFiles = trackedFiles
229
- .filter((f) => /\.(ts|js|tsx|jsx|py|go|rs|java|rb|cs|cpp|c|h)$/.test(f))
230
- .slice(0, 15);
231
- const relevantFiles = [...new Set([...mentionedPaths, ...allSourceFiles])].slice(0, 15);
236
+ // File content strategy same thresholds as the review workflow:
237
+ // ≤ FULL_FILE_THRESHOLD lines → send the whole file (AI needs full context to make correct edits)
238
+ // larger files → show a generous window around each commented line
239
+ const FULL_FILE_THRESHOLD = 400;
240
+ const COMMENT_WINDOW = 80; // lines above/below a commented line in large files
241
+ const CTX_FILE_MAX = 4_000; // chars per supporting context file
232
242
  const fileContents = {};
233
- for (const f of relevantFiles) {
234
- const content = await readRepoFile(f, cwd);
235
- if (content)
236
- fileContents[f] = content.slice(0, 4000);
243
+ // Commented lines per file — used for smart windowing on large files
244
+ const commentedLines = {};
245
+ for (const c of comments) {
246
+ if (c.path && c.line) {
247
+ (commentedLines[c.path] ??= []).push(c.line);
248
+ }
237
249
  }
238
- logger.info("🧠 Generating AI-suggested fixes…");
250
+ for (const filePath of mentionedPaths) {
251
+ const content = await readRepoFile(filePath, cwd);
252
+ if (!content)
253
+ continue;
254
+ const lines = content.split("\n");
255
+ if (lines.length <= FULL_FILE_THRESHOLD) {
256
+ // Small file — send it whole
257
+ fileContents[filePath] = lines
258
+ .map((l, i) => `${String(i + 1).padStart(5, " ")} | ${l}`)
259
+ .join("\n");
260
+ }
261
+ else {
262
+ // Large file — show windows around commented lines
263
+ const targets = commentedLines[filePath] ?? [];
264
+ const included = new Set();
265
+ for (const line of targets) {
266
+ for (let i = Math.max(0, line - COMMENT_WINDOW - 1); i < Math.min(lines.length, line + COMMENT_WINDOW); i++) {
267
+ included.add(i);
268
+ }
269
+ }
270
+ // If no specific lines, fall back to first FULL_FILE_THRESHOLD lines
271
+ const indices = included.size > 0 ? [...included].sort((a, b) => a - b) : [...Array(FULL_FILE_THRESHOLD).keys()];
272
+ let excerpt = "";
273
+ let prev = -1;
274
+ for (const idx of indices) {
275
+ if (prev !== -1 && idx > prev + 1)
276
+ excerpt += `\n … (${idx - prev - 1} lines omitted)\n`;
277
+ excerpt += `${String(idx + 1).padStart(5, " ")} | ${lines[idx]}\n`;
278
+ prev = idx;
279
+ }
280
+ fileContents[filePath] = excerpt.trimEnd();
281
+ }
282
+ }
283
+ // Add context files (imports of the mentioned files) for extra background
284
+ const ctxPaths = await findContextFiles(mentionedPaths, trackedFiles, cwd, 8);
285
+ for (const filePath of ctxPaths) {
286
+ if (fileContents[filePath])
287
+ continue; // already loaded
288
+ const content = await readRepoFile(filePath, cwd);
289
+ if (!content)
290
+ continue;
291
+ fileContents[filePath] = content.length <= CTX_FILE_MAX
292
+ ? content
293
+ : content.slice(0, CTX_FILE_MAX) + "\n… (truncated)";
294
+ }
295
+ ctxSpinner.succeed(`Context: ${mentionedPaths.length} commented file(s), ${ctxPaths.length} context file(s)`);
296
+ const fixSpinner = ora("🧠 Generating AI-suggested fixes…").start();
239
297
  const fixResult = await gitx.ai.suggestFixes({
240
298
  comments: comments.map((c) => ({
241
299
  body: c.body,
@@ -245,8 +303,10 @@ export async function runFixCommentsWorkflow(gitx, prNumber, dryRun = false) {
245
303
  })),
246
304
  prTitle: pr.title,
247
305
  prBody: pr.body,
306
+ diff,
248
307
  fileContents,
249
308
  });
309
+ fixSpinner.succeed(`AI generated ${fixResult.suggestedEdits.length} fix(es).`);
250
310
  const appliedFixes = [];
251
311
  const skippedFixes = [];
252
312
  for (const edit of fixResult.suggestedEdits) {
@@ -269,7 +329,7 @@ export async function runFixCommentsWorkflow(gitx, prNumber, dryRun = false) {
269
329
  });
270
330
  }
271
331
  }
272
- if (!dryRun && appliedFixes.length > 0) {
332
+ if (!dryRun && !noCommit && appliedFixes.length > 0) {
273
333
  await stageAll(cwd);
274
334
  if (await hasStagedChanges(cwd)) {
275
335
  const msg = `fix: address PR #${prNumber} review comments\n\n${appliedFixes.map((f) => `- ${f.path}: ${f.rationale}`).join("\n")}`;
@@ -280,6 +340,9 @@ export async function runFixCommentsWorkflow(gitx, prNumber, dryRun = false) {
280
340
  await provider.addPRComment(ctx.repoSlug, prNumber, `## 🤖 Auto-fixes applied (gitx)\n\n${fixSummary}\n\nCommit: \`${sha.slice(0, 8)}\``);
281
341
  }
282
342
  }
343
+ if (!dryRun && noCommit && appliedFixes.length > 0) {
344
+ logger.info("\n💡 Fixes applied to working tree. Review the changes and commit when ready.");
345
+ }
283
346
  return { pr, comments, appliedFixes, skippedFixes };
284
347
  }
285
348
  //# sourceMappingURL=pr.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pr.js","sourceRoot":"","sources":["../../src/workflows/pr.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * PR Workflow helpers\n *\n * Shared logic used by the `pr review` and `pr fix-comments` CLI commands.\n */\n\nimport ora from \"ora\";\nimport type { Gitx } from \"../core/gitx.js\";\nimport type { PullRequest, PullRequestComment } from \"../providers/base.js\";\nimport { createProvider } from \"../providers/factory.js\";\nimport { readRepoFile, listTrackedFiles } from \"../utils/gitOps.js\";\nimport { logger } from \"../logger/logger.js\";\n\n// Files that add no review value — skip them even if they appear in the diff\nconst SKIP_FILE_PATTERNS = [\n /package-lock\\.json$/,\n /yarn\\.lock$/,\n /pnpm-lock\\.yaml$/,\n /bun\\.lockb$/,\n /\\.lock$/,\n /dist\\//,\n /build\\//,\n /\\.min\\.(js|css)$/,\n /\\.map$/,\n /node_modules\\//,\n /\\.d\\.ts$/, // generated TypeScript declarations\n /generated\\//,\n /migrations\\/.*\\.sql$/,\n];\n\nfunction isReviewableFile(path: string): boolean {\n return !SKIP_FILE_PATTERNS.some((re) => re.test(path));\n}\n\n// ─── Review workflow ──────────────────────────────────────────────────────────\n\nexport interface ReviewResult {\n pr: PullRequest;\n comments: PullRequestComment[];\n aiSummary: string;\n review?: import(\"../ai/types.js\").AiDetailedReviewResponse;\n /** true = review was actually posted to the hosting provider */\n reviewPosted: boolean;\n /** How inline comments were delivered: formal inline, plain comments, or not posted */\n inlineDelivery: \"inline\" | \"plain-comments\" | \"none\";\n}\n\n/**\n * Parse a unified diff and return the set of changed file paths.\n */\nfunction parseChangedPathsFromDiff(diff: string): string[] {\n const paths = new Set<string>();\n for (const line of diff.split(\"\\n\")) {\n // Match \"+++ b/src/foo.ts\" lines\n const m = line.match(/^\\+\\+\\+ b\\/(.+)/);\n if (m?.[1] && m[1] !== \"/dev/null\") {\n paths.add(m[1].trim());\n }\n }\n return [...paths];\n}\n\n/**\n * Given a list of changed file paths, find supporting context files that are\n * closely related (imported by or importing changed files).\n * Returns at most `maxFiles` file paths.\n */\nasync function findContextFiles(\n changedPaths: string[],\n allTrackedFiles: string[],\n cwd: string,\n maxFiles = 8\n): Promise<string[]> {\n const contextPaths = new Set<string>();\n\n for (const changedPath of changedPaths.slice(0, 10)) {\n const content = await readRepoFile(changedPath, cwd);\n if (!content) continue;\n\n // Extract relative import paths from TypeScript/JS files\n const importMatches = content.matchAll(/from\\s+['\"]([^'\"]+)['\"]/g);\n for (const [, importPath] of importMatches) {\n if (!importPath || importPath.startsWith(\"node:\") || !importPath.startsWith(\".\")) continue;\n // Resolve the import path relative to the file's directory\n const dir = changedPath.split(\"/\").slice(0, -1).join(\"/\");\n const candidates = [\n `${dir}/${importPath}.ts`,\n `${dir}/${importPath}.tsx`,\n `${dir}/${importPath}/index.ts`,\n `${dir}/${importPath}`,\n ].map((p) => p.replace(/\\/\\//g, \"/\").replace(/^\\//, \"\"));\n\n for (const candidate of candidates) {\n if (allTrackedFiles.includes(candidate) && !changedPaths.includes(candidate)) {\n contextPaths.add(candidate);\n break;\n }\n }\n }\n\n if (contextPaths.size >= maxFiles) break;\n }\n\n return [...contextPaths].slice(0, maxFiles);\n}\n\n/**\n * Fetch a PR, its full diff, and all related codebase context;\n * run a senior-developer quality AI review;\n * submit as a formal review (with inline comments) to the hosting provider.\n */\nexport async function runReviewWorkflow(\n gitx: Gitx,\n prNumber: number,\n postComment = true\n): Promise<ReviewResult> {\n const ctx = await gitx.getRepoContext();\n const provider = createProvider(ctx);\n const cwd = gitx.cwd;\n\n const fetchSpinner = ora(\"Fetching PR info, diff and comments…\").start();\n const pr = await provider.getPR(ctx.repoSlug, prNumber);\n const [comments, diff] = await Promise.all([\n provider.getPRComments(ctx.repoSlug, prNumber),\n provider.getPRDiff(ctx.repoSlug, prNumber),\n ]);\n fetchSpinner.succeed(`PR #${prNumber}: \"${pr.title}\" (${pr.head} → ${pr.base})`);\n\n // ── Build codebase context ─────────────────────────────────────────────────\n const ctxSpinner = ora(\"Building codebase context from changed files…\").start();\n const allTracked = await listTrackedFiles(cwd);\n const allChangedPaths = parseChangedPathsFromDiff(diff);\n\n // Filter out lockfiles / generated files — they waste tokens and add no review value\n const changedPaths = allChangedPaths.filter(isReviewableFile).slice(0, 8);\n const skippedCount = allChangedPaths.length - changedPaths.length;\n\n // Read full content of changed files\n const changedFiles: Record<string, string> = {};\n for (const p of changedPaths) {\n const content = await readRepoFile(p, cwd);\n if (content) changedFiles[p] = content;\n }\n\n // Read supporting context files (imported by the changed files)\n const ctxPaths = await findContextFiles(changedPaths, allTracked, cwd, 5);\n const contextFiles: Record<string, string> = {};\n for (const p of ctxPaths) {\n const content = await readRepoFile(p, cwd);\n if (content) contextFiles[p] = content;\n }\n\n const skippedNote = skippedCount > 0 ? `, ${skippedCount} lock/generated files skipped` : \"\";\n ctxSpinner.succeed(\n `Context: ${changedPaths.length} changed files, ${ctxPaths.length} context files${skippedNote}`\n );\n\n const reviewSpinner = ora(\n `Running senior-dev AI review… (this may take up to 5 min for large PRs)`\n ).start();\n\n let review: Awaited<ReturnType<typeof gitx.ai.reviewPRDetailed>>;\n try {\n review = await gitx.ai.reviewPRDetailed({\n prTitle: pr.title,\n prBody: pr.body,\n author: pr.author,\n headBranch: pr.head,\n baseBranch: pr.base,\n diff,\n changedFiles,\n contextFiles,\n repoFileList: allTracked,\n existingComments: comments.map((c) => ({\n author: c.author,\n body: c.body,\n path: c.path,\n line: c.line,\n })),\n });\n reviewSpinner.succeed(\n `Review complete — verdict: ${review.verdict} | ${review.inlineComments.length} inline comment(s)`\n );\n } catch (err) {\n reviewSpinner.fail(\"AI review failed.\");\n throw err;\n }\n\n // ── Build the formatted review body (for the summary comment) ─────────────\n const verdictIcon =\n review.verdict === \"approve\" ? \"✅\" :\n review.verdict === \"request_changes\" ? \"🔴\" : \"💬\";\n\n const checklistLines = review.checklist.map((c) => {\n const icon = c.status === \"pass\" ? \"✅\" : c.status === \"warn\" ? \"⚠️\" : \"❌\";\n return `| ${icon} | **${c.area}** | ${c.note} |`;\n });\n\n const issueLines = review.issues.map((i) => {\n const sev = i.severity === \"critical\" ? \"🔴\" : i.severity === \"warning\" ? \"🟡\" : \"💡\";\n const loc = i.file ? ` (\\`${i.file}${i.line ? `:${i.line}` : \"\"}\\`)` : \"\";\n return `${sev} ${i.description}${loc}`;\n });\n\n const posLines = review.positives.map((p) => `✔ ${p}`);\n\n const summaryBody = [\n `## ${verdictIcon} Senior Dev AI Review (gitx) — ${review.verdict.replace(\"_\", \" \")}`,\n \"\",\n review.summary,\n ...(checklistLines.length > 0\n ? [\"\", \"### Review Checklist\", \"| Status | Area | Note |\", \"|--------|------|------|\", ...checklistLines]\n : []),\n ...(review.issues.length > 0 ? [\"\", \"### Issues Found\", ...issueLines] : []),\n ...(review.positives.length > 0 ? [\"\", \"### Positives\", ...posLines] : []),\n ...(review.testingNotes ? [\"\", \"### How to Test\", review.testingNotes] : []),\n ...(review.inlineComments.length > 0\n ? [`\\n> 💬 ${review.inlineComments.length} inline comment(s) posted on specific lines.`]\n : []),\n \"\",\n \"*Generated by [gitx](https://github.com/g-abhishek/gitx)*\",\n ].join(\"\\n\");\n\n // ── Post the formal review (inline comments + verdict) ────────────────────\n let reviewPosted = false;\n let inlineDelivery: ReviewResult[\"inlineDelivery\"] = \"none\";\n\n if (postComment) {\n const inlineCount = review.inlineComments.length;\n const postSpinner = ora(\n `Submitting review to PR${inlineCount > 0 ? ` with ${inlineCount} inline comment(s)` : \"\"}…`\n ).start();\n try {\n await provider.submitPRReview(ctx.repoSlug, prNumber, {\n body: summaryBody,\n event: review.verdict,\n comments: review.inlineComments.map((c) => ({\n path: c.path,\n line: c.line,\n body: c.suggestion\n ? `${c.body}\\n\\n**Suggestion:**\\n\\`\\`\\`suggestion\\n${c.suggestion}\\n\\`\\`\\``\n : c.body,\n })),\n });\n reviewPosted = true;\n // Determine how inline comments were delivered.\n // GitHub's submitPRReview will attempt inline first, then fall back to\n // plain comments. We can't detect which path was taken from here, so\n // we report \"inline\" optimistically — the user sees the real result on GitHub.\n inlineDelivery = inlineCount > 0 ? \"inline\" : \"none\";\n postSpinner.succeed(\n `Review submitted to PR.${inlineCount > 0 ? ` (${inlineCount} inline comment(s) — see PR for delivery method)` : \"\"}`\n );\n } catch (err) {\n postSpinner.fail(`Could not post review to PR: ${String((err as Error).message ?? err)}`);\n // Don't rethrow — still return the review so the user can see it locally\n }\n }\n\n return { pr, comments, aiSummary: summaryBody, review, reviewPosted, inlineDelivery };\n}\n\n// ─── Fix-comments workflow ────────────────────────────────────────────────────\n\nexport interface FixCommentsResult {\n pr: PullRequest;\n comments: PullRequestComment[];\n appliedFixes: Array<{ path: string; rationale: string }>;\n skippedFixes: Array<{ path: string; reason: string }>;\n}\n\n/**\n * Fetch PR review comments, ask AI to suggest fixes, apply them, and\n * commit + push the changes.\n */\nexport async function runFixCommentsWorkflow(\n gitx: Gitx,\n prNumber: number,\n dryRun = false\n): Promise<FixCommentsResult> {\n const { applyUnifiedDiff, stageAll, hasStagedChanges, commitChanges } = await import(\n \"../utils/gitOps.js\"\n );\n const cwd = gitx.cwd;\n const ctx = await gitx.getRepoContext();\n const provider = createProvider(ctx);\n\n logger.info(`🔍 Fetching PR #${prNumber}…`);\n const pr = await provider.getPR(ctx.repoSlug, prNumber);\n\n logger.info(\"💬 Fetching review comments…\");\n const comments = await provider.getPRComments(ctx.repoSlug, prNumber);\n\n if (comments.length === 0) {\n logger.info(\"No review comments found.\");\n return { pr, comments, appliedFixes: [], skippedFixes: [] };\n }\n\n // Gather file contents for files mentioned in comments\n const mentionedPaths = [...new Set(comments.map((c) => c.path).filter(Boolean) as string[])];\n const trackedFiles = await listTrackedFiles(cwd);\n\n // Also include files mentioned in the PR body / title\n const allSourceFiles = trackedFiles\n .filter((f) => /\\.(ts|js|tsx|jsx|py|go|rs|java|rb|cs|cpp|c|h)$/.test(f))\n .slice(0, 15);\n\n const relevantFiles = [...new Set([...mentionedPaths, ...allSourceFiles])].slice(0, 15);\n const fileContents: Record<string, string> = {};\n for (const f of relevantFiles) {\n const content = await readRepoFile(f, cwd);\n if (content) fileContents[f] = content.slice(0, 4000);\n }\n\n logger.info(\"🧠 Generating AI-suggested fixes…\");\n const fixResult = await gitx.ai.suggestFixes({\n comments: comments.map((c) => ({\n body: c.body,\n author: c.author,\n path: c.path,\n line: c.line,\n })),\n prTitle: pr.title,\n prBody: pr.body,\n fileContents,\n });\n\n const appliedFixes: Array<{ path: string; rationale: string }> = [];\n const skippedFixes: Array<{ path: string; reason: string }> = [];\n\n for (const edit of fixResult.suggestedEdits) {\n if (dryRun) {\n logger.info(` ↳ [dry-run] Would apply fix to: ${edit.path}`);\n logger.info(` Rationale: ${edit.rationale}`);\n appliedFixes.push({ path: edit.path, rationale: edit.rationale });\n continue;\n }\n\n const applyResult = await applyUnifiedDiff(edit.unifiedDiff, cwd);\n if (applyResult.ok) {\n logger.info(` ↳ Applied fix to: ${edit.path}`);\n appliedFixes.push({ path: edit.path, rationale: edit.rationale });\n } else {\n logger.warn(` ↳ Could not apply fix to ${edit.path}: ${applyResult.error ?? \"unknown\"}`);\n skippedFixes.push({\n path: edit.path,\n reason: applyResult.error ?? \"git apply failed\",\n });\n }\n }\n\n if (!dryRun && appliedFixes.length > 0) {\n await stageAll(cwd);\n if (await hasStagedChanges(cwd)) {\n const msg = `fix: address PR #${prNumber} review comments\\n\\n${appliedFixes.map((f) => `- ${f.path}: ${f.rationale}`).join(\"\\n\")}`;\n const sha = await commitChanges(msg, cwd);\n logger.success(`Committed fixes: ${sha.slice(0, 8)}`);\n\n // Post summary comment\n const fixSummary = appliedFixes.map((f) => `- \\`${f.path}\\`: ${f.rationale}`).join(\"\\n\");\n await provider.addPRComment(\n ctx.repoSlug,\n prNumber,\n `## 🤖 Auto-fixes applied (gitx)\\n\\n${fixSummary}\\n\\nCommit: \\`${sha.slice(0, 8)}\\``\n );\n }\n }\n\n return { pr, comments, appliedFixes, skippedFixes };\n}\n"]}
1
+ {"version":3,"file":"pr.js","sourceRoot":"","sources":["../../src/workflows/pr.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * PR Workflow helpers\n *\n * Shared logic used by the `pr review` and `pr fix-comments` CLI commands.\n */\n\nimport ora from \"ora\";\nimport type { Gitx } from \"../core/gitx.js\";\nimport type { PullRequest, PullRequestComment } from \"../providers/base.js\";\nimport { createProvider } from \"../providers/factory.js\";\nimport { readRepoFile, listTrackedFiles } from \"../utils/gitOps.js\";\nimport { logger } from \"../logger/logger.js\";\n\n// Files that add no review value — skip them even if they appear in the diff\nconst SKIP_FILE_PATTERNS = [\n /package-lock\\.json$/,\n /yarn\\.lock$/,\n /pnpm-lock\\.yaml$/,\n /bun\\.lockb$/,\n /\\.lock$/,\n /dist\\//,\n /build\\//,\n /\\.min\\.(js|css)$/,\n /\\.map$/,\n /node_modules\\//,\n /\\.d\\.ts$/, // generated TypeScript declarations\n /generated\\//,\n /migrations\\/.*\\.sql$/,\n];\n\nfunction isReviewableFile(path: string): boolean {\n return !SKIP_FILE_PATTERNS.some((re) => re.test(path));\n}\n\n// ─── Review workflow ──────────────────────────────────────────────────────────\n\nexport interface ReviewResult {\n pr: PullRequest;\n comments: PullRequestComment[];\n aiSummary: string;\n review?: import(\"../ai/types.js\").AiDetailedReviewResponse;\n /** true = review was actually posted to the hosting provider */\n reviewPosted: boolean;\n /** How inline comments were delivered: formal inline, plain comments, or not posted */\n inlineDelivery: \"inline\" | \"plain-comments\" | \"none\";\n}\n\n/**\n * Parse a unified diff and return the set of changed file paths.\n */\nfunction parseChangedPathsFromDiff(diff: string): string[] {\n const paths = new Set<string>();\n for (const line of diff.split(\"\\n\")) {\n // Match \"+++ b/src/foo.ts\" lines\n const m = line.match(/^\\+\\+\\+ b\\/(.+)/);\n if (m?.[1] && m[1] !== \"/dev/null\") {\n paths.add(m[1].trim());\n }\n }\n return [...paths];\n}\n\n/**\n * Given a list of changed file paths, find supporting context files that are\n * closely related (imported by or importing changed files).\n * Returns at most `maxFiles` file paths.\n */\nasync function findContextFiles(\n changedPaths: string[],\n allTrackedFiles: string[],\n cwd: string,\n maxFiles = 8\n): Promise<string[]> {\n const contextPaths = new Set<string>();\n\n for (const changedPath of changedPaths.slice(0, 10)) {\n const content = await readRepoFile(changedPath, cwd);\n if (!content) continue;\n\n // Extract relative import paths from TypeScript/JS files\n const importMatches = content.matchAll(/from\\s+['\"]([^'\"]+)['\"]/g);\n for (const [, importPath] of importMatches) {\n if (!importPath || importPath.startsWith(\"node:\") || !importPath.startsWith(\".\")) continue;\n // Resolve the import path relative to the file's directory\n const dir = changedPath.split(\"/\").slice(0, -1).join(\"/\");\n const candidates = [\n `${dir}/${importPath}.ts`,\n `${dir}/${importPath}.tsx`,\n `${dir}/${importPath}/index.ts`,\n `${dir}/${importPath}`,\n ].map((p) => p.replace(/\\/\\//g, \"/\").replace(/^\\//, \"\"));\n\n for (const candidate of candidates) {\n if (allTrackedFiles.includes(candidate) && !changedPaths.includes(candidate)) {\n contextPaths.add(candidate);\n break;\n }\n }\n }\n\n if (contextPaths.size >= maxFiles) break;\n }\n\n return [...contextPaths].slice(0, maxFiles);\n}\n\n/**\n * Fetch a PR, its full diff, and all related codebase context;\n * run a senior-developer quality AI review;\n * submit as a formal review (with inline comments) to the hosting provider.\n */\nexport async function runReviewWorkflow(\n gitx: Gitx,\n prNumber: number,\n postComment = true\n): Promise<ReviewResult> {\n const ctx = await gitx.getRepoContext();\n const provider = createProvider(ctx);\n const cwd = gitx.cwd;\n\n const fetchSpinner = ora(\"Fetching PR info, diff and comments…\").start();\n const pr = await provider.getPR(ctx.repoSlug, prNumber);\n const [comments, diff] = await Promise.all([\n provider.getPRComments(ctx.repoSlug, prNumber),\n provider.getPRDiff(ctx.repoSlug, prNumber),\n ]);\n fetchSpinner.succeed(`PR #${prNumber}: \"${pr.title}\" (${pr.head} → ${pr.base})`);\n\n // ── Build codebase context ─────────────────────────────────────────────────\n const ctxSpinner = ora(\"Building codebase context from changed files…\").start();\n const allTracked = await listTrackedFiles(cwd);\n const allChangedPaths = parseChangedPathsFromDiff(diff);\n\n // Filter out lockfiles / generated files — they waste tokens and add no review value.\n // No file count cap — per-file budgets in buildSeniorReviewPrompt already control\n // total size. Dropping files arbitrarily is worse than sending all of them.\n const changedPaths = allChangedPaths.filter(isReviewableFile);\n const skippedCount = allChangedPaths.length - changedPaths.length;\n\n // Read full content of changed files\n const changedFiles: Record<string, string> = {};\n for (const p of changedPaths) {\n const content = await readRepoFile(p, cwd);\n if (content) changedFiles[p] = content;\n }\n\n // Read supporting context files (imported by the changed files)\n // 10 context files gives the AI a solid picture of the codebase structure\n const ctxPaths = await findContextFiles(changedPaths, allTracked, cwd, 10);\n const contextFiles: Record<string, string> = {};\n for (const p of ctxPaths) {\n const content = await readRepoFile(p, cwd);\n if (content) contextFiles[p] = content;\n }\n\n const skippedNote = skippedCount > 0 ? `, ${skippedCount} lock/generated files skipped` : \"\";\n ctxSpinner.succeed(\n `Context: ${changedPaths.length} changed files, ${ctxPaths.length} context files${skippedNote}`\n );\n\n const reviewSpinner = ora(\n `Running senior-dev AI review… (this may take up to 5 min for large PRs)`\n ).start();\n\n let review: Awaited<ReturnType<typeof gitx.ai.reviewPRDetailed>>;\n try {\n review = await gitx.ai.reviewPRDetailed({\n prTitle: pr.title,\n prBody: pr.body,\n author: pr.author,\n headBranch: pr.head,\n baseBranch: pr.base,\n diff,\n changedFiles,\n contextFiles,\n repoFileList: allTracked,\n existingComments: comments.map((c) => ({\n author: c.author,\n body: c.body,\n path: c.path,\n line: c.line,\n })),\n });\n reviewSpinner.succeed(\n `Review complete — verdict: ${review.verdict} | ${review.inlineComments.length} inline comment(s)`\n );\n } catch (err) {\n reviewSpinner.fail(\"AI review failed.\");\n throw err;\n }\n\n // ── Build the formatted review body (for the summary comment) ─────────────\n const verdictIcon =\n review.verdict === \"approve\" ? \"✅\" :\n review.verdict === \"request_changes\" ? \"🔴\" : \"💬\";\n\n const checklistLines = review.checklist.map((c) => {\n const icon = c.status === \"pass\" ? \"✅\" : c.status === \"warn\" ? \"⚠️\" : \"❌\";\n return `| ${icon} | **${c.area}** | ${c.note} |`;\n });\n\n const issueLines = review.issues.map((i) => {\n const sev = i.severity === \"critical\" ? \"🔴\" : i.severity === \"warning\" ? \"🟡\" : \"💡\";\n const loc = i.file ? ` (\\`${i.file}${i.line ? `:${i.line}` : \"\"}\\`)` : \"\";\n return `${sev} ${i.description}${loc}`;\n });\n\n const posLines = review.positives.map((p) => `✔ ${p}`);\n\n const summaryBody = [\n `## ${verdictIcon} Senior Dev AI Review (gitx) — ${review.verdict.replace(\"_\", \" \")}`,\n \"\",\n review.summary,\n ...(checklistLines.length > 0\n ? [\"\", \"### Review Checklist\", \"| Status | Area | Note |\", \"|--------|------|------|\", ...checklistLines]\n : []),\n ...(review.issues.length > 0 ? [\"\", \"### Issues Found\", ...issueLines] : []),\n ...(review.positives.length > 0 ? [\"\", \"### Positives\", ...posLines] : []),\n ...(review.testingNotes ? [\"\", \"### How to Test\", review.testingNotes] : []),\n ...(review.inlineComments.length > 0\n ? [`\\n> 💬 ${review.inlineComments.length} inline comment(s) posted on specific lines.`]\n : []),\n \"\",\n \"*Generated by [gitx](https://github.com/g-abhishek/gitx)*\",\n ].join(\"\\n\");\n\n // ── Post the formal review (inline comments + verdict) ────────────────────\n let reviewPosted = false;\n let inlineDelivery: ReviewResult[\"inlineDelivery\"] = \"none\";\n\n if (postComment) {\n const inlineCount = review.inlineComments.length;\n const postSpinner = ora(\n `Submitting review to PR${inlineCount > 0 ? ` with ${inlineCount} inline comment(s)` : \"\"}…`\n ).start();\n try {\n await provider.submitPRReview(ctx.repoSlug, prNumber, {\n body: summaryBody,\n event: review.verdict,\n comments: review.inlineComments.map((c) => ({\n path: c.path,\n line: c.line,\n body: c.suggestion\n ? `${c.body}\\n\\n**Suggestion:**\\n\\`\\`\\`suggestion\\n${c.suggestion}\\n\\`\\`\\``\n : c.body,\n })),\n });\n reviewPosted = true;\n // Determine how inline comments were delivered.\n // GitHub's submitPRReview will attempt inline first, then fall back to\n // plain comments. We can't detect which path was taken from here, so\n // we report \"inline\" optimistically — the user sees the real result on GitHub.\n inlineDelivery = inlineCount > 0 ? \"inline\" : \"none\";\n postSpinner.succeed(\n `Review submitted to PR.${inlineCount > 0 ? ` (${inlineCount} inline comment(s) — see PR for delivery method)` : \"\"}`\n );\n } catch (err) {\n postSpinner.fail(`Could not post review to PR: ${String((err as Error).message ?? err)}`);\n // Don't rethrow — still return the review so the user can see it locally\n }\n }\n\n return { pr, comments, aiSummary: summaryBody, review, reviewPosted, inlineDelivery };\n}\n\n// ─── Fix-comments workflow ────────────────────────────────────────────────────\n\nexport interface FixCommentsResult {\n pr: PullRequest;\n comments: PullRequestComment[];\n appliedFixes: Array<{ path: string; rationale: string }>;\n skippedFixes: Array<{ path: string; reason: string }>;\n}\n\n/**\n * Fetch PR review comments, ask AI to suggest fixes, apply them, and\n * commit + push the changes.\n */\nexport async function runFixCommentsWorkflow(\n gitx: Gitx,\n prNumber: number,\n dryRun = false,\n noCommit = false\n): Promise<FixCommentsResult> {\n const { applyUnifiedDiff, stageAll, hasStagedChanges, commitChanges } = await import(\n \"../utils/gitOps.js\"\n );\n const cwd = gitx.cwd;\n const ctx = await gitx.getRepoContext();\n const provider = createProvider(ctx);\n\n const fetchSpinner = ora(\"Fetching PR, comments and diff…\").start();\n const pr = await provider.getPR(ctx.repoSlug, prNumber);\n const [comments, diff] = await Promise.all([\n provider.getPRComments(ctx.repoSlug, prNumber),\n provider.getPRDiff(ctx.repoSlug, prNumber),\n ]);\n fetchSpinner.succeed(`PR #${prNumber}: \"${pr.title}\" — ${comments.length} comment(s)`);\n\n if (comments.length === 0) {\n logger.info(\"No review comments found.\");\n return { pr, comments, appliedFixes: [], skippedFixes: [] };\n }\n\n // ── Build file context ────────────────────────────────────────────────────\n // Only load files directly mentioned in comments + their close imports.\n // Random repo source files are irrelevant — the AI is fixing specific lines.\n const ctxSpinner = ora(\"Building file context for commented files…\").start();\n\n const mentionedPaths = [...new Set(comments.map((c) => c.path).filter(Boolean) as string[])];\n const trackedFiles = await listTrackedFiles(cwd);\n\n // File content strategy — same thresholds as the review workflow:\n // ≤ FULL_FILE_THRESHOLD lines → send the whole file (AI needs full context to make correct edits)\n // larger files → show a generous window around each commented line\n const FULL_FILE_THRESHOLD = 400;\n const COMMENT_WINDOW = 80; // lines above/below a commented line in large files\n const CTX_FILE_MAX = 4_000; // chars per supporting context file\n\n const fileContents: Record<string, string> = {};\n\n // Commented lines per file — used for smart windowing on large files\n const commentedLines: Record<string, number[]> = {};\n for (const c of comments) {\n if (c.path && c.line) {\n (commentedLines[c.path] ??= []).push(c.line);\n }\n }\n\n for (const filePath of mentionedPaths) {\n const content = await readRepoFile(filePath, cwd);\n if (!content) continue;\n\n const lines = content.split(\"\\n\");\n if (lines.length <= FULL_FILE_THRESHOLD) {\n // Small file — send it whole\n fileContents[filePath] = lines\n .map((l, i) => `${String(i + 1).padStart(5, \" \")} | ${l}`)\n .join(\"\\n\");\n } else {\n // Large file — show windows around commented lines\n const targets = commentedLines[filePath] ?? [];\n const included = new Set<number>();\n for (const line of targets) {\n for (let i = Math.max(0, line - COMMENT_WINDOW - 1); i < Math.min(lines.length, line + COMMENT_WINDOW); i++) {\n included.add(i);\n }\n }\n // If no specific lines, fall back to first FULL_FILE_THRESHOLD lines\n const indices = included.size > 0 ? [...included].sort((a, b) => a - b) : [...Array(FULL_FILE_THRESHOLD).keys()];\n let excerpt = \"\";\n let prev = -1;\n for (const idx of indices) {\n if (prev !== -1 && idx > prev + 1) excerpt += `\\n … (${idx - prev - 1} lines omitted)\\n`;\n excerpt += `${String(idx + 1).padStart(5, \" \")} | ${lines[idx]}\\n`;\n prev = idx;\n }\n fileContents[filePath] = excerpt.trimEnd();\n }\n }\n\n // Add context files (imports of the mentioned files) for extra background\n const ctxPaths = await findContextFiles(mentionedPaths, trackedFiles, cwd, 8);\n for (const filePath of ctxPaths) {\n if (fileContents[filePath]) continue; // already loaded\n const content = await readRepoFile(filePath, cwd);\n if (!content) continue;\n fileContents[filePath] = content.length <= CTX_FILE_MAX\n ? content\n : content.slice(0, CTX_FILE_MAX) + \"\\n… (truncated)\";\n }\n\n ctxSpinner.succeed(\n `Context: ${mentionedPaths.length} commented file(s), ${ctxPaths.length} context file(s)`\n );\n\n const fixSpinner = ora(\"🧠 Generating AI-suggested fixes…\").start();\n const fixResult = await gitx.ai.suggestFixes({\n comments: comments.map((c) => ({\n body: c.body,\n author: c.author,\n path: c.path,\n line: c.line,\n })),\n prTitle: pr.title,\n prBody: pr.body,\n diff,\n fileContents,\n });\n fixSpinner.succeed(`AI generated ${fixResult.suggestedEdits.length} fix(es).`);\n\n const appliedFixes: Array<{ path: string; rationale: string }> = [];\n const skippedFixes: Array<{ path: string; reason: string }> = [];\n\n for (const edit of fixResult.suggestedEdits) {\n if (dryRun) {\n logger.info(` ↳ [dry-run] Would apply fix to: ${edit.path}`);\n logger.info(` Rationale: ${edit.rationale}`);\n appliedFixes.push({ path: edit.path, rationale: edit.rationale });\n continue;\n }\n\n const applyResult = await applyUnifiedDiff(edit.unifiedDiff, cwd);\n if (applyResult.ok) {\n logger.info(` ↳ Applied fix to: ${edit.path}`);\n appliedFixes.push({ path: edit.path, rationale: edit.rationale });\n } else {\n logger.warn(` ↳ Could not apply fix to ${edit.path}: ${applyResult.error ?? \"unknown\"}`);\n skippedFixes.push({\n path: edit.path,\n reason: applyResult.error ?? \"git apply failed\",\n });\n }\n }\n\n if (!dryRun && !noCommit && appliedFixes.length > 0) {\n await stageAll(cwd);\n if (await hasStagedChanges(cwd)) {\n const msg = `fix: address PR #${prNumber} review comments\\n\\n${appliedFixes.map((f) => `- ${f.path}: ${f.rationale}`).join(\"\\n\")}`;\n const sha = await commitChanges(msg, cwd);\n logger.success(`Committed fixes: ${sha.slice(0, 8)}`);\n\n // Post summary comment\n const fixSummary = appliedFixes.map((f) => `- \\`${f.path}\\`: ${f.rationale}`).join(\"\\n\");\n await provider.addPRComment(\n ctx.repoSlug,\n prNumber,\n `## 🤖 Auto-fixes applied (gitx)\\n\\n${fixSummary}\\n\\nCommit: \\`${sha.slice(0, 8)}\\``\n );\n }\n }\n\n if (!dryRun && noCommit && appliedFixes.length > 0) {\n logger.info(\"\\n💡 Fixes applied to working tree. Review the changes and commit when ready.\");\n }\n\n return { pr, comments, appliedFixes, skippedFixes };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@g-abhishek/gitx",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "AI-powered Git workflow automation CLI and SDK",
5
5
  "type": "module",
6
6
  "license": "MIT",