Add schemas for GitLab discussion notes and merge request discussions

This commit is contained in:
simple
2025-03-31 19:10:59 +09:00
parent a1d141f913
commit 8e0c0aedff
4 changed files with 336 additions and 7 deletions

116
index.ts
View File

@ -67,6 +67,11 @@ import {
DeleteLabelSchema,
CreateNoteSchema,
ListGroupProjectsSchema,
// Discussion Schemas
GitLabDiscussionNoteSchema, // Added
GitLabDiscussionSchema,
UpdateMergeRequestNoteSchema, // Added
ListMergeRequestDiscussionsSchema,
type GitLabFork,
type GitLabReference,
type GitLabRepository,
@ -85,6 +90,9 @@ import {
type GitLabNamespaceExistsResponse,
type GitLabProject,
type GitLabLabel,
// Discussion Types
type GitLabDiscussionNote, // Added
type GitLabDiscussion,
} from "./schemas.js";
/**
@ -650,6 +658,76 @@ async function createMergeRequest(
return GitLabMergeRequestSchema.parse(data);
}
/**
* List merge request discussion items
* 병합 요청 토론 목록 조회
*
* @param {string} projectId - The ID or URL-encoded path of the project
* @param {number} mergeRequestIid - The IID of a merge request
* @returns {Promise<GitLabDiscussion[]>} List of discussions
*/
async function listMergeRequestDiscussions(
projectId: string,
mergeRequestIid: number
): Promise<GitLabDiscussion[]> {
const url = new URL(
`${GITLAB_API_URL}/projects/${encodeURIComponent(
projectId
)}/merge_requests/${mergeRequestIid}/discussions`
);
const response = await fetch(url.toString(), {
headers: DEFAULT_HEADERS,
});
await handleGitLabError(response);
const data = await response.json();
// Ensure the response is parsed as an array of discussions
return z.array(GitLabDiscussionSchema).parse(data);
}
/**
* Modify an existing merge request thread note
* 병합 요청 토론 노트 수정
*
* @param {string} projectId - The ID or URL-encoded path of the project
* @param {number} mergeRequestIid - The IID of a merge request
* @param {string} discussionId - The ID of a thread
* @param {number} noteId - The ID of a thread note
* @param {string} body - The new content of the note
* @param {boolean} [resolved] - Resolve/unresolve state
* @returns {Promise<GitLabDiscussionNote>} The updated note
*/
async function updateMergeRequestNote(
projectId: string,
mergeRequestIid: number,
discussionId: string,
noteId: number,
body: string,
resolved?: boolean
): Promise<GitLabDiscussionNote> {
const url = new URL(
`${GITLAB_API_URL}/projects/${encodeURIComponent(
projectId
)}/merge_requests/${mergeRequestIid}/discussions/${discussionId}/notes/${noteId}`
);
const payload: { body: string; resolved?: boolean } = { body };
if (resolved !== undefined) {
payload.resolved = resolved;
}
const response = await fetch(url.toString(), {
method: "PUT",
headers: DEFAULT_HEADERS,
body: JSON.stringify(payload),
});
await handleGitLabError(response);
const data = await response.json();
return GitLabDiscussionNoteSchema.parse(data);
}
/**
* Create or update a file in a GitLab project
* 파일 생성 또는 업데이트
@ -1507,6 +1585,16 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
description: "Create a new note (comment) to an issue or merge request",
inputSchema: zodToJsonSchema(CreateNoteSchema),
},
{
name: "list_merge_request_discussions",
description: "List discussion items for a merge request",
inputSchema: zodToJsonSchema(ListMergeRequestDiscussionsSchema),
},
{
name: "update_merge_request_note",
description: "Modify an existing merge request thread note",
inputSchema: zodToJsonSchema(UpdateMergeRequestNoteSchema),
},
{
name: "list_issues",
description: "List issues in a GitLab project with filtering options",
@ -1733,6 +1821,21 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
};
}
case "update_merge_request_note": {
const args = UpdateMergeRequestNoteSchema.parse(request.params.arguments);
const note = await updateMergeRequestNote(
args.project_id,
args.merge_request_iid,
args.discussion_id,
args.note_id,
args.body,
args.resolved // Pass resolved if provided
);
return {
content: [{ type: "text", text: JSON.stringify(note, null, 2) }],
};
}
case "get_merge_request": {
const args = GetMergeRequestSchema.parse(request.params.arguments);
const mergeRequest = await getMergeRequest(
@ -1773,6 +1876,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
};
}
case "list_merge_request_discussions": {
const args = ListMergeRequestDiscussionsSchema.parse(request.params.arguments);
const discussions = await listMergeRequestDiscussions(
args.project_id,
args.merge_request_iid
);
return {
content: [
{ type: "text", text: JSON.stringify(discussions, null, 2) },
],
};
}
case "list_namespaces": {
const args = ListNamespacesSchema.parse(request.params.arguments);
const url = new URL(`${GITLAB_API_URL}/namespaces`);