@neturely/okffs 0.5.2 → 0.7.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 +26 -1
- package/README.md +48 -12
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +56 -0
- package/dist/config.js.map +1 -1
- package/dist/git.d.ts +12 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +31 -0
- package/dist/git.js.map +1 -1
- package/dist/github.d.ts +59 -1
- package/dist/github.d.ts.map +1 -1
- package/dist/github.js +62 -5
- package/dist/github.js.map +1 -1
- package/dist/index.js +18 -6
- package/dist/index.js.map +1 -1
- package/dist/issue_types.d.ts +5 -0
- package/dist/issue_types.d.ts.map +1 -0
- package/dist/issue_types.js +65 -0
- package/dist/issue_types.js.map +1 -0
- package/dist/prompts/address_pr_review.d.ts.map +1 -1
- package/dist/prompts/address_pr_review.js +6 -4
- package/dist/prompts/address_pr_review.js.map +1 -1
- package/dist/tools/create_issue.d.ts +3 -0
- package/dist/tools/create_issue.d.ts.map +1 -1
- package/dist/tools/create_issue.js +51 -41
- package/dist/tools/create_issue.js.map +1 -1
- package/dist/tools/create_issues_from_list.d.ts +6 -1
- package/dist/tools/create_issues_from_list.d.ts.map +1 -1
- package/dist/tools/create_issues_from_list.js +14 -1
- package/dist/tools/create_issues_from_list.js.map +1 -1
- package/dist/tools/create_pull_request.d.ts +4 -4
- package/dist/tools/create_pull_request.d.ts.map +1 -1
- package/dist/tools/create_pull_request.js +48 -27
- package/dist/tools/create_pull_request.js.map +1 -1
- package/dist/tools/list_issues.d.ts +1 -1
- package/dist/tools/list_issues.d.ts.map +1 -1
- package/dist/tools/list_issues.js +6 -1
- package/dist/tools/list_issues.js.map +1 -1
- package/dist/tools/merge_pull_request.d.ts +17 -0
- package/dist/tools/merge_pull_request.d.ts.map +1 -0
- package/dist/tools/merge_pull_request.js +142 -0
- package/dist/tools/merge_pull_request.js.map +1 -0
- package/dist/tools/plan.d.ts +6 -1
- package/dist/tools/plan.d.ts.map +1 -1
- package/dist/tools/plan.js +16 -1
- package/dist/tools/plan.js.map +1 -1
- package/dist/tools/promote_branch.d.ts +23 -0
- package/dist/tools/promote_branch.d.ts.map +1 -0
- package/dist/tools/promote_branch.js +152 -0
- package/dist/tools/promote_branch.js.map +1 -0
- package/dist/tools/set_issue_fields.d.ts +3 -0
- package/dist/tools/set_issue_fields.d.ts.map +1 -1
- package/dist/tools/set_issue_fields.js +40 -32
- package/dist/tools/set_issue_fields.js.map +1 -1
- package/dist/tools/update_issue.d.ts +32 -0
- package/dist/tools/update_issue.d.ts.map +1 -0
- package/dist/tools/update_issue.js +46 -0
- package/dist/tools/update_issue.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getRepoDefaultBranch, getBranchCommits, createPullRequest, getOpenPullRequestForBranch, updatePullRequest, requestReviewers, } from "../github.js";
|
|
3
|
+
import { config } from "../config.js";
|
|
4
|
+
import { addIssueToProject, getProjectMetadata, setProjectFieldValue } from "../projects.js";
|
|
5
|
+
export const name = "promote_branch";
|
|
6
|
+
export const description = "Open the release/promotion pull request from one long-lived branch into another — e.g. develop → main. " +
|
|
7
|
+
"Use this instead of raw `gh pr create` or create_pull_request for a base→protected promotion: it is deliberately " +
|
|
8
|
+
"ISSUE-LESS (no issue lookup, no Closes #N), authenticates with okffs's token, and adds the PR itself to the " +
|
|
9
|
+
"Projects v2 board so the gate is visible. By default it promotes OKFFS_BASE_BRANCH (head, e.g. develop) into " +
|
|
10
|
+
"OKFFS_PROTECTED_BRANCH — or the repo default branch if no protected branch is set — but head/base can be overridden. " +
|
|
11
|
+
"No confirmation is needed: opening a PR is safe and reversible. okffs opens the PR and hands back — it NEVER merges " +
|
|
12
|
+
"or tags; that stays with the user. If a promotion PR is already open for the head branch it is updated and returned " +
|
|
13
|
+
"rather than erroring (GitHub allows only one open PR per head→base pair). When OKFFS_PROMOTION_AUTO_REVIEW is true, " +
|
|
14
|
+
"OKFFS_PROMOTION_REVIEWERS (e.g. Copilot) are requested — only on a newly-created gate PR, never on re-runs, to avoid " +
|
|
15
|
+
"repeat (possibly billable) reviews; when OKFFS_PROMOTION_STATUS is set, the board card lands in that column.";
|
|
16
|
+
export const inputSchema = z.object({
|
|
17
|
+
head: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Branch to promote FROM (the PR head). Defaults to OKFFS_BASE_BRANCH, e.g. develop."),
|
|
21
|
+
base: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Branch to promote INTO (the PR base). Defaults to OKFFS_PROTECTED_BRANCH, else the repo default branch, e.g. main."),
|
|
25
|
+
summary: z
|
|
26
|
+
.string()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("Optional summary for the PR body. When omitted, the body lists the commits being promoted."),
|
|
29
|
+
});
|
|
30
|
+
const text = (t) => ({ content: [{ type: "text", text: t }] });
|
|
31
|
+
export async function handler(input) {
|
|
32
|
+
// head defaults to the integration branch (OKFFS_BASE_BRANCH). We read
|
|
33
|
+
// config.baseBranch directly rather than getDefaultBranch(), because that
|
|
34
|
+
// helper falls back to the repo default branch — which is the promotion
|
|
35
|
+
// *target*, not a source. If neither an explicit head nor OKFFS_BASE_BRANCH
|
|
36
|
+
// is set, require the caller to pass one.
|
|
37
|
+
const head = input.head ?? config.baseBranch;
|
|
38
|
+
if (!head) {
|
|
39
|
+
return text("No head branch to promote — set OKFFS_BASE_BRANCH (e.g. develop) or pass an explicit `head`.");
|
|
40
|
+
}
|
|
41
|
+
// base defaults to the protected branch (the release/publish branch), else the
|
|
42
|
+
// repo's real default branch. Fetch the repo default up front — also used below
|
|
43
|
+
// to decide whether closing keywords in the PR body could fire.
|
|
44
|
+
const repoDefault = await getRepoDefaultBranch();
|
|
45
|
+
const base = input.base ?? config.protectedBranch ?? repoDefault;
|
|
46
|
+
if (head === base) {
|
|
47
|
+
return text(`Nothing to promote — head and base are both \`${base}\`. Set OKFFS_BASE_BRANCH and OKFFS_PROTECTED_BRANCH to different branches, or pass distinct head/base.`);
|
|
48
|
+
}
|
|
49
|
+
// Report whether the target is the protected branch — informational only. Opening
|
|
50
|
+
// the PR is never gated (the merge/tag are the user-gated steps).
|
|
51
|
+
const targetsProtected = config.protectedBranch && base === config.protectedBranch;
|
|
52
|
+
const commits = await getBranchCommits(head, base);
|
|
53
|
+
if (commits.length === 0) {
|
|
54
|
+
return text(`Nothing to promote — \`${head}\` has no commits ahead of \`${base}\`.`);
|
|
55
|
+
}
|
|
56
|
+
const title = `Promote ${head} → ${base}`;
|
|
57
|
+
// GitHub closing keywords (Close/Closes/Closed/Fix/Fixes/Fixed/Resolve/Resolves/
|
|
58
|
+
// Resolved #N) in a PR body only auto-close when the PR merges into the repo's
|
|
59
|
+
// DEFAULT branch. The list below echoes commit subjects verbatim, and okffs's own
|
|
60
|
+
// commit titles contain `Close #N` — so if this promotion targets the default
|
|
61
|
+
// branch, merging it could unintentionally close whatever issues those subjects
|
|
62
|
+
// reference. When base is the default branch, defuse issue refs in the list
|
|
63
|
+
// (wrap them in backticks so they're inert, non-closing text); otherwise leave
|
|
64
|
+
// them verbatim (links intact, and the keywords are inert anyway). Keeps the
|
|
65
|
+
// basic behaviour, guards the edge case (#188).
|
|
66
|
+
const baseIsDefault = base === repoDefault;
|
|
67
|
+
const subjectOf = (c) => {
|
|
68
|
+
const subject = c.commit.message.split("\n")[0];
|
|
69
|
+
return baseIsDefault ? subject.replace(/#(\d+)/g, "`#$1`") : subject;
|
|
70
|
+
};
|
|
71
|
+
const changes = commits.map((c) => `- ${subjectOf(c)}`).join("\n");
|
|
72
|
+
const body = [
|
|
73
|
+
input.summary ?? `Promotion PR from \`${head}\` into \`${base}\`. No \`Closes #N\` — this is a branch promotion, not an issue.`,
|
|
74
|
+
``,
|
|
75
|
+
`## Promoting (${commits.length} commit${commits.length === 1 ? "" : "s"})`,
|
|
76
|
+
changes,
|
|
77
|
+
].join("\n");
|
|
78
|
+
// Reuse an already-open promotion PR for this head→base rather than erroring —
|
|
79
|
+
// GitHub permits only one open PR per head→base pair. Match on base too: a
|
|
80
|
+
// long-lived head like `develop` can have open PRs into several bases, so
|
|
81
|
+
// head-only matching could reuse/overwrite the wrong PR.
|
|
82
|
+
const existing = await getOpenPullRequestForBranch(head, base);
|
|
83
|
+
let pr;
|
|
84
|
+
let action;
|
|
85
|
+
if (existing) {
|
|
86
|
+
await updatePullRequest(existing.number, { title, body });
|
|
87
|
+
pr = { number: existing.number, html_url: existing.html_url, node_id: existing.node_id };
|
|
88
|
+
action = "updated";
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
pr = await createPullRequest(title, body, head, base);
|
|
92
|
+
action = "created";
|
|
93
|
+
}
|
|
94
|
+
// Best-effort side effects — mirror the create_issue autoPR/board pattern: a
|
|
95
|
+
// failure warns with an [okffs] prefix, is surfaced in the response, and never
|
|
96
|
+
// fails the promotion.
|
|
97
|
+
const notes = [];
|
|
98
|
+
// Auto-request reviewers only when explicitly opted in (OKFFS_PROMOTION_AUTO_REVIEW)
|
|
99
|
+
// and only on a NEWLY-created gate PR — never on updates/re-runs — so a paid
|
|
100
|
+
// reviewer (e.g. Copilot) isn't re-triggered and re-billed each time. On an update
|
|
101
|
+
// we note that reviewers weren't re-requested and how to trigger one manually.
|
|
102
|
+
if (config.promotionAutoReview && config.promotionReviewers.length > 0) {
|
|
103
|
+
if (action === "created") {
|
|
104
|
+
try {
|
|
105
|
+
await requestReviewers(pr.number, config.promotionReviewers);
|
|
106
|
+
notes.push(`Requested review from: ${config.promotionReviewers.join(", ")}.`);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
110
|
+
console.warn(`[okffs] Failed to request reviewers on PR #${pr.number}:`, msg);
|
|
111
|
+
notes.push(`⚠️ Could not request reviewers (${config.promotionReviewers.join(", ")}): ${msg}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
notes.push(`Reviewers not re-requested on this update (auto-review requests on create only, to avoid repeat cost). ` +
|
|
116
|
+
`Re-request manually if you want a fresh review.`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (config.projectEnabled) {
|
|
120
|
+
try {
|
|
121
|
+
// addIssueToProject takes any content node id — a PR node id boards the PR
|
|
122
|
+
// itself as a first-class card (Projects v2 accepts PRs, not just issues).
|
|
123
|
+
const itemId = await addIssueToProject(pr.node_id);
|
|
124
|
+
notes.push(`Added the PR to the project board.`);
|
|
125
|
+
if (config.promotionStatus) {
|
|
126
|
+
const meta = await getProjectMetadata();
|
|
127
|
+
const optionId = meta.statusFieldId ? meta.statusOptions.get(config.promotionStatus) : undefined;
|
|
128
|
+
if (meta.statusFieldId && optionId) {
|
|
129
|
+
await setProjectFieldValue(itemId, meta.statusFieldId, optionId);
|
|
130
|
+
notes.push(`Moved the card to "${config.promotionStatus}".`);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
const opts = [...meta.statusOptions.keys()].join(", ") || "none";
|
|
134
|
+
notes.push(`⚠️ OKFFS_PROMOTION_STATUS "${config.promotionStatus}" is not a board column (available: ${opts}) — left the card in its default column.`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
140
|
+
console.warn(`[okffs] Failed to add promotion PR #${pr.number} to the board:`, msg);
|
|
141
|
+
notes.push(`⚠️ Could not add the PR to the board: ${msg}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const handBack = targetsProtected
|
|
145
|
+
? `\n\n🔒 \`${base}\` is OKFFS_PROTECTED_BRANCH — okffs opened this PR but will NOT merge or tag. Review it, then merge and tag yourself.`
|
|
146
|
+
: `\n\nReview and merge when ready — okffs does not merge or tag.`;
|
|
147
|
+
const lines = [`Promotion PR #${pr.number} ${action}: ${pr.html_url}`];
|
|
148
|
+
if (notes.length > 0)
|
|
149
|
+
lines.push("", ...notes);
|
|
150
|
+
return text(lines.join("\n") + handBack);
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=promote_branch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promote_branch.js","sourceRoot":"","sources":["../../src/tools/promote_branch.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,12 +5,15 @@ export declare const inputSchema: z.ZodObject<{
|
|
|
5
5
|
issue_number: z.ZodNumber;
|
|
6
6
|
priority: z.ZodOptional<z.ZodString>;
|
|
7
7
|
effort: z.ZodOptional<z.ZodString>;
|
|
8
|
+
type: z.ZodOptional<z.ZodString>;
|
|
8
9
|
}, "strip", z.ZodTypeAny, {
|
|
9
10
|
issue_number: number;
|
|
11
|
+
type?: string | undefined;
|
|
10
12
|
priority?: string | undefined;
|
|
11
13
|
effort?: string | undefined;
|
|
12
14
|
}, {
|
|
13
15
|
issue_number: number;
|
|
16
|
+
type?: string | undefined;
|
|
14
17
|
priority?: string | undefined;
|
|
15
18
|
effort?: string | undefined;
|
|
16
19
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set_issue_fields.d.ts","sourceRoot":"","sources":["../../src/tools/set_issue_fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"set_issue_fields.d.ts","sourceRoot":"","sources":["../../src/tools/set_issue_fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,IAAI,qBAAqB,CAAC;AAEvC,eAAO,MAAM,WAAW,QAKyG,CAAC;AAElI,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;EAKtB,CAAC;AASH,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GAiC/D"}
|
|
@@ -2,47 +2,55 @@ import { z } from "zod";
|
|
|
2
2
|
import { getIssue } from "../github.js";
|
|
3
3
|
import { config } from "../config.js";
|
|
4
4
|
import { addIssueToBoard } from "../board.js";
|
|
5
|
+
import { applyIssueType } from "../issue_types.js";
|
|
5
6
|
export const name = "set_issue_fields";
|
|
6
|
-
export const description = "Set
|
|
7
|
-
"Use this to set
|
|
8
|
-
"
|
|
9
|
-
"
|
|
7
|
+
export const description = "Set enumerated fields on an EXISTING issue: the GitHub Projects v2 board Priority and/or Effort, and/or the native GitHub Issue Type (Task/Bug/Feature/…). " +
|
|
8
|
+
"Use this to set these on issues that already exist — create_issue only sets them at creation time. " +
|
|
9
|
+
"Priority/Effort handle both project-native single-select fields and org-level Issue Fields (the latter needs OKFFS_CLASSIC_PAT + a classic admin:org PAT) and require OKFFS_PROJECT_ENABLED. " +
|
|
10
|
+
"Type is a native GitHub Issue Type (org-level; skipped cleanly on user repos / when unavailable) and works independently of the board. " +
|
|
11
|
+
"To move an issue's Status column, use update_project_status; to edit title/assignees/labels/milestone/body, use update_issue.";
|
|
10
12
|
export const inputSchema = z.object({
|
|
11
13
|
issue_number: z.number().int().positive().describe("The issue number to set fields on"),
|
|
12
|
-
priority: z.string().optional().describe("Board Priority to set (e.g. Urgent, High, Medium, Low) — matched against the board's Priority options"),
|
|
13
|
-
effort: z.string().optional().describe("Board Effort to set (e.g. High, Medium, Low) — matched against the board's Effort options"),
|
|
14
|
+
priority: z.string().optional().describe("Board Priority to set (e.g. Urgent, High, Medium, Low) — matched against the board's Priority options. Requires OKFFS_PROJECT_ENABLED."),
|
|
15
|
+
effort: z.string().optional().describe("Board Effort to set (e.g. High, Medium, Low) — matched against the board's Effort options. Requires OKFFS_PROJECT_ENABLED."),
|
|
16
|
+
type: z.string().optional().describe("Native GitHub Issue Type to set (e.g. Task, Bug, Feature, Epic, Story) — matched against the org's enabled Issue Types. Independent of the board."),
|
|
14
17
|
});
|
|
15
18
|
const text = (t) => ({ content: [{ type: "text", text: t }] });
|
|
19
|
+
const renderOutcome = (label, requested, outcome) => "applied" in outcome
|
|
20
|
+
? `${label} → ${outcome.applied}`
|
|
21
|
+
: `⚠ ${label} "${requested}" not set — ${outcome.skipped}`;
|
|
16
22
|
export async function handler(input) {
|
|
17
|
-
if (!
|
|
18
|
-
return text("
|
|
19
|
-
}
|
|
20
|
-
if (!input.priority && !input.effort) {
|
|
21
|
-
return text("Nothing to set — pass a priority and/or an effort. (For the Status column, use update_project_status.)");
|
|
22
|
-
}
|
|
23
|
-
const issue = await getIssue(input.issue_number);
|
|
24
|
-
let result;
|
|
25
|
-
try {
|
|
26
|
-
// addIssueToBoard adds the issue to the board (idempotent — returns the
|
|
27
|
-
// existing item if already present) and sets Priority/Effort via the shared,
|
|
28
|
-
// org-Issue-Field-aware path. Reused so existing issues get identical handling
|
|
29
|
-
// and surfacing to create_issue.
|
|
30
|
-
result = await addIssueToBoard(issue.node_id, { priority: input.priority, effort: input.effort });
|
|
31
|
-
}
|
|
32
|
-
catch (err) {
|
|
33
|
-
return text(`[okffs] Failed to update board fields on #${input.issue_number}: ${err instanceof Error ? err.message : String(err)}`);
|
|
23
|
+
if (!input.priority && !input.effort && !input.type) {
|
|
24
|
+
return text("Nothing to set — pass a priority, effort, and/or type. (Status column → update_project_status; title/assignees/labels/milestone/body → update_issue.)");
|
|
34
25
|
}
|
|
35
26
|
const lines = [];
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
27
|
+
// Board fields (Priority/Effort) — gated on the Projects integration.
|
|
28
|
+
if (input.priority || input.effort) {
|
|
29
|
+
if (!config.projectEnabled) {
|
|
30
|
+
lines.push("⚠ Priority/Effort not set — OKFFS_PROJECT_ENABLED is not set, so board field updates are disabled.");
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const issue = await getIssue(input.issue_number);
|
|
34
|
+
try {
|
|
35
|
+
// addIssueToBoard adds the issue to the board (idempotent) and sets
|
|
36
|
+
// Priority/Effort via the shared, org-Issue-Field-aware path — identical
|
|
37
|
+
// handling and surfacing to create_issue.
|
|
38
|
+
const result = await addIssueToBoard(issue.node_id, { priority: input.priority, effort: input.effort });
|
|
39
|
+
if (result.priority)
|
|
40
|
+
lines.push(renderOutcome("Priority", input.priority, result.priority));
|
|
41
|
+
if (result.effort)
|
|
42
|
+
lines.push(renderOutcome("Effort", input.effort, result.effort));
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
lines.push(`⚠ Failed to update board fields: ${err instanceof Error ? err.message : String(err)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
40
48
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
// Native Issue Type — org-level, independent of the board. Non-fatal.
|
|
50
|
+
if (input.type) {
|
|
51
|
+
const outcome = await applyIssueType(input.issue_number, input.type);
|
|
52
|
+
lines.push(renderOutcome("Type", input.type, outcome));
|
|
45
53
|
}
|
|
46
|
-
return text(`Issue #${input.issue_number}
|
|
54
|
+
return text(`Issue #${input.issue_number} fields:\n${lines.map((l) => ` ${l}`).join("\n")}`);
|
|
47
55
|
}
|
|
48
56
|
//# sourceMappingURL=set_issue_fields.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set_issue_fields.js","sourceRoot":"","sources":["../../src/tools/set_issue_fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"set_issue_fields.js","sourceRoot":"","sources":["../../src/tools/set_issue_fields.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const name = "update_issue";
|
|
3
|
+
export declare const description: string;
|
|
4
|
+
export declare const inputSchema: z.ZodObject<{
|
|
5
|
+
issue_number: z.ZodNumber;
|
|
6
|
+
title: z.ZodOptional<z.ZodString>;
|
|
7
|
+
body: z.ZodOptional<z.ZodString>;
|
|
8
|
+
assignees: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
9
|
+
labels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
10
|
+
milestone: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
11
|
+
}, "strip", z.ZodTypeAny, {
|
|
12
|
+
issue_number: number;
|
|
13
|
+
title?: string | undefined;
|
|
14
|
+
body?: string | undefined;
|
|
15
|
+
assignees?: string[] | undefined;
|
|
16
|
+
labels?: string[] | undefined;
|
|
17
|
+
milestone?: number | null | undefined;
|
|
18
|
+
}, {
|
|
19
|
+
issue_number: number;
|
|
20
|
+
title?: string | undefined;
|
|
21
|
+
body?: string | undefined;
|
|
22
|
+
assignees?: string[] | undefined;
|
|
23
|
+
labels?: string[] | undefined;
|
|
24
|
+
milestone?: number | null | undefined;
|
|
25
|
+
}>;
|
|
26
|
+
export declare function handler(input: z.infer<typeof inputSchema>): Promise<{
|
|
27
|
+
content: {
|
|
28
|
+
type: "text";
|
|
29
|
+
text: string;
|
|
30
|
+
}[];
|
|
31
|
+
}>;
|
|
32
|
+
//# sourceMappingURL=update_issue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update_issue.d.ts","sourceRoot":"","sources":["../../src/tools/update_issue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,IAAI,iBAAiB,CAAC;AAEnC,eAAO,MAAM,WAAW,QAQ0C,CAAC;AAEnE,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;EAOtB,CAAC;AAIH,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GA+B/D"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { updateIssue } from "../github.js";
|
|
3
|
+
export const name = "update_issue";
|
|
4
|
+
export const description = "Mutate the core fields of an EXISTING GitHub issue — title, assignees, labels, milestone, and/or body. " +
|
|
5
|
+
"create_issue only sets these at creation time; this is how you change them afterward (e.g. rename an issue, " +
|
|
6
|
+
"add or change an assignee) without dropping to raw `gh issue edit`. Authenticates with okffs's configured token " +
|
|
7
|
+
"(GITHUB_TOKEN, or the gh CLI fallback when it's unset) and applies okffs conventions. Pass only the fields you " +
|
|
8
|
+
"want to change — omitted fields are left untouched. NOTE: labels and assignees REPLACE the whole set (they do " +
|
|
9
|
+
"not merge with the current values), so pass the complete desired list; an empty array [] clears them, and " +
|
|
10
|
+
"milestone: null clears the milestone. For board Priority/Effort use set_issue_fields, and for the board Status " +
|
|
11
|
+
"column use update_project_status — those are not issue fields.";
|
|
12
|
+
export const inputSchema = z.object({
|
|
13
|
+
issue_number: z.number().int().positive().describe("The issue number to update"),
|
|
14
|
+
title: z.string().optional().describe("New issue title"),
|
|
15
|
+
body: z.string().optional().describe("New issue body. Replaces the existing body — pass the full content, not a fragment."),
|
|
16
|
+
assignees: z.array(z.string()).optional().describe("GitHub usernames to assign. REPLACES the current assignees (not merged); [] clears them."),
|
|
17
|
+
labels: z.array(z.string()).optional().describe("Labels to apply. REPLACES the current labels (not merged); [] clears them."),
|
|
18
|
+
milestone: z.number().int().positive().nullable().optional().describe("Milestone number to assign, or null to clear the milestone."),
|
|
19
|
+
});
|
|
20
|
+
const text = (t) => ({ content: [{ type: "text", text: t }] });
|
|
21
|
+
export async function handler(input) {
|
|
22
|
+
const { issue_number, ...fields } = input;
|
|
23
|
+
// Require at least one field to change — mirrors set_issue_fields' guard so a
|
|
24
|
+
// no-op call gives an actionable message instead of a silent PATCH.
|
|
25
|
+
const provided = ["title", "body", "assignees", "labels", "milestone"].filter((k) => fields[k] !== undefined);
|
|
26
|
+
if (provided.length === 0) {
|
|
27
|
+
return text("Nothing to update — pass at least one of: title, body, assignees, labels, milestone. " +
|
|
28
|
+
"(For board Priority/Effort use set_issue_fields; for the Status column use update_project_status.)");
|
|
29
|
+
}
|
|
30
|
+
let updated;
|
|
31
|
+
try {
|
|
32
|
+
updated = await updateIssue(issue_number, fields);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
return text(`[okffs] Failed to update issue #${issue_number}: ${err instanceof Error ? err.message : String(err)}`);
|
|
36
|
+
}
|
|
37
|
+
const lines = provided.map((k) => {
|
|
38
|
+
const v = fields[k];
|
|
39
|
+
const shown = Array.isArray(v)
|
|
40
|
+
? (v.length ? v.join(", ") : "(cleared)")
|
|
41
|
+
: v === null ? "(cleared)" : String(v);
|
|
42
|
+
return ` ${k} → ${shown}`;
|
|
43
|
+
});
|
|
44
|
+
return text(`Issue #${issue_number} updated:\n${lines.join("\n")}\n${updated.html_url}`);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=update_issue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update_issue.js","sourceRoot":"","sources":["../../src/tools/update_issue.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.
|
|
3
|
+
"version": "0.7.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",
|