@neturely/okffs 0.7.0 → 0.8.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,15 @@ See [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.8.0] - 2026-07-08
9
+ ### Added
10
+ - Add an issue-less "fix PR into base branch" tool (open + merge into develop, the mirror of promote_branch) ([#226](https://github.com/neturely/okffs/issues/226))
11
+ - merge_pull_request: accept pr_number for issue-less fix PRs into the base branch (merge-only mode) ([#224](https://github.com/neturely/okffs/issues/224))
12
+ ### Changed
13
+ - Harden reply_to_review_comment against reply-without-resolve footgun ([#230](https://github.com/neturely/okffs/issues/230))
14
+ - commit_and_update: split hint into subject + body instead of a blind 72-char slice ([#228](https://github.com/neturely/okffs/issues/228))
15
+ - Document fix_into_base + merge_pull_request pr_number mode; remove leaked INSTRUCTIONS.md and gitignore it ([#232](https://github.com/neturely/okffs/issues/232))
16
+
8
17
  ## [0.7.0] - 2026-07-06
9
18
  ### Added
10
19
  - Address #217 review: allow clearing milestone in update_issue + accurate auth wording ([#218](https://github.com/neturely/okffs/issues/218))
@@ -135,7 +144,8 @@ See [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
135
144
  - `create_pull_request` commits the updated CHANGELOG onto the branch and pushes the branch before opening the PR, with non-blocking error handling ([#38](https://github.com/2b9sa2owa/okffs/issues/38)).
136
145
  - All git operations now run via `execFileSync` with argument arrays (no shell), removing command-injection risk from branch names and commit hints; tools also checkout the target branch before committing/pushing and restore the original branch afterward.
137
146
 
138
- [Unreleased]: https://github.com/neturely/okffs/compare/v0.7.0...HEAD
147
+ [Unreleased]: https://github.com/neturely/okffs/compare/v0.8.0...HEAD
148
+ [0.8.0]: https://github.com/neturely/okffs/compare/v0.7.0...v0.8.0
139
149
  [0.7.0]: https://github.com/neturely/okffs/compare/v0.6.0...v0.7.0
140
150
  [0.6.0]: https://github.com/neturely/okffs/compare/v0.5.2...v0.6.0
141
151
  [0.5.2]: https://github.com/neturely/okffs/compare/v0.5.1...v0.5.2
package/dist/index.js CHANGED
@@ -26,9 +26,10 @@ import * as setIssueFields from "./tools/set_issue_fields.js";
26
26
  import * as updateIssue from "./tools/update_issue.js";
27
27
  import * as promoteBranch from "./tools/promote_branch.js";
28
28
  import * as mergePullRequest from "./tools/merge_pull_request.js";
29
+ import * as fixIntoBase from "./tools/fix_into_base.js";
29
30
  import * as addressPrReview from "./prompts/address_pr_review.js";
30
31
  import * as updateGuidance from "./prompts/update_guidance.js";
31
- const tools = [createIssue, listIssues, closeIssue, deleteIssue, deleteBranch, getIssue, commentIssue, createIssuesFromList, plan, linkIssues, createPullRequest, commitAndUpdate, listPrReviewComments, replyToReviewComment, resolveReviewThread, prepareRelease, updateProjectStatus, setIssueFields, updateIssue, promoteBranch, mergePullRequest];
32
+ const tools = [createIssue, listIssues, closeIssue, deleteIssue, deleteBranch, getIssue, commentIssue, createIssuesFromList, plan, linkIssues, createPullRequest, commitAndUpdate, listPrReviewComments, replyToReviewComment, resolveReviewThread, prepareRelease, updateProjectStatus, setIssueFields, updateIssue, promoteBranch, mergePullRequest, fixIntoBase];
32
33
  const prompts = [addressPrReview, updateGuidance];
33
34
  // Read the package version so the server reports the real version (dist/index.js
34
35
  // lives one level below package.json in both dev and the published package).
@@ -56,6 +57,7 @@ Common action → tool:
56
57
  - PR review: list_pr_review_comments → fix → reply_to_review_comment → resolve_review_thread (honours OKFFS_RESOLVE_THREADS); or the /okffs:address_pr_review prompt.
57
58
  - Release prep: prepare_release (bumps version + rolls the changelog; does NOT tag or publish).
58
59
  - Land an issue PR into the BASE branch (e.g. develop): merge_pull_request — the one okffs action that merges. Opt-in (OKFFS_AUTO_MERGE_BASE=true) and heavily gated; it verifies checks/threads itself and NEVER touches OKFFS_PROTECTED_BRANCH. Off by default → it just declines.
60
+ - Land an ISSUE-LESS fix into the BASE branch (no issue, e.g. review-comment cleanups): fix_into_base — the mirror of promote_branch. Opens (always safe) then merges under the same OKFFS_AUTO_MERGE_BASE gating as merge_pull_request. Prefer over raw \`gh pr create\`/\`gh pr merge\`; never targets OKFFS_PROTECTED_BRANCH.
59
61
 
60
62
  Rules: never merge, tag, or publish into OKFFS_PROTECTED_BRANCH autonomously — okffs may OPEN a PR into it (promote_branch), but the merge/tag are yours to hand back for. merge_pull_request only ever lands PRs into the base tier, never the protected branch. Destructive tools (delete_issue, delete_branch) require confirmed: true (call once to preview, again to act).`;
61
63
  const server = new Server({ name: "okffs", version }, { capabilities: { tools: {}, prompts: {} }, instructions: SERVER_INSTRUCTIONS });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,25 @@ export declare const inputSchema: z.ZodObject<{
11
11
  issue_number: number;
12
12
  hint?: string | undefined;
13
13
  }>;
14
+ /**
15
+ * Split a free-text hint into a git commit subject + optional body.
16
+ *
17
+ * - Subject: the first **non-blank** line, truncated to ~72 chars at a **word
18
+ * boundary** (never mid-word) — a single unbreakable word longer than the
19
+ * limit is the only case that gets a hard cut. Leading blank lines are skipped
20
+ * so a hint like "\nAdd X" doesn't produce an empty subject (#236).
21
+ * - Body: any lines after the subject line, plus whatever overflowed past the
22
+ * subject, joined as blank-line-separated paragraphs. `undefined` when the
23
+ * hint fits entirely in the subject, so a short single-line hint behaves
24
+ * exactly as before (subject only). (#228)
25
+ *
26
+ * A whitespace-only hint has no usable subject line and returns `{ subject: "" }`
27
+ * — the handler guards against that by treating a blank hint as absent (#236).
28
+ */
29
+ export declare function splitCommitMessage(hint: string): {
30
+ subject: string;
31
+ body?: string;
32
+ };
14
33
  export declare function handler(input: z.infer<typeof inputSchema>): Promise<{
15
34
  content: {
16
35
  type: "text";
@@ -1 +1 @@
1
- {"version":3,"file":"commit_and_update.d.ts","sourceRoot":"","sources":["../../src/tools/commit_and_update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,IAAI,sBAAsB,CAAC;AACxC,eAAO,MAAM,WAAW,yLACgK,CAAC;AAEzL,eAAO,MAAM,WAAW;;;;;;;;;EAGtB,CAAC;AAEH,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GAyE/D"}
1
+ {"version":3,"file":"commit_and_update.d.ts","sourceRoot":"","sources":["../../src/tools/commit_and_update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,IAAI,sBAAsB,CAAC;AACxC,eAAO,MAAM,WAAW,yLACgK,CAAC;AAEzL,eAAO,MAAM,WAAW;;;;;;;;;EAGtB,CAAC;AAIH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CA0BnF;AAED,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GAmF/D"}
@@ -7,6 +7,49 @@ export const inputSchema = z.object({
7
7
  issue_number: z.number().int().positive().describe("The issue number this work is against"),
8
8
  hint: z.string().optional().describe("Short description of what was done — used to build the commit message and issue comment"),
9
9
  });
10
+ const SUBJECT_MAX = 72;
11
+ /**
12
+ * Split a free-text hint into a git commit subject + optional body.
13
+ *
14
+ * - Subject: the first **non-blank** line, truncated to ~72 chars at a **word
15
+ * boundary** (never mid-word) — a single unbreakable word longer than the
16
+ * limit is the only case that gets a hard cut. Leading blank lines are skipped
17
+ * so a hint like "\nAdd X" doesn't produce an empty subject (#236).
18
+ * - Body: any lines after the subject line, plus whatever overflowed past the
19
+ * subject, joined as blank-line-separated paragraphs. `undefined` when the
20
+ * hint fits entirely in the subject, so a short single-line hint behaves
21
+ * exactly as before (subject only). (#228)
22
+ *
23
+ * A whitespace-only hint has no usable subject line and returns `{ subject: "" }`
24
+ * — the handler guards against that by treating a blank hint as absent (#236).
25
+ */
26
+ export function splitCommitMessage(hint) {
27
+ const lines = hint.split("\n");
28
+ // Take the subject from the first non-blank line, not lines[0], so leading
29
+ // blank lines don't yield an empty subject.
30
+ const firstIdx = lines.findIndex((l) => l.trim() !== "");
31
+ if (firstIdx === -1)
32
+ return { subject: "" };
33
+ const firstLine = lines[firstIdx].trim();
34
+ const rest = lines.slice(firstIdx + 1).join("\n").trim();
35
+ let subject = firstLine;
36
+ let overflow = "";
37
+ if (firstLine.length > SUBJECT_MAX) {
38
+ const slice = firstLine.slice(0, SUBJECT_MAX);
39
+ const lastSpace = slice.lastIndexOf(" ");
40
+ if (lastSpace > 0) {
41
+ subject = firstLine.slice(0, lastSpace).trimEnd();
42
+ overflow = firstLine.slice(lastSpace + 1).trim();
43
+ }
44
+ else {
45
+ // A single word longer than the limit — no boundary to break on.
46
+ subject = slice;
47
+ overflow = firstLine.slice(SUBJECT_MAX).trim();
48
+ }
49
+ }
50
+ const body = [overflow, rest].filter(Boolean).join("\n\n");
51
+ return body ? { subject, body } : { subject };
52
+ }
10
53
  export async function handler(input) {
11
54
  const issue = await getIssue(input.issue_number);
12
55
  const branchName = extractBranchFromBody(issue.body);
@@ -18,12 +61,16 @@ export async function handler(input) {
18
61
  catch {
19
62
  changedFiles = [];
20
63
  }
21
- const hintText = input.hint ?? "";
64
+ // Trim so a whitespace-only hint (e.g. " ") counts as absent — otherwise it
65
+ // is truthy and yields an empty commit subject (#236).
66
+ const hintText = (input.hint ?? "").trim();
22
67
  const filesText = changedFiles.length > 0 ? changedFiles.join(", ") : "various files";
23
- // Build the commit message from the hint when provided, else the file list.
24
- const commitMessage = hintText
25
- ? hintText.slice(0, 72)
26
- : `chore: update ${filesText.slice(0, 60)}`;
68
+ // Build the commit subject (and optional body) from the hint when provided,
69
+ // else the file list. A long/multi-line hint is split into a word-boundary
70
+ // subject plus a body rather than blindly sliced mid-word at 72 chars (#228).
71
+ const { subject: commitMessage, body: commitBody } = hintText
72
+ ? splitCommitMessage(hintText)
73
+ : { subject: `chore: update ${filesText.slice(0, 60)}`, body: undefined };
27
74
  // Stage, commit, and push on the issue branch. Arguments are passed as an
28
75
  // array (no shell), so the hint and branch name can't be interpreted as
29
76
  // shell commands. The caller's original branch is restored afterward.
@@ -34,7 +81,13 @@ export async function handler(input) {
34
81
  git(["checkout", branchName]);
35
82
  }
36
83
  git(["add", "-A"]);
37
- git(["commit", "-m", commitMessage]);
84
+ const commitArgs = ["commit", "-m", commitMessage];
85
+ if (commitBody) {
86
+ // A second -m yields a native subject + body (blank-line separated),
87
+ // still passing every arg as an array (no shell).
88
+ commitArgs.push("-m", commitBody);
89
+ }
90
+ git(commitArgs);
38
91
  if (branchName) {
39
92
  git(["push", "origin", branchName]);
40
93
  }
@@ -1 +1 @@
1
- {"version":3,"file":"commit_and_update.js","sourceRoot":"","sources":["../../src/tools/commit_and_update.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commit_and_update.js","sourceRoot":"","sources":["../../src/tools/commit_and_update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ export declare const name = "fix_into_base";
3
+ export declare const description: string;
4
+ export declare const inputSchema: z.ZodObject<{
5
+ head: z.ZodOptional<z.ZodString>;
6
+ base: z.ZodOptional<z.ZodString>;
7
+ summary: z.ZodOptional<z.ZodString>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ summary?: string | undefined;
10
+ head?: string | undefined;
11
+ base?: string | undefined;
12
+ }, {
13
+ summary?: string | undefined;
14
+ head?: string | undefined;
15
+ base?: string | undefined;
16
+ }>;
17
+ export declare function handler(input: z.infer<typeof inputSchema>): Promise<{
18
+ content: {
19
+ type: "text";
20
+ text: string;
21
+ }[];
22
+ }>;
23
+ //# sourceMappingURL=fix_into_base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix_into_base.d.ts","sourceRoot":"","sources":["../../src/tools/fix_into_base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,eAAO,MAAM,IAAI,kBAAkB,CAAC;AAEpC,eAAO,MAAM,WAAW,QAI4e,CAAC;AAErgB,eAAO,MAAM,WAAW;;;;;;;;;;;;EAatB,CAAC;AAIH,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GA4F/D"}
@@ -0,0 +1,110 @@
1
+ import { z } from "zod";
2
+ import { getDefaultBranch, getBranchCommits, createPullRequest, getOpenPullRequestForBranch, updatePullRequest, } from "../github.js";
3
+ import { git, currentBranch } from "../git.js";
4
+ import { config } from "../config.js";
5
+ import { addIssueToProject, getProjectMetadata, setProjectFieldValue } from "../projects.js";
6
+ import { handler as mergePullRequest } from "./merge_pull_request.js";
7
+ export const name = "fix_into_base";
8
+ export const description = "Open (and, when opted in, merge) an ISSUE-LESS fix PR into the base branch (e.g. develop) — the mirror of promote_branch, which does the base→protected promotion. " +
9
+ "Use this for a small fix that doesn't warrant its own issue (e.g. review-comment cleanups) instead of dropping to raw `gh pr create` + `gh pr merge`: it is deliberately issue-less (no issue lookup, no Closes #N, no **Branch:** line required), authenticates with okffs's token, and — when the board is enabled — adds the PR to the Projects v2 board. " +
10
+ "head defaults to the current branch; base defaults to OKFFS_BASE_BRANCH (or the repo default). It NEVER targets OKFFS_PROTECTED_BRANCH — that stays promote_branch + a manual, user-driven merge. " +
11
+ "Opening the PR is always safe and unconditional. The merge is then attempted under the SAME gates and opt-in as merge_pull_request: it only merges when OKFFS_AUTO_MERGE_BASE=true, OKFFS_PROTECTED_BRANCH is set, and the PR is green (all checks pass), conflict-free, not blocked/behind, and has every review thread resolved — using OKFFS_BASE_MERGE_METHOD. If merge is off or a gate isn't met, the PR is left open with an actionable reason (re-run once it's green, or merge with merge_pull_request({ pr_number })).";
12
+ export const inputSchema = z.object({
13
+ head: z
14
+ .string()
15
+ .optional()
16
+ .describe("Branch to open the fix PR FROM (the PR head). Defaults to the current branch."),
17
+ base: z
18
+ .string()
19
+ .optional()
20
+ .describe("Branch to open the fix PR INTO (the PR base). Defaults to OKFFS_BASE_BRANCH, else the repo default. Never OKFFS_PROTECTED_BRANCH."),
21
+ summary: z
22
+ .string()
23
+ .optional()
24
+ .describe("Optional summary for the PR body. When omitted, the body lists the commits being landed."),
25
+ });
26
+ const text = (t) => ({ content: [{ type: "text", text: t }] });
27
+ export async function handler(input) {
28
+ // head defaults to the checked-out branch — this tool lands the work you're on.
29
+ const head = input.head ?? currentBranch() ?? undefined;
30
+ if (!head) {
31
+ return text("Could not determine the head branch to land — pass an explicit `head`.");
32
+ }
33
+ // base defaults to the base tier (OKFFS_BASE_BRANCH or the repo default).
34
+ const base = input.base ?? (await getDefaultBranch());
35
+ if (head === base) {
36
+ return text(`Nothing to land — head and base are both \`${base}\`. Check out the fix branch first, or pass a distinct \`head\`.`);
37
+ }
38
+ // This tool is base-tier only. Promoting into the protected branch is
39
+ // promote_branch's job (open) + a manual merge — never here.
40
+ if (config.protectedBranch && base === config.protectedBranch) {
41
+ return text(`[okffs] Refusing: \`${base}\` is OKFFS_PROTECTED_BRANCH. fix_into_base only lands into the base tier — use promote_branch to open a PR into the protected branch, then merge it yourself.`);
42
+ }
43
+ // Push the head so GitHub has the branch, then confirm it diverges from base.
44
+ try {
45
+ git(["push", "origin", head]);
46
+ }
47
+ catch (err) {
48
+ return text(`[okffs] Could not push \`${head}\` to origin: ${err instanceof Error ? err.message : String(err)}`);
49
+ }
50
+ const commits = await getBranchCommits(head, base);
51
+ if (commits.length === 0) {
52
+ return text(`Nothing to land — \`${head}\` has no commits ahead of \`${base}\`. Commit your fix first (e.g. commit_and_update).`);
53
+ }
54
+ const title = `Fix into ${base}: ${head}`;
55
+ const changes = commits.map((c) => `- ${c.commit.message.split("\n")[0]}`).join("\n");
56
+ const body = [
57
+ input.summary ?? `Issue-less fix PR from \`${head}\` into \`${base}\`. No \`Closes #N\` — this is a standalone fix, not an issue.`,
58
+ ``,
59
+ `## Landing (${commits.length} commit${commits.length === 1 ? "" : "s"})`,
60
+ changes,
61
+ ].join("\n");
62
+ // Reuse an already-open PR for this head→base rather than erroring (GitHub
63
+ // permits only one open PR per head→base pair).
64
+ const existing = await getOpenPullRequestForBranch(head, base);
65
+ let pr;
66
+ let action;
67
+ if (existing) {
68
+ await updatePullRequest(existing.number, { title, body });
69
+ pr = { number: existing.number, html_url: existing.html_url, node_id: existing.node_id };
70
+ action = "updated";
71
+ }
72
+ else {
73
+ pr = await createPullRequest(title, body, head, base);
74
+ action = "created";
75
+ }
76
+ const notes = [];
77
+ // Best-effort board placement — mirror promote_branch: a PR node id boards the
78
+ // PR itself as a first-class card. Never blocks the PR/merge.
79
+ if (config.projectEnabled) {
80
+ try {
81
+ const itemId = await addIssueToProject(pr.node_id);
82
+ notes.push("Added the PR to the project board.");
83
+ if (config.promotionStatus) {
84
+ const meta = await getProjectMetadata();
85
+ const optionId = meta.statusFieldId ? meta.statusOptions.get(config.promotionStatus) : undefined;
86
+ if (meta.statusFieldId && optionId) {
87
+ await setProjectFieldValue(itemId, meta.statusFieldId, optionId);
88
+ notes.push(`Moved the card to "${config.promotionStatus}".`);
89
+ }
90
+ }
91
+ }
92
+ catch (err) {
93
+ const msg = err instanceof Error ? err.message : String(err);
94
+ console.warn(`[okffs] Failed to add fix PR #${pr.number} to the board:`, msg);
95
+ notes.push(`⚠️ Could not add the PR to the board: ${msg}`);
96
+ }
97
+ }
98
+ const lines = [`Fix PR #${pr.number} ${action}: ${pr.html_url}`];
99
+ if (notes.length > 0)
100
+ lines.push(...notes);
101
+ // Merge step: reuse merge_pull_request's gating verbatim via its pr_number
102
+ // mode. It self-gates on OKFFS_AUTO_MERGE_BASE and every green check, so when
103
+ // merge is off or the PR isn't green it declines with an actionable reason and
104
+ // the PR stays open (re-run once green, or call merge_pull_request directly).
105
+ const mergeResult = await mergePullRequest({ pr_number: pr.number });
106
+ const mergeText = mergeResult.content.map((c) => c.text).join("\n");
107
+ lines.push("", `— Merge attempt —`, mergeText);
108
+ return text(lines.join("\n"));
109
+ }
110
+ //# sourceMappingURL=fix_into_base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix_into_base.js","sourceRoot":"","sources":["../../src/tools/fix_into_base.ts"],"names":[],"mappings":"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"}
@@ -2,11 +2,14 @@ import { z } from "zod";
2
2
  export declare const name = "merge_pull_request";
3
3
  export declare const description: string;
4
4
  export declare const inputSchema: z.ZodObject<{
5
- issue_number: z.ZodNumber;
5
+ issue_number: z.ZodOptional<z.ZodNumber>;
6
+ pr_number: z.ZodOptional<z.ZodNumber>;
6
7
  }, "strip", z.ZodTypeAny, {
7
- issue_number: number;
8
+ issue_number?: number | undefined;
9
+ pr_number?: number | undefined;
8
10
  }, {
9
- issue_number: number;
11
+ issue_number?: number | undefined;
12
+ pr_number?: number | undefined;
10
13
  }>;
11
14
  export declare function handler(input: z.infer<typeof inputSchema>): Promise<{
12
15
  content: {
@@ -1 +1 @@
1
- {"version":3,"file":"merge_pull_request.d.ts","sourceRoot":"","sources":["../../src/tools/merge_pull_request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkBxB,eAAO,MAAM,IAAI,uBAAuB,CAAC;AAEzC,eAAO,MAAM,WAAW,QAK+R,CAAC;AAExT,eAAO,MAAM,WAAW;;;;;;EAEtB,CAAC;AAgBH,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GAgJ/D"}
1
+ {"version":3,"file":"merge_pull_request.d.ts","sourceRoot":"","sources":["../../src/tools/merge_pull_request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkBxB,eAAO,MAAM,IAAI,uBAAuB,CAAC;AAEzC,eAAO,MAAM,WAAW,QAM4S,CAAC;AAErU,eAAO,MAAM,WAAW;;;;;;;;;EAiBtB,CAAC;AAgBH,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GAyK/D"}
@@ -2,13 +2,25 @@ import { z } from "zod";
2
2
  import { getIssue, extractBranchFromBody, getDefaultBranch, getRepoDefaultBranch, getOpenPullRequestForBranch, getPullRequest, getCombinedStatus, getCheckRuns, getPullRequestReview, mergePullRequest, closeIssue, addIssueComment, } from "../github.js";
3
3
  import { config } from "../config.js";
4
4
  export const name = "merge_pull_request";
5
- export const description = "Autonomously merge a GREEN, review-resolved issue PR into the BASE branch (e.g. develop) using the configured per-tier merge method (OKFFS_BASE_MERGE_METHOD, default squash). " +
5
+ export const description = "Autonomously merge a GREEN, review-resolved PR into the BASE branch (e.g. develop) using the configured per-tier merge method (OKFFS_BASE_MERGE_METHOD, default squash). " +
6
+ "Provide EXACTLY ONE of: issue_number (merge the issue's PR and complete the loop — comment on the issue and close it when the base isn't the repo default) OR pr_number (merge-only mode for an ISSUE-LESS fix PR into the base branch — skips the issue lookup, comment, and close, and needs no **Branch:** line). " +
6
7
  "This is the ONE okffs action that merges — every other tool only opens PRs and hands back. It is therefore heavily gated and OPT-IN: it does nothing unless OKFFS_AUTO_MERGE_BASE=true. " +
7
8
  "It NEVER merges OKFFS_PROTECTED_BRANCH (e.g. main) — that stays a manual, user-driven merge/tag — and refuses entirely if OKFFS_PROTECTED_BRANCH is unset, so it can't merge into an unnamed protected branch. " +
8
9
  "Before merging it independently verifies (not merely trusting branch-protection rules): the PR targets the base tier and not the protected branch; it is open, not a draft, and free of conflicts; all commit statuses AND check runs on the head are green (no failing or pending checks); the PR is not blocked by a required gate; and every review thread is resolved. Any unmet gate → it refuses with an actionable reason and does not merge. " +
9
- "On success it merges, comments on the issue, and — when the base isn't the repo default (so GitHub's Closes #N won't auto-close) — closes the issue to complete the loop. Use for landing small review-fix / feature PRs into develop without a human merge; the develop→main promotion always stays with the user.";
10
+ "On success (issue mode) it merges, comments on the issue, and — when the base isn't the repo default (so GitHub's Closes #N won't auto-close) — closes the issue to complete the loop. Use for landing small review-fix / feature PRs into develop without a human merge; the develop→main promotion always stays with the user.";
10
11
  export const inputSchema = z.object({
11
- issue_number: z.number().int().positive().describe("The issue whose PR (into the base branch) should be merged"),
12
+ issue_number: z
13
+ .number()
14
+ .int()
15
+ .positive()
16
+ .optional()
17
+ .describe("The issue whose PR (into the base branch) should be merged — completes the loop (issue comment + close). Provide this OR pr_number, not both."),
18
+ pr_number: z
19
+ .number()
20
+ .int()
21
+ .positive()
22
+ .optional()
23
+ .describe("Merge-only mode: merge an ISSUE-LESS fix PR into the base branch directly by PR number — no issue comment/close and no **Branch:** line required, but all the same green gates apply. Provide this OR issue_number, not both."),
12
24
  });
13
25
  const text = (t) => ({ content: [{ type: "text", text: t }] });
14
26
  // Poll the PR until GitHub finishes computing `mergeable` (it returns null right
@@ -23,6 +35,14 @@ async function getPullRequestWhenComputed(prNumber) {
23
35
  return detail;
24
36
  }
25
37
  export async function handler(input) {
38
+ // ── Gate 0: exactly one of issue_number / pr_number ───────────────────────
39
+ const hasIssue = input.issue_number !== undefined;
40
+ const hasPr = input.pr_number !== undefined;
41
+ if (hasIssue === hasPr) {
42
+ return text("[okffs] Provide exactly one of issue_number (merge an issue's PR and complete the loop — comment + close) " +
43
+ "or pr_number (merge-only mode for an issue-less fix PR into the base branch). " +
44
+ (hasIssue ? "You passed both." : "You passed neither."));
45
+ }
26
46
  // ── Gate 1: opt-in ────────────────────────────────────────────────────────
27
47
  if (!config.autoMergeBase) {
28
48
  return text("Autonomous merge is off. okffs will not merge a PR unless OKFFS_AUTO_MERGE_BASE=true — set it to opt in " +
@@ -33,23 +53,32 @@ export async function handler(input) {
33
53
  return text("[okffs] Refusing to merge: OKFFS_PROTECTED_BRANCH is unset. okffs must know which branch it may never merge " +
34
54
  "into before it merges anything — set OKFFS_PROTECTED_BRANCH (e.g. main) so autonomous merges can be confined to the base tier.");
35
55
  }
36
- const issue = await getIssue(input.issue_number);
37
- const branch = extractBranchFromBody(issue.body);
38
- if (!branch) {
39
- return text(`Issue #${input.issue_number} has no associated branch (no **Branch:** line), so there's no PR to merge.`);
40
- }
41
56
  const baseTier = await getDefaultBranch(); // OKFFS_BASE_BRANCH or the repo default
42
57
  // Misconfiguration guard: the base tier must not itself be the protected branch.
43
58
  if (baseTier === config.protectedBranch) {
44
59
  return text(`[okffs] Refusing to merge: the base branch (\`${baseTier}\`) is the same as OKFFS_PROTECTED_BRANCH. ` +
45
60
  "okffs never autonomously merges the protected branch — set OKFFS_BASE_BRANCH to a distinct base tier (e.g. develop).");
46
61
  }
47
- const prRef = await getOpenPullRequestForBranch(branch, baseTier);
48
- if (!prRef) {
49
- return text(`No open PR found for branch \`${branch}\` into \`${baseTier}\`. Open one with create_pull_request first.`);
62
+ // Resolve the PR to merge. Issue mode reads the issue's **Branch:** line and
63
+ // finds its open PR into the base tier; merge-only mode takes the PR directly.
64
+ let prNumber;
65
+ if (hasIssue) {
66
+ const issue = await getIssue(input.issue_number);
67
+ const branch = extractBranchFromBody(issue.body);
68
+ if (!branch) {
69
+ return text(`Issue #${input.issue_number} has no associated branch (no **Branch:** line), so there's no PR to merge.`);
70
+ }
71
+ const prRef = await getOpenPullRequestForBranch(branch, baseTier);
72
+ if (!prRef) {
73
+ return text(`No open PR found for branch \`${branch}\` into \`${baseTier}\`. Open one with create_pull_request first.`);
74
+ }
75
+ prNumber = prRef.number;
50
76
  }
51
- const pr = await getPullRequestWhenComputed(prRef.number);
52
- const label = `PR #${pr.number} (${branch} → ${pr.base.ref})`;
77
+ else {
78
+ prNumber = input.pr_number;
79
+ }
80
+ const pr = await getPullRequestWhenComputed(prNumber);
81
+ const label = `PR #${pr.number} (${pr.head.ref} → ${pr.base.ref})`;
53
82
  // ── Gate 3: target is the base tier, never the protected branch ───────────
54
83
  if (pr.base.ref === config.protectedBranch) {
55
84
  return text(`[okffs] Refusing to merge ${label}: it targets the protected branch \`${config.protectedBranch}\`. ` +
@@ -114,25 +143,30 @@ export async function handler(input) {
114
143
  return text(`[okffs] Merge of ${label} failed at the GitHub API: ${err instanceof Error ? err.message : String(err)}`);
115
144
  }
116
145
  const lines = [`✅ Merged ${label} into \`${baseTier}\` via ${method}.`];
146
+ // Merge-only mode: there's no issue to comment on or close — we're done.
147
+ if (!hasIssue) {
148
+ return text(lines.join("\n"));
149
+ }
150
+ const issueNumber = input.issue_number;
117
151
  // Complete the loop: `Closes #N` only auto-closes when merging into the repo
118
152
  // default. For a non-default base tier (e.g. develop) the issue stays open, so
119
153
  // close it here. Non-fatal — the merge already succeeded.
120
154
  const repoDefault = await getRepoDefaultBranch();
121
155
  if (baseTier !== repoDefault) {
122
156
  try {
123
- await closeIssue(input.issue_number);
124
- lines.push(`Closed #${input.issue_number} (merging into \`${baseTier}\` doesn't trigger GitHub's auto-close).`);
157
+ await closeIssue(issueNumber);
158
+ lines.push(`Closed #${issueNumber} (merging into \`${baseTier}\` doesn't trigger GitHub's auto-close).`);
125
159
  }
126
160
  catch (err) {
127
- lines.push(`⚠ Could not auto-close #${input.issue_number} — close it manually. (${err instanceof Error ? err.message : String(err)})`);
161
+ lines.push(`⚠ Could not auto-close #${issueNumber} — close it manually. (${err instanceof Error ? err.message : String(err)})`);
128
162
  }
129
163
  }
130
164
  else {
131
- lines.push(`GitHub will auto-close #${input.issue_number} via \`Closes #${input.issue_number}\` (merged into the default branch).`);
165
+ lines.push(`GitHub will auto-close #${issueNumber} via \`Closes #${issueNumber}\` (merged into the default branch).`);
132
166
  }
133
167
  // Log the merge on the issue for an audit trail.
134
168
  try {
135
- await addIssueComment(input.issue_number, lines.join("\n"));
169
+ await addIssueComment(issueNumber, lines.join("\n"));
136
170
  }
137
171
  catch {
138
172
  /* non-fatal: the response still reports the outcome */
@@ -1 +1 @@
1
- {"version":3,"file":"merge_pull_request.js","sourceRoot":"","sources":["../../src/tools/merge_pull_request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,QAAQ,EACR,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,2BAA2B,EAC3B,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,eAAe,GAEhB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,CAAC,MAAM,IAAI,GAAG,oBAAoB,CAAC;AAEzC,MAAM,CAAC,MAAM,WAAW,GACtB,iLAAiL;IACjL,0LAA0L;IAC1L,iNAAiN;IACjN,ubAAub;IACvb,qTAAqT,CAAC;AAExT,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;CACjH,CAAC,CAAC;AAEH,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAEhF,iFAAiF;AACjF,gFAAgF;AAChF,4EAA4E;AAC5E,KAAK,UAAU,0BAA0B,CAAC,QAAgB;IACxD,IAAI,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACxD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC7C,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAkC;IAC9D,6EAA6E;IAC7E,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;QAC1B,OAAO,IAAI,CACT,0GAA0G;YACxG,mFAAmF,CACtF,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;QAC5B,OAAO,IAAI,CACT,8GAA8G;YAC5G,gIAAgI,CACnI,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC,UAAU,KAAK,CAAC,YAAY,6EAA6E,CAAC,CAAC;IACzH,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,gBAAgB,EAAE,CAAC,CAAC,wCAAwC;IAEnF,iFAAiF;IACjF,IAAI,QAAQ,KAAK,MAAM,CAAC,eAAe,EAAE,CAAC;QACxC,OAAO,IAAI,CACT,iDAAiD,QAAQ,6CAA6C;YACpG,sHAAsH,CACzH,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,iCAAiC,MAAM,aAAa,QAAQ,8CAA8C,CAAC,CAAC;IAC1H,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,0BAA0B,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,OAAO,EAAE,CAAC,MAAM,KAAK,MAAM,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;IAE9D,6EAA6E;IAC7E,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3C,OAAO,IAAI,CACT,6BAA6B,KAAK,uCAAuC,MAAM,CAAC,eAAe,MAAM;YACnG,6HAA6H,CAChI,CAAC;IACJ,CAAC;IACD,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CACT,6BAA6B,KAAK,kBAAkB,EAAE,CAAC,IAAI,CAAC,GAAG,2BAA2B,QAAQ,MAAM;YACtG,6DAA6D,CAChE,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,IAAI,EAAE,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC,GAAG,KAAK,qCAAqC,CAAC,CAAC;IAC1E,IAAI,EAAE,CAAC,KAAK,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC,6BAA6B,KAAK,eAAe,EAAE,CAAC,KAAK,aAAa,CAAC,CAAC;IAC7G,IAAI,EAAE,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,6BAA6B,KAAK,qFAAqF,CAAC,CAAC;IAEnJ,6EAA6E;IAC7E,IAAI,EAAE,CAAC,SAAS,KAAK,KAAK,IAAI,EAAE,CAAC,eAAe,KAAK,OAAO,EAAE,CAAC;QAC7D,OAAO,IAAI,CAAC,6BAA6B,KAAK,mCAAmC,QAAQ,+BAA+B,CAAC,CAAC;IAC5H,CAAC;IACD,IAAI,EAAE,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC,6BAA6B,KAAK,4BAA4B,QAAQ,mDAAmD,CAAC,CAAC;IACzI,CAAC;IACD,IAAI,EAAE,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,IAAI,CACT,6BAA6B,KAAK,0GAA0G,CAC7I,CAAC;IACJ,CAAC;IACD,IAAI,EAAE,CAAC,SAAS,KAAK,IAAI,IAAI,EAAE,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QAC9D,OAAO,IAAI,CAAC,6BAA6B,KAAK,yEAAyE,CAAC,CAAC;IAC3H,CAAC;IAED,+EAA+E;IAC/E,8EAA8E;IAC9E,8EAA8E;IAC9E,2BAA2B;IAC3B,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC3C,iBAAiB,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;QAC9B,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;KAC1B,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ;SAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC;SACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;IAE3C,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU;SAChC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;SAC1G,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAEnF,MAAM,OAAO,GAAG,CAAC,GAAG,WAAW,EAAE,GAAG,SAAS,CAAC,CAAC;IAC/C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CACT,6BAA6B,KAAK,4CAA4C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YAClG,kDAAkD,CACrD,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACxF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CACT,6BAA6B,KAAK,KAAK,UAAU,CAAC,MAAM,sCAAsC;YAC5F,0EAA0E,CAC7E,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC;IACtC,IAAI,CAAC;QACH,MAAM,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,IAAI,CAAC,oBAAoB,KAAK,8BAA8B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzH,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,YAAY,KAAK,WAAW,QAAQ,UAAU,MAAM,GAAG,CAAC,CAAC;IAExE,6EAA6E;IAC7E,+EAA+E;IAC/E,0DAA0D;IAC1D,MAAM,WAAW,GAAG,MAAM,oBAAoB,EAAE,CAAC;IACjD,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,YAAY,oBAAoB,QAAQ,0CAA0C,CAAC,CAAC;QAClH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,2BAA2B,KAAK,CAAC,YAAY,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzI,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,2BAA2B,KAAK,CAAC,YAAY,kBAAkB,KAAK,CAAC,YAAY,sCAAsC,CAAC,CAAC;IACtI,CAAC;IAED,iDAAiD;IACjD,IAAI,CAAC;QACH,MAAM,eAAe,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;IACzD,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"merge_pull_request.js","sourceRoot":"","sources":["../../src/tools/merge_pull_request.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,21 @@
1
1
  import { z } from "zod";
2
2
  export declare const name = "reply_to_review_comment";
3
- export declare const description = "Reply to an inline PR review comment thread. Pass the pull request number, the comment id (from list_pr_review_comments), and the reply body. Use after addressing a review comment to record what was changed (e.g. reference the fix commit).";
3
+ export declare const description: string;
4
4
  export declare const inputSchema: z.ZodObject<{
5
5
  pr_number: z.ZodNumber;
6
6
  comment_id: z.ZodNumber;
7
7
  body: z.ZodString;
8
+ resolve: z.ZodOptional<z.ZodBoolean>;
8
9
  }, "strip", z.ZodTypeAny, {
9
10
  body: string;
10
11
  pr_number: number;
11
12
  comment_id: number;
13
+ resolve?: boolean | undefined;
12
14
  }, {
13
15
  body: string;
14
16
  pr_number: number;
15
17
  comment_id: number;
18
+ resolve?: boolean | undefined;
16
19
  }>;
17
20
  export declare function handler(input: z.infer<typeof inputSchema>): Promise<{
18
21
  content: {
@@ -1 +1 @@
1
- {"version":3,"file":"reply_to_review_comment.d.ts","sourceRoot":"","sources":["../../src/tools/reply_to_review_comment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,IAAI,4BAA4B,CAAC;AAE9C,eAAO,MAAM,WAAW,oPAC2N,CAAC;AAEpP,eAAO,MAAM,WAAW;;;;;;;;;;;;EAQtB,CAAC;AAEH,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GAU/D"}
1
+ {"version":3,"file":"reply_to_review_comment.d.ts","sourceRoot":"","sources":["../../src/tools/reply_to_review_comment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,IAAI,4BAA4B,CAAC;AAE9C,eAAO,MAAM,WAAW,QAE0jB,CAAC;AAEnlB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;EActB,CAAC;AAEH,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GAmC/D"}
@@ -1,7 +1,9 @@
1
1
  import { z } from "zod";
2
- import { replyToReviewComment } from "../github.js";
2
+ import { replyToReviewComment, getPullRequestReview, resolveReviewThread } from "../github.js";
3
+ import { config } from "../config.js";
3
4
  export const name = "reply_to_review_comment";
4
- export const description = "Reply to an inline PR review comment thread. Pass the pull request number, the comment id (from list_pr_review_comments), and the reply body. Use after addressing a review comment to record what was changed (e.g. reference the fix commit).";
5
+ export const description = "Reply to an inline PR review comment thread. Pass the pull request number, the comment id (from list_pr_review_comments), and the reply body. Use after addressing a review comment to record what was changed (e.g. reference the fix commit). " +
6
+ "IMPORTANT: a reply does NOT resolve the thread — the thread stays open until you resolve it. The full loop is list_pr_review_comments → reply_to_review_comment → resolve_review_thread; even when OKFFS_RESOLVE_THREADS=true, resolving is a separate, explicit act (this tool leaves the thread open unless you ask it to resolve). To reply and resolve an addressed thread in one call, pass resolve: true (still gated by OKFFS_RESOLVE_THREADS). Prefer this tool over raw `gh api .../replies`, which skips the resolve path and silently leaves threads unresolved despite OKFFS_RESOLVE_THREADS=true.";
5
7
  export const inputSchema = z.object({
6
8
  pr_number: z.number().int().positive().describe("The pull request number"),
7
9
  comment_id: z
@@ -10,16 +12,43 @@ export const inputSchema = z.object({
10
12
  .positive()
11
13
  .describe("The review comment id to reply to (from list_pr_review_comments)"),
12
14
  body: z.string().describe("Reply body"),
15
+ resolve: z
16
+ .boolean()
17
+ .optional()
18
+ .describe("When true, also resolve this comment's thread after replying (reply + resolve in one call). Honours the OKFFS_RESOLVE_THREADS gate: when that env var isn't 'true', the reply is still posted but the thread is left open and the response says so. Use ONLY when the reply signals the thread is addressed — not when the reply asks a question or pushes back, which should stay open."),
13
19
  });
14
20
  export async function handler(input) {
15
21
  const reply = await replyToReviewComment(input.pr_number, input.comment_id, input.body);
16
- return {
17
- content: [
18
- {
19
- type: "text",
20
- text: `Replied to comment #${input.comment_id} on PR #${input.pr_number}: ${reply.html_url}`,
21
- },
22
- ],
23
- };
22
+ const lines = [
23
+ `Replied to comment #${input.comment_id} on PR #${input.pr_number}: ${reply.html_url}`,
24
+ ];
25
+ if (input.resolve) {
26
+ if (!config.resolveThreads) {
27
+ lines.push("Not resolving the thread — OKFFS_RESOLVE_THREADS is not enabled, so the reply is posted but the thread is left open for you to resolve on GitHub. Set OKFFS_RESOLVE_THREADS=true to allow reply+resolve in one call.");
28
+ }
29
+ else {
30
+ try {
31
+ // The reply endpoint works off a comment id; resolving needs the thread
32
+ // node id, so map comment → thread via the PR's review threads.
33
+ const { threads } = await getPullRequestReview(input.pr_number);
34
+ const thread = threads.find((t) => t.comments.some((c) => c.id === input.comment_id));
35
+ if (!thread) {
36
+ lines.push(`Could not find the thread for comment #${input.comment_id} to resolve — the reply was posted; resolve it manually if needed.`);
37
+ }
38
+ else if (thread.isResolved) {
39
+ lines.push(`Thread ${thread.id} was already resolved.`);
40
+ }
41
+ else {
42
+ await resolveReviewThread(thread.id);
43
+ lines.push(`Resolved thread ${thread.id}.`);
44
+ }
45
+ }
46
+ catch (err) {
47
+ const msg = err instanceof Error ? err.message : String(err);
48
+ lines.push(`Reply posted, but resolving the thread failed: ${msg}`);
49
+ }
50
+ }
51
+ }
52
+ return { content: [{ type: "text", text: lines.join("\n") }] };
24
53
  }
25
54
  //# sourceMappingURL=reply_to_review_comment.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reply_to_review_comment.js","sourceRoot":"","sources":["../../src/tools/reply_to_review_comment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,CAAC,MAAM,IAAI,GAAG,yBAAyB,CAAC;AAE9C,MAAM,CAAC,MAAM,WAAW,GACtB,iPAAiP,CAAC;AAEpP,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IAC1E,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,QAAQ,CAAC,kEAAkE,CAAC;IAC/E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;CACxC,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAkC;IAC9D,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACxF,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,uBAAuB,KAAK,CAAC,UAAU,WAAW,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,QAAQ,EAAE;aAC7F;SACF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"reply_to_review_comment.js","sourceRoot":"","sources":["../../src/tools/reply_to_review_comment.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neturely/okffs",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "mcpName": "io.github.neturely/okffs",
5
5
  "description": "MCP server that connects Claude Code to GitHub — create and manage issues and branches without leaving your editor.",
6
6
  "type": "module",