How to Implement Auto-Commit and Auto-PR Workflows with Open Agents

Open Agents provides a complete Git automation pipeline that stages sandbox changes, commits them programmatically, and opens pull requests via the GitHub API without manual intervention.

Open Agents by Vercel Labs ships with a production-ready, end-to-end Git workflow that bridges sandboxed coding sessions and GitHub repositories. This guide explains how to implement auto-commit and auto-PR workflows using the repository's built-in Git flow client, GitHub API integration, and chat UI orchestration layers.

How the Auto-Commit and Auto-PR Architecture Works

The workflow consists of three coordinated layers that handle repository operations, API communication, and UI state management.

The Git-Flow Client

Located in apps/web/lib/git-flow-client.ts, this server-side module exposes commitAndPushSessionChanges, which executes git add . inside the sandbox session, constructs a commit message from UI-provided title and body fields, and runs git commit. When pushing is required, it invokes the Vercel sandbox's pushSessionBranch helper and returns the new commit SHA and message.

The GitHub Client

The apps/web/lib/github/client.ts file provides createPullRequest, which creates a branch reference—or falls back to a user fork if the primary repository rejects direct pushes—and calls the GitHub REST API endpoint POST /repos/:owner/:repo/pulls with the head reference, base branch, title, and body.

The Auto-PR Orchestrator

The apps/web/lib/chat/auto-pr-direct.ts module coordinates the handoff between commit completion and PR creation. It verifies that hasUncommittedGitChanges returns false before invoking createPullRequest, ensuring the working tree is clean. The UI component in git-panel.tsx renders the Commit form first, then automatically displays the Create PR form upon successful commit.

Committing and Pushing Changes Automatically

To implement the commit stage, invoke commitAndPushSessionChanges from your UI or API route with the session identifier and message details.

// apps/web/app/sessions/[sessionId]/chats/[chatId]/git-panel.tsx
const handleCommit = async () => {
  setCommitLoading(true);
  
  const response = await commitAndPushSessionChanges({
    sessionId,
    commitTitle,
    commitBody,
    commitOnly: false, // false triggers push after commit
  });
  
  if (response.error) {
    setCommitError(response.error);
  } else {
    setCommitSuccess({
      commitSha: response.gitActions?.commitSha,
      commitMessage: response.gitActions?.commitMessage,
    });
  }
  
  setCommitLoading(false);
};

Setting commitOnly to false ensures the function pushes the branch to the remote immediately after committing. The response object contains the commit SHA and message for verification.

Creating Pull Requests via the GitHub API

After successfully committing and pushing, create a pull request by calling the GitHub client with repository details and branch references.

// apps/web/lib/chat/auto-pr-direct.ts
export async function maybeCreatePullRequest({
  sessionId,
  branch,
  baseBranch,
  title,
  body,
}: {
  sessionId: string;
  branch: string;
  baseBranch: string;
  title: string;
  body: string;
}) {
  // Guard: prevent PR creation with uncommitted changes
  const status = await getGitStatus({ sessionId });
  if (status.hasUncommittedGitChanges) {
    throw new Error("Commit your changes before creating a PR.");
  }

  const result = await createPullRequest({
    repoOwner: process.env.GITHUB_OWNER!,
    repoName: process.env.GITHUB_REPO!,
    head: branch,
    base: baseBranch,
    title,
    body,
  });

  return result;
}

The createPullRequest function handles branch creation, permission validation, and fork fallback logic automatically.

Exposing Server-Side Endpoints

Wrap the GitHub client in an API route to expose PR creation to the frontend securely.

// apps/web/app/api/pr/route.ts
export async function POST(req: Request) {
  const { sessionId, title, body, base } = await req.json();
  
  const result = await createPullRequest({
    repoOwner: process.env.GITHUB_OWNER!,
    repoName: process.env.GITHUB_REPO!,
    head: `session-${sessionId}`,
    base,
    title,
    body,
  });
  
  return Response.json(result);
}

This endpoint reads repository configuration from environment variables and targets a branch named using the session identifier.

Safety Mechanisms and Fallback Strategies

Open Agents implements several safeguards to handle repository restrictions and transient failures.

Uncommitted Change Guard: The UI disables the PR creation button until hasUncommittedGitChanges returns false, preventing pull requests that reference dirty working trees.

Fork Fallback: When createPullRequest encounters a protected repository that rejects direct pushes, it automatically creates a user fork, pushes the branch to the fork, and opens a PR from forkOwner:branch. This logic is documented in docs/agents/lessons-learned.md.

Retry Logic: If GitHub returns "repository not found" immediately after fork creation due to replication latency, the client retries the push operation multiple times before surfacing a manual fallback URL.

Auto-Merge Support: After PR creation, you can invoke mergePullRequest (also available in apps/web/lib/github/client.ts) to automatically merge when CI checks pass, passing the preferred merge_method (merge, squash, or rebase) to the GitHub API.

Summary

  • Open Agents automates the full Git lifecycle from sandbox to pull request through three coordinated layers.
  • commitAndPushSessionChanges in apps/web/lib/git-flow-client.ts handles staging, committing, and pushing session changes.
  • createPullRequest in apps/web/lib/github/client.ts manages branch creation, API calls, and fork fallback for protected repositories.
  • auto-pr-direct.ts orchestrates the workflow, enforcing the guard that hasUncommittedGitChanges must be false before PR creation.
  • Safety mechanisms include fork fallback for upstream repos, retry logic for transient GitHub errors, and UI guards that prevent premature PR creation.

Frequently Asked Questions

How does Open Agents handle protected branches that disallow direct pushes?

When the primary repository rejects branch pushes due to protection rules, createPullRequest in apps/web/lib/github/client.ts automatically falls back to creating a user-owned fork. It pushes the session branch to the fork and opens the pull request from forkOwner:branch, handling the latency and permission edge cases documented in docs/agents/lessons-learned.md.

What prevents the system from creating a pull request with uncommitted changes?

The maybeCreatePullRequest function in apps/web/lib/chat/auto-pr-direct.ts explicitly checks the session's Git status via getGitStatus and throws an error if hasUncommittedGitChanges is true. Additionally, the UI component git-panel.tsx disables the Create PR button until the commit step succeeds and returns a success state.

Can I customize commit messages and merge strategies programmatically?

Yes. Pass commitTitle and commitBody parameters to commitAndPushSessionChanges to override default messages. For merge strategies, the mergePullRequest function accepts a merge_method parameter that maps directly to GitHub's API options (merge, squash, or rebase), allowing you to enforce repository-specific policies.

Which environment variables are required to enable auto-commit and auto-PR workflows?

The workflow requires GITHUB_OWNER and GITHUB_REPO environment variables to specify the target repository, along with appropriate GitHub App credentials for authentication. The API route in apps/web/app/api/pr/route.ts references these variables to construct the repository context for createPullRequest calls.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →