Skip to content

Commit 023ac90

Browse files
committed
feat: added milestone support
1 parent 513d5ed commit 023ac90

File tree

8 files changed

+1316
-7
lines changed

8 files changed

+1316
-7
lines changed

src/__tests__/graphql-client.test.ts

Lines changed: 434 additions & 1 deletion
Large diffs are not rendered by default.

src/core/handlers/handler.factory.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ProjectHandler } from '../../features/projects/handlers/project.handler
66
import { TeamHandler } from '../../features/teams/handlers/team.handler.js';
77
import { UserHandler } from '../../features/users/handlers/user.handler.js';
88
import { CommentHandler } from '../../features/comments/handlers/comment.handler.js';
9+
import { MilestoneHandler } from '../../features/milestones/handlers/milestone.handler.js';
910

1011
/**
1112
* Factory for creating and managing feature-specific handlers.
@@ -18,6 +19,7 @@ export class HandlerFactory {
1819
private teamHandler: TeamHandler;
1920
private userHandler: UserHandler;
2021
private commentHandler: CommentHandler;
22+
private milestoneHandler: MilestoneHandler;
2123

2224
constructor(auth: LinearAuth, graphqlClient?: LinearGraphQLClient) {
2325
// Initialize all handlers with shared dependencies
@@ -27,13 +29,14 @@ export class HandlerFactory {
2729
this.teamHandler = new TeamHandler(auth, graphqlClient);
2830
this.userHandler = new UserHandler(auth, graphqlClient);
2931
this.commentHandler = new CommentHandler(auth, graphqlClient);
32+
this.milestoneHandler = new MilestoneHandler(auth, graphqlClient);
3033
}
3134

3235
/**
3336
* Gets the appropriate handler for a given tool name.
3437
*/
3538
getHandlerForTool(toolName: string): {
36-
handler: AuthHandler | IssueHandler | ProjectHandler | TeamHandler | UserHandler | CommentHandler;
39+
handler: AuthHandler | IssueHandler | ProjectHandler | TeamHandler | UserHandler | CommentHandler | MilestoneHandler;
3740
method: string;
3841
} {
3942
// Map tool names to their handlers and methods
@@ -64,6 +67,15 @@ export class HandlerFactory {
6467
// Comment tools
6568
linear_get_issue_comments: { handler: this.commentHandler, method: 'handleGetIssueComments' },
6669
linear_create_comment: { handler: this.commentHandler, method: 'handleCreateComment' },
70+
71+
// Milestone tools
72+
linear_create_project_milestone: { handler: this.milestoneHandler, method: 'handleCreateProjectMilestone' },
73+
linear_update_project_milestone: { handler: this.milestoneHandler, method: 'handleUpdateProjectMilestone' },
74+
linear_delete_project_milestone: { handler: this.milestoneHandler, method: 'handleDeleteProjectMilestone' },
75+
linear_get_project_milestone: { handler: this.milestoneHandler, method: 'handleGetProjectMilestone' },
76+
linear_search_project_milestones: { handler: this.milestoneHandler, method: 'handleSearchProjectMilestones' },
77+
linear_get_project_milestones: { handler: this.milestoneHandler, method: 'handleGetProjectMilestones' },
78+
linear_create_project_milestones: { handler: this.milestoneHandler, method: 'handleCreateProjectMilestones' },
6779
};
6880

6981
const handlerInfo = handlerMap[toolName];
@@ -73,4 +85,4 @@ export class HandlerFactory {
7385

7486
return handlerInfo;
7587
}
76-
}
88+
}

src/core/types/tool.types.ts

Lines changed: 219 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,4 +498,222 @@ export const toolSchemas = {
498498
required: ['body', 'issueId'],
499499
},
500500
},
501-
};
501+
502+
linear_create_project_milestone: {
503+
name: 'linear_create_project_milestone',
504+
description: 'Create a new project milestone in Linear',
505+
inputSchema: {
506+
type: 'object',
507+
properties: {
508+
name: {
509+
type: 'string',
510+
description: 'The name of the project milestone',
511+
},
512+
projectId: {
513+
type: 'string',
514+
description: 'The ID of the project this milestone belongs to',
515+
},
516+
description: {
517+
type: 'string',
518+
description: 'The description of the project milestone in markdown format',
519+
optional: true,
520+
},
521+
targetDate: {
522+
type: 'string',
523+
description: 'The planned target date of the project milestone (ISO 8601 format)',
524+
optional: true,
525+
},
526+
sortOrder: {
527+
type: 'number',
528+
description: 'The sort order for the project milestone within a project',
529+
optional: true,
530+
},
531+
},
532+
required: ['name', 'projectId'],
533+
},
534+
},
535+
536+
linear_update_project_milestone: {
537+
name: 'linear_update_project_milestone',
538+
description: 'Update an existing project milestone',
539+
inputSchema: {
540+
type: 'object',
541+
properties: {
542+
id: {
543+
type: 'string',
544+
description: 'The ID of the project milestone to update',
545+
},
546+
name: {
547+
type: 'string',
548+
description: 'The name of the project milestone',
549+
optional: true,
550+
},
551+
description: {
552+
type: 'string',
553+
description: 'The description of the project milestone in markdown format',
554+
optional: true,
555+
},
556+
targetDate: {
557+
type: 'string',
558+
description: 'The planned target date of the project milestone (ISO 8601 format)',
559+
optional: true,
560+
},
561+
projectId: {
562+
type: 'string',
563+
description: 'The ID of the project this milestone belongs to',
564+
optional: true,
565+
},
566+
sortOrder: {
567+
type: 'number',
568+
description: 'The sort order for the project milestone within a project',
569+
optional: true,
570+
},
571+
},
572+
required: ['id'],
573+
},
574+
},
575+
576+
linear_delete_project_milestone: {
577+
name: 'linear_delete_project_milestone',
578+
description: 'Delete a project milestone',
579+
inputSchema: {
580+
type: 'object',
581+
properties: {
582+
id: {
583+
type: 'string',
584+
description: 'The ID of the project milestone to delete',
585+
},
586+
},
587+
required: ['id'],
588+
},
589+
},
590+
591+
linear_get_project_milestone: {
592+
name: 'linear_get_project_milestone',
593+
description: 'Get information about a specific project milestone',
594+
inputSchema: {
595+
type: 'object',
596+
properties: {
597+
id: {
598+
type: 'string',
599+
description: 'The ID of the project milestone to retrieve',
600+
},
601+
},
602+
required: ['id'],
603+
},
604+
},
605+
606+
linear_search_project_milestones: {
607+
name: 'linear_search_project_milestones',
608+
description: 'Search for project milestones with filtering and pagination',
609+
inputSchema: {
610+
type: 'object',
611+
properties: {
612+
name: {
613+
type: 'string',
614+
description: 'Filter by milestone name (exact match)',
615+
optional: true,
616+
},
617+
projectId: {
618+
type: 'string',
619+
description: 'Filter by project ID',
620+
optional: true,
621+
},
622+
targetDate: {
623+
type: 'string',
624+
description: 'Filter by target date (ISO 8601 format)',
625+
optional: true,
626+
},
627+
first: {
628+
type: 'number',
629+
description: 'Number of milestones to return (default: 50)',
630+
optional: true,
631+
},
632+
after: {
633+
type: 'string',
634+
description: 'Cursor for pagination',
635+
optional: true,
636+
},
637+
orderBy: {
638+
type: 'string',
639+
description: 'Field to order by (default: updatedAt)',
640+
optional: true,
641+
},
642+
},
643+
},
644+
},
645+
646+
linear_get_project_milestones: {
647+
name: 'linear_get_project_milestones',
648+
description: 'Get all milestones for a specific project',
649+
inputSchema: {
650+
type: 'object',
651+
properties: {
652+
projectId: {
653+
type: 'string',
654+
description: 'The ID of the project to get milestones for',
655+
},
656+
first: {
657+
type: 'number',
658+
description: 'Number of milestones to return (default: 50)',
659+
optional: true,
660+
},
661+
after: {
662+
type: 'string',
663+
description: 'Cursor for pagination',
664+
optional: true,
665+
},
666+
orderBy: {
667+
type: 'string',
668+
description: 'Field to order by (default: sortOrder)',
669+
optional: true,
670+
},
671+
},
672+
required: ['projectId'],
673+
},
674+
},
675+
676+
linear_create_project_milestones: {
677+
name: 'linear_create_project_milestones',
678+
description: 'Create multiple project milestones at once',
679+
inputSchema: {
680+
type: 'object',
681+
properties: {
682+
projectId: {
683+
type: 'string',
684+
description: 'The ID of the project to create milestones for',
685+
},
686+
milestones: {
687+
type: 'array',
688+
items: {
689+
type: 'object',
690+
properties: {
691+
name: {
692+
type: 'string',
693+
description: 'The name of the project milestone',
694+
},
695+
description: {
696+
type: 'string',
697+
description: 'The description of the project milestone in markdown format',
698+
optional: true,
699+
},
700+
targetDate: {
701+
type: 'string',
702+
description: 'The planned target date of the project milestone (ISO 8601 format)',
703+
optional: true,
704+
},
705+
sortOrder: {
706+
type: 'number',
707+
description: 'The sort order for the project milestone within a project',
708+
optional: true,
709+
},
710+
},
711+
required: ['name'],
712+
},
713+
description: 'Array of milestones to create',
714+
},
715+
},
716+
required: ['projectId', 'milestones'],
717+
},
718+
},
719+
};

0 commit comments

Comments
 (0)