All files / src/entities/iterations registry.ts

100% Statements 43/43
94.73% Branches 18/19
100% Functions 5/5
100% Lines 39/39

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 93 94  24x 24x 24x 24x 24x   24x             24x                       13x   13x   11x   8x   8x 8x 8x 8x 1x 8x 8x   8x 8x   8x 1x     7x       3x   3x 3x   3x 1x     2x                       24x 33x     24x 3x     24x     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 { getGitLabBaseUrl } from '../../utils/gitlab-base-url';
import { normalizeProjectId } from '../../utils/projectIdentifier';
import { ToolRegistry, EnhancedToolDefinition } from '../../types';
import { assertActionAllowed } from '../utils';
 
/**
 * 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),
      requirements: {
        default: { tier: 'premium', notes: 'Iterations/Sprints' },
      },
      handler: async (args: unknown) => {
        const input = BrowseIterationsSchema.parse(args);
 
        assertActionAllowed('browse_iterations', input.action);
 
        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 = `${getGitLabBaseUrl()}/api/v4/groups/${normalizeProjectId(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 = `${getGitLabBaseUrl()}/api/v4/groups/${normalizeProjectId(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();
}