@neturely/okffs 0.7.0 → 0.9.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 (66) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/README.md +15 -2
  3. package/dist/cli/banner.d.ts +17 -0
  4. package/dist/cli/banner.d.ts.map +1 -0
  5. package/dist/cli/banner.js +65 -0
  6. package/dist/cli/banner.js.map +1 -0
  7. package/dist/cli/env.d.ts +30 -0
  8. package/dist/cli/env.d.ts.map +1 -0
  9. package/dist/cli/env.js +171 -0
  10. package/dist/cli/env.js.map +1 -0
  11. package/dist/cli/index.d.ts +12 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +77 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/cli/manifest.d.ts +48 -0
  16. package/dist/cli/manifest.d.ts.map +1 -0
  17. package/dist/cli/manifest.js +303 -0
  18. package/dist/cli/manifest.js.map +1 -0
  19. package/dist/cli/probe.d.ts +32 -0
  20. package/dist/cli/probe.d.ts.map +1 -0
  21. package/dist/cli/probe.js +101 -0
  22. package/dist/cli/probe.js.map +1 -0
  23. package/dist/cli/sanity.d.ts +16 -0
  24. package/dist/cli/sanity.d.ts.map +1 -0
  25. package/dist/cli/sanity.js +99 -0
  26. package/dist/cli/sanity.js.map +1 -0
  27. package/dist/cli/setup.d.ts +2 -0
  28. package/dist/cli/setup.d.ts.map +1 -0
  29. package/dist/cli/setup.js +254 -0
  30. package/dist/cli/setup.js.map +1 -0
  31. package/dist/github.d.ts.map +1 -1
  32. package/dist/github.js +4 -2
  33. package/dist/github.js.map +1 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +19 -105
  36. package/dist/index.js.map +1 -1
  37. package/dist/prompts/setup.d.ts +18 -0
  38. package/dist/prompts/setup.d.ts.map +1 -0
  39. package/dist/prompts/setup.js +77 -0
  40. package/dist/prompts/setup.js.map +1 -0
  41. package/dist/server.d.ts +2 -0
  42. package/dist/server.d.ts.map +1 -0
  43. package/dist/server.js +166 -0
  44. package/dist/server.js.map +1 -0
  45. package/dist/tools/commit_and_update.d.ts +19 -0
  46. package/dist/tools/commit_and_update.d.ts.map +1 -1
  47. package/dist/tools/commit_and_update.js +59 -6
  48. package/dist/tools/commit_and_update.js.map +1 -1
  49. package/dist/tools/configure.d.ts +27 -0
  50. package/dist/tools/configure.d.ts.map +1 -0
  51. package/dist/tools/configure.js +91 -0
  52. package/dist/tools/configure.js.map +1 -0
  53. package/dist/tools/fix_into_base.d.ts +23 -0
  54. package/dist/tools/fix_into_base.d.ts.map +1 -0
  55. package/dist/tools/fix_into_base.js +110 -0
  56. package/dist/tools/fix_into_base.js.map +1 -0
  57. package/dist/tools/merge_pull_request.d.ts +6 -3
  58. package/dist/tools/merge_pull_request.d.ts.map +1 -1
  59. package/dist/tools/merge_pull_request.js +52 -18
  60. package/dist/tools/merge_pull_request.js.map +1 -1
  61. package/dist/tools/reply_to_review_comment.d.ts +4 -1
  62. package/dist/tools/reply_to_review_comment.d.ts.map +1 -1
  63. package/dist/tools/reply_to_review_comment.js +39 -10
  64. package/dist/tools/reply_to_review_comment.js.map +1 -1
  65. package/dist/tools/update_project_status.d.ts +2 -2
  66. package/package.json +6 -2
@@ -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":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,2BAA2B,EAC3B,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEtE,MAAM,CAAC,MAAM,IAAI,GAAG,eAAe,CAAC;AAEpC,MAAM,CAAC,MAAM,WAAW,GACtB,qKAAqK;IACrK,+VAA+V;IAC/V,oMAAoM;IACpM,kgBAAkgB,CAAC;AAErgB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,+EAA+E,CAAC;IAC5F,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,mIAAmI,CAAC;IAChJ,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,0FAA0F,CAAC;CACxG,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,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAkC;IAC9D,gFAAgF;IAChF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,aAAa,EAAE,IAAI,SAAS,CAAC;IACxD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC,wEAAwE,CAAC,CAAC;IACxF,CAAC;IAED,0EAA0E;IAC1E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAAC;IAEtD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,8CAA8C,IAAI,kEAAkE,CAAC,CAAC;IACpI,CAAC;IAED,sEAAsE;IACtE,6DAA6D;IAC7D,IAAI,MAAM,CAAC,eAAe,IAAI,IAAI,KAAK,MAAM,CAAC,eAAe,EAAE,CAAC;QAC9D,OAAO,IAAI,CACT,uBAAuB,IAAI,gKAAgK,CAC5L,CAAC;IACJ,CAAC;IAED,8EAA8E;IAC9E,IAAI,CAAC;QACH,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,IAAI,CAAC,4BAA4B,IAAI,iBAAiB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACnH,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,uBAAuB,IAAI,gCAAgC,IAAI,qDAAqD,CAAC,CAAC;IACpI,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,IAAI,KAAK,IAAI,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtF,MAAM,IAAI,GAAG;QACX,KAAK,CAAC,OAAO,IAAI,4BAA4B,IAAI,aAAa,IAAI,gEAAgE;QAClI,EAAE;QACF,eAAe,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QACzE,OAAO;KACR,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,2EAA2E;IAC3E,gDAAgD;IAChD,MAAM,QAAQ,GAAG,MAAM,2BAA2B,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/D,IAAI,EAAyD,CAAC;IAC9D,IAAI,MAAc,CAAC;IACnB,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,iBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;QACzF,MAAM,GAAG,SAAS,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,EAAE,GAAG,MAAM,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACtD,MAAM,GAAG,SAAS,CAAC;IACrB,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,+EAA+E;IAC/E,8DAA8D;IAC9D,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;YACjD,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;gBAC3B,MAAM,IAAI,GAAG,MAAM,kBAAkB,EAAE,CAAC;gBACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACjG,IAAI,IAAI,CAAC,aAAa,IAAI,QAAQ,EAAE,CAAC;oBACnC,MAAM,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;oBACjE,KAAK,CAAC,IAAI,CAAC,sBAAsB,MAAM,CAAC,eAAe,IAAI,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,CAAC,MAAM,gBAAgB,EAAE,GAAG,CAAC,CAAC;YAC9E,KAAK,CAAC,IAAI,CAAC,yCAAyC,GAAG,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC,MAAM,IAAI,MAAM,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IACjE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;IAE3C,2EAA2E;IAC3E,8EAA8E;IAC9E,+EAA+E;IAC/E,8EAA8E;IAC9E,MAAM,WAAW,GAAG,MAAM,gBAAgB,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,mBAAmB,EAAE,SAAS,CAAC,CAAC;IAE/C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,CAAC"}
@@ -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":"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"}
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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"}
@@ -5,10 +5,10 @@ export declare const inputSchema: z.ZodObject<{
5
5
  issue: z.ZodNumber;
6
6
  status: z.ZodEnum<["Backlog", "Ready", "In Progress", "Review"]>;
7
7
  }, "strip", z.ZodTypeAny, {
8
- status: "Backlog" | "Ready" | "In Progress" | "Review";
8
+ status: "Backlog" | "Review" | "Ready" | "In Progress";
9
9
  issue: number;
10
10
  }, {
11
- status: "Backlog" | "Ready" | "In Progress" | "Review";
11
+ status: "Backlog" | "Review" | "Ready" | "In Progress";
12
12
  issue: number;
13
13
  }>;
14
14
  export declare function handler(input: z.infer<typeof inputSchema>): Promise<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neturely/okffs",
3
- "version": "0.7.0",
3
+ "version": "0.9.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",
@@ -11,7 +11,7 @@
11
11
  "scripts": {
12
12
  "build": "tsc",
13
13
  "prepublishOnly": "npm run build",
14
- "postbuild": "node -e \"const fs=require('fs');const f='dist/index.js';const c=fs.readFileSync(f,'utf8');if(!c.startsWith('#!/usr/bin/env node'))fs.writeFileSync(f,'#!/usr/bin/env node\\n'+c);\" && chmod +x dist/index.js",
14
+ "postbuild": "node -e \"const fs=require('fs');for(const f of ['dist/index.js','dist/cli/index.js']){const c=fs.readFileSync(f,'utf8');if(!c.startsWith('#!/usr/bin/env node'))fs.writeFileSync(f,'#!/usr/bin/env node\\n'+c);}\" && chmod +x dist/index.js dist/cli/index.js",
15
15
  "dev": "node --env-file=.env --import tsx/esm src/index.ts",
16
16
  "start": "node --env-file=.env dist/index.js"
17
17
  },
@@ -35,7 +35,11 @@
35
35
  "publishConfig": {
36
36
  "access": "public"
37
37
  },
38
+ "engines": {
39
+ "node": ">=20.12.0"
40
+ },
38
41
  "dependencies": {
42
+ "@clack/prompts": "^1.7.0",
39
43
  "@modelcontextprotocol/sdk": "^1.12.0",
40
44
  "dotenv": "^17.4.2",
41
45
  "zod": "^3.23.8",