lunaarc-mcp 1.1.4 → 1.2.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/dist/server.js +1 -1
- package/dist/tools/kanban.js +110 -37
- package/package.json +1 -1
package/dist/server.js
CHANGED
package/dist/tools/kanban.js
CHANGED
|
@@ -89,22 +89,28 @@ exports.kanbanTools = [
|
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
name: 'kanban_assigned_get',
|
|
92
|
-
description: `Get
|
|
92
|
+
description: `Get the NEXT kanban card to work on. Returns only ONE card at a time to ensure proper workflow.
|
|
93
93
|
|
|
94
|
-
IMPORTANT -
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
- Are all required information/resources available?
|
|
98
|
-
- Is the task technically feasible?
|
|
94
|
+
IMPORTANT - This tool enforces a strict workflow:
|
|
95
|
+
- If you have a card "In Progress": Only that card is returned (must be completed first!)
|
|
96
|
+
- If no card in progress: The next card from the queue is returned (sorted by priority)
|
|
99
97
|
|
|
100
|
-
|
|
98
|
+
Card queue sorting:
|
|
99
|
+
1. Column: In Progress > Ready for Development > Backlog
|
|
100
|
+
2. Priority: urgent > high > medium > low
|
|
101
|
+
3. Due date: earliest first
|
|
101
102
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
WORKFLOW - You MUST follow these steps:
|
|
104
|
+
1. Move card to "In Progress" BEFORE starting work
|
|
105
|
+
2. Complete the task fully and test it
|
|
106
|
+
3. Add a comment with a summary of changes
|
|
107
|
+
4. Move to "Done" only when fully completed
|
|
108
|
+
5. Call this tool again to get the next card
|
|
106
109
|
|
|
107
|
-
|
|
110
|
+
If a card CANNOT be completed:
|
|
111
|
+
- Add a "## AI Feedback" section explaining WHY
|
|
112
|
+
- Move to "On Hold" (not Done!)
|
|
113
|
+
- Include: reason, missing prerequisites, suggestions`,
|
|
108
114
|
inputSchema: {
|
|
109
115
|
type: 'object',
|
|
110
116
|
properties: {},
|
|
@@ -209,6 +215,29 @@ const priorityEmoji = {
|
|
|
209
215
|
high: '🟠',
|
|
210
216
|
urgent: '🔴',
|
|
211
217
|
};
|
|
218
|
+
// Column priority for sorting (lower = higher priority)
|
|
219
|
+
const columnPriority = {
|
|
220
|
+
'In Progress': 0,
|
|
221
|
+
'Ready for Development': 1,
|
|
222
|
+
'Backlog': 2,
|
|
223
|
+
};
|
|
224
|
+
// Priority sorting (lower = higher priority)
|
|
225
|
+
const priorityOrder = {
|
|
226
|
+
urgent: 0,
|
|
227
|
+
high: 1,
|
|
228
|
+
medium: 2,
|
|
229
|
+
low: 3,
|
|
230
|
+
};
|
|
231
|
+
// Workflow reminder that gets added to every response
|
|
232
|
+
const WORKFLOW_REMINDER = `
|
|
233
|
+
---
|
|
234
|
+
⚠️ **WORKFLOW - Diese Schritte MÜSSEN eingehalten werden:**
|
|
235
|
+
1. Karte nach "In Progress" verschieben BEVOR du anfängst
|
|
236
|
+
2. Task vollständig erledigen und testen
|
|
237
|
+
3. Kommentar mit Zusammenfassung der Änderungen hinzufügen
|
|
238
|
+
4. Erst nach Abschluss nach "Done" verschieben
|
|
239
|
+
5. Dann erneut \`kanban_assigned_get\` aufrufen für die nächste Karte
|
|
240
|
+
`;
|
|
212
241
|
// Tool handlers
|
|
213
242
|
async function handleKanbanTool(client, toolName, args) {
|
|
214
243
|
switch (toolName) {
|
|
@@ -365,38 +394,82 @@ To get cards assigned to you, a team member needs to assign a card to this AI to
|
|
|
365
394
|
],
|
|
366
395
|
};
|
|
367
396
|
}
|
|
368
|
-
|
|
397
|
+
// Sort cards: Column priority > Priority > Due date
|
|
398
|
+
const sortedCards = [...cards].sort((a, b) => {
|
|
399
|
+
// 1. Column priority (In Progress > Ready for Development > Backlog)
|
|
400
|
+
const colA = columnPriority[a.column_name] ?? 99;
|
|
401
|
+
const colB = columnPriority[b.column_name] ?? 99;
|
|
402
|
+
if (colA !== colB)
|
|
403
|
+
return colA - colB;
|
|
404
|
+
// 2. Priority (urgent > high > medium > low)
|
|
405
|
+
const prioA = priorityOrder[a.priority] ?? 99;
|
|
406
|
+
const prioB = priorityOrder[b.priority] ?? 99;
|
|
407
|
+
if (prioA !== prioB)
|
|
408
|
+
return prioA - prioB;
|
|
409
|
+
// 3. Due date (earliest first, null at the end)
|
|
410
|
+
if (a.due_date && b.due_date) {
|
|
411
|
+
return new Date(a.due_date).getTime() - new Date(b.due_date).getTime();
|
|
412
|
+
}
|
|
413
|
+
if (a.due_date && !b.due_date)
|
|
414
|
+
return -1;
|
|
415
|
+
if (!a.due_date && b.due_date)
|
|
416
|
+
return 1;
|
|
417
|
+
return 0;
|
|
418
|
+
});
|
|
419
|
+
// Check if there's a card in "In Progress"
|
|
420
|
+
const inProgressCard = sortedCards.find((c) => c.column_name === 'In Progress');
|
|
421
|
+
const totalCards = cards.length;
|
|
422
|
+
let output = '';
|
|
423
|
+
let cardToShow;
|
|
424
|
+
if (inProgressCard) {
|
|
425
|
+
// There's already a card in progress - MUST finish this first
|
|
426
|
+
cardToShow = inProgressCard;
|
|
427
|
+
output = `# ⚠️ KARTE IN BEARBEITUNG
|
|
369
428
|
|
|
370
|
-
|
|
429
|
+
**Du hast bereits eine Karte in "In Progress"!**
|
|
430
|
+
**Diese MUSS zuerst abgeschlossen werden, bevor du eine neue Karte beginnen kannst.**
|
|
371
431
|
|
|
432
|
+
${totalCards > 1 ? `_(${totalCards - 1} weitere Karte${totalCards > 2 ? 'n' : ''} in der Warteschlange)_\n` : ''}
|
|
372
433
|
---
|
|
373
434
|
|
|
374
435
|
`;
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
// No card in progress - show the next card from the queue
|
|
439
|
+
cardToShow = sortedCards[0];
|
|
440
|
+
output = `# 📋 Nächste Karte
|
|
378
441
|
|
|
379
|
-
**
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
output +=
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
442
|
+
**Karte 1 von ${totalCards}** - Schließe diese ab, bevor du die nächste holst.
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
`;
|
|
447
|
+
}
|
|
448
|
+
// Render the single card
|
|
449
|
+
const priority = priorityEmoji[cardToShow.priority] || '⚪';
|
|
450
|
+
output += `## ${priority} ${cardToShow.title}
|
|
451
|
+
|
|
452
|
+
**ID:** \`${cardToShow.id}\`
|
|
453
|
+
**Column:** ${cardToShow.column_name}
|
|
454
|
+
**Priority:** ${cardToShow.priority}`;
|
|
455
|
+
if (cardToShow.labels.length > 0) {
|
|
456
|
+
output += `\n**Labels:** ${cardToShow.labels.map((l) => `\`${l}\``).join(', ')}`;
|
|
457
|
+
}
|
|
458
|
+
if (cardToShow.due_date) {
|
|
459
|
+
output += `\n**Due:** ${new Date(cardToShow.due_date).toLocaleDateString()}`;
|
|
460
|
+
}
|
|
461
|
+
// Show assigned AI Agent if present
|
|
462
|
+
if (cardToShow.agent_name) {
|
|
463
|
+
output += `\n**AI Agent:** ${cardToShow.agent_name}`;
|
|
464
|
+
}
|
|
465
|
+
output += '\n\n';
|
|
466
|
+
output += cardToShow.description || '_No description_';
|
|
467
|
+
// Include agent context if present
|
|
468
|
+
if (cardToShow.agent_content) {
|
|
469
|
+
output += `\n\n---\n\n### Agent Instructions\n\n${cardToShow.agent_content}`;
|
|
399
470
|
}
|
|
471
|
+
// Add workflow reminder at the end
|
|
472
|
+
output += WORKFLOW_REMINDER;
|
|
400
473
|
return {
|
|
401
474
|
content: [{ type: 'text', text: output }],
|
|
402
475
|
};
|