Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 49 additions & 11 deletions src/tools/repos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function branchesFilterOutIrrelevantProperties(
?.flatMap((branch) => (branch.name ? [branch.name] : []))
?.filter((branch) => branch.startsWith("refs/heads/"))
.map((branch) => branch.replace("refs/heads/", ""))
.sort((a, b) => b.localeCompare(a))
.slice(0, top);
}

Expand Down Expand Up @@ -151,9 +152,11 @@ function configureRepoTools(
"Retrieve a list of repositories for a given project",
{
project: z.string().describe("The name or ID of the Azure DevOps project."),
top: z.number().default(100).describe("The maximum number of repositories to return."),
skip: z.number().default(0).describe("The number of repositories to skip. Defaults to 0."),
repoNameFilter: z.string().optional().describe("Optional filter to search for repositories by name. If provided, only repositories with names containing this string will be returned."),
},
async ({ project, repoNameFilter }) => {
async ({ project, top, skip, repoNameFilter }) => {
const connection = await connectionProvider();
const gitApi = await connection.getGitApi();
const repositories = await gitApi.getRepositories(
Expand All @@ -167,8 +170,12 @@ function configureRepoTools(
? filterReposByName(repositories, repoNameFilter)
: repositories;

const paginatedRepositories = filteredRepositories
?.sort((a, b) => a.name?.localeCompare(b.name ?? "") ?? 0)
.slice(skip, skip + top);

// Filter out the irrelevant properties
const trimmedRepositories = filteredRepositories?.map((repo) => ({
const trimmedRepositories = paginatedRepositories?.map((repo) => ({
id: repo.id,
name: repo.name,
isDisabled: repo.isDisabled,
Expand All @@ -191,11 +198,13 @@ function configureRepoTools(
"Retrieve a list of pull requests for a given repository.",
{
repositoryId: z.string().describe("The ID of the repository where the pull requests are located."),
top: z.number().default(100).describe("The maximum number of pull requests to return."),
skip: z.number().default(0).describe("The number of pull requests to skip."),
created_by_me: z.boolean().default(false).describe("Filter pull requests created by the current user."),
i_am_reviewer: z.boolean().default(false).describe("Filter pull requests where the current user is a reviewer."),
status: z.enum(["abandoned", "active", "all", "completed", "notSet"]).default("active").describe("Filter pull requests by status. Defaults to 'active'."),
},
async ({ repositoryId, created_by_me, i_am_reviewer, status }) => {
async ({ repositoryId, top, skip, created_by_me, i_am_reviewer, status }) => {
const connection = await connectionProvider();
const gitApi = await connection.getGitApi();

Expand Down Expand Up @@ -226,7 +235,11 @@ function configureRepoTools(

const pullRequests = await gitApi.getPullRequests(
repositoryId,
searchCriteria
searchCriteria,
undefined, // project
undefined, // maxCommentLength
skip,
top
);

// Filter out the irrelevant properties
Expand Down Expand Up @@ -256,11 +269,13 @@ function configureRepoTools(
"Retrieve a list of pull requests for a given project Id or Name.",
{
project: z.string().describe("The name or ID of the Azure DevOps project."),
top: z.number().default(100).describe("The maximum number of pull requests to return."),
skip: z.number().default(0).describe("The number of pull requests to skip."),
created_by_me: z.boolean().default(false).describe("Filter pull requests created by the current user."),
i_am_reviewer: z.boolean().default(false).describe("Filter pull requests where the current user is a reviewer."),
status: z.enum(["abandoned", "active", "all", "completed", "notSet"]).default("active").describe("Filter pull requests by status. Defaults to 'active'."),
},
async ({ project, created_by_me, i_am_reviewer, status }) => {
async ({ project, top, skip, created_by_me, i_am_reviewer, status }) => {
const connection = await connectionProvider();
const gitApi = await connection.getGitApi();

Expand Down Expand Up @@ -289,7 +304,10 @@ function configureRepoTools(

const pullRequests = await gitApi.getPullRequestsByProject(
project,
gitPullRequestSearchCriteria
gitPullRequestSearchCriteria,
undefined, // maxCommentLength
skip,
top
);

// Filter out the irrelevant properties
Expand Down Expand Up @@ -324,13 +342,17 @@ function configureRepoTools(
project: z.string().optional().describe("Project ID or project name (optional)"),
iteration: z.number().optional().describe("The iteration ID for which to retrieve threads. Optional, defaults to the latest iteration."),
baseIteration: z.number().optional().describe("The base iteration ID for which to retrieve threads. Optional, defaults to the latest base iteration."),
top: z.number().default(100).describe("The maximum number of threads to return."),
skip: z.number().default(0).describe("The number of threads to skip."),
},
async ({
repositoryId,
pullRequestId,
project,
iteration,
baseIteration,
top,
skip
}) => {
const connection = await connectionProvider();
const gitApi = await connection.getGitApi();
Expand All @@ -343,8 +365,12 @@ function configureRepoTools(
baseIteration
);

const paginatedThreads = threads
?.sort((a, b) => (a.id ?? 0) - (b.id ?? 0))
.slice(skip, skip + top);

return {
content: [{ type: "text", text: JSON.stringify(threads, null, 2) }],
content: [{ type: "text", text: JSON.stringify(paginatedThreads, null, 2) }],
};
}
);
Expand All @@ -357,8 +383,10 @@ function configureRepoTools(
pullRequestId: z.number().describe("The ID of the pull request for which to retrieve thread comments."),
threadId: z.number().describe("The ID of the thread for which to retrieve comments."),
project: z.string().optional().describe("Project ID or project name (optional)"),
top: z.number().default(100).describe("The maximum number of comments to return."),
skip: z.number().default(0).describe("The number of comments to skip."),
},
async ({ repositoryId, pullRequestId, threadId, project }) => {
async ({ repositoryId, pullRequestId, threadId, project, top, skip }) => {
const connection = await connectionProvider();
const gitApi = await connection.getGitApi();

Expand All @@ -370,8 +398,12 @@ function configureRepoTools(
project
);

const paginatedComments = comments
?.sort((a, b) => (a.id ?? 0) - (b.id ?? 0))
.slice(skip, skip + top);

return {
content: [{ type: "text", text: JSON.stringify(comments, null, 2) }],
content: [{ type: "text", text: JSON.stringify(paginatedComments, null, 2) }],
};
}
);
Expand Down Expand Up @@ -406,8 +438,9 @@ function configureRepoTools(
"Retrieve a list of my branches for a given repository Id.",
{
repositoryId: z.string().describe("The ID of the repository where the branches are located."),
top: z.number().default(100).describe("The maximum number of branches to return."),
},
async ({ repositoryId }) => {
async ({ repositoryId, top }) => {
const connection = await connectionProvider();
const gitApi = await connection.getGitApi();
const branches = await gitApi.getRefs(
Expand All @@ -419,8 +452,13 @@ function configureRepoTools(
true
);

const filteredBranches = branchesFilterOutIrrelevantProperties(
branches,
top
);

return {
content: [{ type: "text", text: JSON.stringify(branches, null, 2) }],
content: [{ type: "text", text: JSON.stringify(filteredBranches, null, 2) }],
};
}
);
Expand Down
Loading