Add schemas for GitLab discussion notes and merge request discussions
This commit is contained in:
@ -9,7 +9,11 @@ import { fileURLToPath } from "url";
|
|||||||
import { dirname } from "path";
|
import { dirname } from "path";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, GitLabNamespaceSchema, GitLabNamespaceExistsResponseSchema, GitLabProjectSchema, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabMergeRequestDiffSchema, GetMergeRequestSchema, GetMergeRequestDiffsSchema, UpdateMergeRequestSchema, ListIssuesSchema, GetIssueSchema, UpdateIssueSchema, DeleteIssueSchema, GitLabIssueLinkSchema, GitLabIssueWithLinkDetailsSchema, ListIssueLinksSchema, GetIssueLinkSchema, CreateIssueLinkSchema, DeleteIssueLinkSchema, ListNamespacesSchema, GetNamespaceSchema, VerifyNamespaceSchema, GetProjectSchema, ListProjectsSchema, ListLabelsSchema, GetLabelSchema, CreateLabelSchema, UpdateLabelSchema, DeleteLabelSchema, CreateNoteSchema, ListGroupProjectsSchema, } from "./schemas.js";
|
import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, GitLabNamespaceSchema, GitLabNamespaceExistsResponseSchema, GitLabProjectSchema, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabMergeRequestDiffSchema, GetMergeRequestSchema, GetMergeRequestDiffsSchema, UpdateMergeRequestSchema, ListIssuesSchema, GetIssueSchema, UpdateIssueSchema, DeleteIssueSchema, GitLabIssueLinkSchema, GitLabIssueWithLinkDetailsSchema, ListIssueLinksSchema, GetIssueLinkSchema, CreateIssueLinkSchema, DeleteIssueLinkSchema, ListNamespacesSchema, GetNamespaceSchema, VerifyNamespaceSchema, GetProjectSchema, ListProjectsSchema, ListLabelsSchema, GetLabelSchema, CreateLabelSchema, UpdateLabelSchema, DeleteLabelSchema, CreateNoteSchema, ListGroupProjectsSchema,
|
||||||
|
// Discussion Schemas
|
||||||
|
GitLabDiscussionNoteSchema, // Added
|
||||||
|
GitLabDiscussionSchema, UpdateMergeRequestNoteSchema, // Added
|
||||||
|
ListMergeRequestDiscussionsSchema, } from "./schemas.js";
|
||||||
/**
|
/**
|
||||||
* Read version from package.json
|
* Read version from package.json
|
||||||
*/
|
*/
|
||||||
@ -417,6 +421,51 @@ async function createMergeRequest(projectId, options) {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
return GitLabMergeRequestSchema.parse(data);
|
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, mergeRequestIid) {
|
||||||
|
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, mergeRequestIid, discussionId, noteId, body, resolved) {
|
||||||
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests/${mergeRequestIid}/discussions/${discussionId}/notes/${noteId}`);
|
||||||
|
const payload = { 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
|
* Create or update a file in a GitLab project
|
||||||
* 파일 생성 또는 업데이트
|
* 파일 생성 또는 업데이트
|
||||||
@ -1077,6 +1126,16 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|||||||
description: "Create a new note (comment) to an issue or merge request",
|
description: "Create a new note (comment) to an issue or merge request",
|
||||||
inputSchema: zodToJsonSchema(CreateNoteSchema),
|
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",
|
name: "list_issues",
|
||||||
description: "List issues in a GitLab project with filtering options",
|
description: "List issues in a GitLab project with filtering options",
|
||||||
@ -1269,6 +1328,14 @@ 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": {
|
case "get_merge_request": {
|
||||||
const args = GetMergeRequestSchema.parse(request.params.arguments);
|
const args = GetMergeRequestSchema.parse(request.params.arguments);
|
||||||
const mergeRequest = await getMergeRequest(args.project_id, args.merge_request_iid);
|
const mergeRequest = await getMergeRequest(args.project_id, args.merge_request_iid);
|
||||||
@ -1295,6 +1362,15 @@ 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": {
|
case "list_namespaces": {
|
||||||
const args = ListNamespacesSchema.parse(request.params.arguments);
|
const args = ListNamespacesSchema.parse(request.params.arguments);
|
||||||
const url = new URL(`${GITLAB_API_URL}/namespaces`);
|
const url = new URL(`${GITLAB_API_URL}/namespaces`);
|
||||||
|
@ -6,6 +6,10 @@ export const GitLabAuthorSchema = z.object({
|
|||||||
date: z.string(),
|
date: z.string(),
|
||||||
});
|
});
|
||||||
// Namespace related schemas
|
// Namespace related schemas
|
||||||
|
// Base schema for project-related operations
|
||||||
|
const ProjectParamsSchema = z.object({
|
||||||
|
project_id: z.string().describe("Project ID or URL-encoded path"), // Changed from owner/repo to match GitLab API
|
||||||
|
});
|
||||||
export const GitLabNamespaceSchema = z.object({
|
export const GitLabNamespaceSchema = z.object({
|
||||||
id: z.number(),
|
id: z.number(),
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
@ -324,10 +328,71 @@ export const GitLabMergeRequestSchema = z.object({
|
|||||||
squash: z.boolean().optional(),
|
squash: z.boolean().optional(),
|
||||||
labels: z.array(z.string()).optional(),
|
labels: z.array(z.string()).optional(),
|
||||||
});
|
});
|
||||||
// API Operation Parameter Schemas
|
// Discussion related schemas
|
||||||
const ProjectParamsSchema = z.object({
|
export const GitLabDiscussionNoteSchema = z.object({
|
||||||
project_id: z.string().describe("Project ID or URL-encoded path"), // Changed from owner/repo to match GitLab API
|
id: z.number(),
|
||||||
|
type: z.enum(["DiscussionNote", "DiffNote", "Note"]).nullable(), // Allow null type for regular notes
|
||||||
|
body: z.string(),
|
||||||
|
attachment: z.any().nullable(), // Can be string or object, handle appropriately
|
||||||
|
author: GitLabUserSchema,
|
||||||
|
created_at: z.string(),
|
||||||
|
updated_at: z.string(),
|
||||||
|
system: z.boolean(),
|
||||||
|
noteable_id: z.number(),
|
||||||
|
noteable_type: z.enum(["Issue", "MergeRequest", "Snippet", "Commit", "Epic"]),
|
||||||
|
project_id: z.number().optional(), // Optional for group-level discussions like Epics
|
||||||
|
noteable_iid: z.number().nullable(),
|
||||||
|
resolvable: z.boolean().optional(),
|
||||||
|
resolved: z.boolean().optional(),
|
||||||
|
resolved_by: GitLabUserSchema.nullable().optional(),
|
||||||
|
resolved_at: z.string().nullable().optional(),
|
||||||
|
position: z.object({
|
||||||
|
base_sha: z.string(),
|
||||||
|
start_sha: z.string(),
|
||||||
|
head_sha: z.string(),
|
||||||
|
old_path: z.string(),
|
||||||
|
new_path: z.string(),
|
||||||
|
position_type: z.enum(["text", "image", "file"]),
|
||||||
|
old_line: z.number().nullable(),
|
||||||
|
new_line: z.number().nullable(),
|
||||||
|
line_range: z.object({
|
||||||
|
start: z.object({
|
||||||
|
line_code: z.string(),
|
||||||
|
type: z.enum(["new", "old"]),
|
||||||
|
old_line: z.number().nullable(),
|
||||||
|
new_line: z.number().nullable(),
|
||||||
|
}),
|
||||||
|
end: z.object({
|
||||||
|
line_code: z.string(),
|
||||||
|
type: z.enum(["new", "old"]),
|
||||||
|
old_line: z.number().nullable(),
|
||||||
|
new_line: z.number().nullable(),
|
||||||
|
}),
|
||||||
|
}).nullable().optional(), // For multi-line diff notes
|
||||||
|
width: z.number().optional(), // For image diff notes
|
||||||
|
height: z.number().optional(), // For image diff notes
|
||||||
|
x: z.number().optional(), // For image diff notes
|
||||||
|
y: z.number().optional(), // For image diff notes
|
||||||
|
}).optional(),
|
||||||
});
|
});
|
||||||
|
export const GitLabDiscussionSchema = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
individual_note: z.boolean(),
|
||||||
|
notes: z.array(GitLabDiscussionNoteSchema),
|
||||||
|
});
|
||||||
|
// Input schema for listing merge request discussions
|
||||||
|
export const ListMergeRequestDiscussionsSchema = ProjectParamsSchema.extend({
|
||||||
|
merge_request_iid: z.number().describe("The IID of a merge request"),
|
||||||
|
});
|
||||||
|
// Input schema for updating a merge request discussion note
|
||||||
|
export const UpdateMergeRequestNoteSchema = ProjectParamsSchema.extend({
|
||||||
|
merge_request_iid: z.number().describe("The IID of a merge request"),
|
||||||
|
discussion_id: z.string().describe("The ID of a thread"),
|
||||||
|
note_id: z.number().describe("The ID of a thread note"),
|
||||||
|
body: z.string().describe("The content of the note or reply"),
|
||||||
|
resolved: z.boolean().optional().describe("Resolve or unresolve the note"), // Optional based on API docs
|
||||||
|
});
|
||||||
|
// API Operation Parameter Schemas
|
||||||
export const CreateOrUpdateFileSchema = ProjectParamsSchema.extend({
|
export const CreateOrUpdateFileSchema = ProjectParamsSchema.extend({
|
||||||
file_path: z.string().describe("Path where to create/update the file"),
|
file_path: z.string().describe("Path where to create/update the file"),
|
||||||
content: z.string().describe("Content of the file"),
|
content: z.string().describe("Content of the file"),
|
||||||
|
116
index.ts
116
index.ts
@ -67,6 +67,11 @@ import {
|
|||||||
DeleteLabelSchema,
|
DeleteLabelSchema,
|
||||||
CreateNoteSchema,
|
CreateNoteSchema,
|
||||||
ListGroupProjectsSchema,
|
ListGroupProjectsSchema,
|
||||||
|
// Discussion Schemas
|
||||||
|
GitLabDiscussionNoteSchema, // Added
|
||||||
|
GitLabDiscussionSchema,
|
||||||
|
UpdateMergeRequestNoteSchema, // Added
|
||||||
|
ListMergeRequestDiscussionsSchema,
|
||||||
type GitLabFork,
|
type GitLabFork,
|
||||||
type GitLabReference,
|
type GitLabReference,
|
||||||
type GitLabRepository,
|
type GitLabRepository,
|
||||||
@ -85,6 +90,9 @@ import {
|
|||||||
type GitLabNamespaceExistsResponse,
|
type GitLabNamespaceExistsResponse,
|
||||||
type GitLabProject,
|
type GitLabProject,
|
||||||
type GitLabLabel,
|
type GitLabLabel,
|
||||||
|
// Discussion Types
|
||||||
|
type GitLabDiscussionNote, // Added
|
||||||
|
type GitLabDiscussion,
|
||||||
} from "./schemas.js";
|
} from "./schemas.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -650,6 +658,76 @@ async function createMergeRequest(
|
|||||||
return GitLabMergeRequestSchema.parse(data);
|
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
|
* 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",
|
description: "Create a new note (comment) to an issue or merge request",
|
||||||
inputSchema: zodToJsonSchema(CreateNoteSchema),
|
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",
|
name: "list_issues",
|
||||||
description: "List issues in a GitLab project with filtering options",
|
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": {
|
case "get_merge_request": {
|
||||||
const args = GetMergeRequestSchema.parse(request.params.arguments);
|
const args = GetMergeRequestSchema.parse(request.params.arguments);
|
||||||
const mergeRequest = await getMergeRequest(
|
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": {
|
case "list_namespaces": {
|
||||||
const args = ListNamespacesSchema.parse(request.params.arguments);
|
const args = ListNamespacesSchema.parse(request.params.arguments);
|
||||||
const url = new URL(`${GITLAB_API_URL}/namespaces`);
|
const url = new URL(`${GITLAB_API_URL}/namespaces`);
|
||||||
|
78
schemas.ts
78
schemas.ts
@ -8,6 +8,11 @@ export const GitLabAuthorSchema = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Namespace related schemas
|
// Namespace related schemas
|
||||||
|
|
||||||
|
// Base schema for project-related operations
|
||||||
|
const ProjectParamsSchema = z.object({
|
||||||
|
project_id: z.string().describe("Project ID or URL-encoded path"), // Changed from owner/repo to match GitLab API
|
||||||
|
});
|
||||||
export const GitLabNamespaceSchema = z.object({
|
export const GitLabNamespaceSchema = z.object({
|
||||||
id: z.number(),
|
id: z.number(),
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
@ -354,10 +359,77 @@ export const GitLabMergeRequestSchema = z.object({
|
|||||||
labels: z.array(z.string()).optional(),
|
labels: z.array(z.string()).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// API Operation Parameter Schemas
|
// Discussion related schemas
|
||||||
const ProjectParamsSchema = z.object({
|
export const GitLabDiscussionNoteSchema = z.object({
|
||||||
project_id: z.string().describe("Project ID or URL-encoded path"), // Changed from owner/repo to match GitLab API
|
id: z.number(),
|
||||||
|
type: z.enum(["DiscussionNote", "DiffNote", "Note"]).nullable(), // Allow null type for regular notes
|
||||||
|
body: z.string(),
|
||||||
|
attachment: z.any().nullable(), // Can be string or object, handle appropriately
|
||||||
|
author: GitLabUserSchema,
|
||||||
|
created_at: z.string(),
|
||||||
|
updated_at: z.string(),
|
||||||
|
system: z.boolean(),
|
||||||
|
noteable_id: z.number(),
|
||||||
|
noteable_type: z.enum(["Issue", "MergeRequest", "Snippet", "Commit", "Epic"]),
|
||||||
|
project_id: z.number().optional(), // Optional for group-level discussions like Epics
|
||||||
|
noteable_iid: z.number().nullable(),
|
||||||
|
resolvable: z.boolean().optional(),
|
||||||
|
resolved: z.boolean().optional(),
|
||||||
|
resolved_by: GitLabUserSchema.nullable().optional(),
|
||||||
|
resolved_at: z.string().nullable().optional(),
|
||||||
|
position: z.object({ // Only present for DiffNote
|
||||||
|
base_sha: z.string(),
|
||||||
|
start_sha: z.string(),
|
||||||
|
head_sha: z.string(),
|
||||||
|
old_path: z.string(),
|
||||||
|
new_path: z.string(),
|
||||||
|
position_type: z.enum(["text", "image", "file"]),
|
||||||
|
old_line: z.number().nullable(),
|
||||||
|
new_line: z.number().nullable(),
|
||||||
|
line_range: z.object({
|
||||||
|
start: z.object({
|
||||||
|
line_code: z.string(),
|
||||||
|
type: z.enum(["new", "old"]),
|
||||||
|
old_line: z.number().nullable(),
|
||||||
|
new_line: z.number().nullable(),
|
||||||
|
}),
|
||||||
|
end: z.object({
|
||||||
|
line_code: z.string(),
|
||||||
|
type: z.enum(["new", "old"]),
|
||||||
|
old_line: z.number().nullable(),
|
||||||
|
new_line: z.number().nullable(),
|
||||||
|
}),
|
||||||
|
}).nullable().optional(), // For multi-line diff notes
|
||||||
|
width: z.number().optional(), // For image diff notes
|
||||||
|
height: z.number().optional(), // For image diff notes
|
||||||
|
x: z.number().optional(), // For image diff notes
|
||||||
|
y: z.number().optional(), // For image diff notes
|
||||||
|
}).optional(),
|
||||||
});
|
});
|
||||||
|
export type GitLabDiscussionNote = z.infer<typeof GitLabDiscussionNoteSchema>;
|
||||||
|
|
||||||
|
export const GitLabDiscussionSchema = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
individual_note: z.boolean(),
|
||||||
|
notes: z.array(GitLabDiscussionNoteSchema),
|
||||||
|
});
|
||||||
|
export type GitLabDiscussion = z.infer<typeof GitLabDiscussionSchema>;
|
||||||
|
|
||||||
|
// Input schema for listing merge request discussions
|
||||||
|
export const ListMergeRequestDiscussionsSchema = ProjectParamsSchema.extend({
|
||||||
|
merge_request_iid: z.number().describe("The IID of a merge request"),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Input schema for updating a merge request discussion note
|
||||||
|
export const UpdateMergeRequestNoteSchema = ProjectParamsSchema.extend({
|
||||||
|
merge_request_iid: z.number().describe("The IID of a merge request"),
|
||||||
|
discussion_id: z.string().describe("The ID of a thread"),
|
||||||
|
note_id: z.number().describe("The ID of a thread note"),
|
||||||
|
body: z.string().describe("The content of the note or reply"),
|
||||||
|
resolved: z.boolean().optional().describe("Resolve or unresolve the note"), // Optional based on API docs
|
||||||
|
});
|
||||||
|
|
||||||
|
// API Operation Parameter Schemas
|
||||||
|
|
||||||
export const CreateOrUpdateFileSchema = ProjectParamsSchema.extend({
|
export const CreateOrUpdateFileSchema = ProjectParamsSchema.extend({
|
||||||
file_path: z.string().describe("Path where to create/update the file"),
|
file_path: z.string().describe("Path where to create/update the file"),
|
||||||
|
Reference in New Issue
Block a user