feat: add branch comparison functionality and update related schemas
This commit is contained in:
70
index.ts
70
index.ts
@ -53,7 +53,7 @@ import {
|
||||
CreateMergeRequestSchema,
|
||||
ForkRepositorySchema,
|
||||
CreateBranchSchema,
|
||||
GitLabMergeRequestDiffSchema,
|
||||
GitLabDiffSchema,
|
||||
GetMergeRequestSchema,
|
||||
GetMergeRequestDiffsSchema,
|
||||
UpdateMergeRequestSchema,
|
||||
@ -126,6 +126,9 @@ import {
|
||||
GetRepositoryTreeSchema,
|
||||
type GitLabTreeItem,
|
||||
type GetRepositoryTreeOptions,
|
||||
GitLabCompareResult,
|
||||
GitLabCompareResultSchema,
|
||||
GetBranchDiffsSchema,
|
||||
} from "./schemas.js";
|
||||
|
||||
/**
|
||||
@ -261,6 +264,12 @@ const allTools = [
|
||||
"Get the changes/diffs of a merge request (Either mergeRequestIid or branchName must be provided)",
|
||||
inputSchema: zodToJsonSchema(GetMergeRequestDiffsSchema),
|
||||
},
|
||||
{
|
||||
name: "get_branch_diffs",
|
||||
description:
|
||||
"Get the changes/diffs between two branches or commits in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(GetBranchDiffsSchema),
|
||||
},
|
||||
{
|
||||
name: "update_merge_request",
|
||||
description:
|
||||
@ -436,6 +445,7 @@ const readOnlyTools = [
|
||||
"get_file_contents",
|
||||
"get_merge_request",
|
||||
"get_merge_request_diffs",
|
||||
"get_branch_diffs",
|
||||
"mr_discussions",
|
||||
"list_issues",
|
||||
"get_issue",
|
||||
@ -1552,7 +1562,50 @@ async function getMergeRequestDiffs(
|
||||
|
||||
await handleGitLabError(response);
|
||||
const data = (await response.json()) as { changes: unknown };
|
||||
return z.array(GitLabMergeRequestDiffSchema).parse(data.changes);
|
||||
return z.array(GitLabDiffSchema).parse(data.changes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get branch comparison diffs
|
||||
*
|
||||
* @param {string} projectId - The ID or URL-encoded path of the project
|
||||
* @param {string} from - The branch name or commit SHA to compare from
|
||||
* @param {string} to - The branch name or commit SHA to compare to
|
||||
* @param {boolean} [straight] - Comparison method: false for '...' (default), true for '--'
|
||||
* @returns {Promise<GitLabCompareResult>} Branch comparison results
|
||||
*/
|
||||
async function getBranchDiffs(
|
||||
projectId: string,
|
||||
from: string,
|
||||
to: string,
|
||||
straight?: boolean
|
||||
): Promise<GitLabCompareResult> {
|
||||
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||
|
||||
const url = new URL(
|
||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/compare`
|
||||
);
|
||||
|
||||
url.searchParams.append("from", from);
|
||||
url.searchParams.append("to", to);
|
||||
|
||||
if (straight !== undefined) {
|
||||
url.searchParams.append("straight", straight.toString());
|
||||
}
|
||||
|
||||
const response = await fetch(url.toString(), {
|
||||
...DEFAULT_FETCH_CONFIG,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorBody = await response.text();
|
||||
throw new Error(
|
||||
`GitLab API error: ${response.status} ${response.statusText}\n${errorBody}`
|
||||
);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return GitLabCompareResultSchema.parse(data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2414,6 +2467,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
};
|
||||
}
|
||||
|
||||
case "get_branch_diffs": {
|
||||
const args = GetBranchDiffsSchema.parse(request.params.arguments);
|
||||
const diffs = await getBranchDiffs(
|
||||
args.project_id,
|
||||
args.from,
|
||||
args.to,
|
||||
args.straight
|
||||
);
|
||||
return {
|
||||
content: [{ type: "text", text: JSON.stringify(diffs, null, 2) }],
|
||||
};
|
||||
}
|
||||
|
||||
case "search_repositories": {
|
||||
const args = SearchRepositoriesSchema.parse(request.params.arguments);
|
||||
const results = await searchProjects(
|
||||
|
50
schemas.ts
50
schemas.ts
@ -271,9 +271,15 @@ export const CreateMergeRequestOptionsSchema = z.object({
|
||||
draft: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const CreateBranchOptionsSchema = z.object({
|
||||
name: z.string(), // Changed from ref to match GitLab API
|
||||
ref: z.string(), // The source branch/commit for the new branch
|
||||
export const GitLabDiffSchema = z.object({
|
||||
old_path: z.string(),
|
||||
new_path: z.string(),
|
||||
a_mode: z.string(),
|
||||
b_mode: z.string(),
|
||||
diff: z.string(),
|
||||
new_file: z.boolean(),
|
||||
renamed_file: z.boolean(),
|
||||
deleted_file: z.boolean(),
|
||||
});
|
||||
|
||||
// Response schemas for operations
|
||||
@ -291,6 +297,27 @@ export const GitLabSearchResponseSchema = z.object({
|
||||
items: z.array(GitLabRepositorySchema),
|
||||
});
|
||||
|
||||
// create branch schemas
|
||||
export const CreateBranchOptionsSchema = z.object({
|
||||
name: z.string(), // Changed from ref to match GitLab API
|
||||
ref: z.string(), // The source branch/commit for the new branch
|
||||
});
|
||||
|
||||
export const GitLabCompareResultSchema = z.object({
|
||||
commit: z.object({
|
||||
id: z.string().optional(),
|
||||
short_id: z.string().optional(),
|
||||
title: z.string().optional(),
|
||||
author_name: z.string().optional(),
|
||||
author_email: z.string().optional(),
|
||||
created_at: z.string().optional(),
|
||||
}).optional(),
|
||||
commits: z.array(GitLabCommitSchema),
|
||||
diffs: z.array(GitLabDiffSchema),
|
||||
compare_timeout: z.boolean().optional(),
|
||||
compare_same_ref: z.boolean().optional(),
|
||||
});
|
||||
|
||||
// Issue related schemas
|
||||
export const GitLabLabelSchema = z.object({
|
||||
id: z.number(),
|
||||
@ -596,20 +623,16 @@ export const ForkRepositorySchema = ProjectParamsSchema.extend({
|
||||
namespace: z.string().optional().describe("Namespace to fork to (full path)"),
|
||||
});
|
||||
|
||||
// Branch related schemas
|
||||
export const CreateBranchSchema = ProjectParamsSchema.extend({
|
||||
branch: z.string().describe("Name for the new branch"),
|
||||
ref: z.string().optional().describe("Source branch/commit for new branch"),
|
||||
});
|
||||
|
||||
export const GitLabMergeRequestDiffSchema = z.object({
|
||||
old_path: z.string(),
|
||||
new_path: z.string(),
|
||||
a_mode: z.string(),
|
||||
b_mode: z.string(),
|
||||
diff: z.string(),
|
||||
new_file: z.boolean(),
|
||||
renamed_file: z.boolean(),
|
||||
deleted_file: z.boolean(),
|
||||
export const GetBranchDiffsSchema = ProjectParamsSchema.extend({
|
||||
from: z.string().describe("The base branch or commit SHA to compare from"),
|
||||
to: z.string().describe("The target branch or commit SHA to compare to"),
|
||||
straight: z.boolean().optional().describe("Comparison method: false for '...' (default), true for '--'"),
|
||||
});
|
||||
|
||||
export const GetMergeRequestSchema = ProjectParamsSchema.extend({
|
||||
@ -1082,6 +1105,7 @@ export type GitLabDirectoryContent = z.infer<
|
||||
export type GitLabContent = z.infer<typeof GitLabContentSchema>;
|
||||
export type FileOperation = z.infer<typeof FileOperationSchema>;
|
||||
export type GitLabTree = z.infer<typeof GitLabTreeSchema>;
|
||||
export type GitLabCompareResult = z.infer<typeof GitLabCompareResultSchema>;
|
||||
export type GitLabCommit = z.infer<typeof GitLabCommitSchema>;
|
||||
export type GitLabReference = z.infer<typeof GitLabReferenceSchema>;
|
||||
export type CreateRepositoryOptions = z.infer<
|
||||
@ -1097,7 +1121,7 @@ export type GitLabCreateUpdateFileResponse = z.infer<
|
||||
>;
|
||||
export type GitLabSearchResponse = z.infer<typeof GitLabSearchResponseSchema>;
|
||||
export type GitLabMergeRequestDiff = z.infer<
|
||||
typeof GitLabMergeRequestDiffSchema
|
||||
typeof GitLabDiffSchema
|
||||
>;
|
||||
export type CreateNoteOptions = z.infer<typeof CreateNoteSchema>;
|
||||
export type GitLabIssueLink = z.infer<typeof GitLabIssueLinkSchema>;
|
||||
|
Reference in New Issue
Block a user