This is page 4 of 4. Use http://codebase.md/aashari/mcp-server-atlassian-bitbucket?lines=false&page={x} to view the full context. # Directory Structure ``` ├── .env.example ├── .github │ ├── dependabot.yml │ └── workflows │ ├── ci-dependabot-auto-merge.yml │ ├── ci-dependency-check.yml │ └── ci-semantic-release.yml ├── .gitignore ├── .gitkeep ├── .npmignore ├── .npmrc ├── .prettierrc ├── .releaserc.json ├── .trigger-ci ├── CHANGELOG.md ├── eslint.config.mjs ├── jest.setup.js ├── package-lock.json ├── package.json ├── README.md ├── scripts │ ├── ensure-executable.js │ ├── package.json │ └── update-version.js ├── src │ ├── cli │ │ ├── atlassian.diff.cli.ts │ │ ├── atlassian.pullrequests.cli.test.ts │ │ ├── atlassian.pullrequests.cli.ts │ │ ├── atlassian.repositories.cli.test.ts │ │ ├── atlassian.repositories.cli.ts │ │ ├── atlassian.search.cli.test.ts │ │ ├── atlassian.search.cli.ts │ │ ├── atlassian.workspaces.cli.test.ts │ │ ├── atlassian.workspaces.cli.ts │ │ └── index.ts │ ├── controllers │ │ ├── atlassian.diff.controller.ts │ │ ├── atlassian.diff.formatter.ts │ │ ├── atlassian.pullrequests.approve.controller.ts │ │ ├── atlassian.pullrequests.base.controller.ts │ │ ├── atlassian.pullrequests.comments.controller.ts │ │ ├── atlassian.pullrequests.controller.test.ts │ │ ├── atlassian.pullrequests.controller.ts │ │ ├── atlassian.pullrequests.create.controller.ts │ │ ├── atlassian.pullrequests.formatter.ts │ │ ├── atlassian.pullrequests.get.controller.ts │ │ ├── atlassian.pullrequests.list.controller.ts │ │ ├── atlassian.pullrequests.reject.controller.ts │ │ ├── atlassian.pullrequests.update.controller.ts │ │ ├── atlassian.repositories.branch.controller.ts │ │ ├── atlassian.repositories.commit.controller.ts │ │ ├── atlassian.repositories.content.controller.ts │ │ ├── atlassian.repositories.controller.test.ts │ │ ├── atlassian.repositories.details.controller.ts │ │ ├── atlassian.repositories.formatter.ts │ │ ├── atlassian.repositories.list.controller.ts │ │ ├── atlassian.search.code.controller.ts │ │ ├── atlassian.search.content.controller.ts │ │ ├── atlassian.search.controller.test.ts │ │ ├── atlassian.search.controller.ts │ │ ├── atlassian.search.formatter.ts │ │ ├── atlassian.search.pullrequests.controller.ts │ │ ├── atlassian.search.repositories.controller.ts │ │ ├── atlassian.workspaces.controller.test.ts │ │ ├── atlassian.workspaces.controller.ts │ │ └── atlassian.workspaces.formatter.ts │ ├── index.ts │ ├── services │ │ ├── vendor.atlassian.pullrequests.service.ts │ │ ├── vendor.atlassian.pullrequests.test.ts │ │ ├── vendor.atlassian.pullrequests.types.ts │ │ ├── vendor.atlassian.repositories.diff.service.ts │ │ ├── vendor.atlassian.repositories.diff.types.ts │ │ ├── vendor.atlassian.repositories.service.test.ts │ │ ├── vendor.atlassian.repositories.service.ts │ │ ├── vendor.atlassian.repositories.types.ts │ │ ├── vendor.atlassian.search.service.ts │ │ ├── vendor.atlassian.search.types.ts │ │ ├── vendor.atlassian.workspaces.service.ts │ │ ├── vendor.atlassian.workspaces.test.ts │ │ └── vendor.atlassian.workspaces.types.ts │ ├── tools │ │ ├── atlassian.diff.tool.ts │ │ ├── atlassian.diff.types.ts │ │ ├── atlassian.pullrequests.tool.ts │ │ ├── atlassian.pullrequests.types.test.ts │ │ ├── atlassian.pullrequests.types.ts │ │ ├── atlassian.repositories.tool.ts │ │ ├── atlassian.repositories.types.ts │ │ ├── atlassian.search.tool.ts │ │ ├── atlassian.search.types.ts │ │ ├── atlassian.workspaces.tool.ts │ │ └── atlassian.workspaces.types.ts │ ├── types │ │ └── common.types.ts │ └── utils │ ├── adf.util.test.ts │ ├── adf.util.ts │ ├── atlassian.util.ts │ ├── bitbucket-error-detection.test.ts │ ├── cli.test.util.ts │ ├── config.util.test.ts │ ├── config.util.ts │ ├── constants.util.ts │ ├── defaults.util.ts │ ├── diff.util.ts │ ├── error-handler.util.test.ts │ ├── error-handler.util.ts │ ├── error.util.test.ts │ ├── error.util.ts │ ├── formatter.util.ts │ ├── logger.util.ts │ ├── markdown.util.test.ts │ ├── markdown.util.ts │ ├── pagination.util.ts │ ├── path.util.test.ts │ ├── path.util.ts │ ├── query.util.ts │ ├── shell.util.ts │ ├── transport.util.test.ts │ ├── transport.util.ts │ └── workspace.util.ts ├── STYLE_GUIDE.md └── tsconfig.json ``` # Files -------------------------------------------------------------------------------- /src/cli/atlassian.pullrequests.cli.ts: -------------------------------------------------------------------------------- ```typescript import { Command } from 'commander'; import { Logger } from '../utils/logger.util.js'; import { handleCliError } from '../utils/error.util.js'; import atlassianPullRequestsController from '../controllers/atlassian.pullrequests.controller.js'; /** * CLI module for managing Bitbucket pull requests. * Provides commands for listing, retrieving, and manipulating pull requests. * All commands require valid Atlassian credentials. */ // Create a contextualized logger for this file const cliLogger = Logger.forContext('cli/atlassian.pullrequests.cli.ts'); // Log CLI initialization cliLogger.debug('Bitbucket pull requests CLI module initialized'); /** * Register Bitbucket pull requests CLI commands with the Commander program * @param program - The Commander program instance to register commands with * @throws Error if command registration fails */ function register(program: Command): void { const methodLogger = Logger.forContext( 'cli/atlassian.pullrequests.cli.ts', 'register', ); methodLogger.debug('Registering Bitbucket Pull Requests CLI commands...'); registerListPullRequestsCommand(program); registerGetPullRequestCommand(program); registerListPullRequestCommentsCommand(program); registerAddPullRequestCommentCommand(program); registerAddPullRequestCommand(program); registerUpdatePullRequestCommand(program); registerApprovePullRequestCommand(program); registerRejectPullRequestCommand(program); methodLogger.debug('CLI commands registered successfully'); } /** * Register the command for listing Bitbucket pull requests * @param program - The Commander program instance */ function registerListPullRequestsCommand(program: Command): void { program .command('ls-prs') .description( 'List pull requests in a Bitbucket repository, with filtering and pagination.', ) .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository. If not provided, the system will use your default workspace (either configured via BITBUCKET_DEFAULT_WORKSPACE or the first workspace in your account). Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug containing the pull requests. This must be a valid repository in the specified workspace. Example: "project-api"', ) .option( '-s, --state <state>', 'Filter by pull request state: "OPEN", "MERGED", "DECLINED", or "SUPERSEDED". If omitted, returns pull requests in all states.', ) .option( '-q, --query <string>', 'Filter pull requests by query string. Searches pull request title and description.', ) .option( '-l, --limit <number>', 'Maximum number of items to return (1-100). Defaults to 25 if omitted.', ) .option( '-c, --cursor <string>', 'Pagination cursor for retrieving the next set of results.', ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.pullrequests.cli.ts', 'ls-prs', ); try { actionLogger.debug('Processing command options:', options); // Map CLI options to controller params - keep only type conversions const filterOptions = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, state: options.state as | 'OPEN' | 'MERGED' | 'DECLINED' | 'SUPERSEDED' | undefined, query: options.query, limit: options.limit ? parseInt(options.limit, 10) : undefined, cursor: options.cursor, }; actionLogger.debug( 'Fetching pull requests with filters:', filterOptions, ); const result = await atlassianPullRequestsController.list(filterOptions); actionLogger.debug('Successfully retrieved pull requests'); // Display the content which now includes pagination information console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } /** * Register the command for retrieving a specific Bitbucket pull request * @param program - The Commander program instance */ function registerGetPullRequestCommand(program: Command): void { program .command('get-pr') .description( 'Get detailed information about a specific Bitbucket pull request.', ) .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository. If not provided, uses your default workspace. Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug containing the pull request. Must be a valid repository in the specified workspace. Example: "project-api"', ) .requiredOption( '-p, --pr-id <id>', 'Numeric ID of the pull request to retrieve. Must be a valid pull request ID in the specified repository. Example: "42"', ) .option( '--include-full-diff', 'Retrieve the full diff content instead of just the summary. Default: true (rich output by default)', true, ) .option( '--include-comments', 'Retrieve comments for the pull request. Default: false. Note: Enabling this may increase response time for pull requests with many comments due to additional API calls', false, ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.pullrequests.cli.ts', 'get-pr', ); try { actionLogger.debug('Processing command options:', options); // Map CLI options to controller params const params = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, prId: options.prId, includeFullDiff: options.includeFullDiff, includeComments: options.includeComments, }; actionLogger.debug('Fetching pull request:', params); const result = await atlassianPullRequestsController.get(params); actionLogger.debug('Successfully retrieved pull request'); console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } /** * Register the command for listing comments on a Bitbucket pull request * @param program - The Commander program instance */ function registerListPullRequestCommentsCommand(program: Command): void { program .command('ls-pr-comments') .description( 'List comments on a specific Bitbucket pull request, with pagination.', ) .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository. If not provided, uses your default workspace. Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug containing the pull request. Must be a valid repository in the specified workspace. Example: "project-api"', ) .requiredOption( '-p, --pr-id <id>', 'Numeric ID of the pull request to retrieve comments from. Must be a valid pull request ID in the specified repository. Example: "42"', ) .option( '-l, --limit <number>', 'Maximum number of items to return (1-100). Defaults to 25 if omitted.', ) .option( '-c, --cursor <string>', 'Pagination cursor for retrieving the next set of results.', ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.pullrequests.cli.ts', 'ls-pr-comments', ); try { actionLogger.debug('Processing command options:', options); // Map CLI options to controller params - keep only type conversions const params = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, prId: options.prId, limit: options.limit ? parseInt(options.limit, 10) : undefined, cursor: options.cursor, }; actionLogger.debug('Fetching pull request comments:', params); const result = await atlassianPullRequestsController.listComments(params); actionLogger.debug( 'Successfully retrieved pull request comments', ); // Display the content which now includes pagination information console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } /** * Register the command for adding a comment to a pull request * @param program - The Commander program instance */ function registerAddPullRequestCommentCommand(program: Command): void { program .command('add-pr-comment') .description('Add a comment to a Bitbucket pull request.') .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository. If not provided, uses your default workspace. Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug containing the pull request. Must be a valid repository in the specified workspace. Example: "project-api"', ) .requiredOption( '-p, --pr-id <id>', 'Numeric ID of the pull request to add a comment to. Must be a valid pull request ID in the specified repository. Example: "42"', ) .requiredOption( '-m, --content <text>', 'The content of the comment to add to the pull request. Can include markdown formatting.', ) .option( '-f, --path <file-path>', 'Optional: The file path to add an inline comment to.', ) .option( '-L, --line <line-number>', 'Optional: The line number to add the inline comment to.', parseInt, ) .option( '--parent-id <id>', 'Optional: The ID of the parent comment to reply to. If provided, this comment will be a reply to the specified comment.', ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.pullrequests.cli.ts', 'add-pr-comment', ); try { actionLogger.debug('Processing command options:', options); // Build parameters object const params: { workspaceSlug?: string; repoSlug: string; prId: string; content: string; inline?: { path: string; line: number; }; parentId?: string; } = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, prId: options.prId, content: options.content, }; // Add inline comment details if both path and line are provided if (options.path && options.line) { params.inline = { path: options.path, line: options.line, }; } else if (options.path || options.line) { throw new Error( 'Both -f/--path and -L/--line are required for inline comments', ); } // Add parent ID if provided if (options.parentId) { params.parentId = options.parentId; } actionLogger.debug('Creating pull request comment:', { ...params, content: '(content length: ' + options.content.length + ')', }); const result = await atlassianPullRequestsController.addComment(params); actionLogger.debug('Successfully created pull request comment'); console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } /** * Register the command for adding a new pull request * @param program - The Commander program instance */ function registerAddPullRequestCommand(program: Command): void { program .command('add-pr') .description('Add a new pull request in a Bitbucket repository.') .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository. If not provided, uses your default workspace. Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug to create the pull request in. Must be a valid repository in the specified workspace. Example: "project-api"', ) .requiredOption( '-t, --title <title>', 'Title for the pull request. Example: "Add new feature"', ) .requiredOption( '-s, --source-branch <branch>', 'Source branch name (the branch containing your changes). Example: "feature/new-login"', ) .option( '-d, --destination-branch <branch>', 'Destination branch name (the branch you want to merge into, defaults to main). Example: "develop"', ) .option( '--description <text>', 'Optional description for the pull request.', ) .option( '--close-source-branch', 'Whether to close the source branch after the pull request is merged. Default: false', false, ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.pullrequests.cli.ts', 'add-pr', ); try { actionLogger.debug('Processing command options:', options); // Map CLI options to controller params const params = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, title: options.title, sourceBranch: options.sourceBranch, destinationBranch: options.destinationBranch, description: options.description, closeSourceBranch: options.closeSourceBranch, }; actionLogger.debug('Creating pull request:', { ...params, description: options.description ? '(description provided)' : '(no description)', }); const result = await atlassianPullRequestsController.add(params); actionLogger.debug('Successfully created pull request'); console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } /** * Register the command for updating a Bitbucket pull request * @param program - The Commander program instance */ function registerUpdatePullRequestCommand(program: Command): void { program .command('update-pr') .description( 'Update an existing pull request in a Bitbucket repository.', ) .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository (optional, uses default workspace if not provided). Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug containing the pull request. Example: "project-api"', ) .requiredOption( '-p, --pull-request-id <id>', 'Pull request ID to update. Example: 123', parseInt, ) .option( '-t, --title <title>', 'Updated title for the pull request. Example: "Updated Feature Implementation"', ) .option( '--description <text>', 'Updated description for the pull request.', ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.pullrequests.cli.ts', 'update-pr', ); try { actionLogger.debug('Processing command options:', options); // Validate that at least one field to update is provided if (!options.title && !options.description) { throw new Error( 'At least one field to update (title or description) must be provided', ); } // Map CLI options to controller params const params = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, pullRequestId: options.pullRequestId, title: options.title, description: options.description, }; actionLogger.debug('Updating pull request:', { ...params, description: options.description ? '(description provided)' : '(no description)', }); const result = await atlassianPullRequestsController.update(params); actionLogger.debug('Successfully updated pull request'); console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } /** * Register the command for approving a Bitbucket pull request * @param program - The Commander program instance */ function registerApprovePullRequestCommand(program: Command): void { program .command('approve-pr') .description('Approve a pull request in a Bitbucket repository.') .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository (optional, uses default workspace if not provided). Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug containing the pull request. Example: "project-api"', ) .requiredOption( '-p, --pull-request-id <id>', 'Pull request ID to approve. Example: 123', parseInt, ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.pullrequests.cli.ts', 'approve-pr', ); try { actionLogger.debug('Processing command options:', options); // Map CLI options to controller params const params = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, pullRequestId: options.pullRequestId, }; actionLogger.debug('Approving pull request:', params); const result = await atlassianPullRequestsController.approve(params); actionLogger.debug('Successfully approved pull request'); console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } /** * Register the command for requesting changes on a Bitbucket pull request * @param program - The Commander program instance */ function registerRejectPullRequestCommand(program: Command): void { program .command('reject-pr') .description( 'Request changes on a pull request in a Bitbucket repository.', ) .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository (optional, uses default workspace if not provided). Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug containing the pull request. Example: "project-api"', ) .requiredOption( '-p, --pull-request-id <id>', 'Pull request ID to request changes on. Example: 123', parseInt, ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.pullrequests.cli.ts', 'reject-pr', ); try { actionLogger.debug('Processing command options:', options); // Map CLI options to controller params const params = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, pullRequestId: options.pullRequestId, }; actionLogger.debug( 'Requesting changes on pull request:', params, ); const result = await atlassianPullRequestsController.reject(params); actionLogger.debug( 'Successfully requested changes on pull request', ); console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } export default { register }; ``` -------------------------------------------------------------------------------- /src/cli/atlassian.pullrequests.cli.test.ts: -------------------------------------------------------------------------------- ```typescript import { CliTestUtil } from '../utils/cli.test.util.js'; import { getAtlassianCredentials } from '../utils/transport.util.js'; import { config } from '../utils/config.util.js'; describe('Atlassian Pull Requests CLI Commands', () => { // Load configuration and check for credentials before all tests beforeAll(() => { // Load configuration from all sources config.load(); // Log warning if credentials aren't available const credentials = getAtlassianCredentials(); if (!credentials) { console.warn( 'Skipping Atlassian Pull Requests CLI tests: No credentials available', ); } }); // Helper function to skip tests when credentials are missing const skipIfNoCredentials = () => { const credentials = getAtlassianCredentials(); if (!credentials) { return true; } return false; }; // Helper to get workspace and repository for testing async function getWorkspaceAndRepo(): Promise<{ workspace: string; repository: string; } | null> { // First, get a list of workspaces const workspacesResult = await CliTestUtil.runCommand([ 'ls-workspaces', ]); // Skip if no workspaces are available if ( workspacesResult.stdout.includes('No Bitbucket workspaces found.') ) { return null; // Skip silently for this helper function } // Extract a workspace slug from the output const slugMatch = workspacesResult.stdout.match( /\*\*Slug\*\*:\s+([^\n]+)/, ); if (!slugMatch || !slugMatch[1]) { return null; // Skip silently for this helper function } const workspaceSlug = slugMatch[1].trim(); // Get repositories for this workspace const reposResult = await CliTestUtil.runCommand([ 'ls-repos', '--workspace-slug', workspaceSlug, ]); // Skip if no repositories are available if (reposResult.stdout.includes('No repositories found')) { return null; // Skip silently for this helper function } // Extract a repository slug from the output const repoMatch = reposResult.stdout.match(/\*\*Name\*\*:\s+([^\n]+)/); if (!repoMatch || !repoMatch[1]) { return null; // Skip silently for this helper function } const repoSlug = repoMatch[1].trim(); return { workspace: workspaceSlug, repository: repoSlug, }; } describe('ls-prs command', () => { it('should list pull requests for a repository', async () => { if (skipIfNoCredentials()) { return; } // Get a valid workspace and repository const repoInfo = await getWorkspaceAndRepo(); if (!repoInfo) { return; // Skip if no valid workspace/repo found } // Run the CLI command const result = await CliTestUtil.runCommand([ 'ls-prs', '--workspace-slug', repoInfo.workspace, '--repo-slug', repoInfo.repository, ]); // Instead of expecting success, handle both success and failure if (result.exitCode !== 0) { console.warn( 'Skipping test validation: Could not list pull requests', ); return; } // Verify the output format if (!result.stdout.includes('No pull requests found')) { // Validate expected Markdown structure CliTestUtil.validateOutputContains(result.stdout, [ '# Bitbucket Pull Requests', '**ID**', '**State**', '**Author**', ]); // Validate Markdown formatting CliTestUtil.validateMarkdownOutput(result.stdout); } }, 30000); // Increased timeout for API calls it('should support filtering by state', async () => { if (skipIfNoCredentials()) { return; } // Get a valid workspace and repository const repoInfo = await getWorkspaceAndRepo(); if (!repoInfo) { return; // Skip if no valid workspace/repo found } // States to test const states = ['OPEN', 'MERGED', 'DECLINED']; let testsPassed = false; for (const state of states) { // Run the CLI command with state filter const result = await CliTestUtil.runCommand([ 'ls-prs', '--workspace-slug', repoInfo.workspace, '--repo-slug', repoInfo.repository, '--state', state, ]); // If any command succeeds, consider the test as passed if (result.exitCode === 0) { testsPassed = true; // Verify the output includes state if PRs are found if (!result.stdout.includes('No pull requests found')) { expect(result.stdout.toUpperCase()).toContain(state); } } } // If all commands failed, log a warning and consider the test skipped if (!testsPassed) { console.warn( 'Skipping test validation: Could not list pull requests with state filter', ); } }, 45000); // Increased timeout for multiple API calls it('should support pagination with --limit flag', async () => { if (skipIfNoCredentials()) { return; } // Get a valid workspace and repository const repoInfo = await getWorkspaceAndRepo(); if (!repoInfo) { return; // Skip if no valid workspace/repo found } // Run the CLI command with limit const result = await CliTestUtil.runCommand([ 'ls-prs', '--workspace-slug', repoInfo.workspace, '--repo-slug', repoInfo.repository, '--limit', '1', ]); // Instead of expecting success, handle both success and failure if (result.exitCode !== 0) { console.warn( 'Skipping test validation: Could not list pull requests with pagination', ); return; } // If there are multiple PRs, pagination section should be present if ( !result.stdout.includes('No pull requests found') && result.stdout.includes('items remaining') ) { CliTestUtil.validateOutputContains(result.stdout, [ 'Pagination', 'Next cursor:', ]); } }, 30000); }); describe('get-pr command', () => { it('should retrieve details for a specific pull request', async () => { if (skipIfNoCredentials()) { return; } // Get a valid workspace and repository const repoInfo = await getWorkspaceAndRepo(); if (!repoInfo) { return; // Skip if no valid workspace/repo found } // First, list pull requests to find a valid ID const listResult = await CliTestUtil.runCommand([ 'ls-prs', '--workspace-slug', repoInfo.workspace, '--repo-slug', repoInfo.repository, ]); // Skip if no pull requests are available if (listResult.stdout.includes('No pull requests found')) { return; // Skip silently - no pull requests available } // Extract a pull request ID from the output const prMatch = listResult.stdout.match(/\*\*ID\*\*:\s+(\d+)/); if (!prMatch || !prMatch[1]) { console.warn( 'Skipping test: Could not extract pull request ID', ); return; } const prId = prMatch[1].trim(); // Skip the full validation since we can't guarantee PRs exist // Just verify that the test can find a valid ID and run the command if (prId) { // Run the get-pr command const getResult = await CliTestUtil.runCommand([ 'get-pr', '--workspace-slug', repoInfo.workspace, '--repo-slug', repoInfo.repository, '--pr-id', prId, ]); // The test may pass or fail depending on if the PR exists // Just check that we get a result back expect(getResult).toBeDefined(); } else { // Skip test if no PR ID found return; // Skip silently - no pull request ID available } }, 45000); // Increased timeout for multiple API calls it('should handle missing required parameters', async () => { if (skipIfNoCredentials()) { return; } // Test without workspace parameter (now optional) const missingWorkspace = await CliTestUtil.runCommand([ 'get-pr', '--repo-slug', 'some-repo', '--pr-id', '1', ]); // Now that workspace is optional, we should get a different error // (repository not found), but not a missing parameter error expect(missingWorkspace.exitCode).not.toBe(0); expect(missingWorkspace.stderr).not.toContain('workspace-slug'); // Test without repository parameter const missingRepo = await CliTestUtil.runCommand([ 'get-pr', '--workspace-slug', 'some-workspace', '--pr-id', '1', ]); // Should fail with non-zero exit code expect(missingRepo.exitCode).not.toBe(0); expect(missingRepo.stderr).toContain('required option'); // Test without pull-request parameter const missingPR = await CliTestUtil.runCommand([ 'get-pr', '--workspace-slug', 'some-workspace', '--repo-slug', 'some-repo', ]); // Should fail with non-zero exit code expect(missingPR.exitCode).not.toBe(0); expect(missingPR.stderr).toContain('required option'); }, 15000); }); describe('ls-pr-comments command', () => { it('should list comments for a specific pull request', async () => { if (skipIfNoCredentials()) { return; } // Get a valid workspace and repository const repoInfo = await getWorkspaceAndRepo(); if (!repoInfo) { return; // Skip if no valid workspace/repo found } // First, list pull requests to find a valid ID const listResult = await CliTestUtil.runCommand([ 'ls-prs', '--workspace-slug', repoInfo.workspace, '--repo-slug', repoInfo.repository, ]); // Skip if no pull requests are available if (listResult.stdout.includes('No pull requests found')) { return; // Skip silently - no pull requests available } // Extract a pull request ID from the output const prMatch = listResult.stdout.match(/\*\*ID\*\*:\s+(\d+)/); if (!prMatch || !prMatch[1]) { console.warn( 'Skipping test: Could not extract pull request ID', ); return; } const prId = prMatch[1].trim(); // Skip the full validation since we can't guarantee PRs exist // Just verify that the test can find a valid ID and run the command if (prId) { // Run the ls-pr-comments command const result = await CliTestUtil.runCommand([ 'ls-pr-comments', '--workspace-slug', repoInfo.workspace, '--repo-slug', repoInfo.repository, '--pr-id', prId, ]); // The test may pass or fail depending on if the PR exists // Just check that we get a result back expect(result).toBeDefined(); } else { // Skip test if no PR ID found return; // Skip silently - no pull request ID available } }, 45000); // Increased timeout for multiple API calls it('should handle missing required parameters', async () => { if (skipIfNoCredentials()) { return; } // Test without workspace parameter (now optional) const missingWorkspace = await CliTestUtil.runCommand([ 'ls-pr-comments', '--repo-slug', 'some-repo', '--pr-id', '1', ]); // Now that workspace is optional, we should get a different error // (repository not found), but not a missing parameter error expect(missingWorkspace.exitCode).not.toBe(0); expect(missingWorkspace.stderr).not.toContain('workspace-slug'); // Test without repository parameter const missingRepo = await CliTestUtil.runCommand([ 'ls-pr-comments', '--workspace-slug', 'some-workspace', '--pr-id', '1', ]); // Should fail with non-zero exit code expect(missingRepo.exitCode).not.toBe(0); expect(missingRepo.stderr).toContain('required option'); // Test without pull-request parameter const missingPR = await CliTestUtil.runCommand([ 'ls-pr-comments', '--workspace-slug', 'some-workspace', '--repo-slug', 'some-repo', ]); // Should fail with non-zero exit code expect(missingPR.exitCode).not.toBe(0); expect(missingPR.stderr).toContain('required option'); }, 15000); }); describe('ls-pr-comments with pagination', () => { it('should list comments for a specific pull request with pagination', async () => { if (skipIfNoCredentials()) { return; } // Get a valid workspace and repository const repoInfo = await getWorkspaceAndRepo(); if (!repoInfo) { return; // Skip if no valid workspace/repo found } // First, list pull requests to find a valid ID const listResult = await CliTestUtil.runCommand([ 'ls-prs', '--workspace-slug', repoInfo.workspace, '--repo-slug', repoInfo.repository, ]); // Skip if no pull requests are available if (listResult.stdout.includes('No pull requests found')) { return; // Skip silently - no pull requests available } // Extract a pull request ID from the output const prMatch = listResult.stdout.match(/\*\*ID\*\*:\s+(\d+)/); if (!prMatch || !prMatch[1]) { console.warn( 'Skipping test: Could not extract pull request ID', ); return; } const prId = prMatch[1].trim(); // Skip the full validation since we can't guarantee PRs exist // Just verify that the test can find a valid ID and run the command if (prId) { // Run with pagination limit const limitResult = await CliTestUtil.runCommand([ 'ls-pr-comments', '--workspace-slug', repoInfo.workspace, '--repo-slug', repoInfo.repository, '--pr-id', prId, '--limit', '1', ]); // The test may pass or fail depending on if the PR exists // Just check that we get a result back expect(limitResult).toBeDefined(); } else { // Skip test if no PR ID found return; // Skip silently - no pull request ID available } }, 45000); // Increased timeout for multiple API calls }); describe('add-pr-comment command', () => { it('should display help information', async () => { const result = await CliTestUtil.runCommand([ 'add-pr-comment', '--help', ]); expect(result.exitCode).toBe(0); expect(result.stdout).toContain( 'Add a comment to a Bitbucket pull request.', ); expect(result.stdout).toContain('--workspace-slug'); expect(result.stdout).toContain('--repo-slug'); expect(result.stdout).toContain('--pr-id'); expect(result.stdout).toContain('--content'); expect(result.stdout).toContain('--path'); expect(result.stdout).toContain('--line'); expect(result.stdout).toContain('--parent-id'); }); it('should require repo-slug parameter', async () => { const result = await CliTestUtil.runCommand([ 'add-pr-comment', '--workspace-slug', 'codapayments', ]); expect(result.exitCode).not.toBe(0); expect(result.stderr).toContain('required option'); expect(result.stderr).toContain('repo-slug'); }); it('should use default workspace when workspace is not provided', async () => { const result = await CliTestUtil.runCommand(['add-pr-comment']); expect(result.exitCode).not.toBe(0); expect(result.stderr).toContain('required option'); // Should require repo-slug but not workspace-slug expect(result.stderr).toContain('repo-slug'); expect(result.stderr).not.toContain('workspace-slug'); }); it('should require pr-id parameter', async () => { const result = await CliTestUtil.runCommand([ 'add-pr-comment', '--workspace-slug', 'codapayments', '--repo-slug', 'repo-1', ]); expect(result.exitCode).not.toBe(0); expect(result.stderr).toContain('required option'); expect(result.stderr).toContain('pr-id'); }); it('should require content parameter', async () => { const result = await CliTestUtil.runCommand([ 'add-pr-comment', '--workspace-slug', 'codapayments', '--repo-slug', 'repo-1', '--pr-id', '1', ]); expect(result.exitCode).not.toBe(0); expect(result.stderr).toContain('required option'); expect(result.stderr).toContain('content'); }); it('should detect incomplete inline comment parameters', async () => { const result = await CliTestUtil.runCommand([ 'add-pr-comment', '--workspace-slug', 'codapayments', '--repo-slug', 'repo-1', '--pr-id', '1', '--content', 'Test', '--path', 'README.md', ]); expect(result.exitCode).not.toBe(0); expect(result.stderr).toContain( 'Both -f/--path and -L/--line are required for inline comments', ); }); it('should accept valid parentId parameter for comment replies', async () => { const result = await CliTestUtil.runCommand([ 'add-pr-comment', '--workspace-slug', 'codapayments', '--repo-slug', 'repo-1', '--pr-id', '1', '--content', 'This is a reply', '--parent-id', '123', ]); // Should fail due to invalid repo/PR, but not due to parentId parameter validation expect(result.exitCode).not.toBe(0); // Should NOT contain parameter validation errors for parentId expect(result.stderr).not.toContain('parent-id'); }); // Note: API call test has been removed to avoid creating comments on real PRs during tests }); describe('add-pr command', () => { it('should display help information', async () => { const result = await CliTestUtil.runCommand(['add-pr', '--help']); expect(result.exitCode).toBe(0); expect(result.stdout).toContain( 'Add a new pull request in a Bitbucket repository.', ); expect(result.stdout).toContain('--workspace-slug'); expect(result.stdout).toContain('--repo-slug'); expect(result.stdout).toContain('--title'); expect(result.stdout).toContain('--source-branch'); expect(result.stdout).toContain('--destination-branch'); expect(result.stdout).toContain('--description'); expect(result.stdout).toContain('--close-source-branch'); }); it('should require repo-slug parameter', async () => { const result = await CliTestUtil.runCommand([ 'add-pr', '--workspace-slug', 'test-ws', ]); expect(result.exitCode).not.toBe(0); expect(result.stderr).toContain('required option'); expect(result.stderr).toContain('repo-slug'); }); it('should use default workspace when workspace is not provided', async () => { const result = await CliTestUtil.runCommand(['add-pr']); expect(result.exitCode).not.toBe(0); expect(result.stderr).toContain('required option'); // Should require repo-slug but not workspace-slug expect(result.stderr).toContain('repo-slug'); expect(result.stderr).not.toContain('workspace-slug'); }); it('should require title parameter', async () => { const result = await CliTestUtil.runCommand([ 'add-pr', '--workspace-slug', 'test-ws', '--repo-slug', 'test-repo', ]); expect(result.exitCode).not.toBe(0); expect(result.stderr).toContain('required option'); expect(result.stderr).toContain('title'); }); it('should require source-branch parameter', async () => { const result = await CliTestUtil.runCommand([ 'add-pr', '--workspace-slug', 'test-ws', '--repo-slug', 'test-repo', '--title', 'Test PR', ]); expect(result.exitCode).not.toBe(0); expect(result.stderr).toContain('required option'); expect(result.stderr).toContain('source-branch'); }); // Note: API call test has been removed to avoid creating PRs on real repos during tests }); }); ``` -------------------------------------------------------------------------------- /src/controllers/atlassian.pullrequests.controller.test.ts: -------------------------------------------------------------------------------- ```typescript import { McpError, ErrorType } from '../utils/error.util.js'; import atlassianPullRequestsController from './atlassian.pullrequests.controller.js'; import { getAtlassianCredentials } from '../utils/transport.util.js'; import atlassianPullRequestsService from '../services/vendor.atlassian.pullrequests.service.js'; import atlassianWorkspacesService from '../services/vendor.atlassian.workspaces.service.js'; import atlassianRepositoriesService from '../services/vendor.atlassian.repositories.service.js'; describe('Atlassian Pull Requests Controller', () => { const skipIfNoCredentials = () => !getAtlassianCredentials(); async function getRepositoryInfo(): Promise<{ workspaceSlug: string; repoSlug: string; } | null> { // Skip if no credentials if (skipIfNoCredentials()) return null; try { // Try to get workspaces const workspacesResponse = await atlassianWorkspacesService.list({ pagelen: 1, }); if ( !workspacesResponse.values || workspacesResponse.values.length === 0 ) { console.warn('No workspaces found for test account'); return null; } const workspace = workspacesResponse.values[0]; // The workspace slug might be in different locations depending on the response structure // Try to access it safely from possible locations const workspaceSlug = workspace.workspace?.slug || (workspace as any).slug || (workspace as any).name || null; if (!workspaceSlug) { console.warn( 'Could not determine workspace slug from response', ); return null; } // Get repositories for this workspace const reposResponse = await atlassianRepositoriesService.list({ workspace: workspaceSlug, pagelen: 1, }); if (!reposResponse.values || reposResponse.values.length === 0) { console.warn( `No repositories found in workspace ${workspaceSlug}`, ); return null; } const repo = reposResponse.values[0]; // The repo slug might be in different locations or named differently const repoSlug = (repo as any).slug || (repo as any).name || (repo.full_name?.split('/').pop() as string) || null; if (!repoSlug) { console.warn( 'Could not determine repository slug from response', ); return null; } return { workspaceSlug, repoSlug, }; } catch (error) { console.warn('Failed to get repository info for tests:', error); return null; } } async function getFirstPullRequestId(): Promise<{ workspaceSlug: string; repoSlug: string; prId: string; } | null> { const repoInfo = await getRepositoryInfo(); if (!repoInfo) return null; try { // List PRs const prsResponse = await atlassianPullRequestsService.list({ workspace: repoInfo.workspaceSlug, repo_slug: repoInfo.repoSlug, pagelen: 1, }); if (!prsResponse.values || prsResponse.values.length === 0) { console.warn( `No pull requests found in ${repoInfo.workspaceSlug}/${repoInfo.repoSlug}`, ); return null; } // Return the first PR's info return { workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, prId: prsResponse.values[0].id.toString(), }; } catch (error) { console.warn('Failed to get pull request ID for tests:', error); return null; } } async function getPullRequestInfo(): Promise<{ workspaceSlug: string; repoSlug: string; prId: string; } | null> { // Attempt to get a first PR ID return await getFirstPullRequestId(); } // List tests describe('list', () => { it('should list pull requests for a repository', async () => { if (skipIfNoCredentials()) return; const repoInfo = await getRepositoryInfo(); if (!repoInfo) { console.warn('Skipping test: No repository info found.'); return; } const result = await atlassianPullRequestsController.list({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, }); // Verify the response structure expect(result).toHaveProperty('content'); expect(typeof result.content).toBe('string'); // Check for expected format based on the formatter output expect(result.content).toMatch(/^# Pull Requests/); }, 30000); it('should handle query parameters correctly', async () => { if (skipIfNoCredentials()) return; const repoInfo = await getRepositoryInfo(); if (!repoInfo) { console.warn('Skipping test: No repository info found.'); return; } // A query term that should not match any PRs in any normal repo const uniqueQuery = 'z9x8c7vb6nm5'; const result = await atlassianPullRequestsController.list({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, query: uniqueQuery, }); // Even with no matches, we expect a formatted empty list expect(result).toHaveProperty('content'); expect(result.content).toMatch(/^# Pull Requests/); expect(result.content).toContain('No pull requests found'); }, 30000); it('should handle pagination options (limit)', async () => { if (skipIfNoCredentials()) return; const repoInfo = await getRepositoryInfo(); if (!repoInfo) { console.warn('Skipping test: No repository info found.'); return; } // Fetch with a small limit const result = await atlassianPullRequestsController.list({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, limit: 1, }); // Verify the response structure expect(result).toHaveProperty('content'); // Check if the result contains only one PR or none // First check if there are no PRs if (result.content.includes('No pull requests found')) { console.warn('No pull requests found for pagination test.'); return; } // Extract count const countMatch = result.content.match(/\*Showing (\d+) item/); if (countMatch && countMatch[1]) { const count = parseInt(countMatch[1], 10); expect(count).toBeLessThanOrEqual(1); } }, 30000); it('should handle authorization errors gracefully', async () => { if (skipIfNoCredentials()) return; const repoInfo = await getRepositoryInfo(); if (!repoInfo) { console.warn('Skipping test: No repository info found.'); return; } // Create mocked credentials error by using intentionally invalid credentials jest.spyOn( atlassianPullRequestsService, 'list', ).mockRejectedValueOnce( new McpError('Unauthorized', ErrorType.AUTH_INVALID, 401), ); // Expect to throw a standardized error await expect( atlassianPullRequestsController.list({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, }), ).rejects.toThrow(McpError); // Verify it was called expect(atlassianPullRequestsService.list).toHaveBeenCalled(); // Cleanup mock jest.restoreAllMocks(); }, 30000); it('should require workspace and repository slugs', async () => { if (skipIfNoCredentials()) return; // Missing both slugs await expect( atlassianPullRequestsController.list({} as any), ).rejects.toThrow( /workspace slug and repository slug are required/i, ); // Missing repo slug await expect( atlassianPullRequestsController.list({ workspaceSlug: 'some-workspace', } as any), ).rejects.toThrow( /workspace slug and repository slug are required/i, ); // Missing workspace slug but should try to use default // This will fail with a different error if no default workspace can be found try { await atlassianPullRequestsController.list({ repoSlug: 'some-repo', } as any); } catch (error) { expect(error).toBeInstanceOf(Error); // Either it will fail with "could not determine default" or // it may succeed with a default workspace but fail with a different error } }, 10000); it('should apply default parameters correctly', async () => { if (skipIfNoCredentials()) return; const repoInfo = await getRepositoryInfo(); if (!repoInfo) { console.warn('Skipping test: No repository info found.'); return; } const serviceSpy = jest.spyOn(atlassianPullRequestsService, 'list'); try { await atlassianPullRequestsController.list({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, // No limit provided, should use default }); // Check that the service was called with the default limit const calls = serviceSpy.mock.calls; expect(calls.length).toBeGreaterThan(0); const lastCall = calls[calls.length - 1]; expect(lastCall[0]).toHaveProperty('pagelen'); expect(lastCall[0].pagelen).toBeGreaterThan(0); // Should have some positive default value } finally { serviceSpy.mockRestore(); } }, 30000); it('should format pagination information correctly', async () => { if (skipIfNoCredentials()) return; const repoInfo = await getRepositoryInfo(); if (!repoInfo) { console.warn('Skipping test: No repository info found.'); return; } // Mock a response with pagination const mockResponse = { values: [ { id: 1, title: 'Test PR', state: 'OPEN', created_on: new Date().toISOString(), updated_on: new Date().toISOString(), author: { display_name: 'Test User', }, source: { branch: { name: 'feature-branch' }, }, destination: { branch: { name: 'main' }, }, links: {}, }, ], page: 1, size: 1, pagelen: 1, next: 'https://api.bitbucket.org/2.0/repositories/workspace/repo/pullrequests?page=2', }; jest.spyOn( atlassianPullRequestsService, 'list', ).mockResolvedValueOnce(mockResponse as any); const result = await atlassianPullRequestsController.list({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, limit: 1, }); // Verify pagination info is included expect(result.content).toContain('*Showing 1 item'); expect(result.content).toContain('More results are available'); expect(result.content).toContain('Next cursor: `2`'); // Cleanup mock jest.restoreAllMocks(); }, 10000); }); // Get PR tests describe('get', () => { it('should retrieve detailed pull request information', async () => { if (skipIfNoCredentials()) return; const prInfo = await getPullRequestInfo(); if (!prInfo) { console.warn('Skipping test: No pull request info found.'); return; } const result = await atlassianPullRequestsController.get({ workspaceSlug: prInfo.workspaceSlug, repoSlug: prInfo.repoSlug, prId: prInfo.prId, includeFullDiff: false, includeComments: false, }); // Verify the response structure expect(result).toHaveProperty('content'); expect(typeof result.content).toBe('string'); // Check for expected format based on the formatter output expect(result.content).toMatch(/^# Pull Request/); expect(result.content).toContain('**ID**:'); expect(result.content).toContain('**Title**:'); expect(result.content).toContain('**State**:'); expect(result.content).toContain('**Author**:'); expect(result.content).toContain('**Created**:'); }, 30000); it('should handle errors for non-existent pull requests', async () => { if (skipIfNoCredentials()) return; const repoInfo = await getRepositoryInfo(); if (!repoInfo) { console.warn('Skipping test: No repository info found.'); return; } // Use a PR ID that is very unlikely to exist const nonExistentPrId = '999999999'; await expect( atlassianPullRequestsController.get({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, prId: nonExistentPrId, includeFullDiff: false, includeComments: false, }), ).rejects.toThrow(McpError); // Test that the error has the right status code and type try { await atlassianPullRequestsController.get({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, prId: nonExistentPrId, includeFullDiff: false, includeComments: false, }); } catch (error) { expect(error).toBeInstanceOf(McpError); expect((error as McpError).statusCode).toBe(404); expect((error as McpError).message).toContain('not found'); } }, 30000); it('should require all necessary parameters', async () => { if (skipIfNoCredentials()) return; // No parameters should throw await expect( atlassianPullRequestsController.get({} as any), ).rejects.toThrow(); // Missing PR ID should throw const repoInfo = await getRepositoryInfo(); if (repoInfo) { await expect( atlassianPullRequestsController.get({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, // prId: missing } as any), ).rejects.toThrow(); } }, 10000); }); // List comments tests describe('listComments', () => { it('should return formatted pull request comments in Markdown', async () => { if (skipIfNoCredentials()) return; const prInfo = await getFirstPullRequestId(); if (!prInfo) { console.warn('Skipping test: No pull request ID found.'); return; } const result = await atlassianPullRequestsController.listComments({ workspaceSlug: prInfo.workspaceSlug, repoSlug: prInfo.repoSlug, prId: prInfo.prId, }); // Verify the response structure expect(result).toHaveProperty('content'); expect(typeof result.content).toBe('string'); // Basic Markdown content checks if (result.content !== 'No comments found on this pull request.') { expect(result.content).toMatch(/^# Comments on Pull Request/m); expect(result.content).toContain('**Author**:'); expect(result.content).toContain('**Updated**:'); expect(result.content).toMatch( /---\s*\*Showing \d+ items?\.\*/, ); } }, 30000); it('should handle pagination options (limit/cursor)', async () => { if (skipIfNoCredentials()) return; const prInfo = await getFirstPullRequestId(); if (!prInfo) { console.warn('Skipping test: No pull request ID found.'); return; } // Fetch first page with limit 1 const result1 = await atlassianPullRequestsController.listComments({ workspaceSlug: prInfo.workspaceSlug, repoSlug: prInfo.repoSlug, prId: prInfo.prId, limit: 1, }); // Extract pagination info from content const countMatch1 = result1.content.match( /\*Showing (\d+) items?\.\*/, ); const count1 = countMatch1 ? parseInt(countMatch1[1], 10) : 0; expect(count1).toBeLessThanOrEqual(1); // Extract cursor from content const cursorMatch1 = result1.content.match( /\*Next cursor: `([^`]+)`\*/, ); const nextCursor = cursorMatch1 ? cursorMatch1[1] : null; // Check if pagination indicates more results const hasMoreResults = result1.content.includes( 'More results are available.', ); // If there's a next page, fetch it if (hasMoreResults && nextCursor) { const result2 = await atlassianPullRequestsController.listComments({ workspaceSlug: prInfo.workspaceSlug, repoSlug: prInfo.repoSlug, prId: prInfo.prId, limit: 1, cursor: nextCursor, }); // Extract count from result2 const countMatch2 = result2.content.match( /\*Showing (\d+) items?\.\*/, ); const count2 = countMatch2 ? parseInt(countMatch2[1], 10) : 0; expect(count2).toBeLessThanOrEqual(1); // Ensure content is different (or handle case where only 1 comment exists) if ( result1.content !== 'No comments found on this pull request.' && result2.content !== 'No comments found on this pull request.' && count1 > 0 && count2 > 0 ) { // Only compare if we actually have multiple comments expect(result1.content).not.toEqual(result2.content); } } else { console.warn( 'Skipping cursor part of pagination test: Only one page of comments found or no comments available.', ); } }, 30000); it('should handle empty result scenario', async () => { if (skipIfNoCredentials()) return; // First get a PR without comments, or use a non-existent but valid format PR ID const repoInfo = await getRepositoryInfo(); if (!repoInfo) { console.warn('Skipping test: No repository info found.'); return; } // Try to find a PR without comments try { // First check if we can access the repository const repoResult = await atlassianPullRequestsController.list({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, limit: 1, }); // Extract PR ID from the content if we have any PRs const prIdMatch = repoResult.content.match(/\*\*ID\*\*:\s+(\d+)/); if (!prIdMatch || !prIdMatch[1]) { console.warn( 'Skipping empty result test: No pull requests available.', ); return; } const prId = prIdMatch[1]; // Get comments for this PR const commentsResult = await atlassianPullRequestsController.listComments({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, prId, }); // Check if there are no comments if ( commentsResult.content === 'No comments found on this pull request.' ) { // Verify the expected message for empty results expect(commentsResult.content).toBe( 'No comments found on this pull request.', ); } else { console.warn( 'Skipping empty result test: All PRs have comments.', ); } } catch (error) { console.warn('Error during empty result test:', error); } }, 30000); it('should throw an McpError for a non-existent pull request ID', async () => { if (skipIfNoCredentials()) return; const repoInfo = await getRepositoryInfo(); if (!repoInfo) { console.warn('Skipping test: No repository info found.'); return; } const nonExistentId = '999999999'; // Very high number unlikely to exist // Expect the controller call to reject with an McpError await expect( atlassianPullRequestsController.listComments({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, prId: nonExistentId, }), ).rejects.toThrow(McpError); // Check the status code via the error handler's behavior try { await atlassianPullRequestsController.listComments({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, prId: nonExistentId, }); } catch (e) { expect(e).toBeInstanceOf(McpError); expect((e as McpError).statusCode).toBe(404); // Expecting Not Found expect((e as McpError).message).toContain('not found'); } }, 30000); it('should require all necessary parameters', async () => { if (skipIfNoCredentials()) return; // No parameters await expect( atlassianPullRequestsController.listComments({} as any), ).rejects.toThrow(); // Missing PR ID const repoInfo = await getRepositoryInfo(); if (repoInfo) { await expect( atlassianPullRequestsController.listComments({ workspaceSlug: repoInfo.workspaceSlug, repoSlug: repoInfo.repoSlug, // prId: missing } as any), ).rejects.toThrow(); } }, 10000); }); // Note: addComment test suite has been removed to avoid creating comments on real PRs during tests }); ``` -------------------------------------------------------------------------------- /src/services/vendor.atlassian.pullrequests.service.ts: -------------------------------------------------------------------------------- ```typescript import { createAuthMissingError } from '../utils/error.util.js'; import { Logger } from '../utils/logger.util.js'; import { fetchAtlassian, getAtlassianCredentials, } from '../utils/transport.util.js'; import { PullRequestDetailed, PullRequestsResponse, ListPullRequestsParams, GetPullRequestParams, GetPullRequestCommentsParams, PullRequestCommentsResponse, PullRequestComment, CreatePullRequestCommentParams, CreatePullRequestParams, UpdatePullRequestParams, ApprovePullRequestParams, RejectPullRequestParams, PullRequestParticipant, DiffstatResponse, } from './vendor.atlassian.pullrequests.types.js'; /** * Base API path for Bitbucket REST API v2 * @see https://developer.atlassian.com/cloud/bitbucket/rest/api-group-pullrequests/ * @constant {string} */ const API_PATH = '/2.0'; /** * @namespace VendorAtlassianPullRequestsService * @description Service for interacting with Bitbucket Pull Requests API. * Provides methods for listing pull requests and retrieving pull request details. * All methods require valid Atlassian credentials configured in the environment. */ // Create a contextualized logger for this file const serviceLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', ); // Log service initialization serviceLogger.debug('Bitbucket pull requests service initialized'); /** * List pull requests for a repository * @param {ListPullRequestsParams} params - Parameters for the request * @param {string} params.workspace - The workspace slug or UUID * @param {string} params.repo_slug - The repository slug or UUID * @param {PullRequestState | PullRequestState[]} [params.state] - Filter by pull request state (default: 'OPEN') * @param {string} [params.q] - Query string to filter pull requests * @param {string} [params.sort] - Property to sort by (e.g., 'created_on', '-updated_on') * @param {number} [params.page] - Page number for pagination * @param {number} [params.pagelen] - Number of items per page * @returns {Promise<PullRequestsResponse>} Response containing pull requests * @example * ```typescript * // List open pull requests in a repository, sorted by creation date * const response = await list({ * workspace: 'myworkspace', * repo_slug: 'myrepo', * sort: '-created_on', * pagelen: 25 * }); * ``` */ async function list( params: ListPullRequestsParams, ): Promise<PullRequestsResponse> { const methodLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', 'list', ); methodLogger.debug('Listing Bitbucket pull requests with params:', params); if (!params.workspace || !params.repo_slug) { throw new Error('Both workspace and repo_slug parameters are required'); } const credentials = getAtlassianCredentials(); if (!credentials) { throw createAuthMissingError( 'Atlassian credentials are required for this operation', ); } // Construct query parameters const queryParams = new URLSearchParams(); // Add state parameter(s) - default to OPEN if not specified if (params.state) { if (Array.isArray(params.state)) { // For multiple states, repeat the parameter params.state.forEach((state) => { queryParams.append('state', state); }); } else { queryParams.set('state', params.state); } } // Add optional query parameters if (params.q) { queryParams.set('q', params.q); } if (params.sort) { queryParams.set('sort', params.sort); } if (params.pagelen) { queryParams.set('pagelen', params.pagelen.toString()); } if (params.page) { queryParams.set('page', params.page.toString()); } const queryString = queryParams.toString() ? `?${queryParams.toString()}` : ''; const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests${queryString}`; methodLogger.debug(`Sending request to: ${path}`); return fetchAtlassian<PullRequestsResponse>(credentials, path); } /** * Get detailed information about a specific Bitbucket pull request * * Retrieves comprehensive details about a single pull request. * * @async * @memberof VendorAtlassianPullRequestsService * @param {GetPullRequestParams} params - Parameters for the request * @param {string} params.workspace - The workspace slug or UUID * @param {string} params.repo_slug - The repository slug or UUID * @param {number} params.pull_request_id - The ID of the pull request * @returns {Promise<PullRequestDetailed>} Promise containing the detailed pull request information * @throws {Error} If Atlassian credentials are missing or API request fails * @example * // Get pull request details * const pullRequest = await get({ * workspace: 'my-workspace', * repo_slug: 'my-repo', * pull_request_id: 123 * }); */ async function get(params: GetPullRequestParams): Promise<PullRequestDetailed> { const methodLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', 'get', ); methodLogger.debug( `Getting Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`, ); // Validate pull_request_id is a positive integer const prId = Number(params.pull_request_id); if (isNaN(prId) || prId <= 0 || !Number.isInteger(prId)) { throw new Error( `Invalid pull request ID: ${params.pull_request_id}. Pull request ID must be a positive integer.`, ); } if (!params.workspace || !params.repo_slug || !params.pull_request_id) { throw new Error( 'workspace, repo_slug, and pull_request_id parameters are all required', ); } const credentials = getAtlassianCredentials(); if (!credentials) { throw createAuthMissingError( 'Atlassian credentials are required for this operation', ); } const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}`; methodLogger.debug(`Sending request to: ${path}`); return fetchAtlassian<PullRequestDetailed>(credentials, path); } /** * Get comments for a specific Bitbucket pull request * * Retrieves all comments on a specific pull request, including general comments and * inline code review comments. Supports pagination. * * @async * @memberof VendorAtlassianPullRequestsService * @param {GetPullRequestCommentsParams} params - Parameters for the request * @param {string} params.workspace - The workspace slug or UUID * @param {string} params.repo_slug - The repository slug or UUID * @param {number} params.pull_request_id - The ID of the pull request * @param {number} [params.page] - Page number for pagination * @param {number} [params.pagelen] - Number of items per page * @returns {Promise<PullRequestCommentsResponse>} Promise containing the pull request comments * @throws {Error} If Atlassian credentials are missing or API request fails * @example * // Get comments for a pull request * const comments = await getComments({ * workspace: 'my-workspace', * repo_slug: 'my-repo', * pull_request_id: 123, * pagelen: 25 * }); */ async function getComments( params: GetPullRequestCommentsParams, ): Promise<PullRequestCommentsResponse> { const methodLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', 'getComments', ); methodLogger.debug( `Getting comments for Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`, ); // Validate pull_request_id is a positive integer const prId = Number(params.pull_request_id); if (isNaN(prId) || prId <= 0 || !Number.isInteger(prId)) { throw new Error( `Invalid pull request ID: ${params.pull_request_id}. Pull request ID must be a positive integer.`, ); } if (!params.workspace || !params.repo_slug || !params.pull_request_id) { throw new Error( 'workspace, repo_slug, and pull_request_id parameters are all required', ); } const credentials = getAtlassianCredentials(); if (!credentials) { throw createAuthMissingError( 'Atlassian credentials are required for this operation', ); } // Build query parameters const queryParams = new URLSearchParams(); // Add pagination parameters if provided if (params.pagelen) { queryParams.set('pagelen', params.pagelen.toString()); } if (params.page) { queryParams.set('page', params.page.toString()); } // Add sort parameter if provided if (params.sort) { queryParams.set('sort', params.sort); } const queryString = queryParams.toString() ? `?${queryParams.toString()}` : ''; const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/comments${queryString}`; methodLogger.debug(`Sending request to: ${path}`); return fetchAtlassian<PullRequestCommentsResponse>(credentials, path); } /** * Add a comment to a specific Bitbucket pull request * * Creates a new comment on a pull request, either as a general comment or * as an inline code comment attached to a specific file and line. * * @async * @memberof VendorAtlassianPullRequestsService * @param {CreatePullRequestCommentParams} params - Parameters for the request * @param {string} params.workspace - The workspace slug or UUID * @param {string} params.repo_slug - The repository slug or UUID * @param {number} params.pull_request_id - The ID of the pull request * @param {Object} params.content - The content of the comment * @param {string} params.content.raw - The raw text of the comment * @param {Object} [params.inline] - Optional inline comment location * @param {string} params.inline.path - The file path for the inline comment * @param {number} params.inline.to - The line number in the file * @returns {Promise<PullRequestComment>} Promise containing the created comment * @throws {Error} If Atlassian credentials are missing or API request fails * @example * // Add a general comment to a pull request * const comment = await addComment({ * workspace: 'my-workspace', * repo_slug: 'my-repo', * pull_request_id: 123, * content: { raw: "This looks good to me!" } * }); * * // Add an inline code comment * const comment = await addComment({ * workspace: 'my-workspace', * repo_slug: 'my-repo', * pull_request_id: 123, * content: { raw: "Consider using a constant here instead." }, * inline: { path: "src/main.js", to: 42 } * }); */ async function createComment( params: CreatePullRequestCommentParams, ): Promise<PullRequestComment> { const methodLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', 'createComment', ); methodLogger.debug( `Creating comment on Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`, ); if (!params.workspace || !params.repo_slug || !params.pull_request_id) { throw new Error( 'workspace, repo_slug, and pull_request_id parameters are all required', ); } if (!params.content || !params.content.raw) { throw new Error('Comment content is required'); } const credentials = getAtlassianCredentials(); if (!credentials) { throw createAuthMissingError( 'Atlassian credentials are required for this operation', ); } const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/comments`; methodLogger.debug(`Sending POST request to: ${path}`); return fetchAtlassian<PullRequestComment>(credentials, path, { method: 'POST', body: { content: params.content, inline: params.inline, parent: params.parent, }, }); } /** * Create a new pull request * @param {CreatePullRequestParams} params - Parameters for the request * @param {string} params.workspace - The workspace slug or UUID * @param {string} params.repo_slug - The repository slug or UUID * @param {string} params.title - Title of the pull request * @param {string} params.source.branch.name - Source branch name * @param {string} params.destination.branch.name - Destination branch name (defaults to main/master) * @param {string} [params.description] - Optional description for the pull request * @param {boolean} [params.close_source_branch] - Whether to close the source branch after merge (default: false) * @returns {Promise<PullRequestDetailed>} Detailed information about the created pull request * @example * ```typescript * // Create a new pull request * const pullRequest = await create({ * workspace: 'myworkspace', * repo_slug: 'myrepo', * title: 'Add new feature', * source: { * branch: { * name: 'feature/new-feature' * } * }, * destination: { * branch: { * name: 'main' * } * }, * description: 'This PR adds a new feature...', * close_source_branch: true * }); * ``` */ async function create( params: CreatePullRequestParams, ): Promise<PullRequestDetailed> { const methodLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', 'create', ); methodLogger.debug( 'Creating new Bitbucket pull request with params:', params, ); if (!params.workspace || !params.repo_slug) { throw new Error('Both workspace and repo_slug parameters are required'); } if (!params.title) { throw new Error('Pull request title is required'); } if (!params.source || !params.source.branch || !params.source.branch.name) { throw new Error('Source branch name is required'); } // Destination branch is required but may have a default if ( !params.destination || !params.destination.branch || !params.destination.branch.name ) { throw new Error('Destination branch name is required'); } const credentials = getAtlassianCredentials(); if (!credentials) { throw createAuthMissingError( 'Atlassian credentials are required for this operation', ); } const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests`; // Construct request body with only the fields needed by the API const requestBody = { title: params.title, source: { branch: { name: params.source.branch.name, }, }, destination: { branch: { name: params.destination.branch.name, }, }, description: params.description || '', close_source_branch: !!params.close_source_branch, }; methodLogger.debug(`Sending POST request to: ${path}`); return fetchAtlassian<PullRequestDetailed>(credentials, path, { method: 'POST', body: requestBody, }); } /** * Get raw diff content for a specific Bitbucket pull request * * Retrieves the raw diff content showing actual code changes in the pull request. * The diff is returned in a standard unified diff format. * * @async * @memberof VendorAtlassianPullRequestsService * @param {GetPullRequestParams} params - Parameters for the request * @param {string} params.workspace - The workspace slug or UUID * @param {string} params.repo_slug - The repository slug or UUID * @param {number} params.pull_request_id - The ID of the pull request * @returns {Promise<string>} Promise containing the raw diff content * @throws {Error} If Atlassian credentials are missing or API request fails * @example * // Get raw diff content for a pull request * const diffContent = await getRawDiff({ * workspace: 'my-workspace', * repo_slug: 'my-repo', * pull_request_id: 123 * }); */ async function getRawDiff(params: GetPullRequestParams): Promise<string> { const methodLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', 'getRawDiff', ); methodLogger.debug( `Getting raw diff for Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`, ); if (!params.workspace || !params.repo_slug || !params.pull_request_id) { throw new Error( 'workspace, repo_slug, and pull_request_id parameters are all required', ); } const credentials = getAtlassianCredentials(); if (!credentials) { throw createAuthMissingError( 'Atlassian credentials are required for this operation', ); } // Use the diff endpoint directly const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/diff`; methodLogger.debug(`Sending request to: ${path}`); // Override the Accept header to get raw diff content instead of JSON // The transport utility handles the text response automatically return fetchAtlassian<string>(credentials, path, { headers: { Accept: 'text/plain', }, }); } /** * Get the diffstat information for a pull request * * Returns summary statistics about the changes in a pull request, * including files changed, insertions, and deletions. * * @async * @memberof VendorAtlassianPullRequestsService * @param {GetPullRequestParams} params - Parameters for the request * @returns {Promise<DiffstatResponse>} Promise containing the diffstat response */ async function getDiffstat( params: GetPullRequestParams, ): Promise<DiffstatResponse> { const methodLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', 'getDiffstat', ); methodLogger.debug( `Getting diffstat for Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`, ); if (!params.workspace || !params.repo_slug || !params.pull_request_id) { throw new Error( 'workspace, repo_slug, and pull_request_id parameters are all required', ); } const credentials = getAtlassianCredentials(); if (!credentials) { throw createAuthMissingError( 'Atlassian credentials are required for this operation', ); } const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/diffstat`; methodLogger.debug(`Sending request to: ${path}`); return fetchAtlassian<DiffstatResponse>(credentials, path); } /** * Fetches the raw diff content from a specific Bitbucket API URL. * Used primarily for fetching file-specific diffs linked from inline comments. * * @async * @param {string} url - The exact Bitbucket API URL to fetch the diff from. * @returns {Promise<string>} Promise containing the raw diff content as a string. * @throws {Error} If Atlassian credentials are missing or the API request fails. */ async function getDiffForUrl(url: string): Promise<string> { const methodLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', 'getDiffForUrl', ); methodLogger.debug(`Getting raw diff from URL: ${url}`); if (!url) { throw new Error('URL parameter is required'); } const credentials = getAtlassianCredentials(); if (!credentials) { throw createAuthMissingError( 'Atlassian credentials are required for this operation', ); } // Parse the provided URL to extract the path and query string let urlPath = ''; try { const parsedUrl = new URL(url); urlPath = parsedUrl.pathname + parsedUrl.search; methodLogger.debug(`Parsed path and query from URL: ${urlPath}`); } catch (parseError) { methodLogger.error(`Failed to parse URL: ${url}`, parseError); throw new Error(`Invalid URL provided for diff fetching: ${url}`); } // Pass only the path part to fetchAtlassian // Ensure the Accept header requests plain text for the raw diff. return fetchAtlassian<string>(credentials, urlPath, { headers: { Accept: 'text/plain', }, }); } /** * Update an existing pull request * @param {UpdatePullRequestParams} params - Parameters for the request * @param {string} params.workspace - The workspace slug or UUID * @param {string} params.repo_slug - The repository slug or UUID * @param {number} params.pull_request_id - The ID of the pull request to update * @param {string} [params.title] - Updated title of the pull request * @param {string} [params.description] - Updated description for the pull request * @returns {Promise<PullRequestDetailed>} Updated pull request information * @example * ```typescript * // Update a pull request's title and description * const updatedPR = await update({ * workspace: 'myworkspace', * repo_slug: 'myrepo', * pull_request_id: 123, * title: 'Updated Feature Implementation', * description: 'This PR now includes additional improvements...' * }); * ``` */ async function update( params: UpdatePullRequestParams, ): Promise<PullRequestDetailed> { const methodLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', 'update', ); methodLogger.debug('Updating Bitbucket pull request with params:', params); if (!params.workspace || !params.repo_slug || !params.pull_request_id) { throw new Error( 'workspace, repo_slug, and pull_request_id parameters are all required', ); } // At least one field to update must be provided if (!params.title && !params.description) { throw new Error( 'At least one field to update (title or description) must be provided', ); } const credentials = getAtlassianCredentials(); if (!credentials) { throw createAuthMissingError( 'Atlassian credentials are required for this operation', ); } const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}`; // Construct request body with only the fields to update const requestBody: Record<string, unknown> = {}; if (params.title !== undefined) { requestBody.title = params.title; } if (params.description !== undefined) { requestBody.description = params.description; } methodLogger.debug(`Sending PUT request to: ${path}`); return fetchAtlassian<PullRequestDetailed>(credentials, path, { method: 'PUT', body: requestBody, }); } /** * Approve a pull request * @param {ApprovePullRequestParams} params - Parameters for the request * @param {string} params.workspace - The workspace slug or UUID * @param {string} params.repo_slug - The repository slug or UUID * @param {number} params.pull_request_id - The ID of the pull request to approve * @returns {Promise<PullRequestParticipant>} Participant information showing approval status * @example * ```typescript * // Approve a pull request * const approval = await approve({ * workspace: 'myworkspace', * repo_slug: 'myrepo', * pull_request_id: 123 * }); * ``` */ async function approve( params: ApprovePullRequestParams, ): Promise<PullRequestParticipant> { const methodLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', 'approve', ); methodLogger.debug( `Approving Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`, ); if (!params.workspace || !params.repo_slug || !params.pull_request_id) { throw new Error( 'workspace, repo_slug, and pull_request_id parameters are all required', ); } const credentials = getAtlassianCredentials(); if (!credentials) { throw createAuthMissingError( 'Atlassian credentials are required for this operation', ); } const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/approve`; methodLogger.debug(`Sending POST request to: ${path}`); return fetchAtlassian<PullRequestParticipant>(credentials, path, { method: 'POST', }); } /** * Request changes on a pull request (reject) * @param {RejectPullRequestParams} params - Parameters for the request * @param {string} params.workspace - The workspace slug or UUID * @param {string} params.repo_slug - The repository slug or UUID * @param {number} params.pull_request_id - The ID of the pull request to request changes on * @returns {Promise<PullRequestParticipant>} Participant information showing rejection status * @example * ```typescript * // Request changes on a pull request * const rejection = await reject({ * workspace: 'myworkspace', * repo_slug: 'myrepo', * pull_request_id: 123 * }); * ``` */ async function reject( params: RejectPullRequestParams, ): Promise<PullRequestParticipant> { const methodLogger = Logger.forContext( 'services/vendor.atlassian.pullrequests.service.ts', 'reject', ); methodLogger.debug( `Requesting changes on Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`, ); if (!params.workspace || !params.repo_slug || !params.pull_request_id) { throw new Error( 'workspace, repo_slug, and pull_request_id parameters are all required', ); } const credentials = getAtlassianCredentials(); if (!credentials) { throw createAuthMissingError( 'Atlassian credentials are required for this operation', ); } const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/request-changes`; methodLogger.debug(`Sending POST request to: ${path}`); return fetchAtlassian<PullRequestParticipant>(credentials, path, { method: 'POST', }); } export default { list, get, getComments, createComment, create, update, approve, reject, getRawDiff, getDiffstat, getDiffForUrl, }; ``` -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- ```markdown # [1.45.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.44.2...v1.45.0) (2025-10-05) ### Features * api call timeout CWE-400 ([#118](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/118)) ([d8659ee](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d8659ee8f7d6baca1a5a391a4ee08368af63af84)) ## [1.44.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.44.1...v1.44.2) (2025-09-09) ### Bug Fixes * use single baseUrl for API token authentication ([#117](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/117)) ([a0d5ad1](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a0d5ad1aa6333ab824f882de20af2e1f69540a55)), closes [#61](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/61) ## [1.44.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.44.0...v1.44.1) (2025-09-09) ### Bug Fixes * Prevent dotenv from outputting to STDIO in MCP mode ([#106](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/106)) ([52a8e13](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/52a8e132e35bc215445a15d846d5c79bf49a06fc)) # [1.44.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.43.4...v1.44.0) (2025-09-09) ### Features * modernize dependencies and ensure Zod v3.25.76 MCP SDK compatibility ([#115](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/115)) ([86ceaeb](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/86ceaebed56326d32be0736a77e3b4d528af8003)) ## [1.43.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.43.3...v1.43.4) (2025-08-07) ### Bug Fixes * update .env.example with complete authentication options ([52da9a1](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/52da9a1b37f71cfe6af16fe2322b8d040285718b)) ## [1.43.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.43.2...v1.43.3) (2025-08-07) ### Bug Fixes * correct authentication credentials and config structure ([b53b5d5](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/b53b5d569c97efb9b91ee34063b669210a2e3be5)) ## [1.43.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.43.1...v1.43.2) (2025-08-02) ### Bug Fixes * prevent double formatting in Bitbucket markdown (heading + bold) ([67ec325](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/67ec3253f1c3576cf8427ff6426ae3178e12f96a)) ## [1.43.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.43.0...v1.43.1) (2025-08-02) ### Bug Fixes * resolve bb_get_file tool failure with dynamic default branch detection ([74ca7e0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/74ca7e0f3f042f2f24cdf156d4a94c2e3e026cf5)) # [1.43.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.42.1...v1.43.0) (2025-08-02) ### Bug Fixes * correct logger variable name in repository list controller ([1706725](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1706725a374826068c1d75c80e215543fb3ac4a6)) ### Features * add query logging for repository searches ([c8d776d](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c8d776dcabf8dab4cc63724df508b3837e993cc0)) ## [1.42.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.42.0...v1.42.1) (2025-08-02) ### Bug Fixes * standardize dependencies and fix TypeScript linting issues ([4e5ab79](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4e5ab79431f07da5bd06db0fa5835191ccb2ef08)) # [1.42.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.41.1...v1.42.0) (2025-07-15) ### Features * add support for threaded comments in pull request comments ([#50](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/50)) ([6bcb98a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6bcb98ad95c7073604c6f5173e78c7339821e689)), closes [#49](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/49) ## [1.41.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.41.0...v1.41.1) (2025-06-22) ### Bug Fixes * change default transport from HTTP to STDIO for proper MCP client integration ([51d9a1c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/51d9a1c91490b47ea3498a11fdd4a3fd35940792)) # [1.41.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.40.1...v1.41.0) (2025-06-22) ### Features * implement complete PR CRUD operations (update, approve, reject) ([de5a2a0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/de5a2a045cab06f0ce2a2bbfdd9028bae81d2b73)), closes [#38](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/38) [#39](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/39) [#38](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/38) [#39](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/39) ## [1.40.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.40.0...v1.40.1) (2025-06-22) ### Bug Fixes * update dependencies ([dac5279](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/dac5279c7e5eb2c80adc33ae594c25af942c551b)) # [1.40.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.7...v1.40.0) (2025-06-22) ### Features * add dual transport support (HTTP + STDIO) for MCP server ([313de85](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/313de85ff2be8e37db498a197aa7d873ddb6912e)) ## [1.39.7](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.6...v1.39.7) (2025-06-02) ### Bug Fixes * replace Unix-specific chmod with cross-platform ensure-executable script ([0140fb5](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/0140fb59a3bdc15c009a65e9384c49f9e9c7710b)), closes [#31](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/31) ## [1.39.6](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.5...v1.39.6) (2025-06-02) ### Bug Fixes * update dependencies ([4f94fbc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4f94fbc7a150131aa852728d764ec1458eae2db1)) ## [1.39.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.4...v1.39.5) (2025-05-21) ### Bug Fixes * Move business logic to controllers and fix method naming to follow architectural standards ([51b1a4c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/51b1a4c666469c983393216e68ecc8d60bee17c6)) * update dependencies ([5a3c409](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5a3c409b406b9a935c47574e446c5531ea157c82)) ## [1.39.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.3...v1.39.4) (2025-05-21) ### Bug Fixes * update dependencies ([b7b7dc3](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/b7b7dc39c9dcf3799ecafada2bed44462a91076e)) ## [1.39.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.2...v1.39.3) (2025-05-21) ### Bug Fixes * align search tool implementation with CLI for consistent behavior ([5b81f58](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5b81f580bb7b04366b645a5db1a7d72043a9c809)) * ensure consistent workspace handling across all Bitbucket tool implementations ([1e78be5](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1e78be5fdde5ddb13f395cdc655ae4f0ee639555)) * ensure consistent workspace handling and parameter validation across all Bitbucket tools ([70d5cba](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/70d5cba00c5f4ad71be28b1fa83ff03f30bbc50d)) * rename search tool from 'atlassian_search' to 'bb_search' for consistent naming convention ([a3c467c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a3c467c696bfe55f3f6ae519352324ced7274960)) ## [1.39.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.1...v1.39.2) (2025-05-20) ### Bug Fixes * fix linter errors and unused exports in repository clone feature ([c916f53](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c916f539aa45c6ac903459258dc4f8cc30fba508)) * improve repository clone feature with SSH support and better path handling ([f5955f3](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f5955f3888ded00136dfc6b76e909e2d2261fbf8)) ## [1.39.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.0...v1.39.1) (2025-05-20) ### Bug Fixes * update dependencies ([ae112a6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ae112a60fdd38f1f35e98fd61992a205efc0517c)) # [1.39.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.38.4...v1.39.0) (2025-05-19) ### Features * removed backward compatibility flag from diff cli and deprecated sort parameter from workspaces types ([108ef54](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/108ef549c85e7f894191a1e95ccc39319dd3c32f)) ## [1.38.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.38.3...v1.38.4) (2025-05-19) ### Bug Fixes * remove unused code for better maintainability ([711f86d](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/711f86d81a8f7e26b856560ffba576cedc671a25)) ## [1.38.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.38.2...v1.38.3) (2025-05-19) ### Bug Fixes * refactor repositories controller into separate controllers for better maintainability ([3461d8a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3461d8a32c18ba05be483ae7f24758f51e2b8f55)) * refactor search controller into separate controllers by search type ([38a7d35](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/38a7d35bf4dae83846dbaf316555cfb81cc394ab)) ## [1.38.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.38.1...v1.38.2) (2025-05-19) ### Bug Fixes * remove unused code and exports to improve maintainability ([e419c07](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e419c07f43128d334094fba50ff90b2a76bc0229)) ## [1.38.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.38.0...v1.38.1) (2025-05-19) ### Bug Fixes * correct code block formatting with tabs for nested code blocks ([2c19c16](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2c19c161247723fb04611701420d30f93d1e2cac)) # [1.38.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.37.0...v1.38.0) (2025-05-19) ### Features * update dependencies ([76fd24f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/76fd24f53d69ccf987bcd3971af51204736f6d16)) # [1.37.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.5...v1.37.0) (2025-05-18) ### Features * Refine ControllerResponse implementation ([dbe160f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/dbe160f085ec89c6856b822f16be22271c0fce7f)) ## [1.36.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.4...v1.36.5) (2025-05-17) ### Bug Fixes * remove empty metadata objects from Bitbucket tool responses ([ab65f71](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ab65f71c4eb62ea6a21323bf821650a1e9252c7a)) ## [1.36.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.3...v1.36.4) (2025-05-17) ### Bug Fixes * improve documentation and error guidance for counterintuitive branch and commit diff parameter ordering ([ec374e6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ec374e6443f383d8552ace999b852d4ecc8458e0)) ## [1.36.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.2...v1.36.3) (2025-05-17) ### Bug Fixes * improve diff_commits tool to better handle cases with empty diffstat but existing changes ([736304b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/736304b74b6a0f39644af55a972dde4ec9d9e041)) ## [1.36.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.1...v1.36.2) (2025-05-17) ### Bug Fixes * improve error handling for invalid PR IDs in Bitbucket pull request tool ([14afe1a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/14afe1a499f117ad8fd50b75b326e4d8082618fa)) ## [1.36.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.0...v1.36.1) (2025-05-17) ### Bug Fixes * ensure projectKey is passed from tool to controller for bb_ls_repos ([a0c26db](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a0c26db744edd1f383014c61aa9c25643035b8a3)) # [1.36.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.35.1...v1.36.0) (2025-05-17) ### Bug Fixes * Improve tests, refactor, and document includeComments feature ([5d9fbfd](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5d9fbfd7598218af02abdf439d5b304e325753bd)) * Improve transport utility tests to use real environments ([20b8cf2](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/20b8cf23ef09d42f8556a0f8840ad02f082cc215)) ### Features * Add includeComments option to get-pr command ([ba72020](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ba72020ea49bc0e58b0f559ead7df4d54563a8fa)) * Enhance get-pr to include comments with flag ([a0dbb89](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a0dbb89517e1bd7011b80fb8fcf90352214f784e)) * Enhance get-repo to include recent PRs by default ([0052629](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/005262911c975f5dd91c1a871659b86c16a454da)) * Standardize CLI parameter formats across commands ([c267a14](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c267a147c2d59db5ca7487c87d91fd8a123f39d8)) ## [1.35.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.35.0...v1.35.1) (2025-05-17) ### Bug Fixes * Update Bitbucket README for default workspace and diffs ([fe36a20](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/fe36a20c834ecf584673c921b293cac050571046)) # [1.35.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.34.0...v1.35.0) (2025-05-17) ### Features * make workspaceSlug optional in remaining tools and controllers ([6d2f4d6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6d2f4d6860e76cbcd7ff8cde0fd1e70b8377c464)) # [1.34.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.33.0...v1.34.0) (2025-05-17) ### Features * make workspaceSlug parameter optional with default workspace support ([16e41f5](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/16e41f5c0a37b41078aeb940612f79399c8c4296)) # [1.33.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.5...v1.33.0) (2025-05-17) ### Features * implement core principles of minimal input and rich output by default ([0dc2c0d](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/0dc2c0d2dad7a53f6a6202a67fed0372b80d9968)) ## [1.32.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.4...v1.32.5) (2025-05-16) ### Bug Fixes * implement getFileContent in atlassian.repositories.controller.ts ([5ebc2fb](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5ebc2fbb54e1516de2ee9848dbfcddb643cd2512)) ## [1.32.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.3...v1.32.4) (2025-05-16) ### Bug Fixes * improve documentation and error handling for searching and diffing operations ([2670423](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/267042342b3102d82737aeee588db684e4cf00c5)) ## [1.32.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.2...v1.32.3) (2025-05-16) ### Bug Fixes * Make repoSlug conditionally required for pullrequests and commits scopes in search tool ([a1adc3a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a1adc3af40fec80f4c85dccf3b60c02770d0f306)) ## [1.32.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.1...v1.32.2) (2025-05-16) ### Bug Fixes * improve filtering in Bitbucket commands for projectKey, language, and scope parameters ([3cb34da](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3cb34dae514ee2f76449c3f099a86dd3bd0e47af)) ## [1.32.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.0...v1.32.1) (2025-05-16) ### Bug Fixes * resolve type errors in repository controller stub functions ([4ec45e7](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4ec45e7e05deadc67b9c5e9f17da276f9302aba6)) # [1.32.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.31.0...v1.32.0) (2025-05-15) ### Features * improve search, pagination, and filtering features ([167af40](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/167af40154b69868fdab26a7582d140ee658b0cb)) # [1.31.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.30.3...v1.31.0) (2025-05-15) ### Bug Fixes * resolve duplicate exports in error-handler utilities ([fec7ecb](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/fec7ecb08512467e02a4cc52ef3856adff0c88e6)) ### Features * enhance Bitbucket-specific error handling ([165e566](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/165e566c25c0056bdb498fadf6d543372e41a1d8)) * enhanced error handling for Bitbucket API responses ([a9cf6c0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a9cf6c0184e0d50cbf179a77c3e83342b0376de0)) * enhanced error handling for Bitbucket API responses ([08cbf83](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/08cbf83d81b633201cc2873e4461302377ab9be1)) * enhanced error handling for Bitbucket API responses ([91e3354](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/91e3354746e106d3ed3d4ccca16631db00ef2ab4)) ## [1.30.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.30.2...v1.30.3) (2025-05-15) ### Bug Fixes * set default topic=false for diff operations and remove topic parameter from CLI/tools ([2300228](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/23002286221b70fede8c5d7986d8236c752b7766)) ## [1.30.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.30.1...v1.30.2) (2025-05-15) ### Bug Fixes * apply proper formatting to query handling in listBranches ([169f75b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/169f75b32bf05feb3551c569d12fdfa7e27f553f)) ## [1.30.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.30.0...v1.30.1) (2025-05-14) ### Bug Fixes * remove Dockerfile and smithery.yaml ([42ffad6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/42ffad6cbb0baf7d0644a580957d7c86d39da561)) # [1.30.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.29.1...v1.30.0) (2025-05-14) ### Features * enhance error handling with vendor propagation and enriched CLI/Tool formatting ([db16d11](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/db16d1113d6148e5d207cdbc804e6fec4012d5ea)) ## [1.29.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.29.0...v1.29.1) (2025-05-13) ### Bug Fixes * route enhanced clone error via createApiError to keep details ([4c03cdb](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4c03cdbe6e16bd85a78d106b957a33f51057bc80)) # [1.29.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.28.1...v1.29.0) (2025-05-13) ### Features * enhance clone error handling with user guidance ([3921c1f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3921c1f8c1990aa6b70675622f9b747ea551ff96)) ## [1.28.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.28.0...v1.28.1) (2025-05-13) ### Bug Fixes * prefer ssh clone to use default ssh keys ([ef5a13f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ef5a13f150bc3a2a4a03c0aea2c2a6a5dc910819)) # [1.28.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.27.1...v1.28.0) (2025-05-13) ### Bug Fixes * use HTTPS clone with embedded credentials to avoid SSH access denied in server mode ([3fa0bad](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3fa0bad1d8faeafe0659b76340a0b15682a74083)) ### Features * add list branches feature for Bitbucket repositories (CLI, MCP tool, controller, service, formatter) ([e68e8da](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e68e8da865d0f128b4930ee2c7b40cf799d3fd28)) ## [1.27.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.27.0...v1.27.1) (2025-05-13) ### Bug Fixes * update dependencies ([2c74c7a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2c74c7aae0e422380d19efb5fdccef823f3590af)) # [1.27.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.7...v1.27.0) (2025-05-13) ### Features * add diff tools for branch and commit comparison ([e201f9e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e201f9e6cbe940fc8354eff2224dfe78bc7fa637)) ## [1.26.7](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.6...v1.26.7) (2025-05-09) ### Bug Fixes * increase test timeouts for API-dependent tests to improve reliability ([08a4d75](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/08a4d754c819207b96ff91f813599561c313c3e6)) ## [1.26.6](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.5...v1.26.6) (2025-05-08) ### Bug Fixes * Remove unused ADF conversion functions from Bitbucket implementation ([1abe807](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1abe807ec17ad21a06dde3e88ee90d9597f14519)) ## [1.26.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.4...v1.26.5) (2025-05-08) ### Bug Fixes * Fix bullet list rendering in Bitbucket markdown handling ([c3a4b71](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c3a4b71d2d6e7c2e077ef3941c6b5bea0f5efb15)) * improve markdown rendering in Bitbucket PR descriptions and comments ([4e73784](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4e7378425fd71e629b3fc3c6cc67a6d4f69672ce)) ## [1.26.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.3...v1.26.4) (2025-05-07) ### Performance Improvements * Update dependencies ([37f8849](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/37f884938d94bae4d832c780393f04f061831b56)) ## [1.26.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.2...v1.26.3) (2025-05-07) ### Bug Fixes * Improve directory validation and error handling for repository cloning ([d6c5c7f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d6c5c7f7f7f25be9149084b0ad7e96b0d6ca7ce2)) ### Performance Improvements * Update dependencies ([858dc27](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/858dc274af5a5bda7af4baa5c5c2628ad7aa3b1c)) ## [1.26.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.1...v1.26.2) (2025-05-07) ### Bug Fixes * Simplify bb_clone_repo documentation for clarity ([97871ba](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/97871ba8b36d6aef6bb90cf5fbd646ce3e394425)) ## [1.26.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.0...v1.26.1) (2025-05-07) ### Bug Fixes * Add documentation for get-file functionality in README ([542933e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/542933e9eb14e2bf97e39ad11ad3b70bbd3eb99a)) # [1.26.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.25.1...v1.26.0) (2025-05-07) ### Features * Add file content retrieval via CLI and Tool ([a8a306e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a8a306e154ff2aea30a5161faa7575c499bd82c0)) ## [1.25.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.25.0...v1.25.1) (2025-05-06) ### Bug Fixes * Clarify clone tool targetPath and update README ([92e4e53](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/92e4e53322a8e92324b8e7776503e767bcbcf4d1)) # [1.25.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.24.0...v1.25.0) (2025-05-06) ### Features * Add repository clone functionality via CLI and Tool ([648392f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/648392f1fdd2e0faa3ce94882a550dca363e861c)) # [1.24.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.10...v1.24.0) (2025-05-06) ### Features * sync ADF utility enhancements from Jira project ([9f0c4be](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/9f0c4bed91262790e71c38201722f6bf76b9ff91)) ## [1.23.10](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.9...v1.23.10) (2025-05-06) ### Performance Improvements * Update dependencies ([e22ef5b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e22ef5b4af772f4c627c24021ba92d706483a8d3)) ## [1.23.9](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.8...v1.23.9) (2025-05-06) ### Bug Fixes * Standardize terminology from create to add across operations ([37b7735](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/37b7735727483756a3d530ad6a651a8f623feaa7)) * Update controller method names to match add pattern and fix test cases ([a10317c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a10317c2b1713a7aea91cfb2d73c100f7c7055e6)) * Update controller method references in tools file ([2682de8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2682de83a2caa4aa18f94b884d8d473454d9844d)) ## [1.23.8](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.7...v1.23.8) (2025-05-06) ### Performance Improvements * Update dependencies ([41ffc7b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/41ffc7b92f2cf135d2f67a80a5cf65de565633fa)) ## [1.23.7](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.6...v1.23.7) (2025-05-06) ### Bug Fixes * Revert back the index.ts and package.json ([57eeb01](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/57eeb01321e7995bae7a4ffa3363feda1f8008ae)) ## [1.23.6](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.5...v1.23.6) (2025-05-06) ### Bug Fixes * improve main module detection for npx compatibility ([efe5d4c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/efe5d4c0ed7c15c9729a4ad7d3c91afcb8925c31)) ## [1.23.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.4...v1.23.5) (2025-05-06) ### Bug Fixes * improve main module detection for npx compatibility ([90f0f26](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/90f0f2685bc8fe95e162e2e1fdae7ac7afbb5d76)) ## [1.23.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.3...v1.23.4) (2025-05-05) ### Bug Fixes * revert to working server version that stays running ([a80eef9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a80eef963c9a4de38110112261a772e1fb33385b)) ## [1.23.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.2...v1.23.3) (2025-05-05) ### Bug Fixes * improve signal handling for npx support ([a4a361c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a4a361ca3fd2983446880eacabb5fa979f1336d1)) ## [1.23.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.1...v1.23.2) (2025-05-05) ### Bug Fixes * Remove explicit exit after CLI execution in index.ts ([9b0bed0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/9b0bed07040cb54516fff6e9f0c8cc667ccd5786)) ## [1.23.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.0...v1.23.1) (2025-05-05) ### Bug Fixes * Apply cross-platform compatibility improvements from boilerplate ([3426b97](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3426b97d62cfef5076436600be3126c7a0cf4382)) # [1.23.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.22.0...v1.23.0) (2025-05-05) ### Features * Add --project-key filter to ls-repos command ([f07c044](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f07c0441a4757da5cdd659602ef3e72d6fc38776)) * Add create-branch command ([4cc5bdb](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4cc5bdb921e9d1e12c7b7689e3719d4f1c429821)) * Display comment and task counts in get-pr output ([a1513ef](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a1513efefd0992510a0e8e08e75db487ce87bf60)) * Display main branch name in get-repo output ([12cc91e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/12cc91ea89a241002ddfef4523633ddb90f79c2e)) * Improve search command usability ([c5d1550](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c5d155053a4ea6889f86e6861925b25c7b979727)) # [1.22.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.7...v1.22.0) (2025-05-05) ### Features * Display code snippets for inline PR comments ([5a8024b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5a8024b3cd259fa6ff9804a717149d3933244cc2)) ## [1.21.7](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.6...v1.21.7) (2025-05-05) ### Bug Fixes * Indicate deleted PR comments in output ([f6069c7](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f6069c79c38b8eb1e69b4c6531d5c3eb78c1bdfb)) ## [1.21.6](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.5...v1.21.6) (2025-05-05) ### Bug Fixes * Include PR ID in ls-pr-comments title ([f73c9da](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f73c9dacc50ee2a9450b4ca1bb73a79f29ca3f5c)) ### Performance Improvements * Update dependencies ([7166012](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7166012b406d435eea7dec7a0d80d7ed5a17727b)) ## [1.21.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.4...v1.21.5) (2025-05-05) ### Bug Fixes * Remove commented-out code and unused exports ([d81ad82](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d81ad8239c4f0975aa995dad775038a9fb1ae87d)) ## [1.21.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.3...v1.21.4) (2025-05-05) ### Bug Fixes * apply role filter in list repositories API call ([6ca7e4b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6ca7e4b29015aa689fd86d681ff28b0eabf52a09)) ## [1.21.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.2...v1.21.3) (2025-05-04) ### Performance Improvements * Update dependencies ([32bd5ae](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/32bd5aedf2368d4a1a42ee8709621042586416f8)) ## [1.21.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.1...v1.21.2) (2025-05-04) ### Bug Fixes * **search:** Correct query formatting for ls-prs and search scopes ([31d6def](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/31d6def83c27bc1da3d98cbbf94ff16f41161d69)) ## [1.21.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.0...v1.21.1) (2025-05-04) ### Bug Fixes * refine tool definitions and parameter naming ([1efb27e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1efb27e51c5b13ed4e548098a8600674f2034fd7)) # [1.21.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.20.4...v1.21.0) (2025-05-04) ### Features * **format:** standardize CLI and Tool output formatting ([2ad3f05](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2ad3f05e08848271975695bfab7c9bd97a0d2ff0)) ## [1.20.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.20.3...v1.20.4) (2025-05-04) ### Bug Fixes * update pagination handling in search formatter ([ec8f6ce](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ec8f6ce21660c4e338bc16278fee393c131bc7eb)) ## [1.20.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.20.2...v1.20.3) (2025-05-04) ### Bug Fixes * **bitbucket:** implement Zod validation and align types ([7611404](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/761140440996878f0170c2e453def84d73f9af94)) ## [1.20.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.20.1...v1.20.2) (2025-05-04) ### Bug Fixes * Clean up unused exports and types in Bitbucket server ([3d469fc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3d469fcc2752f8a7eb817d60b04e164901665e3b)) * Remove re-exports from index.ts ([5ab1bf6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5ab1bf60d5f8c7e9b572edb093d7e071972fd222)) ## [1.20.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.20.0...v1.20.1) (2025-05-02) ### Bug Fixes * trigger release ([ae058d8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ae058d8eeb50f811c3c9afe7d0bfa38b16b696b1)) # [1.20.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.19.3...v1.20.0) (2025-05-02) ### Features * Standardize pagination output in tool content text ([f072ae7](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f072ae74a3ca9bfaecf6eb32ddc01cd35d25718a)) ## [1.19.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.19.2...v1.19.3) (2025-05-02) ### Bug Fixes * **bitbucket:** correct repository list formatting and remove redundant title in search ([ac6ce2a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ac6ce2a641751669ab1e345917059febb2b6bbf5)) ## [1.19.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.19.1...v1.19.2) (2025-05-02) ### Bug Fixes * **bitbucket:** correct repository list formatting and remove redundant title in search ([e32071f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e32071f223e83305de6c1056a97f26e9b352ca3a)) ## [1.19.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.19.0...v1.19.1) (2025-05-02) ### Bug Fixes * **bitbucket:** improve formatting for bb_search code results ([5469e37](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5469e3734aa02a532668c36468287ecc8a3760b8)) # [1.19.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.18.0...v1.19.0) (2025-05-02) ### Features * **bitbucket:** add --full-diff option to bb_get_pr tool ([3039fae](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3039faec68ca605898872e87bedec05cc5b1e920)) ### Performance Improvements * Update dependencies ([77dcad9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/77dcad9050c7cd4001af2029bc58d781c1b4d3fe)) # [1.18.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.17.3...v1.18.0) (2025-05-01) ### Bug Fixes * correct option flag format for get-commit-history command ([c97ad6f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c97ad6f25675d19eea953db08c49daad3a84ada6)) * remove unused configuration objects to reduce dead code ([f51dc65](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f51dc6502282c38fd54a8ec6f885f34165c1aa97)) * remove unused formatRelativeTime function for cleaner codebase ([6663157](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/666315765dce68e2ff4cb41c5a9e61580e8504ba)) ### Features * add commit history tool and cli command ([811c155](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/811c1559c1b7a7fbb32fa45a37cbebebc3b225f6)) ### Performance Improvements * streamline Bitbucket tool descriptions for better AI consumption ([1136c3f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1136c3f5f91dda81c34fde0c63e261c670b938cc)) ## [1.17.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.17.2...v1.17.3) (2025-05-01) ### Bug Fixes * standardize on 'create' verb for PR comments ([d3443ea](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d3443eac077fb2a93c77fc41df478a37c04d8709)) * Standardize on 'create' verb for PR comments ([cdcfb66](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/cdcfb663db8fb86d4c1f463114f697b77ffb7519)) ## [1.17.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.17.1...v1.17.2) (2025-04-30) ### Bug Fixes * **cli:** Align command names and descriptions with tool definitions ([d474994](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d474994c1f4b0358a53ac9557be4bd7a306247a8)) ## [1.17.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.17.0...v1.17.1) (2025-04-30) ### Performance Improvements * Update dependencies ([062b651](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/062b651830b0850cf627323fdf9b9606fc4673c2)) # [1.17.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.16.0...v1.17.0) (2025-04-30) ### Bug Fixes * Standardize and shorten MCP tool names ([3c66a60](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3c66a6000be1033c657a52de37ca4c369664b23a)) ### Features * Support multiple keys for global config lookup ([7df9c41](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7df9c414e4719d547113eec58cf38f4b67bf268e)) # [1.16.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.15.3...v1.16.0) (2025-04-25) ### Bug Fixes * unify tool names and descriptions for consistency ([075d996](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/075d9966cddad3101b5a1ea2331cffd44563d644)) ### Features * prefix Bitbucket tool names with 'bitbucket_' for uniqueness ([69d59a8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/69d59a80f9a3ef08c649136cd771fbfd8181337b)) ## [1.15.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.15.2...v1.15.3) (2025-04-22) ### Performance Improvements * Update dependencies ([fae420e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/fae420ee00d9dd5c71dfce18610e33e8d8857403)) ## [1.15.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.15.1...v1.15.2) (2025-04-20) ### Bug Fixes * Update dependencies and fix related type errors ([4acea85](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4acea85c681dce9af6f23f751384c4aae08480b7)) ## [1.15.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.15.0...v1.15.1) (2025-04-09) ### Bug Fixes * **deps:** update dependencies to latest versions ([68c2f39](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/68c2f390499b7694da6771963f856cefa0b812d6)) # [1.15.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.14.2...v1.15.0) (2025-04-04) ### Bug Fixes * improve README clarity and accuracy ([c09711f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c09711fc86dd29f6018907660b891e322bf089b2)) ### Features * **pullrequests:** add code diff and diffstat display to pull request details ([ed2fd3a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ed2fd3a2483117989701bc37b14f8aeed1233e2b)) ## [1.14.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.14.1...v1.14.2) (2025-04-04) ### Bug Fixes * add remaining search functionality improvements ([163d38f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/163d38fb5d18f3b2b7dc47cee778c48be61a23c4)) * improve search results consistency across all search types ([d5f8313](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d5f8313df4f04287d5c97824a3db98202e428f7d)) * standardize tool registration function names to registerTools ([4f4b7c6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4f4b7c6dce51b750048465526f0033239af54921)) ## [1.14.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.14.0...v1.14.1) (2025-04-03) ### Performance Improvements * trigger new release ([9c3cd52](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/9c3cd52bf4ba820df9bb0a9f5a3b7ea6d6f90c99)) # [1.14.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.13.3...v1.14.0) (2025-04-03) ### Features * **logging:** add file logging with session ID to ~/.mcp/data/ ([8e2eae1](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/8e2eae16cdf78579bf7925704fb958a0a97411b7)) ## [1.13.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.13.2...v1.13.3) (2025-04-03) ### Bug Fixes * **logger:** ensure consistent logger implementation across all projects ([30f96e9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/30f96e96eb7576cfdac904534210915c40286aa3)) ## [1.13.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.13.1...v1.13.2) (2025-04-03) ### Performance Improvements * **bitbucket:** improve version handling and module exports ([76f9820](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/76f982098774f8dd22d4694c683fdd485c38112d)) ## [1.13.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.13.0...v1.13.1) (2025-04-03) ### Bug Fixes * update PR tool argument types for Windsurf wave 6 compatibility ([51b3824](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/51b38242cb553f77b73d025280db9cceaa2365d5)), closes [#7](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/7) # [1.13.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.12.0...v1.13.0) (2025-04-01) ### Bug Fixes * **cli:** rename create-pr to create-pull-request and update parameter names for consistency ([6e4dbb2](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6e4dbb2112368544cdbf567561ef800575e91536)) ### Features * **pullrequests:** add create pull request feature to CLI and MCP tools ([73400af](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/73400af266fd787b8b216bcb3ec5058b1fa99ff9)), closes [#3](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/3) # [1.12.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.11.1...v1.12.0) (2025-04-01) ### Bug Fixes * **build:** remove unused skipIfNoCredentials function ([9173010](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/91730106c1a21f33879130ffb20b24d9d3731e78)) * **pr:** fix double JSON.stringify in PR comment API call ([a445dc7](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a445dc7db71bcc6fd73f2b3bf6312686b9424ce1)) ### Features * **pr:** add CLI command and tests for PR comments ([d6d3dc2](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d6d3dc20e3722b22f694e50e7b80542ba951ea54)) ## [1.11.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.11.0...v1.11.1) (2025-03-29) ### Bug Fixes * conflict ([e947249](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e9472496062a64bd9766c3ba8b61944076d16883)) # [1.11.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.10.1...v1.11.0) (2025-03-28) ### Bug Fixes * **cli:** standardize CLI parameter naming conventions ([fe16246](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/fe16246a550674470ce8b03441809e07c0c7016b)) * resolve TypeScript errors and lint warnings in Bitbucket MCP server ([29446b9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/29446b95151e3462f2bef3cd1f772e9726c97a29)) * standardize status parameter and workspace identifiers ([c11b2bf](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c11b2bf5b6cf7f4e3b0eae189c17f300d64c5534)) * **test:** improve Bitbucket workspaces integration tests with better error handling and reliability ([284447f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/284447f0897c9e53c271777d2f81178a65e32ca9)) * **tests:** improve test resiliency for CLI commands ([7f690ba](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7f690ba4f3c42fb2f8bce6cf279ccfb5dc419a74)) ### Features * standardize CLI flag patterns and entity parameter naming ([7b4d719](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7b4d71948d3bf6a4b2cf8659e42b02e57b92f451)) * **test:** add comprehensive test coverage for Bitbucket MCP server ([b69fa8f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/b69fa8f171efbe713f42e9cfde013a83898419dd)) ## [1.10.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.10.0...v1.10.1) (2025-03-28) ### Performance Improvements * rename tools to use underscore instead of hyphen ([bc1f65e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/bc1f65e7d76d3c13f4fd96cde115c441c7d6212f)) # [1.10.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.9.1...v1.10.0) (2025-03-27) ### Bug Fixes * remove sort option from Bitbucket workspaces endpoints, API does not support sorting ([e6ccd9b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e6ccd9b7e78d6316dbbfa7def756b6897550ff29)) * standardize patterns across MCP server projects ([78ca874](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/78ca8748ba2b639e52e13bfc361c91d9573e1340)) * trigger new release ([63b2025](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/63b2025127c509e7db2d82945717b49ea223d77d)) * update applyDefaults utility to work with TypeScript interfaces ([2f682ca](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2f682cacef284ebeb9d2f40577209bf6b45ad1d9)) * update version to 1.10.0 to fix CI/CD workflows ([938f481](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/938f48109fc1a93c7375495d08598dca044a2235)) ### Features * update to version 1.11.0 with new repository command documentation ([0a714df](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/0a714df36671f1a9bd94c90cab9d462cb90105ec)) ## [1.9.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.9.1...v1.9.2) (2025-03-27) ### Bug Fixes * remove sort option from Bitbucket workspaces endpoints, API does not support sorting ([e6ccd9b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e6ccd9b7e78d6316dbbfa7def756b6897550ff29)) * standardize patterns across MCP server projects ([78ca874](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/78ca8748ba2b639e52e13bfc361c91d9573e1340)) * trigger new release ([63b2025](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/63b2025127c509e7db2d82945717b49ea223d77d)) * update applyDefaults utility to work with TypeScript interfaces ([2f682ca](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2f682cacef284ebeb9d2f40577209bf6b45ad1d9)) * update version to 1.10.0 to fix CI/CD workflows ([938f481](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/938f48109fc1a93c7375495d08598dca044a2235)) ## [1.9.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.9.1...v1.9.2) (2025-03-27) ### Bug Fixes * remove sort option from Bitbucket workspaces endpoints, API does not support sorting ([e6ccd9b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e6ccd9b7e78d6316dbbfa7def756b6897550ff29)) * standardize patterns across MCP server projects ([78ca874](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/78ca8748ba2b639e52e13bfc361c91d9573e1340)) * trigger new release ([63b2025](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/63b2025127c509e7db2d82945717b49ea223d77d)) * update applyDefaults utility to work with TypeScript interfaces ([2f682ca](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2f682cacef284ebeb9d2f40577209bf6b45ad1d9)) ## [1.9.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.9.0...v1.9.1) (2025-03-27) ### Bug Fixes * **error:** standardize error handling across all MCP servers ([76834af](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/76834aff1d716e3e2caf210f667df65dfd21d466)) # [1.9.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.8.1...v1.9.0) (2025-03-27) ### Features * **logger:** implement contextual logging pattern ([d6f16b7](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d6f16b76513990dce1e6d68c32767331d075c78b)) ## [1.8.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.8.0...v1.8.1) (2025-03-27) ### Bug Fixes * trigger release ([43a4d06](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/43a4d069c3702f748a751f6f8a5d8b8ff425f5ab)) # [1.8.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.7.3...v1.8.0) (2025-03-26) ### Features * **bitbucket:** add default -updated_on sort to list operations ([ee5dbca](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ee5dbcae32484b61e67f5852e21d5e63ed2ea4a4)) * **bitbucket:** add pull request comments and enhance repository details ([72a91c8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/72a91c89c7ce54aedbdf457ba818af83414c43a6)) ## [1.7.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.7.2...v1.7.3) (2025-03-26) ### Bug Fixes * empty commit to trigger patch version bump ([260911a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/260911a1a2927aaadbe38e77fe04281a45d75334)) ## [1.7.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.7.1...v1.7.2) (2025-03-26) ### Bug Fixes * improve CLI and tool descriptions with consistent formatting and detailed guidance ([ce74835](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ce748354d84f7649d71a230b8e66e80c41547f34)) ## [1.7.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.7.0...v1.7.1) (2025-03-26) ### Bug Fixes * standardize parameter naming conventions in Bitbucket module ([458a6e2](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/458a6e2ce714420794a83b334476c135353639fb)) # [1.7.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.6.0...v1.7.0) (2025-03-26) ### Features * trigger release with semantic versioning ([f4895b8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f4895b82f93d842bf777c59e2707aeedb64fd30c)) # [1.6.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.5.0...v1.6.0) (2025-03-26) ### Features * standardize CLI flags for consistent naming patterns ([b2ee0ba](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/b2ee0ba05dbd386ee3adb42c3fe82287d2b735ab)) # [1.5.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.4.2...v1.5.0) (2025-03-26) ### Features * improve CLI interface by using named parameters instead of positional arguments ([99318be](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/99318bee1cc2f4706b63072800431e43b0c051a4)) ## [1.4.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.4.1...v1.4.2) (2025-03-26) ### Bug Fixes * standardize CLI pagination and query parameter names ([e116b25](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e116b2582eda41f2241bf71454f82fcd2a6bdad0)) ## [1.4.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.4.0...v1.4.1) (2025-03-25) ### Bug Fixes * replace any with unknown in defaults.util.ts ([5dbc0b1](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5dbc0b1050df479ac844907ef1ed26fc26734561)) # [1.4.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.3.0...v1.4.0) (2025-03-25) ### Features * **pagination:** standardize pagination display across all CLI commands ([34f4c91](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/34f4c91f8aeb5c00d56d6975b8fa4c3ee81f4a9a)) # [1.3.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.2.0...v1.3.0) (2025-03-25) ### Features * **format:** implement standardized formatters and update CLI documentation ([9770402](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/9770402096de6b6dffda263b976f7dbf4f4a9ee4)) # [1.2.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.1.1...v1.2.0) (2025-03-25) ### Bug Fixes * standardize logging patterns and fix linter and type errors ([368df0f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/368df0f602e29eea982628ddbc6f4f0702a6fab7)) ### Features * **workspaces:** improve workspace and repository management ([f27daf2](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f27daf2238362c897ca2990a252d268e9d005484)) ## [1.1.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.1.0...v1.1.1) (2025-03-25) ### Bug Fixes * trigger new release for parameter and pagination standardization ([5607ce9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5607ce91179b33ee9f3457e5150608300072a5f9)) * update CLI and tool handlers to use object-based identifiers ([2899adc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2899adc38e2b804bc85098aef1f0a26caa90f5aa)) # [1.1.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.0.0...v1.1.0) (2025-03-25) ### Bug Fixes * conflict ([91d2720](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/91d27204fdb7029d5fdd49282dbdfbdfe6da9090)) * conflict ([bccabbf](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/bccabbf44991eda2c91de592d2662f614adf4fb2)) * improve documentation with additional section ([6849f9b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6849f9b2339c049e0017ef40aedadd184350cee0)) * remove dist directory from git tracking ([7343e65](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7343e65746001cb3465f9d0b0db30297ee43fb09)) * remove dist files from release commit assets ([74e53ce](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/74e53cee60c6a7785561354c81cbdf611323df5a)) * version consistency and release workflow improvements ([1a2baae](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1a2baae4326163c8caf4fa4cfeb9f4b8028d2b5a)) ### Features * enhance get-space command to support both numeric IDs and space keys ([2913153](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/29131536f302abf1923c0c6521d544c51ad222fa)) # 1.0.0 (2025-03-24) ### Bug Fixes - add workflows permission to semantic-release workflow ([de3a335](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/de3a33510bd447af353444db1fcb58e1b1aa02e4)) - correct package name and version consistency ([374a660](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/374a660e88a62b9c7b7c59718beec09806c47c0e)) - ensure executable permissions for bin script ([395f1dc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/395f1dcb5f3b5efee99048d1b91e3b083e9e544f)) - handle empty strings properly in greet function ([546d3a8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/546d3a84209e1065af46b2213053f589340158df)) - improve documentation with additional section ([ccbd814](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ccbd8146ef55bed1edb6ed005f923ac25bfa8dae)) - improve error logging with IP address details ([121f516](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/121f51655517ddbea7d25968372bd6476f1b3e0f)) - improve GitHub Packages publishing with a more robust approach ([fd2aec9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/fd2aec9926cf99d301cbb2b5f5ca961a6b6fec7e)) - improve GitHub Packages publishing with better error handling and debugging ([db25f04](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/db25f04925e884349fcf3ab85316550fde231d1f)) - improve GITHUB_OUTPUT syntax in semantic-release workflow ([6f154bc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6f154bc43f42475857e9256b0a671c3263dc9708)) - improve version detection for global installations ([97a95dc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/97a95dca61d8cd7a86c81bde4cb38c509b810dc0)) - make publish workflow more resilient against version conflicts ([ffd3705](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ffd3705bc064ee9135402052a0dc7fe32645714b)) - remove dist directory from git tracking ([0ed5d4b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/0ed5d4bad05e09cbae3350eb934c98ef1d28ed12)) - remove dist files from release commit assets ([86e486b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/86e486bb68cb18d077852e73eabf8f912d9d007e)) - remove incorrect limit expectation in transport utility tests ([6f7b689](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6f7b689a7eb5db8a8592db88e7fa27ac04d641c8)) - remove invalid workflows permission ([c012e46](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c012e46a29070c8394f7ab596fe7ba68c037d3a3)) - remove type module to fix CommonJS compatibility ([8b1f00c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/8b1f00c37467bc676ad8ec9ab672ba393ed084a9)) - resolve linter errors in version detection code ([5f1f33e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5f1f33e88ae843b7a0d708899713be36fcd2ec2e)) - update examples to use correct API (greet instead of sayHello) ([7c062ca](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7c062ca42765c659f018f990f4b1ec563d1172d3)) - update package name in config loader ([3b8157b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3b8157b076441e4dde562cddfe31671f3696434d)) - update package.json version and scripts, fix transport.util.test.ts, update README ([deefccd](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/deefccdc93311be572abf45feb9a5aae69ed57eb)) - update release workflow to ensure correct versioning in compiled files ([a365394](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a365394b8596defa33ff5a44583d52e2c43f0aa3)) - update version display in CLI ([2b7846c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2b7846cbfa023f4b1a8c81ec511370fa8f5aaf33)) ### Features - add automated dependency management ([efa1b62](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/efa1b6292e0e9b6efd0d43b40cf7099d50769487)) - add CLI usage examples for both JavaScript and TypeScript ([d5743b0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d5743b07a6f2afe1c6cb0b03265228cba771e657)) - add support for custom name in greet command ([be48a05](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/be48a053834a1d910877864608a5e9942d913367)) - add version update script and fix version display ([ec831d3](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ec831d3a3c966d858c15972365007f9dfd6115b8)) - implement Atlassian Bitbucket MCP server with pull request, repository, and workspace features ([a9ff1c9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a9ff1c9ddecaa323ffdbd6620bd5bc02b517079b)) - implement Atlassian Confluence MCP server ([50ee69e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/50ee69e37f4d453cb8f0447e10fa5708a787aa93)) - implement review recommendations ([a23cbc0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a23cbc0608a07e202396b3cd496c1f2078e304c1)) - implement testing, linting, and semantic versioning ([1d7710d](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1d7710dfa11fd1cb04ba3c604e9a2eb785652394)) - improve CI workflows with standardized Node.js version, caching, and dual publishing ([0dc9470](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/0dc94705c81067d7ff63ab978ef9e6a6e3f75784)) - improve development workflow and update documentation ([4458957](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/445895777be6287a624cb19b8cd8a12590a28c7b)) - improve package structure and add better examples ([bd66891](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/bd668915bde84445161cdbd55ff9da0b0af51944)) - initial implementation of Jira MCP server ([79e4651](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/79e4651ddf322d2dcc93d2a4aa2bd1294266550b)) ### Reverts - restore simple version handling ([bd0fadf](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/bd0fadfa8207b4a7cf472c3b9f4ee63d8e36189d)) ## [1.1.4](https://github.com/aashari/mcp-server-atlassian-jira/compare/v1.1.3...v1.1.4) (2025-03-24) ### Bug Fixes - remove dist directory from git tracking ([0ed5d4b](https://github.com/aashari/mcp-server-atlassian-jira/commit/0ed5d4bad05e09cbae3350eb934c98ef1d28ed12)) ## [1.1.3](https://github.com/aashari/mcp-server-atlassian-jira/compare/v1.1.2...v1.1.3) (2025-03-24) ### Bug Fixes - remove dist files from release commit assets ([86e486b](https://github.com/aashari/mcp-server-atlassian-jira/commit/86e486bb68cb18d077852e73eabf8f912d9d007e)) ## [1.1.2](https://github.com/aashari/mcp-server-atlassian-jira/compare/v1.1.1...v1.1.2) (2025-03-24) ### Bug Fixes - correct package name and version consistency ([374a660](https://github.com/aashari/mcp-server-atlassian-jira/commit/374a660e88a62b9c7b7c59718beec09806c47c0e)) ## [1.1.1](https://github.com/aashari/mcp-server-atlassian-jira/compare/v1.1.0...v1.1.1) (2025-03-24) ### Bug Fixes - improve documentation with additional section ([ccbd814](https://github.com/aashari/mcp-server-atlassian-jira/commit/ccbd8146ef55bed1edb6ed005f923ac25bfa8dae)) # [1.1.0](https://github.com/aashari/mcp-server-atlassian-jira/compare/v1.0.0...v1.1.0) (2025-03-23) ### Bug Fixes - remove incorrect limit expectation in transport utility tests ([6f7b689](https://github.com/aashari/mcp-server-atlassian-jira/commit/6f7b689a7eb5db8a8592db88e7fa27ac04d641c8)) - update package.json version and scripts, fix transport.util.test.ts, update README ([deefccd](https://github.com/aashari/mcp-server-atlassian-jira/commit/deefccdc93311be572abf45feb9a5aae69ed57eb)) ### Features - improve development workflow and update documentation ([4458957](https://github.com/aashari/mcp-server-atlassian-jira/commit/445895777be6287a624cb19b8cd8a12590a28c7b)) # 1.0.0 (2025-03-23) ### Bug Fixes - add workflows permission to semantic-release workflow ([de3a335](https://github.com/aashari/mcp-server-atlassian-jira/commit/de3a33510bd447af353444db1fcb58e1b1aa02e4)) - ensure executable permissions for bin script ([395f1dc](https://github.com/aashari/mcp-server-atlassian-jira/commit/395f1dcb5f3b5efee99048d1b91e3b083e9e544f)) - handle empty strings properly in greet function ([546d3a8](https://github.com/aashari/mcp-server-atlassian-jira/commit/546d3a84209e1065af46b2213053f589340158df)) - improve error logging with IP address details ([121f516](https://github.com/aashari/mcp-server-atlassian-jira/commit/121f51655517ddbea7d25968372bd6476f1b3e0f)) - improve GitHub Packages publishing with a more robust approach ([fd2aec9](https://github.com/aashari/mcp-server-atlassian-jira/commit/fd2aec9926cf99d301cbb2b5f5ca961a6b6fec7e)) - improve GitHub Packages publishing with better error handling and debugging ([db25f04](https://github.com/aashari/mcp-server-atlassian-jira/commit/db25f04925e884349fcf3ab85316550fde231d1f)) - improve GITHUB_OUTPUT syntax in semantic-release workflow ([6f154bc](https://github.com/aashari/mcp-server-atlassian-jira/commit/6f154bc43f42475857e9256b0a671c3263dc9708)) - improve version detection for global installations ([97a95dc](https://github.com/aashari/mcp-server-atlassian-jira/commit/97a95dca61d8cd7a86c81bde4cb38c509b810dc0)) - make publish workflow more resilient against version conflicts ([ffd3705](https://github.com/aashari/mcp-server-atlassian-jira/commit/ffd3705bc064ee9135402052a0dc7fe32645714b)) - remove invalid workflows permission ([c012e46](https://github.com/aashari/mcp-server-atlassian-jira/commit/c012e46a29070c8394f7ab596fe7ba68c037d3a3)) - remove type module to fix CommonJS compatibility ([8b1f00c](https://github.com/aashari/mcp-server-atlassian-jira/commit/8b1f00c37467bc676ad8ec9ab672ba393ed084a9)) - resolve linter errors in version detection code ([5f1f33e](https://github.com/aashari/mcp-server-atlassian-jira/commit/5f1f33e88ae843b7a0d708899713be36fcd2ec2e)) - update examples to use correct API (greet instead of sayHello) ([7c062ca](https://github.com/aashari/mcp-server-atlassian-jira/commit/7c062ca42765c659f018f990f4b1ec563d1172d3)) - update package name in config loader ([3b8157b](https://github.com/aashari/mcp-server-atlassian-jira/commit/3b8157b076441e4dde562cddfe31671f3696434d)) - update release workflow to ensure correct versioning in compiled files ([a365394](https://github.com/aashari/mcp-server-atlassian-jira/commit/a365394b8596defa33ff5a44583d52e2c43f0aa3)) - update version display in CLI ([2b7846c](https://github.com/aashari/mcp-server-atlassian-jira/commit/2b7846cbfa023f4b1a8c81ec511370fa8f5aaf33)) ### Features - add automated dependency management ([efa1b62](https://github.com/aashari/mcp-server-atlassian-jira/commit/efa1b6292e0e9b6efd0d43b40cf7099d50769487)) - add CLI usage examples for both JavaScript and TypeScript ([d5743b0](https://github.com/aashari/mcp-server-atlassian-jira/commit/d5743b07a6f2afe1c6cb0b03265228cba771e657)) - add support for custom name in greet command ([be48a05](https://github.com/aashari/mcp-server-atlassian-jira/commit/be48a053834a1d910877864608a5e9942d913367)) - add version update script and fix version display ([ec831d3](https://github.com/aashari/mcp-server-atlassian-jira/commit/ec831d3a3c966d858c15972365007f9dfd6115b8)) - implement Atlassian Confluence MCP server ([50ee69e](https://github.com/aashari/mcp-server-atlassian-jira/commit/50ee69e37f4d453cb8f0447e10fa5708a787aa93)) - implement review recommendations ([a23cbc0](https://github.com/aashari/mcp-server-atlassian-jira/commit/a23cbc0608a07e202396b3cd496c1f2078e304c1)) - implement testing, linting, and semantic versioning ([1d7710d](https://github.com/aashari/mcp-server-atlassian-jira/commit/1d7710dfa11fd1cb04ba3c604e9a2eb785652394)) - improve CI workflows with standardized Node.js version, caching, and dual publishing ([0dc9470](https://github.com/aashari/mcp-server-atlassian-jira/commit/0dc94705c81067d7ff63ab978ef9e6a6e3f75784)) - improve package structure and add better examples ([bd66891](https://github.com/aashari/mcp-server-atlassian-jira/commit/bd668915bde84445161cdbd55ff9da0b0af51944)) - initial implementation of Jira MCP server ([79e4651](https://github.com/aashari/mcp-server-atlassian-jira/commit/79e4651ddf322d2dcc93d2a4aa2bd1294266550b)) ### Reverts - restore simple version handling ([bd0fadf](https://github.com/aashari/mcp-server-atlassian-jira/commit/bd0fadfa8207b4a7cf472c3b9f4ee63d8e36189d)) ## [1.0.1](https://github.com/aashari/mcp-server-atlassian-confluence/compare/v1.0.0...v1.0.1) (2025-03-23) ### Bug Fixes - update package name in config loader ([3b8157b](https://github.com/aashari/mcp-server-atlassian-confluence/commit/3b8157b076441e4dde562cddfe31671f3696434d)) # 1.0.0 (2025-03-23) ### Bug Fixes - add workflows permission to semantic-release workflow ([de3a335](https://github.com/aashari/mcp-server-atlassian-confluence/commit/de3a33510bd447af353444db1fcb58e1b1aa02e4)) - ensure executable permissions for bin script ([395f1dc](https://github.com/aashari/mcp-server-atlassian-confluence/commit/395f1dcb5f3b5efee99048d1b91e3b083e9e544f)) - handle empty strings properly in greet function ([546d3a8](https://github.com/aashari/mcp-server-atlassian-confluence/commit/546d3a84209e1065af46b2213053f589340158df)) - improve error logging with IP address details ([121f516](https://github.com/aashari/mcp-server-atlassian-confluence/commit/121f51655517ddbea7d25968372bd6476f1b3e0f)) - improve GitHub Packages publishing with a more robust approach ([fd2aec9](https://github.com/aashari/mcp-server-atlassian-confluence/commit/fd2aec9926cf99d301cbb2b5f5ca961a6b6fec7e)) - improve GitHub Packages publishing with better error handling and debugging ([db25f04](https://github.com/aashari/mcp-server-atlassian-confluence/commit/db25f04925e884349fcf3ab85316550fde231d1f)) - improve GITHUB_OUTPUT syntax in semantic-release workflow ([6f154bc](https://github.com/aashari/mcp-server-atlassian-confluence/commit/6f154bc43f42475857e9256b0a671c3263dc9708)) - improve version detection for global installations ([97a95dc](https://github.com/aashari/mcp-server-atlassian-confluence/commit/97a95dca61d8cd7a86c81bde4cb38c509b810dc0)) - make publish workflow more resilient against version conflicts ([ffd3705](https://github.com/aashari/mcp-server-atlassian-confluence/commit/ffd3705bc064ee9135402052a0dc7fe32645714b)) - remove invalid workflows permission ([c012e46](https://github.com/aashari/mcp-server-atlassian-confluence/commit/c012e46a29070c8394f7ab596fe7ba68c037d3a3)) - remove type module to fix CommonJS compatibility ([8b1f00c](https://github.com/aashari/mcp-server-atlassian-confluence/commit/8b1f00c37467bc676ad8ec9ab672ba393ed084a9)) - resolve linter errors in version detection code ([5f1f33e](https://github.com/aashari/mcp-server-atlassian-confluence/commit/5f1f33e88ae843b7a0d708899713be36fcd2ec2e)) - update examples to use correct API (greet instead of sayHello) ([7c062ca](https://github.com/aashari/mcp-server-atlassian-confluence/commit/7c062ca42765c659f018f990f4b1ec563d1172d3)) - update release workflow to ensure correct versioning in compiled files ([a365394](https://github.com/aashari/mcp-server-atlassian-confluence/commit/a365394b8596defa33ff5a44583d52e2c43f0aa3)) - update version display in CLI ([2b7846c](https://github.com/aashari/mcp-server-atlassian-confluence/commit/2b7846cbfa023f4b1a8c81ec511370fa8f5aaf33)) ### Features - add automated dependency management ([efa1b62](https://github.com/aashari/mcp-server-atlassian-confluence/commit/efa1b6292e0e9b6efd0d43b40cf7099d50769487)) - add CLI usage examples for both JavaScript and TypeScript ([d5743b0](https://github.com/aashari/mcp-server-atlassian-confluence/commit/d5743b07a6f2afe1c6cb0b03265228cba771e657)) - add support for custom name in greet command ([be48a05](https://github.com/aashari/mcp-server-atlassian-confluence/commit/be48a053834a1d910877864608a5e9942d913367)) - add version update script and fix version display ([ec831d3](https://github.com/aashari/mcp-server-atlassian-confluence/commit/ec831d3a3c966d858c15972365007f9dfd6115b8)) - implement Atlassian Confluence MCP server ([50ee69e](https://github.com/aashari/mcp-server-atlassian-confluence/commit/50ee69e37f4d453cb8f0447e10fa5708a787aa93)) - implement review recommendations ([a23cbc0](https://github.com/aashari/mcp-server-atlassian-confluence/commit/a23cbc0608a07e202396b3cd496c1f2078e304c1)) - implement testing, linting, and semantic versioning ([1d7710d](https://github.com/aashari/mcp-server-atlassian-confluence/commit/1d7710dfa11fd1cb04ba3c604e9a2eb785652394)) - improve CI workflows with standardized Node.js version, caching, and dual publishing ([0dc9470](https://github.com/aashari/mcp-server-atlassian-confluence/commit/0dc94705c81067d7ff63ab978ef9e6a6e3f75784)) - improve package structure and add better examples ([bd66891](https://github.com/aashari/mcp-server-atlassian-confluence/commit/bd668915bde84445161cdbd55ff9da0b0af51944)) ### Reverts - restore simple version handling ([bd0fadf](https://github.com/aashari/mcp-server-atlassian-confluence/commit/bd0fadfa8207b4a7cf472c3b9f4ee63d8e36189d)) # 1.0.0 (2025-03-23) ### Features - Initial release of Atlassian Confluence MCP server - Provides tools for accessing and searching Confluence spaces, pages, and content - Integration with Claude Desktop and Cursor AI via Model Context Protocol - CLI support for direct interaction with Confluence ```