Skip to content

Commit 474e1cc

Browse files
author
iwakitakuma
committed
FEAT: iteration
issue: #173
1 parent 863e057 commit 474e1cc

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

index.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ import {
181181
type GetCommitOptions,
182182
type GetCommitDiffOptions,
183183
ListMergeRequestDiffsSchema,
184+
ListGroupIterationsSchema,
185+
GroupIteration,
184186
} from "./schemas.js";
185187

186188
import { randomUUID } from "crypto";
@@ -736,6 +738,11 @@ const allTools = [
736738
description: "Get changes/diffs of a specific commit",
737739
inputSchema: zodToJsonSchema(GetCommitDiffSchema),
738740
},
741+
{
742+
name: "list_group_iterations",
743+
description: "List group iterations with filtering options",
744+
inputSchema: zodToJsonSchema(ListGroupIterationsSchema),
745+
},
739746
];
740747

741748
// Define which tools are read-only
@@ -777,6 +784,8 @@ const readOnlyTools = [
777784
"list_commits",
778785
"get_commit",
779786
"get_commit_diff",
787+
"list_group_iterations",
788+
"get_group_iteration",
780789
];
781790

782791
// Define which tools are related to wiki and can be toggled by USE_GITLAB_WIKI
@@ -3382,6 +3391,41 @@ async function getCommitDiff(
33823391
return z.array(GitLabDiffSchema).parse(data);
33833392
}
33843393

3394+
/**
3395+
* list group iterations
3396+
*
3397+
* @param {string} groupId
3398+
* @param {Omit<ListGroupIterationsOptions, "group_id">} options
3399+
* @returns {Promise<GetIt[]>}
3400+
*/
3401+
async function listGroupIterations(
3402+
groupId: string,
3403+
options: Omit<z.infer<typeof ListGroupIterationsSchema>, "group_id"> = {}
3404+
): Promise<GroupIteration[]> {
3405+
groupId = decodeURIComponent(groupId);
3406+
const url = new URL(`${GITLAB_API_URL}/groups/${encodeURIComponent(groupId)}/iterations`);
3407+
3408+
// クエリパラメータの追加
3409+
if (options.state) url.searchParams.append("state", options.state);
3410+
if (options.search) url.searchParams.append("search", options.search);
3411+
if (options.in) url.searchParams.append("in", options.in.join(","));
3412+
if (options.include_ancestors !== undefined) url.searchParams.append("include_ancestors", options.include_ancestors.toString());
3413+
if (options.include_descendants !== undefined) url.searchParams.append("include_descendants", options.include_descendants.toString());
3414+
if (options.updated_before) url.searchParams.append("updated_before", options.updated_before);
3415+
if (options.updated_after) url.searchParams.append("updated_after", options.updated_after);
3416+
if (options.page) url.searchParams.append("page", options.page.toString());
3417+
if (options.per_page) url.searchParams.append("per_page", options.per_page.toString());
3418+
3419+
const response = await fetch(url.toString(), DEFAULT_FETCH_CONFIG);
3420+
3421+
if (!response.ok) {
3422+
await handleGitLabError(response);
3423+
}
3424+
3425+
const data = await response.json();
3426+
return z.array(GroupIteration).parse(data);
3427+
}
3428+
33853429
server.setRequestHandler(ListToolsRequestSchema, async () => {
33863430
// Apply read-only filter first
33873431
const tools0 = GITLAB_READ_ONLY_MODE
@@ -4326,6 +4370,14 @@ server.setRequestHandler(CallToolRequestSchema, async request => {
43264370
};
43274371
}
43284372

4373+
case "list_group_iterations": {
4374+
const args = ListGroupIterationsSchema.parse(request.params.arguments);
4375+
const iterations = await listGroupIterations(args.group_id, args);
4376+
return {
4377+
content: [{ type: "text", text: JSON.stringify(iterations, null, 2) }],
4378+
};
4379+
}
4380+
43294381
default:
43304382
throw new Error(`Unknown tool: ${request.params.name}`);
43314383
}

schemas.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,8 @@ export const ListIssuesSchema = z.object({
935935
due_date: z.string().optional().describe("Return issues that have the due date"),
936936
labels: z.array(z.string()).optional().describe("Array of label names"),
937937
milestone: z.string().optional().describe("Milestone title"),
938+
issue_type: z.string().optional().nullable().describe("Filter to a given type of issue. One of issue, incident, test_case or task"),
939+
iteration_id: z.coerce.string().optional().nullable().describe("Return issues assigned to the given iteration ID. None returns issues that do not belong to an iteration. Any returns issues that belong to an iteration. "),
938940
scope: z
939941
.enum(["created_by_me", "assigned_to_me", "all"])
940942
.optional()
@@ -1361,6 +1363,32 @@ export const GetCommitDiffSchema = z.object({
13611363
sha: z.string().describe("The commit hash or name of a repository branch or tag"),
13621364
});
13631365

1366+
export const GroupIteration = z.object({
1367+
id: z.coerce.string(),
1368+
iid: z.coerce.string(),
1369+
sequence: z.number(),
1370+
group_id: z.coerce.string(),
1371+
title: z.string().optional().nullable(),
1372+
description: z.string().optional().nullable(),
1373+
state: z.number(),
1374+
created_at: z.string(),
1375+
updated_at: z.string(),
1376+
due_date: z.string().optional().nullable(),
1377+
start_date: z.string().optional().nullable(),
1378+
web_url: z.string().optional().nullable(),
1379+
});
1380+
1381+
export const ListGroupIterationsSchema = z.object({
1382+
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
1383+
state: z.enum(["opened", "upcoming", "current", "closed", "all"]).optional().describe("Return opened, upcoming, current, closed, or all iterations."),
1384+
search: z.string().optional().describe("Return only iterations with a title matching the provided string."),
1385+
in: z.array(z.enum(["title", "cadence_title"])).optional().describe("Fields in which fuzzy search should be performed with the query given in the argument search. The available options are title and cadence_title. Default is [title]."),
1386+
include_ancestors: flexibleBoolean.optional().describe("Include iterations for group and its ancestors. Defaults to true."),
1387+
include_descendants: flexibleBoolean.optional().describe("Include iterations for group and its descendants. Defaults to false."),
1388+
updated_before: z.string().optional().describe("Return only iterations updated before the given datetime. Expected in ISO 8601 format (2019-03-15T08:00:00Z)."),
1389+
updated_after: z.string().optional().describe("Return only iterations updated after the given datetime. Expected in ISO 8601 format (2019-03-15T08:00:00Z)."),
1390+
}).merge(PaginationOptionsSchema);
1391+
13641392
// Export types
13651393
export type GitLabAuthor = z.infer<typeof GitLabAuthorSchema>;
13661394
export type GitLabFork = z.infer<typeof GitLabForkSchema>;
@@ -1430,3 +1458,5 @@ export type PaginationOptions = z.infer<typeof PaginationOptionsSchema>;
14301458
export type ListCommitsOptions = z.infer<typeof ListCommitsSchema>;
14311459
export type GetCommitOptions = z.infer<typeof GetCommitSchema>;
14321460
export type GetCommitDiffOptions = z.infer<typeof GetCommitDiffSchema>;
1461+
export type GroupIteration = z.infer<typeof GroupIteration>;
1462+
export type ListGroupIterationsOptions = z.infer<typeof ListGroupIterationsSchema>;

0 commit comments

Comments
 (0)