* ## Summary ✅ Successfully updated the merge functionality in [`backend/src/services/git_service.rs`](file:///private/var/folders/kr/jdxkcn7129j376nrg0stj9zm0000gn/T/vibe-kanban/vk-d113-fix-merge/backend/src/services/git_service.rs#L175-L304) with the following improvements: **Key Changes:** 1. **Worktree-based operations** - All merge operations now happen inside the worktree instead of the main repo 2. **Dirty state check** - Added `check_worktree_clean()` to fail if worktree has uncommitted changes 3. **Base branch checkout** - Automatically checkout base branch (`main`/`master`) before merge 4. **Squash merge** - Implemented squash merge that creates a single commit with all task changes 5. **New error handling** - Added `WorktreeDirty` error type for dirty worktree detection **New Helper Methods:** - `check_worktree_clean()` - Validates clean worktree state - `get_default_branch_name_for_repo()` - Detects base branch name - `checkout_branch()` - Switches to specified branch - `perform_squash_merge()` - Creates squash commit with single parent The merge process now: 1. Opens worktree repository 2. Checks for dirty state (fails if found) 3. Detects and checks out base branch 4. Performs squash merge of task branch into base branch 5. Creates single commit with all changes All changes compile successfully and maintain backward compatibility with existing API. * ## Fix Applied Successfully The merge functionality has been updated to resolve the error you encountered. The key changes: **Root Cause Fixed:** The error occurred because Git doesn't allow the same branch to be checked out in multiple places simultaneously. When the main repository had `main` checked out, the worktree couldn't also checkout `main`. **Solution Implemented:** 1. **Temporary Branch Strategy** - Instead of directly checking out the base branch, create a temporary merge branch from the base branch 2. **Worktree-Safe Operations** - All merge operations now happen within the worktree using temporary branches 3. **Automatic Cleanup** - Temporary branches are automatically deleted after merge completion **Updated Process:** 1. ✅ Check worktree is clean (fail if dirty) 2. ✅ Detect base branch (`main`/`master`) 3. ✅ Create temporary merge branch from base branch 4. ✅ Perform squash merge of task branch into base branch 5. ✅ Update base branch reference to point to squash commit 6. ✅ Clean up temporary branch The merge will now work correctly without the "cannot set HEAD" error, as it avoids the Git limitation by using temporary branches during the merge process. * ## Both Issues Fixed ✅ **Problem 1: Error Display Fixed** Updated [`backend/src/routes/task_attempts.rs`](file:///private/var/folders/kr/jdxkcn7129j376nrg0stj9zm0000gn/T/vibe-kanban/vk-d113-fix-merge/backend/src/routes/task_attempts.rs#L306-L312) to return actual error messages instead of generic "Internal server error". The API now returns a proper JSON response with the error details. ✅ **Problem 2: Gitignored Files Fixed** Updated [`backend/src/services/git_service.rs`](file:///private/var/folders/kr/jdxkcn7129j376nrg0stj9zm0000gn/T/vibe-kanban/vk-d113-fix-merge/backend/src/services/git_service.rs#L231-268) to properly filter the worktree status check. Now only considers actual tracked file changes, ignoring: - Untracked files (`node_modules/`, `dist/`, etc.) - Gitignored files (`Cargo.lock`, etc.) - Files that aren't part of the repository **Key Changes:** - **Error Handling**: Backend now returns structured error responses with actual messages - **Status Filtering**: Uses `git2::StatusOptions` to exclude untracked and ignored files - **Tracked Changes Only**: Only flags modifications to files that are actually tracked by Git You should now see proper error messages in the UI instead of "Internal server error", and the merge won't fail due to gitignored files like `Cargo.lock`, `node_modules/`, or build artifacts. * ## Issues Fixed ✅ **Temporary Branch Issue Resolved** Removed the temporary branch creation/deletion that was causing the error. The merge now works directly with the existing branches without creating intermediate branches that get checked out. ✅ **Base Branch Update Fixed** The squash merge now properly updates the base branch reference to point to the new squash commit, ensuring the changes are actually merged into the base branch. **Key Changes:** 1. **Simplified Flow** - No more temporary branch creation/checkout/deletion 2. **Direct Squash Merge** - Creates squash commit directly and updates base branch reference 3. **Stays on Current Branch** - Worktree remains on whatever branch was checked out 4. **Proper Reference Update** - Base branch reference is updated to point to the squash commit **Fixed Process:** 1. ✅ Check worktree is clean (ignoring gitignored files) 2. ✅ Get base branch and task branch references 3. ✅ Create squash commit with task branch tree and base branch as single parent 4. ✅ Update base branch reference to point to new squash commit 5. ✅ Return commit ID The merge should now work correctly without creating temporary branches and will properly update the base branch with the squashed changes from your task branch. * ## Fixed: Now Using Correct Base Branch ✅ **Correct Base Branch Usage** The merge now correctly uses the `base_branch` field from the TaskAttempt model instead of auto-detecting `main`/`master`. **Key Changes:** 1. **TaskAttempt.base_branch** - Now passed to the GitService merge operation 2. **Updated Method Signatures** - Added `base_branch_name` parameter to merge methods 3. **Removed Auto-Detection** - No longer tries to guess the base branch 4. **Proper Branch Resolution** - Uses the exact base branch specified when the TaskAttempt was created **Fixed Flow:** 1. ✅ Load TaskAttempt from database (includes `base_branch` field) 2. ✅ Pass both task branch name AND base branch name to GitService 3. ✅ Verify both branches exist in worktree 4. ✅ Create squash commit merging task branch into specified base branch 5. ✅ Update the base branch reference (not main/master) The merge will now correctly merge your task branch into whatever base branch was specified when the TaskAttempt was created, whether that's `main`, `develop`, `feature/xyz`, or any other branch. * ## Updated Squash Merge Message Format ✅ **Enhanced Commit Message** The squash merge commit message now includes the task UUID and description in the requested format. **New Format:** ``` [Task Title] (vibe-kanban [FIRST_UUID_SECTION]) [Task Description] ``` **Example Output:** ``` Fix user authentication (vibe-kanban [a1b2c3d4]) Update login flow to support OAuth and handle edge cases for third-party providers ``` **Key Changes:** 1. **Task Title + UUID Section** - First line includes task title with first section of UUID 2. **Task Description** - Added on new line after empty line (if description exists) 3. **UUID Extraction** - Takes first section before first hyphen (e.g., `a1b2c3d4` from `a1b2c3d4-e5f6-7890-1234-567890abcdef`) 4. **Conditional Description** - Only adds description if it exists and is not empty **Updated Method Signatures:** - Added `task_description: &Option<String>` and `task_id: uuid::Uuid` parameters - Flows from TaskAttempt context through to GitService merge operations Your squash merge commits will now have more descriptive and traceable commit messages that clearly identify the task and provide context about what was implemented. * update commit message * fmt * solve clippy * fmt
Get 10X more out of Claude Code, Gemini CLI, Codex, Amp and other coding agents...
Overview
AI coding agents are increasingly writing the world's code and human engineers now spend the majority of their time planning, reviewing, and orchestrating tasks. Vibe Kanban streamlines this process, enabling you to:
- Easily switch between different coding agents
- Orchestrate the execution of multiple coding agents in parallel or in sequence
- Quickly review work and start dev servers
- Track the status of tasks that your coding agents are working on
- Centralise configuration of coding agent MCP configs
You can watch a video overview here.
Installation
Make sure you have authenticated with your favourite coding agent. A full list of supported coding agents can be found in the docs. Then in your terminal run:
npx vibe-kanban
Documentation
Please head to the website for the latest documentation and user guides.
Support
Please open an issue on this repo if you find any bugs or have any feature requests.
Contributing
We would prefer that ideas and changes are raised with the core team via GitHub issues, where we can discuss implementation details and alignment with the existing roadmap. Please do not open PRs without first discussing your proposal with the team.
Development
Prerequisites
pnpm i
Running the dev server
pnpm run dev
This will start the frontend and backend with live reloading. A blank DB will be copied from the dev_assets_seed folder.
Build from source
- Run
build-npm-package.sh - In the
npx-clifolder runnpm pack - You can run your build with
npx [GENERATED FILE].tgz
Environment Variables
The following environment variables can be configured at build time or runtime:
| Variable | Type | Default | Description |
|---|---|---|---|
GITHUB_CLIENT_ID |
Build-time | Ov23li9bxz3kKfPOIsGm |
GitHub OAuth app client ID for authentication |
POSTHOG_API_KEY |
Build-time | Empty | PostHog analytics API key (disables analytics if empty) |
POSTHOG_API_ENDPOINT |
Build-time | Empty | PostHog analytics endpoint (disables analytics if empty) |
BACKEND_PORT |
Runtime | 0 (auto-assign) |
Backend server port |
FRONTEND_PORT |
Runtime | 3000 |
Frontend development server port |
DISABLE_WORKTREE_ORPHAN_CLEANUP |
Runtime | Not set | Disable git worktree cleanup (for debugging) |
Build-time variables must be set when running pnpm run build. Runtime variables are read when the application starts.
Custom GitHub OAuth App (Optional)
By default, Vibe Kanban uses Bloop AI's GitHub OAuth app for authentication. To use your own GitHub app for self-hosting or custom branding:
- Create a GitHub OAuth App at GitHub Developer Settings
- Enable "Device Flow" in the app settings
- Set scopes to include
user:email,repo - Build with your client ID:
GITHUB_CLIENT_ID=your_client_id_here pnpm run build
