@zereight/mcp-gitlab 1.0.76 → 2.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -67
- package/build/customSchemas.js +11 -4
- package/build/index.js +623 -38
- package/build/schemas.js +533 -106
- package/build/src/argon2wrapper.js +68 -0
- package/build/src/authentication.js +78 -0
- package/build/src/authhelpers.js +44 -0
- package/build/src/config.js +99 -0
- package/build/src/customSchemas.js +21 -0
- package/build/src/gitlabhandler.js +1649 -0
- package/build/src/gitlabsession.js +103 -0
- package/build/src/logger.js +11 -0
- package/build/src/mcpserver.js +1331 -0
- package/build/src/oauth.js +389 -0
- package/build/src/schemas.js +1678 -0
- package/package.json +3 -2
- package/build/utils.js +0 -9
package/build/schemas.js
CHANGED
|
@@ -91,6 +91,72 @@ export const GitLabPipelineJobSchema = z.object({
|
|
|
91
91
|
.optional(),
|
|
92
92
|
web_url: z.string().optional(),
|
|
93
93
|
});
|
|
94
|
+
// Pipeline trigger job (bridge) schema
|
|
95
|
+
export const GitLabPipelineTriggerJobSchema = z.object({
|
|
96
|
+
id: z.coerce.string(),
|
|
97
|
+
status: z.string(),
|
|
98
|
+
stage: z.string(),
|
|
99
|
+
name: z.string(),
|
|
100
|
+
ref: z.string(),
|
|
101
|
+
tag: flexibleBoolean,
|
|
102
|
+
coverage: z.number().nullable().optional(),
|
|
103
|
+
created_at: z.string(),
|
|
104
|
+
started_at: z.string().nullable().optional(),
|
|
105
|
+
finished_at: z.string().nullable().optional(),
|
|
106
|
+
duration: z.number().nullable().optional(),
|
|
107
|
+
queued_duration: z.number().nullable().optional(),
|
|
108
|
+
user: z
|
|
109
|
+
.object({
|
|
110
|
+
id: z.coerce.string(),
|
|
111
|
+
name: z.string(),
|
|
112
|
+
username: z.string(),
|
|
113
|
+
avatar_url: z.string().nullable().optional(),
|
|
114
|
+
})
|
|
115
|
+
.optional(),
|
|
116
|
+
commit: z
|
|
117
|
+
.object({
|
|
118
|
+
id: z.string(),
|
|
119
|
+
short_id: z.string(),
|
|
120
|
+
title: z.string(),
|
|
121
|
+
author_name: z.string(),
|
|
122
|
+
author_email: z.string(),
|
|
123
|
+
})
|
|
124
|
+
.optional(),
|
|
125
|
+
pipeline: z
|
|
126
|
+
.object({
|
|
127
|
+
id: z.coerce.string(),
|
|
128
|
+
project_id: z.coerce.string(),
|
|
129
|
+
status: z.string(),
|
|
130
|
+
ref: z.string(),
|
|
131
|
+
sha: z.string(),
|
|
132
|
+
created_at: z.string().optional(),
|
|
133
|
+
updated_at: z.string().optional(),
|
|
134
|
+
web_url: z.string().optional(),
|
|
135
|
+
})
|
|
136
|
+
.optional(),
|
|
137
|
+
web_url: z.string().optional(),
|
|
138
|
+
allow_failure: flexibleBoolean.optional(),
|
|
139
|
+
archived: flexibleBoolean.optional(),
|
|
140
|
+
source: z.string().optional(),
|
|
141
|
+
erased_at: z.string().nullable().optional(),
|
|
142
|
+
project: z
|
|
143
|
+
.object({
|
|
144
|
+
ci_job_token_scope_enabled: flexibleBoolean.optional(),
|
|
145
|
+
})
|
|
146
|
+
.optional(),
|
|
147
|
+
downstream_pipeline: z
|
|
148
|
+
.object({
|
|
149
|
+
id: z.coerce.string(),
|
|
150
|
+
sha: z.string(),
|
|
151
|
+
ref: z.string(),
|
|
152
|
+
status: z.string(),
|
|
153
|
+
created_at: z.string(),
|
|
154
|
+
updated_at: z.string(),
|
|
155
|
+
web_url: z.string(),
|
|
156
|
+
})
|
|
157
|
+
.nullable()
|
|
158
|
+
.optional(),
|
|
159
|
+
});
|
|
94
160
|
// Shared base schema for various pagination options
|
|
95
161
|
// See https://docs.gitlab.com/api/rest/#pagination
|
|
96
162
|
export const PaginationOptionsSchema = z.object({
|
|
@@ -98,7 +164,8 @@ export const PaginationOptionsSchema = z.object({
|
|
|
98
164
|
per_page: z.number().optional().describe("Number of items per page (max: 100, default: 20)"),
|
|
99
165
|
});
|
|
100
166
|
// Schema for listing pipelines
|
|
101
|
-
export const ListPipelinesSchema = z
|
|
167
|
+
export const ListPipelinesSchema = z
|
|
168
|
+
.object({
|
|
102
169
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
103
170
|
scope: z
|
|
104
171
|
.enum(["running", "pending", "finished", "branches", "tags"])
|
|
@@ -122,7 +189,9 @@ export const ListPipelinesSchema = z.object({
|
|
|
122
189
|
.describe("The status of pipelines"),
|
|
123
190
|
ref: z.string().optional().describe("The ref of pipelines"),
|
|
124
191
|
sha: z.string().optional().describe("The SHA of pipelines"),
|
|
125
|
-
yaml_errors: flexibleBoolean
|
|
192
|
+
yaml_errors: flexibleBoolean
|
|
193
|
+
.optional()
|
|
194
|
+
.describe("Returns pipelines with invalid configurations"),
|
|
126
195
|
username: z.string().optional().describe("The username of the user who triggered pipelines"),
|
|
127
196
|
updated_after: z
|
|
128
197
|
.string()
|
|
@@ -137,14 +206,16 @@ export const ListPipelinesSchema = z.object({
|
|
|
137
206
|
.optional()
|
|
138
207
|
.describe("Order pipelines by"),
|
|
139
208
|
sort: z.enum(["asc", "desc"]).optional().describe("Sort pipelines"),
|
|
140
|
-
})
|
|
209
|
+
})
|
|
210
|
+
.merge(PaginationOptionsSchema);
|
|
141
211
|
// Schema for getting a specific pipeline
|
|
142
212
|
export const GetPipelineSchema = z.object({
|
|
143
213
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
144
214
|
pipeline_id: z.coerce.string().describe("The ID of the pipeline"),
|
|
145
215
|
});
|
|
146
216
|
// Schema for listing jobs in a pipeline
|
|
147
|
-
export const ListPipelineJobsSchema = z
|
|
217
|
+
export const ListPipelineJobsSchema = z
|
|
218
|
+
.object({
|
|
148
219
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
149
220
|
pipeline_id: z.coerce.string().describe("The ID of the pipeline"),
|
|
150
221
|
scope: z
|
|
@@ -152,7 +223,33 @@ export const ListPipelineJobsSchema = z.object({
|
|
|
152
223
|
.optional()
|
|
153
224
|
.describe("The scope of jobs to show"),
|
|
154
225
|
include_retried: flexibleBoolean.optional().describe("Whether to include retried jobs"),
|
|
155
|
-
})
|
|
226
|
+
})
|
|
227
|
+
.merge(PaginationOptionsSchema);
|
|
228
|
+
// Schema for listing trigger jobs (bridges) in a pipeline
|
|
229
|
+
export const ListPipelineTriggerJobsSchema = z
|
|
230
|
+
.object({
|
|
231
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
232
|
+
pipeline_id: z.coerce.string().describe("The ID of the pipeline"),
|
|
233
|
+
scope: z
|
|
234
|
+
// https://docs.gitlab.com/api/jobs/#job-status-values
|
|
235
|
+
.enum([
|
|
236
|
+
"canceled",
|
|
237
|
+
"canceling",
|
|
238
|
+
"created",
|
|
239
|
+
"failed",
|
|
240
|
+
"manual",
|
|
241
|
+
"pending",
|
|
242
|
+
"preparing",
|
|
243
|
+
"running",
|
|
244
|
+
"scheduled",
|
|
245
|
+
"skipped",
|
|
246
|
+
"success",
|
|
247
|
+
"waiting_for_resource",
|
|
248
|
+
])
|
|
249
|
+
.optional()
|
|
250
|
+
.describe("The scope of trigger jobs to show"),
|
|
251
|
+
})
|
|
252
|
+
.merge(PaginationOptionsSchema);
|
|
156
253
|
// Schema for creating a new pipeline
|
|
157
254
|
export const CreatePipelineSchema = z.object({
|
|
158
255
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -176,27 +273,35 @@ export const CancelPipelineSchema = RetryPipelineSchema;
|
|
|
176
273
|
export const GetPipelineJobOutputSchema = z.object({
|
|
177
274
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
178
275
|
job_id: z.coerce.string().describe("The ID of the job"),
|
|
179
|
-
limit: z
|
|
180
|
-
|
|
276
|
+
limit: z
|
|
277
|
+
.number()
|
|
278
|
+
.optional()
|
|
279
|
+
.describe("Maximum number of lines to return from the end of the log (default: 1000)"),
|
|
280
|
+
offset: z
|
|
281
|
+
.number()
|
|
282
|
+
.optional()
|
|
283
|
+
.describe("Number of lines to skip from the end of the log (default: 0)"),
|
|
181
284
|
});
|
|
182
285
|
// User schemas
|
|
183
286
|
export const GitLabUserSchema = z.object({
|
|
184
|
-
username: z.string(), // Changed from login to match GitLab API
|
|
287
|
+
username: z.string().optional(), // Changed from login to match GitLab API
|
|
185
288
|
id: z.coerce.string(),
|
|
186
|
-
name: z.string(),
|
|
187
|
-
avatar_url: z.string().nullable(),
|
|
188
|
-
web_url: z.string(), // Changed from html_url to match GitLab API
|
|
289
|
+
name: z.string().optional(),
|
|
290
|
+
avatar_url: z.string().nullable().optional(),
|
|
291
|
+
web_url: z.string().optional(), // Changed from html_url to match GitLab API
|
|
189
292
|
});
|
|
190
293
|
export const GetUsersSchema = z.object({
|
|
191
294
|
usernames: z.array(z.string()).describe("Array of usernames to search for"),
|
|
192
295
|
});
|
|
193
|
-
export const GitLabUsersResponseSchema = z.record(z.string(), z
|
|
296
|
+
export const GitLabUsersResponseSchema = z.record(z.string(), z
|
|
297
|
+
.object({
|
|
194
298
|
id: z.coerce.string(),
|
|
195
299
|
username: z.string(),
|
|
196
300
|
name: z.string(),
|
|
197
301
|
avatar_url: z.string().nullable(),
|
|
198
302
|
web_url: z.string(),
|
|
199
|
-
})
|
|
303
|
+
})
|
|
304
|
+
.nullable());
|
|
200
305
|
// Namespace related schemas
|
|
201
306
|
// Base schema for project-related operations
|
|
202
307
|
const ProjectParamsSchema = z.object({
|
|
@@ -376,11 +481,13 @@ export const GitLabCommitSchema = z.object({
|
|
|
376
481
|
message: z.string().optional(), // Add full message field
|
|
377
482
|
web_url: z.string(), // Changed from html_url to match GitLab API
|
|
378
483
|
parent_ids: z.array(z.string()), // Changed from parents to match GitLab API
|
|
379
|
-
stats: z
|
|
484
|
+
stats: z
|
|
485
|
+
.object({
|
|
380
486
|
additions: z.number().optional().nullable(),
|
|
381
487
|
deletions: z.number().optional().nullable(),
|
|
382
488
|
total: z.number().optional().nullable(),
|
|
383
|
-
})
|
|
489
|
+
})
|
|
490
|
+
.optional(), // Only present when with_stats=true
|
|
384
491
|
trailers: z.record(z.string()).optional().default({}), // Git trailers, may be empty object
|
|
385
492
|
extended_trailers: z.record(z.array(z.string())).optional().default({}), // Extended trailers, may be empty object
|
|
386
493
|
});
|
|
@@ -450,14 +557,16 @@ export const CreateBranchOptionsSchema = z.object({
|
|
|
450
557
|
ref: z.string(), // The source branch/commit for the new branch
|
|
451
558
|
});
|
|
452
559
|
export const GitLabCompareResultSchema = z.object({
|
|
453
|
-
commit: z
|
|
560
|
+
commit: z
|
|
561
|
+
.object({
|
|
454
562
|
id: z.string().optional(),
|
|
455
563
|
short_id: z.string().optional(),
|
|
456
564
|
title: z.string().optional(),
|
|
457
565
|
author_name: z.string().optional(),
|
|
458
566
|
author_email: z.string().optional(),
|
|
459
567
|
created_at: z.string().optional(),
|
|
460
|
-
})
|
|
568
|
+
})
|
|
569
|
+
.optional(),
|
|
461
570
|
commits: z.array(GitLabCommitSchema),
|
|
462
571
|
diffs: z.array(GitLabDiffSchema),
|
|
463
572
|
compare_timeout: flexibleBoolean.optional(),
|
|
@@ -520,6 +629,7 @@ export const GitLabIssueSchema = z.object({
|
|
|
520
629
|
due_date: z.string().nullable().optional(),
|
|
521
630
|
discussion_locked: flexibleBooleanNullable.optional(),
|
|
522
631
|
weight: z.number().nullable().optional(),
|
|
632
|
+
issue_type: z.string().describe("the type of issue.").nullish(),
|
|
523
633
|
});
|
|
524
634
|
// NEW SCHEMA: For issue with link details (used in listing issue links)
|
|
525
635
|
export const GitLabIssueWithLinkDetailsSchema = GitLabIssueSchema.extend({
|
|
@@ -585,32 +695,70 @@ export const GitLabMergeRequestSchema = z.object({
|
|
|
585
695
|
squash: flexibleBoolean.optional(),
|
|
586
696
|
labels: z.array(z.string()).optional(),
|
|
587
697
|
});
|
|
588
|
-
export const LineRangeSchema = z
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
type: z
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
698
|
+
export const LineRangeSchema = z
|
|
699
|
+
.object({
|
|
700
|
+
start: z
|
|
701
|
+
.object({
|
|
702
|
+
line_code: z
|
|
703
|
+
.string()
|
|
704
|
+
.nullable()
|
|
705
|
+
.optional()
|
|
706
|
+
.describe("CRITICAL: Line identifier in format '{file_path_sha1_hash}_{old_line_number}_{new_line_number}'. USUALLY REQUIRED for GitLab diff comments despite being optional in schema. Example: 'a1b2c3d4e5f6_10_15'. Get this from GitLab diff API response, never fabricate."),
|
|
707
|
+
type: z
|
|
708
|
+
.enum(["new", "old", "expanded"])
|
|
709
|
+
.nullable()
|
|
710
|
+
.optional()
|
|
711
|
+
.describe("Line type: 'old' = deleted/original line, 'new' = added/modified line, null = unchanged context. MUST match the line_code format and old_line/new_line values."),
|
|
712
|
+
old_line: z
|
|
713
|
+
.number()
|
|
714
|
+
.nullable()
|
|
715
|
+
.optional()
|
|
716
|
+
.describe("Line number in original file (before changes). REQUIRED when type='old', NULL when type='new' (for purely added lines), can be present for context lines."),
|
|
717
|
+
new_line: z
|
|
718
|
+
.number()
|
|
719
|
+
.nullable()
|
|
720
|
+
.optional()
|
|
721
|
+
.describe("Line number in modified file (after changes). REQUIRED when type='new', NULL when type='old' (for purely deleted lines), can be present for context lines."),
|
|
722
|
+
})
|
|
723
|
+
.describe("Start line position for multiline comment range. MUST specify either old_line OR new_line (or both for context), never neither."),
|
|
724
|
+
end: z
|
|
725
|
+
.object({
|
|
726
|
+
line_code: z
|
|
727
|
+
.string()
|
|
728
|
+
.nullable()
|
|
729
|
+
.optional()
|
|
730
|
+
.describe("CRITICAL: Line identifier in format '{file_path_sha1_hash}_{old_line_number}_{new_line_number}'. USUALLY REQUIRED for GitLab diff comments despite being optional in schema. Example: 'a1b2c3d4e5f6_12_17'. Must be from same file as start.line_code."),
|
|
731
|
+
type: z
|
|
732
|
+
.enum(["new", "old", "expanded"])
|
|
733
|
+
.nullable()
|
|
734
|
+
.optional()
|
|
735
|
+
.describe("Line type: 'old' = deleted/original line, 'new' = added/modified line, null = unchanged context. SHOULD MATCH start.type for consistent ranges (don't mix old/new types)."),
|
|
736
|
+
old_line: z
|
|
737
|
+
.number()
|
|
738
|
+
.nullable()
|
|
739
|
+
.optional()
|
|
740
|
+
.describe("Line number in original file (before changes). REQUIRED when type='old', NULL when type='new' (for purely added lines), can be present for context lines. MUST be >= start.old_line if both specified."),
|
|
741
|
+
new_line: z
|
|
742
|
+
.number()
|
|
743
|
+
.nullable()
|
|
744
|
+
.optional()
|
|
745
|
+
.describe("Line number in modified file (after changes). REQUIRED when type='new', NULL when type='old' (for purely deleted lines), can be present for context lines. MUST be >= start.new_line if both specified."),
|
|
746
|
+
})
|
|
747
|
+
.describe("End line position for multiline comment range. MUST specify either old_line OR new_line (or both for context), never neither. Range must be valid (end >= start)."),
|
|
748
|
+
})
|
|
749
|
+
.describe("Line range for multiline comments on GitLab merge request diffs. VALIDATION RULES: 1) line_code is critical for GitLab API success, 2) start/end must have consistent types, 3) line numbers must form valid range, 4) get line_code from GitLab diff API, never generate manually.");
|
|
602
750
|
// Discussion related schemas
|
|
603
751
|
export const GitLabDiscussionNoteSchema = z.object({
|
|
604
752
|
id: z.coerce.string(),
|
|
605
|
-
type: z.enum(["DiscussionNote", "DiffNote", "Note"]).nullable(), // Allow null type for regular notes
|
|
606
|
-
body: z.string(),
|
|
607
|
-
attachment: z.any().nullable(), // Can be string or object, handle appropriately
|
|
608
|
-
author: GitLabUserSchema,
|
|
609
|
-
created_at: z.string(),
|
|
610
|
-
updated_at: z.string(),
|
|
611
|
-
system: flexibleBoolean,
|
|
612
|
-
noteable_id: z.coerce.string(),
|
|
613
|
-
noteable_type: z.enum(["Issue", "MergeRequest", "Snippet", "Commit", "Epic"]),
|
|
753
|
+
type: z.enum(["DiscussionNote", "DiffNote", "Note"]).nullable().optional(), // Allow null type for regular notes
|
|
754
|
+
body: z.string().optional(),
|
|
755
|
+
attachment: z.any().nullable().optional(), // Can be string or object, handle appropriately
|
|
756
|
+
author: GitLabUserSchema.optional(),
|
|
757
|
+
created_at: z.string().optional(),
|
|
758
|
+
updated_at: z.string().optional(),
|
|
759
|
+
system: flexibleBoolean.optional(),
|
|
760
|
+
noteable_id: z.coerce.string().optional(),
|
|
761
|
+
noteable_type: z.enum(["Issue", "MergeRequest", "Snippet", "Commit", "Epic"]).optional(),
|
|
614
762
|
project_id: z.coerce.string().optional(),
|
|
615
763
|
noteable_iid: z.coerce.string().nullable().optional(),
|
|
616
764
|
resolvable: flexibleBoolean.optional(),
|
|
@@ -620,22 +768,31 @@ export const GitLabDiscussionNoteSchema = z.object({
|
|
|
620
768
|
position: z
|
|
621
769
|
.object({
|
|
622
770
|
// Only present for DiffNote
|
|
623
|
-
base_sha: z.string(),
|
|
624
|
-
start_sha: z.string(),
|
|
625
|
-
head_sha: z.string(),
|
|
771
|
+
base_sha: z.string().optional(),
|
|
772
|
+
start_sha: z.string().optional(),
|
|
773
|
+
head_sha: z.string().optional(),
|
|
626
774
|
old_path: z.string().nullable().optional().describe("File path before change"),
|
|
627
775
|
new_path: z.string().nullable().optional().describe("File path after change"),
|
|
628
|
-
position_type: z.enum(["text", "image", "file"]),
|
|
629
|
-
new_line: z
|
|
630
|
-
|
|
776
|
+
position_type: z.enum(["text", "image", "file"]).optional(),
|
|
777
|
+
new_line: z
|
|
778
|
+
.number()
|
|
779
|
+
.nullable()
|
|
780
|
+
.optional()
|
|
781
|
+
.describe("Line number in the modified file (after changes). Used for added lines and context lines. Null for deleted lines."),
|
|
782
|
+
old_line: z
|
|
783
|
+
.number()
|
|
784
|
+
.nullable()
|
|
785
|
+
.optional()
|
|
786
|
+
.describe("Line number in the original file (before changes). Used for deleted lines and context lines. Null for newly added lines."),
|
|
631
787
|
line_range: LineRangeSchema.nullable().optional(), // For multi-line diff notes
|
|
632
788
|
width: z.number().optional(), // For image diff notes
|
|
633
789
|
height: z.number().optional(), // For image diff notes
|
|
634
790
|
x: z.number().optional(), // For image diff notes
|
|
635
791
|
y: z.number().optional(), // For image diff notes
|
|
636
792
|
})
|
|
793
|
+
.passthrough() // Allow additional fields
|
|
637
794
|
.optional(),
|
|
638
|
-
});
|
|
795
|
+
}).passthrough(); // Allow additional fields that GitLab might return
|
|
639
796
|
// Reusable pagination schema for GitLab API responses.
|
|
640
797
|
// See https://docs.gitlab.com/api/rest/#pagination
|
|
641
798
|
export const GitLabPaginationSchema = z.object({
|
|
@@ -661,10 +818,12 @@ export const PaginatedDiscussionsResponseSchema = z.object({
|
|
|
661
818
|
items: z.array(GitLabDiscussionSchema),
|
|
662
819
|
pagination: GitLabPaginationSchema,
|
|
663
820
|
});
|
|
664
|
-
export const ListIssueDiscussionsSchema = z
|
|
821
|
+
export const ListIssueDiscussionsSchema = z
|
|
822
|
+
.object({
|
|
665
823
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
666
824
|
issue_iid: z.coerce.string().describe("The internal ID of the project issue"),
|
|
667
|
-
})
|
|
825
|
+
})
|
|
826
|
+
.merge(PaginationOptionsSchema);
|
|
668
827
|
// Input schema for listing merge request discussions
|
|
669
828
|
export const ListMergeRequestDiscussionsSchema = ProjectParamsSchema.extend({
|
|
670
829
|
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
@@ -714,9 +873,11 @@ export const CreateOrUpdateFileSchema = ProjectParamsSchema.extend({
|
|
|
714
873
|
last_commit_id: z.string().optional().describe("Last known file commit ID"),
|
|
715
874
|
commit_id: z.string().optional().describe("Current file commit ID (for update operations)"),
|
|
716
875
|
});
|
|
717
|
-
export const SearchRepositoriesSchema = z
|
|
876
|
+
export const SearchRepositoriesSchema = z
|
|
877
|
+
.object({
|
|
718
878
|
search: z.string().describe("Search query"), // Changed from query to match GitLab API
|
|
719
|
-
})
|
|
879
|
+
})
|
|
880
|
+
.merge(PaginationOptionsSchema);
|
|
720
881
|
export const CreateRepositorySchema = z.object({
|
|
721
882
|
name: z.string().describe("Repository name"),
|
|
722
883
|
description: z.string().optional().describe("Repository description"),
|
|
@@ -746,6 +907,7 @@ export const CreateIssueSchema = ProjectParamsSchema.extend({
|
|
|
746
907
|
assignee_ids: z.array(z.number()).optional().describe("Array of user IDs to assign"),
|
|
747
908
|
labels: z.array(z.string()).optional().describe("Array of label names"),
|
|
748
909
|
milestone_id: z.coerce.string().optional().describe("Milestone ID to assign"),
|
|
910
|
+
issue_type: z.enum(["issue", "incident", "test_case", "task"]).describe("the type of issue. One of issue, incident, test_case or task.").nullish().default("issue"),
|
|
749
911
|
});
|
|
750
912
|
const MergeRequestOptionsSchema = {
|
|
751
913
|
title: z.string().describe("Merge request title"),
|
|
@@ -753,22 +915,20 @@ const MergeRequestOptionsSchema = {
|
|
|
753
915
|
source_branch: z.string().describe("Branch containing changes"),
|
|
754
916
|
target_branch: z.string().describe("Branch to merge into"),
|
|
755
917
|
target_project_id: z.coerce.string().optional().describe("Numeric ID of the target project."),
|
|
756
|
-
assignee_ids: z
|
|
757
|
-
.array(z.number())
|
|
758
|
-
.optional()
|
|
759
|
-
.describe("The ID of the users to assign the MR to"),
|
|
918
|
+
assignee_ids: z.array(z.number()).optional().describe("The ID of the users to assign the MR to"),
|
|
760
919
|
reviewer_ids: z
|
|
761
920
|
.array(z.number())
|
|
762
921
|
.optional()
|
|
763
922
|
.describe("The ID of the users to assign as reviewers of the MR"),
|
|
764
923
|
labels: z.array(z.string()).optional().describe("Labels for the MR"),
|
|
765
924
|
draft: flexibleBoolean.optional().describe("Create as draft merge request"),
|
|
766
|
-
allow_collaboration: z
|
|
767
|
-
|
|
925
|
+
allow_collaboration: z.boolean().optional().describe("Allow commits from upstream members"),
|
|
926
|
+
remove_source_branch: flexibleBooleanNullable
|
|
768
927
|
.optional()
|
|
769
|
-
.describe("
|
|
770
|
-
|
|
771
|
-
|
|
928
|
+
.describe("Flag indicating if a merge request should remove the source branch when merging."),
|
|
929
|
+
squash: flexibleBooleanNullable
|
|
930
|
+
.optional()
|
|
931
|
+
.describe("If true, squash all commits into a single commit on merge."),
|
|
772
932
|
};
|
|
773
933
|
export const CreateMergeRequestOptionsSchema = z.object(MergeRequestOptionsSchema);
|
|
774
934
|
export const CreateMergeRequestSchema = ProjectParamsSchema.extend(MergeRequestOptionsSchema);
|
|
@@ -783,8 +943,13 @@ export const CreateBranchSchema = ProjectParamsSchema.extend({
|
|
|
783
943
|
export const GetBranchDiffsSchema = ProjectParamsSchema.extend({
|
|
784
944
|
from: z.string().describe("The base branch or commit SHA to compare from"),
|
|
785
945
|
to: z.string().describe("The target branch or commit SHA to compare to"),
|
|
786
|
-
straight: flexibleBoolean
|
|
787
|
-
|
|
946
|
+
straight: flexibleBoolean
|
|
947
|
+
.optional()
|
|
948
|
+
.describe("Comparison method: false for '...' (default), true for '--'"),
|
|
949
|
+
excluded_file_patterns: z
|
|
950
|
+
.array(z.string())
|
|
951
|
+
.optional()
|
|
952
|
+
.describe('Array of regex patterns to exclude files from the diff results. Each pattern is a JavaScript-compatible regular expression that matches file paths to ignore. Examples: ["^test/mocks/", "\\.spec\\.ts$", "package-lock\\.json"]'),
|
|
788
953
|
});
|
|
789
954
|
export const GetMergeRequestSchema = ProjectParamsSchema.extend({
|
|
790
955
|
merge_request_iid: z.coerce.string().optional().describe("The IID of a merge request"),
|
|
@@ -794,10 +959,7 @@ export const UpdateMergeRequestSchema = GetMergeRequestSchema.extend({
|
|
|
794
959
|
title: z.string().optional().describe("The title of the merge request"),
|
|
795
960
|
description: z.string().optional().describe("The description of the merge request"),
|
|
796
961
|
target_branch: z.string().optional().describe("The target branch"),
|
|
797
|
-
assignee_ids: z
|
|
798
|
-
.array(z.number())
|
|
799
|
-
.optional()
|
|
800
|
-
.describe("The ID of the users to assign the MR to"),
|
|
962
|
+
assignee_ids: z.array(z.number()).optional().describe("The ID of the users to assign the MR to"),
|
|
801
963
|
reviewer_ids: z
|
|
802
964
|
.array(z.number())
|
|
803
965
|
.optional()
|
|
@@ -814,13 +976,24 @@ export const UpdateMergeRequestSchema = GetMergeRequestSchema.extend({
|
|
|
814
976
|
squash: flexibleBoolean.optional().describe("Squash commits into a single commit when merging"),
|
|
815
977
|
draft: flexibleBoolean.optional().describe("Work in progress merge request"),
|
|
816
978
|
});
|
|
979
|
+
export const MergeMergeRequestSchema = ProjectParamsSchema.extend({
|
|
980
|
+
merge_request_iid: z.coerce.string().optional().describe("The IID of a merge request"),
|
|
981
|
+
auto_merge: flexibleBoolean.optional().default(false).describe("If true, the merge request merges when the pipeline succeeds."),
|
|
982
|
+
merge_commit_message: z.string().optional().describe("Custom merge commit message"),
|
|
983
|
+
merge_when_pipeline_succeeds: flexibleBoolean.optional().default(false).describe("If true, the merge request merges when the pipeline succeeds.in GitLab 17.11. Use"),
|
|
984
|
+
should_remove_source_branch: flexibleBoolean.optional().default(false).describe("Remove source branch after merge"),
|
|
985
|
+
squash_commit_message: z.string().optional().describe("Custom squash commit message"),
|
|
986
|
+
squash: flexibleBoolean.optional().default(false).describe("Squash commits into a single commit when merging"),
|
|
987
|
+
});
|
|
817
988
|
export const GetMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
|
|
818
989
|
view: z.enum(["inline", "parallel"]).optional().describe("Diff view type"),
|
|
819
990
|
});
|
|
820
991
|
export const ListMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
|
|
821
992
|
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
822
993
|
per_page: z.number().optional().describe("Number of items per page (max: 100, default: 20)"),
|
|
823
|
-
unidiff: flexibleBoolean
|
|
994
|
+
unidiff: flexibleBoolean
|
|
995
|
+
.optional()
|
|
996
|
+
.describe("Present diffs in the unified diff format. Default is false. Introduced in GitLab 16.5."),
|
|
824
997
|
});
|
|
825
998
|
export const CreateNoteSchema = z.object({
|
|
826
999
|
project_id: z.coerce.string().describe("Project ID or namespace/project_path"),
|
|
@@ -831,10 +1004,20 @@ export const CreateNoteSchema = z.object({
|
|
|
831
1004
|
body: z.string().describe("Note content"),
|
|
832
1005
|
});
|
|
833
1006
|
// Issues API operation schemas
|
|
834
|
-
export const ListIssuesSchema = z
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
1007
|
+
export const ListIssuesSchema = z
|
|
1008
|
+
.object({
|
|
1009
|
+
project_id: z.coerce
|
|
1010
|
+
.string()
|
|
1011
|
+
.optional()
|
|
1012
|
+
.describe("Project ID or URL-encoded path (optional - if not provided, lists issues across all accessible projects)"),
|
|
1013
|
+
assignee_id: z.coerce
|
|
1014
|
+
.string()
|
|
1015
|
+
.optional()
|
|
1016
|
+
.describe("Return issues assigned to the given user ID. user id or none or any"),
|
|
1017
|
+
assignee_username: z
|
|
1018
|
+
.array(z.string())
|
|
1019
|
+
.optional()
|
|
1020
|
+
.describe("Return issues assigned to the given username"),
|
|
838
1021
|
author_id: z.coerce.string().optional().describe("Return issues created by the given user ID"),
|
|
839
1022
|
author_username: z.string().optional().describe("Return issues created by the given username"),
|
|
840
1023
|
confidential: flexibleBoolean.optional().describe("Filter confidential or public issues"),
|
|
@@ -843,8 +1026,16 @@ export const ListIssuesSchema = z.object({
|
|
|
843
1026
|
due_date: z.string().optional().describe("Return issues that have the due date"),
|
|
844
1027
|
labels: z.array(z.string()).optional().describe("Array of label names"),
|
|
845
1028
|
milestone: z.string().optional().describe("Milestone title"),
|
|
846
|
-
issue_type: z
|
|
847
|
-
|
|
1029
|
+
issue_type: z
|
|
1030
|
+
.string()
|
|
1031
|
+
.optional()
|
|
1032
|
+
.nullable()
|
|
1033
|
+
.describe("Filter to a given type of issue. One of issue, incident, test_case or task"),
|
|
1034
|
+
iteration_id: z.coerce
|
|
1035
|
+
.string()
|
|
1036
|
+
.optional()
|
|
1037
|
+
.nullable()
|
|
1038
|
+
.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. "),
|
|
848
1039
|
scope: z
|
|
849
1040
|
.enum(["created_by_me", "assigned_to_me", "all"])
|
|
850
1041
|
.optional()
|
|
@@ -857,21 +1048,30 @@ export const ListIssuesSchema = z.object({
|
|
|
857
1048
|
updated_after: z.string().optional().describe("Return issues updated after the given time"),
|
|
858
1049
|
updated_before: z.string().optional().describe("Return issues updated before the given time"),
|
|
859
1050
|
with_labels_details: flexibleBoolean.optional().describe("Return more details for each label"),
|
|
860
|
-
})
|
|
1051
|
+
})
|
|
1052
|
+
.merge(PaginationOptionsSchema);
|
|
861
1053
|
// Merge Requests API operation schemas
|
|
862
|
-
export const ListMergeRequestsSchema = z
|
|
1054
|
+
export const ListMergeRequestsSchema = z
|
|
1055
|
+
.object({
|
|
863
1056
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
864
|
-
assignee_id: z.coerce
|
|
1057
|
+
assignee_id: z.coerce
|
|
1058
|
+
.string()
|
|
1059
|
+
.optional()
|
|
1060
|
+
.describe("Return issues assigned to the given user ID. user id or none or any"),
|
|
865
1061
|
assignee_username: z
|
|
866
1062
|
.string()
|
|
867
1063
|
.optional()
|
|
868
1064
|
.describe("Returns merge requests assigned to the given username"),
|
|
869
|
-
author_id: z.coerce
|
|
1065
|
+
author_id: z.coerce
|
|
1066
|
+
.string()
|
|
1067
|
+
.optional()
|
|
1068
|
+
.describe("Returns merge requests created by the given user ID"),
|
|
870
1069
|
author_username: z
|
|
871
1070
|
.string()
|
|
872
1071
|
.optional()
|
|
873
1072
|
.describe("Returns merge requests created by the given username"),
|
|
874
|
-
reviewer_id: z.coerce
|
|
1073
|
+
reviewer_id: z.coerce
|
|
1074
|
+
.string()
|
|
875
1075
|
.optional()
|
|
876
1076
|
.describe("Returns merge requests which have the user as a reviewer. user id or none or any"),
|
|
877
1077
|
reviewer_username: z
|
|
@@ -906,7 +1106,14 @@ export const ListMergeRequestsSchema = z.object({
|
|
|
906
1106
|
.optional()
|
|
907
1107
|
.describe("Return merge requests with a specific state"),
|
|
908
1108
|
order_by: z
|
|
909
|
-
.enum([
|
|
1109
|
+
.enum([
|
|
1110
|
+
"created_at",
|
|
1111
|
+
"updated_at",
|
|
1112
|
+
"priority",
|
|
1113
|
+
"label_priority",
|
|
1114
|
+
"milestone_due",
|
|
1115
|
+
"popularity",
|
|
1116
|
+
])
|
|
910
1117
|
.optional()
|
|
911
1118
|
.describe("Return merge requests ordered by the given field"),
|
|
912
1119
|
sort: z
|
|
@@ -921,9 +1128,13 @@ export const ListMergeRequestsSchema = z.object({
|
|
|
921
1128
|
.string()
|
|
922
1129
|
.optional()
|
|
923
1130
|
.describe("Return merge requests from a specific source branch"),
|
|
924
|
-
wip: z
|
|
1131
|
+
wip: z
|
|
1132
|
+
.enum(["yes", "no"])
|
|
1133
|
+
.optional()
|
|
1134
|
+
.describe("Filter merge requests against their wip status"),
|
|
925
1135
|
with_labels_details: flexibleBoolean.optional().describe("Return more details for each label"),
|
|
926
|
-
})
|
|
1136
|
+
})
|
|
1137
|
+
.merge(PaginationOptionsSchema);
|
|
927
1138
|
export const GetIssueSchema = z.object({
|
|
928
1139
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
929
1140
|
issue_iid: z.coerce.string().describe("The internal ID of the project issue"),
|
|
@@ -941,6 +1152,7 @@ export const UpdateIssueSchema = z.object({
|
|
|
941
1152
|
milestone_id: z.coerce.string().optional().describe("Milestone ID to assign"),
|
|
942
1153
|
state_event: z.enum(["close", "reopen"]).optional().describe("Update issue state (close/reopen)"),
|
|
943
1154
|
weight: z.number().optional().describe("Weight of the issue (0-9)"),
|
|
1155
|
+
issue_type: z.enum(["issue", "incident", "test_case", "task"]).describe("the type of issue. One of issue, incident, test_case or task."),
|
|
944
1156
|
});
|
|
945
1157
|
export const DeleteIssueSchema = z.object({
|
|
946
1158
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -977,10 +1189,12 @@ export const DeleteIssueLinkSchema = z.object({
|
|
|
977
1189
|
issue_link_id: z.coerce.string().describe("The ID of an issue relationship"),
|
|
978
1190
|
});
|
|
979
1191
|
// Namespace API operation schemas
|
|
980
|
-
export const ListNamespacesSchema = z
|
|
1192
|
+
export const ListNamespacesSchema = z
|
|
1193
|
+
.object({
|
|
981
1194
|
search: z.string().optional().describe("Search term for namespaces"),
|
|
982
1195
|
owned: flexibleBoolean.optional().describe("Filter for namespaces owned by current user"),
|
|
983
|
-
})
|
|
1196
|
+
})
|
|
1197
|
+
.merge(PaginationOptionsSchema);
|
|
984
1198
|
export const GetNamespaceSchema = z.object({
|
|
985
1199
|
namespace_id: z.coerce.string().describe("Namespace ID or full path"),
|
|
986
1200
|
});
|
|
@@ -991,11 +1205,16 @@ export const VerifyNamespaceSchema = z.object({
|
|
|
991
1205
|
export const GetProjectSchema = z.object({
|
|
992
1206
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
993
1207
|
});
|
|
994
|
-
export const ListProjectsSchema = z
|
|
1208
|
+
export const ListProjectsSchema = z
|
|
1209
|
+
.object({
|
|
995
1210
|
search: z.string().optional().describe("Search term for projects"),
|
|
996
|
-
search_namespaces: flexibleBoolean
|
|
1211
|
+
search_namespaces: flexibleBoolean
|
|
1212
|
+
.optional()
|
|
1213
|
+
.describe("Needs to be true if search is full path"),
|
|
997
1214
|
owned: flexibleBoolean.optional().describe("Filter for projects owned by current user"),
|
|
998
|
-
membership: flexibleBoolean
|
|
1215
|
+
membership: flexibleBoolean
|
|
1216
|
+
.optional()
|
|
1217
|
+
.describe("Filter for projects where current user is a member"),
|
|
999
1218
|
simple: flexibleBoolean.optional().describe("Return only limited fields"),
|
|
1000
1219
|
archived: flexibleBoolean.optional().describe("Filter for archived projects"),
|
|
1001
1220
|
visibility: z
|
|
@@ -1019,7 +1238,8 @@ export const ListProjectsSchema = z.object({
|
|
|
1019
1238
|
.optional()
|
|
1020
1239
|
.describe("Filter projects with merge requests feature enabled"),
|
|
1021
1240
|
min_access_level: z.number().optional().describe("Filter by minimum access level"),
|
|
1022
|
-
})
|
|
1241
|
+
})
|
|
1242
|
+
.merge(PaginationOptionsSchema);
|
|
1023
1243
|
// Label operation schemas
|
|
1024
1244
|
export const ListLabelsSchema = z.object({
|
|
1025
1245
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1060,7 +1280,8 @@ export const DeleteLabelSchema = z.object({
|
|
|
1060
1280
|
label_id: z.coerce.string().describe("The ID or title of a project's label"),
|
|
1061
1281
|
});
|
|
1062
1282
|
// Group projects schema
|
|
1063
|
-
export const ListGroupProjectsSchema = z
|
|
1283
|
+
export const ListGroupProjectsSchema = z
|
|
1284
|
+
.object({
|
|
1064
1285
|
group_id: z.coerce.string().describe("Group ID or path"),
|
|
1065
1286
|
include_subgroups: flexibleBoolean.optional().describe("Include projects from subgroups"),
|
|
1066
1287
|
search: z.string().optional().describe("Search term to filter projects"),
|
|
@@ -1088,12 +1309,15 @@ export const ListGroupProjectsSchema = z.object({
|
|
|
1088
1309
|
statistics: flexibleBoolean.optional().describe("Include project statistics"),
|
|
1089
1310
|
with_custom_attributes: flexibleBoolean.optional().describe("Include custom attributes"),
|
|
1090
1311
|
with_security_reports: flexibleBoolean.optional().describe("Include security reports"),
|
|
1091
|
-
})
|
|
1312
|
+
})
|
|
1313
|
+
.merge(PaginationOptionsSchema);
|
|
1092
1314
|
// Add wiki operation schemas
|
|
1093
|
-
export const ListWikiPagesSchema = z
|
|
1315
|
+
export const ListWikiPagesSchema = z
|
|
1316
|
+
.object({
|
|
1094
1317
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1095
1318
|
with_content: flexibleBoolean.optional().describe("Include content of the wiki pages"),
|
|
1096
|
-
})
|
|
1319
|
+
})
|
|
1320
|
+
.merge(PaginationOptionsSchema);
|
|
1097
1321
|
export const GetWikiPageSchema = z.object({
|
|
1098
1322
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1099
1323
|
slug: z.string().describe("URL-encoded slug of the wiki page"),
|
|
@@ -1125,7 +1349,9 @@ export const GitLabWikiPageSchema = z.object({
|
|
|
1125
1349
|
updated_at: z.string().optional(),
|
|
1126
1350
|
});
|
|
1127
1351
|
// Merge Request Thread position schema - used for diff notes
|
|
1128
|
-
|
|
1352
|
+
// Extremely flexible position schema for API responses - accepts any structure
|
|
1353
|
+
// Strict position schema for creating draft notes and merge request threads
|
|
1354
|
+
export const MergeRequestThreadPositionCreateSchema = z.object({
|
|
1129
1355
|
base_sha: z.string().describe("REQUIRED: Base commit SHA in the source branch. Get this from merge request diff_refs.base_sha."),
|
|
1130
1356
|
head_sha: z.string().describe("REQUIRED: SHA referencing HEAD of the source branch. Get this from merge request diff_refs.head_sha."),
|
|
1131
1357
|
start_sha: z.string().describe("REQUIRED: SHA referencing the start commit of the source branch. Get this from merge request diff_refs.start_sha."),
|
|
@@ -1140,6 +1366,115 @@ export const MergeRequestThreadPositionSchema = z.object({
|
|
|
1140
1366
|
x: z.number().optional().describe("IMAGE DIFFS ONLY: X coordinate on the image (for position_type='image')."),
|
|
1141
1367
|
y: z.number().optional().describe("IMAGE DIFFS ONLY: Y coordinate on the image (for position_type='image')."),
|
|
1142
1368
|
});
|
|
1369
|
+
export const MergeRequestThreadPositionSchema = z.object({
|
|
1370
|
+
base_sha: z
|
|
1371
|
+
.string()
|
|
1372
|
+
.describe("REQUIRED: Base commit SHA in the source branch. Get this from merge request diff_refs.base_sha."),
|
|
1373
|
+
head_sha: z
|
|
1374
|
+
.string()
|
|
1375
|
+
.describe("REQUIRED: SHA referencing HEAD of the source branch. Get this from merge request diff_refs.head_sha."),
|
|
1376
|
+
start_sha: z
|
|
1377
|
+
.string()
|
|
1378
|
+
.describe("REQUIRED: SHA referencing the start commit of the source branch. Get this from merge request diff_refs.start_sha."),
|
|
1379
|
+
position_type: z
|
|
1380
|
+
.enum(["text", "image", "file"])
|
|
1381
|
+
.describe("REQUIRED: Position type. Use 'text' for code diffs, 'image' for image diffs, 'file' for file-level comments."),
|
|
1382
|
+
new_path: z
|
|
1383
|
+
.string()
|
|
1384
|
+
.nullable()
|
|
1385
|
+
.optional()
|
|
1386
|
+
.describe("File path after changes. REQUIRED for most diff comments. Use same as old_path if file wasn't renamed."),
|
|
1387
|
+
old_path: z
|
|
1388
|
+
.string()
|
|
1389
|
+
.nullable()
|
|
1390
|
+
.optional()
|
|
1391
|
+
.describe("File path before changes. REQUIRED for most diff comments. Use same as new_path if file wasn't renamed."),
|
|
1392
|
+
new_line: z
|
|
1393
|
+
.number()
|
|
1394
|
+
.nullable()
|
|
1395
|
+
.optional()
|
|
1396
|
+
.describe("Line number in modified file (after changes). Use for added lines or context lines. NULL for deleted lines. For single-line comments on new lines."),
|
|
1397
|
+
old_line: z
|
|
1398
|
+
.number()
|
|
1399
|
+
.nullable()
|
|
1400
|
+
.optional()
|
|
1401
|
+
.describe("Line number in original file (before changes). Use for deleted lines or context lines. NULL for added lines. For single-line comments on old lines."),
|
|
1402
|
+
line_range: LineRangeSchema.optional().describe("MULTILINE COMMENTS: Specify start/end line positions for commenting on multiple lines. Alternative to single old_line/new_line."),
|
|
1403
|
+
width: z
|
|
1404
|
+
.number()
|
|
1405
|
+
.optional()
|
|
1406
|
+
.describe("IMAGE DIFFS ONLY: Width of the image (for position_type='image')."),
|
|
1407
|
+
height: z
|
|
1408
|
+
.number()
|
|
1409
|
+
.optional()
|
|
1410
|
+
.describe("IMAGE DIFFS ONLY: Height of the image (for position_type='image')."),
|
|
1411
|
+
x: z
|
|
1412
|
+
.number()
|
|
1413
|
+
.optional()
|
|
1414
|
+
.describe("IMAGE DIFFS ONLY: X coordinate on the image (for position_type='image')."),
|
|
1415
|
+
y: z
|
|
1416
|
+
.number()
|
|
1417
|
+
.optional()
|
|
1418
|
+
.describe("IMAGE DIFFS ONLY: Y coordinate on the image (for position_type='image')."),
|
|
1419
|
+
});
|
|
1420
|
+
// Draft Notes API schemas
|
|
1421
|
+
export const GitLabDraftNoteSchema = z.object({
|
|
1422
|
+
id: z.coerce.string(),
|
|
1423
|
+
author: GitLabUserSchema.optional(),
|
|
1424
|
+
body: z.string().optional(),
|
|
1425
|
+
note: z.string().optional(), // Some APIs might use 'note' instead of 'body'
|
|
1426
|
+
created_at: z.string().optional(),
|
|
1427
|
+
updated_at: z.string().optional(),
|
|
1428
|
+
position: MergeRequestThreadPositionSchema.nullable().optional(),
|
|
1429
|
+
resolve_discussion: flexibleBoolean.optional(),
|
|
1430
|
+
}).transform((data) => ({
|
|
1431
|
+
// Normalize the response to always have consistent field names
|
|
1432
|
+
id: data.id,
|
|
1433
|
+
author: data.author,
|
|
1434
|
+
body: data.body || data.note || "",
|
|
1435
|
+
created_at: data.created_at || "",
|
|
1436
|
+
updated_at: data.updated_at || "",
|
|
1437
|
+
position: data.position,
|
|
1438
|
+
resolve_discussion: data.resolve_discussion,
|
|
1439
|
+
}));
|
|
1440
|
+
// Get draft note schema
|
|
1441
|
+
export const GetDraftNoteSchema = ProjectParamsSchema.extend({
|
|
1442
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
1443
|
+
draft_note_id: z.coerce.string().describe("The ID of the draft note"),
|
|
1444
|
+
});
|
|
1445
|
+
// List draft notes schema
|
|
1446
|
+
export const ListDraftNotesSchema = ProjectParamsSchema.extend({
|
|
1447
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
1448
|
+
});
|
|
1449
|
+
// Create draft note schema
|
|
1450
|
+
export const CreateDraftNoteSchema = ProjectParamsSchema.extend({
|
|
1451
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
1452
|
+
body: z.string().describe("The content of the draft note"),
|
|
1453
|
+
position: MergeRequestThreadPositionCreateSchema.optional().describe("Position when creating a diff note"),
|
|
1454
|
+
resolve_discussion: flexibleBoolean.optional().describe("Whether to resolve the discussion when publishing"),
|
|
1455
|
+
});
|
|
1456
|
+
// Update draft note schema
|
|
1457
|
+
export const UpdateDraftNoteSchema = ProjectParamsSchema.extend({
|
|
1458
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
1459
|
+
draft_note_id: z.coerce.string().describe("The ID of the draft note"),
|
|
1460
|
+
body: z.string().optional().describe("The content of the draft note"),
|
|
1461
|
+
position: MergeRequestThreadPositionCreateSchema.optional().describe("Position when creating a diff note"),
|
|
1462
|
+
resolve_discussion: flexibleBoolean.optional().describe("Whether to resolve the discussion when publishing"),
|
|
1463
|
+
});
|
|
1464
|
+
// Delete draft note schema
|
|
1465
|
+
export const DeleteDraftNoteSchema = ProjectParamsSchema.extend({
|
|
1466
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
1467
|
+
draft_note_id: z.coerce.string().describe("The ID of the draft note"),
|
|
1468
|
+
});
|
|
1469
|
+
// Publish draft note schema
|
|
1470
|
+
export const PublishDraftNoteSchema = ProjectParamsSchema.extend({
|
|
1471
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
1472
|
+
draft_note_id: z.coerce.string().describe("The ID of the draft note"),
|
|
1473
|
+
});
|
|
1474
|
+
// Bulk publish draft notes schema
|
|
1475
|
+
export const BulkPublishDraftNotesSchema = ProjectParamsSchema.extend({
|
|
1476
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
1477
|
+
});
|
|
1143
1478
|
// Schema for creating a new merge request thread
|
|
1144
1479
|
export const CreateMergeRequestThreadSchema = ProjectParamsSchema.extend({
|
|
1145
1480
|
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
@@ -1208,14 +1543,27 @@ export const GetMilestoneBurndownEventsSchema = GetProjectMilestoneSchema.merge(
|
|
|
1208
1543
|
// Add schemas for commit operations
|
|
1209
1544
|
export const ListCommitsSchema = z.object({
|
|
1210
1545
|
project_id: z.coerce.string().describe("Project ID or complete URL-encoded path to project"),
|
|
1211
|
-
ref_name: z
|
|
1212
|
-
|
|
1213
|
-
|
|
1546
|
+
ref_name: z
|
|
1547
|
+
.string()
|
|
1548
|
+
.optional()
|
|
1549
|
+
.describe("The name of a repository branch, tag or revision range, or if not given the default branch"),
|
|
1550
|
+
since: z
|
|
1551
|
+
.string()
|
|
1552
|
+
.optional()
|
|
1553
|
+
.describe("Only commits after or on this date are returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ"),
|
|
1554
|
+
until: z
|
|
1555
|
+
.string()
|
|
1556
|
+
.optional()
|
|
1557
|
+
.describe("Only commits before or on this date are returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ"),
|
|
1214
1558
|
path: z.string().optional().describe("The file path"),
|
|
1215
1559
|
author: z.string().optional().describe("Search commits by commit author"),
|
|
1216
1560
|
all: flexibleBoolean.optional().describe("Retrieve every commit from the repository"),
|
|
1217
|
-
with_stats: flexibleBoolean
|
|
1218
|
-
|
|
1561
|
+
with_stats: flexibleBoolean
|
|
1562
|
+
.optional()
|
|
1563
|
+
.describe("Stats about each commit are added to the response"),
|
|
1564
|
+
first_parent: flexibleBoolean
|
|
1565
|
+
.optional()
|
|
1566
|
+
.describe("Follow only the first parent commit upon seeing a merge commit"),
|
|
1219
1567
|
order: z.enum(["default", "topo"]).optional().describe("List commits in order"),
|
|
1220
1568
|
trailers: flexibleBoolean.optional().describe("Parse and include Git trailers for every commit"),
|
|
1221
1569
|
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
@@ -1230,6 +1578,64 @@ export const GetCommitDiffSchema = z.object({
|
|
|
1230
1578
|
project_id: z.coerce.string().describe("Project ID or complete URL-encoded path to project"),
|
|
1231
1579
|
sha: z.string().describe("The commit hash or name of a repository branch or tag"),
|
|
1232
1580
|
});
|
|
1581
|
+
// Schema for listing issues assigned to the current user
|
|
1582
|
+
export const MyIssuesSchema = z.object({
|
|
1583
|
+
project_id: z.string().optional().describe("Project ID or URL-encoded path (optional when GITLAB_PROJECT_ID is set)"),
|
|
1584
|
+
state: z
|
|
1585
|
+
.enum(["opened", "closed", "all"])
|
|
1586
|
+
.optional()
|
|
1587
|
+
.describe("Return issues with a specific state (default: opened)"),
|
|
1588
|
+
labels: z.array(z.string()).optional().describe("Array of label names to filter by"),
|
|
1589
|
+
milestone: z.string().optional().describe("Milestone title to filter by"),
|
|
1590
|
+
search: z.string().optional().describe("Search for specific terms in title and description"),
|
|
1591
|
+
created_after: z.string().optional().describe("Return issues created after the given time (ISO 8601)"),
|
|
1592
|
+
created_before: z.string().optional().describe("Return issues created before the given time (ISO 8601)"),
|
|
1593
|
+
updated_after: z.string().optional().describe("Return issues updated after the given time (ISO 8601)"),
|
|
1594
|
+
updated_before: z.string().optional().describe("Return issues updated before the given time (ISO 8601)"),
|
|
1595
|
+
per_page: z.number().optional().describe("Number of items per page (default: 20, max: 100)"),
|
|
1596
|
+
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
1597
|
+
});
|
|
1598
|
+
// Schema for listing project members
|
|
1599
|
+
export const ListProjectMembersSchema = z.object({
|
|
1600
|
+
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
1601
|
+
query: z.string().optional().describe("Search for members by name or username"),
|
|
1602
|
+
user_ids: z.array(z.number()).optional().describe("Filter by user IDs"),
|
|
1603
|
+
skip_users: z.array(z.number()).optional().describe("User IDs to exclude"),
|
|
1604
|
+
per_page: z.number().optional().describe("Number of items per page (default: 20, max: 100)"),
|
|
1605
|
+
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
1606
|
+
});
|
|
1607
|
+
// Schema for GitLab project member
|
|
1608
|
+
export const GitLabProjectMemberSchema = z.object({
|
|
1609
|
+
id: z.number(),
|
|
1610
|
+
username: z.string(),
|
|
1611
|
+
name: z.string(),
|
|
1612
|
+
state: z.string(),
|
|
1613
|
+
avatar_url: z.string().nullable(),
|
|
1614
|
+
web_url: z.string(),
|
|
1615
|
+
access_level: z.number(),
|
|
1616
|
+
access_level_description: z.string().optional(),
|
|
1617
|
+
created_at: z.string(),
|
|
1618
|
+
expires_at: z.string().nullable().optional(),
|
|
1619
|
+
email: z.string().optional(),
|
|
1620
|
+
});
|
|
1621
|
+
// Markdown upload schemas
|
|
1622
|
+
export const GitLabMarkdownUploadSchema = z.object({
|
|
1623
|
+
id: z.number(),
|
|
1624
|
+
alt: z.string(),
|
|
1625
|
+
url: z.string(),
|
|
1626
|
+
full_path: z.string(),
|
|
1627
|
+
markdown: z.string(),
|
|
1628
|
+
});
|
|
1629
|
+
export const MarkdownUploadSchema = z.object({
|
|
1630
|
+
project_id: z.string().describe("Project ID or URL-encoded path of the project"),
|
|
1631
|
+
file_path: z.string().describe("Path to the file to upload"),
|
|
1632
|
+
});
|
|
1633
|
+
export const DownloadAttachmentSchema = z.object({
|
|
1634
|
+
project_id: z.string().describe("Project ID or URL-encoded path of the project"),
|
|
1635
|
+
secret: z.string().describe("The 32-character secret of the upload"),
|
|
1636
|
+
filename: z.string().describe("The filename of the upload"),
|
|
1637
|
+
local_path: z.string().optional().describe("Local path to save the file (optional, defaults to current directory)"),
|
|
1638
|
+
});
|
|
1233
1639
|
export const GroupIteration = z.object({
|
|
1234
1640
|
id: z.coerce.string(),
|
|
1235
1641
|
iid: z.coerce.string(),
|
|
@@ -1244,13 +1650,34 @@ export const GroupIteration = z.object({
|
|
|
1244
1650
|
start_date: z.string().optional().nullable(),
|
|
1245
1651
|
web_url: z.string().optional().nullable(),
|
|
1246
1652
|
});
|
|
1247
|
-
export const ListGroupIterationsSchema = z
|
|
1653
|
+
export const ListGroupIterationsSchema = z
|
|
1654
|
+
.object({
|
|
1248
1655
|
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
|
|
1249
|
-
state: z
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1656
|
+
state: z
|
|
1657
|
+
.enum(["opened", "upcoming", "current", "closed", "all"])
|
|
1658
|
+
.optional()
|
|
1659
|
+
.describe("Return opened, upcoming, current, closed, or all iterations."),
|
|
1660
|
+
search: z
|
|
1661
|
+
.string()
|
|
1662
|
+
.optional()
|
|
1663
|
+
.describe("Return only iterations with a title matching the provided string."),
|
|
1664
|
+
in: z
|
|
1665
|
+
.array(z.enum(["title", "cadence_title"]))
|
|
1666
|
+
.optional()
|
|
1667
|
+
.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]."),
|
|
1668
|
+
include_ancestors: flexibleBoolean
|
|
1669
|
+
.optional()
|
|
1670
|
+
.describe("Include iterations for group and its ancestors. Defaults to true."),
|
|
1671
|
+
include_descendants: flexibleBoolean
|
|
1672
|
+
.optional()
|
|
1673
|
+
.describe("Include iterations for group and its descendants. Defaults to false."),
|
|
1674
|
+
updated_before: z
|
|
1675
|
+
.string()
|
|
1676
|
+
.optional()
|
|
1677
|
+
.describe("Return only iterations updated before the given datetime. Expected in ISO 8601 format (2019-03-15T08:00:00Z)."),
|
|
1678
|
+
updated_after: z
|
|
1679
|
+
.string()
|
|
1680
|
+
.optional()
|
|
1681
|
+
.describe("Return only iterations updated after the given datetime. Expected in ISO 8601 format (2019-03-15T08:00:00Z)."),
|
|
1682
|
+
})
|
|
1683
|
+
.merge(PaginationOptionsSchema);
|