Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 199 additions & 0 deletions docs/api-reference/merge-pull-request.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
---
title: 'mergePullRequest'
description: 'Merge an existing pull request on GitHub'
---

## Overview

The `mergePullRequest` method allows you to programmatically merge an existing pull request on GitHub. It supports different merge methods (merge, squash, rebase) and allows customization of the commit message.

## Method Signature

```typescript
async mergePullRequest(
options: MergePullRequestOptions
): Promise<MergePullRequestResult>
```

## Parameters

### MergePullRequestOptions

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `pullNumber` | `number` | Yes | The number of the pull request to merge |
| `commitTitle` | `string` | No | Custom title for the merge commit |
| `commitMessage` | `string` | No | Custom message for the merge commit |
| `mergeMethod` | `'merge' \| 'squash' \| 'rebase'` | No | The merge method to use (defaults to 'merge') |

### Merge Methods

- **`merge`**: Creates a merge commit with all commits from the feature branch
- **`squash`**: Squashes all commits into a single commit before merging
- **`rebase`**: Rebases the commits onto the base branch

## Return Value

### MergePullRequestResult

| Property | Type | Description |
|----------|------|-------------|
| `sha` | `string` | The SHA of the merge commit |
| `merged` | `boolean` | Whether the pull request was successfully merged |
| `message` | `string` | A message describing the merge result |

## Prerequisites

Before using this method, ensure:

1. **GitHub Configuration**: You only need to configure GitHub credentials:
```typescript
vibekit.withGithub({
token: "your-github-token",
repository: "owner/repo"
})
```
Note: Unlike other methods, `mergePullRequest` does NOT require agent or sandbox configuration.

2. **Pull Request State**: The pull request must be:
- Open and not already merged
- Free of merge conflicts
- Passing all required status checks
- Approved if required by branch protection rules

## Usage Examples

### Basic Merge

```typescript
import { VibeKit } from "vibekit";

const vibekit = new VibeKit()
.withGithub({
token: process.env.GITHUB_TOKEN,
repository: "myorg/myrepo"
});

// Merge a pull request with default settings
const mergeResult = await vibekit.mergePullRequest({
pullNumber: 42
});

console.log(`PR merged with commit SHA: ${mergeResult.sha}`);
```

### Squash and Merge

```typescript
// Squash all commits and merge with a custom message
const mergeResult = await vibekit.mergePullRequest({
pullNumber: 42,
mergeMethod: "squash",
commitTitle: "feat: Add new feature",
commitMessage: "This PR adds the new feature with the following changes:\n- Added X\n- Updated Y\n- Fixed Z"
});
```

### Complete Workflow Example

```typescript
// For operations that require code generation, you'll need agent and sandbox
const vibkitWithAgent = new VibeKit()
.withAgent({
type: "claude",
provider: "anthropic",
apiKey: process.env.ANTHROPIC_API_KEY,
model: "claude-3-opus-20240229"
})
.withSandbox("docker")
.withGithub({
token: process.env.GITHUB_TOKEN,
repository: "myorg/myrepo"
});

// Generate code and create PR (requires agent/sandbox)
await vibkitWithAgent.generateCode({
prompt: "Add a new user authentication feature",
mode: "code",
branch: "feature/auth"
});

await vibkitWithAgent.pushToBranch();
const prResponse = await vibkitWithAgent.createPullRequest(
{
name: "feature",
color: "0366d6",
description: "New feature"
},
"feature"
);

console.log(`Created PR #${prResponse.number}`);

// After review and approval, merge the PR (only needs GitHub config)
const vibkitSimple = new VibeKit()
.withGithub({
token: process.env.GITHUB_TOKEN,
repository: "myorg/myrepo"
});

const mergeResult = await vibkitSimple.mergePullRequest({
pullNumber: prResponse.number,
mergeMethod: "squash"
});

if (mergeResult.merged) {
console.log(`Successfully merged PR #${prResponse.number}`);
}
```

## Error Handling

The method will throw an error in the following cases:

### Configuration Errors
- Missing GitHub token or repository configuration
- Invalid repository URL format

### Pull Request Errors
- **404**: Pull request not found
- **405**: Pull request is not mergeable (conflicts or failed checks)
- **422**: Invalid merge parameters or validation failed

### Example Error Handling

```typescript
try {
const result = await vibekit.mergePullRequest({
pullNumber: 42,
mergeMethod: "squash"
});

if (result.merged) {
console.log("Pull request successfully merged!");
}
} catch (error) {
if (error.message.includes("not mergeable")) {
console.error("PR has conflicts or failed status checks");
} else if (error.message.includes("not found")) {
console.error("PR does not exist");
} else {
console.error("Failed to merge PR:", error.message);
}
}
```

## Notes

- **No agent or sandbox required**: This method only needs GitHub configuration
- The method requires appropriate GitHub permissions (write access to the repository)
- Branch protection rules will be enforced
- The merge will respect all repository settings and requirements
- After a successful merge, the source branch may be automatically deleted depending on repository settings
- This is a direct GitHub API call - no code execution or AI processing is involved

## Related Methods

- [`createPullRequest`](/api-reference/create-pull-request) - Create a new pull request
- [`pushToBranch`](/api-reference/push-to-branch) - Push changes to a branch
- [`generateCode`](/api-reference/generate-code) - Generate code using AI agents
1 change: 1 addition & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"api-reference/generate-code",
"api-reference/execute-command",
"api-reference/create-pull-request",
"api-reference/merge-pull-request",
"api-reference/push-to-branch",
"api-reference/run-tests",
"api-reference/kill-sandbox",
Expand Down
35 changes: 34 additions & 1 deletion docs/sdk/github-integration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,40 @@ const result = await vibeKit.generateCode({
});

await vibeKit.pushToBranch();
```

## Merging Pull Requests

Once a pull request has been reviewed and approved, you can programmatically merge it using the `mergePullRequest` method. This method only requires GitHub configuration - no agent or sandbox needed:

```typescript
// Create a simple VibeKit instance with just GitHub config
const vibekit = new VibeKit()
.withGithub({
token: process.env.GITHUB_TOKEN,
repository: "myorg/myrepo"
});

// Merge a pull request with default settings (regular merge)
const mergeResult = await vibekit.mergePullRequest({
pullNumber: 42
});

console.log(`PR merged! Commit SHA: ${mergeResult.sha}`);

// Or use squash merge with custom commit message
const squashResult = await vibekit.mergePullRequest({
pullNumber: 42,
mergeMethod: "squash",
commitTitle: "feat: Add user authentication",
commitMessage: "Implemented complete authentication flow with validation"
});
```

This comprehensive GitHub integration allows you to build powerful conversational UIs where users can iteratively request code changes, see them applied in real-time, and create pull requests when they're satisfied with the results.
### Merge Methods

- **`merge`** (default): Creates a merge commit with all commits from the feature branch
- **`squash`**: Squashes all commits into a single commit before merging
- **`rebase`**: Rebases the commits onto the base branch

This comprehensive GitHub integration allows you to build powerful conversational UIs where users can iteratively request code changes, see them applied in real-time, create pull requests, and merge them programmatically when they're satisfied with the results.
68 changes: 68 additions & 0 deletions packages/sdk/src/core/vibekit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import type {
SandboxProvider,
Conversation,
LabelOptions,
MergePullRequestOptions,
MergePullRequestResult,
} from "../types";
import { AGENT_TYPES } from "../constants/agents";
import { AgentResponse, ExecuteCommandOptions, PullRequestResult } from "../agents/base";
Expand Down Expand Up @@ -181,6 +183,72 @@ export class VibeKit extends EventEmitter {
return this.agent.pushToBranch(branch);
}

async mergePullRequest(
options: MergePullRequestOptions
): Promise<MergePullRequestResult> {
const { github } = this.options;

if (!github?.token || !github?.repository) {
throw new Error(
"GitHub configuration is required for merging pull requests. Please use withGithub() to configure GitHub credentials."
);
}

const { pullNumber, commitTitle, commitMessage, mergeMethod = 'merge' } = options;

if (!pullNumber || typeof pullNumber !== 'number') {
throw new Error("Pull request number is required and must be a number");
}

const [owner, repo] = github.repository?.split("/") || [];

if (!owner || !repo) {
throw new Error("Invalid repository URL format. Expected format: owner/repo");
}

// Merge the pull request using GitHub API directly
const mergeResponse = await fetch(
`https://api.github.com/repos/${owner}/${repo}/pulls/${pullNumber}/merge`,
{
method: "PUT",
headers: {
Authorization: `token ${github.token}`,
Accept: "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
"Content-Type": "application/json",
},
body: JSON.stringify({
commit_title: commitTitle,
commit_message: commitMessage,
merge_method: mergeMethod,
}),
}
);

const responseData = await mergeResponse.json();

if (!mergeResponse.ok) {
// Handle specific error cases
if (mergeResponse.status === 404) {
throw new Error(`Pull request #${pullNumber} not found in ${github.repository}`);
} else if (mergeResponse.status === 405) {
throw new Error(`Pull request #${pullNumber} is not mergeable. It may have conflicts or failed status checks.`);
} else if (mergeResponse.status === 422) {
throw new Error(`Invalid merge parameters: ${responseData.message || 'Unknown validation error'}`);
} else {
throw new Error(
`Failed to merge pull request #${pullNumber}: ${mergeResponse.status} ${responseData.message || mergeResponse.statusText}`
);
}
}

return {
sha: responseData.sha,
merged: responseData.merged,
message: responseData.message,
};
}

async runTests(): Promise<any> {
if (!this.agent) {
await this.initializeAgent();
Expand Down
2 changes: 2 additions & 0 deletions packages/sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export type {
VibeKitConfig,
Conversation,
LabelOptions,
MergePullRequestOptions,
MergePullRequestResult,
CodexStreamCallbacks,
ClaudeStreamCallbacks,
OpenCodeStreamCallbacks,
Expand Down
14 changes: 14 additions & 0 deletions packages/sdk/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,20 @@ export interface LabelOptions {
description: string;
}

// MERGE PULL REQUEST OPTIONS
export interface MergePullRequestOptions {
pullNumber: number;
commitTitle?: string;
commitMessage?: string;
mergeMethod?: 'merge' | 'squash' | 'rebase';
}

export interface MergePullRequestResult {
sha: string;
merged: boolean;
message: string;
}

// STREAMING CALLBACKS
export interface CodexStreamCallbacks {
onUpdate?: (message: string) => void;
Expand Down