@agllama/mcp 0.1.0 → 0.1.1
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 +161 -162
- package/dist/api-client.d.ts +45 -2
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +108 -2
- package/dist/api-client.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +140 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/backlog.d.ts +13 -7
- package/dist/tools/backlog.d.ts.map +1 -1
- package/dist/tools/backlog.js +59 -9
- package/dist/tools/backlog.js.map +1 -1
- package/dist/tools/boardConfig.d.ts +65 -0
- package/dist/tools/boardConfig.d.ts.map +1 -0
- package/dist/tools/boardConfig.js +150 -0
- package/dist/tools/boardConfig.js.map +1 -0
- package/dist/tools/boardTemplates.d.ts +47 -0
- package/dist/tools/boardTemplates.d.ts.map +1 -0
- package/dist/tools/boardTemplates.js +119 -0
- package/dist/tools/boardTemplates.js.map +1 -0
- package/dist/tools/boards.d.ts +20 -20
- package/dist/tools/boards.d.ts.map +1 -1
- package/dist/tools/boards.js +121 -19
- package/dist/tools/boards.js.map +1 -1
- package/dist/tools/comments.d.ts +24 -24
- package/dist/tools/comments.d.ts.map +1 -1
- package/dist/tools/comments.js +136 -23
- package/dist/tools/comments.js.map +1 -1
- package/dist/tools/connect.d.ts.map +1 -1
- package/dist/tools/connect.js +7 -18
- package/dist/tools/connect.js.map +1 -1
- package/dist/tools/context.d.ts +10 -7
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +57 -7
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/documents.d.ts +99 -0
- package/dist/tools/documents.d.ts.map +1 -0
- package/dist/tools/documents.js +252 -0
- package/dist/tools/documents.js.map +1 -0
- package/dist/tools/help.d.ts.map +1 -1
- package/dist/tools/help.js +70 -6
- package/dist/tools/help.js.map +1 -1
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/issueLinks.d.ts +12 -12
- package/dist/tools/issueLinks.d.ts.map +1 -1
- package/dist/tools/issueLinks.js +69 -12
- package/dist/tools/issueLinks.js.map +1 -1
- package/dist/tools/issues.d.ts +208 -28
- package/dist/tools/issues.d.ts.map +1 -1
- package/dist/tools/issues.js +483 -35
- package/dist/tools/issues.js.map +1 -1
- package/dist/tools/labels.d.ts +18 -18
- package/dist/tools/labels.d.ts.map +1 -1
- package/dist/tools/labels.js +102 -17
- package/dist/tools/labels.js.map +1 -1
- package/dist/tools/members.d.ts.map +1 -1
- package/dist/tools/members.js +2 -2
- package/dist/tools/members.js.map +1 -1
- package/dist/tools/organizations.d.ts.map +1 -1
- package/dist/tools/organizations.js +8 -8
- package/dist/tools/organizations.js.map +1 -1
- package/dist/tools/projects.d.ts.map +1 -1
- package/dist/tools/projects.js +11 -11
- package/dist/tools/projects.js.map +1 -1
- package/dist/tools/search.d.ts +4 -4
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +28 -5
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/session.d.ts +38 -0
- package/dist/tools/session.d.ts.map +1 -0
- package/dist/tools/session.js +158 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/tools/sprints.d.ts +18 -18
- package/dist/tools/sprints.d.ts.map +1 -1
- package/dist/tools/sprints.js +115 -30
- package/dist/tools/sprints.js.map +1 -1
- package/dist/tools/status.d.ts +6 -6
- package/dist/tools/status.d.ts.map +1 -1
- package/dist/tools/status.js +45 -8
- package/dist/tools/status.js.map +1 -1
- package/dist/tools/workflows.d.ts.map +1 -1
- package/dist/tools/workflows.js +19 -19
- package/dist/tools/workflows.js.map +1 -1
- package/dist/types.d.ts +123 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/column-instructions.d.ts +21 -0
- package/dist/utils/column-instructions.d.ts.map +1 -0
- package/dist/utils/column-instructions.js +54 -0
- package/dist/utils/column-instructions.js.map +1 -0
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issues.d.ts","sourceRoot":"","sources":["../../src/tools/issues.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"issues.d.ts","sourceRoot":"","sources":["../../src/tools/issues.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/issues.js
CHANGED
|
@@ -1,24 +1,58 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { getApiClient, LlamaApiError } from '../api-client.js';
|
|
3
|
+
import { getColumnInstructionsForStatus } from '../utils/column-instructions.js';
|
|
4
|
+
import { getSessionDefaults } from './session.js';
|
|
3
5
|
// ============================================
|
|
4
6
|
// Get Issue
|
|
5
7
|
// ============================================
|
|
6
8
|
export const getIssueToolName = 'llama_get_issue';
|
|
7
9
|
export const getIssueToolDescription = `Get full details for a specific issue by its key (e.g., "PROJ-123").
|
|
8
|
-
Returns complete issue information including description, comments, and history.`;
|
|
10
|
+
Returns complete issue information including description, comments, and history. Uses session defaults if orgSlug/projectKey not provided.`;
|
|
9
11
|
export const getIssueToolSchema = z.object({
|
|
10
|
-
orgSlug: z
|
|
11
|
-
|
|
12
|
+
orgSlug: z
|
|
13
|
+
.string()
|
|
14
|
+
.optional()
|
|
15
|
+
.describe('Organization slug (uses session default if not provided)'),
|
|
16
|
+
projectKey: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe('Project key (uses session default if not provided)'),
|
|
12
20
|
issueKey: z.string().describe('Issue key (e.g., "PROJ-123")'),
|
|
13
21
|
});
|
|
14
22
|
export async function executeGetIssue(input) {
|
|
15
23
|
try {
|
|
24
|
+
const session = await getSessionDefaults();
|
|
25
|
+
const orgSlug = input.orgSlug ?? session?.orgSlug;
|
|
26
|
+
const projectKey = input.projectKey ?? session?.projectKey;
|
|
27
|
+
if (!orgSlug) {
|
|
28
|
+
return JSON.stringify({
|
|
29
|
+
success: false,
|
|
30
|
+
error: 'orgSlug is required. Either provide it or set session context with llama_set_context first.',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (!projectKey) {
|
|
34
|
+
return JSON.stringify({
|
|
35
|
+
success: false,
|
|
36
|
+
error: 'projectKey is required. Either provide it or set session context with llama_set_context first.',
|
|
37
|
+
});
|
|
38
|
+
}
|
|
16
39
|
const client = getApiClient();
|
|
17
|
-
|
|
40
|
+
// Record tool call
|
|
41
|
+
try {
|
|
42
|
+
await client.recordToolCall('llama_get_issue', {
|
|
43
|
+
orgSlug,
|
|
44
|
+
projectKey,
|
|
45
|
+
issueKey: input.issueKey,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Ignore recording errors
|
|
50
|
+
}
|
|
51
|
+
const issue = await client.getIssue(orgSlug, projectKey, input.issueKey);
|
|
18
52
|
return JSON.stringify({
|
|
19
53
|
success: true,
|
|
20
54
|
issue,
|
|
21
|
-
}
|
|
55
|
+
});
|
|
22
56
|
}
|
|
23
57
|
catch (error) {
|
|
24
58
|
if (error instanceof LlamaApiError) {
|
|
@@ -26,12 +60,12 @@ export async function executeGetIssue(input) {
|
|
|
26
60
|
success: false,
|
|
27
61
|
error: `Failed to get issue: ${error.message}`,
|
|
28
62
|
statusCode: error.statusCode,
|
|
29
|
-
}
|
|
63
|
+
});
|
|
30
64
|
}
|
|
31
65
|
return JSON.stringify({
|
|
32
66
|
success: false,
|
|
33
67
|
error: error instanceof Error ? error.message : 'Unknown error',
|
|
34
|
-
}
|
|
68
|
+
});
|
|
35
69
|
}
|
|
36
70
|
}
|
|
37
71
|
// ============================================
|
|
@@ -43,11 +77,19 @@ export const createIssueToolDescription = `Create a new issue in Llama.
|
|
|
43
77
|
Issue types: EPIC, STORY, TASK, BUG, SUBTASK
|
|
44
78
|
Priority levels: CRITICAL, HIGH, MEDIUM (default), LOW, TRIVIAL
|
|
45
79
|
|
|
46
|
-
|
|
47
|
-
|
|
80
|
+
**IMPORTANT: SUBTASK type REQUIRES parentKey** - You must provide the parent issue key (e.g., "PROJ-123") when creating a subtask. The parent must be a STORY, TASK, or BUG.
|
|
81
|
+
|
|
82
|
+
To add to a sprint, provide the sprintId from llama_context.
|
|
83
|
+
Uses session defaults if orgSlug/projectKey not provided.`;
|
|
48
84
|
export const createIssueToolSchema = z.object({
|
|
49
|
-
orgSlug: z
|
|
50
|
-
|
|
85
|
+
orgSlug: z
|
|
86
|
+
.string()
|
|
87
|
+
.optional()
|
|
88
|
+
.describe('Organization slug (uses session default if not provided)'),
|
|
89
|
+
projectKey: z
|
|
90
|
+
.string()
|
|
91
|
+
.optional()
|
|
92
|
+
.describe('Project key (uses session default if not provided)'),
|
|
51
93
|
summary: z.string().describe('Issue title/summary'),
|
|
52
94
|
description: z.string().optional().describe('Detailed description (markdown supported)'),
|
|
53
95
|
type: z
|
|
@@ -59,33 +101,67 @@ export const createIssueToolSchema = z.object({
|
|
|
59
101
|
.describe('Priority level (default: MEDIUM)'),
|
|
60
102
|
assigneeId: z.string().optional().describe('User ID to assign the issue to'),
|
|
61
103
|
sprintId: z.string().optional().describe('Sprint ID to add the issue to'),
|
|
62
|
-
parentKey: z.string().optional().describe('Parent issue key for
|
|
104
|
+
parentKey: z.string().optional().describe('Parent issue key - REQUIRED for SUBTASK type (e.g., "PROJ-123"). Parent must be STORY, TASK, or BUG.'),
|
|
63
105
|
epicKey: z.string().optional().describe('Epic issue key to link this issue to (for STORY, TASK, BUG)'),
|
|
64
106
|
estimate: z.number().optional().describe('Story points estimate'),
|
|
65
107
|
labels: z.array(z.string()).optional().describe('Labels to attach'),
|
|
66
108
|
});
|
|
67
109
|
export async function executeCreateIssue(input) {
|
|
68
110
|
try {
|
|
111
|
+
const session = await getSessionDefaults();
|
|
112
|
+
const orgSlug = input.orgSlug ?? session?.orgSlug;
|
|
113
|
+
const projectKey = input.projectKey ?? session?.projectKey;
|
|
114
|
+
if (!orgSlug) {
|
|
115
|
+
return JSON.stringify({
|
|
116
|
+
success: false,
|
|
117
|
+
error: 'orgSlug is required. Either provide it or set session context with llama_set_context first.',
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
if (!projectKey) {
|
|
121
|
+
return JSON.stringify({
|
|
122
|
+
success: false,
|
|
123
|
+
error: 'projectKey is required. Either provide it or set session context with llama_set_context first.',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
69
126
|
const client = getApiClient();
|
|
127
|
+
// Validate SUBTASK requires parentKey
|
|
128
|
+
if (input.type === 'SUBTASK' && !input.parentKey) {
|
|
129
|
+
return JSON.stringify({
|
|
130
|
+
success: false,
|
|
131
|
+
error: 'SUBTASK type requires parentKey. You must specify the parent issue key (e.g., "PROJ-123") when creating a subtask. The parent must be a STORY, TASK, or BUG.',
|
|
132
|
+
});
|
|
133
|
+
}
|
|
70
134
|
// Resolve epicKey to parentId if provided
|
|
71
135
|
let parentId;
|
|
72
136
|
if (input.epicKey) {
|
|
73
137
|
// Look up the Epic to get its ID
|
|
74
|
-
const epic = await client.getIssue(
|
|
138
|
+
const epic = await client.getIssue(orgSlug, projectKey, input.epicKey);
|
|
75
139
|
if (epic.type !== 'EPIC') {
|
|
76
140
|
return JSON.stringify({
|
|
77
141
|
success: false,
|
|
78
142
|
error: `Issue ${input.epicKey} is not an Epic (type: ${epic.type})`,
|
|
79
|
-
}
|
|
143
|
+
});
|
|
80
144
|
}
|
|
81
145
|
parentId = epic.id;
|
|
82
146
|
}
|
|
83
147
|
else if (input.parentKey) {
|
|
84
148
|
// For subtasks, look up the parent to get its ID
|
|
85
|
-
const parent = await client.getIssue(
|
|
149
|
+
const parent = await client.getIssue(orgSlug, projectKey, input.parentKey);
|
|
86
150
|
parentId = parent.id;
|
|
87
151
|
}
|
|
88
|
-
|
|
152
|
+
// Record tool call
|
|
153
|
+
try {
|
|
154
|
+
await client.recordToolCall('llama_create_issue', {
|
|
155
|
+
orgSlug,
|
|
156
|
+
projectKey,
|
|
157
|
+
summary: input.summary,
|
|
158
|
+
type: input.type,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Ignore recording errors
|
|
163
|
+
}
|
|
164
|
+
const issue = await client.createIssue(orgSlug, projectKey, {
|
|
89
165
|
summary: input.summary,
|
|
90
166
|
description: input.description,
|
|
91
167
|
type: input.type,
|
|
@@ -106,7 +182,7 @@ export async function executeCreateIssue(input) {
|
|
|
106
182
|
status: issue.status,
|
|
107
183
|
priority: issue.priority,
|
|
108
184
|
},
|
|
109
|
-
}
|
|
185
|
+
});
|
|
110
186
|
}
|
|
111
187
|
catch (error) {
|
|
112
188
|
if (error instanceof LlamaApiError) {
|
|
@@ -114,12 +190,12 @@ export async function executeCreateIssue(input) {
|
|
|
114
190
|
success: false,
|
|
115
191
|
error: `Failed to create issue: ${error.message}`,
|
|
116
192
|
statusCode: error.statusCode,
|
|
117
|
-
}
|
|
193
|
+
});
|
|
118
194
|
}
|
|
119
195
|
return JSON.stringify({
|
|
120
196
|
success: false,
|
|
121
197
|
error: error instanceof Error ? error.message : 'Unknown error',
|
|
122
|
-
}
|
|
198
|
+
});
|
|
123
199
|
}
|
|
124
200
|
}
|
|
125
201
|
// ============================================
|
|
@@ -128,10 +204,17 @@ export async function executeCreateIssue(input) {
|
|
|
128
204
|
export const updateIssueToolName = 'llama_update_issue';
|
|
129
205
|
export const updateIssueToolDescription = `Update an existing issue's fields.
|
|
130
206
|
Only include the fields you want to change.
|
|
131
|
-
Set assigneeId or sprintId to null to unassign/remove from sprint
|
|
207
|
+
Set assigneeId or sprintId to null to unassign/remove from sprint.
|
|
208
|
+
Uses session defaults if orgSlug/projectKey not provided.`;
|
|
132
209
|
export const updateIssueToolSchema = z.object({
|
|
133
|
-
orgSlug: z
|
|
134
|
-
|
|
210
|
+
orgSlug: z
|
|
211
|
+
.string()
|
|
212
|
+
.optional()
|
|
213
|
+
.describe('Organization slug (uses session default if not provided)'),
|
|
214
|
+
projectKey: z
|
|
215
|
+
.string()
|
|
216
|
+
.optional()
|
|
217
|
+
.describe('Project key (uses session default if not provided)'),
|
|
135
218
|
issueKey: z.string().describe('Issue key to update'),
|
|
136
219
|
summary: z.string().optional().describe('New summary'),
|
|
137
220
|
description: z.string().optional().describe('New description'),
|
|
@@ -158,7 +241,22 @@ export const updateIssueToolSchema = z.object({
|
|
|
158
241
|
});
|
|
159
242
|
export async function executeUpdateIssue(input) {
|
|
160
243
|
try {
|
|
161
|
-
const
|
|
244
|
+
const session = await getSessionDefaults();
|
|
245
|
+
const orgSlug = input.orgSlug ?? session?.orgSlug;
|
|
246
|
+
const projectKey = input.projectKey ?? session?.projectKey;
|
|
247
|
+
if (!orgSlug) {
|
|
248
|
+
return JSON.stringify({
|
|
249
|
+
success: false,
|
|
250
|
+
error: 'orgSlug is required. Either provide it or set session context with llama_set_context first.',
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (!projectKey) {
|
|
254
|
+
return JSON.stringify({
|
|
255
|
+
success: false,
|
|
256
|
+
error: 'projectKey is required. Either provide it or set session context with llama_set_context first.',
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
const { issueKey, ...updates } = input;
|
|
162
260
|
const client = getApiClient();
|
|
163
261
|
// Build update object with only provided fields
|
|
164
262
|
const updateFields = {};
|
|
@@ -192,13 +290,30 @@ export async function executeUpdateIssue(input) {
|
|
|
192
290
|
return JSON.stringify({
|
|
193
291
|
success: false,
|
|
194
292
|
error: `Issue ${updates.epicKey} is not an Epic (type: ${epic.type})`,
|
|
195
|
-
}
|
|
293
|
+
});
|
|
196
294
|
}
|
|
197
295
|
updateFields.parentId = epic.id;
|
|
198
296
|
}
|
|
199
297
|
}
|
|
298
|
+
// Record tool call
|
|
299
|
+
try {
|
|
300
|
+
await client.recordToolCall('llama_update_issue', {
|
|
301
|
+
orgSlug,
|
|
302
|
+
projectKey,
|
|
303
|
+
issueKey,
|
|
304
|
+
updates: Object.keys(updateFields),
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
// Ignore recording errors
|
|
309
|
+
}
|
|
200
310
|
const issue = await client.updateIssue(orgSlug, projectKey, issueKey, updateFields);
|
|
201
|
-
|
|
311
|
+
// Check if status was changed and get column instructions
|
|
312
|
+
let columnInstructions = null;
|
|
313
|
+
if (updates.statusId !== undefined) {
|
|
314
|
+
columnInstructions = await getColumnInstructionsForStatus(orgSlug, projectKey, updates.statusId);
|
|
315
|
+
}
|
|
316
|
+
const response = {
|
|
202
317
|
success: true,
|
|
203
318
|
message: `Updated issue ${issue.key}`,
|
|
204
319
|
issue: {
|
|
@@ -209,7 +324,12 @@ export async function executeUpdateIssue(input) {
|
|
|
209
324
|
priority: issue.priority,
|
|
210
325
|
assignee: issue.assignee,
|
|
211
326
|
},
|
|
212
|
-
}
|
|
327
|
+
};
|
|
328
|
+
// Add column instructions if they exist
|
|
329
|
+
if (columnInstructions) {
|
|
330
|
+
response.columnInstructions = columnInstructions;
|
|
331
|
+
}
|
|
332
|
+
return JSON.stringify(response);
|
|
213
333
|
}
|
|
214
334
|
catch (error) {
|
|
215
335
|
if (error instanceof LlamaApiError) {
|
|
@@ -217,12 +337,12 @@ export async function executeUpdateIssue(input) {
|
|
|
217
337
|
success: false,
|
|
218
338
|
error: `Failed to update issue: ${error.message}`,
|
|
219
339
|
statusCode: error.statusCode,
|
|
220
|
-
}
|
|
340
|
+
});
|
|
221
341
|
}
|
|
222
342
|
return JSON.stringify({
|
|
223
343
|
success: false,
|
|
224
344
|
error: error instanceof Error ? error.message : 'Unknown error',
|
|
225
|
-
}
|
|
345
|
+
});
|
|
226
346
|
}
|
|
227
347
|
}
|
|
228
348
|
// ============================================
|
|
@@ -230,20 +350,53 @@ export async function executeUpdateIssue(input) {
|
|
|
230
350
|
// ============================================
|
|
231
351
|
export const deleteIssueToolName = 'llama_delete_issue';
|
|
232
352
|
export const deleteIssueToolDescription = `Soft-delete an issue. The issue can be restored later if needed.
|
|
233
|
-
Use with caution - this action removes the issue from views
|
|
353
|
+
Use with caution - this action removes the issue from views.
|
|
354
|
+
Uses session defaults if orgSlug/projectKey not provided.`;
|
|
234
355
|
export const deleteIssueToolSchema = z.object({
|
|
235
|
-
orgSlug: z
|
|
236
|
-
|
|
356
|
+
orgSlug: z
|
|
357
|
+
.string()
|
|
358
|
+
.optional()
|
|
359
|
+
.describe('Organization slug (uses session default if not provided)'),
|
|
360
|
+
projectKey: z
|
|
361
|
+
.string()
|
|
362
|
+
.optional()
|
|
363
|
+
.describe('Project key (uses session default if not provided)'),
|
|
237
364
|
issueKey: z.string().describe('Issue key to delete'),
|
|
238
365
|
});
|
|
239
366
|
export async function executeDeleteIssue(input) {
|
|
240
367
|
try {
|
|
368
|
+
const session = await getSessionDefaults();
|
|
369
|
+
const orgSlug = input.orgSlug ?? session?.orgSlug;
|
|
370
|
+
const projectKey = input.projectKey ?? session?.projectKey;
|
|
371
|
+
if (!orgSlug) {
|
|
372
|
+
return JSON.stringify({
|
|
373
|
+
success: false,
|
|
374
|
+
error: 'orgSlug is required. Either provide it or set session context with llama_set_context first.',
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
if (!projectKey) {
|
|
378
|
+
return JSON.stringify({
|
|
379
|
+
success: false,
|
|
380
|
+
error: 'projectKey is required. Either provide it or set session context with llama_set_context first.',
|
|
381
|
+
});
|
|
382
|
+
}
|
|
241
383
|
const client = getApiClient();
|
|
242
|
-
|
|
384
|
+
// Record tool call
|
|
385
|
+
try {
|
|
386
|
+
await client.recordToolCall('llama_delete_issue', {
|
|
387
|
+
orgSlug,
|
|
388
|
+
projectKey,
|
|
389
|
+
issueKey: input.issueKey,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
// Ignore recording errors
|
|
394
|
+
}
|
|
395
|
+
await client.deleteIssue(orgSlug, projectKey, input.issueKey);
|
|
243
396
|
return JSON.stringify({
|
|
244
397
|
success: true,
|
|
245
398
|
message: `Deleted issue ${input.issueKey}`,
|
|
246
|
-
}
|
|
399
|
+
});
|
|
247
400
|
}
|
|
248
401
|
catch (error) {
|
|
249
402
|
if (error instanceof LlamaApiError) {
|
|
@@ -251,12 +404,307 @@ export async function executeDeleteIssue(input) {
|
|
|
251
404
|
success: false,
|
|
252
405
|
error: `Failed to delete issue: ${error.message}`,
|
|
253
406
|
statusCode: error.statusCode,
|
|
254
|
-
}
|
|
407
|
+
});
|
|
255
408
|
}
|
|
256
409
|
return JSON.stringify({
|
|
257
410
|
success: false,
|
|
258
411
|
error: error instanceof Error ? error.message : 'Unknown error',
|
|
259
|
-
}
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// ============================================
|
|
416
|
+
// Batch Create Issues
|
|
417
|
+
// ============================================
|
|
418
|
+
export const batchCreateIssuesToolName = 'llama_batch_create_issues';
|
|
419
|
+
export const batchCreateIssuesToolDescription = `Create multiple issues in one call (max 20).
|
|
420
|
+
Returns individual success/failure for each issue.
|
|
421
|
+
Uses session defaults if orgSlug/projectKey not provided.
|
|
422
|
+
|
|
423
|
+
**IMPORTANT: SUBTASK type REQUIRES parentKey** - When creating subtasks, you must provide the parentKey field.
|
|
424
|
+
|
|
425
|
+
Example:
|
|
426
|
+
issues: [
|
|
427
|
+
{ summary: "Issue 1", type: "TASK" },
|
|
428
|
+
{ summary: "Issue 2", type: "BUG", priority: "HIGH" },
|
|
429
|
+
{ summary: "Subtask 1", type: "SUBTASK", parentKey: "PROJ-1" }
|
|
430
|
+
]`;
|
|
431
|
+
export const batchCreateIssuesToolSchema = z.object({
|
|
432
|
+
orgSlug: z
|
|
433
|
+
.string()
|
|
434
|
+
.optional()
|
|
435
|
+
.describe('Organization slug (uses session default if not provided)'),
|
|
436
|
+
projectKey: z
|
|
437
|
+
.string()
|
|
438
|
+
.optional()
|
|
439
|
+
.describe('Project key (uses session default if not provided)'),
|
|
440
|
+
issues: z
|
|
441
|
+
.array(z.object({
|
|
442
|
+
summary: z.string().describe('Issue title/summary'),
|
|
443
|
+
type: z.enum(['EPIC', 'STORY', 'TASK', 'BUG', 'SUBTASK']).describe('Issue type'),
|
|
444
|
+
description: z.string().optional().nullable().describe('Description (markdown)'),
|
|
445
|
+
priority: z
|
|
446
|
+
.enum(['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'TRIVIAL'])
|
|
447
|
+
.optional()
|
|
448
|
+
.describe('Priority (default: MEDIUM)'),
|
|
449
|
+
assigneeId: z.string().optional().nullable().describe('Assignee user ID'),
|
|
450
|
+
sprintId: z.string().optional().nullable().describe('Sprint ID'),
|
|
451
|
+
estimate: z.number().optional().nullable().describe('Story points'),
|
|
452
|
+
labels: z.array(z.string()).optional().describe('Labels'),
|
|
453
|
+
epicKey: z.string().optional().nullable().describe('Epic key to link to (for STORY, TASK, BUG)'),
|
|
454
|
+
parentKey: z.string().optional().nullable().describe('Parent issue key - REQUIRED for SUBTASK type'),
|
|
455
|
+
}))
|
|
456
|
+
.min(1)
|
|
457
|
+
.max(20)
|
|
458
|
+
.describe('Issues to create (max 20)'),
|
|
459
|
+
});
|
|
460
|
+
export async function executeBatchCreateIssues(input) {
|
|
461
|
+
try {
|
|
462
|
+
const session = await getSessionDefaults();
|
|
463
|
+
const orgSlug = input.orgSlug ?? session?.orgSlug;
|
|
464
|
+
const projectKey = input.projectKey ?? session?.projectKey;
|
|
465
|
+
if (!orgSlug) {
|
|
466
|
+
return JSON.stringify({
|
|
467
|
+
success: false,
|
|
468
|
+
error: 'orgSlug is required. Either provide it or set session context with llama_set_context first.',
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
if (!projectKey) {
|
|
472
|
+
return JSON.stringify({
|
|
473
|
+
success: false,
|
|
474
|
+
error: 'projectKey is required. Either provide it or set session context with llama_set_context first.',
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
const client = getApiClient();
|
|
478
|
+
// Validate SUBTASK issues have parentKey
|
|
479
|
+
const subtasksWithoutParent = input.issues.filter((i) => i.type === 'SUBTASK' && !i.parentKey);
|
|
480
|
+
if (subtasksWithoutParent.length > 0) {
|
|
481
|
+
return JSON.stringify({
|
|
482
|
+
success: false,
|
|
483
|
+
error: `SUBTASK type requires parentKey. The following issues are missing parentKey: ${subtasksWithoutParent.map((i) => i.summary).join(', ')}`,
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
// Record tool call
|
|
487
|
+
try {
|
|
488
|
+
await client.recordToolCall('llama_batch_create_issues', {
|
|
489
|
+
orgSlug,
|
|
490
|
+
projectKey,
|
|
491
|
+
count: input.issues.length,
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
catch {
|
|
495
|
+
// Ignore recording errors
|
|
496
|
+
}
|
|
497
|
+
const issues = input.issues.map((i) => ({
|
|
498
|
+
summary: i.summary,
|
|
499
|
+
type: i.type,
|
|
500
|
+
description: i.description,
|
|
501
|
+
priority: i.priority,
|
|
502
|
+
assigneeId: i.assigneeId,
|
|
503
|
+
sprintId: i.sprintId,
|
|
504
|
+
estimate: i.estimate,
|
|
505
|
+
labels: i.labels,
|
|
506
|
+
epicKey: i.epicKey,
|
|
507
|
+
parentKey: i.parentKey,
|
|
508
|
+
}));
|
|
509
|
+
const result = await client.batchCreateIssues(orgSlug, projectKey, issues);
|
|
510
|
+
return JSON.stringify({
|
|
511
|
+
success: true,
|
|
512
|
+
message: `Created ${result.succeeded} of ${result.total} issues`,
|
|
513
|
+
...result,
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
catch (error) {
|
|
517
|
+
if (error instanceof LlamaApiError) {
|
|
518
|
+
return JSON.stringify({
|
|
519
|
+
success: false,
|
|
520
|
+
error: `Failed to batch create issues: ${error.message}`,
|
|
521
|
+
statusCode: error.statusCode,
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
return JSON.stringify({
|
|
525
|
+
success: false,
|
|
526
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
// ============================================
|
|
531
|
+
// Batch Update Status
|
|
532
|
+
// ============================================
|
|
533
|
+
export const batchUpdateStatusToolName = 'llama_batch_update_status';
|
|
534
|
+
export const batchUpdateStatusToolDescription = `Move multiple issues to the same status in one call (max 50).
|
|
535
|
+
Returns individual success/failure for each issue.
|
|
536
|
+
Uses session defaults if orgSlug/projectKey not provided.
|
|
537
|
+
|
|
538
|
+
First use llama_context to get valid status IDs.`;
|
|
539
|
+
export const batchUpdateStatusToolSchema = z.object({
|
|
540
|
+
orgSlug: z
|
|
541
|
+
.string()
|
|
542
|
+
.optional()
|
|
543
|
+
.describe('Organization slug (uses session default if not provided)'),
|
|
544
|
+
projectKey: z
|
|
545
|
+
.string()
|
|
546
|
+
.optional()
|
|
547
|
+
.describe('Project key (uses session default if not provided)'),
|
|
548
|
+
issueKeys: z
|
|
549
|
+
.array(z.string())
|
|
550
|
+
.min(1)
|
|
551
|
+
.max(50)
|
|
552
|
+
.describe('Issue keys to update (max 50)'),
|
|
553
|
+
statusId: z.string().describe('Target status ID (from llama_context)'),
|
|
554
|
+
});
|
|
555
|
+
export async function executeBatchUpdateStatus(input) {
|
|
556
|
+
try {
|
|
557
|
+
const session = await getSessionDefaults();
|
|
558
|
+
const orgSlug = input.orgSlug ?? session?.orgSlug;
|
|
559
|
+
const projectKey = input.projectKey ?? session?.projectKey;
|
|
560
|
+
if (!orgSlug) {
|
|
561
|
+
return JSON.stringify({
|
|
562
|
+
success: false,
|
|
563
|
+
error: 'orgSlug is required. Either provide it or set session context with llama_set_context first.',
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
if (!projectKey) {
|
|
567
|
+
return JSON.stringify({
|
|
568
|
+
success: false,
|
|
569
|
+
error: 'projectKey is required. Either provide it or set session context with llama_set_context first.',
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
const client = getApiClient();
|
|
573
|
+
// Record tool call
|
|
574
|
+
try {
|
|
575
|
+
await client.recordToolCall('llama_batch_update_status', {
|
|
576
|
+
orgSlug,
|
|
577
|
+
projectKey,
|
|
578
|
+
count: input.issueKeys.length,
|
|
579
|
+
statusId: input.statusId,
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
catch {
|
|
583
|
+
// Ignore recording errors
|
|
584
|
+
}
|
|
585
|
+
const result = await client.batchUpdateStatus(orgSlug, projectKey, input.issueKeys, input.statusId);
|
|
586
|
+
return JSON.stringify({
|
|
587
|
+
success: true,
|
|
588
|
+
message: `Updated ${result.succeeded} of ${result.total} issues`,
|
|
589
|
+
...result,
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
catch (error) {
|
|
593
|
+
if (error instanceof LlamaApiError) {
|
|
594
|
+
return JSON.stringify({
|
|
595
|
+
success: false,
|
|
596
|
+
error: `Failed to batch update status: ${error.message}`,
|
|
597
|
+
statusCode: error.statusCode,
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
return JSON.stringify({
|
|
601
|
+
success: false,
|
|
602
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
// ============================================
|
|
607
|
+
// Batch Update Issues
|
|
608
|
+
// ============================================
|
|
609
|
+
export const batchUpdateIssuesToolName = 'llama_batch_update_issues';
|
|
610
|
+
export const batchUpdateIssuesToolDescription = `Update multiple issues with different field changes (max 50).
|
|
611
|
+
Returns individual success/failure for each issue.
|
|
612
|
+
Uses session defaults if orgSlug/projectKey not provided.
|
|
613
|
+
|
|
614
|
+
Example:
|
|
615
|
+
updates: [
|
|
616
|
+
{ issueKey: "PROJ-1", fields: { priority: "HIGH" } },
|
|
617
|
+
{ issueKey: "PROJ-2", fields: { assigneeId: "user-id", estimate: 5 } }
|
|
618
|
+
]`;
|
|
619
|
+
export const batchUpdateIssuesToolSchema = z.object({
|
|
620
|
+
orgSlug: z
|
|
621
|
+
.string()
|
|
622
|
+
.optional()
|
|
623
|
+
.describe('Organization slug (uses session default if not provided)'),
|
|
624
|
+
projectKey: z
|
|
625
|
+
.string()
|
|
626
|
+
.optional()
|
|
627
|
+
.describe('Project key (uses session default if not provided)'),
|
|
628
|
+
updates: z
|
|
629
|
+
.array(z.object({
|
|
630
|
+
issueKey: z.string().describe('Issue key to update'),
|
|
631
|
+
fields: z.object({
|
|
632
|
+
summary: z.string().optional().describe('New summary'),
|
|
633
|
+
description: z.string().optional().nullable().describe('New description'),
|
|
634
|
+
priority: z
|
|
635
|
+
.enum(['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'TRIVIAL'])
|
|
636
|
+
.optional()
|
|
637
|
+
.describe('New priority'),
|
|
638
|
+
assigneeId: z.string().optional().nullable().describe('Assignee ID or null'),
|
|
639
|
+
sprintId: z.string().optional().nullable().describe('Sprint ID or null'),
|
|
640
|
+
estimate: z.number().optional().nullable().describe('Story points'),
|
|
641
|
+
labels: z.array(z.string()).optional().describe('Replace all labels'),
|
|
642
|
+
}),
|
|
643
|
+
}))
|
|
644
|
+
.min(1)
|
|
645
|
+
.max(50)
|
|
646
|
+
.describe('Updates to apply (max 50)'),
|
|
647
|
+
});
|
|
648
|
+
export async function executeBatchUpdateIssues(input) {
|
|
649
|
+
try {
|
|
650
|
+
const session = await getSessionDefaults();
|
|
651
|
+
const orgSlug = input.orgSlug ?? session?.orgSlug;
|
|
652
|
+
const projectKey = input.projectKey ?? session?.projectKey;
|
|
653
|
+
if (!orgSlug) {
|
|
654
|
+
return JSON.stringify({
|
|
655
|
+
success: false,
|
|
656
|
+
error: 'orgSlug is required. Either provide it or set session context with llama_set_context first.',
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
if (!projectKey) {
|
|
660
|
+
return JSON.stringify({
|
|
661
|
+
success: false,
|
|
662
|
+
error: 'projectKey is required. Either provide it or set session context with llama_set_context first.',
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
const client = getApiClient();
|
|
666
|
+
// Record tool call
|
|
667
|
+
try {
|
|
668
|
+
await client.recordToolCall('llama_batch_update_issues', {
|
|
669
|
+
orgSlug,
|
|
670
|
+
projectKey,
|
|
671
|
+
count: input.updates.length,
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
catch {
|
|
675
|
+
// Ignore recording errors
|
|
676
|
+
}
|
|
677
|
+
const updates = input.updates.map((u) => ({
|
|
678
|
+
issueKey: u.issueKey,
|
|
679
|
+
fields: {
|
|
680
|
+
summary: u.fields.summary,
|
|
681
|
+
description: u.fields.description,
|
|
682
|
+
priority: u.fields.priority,
|
|
683
|
+
assigneeId: u.fields.assigneeId,
|
|
684
|
+
sprintId: u.fields.sprintId,
|
|
685
|
+
estimate: u.fields.estimate,
|
|
686
|
+
labels: u.fields.labels,
|
|
687
|
+
},
|
|
688
|
+
}));
|
|
689
|
+
const result = await client.batchUpdateIssues(orgSlug, projectKey, updates);
|
|
690
|
+
return JSON.stringify({
|
|
691
|
+
success: true,
|
|
692
|
+
message: `Updated ${result.succeeded} of ${result.total} issues`,
|
|
693
|
+
...result,
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
catch (error) {
|
|
697
|
+
if (error instanceof LlamaApiError) {
|
|
698
|
+
return JSON.stringify({
|
|
699
|
+
success: false,
|
|
700
|
+
error: `Failed to batch update issues: ${error.message}`,
|
|
701
|
+
statusCode: error.statusCode,
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
return JSON.stringify({
|
|
705
|
+
success: false,
|
|
706
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
707
|
+
});
|
|
260
708
|
}
|
|
261
709
|
}
|
|
262
710
|
//# sourceMappingURL=issues.js.map
|