UNPKG

@aashari/mcp-server-atlassian-bitbucket

Version:

Node.js/TypeScript MCP server for Atlassian Bitbucket. Enables AI systems (LLMs) to interact with workspaces, repositories, and pull requests via tools (list, get, comment, search). Connects AI directly to version control workflows through the standard MC

175 lines (174 loc) 8.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.formatRepositoriesList = formatRepositoriesList; exports.formatRepositoryDetails = formatRepositoryDetails; exports.formatCommitHistory = formatCommitHistory; const formatter_util_js_1 = require("../utils/formatter.util.js"); /** * Format a list of repositories for display * @param repositoriesData - Raw repositories data from the API * @returns Formatted string with repositories information in markdown format */ function formatRepositoriesList(repositoriesData) { const repositories = repositoriesData.values || []; if (repositories.length === 0) { return 'No repositories found matching your criteria.'; } const lines = [(0, formatter_util_js_1.formatHeading)('Bitbucket Repositories', 1), '']; // Format each repository with its details const formattedList = (0, formatter_util_js_1.formatNumberedList)(repositories, (repo, _index) => { const itemLines = []; itemLines.push((0, formatter_util_js_1.formatHeading)(repo.name, 2)); // Basic information const properties = { Name: repo.name, 'Full Name': repo.full_name, Owner: repo.owner?.display_name || repo.owner?.username || 'Unknown', Description: repo.description || 'No description provided', 'Project Key': repo.project?.key || 'N/A', Private: repo.is_private ? 'Yes' : 'No', Created: repo.created_on ? (0, formatter_util_js_1.formatDate)(repo.created_on) : 'N/A', Updated: repo.updated_on ? (0, formatter_util_js_1.formatDate)(repo.updated_on) : 'N/A', URL: repo.links?.html?.href ? (0, formatter_util_js_1.formatUrl)(repo.links.html.href, repo.full_name) : 'N/A', }; // Format as a bullet list itemLines.push((0, formatter_util_js_1.formatBulletList)(properties, (key) => key)); return itemLines.join('\n'); }); lines.push(formattedList); // Add standard footer with timestamp lines.push('\n\n' + (0, formatter_util_js_1.formatSeparator)()); lines.push(`*Information retrieved at: ${(0, formatter_util_js_1.formatDate)(new Date())}*`); return lines.join('\n'); } /** * Format detailed repository information for display * @param repositoryData - Raw repository data from the API * @param pullRequestsData - Optional pull requests data for this repository * @returns Formatted string with repository details in markdown format */ function formatRepositoryDetails(repositoryData, pullRequestsData) { // Create URL const repoUrl = repositoryData.links?.html?.href || ''; const lines = [ (0, formatter_util_js_1.formatHeading)(`Repository: ${repositoryData.name}`, 1), '', `> A ${repositoryData.is_private ? 'private' : 'public'} repository in the \`${repositoryData.full_name}\` workspace.`, '', (0, formatter_util_js_1.formatHeading)('Basic Information', 2), ]; // Format basic information as a bullet list const basicProperties = { Name: repositoryData.name, 'Full Name': repositoryData.full_name, UUID: repositoryData.uuid, Description: repositoryData.description || 'No description provided', Language: repositoryData.language || 'Not specified', 'Main Branch': repositoryData.mainbranch?.name || 'N/A', Private: repositoryData.is_private ? 'Yes' : 'No', Size: repositoryData.size ? `${(repositoryData.size / 1024).toFixed(2)} KB` : 'Unknown', 'Created On': repositoryData.created_on ? (0, formatter_util_js_1.formatDate)(repositoryData.created_on) : 'N/A', 'Updated On': repositoryData.updated_on ? (0, formatter_util_js_1.formatDate)(repositoryData.updated_on) : 'N/A', }; lines.push((0, formatter_util_js_1.formatBulletList)(basicProperties, (key) => key)); // Owner information if (repositoryData.owner) { lines.push(''); lines.push((0, formatter_util_js_1.formatHeading)('Owner', 2)); const ownerProperties = { Name: repositoryData.owner.display_name || repositoryData.owner.username || 'Unknown', Type: repositoryData.owner.type || 'Not specified', }; lines.push((0, formatter_util_js_1.formatBulletList)(ownerProperties, (key) => key)); } // Links section lines.push(''); lines.push((0, formatter_util_js_1.formatHeading)('Links', 2)); if (repoUrl) { lines.push(`- ${(0, formatter_util_js_1.formatUrl)(repoUrl, 'Open in Bitbucket')}`); } // Add recent pull requests section if available if (pullRequestsData && pullRequestsData.values && pullRequestsData.values.length > 0) { lines.push(''); lines.push((0, formatter_util_js_1.formatHeading)('Recent Pull Requests', 2)); const prList = pullRequestsData.values.slice(0, 25); // Ensure max 25 const formattedPrList = (0, formatter_util_js_1.formatNumberedList)(prList, (pr) => { return `**#${pr.id}**: [${pr.title}](${pr.links.html?.href || '#'}) - ${pr.state} by ${pr.author.display_name || 'Unknown'} (${(0, formatter_util_js_1.formatDate)(pr.updated_on)})`; }); lines.push(formattedPrList); if (repoUrl) { lines.push(`*View all pull requests in Bitbucket: [${repositoryData.full_name}/pull-requests](${repoUrl}/pull-requests)*`); } } else { // Add the section even if no PRs are available lines.push(''); lines.push((0, formatter_util_js_1.formatHeading)('Recent Pull Requests', 2)); lines.push('No open pull requests found for this repository.'); if (repoUrl) { lines.push(`*View all pull requests in Bitbucket: [${repositoryData.full_name}/pull-requests](${repoUrl}/pull-requests)*`); } } // Add standard footer with timestamp lines.push('\n\n' + (0, formatter_util_js_1.formatSeparator)()); lines.push(`*Information retrieved at: ${(0, formatter_util_js_1.formatDate)(new Date())}*`); // Optionally keep the direct link if (repoUrl) { lines.push(`*View this repository in Bitbucket: ${repoUrl}*`); } return lines.join('\n'); } /** * Format commit history for display. * @param commitsData - Raw paginated commits data from the API. * @param options - Filtering options used to retrieve the history. * @returns Formatted string with commit history in markdown format. */ function formatCommitHistory(commitsData, options = {}) { const commits = commitsData.values || []; if (commits.length === 0) { return 'No commits found matching your criteria.'; } const headerParts = ['Commit History']; if (options.revision) { headerParts.push(`for revision \`${options.revision}\``); } if (options.path) { headerParts.push(`on path \`${options.path}\``); } const lines = [(0, formatter_util_js_1.formatHeading)(headerParts.join(' '), 1), '']; const formattedList = (0, formatter_util_js_1.formatNumberedList)(commits, (commit) => { const commitLines = []; const author = commit.author?.user?.display_name || commit.author?.raw || 'Unknown'; const commitUrl = commit.links?.html?.href; const shortHash = commit.hash.substring(0, 7); // Header: Hash (linked) - Date commitLines.push(`**${commitUrl ? (0, formatter_util_js_1.formatUrl)(commitUrl, shortHash) : shortHash}** - ${(0, formatter_util_js_1.formatDate)(commit.date)}`); // Author commitLines.push(` Author: ${author}`); // Message (indented blockquote) const message = commit.message.trim().replace(/\n/g, '\n > '); commitLines.push(' >'); commitLines.push(` > ${message}`); return commitLines.join('\n'); }); lines.push(formattedList); // Add standard footer with timestamp lines.push('\n\n' + (0, formatter_util_js_1.formatSeparator)()); lines.push(`*Information retrieved at: ${(0, formatter_util_js_1.formatDate)(new Date())}*`); return lines.join('\n'); }