@zereight/mcp-gitlab 2.0.34 → 2.0.36
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 +327 -92
- package/build/gitlab-client-pool.js +6 -0
- package/build/index.js +2224 -52
- package/build/oauth-proxy.js +264 -0
- package/build/schemas.js +457 -201
- package/build/test/mcp-oauth-tests.js +552 -0
- package/build/test/multi-server-test.js +16 -8
- package/build/test/schema-tests.js +77 -3
- package/build/test/test-geteffectiveprojectid.js +211 -202
- 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/utils/mock-gitlab-server.js +263 -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",
|
|
@@ -1070,10 +1116,10 @@ export const UpdateIssueNoteSchema = ProjectParamsSchema.extend({
|
|
|
1070
1116
|
.refine(data => !(data.body !== undefined && data.resolved !== undefined), {
|
|
1071
1117
|
message: "Only one of 'body' or 'resolved' can be provided, not both",
|
|
1072
1118
|
});
|
|
1073
|
-
// Input schema for adding a note to an
|
|
1119
|
+
// Input schema for adding a note to an issue (top-level comment or discussion reply)
|
|
1074
1120
|
export const CreateIssueNoteSchema = ProjectParamsSchema.extend({
|
|
1075
1121
|
issue_iid: z.coerce.string().describe("The IID of an issue"),
|
|
1076
|
-
discussion_id: z.coerce.string().describe("The ID of a thread"),
|
|
1122
|
+
discussion_id: z.coerce.string().optional().describe("The ID of a thread. If provided, replies to that thread; otherwise creates a top-level note"),
|
|
1077
1123
|
body: z.string().describe("The content of the note or reply"),
|
|
1078
1124
|
created_at: z.string().optional().describe("Date the note was created at (ISO 8601 format)"),
|
|
1079
1125
|
});
|
|
@@ -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(),
|
|
@@ -1344,13 +1391,29 @@ export const GetMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
|
|
|
1344
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"]'),
|
|
1345
1392
|
});
|
|
1346
1393
|
export const ListMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
|
|
1347
|
-
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
1348
|
-
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)"),
|
|
1349
1396
|
unidiff: z
|
|
1350
1397
|
.boolean()
|
|
1351
1398
|
.optional()
|
|
1352
1399
|
.describe("Present diffs in the unified diff format. Default is false. Introduced in GitLab 16.5."),
|
|
1353
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
|
+
});
|
|
1354
1417
|
// Merge Request Versions API operation schemas
|
|
1355
1418
|
export const ListMergeRequestVersionsSchema = ProjectParamsSchema.extend({
|
|
1356
1419
|
merge_request_iid: z.coerce.string().describe("The internal ID of the merge request"),
|
|
@@ -1387,7 +1450,7 @@ export const ListIssuesSchema = z
|
|
|
1387
1450
|
.describe("Return issues assigned to the given username"),
|
|
1388
1451
|
author_id: z.coerce.string().optional().describe("Return issues created by the given user ID"),
|
|
1389
1452
|
author_username: z.string().optional().describe("Return issues created by the given username"),
|
|
1390
|
-
confidential: z.boolean().optional().describe("Filter confidential or public issues"),
|
|
1453
|
+
confidential: z.coerce.boolean().optional().describe("Filter confidential or public issues"),
|
|
1391
1454
|
created_after: z.string().optional().describe("Return issues created after the given time"),
|
|
1392
1455
|
created_before: z.string().optional().describe("Return issues created before the given time"),
|
|
1393
1456
|
due_date: z.string().optional().describe("Return issues that have the due date"),
|
|
@@ -1412,7 +1475,7 @@ export const ListIssuesSchema = z
|
|
|
1412
1475
|
.describe("Return issues with a specific state"),
|
|
1413
1476
|
updated_after: z.string().optional().describe("Return issues updated after the given time"),
|
|
1414
1477
|
updated_before: z.string().optional().describe("Return issues updated before the given time"),
|
|
1415
|
-
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"),
|
|
1416
1479
|
})
|
|
1417
1480
|
.merge(PaginationOptionsSchema);
|
|
1418
1481
|
// Merge Requests API operation schemas
|
|
@@ -1425,27 +1488,27 @@ export const ListMergeRequestsSchema = z
|
|
|
1425
1488
|
assignee_id: z.coerce
|
|
1426
1489
|
.string()
|
|
1427
1490
|
.optional()
|
|
1428
|
-
.describe("Return
|
|
1491
|
+
.describe("Return MRs assigned to the given user ID (integer), 'none', or 'any'. Mutually exclusive with assignee_username."),
|
|
1429
1492
|
assignee_username: z
|
|
1430
1493
|
.string()
|
|
1431
1494
|
.optional()
|
|
1432
|
-
.describe("Returns merge requests assigned to the given username"),
|
|
1495
|
+
.describe("Returns merge requests assigned to the given username. Mutually exclusive with assignee_id."),
|
|
1433
1496
|
author_id: z.coerce
|
|
1434
1497
|
.string()
|
|
1435
1498
|
.optional()
|
|
1436
|
-
.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."),
|
|
1437
1500
|
author_username: z
|
|
1438
1501
|
.string()
|
|
1439
1502
|
.optional()
|
|
1440
|
-
.describe("Returns merge requests created by the given username"),
|
|
1503
|
+
.describe("Returns merge requests created by the given username. Mutually exclusive with author_id."),
|
|
1441
1504
|
reviewer_id: z.coerce
|
|
1442
1505
|
.string()
|
|
1443
1506
|
.optional()
|
|
1444
|
-
.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."),
|
|
1445
1508
|
reviewer_username: z
|
|
1446
1509
|
.string()
|
|
1447
1510
|
.optional()
|
|
1448
|
-
.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."),
|
|
1449
1512
|
created_after: z
|
|
1450
1513
|
.string()
|
|
1451
1514
|
.optional()
|
|
@@ -1500,7 +1563,7 @@ export const ListMergeRequestsSchema = z
|
|
|
1500
1563
|
.enum(["yes", "no"])
|
|
1501
1564
|
.optional()
|
|
1502
1565
|
.describe("Filter merge requests against their wip status"),
|
|
1503
|
-
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"),
|
|
1504
1567
|
})
|
|
1505
1568
|
.merge(PaginationOptionsSchema);
|
|
1506
1569
|
export const GetIssueSchema = z.object({
|
|
@@ -1512,17 +1575,18 @@ export const UpdateIssueSchema = z.object({
|
|
|
1512
1575
|
issue_iid: z.coerce.string().describe("The internal ID of the project issue"),
|
|
1513
1576
|
title: z.string().optional().describe("The title of the issue"),
|
|
1514
1577
|
description: z.string().optional().describe("The description of the issue"),
|
|
1515
|
-
assignee_ids: z.array(z.number()).optional().describe("Array of user IDs to assign issue to"),
|
|
1516
|
-
confidential: z.boolean().optional().describe("Set the issue to be confidential"),
|
|
1517
|
-
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"),
|
|
1518
1581
|
due_date: z.string().optional().describe("Date the issue is due (YYYY-MM-DD)"),
|
|
1519
1582
|
labels: z.array(z.string()).optional().describe("Array of label names"),
|
|
1520
1583
|
milestone_id: z.coerce.string().optional().describe("Milestone ID to assign"),
|
|
1521
1584
|
state_event: z.enum(["close", "reopen"]).optional().describe("Update issue state (close/reopen)"),
|
|
1522
|
-
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)"),
|
|
1523
1586
|
issue_type: z
|
|
1524
1587
|
.enum(["issue", "incident", "test_case", "task"])
|
|
1525
|
-
.
|
|
1588
|
+
.optional()
|
|
1589
|
+
.describe("The type of issue. One of issue, incident, test_case or task."),
|
|
1526
1590
|
});
|
|
1527
1591
|
export const DeleteIssueSchema = z.object({
|
|
1528
1592
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1562,7 +1626,7 @@ export const DeleteIssueLinkSchema = z.object({
|
|
|
1562
1626
|
export const ListNamespacesSchema = z
|
|
1563
1627
|
.object({
|
|
1564
1628
|
search: z.string().optional().describe("Search term for namespaces"),
|
|
1565
|
-
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"),
|
|
1566
1630
|
})
|
|
1567
1631
|
.merge(PaginationOptionsSchema);
|
|
1568
1632
|
export const GetNamespaceSchema = z.object({
|
|
@@ -1578,14 +1642,14 @@ export const GetProjectSchema = z.object({
|
|
|
1578
1642
|
export const ListProjectsSchema = z
|
|
1579
1643
|
.object({
|
|
1580
1644
|
search: z.string().optional().describe("Search term for projects"),
|
|
1581
|
-
search_namespaces: z.boolean().optional().describe("Needs to be true if search is full path"),
|
|
1582
|
-
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"),
|
|
1583
1647
|
membership: z
|
|
1584
1648
|
.boolean()
|
|
1585
1649
|
.optional()
|
|
1586
1650
|
.describe("Filter for projects where current user is a member"),
|
|
1587
|
-
simple: z.boolean().optional().describe("Return only limited fields"),
|
|
1588
|
-
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"),
|
|
1589
1653
|
visibility: z
|
|
1590
1654
|
.enum(["public", "internal", "private"])
|
|
1591
1655
|
.optional()
|
|
@@ -1606,7 +1670,7 @@ export const ListProjectsSchema = z
|
|
|
1606
1670
|
.boolean()
|
|
1607
1671
|
.optional()
|
|
1608
1672
|
.describe("Filter projects with merge requests feature enabled"),
|
|
1609
|
-
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"),
|
|
1610
1674
|
})
|
|
1611
1675
|
.merge(PaginationOptionsSchema);
|
|
1612
1676
|
// Label operation schemas
|
|
@@ -1616,13 +1680,13 @@ export const ListLabelsSchema = z.object({
|
|
|
1616
1680
|
.boolean()
|
|
1617
1681
|
.optional()
|
|
1618
1682
|
.describe("Whether or not to include issue and merge request counts"),
|
|
1619
|
-
include_ancestor_groups: z.boolean().optional().describe("Include ancestor groups"),
|
|
1683
|
+
include_ancestor_groups: z.coerce.boolean().optional().describe("Include ancestor groups"),
|
|
1620
1684
|
search: z.string().optional().describe("Keyword to filter labels by"),
|
|
1621
1685
|
});
|
|
1622
1686
|
export const GetLabelSchema = z.object({
|
|
1623
1687
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1624
1688
|
label_id: z.coerce.string().describe("The ID or title of a project's label"),
|
|
1625
|
-
include_ancestor_groups: z.boolean().optional().describe("Include ancestor groups"),
|
|
1689
|
+
include_ancestor_groups: z.coerce.boolean().optional().describe("Include ancestor groups"),
|
|
1626
1690
|
});
|
|
1627
1691
|
export const CreateLabelSchema = z.object({
|
|
1628
1692
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1631,7 +1695,7 @@ export const CreateLabelSchema = z.object({
|
|
|
1631
1695
|
.string()
|
|
1632
1696
|
.describe("The color of the label given in 6-digit hex notation with leading '#' sign"),
|
|
1633
1697
|
description: z.string().optional().describe("The description of the label"),
|
|
1634
|
-
priority: z.number().nullable().optional().describe("The priority of the label"),
|
|
1698
|
+
priority: z.coerce.number().nullable().optional().describe("The priority of the label"),
|
|
1635
1699
|
});
|
|
1636
1700
|
export const UpdateLabelSchema = z.object({
|
|
1637
1701
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1642,7 +1706,7 @@ export const UpdateLabelSchema = z.object({
|
|
|
1642
1706
|
.optional()
|
|
1643
1707
|
.describe("The color of the label given in 6-digit hex notation with leading '#' sign"),
|
|
1644
1708
|
description: z.string().optional().describe("The new description of the label"),
|
|
1645
|
-
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"),
|
|
1646
1710
|
});
|
|
1647
1711
|
export const DeleteLabelSchema = z.object({
|
|
1648
1712
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1652,14 +1716,14 @@ export const DeleteLabelSchema = z.object({
|
|
|
1652
1716
|
export const ListGroupProjectsSchema = z
|
|
1653
1717
|
.object({
|
|
1654
1718
|
group_id: z.coerce.string().describe("Group ID or path"),
|
|
1655
|
-
include_subgroups: z.boolean().optional().describe("Include projects from subgroups"),
|
|
1719
|
+
include_subgroups: z.coerce.boolean().optional().describe("Include projects from subgroups"),
|
|
1656
1720
|
search: z.string().optional().describe("Search term to filter projects"),
|
|
1657
1721
|
order_by: z
|
|
1658
1722
|
.enum(["name", "path", "created_at", "updated_at", "last_activity_at"])
|
|
1659
1723
|
.optional()
|
|
1660
1724
|
.describe("Field to sort by"),
|
|
1661
1725
|
sort: z.enum(["asc", "desc"]).optional().describe("Sort direction"),
|
|
1662
|
-
archived: z.boolean().optional().describe("Filter for archived projects"),
|
|
1726
|
+
archived: z.coerce.boolean().optional().describe("Filter for archived projects"),
|
|
1663
1727
|
visibility: z
|
|
1664
1728
|
.enum(["public", "internal", "private"])
|
|
1665
1729
|
.optional()
|
|
@@ -1672,24 +1736,24 @@ export const ListGroupProjectsSchema = z
|
|
|
1672
1736
|
.boolean()
|
|
1673
1737
|
.optional()
|
|
1674
1738
|
.describe("Filter projects with merge requests feature enabled"),
|
|
1675
|
-
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"),
|
|
1676
1740
|
with_programming_language: z.string().optional().describe("Filter by programming language"),
|
|
1677
|
-
starred: z.boolean().optional().describe("Filter by starred projects"),
|
|
1678
|
-
statistics: z.boolean().optional().describe("Include project statistics"),
|
|
1679
|
-
with_custom_attributes: z.boolean().optional().describe("Include custom attributes"),
|
|
1680
|
-
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"),
|
|
1681
1745
|
})
|
|
1682
1746
|
.merge(PaginationOptionsSchema);
|
|
1683
1747
|
// Add wiki operation schemas
|
|
1684
1748
|
export const ListWikiPagesSchema = z
|
|
1685
1749
|
.object({
|
|
1686
1750
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1687
|
-
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"),
|
|
1688
1752
|
})
|
|
1689
1753
|
.merge(PaginationOptionsSchema);
|
|
1690
1754
|
export const GetWikiPageSchema = z.object({
|
|
1691
1755
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1692
|
-
slug: z.string().describe("
|
|
1756
|
+
slug: z.string().describe("Slug of the wiki page (will be URL-encoded internally)"),
|
|
1693
1757
|
});
|
|
1694
1758
|
export const CreateWikiPageSchema = z.object({
|
|
1695
1759
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1699,14 +1763,14 @@ export const CreateWikiPageSchema = z.object({
|
|
|
1699
1763
|
});
|
|
1700
1764
|
export const UpdateWikiPageSchema = z.object({
|
|
1701
1765
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1702
|
-
slug: z.string().describe("
|
|
1766
|
+
slug: z.string().describe("Slug of the wiki page (will be URL-encoded internally)"),
|
|
1703
1767
|
title: z.string().optional().describe("New title of the wiki page"),
|
|
1704
1768
|
content: z.string().optional().describe("New content of the wiki page"),
|
|
1705
1769
|
format: z.string().optional().describe("Content format, e.g., markdown, rdoc"),
|
|
1706
1770
|
});
|
|
1707
1771
|
export const DeleteWikiPageSchema = z.object({
|
|
1708
1772
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
1709
|
-
slug: z.string().describe("
|
|
1773
|
+
slug: z.string().describe("Slug of the wiki page (will be URL-encoded internally)"),
|
|
1710
1774
|
});
|
|
1711
1775
|
// Define wiki response schemas
|
|
1712
1776
|
export const GitLabWikiPageSchema = z.object({
|
|
@@ -1717,6 +1781,34 @@ export const GitLabWikiPageSchema = z.object({
|
|
|
1717
1781
|
created_at: z.string().optional(),
|
|
1718
1782
|
updated_at: z.string().optional(),
|
|
1719
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
|
+
});
|
|
1720
1812
|
// Merge Request Thread position schema - used for diff notes
|
|
1721
1813
|
// Extremely flexible position schema for API responses - accepts any structure
|
|
1722
1814
|
// Strict position schema for creating draft notes and merge request threads
|
|
@@ -1842,7 +1934,7 @@ export const GitLabDraftNoteSchema = z
|
|
|
1842
1934
|
updated_at: z.string().optional(),
|
|
1843
1935
|
discussion_id: z.string().nullable().optional(),
|
|
1844
1936
|
position: z.record(z.unknown()).nullable().optional(),
|
|
1845
|
-
resolve_discussion: z.boolean().optional(),
|
|
1937
|
+
resolve_discussion: z.coerce.boolean().optional(),
|
|
1846
1938
|
})
|
|
1847
1939
|
.transform(data => ({
|
|
1848
1940
|
// Normalize the response to always have consistent field names
|
|
@@ -1913,12 +2005,12 @@ export const CreateMergeRequestThreadSchema = ProjectParamsSchema.extend({
|
|
|
1913
2005
|
export const ResolveMergeRequestThreadSchema = ProjectParamsSchema.extend({
|
|
1914
2006
|
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
1915
2007
|
discussion_id: z.coerce.string().describe("The ID of a thread"),
|
|
1916
|
-
resolved: z.boolean().describe("Whether to resolve the thread"),
|
|
2008
|
+
resolved: z.coerce.boolean().describe("Whether to resolve the thread"),
|
|
1917
2009
|
});
|
|
1918
2010
|
// Milestone related schemas
|
|
1919
2011
|
// Schema for listing project milestones
|
|
1920
2012
|
export const ListProjectMilestonesSchema = ProjectParamsSchema.extend({
|
|
1921
|
-
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"),
|
|
1922
2014
|
state: z
|
|
1923
2015
|
.enum(["active", "closed"])
|
|
1924
2016
|
.optional()
|
|
@@ -1931,7 +2023,7 @@ export const ListProjectMilestonesSchema = ProjectParamsSchema.extend({
|
|
|
1931
2023
|
.string()
|
|
1932
2024
|
.optional()
|
|
1933
2025
|
.describe("Return only milestones with a title or description matching the provided string"),
|
|
1934
|
-
include_ancestors: z.boolean().optional().describe("Include ancestor groups"),
|
|
2026
|
+
include_ancestors: z.coerce.boolean().optional().describe("Include ancestor groups"),
|
|
1935
2027
|
updated_before: z
|
|
1936
2028
|
.string()
|
|
1937
2029
|
.optional()
|
|
@@ -1990,21 +2082,21 @@ export const ListCommitsSchema = z.object({
|
|
|
1990
2082
|
.describe("Only commits before or on this date are returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ"),
|
|
1991
2083
|
path: z.string().optional().describe("The file path"),
|
|
1992
2084
|
author: z.string().optional().describe("Search commits by commit author"),
|
|
1993
|
-
all: z.boolean().optional().describe("Retrieve every commit from the repository"),
|
|
1994
|
-
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"),
|
|
1995
2087
|
first_parent: z
|
|
1996
2088
|
.boolean()
|
|
1997
2089
|
.optional()
|
|
1998
2090
|
.describe("Follow only the first parent commit upon seeing a merge commit"),
|
|
1999
2091
|
order: z.enum(["default", "topo"]).optional().describe("List commits in order"),
|
|
2000
|
-
trailers: z.boolean().optional().describe("Parse and include Git trailers for every commit"),
|
|
2001
|
-
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
2002
|
-
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)"),
|
|
2003
2095
|
});
|
|
2004
2096
|
export const GetCommitSchema = z.object({
|
|
2005
2097
|
project_id: z.coerce.string().describe("Project ID or complete URL-encoded path to project"),
|
|
2006
2098
|
sha: z.string().describe("The commit hash or name of a repository branch or tag"),
|
|
2007
|
-
stats: z.boolean().optional().describe("Include commit stats"),
|
|
2099
|
+
stats: z.coerce.boolean().optional().describe("Include commit stats"),
|
|
2008
2100
|
});
|
|
2009
2101
|
export const GetCommitDiffSchema = z.object({
|
|
2010
2102
|
project_id: z.coerce.string().describe("Project ID or complete URL-encoded path to project"),
|
|
@@ -2043,31 +2135,31 @@ export const MyIssuesSchema = z.object({
|
|
|
2043
2135
|
.string()
|
|
2044
2136
|
.optional()
|
|
2045
2137
|
.describe("Return issues updated before the given time (ISO 8601)"),
|
|
2046
|
-
per_page: z.number().optional().describe("Number of items per page (default: 20, max: 100)"),
|
|
2047
|
-
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)"),
|
|
2048
2140
|
});
|
|
2049
2141
|
// Schema for listing project members
|
|
2050
2142
|
export const ListProjectMembersSchema = z.object({
|
|
2051
2143
|
project_id: z.string().describe("Project ID or URL-encoded path"),
|
|
2052
2144
|
query: z.string().optional().describe("Search for members by name or username"),
|
|
2053
|
-
user_ids: z.array(z.number()).optional().describe("Filter by user IDs"),
|
|
2054
|
-
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"),
|
|
2055
2147
|
include_inheritance: z
|
|
2056
2148
|
.boolean()
|
|
2057
2149
|
.optional()
|
|
2058
2150
|
.describe("Include inherited members. Defaults to false."),
|
|
2059
|
-
per_page: z.number().optional().describe("Number of items per page (default: 20, max: 100)"),
|
|
2060
|
-
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)"),
|
|
2061
2153
|
});
|
|
2062
2154
|
// Schema for GitLab project member
|
|
2063
2155
|
export const GitLabProjectMemberSchema = z.object({
|
|
2064
|
-
id: z.number(),
|
|
2156
|
+
id: z.coerce.number(),
|
|
2065
2157
|
username: z.string(),
|
|
2066
2158
|
name: z.string(),
|
|
2067
2159
|
state: z.string(),
|
|
2068
2160
|
avatar_url: z.string().nullable(),
|
|
2069
2161
|
web_url: z.string(),
|
|
2070
|
-
access_level: z.number(),
|
|
2162
|
+
access_level: z.coerce.number(),
|
|
2071
2163
|
access_level_description: z.string().optional(),
|
|
2072
2164
|
created_at: z.string(),
|
|
2073
2165
|
expires_at: z.string().nullable().optional(),
|
|
@@ -2075,7 +2167,7 @@ export const GitLabProjectMemberSchema = z.object({
|
|
|
2075
2167
|
});
|
|
2076
2168
|
// Markdown upload schemas
|
|
2077
2169
|
export const GitLabMarkdownUploadSchema = z.object({
|
|
2078
|
-
id: z.number(),
|
|
2170
|
+
id: z.coerce.number(),
|
|
2079
2171
|
alt: z.string(),
|
|
2080
2172
|
url: z.string(),
|
|
2081
2173
|
full_path: z.string(),
|
|
@@ -2097,11 +2189,11 @@ export const DownloadAttachmentSchema = z.object({
|
|
|
2097
2189
|
export const GroupIteration = z.object({
|
|
2098
2190
|
id: z.coerce.string(),
|
|
2099
2191
|
iid: z.coerce.string(),
|
|
2100
|
-
sequence: z.number(),
|
|
2192
|
+
sequence: z.coerce.number(),
|
|
2101
2193
|
group_id: z.coerce.string(),
|
|
2102
2194
|
title: z.string().optional().nullable(),
|
|
2103
2195
|
description: z.string().optional().nullable(),
|
|
2104
|
-
state: z.number(),
|
|
2196
|
+
state: z.coerce.number(),
|
|
2105
2197
|
created_at: z.string(),
|
|
2106
2198
|
updated_at: z.string(),
|
|
2107
2199
|
due_date: z.string().optional().nullable(),
|
|
@@ -2163,7 +2255,7 @@ export const GitLabEventSchema = z
|
|
|
2163
2255
|
created_at: z.string(),
|
|
2164
2256
|
author: GitLabEventAuthorSchema,
|
|
2165
2257
|
author_username: z.string(),
|
|
2166
|
-
imported: z.boolean(),
|
|
2258
|
+
imported: z.coerce.boolean(),
|
|
2167
2259
|
imported_from: z.string(),
|
|
2168
2260
|
})
|
|
2169
2261
|
.passthrough(); // Allow additional fields
|
|
@@ -2190,8 +2282,8 @@ export const ListEventsSchema = z.object({
|
|
|
2190
2282
|
.enum(["asc", "desc"])
|
|
2191
2283
|
.optional()
|
|
2192
2284
|
.describe("Direction to sort the results by creation date. Default: desc"),
|
|
2193
|
-
page: z.number().optional().describe("Returns the specified results page. Default: 1"),
|
|
2194
|
-
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"),
|
|
2195
2287
|
});
|
|
2196
2288
|
// Get project events schema
|
|
2197
2289
|
export const GetProjectEventsSchema = z.object({
|
|
@@ -2216,17 +2308,17 @@ export const GetProjectEventsSchema = z.object({
|
|
|
2216
2308
|
.enum(["asc", "desc"])
|
|
2217
2309
|
.optional()
|
|
2218
2310
|
.describe("Direction to sort the results by creation date. Default: desc"),
|
|
2219
|
-
page: z.number().optional().describe("Returns the specified results page. Default: 1"),
|
|
2220
|
-
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"),
|
|
2221
2313
|
});
|
|
2222
2314
|
// Merge Request Versions schemas - Response schemas based on GitLab API documentation
|
|
2223
2315
|
export const GitLabMergeRequestVersionSchema = z.object({
|
|
2224
|
-
id: z.number(),
|
|
2316
|
+
id: z.coerce.number(),
|
|
2225
2317
|
head_commit_sha: z.string(),
|
|
2226
2318
|
base_commit_sha: z.string(),
|
|
2227
2319
|
start_commit_sha: z.string(),
|
|
2228
2320
|
created_at: z.string(),
|
|
2229
|
-
merge_request_id: z.number(),
|
|
2321
|
+
merge_request_id: z.coerce.number(),
|
|
2230
2322
|
state: z.string(),
|
|
2231
2323
|
real_size: z.string(),
|
|
2232
2324
|
patch_id_sha: z.string(),
|
|
@@ -2242,7 +2334,7 @@ export const ExecuteGraphQLSchema = z.object({
|
|
|
2242
2334
|
});
|
|
2243
2335
|
// Release schemas
|
|
2244
2336
|
export const GitLabReleaseAssetLinkSchema = z.object({
|
|
2245
|
-
id: z.number().optional(),
|
|
2337
|
+
id: z.coerce.number().optional(),
|
|
2246
2338
|
name: z.string(),
|
|
2247
2339
|
url: z.string(),
|
|
2248
2340
|
direct_asset_path: z.string().optional(),
|
|
@@ -2253,7 +2345,7 @@ export const GitLabReleaseAssetSourceSchema = z.object({
|
|
|
2253
2345
|
url: z.string(),
|
|
2254
2346
|
});
|
|
2255
2347
|
export const GitLabReleaseAssetsSchema = z.object({
|
|
2256
|
-
count: z.number().optional(),
|
|
2348
|
+
count: z.coerce.number().optional(),
|
|
2257
2349
|
sources: z.array(GitLabReleaseAssetSourceSchema).optional(),
|
|
2258
2350
|
links: z.array(GitLabReleaseAssetLinkSchema).optional(),
|
|
2259
2351
|
evidence_file_path: z.string().optional(),
|
|
@@ -2272,7 +2364,7 @@ export const GitLabReleaseSchema = z.object({
|
|
|
2272
2364
|
released_at: z.string().nullable().optional(),
|
|
2273
2365
|
author: z
|
|
2274
2366
|
.object({
|
|
2275
|
-
id: z.number(),
|
|
2367
|
+
id: z.coerce.number(),
|
|
2276
2368
|
name: z.string(),
|
|
2277
2369
|
username: z.string(),
|
|
2278
2370
|
state: z.string(),
|
|
@@ -2312,8 +2404,8 @@ export const GitLabReleaseSchema = z.object({
|
|
|
2312
2404
|
self: z.string().optional(),
|
|
2313
2405
|
})
|
|
2314
2406
|
.optional(),
|
|
2315
|
-
upcoming_release: z.boolean().optional(),
|
|
2316
|
-
historical_release: z.boolean().optional(),
|
|
2407
|
+
upcoming_release: z.coerce.boolean().optional(),
|
|
2408
|
+
historical_release: z.coerce.boolean().optional(),
|
|
2317
2409
|
});
|
|
2318
2410
|
export const ListReleasesSchema = z
|
|
2319
2411
|
.object({
|
|
@@ -2427,7 +2519,7 @@ export const GitLabArtifactEntrySchema = z.object({
|
|
|
2427
2519
|
name: z.string(),
|
|
2428
2520
|
path: z.string(),
|
|
2429
2521
|
type: z.enum(["file", "directory"]),
|
|
2430
|
-
size: z.number().optional(),
|
|
2522
|
+
size: z.coerce.number().optional(),
|
|
2431
2523
|
mode: z.string().optional(),
|
|
2432
2524
|
});
|
|
2433
2525
|
export const DownloadJobArtifactsSchema = z.object({
|
|
@@ -2452,6 +2544,170 @@ export const DownloadReleaseAssetSchema = z.object({
|
|
|
2452
2544
|
.string()
|
|
2453
2545
|
.describe("Path to the release asset file as specified when creating or updating its link"),
|
|
2454
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
|
+
});
|
|
2455
2711
|
// --- Webhook schemas ---
|
|
2456
2712
|
export const ListWebhooksSchema = z
|
|
2457
2713
|
.object({
|
|
@@ -2480,7 +2736,7 @@ export const ListWebhookEventsSchema = z
|
|
|
2480
2736
|
.describe("Group ID or URL-encoded path. Provide either project_id or group_id, not both."),
|
|
2481
2737
|
hook_id: z.coerce.number().describe("ID of the webhook"),
|
|
2482
2738
|
status: z
|
|
2483
|
-
.union([z.number(), z.string()])
|
|
2739
|
+
.union([z.coerce.number(), z.string()])
|
|
2484
2740
|
.optional()
|
|
2485
2741
|
.describe("Filter by response status code (e.g. 200, 500) or category: successful, client_failure, server_failure"),
|
|
2486
2742
|
summary: z
|
|
@@ -2493,7 +2749,7 @@ export const ListWebhookEventsSchema = z
|
|
|
2493
2749
|
.optional()
|
|
2494
2750
|
.default(20)
|
|
2495
2751
|
.describe("Number of events per page"),
|
|
2496
|
-
page: z.number().optional().describe("Page number for pagination"),
|
|
2752
|
+
page: z.coerce.number().optional().describe("Page number for pagination"),
|
|
2497
2753
|
})
|
|
2498
2754
|
.refine(data => (data.project_id || data.group_id) && !(data.project_id && data.group_id), {
|
|
2499
2755
|
message: "Provide exactly one of project_id or group_id",
|