* Perfect! I've successfully implemented the Shift+Tab keyboard shortcut to cycle between agent configurations. Here's a summary of the changes:
Added Shift+Tab keyboard shortcut to cycle through agent configuration variants when editing the follow-up textbox.
1. **TaskFollowUpSection.tsx** (frontend/src/components/tasks/TaskFollowUpSection.tsx:125-136, 400)
- Added `cycleVariant` function that cycles to the next variant in the current profile
- Passed `onShiftTab={cycleVariant}` to `FollowUpEditorCard`
2. **FollowUpEditorCard.tsx** (frontend/src/components/tasks/follow-up/FollowUpEditorCard.tsx:17, 31, 50)
- Added `onShiftTab?: () => void` prop to component interface
- Passed through to `FileSearchTextarea`
3. **file-search-textarea.tsx** (frontend/src/components/ui/file-search-textarea.tsx:25, 40, 294)
- Added `onShiftTab?: () => void` prop to component interface
- Passed through to `AutoExpandingTextarea`
4. **auto-expanding-textarea.tsx** (frontend/src/components/ui/auto-expanding-textarea.tsx:8, 21, 62-65, 77)
- Added `onShiftTab?: () => void` prop to component interface
- Implemented Shift+Tab handler in `handleKeyDown` that prevents default behavior and calls the callback
- Added to useCallback dependencies
- When the user presses **Shift+Tab** while editing the follow-up textbox, it cycles to the next agent configuration variant
- The `VariantSelector` component already has bump animation implemented (TaskFollowUpSection.tsx line 23-30 in VariantSelector.tsx) which will trigger on variant change
- The shortcut only works when the textbox is editable and active
The fix ensures that when `selectedVariant` is `null`, the first press of Shift+Tab will explicitly set the variant to the first one in the list (index 0), making the cycling work correctly from the start.
Perfect! I've updated the `cycleVariant` function to treat "DEFAULT" as a regular variant in the cycle. Here's what the fix does:
**The fix ensures that:**
1. When `selectedVariant` is `null`, it's treated as `"DEFAULT"` for lookup purposes
2. All variants including "DEFAULT" are included in the cycling
3. The cycle works: DEFAULT → variant1 → variant2 → ... → DEFAULT
4. When cycling lands on "DEFAULT", it converts back to `null` (since that's what the backend/API expects)
**Why this works:**
- First press from `null` (DEFAULT): Cycles to the first non-DEFAULT variant ✓
- Provides keyboard access to cycle back to DEFAULT ✓
- Treats "DEFAULT" as what it truly is: a configured variant, not a special case ✓
- No hacky filters or special-casing needed ✓
The implementation is clean and treats "DEFAULT" as a first-class variant in the cycling logic, while maintaining the existing API contract where `null` represents DEFAULT.
Perfect! Now the Shift+Tab interception only happens when `onShiftTab` is actually provided. This ensures:
1. **Follow-up text box**: Shift+Tab cycles through variants (has `onShiftTab` handler)
2. **All other textareas**: Shift+Tab works normally for browser focus navigation (no `onShiftTab` handler)
The fix preserves the default browser behavior for all existing uses of `AutoExpandingTextarea` while enabling the variant cycling feature only where it's needed.
Refactor keyboard shortcuts (vibe-kanban 67d268cf)
We did this in the last 4 commits:
Add a shortcut to cycle between agent configurations (previously called profile variants) when typing a follow up. Should be active when the user is editing the follow-up text box.
User shift tab to trigger the shortcut.
However this doesnt use the current pattern we want to use for shortcuts. Figure out the correct way and migrate.
Refactor keyboard shortcuts (vibe-kanban 4d35f44f)
Your colleague already handled one:
Refactoring Summary
The Shift+Tab shortcut was refactored from a prop-drilling approach (passing onShiftTab through multiple components) to the centralized keyboard system using the semantic hook pattern. The new implementation:
Registered the shortcut in registry.ts as CYCLE_VARIANT action bound to shift+tab in the FOLLOW_UP scope
Created a semantic hook useKeyCycleVariant for type-safe usage
Used scope management with enableScope(Scope.FOLLOW_UP) to control when the shortcut is active (only when textarea is focused AND editable)
Removed prop drilling - deleted onShiftTab props from FollowUpEditorCard, FileSearchTextarea, and AutoExpandingTextarea
Pattern for other shortcuts: Add the action/keys to registry.ts, create a semantic hook in hooks.ts, use the hook in your component with appropriate scope, and manage scope activation with enableScope/disableScope based on when the feature should be available. The when clause is only for additional runtime conditions beyond what scope controls.
Can we mirgate the rest of the shortcuts in frontend/src/components/tasks/TaskFollowUpSection.tsx
Fix shortcut regressions (vibe-kanban c07e229f)
To‑Do For Shortcuts
Restore submit shortcut in task dialog (frontend/src/components/dialogs/tasks/TaskFormDialog.tsx:491): reintroduce Cmd+Enter / Cmd+Shift+Enter when focus is in the description FileSearchTextarea. Prefer the new keyboard system—add a semantic hook (likely useKeySubmitTask) scoped appropriately, or, if we don’t have one yet, bind via useKeySubmit while the dialog is active. The binding must only be enabled when the form can submit and the textarea is focused.
Re-enable Cmd+Enter save in inline review comments (frontend/src/components/diff/CommentWidgetLine.tsx:69): same story—bring back the shortcut using our keyboard hooks so reviewers can submit without leaving the textarea.
Fix FileSearchTextarea event propagation (frontend/src/components/ui/file-search-textarea.tsx:12, :235): the component still lists onKeyDown but never calls it. Destructure onKeyDown from props and invoke it at the end of handleKeyDown so parent components can layer their own key handling again.
Fix shortcut regressions (vibe-kanban c07e229f)
To‑Do For Shortcuts
Restore submit shortcut in task dialog (frontend/src/components/dialogs/tasks/TaskFormDialog.tsx:491): reintroduce Cmd+Enter / Cmd+Shift+Enter when focus is in the description FileSearchTextarea. Prefer the new keyboard system—add a semantic hook (likely useKeySubmitTask) scoped appropriately, or, if we don’t have one yet, bind via useKeySubmit while the dialog is active. The binding must only be enabled when the form can submit and the textarea is focused.
Re-enable Cmd+Enter save in inline review comments (frontend/src/components/diff/CommentWidgetLine.tsx:69): same story—bring back the shortcut using our keyboard hooks so reviewers can submit without leaving the textarea.
Fix FileSearchTextarea event propagation (frontend/src/components/ui/file-search-textarea.tsx:12, :235): the component still lists onKeyDown but never calls it. Destructure onKeyDown from props and invoke it at the end of handleKeyDown so parent components can layer their own key handling again.
Fmt
* Perfect! I've added the `isComposing` check to `useKeyboardShortcut.ts` at line 68. This fix ensures that:
## What Was Fixed
The `isComposing` check that was lost during the rebase has been restored, but in the new architecture's proper location:
**Before the rebase (old architecture):**
- Each component (`AutoExpandingTextarea`, `Input`) had its own keyboard handlers
- The `isComposing` check was added to these handlers: `if (e.key === 'Enter' && !e.nativeEvent.isComposing)`
**After the rebase (new architecture):**
- All keyboard shortcuts centralized through `useKeyboardShortcut.ts` → `react-hotkeys-hook`
- The check needed to move to the central handler
**The fix:**
- Added `if (event.isComposing) return;` at line 68 in `useKeyboardShortcut.ts`
- This protects **all** keyboard shortcuts (not just Enter) from firing during IME composition
- Covers all actions: `SUBMIT_FOLLOW_UP`, `SUBMIT_TASK`, `CYCLE_VARIANT`, etc.
## Impact
Now when users input text using IME (Japanese, Chinese, Korean, etc.):
- Pressing Enter to confirm text conversion won't accidentally trigger shortcuts
- Pressing Shift+Tab during composition won't cycle variants
- All keyboard shortcuts properly respect IME composition state
This is actually **better** than the old fix because it applies universally to all shortcuts, not just the ones that were manually checked before.
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
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. A blank DB will be copied from the dev_assets_seed folder.
Building the frontend
To build just the frontend:
cd frontend
pnpm build
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 |
HOST |
Runtime | 127.0.0.1 |
Backend server host |
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
