mcp-osp-prompt 1.0.3 → 1.0.4
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/package.json +1 -1
- package/prompt-manager.js +16 -0
- package/server.js +4 -1
- package/tools.js +125 -1
package/package.json
CHANGED
package/prompt-manager.js
CHANGED
|
@@ -308,6 +308,22 @@ class PromptManager {
|
|
|
308
308
|
},
|
|
309
309
|
required: ['random_string']
|
|
310
310
|
}
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
name: 'gitlab-mr-fetch',
|
|
314
|
+
type: 'handler',
|
|
315
|
+
handler: 'handleGitlabMrFetch',
|
|
316
|
+
description: 'Fetch GitLab Merge Request details and code diff',
|
|
317
|
+
schema: {
|
|
318
|
+
type: 'object',
|
|
319
|
+
properties: {
|
|
320
|
+
mr_url: {
|
|
321
|
+
type: 'string',
|
|
322
|
+
description: 'GitLab Merge Request URL, e.g., https://gitlab.com/group/project/-/merge_requests/123'
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
required: ['mr_url']
|
|
326
|
+
}
|
|
311
327
|
}
|
|
312
328
|
];
|
|
313
329
|
|
package/server.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import process from 'process';
|
|
3
3
|
import { initializePrompts, getToolsConfiguration } from './prompt-manager.js';
|
|
4
|
-
import { handleDevTool, handleDevManual, handleDevFeedback } from './tools.js';
|
|
4
|
+
import { handleDevTool, handleDevManual, handleDevFeedback, handleGitlabMrFetch } from './tools.js';
|
|
5
5
|
import { CFG } from './config.js';
|
|
6
6
|
import {
|
|
7
7
|
createSuccessResponse,
|
|
@@ -233,6 +233,9 @@ async function handleToolCall(req) {
|
|
|
233
233
|
⚠️ **MANDATORY NEXT STEP REMINDER:** 在完成下一个实施步骤后,必须再次调用dev-feedback工具汇报进度并获取确认。每个步骤完成后都需要调用feedback工具 - 这是强制要求!`;
|
|
234
234
|
}
|
|
235
235
|
break;
|
|
236
|
+
case 'handleGitlabMrFetch':
|
|
237
|
+
resultText = await handleGitlabMrFetch(args);
|
|
238
|
+
break;
|
|
236
239
|
default:
|
|
237
240
|
throw new Error(`Unknown handler: ${tool.handler}`);
|
|
238
241
|
}
|
package/tools.js
CHANGED
|
@@ -3,6 +3,7 @@ import { getToolsConfiguration, getLocalPromptInfo } from './prompt-manager.js';
|
|
|
3
3
|
import { showInputDialog, showConfirmDialog, showSelectDialog, showPlanAdjustmentDialog } from './dialog/index.js';
|
|
4
4
|
// ✅ UNIFIED: 导入统一的按钮管理常量
|
|
5
5
|
import { BASE_DIALOG_BUTTONS, getSafeButtons, getStandardButtons } from './dialog/constants.js';
|
|
6
|
+
import { createAuthHeaders } from './platform-utils.js';
|
|
6
7
|
|
|
7
8
|
// 动态获取工具的source映射
|
|
8
9
|
function getToolSource(toolName) {
|
|
@@ -564,4 +565,127 @@ export async function handleDevFeedback(args) {
|
|
|
564
565
|
}
|
|
565
566
|
|
|
566
567
|
// handleDevReload removed - configuration now loads automatically from environment and mcp.json
|
|
567
|
-
// No manual reload needed as per user requirements
|
|
568
|
+
// No manual reload needed as per user requirements
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Parse GitLab MR URL to extract project and MR IID
|
|
572
|
+
* @param {string} mrUrl - GitLab MR URL
|
|
573
|
+
* @returns {object} Parsed info { projectPath, mrIid, apiBase }
|
|
574
|
+
*/
|
|
575
|
+
function parseGitlabMrUrl(mrUrl) {
|
|
576
|
+
// Match: https://gitlab.com/group/project/-/merge_requests/123
|
|
577
|
+
// Or: https://gitlab.example.com/group/subgroup/project/-/merge_requests/123
|
|
578
|
+
const match = mrUrl.match(/^(https?:\/\/[^\/]+)\/(.+?)\/-\/merge_requests\/(\d+)/);
|
|
579
|
+
|
|
580
|
+
if (!match) {
|
|
581
|
+
throw new Error(`Invalid GitLab MR URL format: ${mrUrl}. Expected format: https://gitlab.com/group/project/-/merge_requests/123`);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
return {
|
|
585
|
+
apiBase: match[1],
|
|
586
|
+
projectPath: match[2],
|
|
587
|
+
mrIid: match[3]
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* Fetch GitLab Merge Request details and code diff
|
|
593
|
+
* @param {object} args - Arguments with mr_url
|
|
594
|
+
* @returns {string} Formatted MR information with diffs
|
|
595
|
+
*/
|
|
596
|
+
export async function handleGitlabMrFetch(args) {
|
|
597
|
+
const { mr_url } = args;
|
|
598
|
+
|
|
599
|
+
if (!mr_url) {
|
|
600
|
+
throw new Error('mr_url is required');
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
const token = process.env.GIT_TOKEN;
|
|
604
|
+
if (!token) {
|
|
605
|
+
throw new Error('GIT_TOKEN environment variable is required for GitLab API access');
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
const { apiBase, projectPath, mrIid } = parseGitlabMrUrl(mr_url);
|
|
609
|
+
const projectEnc = encodeURIComponent(projectPath);
|
|
610
|
+
const headers = createAuthHeaders('gitlab', token);
|
|
611
|
+
|
|
612
|
+
console.error(`[GitLab MR] Fetching MR ${mrIid} from ${projectPath}`);
|
|
613
|
+
|
|
614
|
+
try {
|
|
615
|
+
// Fetch MR details
|
|
616
|
+
const mrResponse = await fetch(
|
|
617
|
+
`${apiBase}/api/v4/projects/${projectEnc}/merge_requests/${mrIid}`,
|
|
618
|
+
{ headers }
|
|
619
|
+
);
|
|
620
|
+
|
|
621
|
+
if (!mrResponse.ok) {
|
|
622
|
+
const errorText = await mrResponse.text();
|
|
623
|
+
throw new Error(`GitLab API error (${mrResponse.status}): ${errorText}`);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
const mrData = await mrResponse.json();
|
|
627
|
+
|
|
628
|
+
// Fetch MR changes (diffs)
|
|
629
|
+
const changesResponse = await fetch(
|
|
630
|
+
`${apiBase}/api/v4/projects/${projectEnc}/merge_requests/${mrIid}/changes`,
|
|
631
|
+
{ headers }
|
|
632
|
+
);
|
|
633
|
+
|
|
634
|
+
if (!changesResponse.ok) {
|
|
635
|
+
const errorText = await changesResponse.text();
|
|
636
|
+
throw new Error(`GitLab API error fetching changes (${changesResponse.status}): ${errorText}`);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
const changesData = await changesResponse.json();
|
|
640
|
+
|
|
641
|
+
// Format the output
|
|
642
|
+
let output = `# GitLab Merge Request Details
|
|
643
|
+
|
|
644
|
+
## Basic Information
|
|
645
|
+
- **Title:** ${mrData.title}
|
|
646
|
+
- **MR IID:** !${mrData.iid}
|
|
647
|
+
- **Author:** ${mrData.author?.name || 'Unknown'} (@${mrData.author?.username || 'unknown'})
|
|
648
|
+
- **Source Branch:** ${mrData.source_branch}
|
|
649
|
+
- **Target Branch:** ${mrData.target_branch}
|
|
650
|
+
- **State:** ${mrData.state}
|
|
651
|
+
- **Created At:** ${mrData.created_at}
|
|
652
|
+
- **Updated At:** ${mrData.updated_at}
|
|
653
|
+
- **URL:** ${mr_url}
|
|
654
|
+
|
|
655
|
+
## Description
|
|
656
|
+
${mrData.description || '_No description provided_'}
|
|
657
|
+
|
|
658
|
+
## Changed Files (${changesData.changes?.length || 0} files)
|
|
659
|
+
|
|
660
|
+
`;
|
|
661
|
+
|
|
662
|
+
// Add file changes
|
|
663
|
+
if (changesData.changes && changesData.changes.length > 0) {
|
|
664
|
+
for (const change of changesData.changes) {
|
|
665
|
+
const status = change.new_file ? '🆕 New' :
|
|
666
|
+
change.deleted_file ? '🗑️ Deleted' :
|
|
667
|
+
change.renamed_file ? '📝 Renamed' : '✏️ Modified';
|
|
668
|
+
|
|
669
|
+
output += `### ${status}: \`${change.new_path}\`\n`;
|
|
670
|
+
|
|
671
|
+
if (change.renamed_file && change.old_path !== change.new_path) {
|
|
672
|
+
output += `_Renamed from: ${change.old_path}_\n`;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
output += '\n```diff\n';
|
|
676
|
+
output += change.diff || '_Binary file or no diff available_';
|
|
677
|
+
output += '\n```\n\n';
|
|
678
|
+
}
|
|
679
|
+
} else {
|
|
680
|
+
output += '_No changes found_\n';
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
console.error(`[GitLab MR] Successfully fetched MR with ${changesData.changes?.length || 0} changed files`);
|
|
684
|
+
|
|
685
|
+
return output;
|
|
686
|
+
|
|
687
|
+
} catch (error) {
|
|
688
|
+
console.error(`[GitLab MR] Error:`, error.message);
|
|
689
|
+
throw error;
|
|
690
|
+
}
|
|
691
|
+
}
|