@aaronsb/jira-cloud-mcp 0.1.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/README.md +70 -0
- package/build/client/jira-client.js +721 -0
- package/build/handlers/board-handlers.js +326 -0
- package/build/handlers/filter-handlers.js +427 -0
- package/build/handlers/issue-handlers.js +311 -0
- package/build/handlers/project-handlers.js +368 -0
- package/build/handlers/resource-handlers.js +320 -0
- package/build/handlers/search-handlers.js +103 -0
- package/build/handlers/sprint-handlers.js +433 -0
- package/build/handlers/tool-resource-handlers.js +1185 -0
- package/build/health-check.js +67 -0
- package/build/index.js +141 -0
- package/build/schemas/request-schemas.js +187 -0
- package/build/schemas/tool-schemas.js +450 -0
- package/build/types/index.js +1 -0
- package/build/utils/formatters/base-formatter.js +58 -0
- package/build/utils/formatters/board-formatter.js +63 -0
- package/build/utils/formatters/filter-formatter.js +66 -0
- package/build/utils/formatters/index.js +7 -0
- package/build/utils/formatters/issue-formatter.js +84 -0
- package/build/utils/formatters/project-formatter.js +55 -0
- package/build/utils/formatters/search-formatter.js +62 -0
- package/build/utils/formatters/sprint-formatter.js +111 -0
- package/build/utils/text-processing.js +343 -0
- package/package.json +65 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
export const toolSchemas = {
|
|
2
|
+
// Filter Management API
|
|
3
|
+
manage_jira_filter: {
|
|
4
|
+
name: 'manage_jira_filter',
|
|
5
|
+
description: 'Filter management with CRUD operations and issue retrieval',
|
|
6
|
+
inputSchema: {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
operation: {
|
|
10
|
+
type: 'string',
|
|
11
|
+
enum: ['get', 'create', 'update', 'delete', 'list', 'execute_filter', 'execute_jql'],
|
|
12
|
+
description: 'Operation to perform on the filter',
|
|
13
|
+
},
|
|
14
|
+
// Parameters for get, update, delete, execute_filter operations
|
|
15
|
+
filterId: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description: 'The ID of the filter. Required for get, update, delete, and execute_filter operations. Can also use snake_case "filter_id".',
|
|
18
|
+
},
|
|
19
|
+
// Parameters for create and update operations
|
|
20
|
+
name: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
description: 'Name of the filter. Required for create operation, optional for update.',
|
|
23
|
+
},
|
|
24
|
+
jql: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
description: 'JQL query string. Supports a wide range of search patterns:\n\n' +
|
|
27
|
+
'# Portfolio/Plans Queries\n' +
|
|
28
|
+
'- Find child issues: issue in portfolioChildIssuesOf("PROJ-123")\n' +
|
|
29
|
+
'- Combined portfolio search: issue in portfolioChildIssuesOf("PROJ-123") AND status = "In Progress"\n' +
|
|
30
|
+
'- Multiple portfolios: issue in portfolioChildIssuesOf("PROJ-123") OR issue in portfolioChildIssuesOf("PROJ-456")\n\n' +
|
|
31
|
+
'# Common Search Patterns\n' +
|
|
32
|
+
'- Assigned issues: assignee = currentUser()\n' +
|
|
33
|
+
'- Unassigned issues: assignee IS EMPTY\n' +
|
|
34
|
+
'- Recent changes: status CHANGED AFTER -1w\n' +
|
|
35
|
+
'- Multiple statuses: status IN ("In Progress", "Under Review", "Testing")\n' +
|
|
36
|
+
'- Priority tasks: priority = High AND status = Open\n' +
|
|
37
|
+
'- Component search: component = "User Interface" OR component = "API"\n\n' +
|
|
38
|
+
'# Advanced Functions\n' +
|
|
39
|
+
'- Sort results: ORDER BY created DESC\n' +
|
|
40
|
+
'- Track changes: status WAS "Resolved" AND status = "Open"\n' +
|
|
41
|
+
'- Team filters: assignee IN MEMBERSOF("developers")\n\n' +
|
|
42
|
+
'JQL supports complex combinations using AND, OR, NOT operators and parentheses for grouping. ' +
|
|
43
|
+
'All text values are case-sensitive and must be enclosed in quotes when they contain spaces.',
|
|
44
|
+
},
|
|
45
|
+
description: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
description: 'Description of the filter. Optional for create/update.',
|
|
48
|
+
},
|
|
49
|
+
favourite: {
|
|
50
|
+
type: 'boolean',
|
|
51
|
+
description: 'Whether to mark the filter as a favorite. Optional for create/update.',
|
|
52
|
+
},
|
|
53
|
+
// Parameters for list operation
|
|
54
|
+
startAt: {
|
|
55
|
+
type: 'integer',
|
|
56
|
+
description: 'Index of the first filter to return (0-based). Used for list and execute_jql operations. Can also use snake_case "start_at".',
|
|
57
|
+
default: 0,
|
|
58
|
+
},
|
|
59
|
+
maxResults: {
|
|
60
|
+
type: 'integer',
|
|
61
|
+
description: 'Maximum number of filters or issues to return. Used for list and execute_jql operations. Can also use snake_case "max_results".',
|
|
62
|
+
default: 50,
|
|
63
|
+
},
|
|
64
|
+
// Parameters for sharing
|
|
65
|
+
sharePermissions: {
|
|
66
|
+
type: 'array',
|
|
67
|
+
items: {
|
|
68
|
+
type: 'object',
|
|
69
|
+
properties: {
|
|
70
|
+
type: {
|
|
71
|
+
type: 'string',
|
|
72
|
+
enum: ['group', 'project', 'global'],
|
|
73
|
+
description: 'Type of share permission',
|
|
74
|
+
},
|
|
75
|
+
group: {
|
|
76
|
+
type: 'string',
|
|
77
|
+
description: 'Group name (required when type is "group")',
|
|
78
|
+
},
|
|
79
|
+
project: {
|
|
80
|
+
type: 'string',
|
|
81
|
+
description: 'Project key (required when type is "project")',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
required: ['type'],
|
|
85
|
+
},
|
|
86
|
+
description: 'Share permissions for the filter. Optional for create/update. Can also use snake_case "share_permissions".',
|
|
87
|
+
},
|
|
88
|
+
// Common expansion options
|
|
89
|
+
expand: {
|
|
90
|
+
type: 'array',
|
|
91
|
+
items: {
|
|
92
|
+
type: 'string',
|
|
93
|
+
enum: ['jql', 'description', 'permissions', 'issue_count', 'issue_details', 'transitions', 'comments_preview'],
|
|
94
|
+
},
|
|
95
|
+
description: 'Optional fields to include in the response',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
required: ['operation'],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
// Sprint Management API
|
|
102
|
+
manage_jira_sprint: {
|
|
103
|
+
name: 'manage_jira_sprint',
|
|
104
|
+
description: 'Sprint management with CRUD operations and issue management',
|
|
105
|
+
inputSchema: {
|
|
106
|
+
type: 'object',
|
|
107
|
+
properties: {
|
|
108
|
+
operation: {
|
|
109
|
+
type: 'string',
|
|
110
|
+
enum: ['get', 'create', 'update', 'delete', 'list', 'manage_issues'],
|
|
111
|
+
description: 'Operation to perform on the sprint',
|
|
112
|
+
},
|
|
113
|
+
// Parameters for get operation
|
|
114
|
+
sprintId: {
|
|
115
|
+
type: 'integer',
|
|
116
|
+
description: 'The ID of the sprint. Required for get, update, delete, and manage_issues operations. Can also use snake_case "sprint_id".',
|
|
117
|
+
},
|
|
118
|
+
// Parameters for create operation
|
|
119
|
+
boardId: {
|
|
120
|
+
type: 'integer',
|
|
121
|
+
description: 'The ID of the board. Required for create and list operations. Can also use snake_case "board_id".',
|
|
122
|
+
},
|
|
123
|
+
name: {
|
|
124
|
+
type: 'string',
|
|
125
|
+
description: 'Name of the sprint. Required for create operation, optional for update.',
|
|
126
|
+
},
|
|
127
|
+
// Common parameters for create and update
|
|
128
|
+
startDate: {
|
|
129
|
+
type: 'string',
|
|
130
|
+
description: 'Start date for the sprint in ISO format (e.g., "2025-03-20T00:00:00.000Z"). Can also use snake_case "start_date".',
|
|
131
|
+
},
|
|
132
|
+
endDate: {
|
|
133
|
+
type: 'string',
|
|
134
|
+
description: 'End date for the sprint in ISO format (e.g., "2025-04-03T00:00:00.000Z"). Can also use snake_case "end_date".',
|
|
135
|
+
},
|
|
136
|
+
goal: {
|
|
137
|
+
type: 'string',
|
|
138
|
+
description: 'Goal or objective for the sprint',
|
|
139
|
+
},
|
|
140
|
+
state: {
|
|
141
|
+
type: 'string',
|
|
142
|
+
enum: ['future', 'active', 'closed'],
|
|
143
|
+
description: 'Sprint state. Used for filtering in list operation or changing state in update operation.',
|
|
144
|
+
},
|
|
145
|
+
// Parameters for list operation
|
|
146
|
+
startAt: {
|
|
147
|
+
type: 'integer',
|
|
148
|
+
description: 'Index of the first sprint to return (0-based). Used for list operation. Can also use snake_case "start_at".',
|
|
149
|
+
default: 0,
|
|
150
|
+
},
|
|
151
|
+
maxResults: {
|
|
152
|
+
type: 'integer',
|
|
153
|
+
description: 'Maximum number of sprints to return. Used for list operation. Can also use snake_case "max_results".',
|
|
154
|
+
default: 50,
|
|
155
|
+
},
|
|
156
|
+
// Parameters for manage_issues operation
|
|
157
|
+
add: {
|
|
158
|
+
type: 'array',
|
|
159
|
+
items: {
|
|
160
|
+
type: 'string',
|
|
161
|
+
},
|
|
162
|
+
description: 'Array of issue keys to add to the sprint. Used for manage_issues operation.',
|
|
163
|
+
},
|
|
164
|
+
remove: {
|
|
165
|
+
type: 'array',
|
|
166
|
+
items: {
|
|
167
|
+
type: 'string',
|
|
168
|
+
},
|
|
169
|
+
description: 'Array of issue keys to remove from the sprint. Used for manage_issues operation.',
|
|
170
|
+
},
|
|
171
|
+
// Common expansion options
|
|
172
|
+
expand: {
|
|
173
|
+
type: 'array',
|
|
174
|
+
items: {
|
|
175
|
+
type: 'string',
|
|
176
|
+
enum: ['issues', 'report', 'board'],
|
|
177
|
+
},
|
|
178
|
+
description: 'Optional fields to include in the response',
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
required: ['operation'],
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
// Issue Management API
|
|
185
|
+
manage_jira_issue: {
|
|
186
|
+
name: 'manage_jira_issue',
|
|
187
|
+
description: 'Issue management with CRUD operations, transitions, comments, and linking',
|
|
188
|
+
inputSchema: {
|
|
189
|
+
type: 'object',
|
|
190
|
+
properties: {
|
|
191
|
+
operation: {
|
|
192
|
+
type: 'string',
|
|
193
|
+
enum: ['create', 'get', 'update', 'delete', 'transition', 'comment', 'link'],
|
|
194
|
+
description: 'Operation to perform on the issue',
|
|
195
|
+
},
|
|
196
|
+
// Parameters for get, update, delete, transition, comment, and link operations
|
|
197
|
+
issueKey: {
|
|
198
|
+
type: 'string',
|
|
199
|
+
description: 'The Jira issue key (e.g., WORK-123). Required for all operations except create. Can also use snake_case "issue_key".',
|
|
200
|
+
},
|
|
201
|
+
// Parameters for create operation
|
|
202
|
+
projectKey: {
|
|
203
|
+
type: 'string',
|
|
204
|
+
description: 'Project key (e.g., PROJ). Required for create operation. Can also use snake_case "project_key".',
|
|
205
|
+
},
|
|
206
|
+
// Common parameters for create and update
|
|
207
|
+
summary: {
|
|
208
|
+
type: 'string',
|
|
209
|
+
description: 'Issue summary/title. Required for create, optional for update.',
|
|
210
|
+
},
|
|
211
|
+
description: {
|
|
212
|
+
type: 'string',
|
|
213
|
+
description: 'Detailed description of the issue. Optional for create/update.',
|
|
214
|
+
},
|
|
215
|
+
issueType: {
|
|
216
|
+
type: 'string',
|
|
217
|
+
description: 'Type of issue (e.g., Story, Bug, Task). Required for create. Can also use snake_case "issue_type".',
|
|
218
|
+
},
|
|
219
|
+
priority: {
|
|
220
|
+
type: 'string',
|
|
221
|
+
description: 'Issue priority (e.g., High, Medium, Low). Optional for create/update.',
|
|
222
|
+
},
|
|
223
|
+
assignee: {
|
|
224
|
+
type: 'string',
|
|
225
|
+
description: 'Username of the assignee. Optional for create/update.',
|
|
226
|
+
},
|
|
227
|
+
labels: {
|
|
228
|
+
type: 'array',
|
|
229
|
+
items: {
|
|
230
|
+
type: 'string'
|
|
231
|
+
},
|
|
232
|
+
description: 'Array of labels to apply to the issue. Optional for create/update.',
|
|
233
|
+
},
|
|
234
|
+
customFields: {
|
|
235
|
+
type: 'object',
|
|
236
|
+
description: 'Custom field values as key-value pairs. Optional for create/update. Can also use snake_case "custom_fields".',
|
|
237
|
+
},
|
|
238
|
+
// Parameters for update operation
|
|
239
|
+
parent: {
|
|
240
|
+
type: ['string', 'null'],
|
|
241
|
+
description: 'The key of the parent issue (e.g., PROJ-123) or null to remove parent. Optional for update.',
|
|
242
|
+
},
|
|
243
|
+
// Parameters for transition operation
|
|
244
|
+
transitionId: {
|
|
245
|
+
type: 'string',
|
|
246
|
+
description: 'The ID of the transition to perform. Required for transition operation. Can also use snake_case "transition_id".',
|
|
247
|
+
},
|
|
248
|
+
// Parameters for comment and transition operations
|
|
249
|
+
comment: {
|
|
250
|
+
type: 'string',
|
|
251
|
+
description: 'Comment text. Required for comment operation, optional for transition.',
|
|
252
|
+
},
|
|
253
|
+
// Parameters for link operation
|
|
254
|
+
linkType: {
|
|
255
|
+
type: 'string',
|
|
256
|
+
description: 'Type of link between issues (e.g., "relates to", "blocks"). Required for link operation. Can also use snake_case "link_type".',
|
|
257
|
+
},
|
|
258
|
+
linkedIssueKey: {
|
|
259
|
+
type: 'string',
|
|
260
|
+
description: 'The key of the issue to link to. Required for link operation. Can also use snake_case "linked_issue_key".',
|
|
261
|
+
},
|
|
262
|
+
// Common expansion options
|
|
263
|
+
expand: {
|
|
264
|
+
type: 'array',
|
|
265
|
+
items: {
|
|
266
|
+
type: 'string',
|
|
267
|
+
enum: ['comments', 'transitions', 'attachments', 'related_issues', 'history'],
|
|
268
|
+
},
|
|
269
|
+
description: 'Optional fields to include in the response',
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
required: ['operation'],
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
// Project Management API
|
|
276
|
+
manage_jira_project: {
|
|
277
|
+
name: 'manage_jira_project',
|
|
278
|
+
description: 'Project management with CRUD operations and related data',
|
|
279
|
+
inputSchema: {
|
|
280
|
+
type: 'object',
|
|
281
|
+
properties: {
|
|
282
|
+
operation: {
|
|
283
|
+
type: 'string',
|
|
284
|
+
enum: ['get', 'create', 'update', 'delete', 'list'],
|
|
285
|
+
description: 'Operation to perform on the project',
|
|
286
|
+
},
|
|
287
|
+
// Parameters for get, update, delete operations
|
|
288
|
+
projectKey: {
|
|
289
|
+
type: 'string',
|
|
290
|
+
description: 'The Jira project key (e.g., PROJ). Required for get, update, and delete operations. Can also use snake_case "project_key".',
|
|
291
|
+
},
|
|
292
|
+
// Parameters for create operation
|
|
293
|
+
name: {
|
|
294
|
+
type: 'string',
|
|
295
|
+
description: 'Name of the project. Required for create operation, optional for update.',
|
|
296
|
+
},
|
|
297
|
+
key: {
|
|
298
|
+
type: 'string',
|
|
299
|
+
description: 'Project key. Required for create operation.',
|
|
300
|
+
},
|
|
301
|
+
// Common parameters for create and update
|
|
302
|
+
description: {
|
|
303
|
+
type: 'string',
|
|
304
|
+
description: 'Description of the project. Optional for create/update.',
|
|
305
|
+
},
|
|
306
|
+
lead: {
|
|
307
|
+
type: 'string',
|
|
308
|
+
description: 'Username of the project lead. Optional for create/update.',
|
|
309
|
+
},
|
|
310
|
+
// Parameters for list operation
|
|
311
|
+
startAt: {
|
|
312
|
+
type: 'integer',
|
|
313
|
+
description: 'Index of the first project to return (0-based). Used for list operation. Can also use snake_case "start_at".',
|
|
314
|
+
default: 0,
|
|
315
|
+
},
|
|
316
|
+
maxResults: {
|
|
317
|
+
type: 'integer',
|
|
318
|
+
description: 'Maximum number of projects to return. Used for list operation. Can also use snake_case "max_results".',
|
|
319
|
+
default: 50,
|
|
320
|
+
},
|
|
321
|
+
// Common expansion options
|
|
322
|
+
expand: {
|
|
323
|
+
type: 'array',
|
|
324
|
+
items: {
|
|
325
|
+
type: 'string',
|
|
326
|
+
enum: ['boards', 'components', 'versions', 'recent_issues'],
|
|
327
|
+
},
|
|
328
|
+
description: 'Optional fields to include in the response',
|
|
329
|
+
},
|
|
330
|
+
include_status_counts: {
|
|
331
|
+
type: 'boolean',
|
|
332
|
+
description: 'Whether to include issue counts by status',
|
|
333
|
+
default: true,
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
required: ['operation'],
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
// Board Management API
|
|
340
|
+
manage_jira_board: {
|
|
341
|
+
name: 'manage_jira_board',
|
|
342
|
+
description: 'Board management with CRUD operations and related data',
|
|
343
|
+
inputSchema: {
|
|
344
|
+
type: 'object',
|
|
345
|
+
properties: {
|
|
346
|
+
operation: {
|
|
347
|
+
type: 'string',
|
|
348
|
+
enum: ['get', 'list', 'create', 'update', 'delete', 'get_configuration'],
|
|
349
|
+
description: 'Operation to perform on the board',
|
|
350
|
+
},
|
|
351
|
+
// Parameters for get, update, delete, get_configuration operations
|
|
352
|
+
boardId: {
|
|
353
|
+
type: 'integer',
|
|
354
|
+
description: 'The ID of the board. Required for get, update, delete, and get_configuration operations. Can also use snake_case "board_id".',
|
|
355
|
+
},
|
|
356
|
+
// Parameters for create operation
|
|
357
|
+
name: {
|
|
358
|
+
type: 'string',
|
|
359
|
+
description: 'Name of the board. Required for create operation, optional for update.',
|
|
360
|
+
},
|
|
361
|
+
type: {
|
|
362
|
+
type: 'string',
|
|
363
|
+
enum: ['scrum', 'kanban'],
|
|
364
|
+
description: 'Type of board. Required for create operation.',
|
|
365
|
+
},
|
|
366
|
+
projectKey: {
|
|
367
|
+
type: 'string',
|
|
368
|
+
description: 'Project key for the board. Required for create operation. Can also use snake_case "project_key".',
|
|
369
|
+
},
|
|
370
|
+
// Parameters for list operation
|
|
371
|
+
startAt: {
|
|
372
|
+
type: 'integer',
|
|
373
|
+
description: 'Index of the first board to return (0-based). Used for list operation. Can also use snake_case "start_at".',
|
|
374
|
+
default: 0,
|
|
375
|
+
},
|
|
376
|
+
maxResults: {
|
|
377
|
+
type: 'integer',
|
|
378
|
+
description: 'Maximum number of boards to return. Used for list operation. Can also use snake_case "max_results".',
|
|
379
|
+
default: 50,
|
|
380
|
+
},
|
|
381
|
+
// Common expansion options
|
|
382
|
+
expand: {
|
|
383
|
+
type: 'array',
|
|
384
|
+
items: {
|
|
385
|
+
type: 'string',
|
|
386
|
+
enum: ['sprints', 'issues', 'configuration'],
|
|
387
|
+
},
|
|
388
|
+
description: 'Optional fields to include in the response',
|
|
389
|
+
},
|
|
390
|
+
include_sprints: {
|
|
391
|
+
type: 'boolean',
|
|
392
|
+
description: 'Whether to include active sprints for each board (shorthand for expand: ["sprints"])',
|
|
393
|
+
default: false,
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
required: ['operation'],
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
// Enhanced Search API - will be deprecated after consolidation
|
|
400
|
+
search_jira_issues: {
|
|
401
|
+
name: 'search_jira_issues',
|
|
402
|
+
description: 'Search for issues using JQL with enhanced results and optional expansions',
|
|
403
|
+
inputSchema: {
|
|
404
|
+
type: 'object',
|
|
405
|
+
properties: {
|
|
406
|
+
jql: {
|
|
407
|
+
type: 'string',
|
|
408
|
+
description: 'JQL query string. Supports a wide range of search patterns:\n\n' +
|
|
409
|
+
'# Portfolio/Plans Queries\n' +
|
|
410
|
+
'- Find child issues: issue in portfolioChildIssuesOf("PROJ-123")\n' +
|
|
411
|
+
'- Combined portfolio search: issue in portfolioChildIssuesOf("PROJ-123") AND status = "In Progress"\n' +
|
|
412
|
+
'- Multiple portfolios: issue in portfolioChildIssuesOf("PROJ-123") OR issue in portfolioChildIssuesOf("PROJ-456")\n\n' +
|
|
413
|
+
'# Common Search Patterns\n' +
|
|
414
|
+
'- Assigned issues: assignee = currentUser()\n' +
|
|
415
|
+
'- Unassigned issues: assignee IS EMPTY\n' +
|
|
416
|
+
'- Recent changes: status CHANGED AFTER -1w\n' +
|
|
417
|
+
'- Multiple statuses: status IN ("In Progress", "Under Review", "Testing")\n' +
|
|
418
|
+
'- Priority tasks: priority = High AND status = Open\n' +
|
|
419
|
+
'- Component search: component = "User Interface" OR component = "API"\n\n' +
|
|
420
|
+
'# Advanced Functions\n' +
|
|
421
|
+
'- Sort results: ORDER BY created DESC\n' +
|
|
422
|
+
'- Track changes: status WAS "Resolved" AND status = "Open"\n' +
|
|
423
|
+
'- Team filters: assignee IN MEMBERSOF("developers")\n\n' +
|
|
424
|
+
'JQL supports complex combinations using AND, OR, NOT operators and parentheses for grouping. ' +
|
|
425
|
+
'All text values are case-sensitive and must be enclosed in quotes when they contain spaces.',
|
|
426
|
+
},
|
|
427
|
+
startAt: {
|
|
428
|
+
type: 'number',
|
|
429
|
+
description: 'Index of the first issue to return (0-based). Can also use snake_case "start_at".',
|
|
430
|
+
default: 0,
|
|
431
|
+
},
|
|
432
|
+
maxResults: {
|
|
433
|
+
type: 'number',
|
|
434
|
+
description: 'Maximum number of issues to return (default: 25, max: 100). Can also use snake_case "max_results".',
|
|
435
|
+
default: 25,
|
|
436
|
+
maximum: 100,
|
|
437
|
+
},
|
|
438
|
+
expand: {
|
|
439
|
+
type: 'array',
|
|
440
|
+
items: {
|
|
441
|
+
type: 'string',
|
|
442
|
+
enum: ['issue_details', 'transitions', 'comments_preview'],
|
|
443
|
+
},
|
|
444
|
+
description: 'Optional fields to include in the response',
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
required: ['jql'],
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base formatter for consistent response structure across all entity types
|
|
3
|
+
*/
|
|
4
|
+
export class BaseFormatter {
|
|
5
|
+
/**
|
|
6
|
+
* Format a response with the standard structure
|
|
7
|
+
* @param data The main data for the response
|
|
8
|
+
* @param metadata Optional metadata about the response
|
|
9
|
+
* @param summary Optional summary information
|
|
10
|
+
* @returns A formatted response object
|
|
11
|
+
*/
|
|
12
|
+
static formatResponse(data, metadata, summary) {
|
|
13
|
+
return {
|
|
14
|
+
data,
|
|
15
|
+
...(metadata && { _metadata: metadata }),
|
|
16
|
+
...(summary && { _summary: summary }),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create metadata for a response
|
|
21
|
+
* @param options Metadata options
|
|
22
|
+
* @returns Response metadata
|
|
23
|
+
*/
|
|
24
|
+
static createMetadata(options) {
|
|
25
|
+
const metadata = {};
|
|
26
|
+
if (options.expansions && options.expansions.length > 0) {
|
|
27
|
+
metadata.expansions = options.expansions;
|
|
28
|
+
}
|
|
29
|
+
if (options.related && Object.keys(options.related).length > 0) {
|
|
30
|
+
metadata.related = options.related;
|
|
31
|
+
}
|
|
32
|
+
if (options.pagination) {
|
|
33
|
+
const { startAt, maxResults, total } = options.pagination;
|
|
34
|
+
metadata.pagination = {
|
|
35
|
+
startAt,
|
|
36
|
+
maxResults,
|
|
37
|
+
total,
|
|
38
|
+
hasMore: startAt + maxResults < total,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return metadata;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create a summary for a response
|
|
45
|
+
* @param options Summary options
|
|
46
|
+
* @returns Response summary
|
|
47
|
+
*/
|
|
48
|
+
static createSummary(options) {
|
|
49
|
+
const summary = {};
|
|
50
|
+
if (options.status_counts && Object.keys(options.status_counts).length > 0) {
|
|
51
|
+
summary.status_counts = options.status_counts;
|
|
52
|
+
}
|
|
53
|
+
if (options.suggested_actions && options.suggested_actions.length > 0) {
|
|
54
|
+
summary.suggested_actions = options.suggested_actions;
|
|
55
|
+
}
|
|
56
|
+
return summary;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { BaseFormatter } from './base-formatter.js';
|
|
2
|
+
export class BoardFormatter {
|
|
3
|
+
/**
|
|
4
|
+
* Format a board response with the standard structure and optional expansions
|
|
5
|
+
* @param board The board data
|
|
6
|
+
* @param options Expansion options
|
|
7
|
+
* @returns A formatted board response
|
|
8
|
+
*/
|
|
9
|
+
static formatBoard(board, options = {}) {
|
|
10
|
+
// Create metadata with available expansions
|
|
11
|
+
const metadata = this.createBoardMetadata(board, options);
|
|
12
|
+
// Create summary
|
|
13
|
+
const summary = this.createBoardSummary(board);
|
|
14
|
+
return BaseFormatter.formatResponse(board, metadata, summary);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create metadata for a board response
|
|
18
|
+
*/
|
|
19
|
+
static createBoardMetadata(board, options) {
|
|
20
|
+
// Determine which expansions are available but not included
|
|
21
|
+
const availableExpansions = [];
|
|
22
|
+
if (!options.sprints && !board.sprints) {
|
|
23
|
+
availableExpansions.push('sprints');
|
|
24
|
+
}
|
|
25
|
+
if (!options.issues) {
|
|
26
|
+
availableExpansions.push('issues');
|
|
27
|
+
}
|
|
28
|
+
if (!options.configuration) {
|
|
29
|
+
availableExpansions.push('configuration');
|
|
30
|
+
}
|
|
31
|
+
// Create related entities map
|
|
32
|
+
const related = {};
|
|
33
|
+
if (board.location?.projectId) {
|
|
34
|
+
related.project = board.location.projectName || `Project ${board.location.projectId}`;
|
|
35
|
+
}
|
|
36
|
+
return BaseFormatter.createMetadata({
|
|
37
|
+
expansions: availableExpansions,
|
|
38
|
+
related
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a summary for a board response
|
|
43
|
+
*/
|
|
44
|
+
static createBoardSummary(board) {
|
|
45
|
+
const suggestedActions = [
|
|
46
|
+
{
|
|
47
|
+
text: `View all issues on ${board.name}`
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
// Add sprint-related actions if sprints are available
|
|
51
|
+
if (board.sprints && board.sprints.length > 0) {
|
|
52
|
+
const activeSprints = board.sprints.filter(sprint => sprint.state === 'active');
|
|
53
|
+
if (activeSprints.length > 0) {
|
|
54
|
+
suggestedActions.push({
|
|
55
|
+
text: `View active sprint: ${activeSprints[0].name}`
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return BaseFormatter.createSummary({
|
|
60
|
+
suggested_actions: suggestedActions
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { BaseFormatter } from './base-formatter.js';
|
|
2
|
+
export class FilterFormatter {
|
|
3
|
+
/**
|
|
4
|
+
* Format a filter response with the standard structure and optional expansions
|
|
5
|
+
* @param filter The filter data
|
|
6
|
+
* @param options Expansion options
|
|
7
|
+
* @returns A formatted filter response
|
|
8
|
+
*/
|
|
9
|
+
static formatFilter(filter, options = {}) {
|
|
10
|
+
// Create metadata with available expansions
|
|
11
|
+
const metadata = this.createFilterMetadata(filter, options);
|
|
12
|
+
// Create summary
|
|
13
|
+
const summary = this.createFilterSummary(filter);
|
|
14
|
+
return BaseFormatter.formatResponse(filter, metadata, summary);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create metadata for a filter response
|
|
18
|
+
*/
|
|
19
|
+
static createFilterMetadata(filter, options) {
|
|
20
|
+
// Determine which expansions are available but not included
|
|
21
|
+
const availableExpansions = [];
|
|
22
|
+
if (!options.jql && !filter.jql) {
|
|
23
|
+
availableExpansions.push('jql');
|
|
24
|
+
}
|
|
25
|
+
if (!options.description && !filter.description) {
|
|
26
|
+
availableExpansions.push('description');
|
|
27
|
+
}
|
|
28
|
+
if (!options.permissions && !filter.sharePermissions) {
|
|
29
|
+
availableExpansions.push('permissions');
|
|
30
|
+
}
|
|
31
|
+
if (!options.issue_count && filter.issueCount === undefined) {
|
|
32
|
+
availableExpansions.push('issue_count');
|
|
33
|
+
}
|
|
34
|
+
// Create related entities map
|
|
35
|
+
const related = {
|
|
36
|
+
owner: filter.owner
|
|
37
|
+
};
|
|
38
|
+
return BaseFormatter.createMetadata({
|
|
39
|
+
expansions: availableExpansions,
|
|
40
|
+
related
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create a summary for a filter response
|
|
45
|
+
*/
|
|
46
|
+
static createFilterSummary(filter) {
|
|
47
|
+
const suggestedActions = [
|
|
48
|
+
{
|
|
49
|
+
text: `View filter results: ${filter.name}`
|
|
50
|
+
}
|
|
51
|
+
];
|
|
52
|
+
if (filter.jql) {
|
|
53
|
+
suggestedActions.push({
|
|
54
|
+
text: `Edit JQL: ${filter.name}`
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (!filter.favourite) {
|
|
58
|
+
suggestedActions.push({
|
|
59
|
+
text: `Add to favorites`
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return BaseFormatter.createSummary({
|
|
63
|
+
suggested_actions: suggestedActions
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './base-formatter.js';
|
|
2
|
+
export * from './issue-formatter.js';
|
|
3
|
+
export * from './project-formatter.js';
|
|
4
|
+
export * from './search-formatter.js';
|
|
5
|
+
export * from './board-formatter.js';
|
|
6
|
+
export * from './sprint-formatter.js';
|
|
7
|
+
export * from './filter-formatter.js';
|