lunaarc-mcp 1.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.
@@ -0,0 +1,488 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.kanbanTools = void 0;
4
+ exports.handleKanbanTool = handleKanbanTool;
5
+ // Tool definitions for kanban operations
6
+ exports.kanbanTools = [
7
+ {
8
+ name: 'kanban_board_get',
9
+ description: 'Get the kanban board structure with all columns and cards. Shows the complete workflow including AI Inbox, card titles, priorities, and labels.',
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {},
13
+ required: [],
14
+ },
15
+ },
16
+ {
17
+ name: 'kanban_card_read',
18
+ description: 'Read detailed information about a specific kanban card. Returns title, description, priority, labels, and timestamps.',
19
+ inputSchema: {
20
+ type: 'object',
21
+ properties: {
22
+ card_id: {
23
+ type: 'string',
24
+ description: 'The card ID (UUID)',
25
+ },
26
+ },
27
+ required: ['card_id'],
28
+ },
29
+ },
30
+ {
31
+ name: 'kanban_card_create',
32
+ description: 'Create a new kanban card in the AI Inbox column. Cards created by AI are automatically placed in the AI Inbox for human review before being moved to the main workflow.',
33
+ inputSchema: {
34
+ type: 'object',
35
+ properties: {
36
+ title: {
37
+ type: 'string',
38
+ description: 'The card title (required)',
39
+ },
40
+ description: {
41
+ type: 'string',
42
+ description: 'Detailed description of the task or item (optional, supports markdown)',
43
+ },
44
+ priority: {
45
+ type: 'string',
46
+ enum: ['low', 'medium', 'high', 'urgent'],
47
+ description: 'Priority level (optional, defaults to medium)',
48
+ },
49
+ labels: {
50
+ type: 'array',
51
+ items: { type: 'string' },
52
+ description: 'Array of labels/tags for categorization (optional)',
53
+ },
54
+ },
55
+ required: ['title'],
56
+ },
57
+ },
58
+ {
59
+ name: 'kanban_card_update',
60
+ description: 'Update an existing kanban card. Only cards in the AI Inbox that were created by AI can be updated. Human-moved or human-created cards cannot be modified by AI.',
61
+ inputSchema: {
62
+ type: 'object',
63
+ properties: {
64
+ card_id: {
65
+ type: 'string',
66
+ description: 'The card ID to update (UUID)',
67
+ },
68
+ title: {
69
+ type: 'string',
70
+ description: 'New title (optional)',
71
+ },
72
+ description: {
73
+ type: 'string',
74
+ description: 'New description (optional, supports markdown)',
75
+ },
76
+ priority: {
77
+ type: 'string',
78
+ enum: ['low', 'medium', 'high', 'urgent'],
79
+ description: 'New priority level (optional)',
80
+ },
81
+ labels: {
82
+ type: 'array',
83
+ items: { type: 'string' },
84
+ description: 'New labels array (optional, replaces existing labels)',
85
+ },
86
+ },
87
+ required: ['card_id'],
88
+ },
89
+ },
90
+ {
91
+ name: 'kanban_assigned_get',
92
+ description: `Get all kanban cards that are assigned to this AI. Returns cards from any column that have been assigned to this AI token for processing.
93
+
94
+ IMPORTANT - AI Workflow Guidelines:
95
+ 1. BEFORE starting work on a card, verify:
96
+ - Is the task clearly defined and understandable?
97
+ - Are all required information/resources available?
98
+ - Is the task technically feasible?
99
+
100
+ 2. Move card to "In Progress" before starting work.
101
+
102
+ 3. If a card CANNOT be completed:
103
+ - Update the description with a "## AI Feedback" section explaining WHY
104
+ - Move the card to "On Hold" (not Done!)
105
+ - Include: reason, missing prerequisites, and suggestions
106
+
107
+ 4. Only move to "Done" when the task is fully completed.`,
108
+ inputSchema: {
109
+ type: 'object',
110
+ properties: {},
111
+ required: [],
112
+ },
113
+ },
114
+ {
115
+ name: 'kanban_card_move',
116
+ description: `Move a card that is assigned to this AI to another column. Only works for cards assigned to this AI token.
117
+
118
+ Target columns:
119
+ - "In Progress" - When starting work on a card
120
+ - "Done" - ONLY when task is fully completed
121
+ - "On Hold" - When card cannot be completed (add explanation to description first!)
122
+ - "Review" - When work needs human review`,
123
+ inputSchema: {
124
+ type: 'object',
125
+ properties: {
126
+ card_id: {
127
+ type: 'string',
128
+ description: 'The card ID to move (UUID)',
129
+ },
130
+ column: {
131
+ type: 'string',
132
+ description: 'Target column name (e.g., "Done", "In Progress", "On Hold", "Review")',
133
+ },
134
+ },
135
+ required: ['card_id', 'column'],
136
+ },
137
+ },
138
+ {
139
+ name: 'kanban_assigned_update',
140
+ description: `Update a card that is assigned to this AI. Works on assigned cards in any column.
141
+
142
+ Use this to add AI feedback when a card cannot be completed. Add a section like:
143
+ ---
144
+ ## AI Feedback
145
+ **Status:** Cannot complete / Needs clarification
146
+ **Reason:** [Explain why]
147
+ **Missing:** [What is needed]
148
+ **Suggestion:** [How to resolve]`,
149
+ inputSchema: {
150
+ type: 'object',
151
+ properties: {
152
+ card_id: {
153
+ type: 'string',
154
+ description: 'The card ID to update (UUID)',
155
+ },
156
+ title: {
157
+ type: 'string',
158
+ description: 'New title (optional)',
159
+ },
160
+ description: {
161
+ type: 'string',
162
+ description: 'New description (optional, supports markdown). Use to add AI feedback.',
163
+ },
164
+ priority: {
165
+ type: 'string',
166
+ enum: ['low', 'medium', 'high', 'urgent'],
167
+ description: 'New priority level (optional)',
168
+ },
169
+ labels: {
170
+ type: 'array',
171
+ items: { type: 'string' },
172
+ description: 'New labels array (optional, replaces existing labels)',
173
+ },
174
+ },
175
+ required: ['card_id'],
176
+ },
177
+ },
178
+ {
179
+ name: 'kanban_card_comment',
180
+ description: `Add a comment to a kanban card that is assigned to this AI.
181
+
182
+ Use this to:
183
+ - Provide status updates on work progress
184
+ - Ask clarifying questions
185
+ - Document decisions or blockers
186
+ - Leave notes for human review
187
+
188
+ Comments are visible to all team members and provide a transparent record of AI activity on the card.`,
189
+ inputSchema: {
190
+ type: 'object',
191
+ properties: {
192
+ card_id: {
193
+ type: 'string',
194
+ description: 'The card ID to comment on (UUID)',
195
+ },
196
+ content: {
197
+ type: 'string',
198
+ description: 'The comment text (supports markdown)',
199
+ },
200
+ },
201
+ required: ['card_id', 'content'],
202
+ },
203
+ },
204
+ ];
205
+ // Priority display mapping
206
+ const priorityEmoji = {
207
+ low: '🟢',
208
+ medium: '🟡',
209
+ high: '🟠',
210
+ urgent: '🔴',
211
+ };
212
+ // Tool handlers
213
+ async function handleKanbanTool(client, toolName, args) {
214
+ switch (toolName) {
215
+ case 'kanban_board_get': {
216
+ const board = await client.getKanbanBoard();
217
+ let output = `# ${board.board.name}\n`;
218
+ if (board.board.description) {
219
+ output += `${board.board.description}\n`;
220
+ }
221
+ output += '\n---\n\n';
222
+ for (const column of board.columns) {
223
+ // Column header with AI Inbox indicator
224
+ const aiIndicator = column.is_ai_inbox ? ' 🤖' : '';
225
+ const colorIndicator = column.color ? ` [${column.color}]` : '';
226
+ output += `## ${column.name}${aiIndicator}${colorIndicator}\n`;
227
+ output += `Cards: ${column.card_count}`;
228
+ if (column.wip_limit) {
229
+ output += ` / WIP Limit: ${column.wip_limit}`;
230
+ }
231
+ output += '\n\n';
232
+ if (column.cards.length === 0) {
233
+ output += '_No cards_\n\n';
234
+ }
235
+ else {
236
+ for (const card of column.cards) {
237
+ const priority = priorityEmoji[card.priority] || '⚪';
238
+ const aiMark = card.created_by_ai ? ' 🤖' : '';
239
+ output += `- ${priority} **${card.title}**${aiMark}\n`;
240
+ output += ` ID: \`${card.id}\`\n`;
241
+ if (card.labels.length > 0) {
242
+ output += ` Labels: ${card.labels.map((l) => `\`${l}\``).join(', ')}\n`;
243
+ }
244
+ if (card.due_date) {
245
+ output += ` Due: ${new Date(card.due_date).toLocaleDateString()}\n`;
246
+ }
247
+ }
248
+ output += '\n';
249
+ }
250
+ }
251
+ return {
252
+ content: [{ type: 'text', text: output }],
253
+ };
254
+ }
255
+ case 'kanban_card_read': {
256
+ const cardId = args.card_id;
257
+ if (!cardId) {
258
+ throw new Error('card_id parameter is required');
259
+ }
260
+ const card = await client.getKanbanCard(cardId);
261
+ const priority = priorityEmoji[card.priority] || '⚪';
262
+ const aiMark = card.created_by_ai ? '\n**Created by:** AI 🤖' : '';
263
+ let output = `# ${priority} ${card.title}
264
+
265
+ **ID:** \`${card.id}\`
266
+ **Priority:** ${card.priority}${aiMark}
267
+ **Created:** ${new Date(card.created_at).toLocaleString()}
268
+ **Updated:** ${new Date(card.updated_at).toLocaleString()}`;
269
+ if (card.labels.length > 0) {
270
+ output += `\n**Labels:** ${card.labels.map((l) => `\`${l}\``).join(', ')}`;
271
+ }
272
+ if (card.due_date) {
273
+ output += `\n**Due Date:** ${new Date(card.due_date).toLocaleDateString()}`;
274
+ }
275
+ output += '\n\n---\n\n';
276
+ output += card.description || '_No description_';
277
+ return {
278
+ content: [{ type: 'text', text: output }],
279
+ };
280
+ }
281
+ case 'kanban_card_create': {
282
+ const title = args.title;
283
+ const description = args.description;
284
+ const priority = args.priority;
285
+ const labels = args.labels;
286
+ if (!title) {
287
+ throw new Error('title parameter is required');
288
+ }
289
+ const result = await client.createKanbanCard({
290
+ title,
291
+ description,
292
+ priority,
293
+ labels,
294
+ });
295
+ return {
296
+ content: [
297
+ {
298
+ type: 'text',
299
+ text: `✅ Card created successfully in AI Inbox!
300
+
301
+ **Card ID:** \`${result.id}\`
302
+ **Title:** ${title}
303
+ ${priority ? `**Priority:** ${priority}` : ''}
304
+ ${labels && labels.length > 0 ? `**Labels:** ${labels.join(', ')}` : ''}
305
+
306
+ The card is now in the AI Inbox column and will be reviewed by a team member before being moved to the main workflow.`,
307
+ },
308
+ ],
309
+ };
310
+ }
311
+ case 'kanban_card_update': {
312
+ const cardId = args.card_id;
313
+ const title = args.title;
314
+ const description = args.description;
315
+ const priority = args.priority;
316
+ const labels = args.labels;
317
+ if (!cardId) {
318
+ throw new Error('card_id parameter is required');
319
+ }
320
+ if (!title && !description && !priority && !labels) {
321
+ throw new Error('At least one field (title, description, priority, labels) must be provided');
322
+ }
323
+ await client.updateKanbanCard(cardId, {
324
+ title,
325
+ description,
326
+ priority,
327
+ labels,
328
+ });
329
+ const updates = [];
330
+ if (title)
331
+ updates.push(`Title → ${title}`);
332
+ if (description)
333
+ updates.push('Description updated');
334
+ if (priority)
335
+ updates.push(`Priority → ${priority}`);
336
+ if (labels)
337
+ updates.push(`Labels → ${labels.join(', ')}`);
338
+ return {
339
+ content: [
340
+ {
341
+ type: 'text',
342
+ text: `✅ Card updated successfully!
343
+
344
+ **Card ID:** \`${cardId}\`
345
+
346
+ **Changes:**
347
+ ${updates.map((u) => `- ${u}`).join('\n')}`,
348
+ },
349
+ ],
350
+ };
351
+ }
352
+ case 'kanban_assigned_get': {
353
+ const cards = await client.getAIAssignedCards();
354
+ if (cards.length === 0) {
355
+ return {
356
+ content: [
357
+ {
358
+ type: 'text',
359
+ text: `# AI Assigned Cards
360
+
361
+ _No cards are currently assigned to this AI._
362
+
363
+ To get cards assigned to you, a team member needs to assign a card to this AI token in the Kanban board.`,
364
+ },
365
+ ],
366
+ };
367
+ }
368
+ let output = `# AI Assigned Cards
369
+
370
+ **${cards.length} card${cards.length === 1 ? '' : 's'} assigned to this AI**
371
+
372
+ ---
373
+
374
+ `;
375
+ for (const card of cards) {
376
+ const priority = priorityEmoji[card.priority] || '⚪';
377
+ output += `## ${priority} ${card.title}
378
+
379
+ **ID:** \`${card.id}\`
380
+ **Column:** ${card.column_name}
381
+ **Priority:** ${card.priority}`;
382
+ if (card.labels.length > 0) {
383
+ output += `\n**Labels:** ${card.labels.map((l) => `\`${l}\``).join(', ')}`;
384
+ }
385
+ if (card.due_date) {
386
+ output += `\n**Due:** ${new Date(card.due_date).toLocaleDateString()}`;
387
+ }
388
+ output += '\n\n';
389
+ output += card.description || '_No description_';
390
+ output += '\n\n---\n\n';
391
+ }
392
+ return {
393
+ content: [{ type: 'text', text: output }],
394
+ };
395
+ }
396
+ case 'kanban_card_move': {
397
+ const cardId = args.card_id;
398
+ const column = args.column;
399
+ if (!cardId) {
400
+ throw new Error('card_id parameter is required');
401
+ }
402
+ if (!column) {
403
+ throw new Error('column parameter is required');
404
+ }
405
+ await client.moveKanbanCard(cardId, column);
406
+ return {
407
+ content: [
408
+ {
409
+ type: 'text',
410
+ text: `✅ Card moved successfully!
411
+
412
+ **Card ID:** \`${cardId}\`
413
+ **Moved to:** ${column}
414
+
415
+ The card has been moved to the "${column}" column.`,
416
+ },
417
+ ],
418
+ };
419
+ }
420
+ case 'kanban_assigned_update': {
421
+ const cardId = args.card_id;
422
+ const title = args.title;
423
+ const description = args.description;
424
+ const priority = args.priority;
425
+ const labels = args.labels;
426
+ if (!cardId) {
427
+ throw new Error('card_id parameter is required');
428
+ }
429
+ if (!title && !description && !priority && !labels) {
430
+ throw new Error('At least one field (title, description, priority, labels) must be provided');
431
+ }
432
+ await client.updateAIAssignedCard(cardId, {
433
+ title,
434
+ description,
435
+ priority,
436
+ labels,
437
+ });
438
+ const updates = [];
439
+ if (title)
440
+ updates.push(`Title → ${title}`);
441
+ if (description)
442
+ updates.push('Description updated');
443
+ if (priority)
444
+ updates.push(`Priority → ${priority}`);
445
+ if (labels)
446
+ updates.push(`Labels → ${labels.join(', ')}`);
447
+ return {
448
+ content: [
449
+ {
450
+ type: 'text',
451
+ text: `✅ Assigned card updated successfully!
452
+
453
+ **Card ID:** \`${cardId}\`
454
+
455
+ **Changes:**
456
+ ${updates.map((u) => `- ${u}`).join('\n')}`,
457
+ },
458
+ ],
459
+ };
460
+ }
461
+ case 'kanban_card_comment': {
462
+ const cardId = args.card_id;
463
+ const content = args.content;
464
+ if (!cardId) {
465
+ throw new Error('card_id parameter is required');
466
+ }
467
+ if (!content || content.trim().length === 0) {
468
+ throw new Error('content parameter is required and cannot be empty');
469
+ }
470
+ const commentId = await client.addKanbanCardComment(cardId, content.trim());
471
+ return {
472
+ content: [
473
+ {
474
+ type: 'text',
475
+ text: `✅ Comment added successfully!
476
+
477
+ **Card ID:** \`${cardId}\`
478
+ **Comment ID:** \`${commentId}\`
479
+
480
+ Your comment has been added to the card and is visible to all team members.`,
481
+ },
482
+ ],
483
+ };
484
+ }
485
+ default:
486
+ throw new Error(`Unknown kanban tool: ${toolName}`);
487
+ }
488
+ }
@@ -0,0 +1,98 @@
1
+ import { LunaArcApiClient } from '../api/client.js';
2
+ export declare const todosTools: ({
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ type: "object";
7
+ properties: {
8
+ todo_id?: undefined;
9
+ todo_list_id?: undefined;
10
+ title?: undefined;
11
+ description?: undefined;
12
+ due_date?: undefined;
13
+ completed?: undefined;
14
+ };
15
+ required: never[];
16
+ };
17
+ } | {
18
+ name: string;
19
+ description: string;
20
+ inputSchema: {
21
+ type: "object";
22
+ properties: {
23
+ todo_id: {
24
+ type: string;
25
+ description: string;
26
+ };
27
+ todo_list_id?: undefined;
28
+ title?: undefined;
29
+ description?: undefined;
30
+ due_date?: undefined;
31
+ completed?: undefined;
32
+ };
33
+ required: string[];
34
+ };
35
+ } | {
36
+ name: string;
37
+ description: string;
38
+ inputSchema: {
39
+ type: "object";
40
+ properties: {
41
+ todo_list_id: {
42
+ type: string;
43
+ description: string;
44
+ };
45
+ title: {
46
+ type: string;
47
+ description: string;
48
+ };
49
+ description: {
50
+ type: string;
51
+ description: string;
52
+ };
53
+ due_date: {
54
+ type: string;
55
+ description: string;
56
+ };
57
+ todo_id?: undefined;
58
+ completed?: undefined;
59
+ };
60
+ required: string[];
61
+ };
62
+ } | {
63
+ name: string;
64
+ description: string;
65
+ inputSchema: {
66
+ type: "object";
67
+ properties: {
68
+ todo_id: {
69
+ type: string;
70
+ description: string;
71
+ };
72
+ title: {
73
+ type: string;
74
+ description: string;
75
+ };
76
+ description: {
77
+ type: string;
78
+ description: string;
79
+ };
80
+ completed: {
81
+ type: string;
82
+ description: string;
83
+ };
84
+ due_date: {
85
+ type: string;
86
+ description: string;
87
+ };
88
+ todo_list_id?: undefined;
89
+ };
90
+ required: string[];
91
+ };
92
+ })[];
93
+ export declare function handleTodosTool(client: LunaArcApiClient, toolName: string, args: Record<string, unknown>): Promise<{
94
+ content: {
95
+ type: 'text';
96
+ text: string;
97
+ }[];
98
+ }>;