Commit Graph

1177 Commits

Author SHA1 Message Date
Louis Knight-Webb
b8abd9a05e Done! I've updated the README to: (#1494)
1. Added the `PORT` environment variable with its dual behavior (production vs dev)
2. Clarified that `BACKEND_PORT` and `FRONTEND_PORT` are dev mode only and override the PORT-derived values

The changes are minimal and accurate based on the code exploration.
2025-12-11 10:30:40 +00:00
ukwksk
85f6ee5237 fix: use gitignore-aware selective watching to reduce memory usage (#1399)
* fix: skip watching heavy directories to avoid memory leak

* fix: reduce memory usage in filesystem watcher for pnpm projects

Use gitignore-aware directory collection to prevent OS-level watchers
from being set up on heavy directories like node_modules.

Changes:
- Use WalkBuilder's git_ignore(true) to respect .gitignore when collecting watch directories
- Use NonRecursive watch mode for each directory instead of single Recursive watch
- Simplify ALWAYS_SKIP_DIRS to only contain .git (not in .gitignore but should be skipped)

This fixes high memory usage when running vibe-kanban on pnpm-managed
repositories, which contain many symlinks in node_modules.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: simplify filesystem watcher error handling and fix clippy warnings

- Remove debug logs that were added during development
- Fail fast on watch errors instead of continuing in a partially broken state
- Collapse nested if statements to satisfy clippy::collapsible_if

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: check only parent directories in path_allowed

Only check parent directory names against ALWAYS_SKIP_DIRS since
should_skip_dir is meant for directories, not file names.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: add watch directories changes

* Stop leaking filesystem watcher

Use weak references so the background thread exits once the diff stream releases the debouncer.

* Memoize ignored-descendant scan

Cache per-directory results so collecting watch targets stays linear.

* Improve watcher gitignore classification

Use real metadata when available, fall back to the old heuristic only when the file is already gone, and document the limitation.

* Handle directory renames in watcher

* Deduplicate watch directories more efficiently

Sort once and do a single sweep instead of quadratic filtering.

* Document gitignore watcher limitation

* Cascade watcher removal on directory delete

Drop all descendant watchers when a parent directory disappears so stale handles don’t linger.

* Watch subdirectories when new directories are added

Track recursive parent watchers so we skip redundant child watches and prune them when a parent becomes recursive.

* Always ignore node_modules

* Use a high-performance line count diff implementation

The `similar` diff stat implementation was causing cpu spikes of up to 600% over 10 seconds.

* exclude node_modules from git diff commands

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Solomon <abcpro11051@disroot.org>
2025-12-10 18:08:42 +00:00
Solomon
72c952626a Allow changing target branch when agent is running (#1474)
Changing the target branch is a no-op.
2025-12-09 16:28:54 +00:00
Alex Netsch
cbe27a7549 Update claude.md (vibe-kanban) (#1484)
* Done. I've replaced the contents of `CLAUDE.md` with the contents from `agents.md`. The file now contains the repository guidelines from agents.md.

* Done. I've updated CLAUDE.md with the following fixes:

1. **Added `remote` crate** to the crates list
2. **Added `remote-frontend/`** directory
3. **Removed `dev_assets/`** (doesn't exist, only `dev_assets_seed/` does)
4. **Added `docs/`** directory

The rest of the file (commands, coding style, testing guidelines, security tips) appears accurate based on the `package.json` scripts I reviewed.

* Done. Added `dev_assets/` back to the assets line.

* Done. `CLAUDE.md` is now a symlink to `AGENTS.md`:

```
CLAUDE.md -> AGENTS.md
```

Both files will stay in sync since they're the same file now.
2025-12-09 16:04:20 +00:00
Gabriel Gordon-Hall
84d80659b3 normalize tool display; remove backticks (#1482) 2025-12-09 15:50:17 +00:00
GitHub Action
d0392e6d5e chore: bump version to 0.0.132 2025-12-09 12:32:34 +00:00
Louis Knight-Webb
55ca4d3655 Add auto-generate PR description feature (Vibe Kanban) (#1479)
* I've completed the implementation. Here's a summary of the changes made:

## Summary

### Backend (Rust)

1. **`crates/services/src/services/config/versions/v8.rs`**
   - Added two new config fields:
     - `pr_auto_description_enabled: bool` - defaults to `false`
     - `pr_auto_description_prompt: Option<String>` - defaults to `None`

2. **`crates/server/src/routes/task_attempts.rs`**
   - Added `auto_generate_description: bool` field to `CreateGitHubPrRequest`
   - Added `DEFAULT_PR_DESCRIPTION_PROMPT` constant with the default prompt
   - Added `trigger_pr_description_follow_up()` helper function that:
     - Gets the custom prompt from config or uses default
     - Replaces `{pr_number}` and `{pr_url}` placeholders
     - Triggers a follow-up (or initial if no session) coding agent execution
   - Modified `create_github_pr()` to call the follow-up trigger after successful PR creation

### Frontend (TypeScript/React)

3. **`frontend/src/components/dialogs/tasks/CreatePRDialog.tsx`**
   - Added `autoGenerateDescription` state, initialized from `config.pr_auto_description_enabled`
   - Added checkbox to toggle auto-generate PR description
   - Included `auto_generate_description` in the API call payload

4. **`frontend/src/pages/settings/GeneralSettings.tsx`**
   - Added "Pull Requests" Card section with:
     - Checkbox to enable/disable auto-generate by default
     - Textarea for custom prompt override

5. **Translation files**
   - Added `autoGenerateLabel` to `tasks.json`
   - Added `pullRequests` section to `settings.json`

6. **`shared/types.ts`** - Auto-generated with new types

### Key Features
- Toggle in PR creation dialog, defaulting to the global config setting
- Settings page for configuring default behavior and custom prompt
- Placeholders `{pr_number}` and `{pr_url}` for custom prompts
- Uses the same executor profile as the original task attempt
- Graceful error handling (warns but doesn't fail PR creation if follow-up fails)

* Cleanup script changes for task attempt 46e66dfc-f608-47a4-baca-e38399d2da15

* Done! I've updated the placeholder text in `settings.json` to show the actual default prompt. Now users can see exactly what prompt the AI agent will use by default, and they know what they're customizing when they enter a custom prompt.

The placeholder now shows:
```
Update the GitHub PR that was just created with a better title and description.
The PR number is #{pr_number} and the URL is {pr_url}.

Analyze the changes in this branch and write:
1. A concise, descriptive title that summarizes the changes
2. A detailed description that explains:
   - What changes were made
   - Why they were made (based on the task context)
   - Any important implementation details

Use `gh pr edit` to update the PR.
```

I also updated the helper text to mention the placeholder variables (`{pr_number}` and `{pr_url}`) so users know what variables they can use in their custom prompts.

* Cleanup script changes for task attempt 46e66dfc-f608-47a4-baca-e38399d2da15

* Done! Updated the label to "Ask AI agent to generate a better PR description" as requested.

* All done! The refactoring is complete:

**Summary of changes:**

1. **Created `crates/server/src/routes/task_attempts/pr.rs`** - New submodule containing all PR-related code:
   - Types: `CreateGitHubPrRequest`, `CreatePrError`, `AttachPrResponse`, `PrCommentsResponse`, `GetPrCommentsError`
   - Constants: `DEFAULT_PR_DESCRIPTION_PROMPT`
   - Functions: `trigger_pr_description_follow_up`, `create_github_pr`, `attach_existing_pr`, `get_pr_comments`

2. **Updated `crates/server/src/routes/task_attempts.rs`** - Added `pub mod pr;` and updated router to use `pr::` prefix for PR routes

3. **Updated `crates/server/src/bin/generate_types.rs`** - Fixed all paths to reference `pr::` submodule for the PR-related types

Both backend (cargo check) and frontend (TypeScript) compile successfully, and TypeScript types have been regenerated.

* Cleanup script changes for task attempt 46e66dfc-f608-47a4-baca-e38399d2da15

* Done! I've updated the default PR description prompt in both locations:

1. **`crates/server/src/routes/task_attempts/pr.rs`** - Updated `DEFAULT_PR_DESCRIPTION_PROMPT` constant
2. **`frontend/src/i18n/locales/en/settings.json`** - Updated `pullRequests.customPrompt.placeholder`

The changes are:
- Title should now be postfixed with "(Vibe Kanban)"
- Description should include a note at the end: "This PR was written using [Vibe Kanban](https://vibekanban.com)"

* Done! I've updated `pr_auto_description_enabled` to default to `true` in three places:

1. Added `default_pr_auto_description_enabled()` function that returns `true`
2. Updated the `#[serde(default)]` attribute to use this function
3. Updated the `from_v7_config` migration to set it to `true`
4. Updated the `Default` impl to set it to `true`

* All done! I've added i18n translations for the PR auto-description feature to all supported languages:

**settings.json** - Added `pullRequests` section with:
- `title`, `description`
- `autoDescription.label`, `autoDescription.helper`
- `customPrompt.label`, `customPrompt.placeholder`, `customPrompt.helper`

**tasks.json** - Added `autoGenerateLabel` key

Languages updated:
- Spanish (es)
- Japanese (ja)
- Korean (ko)
- Simplified Chinese (zh-Hans)

* Update frontend/src/i18n/locales/en/tasks.json

Co-authored-by: Gabriel Gordon-Hall <gabriel@bloop.ai>

* Done! I've implemented the UX improvement from the PR review:

1. **Moved the auto-generate checkbox** to the top of the form (above title and description)
2. **Added `disabled` prop** to both the title Input and description Textarea when `autoGenerateDescription` is true
3. **Added greyed-out styling** (`opacity-50 cursor-not-allowed`) to visually indicate the fields are disabled

The new field order is:
1. Auto-generate checkbox
2. Title input (disabled when checked)
3. Description textarea (disabled when checked)
4. Base branch selector
5. Draft checkbox

* All done! I've:

1. **Made `DEFAULT_PR_DESCRIPTION_PROMPT` public** in `pr.rs`

2. **Exported the constant to `shared/types.ts`** via `generate_types.rs`:
   - Imported the constant from the pr module
   - Added code to append `export const DEFAULT_PR_DESCRIPTION_PROMPT = \`...\`;` to the generated types

3. **Updated `GeneralSettings.tsx`** to import and use the constant directly as the placeholder

4. **Removed the duplicate `placeholder` key** from all i18n `settings.json` files (en, es, ja, ko, zh-Hans)

The default prompt is now defined in a single place (the Rust backend) and exported to TypeScript, eliminating duplication across all i18n files.

* Cleanup script changes for task attempt 46e66dfc-f608-47a4-baca-e38399d2da15

* Done! I've implemented the two-step UX for the custom prompt:

1. **Updated `GeneralSettings.tsx`**:
   - Replaced the always-visible textarea with a "Use custom prompt" checkbox
   - When checked, pre-fills the textarea with `DEFAULT_PR_DESCRIPTION_PROMPT`
   - When unchecked, sets `pr_auto_description_prompt` to `null` (reverts to default)
   - Textarea only visible when custom prompt is enabled

2. **Updated i18n files** (all 5 languages):
   - Replaced `label` with `useCustom` key
   - Updated `helper` text to remove "Leave empty to use the default" since that's now handled by the checkbox
   - Added translations:
     - **en**: "Use custom prompt"
     - **es**: "Usar prompt personalizado"
     - **ja**: "カスタムプロンプトを使用"
     - **ko**: "사용자 정의 프롬프트 사용"
     - **zh-Hans**: "使用自定义提示"

* Done! The custom prompt UX has been updated:

- **Textarea is now always visible** showing the current prompt (default or custom)
- **When "Use custom prompt" is unchecked**: textarea shows `DEFAULT_PR_DESCRIPTION_PROMPT` but is disabled/read-only with greyed-out styling
- **When "Use custom prompt" is checked**: textarea becomes editable, pre-filled with the default prompt for customization

This gives users visibility into what prompt will be used even when using the default, while still allowing them to customize it by checking the checkbox.

* Cleanup script changes for task attempt 46e66dfc-f608-47a4-baca-e38399d2da15

* Done! The fix has been applied. Now when the "Use custom prompt" checkbox is checked, users can:
- Clear all the text in the textarea to start from scratch
- The text no longer automatically reverts to the default prompt when emptied

---------

Co-authored-by: Gabriel Gordon-Hall <gabriel@bloop.ai>
2025-12-09 12:31:22 +00:00
Louis Knight-Webb
d8eeab628c Auto set task as subtask based on Git branch (vibe-kanban) (#1468)
* All implementation steps are complete. Here's a summary of what was implemented:

Implemented auto-linking of subtasks when creating tasks with 6 changes:

1. **`crates/db/src/models/task_attempt.rs`** - Added `find_by_branch()` query to look up task attempts by branch name within a project

2. **`crates/db/src/models/task.rs`** - Added:
   - `Clone` derive to `CreateTask` struct
   - `with_parent_from_branch()` helper method on `CreateTask` for fluent branch-based parent resolution
   - `update_parent_task_attempt()` method on `Task` to update parent linkage for existing tasks

3. **`crates/server/src/routes/tasks.rs`** - Updated `create_task_and_start()` to use `with_parent_from_branch()` helper before creating the task

4. **`crates/server/src/routes/task_attempts.rs`** - Updated `create_task_attempt()` to link existing tasks to parent attempts when `base_branch` matches an existing attempt's branch

5. **`crates/server/src/mcp/task_server.rs`** - Updated MCP `create_task` to automatically set `parent_task_attempt` from the current context's `attempt_id`

6. **`crates/db/.sqlx/`** - Updated SQLx query cache with the new queries

* Cleanup script changes for task attempt 3bcb8f0d-6655-4b34-9cd2-c3c731795b78

* All implementation steps are complete. Here's a summary of what was implemented:

## Summary

Auto-linking of subtasks when creating tasks is now implemented for all three scenarios:

1. **MCP create_task** (`task_server.rs:404-432`): When an AI agent creates a task via MCP while working in a worktree, the new task automatically becomes a subtask of the current attempt (uses `McpContext.attempt_id`)

2. **Branch-based targeting**:
   - `create_task_and_start` (`tasks.rs`): Uses `with_parent_from_branch` helper to auto-link when `base_branch` matches an existing attempt
   - `create_task_attempt` (`task_attempts.rs`): Updates existing task's parent when creating an attempt with a matching `base_branch`

3. **Rebase** (`task_attempts.rs:1249-1257`): When rebasing a task attempt onto another attempt's branch, the task's `parent_task_attempt` is updated to point to that attempt

### Files modified:
- `crates/db/src/models/task_attempt.rs` - Added `find_by_branch` query
- `crates/db/src/models/task.rs` - Added `Clone` derive, `with_parent_from_branch` helper, `update_parent_task_attempt` method
- `crates/server/src/routes/tasks.rs` - Updated `create_task_and_start`
- `crates/server/src/routes/task_attempts.rs` - Updated `create_task_attempt` and `rebase_task_attempt`
- `crates/server/src/mcp/task_server.rs` - Updated MCP `create_task`

* Cleanup script changes for task attempt 3bcb8f0d-6655-4b34-9cd2-c3c731795b78

* All 8 steps are now complete. Here's a summary of the implementation:

## Summary

Added auto-linking of subtasks in the `change_target_branch` endpoint (`task_attempts.rs:1047-1055`). When a user changes a task attempt's target branch to match another attempt's branch, the task automatically becomes a subtask of that attempt.

The full implementation now covers all 4 scenarios:

1. **MCP create_task** - Links via `McpContext.attempt_id`
2. **Branch-based targeting** - Links in `create_task_and_start` and `create_task_attempt` via `with_parent_from_branch`
3. **Rebase** - Links in `rebase_task_attempt` after successful git rebase
4. **Change target branch** - Links in `change_target_branch` after updating target_branch (newly added)

* Done. Removed `from_title_description` helper from `task.rs` and updated `task_server.rs` to construct `CreateTask` directly with all fields set correctly. All checks pass.
2025-12-09 11:54:34 +00:00
Solomon
aee6ac35b8 Opencode ACP (#1471)
* Opencode ACP

switch opencode to ACP.

Simplifies the implementation and adds fork/retry support.

* display relative file path for read tool

* remove empty assitant messages
2025-12-09 11:29:19 +00:00
Solomon
1ee05ea862 normalize cursor todo items (#1473) 2025-12-09 10:54:21 +00:00
Louis Knight-Webb
e83e0ee169 MCP server expand tag (vibe-kanban) (#1458)
* Implementation is complete. Let me provide a summary of the changes made:

## Summary

I've implemented tag expansion for the MCP server. Here are the changes:

### Files Modified

1. **`crates/server/Cargo.toml`** - Added `regex = "1"` dependency

2. **`crates/server/src/mcp/task_server.rs`** - Three changes:
   - Added imports for `Tag` and `Regex`
   - Added `expand_tags()` helper function that:
     - Finds all `@tagname` patterns using regex `@([^\s@]+)`
     - Fetches tags from `/api/tags` endpoint
     - Replaces each `@tagname` with the tag's content
     - Returns original text if tag not found or on error
   - Updated `create_task` to expand tags in description before creating
   - Updated `update_task` to expand tags in description before updating
   - Updated tool descriptions to mention tag expansion support

### How It Works

When an AI agent calls `create_task` or `update_task` with a description containing `@tagname` (e.g., `"Please implement this feature @requirements"`), the MCP server will:

1. Parse the description for `@tagname` patterns
2. Fetch all available tags from the backend API
3. Replace each `@tagname` with the corresponding tag's `content`
4. Save the task with the expanded description

If a tag is not found, the `@tagname` is left as-is. If there's a network error, the original text is preserved to ensure task creation doesn't fail.

* Update crates/server/src/mcp/task_server.rs

Co-authored-by: Solomon <abcpro11051@disroot.org>

* Update crates/server/src/mcp/task_server.rs

Co-authored-by: Solomon <abcpro11051@disroot.org>

---------

Co-authored-by: Solomon <abcpro11051@disroot.org>
2025-12-09 10:37:46 +00:00
Louis Knight-Webb
21d175bccc Play notification sound when approval needed (vibe-kanban) (#1463)
* The implementation is complete. Here's a summary of the changes:

## Summary

Added notification sound when approval is needed, using the same notification system as task finalization.

**Files modified:**

1. **`crates/services/src/services/approvals/executor_approvals.rs`**
   - Added `config: Arc<RwLock<Config>>` field to `ExecutorApprovalBridge`
   - Added imports for `Config`, `NotificationService`, and `RwLock`
   - Added notification call in `request_tool_approval()` after creating the approval request

2. **`crates/local-deployment/src/container.rs`**
   - Passed `self.config.clone()` to `ExecutorApprovalBridge::new()`

When an approval is requested, the notification will display:
- **Title:** "Approval Needed"
- **Message:** "Tool '{tool_name}' requires approval"

The notification uses the user's configured sound file and respects their notification settings (sound enabled/disabled, push enabled/disabled).

* Cleanup script changes for task attempt af6bac2d-a3ba-4c6a-ae35-3a54bd05212f

* Done! Here's a summary of the refactored implementation:

## Summary

Refactored `NotificationService` to hold config internally and added approval notification sound:

**Files modified:**

1. **`crates/services/src/services/notification.rs`**
   - Added `config: Arc<RwLock<Config>>` field
   - Added `new(config)` constructor
   - Changed `notify` and `notify_execution_halted` from static to instance methods
   - Added internal `send_notification` helper method

2. **`crates/services/src/services/container.rs`**
   - Updated `finalize_task` trait method to accept `&NotificationService` instead of `&Arc<RwLock<Config>>`
   - Removed unused `Config` import

3. **`crates/local-deployment/src/container.rs`**
   - Added `notification_service: NotificationService` field to `LocalContainerService`
   - Initialize service in `new()` with config
   - Updated all `finalize_task` calls to pass `&self.notification_service`
   - Updated `ExecutorApprovalBridge::new()` to pass `notification_service`

4. **`crates/services/src/services/approvals/executor_approvals.rs`**
   - Replaced `config: Arc<RwLock<Config>>` with `notification_service: NotificationService`
   - Updated constructor and notification call to use the service

The notification uses the user's configured sound and settings, and triggers when a tool requires approval.

* Cleanup script changes for task attempt af6bac2d-a3ba-4c6a-ae35-3a54bd05212f

* Done! The refactoring is complete. Here's a summary:

## Summary

Refactored `NotificationService` to be accessed via the `ContainerService` trait, making it cleaner:

**Changes made:**

1. **`crates/services/src/services/container.rs`**
   - Added `fn notification_service(&self) -> &NotificationService` to the trait
   - Simplified `finalize_task` signature to `(&self, share_publisher, ctx)` - removed the notification_service parameter
   - `finalize_task` now calls `self.notification_service().notify_execution_halted(ctx)`

2. **`crates/local-deployment/src/container.rs`**
   - Implemented `fn notification_service(&self) -> &NotificationService` returning `&self.notification_service`
   - Updated all 4 `finalize_task` call sites to use the simplified signature

The notification service is now a first-class member of the `ContainerService` trait, following the same pattern as `db()`, `git()`, and `share_publisher()`.

* Cleanup script changes for task attempt af6bac2d-a3ba-4c6a-ae35-3a54bd05212f

* Done! Here's a summary of all the changes:

## Final Summary

**Feature implemented:** Play notification sound when approval is needed.

**Files modified:**

1. **`crates/services/src/services/notification.rs`**
   - Added `config: Arc<RwLock<Config>>` field and `new()` constructor
   - Removed `notify_execution_halted` method (moved application logic out)
   - Kept only generic `notify(title, message)` method

2. **`crates/services/src/services/container.rs`**
   - Added `fn notification_service(&self) -> &NotificationService` to trait
   - Moved notification logic into `finalize_task`:
     - Skip notification if process was killed
     - Build title/message based on execution status
     - Call `self.notification_service().notify(...)`

3. **`crates/local-deployment/src/container.rs`**
   - Added `notification_service: NotificationService` field
   - Implemented `notification_service()` accessor
   - Simplified `finalize_task` calls (removed notification_service parameter)
   - Pass `notification_service.clone()` to `ExecutorApprovalBridge`

4. **`crates/services/src/services/approvals/executor_approvals.rs`**
   - Added `notification_service: NotificationService` field
   - Calls `self.notification_service.notify("Approval Needed", ...)` when approval is requested

The `NotificationService` is now a clean, reusable service that only handles notifications without any application-specific logic.

* Cleanup script changes for task attempt af6bac2d-a3ba-4c6a-ae35-3a54bd05212f
2025-12-09 09:57:42 +00:00
Louis Knight-Webb
8846e6621c Improve reset dialog (vibe-kanban) (#1466)
* Excellent! All checks pass. Let me provide a summary of the changes made:

## Summary

I've successfully implemented all the requested changes to improve the Reset Dialog:

### 1. Safety Improvements
- **Default `worktreeResetOn` to `false`** (`RestoreLogsDialog.tsx:45`) - The "Reset worktree" toggle is now off by default, preventing accidental destructive actions.

- **Added `acknowledgeUncommitted` toggle** - When uncommitted changes are detected, a new amber-colored section appears with a toggle that users must enable before proceeding. This ensures users explicitly acknowledge that their uncommitted changes may be affected.

- **Updated `isConfirmDisabled` logic** (`RestoreLogsDialog.tsx:130-133`) - The confirm button is now disabled when there are uncommitted changes until the user toggles the acknowledgment.

### 2. i18n Migration
All hardcoded strings in the dialog have been migrated to use i18n with full support for 5 languages:
- English (`en/tasks.json`)
- Japanese (`ja/tasks.json`)
- Spanish (`es/tasks.json`)
- Korean (`ko/tasks.json`)
- Chinese Simplified (`zh-Hans/tasks.json`)

The translations include proper pluralization support using i18next's `_one`/`_other` suffixes for counts.

### Files Modified
- `frontend/src/components/dialogs/tasks/RestoreLogsDialog.tsx` - Main component changes
- `frontend/src/i18n/locales/en/tasks.json` - English translations
- `frontend/src/i18n/locales/ja/tasks.json` - Japanese translations
- `frontend/src/i18n/locales/es/tasks.json` - Spanish translations
- `frontend/src/i18n/locales/ko/tasks.json` - Korean translations
- `frontend/src/i18n/locales/zh-Hans/tasks.json` - Chinese translations

* Cleanup script changes for task attempt 0279d8b9-dcc8-4274-8da5-14b27672d604
2025-12-09 09:35:29 +00:00
Louis Knight-Webb
a82c7e37e7 GitHub comment dialog overflow issue (vibe-kanban) (#1465)
* All changes are complete and tests pass. Here's a summary of what was done:

## Summary

Fixed the GitHub Comments Dialog overflow issue with two files modified:

### 1. `frontend/src/components/ui/github-comment-card.tsx`
- Made the layout classes (`inline-block`, `align-bottom`, `max-w-md`) conditional
- They only apply when no custom layout className is provided (checked for `flex-`, `block`, or `w-` in className)
- This preserves the WYSIWYG editor behavior while allowing the dialog to override

### 2. `frontend/src/components/dialogs/tasks/GitHubCommentsDialog.tsx`
- Added `min-w-0` to the scrollable content container (line 108)
- Added `min-w-0` to each comment row flex container (line 145)
- Simplified the GitHubCommentCard className to `"flex-1 min-w-0"` (line 175)

The `min-w-0` classes are essential for proper flex containment - they override the default `min-width: auto` behavior that prevents flex items from shrinking below their content size.

Both TypeScript type checking and ESLint pass successfully.

* All changes are complete and tests pass. Here's a summary of what was fixed:

## Summary

**Root cause**: The Dialog component's API was being misused. Width classes (`max-w-2xl`) were being passed to `DialogContent` instead of `Dialog`. Since `DialogContent` is nested inside the Dialog's inner container (which has default `max-w-lg`), the width override was ineffective.

**Changes made**:

1. **`GitHubCommentsDialog.tsx`**: Moved sizing classes from `DialogContent` to `Dialog`:
   - `Dialog` now has `className="max-w-2xl p-0 max-h-[80vh] overflow-hidden"`
   - `DialogContent` now has `className="flex flex-col h-full"`

2. **`github-comment-card.tsx`**: Added `overflow-hidden` to the FullCard container so inner elements (DiffHunk `<pre>`) can scroll properly within the card boundaries.

The dialog should now:
- Be properly sized at `max-w-2xl` (672px) instead of being constrained to `max-w-lg` (512px)
- Properly contain content without horizontal overflow
- Allow diff hunks to scroll horizontally within the cards

* All changes are complete and tests pass. Summary of the fix for vertical scrolling:

1. **`dialog.tsx`**: Changed `grid` to `flex flex-col` in the Dialog inner container - this enables proper flex-based height constraints for child elements

2. **`GitHubCommentsDialog.tsx`**: Added `min-h-0` to the scrollable content div - this overrides the default `min-height: auto` which was preventing the flex item from shrinking below its content size

The dialog should now scroll vertically when there are many comments.

* All changes are complete and tests pass. Here's a summary of what was done:

**Changes to fix vertical scrolling:**

The dialog now follows the same pattern as `ViewProcessesDialog`:

1. **Dialog**: `className="max-w-2xl p-0 overflow-hidden"` - removed height constraints
2. **DialogContent**: `className="p-0"` - removed `h-full` and flex classes
3. **Added wrapper div**: `className="max-h-[70vh] flex flex-col min-h-0"` - explicit height constraint on inner wrapper
4. **Scrollable content**: `className="p-4 overflow-auto flex-1 min-h-0"` - scrolls within the constrained wrapper

The key insight was that putting the height constraint (`max-h-[70vh]`) on an **inner wrapper** rather than on the Dialog itself makes the flex-based scrolling work correctly. The header and footer remain outside this wrapper so they stay fixed.

* Cleanup script changes for task attempt a7065bc4-aa62-4dab-90c7-d15524acc50f

* Done! The hacky string matching has been replaced with an explicit `layout` prop:

**Changes:**

1. **`github-comment-card.tsx`**:
   - Added `layout?: 'inline' | 'block'` prop to `GitHubCommentCardProps`
   - Replaced the string matching logic with a simple `layout === 'inline'` check
   - Default is `'inline'` for backwards compatibility (WYSIWYG editor)

2. **`GitHubCommentsDialog.tsx`**:
   - Added `layout="block"` prop to `GitHubCommentCard`

The WYSIWYG editor (`github-comment-node.tsx`) doesn't need changes since it uses the default `layout="inline"`.

* Done! The hacky string matching has been replaced with an explicit `layout` prop:

**Summary of changes:**

1. **`github-comment-card.tsx`**:
   - Consolidated `variant` and `layout` into a single required `variant` prop
   - Three values: `'compact'` (inline chip), `'full'` (inline card with max-width), `'list'` (block card)
   - Removed the `layout` prop entirely
   - Made `variant` required (no default)

2. **`GitHubCommentsDialog.tsx`**:
   - Changed from `variant="full" layout="block"` to just `variant="list"`

3. **`github-comment-node.tsx`**:
   - Already had `variant="full"` explicitly set, no change needed
2025-12-08 17:34:12 +00:00
Solomon
0b1af7e38a Bump Copilot-cli version (#1469) 2025-12-08 17:20:14 +00:00
Louis Knight-Webb
9c70858b21 Make it possible to create draft PRs (vibe-kanban) (#1460)
* All checks pass. Let me summarize what was implemented:

## Summary

I've successfully implemented the draft PR feature. Here's what was changed:

### Backend Changes

1. **`crates/server/src/routes/task_attempts.rs`** (lines 70-76, 724-731):
   - Added `draft: Option<bool>` field to `CreateGitHubPrRequest` struct
   - Pass the draft field to the `CreatePrRequest` when creating PRs

2. **`crates/services/src/services/github.rs`** (lines 146-153):
   - Added `draft: Option<bool>` field to `CreatePrRequest` struct

3. **`crates/services/src/services/github/cli.rs`** (lines 158-160):
   - Added logic to pass `--draft` flag to `gh pr create` when draft is true

### Frontend Changes

4. **`frontend/src/components/dialogs/tasks/CreatePRDialog.tsx`**:
   - Added `Checkbox` import
   - Added `isDraft` state (default: false)
   - Added checkbox UI with label from translations
   - Pass `draft: isDraft` in the API call
   - Reset `isDraft` on success and cancel

### Type Generation

5. **`shared/types.ts`** (auto-generated):
   - `CreateGitHubPrRequest` now includes `draft: boolean | null`

### Translations

6. Added `"draftLabel"` translation key to all locale files:
   - `frontend/src/i18n/locales/en/tasks.json`: "Create as draft"
   - `frontend/src/i18n/locales/es/tasks.json`: "Crear como borrador"
   - `frontend/src/i18n/locales/ja/tasks.json`: "下書きとして作成"
   - `frontend/src/i18n/locales/ko/tasks.json`: "초안으로 만들기"
   - `frontend/src/i18n/locales/zh-Hans/tasks.json`: "创建为草稿"

* Done. I've updated the checkbox to use `h-5 w-5` (20px) and added `text-sm` to the label for consistent sizing.
2025-12-08 16:53:37 +00:00
Louis Knight-Webb
047695e554 Exiting settings should navigate to previous location (#1467)
**Summary:** Updated `SettingsLayout.tsx` to simplify the `handleBack` function - now it always uses `navigate(-1)` to go back in browser history. This means pressing ESC (or clicking the X button) in Settings will return users to whatever page they came from. Removed the unused `useLocation` import as it was no longer needed.
2025-12-08 16:46:57 +00:00
Gabriel Gordon-Hall
08d8848346 remove redundant or unused deps (#1462) 2025-12-08 15:36:38 +00:00
Gabriel Gordon-Hall
45d0359118 feat: move default agent configuration to Agent Settings (vibe-kanban) (#1453) 2025-12-08 15:25:49 +00:00
Louis Knight-Webb
e28e25720a add opus variant for claude code (#1452) 2025-12-08 14:30:01 +00:00
Louis Knight-Webb
f045b3f935 All i18n issues are fixed. I added the missing parallelLabel and parallelHelper keys to the Chinese (Simplified) translation file (zh-Hans/settings.json). These keys were already present in English, Japanese, Korean, and Spanish but were missing from the Chinese translation. (#1455) 2025-12-08 14:06:28 +00:00
Louis Knight-Webb
76877ea631 Run setup script in parallel with coding agent (vibe-kanban) (#1446)
* The implementation is complete. Here's a summary of all the changes made:

## Summary

### Files Created
- `crates/db/migrations/20251206000000_add_parallel_setup_script_to_projects.sql` - Database migration

### Files Modified

**Backend (Rust):**
- `crates/db/src/models/project.rs` - Added `parallel_setup_script: bool` field to `Project`, `Option<bool>` to `CreateProject`/`UpdateProject`, updated all SQL queries
- `crates/services/src/services/container.rs` - Modified `start_attempt()` to support parallel execution when `parallel_setup_script` is true
- `crates/server/src/routes/projects.rs` - Updated create/update handlers to include new field
- `crates/deployment/src/lib.rs` - Added field to auto-created projects

**Frontend (TypeScript/React):**
- `frontend/src/pages/settings/ProjectSettings.tsx` - Added checkbox UI for parallel setup script setting
- `frontend/src/components/dialogs/projects/ProjectFormDialog.tsx` - Added field to create data
- `frontend/src/components/tasks/TaskDetails/preview/NoServerContent.tsx` - Added field to update data

**i18n:**
- `frontend/src/i18n/locales/en/settings.json` - Added translation strings
- `frontend/src/i18n/locales/es/settings.json` - Added Spanish translations
- `frontend/src/i18n/locales/ja/settings.json` - Added Japanese translations
- `frontend/src/i18n/locales/ko/settings.json` - Added Korean translations

**SQLx Cache:**
- `crates/db/.sqlx/` - Updated query cache files

### Behavior
- When `parallel_setup_script` is `false` (default): Sequential execution (setup → coding agent → cleanup)
- When `parallel_setup_script` is `true`: Setup script and coding agent start simultaneously, setup script failure does not stop the coding agent

* update useConversationHistory to display multiple running conversation threads at once

* The bug fix is complete. Here's a summary of the changes:

## Bug Fix Summary

**Problem:** When running in parallel mode, if the setup script finishes before the coding agent, the task incorrectly moves to "InReview" status while the coding agent is still running.

**Root Cause:** The `should_finalize()` method returned `true` when `next_action.is_none()`, which is the case for setup scripts in parallel mode. This caused premature task finalization.

**Solution:** Modified `should_finalize()` to check if there are other running non-DevServer processes for the same task attempt before finalizing.

### Files Modified

1. **`crates/db/src/models/execution_process.rs`**
   - Added `has_running_non_dev_server_processes_excluding()` method that accepts an optional `exclude_id` parameter
   - Refactored existing `has_running_non_dev_server_processes()` to delegate to the new method

2. **`crates/services/src/services/container.rs`**
   - Changed `should_finalize()` from sync to async
   - Added check for other running processes before allowing finalization

3. **`crates/local-deployment/src/container.rs`**
   - Updated call site to use `.await` on the now-async `should_finalize()`

* The bug fix is complete. Here's a summary of the changes:

**Fixed files:**

1. **`crates/services/src/services/container.rs`** - Simplified `should_finalize()`:
   - Changed from `async fn` back to `fn` (non-async)
   - Removed the complex database check for other running processes
   - Added a simple check: if the run_reason is `SetupScript` AND `next_action.is_none()` (parallel mode), return `false` (don't finalize)

2. **`crates/local-deployment/src/container.rs`** - Removed `.await` from the `should_finalize()` call

3. **`crates/db/src/models/execution_process.rs`** - Cleaned up by removing the unused `has_running_non_dev_server_processes_excluding()` function and simplifying `has_running_non_dev_server_processes()` back to its original form

**How the fix works:**

- In **parallel mode**: Setup scripts have `next_action: None`, so the new check catches this case and prevents finalization
- In **sequential mode**: Setup scripts have `next_action: Some(coding_agent)`, so they pass this check but won't finalize anyway because `next_action.is_none()` returns `false`
2025-12-07 15:25:13 +00:00
Stephan Fitzpatrick
7da884bc3a Add environment variables to executor profiles (#1444)
* The implementation is complete. Here's a summary of what was done:

Successfully added environment variable configuration support to executor profiles. Users can now configure env vars like this:

```json
{
  "CLAUDE_CODE": {
    "DEFAULT": {
      "CLAUDE_CODE": {
        "env": {
          "ANTHROPIC_AUTH_TOKEN": "...",
          "ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic",
          "API_TIMEOUT_MS": "3000000",
          "ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-4.6"
        }
      }
    }
  }
}
```

1. **`crates/executors/src/command.rs`**:
   - Added `env: Option<HashMap<String, String>>` to `CmdOverrides` struct
   - Added `apply_env_vars()` helper function

2. **Updated all executors to apply env vars**:
   - `claude.rs` - `spawn_internal()`
   - `codex.rs` - `spawn()`
   - `amp.rs` - `spawn()` and `spawn_follow_up()`
   - `droid.rs` - module-level `spawn()` function
   - `copilot.rs` - both spawn methods
   - `cursor.rs` - both spawn methods
   - `opencode.rs` - both spawn methods
   - `acp/harness.rs` - `spawn_with_command()` and `spawn_follow_up_with_command()` (used by Gemini/Qwen)

3. **Type Generation**: All JSON schemas and TypeScript types now include the `env` field

This allows users to set environment variables for all supported coding agents (Claude Code, Codex, Gemini, Amp, Droid, Copilot, Cursor, OpenCode, Qwen) through profile configuration, eliminating the need for external tools like claude-code-router.

* The implementation is complete. Here's a summary of what was done:

## Summary

### Backend Changes
- Added `env: Option<HashMap<String, String>>` field to `CmdOverrides` struct in `crates/executors/src/command.rs`
- Created `apply_env_vars()` helper function to inject env vars into `tokio::process::Command`
- Updated all 9 executors to apply env vars during spawn:
  - claude.rs, codex.rs, amp.rs, droid.rs, copilot.rs, cursor.rs, opencode.rs
  - gemini.rs and qwen.rs (via ACP harness)
- Modified ACP harness signature to accept `Option<&CmdOverrides>`

### Frontend Changes
- Created `KeyValueField.tsx` - custom RJSF field for editing key-value pairs
- Registered the field in `theme.ts`
- Added `uiSchema` to `ExecutorConfigForm.tsx` to use the custom field for `env`

### Generated Files
- `shared/types.ts` - TypeScript types updated with `env` field
- `shared/schemas/*.json` - All 9 executor schemas include `env` property

The environment variables UI will now appear in Settings > Agent Settings as a key-value editor with "Environment Variables" label and description. Users can add/remove/edit env vars that will be passed to the CLI execution environment.

* cleanup env structs

* fix form

* fmt

* remove mise.toml

* fmt

* Seprate config form per selected variant

---------

Co-authored-by: Louis Knight-Webb <louis@bloop.ai>
Co-authored-by: Solomon <abcpro11051@disroot.org>
2025-12-07 15:01:12 +00:00
GitHub Action
e1c9c15f43 chore: bump version to 0.0.131 2025-12-07 14:13:05 +00:00
CG-man
757a483696 Add internationalization support for Simplified Chinese (#1438)
* Add internationalization support for Simplified Chinese (vibe-kanban 1e5a14ae)

* fmt

---------

Co-authored-by: Gabriel Gordon-Hall <ggordonhall@gmail.com>
Co-authored-by: Gabriel Gordon-Hall <gabriel@bloop.ai>
2025-12-07 13:48:27 +00:00
Alex Netsch
d72ec43d3b Auto approve in plan mode (#1450) 2025-12-07 13:47:57 +00:00
Gabriel Gordon-Hall
e6a5694bda fix i18n 2025-12-07 13:36:11 +00:00
Gabriel Gordon-Hall
77d4fcbf3f fmt 2025-12-07 13:23:39 +00:00
CG-man
52c84f0cce Add internationalization support for Simplified Chinese (vibe-kanban 1e5a14ae) 2025-12-07 13:23:39 +00:00
GitHub Action
9c434822d6 chore: bump version to 0.0.130 2025-12-06 19:27:31 +00:00
Louis Knight-Webb
9107b4b384 Add GitHub comments to WYSIWYG (vibe-kanban) (#1449)
* The implementation is complete. Here's a summary of what was added:

## Summary

I've implemented the endpoint to fetch all GitHub PR comments for a task attempt. The new endpoint is:

**`GET /api/task-attempts/{id}/pr/comments`**

### Files Modified

1. **`crates/services/src/services/github/cli.rs`**
   - Added `PrCommentAuthor` and `PrComment` types
   - Added `get_pr_comments()` method to `GhCli` that runs `gh pr view N --repo owner/repo --json comments`
   - Added `parse_pr_comments()` helper to parse the JSON response

2. **`crates/services/src/services/github.rs`**
   - Exported `PrComment` and `PrCommentAuthor` types
   - Added async `get_pr_comments()` method with retry logic (exponential backoff)

3. **`crates/server/src/routes/task_attempts.rs`**
   - Added `PrCommentsResponse` struct
   - Added `GetPrCommentsError` enum with variants: `NoPrAttached`, `GithubCliNotInstalled`, `GithubCliNotLoggedIn`
   - Added `get_pr_comments()` handler function
   - Registered the route at `/pr/comments`

4. **`crates/server/src/bin/generate_types.rs`**
   - Registered all new types for TypeScript generation

### Generated TypeScript Types

```typescript
type PrCommentsResponse = { comments: Array<PrComment> };

type GetPrCommentsError =
  | { "type": "no_pr_attached" }
  | { "type": "github_cli_not_installed" }
  | { "type": "github_cli_not_logged_in" };

type PrComment = {
  id: string,
  author: PrCommentAuthor,
  authorAssociation: string,
  body: string,
  createdAt: string,
  url: string
};

type PrCommentAuthor = { login: string };
```

* The enhancement is complete. Here's a summary of the changes:

## Summary

Enhanced the `GET /api/task-attempts/{id}/pr/comments` endpoint to fetch **both** general PR comments AND inline review comments, merged into a unified timeline.

### Response Format

```json
{
  "success": true,
  "data": {
    "comments": [
      {
        "comment_type": "general",
        "id": "IC_kwDOO7s21M7XzqRP",
        "author": "stunningpixels",
        "author_association": "MEMBER",
        "body": "Testing comments",
        "created_at": "2025-12-06T16:15:10Z",
        "url": "https://github.com/BloopAI/vibe-kanban/pull/1447#issuecomment-..."
      },
      {
        "comment_type": "review",
        "id": 2595085092,
        "author": "stunningpixels",
        "author_association": "MEMBER",
        "body": "undo this",
        "created_at": "2025-12-06T16:15:18Z",
        "url": "https://github.com/BloopAI/vibe-kanban/pull/1447#discussion_r...",
        "path": "frontend/src/components/layout/Navbar.tsx",
        "line": 23,
        "diff_hunk": "@@ -20,7 +20,6 @@ import {...}"
      }
    ]
  }
}
```

### TypeScript Types

```typescript
type UnifiedPrComment =
  | { comment_type: "general"; id: string; author: string; author_association: string; body: string; created_at: string; url: string; }
  | { comment_type: "review"; id: bigint; author: string; author_association: string; body: string; created_at: string; url: string; path: string; line: bigint | null; diff_hunk: string; };
```

* Add GitHub review comments (vibe-kanban b9ab9ab2)

frontend/src/components/tasks/TaskFollowUpSection.tsx

- New button to the right of attachment with github comment icon
- If user clicks, opens dialog
- Dialog will display list of comments, format like this:

```javascript

{

  "comments": [

    {

      "id": "IC_kwDOO7s21M7XAc3c",

      "author": {

        "login": "LSRCT"

      },

      "authorAssociation": "MEMBER",

      "body": "Hi! I tried to get claude to use the `AskUserQuestion` tool in vibe kanban but did not manage, it does not seem to have access to the tool at all. Could you give me a hint on how to best test this PR?",

      "createdAt": "2025-12-03T14:46:49Z",

      "includesCreatedEdit": false,

      "isMinimized": false,

      "minimizedReason": "",

      "reactionGroups": [],

      "url": "https://github.com/BloopAI/vibe-kanban/pull/1395#issuecomment-3607219676",

      "viewerDidAuthor": false

    },

    {

      "id": "IC_kwDOO7s21M7Xc1Pi",

      "author": {

        "login": "davidrudduck"

      },

      "authorAssociation": "NONE",

      "body": "> Hi! I tried to get claude to use the `AskUserQuestion` tool in vibe kanban but did not manage, it does not seem to have access to the tool at all. Could you give me a hint on how to best test this PR?\r\n\r\nI must have been having a daft night when I submitted this - am fixing this at the moment.",

      "createdAt": "2025-12-04T22:57:18Z",

      "includesCreatedEdit": false,

      "isMinimized": false,

      "minimizedReason": "",

      "reactionGroups": [],

      "url": "https://github.com/BloopAI/vibe-kanban/pull/1395#issuecomment-3614659554",

      "viewerDidAuthor": false

    }

  ]

}

```

The user will select a comment, this will then be added as a component to the chat.

The component should be fully serializable/deserializable as markdown <> WYSIWYG, just like we do for images atm.

The backend will be implemented separately so just hardcode a mock response in the frontend for now.

* PR 1449 failed because of i18n regressions (vibe-kanban 723e309c)

Please resolve the 7 hardcoded strings this PR introduces https://github.com/BloopAI/vibe-kanban/pull/1449

* PR 1449 failed because of i18n regressions (vibe-kanban 723e309c)

Please resolve the 7 hardcoded strings this PR introduces https://github.com/BloopAI/vibe-kanban/pull/1449
2025-12-06 19:26:29 +00:00
Louis Knight-Webb
86705f9c8e The fix is complete. Here's a summary of the changes: (#1441)
**Changes made:**

1. **`frontend/src/components/ui/wysiwyg.tsx`**:
   - Removed imports for `INLINE_CODE`, `InlineCodeNode`, and `INLINE_CODE_TRANSFORMER`
   - Removed `InlineCodeNode` from the registered nodes array
   - Simplified transformers to use Lexical's built-in `TRANSFORMERS` (which includes `INLINE_CODE`)

2. **Deleted files:**
   - `frontend/src/components/ui/wysiwyg/nodes/inline-code-node.tsx`
   - `frontend/src/components/ui/wysiwyg/transformers/inline-code-transformer.ts`

**What this fixes:**
1. **Escaping bug** - Backticks will no longer be incorrectly escaped when saving inline code
2. **Cannot edit inline code** - You can now edit characters within inline code blocks (TextNode is editable, unlike DecoratorNode which was atomic)

The TypeScript and lint checks pass. You can test by:
1. Creating a task with inline code like `` `console.log()` ``
2. Saving and reloading - no backslashes should appear
3. Clicking inside inline code and editing individual characters
2025-12-05 16:25:23 +00:00
GitHub Action
d81be475c5 chore: bump version to 0.0.129 2025-12-05 10:50:01 +00:00
Louis Knight-Webb
89c0f1b0ef revert (#1439) 2025-12-05 10:48:16 +00:00
Louis Knight-Webb
32c689dfc5 Run setup or cleanup scripts (vibe-kanban) (#1428)
* I've successfully implemented the two new API endpoints for running setup and cleanup scripts on task attempts. Here's a summary of the changes:

## Summary

### Files Modified

1. **`crates/server/src/routes/task_attempts.rs`**
   - Added `RunScriptError` enum type for error handling when no script is configured
   - Added `run_setup_script` handler - POST endpoint to run a project's setup script
   - Added `run_cleanup_script` handler - POST endpoint to run a project's cleanup script
   - Registered both routes: `/run-setup-script` and `/run-cleanup-script`

2. **`crates/server/src/bin/generate_types.rs`**
   - Added `RunScriptError` to the list of types to export to TypeScript

3. **`shared/types.ts`** (auto-generated)
   - Now includes the `RunScriptError` TypeScript type

### New Endpoints

- **`POST /api/task-attempts/{id}/run-setup-script`** - Runs the project's setup script in the task attempt's worktree
- **`POST /api/task-attempts/{id}/run-cleanup-script`** - Runs the project's cleanup script in the task attempt's worktree

Both endpoints:
- Return `ExecutionProcess` on success with the created execution process
- Return `RunScriptError::NoScriptConfigured` if the project doesn't have the respective script configured
- Track analytics events (`setup_script_executed` / `cleanup_script_executed`)
- Use the existing `ScriptContext::SetupScript` / `ScriptContext::CleanupScript` and `ExecutionProcessRunReason::SetupScript` / `ExecutionProcessRunReason::CleanupScript` patterns

* Done! I've added the running process check to both `run_setup_script` and `run_cleanup_script` endpoints. Here's a summary of the changes:

## Summary

### Files Modified

1. **`crates/db/src/models/execution_process.rs`**
   - Added `has_running_non_dev_server_processes` method that checks if any running processes (excluding dev servers) exist for a task attempt

2. **`crates/server/src/routes/task_attempts.rs`**
   - Added `ProcessAlreadyRunning` variant to `RunScriptError` enum
   - Added check at the start of both `run_setup_script` and `run_cleanup_script` handlers to return an error if non-dev-server processes are already running

3. **`shared/types.ts`** (auto-generated)
   - `RunScriptError` now includes both `no_script_configured` and `process_already_running` variants

### Behavior

Both endpoints now:
1. First check if any non-dev-server processes (coding agents, setup/cleanup scripts) are running on the task attempt
2. If running processes exist, return `RunScriptError::ProcessAlreadyRunning`
3. Otherwise proceed with script execution as before

* Cleanup script changes for task attempt cdb9cbd9-a6e7-4936-8e75-6dd837c634f3

* Done! I've implemented the frontend changes for the setup/cleanup script dropdown. Here's a summary:

## Summary of Frontend Changes

### Files Modified

1. **`frontend/src/lib/api.ts`**
   - Added `RunScriptError` to imports from shared types
   - Added `runSetupScript` and `runCleanupScript` methods to `attemptsApi`

2. **`frontend/src/components/tasks/TaskFollowUpSection.tsx`**
   - Added imports for `Terminal` icon, `DropdownMenu`, and `Tooltip` components
   - Added `attemptsApi` import
   - Updated `useProject()` to also get `project` data
   - Added computed values: `hasSetupScript`, `hasCleanupScript`, `hasAnyScript`
   - Added handlers: `handleRunSetupScript`, `handleRunCleanupScript`
   - Added dropdown button with Terminal icon after the Attach button
   - Dropdown only shows if project has at least one script configured
   - Menu items are disabled with tooltips when scripts are not configured
   - Button is disabled when `isAttemptRunning` is true

3. **`frontend/src/i18n/locales/en/tasks.json`**
   - Added translation strings for the dropdown menu items and tooltips

### Behavior

- **Dropdown visibility**: Only shown if project has `setup_script` or `cleanup_script` configured
- **Button disabled state**: When `isAttemptRunning` is true (tooltip explains why)
- **Menu item disabled states**:
  - "Run setup script" disabled if no `setup_script` (tooltip explains)
  - "Run cleanup script" disabled if no `cleanup_script` (tooltip explains)
- **After clicking**: Script starts executing and `isAttemptRunning` becomes true automatically, preventing further interactions

* Done! I've added translations for all languages:

- **Spanish (es)**:
  - "Ejecutar script de configuración" / "Ejecutar script de limpieza"
  - Tooltips in Spanish

- **Japanese (ja)**:
  - "セットアップスクリプトを実行" / "クリーンアップスクリプトを実行"
  - Tooltips in Japanese

- **Korean (ko)**:
  - "설정 스크립트 실행" / "정리 스크립트 실행"
  - Tooltips in Korean

* Done! I've removed all the fallback strings from the `t()` calls. All 5 translation calls now use just the key:

- `{t('followUp.scriptsDisabledWhileRunning')}`
- `{t('followUp.runSetupScript')}`
- `{t('followUp.noSetupScript')}`
- `{t('followUp.runCleanupScript')}`
- `{t('followUp.noCleanupScript')}`
2025-12-04 17:57:43 +00:00
Louis Knight-Webb
0d2e77dceb The fix is complete. Here's a summary of the changes: (#1435)
## Summary

Fixed GitHub issue #1433 - "Clicking on add review comment button no longer focus on the edit box"

### Changes Made

**1. `frontend/src/components/ui/wysiwyg.tsx`** (+5 lines)
- Added import for `AutoFocusPlugin` from `@lexical/react/LexicalAutoFocusPlugin`
- Added `autoFocus?: boolean` prop to `WysiwygProps` type
- Conditionally renders `<AutoFocusPlugin />` when `autoFocus` is true and editor is editable

**2. `frontend/src/components/diff/CommentWidgetLine.tsx`** (+1 line)
- Added `autoFocus` prop to the `WYSIWYGEditor` when creating new review comments

**3. `frontend/src/components/diff/ReviewCommentRenderer.tsx`** (+1 line)
- Added `autoFocus` prop to the `WYSIWYGEditor` when editing existing review comments

### Verification
- TypeScript type check: Passed
- ESLint: Passed
- Prettier: Passed
2025-12-04 17:48:26 +00:00
GitHub Action
6805be6962 chore: bump version to 0.0.128 2025-12-04 17:31:57 +00:00
Britannio Jarrett
63423f970b The issue was that links in the markdown view (used for user messages, tool outputs, etc.) were styled with text-primary, which resolves to the same color as the background or main text in some themes (effectively making them invisible or indistinguishable). I updated the WYSIWYGEditor configuration to use standard blue coloring for links in both light and dark modes. (#1418)
**Changes applied:**

1.  **Modified `frontend/src/components/ui/wysiwyg.tsx`**:
    -   Updated the `theme.link` property to use `text-blue-600` (light mode) and `dark:text-blue-400` (dark mode).
    -   Added hover states `hover:text-blue-800` and `dark:hover:text-blue-300` for better interactivity.

This change ensures links are clearly visible and themed correctly in user messages and all other places where the `WYSIWYGEditor` is used for markdown rendering.

I verified the changes by running `pnpm run check`, which passed successfully.
2025-12-04 17:28:54 +00:00
Louis Knight-Webb
58aecc0377 Done. All three changes have been applied: (#1432)
1. Added `text-sm` to the container wrapper (line 190)
2. Removed redundant `text-sm` from the `paragraph` theme (line 102)
3. Removed redundant `text-sm` from the `code` theme (line 129)

Now all markdown elements in the WYSIWYG editor will inherit `text-sm` from the container, ensuring consistent font sizing for paragraphs, lists, blockquotes, and other elements.
2025-12-04 17:27:10 +00:00
Alex Netsch
92a65b4e0e Switch back to nightly (#1434) 2025-12-04 16:50:51 +00:00
Solomon
2b11040d07 Upgrade Gemini and ACP (#1431)
* Upgrade Gemini and ACP

Upgrade ACP SDK version to the latest.
Upgrade Gemini-CLI to the latest working version.

* fmt
2025-12-04 16:13:59 +00:00
Alex Netsch
8a91dba6e3 Check prepare db in CI (vibe-kanban) (#1423)
* Done! Here's a summary of the changes:

1. **`scripts/prepare-db.js`** - Added `--check` flag support that runs `cargo sqlx prepare --check` instead of `cargo sqlx prepare`

2. **`package.json`** - Added new script:
   ```json
   "prepare-db:check": "node scripts/prepare-db.js --check"
   ```

3. **`.github/workflows/test.yml`** - Added `npm run prepare-db:check` to the Checks step

The check will verify that the `.sqlx/` cached query metadata is up-to-date with the actual SQL queries in the codebase. If a developer modifies a SQL query but forgets to run `npm run prepare-db`, the CI will fail.

* Fix image queries

* Done! Added check mode support to the remote script:

1. **`crates/remote/scripts/prepare-db.sh`** - Added `--check` flag support that runs `cargo sqlx prepare --check` when passed

2. **`package.json`** - Added:
   ```json
   "remote:prepare-db:check": "cd crates/remote && bash scripts/prepare-db.sh --check"
   ```

Note: I didn't add `remote:prepare-db:check` to CI since it requires PostgreSQL (`initdb`, `pg_ctl`) which may not be available on the CI runner. The local SQLite-based `prepare-db:check` is already in CI. Let me know if you'd like to add the remote check to CI as well (would require installing PostgreSQL in the workflow).

* Add remote db check to workflow

* Added a step to install `sqlx-cli` with both SQLite and PostgreSQL features. The Rust cache should help speed up subsequent runs since it caches installed crates.

* Done! All three files updated to use Rust `1.89.0`:

1. `rust-toolchain.toml` - `channel = "1.89.0"`
2. `.github/workflows/test.yml` - `toolchain: 1.89.0`
3. `.github/workflows/pre-release.yml` - `RUST_TOOLCHAIN: 1.89.0`

This should fix the `zerocopy` AVX512 compile error since 1.89.0 has `stdarch_x86_avx512` stabilized.

* Done. Added a step to install PostgreSQL before the Checks step so `npm run remote:prepare-db:check` can run.

* Updated to install `postgresql-16` and add `/usr/lib/postgresql/16/bin` to PATH so `initdb`, `pg_ctl`, and `createdb` are available.

* Added the official PostgreSQL apt repository so we can install PostgreSQL 16.

* Much cleaner. Using the `ikalnytskyi/action-setup-postgres@v7` action which handles the PostgreSQL 16 installation and PATH setup automatically.

* Done. Changes made:

1. **`crates/remote/scripts/prepare-db.sh`**: Now checks if `DATABASE_URL` is set. If so, uses the existing PostgreSQL server. Otherwise creates a temp cluster as before.

2. **`.github/workflows/test.yml`**:
   - Added `database: remote` to the PostgreSQL action to create the database
   - Added `DATABASE_URL: postgres://postgres@localhost:5432/remote` env var to the Checks step

* Done. Changes made:

1. **`.github/workflows/test.yml`**: Removed PostgreSQL setup step and `DATABASE_URL` env var
2. **`crates/remote/scripts/prepare-db.sh`**: Simplified - for `--check` mode, exits early with `SQLX_OFFLINE=true cargo sqlx prepare --check` (no database needed)
2025-12-04 15:57:32 +00:00
Louis Knight-Webb
a369cec373 Inject ENV vars into shell (vibe-kanban) (#1426)
* The implementation is complete. Here's a summary of what was done:

I've implemented environment variable injection when launching coding agents. The following environment variables are now injected into the shell when an executor is spawned:

- `VK_PROJECT_NAME` - Name of the project
- `VK_TASK_ID` - UUID of the task
- `VK_ATTEMPT_ID` - UUID of the task attempt
- `VK_ATTEMPT_BRANCH` - Branch name for the attempt (e.g., `vk/branch-name`)

1. **Created `crates/executors/src/env.rs`** - New module containing `ExecutionEnv` struct with:
   - `HashMap<String, String>` to store env vars
   - `insert()` method to add env vars
   - `apply_to_command()` method to apply env vars to a `tokio::process::Command`

2. **Updated `crates/executors/src/actions/mod.rs`** - Modified `Executable` trait to accept `Option<&ExecutionEnv>` parameter

3. **Updated `crates/executors/src/executors/mod.rs`** - Modified `StandardCodingAgentExecutor` trait's `spawn()` and `spawn_follow_up()` to accept `Option<&ExecutionEnv>` parameter

4. **Updated all action implementations**:
   - `coding_agent_initial.rs` - forwards env to agent spawn
   - `coding_agent_follow_up.rs` - forwards env to agent spawn
   - `script.rs` - applies env vars to script commands

5. **Updated all executor implementations** to apply env vars:
   - `claude.rs`, `amp.rs`, `gemini.rs`, `codex.rs`, `qwen.rs`, `droid.rs`, `cursor.rs`, `copilot.rs`, `opencode.rs`
   - Also updated `acp/harness.rs` which is used by gemini and qwen

6. **Updated `crates/local-deployment/src/container.rs`** - Modified `start_execution_inner()` to:
   - Load task and project context from database
   - Create `ExecutionEnv` with the four `VK_*` variables
   - Pass the env to `executor_action.spawn()`

* Cleanup script changes for task attempt 4dc9b26c-c637-465a-ae71-644c828ea8f7

* The refactoring is complete. I've successfully updated the `env` parameter from `Option<&ExecutionEnv>` to `&ExecutionEnv` across all relevant files:

**Summary of changes:**

1. **Trait updates:**
   - `Executable` trait in `crates/executors/src/actions/mod.rs`
   - `StandardCodingAgentExecutor` trait in `crates/executors/src/executors/mod.rs`

2. **Action implementations:**
   - `coding_agent_initial.rs`
   - `coding_agent_follow_up.rs`
   - `script.rs`

3. **Executor implementations (all 10 executors):**
   - `claude.rs` - spawn, spawn_follow_up, spawn_internal
   - `amp.rs` - spawn, spawn_follow_up
   - `gemini.rs` - spawn, spawn_follow_up
   - `codex.rs` - spawn, spawn_follow_up, spawn_inner
   - `qwen.rs` - spawn, spawn_follow_up
   - `droid.rs` - spawn, spawn_follow_up, spawn_droid helper
   - `cursor.rs` - spawn, spawn_follow_up
   - `copilot.rs` - spawn, spawn_follow_up
   - `opencode.rs` - spawn, spawn_follow_up
   - `acp/harness.rs` - spawn_with_command, spawn_follow_up_with_command

4. **Call site:**
   - `container.rs` in `start_execution_inner` - changed `Some(&env)` to `&env`

All tests pass (137 tests) and clippy reports no warnings.

* All tests pass. The change is complete.

**Summary**: Added `VK_PROJECT_ID` to the environment variables injected when launching coding agents.

The environment variables now include:
- `VK_PROJECT_NAME` - project name
- `VK_PROJECT_ID` - project UUID (newly added)
- `VK_TASK_ID` - task UUID
- `VK_ATTEMPT_ID` - attempt UUID
- `VK_ATTEMPT_BRANCH` - git branch name for the attempt

* undo ts-rs bindings

* All 147 tests pass. The rebase conflict has been resolved successfully.

**Summary:**
- Resolved the rebase conflict in `crates/local-deployment/src/container.rs`
- The conflict was in the imports section where:
  - `origin/main` added `InterruptSender` to the executors import
  - Our branch added `env::ExecutionEnv` import
- Resolution: Combined both changes to keep `ExecutionEnv` import AND `InterruptSender`
- All tests pass (147 tests)

The branch `vk/4dc9-inject-env-vars` is now rebased onto `origin/main` with the complete environment variable injection feature, including:
- `VK_PROJECT_NAME`
- `VK_PROJECT_ID`
- `VK_TASK_ID`
- `VK_ATTEMPT_ID`
- `VK_ATTEMPT_BRANCH`

* remove bindings (again)
2025-12-04 15:55:55 +00:00
Alex Netsch
9f4fabc285 Add agent interrupts (#1408)
* Add interrupt sender to gracefully stop claude code

* Remove debug logs

* Lint

* interrupt agent in read loop

* rm comments

* Revert claude client arch change
2025-12-04 15:36:34 +00:00
Alex Netsch
ef1ba1b4bb Glob copy files (#1420)
* Simplify glob file search

Switch to globwalk

* Cleanup

* Fix single file continue, add timeout to copy files

* Remove error in copy file dropdown when no match found

* Remove error message for file search text are, remove dead code

* Move copy logic to copy.rs
2025-12-04 15:36:14 +00:00
Louis Knight-Webb
9bfaa6dde5 Add button to copy all process logs (vibe-kanban) (#1429)
* Done! I've implemented the "Copy all process logs" button for the `ViewProcessesDialog`. Here's a summary of the changes:

**Files modified:**

1. **`ProcessLogsViewer.tsx`** - Added `onLogsChange` callback prop and exported the `LogEntry` type

2. **`ProcessesTab.tsx`** - Added `onLogsChange` prop that passes through to ProcessLogsViewer, and clears logs when no process is selected

3. **`ViewProcessesDialog.tsx`** - Added the copy button with:
   - State management for logs and copied feedback
   - Copy button in the dialog header (right-aligned)
   - Tooltip showing "Copy logs" / "Copied!"
   - Button disabled when no logs are available
   - Uses `Copy`/`Check` icons from lucide-react

4. **i18n files** (en, es, ko, ja) - Added translation keys:
   - `copyLogs`: "Copy logs"
   - `logsCopied`: "Copied!"

**Behavior:**
- The copy button appears in the dialog header next to the title
- When clicked, it copies all log content (joined by newlines) to clipboard
- Shows a checkmark icon for 2 seconds after successful copy
- Button is disabled when viewing the process list (no logs selected)

* Cleanup script changes for task attempt 2060681f-e4c3-46a7-aca3-3e9705b53248

* Fixed! I wrapped the `Tooltip` component in `TooltipProvider` as required by shadcn/ui. The error should now be resolved - the copy button should work properly.

* Done! I've made the following changes:

1. Removed the `Tooltip`, `TooltipProvider`, `TooltipContent`, and `TooltipTrigger` components
2. Added `mr-8` margin to position the button left of the dialog's native close button
3. Added `text-green-500` to the `Check` icon for green success feedback

The button should now be properly positioned and show a green checkmark when logs are copied.

* Done! Changed `text-green-500` to `text-success` so the check icon uses the theme's success color instead of a hardcoded green.

* Done! I've fixed the vertical alignment by:

1. Moving the button outside the `DialogHeader` and positioning it absolutely
2. Using `absolute right-12 top-4` to place it exactly to the left of the close button (which is at `right-4 top-4`)
3. Using `h-4 w-4` to match the close button's icon size
4. Added `rounded-sm opacity-70 hover:opacity-100` to match the close button's styling

The copy button should now be perfectly aligned with the close button.

* Done! I've moved the copy button to `ProcessesTab` next to the "Back to list" button. The changes:

1. **Removed** the absolute-positioned icon button from `ViewProcessesDialog`
2. **Added** a text button "Copy logs" / "Copied!" in `ProcessesTab` next to "Back to list"
3. **Moved** the i18n keys from `viewProcessesDialog` to `processes` section
4. The button uses the same styling as the "Back to list" button for consistency
5. Shows green "Copied!" text for 2 seconds after successful copy

* Done! I've made the following changes to address the review comment:

1. **`ProcessLogsViewer.tsx`**: Removed the `export` keyword from `LogEntry` type - it's now internal to the file
2. **`ProcessesTab.tsx`**: Changed import from `LogEntry` to `PatchType` from `shared/types`, and updated the state and callback types accordingly

The type check passes successfully.

* Done! I've addressed the review comment by:

1. **Lifted `useLogStream` to `ProcessesTab`** - Now `ProcessesTab` calls `useLogStream(selectedProcess?.id ?? '')` directly, giving it direct access to the logs for the copy button

2. **Removed the hacky `onLogsChange` callback** - No more `useEffect` to propagate logs up via callback

3. **Using `ProcessLogsViewerContent` directly** - `ProcessesTab` now imports and uses `ProcessLogsViewerContent` with the logs from `useLogStream`

4. **Kept `ProcessLogsViewer` as a simpler component** - The default export still exists for other potential consumers, but it's now a simple wrapper without the callback prop

The data flow is now cleaner:
- `ProcessesTab` owns the log data via `useLogStream`
- `ProcessLogsViewerContent` is a pure presentation component
- No callback prop threading needed

* Done! I've added proper translations for the i18n keys:

- **Spanish (es):** "Copiar registros" / "¡Copiado!"
- **Korean (ko):** "로그 복사" / "복사됨!"
- **Japanese (ja):** "ログをコピー" / "コピーしました!"
2025-12-04 15:33:38 +00:00
Britannio Jarrett
7989168e7a bump amp (vibe-kanban) (#1422)
* I have bumped the `amp` version to `0.0.1764705684-g95eb77` in [crates/executors/src/executors/amp.rs](file:///private/var/folders/fr/0c4ky3392mb4yz5knw_wjdd00000gn/T/vibe-kanban/worktrees/5070-bump-amp/crates/executors/src/executors/amp.rs).

I verified the changes by running `cargo check --workspace`, which passed successfully.

* I have updated the `amp` version to `0.0.1764777697-g907e30` in [crates/executors/src/executors/amp.rs](file:///private/var/folders/fr/0c4ky3392mb4yz5knw_wjdd00000gn/T/vibe-kanban/worktrees/5070-bump-amp/crates/executors/src/executors/amp.rs).

I verified the changes by running `cargo check --workspace` (after resolving a transient `libsqlite3-sys` build issue).
2025-12-04 15:12:17 +00:00
Louis Knight-Webb
fa4a8f9e22 Cleanup task follow up section loading (vibe-kanban) (#1430)
Solve component completely unmounting when navigating between task attempts
2025-12-04 14:56:27 +00:00
Louis Knight-Webb
b6a4f76e43 Both TypeScript and ESLint pass. The fix is complete. (#1427)
**Summary**: Added a single guard condition to the `useEffect` that syncs `localMessage` from scratch data. When `isTextareaFocused` is true, the effect now returns early, preventing the cursor jump issue caused by the WebSocket sync overwriting the local message while the user is actively typing.
2025-12-04 13:06:46 +00:00
Alex Netsch
e1cb24923a All done! I've updated the copy, edit, and delete buttons in frontend/src/components/ui/wysiwyg.tsx to use semantic colors: (#1412)
**Changes made:**
- Button backgrounds: `bg-foreground` → `bg-muted`
- Icon colors: `text-background` → `text-muted-foreground`
- Check icon (copied state): `text-green-600` → `text-success`

These semantic colors will now adapt correctly to both light and dark modes, following the established patterns in the codebase.
2025-12-04 12:35:30 +00:00