* feat(conversation): add turn navigation popover for jumping to user messages
Replace the single "scroll to previous message" button with a popover
that lists all user messages as numbered turns. Clicking a turn scrolls
the conversation to that message. Follows the TodoProgressPopup pattern
using Radix Popover with ListNumbersIcon trigger.
- New TurnNavigationPopup component in packages/ui
- Add scrollToEntryByPatchKey to ConversationListHandle
- Derive userMessageTurns from EntriesContext in SessionChatBoxContainer
- Wire through WorkspacesMain, VSCode, and Kanban sidebar callers
- Incidental formatting changes from pnpm run format
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(conversation): show turn navigation on hover of scroll-to-previous button
Restore the ArrowUp "scroll to previous message" button as the primary
visible control, and show the turn navigation list as a hover popover
over it instead of replacing it entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: apply formatter to web-core files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(conversation): highlight currently viewed message in turn navigation
Query the scroll position to determine which user message is currently
visible when the turn navigation popover opens, and highlight it with
brand-colored styling. The list also scrolls to center the active turn
rather than always scrolling to the bottom.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: fix Prettier formatting in SessionChatBox
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: fix remaining Prettier indentation in SessionChatBox
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: fix Prettier formatting using packages/ui config
The root and packages/ui Prettier configs disagree on indentation
inside Boolean(). Use the packages/ui formatting since CI checks
run from that directory.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: fix SessionChatBox quotes to match singleQuote Prettier config
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: fix SessionChatBox formatting with packages/ui Prettier 3.6.1
Use pnpm --filter @vibe/ui run format to match CI's exact Prettier
version and config.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(conversation): address review feedback on turn navigation
- Prevent PopoverTrigger click from toggling popover (hover-only open)
- Add releaseBottomLock() before scrollToEntryByPatchKey to prevent
snap-back when navigating from conversation bottom
- Wire getActiveTurnPatchKey through VSCode and Kanban sidebar callers
- Use useLayoutEffect for popover scroll to avoid paint flash
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: fix Prettier formatting in VSCode and Kanban sidebar containers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(conversation): allow Escape and outside-click to dismiss turn popover
Restore onOpenChange on the controlled Popover but only allow close
events (not open), so Escape key and clicking outside properly dismiss
the popover while still preventing click-to-toggle on the trigger.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(conversation): use manual scrollTop instead of scrollIntoView in turn nav
scrollIntoView({ block: 'center' }) can scroll ancestor containers,
disrupting the main conversation scroll position. Use manual offsetTop
calculation to scroll only the popover's internal list.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Revert "fix(conversation): use manual scrollTop instead of scrollIntoView in turn nav"
This reverts commit 8ea5171eb8.
* fix(conversation): use list-relative scrollTop for turn nav popover
Replace scrollIntoView() with manual scrollTop calculation using
offsetTop relative to the list container. This avoids scrolling
ancestor containers while correctly centering the active turn.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(conversation): use correction loop for turn nav scroll
scrollToEntryByPatchKey previously used a single smooth scroll call
which was unreliable with virtualized rows (estimated sizes) and
caused the active turn highlight to be wrong on re-hover (viewport
queried before smooth scroll completes).
Use the same instant-scroll + requestAnimationFrame correction loop
pattern as scrollToPreviousUserMessage for accurate positioning.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(conversation): address turn nav scroll and highlight issues
- scrollToEntryByPatchKey: use scrollToAbsoluteIndex for initial scroll
which correctly handles both virtualized and unvirtualized tail rows,
then run rAF correction loop for size-estimate adjustments.
- TurnNavigationPopup: track last navigated patchKey so that if
mouseenter re-fires before the scroll correction loop finishes,
the highlight reflects the just-clicked turn rather than stale
viewport state. Cleared on next open to resume viewport detection.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Get 10X more out of Claude Code, Gemini CLI, Codex, Amp and other coding agents...
We're hiring!
Overview
In a world where software engineers spend most of their time planning and reviewing coding agents, the most impactful way to ship more is to get faster at planning and review.
Vibe Kanban is built for this. Use kanban issues to plan work, either privately or with your team. When you're ready to begin, create workspaces where coding agents can execute.
- Plan with kanban issues — create, prioritise, and assign issues on a kanban board
- Run coding agents in workspaces — each workspace gives an agent a branch, a terminal, and a dev server
- Review diffs and leave inline comments — send feedback directly to the agent without leaving the UI
- Preview your app — built-in browser with devtools, inspect mode, and device emulation
- Switch between 10+ coding agents — Claude Code, Codex, Gemini CLI, GitHub Copilot, Amp, Cursor, OpenCode, Droid, CCR, and Qwen Code
- Create pull requests and merge — open PRs with AI-generated descriptions, review on GitHub, and merge
One command. Describe the work, review the diff, ship it.
npx vibe-kanban
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
Head to the website for the latest documentation and user guides.
Self-Hosting
Want to host your own Vibe Kanban Cloud instance? See our self-hosting guide.
Support
We use GitHub Discussions for feature requests. Please open a discussion to create a feature request. For bugs please open an issue on this repo.
Contributing
We would prefer that ideas and changes are first raised with the core team via GitHub Discussions or Discord, 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
Additional development tools:
cargo install cargo-watch
cargo install sqlx-cli
Install dependencies:
pnpm i
Running the dev server
pnpm run dev
This will start the backend and web app. A blank DB will be copied from the dev_assets_seed folder.
Building the web app
To build just the web app:
cd packages/local-web
pnpm run build
Build from source (macOS)
- Run
./local-build.sh - Test with
cd npx-cli && node bin/cli.js
Environment Variables
The following environment variables can be configured at build time or runtime:
| Variable | Type | Default | Description |
|---|---|---|---|
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) |
PORT |
Runtime | Auto-assign | Production: Server port. Dev: Frontend port (backend uses PORT+1) |
BACKEND_PORT |
Runtime | 0 (auto-assign) |
Backend server port (dev mode only, overrides PORT+1) |
FRONTEND_PORT |
Runtime | 3000 |
Frontend dev server port (dev mode only, overrides PORT) |
HOST |
Runtime | 127.0.0.1 |
Backend server host |
MCP_HOST |
Runtime | Value of HOST |
MCP server connection host (use 127.0.0.1 when HOST=0.0.0.0 on Windows) |
MCP_PORT |
Runtime | Value of BACKEND_PORT |
MCP server connection port |
DISABLE_WORKTREE_CLEANUP |
Runtime | Not set | Disable all git worktree cleanup including orphan and expired workspace cleanup (for debugging) |
VK_ALLOWED_ORIGINS |
Runtime | Not set | Comma-separated list of origins that are allowed to make backend API requests (e.g., https://my-vibekanban-frontend.com) |
VK_SHARED_API_BASE |
Runtime | Not set | Base URL for the remote/cloud API used by the local desktop app |
VK_SHARED_RELAY_API_BASE |
Runtime | Not set | Base URL for the relay API used by tunnel-mode connections |
VK_TUNNEL |
Runtime | Not set | Enable relay tunnel mode when set (requires relay API base URL) |
Build-time variables must be set when running pnpm run build. Runtime variables are read when the application starts.
Self-Hosting with a Reverse Proxy or Custom Domain
When running Vibe Kanban behind a reverse proxy (e.g., nginx, Caddy, Traefik) or on a custom domain, you must set the VK_ALLOWED_ORIGINS environment variable. Without this, the browser's Origin header won't match the backend's expected host, and API requests will be rejected with a 403 Forbidden error.
Set it to the full origin URL(s) where your frontend is accessible:
# Single origin
VK_ALLOWED_ORIGINS=https://vk.example.com
# Multiple origins (comma-separated)
VK_ALLOWED_ORIGINS=https://vk.example.com,https://vk-staging.example.com
Remote Deployment
When running Vibe Kanban on a remote server (e.g., via systemctl, Docker, or cloud hosting), you can configure your editor to open projects via SSH:
- Access via tunnel: Use Cloudflare Tunnel, ngrok, or similar to expose the web UI
- Configure remote SSH in Settings → Editor Integration:
- Set Remote SSH Host to your server hostname or IP
- Set Remote SSH User to your SSH username (optional)
- Prerequisites:
- SSH access from your local machine to the remote server
- SSH keys configured (passwordless authentication)
- VSCode Remote-SSH extension
When configured, the "Open in VSCode" buttons will generate URLs like vscode://vscode-remote/ssh-remote+user@host/path that open your local editor and connect to the remote server.
See the documentation for detailed setup instructions.

