Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 16x 16x 16x 16x 16x 12x 12x 2x 10x 7x 7x 7x 7x 7x 1x 7x 7x 7x 7x 7x 1x 6x 3x 3x 3x 3x 1x 2x 16x 12x 16x 3x 16x 3x 1x 1x 1x 2x | /* eslint-disable @typescript-eslint/no-unsafe-return */
import * as z from "zod";
import { BrowseIterationsSchema } from "./schema-readonly";
import { enhancedFetch } from "../../utils/fetch";
import { ToolRegistry, EnhancedToolDefinition } from "../../types";
import { isActionDenied } from "../../config";
/**
* Iterations tools registry - 1 CQRS tool
*
* browse_iterations (Query): list and get iterations for agile sprint planning
*/
export const iterationsToolRegistry: ToolRegistry = new Map<string, EnhancedToolDefinition>([
[
"browse_iterations",
{
name: "browse_iterations",
description:
"View group iterations for agile sprint planning. Actions: list (filter by state: current, upcoming, closed), get (retrieve specific iteration details). Related: browse_work_items for items in an iteration.",
inputSchema: z.toJSONSchema(BrowseIterationsSchema),
handler: async (args: unknown) => {
const input = BrowseIterationsSchema.parse(args);
// Runtime validation: reject denied actions even if they bypass schema filtering
if (isActionDenied("browse_iterations", input.action)) {
throw new Error(`Action '${input.action}' is not allowed for browse_iterations tool`);
}
switch (input.action) {
case "list": {
const { group_id } = input;
const queryParams = new URLSearchParams();
if (input.state) queryParams.set("state", input.state);
if (input.search) queryParams.set("search", input.search);
if (input.include_ancestors !== undefined)
queryParams.set("include_ancestors", String(input.include_ancestors));
Eif (input.per_page) queryParams.set("per_page", String(input.per_page));
if (input.page) queryParams.set("page", String(input.page));
const apiUrl = `${process.env.GITLAB_API_URL}/api/v4/groups/${encodeURIComponent(group_id)}/iterations?${queryParams}`;
const response = await enhancedFetch(apiUrl);
if (!response.ok) {
throw new Error(`GitLab API error: ${response.status} ${response.statusText}`);
}
return await response.json();
}
case "get": {
const { group_id, iteration_id } = input;
const apiUrl = `${process.env.GITLAB_API_URL}/api/v4/groups/${encodeURIComponent(group_id)}/iterations/${encodeURIComponent(iteration_id)}`;
const response = await enhancedFetch(apiUrl);
if (!response.ok) {
throw new Error(`GitLab API error: ${response.status} ${response.statusText}`);
}
return await response.json();
}
/* istanbul ignore next -- unreachable with Zod discriminatedUnion */
default:
throw new Error(`Unknown action: ${(input as { action: string }).action}`);
}
},
},
],
]);
export function getIterationsReadOnlyToolNames(): string[] {
return ["browse_iterations"];
}
export function getIterationsToolDefinitions(): EnhancedToolDefinition[] {
return Array.from(iterationsToolRegistry.values());
}
export function getFilteredIterationsTools(
readOnlyMode: boolean = false
): EnhancedToolDefinition[] {
if (readOnlyMode) {
const readOnlyNames = getIterationsReadOnlyToolNames();
return Array.from(iterationsToolRegistry.values()).filter(tool =>
readOnlyNames.includes(tool.name)
);
}
return getIterationsToolDefinitions();
}
|