@zereight/mcp-gitlab 2.1.24 → 2.1.26
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 +5 -0
- package/build/config.js +1 -0
- package/build/index.js +644 -324
- package/build/oauth.js +65 -3
- package/build/schemas.js +475 -197
- package/build/test/dynamic-api-url-test.js +3 -3
- package/build/test/oauth-tests.js +39 -0
- package/build/test/remote-auth-simple-test.js +13 -2
- package/build/test/schema-tests.js +51 -0
- package/build/test/streamable-http-concurrent-session.test.js +92 -0
- package/build/test/streamable-http-unauthenticated-discovery.test.js +113 -0
- package/build/test/test-ci-catalog.js +177 -0
- package/build/test/test-create-repository.js +120 -0
- package/build/test/test-list-issues.js +15 -3
- package/build/test/test-toolset-filtering.js +6 -5
- package/build/test/test-update-project.js +112 -0
- package/build/test/utils/forwarded-public-base-url.test.js +38 -0
- package/build/tools/registry.js +26 -3
- package/build/utils/forwarded-public-base-url.js +62 -0
- package/build/utils/schema.js +15 -1
- package/package.json +4 -2
package/build/schemas.js
CHANGED
|
@@ -2,18 +2,20 @@ import { z } from "zod";
|
|
|
2
2
|
import { omitIncompleteMergeRequestPosition } from "./utils/merge-request-position.js";
|
|
3
3
|
// Helper: coerce a JSON-stringified array to an actual array.
|
|
4
4
|
// LLMs sometimes send '["a", "b"]' (string) instead of ["a", "b"] (array).
|
|
5
|
-
const coerceStringArray = z.preprocess(
|
|
5
|
+
const coerceStringArray = z.preprocess(val => {
|
|
6
6
|
if (typeof val === "string") {
|
|
7
7
|
try {
|
|
8
8
|
const parsed = JSON.parse(val);
|
|
9
9
|
if (Array.isArray(parsed))
|
|
10
10
|
return parsed;
|
|
11
11
|
}
|
|
12
|
-
catch {
|
|
12
|
+
catch {
|
|
13
|
+
/* not JSON, fall through */
|
|
14
|
+
}
|
|
13
15
|
}
|
|
14
16
|
return val;
|
|
15
17
|
}, z.array(z.string()));
|
|
16
|
-
const coerceBooleanString = z.preprocess(
|
|
18
|
+
const coerceBooleanString = z.preprocess(val => {
|
|
17
19
|
if (typeof val === "string") {
|
|
18
20
|
const normalized = val.trim().toLowerCase();
|
|
19
21
|
if (normalized === "true")
|
|
@@ -199,7 +201,10 @@ export const GitLabPipelineTriggerJobSchema = z.object({
|
|
|
199
201
|
// See https://docs.gitlab.com/api/rest/#pagination
|
|
200
202
|
export const PaginationOptionsSchema = z.object({
|
|
201
203
|
page: z.coerce.number().optional().describe("Page number for pagination (default: 1)"),
|
|
202
|
-
per_page: z.coerce
|
|
204
|
+
per_page: z.coerce
|
|
205
|
+
.number()
|
|
206
|
+
.optional()
|
|
207
|
+
.describe("Number of items per page (max: 100, default: 20)"),
|
|
203
208
|
});
|
|
204
209
|
// Schema for listing pipelines
|
|
205
210
|
export const ListPipelinesSchema = z
|
|
@@ -227,7 +232,10 @@ export const ListPipelinesSchema = z
|
|
|
227
232
|
.describe("The status of pipelines"),
|
|
228
233
|
ref: z.string().optional().describe("The ref of pipelines"),
|
|
229
234
|
sha: z.string().optional().describe("The SHA of pipelines"),
|
|
230
|
-
yaml_errors: z.coerce
|
|
235
|
+
yaml_errors: z.coerce
|
|
236
|
+
.boolean()
|
|
237
|
+
.optional()
|
|
238
|
+
.describe("Returns pipelines with invalid configurations"),
|
|
231
239
|
username: z.string().optional().describe("The username of the user who triggered pipelines"),
|
|
232
240
|
updated_after: z
|
|
233
241
|
.string()
|
|
@@ -319,12 +327,56 @@ export const ValidateProjectCiLintSchema = z.object({
|
|
|
319
327
|
.optional()
|
|
320
328
|
.describe("Commit SHA, branch, or tag to read the existing CI config from"),
|
|
321
329
|
dry_run: z.coerce.boolean().optional().describe("Run pipeline creation simulation"),
|
|
322
|
-
dry_run_ref: z
|
|
323
|
-
.string()
|
|
324
|
-
.optional()
|
|
325
|
-
.describe("Branch or tag context for dry_run validation"),
|
|
330
|
+
dry_run_ref: z.string().optional().describe("Branch or tag context for dry_run validation"),
|
|
326
331
|
include_jobs: z.coerce.boolean().optional().describe("Include jobs in the lint response"),
|
|
327
332
|
});
|
|
333
|
+
const CiCatalogResourceSortSchema = z.enum([
|
|
334
|
+
"CREATED_ASC",
|
|
335
|
+
"CREATED_DESC",
|
|
336
|
+
"LATEST_RELEASED_AT_ASC",
|
|
337
|
+
"LATEST_RELEASED_AT_DESC",
|
|
338
|
+
"NAME_ASC",
|
|
339
|
+
"NAME_DESC",
|
|
340
|
+
"STAR_COUNT_ASC",
|
|
341
|
+
"STAR_COUNT_DESC",
|
|
342
|
+
"USAGE_COUNT_ASC",
|
|
343
|
+
"USAGE_COUNT_DESC",
|
|
344
|
+
]);
|
|
345
|
+
const CiCatalogResourceVerificationLevelSchema = z.enum([
|
|
346
|
+
"GITLAB_MAINTAINED",
|
|
347
|
+
"GITLAB_PARTNER_MAINTAINED",
|
|
348
|
+
"UNVERIFIED",
|
|
349
|
+
"VERIFIED_CREATOR_MAINTAINED",
|
|
350
|
+
"VERIFIED_CREATOR_SELF_MANAGED",
|
|
351
|
+
]);
|
|
352
|
+
export const ListCiCatalogResourcesSchema = z.object({
|
|
353
|
+
search: z.string().optional().describe("Search catalog resources by name or description"),
|
|
354
|
+
first: z.coerce.number().int().min(1).max(100).optional().describe("Number of resources to return (default: 20, max: 100)"),
|
|
355
|
+
after: z.string().optional().describe("GraphQL cursor for the next page"),
|
|
356
|
+
group_ids: z.array(z.string()).optional().describe("Filter to catalog resources in these group IDs"),
|
|
357
|
+
scope: z.enum(["ALL", "NAMESPACES"]).optional().describe("Catalog resource scope"),
|
|
358
|
+
sort: CiCatalogResourceSortSchema.optional().describe("Sort order"),
|
|
359
|
+
topics: z.array(z.string()).optional().describe("Filter by project topic names"),
|
|
360
|
+
verification_level: CiCatalogResourceVerificationLevelSchema.optional().describe("Filter by verification level"),
|
|
361
|
+
});
|
|
362
|
+
const GetCiCatalogResourceOptionsSchema = z.object({
|
|
363
|
+
version_limit: z.coerce.number().int().min(1).max(20).optional().describe("Number of versions to include (default: 5, max: 20)"),
|
|
364
|
+
component_limit: z.coerce.number().int().min(1).max(50).optional().describe("Number of components per version to include (default: 20, max: 50)"),
|
|
365
|
+
component_name: z.string().optional().describe("Filter returned components by component name"),
|
|
366
|
+
include_readme: z.coerce.boolean().optional().describe("Include version README content"),
|
|
367
|
+
});
|
|
368
|
+
export const GetCiCatalogResourceSchema = z.union([
|
|
369
|
+
GetCiCatalogResourceOptionsSchema.extend({
|
|
370
|
+
id: z.string().min(1).describe("CI/CD Catalog resource global ID. Required when full_path is omitted."),
|
|
371
|
+
full_path: z.string().min(1).optional().describe("CI/CD Catalog resource full project path. Required when id is omitted."),
|
|
372
|
+
}),
|
|
373
|
+
GetCiCatalogResourceOptionsSchema.extend({
|
|
374
|
+
id: z.string().min(1).optional().describe("CI/CD Catalog resource global ID. Required when full_path is omitted."),
|
|
375
|
+
full_path: z.string().min(1).describe("CI/CD Catalog resource full project path. Required when id is omitted."),
|
|
376
|
+
}),
|
|
377
|
+
]).refine(args => Boolean(args.id) !== Boolean(args.full_path), {
|
|
378
|
+
message: "Provide exactly one of id or full_path",
|
|
379
|
+
});
|
|
328
380
|
// Deployment related schemas
|
|
329
381
|
export const GitLabDeploymentSchema = z.object({
|
|
330
382
|
id: z.coerce.string(),
|
|
@@ -435,10 +487,7 @@ export const ListEnvironmentsSchema = z
|
|
|
435
487
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
436
488
|
name: z.string().optional().describe("Return environments with this exact name"),
|
|
437
489
|
search: z.string().optional().describe("Search environments by name"),
|
|
438
|
-
states: z
|
|
439
|
-
.enum(["available", "stopped"])
|
|
440
|
-
.optional()
|
|
441
|
-
.describe("Filter environments by state"),
|
|
490
|
+
states: z.enum(["available", "stopped"]).optional().describe("Filter environments by state"),
|
|
442
491
|
})
|
|
443
492
|
.merge(PaginationOptionsSchema);
|
|
444
493
|
export const GetEnvironmentSchema = z.object({
|
|
@@ -532,7 +581,8 @@ export const GitLabUsersResponseSchema = z.record(z.string(), z
|
|
|
532
581
|
export const GetUserSchema = z.object({
|
|
533
582
|
user_id: z.coerce.string().describe("The ID of the user"),
|
|
534
583
|
});
|
|
535
|
-
export const GitLabUserFullSchema = z
|
|
584
|
+
export const GitLabUserFullSchema = z
|
|
585
|
+
.object({
|
|
536
586
|
id: z.coerce.string(),
|
|
537
587
|
username: z.string(),
|
|
538
588
|
name: z.string(),
|
|
@@ -561,19 +611,23 @@ export const GitLabUserFullSchema = z.object({
|
|
|
561
611
|
color_scheme_id: z.number().nullable().optional(),
|
|
562
612
|
projects_limit: z.number().nullable().optional(),
|
|
563
613
|
current_sign_in_at: z.string().nullable().optional(),
|
|
564
|
-
identities: z
|
|
614
|
+
identities: z
|
|
615
|
+
.array(z.object({
|
|
565
616
|
provider: z.string(),
|
|
566
617
|
extern_uid: z.string(),
|
|
567
|
-
}))
|
|
618
|
+
}))
|
|
619
|
+
.optional(),
|
|
568
620
|
can_create_group: z.boolean().nullable().optional(),
|
|
569
621
|
can_create_project: z.boolean().nullable().optional(),
|
|
570
622
|
two_factor_enabled: z.boolean().nullable().optional(),
|
|
571
623
|
external: z.boolean().nullable().optional(),
|
|
572
624
|
private_profile: z.boolean().nullable().optional(),
|
|
573
625
|
is_admin: z.boolean().nullable().optional(),
|
|
574
|
-
})
|
|
626
|
+
})
|
|
627
|
+
.passthrough();
|
|
575
628
|
export const WhoAmISchema = z.object({});
|
|
576
|
-
export const GitLabCurrentUserSchema = z
|
|
629
|
+
export const GitLabCurrentUserSchema = z
|
|
630
|
+
.object({
|
|
577
631
|
id: z.coerce.string(),
|
|
578
632
|
username: z.string(),
|
|
579
633
|
name: z.string(),
|
|
@@ -594,17 +648,23 @@ export const GitLabCurrentUserSchema = z.object({
|
|
|
594
648
|
is_admin: z.boolean().optional(),
|
|
595
649
|
can_create_group: z.boolean().optional(),
|
|
596
650
|
can_create_project: z.boolean().optional(),
|
|
597
|
-
identities: z
|
|
651
|
+
identities: z
|
|
652
|
+
.array(z.object({
|
|
598
653
|
provider: z.string(),
|
|
599
654
|
extern_uid: z.string(),
|
|
600
|
-
}))
|
|
601
|
-
|
|
655
|
+
}))
|
|
656
|
+
.optional(),
|
|
657
|
+
})
|
|
658
|
+
.passthrough();
|
|
602
659
|
// Group related schemas
|
|
603
660
|
export const CreateGroupSchema = z.object({
|
|
604
661
|
name: z.string().describe("The name of the group"),
|
|
605
662
|
path: z.string().describe("The path of the group"),
|
|
606
663
|
description: z.string().optional().describe("The group's description"),
|
|
607
|
-
visibility: z
|
|
664
|
+
visibility: z
|
|
665
|
+
.enum(["private", "internal", "public"])
|
|
666
|
+
.optional()
|
|
667
|
+
.describe("The group's visibility level"),
|
|
608
668
|
parent_id: z.coerce.number().optional().describe("The parent group ID for creating a subgroup"),
|
|
609
669
|
});
|
|
610
670
|
export const GitLabGroupSchema = z.object({
|
|
@@ -882,6 +942,7 @@ export const GitLabMilestonesSchema = z.object({
|
|
|
882
942
|
// Input schemas for operations
|
|
883
943
|
export const CreateRepositoryOptionsSchema = z.object({
|
|
884
944
|
name: z.string(),
|
|
945
|
+
namespace_id: z.preprocess(val => (val === "" ? undefined : val), z.coerce.number().int().min(1).optional()),
|
|
885
946
|
description: z.string().optional(),
|
|
886
947
|
visibility: z.enum(["private", "internal", "public"]).optional(), // Changed from private to match GitLab API
|
|
887
948
|
initialize_with_readme: z.coerce.boolean().optional(), // Changed from auto_init to match GitLab API
|
|
@@ -936,10 +997,7 @@ const SearchBlobsBaseSchema = z.object({
|
|
|
936
997
|
search: z
|
|
937
998
|
.string()
|
|
938
999
|
.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.'),
|
|
939
|
-
filename: z
|
|
940
|
-
.string()
|
|
941
|
-
.optional()
|
|
942
|
-
.describe("Filter by filename (supports * wildcard, e.g. '*.ts')"),
|
|
1000
|
+
filename: z.string().optional().describe("Filter by filename (supports * wildcard, e.g. '*.ts')"),
|
|
943
1001
|
path: z
|
|
944
1002
|
.string()
|
|
945
1003
|
.optional()
|
|
@@ -1093,6 +1151,12 @@ export const GitLabMergeRequestSchema = z.object({
|
|
|
1093
1151
|
merged_at: z.string().nullable(),
|
|
1094
1152
|
closed_at: z.string().nullable(),
|
|
1095
1153
|
merge_commit_sha: z.string().nullable(),
|
|
1154
|
+
merge_user: GitLabUserSchema.nullable()
|
|
1155
|
+
.optional()
|
|
1156
|
+
.describe("User who performed the merge (GitLab API v4 field)"),
|
|
1157
|
+
merged_by: GitLabUserSchema.nullable()
|
|
1158
|
+
.optional()
|
|
1159
|
+
.describe("Deprecated alias for merge_user, kept for backwards compatibility"),
|
|
1096
1160
|
detailed_merge_status: z.string().optional(),
|
|
1097
1161
|
merge_status: z.string().optional(),
|
|
1098
1162
|
merge_error: z.string().nullable().optional(),
|
|
@@ -1108,8 +1172,8 @@ export const GitLabMergeRequestSchema = z.object({
|
|
|
1108
1172
|
.nullable()
|
|
1109
1173
|
.optional()
|
|
1110
1174
|
.describe("Number of commits the source branch is behind the target branch"),
|
|
1111
|
-
rebase_in_progress: z
|
|
1112
|
-
.
|
|
1175
|
+
rebase_in_progress: z.coerce
|
|
1176
|
+
.boolean()
|
|
1113
1177
|
.optional()
|
|
1114
1178
|
.describe("Whether rebase is currently in progress for this merge request"),
|
|
1115
1179
|
merge_when_pipeline_succeeds: z.coerce.boolean().optional(),
|
|
@@ -1324,7 +1388,10 @@ export const UpdateIssueNoteSchema = ProjectParamsSchema.extend({
|
|
|
1324
1388
|
// Input schema for adding a note to an issue (top-level comment or discussion reply)
|
|
1325
1389
|
export const CreateIssueNoteSchema = ProjectParamsSchema.extend({
|
|
1326
1390
|
issue_iid: z.coerce.string().describe("The IID of an issue"),
|
|
1327
|
-
discussion_id: z.coerce
|
|
1391
|
+
discussion_id: z.coerce
|
|
1392
|
+
.string()
|
|
1393
|
+
.optional()
|
|
1394
|
+
.describe("The ID of a thread. If provided, replies to that thread; otherwise creates a top-level note"),
|
|
1328
1395
|
body: z.string().describe("The content of the note or reply"),
|
|
1329
1396
|
created_at: z.string().optional().describe("Date the note was created at (ISO 8601 format)"),
|
|
1330
1397
|
});
|
|
@@ -1344,7 +1411,7 @@ export const SearchRepositoriesSchema = z
|
|
|
1344
1411
|
query: z.string().optional().describe("Search query (alias for 'search')"),
|
|
1345
1412
|
})
|
|
1346
1413
|
.merge(PaginationOptionsSchema)
|
|
1347
|
-
.transform(
|
|
1414
|
+
.transform(data => {
|
|
1348
1415
|
const search = data.search || data.query;
|
|
1349
1416
|
if (!search) {
|
|
1350
1417
|
throw new Error("Either 'search' or 'query' must be provided");
|
|
@@ -1353,6 +1420,9 @@ export const SearchRepositoriesSchema = z
|
|
|
1353
1420
|
});
|
|
1354
1421
|
export const CreateRepositorySchema = z.object({
|
|
1355
1422
|
name: z.string().describe("Repository name"),
|
|
1423
|
+
namespace_id: z
|
|
1424
|
+
.preprocess(val => (val === "" ? undefined : val), z.coerce.number().int().min(1).optional())
|
|
1425
|
+
.describe("Group namespace ID to create the project in. Omit to use the current user's namespace."),
|
|
1356
1426
|
description: z.string().optional().describe("Repository description"),
|
|
1357
1427
|
visibility: z
|
|
1358
1428
|
.enum(["private", "internal", "public"])
|
|
@@ -1383,7 +1453,7 @@ export const GetFileContentsSchema = z
|
|
|
1383
1453
|
path: ["file_path"],
|
|
1384
1454
|
});
|
|
1385
1455
|
}
|
|
1386
|
-
const finalPath = fp && fp.length > 0 ? fp : p ?? "";
|
|
1456
|
+
const finalPath = fp && fp.length > 0 ? fp : (p ?? "");
|
|
1387
1457
|
if (finalPath.trim().length === 0) {
|
|
1388
1458
|
ctx.addIssue({
|
|
1389
1459
|
code: z.ZodIssueCode.custom,
|
|
@@ -1418,7 +1488,10 @@ export const CreateIssueSchema = ProjectParamsSchema.extend({
|
|
|
1418
1488
|
.optional()
|
|
1419
1489
|
.default("issue")
|
|
1420
1490
|
.describe("The type of issue. One of issue, incident, test_case or task."),
|
|
1421
|
-
weight: z.coerce
|
|
1491
|
+
weight: z.coerce
|
|
1492
|
+
.number()
|
|
1493
|
+
.optional()
|
|
1494
|
+
.describe("Weight of the issue (numeric, typically hours of work)"),
|
|
1422
1495
|
});
|
|
1423
1496
|
export const GitLabTodoSchema = z.object({
|
|
1424
1497
|
id: z.coerce.number(),
|
|
@@ -1480,21 +1553,27 @@ const MergeRequestOptionsSchema = {
|
|
|
1480
1553
|
source_branch: z.string().describe("Branch containing changes"),
|
|
1481
1554
|
target_branch: z.string().describe("Branch to merge into"),
|
|
1482
1555
|
target_project_id: z.coerce.string().optional().describe("Numeric ID of the target project."),
|
|
1483
|
-
assignee_ids: z
|
|
1556
|
+
assignee_ids: z
|
|
1557
|
+
.array(z.coerce.number())
|
|
1558
|
+
.optional()
|
|
1559
|
+
.describe("The ID of the users to assign the MR to"),
|
|
1484
1560
|
reviewer_ids: z
|
|
1485
1561
|
.array(z.coerce.number())
|
|
1486
1562
|
.optional()
|
|
1487
1563
|
.describe("The ID of the users to assign as reviewers of the MR"),
|
|
1488
1564
|
labels: coerceStringArray.optional().describe("Labels for the MR"),
|
|
1489
1565
|
draft: z.coerce.boolean().optional().describe("Create as draft merge request"),
|
|
1490
|
-
allow_collaboration: z.coerce
|
|
1491
|
-
|
|
1492
|
-
.
|
|
1566
|
+
allow_collaboration: z.coerce
|
|
1567
|
+
.boolean()
|
|
1568
|
+
.optional()
|
|
1569
|
+
.describe("Allow commits from upstream members"),
|
|
1570
|
+
remove_source_branch: z.coerce
|
|
1571
|
+
.boolean()
|
|
1493
1572
|
.nullable()
|
|
1494
1573
|
.optional()
|
|
1495
1574
|
.describe("Flag indicating if a merge request should remove the source branch when merging."),
|
|
1496
|
-
squash: z
|
|
1497
|
-
.
|
|
1575
|
+
squash: z.coerce
|
|
1576
|
+
.boolean()
|
|
1498
1577
|
.nullable()
|
|
1499
1578
|
.optional()
|
|
1500
1579
|
.describe("If true, squash all commits into a single commit on merge."),
|
|
@@ -1526,7 +1605,7 @@ export const GetProtectedBranchSchema = ProjectParamsSchema.extend({
|
|
|
1526
1605
|
branch_name: z.string().describe("Name of the protected branch"),
|
|
1527
1606
|
});
|
|
1528
1607
|
// String-aware boolean preprocessing: correctly handles "false" → false
|
|
1529
|
-
const stringBoolean = z.preprocess(
|
|
1608
|
+
const stringBoolean = z.preprocess(val => {
|
|
1530
1609
|
if (typeof val === "string") {
|
|
1531
1610
|
const lower = val.toLowerCase();
|
|
1532
1611
|
if (lower === "false" || lower === "0")
|
|
@@ -1539,10 +1618,10 @@ const stringBoolean = z.preprocess((val) => {
|
|
|
1539
1618
|
const protectedBranchAccessLevel = z.coerce
|
|
1540
1619
|
.number()
|
|
1541
1620
|
.int()
|
|
1542
|
-
.refine(
|
|
1621
|
+
.refine(level => [0, 30, 40, 60].includes(level), {
|
|
1543
1622
|
message: "Access level must be one of 0 (No access), 30 (Developer), 40 (Maintainer), or 60 (Admin)",
|
|
1544
1623
|
});
|
|
1545
|
-
export const ProtectBranchSchema = z.preprocess(
|
|
1624
|
+
export const ProtectBranchSchema = z.preprocess(input => {
|
|
1546
1625
|
if (typeof input !== "object" || input === null) {
|
|
1547
1626
|
return input;
|
|
1548
1627
|
}
|
|
@@ -1616,8 +1695,8 @@ export const GitLabBranchSchema = z.object({
|
|
|
1616
1695
|
export const GetBranchDiffsSchema = ProjectParamsSchema.extend({
|
|
1617
1696
|
from: z.string().describe("The base branch or commit SHA to compare from"),
|
|
1618
1697
|
to: z.string().describe("The target branch or commit SHA to compare to"),
|
|
1619
|
-
straight: z
|
|
1620
|
-
.
|
|
1698
|
+
straight: z.coerce
|
|
1699
|
+
.boolean()
|
|
1621
1700
|
.optional()
|
|
1622
1701
|
.describe("Comparison method: false for '...' (default), true for '--'"),
|
|
1623
1702
|
excluded_file_patterns: z
|
|
@@ -1642,7 +1721,10 @@ export const UpdateMergeRequestSchema = GetMergeRequestSchema.extend({
|
|
|
1642
1721
|
title: z.string().optional().describe("The title of the merge request"),
|
|
1643
1722
|
description: z.string().optional().describe("The description of the merge request"),
|
|
1644
1723
|
target_branch: z.string().optional().describe("The target branch"),
|
|
1645
|
-
assignee_ids: z
|
|
1724
|
+
assignee_ids: z
|
|
1725
|
+
.array(z.coerce.number())
|
|
1726
|
+
.optional()
|
|
1727
|
+
.describe("The ID of the users to assign the MR to"),
|
|
1646
1728
|
reviewer_ids: z
|
|
1647
1729
|
.array(z.coerce.number())
|
|
1648
1730
|
.optional()
|
|
@@ -1652,11 +1734,14 @@ export const UpdateMergeRequestSchema = GetMergeRequestSchema.extend({
|
|
|
1652
1734
|
.enum(["close", "reopen"])
|
|
1653
1735
|
.optional()
|
|
1654
1736
|
.describe("New state (close/reopen) for the MR"),
|
|
1655
|
-
remove_source_branch: z
|
|
1656
|
-
.
|
|
1737
|
+
remove_source_branch: z.coerce
|
|
1738
|
+
.boolean()
|
|
1657
1739
|
.optional()
|
|
1658
1740
|
.describe("Flag indicating if the source branch should be removed"),
|
|
1659
|
-
squash: z.coerce
|
|
1741
|
+
squash: z.coerce
|
|
1742
|
+
.boolean()
|
|
1743
|
+
.optional()
|
|
1744
|
+
.describe("Squash commits into a single commit when merging"),
|
|
1660
1745
|
draft: z.coerce.boolean().optional().describe("Work in progress merge request"),
|
|
1661
1746
|
});
|
|
1662
1747
|
export const MergeMergeRequestSchema = ProjectParamsSchema.extend({
|
|
@@ -1783,9 +1868,12 @@ export const GetMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
|
|
|
1783
1868
|
});
|
|
1784
1869
|
export const ListMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
|
|
1785
1870
|
page: z.coerce.number().optional().describe("Page number for pagination (default: 1)"),
|
|
1786
|
-
per_page: z.coerce
|
|
1787
|
-
|
|
1788
|
-
.
|
|
1871
|
+
per_page: z.coerce
|
|
1872
|
+
.number()
|
|
1873
|
+
.optional()
|
|
1874
|
+
.describe("Number of items per page (max: 100, default: 20)"),
|
|
1875
|
+
unidiff: z.coerce
|
|
1876
|
+
.boolean()
|
|
1789
1877
|
.optional()
|
|
1790
1878
|
.describe("Present diffs in the unified diff format. Default is false. Introduced in GitLab 16.5."),
|
|
1791
1879
|
});
|
|
@@ -1800,8 +1888,8 @@ export const GetMergeRequestFileDiffSchema = GetMergeRequestSchema.extend({
|
|
|
1800
1888
|
.array(z.string())
|
|
1801
1889
|
.describe("List of file paths to retrieve diffs for (e.g. ['src/api/users.ts', 'src/repo/user.go']). " +
|
|
1802
1890
|
"Call list_merge_request_changed_files first to get the full list of changed paths."),
|
|
1803
|
-
unidiff: z
|
|
1804
|
-
.
|
|
1891
|
+
unidiff: z.coerce
|
|
1892
|
+
.boolean()
|
|
1805
1893
|
.optional()
|
|
1806
1894
|
.describe("Present diff in the unified diff format. Default is false."),
|
|
1807
1895
|
});
|
|
@@ -1811,8 +1899,8 @@ export const ListMergeRequestVersionsSchema = ProjectParamsSchema.extend({
|
|
|
1811
1899
|
});
|
|
1812
1900
|
export const GetMergeRequestVersionSchema = ListMergeRequestVersionsSchema.extend({
|
|
1813
1901
|
version_id: z.coerce.string().describe("The ID of the merge request diff version"),
|
|
1814
|
-
unidiff: z
|
|
1815
|
-
.
|
|
1902
|
+
unidiff: z.coerce
|
|
1903
|
+
.boolean()
|
|
1816
1904
|
.optional()
|
|
1817
1905
|
.describe("Present diffs in the unified diff format. Default is false. Introduced in GitLab 16.5."),
|
|
1818
1906
|
});
|
|
@@ -1872,7 +1960,10 @@ export const ListIssuesSchema = z
|
|
|
1872
1960
|
.describe("Return issues with a specific state"),
|
|
1873
1961
|
updated_after: z.string().optional().describe("Return issues updated after the given time"),
|
|
1874
1962
|
updated_before: z.string().optional().describe("Return issues updated before the given time"),
|
|
1875
|
-
with_labels_details: z.coerce
|
|
1963
|
+
with_labels_details: z.coerce
|
|
1964
|
+
.boolean()
|
|
1965
|
+
.optional()
|
|
1966
|
+
.describe("Return more details for each label"),
|
|
1876
1967
|
})
|
|
1877
1968
|
.merge(PaginationOptionsSchema);
|
|
1878
1969
|
// Merge Requests API operation schemas
|
|
@@ -1963,7 +2054,10 @@ export const ListMergeRequestsSchema = z
|
|
|
1963
2054
|
.enum(["yes", "no"])
|
|
1964
2055
|
.optional()
|
|
1965
2056
|
.describe("Filter merge requests against their wip status"),
|
|
1966
|
-
with_labels_details: z.coerce
|
|
2057
|
+
with_labels_details: z.coerce
|
|
2058
|
+
.boolean()
|
|
2059
|
+
.optional()
|
|
2060
|
+
.describe("Return more details for each label"),
|
|
1967
2061
|
})
|
|
1968
2062
|
.merge(PaginationOptionsSchema);
|
|
1969
2063
|
export const GetIssueSchema = z.object({
|
|
@@ -1975,15 +2069,23 @@ export const UpdateIssueSchema = z.object({
|
|
|
1975
2069
|
issue_iid: z.coerce.string().describe("The internal ID of the project issue"),
|
|
1976
2070
|
title: z.string().optional().describe("The title of the issue"),
|
|
1977
2071
|
description: z.string().optional().describe("The description of the issue"),
|
|
1978
|
-
assignee_ids: z
|
|
2072
|
+
assignee_ids: z
|
|
2073
|
+
.array(z.coerce.number())
|
|
2074
|
+
.optional()
|
|
2075
|
+
.describe("Array of user IDs to assign issue to"),
|
|
1979
2076
|
confidential: z.coerce.boolean().optional().describe("Set the issue to be confidential"),
|
|
1980
2077
|
discussion_locked: z.coerce.boolean().optional().describe("Flag to lock discussions"),
|
|
1981
2078
|
due_date: z.string().optional().describe("Date the issue is due (YYYY-MM-DD)"),
|
|
1982
2079
|
labels: coerceStringArray.optional().describe("Array of label names"),
|
|
1983
2080
|
milestone_id: z.coerce.string().optional().describe("Milestone ID to assign"),
|
|
1984
2081
|
state_event: z.enum(["close", "reopen"]).optional().describe("Update issue state (close/reopen)"),
|
|
1985
|
-
weight: z.coerce
|
|
1986
|
-
|
|
2082
|
+
weight: z.coerce
|
|
2083
|
+
.number()
|
|
2084
|
+
.optional()
|
|
2085
|
+
.describe("Weight of the issue (numeric, typically hours of work)"),
|
|
2086
|
+
issue_type: z
|
|
2087
|
+
.preprocess(val => (typeof val === "string" ? val.toLowerCase() : val), z.enum(["issue", "incident", "test_case", "task"]).optional())
|
|
2088
|
+
.describe("The type of issue. One of issue, incident, test_case or task."),
|
|
1987
2089
|
});
|
|
1988
2090
|
export const DeleteIssueSchema = z.object({
|
|
1989
2091
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -1998,10 +2100,16 @@ export const UpdateIssueDescriptionPatchSchema = z.object({
|
|
|
1998
2100
|
.min(1)
|
|
1999
2101
|
.max(50000)
|
|
2000
2102
|
.describe("The patch content to apply to the issue description"),
|
|
2001
|
-
dry_run: z.coerce
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
.
|
|
2103
|
+
dry_run: z.coerce
|
|
2104
|
+
.boolean()
|
|
2105
|
+
.optional()
|
|
2106
|
+
.describe("If true, preview changes without updating the issue"),
|
|
2107
|
+
create_note: z.coerce
|
|
2108
|
+
.boolean()
|
|
2109
|
+
.optional()
|
|
2110
|
+
.describe("If true, add a note summarizing the change after update"),
|
|
2111
|
+
allow_multiple: z.coerce
|
|
2112
|
+
.boolean()
|
|
2005
2113
|
.optional()
|
|
2006
2114
|
.describe("For search_replace: allow multiple matches to all be replaced (default: false — fail on duplicate)"),
|
|
2007
2115
|
});
|
|
@@ -2047,18 +2155,65 @@ export const GetNamespaceSchema = z.object({
|
|
|
2047
2155
|
});
|
|
2048
2156
|
export const VerifyNamespaceSchema = z.object({
|
|
2049
2157
|
path: z.string().describe("Namespace path to verify"),
|
|
2158
|
+
parent_id: z
|
|
2159
|
+
.preprocess(val => (val === "" ? undefined : val), z.number().int().optional())
|
|
2160
|
+
.describe("Parent namespace ID; required to correctly resolve paths in nested namespaces where the same path may exist under different parents"),
|
|
2050
2161
|
});
|
|
2051
2162
|
// Project API operation schemas
|
|
2052
2163
|
export const GetProjectSchema = z.object({
|
|
2053
2164
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2054
2165
|
});
|
|
2166
|
+
const ProjectFeatureAccessLevelSchema = z
|
|
2167
|
+
.enum(["disabled", "private", "enabled"])
|
|
2168
|
+
.describe("Project feature access level");
|
|
2169
|
+
const ProjectPagesAccessLevelSchema = z
|
|
2170
|
+
.enum(["disabled", "private", "enabled", "public"])
|
|
2171
|
+
.describe("Project pages access level. Unlike other features, pages can be set to 'public'");
|
|
2172
|
+
export const UpdateProjectSchema = ProjectParamsSchema.extend({
|
|
2173
|
+
name: z.string().optional().describe("Project display name"),
|
|
2174
|
+
path: z.string().optional().describe("Project path/slug"),
|
|
2175
|
+
description: z.string().optional().describe("Project description"),
|
|
2176
|
+
default_branch: z.string().optional().describe("Default branch name"),
|
|
2177
|
+
visibility: z.enum(["private", "internal", "public"]).optional().describe("Project visibility"),
|
|
2178
|
+
topics: z.array(z.string()).optional().describe("Project topics"),
|
|
2179
|
+
request_access_enabled: coerceBooleanString.optional().describe("Allow users to request access"),
|
|
2180
|
+
remove_source_branch_after_merge: coerceBooleanString
|
|
2181
|
+
.optional()
|
|
2182
|
+
.describe("Remove source branches after merge by default"),
|
|
2183
|
+
only_allow_merge_if_pipeline_succeeds: coerceBooleanString
|
|
2184
|
+
.optional()
|
|
2185
|
+
.describe("Require successful pipeline before merge"),
|
|
2186
|
+
only_allow_merge_if_all_discussions_are_resolved: coerceBooleanString
|
|
2187
|
+
.optional()
|
|
2188
|
+
.describe("Require all discussions to be resolved before merge"),
|
|
2189
|
+
squash_option: z
|
|
2190
|
+
.enum(["never", "always", "default_on", "default_off"])
|
|
2191
|
+
.optional()
|
|
2192
|
+
.describe("Squash commits setting"),
|
|
2193
|
+
merge_method: z.enum(["merge", "rebase_merge", "ff"]).optional().describe("Merge method"),
|
|
2194
|
+
issues_access_level: ProjectFeatureAccessLevelSchema.optional().describe("Issues feature visibility"),
|
|
2195
|
+
merge_requests_access_level: ProjectFeatureAccessLevelSchema.optional().describe("Merge requests feature visibility"),
|
|
2196
|
+
builds_access_level: ProjectFeatureAccessLevelSchema.optional().describe("CI/CD pipelines feature visibility"),
|
|
2197
|
+
wiki_access_level: ProjectFeatureAccessLevelSchema.optional().describe("Wiki feature visibility"),
|
|
2198
|
+
snippets_access_level: ProjectFeatureAccessLevelSchema.optional().describe("Snippets feature visibility"),
|
|
2199
|
+
container_registry_access_level: ProjectFeatureAccessLevelSchema.optional().describe("Container registry feature visibility"),
|
|
2200
|
+
environments_access_level: ProjectFeatureAccessLevelSchema.optional().describe("Environments feature visibility"),
|
|
2201
|
+
forking_access_level: ProjectFeatureAccessLevelSchema.optional().describe("Forking feature visibility"),
|
|
2202
|
+
package_registry_access_level: ProjectFeatureAccessLevelSchema.optional().describe("Package registry feature visibility"),
|
|
2203
|
+
pages_access_level: ProjectPagesAccessLevelSchema.optional().describe("Pages feature visibility"),
|
|
2204
|
+
}).refine(args => Object.keys(args).some(key => key !== "project_id" && args[key] !== undefined), {
|
|
2205
|
+
message: "Provide at least one project setting to update",
|
|
2206
|
+
});
|
|
2055
2207
|
export const ListProjectsSchema = z
|
|
2056
2208
|
.object({
|
|
2057
2209
|
search: z.string().optional().describe("Search term for projects"),
|
|
2058
|
-
search_namespaces: z.coerce
|
|
2210
|
+
search_namespaces: z.coerce
|
|
2211
|
+
.boolean()
|
|
2212
|
+
.optional()
|
|
2213
|
+
.describe("Needs to be true if search is full path"),
|
|
2059
2214
|
owned: z.coerce.boolean().optional().describe("Filter for projects owned by current user"),
|
|
2060
|
-
membership: z
|
|
2061
|
-
.
|
|
2215
|
+
membership: z.coerce
|
|
2216
|
+
.boolean()
|
|
2062
2217
|
.optional()
|
|
2063
2218
|
.describe("Filter for projects where current user is a member"),
|
|
2064
2219
|
simple: z.coerce.boolean().optional().describe("Return only limited fields"),
|
|
@@ -2075,12 +2230,12 @@ export const ListProjectsSchema = z
|
|
|
2075
2230
|
.enum(["asc", "desc"])
|
|
2076
2231
|
.optional()
|
|
2077
2232
|
.describe("Return projects sorted in ascending or descending order"),
|
|
2078
|
-
with_issues_enabled: z
|
|
2079
|
-
.
|
|
2233
|
+
with_issues_enabled: z.coerce
|
|
2234
|
+
.boolean()
|
|
2080
2235
|
.optional()
|
|
2081
2236
|
.describe("Filter projects with issues feature enabled"),
|
|
2082
|
-
with_merge_requests_enabled: z
|
|
2083
|
-
.
|
|
2237
|
+
with_merge_requests_enabled: z.coerce
|
|
2238
|
+
.boolean()
|
|
2084
2239
|
.optional()
|
|
2085
2240
|
.describe("Filter projects with merge requests feature enabled"),
|
|
2086
2241
|
min_access_level: z.coerce.number().optional().describe("Filter by minimum access level"),
|
|
@@ -2091,8 +2246,8 @@ export const ListProjectsSchema = z
|
|
|
2091
2246
|
export const ListLabelsSchema = z
|
|
2092
2247
|
.object({
|
|
2093
2248
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2094
|
-
with_counts: z
|
|
2095
|
-
.
|
|
2249
|
+
with_counts: z.coerce
|
|
2250
|
+
.boolean()
|
|
2096
2251
|
.optional()
|
|
2097
2252
|
.describe("Whether to include issue and merge request counts"),
|
|
2098
2253
|
include_ancestor_groups: z.coerce.boolean().optional().describe("Include ancestor groups"),
|
|
@@ -2144,12 +2299,12 @@ export const ListGroupProjectsSchema = z
|
|
|
2144
2299
|
.enum(["public", "internal", "private"])
|
|
2145
2300
|
.optional()
|
|
2146
2301
|
.describe("Filter by project visibility"),
|
|
2147
|
-
with_issues_enabled: z
|
|
2148
|
-
.
|
|
2302
|
+
with_issues_enabled: z.coerce
|
|
2303
|
+
.boolean()
|
|
2149
2304
|
.optional()
|
|
2150
2305
|
.describe("Filter projects with issues feature enabled"),
|
|
2151
|
-
with_merge_requests_enabled: z
|
|
2152
|
-
.
|
|
2306
|
+
with_merge_requests_enabled: z.coerce
|
|
2307
|
+
.boolean()
|
|
2153
2308
|
.optional()
|
|
2154
2309
|
.describe("Filter projects with merge requests feature enabled"),
|
|
2155
2310
|
min_access_level: z.coerce.number().optional().describe("Filter by minimum access level"),
|
|
@@ -2383,8 +2538,8 @@ export const CreateDraftNoteSchema = ProjectParamsSchema.extend({
|
|
|
2383
2538
|
.optional()
|
|
2384
2539
|
.describe("The ID of a discussion the draft note replies to"),
|
|
2385
2540
|
position: optionalMergeRequestThreadPosition.describe("Position when creating a diff note"),
|
|
2386
|
-
resolve_discussion: z
|
|
2387
|
-
.
|
|
2541
|
+
resolve_discussion: z.coerce
|
|
2542
|
+
.boolean()
|
|
2388
2543
|
.optional()
|
|
2389
2544
|
.describe("Whether to resolve the discussion when publishing"),
|
|
2390
2545
|
});
|
|
@@ -2394,8 +2549,8 @@ export const UpdateDraftNoteSchema = ProjectParamsSchema.extend({
|
|
|
2394
2549
|
draft_note_id: z.coerce.string().describe("The ID of the draft note"),
|
|
2395
2550
|
body: z.string().optional().describe("The content of the draft note"),
|
|
2396
2551
|
position: optionalMergeRequestThreadPosition.describe("Position when creating a diff note"),
|
|
2397
|
-
resolve_discussion: z
|
|
2398
|
-
.
|
|
2552
|
+
resolve_discussion: z.coerce
|
|
2553
|
+
.boolean()
|
|
2399
2554
|
.optional()
|
|
2400
2555
|
.describe("Whether to resolve the discussion when publishing"),
|
|
2401
2556
|
});
|
|
@@ -2428,7 +2583,10 @@ export const ResolveMergeRequestThreadSchema = ProjectParamsSchema.extend({
|
|
|
2428
2583
|
// Milestone related schemas
|
|
2429
2584
|
// Schema for listing project milestones
|
|
2430
2585
|
export const ListProjectMilestonesSchema = ProjectParamsSchema.extend({
|
|
2431
|
-
iids: z
|
|
2586
|
+
iids: z
|
|
2587
|
+
.array(z.coerce.number())
|
|
2588
|
+
.optional()
|
|
2589
|
+
.describe("Return only the milestones having the given iid"),
|
|
2432
2590
|
state: z
|
|
2433
2591
|
.enum(["active", "closed"])
|
|
2434
2592
|
.optional()
|
|
@@ -2501,15 +2659,24 @@ export const ListCommitsSchema = z.object({
|
|
|
2501
2659
|
path: z.string().optional().describe("The file path"),
|
|
2502
2660
|
author: z.string().optional().describe("Search commits by commit author"),
|
|
2503
2661
|
all: z.coerce.boolean().optional().describe("Retrieve every commit from the repository"),
|
|
2504
|
-
with_stats: z.coerce
|
|
2505
|
-
|
|
2506
|
-
.
|
|
2662
|
+
with_stats: z.coerce
|
|
2663
|
+
.boolean()
|
|
2664
|
+
.optional()
|
|
2665
|
+
.describe("Stats about each commit are added to the response"),
|
|
2666
|
+
first_parent: z.coerce
|
|
2667
|
+
.boolean()
|
|
2507
2668
|
.optional()
|
|
2508
2669
|
.describe("Follow only the first parent commit upon seeing a merge commit"),
|
|
2509
2670
|
order: z.enum(["default", "topo"]).optional().describe("List commits in order"),
|
|
2510
|
-
trailers: z.coerce
|
|
2671
|
+
trailers: z.coerce
|
|
2672
|
+
.boolean()
|
|
2673
|
+
.optional()
|
|
2674
|
+
.describe("Parse and include Git trailers for every commit"),
|
|
2511
2675
|
page: z.coerce.number().optional().describe("Page number for pagination (default: 1)"),
|
|
2512
|
-
per_page: z.coerce
|
|
2676
|
+
per_page: z.coerce
|
|
2677
|
+
.number()
|
|
2678
|
+
.optional()
|
|
2679
|
+
.describe("Number of items per page (max: 100, default: 20)"),
|
|
2513
2680
|
});
|
|
2514
2681
|
export const GetCommitSchema = z.object({
|
|
2515
2682
|
project_id: z.coerce.string().describe("Project ID or complete URL-encoded path to project"),
|
|
@@ -2519,8 +2686,8 @@ export const GetCommitSchema = z.object({
|
|
|
2519
2686
|
export const GetCommitDiffSchema = z.object({
|
|
2520
2687
|
project_id: z.coerce.string().describe("Project ID or complete URL-encoded path to project"),
|
|
2521
2688
|
sha: z.string().describe("The commit hash or name of a repository branch or tag"),
|
|
2522
|
-
full_diff: z
|
|
2523
|
-
.
|
|
2689
|
+
full_diff: z.coerce
|
|
2690
|
+
.boolean()
|
|
2524
2691
|
.optional()
|
|
2525
2692
|
.describe("Whether to return the full diff or only first page (default: false)"),
|
|
2526
2693
|
});
|
|
@@ -2528,27 +2695,23 @@ export const GetFileBlameSchema = z
|
|
|
2528
2695
|
.object({
|
|
2529
2696
|
project_id: z.coerce.string().describe("Project ID or complete URL-encoded path to project"),
|
|
2530
2697
|
file_path: z.string().describe("The full path of the file to blame, relative to repo root"),
|
|
2531
|
-
ref: z
|
|
2532
|
-
|
|
2533
|
-
.
|
|
2534
|
-
range_start: z
|
|
2535
|
-
.coerce.number()
|
|
2698
|
+
ref: z.string().describe("The name of branch, tag or commit (required by GitLab blame API)"),
|
|
2699
|
+
range_start: z.coerce
|
|
2700
|
+
.number()
|
|
2536
2701
|
.int()
|
|
2537
2702
|
.optional()
|
|
2538
2703
|
.describe("First line of the blame range (inclusive, 1-based). Both range[start] and range[end] must be set together."),
|
|
2539
|
-
range_end: z
|
|
2540
|
-
.
|
|
2704
|
+
range_end: z.coerce
|
|
2705
|
+
.number()
|
|
2541
2706
|
.int()
|
|
2542
2707
|
.optional()
|
|
2543
2708
|
.describe("Last line of the blame range (inclusive, 1-based). Both range[start] and range[end] must be set together."),
|
|
2544
2709
|
})
|
|
2545
|
-
.refine(
|
|
2710
|
+
.refine(v => (v.range_start === undefined) === (v.range_end === undefined), {
|
|
2546
2711
|
message: "range_start and range_end must be provided together (both or neither). Passing only one silently returned full-file blame on GitLab side.",
|
|
2547
2712
|
path: ["range_end"],
|
|
2548
2713
|
})
|
|
2549
|
-
.refine(
|
|
2550
|
-
v.range_end === undefined ||
|
|
2551
|
-
v.range_start <= v.range_end, {
|
|
2714
|
+
.refine(v => v.range_start === undefined || v.range_end === undefined || v.range_start <= v.range_end, {
|
|
2552
2715
|
message: "range_start must be less than or equal to range_end.",
|
|
2553
2716
|
path: ["range_start"],
|
|
2554
2717
|
});
|
|
@@ -2576,10 +2739,7 @@ export const ListCommitStatusesSchema = z
|
|
|
2576
2739
|
stage: z.string().optional().describe("Filter statuses by build stage"),
|
|
2577
2740
|
name: z.string().optional().describe("Filter statuses by status name or context"),
|
|
2578
2741
|
pipeline_id: z.coerce.number().optional().describe("Filter statuses by pipeline ID"),
|
|
2579
|
-
order_by: z
|
|
2580
|
-
.enum(["id", "pipeline_id"])
|
|
2581
|
-
.optional()
|
|
2582
|
-
.describe("Field to order statuses by"),
|
|
2742
|
+
order_by: z.enum(["id", "pipeline_id"]).optional().describe("Field to order statuses by"),
|
|
2583
2743
|
sort: z.enum(["asc", "desc"]).optional().describe("Sort direction"),
|
|
2584
2744
|
all: coerceBooleanString.optional().describe("Return all statuses, not only latest ones"),
|
|
2585
2745
|
})
|
|
@@ -2611,7 +2771,7 @@ export const MyIssuesSchema = z.object({
|
|
|
2611
2771
|
project_id: z
|
|
2612
2772
|
.string()
|
|
2613
2773
|
.optional()
|
|
2614
|
-
.describe("Project ID or URL-encoded path (optional
|
|
2774
|
+
.describe("Project ID or URL-encoded path (optional to search across all accessible projects)"),
|
|
2615
2775
|
state: z
|
|
2616
2776
|
.enum(["opened", "closed", "all"])
|
|
2617
2777
|
.optional()
|
|
@@ -2635,7 +2795,10 @@ export const MyIssuesSchema = z.object({
|
|
|
2635
2795
|
.string()
|
|
2636
2796
|
.optional()
|
|
2637
2797
|
.describe("Return issues updated before the given time (ISO 8601)"),
|
|
2638
|
-
per_page: z.coerce
|
|
2798
|
+
per_page: z.coerce
|
|
2799
|
+
.number()
|
|
2800
|
+
.optional()
|
|
2801
|
+
.describe("Number of items per page (default: 20, max: 100)"),
|
|
2639
2802
|
page: z.coerce.number().optional().describe("Page number for pagination (default: 1)"),
|
|
2640
2803
|
});
|
|
2641
2804
|
// Schema for listing project members
|
|
@@ -2644,11 +2807,14 @@ export const ListProjectMembersSchema = z.object({
|
|
|
2644
2807
|
query: z.string().optional().describe("Search for members by name or username"),
|
|
2645
2808
|
user_ids: z.array(z.coerce.number()).optional().describe("Filter by user IDs"),
|
|
2646
2809
|
skip_users: z.array(z.coerce.number()).optional().describe("User IDs to exclude"),
|
|
2647
|
-
include_inheritance: z
|
|
2648
|
-
.
|
|
2810
|
+
include_inheritance: z.coerce
|
|
2811
|
+
.boolean()
|
|
2649
2812
|
.optional()
|
|
2650
2813
|
.describe("Include inherited members. Defaults to false."),
|
|
2651
|
-
per_page: z.coerce
|
|
2814
|
+
per_page: z.coerce
|
|
2815
|
+
.number()
|
|
2816
|
+
.optional()
|
|
2817
|
+
.describe("Number of items per page (default: 20, max: 100)"),
|
|
2652
2818
|
page: z.coerce.number().optional().describe("Page number for pagination (default: 1)"),
|
|
2653
2819
|
});
|
|
2654
2820
|
// Schema for GitLab project member
|
|
@@ -2667,7 +2833,7 @@ export const GitLabProjectMemberSchema = z.object({
|
|
|
2667
2833
|
});
|
|
2668
2834
|
// Markdown upload schemas
|
|
2669
2835
|
export const GitLabMarkdownUploadSchema = z.object({
|
|
2670
|
-
id: z.preprocess(
|
|
2836
|
+
id: z.preprocess(val => (val == null ? undefined : val), z.coerce.number().optional()),
|
|
2671
2837
|
alt: z.string(),
|
|
2672
2838
|
url: z.string(),
|
|
2673
2839
|
full_path: z.string(),
|
|
@@ -2725,12 +2891,12 @@ export const ListGroupIterationsSchema = z
|
|
|
2725
2891
|
.array(z.enum(["title", "cadence_title"]))
|
|
2726
2892
|
.optional()
|
|
2727
2893
|
.describe("Fields in which fuzzy search should be performed with the query given in the argument search. The available options are title and cadence_title. Default is [title]."),
|
|
2728
|
-
include_ancestors: z
|
|
2729
|
-
.
|
|
2894
|
+
include_ancestors: z.coerce
|
|
2895
|
+
.boolean()
|
|
2730
2896
|
.optional()
|
|
2731
2897
|
.describe("Include iterations for group and its ancestors. Defaults to true."),
|
|
2732
|
-
include_descendants: z
|
|
2733
|
-
.
|
|
2898
|
+
include_descendants: z.coerce
|
|
2899
|
+
.boolean()
|
|
2734
2900
|
.optional()
|
|
2735
2901
|
.describe("Include iterations for group and its descendants. Defaults to false."),
|
|
2736
2902
|
updated_before: z
|
|
@@ -2928,8 +3094,8 @@ export const ListReleasesSchema = z
|
|
|
2928
3094
|
.enum(["desc", "asc"])
|
|
2929
3095
|
.optional()
|
|
2930
3096
|
.describe("The direction of the order. Either desc (default) for descending order or asc for ascending order."),
|
|
2931
|
-
include_html_description: z
|
|
2932
|
-
.
|
|
3097
|
+
include_html_description: z.coerce
|
|
3098
|
+
.boolean()
|
|
2933
3099
|
.optional()
|
|
2934
3100
|
.describe("If true, a response includes HTML rendered Markdown of the release description."),
|
|
2935
3101
|
})
|
|
@@ -2937,8 +3103,8 @@ export const ListReleasesSchema = z
|
|
|
2937
3103
|
export const GetReleaseSchema = z.object({
|
|
2938
3104
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
2939
3105
|
tag_name: z.string().describe("The Git tag the release is associated with"),
|
|
2940
|
-
include_html_description: z
|
|
2941
|
-
.
|
|
3106
|
+
include_html_description: z.coerce
|
|
3107
|
+
.boolean()
|
|
2942
3108
|
.optional()
|
|
2943
3109
|
.describe("If true, a response includes HTML rendered Markdown of the release description."),
|
|
2944
3110
|
});
|
|
@@ -3020,10 +3186,7 @@ export const ListJobArtifactsSchema = z.object({
|
|
|
3020
3186
|
.string()
|
|
3021
3187
|
.optional()
|
|
3022
3188
|
.describe("Directory path within the artifacts archive (defaults to root)"),
|
|
3023
|
-
recursive: z
|
|
3024
|
-
.coerce.boolean()
|
|
3025
|
-
.optional()
|
|
3026
|
-
.describe("Whether to list artifacts recursively"),
|
|
3189
|
+
recursive: z.coerce.boolean().optional().describe("Whether to list artifacts recursively"),
|
|
3027
3190
|
});
|
|
3028
3191
|
export const GitLabArtifactEntrySchema = z.object({
|
|
3029
3192
|
name: z.string(),
|
|
@@ -3047,9 +3210,7 @@ export const DownloadJobArtifactsRemoteSchema = z.object({
|
|
|
3047
3210
|
export const GetJobArtifactFileSchema = z.object({
|
|
3048
3211
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
3049
3212
|
job_id: z.coerce.string().describe("The ID of the job"),
|
|
3050
|
-
artifact_path: z
|
|
3051
|
-
.string()
|
|
3052
|
-
.describe("Path to the file within the artifacts archive"),
|
|
3213
|
+
artifact_path: z.string().describe("Path to the file within the artifacts archive"),
|
|
3053
3214
|
});
|
|
3054
3215
|
export const DownloadReleaseAssetSchema = z.object({
|
|
3055
3216
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
@@ -3138,8 +3299,23 @@ export const GitLabTagSignatureSchema = z.object({
|
|
|
3138
3299
|
});
|
|
3139
3300
|
// --- Work item schemas (GraphQL-based) ---
|
|
3140
3301
|
// Case-insensitive work item type enum (accepts "ISSUE", "Issue", "issue")
|
|
3141
|
-
const workItemTypeEnum = z
|
|
3142
|
-
|
|
3302
|
+
const workItemTypeEnum = z
|
|
3303
|
+
.string()
|
|
3304
|
+
.transform(v => v.toLowerCase())
|
|
3305
|
+
.pipe(z.enum([
|
|
3306
|
+
"issue",
|
|
3307
|
+
"task",
|
|
3308
|
+
"incident",
|
|
3309
|
+
"test_case",
|
|
3310
|
+
"epic",
|
|
3311
|
+
"key_result",
|
|
3312
|
+
"objective",
|
|
3313
|
+
"requirement",
|
|
3314
|
+
"ticket",
|
|
3315
|
+
]));
|
|
3316
|
+
const ProjectIdOrPathSchema = z.coerce
|
|
3317
|
+
.string()
|
|
3318
|
+
.describe("Project ID, URL-encoded project path, or group path (e.g. 'group/subgroup' for group-level work items)");
|
|
3143
3319
|
// Common params for work item tools
|
|
3144
3320
|
const WorkItemParamsSchema = z.object({
|
|
3145
3321
|
project_id: ProjectIdOrPathSchema,
|
|
@@ -3152,24 +3328,12 @@ export const ListWorkItemsSchema = z.object({
|
|
|
3152
3328
|
.array(workItemTypeEnum)
|
|
3153
3329
|
.optional()
|
|
3154
3330
|
.describe("Filter by work item types. If not set, returns all types."),
|
|
3155
|
-
state: z
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
.
|
|
3161
|
-
.optional()
|
|
3162
|
-
.describe("Search in title and description"),
|
|
3163
|
-
assignee_usernames: z
|
|
3164
|
-
.array(z.string())
|
|
3165
|
-
.optional()
|
|
3166
|
-
.describe("Filter by assignee usernames"),
|
|
3167
|
-
label_names: z
|
|
3168
|
-
.array(z.string())
|
|
3169
|
-
.optional()
|
|
3170
|
-
.describe("Filter by label names"),
|
|
3171
|
-
first: z
|
|
3172
|
-
.coerce.number()
|
|
3331
|
+
state: z.enum(["opened", "closed"]).optional().describe("Filter by state"),
|
|
3332
|
+
search: z.string().optional().describe("Search in title and description"),
|
|
3333
|
+
assignee_usernames: z.array(z.string()).optional().describe("Filter by assignee usernames"),
|
|
3334
|
+
label_names: z.array(z.string()).optional().describe("Filter by label names"),
|
|
3335
|
+
first: z.coerce
|
|
3336
|
+
.number()
|
|
3173
3337
|
.optional()
|
|
3174
3338
|
.default(20)
|
|
3175
3339
|
.describe("Number of items to return (max 100). Default 20."),
|
|
@@ -3190,11 +3354,20 @@ export const CreateWorkItemSchema = z.object({
|
|
|
3190
3354
|
assignee_usernames: coerceStringArray.optional().describe("Array of usernames to assign"),
|
|
3191
3355
|
parent_iid: z.coerce.number().optional().describe("IID of the parent work item to set hierarchy"),
|
|
3192
3356
|
weight: z.coerce.number().optional().describe("Weight of the work item"),
|
|
3193
|
-
health_status: z
|
|
3357
|
+
health_status: z
|
|
3358
|
+
.enum(["onTrack", "needsAttention", "atRisk"])
|
|
3359
|
+
.optional()
|
|
3360
|
+
.describe("Set health status"),
|
|
3194
3361
|
start_date: z.string().optional().describe("Start date in YYYY-MM-DD format"),
|
|
3195
3362
|
due_date: z.string().optional().describe("Due date in YYYY-MM-DD format"),
|
|
3196
|
-
milestone_id: z
|
|
3197
|
-
|
|
3363
|
+
milestone_id: z
|
|
3364
|
+
.string()
|
|
3365
|
+
.optional()
|
|
3366
|
+
.describe("Milestone ID (GitLab global ID format, e.g. 'gid://gitlab/Milestone/123', or numeric ID)"),
|
|
3367
|
+
iteration_id: z
|
|
3368
|
+
.string()
|
|
3369
|
+
.optional()
|
|
3370
|
+
.describe("Iteration ID (e.g. 'gid://gitlab/Iteration/123' or numeric ID). Use list_group_iterations to find available iterations."),
|
|
3198
3371
|
confidential: z.coerce.boolean().optional().describe("Set confidentiality"),
|
|
3199
3372
|
});
|
|
3200
3373
|
export const UpdateWorkItemSchema = WorkItemParamsSchema.extend({
|
|
@@ -3202,43 +3375,105 @@ export const UpdateWorkItemSchema = WorkItemParamsSchema.extend({
|
|
|
3202
3375
|
description: z.string().optional().describe("New description (Markdown supported)"),
|
|
3203
3376
|
add_labels: coerceStringArray.optional().describe("Label names to add"),
|
|
3204
3377
|
remove_labels: coerceStringArray.optional().describe("Label names to remove"),
|
|
3205
|
-
assignee_usernames: coerceStringArray
|
|
3378
|
+
assignee_usernames: coerceStringArray
|
|
3379
|
+
.optional()
|
|
3380
|
+
.describe("Set assignees by username (replaces existing)"),
|
|
3206
3381
|
state_event: z.enum(["close", "reopen"]).optional().describe("Close or reopen the work item"),
|
|
3207
3382
|
weight: z.coerce.number().optional().describe("Set weight (issues, tasks, epics only)"),
|
|
3208
|
-
status: z
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3383
|
+
status: z
|
|
3384
|
+
.string()
|
|
3385
|
+
.optional()
|
|
3386
|
+
.describe("Set status by ID. Use list_work_item_statuses to get available status IDs."),
|
|
3387
|
+
parent_iid: z.coerce
|
|
3388
|
+
.number()
|
|
3389
|
+
.optional()
|
|
3390
|
+
.describe("Set parent work item by IID. Use with parent_project_id if parent is in a different project."),
|
|
3391
|
+
parent_project_id: z.coerce
|
|
3392
|
+
.string()
|
|
3393
|
+
.optional()
|
|
3394
|
+
.describe("Project ID or path of the parent work item (defaults to same project as the work item)"),
|
|
3395
|
+
remove_parent: z.coerce
|
|
3396
|
+
.boolean()
|
|
3397
|
+
.optional()
|
|
3398
|
+
.describe("Set to true to remove the parent from hierarchy"),
|
|
3399
|
+
children_to_add: z
|
|
3400
|
+
.array(z.object({
|
|
3401
|
+
project_id: z.coerce
|
|
3402
|
+
.string()
|
|
3403
|
+
.optional()
|
|
3404
|
+
.describe("Project ID or path of the child work item. Defaults to the parent work item's project if omitted."),
|
|
3214
3405
|
iid: z.coerce.number().describe("IID of the child work item"),
|
|
3215
|
-
}))
|
|
3216
|
-
|
|
3217
|
-
|
|
3406
|
+
}))
|
|
3407
|
+
.optional()
|
|
3408
|
+
.describe("Array of children to add to this work item's hierarchy"),
|
|
3409
|
+
children_to_remove: z
|
|
3410
|
+
.array(z.object({
|
|
3411
|
+
project_id: z.coerce
|
|
3412
|
+
.string()
|
|
3413
|
+
.optional()
|
|
3414
|
+
.describe("Project ID or path of the child work item. Defaults to the parent work item's project if omitted."),
|
|
3218
3415
|
iid: z.coerce.number().describe("IID of the child work item"),
|
|
3219
|
-
}))
|
|
3220
|
-
|
|
3416
|
+
}))
|
|
3417
|
+
.optional()
|
|
3418
|
+
.describe("Array of children to remove from this work item's hierarchy"),
|
|
3419
|
+
health_status: z
|
|
3420
|
+
.enum(["onTrack", "needsAttention", "atRisk"])
|
|
3421
|
+
.optional()
|
|
3422
|
+
.describe("Set health status on issues and epics"),
|
|
3221
3423
|
start_date: z.string().optional().describe("Start date in YYYY-MM-DD format"),
|
|
3222
3424
|
due_date: z.string().optional().describe("Due date in YYYY-MM-DD format"),
|
|
3223
|
-
milestone_id: z
|
|
3224
|
-
|
|
3425
|
+
milestone_id: z
|
|
3426
|
+
.string()
|
|
3427
|
+
.optional()
|
|
3428
|
+
.describe("Milestone ID (GitLab global ID format, e.g. 'gid://gitlab/Milestone/123', or numeric ID)"),
|
|
3429
|
+
iteration_id: z
|
|
3430
|
+
.string()
|
|
3431
|
+
.optional()
|
|
3432
|
+
.describe("Iteration ID (e.g. 'gid://gitlab/Iteration/123' or numeric ID). Use list_group_iterations to find available iterations."),
|
|
3225
3433
|
confidential: z.coerce.boolean().optional().describe("Set confidentiality"),
|
|
3226
|
-
linked_items_to_add: z
|
|
3227
|
-
|
|
3434
|
+
linked_items_to_add: z
|
|
3435
|
+
.array(z.object({
|
|
3436
|
+
project_id: z.coerce
|
|
3437
|
+
.string()
|
|
3438
|
+
.optional()
|
|
3439
|
+
.describe("Project ID or path of the work item to link. Defaults to the same project if omitted."),
|
|
3228
3440
|
iid: z.coerce.number().describe("IID of the work item to link"),
|
|
3229
|
-
link_type: z
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3441
|
+
link_type: z
|
|
3442
|
+
.enum(["RELATED", "BLOCKED_BY", "BLOCKS"])
|
|
3443
|
+
.optional()
|
|
3444
|
+
.default("RELATED")
|
|
3445
|
+
.describe("Link type: RELATED, BLOCKED_BY, or BLOCKS. Defaults to RELATED."),
|
|
3446
|
+
}))
|
|
3447
|
+
.optional()
|
|
3448
|
+
.describe("Work items to link"),
|
|
3449
|
+
linked_items_to_remove: z
|
|
3450
|
+
.array(z.object({
|
|
3451
|
+
project_id: z.coerce
|
|
3452
|
+
.string()
|
|
3453
|
+
.optional()
|
|
3454
|
+
.describe("Project ID or path of the linked work item to remove. Defaults to the same project if omitted."),
|
|
3233
3455
|
iid: z.coerce.number().describe("IID of the linked work item to remove"),
|
|
3234
|
-
}))
|
|
3235
|
-
|
|
3236
|
-
|
|
3456
|
+
}))
|
|
3457
|
+
.optional()
|
|
3458
|
+
.describe("Linked work items to remove"),
|
|
3459
|
+
custom_fields: z
|
|
3460
|
+
.array(z.object({
|
|
3461
|
+
custom_field_id: z
|
|
3462
|
+
.string()
|
|
3463
|
+
.describe("Custom field ID (e.g. 'gid://gitlab/IssuablesCustomField/123' or numeric ID)"),
|
|
3237
3464
|
text_value: z.string().optional().describe("Text value (for text fields)"),
|
|
3238
3465
|
number_value: z.coerce.number().optional().describe("Number value (for number fields)"),
|
|
3239
|
-
selected_option_ids: z
|
|
3240
|
-
|
|
3241
|
-
|
|
3466
|
+
selected_option_ids: z
|
|
3467
|
+
.array(z.string())
|
|
3468
|
+
.optional()
|
|
3469
|
+
.describe("Selected option IDs (for select fields)"),
|
|
3470
|
+
date_value: z
|
|
3471
|
+
.string()
|
|
3472
|
+
.optional()
|
|
3473
|
+
.describe("Date value in YYYY-MM-DD format (for date fields)"),
|
|
3474
|
+
}))
|
|
3475
|
+
.optional()
|
|
3476
|
+
.describe("Custom field values to set"),
|
|
3242
3477
|
severity: z
|
|
3243
3478
|
.enum(["UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"])
|
|
3244
3479
|
.optional()
|
|
@@ -3263,21 +3498,40 @@ export const ListWorkItemStatusesSchema = z.object({
|
|
|
3263
3498
|
export const ListWorkItemNotesSchema = z.object({
|
|
3264
3499
|
project_id: ProjectIdOrPathSchema,
|
|
3265
3500
|
iid: z.coerce.number().describe("The internal ID of the work item"),
|
|
3266
|
-
page_size: z.coerce
|
|
3501
|
+
page_size: z.coerce
|
|
3502
|
+
.number()
|
|
3503
|
+
.optional()
|
|
3504
|
+
.default(20)
|
|
3505
|
+
.describe("Number of discussions to return (default 20)"),
|
|
3267
3506
|
after: z.string().optional().describe("Cursor for pagination"),
|
|
3268
|
-
sort: z
|
|
3507
|
+
sort: z
|
|
3508
|
+
.enum(["CREATED_ASC", "CREATED_DESC"])
|
|
3509
|
+
.optional()
|
|
3510
|
+
.default("CREATED_ASC")
|
|
3511
|
+
.describe("Sort order for discussions"),
|
|
3269
3512
|
});
|
|
3270
3513
|
export const CreateWorkItemNoteSchema = z.object({
|
|
3271
3514
|
project_id: ProjectIdOrPathSchema,
|
|
3272
3515
|
iid: z.coerce.number().describe("The internal ID of the work item"),
|
|
3273
3516
|
body: z.string().describe("Note body (Markdown supported)"),
|
|
3274
|
-
internal: z.coerce
|
|
3275
|
-
|
|
3517
|
+
internal: z.coerce
|
|
3518
|
+
.boolean()
|
|
3519
|
+
.optional()
|
|
3520
|
+
.default(false)
|
|
3521
|
+
.describe("Create as internal/confidential note (only visible to project members)"),
|
|
3522
|
+
discussion_id: z
|
|
3523
|
+
.string()
|
|
3524
|
+
.optional()
|
|
3525
|
+
.describe("Discussion ID to reply to (for threaded replies). If omitted, creates a new top-level note."),
|
|
3276
3526
|
});
|
|
3277
3527
|
export const MoveWorkItemSchema = z.object({
|
|
3278
|
-
project_id: z.coerce
|
|
3528
|
+
project_id: z.coerce
|
|
3529
|
+
.string()
|
|
3530
|
+
.describe("Project ID, URL-encoded project path, or group path of the source namespace"),
|
|
3279
3531
|
iid: z.coerce.number().describe("The internal ID of the work item to move"),
|
|
3280
|
-
target_project_id: z.coerce
|
|
3532
|
+
target_project_id: z.coerce
|
|
3533
|
+
.string()
|
|
3534
|
+
.describe("Project ID, URL-encoded project path, or group path of the target namespace"),
|
|
3281
3535
|
});
|
|
3282
3536
|
export const ListCustomFieldDefinitionsSchema = z.object({
|
|
3283
3537
|
project_id: ProjectIdOrPathSchema,
|
|
@@ -3287,9 +3541,14 @@ export const ListCustomFieldDefinitionsSchema = z.object({
|
|
|
3287
3541
|
.describe("The work item type to list custom field definitions for. Defaults to 'issue'."),
|
|
3288
3542
|
});
|
|
3289
3543
|
// --- Emoji Reaction schemas (REST: MRs and Issues) ---
|
|
3290
|
-
const emojiNameField = z
|
|
3544
|
+
const emojiNameField = z
|
|
3545
|
+
.string()
|
|
3546
|
+
.describe("Name of the emoji without colons (e.g. 'thumbsup', 'rocket', 'eyes')");
|
|
3291
3547
|
const awardIdField = z.coerce.string().describe("The ID of the emoji reaction to delete");
|
|
3292
|
-
const noteEmojiDiscussionField = z.coerce
|
|
3548
|
+
const noteEmojiDiscussionField = z.coerce
|
|
3549
|
+
.string()
|
|
3550
|
+
.optional()
|
|
3551
|
+
.describe("The ID of a discussion thread. Required for notes that are discussion replies; omit for top-level notes.");
|
|
3293
3552
|
export const CreateMergeRequestEmojiReactionSchema = ProjectParamsSchema.extend({
|
|
3294
3553
|
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
3295
3554
|
name: emojiNameField,
|
|
@@ -3344,13 +3603,17 @@ export const DeleteWorkItemEmojiReactionSchema = z.object({
|
|
|
3344
3603
|
export const CreateWorkItemNoteEmojiReactionSchema = z.object({
|
|
3345
3604
|
project_id: ProjectIdOrPathSchema,
|
|
3346
3605
|
iid: z.coerce.number().describe("The internal ID of the work item"),
|
|
3347
|
-
note_id: z
|
|
3606
|
+
note_id: z
|
|
3607
|
+
.string()
|
|
3608
|
+
.describe("The GraphQL GID of the note (e.g. 'gid://gitlab/Note/123' from list_work_item_notes)"),
|
|
3348
3609
|
name: emojiNameField,
|
|
3349
3610
|
});
|
|
3350
3611
|
export const DeleteWorkItemNoteEmojiReactionSchema = z.object({
|
|
3351
3612
|
project_id: ProjectIdOrPathSchema,
|
|
3352
3613
|
iid: z.coerce.number().describe("The internal ID of the work item"),
|
|
3353
|
-
note_id: z
|
|
3614
|
+
note_id: z
|
|
3615
|
+
.string()
|
|
3616
|
+
.describe("The GraphQL GID of the note (e.g. 'gid://gitlab/Note/123' from list_work_item_notes)"),
|
|
3354
3617
|
name: emojiNameField,
|
|
3355
3618
|
});
|
|
3356
3619
|
export const ListMergeRequestEmojiReactionsSchema = ProjectParamsSchema.extend({
|
|
@@ -3376,7 +3639,9 @@ export const ListWorkItemEmojiReactionsSchema = z.object({
|
|
|
3376
3639
|
export const ListWorkItemNoteEmojiReactionsSchema = z.object({
|
|
3377
3640
|
project_id: ProjectIdOrPathSchema,
|
|
3378
3641
|
iid: z.coerce.number().describe("The internal ID of the work item"),
|
|
3379
|
-
note_id: z
|
|
3642
|
+
note_id: z
|
|
3643
|
+
.string()
|
|
3644
|
+
.describe("The GraphQL GID of the note (e.g. 'gid://gitlab/Note/123' from list_work_item_notes)"),
|
|
3380
3645
|
});
|
|
3381
3646
|
// --- Incident Timeline Event schemas ---
|
|
3382
3647
|
export const GetTimelineEventsSchema = z.object({
|
|
@@ -3387,9 +3652,18 @@ export const CreateTimelineEventSchema = z.object({
|
|
|
3387
3652
|
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
3388
3653
|
incident_iid: z.coerce.number().describe("The internal ID (IID) of the incident"),
|
|
3389
3654
|
note: z.string().describe("Description of the timeline event (Markdown supported)"),
|
|
3390
|
-
occurred_at: z
|
|
3655
|
+
occurred_at: z
|
|
3656
|
+
.string()
|
|
3657
|
+
.describe("When the event occurred in ISO 8601 format (e.g. '2026-03-15T09:00:00.000Z')"),
|
|
3391
3658
|
tag_names: z
|
|
3392
|
-
.array(z.enum([
|
|
3659
|
+
.array(z.enum([
|
|
3660
|
+
"Start time",
|
|
3661
|
+
"End time",
|
|
3662
|
+
"Impact detected",
|
|
3663
|
+
"Response initiated",
|
|
3664
|
+
"Impact mitigated",
|
|
3665
|
+
"Cause identified",
|
|
3666
|
+
]))
|
|
3393
3667
|
.optional()
|
|
3394
3668
|
.describe("Timeline event tags to attach. Available: 'Start time', 'End time', 'Impact detected', 'Response initiated', 'Impact mitigated', 'Cause identified'."),
|
|
3395
3669
|
});
|
|
@@ -3424,16 +3698,11 @@ export const ListWebhookEventsSchema = z
|
|
|
3424
3698
|
.union([z.coerce.number(), z.string()])
|
|
3425
3699
|
.optional()
|
|
3426
3700
|
.describe("Filter by response status code (e.g. 200, 500) or category: successful, client_failure, server_failure"),
|
|
3427
|
-
summary: z
|
|
3428
|
-
.
|
|
3701
|
+
summary: z.coerce
|
|
3702
|
+
.boolean()
|
|
3429
3703
|
.optional()
|
|
3430
3704
|
.describe("If true, return only summary fields (id, url, trigger, response_status, execution_duration) without full request/response payloads. Recommended for overview queries to avoid huge responses."),
|
|
3431
|
-
per_page: z
|
|
3432
|
-
.number()
|
|
3433
|
-
.max(20)
|
|
3434
|
-
.optional()
|
|
3435
|
-
.default(20)
|
|
3436
|
-
.describe("Number of events per page"),
|
|
3705
|
+
per_page: z.number().max(20).optional().default(20).describe("Number of events per page"),
|
|
3437
3706
|
page: z.coerce.number().optional().describe("Page number for pagination"),
|
|
3438
3707
|
})
|
|
3439
3708
|
.refine(data => (data.project_id || data.group_id) && !(data.project_id && data.group_id), {
|
|
@@ -3484,7 +3753,10 @@ const ciVariableFields = {
|
|
|
3484
3753
|
.optional()
|
|
3485
3754
|
.describe("Whether the variable is only available on protected branches/tags"),
|
|
3486
3755
|
masked: z.boolean().optional().describe("Whether the variable value is masked in job logs"),
|
|
3487
|
-
raw: z
|
|
3756
|
+
raw: z
|
|
3757
|
+
.boolean()
|
|
3758
|
+
.optional()
|
|
3759
|
+
.describe("Whether the variable is not expanded (treated as raw string)"),
|
|
3488
3760
|
environment_scope: z
|
|
3489
3761
|
.string()
|
|
3490
3762
|
.optional()
|
|
@@ -3610,13 +3882,19 @@ export const GetDependencyProxySettingsSchema = z.object({
|
|
|
3610
3882
|
export const UpdateDependencyProxySettingsSchema = z.object({
|
|
3611
3883
|
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
|
|
3612
3884
|
enabled: z.boolean().optional().describe("Enable or disable the dependency proxy"),
|
|
3613
|
-
identity: z
|
|
3885
|
+
identity: z
|
|
3886
|
+
.string()
|
|
3887
|
+
.optional()
|
|
3888
|
+
.describe("Proxy username for authenticated Docker Hub pulls (Premium/Ultimate)"),
|
|
3614
3889
|
secret: z.string().optional().describe("Proxy password / access token for authenticated pulls"),
|
|
3615
3890
|
});
|
|
3616
3891
|
export const ListDependencyProxyBlobsSchema = z.object({
|
|
3617
3892
|
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
|
|
3618
3893
|
first: z.number().int().optional().describe("Number of blobs to return (default: 20)"),
|
|
3619
|
-
after: z
|
|
3894
|
+
after: z
|
|
3895
|
+
.string()
|
|
3896
|
+
.optional()
|
|
3897
|
+
.describe("Cursor for pagination (from previous response pageInfo.endCursor)"),
|
|
3620
3898
|
});
|
|
3621
3899
|
export const PurgeDependencyProxyCacheSchema = z.object({
|
|
3622
3900
|
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
|