@paretools/github 0.8.5 → 0.10.0

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 (99) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/index.js.map +1 -1
  3. package/dist/lib/formatters.d.ts +10 -2
  4. package/dist/lib/formatters.d.ts.map +1 -1
  5. package/dist/lib/formatters.js +144 -16
  6. package/dist/lib/formatters.js.map +1 -1
  7. package/dist/lib/gh-runner.d.ts.map +1 -1
  8. package/dist/lib/gh-runner.js +2 -1
  9. package/dist/lib/gh-runner.js.map +1 -1
  10. package/dist/lib/parsers.d.ts +54 -18
  11. package/dist/lib/parsers.d.ts.map +1 -1
  12. package/dist/lib/parsers.js +426 -38
  13. package/dist/lib/parsers.js.map +1 -1
  14. package/dist/lib/path-validation.d.ts +13 -0
  15. package/dist/lib/path-validation.d.ts.map +1 -0
  16. package/dist/lib/path-validation.js +54 -0
  17. package/dist/lib/path-validation.js.map +1 -0
  18. package/dist/schemas/index.d.ts +267 -4
  19. package/dist/schemas/index.d.ts.map +1 -1
  20. package/dist/schemas/index.js +195 -4
  21. package/dist/schemas/index.js.map +1 -1
  22. package/dist/tools/api.d.ts.map +1 -1
  23. package/dist/tools/api.js +134 -8
  24. package/dist/tools/api.js.map +1 -1
  25. package/dist/tools/gist-create.d.ts.map +1 -1
  26. package/dist/tools/gist-create.js +91 -21
  27. package/dist/tools/gist-create.js.map +1 -1
  28. package/dist/tools/index.d.ts.map +1 -1
  29. package/dist/tools/index.js +6 -0
  30. package/dist/tools/index.js.map +1 -1
  31. package/dist/tools/issue-close.d.ts.map +1 -1
  32. package/dist/tools/issue-close.js +56 -9
  33. package/dist/tools/issue-close.js.map +1 -1
  34. package/dist/tools/issue-comment.d.ts.map +1 -1
  35. package/dist/tools/issue-comment.js +60 -9
  36. package/dist/tools/issue-comment.js.map +1 -1
  37. package/dist/tools/issue-create.d.ts.map +1 -1
  38. package/dist/tools/issue-create.js +95 -9
  39. package/dist/tools/issue-create.js.map +1 -1
  40. package/dist/tools/issue-list.d.ts.map +1 -1
  41. package/dist/tools/issue-list.js +139 -11
  42. package/dist/tools/issue-list.js.map +1 -1
  43. package/dist/tools/issue-update.d.ts.map +1 -1
  44. package/dist/tools/issue-update.js +142 -15
  45. package/dist/tools/issue-update.js.map +1 -1
  46. package/dist/tools/issue-view.d.ts.map +1 -1
  47. package/dist/tools/issue-view.js +26 -14
  48. package/dist/tools/issue-view.js.map +1 -1
  49. package/dist/tools/label-create.d.ts +4 -0
  50. package/dist/tools/label-create.d.ts.map +1 -0
  51. package/dist/tools/label-create.js +73 -0
  52. package/dist/tools/label-create.js.map +1 -0
  53. package/dist/tools/label-list.d.ts +4 -0
  54. package/dist/tools/label-list.d.ts.map +1 -0
  55. package/dist/tools/label-list.js +71 -0
  56. package/dist/tools/label-list.js.map +1 -0
  57. package/dist/tools/pr-checks.d.ts.map +1 -1
  58. package/dist/tools/pr-checks.js +57 -11
  59. package/dist/tools/pr-checks.js.map +1 -1
  60. package/dist/tools/pr-comment.d.ts.map +1 -1
  61. package/dist/tools/pr-comment.js +60 -9
  62. package/dist/tools/pr-comment.js.map +1 -1
  63. package/dist/tools/pr-create.d.ts.map +1 -1
  64. package/dist/tools/pr-create.js +154 -9
  65. package/dist/tools/pr-create.js.map +1 -1
  66. package/dist/tools/pr-diff.d.ts.map +1 -1
  67. package/dist/tools/pr-diff.js +63 -16
  68. package/dist/tools/pr-diff.js.map +1 -1
  69. package/dist/tools/pr-list.d.ts.map +1 -1
  70. package/dist/tools/pr-list.js +115 -11
  71. package/dist/tools/pr-list.js.map +1 -1
  72. package/dist/tools/pr-merge.d.ts.map +1 -1
  73. package/dist/tools/pr-merge.js +104 -15
  74. package/dist/tools/pr-merge.js.map +1 -1
  75. package/dist/tools/pr-review.d.ts.map +1 -1
  76. package/dist/tools/pr-review.js +41 -8
  77. package/dist/tools/pr-review.js.map +1 -1
  78. package/dist/tools/pr-update.d.ts.map +1 -1
  79. package/dist/tools/pr-update.js +157 -10
  80. package/dist/tools/pr-update.js.map +1 -1
  81. package/dist/tools/pr-view.d.ts.map +1 -1
  82. package/dist/tools/pr-view.js +27 -14
  83. package/dist/tools/pr-view.js.map +1 -1
  84. package/dist/tools/release-create.d.ts.map +1 -1
  85. package/dist/tools/release-create.js +106 -9
  86. package/dist/tools/release-create.js.map +1 -1
  87. package/dist/tools/release-list.d.ts.map +1 -1
  88. package/dist/tools/release-list.js +39 -13
  89. package/dist/tools/release-list.js.map +1 -1
  90. package/dist/tools/run-list.d.ts.map +1 -1
  91. package/dist/tools/run-list.js +111 -12
  92. package/dist/tools/run-list.js.map +1 -1
  93. package/dist/tools/run-rerun.d.ts.map +1 -1
  94. package/dist/tools/run-rerun.js +38 -8
  95. package/dist/tools/run-rerun.js.map +1 -1
  96. package/dist/tools/run-view.d.ts.map +1 -1
  97. package/dist/tools/run-view.js +64 -13
  98. package/dist/tools/run-view.js.map +1 -1
  99. package/package.json +2 -2
@@ -4,13 +4,18 @@ import { assertNoFlagInjection } from "@paretools/shared";
4
4
  import { ghCmd } from "../lib/gh-runner.js";
5
5
  import { formatPrDiff, compactPrDiffMap, formatPrDiffCompact } from "../lib/formatters.js";
6
6
  import { PrDiffResultSchema } from "../schemas/index.js";
7
+ /** Maximum diff output size before marking as truncated (256 KB). */
8
+ const MAX_DIFF_SIZE = 256 * 1024;
7
9
  /** Registers the `pr-diff` tool on the given MCP server. */
8
10
  export function registerPrDiffTool(server) {
9
11
  server.registerTool("pr-diff", {
10
12
  title: "PR Diff",
11
- description: "Returns file-level diff statistics for a pull request. Use full=true for patch content. Use instead of running `gh pr diff` in the terminal.",
13
+ description: "Returns file-level diff statistics for a pull request. Use full=true for patch content.",
12
14
  inputSchema: {
13
- pr: z.number().describe("Pull request number"),
15
+ number: z
16
+ .string()
17
+ .max(INPUT_LIMITS.STRING_MAX)
18
+ .describe("Pull request number, URL, or branch name"),
14
19
  repo: z
15
20
  .string()
16
21
  .max(INPUT_LIMITS.SHORT_STRING_MAX)
@@ -21,31 +26,40 @@ export function registerPrDiffTool(server) {
21
26
  .optional()
22
27
  .default(false)
23
28
  .describe("Include full patch content in chunks"),
24
- compact: z
25
- .boolean()
26
- .optional()
27
- .default(true)
28
- .describe("Auto-compact when structured output exceeds raw CLI tokens. Set false to always get full schema."),
29
+ nameOnly: z.boolean().optional().describe("List only changed file names (--name-only)"),
30
+ compact: z.boolean().optional().default(true).describe("Prefer compact output"),
29
31
  },
30
32
  outputSchema: PrDiffResultSchema,
31
- }, async ({ pr, repo, full, compact }) => {
33
+ }, async ({ number, repo, full, nameOnly, compact }) => {
32
34
  if (repo) {
33
35
  assertNoFlagInjection(repo, "repo");
34
36
  }
37
+ if (typeof number === "string") {
38
+ assertNoFlagInjection(number, "number");
39
+ }
40
+ const selector = String(number);
35
41
  // Get numstat for structured file-level stats
36
- const numstatArgs = ["pr", "diff", String(pr), "--patch=false"];
42
+ const numstatArgs = ["pr", "diff", selector, "--patch=false"];
37
43
  if (repo)
38
44
  numstatArgs.push("--repo", repo);
39
45
  // We use a two-pass approach: first get numstat, then optionally get full patch
40
- const diffArgs = ["pr", "diff", String(pr)];
46
+ const diffArgs = ["pr", "diff", selector];
41
47
  if (repo)
42
48
  diffArgs.push("--repo", repo);
49
+ if (nameOnly)
50
+ diffArgs.push("--name-only");
43
51
  const result = await ghCmd(diffArgs, { cwd: process.cwd() });
44
52
  if (result.exitCode !== 0) {
45
53
  throw new Error(`gh pr diff failed: ${result.stderr}`);
46
54
  }
55
+ // S-gap: Detect truncation
56
+ const truncated = result.stdout.length >= MAX_DIFF_SIZE;
47
57
  // Parse the unified diff output to extract numstat-like data
48
58
  const diff = parsePrDiffFromPatch(result.stdout);
59
+ // S-gap: Set truncation flag
60
+ if (truncated) {
61
+ diff.truncated = true;
62
+ }
49
63
  // If full patch requested, attach chunk data
50
64
  if (full && diff.files.length > 0) {
51
65
  const filePatches = result.stdout.split(/^diff --git /m).filter(Boolean);
@@ -54,6 +68,11 @@ export function registerPrDiffTool(server) {
54
68
  if (fileMatch) {
55
69
  const matchedFile = diff.files.find((f) => f.file === fileMatch[1]);
56
70
  if (matchedFile) {
71
+ // S-gap: Extract file mode if present
72
+ const modeMatch = patch.match(/(?:new|old|index|diff) (?:file )?mode (\d+)/);
73
+ if (modeMatch) {
74
+ matchedFile.mode = modeMatch[1];
75
+ }
57
76
  const chunks = patch.split(/^@@/m).slice(1);
58
77
  matchedFile.chunks = chunks.map((chunk) => {
59
78
  const headerEnd = chunk.indexOf("\n");
@@ -76,14 +95,40 @@ export function registerPrDiffTool(server) {
76
95
  function parsePrDiffFromPatch(patchOutput) {
77
96
  const filePatches = patchOutput.split(/^diff --git /m).filter(Boolean);
78
97
  const files = filePatches.map((patch) => {
79
- // Extract file path from "a/path b/path" header
80
- const headerMatch = patch.match(/^a\/(.+?) b\/(.+?)\n/);
81
- const oldFile = headerMatch?.[1] ?? "";
82
- const newFile = headerMatch?.[2] ?? "";
98
+ // Extract file paths from the diff header, handling quoted paths with spaces.
99
+ const headerLine = patch.split("\n", 1)[0] ?? "";
100
+ let oldFile = "";
101
+ let newFile = "";
102
+ const quotedHeader = headerLine.match(/^"a\/(.+)" "b\/(.+)"$/);
103
+ if (quotedHeader) {
104
+ oldFile = quotedHeader[1];
105
+ newFile = quotedHeader[2];
106
+ }
107
+ else {
108
+ const plainHeader = headerLine.match(/^a\/(.+?) b\/(.+)$/);
109
+ if (plainHeader) {
110
+ oldFile = plainHeader[1];
111
+ newFile = plainHeader[2];
112
+ }
113
+ }
114
+ // Rename metadata is more reliable than the header for rename edge-cases.
115
+ const renameFromMatch = patch.match(/^rename from (.+)$/m);
116
+ const renameToMatch = patch.match(/^rename to (.+)$/m);
117
+ if (renameFromMatch)
118
+ oldFile = renameFromMatch[1];
119
+ if (renameToMatch)
120
+ newFile = renameToMatch[1];
83
121
  // Detect status from diff headers
84
122
  const isNew = /^new file mode/m.test(patch);
85
123
  const isDeleted = /^deleted file mode/m.test(patch);
86
- const isRenamed = /^rename from /m.test(patch) || /^similarity index/m.test(patch);
124
+ const isRenamed = !!renameFromMatch || !!renameToMatch || /^similarity index/m.test(patch);
125
+ // Detect binary files from diff markers
126
+ const isBinary = /^Binary files .* differ$/m.test(patch) ||
127
+ /^GIT binary patch$/m.test(patch) ||
128
+ /^Binary file .* has changed$/m.test(patch);
129
+ // S-gap: Extract file mode
130
+ const modeMatch = patch.match(/(?:new|old) file mode (\d+)/);
131
+ const mode = modeMatch ? modeMatch[1] : undefined;
87
132
  // Count additions and deletions from diff lines
88
133
  let additions = 0;
89
134
  let deletions = 0;
@@ -114,11 +159,13 @@ function parsePrDiffFromPatch(patchOutput) {
114
159
  ? "renamed"
115
160
  : "modified";
116
161
  return {
117
- file: newFile,
162
+ file: newFile || oldFile,
118
163
  status,
119
164
  additions,
120
165
  deletions,
121
166
  ...(isRenamed && oldFile !== newFile ? { oldFile } : {}),
167
+ ...(mode ? { mode } : {}),
168
+ ...(isBinary ? { binary: true } : {}),
122
169
  };
123
170
  });
124
171
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"pr-diff.js","sourceRoot":"","sources":["../../src/tools/pr-diff.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pr-diff.js","sourceRoot":"","sources":["../../src/tools/pr-diff.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pr-list.d.ts","sourceRoot":"","sources":["../../src/tools/pr-list.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASzE,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,QAmEnD"}
1
+ {"version":3,"file":"pr-list.d.ts","sourceRoot":"","sources":["../../src/tools/pr-list.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAWzE,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,QAgKnD"}
@@ -4,12 +4,13 @@ import { ghCmd } from "../lib/gh-runner.js";
4
4
  import { parsePrList } from "../lib/parsers.js";
5
5
  import { formatPrList, compactPrListMap, formatPrListCompact } from "../lib/formatters.js";
6
6
  import { PrListResultSchema } from "../schemas/index.js";
7
- const PR_LIST_FIELDS = "number,state,title,url,headRefName,author";
7
+ // S-gap: Add labels, isDraft, baseRefName, reviewDecision, mergeable to JSON fields
8
+ const PR_LIST_FIELDS = "number,state,title,url,headRefName,baseRefName,author,labels,isDraft,reviewDecision,mergeable";
8
9
  /** Registers the `pr-list` tool on the given MCP server. */
9
10
  export function registerPrListTool(server) {
10
11
  server.registerTool("pr-list", {
11
12
  title: "PR List",
12
- description: "Lists pull requests with optional filters. Returns structured list with PR number, state, title, author, and branch. Use instead of running `gh pr list` in the terminal.",
13
+ description: "Lists pull requests with optional filters. Returns structured list with PR number, state, title, author, branch, labels, draft status, and merge readiness.",
13
14
  inputSchema: {
14
15
  state: z
15
16
  .enum(["open", "closed", "merged", "all"])
@@ -27,24 +28,76 @@ export function registerPrListTool(server) {
27
28
  .optional()
28
29
  .describe("Filter by author username"),
29
30
  label: z.string().max(INPUT_LIMITS.SHORT_STRING_MAX).optional().describe("Filter by label"),
30
- path: z
31
+ // S-gap P1: Add label as array for multiple label filtering
32
+ labels: z
33
+ .array(z.string().max(INPUT_LIMITS.SHORT_STRING_MAX))
34
+ .max(INPUT_LIMITS.ARRAY_MAX)
35
+ .optional()
36
+ .describe("Filter by multiple labels (each maps to --label)"),
37
+ draft: z.boolean().optional().describe("Filter by draft status (-d/--draft)"),
38
+ // S-gap P0: Add base branch filter
39
+ base: z
40
+ .string()
41
+ .max(INPUT_LIMITS.SHORT_STRING_MAX)
42
+ .optional()
43
+ .describe("Filter by base branch (-B/--base)"),
44
+ // S-gap P0: Add head branch filter
45
+ head: z
46
+ .string()
47
+ .max(INPUT_LIMITS.SHORT_STRING_MAX)
48
+ .optional()
49
+ .describe("Filter by head branch (-H/--head)"),
50
+ // S-gap P1: Add assignee filter
51
+ assignee: z
52
+ .string()
53
+ .max(INPUT_LIMITS.SHORT_STRING_MAX)
54
+ .optional()
55
+ .describe("Filter by assignee username (-a/--assignee)"),
56
+ // S-gap P1: Add search
57
+ search: z
31
58
  .string()
32
- .max(INPUT_LIMITS.PATH_MAX)
59
+ .max(INPUT_LIMITS.STRING_MAX)
33
60
  .optional()
34
- .describe("Repository path (default: cwd)"),
35
- compact: z
36
- .boolean()
61
+ .describe("GitHub search syntax (-S/--search)"),
62
+ // S-gap P1: Add repo for cross-repo listing
63
+ repo: z
64
+ .string()
65
+ .max(INPUT_LIMITS.SHORT_STRING_MAX)
37
66
  .optional()
38
- .default(true)
39
- .describe("Auto-compact when structured output exceeds raw CLI tokens. Set false to always get full schema."),
67
+ .describe("Repository in OWNER/REPO format (--repo). Default: current repo."),
68
+ // S-gap P2: Add app filter
69
+ app: z
70
+ .string()
71
+ .max(INPUT_LIMITS.SHORT_STRING_MAX)
72
+ .optional()
73
+ .describe("Filter by GitHub App (--app)"),
74
+ path: z.string().max(INPUT_LIMITS.PATH_MAX).optional().describe("Repository path"),
75
+ compact: z.boolean().optional().default(true).describe("Prefer compact output"),
40
76
  },
41
77
  outputSchema: PrListResultSchema,
42
- }, async ({ state, limit, author, label, path, compact }) => {
78
+ }, async ({ state, limit, author, label, labels, draft, base, head, assignee, search, repo, app, path, compact, }) => {
43
79
  const cwd = path || process.cwd();
44
80
  if (author)
45
81
  assertNoFlagInjection(author, "author");
46
82
  if (label)
47
83
  assertNoFlagInjection(label, "label");
84
+ if (labels) {
85
+ for (const l of labels) {
86
+ assertNoFlagInjection(l, "labels");
87
+ }
88
+ }
89
+ if (base)
90
+ assertNoFlagInjection(base, "base");
91
+ if (head)
92
+ assertNoFlagInjection(head, "head");
93
+ if (assignee)
94
+ assertNoFlagInjection(assignee, "assignee");
95
+ if (search)
96
+ assertNoFlagInjection(search, "search");
97
+ if (repo)
98
+ assertNoFlagInjection(repo, "repo");
99
+ if (app)
100
+ assertNoFlagInjection(app, "app");
48
101
  const args = ["pr", "list", "--json", PR_LIST_FIELDS, "--limit", String(limit)];
49
102
  if (state)
50
103
  args.push("--state", state);
@@ -52,11 +105,62 @@ export function registerPrListTool(server) {
52
105
  args.push("--author", author);
53
106
  if (label)
54
107
  args.push("--label", label);
108
+ if (labels && labels.length > 0) {
109
+ for (const l of labels) {
110
+ args.push("--label", l);
111
+ }
112
+ }
113
+ if (draft)
114
+ args.push("--draft");
115
+ if (base)
116
+ args.push("--base", base);
117
+ if (head)
118
+ args.push("--head", head);
119
+ if (assignee)
120
+ args.push("--assignee", assignee);
121
+ if (search)
122
+ args.push("--search", search);
123
+ if (repo)
124
+ args.push("--repo", repo);
125
+ if (app)
126
+ args.push("--app", app);
55
127
  const result = await ghCmd(args, cwd);
56
128
  if (result.exitCode !== 0) {
57
129
  throw new Error(`gh pr list failed: ${result.stderr}`);
58
130
  }
59
- const data = parsePrList(result.stdout);
131
+ let totalAvailable;
132
+ if (limit < 1000) {
133
+ const countArgs = ["pr", "list", "--json", PR_LIST_FIELDS, "--limit", "1000"];
134
+ if (state)
135
+ countArgs.push("--state", state);
136
+ if (author)
137
+ countArgs.push("--author", author);
138
+ if (label)
139
+ countArgs.push("--label", label);
140
+ if (labels && labels.length > 0) {
141
+ for (const l of labels)
142
+ countArgs.push("--label", l);
143
+ }
144
+ if (draft)
145
+ countArgs.push("--draft");
146
+ if (base)
147
+ countArgs.push("--base", base);
148
+ if (head)
149
+ countArgs.push("--head", head);
150
+ if (assignee)
151
+ countArgs.push("--assignee", assignee);
152
+ if (search)
153
+ countArgs.push("--search", search);
154
+ if (repo)
155
+ countArgs.push("--repo", repo);
156
+ if (app)
157
+ countArgs.push("--app", app);
158
+ const countResult = await ghCmd(countArgs, cwd);
159
+ if (countResult.exitCode === 0) {
160
+ totalAvailable = parsePrList(countResult.stdout).total;
161
+ }
162
+ }
163
+ const data = parsePrList(result.stdout, totalAvailable);
60
164
  return compactDualOutput(data, result.stdout, formatPrList, compactPrListMap, formatPrListCompact, compact === false);
61
165
  });
62
166
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pr-list.js","sourceRoot":"","sources":["../../src/tools/pr-list.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pr-list.js","sourceRoot":"","sources":["../../src/tools/pr-list.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pr-merge.d.ts","sourceRoot":"","sources":["../../src/tools/pr-merge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,6DAA6D;AAC7D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,QA8CpD"}
1
+ {"version":3,"file":"pr-merge.d.ts","sourceRoot":"","sources":["../../src/tools/pr-merge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAkBzE,6DAA6D;AAC7D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,QAiIpD"}
@@ -1,44 +1,133 @@
1
1
  import { z } from "zod";
2
- import { dualOutput, INPUT_LIMITS } from "@paretools/shared";
2
+ import { dualOutput, assertNoFlagInjection, INPUT_LIMITS } from "@paretools/shared";
3
3
  import { ghCmd } from "../lib/gh-runner.js";
4
4
  import { parsePrMerge } from "../lib/parsers.js";
5
5
  import { formatPrMerge } from "../lib/formatters.js";
6
6
  import { PrMergeResultSchema } from "../schemas/index.js";
7
+ function classifyPrMergeError(text) {
8
+ const lower = text.toLowerCase();
9
+ if (/already merged|is already merged/.test(lower))
10
+ return "already-merged";
11
+ if (/merge conflict|conflicts/.test(lower))
12
+ return "merge-conflict";
13
+ if (/checks? (have )?not passed|required status check/.test(lower))
14
+ return "blocked-checks";
15
+ if (/forbidden|permission|403/.test(lower))
16
+ return "permission-denied";
17
+ return "unknown";
18
+ }
7
19
  /** Registers the `pr-merge` tool on the given MCP server. */
8
20
  export function registerPrMergeTool(server) {
9
21
  server.registerTool("pr-merge", {
10
22
  title: "PR Merge",
11
- description: "Merges a pull request by number. Returns structured data with merge status, method, and URL. Use instead of running `gh pr merge` in the terminal.",
23
+ description: "Merges a pull request by number, URL, or branch. Returns structured data with merge status, method, URL, and branch deletion status.",
12
24
  inputSchema: {
13
- number: z.number().describe("Pull request number"),
25
+ number: z
26
+ .string()
27
+ .max(INPUT_LIMITS.STRING_MAX)
28
+ .describe("Pull request number, URL, or branch name"),
14
29
  method: z
15
30
  .enum(["squash", "merge", "rebase"])
16
31
  .optional()
17
32
  .default("squash")
18
33
  .describe("Merge method (default: squash)"),
19
34
  deleteBranch: z.boolean().optional().default(false).describe("Delete branch after merge"),
20
- path: z
21
- .string()
22
- .max(INPUT_LIMITS.PATH_MAX)
35
+ admin: z
36
+ .boolean()
23
37
  .optional()
24
- .describe("Repository path (default: cwd)"),
25
- compact: z
38
+ .default(false)
39
+ .describe("Bypass branch protection rules (--admin)"),
40
+ auto: z
26
41
  .boolean()
27
42
  .optional()
28
- .default(true)
29
- .describe("Auto-compact when structured output exceeds raw CLI tokens. Set false to always get full schema."),
43
+ .describe("Enable auto-merge when requirements are met (--auto)"),
44
+ disableAuto: z
45
+ .boolean()
46
+ .optional()
47
+ .describe("Disable auto-merge for this PR (--disable-auto)"),
48
+ subject: z
49
+ .string()
50
+ .max(INPUT_LIMITS.SHORT_STRING_MAX)
51
+ .optional()
52
+ .describe("Commit subject for merge commit (--subject)"),
53
+ commitBody: z
54
+ .string()
55
+ .max(INPUT_LIMITS.STRING_MAX)
56
+ .optional()
57
+ .describe("Commit body for merge commit (--body)"),
58
+ authorEmail: z
59
+ .string()
60
+ .max(INPUT_LIMITS.SHORT_STRING_MAX)
61
+ .optional()
62
+ .describe("Author email for merge commit (--author-email)"),
63
+ // S-gap P0: Add matchHeadCommit for safety check
64
+ matchHeadCommit: z
65
+ .string()
66
+ .max(INPUT_LIMITS.SHORT_STRING_MAX)
67
+ .optional()
68
+ .describe("Safety check: only merge if HEAD SHA matches this value (--match-head-commit)"),
69
+ // S-gap P1: Add repo for cross-repo merging
70
+ repo: z
71
+ .string()
72
+ .max(INPUT_LIMITS.SHORT_STRING_MAX)
73
+ .optional()
74
+ .describe("Repository in OWNER/REPO format (--repo). Default: current repo."),
75
+ path: z.string().max(INPUT_LIMITS.PATH_MAX).optional().describe("Repository path"),
76
+ compact: z.boolean().optional().default(true).describe("Prefer compact output"),
30
77
  },
31
78
  outputSchema: PrMergeResultSchema,
32
- }, async ({ number, method, deleteBranch, path }) => {
79
+ }, async ({ number, method, deleteBranch, admin, auto, disableAuto, subject, commitBody, authorEmail, matchHeadCommit, repo, path, }) => {
33
80
  const cwd = path || process.cwd();
34
- const args = ["pr", "merge", String(number), `--${method}`];
81
+ if (subject)
82
+ assertNoFlagInjection(subject, "subject");
83
+ if (authorEmail)
84
+ assertNoFlagInjection(authorEmail, "authorEmail");
85
+ if (matchHeadCommit)
86
+ assertNoFlagInjection(matchHeadCommit, "matchHeadCommit");
87
+ if (repo)
88
+ assertNoFlagInjection(repo, "repo");
89
+ if (typeof number === "string")
90
+ assertNoFlagInjection(number, "number");
91
+ const selector = String(number);
92
+ const prNum = typeof number === "number" ? number : 0;
93
+ const args = ["pr", "merge", selector, `--${method}`];
35
94
  if (deleteBranch)
36
95
  args.push("--delete-branch");
37
- const result = await ghCmd(args, cwd);
96
+ if (admin)
97
+ args.push("--admin");
98
+ if (auto)
99
+ args.push("--auto");
100
+ if (disableAuto)
101
+ args.push("--disable-auto");
102
+ if (subject)
103
+ args.push("--subject", subject);
104
+ // Use --body-file - to pass commitBody via stdin, avoiding shell escaping issues
105
+ // for bodies with special characters (backticks, pipes, etc.) — especially on Windows
106
+ let stdin;
107
+ if (commitBody) {
108
+ args.push("--body-file", "-");
109
+ stdin = commitBody;
110
+ }
111
+ if (authorEmail)
112
+ args.push("--author-email", authorEmail);
113
+ if (matchHeadCommit)
114
+ args.push("--match-head-commit", matchHeadCommit);
115
+ if (repo)
116
+ args.push("--repo", repo);
117
+ const result = await ghCmd(args, { cwd, stdin });
38
118
  if (result.exitCode !== 0) {
39
- throw new Error(`gh pr merge failed: ${result.stderr}`);
119
+ const combined = `${result.stdout}\n${result.stderr}`.trim();
120
+ return dualOutput({
121
+ number: prNum,
122
+ merged: false,
123
+ method: method,
124
+ url: "",
125
+ state: disableAuto ? "auto-merge-disabled" : auto ? "auto-merge-enabled" : undefined,
126
+ errorType: classifyPrMergeError(combined),
127
+ errorMessage: combined || "gh pr merge failed",
128
+ }, formatPrMerge);
40
129
  }
41
- const data = parsePrMerge(result.stdout, number, method);
130
+ const data = parsePrMerge(result.stdout, prNum, method, !!deleteBranch, auto, disableAuto);
42
131
  return dualOutput(data, formatPrMerge);
43
132
  });
44
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pr-merge.js","sourceRoot":"","sources":["../../src/tools/pr-merge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,6DAA6D;AAC7D,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACjB,UAAU,EACV;QACE,KAAK,EAAE,UAAU;QACjB,WAAW,EACT,oJAAoJ;QACtJ,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YAClD,MAAM,EAAE,CAAC;iBACN,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;iBACnC,QAAQ,EAAE;iBACV,OAAO,CAAC,QAAQ,CAAC;iBACjB,QAAQ,CAAC,gCAAgC,CAAC;YAC7C,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC;YACzF,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC;iBAC1B,QAAQ,EAAE;iBACV,QAAQ,CAAC,gCAAgC,CAAC;YAC7C,OAAO,EAAE,CAAC;iBACP,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,OAAO,CAAC,IAAI,CAAC;iBACb,QAAQ,CACP,kGAAkG,CACnG;SACJ;QACD,YAAY,EAAE,mBAAmB;KAClC,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE;QAC/C,MAAM,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAElC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC,CAAC;QAC5D,IAAI,YAAY;YAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAE/C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAEtC,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,uBAAuB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,OAAO,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IACzC,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"pr-merge.js","sourceRoot":"","sources":["../../src/tools/pr-merge.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pr-review.d.ts","sourceRoot":"","sources":["../../src/tools/pr-review.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,8DAA8D;AAC9D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,QAwDrD"}
1
+ {"version":3,"file":"pr-review.d.ts","sourceRoot":"","sources":["../../src/tools/pr-review.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,8DAA8D;AAC9D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,QAqFrD"}
@@ -8,9 +8,12 @@ import { PrReviewResultSchema } from "../schemas/index.js";
8
8
  export function registerPrReviewTool(server) {
9
9
  server.registerTool("pr-review", {
10
10
  title: "PR Review",
11
- description: "Submits a review on a pull request (approve, request-changes, or comment). Returns structured data with the review event and URL. Use instead of running `gh pr review` in the terminal.",
11
+ description: "Submits a review on a pull request (approve, request-changes, or comment). Returns structured data with the review event, URL, and body echo.",
12
12
  inputSchema: {
13
- number: z.number().describe("Pull request number"),
13
+ number: z
14
+ .string()
15
+ .max(INPUT_LIMITS.STRING_MAX)
16
+ .describe("Pull request number, URL, or branch name"),
14
17
  event: z
15
18
  .enum(["approve", "request-changes", "comment"])
16
19
  .describe("Review type: approve, request-changes, or comment"),
@@ -19,34 +22,64 @@ export function registerPrReviewTool(server) {
19
22
  .max(INPUT_LIMITS.STRING_MAX)
20
23
  .optional()
21
24
  .describe("Review body (required for request-changes and comment)"),
22
- path: z
25
+ // S-gap P0: Add repo for cross-repo review
26
+ repo: z
27
+ .string()
28
+ .max(INPUT_LIMITS.SHORT_STRING_MAX)
29
+ .optional()
30
+ .describe("Repository in OWNER/REPO format (--repo). Default: current repo."),
31
+ // S-gap P2: Add bodyFile for reading review body from file
32
+ bodyFile: z
23
33
  .string()
24
34
  .max(INPUT_LIMITS.PATH_MAX)
25
35
  .optional()
26
- .describe("Repository path (default: cwd)"),
36
+ .describe("Read review body from file (--body-file). Mutually exclusive with body."),
37
+ path: z.string().max(INPUT_LIMITS.PATH_MAX).optional().describe("Repository path"),
27
38
  },
28
39
  outputSchema: PrReviewResultSchema,
29
- }, async ({ number, event, body, path }) => {
40
+ }, async ({ number, event, body, repo, bodyFile, path }) => {
30
41
  const cwd = path || process.cwd();
31
42
  if (body) {
32
43
  assertNoFlagInjection(body, "body");
33
44
  }
45
+ if (repo)
46
+ assertNoFlagInjection(repo, "repo");
47
+ if (bodyFile)
48
+ assertNoFlagInjection(bodyFile, "bodyFile");
49
+ if (typeof number === "string")
50
+ assertNoFlagInjection(number, "number");
34
51
  // request-changes and comment require a body
35
- if ((event === "request-changes" || event === "comment") && !body) {
52
+ if ((event === "request-changes" || event === "comment") && !body && !bodyFile) {
36
53
  throw new Error(`Review body is required for "${event}" reviews.`);
37
54
  }
38
- const args = ["pr", "review", String(number), `--${event}`];
55
+ const selector = String(number);
56
+ const prNum = typeof number === "number" ? number : 0;
57
+ const args = ["pr", "review", selector, `--${event}`];
58
+ if (repo)
59
+ args.push("--repo", repo);
39
60
  // Pass body via stdin (--body-file -) to avoid shell escaping issues
40
61
  let stdin;
41
62
  if (body) {
42
63
  args.push("--body-file", "-");
43
64
  stdin = body;
44
65
  }
66
+ else if (bodyFile) {
67
+ // S-gap P2: Read body from file
68
+ args.push("--body-file", bodyFile);
69
+ }
45
70
  const result = await ghCmd(args, { cwd, stdin });
71
+ // P1-gap #146: Classify errors instead of always throwing
46
72
  if (result.exitCode !== 0) {
73
+ // Return structured error output with classification
74
+ const data = parsePrReview(result.stdout, prNum, event, body, result.stderr);
75
+ if (data.errorType && data.errorType !== "unknown") {
76
+ // Return structured result with error classification
77
+ return dualOutput(data, formatPrReview);
78
+ }
47
79
  throw new Error(`gh pr review failed: ${result.stderr}`);
48
80
  }
49
- const data = parsePrReview(result.stdout, number, event);
81
+ // P1-gap #145: Pass body for echo in output (event mapped to GitHub type)
82
+ const data = parsePrReview(result.stdout, prNum, event, body);
50
83
  return dualOutput(data, formatPrReview);
51
84
  });
52
85
  }