@gitlab/opencode-gitlab-plugin 1.2.0 → 1.4.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,31 @@
|
|
|
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.4.0](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/compare/v1.3.0...v1.4.0) (2026-02-02)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ✨ Features
|
|
9
|
+
|
|
10
|
+
* **todos:** migrate listTodos to GraphQL API with pagination support ([5726c8b](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/commit/5726c8bb3b8fbce6f014c0f3500bf4d913eb4033))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### 🐛 Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **todos:** add validation for conflicting pagination parameters ([f46d8c2](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/commit/f46d8c2d4c0f4e4b6363013fc3bcee676b78d777))
|
|
16
|
+
* **todos:** address MR review feedback ([87b3afa](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/commit/87b3afae2992e789c59f0c908c7b48a957e4a931))
|
|
17
|
+
|
|
18
|
+
## [1.3.0](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/compare/v1.2.0...v1.3.0) (2026-01-30)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### ✨ Features
|
|
22
|
+
|
|
23
|
+
* **notes:** migrate notes listing to GraphQL API with pagination support ([2ec5d65](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/commit/2ec5d6528b27b86a08f5c747f38762f90eb1f297))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### 🐛 Bug Fixes
|
|
27
|
+
|
|
28
|
+
* address review feedback for notes GraphQL migration ([fcb1a35](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/commit/fcb1a355f3ecbddf2429b0e2fecaeb1f02d29ffe))
|
|
29
|
+
|
|
5
30
|
## [1.2.0](https://gitlab.com/gitlab-org/editor-extensions/opencode-gitlab-plugin/compare/v1.1.0...v1.2.0) (2026-01-29)
|
|
6
31
|
|
|
7
32
|
|
|
Binary file
|
package/dist/index.js
CHANGED
|
@@ -82,7 +82,84 @@ var GitLabApiClient = class {
|
|
|
82
82
|
}
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
+
// src/client/notes-types.ts
|
|
86
|
+
function buildPaginationVariables(options) {
|
|
87
|
+
const variables = {};
|
|
88
|
+
if (options?.first !== void 0) {
|
|
89
|
+
variables.first = options.first;
|
|
90
|
+
} else if (options?.last == null) {
|
|
91
|
+
variables.first = 20;
|
|
92
|
+
}
|
|
93
|
+
if (options?.after) variables.after = options.after;
|
|
94
|
+
if (options?.last !== void 0) variables.last = options.last;
|
|
95
|
+
if (options?.before) variables.before = options.before;
|
|
96
|
+
if (options?.filter) variables.filter = options.filter;
|
|
97
|
+
return variables;
|
|
98
|
+
}
|
|
99
|
+
var NOTES_FRAGMENT = `
|
|
100
|
+
fragment NoteFields on Note {
|
|
101
|
+
id
|
|
102
|
+
body
|
|
103
|
+
bodyHtml
|
|
104
|
+
createdAt
|
|
105
|
+
updatedAt
|
|
106
|
+
system
|
|
107
|
+
internal
|
|
108
|
+
resolvable
|
|
109
|
+
resolved
|
|
110
|
+
resolvedAt
|
|
111
|
+
url
|
|
112
|
+
author {
|
|
113
|
+
id
|
|
114
|
+
username
|
|
115
|
+
name
|
|
116
|
+
avatarUrl
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
`;
|
|
120
|
+
var NOTES_CONNECTION_FRAGMENT = `
|
|
121
|
+
fragment NotesConnectionFields on NoteConnection {
|
|
122
|
+
count
|
|
123
|
+
pageInfo {
|
|
124
|
+
hasNextPage
|
|
125
|
+
hasPreviousPage
|
|
126
|
+
startCursor
|
|
127
|
+
endCursor
|
|
128
|
+
}
|
|
129
|
+
nodes {
|
|
130
|
+
...NoteFields
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
`;
|
|
134
|
+
|
|
85
135
|
// src/client/merge-requests.ts
|
|
136
|
+
var LIST_MR_NOTES_QUERY = `
|
|
137
|
+
${NOTES_FRAGMENT}
|
|
138
|
+
${NOTES_CONNECTION_FRAGMENT}
|
|
139
|
+
query listMrNotes(
|
|
140
|
+
$projectPath: ID!
|
|
141
|
+
$mrIid: String!
|
|
142
|
+
$first: Int
|
|
143
|
+
$after: String
|
|
144
|
+
$last: Int
|
|
145
|
+
$before: String
|
|
146
|
+
$filter: WorkItemNotesFilterType
|
|
147
|
+
) {
|
|
148
|
+
project(fullPath: $projectPath) {
|
|
149
|
+
mergeRequest(iid: $mrIid) {
|
|
150
|
+
notes(
|
|
151
|
+
first: $first
|
|
152
|
+
after: $after
|
|
153
|
+
last: $last
|
|
154
|
+
before: $before
|
|
155
|
+
filter: $filter
|
|
156
|
+
) {
|
|
157
|
+
...NotesConnectionFields
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
`;
|
|
86
163
|
var SET_AUTO_MERGE_MUTATION = `
|
|
87
164
|
mutation setAutoMerge(
|
|
88
165
|
$projectPath: ID!
|
|
@@ -183,12 +260,25 @@ var MergeRequestsClient = class extends GitLabApiClient {
|
|
|
183
260
|
requestBody
|
|
184
261
|
);
|
|
185
262
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
263
|
+
/**
|
|
264
|
+
* List notes on a merge request using GraphQL API with pagination support
|
|
265
|
+
*/
|
|
266
|
+
async listMrNotes(projectId, mrIid, options) {
|
|
267
|
+
const variables = {
|
|
268
|
+
projectPath: projectId,
|
|
269
|
+
mrIid: String(mrIid),
|
|
270
|
+
...buildPaginationVariables(options)
|
|
271
|
+
};
|
|
272
|
+
const result = await this.fetchGraphQL(LIST_MR_NOTES_QUERY, variables);
|
|
273
|
+
const notes = result.project?.mergeRequest?.notes;
|
|
274
|
+
if (!notes) {
|
|
275
|
+
throw new Error("Merge request not found or access denied");
|
|
276
|
+
}
|
|
277
|
+
return {
|
|
278
|
+
notes,
|
|
279
|
+
pageInfo: notes.pageInfo,
|
|
280
|
+
totalCount: notes.count
|
|
281
|
+
};
|
|
192
282
|
}
|
|
193
283
|
async createMrNote(projectId, mrIid, body, discussionId) {
|
|
194
284
|
const encodedProject = this.encodeProjectId(projectId);
|
|
@@ -235,10 +325,6 @@ var MergeRequestsClient = class extends GitLabApiClient {
|
|
|
235
325
|
`/projects/${encodedProject}/merge_requests/${mrIid}/pipelines`
|
|
236
326
|
);
|
|
237
327
|
}
|
|
238
|
-
/**
|
|
239
|
-
* List merge request diffs with pagination support
|
|
240
|
-
* API: GET /projects/:id/merge_requests/:merge_request_iid/diffs
|
|
241
|
-
*/
|
|
242
328
|
async listMergeRequestDiffs(projectId, mrIid, options = {}) {
|
|
243
329
|
const encodedProject = this.encodeProjectId(projectId);
|
|
244
330
|
const params = new URLSearchParams();
|
|
@@ -270,6 +356,33 @@ var MergeRequestsClient = class extends GitLabApiClient {
|
|
|
270
356
|
};
|
|
271
357
|
|
|
272
358
|
// src/client/issues.ts
|
|
359
|
+
var LIST_ISSUE_NOTES_QUERY = `
|
|
360
|
+
${NOTES_FRAGMENT}
|
|
361
|
+
${NOTES_CONNECTION_FRAGMENT}
|
|
362
|
+
query listIssueNotes(
|
|
363
|
+
$projectPath: ID!
|
|
364
|
+
$issueIid: String!
|
|
365
|
+
$first: Int
|
|
366
|
+
$after: String
|
|
367
|
+
$last: Int
|
|
368
|
+
$before: String
|
|
369
|
+
$filter: WorkItemNotesFilterType
|
|
370
|
+
) {
|
|
371
|
+
project(fullPath: $projectPath) {
|
|
372
|
+
issue(iid: $issueIid) {
|
|
373
|
+
notes(
|
|
374
|
+
first: $first
|
|
375
|
+
after: $after
|
|
376
|
+
last: $last
|
|
377
|
+
before: $before
|
|
378
|
+
filter: $filter
|
|
379
|
+
) {
|
|
380
|
+
...NotesConnectionFields
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
`;
|
|
273
386
|
var IssuesClient = class extends GitLabApiClient {
|
|
274
387
|
async createIssue(projectId, title, options) {
|
|
275
388
|
const encodedProject = this.encodeProjectId(projectId);
|
|
@@ -305,12 +418,25 @@ var IssuesClient = class extends GitLabApiClient {
|
|
|
305
418
|
}
|
|
306
419
|
return this.fetch("GET", path2);
|
|
307
420
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
421
|
+
/**
|
|
422
|
+
* List notes on an issue using GraphQL API with pagination support
|
|
423
|
+
*/
|
|
424
|
+
async listIssueNotes(projectId, issueIid, options) {
|
|
425
|
+
const variables = {
|
|
426
|
+
projectPath: projectId,
|
|
427
|
+
issueIid: String(issueIid),
|
|
428
|
+
...buildPaginationVariables(options)
|
|
429
|
+
};
|
|
430
|
+
const result = await this.fetchGraphQL(LIST_ISSUE_NOTES_QUERY, variables);
|
|
431
|
+
const notes = result.project?.issue?.notes;
|
|
432
|
+
if (!notes) {
|
|
433
|
+
throw new Error("Issue not found or access denied");
|
|
434
|
+
}
|
|
435
|
+
return {
|
|
436
|
+
notes,
|
|
437
|
+
pageInfo: notes.pageInfo,
|
|
438
|
+
totalCount: notes.count
|
|
439
|
+
};
|
|
314
440
|
}
|
|
315
441
|
async listIssueDiscussions(projectId, issueIid) {
|
|
316
442
|
const encodedProject = this.encodeProjectId(projectId);
|
|
@@ -357,10 +483,6 @@ var IssuesClient = class extends GitLabApiClient {
|
|
|
357
483
|
{ resolved: false }
|
|
358
484
|
);
|
|
359
485
|
}
|
|
360
|
-
/**
|
|
361
|
-
* Get a single note from an issue
|
|
362
|
-
* API: GET /projects/:id/issues/:issue_iid/notes/:note_id
|
|
363
|
-
*/
|
|
364
486
|
async getIssueNote(projectId, issueIid, noteId) {
|
|
365
487
|
const encodedProject = this.encodeProjectId(projectId);
|
|
366
488
|
return this.fetch(
|
|
@@ -1084,20 +1206,163 @@ var SecurityClient = class extends GitLabApiClient {
|
|
|
1084
1206
|
};
|
|
1085
1207
|
|
|
1086
1208
|
// src/client/todos.ts
|
|
1209
|
+
var LIST_TODOS_QUERY = `
|
|
1210
|
+
query listTodos(
|
|
1211
|
+
$state: [TodoStateEnum!]
|
|
1212
|
+
$action: [TodoActionEnum!]
|
|
1213
|
+
$type: [TodoTargetEnum!]
|
|
1214
|
+
$projectId: [ID!]
|
|
1215
|
+
$groupId: [ID!]
|
|
1216
|
+
$authorId: [ID!]
|
|
1217
|
+
$first: Int
|
|
1218
|
+
$after: String
|
|
1219
|
+
$last: Int
|
|
1220
|
+
$before: String
|
|
1221
|
+
) {
|
|
1222
|
+
currentUser {
|
|
1223
|
+
todos(
|
|
1224
|
+
state: $state
|
|
1225
|
+
action: $action
|
|
1226
|
+
type: $type
|
|
1227
|
+
projectId: $projectId
|
|
1228
|
+
groupId: $groupId
|
|
1229
|
+
authorId: $authorId
|
|
1230
|
+
first: $first
|
|
1231
|
+
after: $after
|
|
1232
|
+
last: $last
|
|
1233
|
+
before: $before
|
|
1234
|
+
) {
|
|
1235
|
+
count
|
|
1236
|
+
pageInfo {
|
|
1237
|
+
hasNextPage
|
|
1238
|
+
hasPreviousPage
|
|
1239
|
+
startCursor
|
|
1240
|
+
endCursor
|
|
1241
|
+
}
|
|
1242
|
+
nodes {
|
|
1243
|
+
id
|
|
1244
|
+
body
|
|
1245
|
+
state
|
|
1246
|
+
action
|
|
1247
|
+
createdAt
|
|
1248
|
+
targetType
|
|
1249
|
+
targetUrl
|
|
1250
|
+
snoozedUntil
|
|
1251
|
+
project {
|
|
1252
|
+
id
|
|
1253
|
+
name
|
|
1254
|
+
fullPath
|
|
1255
|
+
}
|
|
1256
|
+
group {
|
|
1257
|
+
id
|
|
1258
|
+
name
|
|
1259
|
+
fullPath
|
|
1260
|
+
}
|
|
1261
|
+
author {
|
|
1262
|
+
id
|
|
1263
|
+
username
|
|
1264
|
+
name
|
|
1265
|
+
avatarUrl
|
|
1266
|
+
}
|
|
1267
|
+
targetEntity {
|
|
1268
|
+
__typename
|
|
1269
|
+
... on Issue {
|
|
1270
|
+
id
|
|
1271
|
+
title
|
|
1272
|
+
iid
|
|
1273
|
+
}
|
|
1274
|
+
... on MergeRequest {
|
|
1275
|
+
id
|
|
1276
|
+
title
|
|
1277
|
+
iid
|
|
1278
|
+
}
|
|
1279
|
+
... on Epic {
|
|
1280
|
+
id
|
|
1281
|
+
title
|
|
1282
|
+
iid
|
|
1283
|
+
}
|
|
1284
|
+
... on Commit {
|
|
1285
|
+
id
|
|
1286
|
+
title
|
|
1287
|
+
}
|
|
1288
|
+
... on DesignManagement__Design {
|
|
1289
|
+
id
|
|
1290
|
+
}
|
|
1291
|
+
... on AlertManagement__Alert {
|
|
1292
|
+
id
|
|
1293
|
+
title
|
|
1294
|
+
iid
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
`;
|
|
1087
1302
|
var TodosClient = class extends GitLabApiClient {
|
|
1088
1303
|
async listTodos(options) {
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1304
|
+
if (options?.first !== void 0 && options?.last !== void 0) {
|
|
1305
|
+
throw new Error(
|
|
1306
|
+
'Cannot specify both "first" and "last" pagination parameters. Use "first"/"after" for forward pagination or "last"/"before" for backward pagination.'
|
|
1307
|
+
);
|
|
1308
|
+
}
|
|
1309
|
+
const variables = {};
|
|
1310
|
+
if (options?.first !== void 0) {
|
|
1311
|
+
variables.first = options.first;
|
|
1312
|
+
} else if (options?.last === void 0) {
|
|
1313
|
+
variables.first = 20;
|
|
1314
|
+
}
|
|
1315
|
+
if (options?.after) variables.after = options.after;
|
|
1316
|
+
if (options?.last !== void 0) variables.last = options.last;
|
|
1317
|
+
if (options?.before) variables.before = options.before;
|
|
1318
|
+
if (options?.action) {
|
|
1319
|
+
variables.action = [this.mapTodoAction(options.action)];
|
|
1320
|
+
}
|
|
1321
|
+
if (options?.author_id) {
|
|
1322
|
+
variables.authorId = [`gid://gitlab/User/${options.author_id}`];
|
|
1323
|
+
}
|
|
1093
1324
|
if (options?.project_id) {
|
|
1094
|
-
|
|
1095
|
-
params.set("project_id", encodedProject);
|
|
1325
|
+
variables.projectId = [options.project_id];
|
|
1096
1326
|
}
|
|
1097
|
-
if (options?.group_id)
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1327
|
+
if (options?.group_id) {
|
|
1328
|
+
variables.groupId = [options.group_id];
|
|
1329
|
+
}
|
|
1330
|
+
if (options?.state) {
|
|
1331
|
+
variables.state = [options.state.toLowerCase()];
|
|
1332
|
+
}
|
|
1333
|
+
if (options?.type) {
|
|
1334
|
+
variables.type = [this.mapTodoTargetType(options.type)];
|
|
1335
|
+
}
|
|
1336
|
+
const result = await this.fetchGraphQL(LIST_TODOS_QUERY, variables);
|
|
1337
|
+
const todos = result.currentUser.todos;
|
|
1338
|
+
return {
|
|
1339
|
+
todos
|
|
1340
|
+
};
|
|
1341
|
+
}
|
|
1342
|
+
mapTodoAction(action) {
|
|
1343
|
+
const actionMap = {
|
|
1344
|
+
assigned: "ASSIGNED",
|
|
1345
|
+
mentioned: "MENTIONED",
|
|
1346
|
+
build_failed: "BUILD_FAILED",
|
|
1347
|
+
marked: "MARKED",
|
|
1348
|
+
approval_required: "APPROVAL_REQUIRED",
|
|
1349
|
+
unmergeable: "UNMERGEABLE",
|
|
1350
|
+
directly_addressed: "DIRECTLY_ADDRESSED",
|
|
1351
|
+
merge_train_removed: "MERGE_TRAIN_REMOVED",
|
|
1352
|
+
review_requested: "REVIEW_REQUESTED"
|
|
1353
|
+
};
|
|
1354
|
+
return actionMap[action] || action.toUpperCase();
|
|
1355
|
+
}
|
|
1356
|
+
mapTodoTargetType(type) {
|
|
1357
|
+
const typeMap = {
|
|
1358
|
+
Issue: "ISSUE",
|
|
1359
|
+
MergeRequest: "MERGEREQUEST",
|
|
1360
|
+
"DesignManagement::Design": "DESIGN",
|
|
1361
|
+
Alert: "ALERT",
|
|
1362
|
+
Commit: "COMMIT",
|
|
1363
|
+
Epic: "EPIC"
|
|
1364
|
+
};
|
|
1365
|
+
return typeMap[type] || type;
|
|
1101
1366
|
}
|
|
1102
1367
|
async markTodoAsDone(todoId) {
|
|
1103
1368
|
return this.fetch("POST", `/todos/${todoId}/mark_as_done`);
|
|
@@ -1106,11 +1371,37 @@ var TodosClient = class extends GitLabApiClient {
|
|
|
1106
1371
|
return this.fetch("POST", "/todos/mark_as_done");
|
|
1107
1372
|
}
|
|
1108
1373
|
async getTodoCount() {
|
|
1109
|
-
|
|
1374
|
+
const result = await this.fetchGraphQL(`query { currentUser { todos(state: [pending]) { count } } }`);
|
|
1375
|
+
return { count: result.currentUser.todos.count };
|
|
1110
1376
|
}
|
|
1111
1377
|
};
|
|
1112
1378
|
|
|
1113
1379
|
// src/client/epics.ts
|
|
1380
|
+
var LIST_EPIC_NOTES_QUERY = `
|
|
1381
|
+
${NOTES_FRAGMENT}
|
|
1382
|
+
${NOTES_CONNECTION_FRAGMENT}
|
|
1383
|
+
query listEpicNotes(
|
|
1384
|
+
$groupPath: ID!
|
|
1385
|
+
$epicIid: ID!
|
|
1386
|
+
$first: Int
|
|
1387
|
+
$after: String
|
|
1388
|
+
$last: Int
|
|
1389
|
+
$before: String
|
|
1390
|
+
) {
|
|
1391
|
+
group(fullPath: $groupPath) {
|
|
1392
|
+
epic(iid: $epicIid) {
|
|
1393
|
+
notes(
|
|
1394
|
+
first: $first
|
|
1395
|
+
after: $after
|
|
1396
|
+
last: $last
|
|
1397
|
+
before: $before
|
|
1398
|
+
) {
|
|
1399
|
+
...NotesConnectionFields
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
`;
|
|
1114
1405
|
var EpicsClient = class extends GitLabApiClient {
|
|
1115
1406
|
async getEpic(groupId, epicIid) {
|
|
1116
1407
|
const encodedGroup = encodeURIComponent(groupId);
|
|
@@ -1159,12 +1450,25 @@ var EpicsClient = class extends GitLabApiClient {
|
|
|
1159
1450
|
`/groups/${encodedGroup}/epics/${epicIid}/issues/${epicIssueId}`
|
|
1160
1451
|
);
|
|
1161
1452
|
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1453
|
+
/**
|
|
1454
|
+
* List notes on an epic using GraphQL API with pagination support
|
|
1455
|
+
*/
|
|
1456
|
+
async listEpicNotes(groupId, epicIid, options) {
|
|
1457
|
+
const variables = {
|
|
1458
|
+
groupPath: groupId,
|
|
1459
|
+
epicIid: String(epicIid),
|
|
1460
|
+
...buildPaginationVariables(options)
|
|
1461
|
+
};
|
|
1462
|
+
const result = await this.fetchGraphQL(LIST_EPIC_NOTES_QUERY, variables);
|
|
1463
|
+
const notes = result.group?.epic?.notes;
|
|
1464
|
+
if (!notes) {
|
|
1465
|
+
throw new Error("Epic not found or access denied");
|
|
1466
|
+
}
|
|
1467
|
+
return {
|
|
1468
|
+
notes,
|
|
1469
|
+
pageInfo: notes.pageInfo,
|
|
1470
|
+
totalCount: notes.count
|
|
1471
|
+
};
|
|
1168
1472
|
}
|
|
1169
1473
|
async listEpicDiscussions(groupId, epicIid) {
|
|
1170
1474
|
const encodedGroup = encodeURIComponent(groupId);
|
|
@@ -1195,10 +1499,6 @@ var EpicsClient = class extends GitLabApiClient {
|
|
|
1195
1499
|
{ body }
|
|
1196
1500
|
);
|
|
1197
1501
|
}
|
|
1198
|
-
/**
|
|
1199
|
-
* Get a single note from an epic
|
|
1200
|
-
* API: GET /groups/:id/epics/:epic_iid/notes/:note_id
|
|
1201
|
-
*/
|
|
1202
1502
|
async getEpicNote(groupId, epicIid, noteId) {
|
|
1203
1503
|
const encodedGroup = encodeURIComponent(groupId);
|
|
1204
1504
|
return this.fetch(
|
|
@@ -1209,6 +1509,30 @@ var EpicsClient = class extends GitLabApiClient {
|
|
|
1209
1509
|
};
|
|
1210
1510
|
|
|
1211
1511
|
// src/client/snippets.ts
|
|
1512
|
+
var LIST_SNIPPET_NOTES_QUERY = `
|
|
1513
|
+
${NOTES_FRAGMENT}
|
|
1514
|
+
${NOTES_CONNECTION_FRAGMENT}
|
|
1515
|
+
query listSnippetNotes(
|
|
1516
|
+
$snippetGid: SnippetID!
|
|
1517
|
+
$first: Int
|
|
1518
|
+
$after: String
|
|
1519
|
+
$last: Int
|
|
1520
|
+
$before: String
|
|
1521
|
+
) {
|
|
1522
|
+
snippets(ids: [$snippetGid]) {
|
|
1523
|
+
nodes {
|
|
1524
|
+
notes(
|
|
1525
|
+
first: $first
|
|
1526
|
+
after: $after
|
|
1527
|
+
last: $last
|
|
1528
|
+
before: $before
|
|
1529
|
+
) {
|
|
1530
|
+
...NotesConnectionFields
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
`;
|
|
1212
1536
|
var SnippetsClient = class extends GitLabApiClient {
|
|
1213
1537
|
async listSnippetDiscussions(projectId, snippetId) {
|
|
1214
1538
|
const encodedProject = this.encodeProjectId(projectId);
|
|
@@ -1224,12 +1548,30 @@ var SnippetsClient = class extends GitLabApiClient {
|
|
|
1224
1548
|
`/projects/${encodedProject}/snippets/${snippetId}/discussions/${discussionId}`
|
|
1225
1549
|
);
|
|
1226
1550
|
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1551
|
+
/**
|
|
1552
|
+
* List notes on a snippet using GraphQL API with pagination support
|
|
1553
|
+
*/
|
|
1554
|
+
async listSnippetNotes(projectId, snippetId, options) {
|
|
1555
|
+
const variables = {
|
|
1556
|
+
snippetGid: `gid://gitlab/ProjectSnippet/${snippetId}`,
|
|
1557
|
+
...buildPaginationVariables(options)
|
|
1558
|
+
};
|
|
1559
|
+
const result = await this.fetchGraphQL(LIST_SNIPPET_NOTES_QUERY, variables);
|
|
1560
|
+
const notes = result.snippets.nodes[0]?.notes || {
|
|
1561
|
+
nodes: [],
|
|
1562
|
+
pageInfo: {
|
|
1563
|
+
hasNextPage: false,
|
|
1564
|
+
hasPreviousPage: false,
|
|
1565
|
+
startCursor: null,
|
|
1566
|
+
endCursor: null
|
|
1567
|
+
},
|
|
1568
|
+
count: 0
|
|
1569
|
+
};
|
|
1570
|
+
return {
|
|
1571
|
+
notes,
|
|
1572
|
+
pageInfo: notes.pageInfo,
|
|
1573
|
+
totalCount: notes.count
|
|
1574
|
+
};
|
|
1233
1575
|
}
|
|
1234
1576
|
async createSnippetNote(projectId, snippetId, body, discussionId) {
|
|
1235
1577
|
const encodedProject = this.encodeProjectId(projectId);
|
|
@@ -1583,17 +1925,32 @@ Note: For a flattened list of all comments, use gitlab_list_mr_notes instead.`,
|
|
|
1583
1925
|
}
|
|
1584
1926
|
}),
|
|
1585
1927
|
gitlab_list_mr_notes: tool({
|
|
1586
|
-
description: `List all notes/comments on a merge request
|
|
1928
|
+
description: `List all notes/comments on a merge request using GraphQL API with pagination support.
|
|
1587
1929
|
Returns all comments including system notes, code review comments, and general discussion.
|
|
1588
|
-
This is easier to read than discussions which have nested structure
|
|
1930
|
+
This is easier to read than discussions which have nested structure.
|
|
1931
|
+
|
|
1932
|
+
The response includes pagination information (pageInfo) with cursors for fetching additional pages.
|
|
1933
|
+
Use 'after' with the 'endCursor' from pageInfo to get the next page.
|
|
1934
|
+
Use 'before' with the 'startCursor' from pageInfo to get the previous page.`,
|
|
1589
1935
|
args: {
|
|
1590
1936
|
project_id: z.string().describe("The project ID or URL-encoded path"),
|
|
1591
|
-
mr_iid: z.number().describe("The internal ID of the merge request")
|
|
1937
|
+
mr_iid: z.number().describe("The internal ID of the merge request"),
|
|
1938
|
+
first: z.number().optional().describe("Number of items to return from the beginning (default: 20, max: 100)"),
|
|
1939
|
+
after: z.string().optional().describe("Cursor for forward pagination - use endCursor from previous response"),
|
|
1940
|
+
last: z.number().optional().describe("Number of items to return from the end (for backward pagination)"),
|
|
1941
|
+
before: z.string().optional().describe("Cursor for backward pagination - use startCursor from previous response"),
|
|
1942
|
+
filter: z.enum(["ALL_NOTES", "ONLY_COMMENTS", "ONLY_ACTIVITY"]).optional().describe("Filter notes by type: ALL_NOTES (default), ONLY_COMMENTS, or ONLY_ACTIVITY")
|
|
1592
1943
|
},
|
|
1593
1944
|
execute: async (args, _ctx) => {
|
|
1594
1945
|
const client = getGitLabClient();
|
|
1595
|
-
const
|
|
1596
|
-
|
|
1946
|
+
const result = await client.listMrNotes(args.project_id, args.mr_iid, {
|
|
1947
|
+
first: args.first,
|
|
1948
|
+
after: args.after,
|
|
1949
|
+
last: args.last,
|
|
1950
|
+
before: args.before,
|
|
1951
|
+
filter: args.filter
|
|
1952
|
+
});
|
|
1953
|
+
return JSON.stringify(result, null, 2);
|
|
1597
1954
|
}
|
|
1598
1955
|
}),
|
|
1599
1956
|
gitlab_create_mr_note: tool({
|
|
@@ -1926,16 +2283,31 @@ Can filter by state, labels, assignee, milestone.`,
|
|
|
1926
2283
|
}
|
|
1927
2284
|
}),
|
|
1928
2285
|
gitlab_list_issue_notes: tool2({
|
|
1929
|
-
description: `List all notes/comments on an issue.
|
|
1930
|
-
Returns all comments including system notes in chronological order
|
|
2286
|
+
description: `List all notes/comments on an issue using GraphQL API with pagination support.
|
|
2287
|
+
Returns all comments including system notes in chronological order.
|
|
2288
|
+
|
|
2289
|
+
The response includes pagination information (pageInfo) with cursors for fetching additional pages.
|
|
2290
|
+
Use 'after' with the 'endCursor' from pageInfo to get the next page.
|
|
2291
|
+
Use 'before' with the 'startCursor' from pageInfo to get the previous page.`,
|
|
1931
2292
|
args: {
|
|
1932
2293
|
project_id: z2.string().describe("The project ID or URL-encoded path"),
|
|
1933
|
-
issue_iid: z2.number().describe("The internal ID of the issue")
|
|
2294
|
+
issue_iid: z2.number().describe("The internal ID of the issue"),
|
|
2295
|
+
first: z2.number().optional().describe("Number of items to return from the beginning (default: 20, max: 100)"),
|
|
2296
|
+
after: z2.string().optional().describe("Cursor for forward pagination - use endCursor from previous response"),
|
|
2297
|
+
last: z2.number().optional().describe("Number of items to return from the end (for backward pagination)"),
|
|
2298
|
+
before: z2.string().optional().describe("Cursor for backward pagination - use startCursor from previous response"),
|
|
2299
|
+
filter: z2.enum(["ALL_NOTES", "ONLY_COMMENTS", "ONLY_ACTIVITY"]).optional().describe("Filter notes by type: ALL_NOTES (default), ONLY_COMMENTS, or ONLY_ACTIVITY")
|
|
1934
2300
|
},
|
|
1935
2301
|
execute: async (args, _ctx) => {
|
|
1936
2302
|
const client = getGitLabClient();
|
|
1937
|
-
const
|
|
1938
|
-
|
|
2303
|
+
const result = await client.listIssueNotes(args.project_id, args.issue_iid, {
|
|
2304
|
+
first: args.first,
|
|
2305
|
+
after: args.after,
|
|
2306
|
+
last: args.last,
|
|
2307
|
+
before: args.before,
|
|
2308
|
+
filter: args.filter
|
|
2309
|
+
});
|
|
2310
|
+
return JSON.stringify(result, null, 2);
|
|
1939
2311
|
}
|
|
1940
2312
|
}),
|
|
1941
2313
|
gitlab_list_issue_discussions: tool2({
|
|
@@ -2190,16 +2562,29 @@ Removes the association between the issue and the epic.`,
|
|
|
2190
2562
|
}
|
|
2191
2563
|
}),
|
|
2192
2564
|
gitlab_list_epic_notes: tool3({
|
|
2193
|
-
description: `List all comments/notes on an epic
|
|
2194
|
-
Returns all comments in chronological order
|
|
2565
|
+
description: `List all comments/notes on an epic using GraphQL API with pagination support.
|
|
2566
|
+
Returns all comments in chronological order.
|
|
2567
|
+
|
|
2568
|
+
The response includes pagination information (pageInfo) with cursors for fetching additional pages.
|
|
2569
|
+
Use 'after' with the 'endCursor' from pageInfo to get the next page.
|
|
2570
|
+
Use 'before' with the 'startCursor' from pageInfo to get the previous page.`,
|
|
2195
2571
|
args: {
|
|
2196
2572
|
group_id: z3.string().describe("The group ID or URL-encoded path"),
|
|
2197
|
-
epic_iid: z3.number().describe("The internal ID of the epic")
|
|
2573
|
+
epic_iid: z3.number().describe("The internal ID of the epic"),
|
|
2574
|
+
first: z3.number().optional().describe("Number of items to return from the beginning (default: 20, max: 100)"),
|
|
2575
|
+
after: z3.string().optional().describe("Cursor for forward pagination - use endCursor from previous response"),
|
|
2576
|
+
last: z3.number().optional().describe("Number of items to return from the end (for backward pagination)"),
|
|
2577
|
+
before: z3.string().optional().describe("Cursor for backward pagination - use startCursor from previous response")
|
|
2198
2578
|
},
|
|
2199
2579
|
execute: async (args, _ctx) => {
|
|
2200
2580
|
const client = getGitLabClient();
|
|
2201
|
-
const
|
|
2202
|
-
|
|
2581
|
+
const result = await client.listEpicNotes(args.group_id, args.epic_iid, {
|
|
2582
|
+
first: args.first,
|
|
2583
|
+
after: args.after,
|
|
2584
|
+
last: args.last,
|
|
2585
|
+
before: args.before
|
|
2586
|
+
});
|
|
2587
|
+
return JSON.stringify(result, null, 2);
|
|
2203
2588
|
}
|
|
2204
2589
|
}),
|
|
2205
2590
|
gitlab_list_epic_discussions: tool3({
|
|
@@ -3210,16 +3595,29 @@ Use this to get the full context of a specific conversation.`,
|
|
|
3210
3595
|
}
|
|
3211
3596
|
}),
|
|
3212
3597
|
gitlab_list_snippet_notes: tool9({
|
|
3213
|
-
description: `List all notes/comments on a project snippet
|
|
3214
|
-
Returns all comments including system notes in chronological order
|
|
3598
|
+
description: `List all notes/comments on a project snippet using GraphQL API with pagination support.
|
|
3599
|
+
Returns all comments including system notes in chronological order.
|
|
3600
|
+
|
|
3601
|
+
The response includes pagination information (pageInfo) with cursors for fetching additional pages.
|
|
3602
|
+
Use 'after' with the 'endCursor' from pageInfo to get the next page.
|
|
3603
|
+
Use 'before' with the 'startCursor' from pageInfo to get the previous page.`,
|
|
3215
3604
|
args: {
|
|
3216
3605
|
project_id: z9.string().describe("The project ID or URL-encoded path"),
|
|
3217
|
-
snippet_id: z9.number().describe("The ID of the snippet")
|
|
3606
|
+
snippet_id: z9.number().describe("The ID of the snippet"),
|
|
3607
|
+
first: z9.number().optional().describe("Number of items to return from the beginning (default: 20, max: 100)"),
|
|
3608
|
+
after: z9.string().optional().describe("Cursor for forward pagination - use endCursor from previous response"),
|
|
3609
|
+
last: z9.number().optional().describe("Number of items to return from the end (for backward pagination)"),
|
|
3610
|
+
before: z9.string().optional().describe("Cursor for backward pagination - use startCursor from previous response")
|
|
3218
3611
|
},
|
|
3219
3612
|
execute: async (args, _ctx) => {
|
|
3220
3613
|
const client = getGitLabClient();
|
|
3221
|
-
const
|
|
3222
|
-
|
|
3614
|
+
const result = await client.listSnippetNotes(args.project_id, args.snippet_id, {
|
|
3615
|
+
first: args.first,
|
|
3616
|
+
after: args.after,
|
|
3617
|
+
last: args.last,
|
|
3618
|
+
before: args.before
|
|
3619
|
+
});
|
|
3620
|
+
return JSON.stringify(result, null, 2);
|
|
3223
3621
|
}
|
|
3224
3622
|
}),
|
|
3225
3623
|
gitlab_create_snippet_note: tool9({
|
|
@@ -3270,9 +3668,13 @@ import { tool as tool10 } from "@opencode-ai/plugin";
|
|
|
3270
3668
|
var z10 = tool10.schema;
|
|
3271
3669
|
var todoTools = {
|
|
3272
3670
|
gitlab_list_todos: tool10({
|
|
3273
|
-
description: `List TODO items for the current user.
|
|
3671
|
+
description: `List TODO items for the current user using GraphQL API with pagination support.
|
|
3274
3672
|
Returns a list of pending or done TODO items assigned to the authenticated user.
|
|
3275
|
-
TODOs are created when you are assigned to an issue/MR, mentioned in a comment, or when someone requests your review
|
|
3673
|
+
TODOs are created when you are assigned to an issue/MR, mentioned in a comment, or when someone requests your review.
|
|
3674
|
+
|
|
3675
|
+
The response includes pagination information (pageInfo) with cursors for fetching additional pages.
|
|
3676
|
+
Use 'after' with the 'endCursor' from pageInfo to get the next page.
|
|
3677
|
+
Use 'before' with the 'startCursor' from pageInfo to get the previous page.`,
|
|
3276
3678
|
args: {
|
|
3277
3679
|
action: z10.enum([
|
|
3278
3680
|
"assigned",
|
|
@@ -3289,21 +3691,27 @@ TODOs are created when you are assigned to an issue/MR, mentioned in a comment,
|
|
|
3289
3691
|
project_id: z10.string().optional().describe("Filter by project ID or path"),
|
|
3290
3692
|
group_id: z10.string().optional().describe("Filter by group ID"),
|
|
3291
3693
|
state: z10.enum(["pending", "done"]).optional().describe("Filter by state (default: pending)"),
|
|
3292
|
-
type: z10.enum(["Issue", "MergeRequest", "DesignManagement::Design", "Alert"]).optional().describe("Filter by target type"),
|
|
3293
|
-
|
|
3694
|
+
type: z10.enum(["Issue", "MergeRequest", "DesignManagement::Design", "Alert", "Epic", "Commit"]).optional().describe("Filter by target type"),
|
|
3695
|
+
first: z10.number().optional().describe("Number of items to return from the beginning (default: 20, max: 100)"),
|
|
3696
|
+
after: z10.string().optional().describe("Cursor for forward pagination - use endCursor from previous response"),
|
|
3697
|
+
last: z10.number().optional().describe("Number of items to return from the end (for backward pagination)"),
|
|
3698
|
+
before: z10.string().optional().describe("Cursor for backward pagination - use startCursor from previous response")
|
|
3294
3699
|
},
|
|
3295
3700
|
execute: async (args, _ctx) => {
|
|
3296
3701
|
const client = getGitLabClient();
|
|
3297
|
-
const
|
|
3702
|
+
const result = await client.listTodos({
|
|
3298
3703
|
action: args.action,
|
|
3299
3704
|
author_id: args.author_id,
|
|
3300
3705
|
project_id: args.project_id,
|
|
3301
3706
|
group_id: args.group_id,
|
|
3302
3707
|
state: args.state,
|
|
3303
3708
|
type: args.type,
|
|
3304
|
-
|
|
3709
|
+
first: args.first,
|
|
3710
|
+
after: args.after,
|
|
3711
|
+
last: args.last,
|
|
3712
|
+
before: args.before
|
|
3305
3713
|
});
|
|
3306
|
-
return JSON.stringify(
|
|
3714
|
+
return JSON.stringify(result, null, 2);
|
|
3307
3715
|
}
|
|
3308
3716
|
}),
|
|
3309
3717
|
gitlab_mark_todo_done: tool10({
|
package/package.json
CHANGED
|
Binary file
|