@zereight/mcp-gitlab 2.0.33 → 2.0.35
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 +233 -90
- package/build/gitlab-client-pool.js +114 -6
- package/build/index.js +2244 -98
- package/build/oauth-proxy.js +257 -0
- package/build/oauth.js +11 -6
- package/build/schemas.js +458 -199
- package/build/test/mcp-oauth-tests.js +443 -0
- package/build/test/multi-server-test.js +16 -8
- package/build/test/no-proxy-integration-test.js +183 -0
- package/build/test/no-proxy-test.js +138 -0
- package/build/test/remote-auth-simple-test.js +12 -1
- package/build/test/test-geteffectiveprojectid.js +245 -0
- package/build/test/test-mr-file-diffs.js +251 -0
- package/build/test/test-search-code.js +272 -0
- package/build/test/test-toolset-filtering.js +22 -17
- package/build/test/test-upload-markdown.js +148 -0
- package/build/test/utils/mock-gitlab-server.js +267 -163
- package/build/test/utils/server-launcher.js +45 -41
- package/package.json +3 -2
package/build/schemas.js
CHANGED
|
@@ -16,7 +16,7 @@ export const GitLabPipelineSchema = z.object({
|
|
|
16
16
|
created_at: z.string(),
|
|
17
17
|
updated_at: z.string(),
|
|
18
18
|
web_url: z.string(),
|
|
19
|
-
duration: z.number().nullable().optional(),
|
|
19
|
+
duration: z.coerce.number().nullable().optional(),
|
|
20
20
|
started_at: z.string().nullable().optional(),
|
|
21
21
|
finished_at: z.string().nullable().optional(),
|
|
22
22
|
coverage: z.coerce.number().nullable().optional(),
|
|
@@ -35,7 +35,7 @@ export const GitLabPipelineSchema = z.object({
|
|
|
35
35
|
label: z.string().optional(),
|
|
36
36
|
group: z.string().optional(),
|
|
37
37
|
tooltip: z.string().optional(),
|
|
38
|
-
has_details: z.boolean().optional(),
|
|
38
|
+
has_details: z.coerce.boolean().optional(),
|
|
39
39
|
details_path: z.string().optional(),
|
|
40
40
|
illustration: z
|
|
41
41
|
.object({
|
|
@@ -56,13 +56,13 @@ export const GitLabPipelineJobSchema = z.object({
|
|
|
56
56
|
stage: z.string(),
|
|
57
57
|
name: z.string(),
|
|
58
58
|
ref: z.string(),
|
|
59
|
-
tag: z.boolean(),
|
|
59
|
+
tag: z.coerce.boolean(),
|
|
60
60
|
coverage: z.coerce.number().nullable().optional(),
|
|
61
61
|
created_at: z.string(),
|
|
62
62
|
started_at: z.string().nullable().optional(),
|
|
63
63
|
finished_at: z.string().nullable().optional(),
|
|
64
|
-
duration: z.number().nullable().optional(),
|
|
65
|
-
queued_duration: z.number().nullable().optional(),
|
|
64
|
+
duration: z.coerce.number().nullable().optional(),
|
|
65
|
+
queued_duration: z.coerce.number().nullable().optional(),
|
|
66
66
|
failure_reason: z.string().nullable().optional(),
|
|
67
67
|
user: z
|
|
68
68
|
.object({
|
|
@@ -91,15 +91,15 @@ export const GitLabPipelineJobSchema = z.object({
|
|
|
91
91
|
})
|
|
92
92
|
.optional(),
|
|
93
93
|
web_url: z.string().optional(),
|
|
94
|
-
allow_failure: z.boolean().optional(),
|
|
95
|
-
retried: z.boolean().optional(),
|
|
94
|
+
allow_failure: z.coerce.boolean().optional(),
|
|
95
|
+
retried: z.coerce.boolean().optional(),
|
|
96
96
|
tag_list: z.array(z.string()).optional(),
|
|
97
97
|
runner: z
|
|
98
98
|
.object({
|
|
99
99
|
id: z.coerce.string().optional(),
|
|
100
100
|
description: z.string().nullable().optional(),
|
|
101
|
-
active: z.boolean().optional(),
|
|
102
|
-
is_shared: z.boolean().optional(),
|
|
101
|
+
active: z.coerce.boolean().optional(),
|
|
102
|
+
is_shared: z.coerce.boolean().optional(),
|
|
103
103
|
runner_type: z.string().optional(),
|
|
104
104
|
})
|
|
105
105
|
.nullable()
|
|
@@ -112,13 +112,13 @@ export const GitLabPipelineTriggerJobSchema = z.object({
|
|
|
112
112
|
stage: z.string(),
|
|
113
113
|
name: z.string(),
|
|
114
114
|
ref: z.string(),
|
|
115
|
-
tag: z.boolean(),
|
|
116
|
-
coverage: z.number().nullable().optional(),
|
|
115
|
+
tag: z.coerce.boolean(),
|
|
116
|
+
coverage: z.coerce.number().nullable().optional(),
|
|
117
117
|
created_at: z.string(),
|
|
118
118
|
started_at: z.string().nullable().optional(),
|
|
119
119
|
finished_at: z.string().nullable().optional(),
|
|
120
|
-
duration: z.number().nullable().optional(),
|
|
121
|
-
queued_duration: z.number().nullable().optional(),
|
|
120
|
+
duration: z.coerce.number().nullable().optional(),
|
|
121
|
+
queued_duration: z.coerce.number().nullable().optional(),
|
|
122
122
|
user: z
|
|
123
123
|
.object({
|
|
124
124
|
id: z.coerce.string(),
|
|
@@ -149,13 +149,13 @@ export const GitLabPipelineTriggerJobSchema = z.object({
|
|
|
149
149
|
})
|
|
150
150
|
.optional(),
|
|
151
151
|
web_url: z.string().optional(),
|
|
152
|
-
allow_failure: z.boolean().optional(),
|
|
153
|
-
archived: z.boolean().optional(),
|
|
152
|
+
allow_failure: z.coerce.boolean().optional(),
|
|
153
|
+
archived: z.coerce.boolean().optional(),
|
|
154
154
|
source: z.string().optional(),
|
|
155
155
|
erased_at: z.string().nullable().optional(),
|
|
156
156
|
project: z
|
|
157
157
|
.object({
|
|
158
|
-
ci_job_token_scope_enabled: z.boolean().optional(),
|
|
158
|
+
ci_job_token_scope_enabled: z.coerce.boolean().optional(),
|
|
159
159
|
})
|
|
160
160
|
.optional(),
|
|
161
161
|
downstream_pipeline: z
|
|
@@ -174,8 +174,8 @@ export const GitLabPipelineTriggerJobSchema = z.object({
|
|
|
174
174
|
// Shared base schema for various pagination options
|
|
175
175
|
// See https://docs.gitlab.com/api/rest/#pagination
|
|
176
176
|
export const PaginationOptionsSchema = z.object({
|
|
177
|
-
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
178
|
-
per_page: z.number().optional().describe("Number of items per page (max: 100, default: 20)"),
|
|
177
|
+
page: z.coerce.number().optional().describe("Page number for pagination (default: 1)"),
|
|
178
|
+
per_page: z.coerce.number().optional().describe("Number of items per page (max: 100, default: 20)"),
|
|
179
179
|
});
|
|
180
180
|
// Schema for listing pipelines
|
|
181
181
|
export const ListPipelinesSchema = z
|
|
@@ -203,7 +203,7 @@ export const ListPipelinesSchema = z
|
|
|
203
203
|
.describe("The status of pipelines"),
|
|
204
204
|
ref: z.string().optional().describe("The ref of pipelines"),
|
|
205
205
|
sha: z.string().optional().describe("The SHA of pipelines"),
|
|
206
|
-
yaml_errors: z.boolean().optional().describe("Returns pipelines with invalid configurations"),
|
|
206
|
+
yaml_errors: z.coerce.boolean().optional().describe("Returns pipelines with invalid configurations"),
|
|
207
207
|
username: z.string().optional().describe("The username of the user who triggered pipelines"),
|
|
208
208
|
updated_after: z
|
|
209
209
|
.string()
|
|
@@ -234,7 +234,7 @@ export const ListPipelineJobsSchema = z
|
|
|
234
234
|
.enum(["created", "pending", "running", "failed", "success", "canceled", "skipped", "manual"])
|
|
235
235
|
.optional()
|
|
236
236
|
.describe("The scope of jobs to show"),
|
|
237
|
-
include_retried: z.boolean().optional().describe("Whether to include retried jobs"),
|
|
237
|
+
include_retried: z.coerce.boolean().optional().describe("Whether to include retried jobs"),
|
|
238
238
|
})
|
|
239
239
|
.merge(PaginationOptionsSchema);
|
|
240
240
|
// Schema for listing trigger jobs (bridges) in a pipeline
|
|
@@ -362,7 +362,7 @@ export const GitLabEnvironmentSchema = z.object({
|
|
|
362
362
|
created_at: z.string().optional(),
|
|
363
363
|
updated_at: z.string().optional(),
|
|
364
364
|
auto_stop_at: z.string().nullable().optional(),
|
|
365
|
-
enable_advanced_logs_querying: z.boolean().optional(),
|
|
365
|
+
enable_advanced_logs_querying: z.coerce.boolean().optional(),
|
|
366
366
|
logs_api_path: z.string().optional(),
|
|
367
367
|
web_url: z.string().optional(),
|
|
368
368
|
last_deployment: GitLabEnvironmentLastDeploymentSchema.nullable().optional(),
|
|
@@ -441,7 +441,7 @@ export const RetryPipelineJobSchema = PipelineJobControlSchema;
|
|
|
441
441
|
export const CancelPipelineJobSchema = z.object({
|
|
442
442
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
443
443
|
job_id: z.coerce.string().describe("The ID of the job"),
|
|
444
|
-
force: z.boolean().optional().describe("Force cancellation of the job"),
|
|
444
|
+
force: z.coerce.boolean().optional().describe("Force cancellation of the job"),
|
|
445
445
|
});
|
|
446
446
|
// User schemas
|
|
447
447
|
export const GitLabUserSchema = z.object({
|
|
@@ -477,19 +477,19 @@ export const GitLabNamespaceSchema = z.object({
|
|
|
477
477
|
parent_id: z.coerce.string().nullable(),
|
|
478
478
|
avatar_url: z.string().nullable(),
|
|
479
479
|
web_url: z.string(),
|
|
480
|
-
members_count_with_descendants: z.number().optional(),
|
|
481
|
-
billable_members_count: z.number().optional(),
|
|
482
|
-
max_seats_used: z.number().optional(),
|
|
483
|
-
seats_in_use: z.number().optional(),
|
|
480
|
+
members_count_with_descendants: z.coerce.number().optional(),
|
|
481
|
+
billable_members_count: z.coerce.number().optional(),
|
|
482
|
+
max_seats_used: z.coerce.number().optional(),
|
|
483
|
+
seats_in_use: z.coerce.number().optional(),
|
|
484
484
|
plan: z.string().optional(),
|
|
485
485
|
end_date: z.string().nullable().optional(),
|
|
486
486
|
trial_ends_on: z.string().nullable().optional(),
|
|
487
|
-
trial: z.boolean().optional(),
|
|
488
|
-
root_repository_size: z.number().optional(),
|
|
489
|
-
projects_count: z.number().optional(),
|
|
487
|
+
trial: z.coerce.boolean().optional(),
|
|
488
|
+
root_repository_size: z.coerce.number().optional(),
|
|
489
|
+
projects_count: z.coerce.number().optional(),
|
|
490
490
|
});
|
|
491
491
|
export const GitLabNamespaceExistsResponseSchema = z.object({
|
|
492
|
-
exists: z.boolean(),
|
|
492
|
+
exists: z.coerce.boolean(),
|
|
493
493
|
suggests: z.array(z.string()).optional(),
|
|
494
494
|
});
|
|
495
495
|
// Repository related schemas
|
|
@@ -509,7 +509,7 @@ export const GitLabRepositorySchema = z.object({
|
|
|
509
509
|
owner: GitLabOwnerSchema.optional(),
|
|
510
510
|
web_url: z.string().optional(),
|
|
511
511
|
description: z.string().nullable(),
|
|
512
|
-
fork: z.boolean().optional(),
|
|
512
|
+
fork: z.coerce.boolean().optional(),
|
|
513
513
|
ssh_url_to_repo: z.string().optional(),
|
|
514
514
|
http_url_to_repo: z.string().optional(),
|
|
515
515
|
created_at: z.string().optional(),
|
|
@@ -529,45 +529,45 @@ export const GitLabRepositorySchema = z.object({
|
|
|
529
529
|
readme_url: z.string().optional().nullable(),
|
|
530
530
|
topics: z.array(z.string()).optional(),
|
|
531
531
|
tag_list: z.array(z.string()).optional(), // deprecated but still present
|
|
532
|
-
open_issues_count: z.number().optional(),
|
|
533
|
-
archived: z.boolean().optional(),
|
|
534
|
-
forks_count: z.number().optional(),
|
|
535
|
-
star_count: z.number().optional(),
|
|
532
|
+
open_issues_count: z.coerce.number().optional(),
|
|
533
|
+
archived: z.coerce.boolean().optional(),
|
|
534
|
+
forks_count: z.coerce.number().optional(),
|
|
535
|
+
star_count: z.coerce.number().optional(),
|
|
536
536
|
permissions: z
|
|
537
537
|
.object({
|
|
538
538
|
project_access: z
|
|
539
539
|
.object({
|
|
540
|
-
access_level: z.number(),
|
|
541
|
-
notification_level: z.number().nullable().optional(),
|
|
540
|
+
access_level: z.coerce.number(),
|
|
541
|
+
notification_level: z.coerce.number().nullable().optional(),
|
|
542
542
|
})
|
|
543
543
|
.optional()
|
|
544
544
|
.nullable(),
|
|
545
545
|
group_access: z
|
|
546
546
|
.object({
|
|
547
|
-
access_level: z.number(),
|
|
548
|
-
notification_level: z.number().nullable().optional(),
|
|
547
|
+
access_level: z.coerce.number(),
|
|
548
|
+
notification_level: z.coerce.number().nullable().optional(),
|
|
549
549
|
})
|
|
550
550
|
.optional()
|
|
551
551
|
.nullable(),
|
|
552
552
|
})
|
|
553
553
|
.optional(),
|
|
554
|
-
container_registry_enabled: z.boolean().optional(),
|
|
554
|
+
container_registry_enabled: z.coerce.boolean().optional(),
|
|
555
555
|
container_registry_access_level: z.string().optional(),
|
|
556
|
-
issues_enabled: z.boolean().optional(),
|
|
557
|
-
merge_requests_enabled: z.boolean().optional(),
|
|
556
|
+
issues_enabled: z.coerce.boolean().optional(),
|
|
557
|
+
merge_requests_enabled: z.coerce.boolean().optional(),
|
|
558
558
|
merge_requests_template: z.string().nullable().optional(),
|
|
559
|
-
wiki_enabled: z.boolean().optional(),
|
|
560
|
-
jobs_enabled: z.boolean().optional(),
|
|
561
|
-
snippets_enabled: z.boolean().optional(),
|
|
562
|
-
can_create_merge_request_in: z.boolean().optional(),
|
|
563
|
-
resolve_outdated_diff_discussions: z.boolean().nullable().optional(),
|
|
564
|
-
shared_runners_enabled: z.boolean().optional(),
|
|
559
|
+
wiki_enabled: z.coerce.boolean().optional(),
|
|
560
|
+
jobs_enabled: z.coerce.boolean().optional(),
|
|
561
|
+
snippets_enabled: z.coerce.boolean().optional(),
|
|
562
|
+
can_create_merge_request_in: z.coerce.boolean().optional(),
|
|
563
|
+
resolve_outdated_diff_discussions: z.coerce.boolean().nullable().optional(),
|
|
564
|
+
shared_runners_enabled: z.coerce.boolean().optional(),
|
|
565
565
|
shared_with_groups: z
|
|
566
566
|
.array(z.object({
|
|
567
567
|
group_id: z.coerce.string(),
|
|
568
568
|
group_name: z.string(),
|
|
569
569
|
group_full_path: z.string(),
|
|
570
|
-
group_access_level: z.number(),
|
|
570
|
+
group_access_level: z.coerce.number(),
|
|
571
571
|
}))
|
|
572
572
|
.optional(),
|
|
573
573
|
});
|
|
@@ -585,7 +585,7 @@ export const GitLabFileContentSchema = z.object({
|
|
|
585
585
|
blob_id: z.string().optional(),
|
|
586
586
|
commit_id: z.string().optional(),
|
|
587
587
|
last_commit_id: z.string().optional(),
|
|
588
|
-
execute_filemode: z.boolean().optional(),
|
|
588
|
+
execute_filemode: z.coerce.boolean().optional(),
|
|
589
589
|
});
|
|
590
590
|
export const GitLabDirectoryContentSchema = z.object({
|
|
591
591
|
name: z.string(),
|
|
@@ -619,8 +619,8 @@ export const GetRepositoryTreeSchema = z.object({
|
|
|
619
619
|
.string()
|
|
620
620
|
.optional()
|
|
621
621
|
.describe("The name of a repository branch or tag. Defaults to the default branch."),
|
|
622
|
-
recursive: z.boolean().optional().describe("Boolean value to get a recursive tree"),
|
|
623
|
-
per_page: z.number().optional().describe("Number of results to show per page"),
|
|
622
|
+
recursive: z.coerce.boolean().optional().describe("Boolean value to get a recursive tree"),
|
|
623
|
+
per_page: z.coerce.number().optional().describe("Number of results to show per page"),
|
|
624
624
|
page_token: z.string().optional().describe("The tree record ID for pagination"),
|
|
625
625
|
pagination: z.string().optional().describe("Pagination method (keyset)"),
|
|
626
626
|
});
|
|
@@ -644,9 +644,9 @@ export const GitLabCommitSchema = z.object({
|
|
|
644
644
|
parent_ids: z.array(z.string()), // Changed from parents to match GitLab API
|
|
645
645
|
stats: z
|
|
646
646
|
.object({
|
|
647
|
-
additions: z.number().optional().nullable(),
|
|
648
|
-
deletions: z.number().optional().nullable(),
|
|
649
|
-
total: z.number().optional().nullable(),
|
|
647
|
+
additions: z.coerce.number().optional().nullable(),
|
|
648
|
+
deletions: z.coerce.number().optional().nullable(),
|
|
649
|
+
total: z.coerce.number().optional().nullable(),
|
|
650
650
|
})
|
|
651
651
|
.optional(), // Only present when with_stats=true
|
|
652
652
|
trailers: z.record(z.string()).optional().default({}), // Git trailers, may be empty object
|
|
@@ -672,7 +672,7 @@ export const GitLabMilestonesSchema = z.object({
|
|
|
672
672
|
state: z.string(),
|
|
673
673
|
updated_at: z.string(),
|
|
674
674
|
created_at: z.string(),
|
|
675
|
-
expired: z.boolean(),
|
|
675
|
+
expired: z.coerce.boolean(),
|
|
676
676
|
web_url: z.string().optional(),
|
|
677
677
|
});
|
|
678
678
|
// Input schemas for operations
|
|
@@ -680,14 +680,19 @@ export const CreateRepositoryOptionsSchema = z.object({
|
|
|
680
680
|
name: z.string(),
|
|
681
681
|
description: z.string().optional(),
|
|
682
682
|
visibility: z.enum(["private", "internal", "public"]).optional(), // Changed from private to match GitLab API
|
|
683
|
-
initialize_with_readme: z.boolean().optional(), // Changed from auto_init to match GitLab API
|
|
683
|
+
initialize_with_readme: z.coerce.boolean().optional(), // Changed from auto_init to match GitLab API
|
|
684
684
|
});
|
|
685
685
|
export const CreateIssueOptionsSchema = z.object({
|
|
686
686
|
title: z.string(),
|
|
687
687
|
description: z.string().optional(), // Changed from body to match GitLab API
|
|
688
|
-
assignee_ids: z.array(z.number()).optional(), // Changed from assignees to match GitLab API
|
|
688
|
+
assignee_ids: z.array(z.coerce.number()).optional(), // Changed from assignees to match GitLab API
|
|
689
689
|
milestone_id: z.coerce.string().optional(), // Changed from milestone to match GitLab API
|
|
690
690
|
labels: z.array(z.string()).optional(),
|
|
691
|
+
issue_type: z
|
|
692
|
+
.enum(["issue", "incident", "test_case", "task"])
|
|
693
|
+
.optional()
|
|
694
|
+
.describe("The type of issue. One of issue, incident, test_case or task."),
|
|
695
|
+
weight: z.coerce.number().optional().describe("Weight of the issue (0-9)"),
|
|
691
696
|
});
|
|
692
697
|
export const GitLabDiffSchema = z.object({
|
|
693
698
|
old_path: z.string(),
|
|
@@ -695,9 +700,9 @@ export const GitLabDiffSchema = z.object({
|
|
|
695
700
|
a_mode: z.string(),
|
|
696
701
|
b_mode: z.string(),
|
|
697
702
|
diff: z.string(),
|
|
698
|
-
new_file: z.boolean(),
|
|
699
|
-
renamed_file: z.boolean(),
|
|
700
|
-
deleted_file: z.boolean(),
|
|
703
|
+
new_file: z.coerce.boolean(),
|
|
704
|
+
renamed_file: z.coerce.boolean(),
|
|
705
|
+
deleted_file: z.coerce.boolean(),
|
|
701
706
|
});
|
|
702
707
|
// Response schemas for operations
|
|
703
708
|
export const GitLabCreateUpdateFileResponseSchema = z.object({
|
|
@@ -707,11 +712,52 @@ export const GitLabCreateUpdateFileResponseSchema = z.object({
|
|
|
707
712
|
content: GitLabFileContentSchema.optional(),
|
|
708
713
|
});
|
|
709
714
|
export const GitLabSearchResponseSchema = z.object({
|
|
710
|
-
count: z.number().optional(),
|
|
711
|
-
total_pages: z.number().optional(),
|
|
712
|
-
current_page: z.number().optional(),
|
|
715
|
+
count: z.coerce.number().optional(),
|
|
716
|
+
total_pages: z.coerce.number().optional(),
|
|
717
|
+
current_page: z.coerce.number().optional(),
|
|
713
718
|
items: z.array(GitLabRepositorySchema),
|
|
714
719
|
});
|
|
720
|
+
// Search blobs (code search) schemas
|
|
721
|
+
export const GitLabSearchBlobResultSchema = z.object({
|
|
722
|
+
basename: z.string(),
|
|
723
|
+
data: z.string(),
|
|
724
|
+
path: z.string(),
|
|
725
|
+
filename: z.string(),
|
|
726
|
+
id: z.union([z.string(), z.null()]).optional(),
|
|
727
|
+
ref: z.string(),
|
|
728
|
+
startline: z.coerce.number(),
|
|
729
|
+
project_id: z.coerce.string(),
|
|
730
|
+
});
|
|
731
|
+
const SearchBlobsBaseSchema = z.object({
|
|
732
|
+
search: z
|
|
733
|
+
.string()
|
|
734
|
+
.describe('Code search query string. On instances with exact code search (Zoekt), the query supports rich inline syntax: "class foo" (exact match), foo file:\\.js$ (file pattern), foo lang:ruby (language), sym:foo (symbol search), foo -bar (negation), case:yes (case-sensitive). When using Zoekt inline filters, prefer them over the separate filename/path/extension params which are for basic search.'),
|
|
735
|
+
filename: z
|
|
736
|
+
.string()
|
|
737
|
+
.optional()
|
|
738
|
+
.describe("Filter by filename (supports * wildcard, e.g. '*.ts')"),
|
|
739
|
+
path: z
|
|
740
|
+
.string()
|
|
741
|
+
.optional()
|
|
742
|
+
.describe("Filter by file path (supports * wildcard, e.g. 'src/utils/*')"),
|
|
743
|
+
extension: z
|
|
744
|
+
.string()
|
|
745
|
+
.optional()
|
|
746
|
+
.describe("Filter by file extension without dot (e.g. 'py', 'ts')"),
|
|
747
|
+
});
|
|
748
|
+
export const SearchCodeSchema = SearchBlobsBaseSchema.merge(PaginationOptionsSchema);
|
|
749
|
+
export const SearchProjectCodeSchema = ProjectParamsSchema.extend({
|
|
750
|
+
...SearchBlobsBaseSchema.shape,
|
|
751
|
+
ref: z.string().optional().describe("Branch or tag to search in (defaults to default branch)"),
|
|
752
|
+
}).merge(PaginationOptionsSchema);
|
|
753
|
+
export const SearchGroupCodeSchema = z
|
|
754
|
+
.object({
|
|
755
|
+
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
|
|
756
|
+
})
|
|
757
|
+
.extend({
|
|
758
|
+
...SearchBlobsBaseSchema.shape,
|
|
759
|
+
})
|
|
760
|
+
.merge(PaginationOptionsSchema);
|
|
715
761
|
// create branch schemas
|
|
716
762
|
export const CreateBranchOptionsSchema = z.object({
|
|
717
763
|
name: z.string(), // Changed from ref to match GitLab API
|
|
@@ -730,8 +776,8 @@ export const GitLabCompareResultSchema = z.object({
|
|
|
730
776
|
.optional(),
|
|
731
777
|
commits: z.array(GitLabCommitSchema),
|
|
732
778
|
diffs: z.array(GitLabDiffSchema),
|
|
733
|
-
compare_timeout: z.boolean().optional(),
|
|
734
|
-
compare_same_ref: z.boolean().optional(),
|
|
779
|
+
compare_timeout: z.coerce.boolean().optional(),
|
|
780
|
+
compare_same_ref: z.coerce.boolean().optional(),
|
|
735
781
|
});
|
|
736
782
|
// Issue related schemas
|
|
737
783
|
export const GitLabLabelSchema = z.object({
|
|
@@ -741,12 +787,12 @@ export const GitLabLabelSchema = z.object({
|
|
|
741
787
|
text_color: z.string(),
|
|
742
788
|
description: z.string().nullable(),
|
|
743
789
|
description_html: z.string().nullable(),
|
|
744
|
-
open_issues_count: z.number().optional(),
|
|
745
|
-
closed_issues_count: z.number().optional(),
|
|
746
|
-
open_merge_requests_count: z.number().optional(),
|
|
747
|
-
subscribed: z.boolean().optional(),
|
|
748
|
-
priority: z.number().nullable().optional(),
|
|
749
|
-
is_project_label: z.boolean().optional(),
|
|
790
|
+
open_issues_count: z.coerce.number().optional(),
|
|
791
|
+
closed_issues_count: z.coerce.number().optional(),
|
|
792
|
+
open_merge_requests_count: z.coerce.number().optional(),
|
|
793
|
+
subscribed: z.coerce.boolean().optional(),
|
|
794
|
+
priority: z.coerce.number().nullable().optional(),
|
|
795
|
+
is_project_label: z.coerce.boolean().optional(),
|
|
750
796
|
});
|
|
751
797
|
export const GitLabMilestoneSchema = z.object({
|
|
752
798
|
id: z.coerce.string(),
|
|
@@ -780,16 +826,16 @@ export const GitLabIssueSchema = z.object({
|
|
|
780
826
|
.optional(),
|
|
781
827
|
time_stats: z
|
|
782
828
|
.object({
|
|
783
|
-
time_estimate: z.number(),
|
|
784
|
-
total_time_spent: z.number(),
|
|
829
|
+
time_estimate: z.coerce.number(),
|
|
830
|
+
total_time_spent: z.coerce.number(),
|
|
785
831
|
human_time_estimate: z.string().nullable(),
|
|
786
832
|
human_total_time_spent: z.string().nullable(),
|
|
787
833
|
})
|
|
788
834
|
.optional(),
|
|
789
|
-
confidential: z.boolean().optional(),
|
|
835
|
+
confidential: z.coerce.boolean().optional(),
|
|
790
836
|
due_date: z.string().nullable().optional(),
|
|
791
|
-
discussion_locked: z.boolean().nullable().optional(),
|
|
792
|
-
weight: z.number().nullable().optional(),
|
|
837
|
+
discussion_locked: z.coerce.boolean().nullable().optional(),
|
|
838
|
+
weight: z.coerce.number().nullable().optional(),
|
|
793
839
|
issue_type: z.string().describe("the type of issue.").nullish(),
|
|
794
840
|
});
|
|
795
841
|
// NEW SCHEMA: For issue with link details (used in listing issue links)
|
|
@@ -828,8 +874,8 @@ export const GitLabMergeRequestSchema = z.object({
|
|
|
828
874
|
title: z.string(),
|
|
829
875
|
description: z.string().nullable(),
|
|
830
876
|
state: z.string(),
|
|
831
|
-
merged: z.boolean().optional(),
|
|
832
|
-
draft: z.boolean().optional(),
|
|
877
|
+
merged: z.coerce.boolean().optional(),
|
|
878
|
+
draft: z.coerce.boolean().optional(),
|
|
833
879
|
author: GitLabUserSchema,
|
|
834
880
|
assignees: z.array(GitLabUserSchema).optional(),
|
|
835
881
|
reviewers: z.array(GitLabUserSchema).optional(),
|
|
@@ -845,12 +891,12 @@ export const GitLabMergeRequestSchema = z.object({
|
|
|
845
891
|
detailed_merge_status: z.string().optional(),
|
|
846
892
|
merge_status: z.string().optional(),
|
|
847
893
|
merge_error: z.string().nullable().optional(),
|
|
848
|
-
work_in_progress: z.boolean().optional(),
|
|
849
|
-
blocking_discussions_resolved: z.boolean().optional(),
|
|
850
|
-
should_remove_source_branch: z.boolean().nullable().optional(),
|
|
851
|
-
force_remove_source_branch: z.boolean().nullable().optional(),
|
|
852
|
-
allow_collaboration: z.boolean().optional(),
|
|
853
|
-
allow_maintainer_to_push: z.boolean().optional(),
|
|
894
|
+
work_in_progress: z.coerce.boolean().optional(),
|
|
895
|
+
blocking_discussions_resolved: z.coerce.boolean().optional(),
|
|
896
|
+
should_remove_source_branch: z.coerce.boolean().nullable().optional(),
|
|
897
|
+
force_remove_source_branch: z.coerce.boolean().nullable().optional(),
|
|
898
|
+
allow_collaboration: z.coerce.boolean().optional(),
|
|
899
|
+
allow_maintainer_to_push: z.coerce.boolean().optional(),
|
|
854
900
|
changes_count: z.string().nullable().optional(),
|
|
855
901
|
diverged_commits_count: z.coerce
|
|
856
902
|
.number()
|
|
@@ -861,8 +907,8 @@ export const GitLabMergeRequestSchema = z.object({
|
|
|
861
907
|
.boolean()
|
|
862
908
|
.optional()
|
|
863
909
|
.describe("Whether rebase is currently in progress for this merge request"),
|
|
864
|
-
merge_when_pipeline_succeeds: z.boolean().optional(),
|
|
865
|
-
squash: z.boolean().optional(),
|
|
910
|
+
merge_when_pipeline_succeeds: z.coerce.boolean().optional(),
|
|
911
|
+
squash: z.coerce.boolean().optional(),
|
|
866
912
|
labels: z.array(z.string()).optional(),
|
|
867
913
|
});
|
|
868
914
|
export const LineRangeSchema = z
|
|
@@ -927,13 +973,13 @@ export const GitLabDiscussionNoteSchema = z
|
|
|
927
973
|
author: GitLabUserSchema.optional(),
|
|
928
974
|
created_at: z.string().optional(),
|
|
929
975
|
updated_at: z.string().optional(),
|
|
930
|
-
system: z.boolean().optional(),
|
|
976
|
+
system: z.coerce.boolean().optional(),
|
|
931
977
|
noteable_id: z.coerce.string().optional(),
|
|
932
978
|
noteable_type: z.enum(["Issue", "MergeRequest", "Snippet", "Commit", "Epic"]).optional(),
|
|
933
979
|
project_id: z.coerce.string().optional(),
|
|
934
980
|
noteable_iid: z.coerce.string().nullable().optional(),
|
|
935
|
-
resolvable: z.boolean().optional(),
|
|
936
|
-
resolved: z.boolean().optional(),
|
|
981
|
+
resolvable: z.coerce.boolean().optional(),
|
|
982
|
+
resolved: z.coerce.boolean().optional(),
|
|
937
983
|
resolved_by: GitLabUserSchema.nullable().optional(),
|
|
938
984
|
resolved_at: z.string().nullable().optional(),
|
|
939
985
|
position: z
|
|
@@ -956,10 +1002,10 @@ export const GitLabDiscussionNoteSchema = z
|
|
|
956
1002
|
.optional()
|
|
957
1003
|
.describe("Line number in the original file (before changes). Used for deleted lines and context lines. Null for newly added lines."),
|
|
958
1004
|
line_range: LineRangeSchema.nullable().optional(), // Accept any value for line_range including null
|
|
959
|
-
width: z.number().nullable().optional(), // For image diff notes
|
|
960
|
-
height: z.number().nullable().optional(), // For image diff notes
|
|
961
|
-
x: z.number().nullable().optional(), // For image diff notes
|
|
962
|
-
y: z.number().nullable().optional(), // For image diff notes
|
|
1005
|
+
width: z.coerce.number().nullable().optional(), // For image diff notes
|
|
1006
|
+
height: z.coerce.number().nullable().optional(), // For image diff notes
|
|
1007
|
+
x: z.coerce.number().nullable().optional(), // For image diff notes
|
|
1008
|
+
y: z.coerce.number().nullable().optional(), // For image diff notes
|
|
963
1009
|
})
|
|
964
1010
|
.passthrough() // Allow additional fields
|
|
965
1011
|
.optional(),
|
|
@@ -968,12 +1014,12 @@ export const GitLabDiscussionNoteSchema = z
|
|
|
968
1014
|
// Reusable pagination schema for GitLab API responses.
|
|
969
1015
|
// See https://docs.gitlab.com/api/rest/#pagination
|
|
970
1016
|
export const GitLabPaginationSchema = z.object({
|
|
971
|
-
x_next_page: z.number().nullable().optional(),
|
|
972
|
-
x_page: z.number().optional(),
|
|
973
|
-
x_per_page: z.number().optional(),
|
|
974
|
-
x_prev_page: z.number().nullable().optional(),
|
|
975
|
-
x_total: z.number().nullable().optional(),
|
|
976
|
-
x_total_pages: z.number().nullable().optional(),
|
|
1017
|
+
x_next_page: z.coerce.number().nullable().optional(),
|
|
1018
|
+
x_page: z.coerce.number().optional(),
|
|
1019
|
+
x_per_page: z.coerce.number().optional(),
|
|
1020
|
+
x_prev_page: z.coerce.number().nullable().optional(),
|
|
1021
|
+
x_total: z.coerce.number().nullable().optional(),
|
|
1022
|
+
x_total_pages: z.coerce.number().nullable().optional(),
|
|
977
1023
|
});
|
|
978
1024
|
// Base paginated response schema that can be extended.
|
|
979
1025
|
// See https://docs.gitlab.com/api/rest/#pagination
|
|
@@ -982,7 +1028,7 @@ export const PaginatedResponseSchema = z.object({
|
|
|
982
1028
|
});
|
|
983
1029
|
export const GitLabDiscussionSchema = z.object({
|
|
984
1030
|
id: z.coerce.string(),
|
|
985
|
-
individual_note: z.boolean(),
|
|
1031
|
+
individual_note: z.coerce.boolean(),
|
|
986
1032
|
notes: z.array(GitLabDiscussionNoteSchema),
|
|
987
1033
|
});
|
|
988
1034
|
// Create a schema for paginated discussions response
|
|
@@ -1041,7 +1087,7 @@ export const UpdateMergeRequestDiscussionNoteSchema = ProjectParamsSchema.extend
|
|
|
1041
1087
|
discussion_id: z.coerce.string().describe("The ID of a thread"),
|
|
1042
1088
|
note_id: z.coerce.string().describe("The ID of a thread note"),
|
|
1043
1089
|
body: z.string().optional().describe("The content of the note or reply"),
|
|
1044
|
-
resolved: z.boolean().optional().describe("Resolve or unresolve the note"),
|
|
1090
|
+
resolved: z.coerce.boolean().optional().describe("Resolve or unresolve the note"),
|
|
1045
1091
|
})
|
|
1046
1092
|
.refine(data => data.body !== undefined || data.resolved !== undefined, {
|
|
1047
1093
|
message: "At least one of 'body' or 'resolved' must be provided",
|
|
@@ -1062,7 +1108,7 @@ export const UpdateIssueNoteSchema = ProjectParamsSchema.extend({
|
|
|
1062
1108
|
discussion_id: z.coerce.string().describe("The ID of a thread"),
|
|
1063
1109
|
note_id: z.coerce.string().describe("The ID of a thread note"),
|
|
1064
1110
|
body: z.string().optional().describe("The content of the note or reply"),
|
|
1065
|
-
resolved: z.boolean().optional().describe("Resolve or unresolve the note"),
|
|
1111
|
+
resolved: z.coerce.boolean().optional().describe("Resolve or unresolve the note"),
|
|
1066
1112
|
})
|
|
1067
1113
|
.refine(data => data.body !== undefined || data.resolved !== undefined, {
|
|
1068
1114
|
message: "At least one of 'body' or 'resolved' must be provided",
|
|
@@ -1099,7 +1145,7 @@ export const CreateRepositorySchema = z.object({
|
|
|
1099
1145
|
.enum(["private", "internal", "public"])
|
|
1100
1146
|
.optional()
|
|
1101
1147
|
.describe("Repository visibility level"),
|
|
1102
|
-
initialize_with_readme: z.boolean().optional().describe("Initialize with README.md"),
|
|
1148
|
+
initialize_with_readme: z.coerce.boolean().optional().describe("Initialize with README.md"),
|
|
1103
1149
|
});
|
|
1104
1150
|
export const GetFileContentsSchema = z
|
|
1105
1151
|
.object({
|
|
@@ -1151,14 +1197,15 @@ export const PushFilesSchema = ProjectParamsSchema.extend({
|
|
|
1151
1197
|
export const CreateIssueSchema = ProjectParamsSchema.extend({
|
|
1152
1198
|
title: z.string().describe("Issue title"),
|
|
1153
1199
|
description: z.string().optional().describe("Issue description"),
|
|
1154
|
-
assignee_ids: z.array(z.number()).optional().describe("Array of user IDs to assign"),
|
|
1200
|
+
assignee_ids: z.array(z.coerce.number()).optional().describe("Array of user IDs to assign"),
|
|
1155
1201
|
labels: z.array(z.string()).optional().describe("Array of label names"),
|
|
1156
1202
|
milestone_id: z.coerce.string().optional().describe("Milestone ID to assign"),
|
|
1157
1203
|
issue_type: z
|
|
1158
1204
|
.enum(["issue", "incident", "test_case", "task"])
|
|
1159
|
-
.
|
|
1160
|
-
.
|
|
1161
|
-
.
|
|
1205
|
+
.optional()
|
|
1206
|
+
.default("issue")
|
|
1207
|
+
.describe("The type of issue. One of issue, incident, test_case or task."),
|
|
1208
|
+
weight: z.coerce.number().optional().describe("Weight of the issue (numeric, typically hours of work)"),
|
|
1162
1209
|
});
|
|
1163
1210
|
const MergeRequestOptionsSchema = {
|
|
1164
1211
|
title: z.string().describe("Merge request title"),
|
|
@@ -1166,14 +1213,14 @@ const MergeRequestOptionsSchema = {
|
|
|
1166
1213
|
source_branch: z.string().describe("Branch containing changes"),
|
|
1167
1214
|
target_branch: z.string().describe("Branch to merge into"),
|
|
1168
1215
|
target_project_id: z.coerce.string().optional().describe("Numeric ID of the target project."),
|
|
1169
|
-
assignee_ids: z.array(z.number()).optional().describe("The ID of the users to assign the MR to"),
|
|
1216
|
+
assignee_ids: z.array(z.coerce.number()).optional().describe("The ID of the users to assign the MR to"),
|
|
1170
1217
|
reviewer_ids: z
|
|
1171
|
-
.array(z.number())
|
|
1218
|
+
.array(z.coerce.number())
|
|
1172
1219
|
.optional()
|
|
1173
1220
|
.describe("The ID of the users to assign as reviewers of the MR"),
|
|
1174
1221
|
labels: z.array(z.string()).optional().describe("Labels for the MR"),
|
|
1175
|
-
draft: z.boolean().optional().describe("Create as draft merge request"),
|
|
1176
|
-
allow_collaboration: z.boolean().optional().describe("Allow commits from upstream members"),
|
|
1222
|
+
draft: z.coerce.boolean().optional().describe("Create as draft merge request"),
|
|
1223
|
+
allow_collaboration: z.coerce.boolean().optional().describe("Allow commits from upstream members"),
|
|
1177
1224
|
remove_source_branch: z
|
|
1178
1225
|
.boolean()
|
|
1179
1226
|
.nullable()
|
|
@@ -1215,9 +1262,9 @@ export const UpdateMergeRequestSchema = GetMergeRequestSchema.extend({
|
|
|
1215
1262
|
title: z.string().optional().describe("The title of the merge request"),
|
|
1216
1263
|
description: z.string().optional().describe("The description of the merge request"),
|
|
1217
1264
|
target_branch: z.string().optional().describe("The target branch"),
|
|
1218
|
-
assignee_ids: z.array(z.number()).optional().describe("The ID of the users to assign the MR to"),
|
|
1265
|
+
assignee_ids: z.array(z.coerce.number()).optional().describe("The ID of the users to assign the MR to"),
|
|
1219
1266
|
reviewer_ids: z
|
|
1220
|
-
.array(z.number())
|
|
1267
|
+
.array(z.coerce.number())
|
|
1221
1268
|
.optional()
|
|
1222
1269
|
.describe("The ID of the users to assign as reviewers of the MR"),
|
|
1223
1270
|
labels: z.array(z.string()).optional().describe("Labels for the MR"),
|
|
@@ -1229,8 +1276,8 @@ export const UpdateMergeRequestSchema = GetMergeRequestSchema.extend({
|
|
|
1229
1276
|
.boolean()
|
|
1230
1277
|
.optional()
|
|
1231
1278
|
.describe("Flag indicating if the source branch should be removed"),
|
|
1232
|
-
squash: z.boolean().optional().describe("Squash commits into a single commit when merging"),
|
|
1233
|
-
draft: z.boolean().optional().describe("Work in progress merge request"),
|
|
1279
|
+
squash: z.coerce.boolean().optional().describe("Squash commits into a single commit when merging"),
|
|
1280
|
+
draft: z.coerce.boolean().optional().describe("Work in progress merge request"),
|
|
1234
1281
|
});
|
|
1235
1282
|
export const MergeMergeRequestSchema = ProjectParamsSchema.extend({
|
|
1236
1283
|
merge_request_iid: z.coerce.string().optional().describe("The IID of a merge request"),
|
|
@@ -1286,7 +1333,7 @@ export const GitLabApprovalRuleSchema = z.object({
|
|
|
1286
1333
|
name: z.string(),
|
|
1287
1334
|
rule_type: z.string(),
|
|
1288
1335
|
eligible_approvers: z.array(GitLabApprovalUserSchema).optional(),
|
|
1289
|
-
approvals_required: z.number(),
|
|
1336
|
+
approvals_required: z.coerce.number(),
|
|
1290
1337
|
users: z.array(GitLabApprovalUserSchema).optional(),
|
|
1291
1338
|
groups: z
|
|
1292
1339
|
.array(z.object({
|
|
@@ -1298,7 +1345,7 @@ export const GitLabApprovalRuleSchema = z.object({
|
|
|
1298
1345
|
web_url: z.string(),
|
|
1299
1346
|
}))
|
|
1300
1347
|
.optional(),
|
|
1301
|
-
contains_hidden_groups: z.boolean().optional(),
|
|
1348
|
+
contains_hidden_groups: z.coerce.boolean().optional(),
|
|
1302
1349
|
approved_by: z.array(GitLabApprovalUserSchema).optional(),
|
|
1303
1350
|
source_rule: z
|
|
1304
1351
|
.object({
|
|
@@ -1308,12 +1355,12 @@ export const GitLabApprovalRuleSchema = z.object({
|
|
|
1308
1355
|
})
|
|
1309
1356
|
.nullable()
|
|
1310
1357
|
.optional(),
|
|
1311
|
-
approved: z.boolean().optional(),
|
|
1358
|
+
approved: z.coerce.boolean().optional(),
|
|
1312
1359
|
});
|
|
1313
1360
|
export const GitLabMergeRequestApprovalsResponseSchema = z.object({
|
|
1314
|
-
approved: z.boolean().optional(),
|
|
1315
|
-
user_has_approved: z.boolean().optional(),
|
|
1316
|
-
user_can_approve: z.boolean().optional(),
|
|
1361
|
+
approved: z.coerce.boolean().optional(),
|
|
1362
|
+
user_has_approved: z.coerce.boolean().optional(),
|
|
1363
|
+
user_can_approve: z.coerce.boolean().optional(),
|
|
1317
1364
|
approved_by: z
|
|
1318
1365
|
.array(z.object({
|
|
1319
1366
|
user: GitLabApprovalUserSchema,
|
|
@@ -1321,11 +1368,11 @@ export const GitLabMergeRequestApprovalsResponseSchema = z.object({
|
|
|
1321
1368
|
.optional(),
|
|
1322
1369
|
});
|
|
1323
1370
|
export const GitLabMergeRequestApprovalStateSchema = z.object({
|
|
1324
|
-
approval_rules_overwritten: z.boolean().optional(),
|
|
1371
|
+
approval_rules_overwritten: z.coerce.boolean().optional(),
|
|
1325
1372
|
rules: z.array(GitLabApprovalRuleSchema).optional(),
|
|
1326
|
-
approved: z.boolean().optional(),
|
|
1327
|
-
user_has_approved: z.boolean().optional(),
|
|
1328
|
-
user_can_approve: z.boolean().optional(),
|
|
1373
|
+
approved: z.coerce.boolean().optional(),
|
|
1374
|
+
user_has_approved: z.coerce.boolean().optional(),
|
|
1375
|
+
user_can_approve: z.coerce.boolean().optional(),
|
|
1329
1376
|
approved_by: z.array(GitLabApprovalUserSchema).optional(),
|
|
1330
1377
|
approved_by_usernames: z.array(z.string()).optional(),
|
|
1331
1378
|
source_endpoint: z.enum(["approval_state", "approvals"]).optional(),
|
|
@@ -1333,6 +1380,9 @@ export const GitLabMergeRequestApprovalStateSchema = z.object({
|
|
|
1333
1380
|
export const GetMergeRequestApprovalStateSchema = ProjectParamsSchema.extend({
|
|
1334
1381
|
merge_request_iid: z.coerce.string().describe("The IID of the merge request"),
|
|
1335
1382
|
});
|
|
1383
|
+
export const GetMergeRequestConflictsSchema = ProjectParamsSchema.extend({
|
|
1384
|
+
merge_request_iid: z.coerce.string().describe("The IID of the merge request"),
|
|
1385
|
+
});
|
|
1336
1386
|
export const GetMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
|
|
1337
1387
|
view: z.enum(["inline", "parallel"]).optional().describe("Diff view type"),
|
|
1338
1388
|
excluded_file_patterns: z
|
|
@@ -1341,13 +1391,29 @@ export const GetMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
|
|
|
1341
1391
|
.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: ["^vendor/", "^test/mocks/", "\\.spec\\.ts$", "package-lock\\.json"]'),
|
|
1342
1392
|
});
|
|
1343
1393
|
export const ListMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
|
|
1344
|
-
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
1345
|
-
per_page: z.number().optional().describe("Number of items per page (max: 100, default: 20)"),
|
|
1394
|
+
page: z.coerce.number().optional().describe("Page number for pagination (default: 1)"),
|
|
1395
|
+
per_page: z.coerce.number().optional().describe("Number of items per page (max: 100, default: 20)"),
|
|
1346
1396
|
unidiff: z
|
|
1347
1397
|
.boolean()
|
|
1348
1398
|
.optional()
|
|
1349
1399
|
.describe("Present diffs in the unified diff format. Default is false. Introduced in GitLab 16.5."),
|
|
1350
1400
|
});
|
|
1401
|
+
export const ListMergeRequestChangedFilesSchema = GetMergeRequestSchema.extend({
|
|
1402
|
+
excluded_file_patterns: z
|
|
1403
|
+
.array(z.string())
|
|
1404
|
+
.optional()
|
|
1405
|
+
.describe('Array of regex patterns to exclude files. Examples: ["^vendor/", "\\.pb\\.go$"]'),
|
|
1406
|
+
});
|
|
1407
|
+
export const GetMergeRequestFileDiffSchema = GetMergeRequestSchema.extend({
|
|
1408
|
+
file_paths: z
|
|
1409
|
+
.array(z.string())
|
|
1410
|
+
.describe("List of file paths to retrieve diffs for (e.g. ['src/api/users.ts', 'src/repo/user.go']). " +
|
|
1411
|
+
"Call list_merge_request_changed_files first to get the full list of changed paths."),
|
|
1412
|
+
unidiff: z
|
|
1413
|
+
.boolean()
|
|
1414
|
+
.optional()
|
|
1415
|
+
.describe("Present diff in the unified diff format. Default is false."),
|
|
1416
|
+
});
|
|
1351
1417
|
// Merge Request Versions API operation schemas
|
|
1352
1418
|
export const ListMergeRequestVersionsSchema = ProjectParamsSchema.extend({
|
|
1353
1419
|
merge_request_iid: z.coerce.string().describe("The internal ID of the merge request"),
|
|
@@ -1384,7 +1450,7 @@ export const ListIssuesSchema = z
|
|
|
1384
1450
|
.describe("Return issues assigned to the given username"),
|
|
1385
1451
|
author_id: z.coerce.string().optional().describe("Return issues created by the given user ID"),
|
|
1386
1452
|
author_username: z.string().optional().describe("Return issues created by the given username"),
|
|
1387
|
-
confidential: z.boolean().optional().describe("Filter confidential or public issues"),
|
|
1453
|
+
confidential: z.coerce.boolean().optional().describe("Filter confidential or public issues"),
|
|
1388
1454
|
created_after: z.string().optional().describe("Return issues created after the given time"),
|
|
1389
1455
|
created_before: z.string().optional().describe("Return issues created before the given time"),
|
|
1390
1456
|
due_date: z.string().optional().describe("Return issues that have the due date"),
|
|
@@ -1409,7 +1475,7 @@ export const ListIssuesSchema = z
|
|
|
1409
1475
|
.describe("Return issues with a specific state"),
|
|
1410
1476
|
updated_after: z.string().optional().describe("Return issues updated after the given time"),
|
|
1411
1477
|
updated_before: z.string().optional().describe("Return issues updated before the given time"),
|
|
1412
|
-
with_labels_details: z.boolean().optional().describe("Return more details for each label"),
|
|
1478
|
+
with_labels_details: z.coerce.boolean().optional().describe("Return more details for each label"),
|
|
1413
1479
|
})
|
|
1414
1480
|
.merge(PaginationOptionsSchema);
|
|
1415
1481
|
// Merge Requests API operation schemas
|
|
@@ -1422,27 +1488,27 @@ export const ListMergeRequestsSchema = z
|
|
|
1422
1488
|
assignee_id: z.coerce
|
|
1423
1489
|
.string()
|
|
1424
1490
|
.optional()
|
|
1425
|
-
.describe("Return
|
|
1491
|
+
.describe("Return MRs assigned to the given user ID (integer), 'none', or 'any'. Mutually exclusive with assignee_username."),
|
|
1426
1492
|
assignee_username: z
|
|
1427
1493
|
.string()
|
|
1428
1494
|
.optional()
|
|
1429
|
-
.describe("Returns merge requests assigned to the given username"),
|
|
1495
|
+
.describe("Returns merge requests assigned to the given username. Mutually exclusive with assignee_id."),
|
|
1430
1496
|
author_id: z.coerce
|
|
1431
1497
|
.string()
|
|
1432
1498
|
.optional()
|
|
1433
|
-
.describe("Returns merge requests created by the given user ID"),
|
|
1499
|
+
.describe("Returns merge requests created by the given user ID (integer). Mutually exclusive with author_username."),
|
|
1434
1500
|
author_username: z
|
|
1435
1501
|
.string()
|
|
1436
1502
|
.optional()
|
|
1437
|
-
.describe("Returns merge requests created by the given username"),
|
|
1503
|
+
.describe("Returns merge requests created by the given username. Mutually exclusive with author_id."),
|
|
1438
1504
|
reviewer_id: z.coerce
|
|
1439
1505
|
.string()
|
|
1440
1506
|
.optional()
|
|
1441
|
-
.describe("Returns merge requests which have the user as a reviewer.
|
|
1507
|
+
.describe("Returns merge requests which have the user as a reviewer. Must be an integer, 'none', or 'any'. Mutually exclusive with reviewer_username."),
|
|
1442
1508
|
reviewer_username: z
|
|
1443
1509
|
.string()
|
|
1444
1510
|
.optional()
|
|
1445
|
-
.describe("Returns merge requests which have the user as a reviewer"),
|
|
1511
|
+
.describe("Returns merge requests which have the user as a reviewer by username. Mutually exclusive with reviewer_id."),
|
|
1446
1512
|
created_after: z
|
|
1447
1513
|
.string()
|
|
1448
1514
|
.optional()
|
|
@@ -1497,7 +1563,7 @@ export const ListMergeRequestsSchema = z
|
|
|
1497
1563
|
.enum(["yes", "no"])
|
|
1498
1564
|
.optional()
|
|
1499
1565
|
.describe("Filter merge requests against their wip status"),
|
|
1500
|
-
with_labels_details: z.boolean().optional().describe("Return more details for each label"),
|
|
1566
|
+
with_labels_details: z.coerce.boolean().optional().describe("Return more details for each label"),
|
|
1501
1567
|
})
|
|
1502
1568
|
.merge(PaginationOptionsSchema);
|
|
1503
1569
|
export const GetIssueSchema = z.object({
|
|
@@ -1509,17 +1575,18 @@ export const UpdateIssueSchema = z.object({
|
|
|
1509
1575
|
issue_iid: z.coerce.string().describe("The internal ID of the project issue"),
|
|
1510
1576
|
title: z.string().optional().describe("The title of the issue"),
|
|
1511
1577
|
description: z.string().optional().describe("The description of the issue"),
|
|
1512
|
-
assignee_ids: z.array(z.number()).optional().describe("Array of user IDs to assign issue to"),
|
|
1513
|
-
confidential: z.boolean().optional().describe("Set the issue to be confidential"),
|
|
1514
|
-
discussion_locked: z.boolean().optional().describe("Flag to lock discussions"),
|
|
1578
|
+
assignee_ids: z.array(z.coerce.number()).optional().describe("Array of user IDs to assign issue to"),
|
|
1579
|
+
confidential: z.coerce.boolean().optional().describe("Set the issue to be confidential"),
|
|
1580
|
+
discussion_locked: z.coerce.boolean().optional().describe("Flag to lock discussions"),
|
|
1515
1581
|
due_date: z.string().optional().describe("Date the issue is due (YYYY-MM-DD)"),
|
|
1516
1582
|
labels: z.array(z.string()).optional().describe("Array of label names"),
|
|
1517
1583
|
milestone_id: z.coerce.string().optional().describe("Milestone ID to assign"),
|
|
1518
1584
|
state_event: z.enum(["close", "reopen"]).optional().describe("Update issue state (close/reopen)"),
|
|
1519
|
-
weight: z.number().optional().describe("Weight of the issue (
|
|
1585
|
+
weight: z.coerce.number().optional().describe("Weight of the issue (numeric, typically hours of work)"),
|
|
1520
1586
|
issue_type: z
|
|
1521
1587
|
.enum(["issue", "incident", "test_case", "task"])
|
|
1522
|
-
.
|
|
1588
|
+
.optional()
|
|
1589
|
+
.describe("The type of issue. One of issue, incident, test_case or task."),
|
|
1523
1590
|
});
|
|
1524
1591
|
export const DeleteIssueSchema = z.object({
|
|
1525
1592
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1559,7 +1626,7 @@ export const DeleteIssueLinkSchema = z.object({
|
|
|
1559
1626
|
export const ListNamespacesSchema = z
|
|
1560
1627
|
.object({
|
|
1561
1628
|
search: z.string().optional().describe("Search term for namespaces"),
|
|
1562
|
-
owned: z.boolean().optional().describe("Filter for namespaces owned by current user"),
|
|
1629
|
+
owned: z.coerce.boolean().optional().describe("Filter for namespaces owned by current user"),
|
|
1563
1630
|
})
|
|
1564
1631
|
.merge(PaginationOptionsSchema);
|
|
1565
1632
|
export const GetNamespaceSchema = z.object({
|
|
@@ -1575,14 +1642,14 @@ export const GetProjectSchema = z.object({
|
|
|
1575
1642
|
export const ListProjectsSchema = z
|
|
1576
1643
|
.object({
|
|
1577
1644
|
search: z.string().optional().describe("Search term for projects"),
|
|
1578
|
-
search_namespaces: z.boolean().optional().describe("Needs to be true if search is full path"),
|
|
1579
|
-
owned: z.boolean().optional().describe("Filter for projects owned by current user"),
|
|
1645
|
+
search_namespaces: z.coerce.boolean().optional().describe("Needs to be true if search is full path"),
|
|
1646
|
+
owned: z.coerce.boolean().optional().describe("Filter for projects owned by current user"),
|
|
1580
1647
|
membership: z
|
|
1581
1648
|
.boolean()
|
|
1582
1649
|
.optional()
|
|
1583
1650
|
.describe("Filter for projects where current user is a member"),
|
|
1584
|
-
simple: z.boolean().optional().describe("Return only limited fields"),
|
|
1585
|
-
archived: z.boolean().optional().describe("Filter for archived projects"),
|
|
1651
|
+
simple: z.coerce.boolean().optional().describe("Return only limited fields"),
|
|
1652
|
+
archived: z.coerce.boolean().optional().describe("Filter for archived projects"),
|
|
1586
1653
|
visibility: z
|
|
1587
1654
|
.enum(["public", "internal", "private"])
|
|
1588
1655
|
.optional()
|
|
@@ -1603,7 +1670,7 @@ export const ListProjectsSchema = z
|
|
|
1603
1670
|
.boolean()
|
|
1604
1671
|
.optional()
|
|
1605
1672
|
.describe("Filter projects with merge requests feature enabled"),
|
|
1606
|
-
min_access_level: z.number().optional().describe("Filter by minimum access level"),
|
|
1673
|
+
min_access_level: z.coerce.number().optional().describe("Filter by minimum access level"),
|
|
1607
1674
|
})
|
|
1608
1675
|
.merge(PaginationOptionsSchema);
|
|
1609
1676
|
// Label operation schemas
|
|
@@ -1613,13 +1680,13 @@ export const ListLabelsSchema = z.object({
|
|
|
1613
1680
|
.boolean()
|
|
1614
1681
|
.optional()
|
|
1615
1682
|
.describe("Whether or not to include issue and merge request counts"),
|
|
1616
|
-
include_ancestor_groups: z.boolean().optional().describe("Include ancestor groups"),
|
|
1683
|
+
include_ancestor_groups: z.coerce.boolean().optional().describe("Include ancestor groups"),
|
|
1617
1684
|
search: z.string().optional().describe("Keyword to filter labels by"),
|
|
1618
1685
|
});
|
|
1619
1686
|
export const GetLabelSchema = z.object({
|
|
1620
1687
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1621
1688
|
label_id: z.coerce.string().describe("The ID or title of a project's label"),
|
|
1622
|
-
include_ancestor_groups: z.boolean().optional().describe("Include ancestor groups"),
|
|
1689
|
+
include_ancestor_groups: z.coerce.boolean().optional().describe("Include ancestor groups"),
|
|
1623
1690
|
});
|
|
1624
1691
|
export const CreateLabelSchema = z.object({
|
|
1625
1692
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1628,7 +1695,7 @@ export const CreateLabelSchema = z.object({
|
|
|
1628
1695
|
.string()
|
|
1629
1696
|
.describe("The color of the label given in 6-digit hex notation with leading '#' sign"),
|
|
1630
1697
|
description: z.string().optional().describe("The description of the label"),
|
|
1631
|
-
priority: z.number().nullable().optional().describe("The priority of the label"),
|
|
1698
|
+
priority: z.coerce.number().nullable().optional().describe("The priority of the label"),
|
|
1632
1699
|
});
|
|
1633
1700
|
export const UpdateLabelSchema = z.object({
|
|
1634
1701
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1639,7 +1706,7 @@ export const UpdateLabelSchema = z.object({
|
|
|
1639
1706
|
.optional()
|
|
1640
1707
|
.describe("The color of the label given in 6-digit hex notation with leading '#' sign"),
|
|
1641
1708
|
description: z.string().optional().describe("The new description of the label"),
|
|
1642
|
-
priority: z.number().nullable().optional().describe("The new priority of the label"),
|
|
1709
|
+
priority: z.coerce.number().nullable().optional().describe("The new priority of the label"),
|
|
1643
1710
|
});
|
|
1644
1711
|
export const DeleteLabelSchema = z.object({
|
|
1645
1712
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1649,14 +1716,14 @@ export const DeleteLabelSchema = z.object({
|
|
|
1649
1716
|
export const ListGroupProjectsSchema = z
|
|
1650
1717
|
.object({
|
|
1651
1718
|
group_id: z.coerce.string().describe("Group ID or path"),
|
|
1652
|
-
include_subgroups: z.boolean().optional().describe("Include projects from subgroups"),
|
|
1719
|
+
include_subgroups: z.coerce.boolean().optional().describe("Include projects from subgroups"),
|
|
1653
1720
|
search: z.string().optional().describe("Search term to filter projects"),
|
|
1654
1721
|
order_by: z
|
|
1655
1722
|
.enum(["name", "path", "created_at", "updated_at", "last_activity_at"])
|
|
1656
1723
|
.optional()
|
|
1657
1724
|
.describe("Field to sort by"),
|
|
1658
1725
|
sort: z.enum(["asc", "desc"]).optional().describe("Sort direction"),
|
|
1659
|
-
archived: z.boolean().optional().describe("Filter for archived projects"),
|
|
1726
|
+
archived: z.coerce.boolean().optional().describe("Filter for archived projects"),
|
|
1660
1727
|
visibility: z
|
|
1661
1728
|
.enum(["public", "internal", "private"])
|
|
1662
1729
|
.optional()
|
|
@@ -1669,24 +1736,24 @@ export const ListGroupProjectsSchema = z
|
|
|
1669
1736
|
.boolean()
|
|
1670
1737
|
.optional()
|
|
1671
1738
|
.describe("Filter projects with merge requests feature enabled"),
|
|
1672
|
-
min_access_level: z.number().optional().describe("Filter by minimum access level"),
|
|
1739
|
+
min_access_level: z.coerce.number().optional().describe("Filter by minimum access level"),
|
|
1673
1740
|
with_programming_language: z.string().optional().describe("Filter by programming language"),
|
|
1674
|
-
starred: z.boolean().optional().describe("Filter by starred projects"),
|
|
1675
|
-
statistics: z.boolean().optional().describe("Include project statistics"),
|
|
1676
|
-
with_custom_attributes: z.boolean().optional().describe("Include custom attributes"),
|
|
1677
|
-
with_security_reports: z.boolean().optional().describe("Include security reports"),
|
|
1741
|
+
starred: z.coerce.boolean().optional().describe("Filter by starred projects"),
|
|
1742
|
+
statistics: z.coerce.boolean().optional().describe("Include project statistics"),
|
|
1743
|
+
with_custom_attributes: z.coerce.boolean().optional().describe("Include custom attributes"),
|
|
1744
|
+
with_security_reports: z.coerce.boolean().optional().describe("Include security reports"),
|
|
1678
1745
|
})
|
|
1679
1746
|
.merge(PaginationOptionsSchema);
|
|
1680
1747
|
// Add wiki operation schemas
|
|
1681
1748
|
export const ListWikiPagesSchema = z
|
|
1682
1749
|
.object({
|
|
1683
1750
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1684
|
-
with_content: z.boolean().optional().describe("Include content of the wiki pages"),
|
|
1751
|
+
with_content: z.coerce.boolean().optional().describe("Include content of the wiki pages"),
|
|
1685
1752
|
})
|
|
1686
1753
|
.merge(PaginationOptionsSchema);
|
|
1687
1754
|
export const GetWikiPageSchema = z.object({
|
|
1688
1755
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1689
|
-
slug: z.string().describe("
|
|
1756
|
+
slug: z.string().describe("Slug of the wiki page (will be URL-encoded internally)"),
|
|
1690
1757
|
});
|
|
1691
1758
|
export const CreateWikiPageSchema = z.object({
|
|
1692
1759
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1696,14 +1763,14 @@ export const CreateWikiPageSchema = z.object({
|
|
|
1696
1763
|
});
|
|
1697
1764
|
export const UpdateWikiPageSchema = z.object({
|
|
1698
1765
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1699
|
-
slug: z.string().describe("
|
|
1766
|
+
slug: z.string().describe("Slug of the wiki page (will be URL-encoded internally)"),
|
|
1700
1767
|
title: z.string().optional().describe("New title of the wiki page"),
|
|
1701
1768
|
content: z.string().optional().describe("New content of the wiki page"),
|
|
1702
1769
|
format: z.string().optional().describe("Content format, e.g., markdown, rdoc"),
|
|
1703
1770
|
});
|
|
1704
1771
|
export const DeleteWikiPageSchema = z.object({
|
|
1705
1772
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1706
|
-
slug: z.string().describe("
|
|
1773
|
+
slug: z.string().describe("Slug of the wiki page (will be URL-encoded internally)"),
|
|
1707
1774
|
});
|
|
1708
1775
|
// Define wiki response schemas
|
|
1709
1776
|
export const GitLabWikiPageSchema = z.object({
|
|
@@ -1714,6 +1781,34 @@ export const GitLabWikiPageSchema = z.object({
|
|
|
1714
1781
|
created_at: z.string().optional(),
|
|
1715
1782
|
updated_at: z.string().optional(),
|
|
1716
1783
|
});
|
|
1784
|
+
// Group Wiki operation schemas
|
|
1785
|
+
export const ListGroupWikiPagesSchema = z
|
|
1786
|
+
.object({
|
|
1787
|
+
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
|
|
1788
|
+
with_content: z.boolean().optional().describe("Include content of the wiki pages"),
|
|
1789
|
+
})
|
|
1790
|
+
.merge(PaginationOptionsSchema);
|
|
1791
|
+
export const GetGroupWikiPageSchema = z.object({
|
|
1792
|
+
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
|
|
1793
|
+
slug: z.string().describe("Slug of the wiki page (will be URL-encoded internally)"),
|
|
1794
|
+
});
|
|
1795
|
+
export const CreateGroupWikiPageSchema = z.object({
|
|
1796
|
+
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
|
|
1797
|
+
title: z.string().describe("Title of the wiki page"),
|
|
1798
|
+
content: z.string().describe("Content of the wiki page"),
|
|
1799
|
+
format: z.string().optional().describe("Content format, e.g., markdown, rdoc"),
|
|
1800
|
+
});
|
|
1801
|
+
export const UpdateGroupWikiPageSchema = z.object({
|
|
1802
|
+
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
|
|
1803
|
+
slug: z.string().describe("Slug of the wiki page (will be URL-encoded internally)"),
|
|
1804
|
+
title: z.string().optional().describe("New title of the wiki page"),
|
|
1805
|
+
content: z.string().optional().describe("New content of the wiki page"),
|
|
1806
|
+
format: z.string().optional().describe("Content format, e.g., markdown, rdoc"),
|
|
1807
|
+
});
|
|
1808
|
+
export const DeleteGroupWikiPageSchema = z.object({
|
|
1809
|
+
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
|
|
1810
|
+
slug: z.string().describe("Slug of the wiki page (will be URL-encoded internally)"),
|
|
1811
|
+
});
|
|
1717
1812
|
// Merge Request Thread position schema - used for diff notes
|
|
1718
1813
|
// Extremely flexible position schema for API responses - accepts any structure
|
|
1719
1814
|
// Strict position schema for creating draft notes and merge request threads
|
|
@@ -1839,7 +1934,7 @@ export const GitLabDraftNoteSchema = z
|
|
|
1839
1934
|
updated_at: z.string().optional(),
|
|
1840
1935
|
discussion_id: z.string().nullable().optional(),
|
|
1841
1936
|
position: z.record(z.unknown()).nullable().optional(),
|
|
1842
|
-
resolve_discussion: z.boolean().optional(),
|
|
1937
|
+
resolve_discussion: z.coerce.boolean().optional(),
|
|
1843
1938
|
})
|
|
1844
1939
|
.transform(data => ({
|
|
1845
1940
|
// Normalize the response to always have consistent field names
|
|
@@ -1910,12 +2005,12 @@ export const CreateMergeRequestThreadSchema = ProjectParamsSchema.extend({
|
|
|
1910
2005
|
export const ResolveMergeRequestThreadSchema = ProjectParamsSchema.extend({
|
|
1911
2006
|
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
1912
2007
|
discussion_id: z.coerce.string().describe("The ID of a thread"),
|
|
1913
|
-
resolved: z.boolean().describe("Whether to resolve the thread"),
|
|
2008
|
+
resolved: z.coerce.boolean().describe("Whether to resolve the thread"),
|
|
1914
2009
|
});
|
|
1915
2010
|
// Milestone related schemas
|
|
1916
2011
|
// Schema for listing project milestones
|
|
1917
2012
|
export const ListProjectMilestonesSchema = ProjectParamsSchema.extend({
|
|
1918
|
-
iids: z.array(z.number()).optional().describe("Return only the milestones having the given iid"),
|
|
2013
|
+
iids: z.array(z.coerce.number()).optional().describe("Return only the milestones having the given iid"),
|
|
1919
2014
|
state: z
|
|
1920
2015
|
.enum(["active", "closed"])
|
|
1921
2016
|
.optional()
|
|
@@ -1928,7 +2023,7 @@ export const ListProjectMilestonesSchema = ProjectParamsSchema.extend({
|
|
|
1928
2023
|
.string()
|
|
1929
2024
|
.optional()
|
|
1930
2025
|
.describe("Return only milestones with a title or description matching the provided string"),
|
|
1931
|
-
include_ancestors: z.boolean().optional().describe("Include ancestor groups"),
|
|
2026
|
+
include_ancestors: z.coerce.boolean().optional().describe("Include ancestor groups"),
|
|
1932
2027
|
updated_before: z
|
|
1933
2028
|
.string()
|
|
1934
2029
|
.optional()
|
|
@@ -1987,21 +2082,21 @@ export const ListCommitsSchema = z.object({
|
|
|
1987
2082
|
.describe("Only commits before or on this date are returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ"),
|
|
1988
2083
|
path: z.string().optional().describe("The file path"),
|
|
1989
2084
|
author: z.string().optional().describe("Search commits by commit author"),
|
|
1990
|
-
all: z.boolean().optional().describe("Retrieve every commit from the repository"),
|
|
1991
|
-
with_stats: z.boolean().optional().describe("Stats about each commit are added to the response"),
|
|
2085
|
+
all: z.coerce.boolean().optional().describe("Retrieve every commit from the repository"),
|
|
2086
|
+
with_stats: z.coerce.boolean().optional().describe("Stats about each commit are added to the response"),
|
|
1992
2087
|
first_parent: z
|
|
1993
2088
|
.boolean()
|
|
1994
2089
|
.optional()
|
|
1995
2090
|
.describe("Follow only the first parent commit upon seeing a merge commit"),
|
|
1996
2091
|
order: z.enum(["default", "topo"]).optional().describe("List commits in order"),
|
|
1997
|
-
trailers: z.boolean().optional().describe("Parse and include Git trailers for every commit"),
|
|
1998
|
-
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
1999
|
-
per_page: z.number().optional().describe("Number of items per page (max: 100, default: 20)"),
|
|
2092
|
+
trailers: z.coerce.boolean().optional().describe("Parse and include Git trailers for every commit"),
|
|
2093
|
+
page: z.coerce.number().optional().describe("Page number for pagination (default: 1)"),
|
|
2094
|
+
per_page: z.coerce.number().optional().describe("Number of items per page (max: 100, default: 20)"),
|
|
2000
2095
|
});
|
|
2001
2096
|
export const GetCommitSchema = z.object({
|
|
2002
2097
|
project_id: z.coerce.string().describe("Project ID or complete URL-encoded path to project"),
|
|
2003
2098
|
sha: z.string().describe("The commit hash or name of a repository branch or tag"),
|
|
2004
|
-
stats: z.boolean().optional().describe("Include commit stats"),
|
|
2099
|
+
stats: z.coerce.boolean().optional().describe("Include commit stats"),
|
|
2005
2100
|
});
|
|
2006
2101
|
export const GetCommitDiffSchema = z.object({
|
|
2007
2102
|
project_id: z.coerce.string().describe("Project ID or complete URL-encoded path to project"),
|
|
@@ -2040,31 +2135,31 @@ export const MyIssuesSchema = z.object({
|
|
|
2040
2135
|
.string()
|
|
2041
2136
|
.optional()
|
|
2042
2137
|
.describe("Return issues updated before the given time (ISO 8601)"),
|
|
2043
|
-
per_page: z.number().optional().describe("Number of items per page (default: 20, max: 100)"),
|
|
2044
|
-
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
2138
|
+
per_page: z.coerce.number().optional().describe("Number of items per page (default: 20, max: 100)"),
|
|
2139
|
+
page: z.coerce.number().optional().describe("Page number for pagination (default: 1)"),
|
|
2045
2140
|
});
|
|
2046
2141
|
// Schema for listing project members
|
|
2047
2142
|
export const ListProjectMembersSchema = z.object({
|
|
2048
2143
|
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
2049
2144
|
query: z.string().optional().describe("Search for members by name or username"),
|
|
2050
|
-
user_ids: z.array(z.number()).optional().describe("Filter by user IDs"),
|
|
2051
|
-
skip_users: z.array(z.number()).optional().describe("User IDs to exclude"),
|
|
2145
|
+
user_ids: z.array(z.coerce.number()).optional().describe("Filter by user IDs"),
|
|
2146
|
+
skip_users: z.array(z.coerce.number()).optional().describe("User IDs to exclude"),
|
|
2052
2147
|
include_inheritance: z
|
|
2053
2148
|
.boolean()
|
|
2054
2149
|
.optional()
|
|
2055
2150
|
.describe("Include inherited members. Defaults to false."),
|
|
2056
|
-
per_page: z.number().optional().describe("Number of items per page (default: 20, max: 100)"),
|
|
2057
|
-
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
2151
|
+
per_page: z.coerce.number().optional().describe("Number of items per page (default: 20, max: 100)"),
|
|
2152
|
+
page: z.coerce.number().optional().describe("Page number for pagination (default: 1)"),
|
|
2058
2153
|
});
|
|
2059
2154
|
// Schema for GitLab project member
|
|
2060
2155
|
export const GitLabProjectMemberSchema = z.object({
|
|
2061
|
-
id: z.number(),
|
|
2156
|
+
id: z.coerce.number(),
|
|
2062
2157
|
username: z.string(),
|
|
2063
2158
|
name: z.string(),
|
|
2064
2159
|
state: z.string(),
|
|
2065
2160
|
avatar_url: z.string().nullable(),
|
|
2066
2161
|
web_url: z.string(),
|
|
2067
|
-
access_level: z.number(),
|
|
2162
|
+
access_level: z.coerce.number(),
|
|
2068
2163
|
access_level_description: z.string().optional(),
|
|
2069
2164
|
created_at: z.string(),
|
|
2070
2165
|
expires_at: z.string().nullable().optional(),
|
|
@@ -2072,7 +2167,7 @@ export const GitLabProjectMemberSchema = z.object({
|
|
|
2072
2167
|
});
|
|
2073
2168
|
// Markdown upload schemas
|
|
2074
2169
|
export const GitLabMarkdownUploadSchema = z.object({
|
|
2075
|
-
id: z.number(),
|
|
2170
|
+
id: z.coerce.number(),
|
|
2076
2171
|
alt: z.string(),
|
|
2077
2172
|
url: z.string(),
|
|
2078
2173
|
full_path: z.string(),
|
|
@@ -2094,11 +2189,11 @@ export const DownloadAttachmentSchema = z.object({
|
|
|
2094
2189
|
export const GroupIteration = z.object({
|
|
2095
2190
|
id: z.coerce.string(),
|
|
2096
2191
|
iid: z.coerce.string(),
|
|
2097
|
-
sequence: z.number(),
|
|
2192
|
+
sequence: z.coerce.number(),
|
|
2098
2193
|
group_id: z.coerce.string(),
|
|
2099
2194
|
title: z.string().optional().nullable(),
|
|
2100
2195
|
description: z.string().optional().nullable(),
|
|
2101
|
-
state: z.number(),
|
|
2196
|
+
state: z.coerce.number(),
|
|
2102
2197
|
created_at: z.string(),
|
|
2103
2198
|
updated_at: z.string(),
|
|
2104
2199
|
due_date: z.string().optional().nullable(),
|
|
@@ -2160,7 +2255,7 @@ export const GitLabEventSchema = z
|
|
|
2160
2255
|
created_at: z.string(),
|
|
2161
2256
|
author: GitLabEventAuthorSchema,
|
|
2162
2257
|
author_username: z.string(),
|
|
2163
|
-
imported: z.boolean(),
|
|
2258
|
+
imported: z.coerce.boolean(),
|
|
2164
2259
|
imported_from: z.string(),
|
|
2165
2260
|
})
|
|
2166
2261
|
.passthrough(); // Allow additional fields
|
|
@@ -2187,8 +2282,8 @@ export const ListEventsSchema = z.object({
|
|
|
2187
2282
|
.enum(["asc", "desc"])
|
|
2188
2283
|
.optional()
|
|
2189
2284
|
.describe("Direction to sort the results by creation date. Default: desc"),
|
|
2190
|
-
page: z.number().optional().describe("Returns the specified results page. Default: 1"),
|
|
2191
|
-
per_page: z.number().optional().describe("Number of results per page. Default: 20"),
|
|
2285
|
+
page: z.coerce.number().optional().describe("Returns the specified results page. Default: 1"),
|
|
2286
|
+
per_page: z.coerce.number().optional().describe("Number of results per page. Default: 20"),
|
|
2192
2287
|
});
|
|
2193
2288
|
// Get project events schema
|
|
2194
2289
|
export const GetProjectEventsSchema = z.object({
|
|
@@ -2213,17 +2308,17 @@ export const GetProjectEventsSchema = z.object({
|
|
|
2213
2308
|
.enum(["asc", "desc"])
|
|
2214
2309
|
.optional()
|
|
2215
2310
|
.describe("Direction to sort the results by creation date. Default: desc"),
|
|
2216
|
-
page: z.number().optional().describe("Returns the specified results page. Default: 1"),
|
|
2217
|
-
per_page: z.number().optional().describe("Number of results per page. Default: 20"),
|
|
2311
|
+
page: z.coerce.number().optional().describe("Returns the specified results page. Default: 1"),
|
|
2312
|
+
per_page: z.coerce.number().optional().describe("Number of results per page. Default: 20"),
|
|
2218
2313
|
});
|
|
2219
2314
|
// Merge Request Versions schemas - Response schemas based on GitLab API documentation
|
|
2220
2315
|
export const GitLabMergeRequestVersionSchema = z.object({
|
|
2221
|
-
id: z.number(),
|
|
2316
|
+
id: z.coerce.number(),
|
|
2222
2317
|
head_commit_sha: z.string(),
|
|
2223
2318
|
base_commit_sha: z.string(),
|
|
2224
2319
|
start_commit_sha: z.string(),
|
|
2225
2320
|
created_at: z.string(),
|
|
2226
|
-
merge_request_id: z.number(),
|
|
2321
|
+
merge_request_id: z.coerce.number(),
|
|
2227
2322
|
state: z.string(),
|
|
2228
2323
|
real_size: z.string(),
|
|
2229
2324
|
patch_id_sha: z.string(),
|
|
@@ -2239,7 +2334,7 @@ export const ExecuteGraphQLSchema = z.object({
|
|
|
2239
2334
|
});
|
|
2240
2335
|
// Release schemas
|
|
2241
2336
|
export const GitLabReleaseAssetLinkSchema = z.object({
|
|
2242
|
-
id: z.number().optional(),
|
|
2337
|
+
id: z.coerce.number().optional(),
|
|
2243
2338
|
name: z.string(),
|
|
2244
2339
|
url: z.string(),
|
|
2245
2340
|
direct_asset_path: z.string().optional(),
|
|
@@ -2250,7 +2345,7 @@ export const GitLabReleaseAssetSourceSchema = z.object({
|
|
|
2250
2345
|
url: z.string(),
|
|
2251
2346
|
});
|
|
2252
2347
|
export const GitLabReleaseAssetsSchema = z.object({
|
|
2253
|
-
count: z.number().optional(),
|
|
2348
|
+
count: z.coerce.number().optional(),
|
|
2254
2349
|
sources: z.array(GitLabReleaseAssetSourceSchema).optional(),
|
|
2255
2350
|
links: z.array(GitLabReleaseAssetLinkSchema).optional(),
|
|
2256
2351
|
evidence_file_path: z.string().optional(),
|
|
@@ -2269,7 +2364,7 @@ export const GitLabReleaseSchema = z.object({
|
|
|
2269
2364
|
released_at: z.string().nullable().optional(),
|
|
2270
2365
|
author: z
|
|
2271
2366
|
.object({
|
|
2272
|
-
id: z.number(),
|
|
2367
|
+
id: z.coerce.number(),
|
|
2273
2368
|
name: z.string(),
|
|
2274
2369
|
username: z.string(),
|
|
2275
2370
|
state: z.string(),
|
|
@@ -2309,8 +2404,8 @@ export const GitLabReleaseSchema = z.object({
|
|
|
2309
2404
|
self: z.string().optional(),
|
|
2310
2405
|
})
|
|
2311
2406
|
.optional(),
|
|
2312
|
-
upcoming_release: z.boolean().optional(),
|
|
2313
|
-
historical_release: z.boolean().optional(),
|
|
2407
|
+
upcoming_release: z.coerce.boolean().optional(),
|
|
2408
|
+
historical_release: z.coerce.boolean().optional(),
|
|
2314
2409
|
});
|
|
2315
2410
|
export const ListReleasesSchema = z
|
|
2316
2411
|
.object({
|
|
@@ -2424,7 +2519,7 @@ export const GitLabArtifactEntrySchema = z.object({
|
|
|
2424
2519
|
name: z.string(),
|
|
2425
2520
|
path: z.string(),
|
|
2426
2521
|
type: z.enum(["file", "directory"]),
|
|
2427
|
-
size: z.number().optional(),
|
|
2522
|
+
size: z.coerce.number().optional(),
|
|
2428
2523
|
mode: z.string().optional(),
|
|
2429
2524
|
});
|
|
2430
2525
|
export const DownloadJobArtifactsSchema = z.object({
|
|
@@ -2449,6 +2544,170 @@ export const DownloadReleaseAssetSchema = z.object({
|
|
|
2449
2544
|
.string()
|
|
2450
2545
|
.describe("Path to the release asset file as specified when creating or updating its link"),
|
|
2451
2546
|
});
|
|
2547
|
+
// --- Work item schemas (GraphQL-based) ---
|
|
2548
|
+
// Case-insensitive work item type enum (accepts "ISSUE", "Issue", "issue")
|
|
2549
|
+
const workItemTypeEnum = z.string().transform(v => v.toLowerCase()).pipe(z.enum(["issue", "task", "incident", "test_case", "epic", "key_result", "objective", "requirement", "ticket"]));
|
|
2550
|
+
// Common params for work item tools
|
|
2551
|
+
const WorkItemParamsSchema = z.object({
|
|
2552
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2553
|
+
iid: z.coerce.number().describe("The internal ID (IID) of the work item"),
|
|
2554
|
+
});
|
|
2555
|
+
export const GetWorkItemSchema = WorkItemParamsSchema;
|
|
2556
|
+
export const ListWorkItemsSchema = z.object({
|
|
2557
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2558
|
+
types: z
|
|
2559
|
+
.array(workItemTypeEnum)
|
|
2560
|
+
.optional()
|
|
2561
|
+
.describe("Filter by work item types. If not set, returns all types."),
|
|
2562
|
+
state: z
|
|
2563
|
+
.enum(["opened", "closed"])
|
|
2564
|
+
.optional()
|
|
2565
|
+
.describe("Filter by state"),
|
|
2566
|
+
search: z
|
|
2567
|
+
.string()
|
|
2568
|
+
.optional()
|
|
2569
|
+
.describe("Search in title and description"),
|
|
2570
|
+
assignee_usernames: z
|
|
2571
|
+
.array(z.string())
|
|
2572
|
+
.optional()
|
|
2573
|
+
.describe("Filter by assignee usernames"),
|
|
2574
|
+
label_names: z
|
|
2575
|
+
.array(z.string())
|
|
2576
|
+
.optional()
|
|
2577
|
+
.describe("Filter by label names"),
|
|
2578
|
+
first: z
|
|
2579
|
+
.coerce.number()
|
|
2580
|
+
.optional()
|
|
2581
|
+
.default(20)
|
|
2582
|
+
.describe("Number of items to return (max 100). Default 20."),
|
|
2583
|
+
after: z
|
|
2584
|
+
.string()
|
|
2585
|
+
.optional()
|
|
2586
|
+
.describe("Cursor for pagination (from previous response's endCursor)"),
|
|
2587
|
+
});
|
|
2588
|
+
export const CreateWorkItemSchema = z.object({
|
|
2589
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2590
|
+
title: z.string().describe("Title of the work item"),
|
|
2591
|
+
type: workItemTypeEnum
|
|
2592
|
+
.optional()
|
|
2593
|
+
.default("issue")
|
|
2594
|
+
.describe("Type of work item to create. Defaults to 'issue'."),
|
|
2595
|
+
description: z.string().optional().describe("Description of the work item (Markdown supported)"),
|
|
2596
|
+
labels: z.array(z.string()).optional().describe("Array of label names to assign"),
|
|
2597
|
+
assignee_usernames: z.array(z.string()).optional().describe("Array of usernames to assign"),
|
|
2598
|
+
parent_iid: z.coerce.number().optional().describe("IID of the parent work item to set hierarchy"),
|
|
2599
|
+
weight: z.coerce.number().optional().describe("Weight of the work item"),
|
|
2600
|
+
health_status: z.enum(["onTrack", "needsAttention", "atRisk"]).optional().describe("Set health status"),
|
|
2601
|
+
start_date: z.string().optional().describe("Start date in YYYY-MM-DD format"),
|
|
2602
|
+
due_date: z.string().optional().describe("Due date in YYYY-MM-DD format"),
|
|
2603
|
+
milestone_id: z.string().optional().describe("Milestone ID (GitLab global ID format, e.g. 'gid://gitlab/Milestone/123', or numeric ID)"),
|
|
2604
|
+
iteration_id: z.string().optional().describe("Iteration ID (e.g. 'gid://gitlab/Iteration/123' or numeric ID). Use list_group_iterations to find available iterations."),
|
|
2605
|
+
confidential: z.coerce.boolean().optional().describe("Set confidentiality"),
|
|
2606
|
+
});
|
|
2607
|
+
export const UpdateWorkItemSchema = WorkItemParamsSchema.extend({
|
|
2608
|
+
title: z.string().optional().describe("New title"),
|
|
2609
|
+
description: z.string().optional().describe("New description (Markdown supported)"),
|
|
2610
|
+
add_labels: z.array(z.string()).optional().describe("Label names to add"),
|
|
2611
|
+
remove_labels: z.array(z.string()).optional().describe("Label names to remove"),
|
|
2612
|
+
assignee_usernames: z.array(z.string()).optional().describe("Set assignees by username (replaces existing)"),
|
|
2613
|
+
state_event: z.enum(["close", "reopen"]).optional().describe("Close or reopen the work item"),
|
|
2614
|
+
weight: z.coerce.number().optional().describe("Set weight (issues, tasks, epics only)"),
|
|
2615
|
+
status: z.string().optional().describe("Set status by ID. Use list_work_item_statuses to get available status IDs."),
|
|
2616
|
+
parent_iid: z.coerce.number().optional().describe("Set parent work item by IID. Use with parent_project_id if parent is in a different project."),
|
|
2617
|
+
parent_project_id: z.coerce.string().optional().describe("Project ID or path of the parent work item (defaults to same project as the work item)"),
|
|
2618
|
+
remove_parent: z.coerce.boolean().optional().describe("Set to true to remove the parent from hierarchy"),
|
|
2619
|
+
children_to_add: z.array(z.object({
|
|
2620
|
+
project_id: z.coerce.string().describe("Project ID or path of the child work item"),
|
|
2621
|
+
iid: z.coerce.number().describe("IID of the child work item"),
|
|
2622
|
+
})).optional().describe("Array of children to add to this work item's hierarchy"),
|
|
2623
|
+
children_to_remove: z.array(z.object({
|
|
2624
|
+
project_id: z.coerce.string().describe("Project ID or path of the child work item"),
|
|
2625
|
+
iid: z.coerce.number().describe("IID of the child work item"),
|
|
2626
|
+
})).optional().describe("Array of children to remove from this work item's hierarchy"),
|
|
2627
|
+
health_status: z.enum(["onTrack", "needsAttention", "atRisk"]).optional().describe("Set health status on issues and epics"),
|
|
2628
|
+
start_date: z.string().optional().describe("Start date in YYYY-MM-DD format"),
|
|
2629
|
+
due_date: z.string().optional().describe("Due date in YYYY-MM-DD format"),
|
|
2630
|
+
milestone_id: z.string().optional().describe("Milestone ID (GitLab global ID format, e.g. 'gid://gitlab/Milestone/123', or numeric ID)"),
|
|
2631
|
+
iteration_id: z.string().optional().describe("Iteration ID (e.g. 'gid://gitlab/Iteration/123' or numeric ID). Use list_group_iterations to find available iterations."),
|
|
2632
|
+
confidential: z.coerce.boolean().optional().describe("Set confidentiality"),
|
|
2633
|
+
linked_items_to_add: z.array(z.object({
|
|
2634
|
+
project_id: z.coerce.string().describe("Project ID or path of the work item to link"),
|
|
2635
|
+
iid: z.coerce.number().describe("IID of the work item to link"),
|
|
2636
|
+
link_type: z.enum(["RELATED", "BLOCKED_BY", "BLOCKS"]).optional().default("RELATED").describe("Link type: RELATED, BLOCKED_BY, or BLOCKS. Defaults to RELATED."),
|
|
2637
|
+
})).optional().describe("Work items to link"),
|
|
2638
|
+
linked_items_to_remove: z.array(z.object({
|
|
2639
|
+
project_id: z.coerce.string().describe("Project ID or path of the linked work item to remove"),
|
|
2640
|
+
iid: z.coerce.number().describe("IID of the linked work item to remove"),
|
|
2641
|
+
})).optional().describe("Linked work items to remove"),
|
|
2642
|
+
custom_fields: z.array(z.object({
|
|
2643
|
+
custom_field_id: z.string().describe("Custom field ID (e.g. 'gid://gitlab/IssuablesCustomField/123' or numeric ID)"),
|
|
2644
|
+
text_value: z.string().optional().describe("Text value (for text fields)"),
|
|
2645
|
+
number_value: z.coerce.number().optional().describe("Number value (for number fields)"),
|
|
2646
|
+
selected_option_ids: z.array(z.string()).optional().describe("Selected option IDs (for select fields)"),
|
|
2647
|
+
date_value: z.string().optional().describe("Date value in YYYY-MM-DD format (for date fields)"),
|
|
2648
|
+
})).optional().describe("Custom field values to set"),
|
|
2649
|
+
severity: z
|
|
2650
|
+
.enum(["UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"])
|
|
2651
|
+
.optional()
|
|
2652
|
+
.describe("Incident only: set severity level"),
|
|
2653
|
+
escalation_status: z
|
|
2654
|
+
.enum(["TRIGGERED", "ACKNOWLEDGED", "RESOLVED", "IGNORED"])
|
|
2655
|
+
.optional()
|
|
2656
|
+
.describe("Incident only: set escalation status"),
|
|
2657
|
+
});
|
|
2658
|
+
export const ConvertWorkItemTypeSchema = z.object({
|
|
2659
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2660
|
+
iid: z.coerce.number().describe("The internal ID of the work item"),
|
|
2661
|
+
new_type: workItemTypeEnum.describe("The target work item type to convert to"),
|
|
2662
|
+
});
|
|
2663
|
+
export const ListWorkItemStatusesSchema = z.object({
|
|
2664
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2665
|
+
work_item_type: workItemTypeEnum
|
|
2666
|
+
.optional()
|
|
2667
|
+
.default("issue")
|
|
2668
|
+
.describe("The work item type to list available statuses for. Defaults to 'issue'."),
|
|
2669
|
+
});
|
|
2670
|
+
export const ListWorkItemNotesSchema = z.object({
|
|
2671
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2672
|
+
iid: z.coerce.number().describe("The internal ID of the work item"),
|
|
2673
|
+
page_size: z.coerce.number().optional().default(20).describe("Number of discussions to return (default 20)"),
|
|
2674
|
+
after: z.string().optional().describe("Cursor for pagination"),
|
|
2675
|
+
sort: z.enum(["CREATED_ASC", "CREATED_DESC"]).optional().default("CREATED_ASC").describe("Sort order for discussions"),
|
|
2676
|
+
});
|
|
2677
|
+
export const CreateWorkItemNoteSchema = z.object({
|
|
2678
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2679
|
+
iid: z.coerce.number().describe("The internal ID of the work item"),
|
|
2680
|
+
body: z.string().describe("Note body (Markdown supported)"),
|
|
2681
|
+
internal: z.coerce.boolean().optional().default(false).describe("Create as internal/confidential note (only visible to project members)"),
|
|
2682
|
+
discussion_id: z.string().optional().describe("Discussion ID to reply to (for threaded replies). If omitted, creates a new top-level note."),
|
|
2683
|
+
});
|
|
2684
|
+
export const MoveWorkItemSchema = z.object({
|
|
2685
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path of the source project"),
|
|
2686
|
+
iid: z.coerce.number().describe("The internal ID of the work item to move"),
|
|
2687
|
+
target_project_id: z.coerce.string().describe("Project ID or URL-encoded path of the target project"),
|
|
2688
|
+
});
|
|
2689
|
+
export const ListCustomFieldDefinitionsSchema = z.object({
|
|
2690
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2691
|
+
work_item_type: workItemTypeEnum
|
|
2692
|
+
.optional()
|
|
2693
|
+
.default("issue")
|
|
2694
|
+
.describe("The work item type to list custom field definitions for. Defaults to 'issue'."),
|
|
2695
|
+
});
|
|
2696
|
+
// --- Incident Timeline Event schemas ---
|
|
2697
|
+
export const GetTimelineEventsSchema = z.object({
|
|
2698
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2699
|
+
incident_iid: z.coerce.number().describe("The internal ID (IID) of the incident"),
|
|
2700
|
+
});
|
|
2701
|
+
export const CreateTimelineEventSchema = z.object({
|
|
2702
|
+
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2703
|
+
incident_iid: z.coerce.number().describe("The internal ID (IID) of the incident"),
|
|
2704
|
+
note: z.string().describe("Description of the timeline event (Markdown supported)"),
|
|
2705
|
+
occurred_at: z.string().describe("When the event occurred in ISO 8601 format (e.g. '2026-03-15T09:00:00.000Z')"),
|
|
2706
|
+
tag_names: z
|
|
2707
|
+
.array(z.enum(["Start time", "End time", "Impact detected", "Response initiated", "Impact mitigated", "Cause identified"]))
|
|
2708
|
+
.optional()
|
|
2709
|
+
.describe("Timeline event tags to attach. Available: 'Start time', 'End time', 'Impact detected', 'Response initiated', 'Impact mitigated', 'Cause identified'."),
|
|
2710
|
+
});
|
|
2452
2711
|
// --- Webhook schemas ---
|
|
2453
2712
|
export const ListWebhooksSchema = z
|
|
2454
2713
|
.object({
|
|
@@ -2477,7 +2736,7 @@ export const ListWebhookEventsSchema = z
|
|
|
2477
2736
|
.describe("Group ID or URL-encoded path. Provide either project_id or group_id, not both."),
|
|
2478
2737
|
hook_id: z.coerce.number().describe("ID of the webhook"),
|
|
2479
2738
|
status: z
|
|
2480
|
-
.union([z.number(), z.string()])
|
|
2739
|
+
.union([z.coerce.number(), z.string()])
|
|
2481
2740
|
.optional()
|
|
2482
2741
|
.describe("Filter by response status code (e.g. 200, 500) or category: successful, client_failure, server_failure"),
|
|
2483
2742
|
summary: z
|
|
@@ -2490,7 +2749,7 @@ export const ListWebhookEventsSchema = z
|
|
|
2490
2749
|
.optional()
|
|
2491
2750
|
.default(20)
|
|
2492
2751
|
.describe("Number of events per page"),
|
|
2493
|
-
page: z.number().optional().describe("Page number for pagination"),
|
|
2752
|
+
page: z.coerce.number().optional().describe("Page number for pagination"),
|
|
2494
2753
|
})
|
|
2495
2754
|
.refine(data => (data.project_id || data.group_id) && !(data.project_id && data.group_id), {
|
|
2496
2755
|
message: "Provide exactly one of project_id or group_id",
|