@gitlab/opencode-gitlab-plugin 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [1.8.0](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/compare/v1.7.1...v1.8.0) (2026-02-25)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ✨ Features
|
|
9
|
+
|
|
10
|
+
* **users:** add user lookup and status tools ([992cb91](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/commit/992cb91565d94f9b69e764262c9f792fe05c1b12))
|
|
11
|
+
|
|
12
|
+
## [1.7.1](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/compare/v1.7.0...v1.7.1) (2026-02-24)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### 📚 Documentation
|
|
16
|
+
|
|
17
|
+
* **discussions:** improve gitlab_create_discussion description for reply use case ([a0d2296](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/commit/a0d2296cf2aa42258c7ca1749df86810c852174b))
|
|
18
|
+
|
|
5
19
|
## [1.7.0](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/compare/v1.6.2...v1.7.0) (2026-02-24)
|
|
6
20
|
|
|
7
21
|
|
|
Binary file
|
package/dist/index.js
CHANGED
|
@@ -1159,6 +1159,29 @@ var UsersClient = class extends GitLabApiClient {
|
|
|
1159
1159
|
async getCurrentUser() {
|
|
1160
1160
|
return this.fetch("GET", "/user");
|
|
1161
1161
|
}
|
|
1162
|
+
/**
|
|
1163
|
+
* Get a user by ID
|
|
1164
|
+
* @param userId - The user ID
|
|
1165
|
+
*/
|
|
1166
|
+
async getUser(userId) {
|
|
1167
|
+
return this.fetch("GET", `/users/${userId}`);
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Find users by username
|
|
1171
|
+
* @param username - The username to search for (exact match)
|
|
1172
|
+
*/
|
|
1173
|
+
async getUserByUsername(username) {
|
|
1174
|
+
const params = new URLSearchParams();
|
|
1175
|
+
params.set("username", username);
|
|
1176
|
+
return this.fetch("GET", `/users?${params}`);
|
|
1177
|
+
}
|
|
1178
|
+
/**
|
|
1179
|
+
* Get a user's status
|
|
1180
|
+
* @param userId - The user ID
|
|
1181
|
+
*/
|
|
1182
|
+
async getUserStatus(userId) {
|
|
1183
|
+
return this.fetch("GET", `/users/${userId}/status`);
|
|
1184
|
+
}
|
|
1162
1185
|
};
|
|
1163
1186
|
|
|
1164
1187
|
// src/client/wikis.ts
|
|
@@ -3144,8 +3167,12 @@ var projectTools = {
|
|
|
3144
3167
|
}
|
|
3145
3168
|
})
|
|
3146
3169
|
};
|
|
3170
|
+
|
|
3171
|
+
// src/tools/users.ts
|
|
3172
|
+
import { tool as tool8 } from "@opencode-ai/plugin";
|
|
3173
|
+
var z8 = tool8.schema;
|
|
3147
3174
|
var userTools = {
|
|
3148
|
-
gitlab_get_current_user:
|
|
3175
|
+
gitlab_get_current_user: tool8({
|
|
3149
3176
|
description: `Get current user information.
|
|
3150
3177
|
Returns details about the authenticated user including username, email, and permissions.`,
|
|
3151
3178
|
args: {},
|
|
@@ -3154,21 +3181,73 @@ Returns details about the authenticated user including username, email, and perm
|
|
|
3154
3181
|
const user = await client.getCurrentUser();
|
|
3155
3182
|
return JSON.stringify(user, null, 2);
|
|
3156
3183
|
}
|
|
3184
|
+
}),
|
|
3185
|
+
gitlab_get_user: tool8({
|
|
3186
|
+
description: `Get a user by their ID.
|
|
3187
|
+
Returns user details including username, name, state, and profile information.`,
|
|
3188
|
+
args: {
|
|
3189
|
+
user_id: z8.number().describe("The user ID")
|
|
3190
|
+
},
|
|
3191
|
+
execute: async (args, _ctx) => {
|
|
3192
|
+
const client = getGitLabClient();
|
|
3193
|
+
const user = await client.getUser(args.user_id);
|
|
3194
|
+
return JSON.stringify(user, null, 2);
|
|
3195
|
+
}
|
|
3196
|
+
}),
|
|
3197
|
+
gitlab_get_user_by_username: tool8({
|
|
3198
|
+
description: `Find a user by their username.
|
|
3199
|
+
Returns user details including ID, name, state, and profile information.
|
|
3200
|
+
Useful for looking up a user's ID when you only know their username.`,
|
|
3201
|
+
args: {
|
|
3202
|
+
username: z8.string().describe("The username to look up (without @ prefix)")
|
|
3203
|
+
},
|
|
3204
|
+
execute: async (args, _ctx) => {
|
|
3205
|
+
const client = getGitLabClient();
|
|
3206
|
+
const username = args.username.replace(/^@/, "");
|
|
3207
|
+
const users = await client.getUserByUsername(username);
|
|
3208
|
+
if (users.length === 0) {
|
|
3209
|
+
return JSON.stringify({ error: `No user found with username: ${username}` });
|
|
3210
|
+
}
|
|
3211
|
+
if (users.length > 1) {
|
|
3212
|
+
return JSON.stringify(
|
|
3213
|
+
{
|
|
3214
|
+
warning: `Multiple users found for username: ${username}`,
|
|
3215
|
+
users
|
|
3216
|
+
},
|
|
3217
|
+
null,
|
|
3218
|
+
2
|
|
3219
|
+
);
|
|
3220
|
+
}
|
|
3221
|
+
return JSON.stringify(users[0], null, 2);
|
|
3222
|
+
}
|
|
3223
|
+
}),
|
|
3224
|
+
gitlab_get_user_status: tool8({
|
|
3225
|
+
description: `Get a user's status including availability.
|
|
3226
|
+
Returns the user's status emoji, message, and availability (e.g., "busy").
|
|
3227
|
+
Useful for checking if someone is available before requesting a review.`,
|
|
3228
|
+
args: {
|
|
3229
|
+
user_id: z8.number().describe("The user ID")
|
|
3230
|
+
},
|
|
3231
|
+
execute: async (args, _ctx) => {
|
|
3232
|
+
const client = getGitLabClient();
|
|
3233
|
+
const status = await client.getUserStatus(args.user_id);
|
|
3234
|
+
return JSON.stringify(status, null, 2);
|
|
3235
|
+
}
|
|
3157
3236
|
})
|
|
3158
3237
|
};
|
|
3159
3238
|
|
|
3160
3239
|
// src/tools/security.ts
|
|
3161
|
-
import { tool as
|
|
3162
|
-
var
|
|
3240
|
+
import { tool as tool9 } from "@opencode-ai/plugin";
|
|
3241
|
+
var z9 = tool9.schema;
|
|
3163
3242
|
var securityTools = {
|
|
3164
|
-
gitlab_list_vulnerabilities:
|
|
3243
|
+
gitlab_list_vulnerabilities: tool9({
|
|
3165
3244
|
description: `List persisted vulnerabilities for a project.
|
|
3166
3245
|
Returns security vulnerabilities detected in the project.`,
|
|
3167
3246
|
args: {
|
|
3168
|
-
project_id:
|
|
3169
|
-
state:
|
|
3170
|
-
severity:
|
|
3171
|
-
report_type:
|
|
3247
|
+
project_id: z9.string().describe("The project ID or URL-encoded path"),
|
|
3248
|
+
state: z9.enum(["detected", "confirmed", "dismissed", "resolved"]).optional().describe("Filter by vulnerability state"),
|
|
3249
|
+
severity: z9.enum(["undefined", "info", "unknown", "low", "medium", "high", "critical"]).optional().describe("Filter by severity level"),
|
|
3250
|
+
report_type: z9.enum([
|
|
3172
3251
|
"sast",
|
|
3173
3252
|
"dast",
|
|
3174
3253
|
"dependency_scanning",
|
|
@@ -3177,7 +3256,7 @@ Returns security vulnerabilities detected in the project.`,
|
|
|
3177
3256
|
"coverage_fuzzing",
|
|
3178
3257
|
"api_fuzzing"
|
|
3179
3258
|
]).optional().describe("Filter by report type"),
|
|
3180
|
-
limit:
|
|
3259
|
+
limit: z9.number().optional().describe("Maximum number of results (default: 20)")
|
|
3181
3260
|
},
|
|
3182
3261
|
execute: async (args, _ctx) => {
|
|
3183
3262
|
const client = getGitLabClient();
|
|
@@ -3190,12 +3269,12 @@ Returns security vulnerabilities detected in the project.`,
|
|
|
3190
3269
|
return JSON.stringify(vulnerabilities, null, 2);
|
|
3191
3270
|
}
|
|
3192
3271
|
}),
|
|
3193
|
-
gitlab_get_vulnerability_details:
|
|
3272
|
+
gitlab_get_vulnerability_details: tool9({
|
|
3194
3273
|
description: `Get details for a specific vulnerability.
|
|
3195
3274
|
Returns full information about a security vulnerability including description, location, and remediation.`,
|
|
3196
3275
|
args: {
|
|
3197
|
-
project_id:
|
|
3198
|
-
vulnerability_id:
|
|
3276
|
+
project_id: z9.string().describe("The project ID or URL-encoded path"),
|
|
3277
|
+
vulnerability_id: z9.number().describe("The ID of the vulnerability")
|
|
3199
3278
|
},
|
|
3200
3279
|
execute: async (args, _ctx) => {
|
|
3201
3280
|
const client = getGitLabClient();
|
|
@@ -3206,13 +3285,13 @@ Returns full information about a security vulnerability including description, l
|
|
|
3206
3285
|
return JSON.stringify(vulnerability, null, 2);
|
|
3207
3286
|
}
|
|
3208
3287
|
}),
|
|
3209
|
-
gitlab_create_vulnerability_issue:
|
|
3288
|
+
gitlab_create_vulnerability_issue: tool9({
|
|
3210
3289
|
description: `Create a new issue linked to one or more security vulnerabilities.
|
|
3211
3290
|
This creates an issue in the project and automatically links it to the specified vulnerabilities.
|
|
3212
3291
|
Requires Developer role or higher.`,
|
|
3213
3292
|
args: {
|
|
3214
|
-
project_path:
|
|
3215
|
-
vulnerability_ids:
|
|
3293
|
+
project_path: z9.string().describe('Full path of the project (e.g., "group/project" or "group/subgroup/project")'),
|
|
3294
|
+
vulnerability_ids: z9.array(z9.string()).describe(
|
|
3216
3295
|
'Array of vulnerability IDs in format "gid://gitlab/Vulnerability/{id}". Get these from gitlab_list_vulnerabilities.'
|
|
3217
3296
|
)
|
|
3218
3297
|
},
|
|
@@ -3225,22 +3304,22 @@ Requires Developer role or higher.`,
|
|
|
3225
3304
|
return JSON.stringify(issue, null, 2);
|
|
3226
3305
|
}
|
|
3227
3306
|
}),
|
|
3228
|
-
gitlab_dismiss_vulnerability:
|
|
3307
|
+
gitlab_dismiss_vulnerability: tool9({
|
|
3229
3308
|
description: `Dismiss a security vulnerability with a reason.
|
|
3230
3309
|
Use this when a vulnerability is not applicable, is a false positive, or has been mitigated.
|
|
3231
3310
|
Requires Developer role or higher.`,
|
|
3232
3311
|
args: {
|
|
3233
|
-
vulnerability_id:
|
|
3312
|
+
vulnerability_id: z9.string().describe(
|
|
3234
3313
|
'Vulnerability ID in format "gid://gitlab/Vulnerability/{id}". Get this from gitlab_list_vulnerabilities.'
|
|
3235
3314
|
),
|
|
3236
|
-
reason:
|
|
3315
|
+
reason: z9.enum([
|
|
3237
3316
|
"ACCEPTABLE_RISK",
|
|
3238
3317
|
"FALSE_POSITIVE",
|
|
3239
3318
|
"MITIGATING_CONTROL",
|
|
3240
3319
|
"USED_IN_TESTS",
|
|
3241
3320
|
"NOT_APPLICABLE"
|
|
3242
3321
|
]).describe("Reason for dismissing the vulnerability"),
|
|
3243
|
-
comment:
|
|
3322
|
+
comment: z9.string().optional().describe("Optional comment explaining the dismissal")
|
|
3244
3323
|
},
|
|
3245
3324
|
execute: async (args, _ctx) => {
|
|
3246
3325
|
const client = getGitLabClient();
|
|
@@ -3252,15 +3331,15 @@ Requires Developer role or higher.`,
|
|
|
3252
3331
|
return JSON.stringify(vulnerability, null, 2);
|
|
3253
3332
|
}
|
|
3254
3333
|
}),
|
|
3255
|
-
gitlab_confirm_vulnerability:
|
|
3334
|
+
gitlab_confirm_vulnerability: tool9({
|
|
3256
3335
|
description: `Confirm a security vulnerability.
|
|
3257
3336
|
Use this to acknowledge that a vulnerability is valid and needs attention.
|
|
3258
3337
|
Requires Developer role or higher.`,
|
|
3259
3338
|
args: {
|
|
3260
|
-
vulnerability_id:
|
|
3339
|
+
vulnerability_id: z9.string().describe(
|
|
3261
3340
|
'Vulnerability ID in format "gid://gitlab/Vulnerability/{id}". Get this from gitlab_list_vulnerabilities.'
|
|
3262
3341
|
),
|
|
3263
|
-
comment:
|
|
3342
|
+
comment: z9.string().optional().describe("Optional comment about the confirmation")
|
|
3264
3343
|
},
|
|
3265
3344
|
execute: async (args, _ctx) => {
|
|
3266
3345
|
const client = getGitLabClient();
|
|
@@ -3268,15 +3347,15 @@ Requires Developer role or higher.`,
|
|
|
3268
3347
|
return JSON.stringify(vulnerability, null, 2);
|
|
3269
3348
|
}
|
|
3270
3349
|
}),
|
|
3271
|
-
gitlab_revert_vulnerability_to_detected:
|
|
3350
|
+
gitlab_revert_vulnerability_to_detected: tool9({
|
|
3272
3351
|
description: `Revert a vulnerability back to detected state.
|
|
3273
3352
|
Use this to undo a previous confirmation or dismissal.
|
|
3274
3353
|
Requires Developer role or higher.`,
|
|
3275
3354
|
args: {
|
|
3276
|
-
vulnerability_id:
|
|
3355
|
+
vulnerability_id: z9.string().describe(
|
|
3277
3356
|
'Vulnerability ID in format "gid://gitlab/Vulnerability/{id}". Get this from gitlab_list_vulnerabilities.'
|
|
3278
3357
|
),
|
|
3279
|
-
comment:
|
|
3358
|
+
comment: z9.string().optional().describe("Optional comment about reverting the state")
|
|
3280
3359
|
},
|
|
3281
3360
|
execute: async (args, _ctx) => {
|
|
3282
3361
|
const client = getGitLabClient();
|
|
@@ -3284,16 +3363,16 @@ Requires Developer role or higher.`,
|
|
|
3284
3363
|
return JSON.stringify(vulnerability, null, 2);
|
|
3285
3364
|
}
|
|
3286
3365
|
}),
|
|
3287
|
-
gitlab_update_vulnerability_severity:
|
|
3366
|
+
gitlab_update_vulnerability_severity: tool9({
|
|
3288
3367
|
description: `Update the severity level of one or more vulnerabilities.
|
|
3289
3368
|
Use this to adjust the severity rating based on your assessment.
|
|
3290
3369
|
Requires Developer role or higher.`,
|
|
3291
3370
|
args: {
|
|
3292
|
-
vulnerability_ids:
|
|
3371
|
+
vulnerability_ids: z9.array(z9.string()).describe(
|
|
3293
3372
|
'Array of vulnerability IDs in format "gid://gitlab/Vulnerability/{id}". Get these from gitlab_list_vulnerabilities.'
|
|
3294
3373
|
),
|
|
3295
|
-
severity:
|
|
3296
|
-
comment:
|
|
3374
|
+
severity: z9.enum(["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO", "UNKNOWN"]).describe("New severity level for the vulnerabilities"),
|
|
3375
|
+
comment: z9.string().describe("Comment explaining the severity change (required)")
|
|
3297
3376
|
},
|
|
3298
3377
|
execute: async (args, _ctx) => {
|
|
3299
3378
|
const client = getGitLabClient();
|
|
@@ -3305,15 +3384,15 @@ Requires Developer role or higher.`,
|
|
|
3305
3384
|
return JSON.stringify(vulnerabilities, null, 2);
|
|
3306
3385
|
}
|
|
3307
3386
|
}),
|
|
3308
|
-
gitlab_link_vulnerability_to_issue:
|
|
3387
|
+
gitlab_link_vulnerability_to_issue: tool9({
|
|
3309
3388
|
description: `Link an existing issue to one or more vulnerabilities.
|
|
3310
3389
|
Use this to associate vulnerabilities with an existing issue for tracking.
|
|
3311
3390
|
Requires Developer role or higher.`,
|
|
3312
3391
|
args: {
|
|
3313
|
-
issue_id:
|
|
3392
|
+
issue_id: z9.string().describe(
|
|
3314
3393
|
'Issue ID in format "gid://gitlab/Issue/{id}". You can construct this from the issue IID.'
|
|
3315
3394
|
),
|
|
3316
|
-
vulnerability_ids:
|
|
3395
|
+
vulnerability_ids: z9.array(z9.string()).describe(
|
|
3317
3396
|
'Array of vulnerability IDs in format "gid://gitlab/Vulnerability/{id}". Get these from gitlab_list_vulnerabilities.'
|
|
3318
3397
|
)
|
|
3319
3398
|
},
|
|
@@ -3326,10 +3405,10 @@ Requires Developer role or higher.`,
|
|
|
3326
3405
|
};
|
|
3327
3406
|
|
|
3328
3407
|
// src/tools/todos.ts
|
|
3329
|
-
import { tool as
|
|
3330
|
-
var
|
|
3408
|
+
import { tool as tool10 } from "@opencode-ai/plugin";
|
|
3409
|
+
var z10 = tool10.schema;
|
|
3331
3410
|
var todoTools = {
|
|
3332
|
-
gitlab_list_todos:
|
|
3411
|
+
gitlab_list_todos: tool10({
|
|
3333
3412
|
description: `List TODO items for the current user using GraphQL API with pagination support.
|
|
3334
3413
|
Returns a list of pending or done TODO items assigned to the authenticated user.
|
|
3335
3414
|
TODOs are created when you are assigned to an issue/MR, mentioned in a comment, or when someone requests your review.
|
|
@@ -3338,7 +3417,7 @@ The response includes pagination information (pageInfo) with cursors for fetchin
|
|
|
3338
3417
|
Use 'after' with the 'endCursor' from pageInfo to get the next page.
|
|
3339
3418
|
Use 'before' with the 'startCursor' from pageInfo to get the previous page.`,
|
|
3340
3419
|
args: {
|
|
3341
|
-
action:
|
|
3420
|
+
action: z10.enum([
|
|
3342
3421
|
"assigned",
|
|
3343
3422
|
"mentioned",
|
|
3344
3423
|
"build_failed",
|
|
@@ -3349,15 +3428,15 @@ Use 'before' with the 'startCursor' from pageInfo to get the previous page.`,
|
|
|
3349
3428
|
"merge_train_removed",
|
|
3350
3429
|
"review_requested"
|
|
3351
3430
|
]).optional().describe("Filter by action type"),
|
|
3352
|
-
author_id:
|
|
3353
|
-
project_id:
|
|
3354
|
-
group_id:
|
|
3355
|
-
state:
|
|
3356
|
-
type:
|
|
3357
|
-
first:
|
|
3358
|
-
after:
|
|
3359
|
-
last:
|
|
3360
|
-
before:
|
|
3431
|
+
author_id: z10.number().optional().describe("Filter by author ID"),
|
|
3432
|
+
project_id: z10.string().optional().describe("Filter by project ID or path"),
|
|
3433
|
+
group_id: z10.string().optional().describe("Filter by group ID"),
|
|
3434
|
+
state: z10.enum(["pending", "done"]).optional().describe("Filter by state (default: pending)"),
|
|
3435
|
+
type: z10.enum(["Issue", "MergeRequest", "DesignManagement::Design", "Alert", "Epic", "Commit"]).optional().describe("Filter by target type"),
|
|
3436
|
+
first: z10.number().optional().describe("Number of items to return from the beginning (default: 20, max: 100)"),
|
|
3437
|
+
after: z10.string().optional().describe("Cursor for forward pagination - use endCursor from previous response"),
|
|
3438
|
+
last: z10.number().optional().describe("Number of items to return from the end (for backward pagination)"),
|
|
3439
|
+
before: z10.string().optional().describe("Cursor for backward pagination - use startCursor from previous response")
|
|
3361
3440
|
},
|
|
3362
3441
|
execute: async (args, _ctx) => {
|
|
3363
3442
|
const client = getGitLabClient();
|
|
@@ -3376,7 +3455,7 @@ Use 'before' with the 'startCursor' from pageInfo to get the previous page.`,
|
|
|
3376
3455
|
return JSON.stringify(result, null, 2);
|
|
3377
3456
|
}
|
|
3378
3457
|
}),
|
|
3379
|
-
gitlab_mark_todo_done:
|
|
3458
|
+
gitlab_mark_todo_done: tool10({
|
|
3380
3459
|
description: `Mark TODO items as done.
|
|
3381
3460
|
|
|
3382
3461
|
Actions:
|
|
@@ -3387,8 +3466,8 @@ Examples:
|
|
|
3387
3466
|
- Mark one: action="one", todo_id=123
|
|
3388
3467
|
- Mark all: action="all"`,
|
|
3389
3468
|
args: {
|
|
3390
|
-
action:
|
|
3391
|
-
todo_id:
|
|
3469
|
+
action: z10.enum(["one", "all"]).describe('Action to perform: "one" for single TODO, "all" for all TODOs'),
|
|
3470
|
+
todo_id: z10.number().optional().describe('The ID of the TODO item (required for action="one")')
|
|
3392
3471
|
},
|
|
3393
3472
|
execute: async (args, _ctx) => {
|
|
3394
3473
|
const client = getGitLabClient();
|
|
@@ -3424,7 +3503,7 @@ Examples:
|
|
|
3424
3503
|
}
|
|
3425
3504
|
}
|
|
3426
3505
|
}),
|
|
3427
|
-
gitlab_get_todo_count:
|
|
3506
|
+
gitlab_get_todo_count: tool10({
|
|
3428
3507
|
description: `Get the count of pending TODO items.
|
|
3429
3508
|
Returns the total number of pending TODOs for the current user.`,
|
|
3430
3509
|
args: {},
|
|
@@ -3437,15 +3516,15 @@ Returns the total number of pending TODOs for the current user.`,
|
|
|
3437
3516
|
};
|
|
3438
3517
|
|
|
3439
3518
|
// src/tools/wikis.ts
|
|
3440
|
-
import { tool as
|
|
3441
|
-
var
|
|
3519
|
+
import { tool as tool11 } from "@opencode-ai/plugin";
|
|
3520
|
+
var z11 = tool11.schema;
|
|
3442
3521
|
var wikiTools = {
|
|
3443
|
-
gitlab_get_wiki_page:
|
|
3522
|
+
gitlab_get_wiki_page: tool11({
|
|
3444
3523
|
description: `Get a wiki page with its content.
|
|
3445
3524
|
Returns the wiki page content and metadata.`,
|
|
3446
3525
|
args: {
|
|
3447
|
-
project_id:
|
|
3448
|
-
slug:
|
|
3526
|
+
project_id: z11.string().describe("The project ID or URL-encoded path"),
|
|
3527
|
+
slug: z11.string().describe("The slug (URL-friendly name) of the wiki page")
|
|
3449
3528
|
},
|
|
3450
3529
|
execute: async (args, _ctx) => {
|
|
3451
3530
|
const client = getGitLabClient();
|
|
@@ -3456,15 +3535,15 @@ Returns the wiki page content and metadata.`,
|
|
|
3456
3535
|
};
|
|
3457
3536
|
|
|
3458
3537
|
// src/tools/work-items.ts
|
|
3459
|
-
import { tool as
|
|
3460
|
-
var
|
|
3538
|
+
import { tool as tool12 } from "@opencode-ai/plugin";
|
|
3539
|
+
var z12 = tool12.schema;
|
|
3461
3540
|
var workItemTools = {
|
|
3462
|
-
gitlab_get_work_item:
|
|
3541
|
+
gitlab_get_work_item: tool12({
|
|
3463
3542
|
description: `Get a single work item (issue, epic, task, etc.).
|
|
3464
3543
|
Work items are the new unified model for issues, epics, tasks, and other work tracking items in GitLab.`,
|
|
3465
3544
|
args: {
|
|
3466
|
-
project_id:
|
|
3467
|
-
work_item_id:
|
|
3545
|
+
project_id: z12.string().describe("The project ID or URL-encoded path"),
|
|
3546
|
+
work_item_id: z12.number().describe("The ID of the work item")
|
|
3468
3547
|
},
|
|
3469
3548
|
execute: async (args, _ctx) => {
|
|
3470
3549
|
const client = getGitLabClient();
|
|
@@ -3472,17 +3551,17 @@ Work items are the new unified model for issues, epics, tasks, and other work tr
|
|
|
3472
3551
|
return JSON.stringify(workItem, null, 2);
|
|
3473
3552
|
}
|
|
3474
3553
|
}),
|
|
3475
|
-
gitlab_list_work_items:
|
|
3554
|
+
gitlab_list_work_items: tool12({
|
|
3476
3555
|
description: `List work items in a project or group.
|
|
3477
3556
|
Work items include issues, epics, tasks, and other work tracking items.`,
|
|
3478
3557
|
args: {
|
|
3479
|
-
project_id:
|
|
3480
|
-
group_id:
|
|
3481
|
-
state:
|
|
3482
|
-
search:
|
|
3483
|
-
labels:
|
|
3484
|
-
work_item_type:
|
|
3485
|
-
limit:
|
|
3558
|
+
project_id: z12.string().optional().describe("The project ID or URL-encoded path"),
|
|
3559
|
+
group_id: z12.string().optional().describe("The group ID or URL-encoded path"),
|
|
3560
|
+
state: z12.enum(["opened", "closed", "all"]).optional().describe("Filter by state (default: opened)"),
|
|
3561
|
+
search: z12.string().optional().describe("Search work items by title or description"),
|
|
3562
|
+
labels: z12.string().optional().describe("Comma-separated list of labels to filter by"),
|
|
3563
|
+
work_item_type: z12.string().optional().describe("Filter by work item type (e.g., 'Issue', 'Epic', 'Task')"),
|
|
3564
|
+
limit: z12.number().optional().describe("Maximum number of results (default: 20)")
|
|
3486
3565
|
},
|
|
3487
3566
|
execute: async (args, _ctx) => {
|
|
3488
3567
|
const client = getGitLabClient();
|
|
@@ -3498,12 +3577,12 @@ Work items include issues, epics, tasks, and other work tracking items.`,
|
|
|
3498
3577
|
return JSON.stringify(workItems, null, 2);
|
|
3499
3578
|
}
|
|
3500
3579
|
}),
|
|
3501
|
-
gitlab_get_work_item_notes:
|
|
3580
|
+
gitlab_get_work_item_notes: tool12({
|
|
3502
3581
|
description: `Get all comments for a work item.
|
|
3503
3582
|
Returns all notes/comments on the work item in chronological order.`,
|
|
3504
3583
|
args: {
|
|
3505
|
-
project_id:
|
|
3506
|
-
work_item_id:
|
|
3584
|
+
project_id: z12.string().describe("The project ID or URL-encoded path"),
|
|
3585
|
+
work_item_id: z12.number().describe("The ID of the work item")
|
|
3507
3586
|
},
|
|
3508
3587
|
execute: async (args, _ctx) => {
|
|
3509
3588
|
const client = getGitLabClient();
|
|
@@ -3511,16 +3590,16 @@ Returns all notes/comments on the work item in chronological order.`,
|
|
|
3511
3590
|
return JSON.stringify(notes, null, 2);
|
|
3512
3591
|
}
|
|
3513
3592
|
}),
|
|
3514
|
-
gitlab_create_work_item:
|
|
3593
|
+
gitlab_create_work_item: tool12({
|
|
3515
3594
|
description: `Create a new work item (issue, task, etc.).
|
|
3516
3595
|
Work items are the new unified model for issues, epics, tasks, and other work tracking items.`,
|
|
3517
3596
|
args: {
|
|
3518
|
-
project_id:
|
|
3519
|
-
title:
|
|
3520
|
-
work_item_type_id:
|
|
3521
|
-
description:
|
|
3522
|
-
labels:
|
|
3523
|
-
assignee_ids:
|
|
3597
|
+
project_id: z12.string().describe("The project ID or URL-encoded path"),
|
|
3598
|
+
title: z12.string().describe("The title of the work item"),
|
|
3599
|
+
work_item_type_id: z12.number().describe("The ID of the work item type (e.g., 1 for Issue, 2 for Task)"),
|
|
3600
|
+
description: z12.string().optional().describe("The description of the work item (supports Markdown)"),
|
|
3601
|
+
labels: z12.array(z12.string()).optional().describe("Array of label names"),
|
|
3602
|
+
assignee_ids: z12.array(z12.number()).optional().describe("Array of user IDs to assign")
|
|
3524
3603
|
},
|
|
3525
3604
|
execute: async (args, _ctx) => {
|
|
3526
3605
|
const client = getGitLabClient();
|
|
@@ -3534,17 +3613,17 @@ Work items are the new unified model for issues, epics, tasks, and other work tr
|
|
|
3534
3613
|
return JSON.stringify(workItem, null, 2);
|
|
3535
3614
|
}
|
|
3536
3615
|
}),
|
|
3537
|
-
gitlab_update_work_item:
|
|
3616
|
+
gitlab_update_work_item: tool12({
|
|
3538
3617
|
description: `Update an existing work item.
|
|
3539
3618
|
Can update title, description, state, labels, and assignees.`,
|
|
3540
3619
|
args: {
|
|
3541
|
-
project_id:
|
|
3542
|
-
work_item_id:
|
|
3543
|
-
title:
|
|
3544
|
-
description:
|
|
3545
|
-
state_event:
|
|
3546
|
-
labels:
|
|
3547
|
-
assignee_ids:
|
|
3620
|
+
project_id: z12.string().describe("The project ID or URL-encoded path"),
|
|
3621
|
+
work_item_id: z12.number().describe("The ID of the work item"),
|
|
3622
|
+
title: z12.string().optional().describe("The new title"),
|
|
3623
|
+
description: z12.string().optional().describe("The new description (supports Markdown)"),
|
|
3624
|
+
state_event: z12.enum(["close", "reopen"]).optional().describe("Change the state (close or reopen)"),
|
|
3625
|
+
labels: z12.array(z12.string()).optional().describe("Array of label names"),
|
|
3626
|
+
assignee_ids: z12.array(z12.number()).optional().describe("Array of user IDs to assign")
|
|
3548
3627
|
},
|
|
3549
3628
|
execute: async (args, _ctx) => {
|
|
3550
3629
|
const client = getGitLabClient();
|
|
@@ -3558,12 +3637,12 @@ Can update title, description, state, labels, and assignees.`,
|
|
|
3558
3637
|
return JSON.stringify(workItem, null, 2);
|
|
3559
3638
|
}
|
|
3560
3639
|
}),
|
|
3561
|
-
gitlab_create_work_item_note:
|
|
3640
|
+
gitlab_create_work_item_note: tool12({
|
|
3562
3641
|
description: `Create a comment on a work item.`,
|
|
3563
3642
|
args: {
|
|
3564
|
-
project_id:
|
|
3565
|
-
work_item_id:
|
|
3566
|
-
body:
|
|
3643
|
+
project_id: z12.string().describe("The project ID or URL-encoded path"),
|
|
3644
|
+
work_item_id: z12.number().describe("The ID of the work item"),
|
|
3645
|
+
body: z12.string().describe("The content of the note/comment (supports Markdown)")
|
|
3567
3646
|
},
|
|
3568
3647
|
execute: async (args, _ctx) => {
|
|
3569
3648
|
const client = getGitLabClient();
|
|
@@ -3574,8 +3653,8 @@ Can update title, description, state, labels, and assignees.`,
|
|
|
3574
3653
|
};
|
|
3575
3654
|
|
|
3576
3655
|
// src/tools/discussions-unified.ts
|
|
3577
|
-
import { tool as
|
|
3578
|
-
var
|
|
3656
|
+
import { tool as tool13 } from "@opencode-ai/plugin";
|
|
3657
|
+
var z13 = tool13.schema;
|
|
3579
3658
|
function normalizeBoolean(value) {
|
|
3580
3659
|
if (typeof value === "boolean") return value;
|
|
3581
3660
|
if (value === "true") return true;
|
|
@@ -3596,15 +3675,15 @@ function filterDiscussionsByResolved(result, resolved) {
|
|
|
3596
3675
|
}
|
|
3597
3676
|
};
|
|
3598
3677
|
}
|
|
3599
|
-
var positionSchema =
|
|
3600
|
-
base_sha:
|
|
3601
|
-
start_sha:
|
|
3602
|
-
head_sha:
|
|
3603
|
-
position_type:
|
|
3604
|
-
old_path:
|
|
3605
|
-
new_path:
|
|
3606
|
-
old_line:
|
|
3607
|
-
new_line:
|
|
3678
|
+
var positionSchema = z13.object({
|
|
3679
|
+
base_sha: z13.string().describe("SHA of the base commit"),
|
|
3680
|
+
start_sha: z13.string().describe("SHA of the start commit"),
|
|
3681
|
+
head_sha: z13.string().describe("SHA of the head commit"),
|
|
3682
|
+
position_type: z13.enum(["text", "image"]).describe("Type of position"),
|
|
3683
|
+
old_path: z13.string().optional().describe("Path of the file before changes"),
|
|
3684
|
+
new_path: z13.string().optional().describe("Path of the file after changes"),
|
|
3685
|
+
old_line: z13.number().optional().describe("Line number in the old version"),
|
|
3686
|
+
new_line: z13.number().optional().describe("Line number in the new version")
|
|
3608
3687
|
});
|
|
3609
3688
|
function validateResourceParams(resourceType, args) {
|
|
3610
3689
|
switch (resourceType) {
|
|
@@ -3631,7 +3710,7 @@ var discussionsUnifiedTools = {
|
|
|
3631
3710
|
/**
|
|
3632
3711
|
* List discussions for any GitLab resource type
|
|
3633
3712
|
*/
|
|
3634
|
-
gitlab_list_discussions:
|
|
3713
|
+
gitlab_list_discussions: tool13({
|
|
3635
3714
|
description: `List discussions (comment threads) on any GitLab resource.
|
|
3636
3715
|
Supports: merge_requests, issues, epics, commits, snippets.
|
|
3637
3716
|
|
|
@@ -3647,21 +3726,21 @@ Examples:
|
|
|
3647
3726
|
- Commit: resource_type="commit", project_id="group/project", sha="abc123"
|
|
3648
3727
|
- Snippet: resource_type="snippet", project_id="group/project", snippet_id=789`,
|
|
3649
3728
|
args: {
|
|
3650
|
-
resource_type:
|
|
3651
|
-
project_id:
|
|
3652
|
-
group_id:
|
|
3653
|
-
iid:
|
|
3654
|
-
sha:
|
|
3655
|
-
snippet_id:
|
|
3729
|
+
resource_type: z13.enum(["merge_request", "issue", "epic", "commit", "snippet"]).describe("Type of GitLab resource"),
|
|
3730
|
+
project_id: z13.string().optional().describe("Project ID or path. Required for merge_request, issue, commit, snippet"),
|
|
3731
|
+
group_id: z13.string().optional().describe("Group ID or path. Required for epic"),
|
|
3732
|
+
iid: z13.number().optional().describe("Internal ID of the resource (for merge_request, issue, epic)"),
|
|
3733
|
+
sha: z13.string().optional().describe("Commit SHA (required for commit)"),
|
|
3734
|
+
snippet_id: z13.number().optional().describe("Snippet ID (required for snippet)"),
|
|
3656
3735
|
// Filtering
|
|
3657
|
-
resolved:
|
|
3736
|
+
resolved: z13.boolean().optional().describe(
|
|
3658
3737
|
"Filter by resolved status: true for resolved, false for unresolved. Only returns resolvable discussions (excludes system notes). Client-side filtering."
|
|
3659
3738
|
),
|
|
3660
3739
|
// Pagination
|
|
3661
|
-
first:
|
|
3662
|
-
after:
|
|
3663
|
-
before:
|
|
3664
|
-
last:
|
|
3740
|
+
first: z13.number().optional().describe("Number of items to return (default: 20)"),
|
|
3741
|
+
after: z13.string().optional().describe("Cursor for pagination - use endCursor from previous response"),
|
|
3742
|
+
before: z13.string().optional().describe("Cursor for backward pagination"),
|
|
3743
|
+
last: z13.number().optional().describe("Number of items from the end")
|
|
3665
3744
|
},
|
|
3666
3745
|
execute: async (args, _ctx) => {
|
|
3667
3746
|
validateResourceParams(args.resource_type, args);
|
|
@@ -3710,7 +3789,7 @@ Examples:
|
|
|
3710
3789
|
/**
|
|
3711
3790
|
* Get a specific discussion thread from any GitLab resource
|
|
3712
3791
|
*/
|
|
3713
|
-
gitlab_get_discussion:
|
|
3792
|
+
gitlab_get_discussion: tool13({
|
|
3714
3793
|
description: `Get a specific discussion thread with all its replies.
|
|
3715
3794
|
Returns the discussion with its 'notes' array containing all comments.
|
|
3716
3795
|
|
|
@@ -3723,13 +3802,13 @@ Required parameters vary by resource type:
|
|
|
3723
3802
|
- commit: project_id, sha, discussion_id
|
|
3724
3803
|
- snippet: project_id, snippet_id, discussion_id`,
|
|
3725
3804
|
args: {
|
|
3726
|
-
resource_type:
|
|
3727
|
-
discussion_id:
|
|
3728
|
-
project_id:
|
|
3729
|
-
group_id:
|
|
3730
|
-
iid:
|
|
3731
|
-
sha:
|
|
3732
|
-
snippet_id:
|
|
3805
|
+
resource_type: z13.enum(["merge_request", "issue", "epic", "commit", "snippet"]).describe("Type of GitLab resource"),
|
|
3806
|
+
discussion_id: z13.string().describe("The ID of the discussion thread"),
|
|
3807
|
+
project_id: z13.string().optional().describe("Project ID or path"),
|
|
3808
|
+
group_id: z13.string().optional().describe("Group ID or path (for epic)"),
|
|
3809
|
+
iid: z13.number().optional().describe("Internal ID (for merge_request, issue, epic)"),
|
|
3810
|
+
sha: z13.string().optional().describe("Commit SHA (for commit)"),
|
|
3811
|
+
snippet_id: z13.number().optional().describe("Snippet ID (for snippet)")
|
|
3733
3812
|
},
|
|
3734
3813
|
execute: async (args, _ctx) => {
|
|
3735
3814
|
validateResourceParams(args.resource_type, args);
|
|
@@ -3777,27 +3856,29 @@ Required parameters vary by resource type:
|
|
|
3777
3856
|
/**
|
|
3778
3857
|
* Create a new discussion thread or reply to an existing one
|
|
3779
3858
|
*/
|
|
3780
|
-
gitlab_create_discussion:
|
|
3859
|
+
gitlab_create_discussion: tool13({
|
|
3781
3860
|
description: `Create a new discussion thread or reply to an existing one.
|
|
3782
3861
|
|
|
3783
|
-
|
|
3784
|
-
|
|
3862
|
+
REPLYING TO EXISTING THREADS:
|
|
3863
|
+
To reply to an existing discussion, provide the discussion_id parameter.
|
|
3864
|
+
This is the recommended way to reply in-thread rather than creating a standalone comment.
|
|
3785
3865
|
|
|
3786
|
-
|
|
3866
|
+
STARTING A NEW DISCUSSION:
|
|
3867
|
+
Omit discussion_id to create a new thread. For code-specific comments on MRs/commits, provide position information.
|
|
3787
3868
|
|
|
3788
3869
|
Examples:
|
|
3789
|
-
-
|
|
3790
|
-
-
|
|
3791
|
-
- Code comment: resource_type="merge_request",
|
|
3870
|
+
- Reply to thread: resource_type="merge_request", project_id="group/project", iid=123, discussion_id="abc123def", body="Thanks for the feedback!"
|
|
3871
|
+
- New comment: resource_type="merge_request", project_id="group/project", iid=123, body="General comment"
|
|
3872
|
+
- Code comment: resource_type="merge_request", project_id="group/project", iid=123, body="...", position={base_sha, head_sha, new_path, new_line, ...}`,
|
|
3792
3873
|
args: {
|
|
3793
|
-
resource_type:
|
|
3794
|
-
body:
|
|
3795
|
-
project_id:
|
|
3796
|
-
group_id:
|
|
3797
|
-
iid:
|
|
3798
|
-
sha:
|
|
3799
|
-
snippet_id:
|
|
3800
|
-
discussion_id:
|
|
3874
|
+
resource_type: z13.enum(["merge_request", "issue", "epic", "commit", "snippet"]).describe("Type of GitLab resource"),
|
|
3875
|
+
body: z13.string().describe("The comment text (Markdown supported)"),
|
|
3876
|
+
project_id: z13.string().optional().describe("Project ID or path"),
|
|
3877
|
+
group_id: z13.string().optional().describe("Group ID or path (for epic)"),
|
|
3878
|
+
iid: z13.number().optional().describe("Internal ID (for merge_request, issue, epic)"),
|
|
3879
|
+
sha: z13.string().optional().describe("Commit SHA (for commit)"),
|
|
3880
|
+
snippet_id: z13.number().optional().describe("Snippet ID (for snippet)"),
|
|
3881
|
+
discussion_id: z13.string().optional().describe("If provided, replies to existing discussion. If omitted, creates new thread"),
|
|
3801
3882
|
position: positionSchema.optional().describe("Position for code-specific comments (MR/commit only)")
|
|
3802
3883
|
},
|
|
3803
3884
|
execute: async (args, _ctx) => {
|
|
@@ -3862,7 +3943,7 @@ Examples:
|
|
|
3862
3943
|
/**
|
|
3863
3944
|
* Resolve or unresolve a discussion thread
|
|
3864
3945
|
*/
|
|
3865
|
-
gitlab_resolve_discussion:
|
|
3946
|
+
gitlab_resolve_discussion: tool13({
|
|
3866
3947
|
description: `Mark a discussion thread as resolved or unresolve it.
|
|
3867
3948
|
Only works for resolvable discussions (MRs and issues only).
|
|
3868
3949
|
|
|
@@ -3871,11 +3952,11 @@ Uses GraphQL API which handles all discussion types including outdated discussio
|
|
|
3871
3952
|
|
|
3872
3953
|
Use after addressing feedback to indicate the discussion is complete.`,
|
|
3873
3954
|
args: {
|
|
3874
|
-
resource_type:
|
|
3875
|
-
action:
|
|
3876
|
-
discussion_id:
|
|
3877
|
-
project_id:
|
|
3878
|
-
iid:
|
|
3955
|
+
resource_type: z13.enum(["merge_request", "issue"]).describe("Type of resource (only MR and issue discussions can be resolved)"),
|
|
3956
|
+
action: z13.enum(["resolve", "unresolve"]).describe("Whether to resolve or unresolve"),
|
|
3957
|
+
discussion_id: z13.string().describe("The ID of the discussion thread"),
|
|
3958
|
+
project_id: z13.string().describe("Project ID or path"),
|
|
3959
|
+
iid: z13.number().describe("Internal ID of the MR or issue")
|
|
3879
3960
|
},
|
|
3880
3961
|
execute: async (args, _ctx) => {
|
|
3881
3962
|
const client = getGitLabClient();
|
|
@@ -3890,8 +3971,8 @@ Use after addressing feedback to indicate the discussion is complete.`,
|
|
|
3890
3971
|
};
|
|
3891
3972
|
|
|
3892
3973
|
// src/tools/notes-unified.ts
|
|
3893
|
-
import { tool as
|
|
3894
|
-
var
|
|
3974
|
+
import { tool as tool14 } from "@opencode-ai/plugin";
|
|
3975
|
+
var z14 = tool14.schema;
|
|
3895
3976
|
function normalizeBoolean2(value) {
|
|
3896
3977
|
if (typeof value === "boolean") return value;
|
|
3897
3978
|
if (value === "true") return true;
|
|
@@ -3962,7 +4043,7 @@ var notesUnifiedTools = {
|
|
|
3962
4043
|
/**
|
|
3963
4044
|
* List notes/comments for any GitLab resource type
|
|
3964
4045
|
*/
|
|
3965
|
-
gitlab_list_notes:
|
|
4046
|
+
gitlab_list_notes: tool14({
|
|
3966
4047
|
description: `List all notes/comments on any GitLab resource using GraphQL API with pagination support.
|
|
3967
4048
|
Returns all comments including system notes in chronological order.
|
|
3968
4049
|
This is easier to read than discussions which have nested structure.
|
|
@@ -3977,20 +4058,20 @@ Examples:
|
|
|
3977
4058
|
- Epic: resource_type="epic", group_id="my-group", iid=1
|
|
3978
4059
|
- Snippet: resource_type="snippet", project_id="group/project", snippet_id=789`,
|
|
3979
4060
|
args: {
|
|
3980
|
-
resource_type:
|
|
3981
|
-
project_id:
|
|
3982
|
-
group_id:
|
|
3983
|
-
iid:
|
|
3984
|
-
snippet_id:
|
|
4061
|
+
resource_type: z14.enum(["merge_request", "issue", "epic", "snippet"]).describe("Type of GitLab resource"),
|
|
4062
|
+
project_id: z14.string().optional().describe("Project ID or path. Required for merge_request, issue, snippet"),
|
|
4063
|
+
group_id: z14.string().optional().describe("Group ID or path. Required for epic"),
|
|
4064
|
+
iid: z14.number().optional().describe("Internal ID of the resource (for merge_request, issue, epic)"),
|
|
4065
|
+
snippet_id: z14.number().optional().describe("Snippet ID (required for snippet)"),
|
|
3985
4066
|
// Filtering
|
|
3986
|
-
resolved:
|
|
4067
|
+
resolved: z14.boolean().optional().describe(
|
|
3987
4068
|
"Filter by resolved status: true for resolved, false for unresolved. Only returns resolvable notes (excludes system notes). Client-side filtering."
|
|
3988
4069
|
),
|
|
3989
4070
|
// Pagination
|
|
3990
|
-
first:
|
|
3991
|
-
after:
|
|
3992
|
-
last:
|
|
3993
|
-
before:
|
|
4071
|
+
first: z14.number().optional().describe("Number of items to return from the beginning (default: 20, max: 100)"),
|
|
4072
|
+
after: z14.string().optional().describe("Cursor for forward pagination - use endCursor from previous response"),
|
|
4073
|
+
last: z14.number().optional().describe("Number of items to return from the end (for backward pagination)"),
|
|
4074
|
+
before: z14.string().optional().describe("Cursor for backward pagination - use startCursor from previous response")
|
|
3994
4075
|
},
|
|
3995
4076
|
execute: async (args, _ctx) => {
|
|
3996
4077
|
validateListCreateParams(args.resource_type, args);
|
|
@@ -4029,7 +4110,7 @@ Examples:
|
|
|
4029
4110
|
/**
|
|
4030
4111
|
* Get a single note/comment by its ID
|
|
4031
4112
|
*/
|
|
4032
|
-
gitlab_get_note:
|
|
4113
|
+
gitlab_get_note: tool14({
|
|
4033
4114
|
description: `Get a single note/comment from an issue or epic by its ID.
|
|
4034
4115
|
Returns the full details of a specific note including author, body, timestamps, and metadata.
|
|
4035
4116
|
Useful when you need to retrieve a specific comment without fetching all notes.
|
|
@@ -4040,11 +4121,11 @@ Examples:
|
|
|
4040
4121
|
- Issue note: resource_type="issue", project_id="group/project", iid=456, note_id=123
|
|
4041
4122
|
- Epic note: resource_type="epic", group_id="my-group", iid=1, note_id=456`,
|
|
4042
4123
|
args: {
|
|
4043
|
-
resource_type:
|
|
4044
|
-
note_id:
|
|
4045
|
-
project_id:
|
|
4046
|
-
group_id:
|
|
4047
|
-
iid:
|
|
4124
|
+
resource_type: z14.enum(["issue", "epic"]).describe("Type of GitLab resource (issue or epic only)"),
|
|
4125
|
+
note_id: z14.number().describe("The ID of the note to retrieve"),
|
|
4126
|
+
project_id: z14.string().optional().describe("Project ID or path. Required for issue"),
|
|
4127
|
+
group_id: z14.string().optional().describe("Group ID or path. Required for epic"),
|
|
4128
|
+
iid: z14.number().describe("Internal ID of the issue or epic")
|
|
4048
4129
|
},
|
|
4049
4130
|
execute: async (args, _ctx) => {
|
|
4050
4131
|
validateGetNoteParams(args.resource_type, args);
|
|
@@ -4070,7 +4151,7 @@ Examples:
|
|
|
4070
4151
|
/**
|
|
4071
4152
|
* Create a simple note/comment on any GitLab resource
|
|
4072
4153
|
*/
|
|
4073
|
-
gitlab_create_note:
|
|
4154
|
+
gitlab_create_note: tool14({
|
|
4074
4155
|
description: `Add a simple comment/note to any GitLab resource.
|
|
4075
4156
|
Creates a standalone comment (not part of a thread).
|
|
4076
4157
|
|
|
@@ -4083,12 +4164,12 @@ Examples:
|
|
|
4083
4164
|
- Epic comment: resource_type="epic", group_id="my-group", iid=1, body="Planning complete"
|
|
4084
4165
|
- Snippet comment: resource_type="snippet", project_id="group/project", snippet_id=789, body="Nice code!"`,
|
|
4085
4166
|
args: {
|
|
4086
|
-
resource_type:
|
|
4087
|
-
body:
|
|
4088
|
-
project_id:
|
|
4089
|
-
group_id:
|
|
4090
|
-
iid:
|
|
4091
|
-
snippet_id:
|
|
4167
|
+
resource_type: z14.enum(["merge_request", "issue", "epic", "snippet"]).describe("Type of GitLab resource"),
|
|
4168
|
+
body: z14.string().describe("The content of the note/comment (supports Markdown)"),
|
|
4169
|
+
project_id: z14.string().optional().describe("Project ID or path. Required for merge_request, issue, snippet"),
|
|
4170
|
+
group_id: z14.string().optional().describe("Group ID or path. Required for epic"),
|
|
4171
|
+
iid: z14.number().optional().describe("Internal ID of the resource (for merge_request, issue, epic)"),
|
|
4172
|
+
snippet_id: z14.number().optional().describe("Snippet ID (required for snippet)")
|
|
4092
4173
|
},
|
|
4093
4174
|
execute: async (args, _ctx) => {
|
|
4094
4175
|
validateListCreateParams(args.resource_type, args);
|
|
@@ -4126,7 +4207,7 @@ Examples:
|
|
|
4126
4207
|
};
|
|
4127
4208
|
|
|
4128
4209
|
// src/tools/git.ts
|
|
4129
|
-
import { tool as
|
|
4210
|
+
import { tool as tool15 } from "@opencode-ai/plugin";
|
|
4130
4211
|
|
|
4131
4212
|
// src/client/git.ts
|
|
4132
4213
|
import { execFile } from "child_process";
|
|
@@ -4295,7 +4376,7 @@ ${stderr}` : stdout;
|
|
|
4295
4376
|
};
|
|
4296
4377
|
|
|
4297
4378
|
// src/tools/git.ts
|
|
4298
|
-
var
|
|
4379
|
+
var z15 = tool15.schema;
|
|
4299
4380
|
var gitClient = null;
|
|
4300
4381
|
function getGitClient() {
|
|
4301
4382
|
if (!gitClient) {
|
|
@@ -4304,7 +4385,7 @@ function getGitClient() {
|
|
|
4304
4385
|
return gitClient;
|
|
4305
4386
|
}
|
|
4306
4387
|
var gitTools = {
|
|
4307
|
-
run_git_command:
|
|
4388
|
+
run_git_command: tool15({
|
|
4308
4389
|
description: `Execute safe, read-only git commands in the repository working directory.
|
|
4309
4390
|
|
|
4310
4391
|
Security restrictions:
|
|
@@ -4346,9 +4427,9 @@ Examples:
|
|
|
4346
4427
|
- run_git_command("branch", ["-a"]) - List all branches
|
|
4347
4428
|
- run_git_command("show", ["HEAD:README.md"]) - Show README.md from HEAD commit`,
|
|
4348
4429
|
args: {
|
|
4349
|
-
command:
|
|
4350
|
-
args:
|
|
4351
|
-
working_directory:
|
|
4430
|
+
command: z15.string().describe('The git command to execute (without "git" prefix)'),
|
|
4431
|
+
args: z15.array(z15.string()).optional().describe("Array of arguments for the git command (default: [])"),
|
|
4432
|
+
working_directory: z15.string().optional().describe(
|
|
4352
4433
|
"Path to the git repository (default: current working directory). Use this to execute git commands in a specific repository."
|
|
4353
4434
|
)
|
|
4354
4435
|
},
|
|
@@ -4371,22 +4452,22 @@ Examples:
|
|
|
4371
4452
|
};
|
|
4372
4453
|
|
|
4373
4454
|
// src/tools/audit.ts
|
|
4374
|
-
import { tool as
|
|
4375
|
-
var
|
|
4455
|
+
import { tool as tool16 } from "@opencode-ai/plugin";
|
|
4456
|
+
var z16 = tool16.schema;
|
|
4376
4457
|
var auditTools = {
|
|
4377
|
-
gitlab_list_project_audit_events:
|
|
4458
|
+
gitlab_list_project_audit_events: tool16({
|
|
4378
4459
|
description: `List audit events for a project.
|
|
4379
4460
|
Returns audit events including actions like project settings changes, member additions/removals, and other security-relevant activities.
|
|
4380
4461
|
Note: Requires project owner role or higher.`,
|
|
4381
4462
|
args: {
|
|
4382
|
-
project_id:
|
|
4383
|
-
created_after:
|
|
4384
|
-
created_before:
|
|
4385
|
-
entity_type:
|
|
4386
|
-
entity_id:
|
|
4387
|
-
author_id:
|
|
4388
|
-
per_page:
|
|
4389
|
-
page:
|
|
4463
|
+
project_id: z16.string().describe("The project ID or URL-encoded path"),
|
|
4464
|
+
created_after: z16.string().optional().describe("Return audit events created after this date (ISO 8601 format)"),
|
|
4465
|
+
created_before: z16.string().optional().describe("Return audit events created before this date (ISO 8601 format)"),
|
|
4466
|
+
entity_type: z16.string().optional().describe('Filter by entity type (e.g., "User", "Project", "Group")'),
|
|
4467
|
+
entity_id: z16.number().optional().describe("Filter by entity ID"),
|
|
4468
|
+
author_id: z16.number().optional().describe("Filter by author user ID"),
|
|
4469
|
+
per_page: z16.number().optional().describe("Number of results per page (default: 20)"),
|
|
4470
|
+
page: z16.number().optional().describe("Page number for pagination (default: 1)")
|
|
4390
4471
|
},
|
|
4391
4472
|
execute: async (args, _ctx) => {
|
|
4392
4473
|
const client = getGitLabClient();
|
|
@@ -4402,19 +4483,19 @@ Note: Requires project owner role or higher.`,
|
|
|
4402
4483
|
return JSON.stringify(events, null, 2);
|
|
4403
4484
|
}
|
|
4404
4485
|
}),
|
|
4405
|
-
gitlab_list_group_audit_events:
|
|
4486
|
+
gitlab_list_group_audit_events: tool16({
|
|
4406
4487
|
description: `List audit events for a group.
|
|
4407
4488
|
Returns audit events including actions like group settings changes, member additions/removals, subgroup operations, and other security-relevant activities.
|
|
4408
4489
|
Note: Requires group owner role or higher.`,
|
|
4409
4490
|
args: {
|
|
4410
|
-
group_id:
|
|
4411
|
-
created_after:
|
|
4412
|
-
created_before:
|
|
4413
|
-
entity_type:
|
|
4414
|
-
entity_id:
|
|
4415
|
-
author_id:
|
|
4416
|
-
per_page:
|
|
4417
|
-
page:
|
|
4491
|
+
group_id: z16.string().describe("The group ID or URL-encoded path"),
|
|
4492
|
+
created_after: z16.string().optional().describe("Return audit events created after this date (ISO 8601 format)"),
|
|
4493
|
+
created_before: z16.string().optional().describe("Return audit events created before this date (ISO 8601 format)"),
|
|
4494
|
+
entity_type: z16.string().optional().describe('Filter by entity type (e.g., "User", "Project", "Group")'),
|
|
4495
|
+
entity_id: z16.number().optional().describe("Filter by entity ID"),
|
|
4496
|
+
author_id: z16.number().optional().describe("Filter by author user ID"),
|
|
4497
|
+
per_page: z16.number().optional().describe("Number of results per page (default: 20)"),
|
|
4498
|
+
page: z16.number().optional().describe("Page number for pagination (default: 1)")
|
|
4418
4499
|
},
|
|
4419
4500
|
execute: async (args, _ctx) => {
|
|
4420
4501
|
const client = getGitLabClient();
|
|
@@ -4430,18 +4511,18 @@ Note: Requires group owner role or higher.`,
|
|
|
4430
4511
|
return JSON.stringify(events, null, 2);
|
|
4431
4512
|
}
|
|
4432
4513
|
}),
|
|
4433
|
-
gitlab_list_instance_audit_events:
|
|
4514
|
+
gitlab_list_instance_audit_events: tool16({
|
|
4434
4515
|
description: `List instance-level audit events.
|
|
4435
4516
|
Returns audit events for the entire GitLab instance including actions like instance settings changes, user management, license changes, and other system-wide security-relevant activities.
|
|
4436
4517
|
Note: Requires administrator access.`,
|
|
4437
4518
|
args: {
|
|
4438
|
-
created_after:
|
|
4439
|
-
created_before:
|
|
4440
|
-
entity_type:
|
|
4441
|
-
entity_id:
|
|
4442
|
-
author_id:
|
|
4443
|
-
per_page:
|
|
4444
|
-
page:
|
|
4519
|
+
created_after: z16.string().optional().describe("Return audit events created after this date (ISO 8601 format)"),
|
|
4520
|
+
created_before: z16.string().optional().describe("Return audit events created before this date (ISO 8601 format)"),
|
|
4521
|
+
entity_type: z16.string().optional().describe('Filter by entity type (e.g., "User", "Project", "Group")'),
|
|
4522
|
+
entity_id: z16.number().optional().describe("Filter by entity ID"),
|
|
4523
|
+
author_id: z16.number().optional().describe("Filter by author user ID"),
|
|
4524
|
+
per_page: z16.number().optional().describe("Number of results per page (default: 20)"),
|
|
4525
|
+
page: z16.number().optional().describe("Page number for pagination (default: 1)")
|
|
4445
4526
|
},
|
|
4446
4527
|
execute: async (args, _ctx) => {
|
|
4447
4528
|
const client = getGitLabClient();
|
|
@@ -4460,8 +4541,8 @@ Note: Requires administrator access.`,
|
|
|
4460
4541
|
};
|
|
4461
4542
|
|
|
4462
4543
|
// src/tools/award-emoji.ts
|
|
4463
|
-
import { tool as
|
|
4464
|
-
var
|
|
4544
|
+
import { tool as tool17 } from "@opencode-ai/plugin";
|
|
4545
|
+
var z17 = tool17.schema;
|
|
4465
4546
|
function validateAwardEmojiParams(args) {
|
|
4466
4547
|
if (!args.project_id) {
|
|
4467
4548
|
throw new Error("project_id is required");
|
|
@@ -4482,7 +4563,7 @@ var awardEmojiTools = {
|
|
|
4482
4563
|
/**
|
|
4483
4564
|
* Add a reaction (award emoji) to a resource or note
|
|
4484
4565
|
*/
|
|
4485
|
-
gitlab_create_award_emoji:
|
|
4566
|
+
gitlab_create_award_emoji: tool17({
|
|
4486
4567
|
description: `Add a reaction (award emoji) to a merge request, issue, snippet, or a note/comment on these resources.
|
|
4487
4568
|
|
|
4488
4569
|
Common emoji names: thumbsup, thumbsdown, smile, tada, rocket, eyes, heart, +1, -1
|
|
@@ -4493,13 +4574,13 @@ Examples:
|
|
|
4493
4574
|
- React to MR: resource_type="merge_request", project_id="group/project", resource_iid=123, name="thumbsup"
|
|
4494
4575
|
- React to issue comment: resource_type="issue", project_id="group/project", resource_iid=456, note_id=789, name="rocket"`,
|
|
4495
4576
|
args: {
|
|
4496
|
-
resource_type:
|
|
4497
|
-
project_id:
|
|
4498
|
-
resource_iid:
|
|
4499
|
-
name:
|
|
4577
|
+
resource_type: z17.enum(["merge_request", "issue", "snippet"]).describe("Type of resource to add the reaction to"),
|
|
4578
|
+
project_id: z17.string().describe("Project ID or URL-encoded path"),
|
|
4579
|
+
resource_iid: z17.number().describe("Internal ID of the merge request, issue, or snippet"),
|
|
4580
|
+
name: z17.string().describe(
|
|
4500
4581
|
'Emoji name without colons (e.g., "thumbsup", "rocket", "eyes", "heart", "tada")'
|
|
4501
4582
|
),
|
|
4502
|
-
note_id:
|
|
4583
|
+
note_id: z17.number().optional().describe("Note/comment ID to add the reaction to (if reacting to a specific comment)")
|
|
4503
4584
|
},
|
|
4504
4585
|
execute: async (args, _ctx) => {
|
|
4505
4586
|
validateAwardEmojiParams(args);
|
|
@@ -4512,17 +4593,17 @@ Examples:
|
|
|
4512
4593
|
/**
|
|
4513
4594
|
* List all reactions on a resource or note
|
|
4514
4595
|
*/
|
|
4515
|
-
gitlab_list_award_emoji:
|
|
4596
|
+
gitlab_list_award_emoji: tool17({
|
|
4516
4597
|
description: `List all reactions (award emoji) on a merge request, issue, snippet, or a specific note/comment.
|
|
4517
4598
|
|
|
4518
4599
|
Examples:
|
|
4519
4600
|
- List reactions on MR: resource_type="merge_request", project_id="group/project", resource_iid=123
|
|
4520
4601
|
- List reactions on a comment: resource_type="issue", project_id="group/project", resource_iid=456, note_id=789`,
|
|
4521
4602
|
args: {
|
|
4522
|
-
resource_type:
|
|
4523
|
-
project_id:
|
|
4524
|
-
resource_iid:
|
|
4525
|
-
note_id:
|
|
4603
|
+
resource_type: z17.enum(["merge_request", "issue", "snippet"]).describe("Type of resource"),
|
|
4604
|
+
project_id: z17.string().describe("Project ID or URL-encoded path"),
|
|
4605
|
+
resource_iid: z17.number().describe("Internal ID of the merge request, issue, or snippet"),
|
|
4606
|
+
note_id: z17.number().optional().describe("Note/comment ID to list reactions for (if listing for a specific comment)")
|
|
4526
4607
|
},
|
|
4527
4608
|
execute: async (args, _ctx) => {
|
|
4528
4609
|
validateAwardEmojiParams(args);
|
|
@@ -4535,7 +4616,7 @@ Examples:
|
|
|
4535
4616
|
/**
|
|
4536
4617
|
* Remove a reaction from a resource or note
|
|
4537
4618
|
*/
|
|
4538
|
-
gitlab_delete_award_emoji:
|
|
4619
|
+
gitlab_delete_award_emoji: tool17({
|
|
4539
4620
|
description: `Remove a reaction (award emoji) from a merge request, issue, snippet, or note/comment.
|
|
4540
4621
|
|
|
4541
4622
|
You need the award_id which can be found using gitlab_list_award_emoji.
|
|
@@ -4544,11 +4625,11 @@ Examples:
|
|
|
4544
4625
|
- Remove reaction from MR: resource_type="merge_request", project_id="group/project", resource_iid=123, award_id=456
|
|
4545
4626
|
- Remove from comment: resource_type="issue", ..., note_id=789, award_id=456`,
|
|
4546
4627
|
args: {
|
|
4547
|
-
resource_type:
|
|
4548
|
-
project_id:
|
|
4549
|
-
resource_iid:
|
|
4550
|
-
award_id:
|
|
4551
|
-
note_id:
|
|
4628
|
+
resource_type: z17.enum(["merge_request", "issue", "snippet"]).describe("Type of resource"),
|
|
4629
|
+
project_id: z17.string().describe("Project ID or URL-encoded path"),
|
|
4630
|
+
resource_iid: z17.number().describe("Internal ID of the merge request, issue, or snippet"),
|
|
4631
|
+
award_id: z17.number().describe("ID of the award emoji to remove"),
|
|
4632
|
+
note_id: z17.number().optional().describe("Note/comment ID if removing from a specific comment")
|
|
4552
4633
|
},
|
|
4553
4634
|
execute: async (args, _ctx) => {
|
|
4554
4635
|
validateAwardEmojiParams(args);
|
package/package.json
CHANGED
|
Binary file
|