* fix remote branch detection and worktree interactions
Refactor GitService to improve remote handling and branch management
fix: update branch selection logic to include all branches and improve condition checks
* Clippy, fmt
* Fix branch upstream setting in GitService to handle non-remote branches
* Remove force push from refspec in GitService to prevent non-fast-forward updates
* Add error handling for diverged branches in GitService
* Fix base-branch normalization robust for PRs
---------
Co-authored-by: Solomon <abcpro11051@disroot.org>
* Allow multiple merge for a single task attempt
Merge more than once (vibe-kanban 618829fc)
When creating a PR, new changes can be pushed after creation.
We need merge to work the same way, when changes have been made after the first merge, a second one should work.
Commit changes from coding agent for task attempt 548ff450-df77-47b2-a5ba-c88d0aa4a334
Merge more than once (vibe-kanban 618829fc)
When creating a PR, new changes can be pushed after creation.
We need merge to work the same way, when changes have been made after the first merge, a second one should work.
Remove pinned todo list (vibe-kanban cc66cda2)
Make a minimal change to remove the pinned todo list from the frontend
Remove pinned todo list (vibe-kanban cc66cda2)
Make a minimal change to remove the pinned todo list from the frontend
* Create merges table; remove task_attempt.merge_commit
Add merge model, replace ta.merge_commit with m.merge_commit
Fix frontend
* Move PR to merges table
* Refactor GitHub repository info retrieval to return structured data
* Fix frontend
* Reset task branch after PR merge
Add branch status handling to TaskDetailsProvider and related components
fmt
Add branch status handling to TaskDetailsProvider and related components
fmt
Test (vibe-kanban 1bf1a80f)
add test.txt
Show merged diff when no worktree present
Refresh branch status after PR creation
Test (vibe-kanban 1bf1a80f)
add test.txt
Test (vibe-kanban 1bf1a80f)
add test.txt
Show rebase when behind
Refactor container service to check if the container is clean before showing merged diff; remove unused BranchStatus import
Test (vibe-kanban a3c1b297)
add test.txt
Refactor branch status handling: rename BranchStatusResponse to BranchStatus and update related types and usages
Test (vibe-kanban) (#540)
* Remove test.txt
* Test (vibe-kanban aade357e)
add test.txt
* test.txt removed.
* Fix diff when merged and new commits have been made
* Remvoe logging (vibe-kanban) (#541)
* Test (vibe-kanban aade357e)
add test.txt
* Test (vibe-kanban aade357e)
add test.txt
* Perfect! I've successfully removed the "Fetching branch status" logging statement from the code. The logging has been removed from `crates/server/src/routes/task_attempts.rs:568-571`.
* Clear previous errors on successful PR creation, push, merge, and rebase actions
* Show branch in worktree dirty error message
* Add success indicators for push and merge actions in CurrentAttempt
* Refactor status display logic in CurrentAttempt for improved readability and maintainability
* Add target_branch_name to merge models and queries for direct and PR merges
* Enhance merge status display logic in CurrentAttempt for better clarity on direct merges
* Remove unnecessary condition check in attempt data fetching interval
* Clippy
* Add index for task_attempt_id in merges table to improve query performance
* Pass PR creation error
* Disable buttons (vibe-kanban 240346bf)
Instead of not showing the merge/pr buttons when theyre not available we should disable them. frontend/src/components/tasks/Toolbar/CurrentAttempt.tsx
* Perfect! The implementation is complete and passes all checks.
## Summary
Added browser window close protection to prevent data loss when users have unsaved changes in the task dialog:
- **Added `beforeunload` event listener** in [`TaskFormDialog.tsx`](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-f59b-don-t-let/frontend/src/components/tasks/TaskFormDialog.tsx#L95-L111)
- **Integrates with existing `hasUnsavedChanges()` logic** - no duplication
- **Only active when dialog is open AND has unsaved content**
- **Automatic cleanup** when dialog closes or changes are saved
- **Browser-standard confirmation dialog** appears when user tries to close tab/window
The feature now protects against data loss from both dialog close (existing) and browser window close (new) scenarios.
* Cleanup script changes for task attempt f59bea00-6158-4cdd-ad19-1f30e40c1324
* Perfect! Now the browser window close protection works for both scenarios:
## Updated Implementation
**Create mode:** Warns when user has entered title or description content
**Edit mode:** Warns when user has modified title, description, or status from original values
The `beforeunload` event will now trigger when:
- **Creating a task** and typing content, then trying to close browser
- **Editing a task** and changing any field, then trying to close browser
Both the existing dialog close warning and new browser window close warning now protect against data loss in all editing scenarios.
* Cleanup script changes for task attempt f59bea00-6158-4cdd-ad19-1f30e40c1324
* ## Summary
Fixed the string slicing panic in [crates/local-deployment/src/container.rs](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-0ec9-summary-er/crates/local-deployment/src/container.rs#L1106-L1118). The issue was at line 1109 where `&summary[..summary.len().min(100)]` used byte-based slicing, causing a panic when byte index 100 fell inside the multi-byte UTF-8 character ✨.
**Solution implemented:**
- Replaced byte-based slicing with character-aware slicing using `char_indices()`
- The fix ensures slicing only occurs at valid UTF-8 character boundaries
- No allocation overhead - uses the Oracle-recommended approach with string slices
The code now safely truncates to the first 100 Unicode characters (or end of string if shorter) without risking panics on multi-byte characters.
* Fixed. Removed the problematic debug log entirely from the [`update_executor_session_summary` function](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-0ec9-summary-er/crates/local-deployment/src/container.rs#L1105-L1106). This eliminates the UTF-8 string slicing panic without adding complexity.
* ## Implementation Complete ✅
I've successfully implemented the feature to skip running cleanup scripts when no changes are made during coding agent execution.
### **Changes Made**
1. **Modified [`GitService::commit()`](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-92b8-skip-runni/crates/services/src/services/git.rs#L174-L218)**:
- Changed return type from `Result<(), GitServiceError>` to `Result<bool, GitServiceError>`
- Returns `Ok(false)` when no changes to commit
- Returns `Ok(true)` when changes are committed
2. **Updated [`Container` trait](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-92b8-skip-runni/crates/services/src/services/container.rs#L125)**:
- Changed `try_commit_changes()` signature to return `Result<bool, ContainerError>`
3. **Updated [`LocalContainerService`](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-92b8-skip-runni/crates/local-deployment/src/container.rs#L889-L954)**:
- Modified implementation to propagate commit feedback
- Returns `false` for non-commit operations, `true`/`false` based on git changes
4. **Enhanced [execution monitor logic](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-92b8-skip-runni/crates/local-deployment/src/container.rs#L335-L374)**:
- Conditionally calls `try_start_next_action()` based on whether changes were committed
- Skips cleanup script when coding agent made no changes
- Preserves existing behavior for setup scripts (always proceed to coding agent)
- Added informative logging when cleanup is skipped
### **Behavior**
**Before:**
```
CodingAgent (no changes) → try_commit_changes() → CleanupScript (always runs)
```
**After:**
```
CodingAgent (no changes) → try_commit_changes() returns false → Skip CleanupScript ✅
CodingAgent (has changes) → try_commit_changes() returns true → CleanupScript runs ✅
```
### **Safety Features**
- **Conservative error handling**: Commit failures are treated as "changes made" to ensure cleanup runs
- **Preserved workflows**: Setup scripts always proceed to coding agent (unchanged)
- **Informative logging**: Clear indication when cleanup is skipped
- **Type safety**: Compiler enforces correct return types throughout the call chain
### **Verification**
- ✅ Code compiles successfully
- ✅ All existing tests pass (47/47)
- ✅ Type checker passes
- ✅ No breaking changes to other parts of the codebase
The implementation is complete and ready for use!
* Cleanup script changes for task attempt 92b80e80-dbc1-470c-a3c8-172c38549b61
* Cleanup script changes for task attempt 92b80e80-dbc1-470c-a3c8-172c38549b61
* ## Task Status Fix Complete ✅
I've successfully fixed the issue where tasks weren't transitioning from `InProgress` to `InReview` when cleanup scripts are skipped.
### **Changes Made**
1. **Created [`finalize_task()` helper method](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-92b8-skip-runni/crates/local-deployment/src/container.rs#L116-L128)**:
```rust
async fn finalize_task(
db: &DBService,
config: &Arc<RwLock<Config>>,
ctx: &ExecutionContext,
) {
// Updates task status to InReview
// Sends notifications via NotificationService
}
```
2. **Added manual finalization when skipping cleanup** ([lines 389-391](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-92b8-skip-runni/crates/local-deployment/src/container.rs#L389-L391)):
```rust
} else {
tracing::info!("Skipping cleanup script - no changes made by coding agent");
// Manually finalize task since we're bypassing normal execution flow
Self::finalize_task(&db, &config, &ctx).await;
}
```
3. **Refactored existing finalization** to use the helper method ([line 395](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-92b8-skip-runni/crates/local-deployment/src/container.rs#L395-L397)):
```rust
if Self::should_finalize(&ctx) {
Self::finalize_task(&db, &config, &ctx).await;
}
```
### **Fixed Flow**
**Before (Broken):**
```
CodingAgent (no changes) → Skip cleanup → should_finalize() = false → Task stuck in InProgress ❌
```
**After (Fixed):**
```
CodingAgent (no changes) → Skip cleanup → Manual finalize_task() → Task → InReview ✅
CodingAgent (has changes) → Cleanup runs → should_finalize() = true → Task → InReview ✅
```
### **Benefits**
- ✅ **Fixes the bug**: Tasks now properly transition to `InReview` when cleanup is skipped
- ✅ **DRY principle**: Reuses finalization logic instead of duplicating
- ✅ **No double finalization**: Helper is idempotent and safely reusable
- ✅ **Preserves notifications**: Same notification behavior as normal cleanup completion
- ✅ **Clean separation**: `should_finalize()` logic unchanged for normal flows
### **Verification**
- ✅ Code compiles successfully
- ✅ All tests pass (47/47)
- ✅ Type checker passes
- ✅ Same finalization behavior for both paths
The complete feature is now implemented: cleanup scripts are skipped when no changes are made during coding agent execution, AND tasks properly transition to `InReview` status in both scenarios!
* Cleanup script changes for task attempt 92b80e80-dbc1-470c-a3c8-172c38549b61
* ## UI Copy Updates Complete ✅
I've successfully updated the project settings UI to clearly communicate that the cleanup script only runs when changes are made by the coding agent.
### **Changes Made**
1. **Updated description text** in [`project-form-fields.tsx`](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-92b8-skip-runni/frontend/src/components/projects/project-form-fields.tsx#L249-L253):
```diff
- This script will run after coding agent execution is complete.
+ This script runs after coding agent execution only if changes were made.
+ Use it for quality assurance tasks like running linters, formatters, tests,
+ or other validation steps. If no changes are made, this script is skipped.
```
2. **Updated Unix placeholder** in [`script-placeholders.ts`](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-92b8-skip-runni/frontend/src/utils/script-placeholders.ts#L36-L38):
```diff
- # This runs after coding agent execution
+ # This runs after coding agent execution - only if changes were made
```
3. **Updated Windows placeholder** in [`script-placeholders.ts`](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/vk-92b8-skip-runni/frontend/src/utils/script-placeholders.ts#L20-L22):
```diff
- REM This runs after coding agent execution
+ REM This runs after coding agent execution - only if changes were made
```
### **User Experience**
Now when users configure a cleanup script in project settings, they will see:
**Label**: "Cleanup Script (Optional)"
**Description**:
> This script runs after coding agent execution **only if changes were made**. Use it for quality assurance tasks like running linters, formatters, tests, or other validation steps. If no changes are made, this script is skipped.
**Placeholder text**:
```bash
#!/bin/bash
# Add cleanup commands here...
# This runs after coding agent execution - only if changes were made
```
### **Benefits**
- ✅ **Clear expectations**: Users understand the conditional behavior upfront
- ✅ **Emphasized condition**: "only if changes were made" is bolded for visibility
- ✅ **Comprehensive coverage**: Updated both description and placeholder text
- ✅ **Cross-platform**: Updated both Unix and Windows placeholders
- ✅ **TypeScript verified**: Frontend code compiles successfully
Users will now have clear visibility into when their cleanup scripts will and won't run, preventing any confusion about the new conditional execution behavior!
* Cleanup script changes for task attempt 92b80e80-dbc1-470c-a3c8-172c38549b61
* Commit changes from coding agent for task attempt 66756e53-531f-4155-88cf-079c19c69bc2
* Cleanup script changes for task attempt 66756e53-531f-4155-88cf-079c19c69bc2
* Commit changes from coding agent for task attempt 66756e53-531f-4155-88cf-079c19c69bc2
* give user instruction to resolve manually
* feat: allow pushing updates to open PRs (#470)
PR push after creation (vibe-kanban c22efac9)
In the last commit, we added the ability to push new changes after a PR has been created. Is there a good way to only show this if there are actually new changes?
feat: allow pushing updates to open PRs (#470)
Commit changes from coding agent for task attempt 771ed0db-8c90-4556-b732-5888b665c42b
refactor: simplify unpushed commits check by focusing on origin/branch_name
PR creation review (vibe-kanban 89c2ecdd)
In the last two commits, we added the ability to push new changes after a PR has been created.
Please review this and explain potential shortcomings
* Fix git push frontend
* Use GitService provided by deployment
* Fix ssh auth failing blocking BranchStatus request
* Fix refspec
* Fix frontend to reflect disconnected
* Cleanup script changes for task attempt caee75ee-8c4c-43fd-9956-925a7c66eb23
* Fix session ID retrieval in follow-up function
- Add find_latest_by_task_attempt_and_run_reason_with_session_id method to ExecutionProcess
- Update follow_up function to get latest execution process that already has session_id
- Prevents failures when latest process doesn't have session_id yet
- Uses JOIN query to guarantee session_id exists before proceeding
Amp-Thread: https://ampcode.com/threads/T-f343662d-4028-4c52-8eb4-37393dc759ae
Co-authored-by: Amp <amp@ampcode.com>
* Cleanup script changes for task attempt caee75ee-8c4c-43fd-9956-925a7c66eb23
* sqlx
* cleanup
* Optimize session ID retrieval with single SQL query
- Add ExecutionProcessWithSessionId struct for combined query results
- Replace two-query approach with find_latest_with_session_id method
- Reduce database round-trips from 2 to 1 for follow-up requests
- Remove unused ExecutorSession import
- Maintain same functionality with 50% fewer DB queries
Amp-Thread: https://ampcode.com/threads/T-f343662d-4028-4c52-8eb4-37393dc759ae
Co-authored-by: Amp <amp@ampcode.com>
* Cleanup script changes for task attempt caee75ee-8c4c-43fd-9956-925a7c66eb23
* Commit changes from coding agent for task attempt caee75ee-8c4c-43fd-9956-925a7c66eb23
* Cleanup script changes for task attempt caee75ee-8c4c-43fd-9956-925a7c66eb23
* fmt
---------
Co-authored-by: Amp <amp@ampcode.com>
* wip: backend todo normalisation
* fe implementation
* remove unused dep
* cursor return ActionType::TodoManagement
* use lucide icons rather than emojis in the todo list
* review comments
* edit profiles.json
* move default crate configuration to a default_profiles.json
button to open mcp config in editor
initialse empty mcp config files
fix test
new JSON structure
remove editor buttons
fmt and types
* feat: add profile field to follow-up attempt (#442)
* move default crate configuration to a default_profiles.json
* new JSON structure
* feat: add profile field to follow-up attempt; fix follow ups using wrong session id at 2nd+ follow up
fmt
Profile selection (vibe-kanban cf714482)
Right now in the frontend, when viewing a task card, we show the base_coding_agent from the task attempt. We should also show the currently selected profile there in the same way
feat: add watchkill support to CommandBuilder and integrate with Claude executor
feat: refactor profile handling to use ProfileVariant across executors and requests
feat: restructure command modes in default_profiles.json for clarity and consistency
update profile handling to use ProfileVariant across components and add mode selection
fmt
feat: refactor profile handling to use variants instead of modes across components and update related structures
Fix frontend
* Refactor coding agent representation in task and task attempt models
- Changed `base_coding_agent` field to `profile` in `TaskWithAttemptStatus` and `TaskAttempt` structs.
- Updated SQL queries and data handling to reflect the new `profile` field.
- Modified related API endpoints and request/response structures to use `profile` instead of `base_coding_agent`.
- Adjusted frontend API calls and components to align with the updated data structure.
- Removed unused `BaseCodingAgent` enum and related type guards from the frontend.
- Enhanced MCP server configuration handling to utilize the new profile-based approach.
feat: Introduce MCP configuration management
- Added `McpConfig` struct for managing MCP server configurations.
- Implemented reading and writing of agent config files in JSON and TOML formats.
- Refactored MCP server handling in the `McpServers` component to utilize the new configuration structure.
- Removed deprecated `agent_config.rs` and updated related imports.
- Enhanced error handling for MCP server operations.
- Updated frontend strategies to accommodate the new MCP configuration structure.
feat: Introduce MCP configuration management
- Added `McpConfig` struct for managing MCP server configurations.
- Implemented reading and writing of agent config files in JSON and TOML formats.
- Refactored MCP server handling in the `McpServers` component to utilize the new configuration structure.
- Removed deprecated `agent_config.rs` and updated related imports.
- Enhanced error handling for MCP server operations.
- Updated frontend strategies to accommodate the new MCP configuration structure.
Best effort migration; add missing feature flag
feat: refactor execution process handling and introduce profile variant extraction
feat: add default follow-up variant handling in task details context
feat: enhance profile variant selection with dropdown menus in onboarding and task sections
fmt, types
* refactor: rename ProfileVariant to ProfileVariantLabel; Modified AgentProfile to wrap AgentProfileVariant
Fmt, clippy
* Fix rebase issues
* refactor: replace OnceLock with RwLock for AgentProfiles caching; update profile retrieval in executors and routes
---------
Co-authored-by: Gabriel Gordon-Hall <ggordonhall@gmail.com>
Fmt
Fix tests
refactor: clean up unused imports and default implementations in executor modules
Move profiles to profiles.rs
* rename profile to profile_variant_label for readability
rename AgentProfile to ProfileConfig, AgentProfileVariant to VariantAgentConfig
* remove duplicated profile state
* Amp yolo
---------
Co-authored-by: Alex Netsch <alex@bloop.ai>