829 lines
28 KiB
TypeScript
829 lines
28 KiB
TypeScript
/**
|
|
* MCP tool router that maps tool calls to Bitbucket API operations.
|
|
*/
|
|
|
|
import { BitbucketClient } from './bitbucket-client.js';
|
|
import { DefaultConfigLoader } from './config.js';
|
|
|
|
interface ToolCallParams {
|
|
[key: string]: any;
|
|
}
|
|
|
|
export interface ToolResult {
|
|
success: boolean;
|
|
data?: any;
|
|
error?: string;
|
|
}
|
|
|
|
/**
|
|
* Router that maps MCP tool calls to Bitbucket API operations.
|
|
*/
|
|
export class BitbucketRouter {
|
|
private client: BitbucketClient;
|
|
|
|
constructor() {
|
|
this.client = new BitbucketClient();
|
|
}
|
|
|
|
private getDefaultParams(params: ToolCallParams): { workspace: string | undefined; repoSlug: string | undefined } {
|
|
const defaults = DefaultConfigLoader.load();
|
|
return {
|
|
workspace: params.workspace || defaults.workspace || undefined,
|
|
repoSlug: params.repository || params.repo || defaults.repo || undefined
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Validate the Bitbucket token.
|
|
*/
|
|
private async validateToken(): Promise<ToolResult> {
|
|
try {
|
|
const result = await this.client.validateToken();
|
|
return {
|
|
success: result.valid,
|
|
data: result
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: `Token validation failed: ${String(error)}`
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Execute a tool call and return MCP-compatible result.
|
|
*/
|
|
async executeTool(
|
|
toolName: string,
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
switch (toolName) {
|
|
case 'validate_token':
|
|
return this.validateToken();
|
|
|
|
case 'list_pull_requests':
|
|
return this.listPullRequests(params);
|
|
|
|
case 'get_pull_request':
|
|
return this.getPullRequest(params);
|
|
|
|
case 'get_pull_request_activities':
|
|
return this.getPullRequestActivities(params);
|
|
|
|
case 'get_pull_request_changes':
|
|
return this.getPullRequestChanges(params);
|
|
|
|
case 'get_pull_request_comments':
|
|
return this.getPullRequestComments(params);
|
|
|
|
case 'get_pull_request_comment':
|
|
return this.getPullRequestComment(params);
|
|
|
|
case 'get_pull_request_commits':
|
|
return this.getPullRequestCommits(params);
|
|
|
|
case 'get_pull_request_diff':
|
|
return this.getPullRequestDiff(params);
|
|
|
|
case 'get_pull_request_patch':
|
|
return this.getPullRequestPatch(params);
|
|
|
|
case 'get_pull_request_participants':
|
|
return this.getPullRequestParticipants(params);
|
|
|
|
case 'get_pull_request_reviewers':
|
|
return this.getPullRequestReviewers(params);
|
|
|
|
case 'get_pull_request_status':
|
|
return this.getPullRequestStatus(params);
|
|
|
|
case 'get_pull_request_tasks':
|
|
return this.getPullRequestTasks(params);
|
|
|
|
case 'get_pull_request_task_count':
|
|
return this.getPullRequestTaskCount(params);
|
|
|
|
case 'get_full_pull_request':
|
|
return this.getFullPullRequest(params);
|
|
|
|
case 'list_workspaces':
|
|
return this.listWorkspaces(params);
|
|
|
|
case 'list_repositories':
|
|
return this.listRepositories(params);
|
|
|
|
case 'get_repository':
|
|
return this.getRepository(params);
|
|
|
|
case 'list_branches':
|
|
return this.listBranches(params);
|
|
|
|
case 'create_pull_request':
|
|
return this.createPullRequest(params);
|
|
|
|
case 'update_pull_request':
|
|
return this.updatePullRequest(params);
|
|
|
|
case 'merge_pull_request':
|
|
return this.mergePullRequest(params);
|
|
|
|
case 'decline_pull_request':
|
|
return this.declinePullRequest(params);
|
|
|
|
case 'approve_pull_request':
|
|
return this.approvePullRequest(params);
|
|
|
|
case 'unapprove_pull_request':
|
|
return this.unapprovePullRequest(params);
|
|
|
|
case 'request_changes_pull_request':
|
|
return this.requestChangesPullRequest(params);
|
|
|
|
case 'remove_request_changes_pull_request':
|
|
return this.removeRequestChangesPullRequest(params);
|
|
|
|
case 'add_pull_request_comment':
|
|
return this.addPullRequestComment(params);
|
|
|
|
case 'update_pull_request_comment':
|
|
return this.updatePullRequestComment(params);
|
|
|
|
case 'delete_pull_request_comment':
|
|
return this.deletePullRequestComment(params);
|
|
|
|
case 'create_pull_request_task':
|
|
return this.createPullRequestTask(params);
|
|
|
|
case 'update_pull_request_task':
|
|
return this.updatePullRequestTask(params);
|
|
|
|
case 'delete_pull_request_task':
|
|
return this.deletePullRequestTask(params);
|
|
|
|
default:
|
|
return {
|
|
success: false,
|
|
error: `Unknown tool: ${toolName}`
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* List pull requests in a repository.
|
|
*/
|
|
private async listPullRequests(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
|
|
if (!workspace || !repoSlug) {
|
|
return {
|
|
success: false,
|
|
error: 'Missing required parameters: workspace and repository'
|
|
};
|
|
}
|
|
|
|
// Default to open PRs if state not specified
|
|
const options = params.state ? { state: params.state } : undefined;
|
|
|
|
const prs = await this.client.listPullRequests(workspace, repoSlug, options);
|
|
|
|
return {
|
|
success: true,
|
|
data: {
|
|
pull_requests: prs,
|
|
count: prs.length
|
|
}
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: `List pull requests failed: ${typeof error === 'string' ? error : String(error)}`
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a specific pull request.
|
|
*/
|
|
private async getPullRequest(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return {
|
|
success: false,
|
|
error: 'Missing required parameters'
|
|
};
|
|
}
|
|
|
|
const pr = await this.client.getPullRequest(workspace, repoSlug, prId);
|
|
|
|
return {
|
|
success: true,
|
|
data: pr
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error: `Get pull request failed: ${typeof error === 'string' ? error : String(error)}`
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get pull request activities (events/actions).
|
|
*/
|
|
private async getPullRequestActivities(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestActivities(workspace, repoSlug, prId, {
|
|
limit: params.limit,
|
|
start: params.start
|
|
});
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get activities failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get pull request changes (files modified).
|
|
*/
|
|
private async getPullRequestChanges(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestChanges(workspace, repoSlug, prId, {
|
|
limit: params.limit,
|
|
start: params.start
|
|
});
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get changes failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get pull request comments.
|
|
*/
|
|
private async getPullRequestComments(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestComments(workspace, repoSlug, prId, {
|
|
limit: params.limit,
|
|
start: params.start
|
|
});
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get comments failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a specific pull request comment.
|
|
*/
|
|
private async getPullRequestComment(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
const commentId = parseInt(params.commentId || params.comment_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId) || isNaN(commentId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestComment(workspace, repoSlug, prId, commentId);
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get comment failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get commits in a pull request.
|
|
*/
|
|
private async getPullRequestCommits(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestCommits(workspace, repoSlug, prId, {
|
|
limit: params.limit,
|
|
start: params.start
|
|
});
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get commits failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get pull request diff.
|
|
*/
|
|
private async getPullRequestDiff(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestDiff(workspace, repoSlug, prId, {
|
|
context: params.context,
|
|
path: params.path,
|
|
whitespace: params.whitespace
|
|
});
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get diff failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get pull request patch.
|
|
*/
|
|
private async getPullRequestPatch(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestPatch(workspace, repoSlug, prId);
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get patch failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get pull request participants.
|
|
*/
|
|
private async getPullRequestParticipants(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestParticipants(workspace, repoSlug, prId);
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get participants failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get pull request reviewers.
|
|
*/
|
|
private async getPullRequestReviewers(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestReviewers(workspace, repoSlug, prId);
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get reviewers failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get pull request status.
|
|
*/
|
|
private async getPullRequestStatus(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestStatus(workspace, repoSlug, prId);
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get status failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get pull request tasks.
|
|
*/
|
|
private async getPullRequestTasks(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestTasks(workspace, repoSlug, prId);
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get tasks failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get pull request task count.
|
|
*/
|
|
private async getPullRequestTaskCount(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getPullRequestTaskCount(workspace, repoSlug, prId);
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get task count failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get full pull request details.
|
|
*/
|
|
private async getFullPullRequest(
|
|
params: ToolCallParams
|
|
): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
|
|
const result = await this.client.getFullPullRequest(workspace, repoSlug, prId);
|
|
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get full PR failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async listWorkspaces(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const result = await this.client.listWorkspaces({
|
|
page: params.page,
|
|
pagelen: params.pagelen,
|
|
});
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `List workspaces failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async listRepositories(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace } = this.getDefaultParams(params);
|
|
if (!workspace) {
|
|
return { success: false, error: 'Missing required parameters: workspace' };
|
|
}
|
|
const result = await this.client.listRepositories(workspace, {
|
|
role: params.role,
|
|
page: params.page,
|
|
pagelen: params.pagelen,
|
|
});
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `List repositories failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async getRepository(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
if (!workspace || !repoSlug) {
|
|
return { success: false, error: 'Missing required parameters: workspace and repository' };
|
|
}
|
|
const result = await this.client.getRepository(workspace, repoSlug);
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Get repository failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async listBranches(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
if (!workspace || !repoSlug) {
|
|
return { success: false, error: 'Missing required parameters: workspace and repository' };
|
|
}
|
|
const result = await this.client.listBranches(workspace, repoSlug, {
|
|
filter_by_name: params.filter_by_name,
|
|
page: params.page,
|
|
pagelen: params.pagelen,
|
|
});
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `List branches failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async createPullRequest(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
if (!workspace || !repoSlug || !params.title || !params.source_branch || !params.destination_branch) {
|
|
return { success: false, error: 'Missing required parameters: workspace, repository, title, source_branch, destination_branch' };
|
|
}
|
|
const result = await this.client.createPullRequest(workspace, repoSlug, {
|
|
title: params.title,
|
|
source_branch: params.source_branch,
|
|
destination_branch: params.destination_branch,
|
|
description: params.description,
|
|
reviewers: params.reviewers,
|
|
close_source_branch: params.close_source_branch,
|
|
});
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Create pull request failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async updatePullRequest(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
const result = await this.client.updatePullRequest(workspace, repoSlug, prId, {
|
|
title: params.title,
|
|
description: params.description,
|
|
reviewers: params.reviewers,
|
|
destination_branch: params.destination_branch,
|
|
});
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Update pull request failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async mergePullRequest(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
const result = await this.client.mergePullRequest(workspace, repoSlug, prId, {
|
|
merge_strategy: params.merge_strategy,
|
|
commit_message: params.commit_message,
|
|
close_source_branch: params.close_source_branch,
|
|
});
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Merge pull request failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async declinePullRequest(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
const result = await this.client.declinePullRequest(workspace, repoSlug, prId);
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Decline pull request failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async approvePullRequest(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
const result = await this.client.approvePullRequest(workspace, repoSlug, prId);
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Approve pull request failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async unapprovePullRequest(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
const result = await this.client.unapprovePullRequest(workspace, repoSlug, prId);
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Unapprove pull request failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async requestChangesPullRequest(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
const result = await this.client.requestChangesPullRequest(workspace, repoSlug, prId);
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Request changes failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async removeRequestChangesPullRequest(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
const result = await this.client.removeRequestChangesPullRequest(workspace, repoSlug, prId);
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Remove request-changes failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async addPullRequestComment(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId) || !params.content) {
|
|
return { success: false, error: 'Missing required parameters: workspace, repository, pullRequestId, content' };
|
|
}
|
|
const opts: any = { content: params.content };
|
|
if (params.inline_path && params.inline_line) {
|
|
opts.inline = { path: params.inline_path, to: parseInt(params.inline_line, 10) };
|
|
}
|
|
if (params.parent_comment_id) {
|
|
opts.parent_id = parseInt(params.parent_comment_id, 10);
|
|
}
|
|
const result = await this.client.addPullRequestComment(workspace, repoSlug, prId, opts);
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Add comment failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async updatePullRequestComment(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
const commentId = parseInt(params.commentId || params.comment_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId) || isNaN(commentId) || !params.content) {
|
|
return { success: false, error: 'Missing required parameters: workspace, repository, pullRequestId, commentId, content' };
|
|
}
|
|
const result = await this.client.updatePullRequestComment(workspace, repoSlug, prId, commentId, { content: params.content });
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Update comment failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async deletePullRequestComment(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
const commentId = parseInt(params.commentId || params.comment_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId) || isNaN(commentId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
const result = await this.client.deletePullRequestComment(workspace, repoSlug, prId, commentId);
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Delete comment failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async createPullRequestTask(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId) || !params.content) {
|
|
return { success: false, error: 'Missing required parameters: workspace, repository, pullRequestId, content' };
|
|
}
|
|
const opts: any = { content: params.content };
|
|
if (params.comment_id) opts.comment_id = parseInt(params.comment_id, 10);
|
|
const result = await this.client.createPullRequestTask(workspace, repoSlug, prId, opts);
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Create task failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async updatePullRequestTask(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
const taskId = parseInt(params.taskId || params.task_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId) || isNaN(taskId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
const result = await this.client.updatePullRequestTask(workspace, repoSlug, prId, taskId, {
|
|
content: params.content,
|
|
state: params.state,
|
|
});
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Update task failed: ${String(error)}` };
|
|
}
|
|
}
|
|
|
|
private async deletePullRequestTask(params: ToolCallParams): Promise<ToolResult> {
|
|
try {
|
|
const { workspace, repoSlug } = this.getDefaultParams(params);
|
|
const prId = parseInt(params.pullRequestId || params.pr_id, 10);
|
|
const taskId = parseInt(params.taskId || params.task_id, 10);
|
|
if (!workspace || !repoSlug || isNaN(prId) || isNaN(taskId)) {
|
|
return { success: false, error: 'Missing required parameters' };
|
|
}
|
|
const result = await this.client.deletePullRequestTask(workspace, repoSlug, prId, taskId);
|
|
return { success: true, data: result };
|
|
} catch (error) {
|
|
return { success: false, error: `Delete task failed: ${String(error)}` };
|
|
}
|
|
}
|
|
}
|
|
|
|
export default BitbucketRouter; |