Commit Graph

105 Commits

Author SHA1 Message Date
GitHub Action
d1d0b7eacd chore: bump version to 0.0.155 2026-01-17 09:43:17 +00:00
GitHub Action
4ffd7c92b9 chore: bump version to 0.0.154 2026-01-16 17:57:36 +00:00
Louis Knight-Webb
d941e9a5e0 Add integrated terminal with PTY backend and xterm.js frontend (Vibe Kanban) (#2104)
* integrated terminal

* ci

* persist terminal

* Done! I've moved the TerminalPanelContainer from the main panel area to the right sidebar. Here's a summary of the changes:

- Added `isTerminalVisible: boolean` to global state (defaults to `true`)
- Added `toggleTerminal()` and `setTerminalVisible(value)` actions
- Added `isTerminalVisible` to the persisted state and the `useWorkspacePanelState` hook

- Imported `TerminalPanelContainer` and `useUiPreferencesStore`
- Restructured the component to always include a terminal section at the bottom (when not in create mode and `isTerminalVisible` is true)
- Dynamic flex ratios:
  - With upper content + terminal: flex-4 (content) / flex-2 (git) / flex-4 (terminal)
  - Without upper content + terminal: flex-3 (git) / flex-7 (terminal)
  - When terminal is hidden: original ratios preserved

- Removed the `TerminalPanelContainer` import
- Removed the TERMINAL case from the right main panel rendering

- Added `isTerminalVisible` to `ActionVisibilityContext` interface
- Updated `ToggleTerminalMode` action to use `toggleTerminal()` and check `isTerminalVisible`

- Added `isTerminalVisible` from `panelState` to the visibility context

The terminal now appears permanently at the bottom of the right sidebar (when visible), and the toggle button collapses/expands just the terminal section within the sidebar. The visibility state is persisted to localStorage.

* Frontend ESLint passes with no errors. The backend Rust error (`crates/utils/src/shell.rs:31`) is a pre-existing issue in the codebase, not related to my changes.

* `cargo check` passes now. The fix was adding `.to_path_buf()` to convert the `&Path` reference to an owned `PathBuf`.

* The code compiles. Done! I've added three environment variables in `crates/local-deployment/src/pty.rs:73-75`:

1. `ZDOTDIR=/nonexistent` - prevents zsh from loading `~/.zshrc`
2. `PS1="$ "` - sets the bash prompt
3. `PROMPT="$ "` - sets the zsh prompt

The terminal prompt will now show just `$ ` instead of `lkw@Louiss-MacBook-Pro vibe-kanban %`. Run `pnpm run dev:qa` and open the terminal panel to verify.

* Cleanup script changes for workspace 928e696e-5f40-4603-9227-798f0520e07f

* Done! The fix is simpler - using `cmd.arg("-f")` to tell zsh/bash to skip loading config files. This:

1. Removes the `ZDOTDIR=/nonexistent` that was causing errors
2. Adds `-f` flag which skips `.zshrc`/`.bashrc` loading
3. Keeps `PS1` and `PROMPT` env vars which will now be respected

Run `pnpm run dev:qa` and open the terminal to verify the prompt shows `$ `.

* Cleanup script changes for workspace 928e696e-5f40-4603-9227-798f0520e07f

* I've implemented the terminal theme integration. Here's a summary of the changes:

## Changes Made

**1. Created `frontend/src/utils/terminalTheme.ts`**
- `hslToHex()` function to convert HSL CSS variable format (`"210 40% 98%"`) to hex colors
- `getCssVariable()` helper to read CSS variables from the `.new-design` element
- `getTerminalTheme()` function that builds an xterm.js `ITheme` object from CSS variables:
  - Uses `--console-background` and `--console-foreground` for main colors
  - Uses `--console-success` and `--console-error` for green/red ANSI colors
  - Provides appropriate ANSI color palettes for both light and dark modes

**2. Updated `frontend/src/components/ui-new/terminal/XTermInstance.tsx`**
- Imported `useTheme` hook and `getTerminalTheme` utility
- Replaced hardcoded Tokyo Night theme with dynamic `getTerminalTheme()` call
- Added effect to update terminal theme when app theme changes (`terminal.options.theme = getTerminalTheme()`)

The terminal will now:
- Initialize with colors matching the current theme
- Automatically update colors when switching between light and dark mode
- Use the console color variables defined in `index.css`

* Cleanup script changes for workspace 928e696e-5f40-4603-9227-798f0520e07f

* Now I understand the issue clearly. Here are the relevant variables:

| Variable | Light Mode | Dark Mode | Purpose |
|----------|------------|-----------|---------|
| `--_primary` | `0 0% 5%` (dark) | `240 4.8% 95.9%` (light) | Button background - **inverted** |
| `--_console-background` | `0 0% 100%` (white) | `0 0% 0%` (black) | Terminal background - **correct** |
| `--_console-foreground` | `0 0% 5%` (dark) | `210 40% 98%` (light) | Terminal text - **correct** |
| `--bg-primary` | `0 0% 100%` (white) | `0 0% 13%` (dark gray) | Page background |

The code was changed to use `--primary` but that's the wrong variable. For the terminal, you should use:
- `--console-background` / `--_console-background` for the background
- `--console-foreground` / `--_console-foreground` for the text

Or if you prefer to match other UI elements:
- `--bg-primary` for background
- `--text-high` for foreground text

Which approach would you prefer? The original `--console-*` variables were specifically designed for terminal styling, or we can use `--bg-primary`/`--text-high` to match the general UI background.

* Cleanup script changes for workspace 928e696e-5f40-4603-9227-798f0520e07f

* Done. The terminal will now use `--bg-primary` for the background and `--text-high` for the foreground text. This means:

- **Light mode**: White background (`0 0% 100%`) with dark text (`0 0% 5%`)
- **Dark mode**: Dark gray background (`0 0% 13%`) with light text (`0 0% 96%`)

* Done. The terminal will now use `--bg-secondary` for the background and `--text-high` for the foreground text. This means:

- **Light mode**: Light gray background (`0 0% 95%`) with dark text (`0 0% 5%`)
- **Dark mode**: Darker gray background (`0 0% 11%`) with light text (`0 0% 96%`)

* Let me know if you find any issues during testing or need adjustments!

* Cleanup script changes for workspace 928e696e-5f40-4603-9227-798f0520e07f

* terminal

* sidebar cleanup

* fix chat collapse

Amp-Thread-ID: https://ampcode.com/threads/T-019bc754-8db9-712a-a915-58d74d210cad
Co-authored-by: Amp <amp@ampcode.com>

* for the terminal on windows we need to default to powershell if avalibale for the pty  (vibe-kanban 049dbf73)

only if powershell.exe cannot be resolved, we should use cmd.

* he colour theme used for the terminal ui isn't visible enough in light mode (vibe-kanban 5f50878a)

t I think we either don't override the ANSI colour mapping with our own, or it's not contrasted enough

* fmt

---------

Co-authored-by: Gabriel Gordon-Hall <ggordonhall@gmail.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: Solomon <abcpro11051@disroot.org>
2026-01-16 17:56:28 +00:00
GitHub Action
7b465cbae6 chore: bump version to 0.0.153 2026-01-15 10:58:39 +00:00
GitHub Action
c861de8b29 chore: bump version to 0.0.152 2026-01-14 11:12:48 +00:00
Theo Browne
cd579ca791 Replace allotment with react-resizable-panels and simplify layout (#2029)
* merge

* switch out panel lib

* fmt

* remove allotment dep

* bump lock

* The position of the react resizable panel is lost when the page is reloaded in (vibe-kanban 6ac32e23)

`WorkspacesLayout.tsx` , but should be stored in `useUiPreferencesStore.ts`

`vibe-kanban/frontend/src/components/ui-new/containers/WorkspacesLayout.tsx`

`vibe-kanban/frontend/src/stores/useUiPreferencesStore.ts`

* remove redundant type

* add dep

---------

Co-authored-by: Louis Knight-Webb <louis@bloop.ai>
2026-01-14 11:04:11 +00:00
Theo Browne
2af42a7600 Set up React Compiler (#2030)
- Added required deps: `react-compiler-runtime` + `babel-plugin-react-compiler` in `frontend/package.json:70` and `frontend/package.json:99`, plus `remote-frontend/package.json:20` and `remote-frontend/package.json:30` (lockfile updated in `pnpm-lock.yaml`).
2026-01-14 09:11:07 +00:00
GitHub Action
d17c41a73d chore: bump version to 0.0.151 2026-01-13 18:32:23 +00:00
GitHub Action
6d5c8ac486 chore: bump version to 0.0.150 2026-01-12 21:53:09 +00:00
GitHub Action
2c474d689c chore: bump version to 0.0.149 2026-01-12 16:57:54 +00:00
GitHub Action
bd09ba8bd0 chore: bump version to 0.0.148 2026-01-09 18:36:00 +00:00
GitHub Action
3ad03a0a99 chore: bump version to 0.0.147 2026-01-09 14:46:16 +00:00
Louis Knight-Webb
527febdc52 Workspaces FE (#1733) 2026-01-08 22:14:38 +00:00
GitHub Action
fe2215ba85 chore: bump version to 0.0.146 2026-01-08 19:40:01 +00:00
GitHub Action
ae852b297f chore: bump version to 0.0.145 2026-01-08 18:46:22 +00:00
GitHub Action
edef39c3fb chore: bump version to 0.0.144 2026-01-06 13:14:34 +00:00
GitHub Action
f99d2f06f2 chore: bump version to 0.0.143 2025-12-29 18:01:52 +00:00
GitHub Action
033ae2f1c6 chore: bump version to 0.0.142 2025-12-21 17:48:14 +00:00
GitHub Action
bcbe7aca69 chore: bump version to 0.0.141 2025-12-20 14:13:04 +00:00
GitHub Action
ca2b578231 chore: bump version to 0.0.140 2025-12-19 18:12:47 +00:00
GitHub Action
84ea4b71ee chore: bump version to 0.0.139 2025-12-19 09:32:22 +00:00
GitHub Action
fd210419cd chore: bump version to 0.0.138 2025-12-17 15:24:54 +00:00
GitHub Action
37af711712 chore: bump version to 0.0.137 2025-12-16 14:24:51 +00:00
Louis Knight-Webb
7f9f1433af Store binaries in Cloudflare R2 instead of bundling in npm package (Vibe Kanban) (#1554)
* All changes are complete. Let me provide a summary of what was implemented:

## Summary

I've implemented the Cloudflare R2 binary storage feature. Here are the changes:

### Files Created
- **`npx-cli/bin/download.js`** - New module that handles downloading binaries from R2 with:
  - SHA-256 checksum verification
  - Progress reporting
  - Redirect handling
  - Local caching in `~/.vibe-kanban/bin/{version}/{platform}/`

### Files Modified

1. **`npx-cli/bin/cli.js`**
   - Converted to async for on-demand downloads
   - Downloads binaries from R2 instead of using bundled files
   - Non-blocking update check shows notice if newer version available
   - Caches binaries locally per version/platform

2. **`npx-cli/package.json`**
   - Removed `"dist"` from `files` array (package now ~15KB instead of ~150MB)

3. **`.github/workflows/pre-release.yml`**
   - Added new `upload-to-r2` job that:
     - Downloads all platform packages from artifacts
     - Generates manifest.json with SHA-256 checksums for each binary
     - Uploads binaries to R2 at `binaries/v{version}/{platform}/{binary}.zip`
     - Updates global manifest with latest version
   - Modified `create-prerelease` job to:
     - Depend on `upload-to-r2` instead of `package-npx-cli`
     - Inject R2 public URL into download.js via `sed`
     - No longer download/bundle binaries in the npm package

### Required GitHub Secrets

You'll need to add these secrets to your repository:
- `R2_BINARIES_ACCESS_KEY_ID`
- `R2_BINARIES_SECRET_ACCESS_KEY`
- `R2_BINARIES_ENDPOINT` (e.g., `https://<account_id>.r2.cloudflarestorage.com`)
- `R2_BINARIES_BUCKET`
- `R2_BINARIES_PUBLIC_URL` (the public URL for your R2 bucket, e.g., custom domain or public R2 URL)

### R2 Bucket Structure
```
binaries/
  manifest.json                    # {"latest": "0.0.135"}
  v0.0.135/
    manifest.json                  # Per-version manifest with checksums
    linux-x64/
      vibe-kanban.zip
      vibe-kanban-mcp.zip
      vibe-kanban-review.zip
    ...
```

* Done! I've updated the implementation to use full tags (with timestamps) instead of just version numbers. Here's a summary of what changed:

## Changes Made

1. **`npx-cli/bin/download.js`**:
   - Added `BINARY_TAG` constant (placeholder `__BINARY_TAG__`)
   - Changed `ensureBinary()` to use `BINARY_TAG` instead of accepting version as parameter
   - Cache paths now use the tag: `~/.vibe-kanban/bin/{tag}/{platform}/`

2. **`npx-cli/bin/cli.js`**:
   - Updated to import `BINARY_TAG` from download.js
   - Cache directory now uses `BINARY_TAG` instead of `CLI_VERSION`
   - Updated `ensureBinary()` call to not pass version

3. **`.github/workflows/pre-release.yml`**:
   - `upload-to-r2` job now uses `new_tag` instead of `new_version` for R2 paths
   - Binaries are stored at `binaries/{tag}/{platform}/{binary}.zip`
   - Global manifest stores the full tag: `{"latest": "v0.0.135-20251215122030"}`
   - `create-prerelease` job now injects both `__R2_PUBLIC_URL__` and `__BINARY_TAG__`

This allows multiple pre-releases to coexist in R2 (e.g., `v0.0.135-20251215122030` and `v0.0.135-20251215100000`), making rollbacks easy.

* chore: bump version to 0.0.136

---------

Co-authored-by: GitHub Action <action@github.com>
2025-12-15 23:48:27 +00:00
Louis Knight-Webb
e16602cc0f Downgrade version 2025-12-15 22:12:03 +00:00
Louis Knight-Webb
8a623ee924 Larger runner (#1552)
* Use a larger ubuntu runner

* chore: bump version to 0.0.136

---------

Co-authored-by: Solomon <abcpro11051@disroot.org>
Co-authored-by: GitHub Action <action@github.com>
2025-12-15 22:01:46 +00:00
GitHub Action
5710cc3371 chore: bump version to 0.0.135 2025-12-15 13:37:12 +00:00
GitHub Action
dffa4d9621 chore: bump version to 0.0.134 2025-12-11 19:12:50 +00:00
Gabriel Gordon-Hall
2366e4ad23 chore: remove unused code and dependencies identified by knip (Vibe Kanban) (#1499)
* Here's a summary of what was cleaned up:

## Removed Unused Files (11 files)
- `frontend/src/components/layout/ResponsiveTwoPane.tsx`
- `frontend/src/components/OrgMemberAvatars.tsx`
- `frontend/src/components/tasks/FollowUpStatusRow.tsx`
- `frontend/src/components/tasks/TaskRelationshipCard.tsx`
- `frontend/src/components/tasks/TaskRelationshipViewer.tsx`
- `frontend/src/components/ui/image-upload-section.tsx`
- `frontend/src/components/ui/tabs.tsx`
- `frontend/src/components/ui/title-description-editor.tsx`
- `frontend/src/lib/caretPosition.ts`
- `frontend/src/utils/markdownImages.ts`
- `remote-frontend/src/App.tsx`

## Removed Unused Dependencies (10 packages from frontend/package.json)
- `@dnd-kit/modifiers`
- `@lexical/utils`
- `@radix-ui/react-tabs`
- `@tailwindcss/typography`
- `@tanstack/react-devtools`
- `@tanstack/react-form-devtools`
- `@types/react-window`
- `react-use-websocket`
- `react-window`
- `zod`

## Removed Unused Exports
- `useTabNavigation` hook from `TabNavigationContext.tsx`

## Not Removed (false positives or intentional)
- `shared/types.ts` - auto-generated file used throughout the project
- `@rjsf/shadcn` - used in tailwind.config.js content paths
- `wa-sqlite` - used in vite.config.ts optimizeDeps
- `eslint-plugin-prettier`, `vite` (root) - kept per user preference
- Barrel re-exports in index.ts files (dialogs, hooks, ui) - intentional public APIs
- Type exports - part of public API contracts

* Done. Restored `remote-frontend/src/App.tsx` as a placeholder.

* Update pnpm lockfile after removing unused dependencies

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 12:45:04 +00:00
GitHub Action
b37672a475 chore: bump version to 0.0.133 2025-12-11 11:28:42 +00:00
GitHub Action
d0392e6d5e chore: bump version to 0.0.132 2025-12-09 12:32:34 +00:00
GitHub Action
e1c9c15f43 chore: bump version to 0.0.131 2025-12-07 14:13:05 +00:00
GitHub Action
9c434822d6 chore: bump version to 0.0.130 2025-12-06 19:27:31 +00:00
GitHub Action
d81be475c5 chore: bump version to 0.0.129 2025-12-05 10:50:01 +00:00
GitHub Action
6805be6962 chore: bump version to 0.0.128 2025-12-04 17:31:57 +00:00
GitHub Action
c92b769fe1 chore: bump version to 0.0.127 2025-12-03 13:11:58 +00:00
Solomon
a763a0eae9 Migrate task sharing to ElectricSQL + Tanstack DB (#1379)
* WIP - Migrate task sharing to ElectricSQL + Tanstack DB

* WIP auth proxy

* Simplify electric host

* Electric token

Only set in cloud. Acts like a DB password.

* Add org membership validation

* fix Electric auth param

* trigger dev deployment

* Validate where clause

* Simplify check macro

* Cleanup

* Reduce Electric Postgres privileges

Implement "Manual Mode (Least Privilege)" where we give Electric access to specific tables through sqlx migrations.
https://electric-sql.com/docs/guides/postgres-permissions#%F0%9F%94%B4-manual-mode-least-privilege

* Fetch task assignee user name

* Create a local task to link with shared task assigned to current user

* chore: code cleanup

* chore: code cleanup

* chore: unify task status serialization format

use lowercase format

* lint fix

* chore: remove backend ws client

* chore: remove unused deps

* Disable editing shared tasks when user isn logged out

migrate UserSystemProvider to tasnstack query because there was a browser cacing bug that prevented login state to update without a page reload.

* auto-unlink non-existing shared tasks

* Invalidate useLiveQuery cache on sign-in change

Also display local shared tasks when user is signed out

* set VITE_VK_SHARED_API_BASE in CI

* rebase cleanup

* re-order migration

* increase node build memory in CI

* Setup CORS properly

* Prevent linking non-existing shared tasks

* Fix login dialog in background (#1413)

* Unlink already linked projects when linking again (vibe-kanban) (#1414)

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

## Summary

Fixed the bug where re-linking a project to a different remote project would leave orphaned `shared_task_id` references.

**File modified:** `crates/server/src/routes/projects.rs:167-208`

**Change:** The `apply_remote_project_link` function now:
1. Fetches the existing project to check if it's already linked
2. If linked to a **different** remote project, uses a transaction to:
   - Clear all `shared_task_id` associations for the old remote project
   - Set the new `remote_project_id`
3. If no existing link, sets the new link directly
4. If linking to the **same** remote project, does nothing (already linked)

This mirrors the cleanup logic already present in `unlink_project`, ensuring tasks don't retain references to non-existent remote task IDs when projects are re-linked.

* You're right, let me think more carefully about the transaction.

Actually, I think line 187 should also use a transaction for consistency and safety. Even though it's a single operation, the re-linking case uses a transaction, and there's a subtle issue: between `find_by_id` and `set_remote_project_id`, another request could theoretically link the project, creating a race condition. Using a transaction would provide row-level locking.

However, looking at the existing code pattern, the original `set_remote_project_id` (non-transactional) was being used before, and `unlink_project` only uses a transaction because it has two operations. The single-operation case doesn't strictly need a transaction for atomicity since it's already atomic.

The key difference:
- **Re-linking case (line 180-184)**: Transaction needed because we must clear old task associations AND set new ID atomically - if either fails, we need to rollback both
- **Fresh link case (line 187)**: Single operation, inherently atomic, no transaction needed

The code is correct as-is. Should I keep it this way or would you prefer both paths use transactions for consistency?

* Done. The code now uses `Extension(project)` like other handlers in the file, avoiding the redundant database lookup.

* Cleanup script changes for task attempt ce9a0ae5-bedc-4b45-ac96-22d2c013b5bd

* Done. Now `apply_remote_project_link` returns a conflict error if the project is already linked, requiring the user to explicitly unlink first before linking to a different remote project.

* Both pass. Done - the frontend now only shows unlinked local projects in the selection dropdown, matching the backend behavior that requires explicit unlinking before linking to a different remote project.

* prevent modification of shared task offline

* reset oauth modal on login/logout events

* darken success alert font colour (#1416)

---------

Co-authored-by: Alex Netsch <alex@bloop.ai>
Co-authored-by: Louis Knight-Webb <louis@bloop.ai>
Co-authored-by: Gabriel Gordon-Hall <gabriel@bloop.ai>
2025-12-03 13:11:00 +00:00
GitHub Action
72f2ab1320 chore: bump version to 0.0.126 2025-12-02 15:22:38 +00:00
Louis Knight-Webb
d3317f68ff WYSIWYG editor (#1397)
* Replace follow up section with WYSIWYG (vibe-kanban 55b58b24)

frontend/src/components/tasks/TaskFollowUpSection.tsx
frontend/src/components/ui/wysiwyg.tsx

* Delete all usage of image chip component (vibe-kanban 5c90eac1)

frontend/src/components/ui/wysiwyg/image-chip-markdown.ts
frontend/src/components/ui/wysiwyg/image-chip-node.tsx

* Trigger file / tag picker from WYSIWYG (vibe-kanban 3e73cf53)

LexicalTypeaheadMenuPlugin
frontend/src/components/ui/wysiwyg.tsx
frontend/src/components/ui/file-search-textarea.tsx (old)

* Editor state should be saved as JSON (vibe-kanban 4f9eec74)

Instead of saving markdown, we should save JSON eg `editorState.toJSON();`.

This will enable us to properly serialize custom Elements in the future.

frontend/src/components/ui/wysiwyg.tsx
frontend/src/components/tasks/follow-up/FollowUpEditorCard.tsx

* In WYSIWYG, the search dialog can exceed screen (vibe-kanban 25337029)

When searching for tags/files. Sometimes the dialog is cut off the bottom of the screen.

frontend/src/components/ui/wysiwyg.tsx

* Use WYSIWYG for tasks (vibe-kanban 5485d481)

Currently used for follow ups, we should also use for task
frontend/src/components/tasks/follow-up/FollowUpEditorCard.tsx
frontend/src/components/dialogs/tasks/TaskFormDialog.tsx
frontend/src/components/ui/wysiwyg.tsx

* Keyboard shortcuts when typing in WYSIWYG (vibe-kanban 04bd70bc)

We used to have a callback for:
- CMD+Enter
- Shift+CMD+Enter

In create task dialog:
- CMD+Enter = create and start
- Shift+CMD+Enter = create without start

In follow up:
- CMD+Enter = Follow up
- Shift+CMD+Enter = nothing

frontend/src/components/tasks/follow-up/FollowUpEditorCard.tsx
frontend/src/components/ui/wysiwyg.tsx
frontend/src/components/dialogs/tasks/TaskFormDialog.tsx

Ideally we can use the relevant Lexical plugin and callbacks, cleaning up the old `@/keyboard` hooks which no longer work.

* Trigger file / tag picker from WYSIWYG (vibe-kanban 3e73cf53)

LexicalTypeaheadMenuPlugin
frontend/src/components/ui/wysiwyg.tsx
frontend/src/components/ui/file-search-textarea.tsx (old)

* Use WYSIWYG for tasks (vibe-kanban 5485d481)

Currently used for follow ups, we should also use for task
frontend/src/components/tasks/follow-up/FollowUpEditorCard.tsx
frontend/src/components/dialogs/tasks/TaskFormDialog.tsx
frontend/src/components/ui/wysiwyg.tsx

* Introduce new user-message table and struct (vibe-kanban 09116513)

{
ID,
message_json: Value,
message_md: String
}

We'll also need some endpoints to CRUD them.

crates/db
crates/server

* Stream individual scratch (vibe-kanban 321b50a1)

crates/server/src/routes/scratch.rs

It should be possible to listen for updates made to a single scratch

* Refactor useScratch (vibe-kanban 51ea2317)

To consolidate the API stuff into frontend/src/lib/api.ts

* Update scratch API (vibe-kanban 878f40c5)

Primary key should come from: ID and scratch type combination

The frontend will provide both.

Scratch IDs should not be generated on the backend.

* Remove all usage of hook from follow up (vibe-kanban 2d691095)

Use of hooks that reside in frontend/src/hooks/follow-up/* should be removed, except for frontend/src/hooks/follow-up/useFollowUpSend.ts

From: frontend/src/components/tasks/TaskFollowUpSection.tsx

* Task follow up should use scratch (vibe-kanban d37d3b18)

The current task attempt ID should be used to save the content of the follow up box as scratch.

frontend/src/components/tasks/TaskFollowUpSection.tsx

* Use just markdown serialization for scratch (vibe-kanban 42f5507f)

frontend/src/hooks/useScratch.ts
crates/server/src/routes/scratch.rs
crates/db/src/models/scratch.rs

We are currently storing JSON + MD, however we should now store just MD and import/export the markdown into lexical.

* Consolidate MarkdownRenderer and WYSIWYG (vibe-kanban f61a7d40)

Currently we have an old implementation of markdown rendering in frontend/src/components/ui/markdown-renderer.tsx

But we have recently introduced the new WYSIWYG editor frontend/src/components/ui/wysiwyg.tsx

wysiwyg takes JSON as input, not raw markdown.

Ideally we could just use a single component and have a read only mode, removing Markdown Renderer and its dependencies and custom styling.

* WYSIWYG images (vibe-kanban 8cc3c0e7)

Create a Lexical plugin for images, with markdown import/export support.

Visually, images should be displayed as a small thumbnail with the path truncated.

Export/import should support standard markdown image format.

* Get image metadata endpoint (vibe-kanban 2c0dfbff)

Task attempt endpoint to get info, given the relative URL of an image.

We will also need an image that acts as a proxy to the file.

Info to return:
- Whether file exists
- Size of image
- Format
- File name
- Path
- URL to get image (the proxy URL)

The images are stored in the `.vibe-images` folder, relative to the task attempt container.

crates/server/src/routes/task_attempts.rs

* Inject relative path not absolute to image (vibe-kanban 007d589b)

Currently when we upload an image, it adds markdown with the full relative path of the image, eg:
/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban-dev/worktrees/2702-testing-images/.vibe-images/b01e6b02-dbd0-464c-aa9f-a42a89f6d67b.png

However, we should change this to be the path relative to the worktree eg .vibe-images/b01e6b02-dbd0-464c-aa9f-a42a89f6d67b.png

* Improve image in WYSIWYG (vibe-kanban 53de9071)

frontend/src/components/ui/wysiwyg/nodes/image-node.tsx

Check if the image comes from `./vibe-images/...`, if so:
Use the API endpoints to get and display metadata.
Use the image proxy to display the thumbnail image.

Do not render non `.vibe-images` images, instead just show the path and show a question icon as a thumbnail.

* rebase fixes

* Add Lexical toolbar (vibe-kanban b8904ad9)

frontend/src/components/ui/wysiwyg.tsx

* Clicking image once should open dialog (vibe-kanban aab2e6f4)

frontend/src/components/ui/wysiwyg/nodes/image-node.tsx

* Style quotes better (vibe-kanban 54718e76)

frontend/src/components/ui/wysiwyg.tsx

* Auto detect multi-line code blocks (vibe-kanban ce33792d)

Currently when I type triple backticks it doesn't create a multi-line code block

frontend/src/components/ui/wysiwyg.tsx

* Update how image upload works on the backend (vibe-kanban 62d97322)

I am only referring to the image upload for sending a follow up message.

Currently we:
- upload an image
- when a follow up is made, send file IDs
- copy the image into container based on those file IDs

We should tweak this so that:
- upload an image
- immediately the image is copied into container
- the image file location is added to the markdown of the follow up message (on the frontend)
- when user makes follow up, the image is already in the container

crates/server/src/routes/images.rs
crates/server/src/routes/task_attempts/images.rs

* Use @lexical/code to render code (vibe-kanban 60605a2c)

frontend/src/components/ui/wysiwyg.tsx

* Save variant in scratch (vibe-kanban 06e1e255)

frontend/src/components/tasks/TaskFollowUpSection.tsx

* prepare db

* Solve follow up loading when empty (vibe-kanban 1991bf3d)

frontend/src/components/tasks/TaskFollowUpSection.tsx
Currently the loader shows when the scratch data is loading, but also when there is no scratch data - which means the user can never see the follow up inputs

* descriptive scratch error

* Triple backtick WYSIWYG not working properly (vibe-kanban 30b0114e)

When I paste in a multi-line code block, eg

```js
var x = 100;
```

It doesn't add a multi-line code block properly, instead it created two multi-line code blocks above and below the code.

frontend/src/components/ui/wysiwyg.tsx

* Safe scratch fail (vibe-kanban c3f99b37)

It's possible to get an error like:

scratch WS closed: Failed to get scratch item: invalid type: string "\\`\\`\\`js\n\nvar x = 100;\n\n\\`\\`\\` \n\n\n", expected struct DraftFollowUpData at line 1 column 49

In this situation the websocket should act in the same way when no scratch exists yet.

* Remove drafts (vibe-kanban 0af2e9aa)

crates/services/src/services/drafts.rs
crates/db/src/models/draft.rs

* Cleanup scratch (vibe-kanban 0baf9b69)

Remove:
- frontend/src/pages/TestScratch.tsx
- frontend/src/components/ScratchEditor.tsx

* Improve styling of WYSIWYG + attachment (vibe-kanban 042a18da)

frontend/src/components/ui/wysiwyg.tsx

The placeholder can overlap the attachment icon

* Introduce queued message service (vibe-kanban 442164ae)

- New service (crates/services/src/services/...) that holds an in memory store
- When the final executor_action finishes, if another follow up prompt (scratch ID) is queued then we can automatically begin executing it (crates/local-deployment/src/container.rs after finalize)
- New endpoint required to modify the queue for a task attempt.
- Scratch should be wiped after the execution process is created
- Scratch can't be edited while queued
- Add button to TaskFollowUpSection to make current scratch queued, or cancel queued item

* prepare db

* Follow up box does not reset after sending message (vibe-kanban c032bc21)

- Type follow up
- Press send
- Expect follow up to be reset, but it is not

frontend/src/components/tasks/TaskFollowUpSection.tsx

* bg

* Fix i18n (vibe-kanban a7ee5604)

i18next::translator: missingKey en-GB tasks followUp.queue Queue

* Reduce re-renders (vibe-kanban 86ec1b47)

frontend/src/components/ui/wysiwyg.tsx
frontend/src/components/tasks/TaskFollowUpSection.tsx

* Speed up button transitions (vibe-kanban be499249)

It takes 0.5-1s for the send button to go from no opacity to full opacity after I start typing

frontend/src/components/tasks/TaskFollowUpSection.tsx

* add icon to variant selection (vibe-kanban 92fca0e6)

frontend/src/components/tasks/TaskFollowUpSection.tsx

Dropdown should have settings-2

* Queued message functionality (vibe-kanban 21c7a725)

Say I have two messages to send:
- I send first
- I queue the second
- I now see "message queued" and the follow up editable text contains the second
- First finishes, second starts, no tasks are queued
- I still see "message queued" box but the follow up editable text gets wiped

frontend/src/components/tasks/TaskFollowUpSection.tsx

* variant width adjust

* Move the attach button (vibe-kanban b7f89e6e)

Attach button should be to the left of of the send button

frontend/src/components/ui/wysiwyg.tsx
frontend/src/components/tasks/TaskFollowUpSection.tsx

* Cleanup WYSIWYG (vibe-kanban 62997d6c)

Props, and upstream logic:
- make placeholder optional:
- remove defaultValue: this seems redundant as value is always controlled, there may also be related cleanups for uncontrolled mode
- remove onFocusChange: toggling states is unnecessary here
- remove enableCopyButton: this is always enabled when the editor is disabled

frontend/src/components/ui/wysiwyg.tsx

* cleanup scratch types

* further scratch cleanup

* Tweak queue (vibe-kanban 642aa7be)

If a task is stopped or fails, the next queued task runs, however this is not the desired behaviour. Instead the queued task should be removed from the queue

* Can't see attach button and queue at the same time (vibe-kanban 75ca5428)

frontend/src/components/tasks/TaskFollowUpSection.tsx

* move follow up hooks

* WYSIWYG code blocks should scroll horizontally (vibe-kanban 6c5dbc99)

frontend/src/components/ui/wysiwyg.tsx

* Refactor useDefaultVariant (vibe-kanban 10ec12ec)

I think we could change this so that it accepts a default variant and then returns what variant is currently selected, based on the user's preferences and if they select one from the dropdown

* Can't retry a task (vibe-kanban dfde6ad8)

It seems to retry functionality was removed fromfrontend/src/components/NormalizedConversation/UserMessage.tsx

* If execution startup is slow, scratch is not reset (vibe-kanban 6e721b8e)

frontend/src/components/tasks/TaskFollowUpSection.tsx

If you write out a follow up and then hit send, if you then navigate away from the page quickly the scratch will still be present when you visit the page, when the expected behaviour is that the previous text would be cleared

* Code highlighting for inline code block (vibe-kanban 956f1d5c)

Currently works for multi-line, can we get it working for multi-line

frontend/src/components/ui/wysiwyg.tsx

* Delete FileSearchTextArea (vibe-kanban 01107879)

Replace with frontend/src/components/ui/wysiwyg.tsx

not frontend/src/components/ui/file-search-textarea.tsx

* Tweak styles in task dialog (vibe-kanban 8dfe95a9)

frontend/src/components/dialogs/tasks/TaskFormDialog.tsx

- Placeholder for WYSIWYG too small, just use default
- Make title same size as WYSIWYG H1

* Refactor retry to use variant hook (vibe-kanban 69c969c9)

frontend/src/hooks/useVariant.ts

frontend/src/components/NormalizedConversation/RetryEditorInline.tsx

frontend/src/contexts/RetryUiContext.tsx

Removing all existing logic related to variant picking

* Refactor approval message styles (vibe-kanban b9a905e1)

Refactor the WYSIWYG implementation in thefrontend/src/components/NormalizedConversation/PendingApprovalEntry.tsx so the styles align with usage infrontend/src/components/tasks/TaskFollowUpSection.tsx

* Fix follow up box font (vibe-kanban 4fa9cd39)

When I start typing, it's a really small font for some reason

frontend/src/components/tasks/TaskFollowUpSection.tsx

* Remove double border for plan approval (vibe-kanban 3f12c591)

frontend/src/components/NormalizedConversation/PendingApprovalEntry.tsx

- Also multi-line code block colour is broken when looking at plans (but not single line strangely...)

* Retry Editor shouldn't call API directly (vibe-kanban 3df9cde5)

Should use hooks frontend/src/components/NormalizedConversation/RetryEditorInline.tsx

* Image metadata for task creation (vibe-kanban 8dd18a28)

We have an endpoint for image metadata in task attempt, but not for task

crates/server/src/routes/images.rs

This means we can't currently render the image (and metadata) in the WYSIWYG editorfrontend/src/components/dialogs/tasks/TaskFormDialog.tsx

* Add file upload to retry (vibe-kanban 8dffeed2)

frontend/src/components/NormalizedConversation/RetryEditorInline.tsx

Similar to:

frontend/src/components/tasks/TaskFollowUpSection.tsx

Infact we should reuse the same component as much as possible

* Remove the client side scratch deletion (vibe-kanban c6b0a613)

frontend/src/components/tasks/TaskFollowUpSection.tsx

This happens now on backend.

Also on backend when queued task is triggered we should also wipe the scratch.

* Queued task style (vibe-kanban 0c9bc110)

frontend/src/components/tasks/TaskFollowUpSection.tsx

When a message is queued it repeats the message under "will execute when current run finishes", however the message is visible anyway in the message box so we can remove that

* WYSIWYG base font size decrease

* Queueing a message change (vibe-kanban 30ee2d4d)

Currently when we queue a message I can see in the logs: Failed to save follow-up draft ApiError: Cannot edit scratch while a message is queued

I think this is because the following is happening:

- User types
- Clicks queue
- Debounce tries to save message
- Can't save message because of queue
2025-12-02 14:52:27 +00:00
GitHub Action
41300de309 chore: bump version to 0.0.125 2025-11-28 16:32:07 +00:00
GitHub Action
9dabff0752 chore: bump version to 0.0.124 2025-11-26 10:25:47 +00:00
GitHub Action
43bfe63931 chore: bump version to 0.0.123 2025-11-25 11:18:10 +00:00
GitHub Action
f691fbd9cb chore: bump version to 0.0.122 2025-11-20 10:52:34 +00:00
GitHub Action
853b178ebf chore: bump version to 0.0.121 2025-11-19 18:32:43 +00:00
GitHub Action
050d832dad chore: bump version to 0.0.120 2025-11-18 22:21:01 +00:00
GitHub Action
078554b5c7 chore: bump version to 0.0.119 2025-11-18 17:45:59 +00:00
Louis Knight-Webb
36bde0b4b9 Frontend file naming eslint rule (vibe-kanban) (#1322)
* Perfect! Now let me create a summary for you:

##  ESLint Configuration Complete

The linter has identified **29 files** that need to be renamed:

### **Files to Rename:**

#### **Components → PascalCase (15 files)**
```
config-provider.tsx → ConfigProvider.tsx
diff-view-switch.tsx → DiffViewSwitch.tsx
logo.tsx → Logo.tsx
navbar.tsx → Navbar.tsx (in layout/)
search-bar.tsx → SearchBar.tsx
theme-provider.tsx → ThemeProvider.tsx
style-override.tsx → StyleOverride.tsx

copy-files-field.tsx → CopyFilesField.tsx (in projects/)
project-detail.tsx → ProjectDetail.tsx (in projects/)
project-form-fields.tsx → ProjectFormFields.tsx (in projects/)
project-list.tsx → ProjectList.tsx (in projects/)
```

#### **Contexts → PascalCase (2 files)**
```
project-context.tsx → ProjectContext.tsx
search-context.tsx → SearchContext.tsx
```

#### **Pages → PascalCase (3 files)**
```
full-attempt-logs.tsx → FullAttemptLogs.tsx
project-tasks.tsx → ProjectTasks.tsx
projects.tsx → Projects.tsx
```

#### **Lib → camelCase (2 files)**
```
caret-position.ts → caretPosition.ts
mcp-strategies.ts → mcpStrategies.ts
```

#### **Utils → camelCase (3 files)**
```
companion-install-task.ts → companionInstallTask.ts
script-placeholders.ts → scriptPlaceholders.ts
status-labels.ts → statusLabels.ts
```

#### **UI (shadcn) → kebab-case (4 files)**
```
ActionsDropdown.tsx → actions-dropdown.tsx
ImageUploadSection.tsx → image-upload-section.tsx
TitleDescriptionEditor.tsx → title-description-editor.tsx
DataTable.tsx → data-table.tsx (in table/)
Table.tsx → table.tsx (in table/)
ImageChipNode.tsx → image-chip-node.tsx (in wysiwyg/)
imageChipMarkdown.ts → image-chip-markdown.ts (in wysiwyg/)
```

#### **Entry Point (special case - 1 file)**
```
main.tsx → can stay as main.tsx (entry point convention)
```

**Next steps:** Should I proceed with renaming these files using `git mv`?

* ##  Complete! File Naming Standardization Successful

### **Summary**

Successfully implemented and enforced file naming conventions for the frontend:

### **What Was Done:**

1.  **Installed** `eslint-plugin-check-file@^2.8.0`

2.  **Configured ESLint** with file naming rules:
   - **Components (.tsx)**: `PascalCase`
   - **Hooks (.ts)**: `camelCase` (with `use` prefix)
   - **Utils/Lib (.ts)**: `camelCase`
   - **Shadcn UI**: `kebab-case` (library convention)
   - **Entry points**: Excluded (`main.tsx`, `vite-env.d.ts`)

3.  **Renamed 28 files** using `git mv`:
   - 10 components → PascalCase
   - 2 contexts → PascalCase
   - 3 pages → PascalCase
   - 2 lib files → camelCase
   - 3 utils → camelCase
   - 7 UI components → kebab-case
   - 1 utils component → PascalCase

4.  **Fixed all imports** across the codebase (77 files modified)

5.  **Verified**:
   -  ESLint passes (no filename errors)
   -  TypeScript check passes (no errors)
   -  Build successful

### **Git Status:**
- 28 files renamed (with history preserved via `git mv`)
- 77 total files changed (renames + import updates)

### **Ready for commit!**

The codebase now has consistent, enforceable file naming conventions that will prevent future inconsistencies.

* Cleanup script changes for task attempt 11f8d7b9-99b5-41ce-934c-5ce75008a200
2025-11-18 17:05:18 +00:00
Louis Knight-Webb
0bd36a3b3a disable eslint-disable comments (vibe-kanban) (#1321)
* Done! All eslint-disable comments are now banned and the codebase is clean.

**Summary of changes:**

1. **Installed** `eslint-plugin-eslint-comments`
2. **Updated** [frontend/.eslintrc.cjs](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/2550-disable-eslint-d/frontend/.eslintrc.cjs) to enforce the ban
3. **Fixed 3 files** by refactoring code instead of suppressing rules:
   - [FeatureShowcaseModal.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/2550-disable-eslint-d/frontend/src/components/showcase/FeatureShowcaseModal.tsx): Added ref to track activeScopes snapshot
   - [ShareDialog.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/2550-disable-eslint-d/frontend/src/components/dialogs/tasks/ShareDialog.tsx): Added shareTask object to dependencies
   - [wysiwyg.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/2550-disable-eslint-d/frontend/src/components/ui/wysiwyg.tsx): Added didInit ref guard for run-once effect

All checks pass ✓

* lint fix
2025-11-18 16:45:10 +00:00
Louis Knight-Webb
1dae217f1a Resolve frontend warnings (vibe-kanban) (#1316)
* ##  Batch 1 Complete

Successfully fixed all 6 warnings in batch 1 (message boundaries & streams):

### Changes made:

**[bridge.ts](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/19c9-resolve-frontend/frontend/src/vscode/bridge.ts)** - 5 fixes:
- Replaced `(window as any).InputEvent` checks with `typeof InputEvent === 'function'`
- Removed unnecessary type assertions on `dispatchEvent` calls
- More readable runtime guards using built-in DOM types

**[useJsonPatchWsStream.ts](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/19c9-resolve-frontend/frontend/src/hooks/useJsonPatchWsStream.ts)** - 1 fix:
- Added eslint suppression with explanation for `rfc6902` library requirement

**[frontend/package.json](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/19c9-resolve-frontend/frontend/package.json)**:
- Reduced `max-warnings` from 110 → 30 to lock in progress

### Results:
- **Before:** 32 warnings
- **After:** 26 warnings
- **Eliminated:** 6 warnings from batch 1
- **Remaining batches:** 2-6 (26 warnings)

* Perfect!  The solution works without any `eslint-disable` comments.

## What we changed:

1. **Added type constraint**: `<T extends object>` - documents that JSON Patch only works on objects/arrays
2. **Used local variable narrowing**: `const current = dataRef.current` narrows `T | undefined` to `T`
3. **Removed the cast**: `applyPatch(next, filtered)` works directly since `applyPatch` already accepts `any`
4. **Cleaner code flow**: `const next = structuredClone(current)` then update refs

The code is now more readable, type-safe (within TypeScript's limits for this library), and passes both lint and typecheck with **no suppressions needed**.
2025-11-18 11:12:59 +00:00
Louis Knight-Webb
41376eba94 Batch C: Fix medium-priority 'any' in UI components (vibe-kanban) (#1312)
* ##  Batch C Complete

All medium-priority TypeScript `any` types have been fixed across 7 files:

1. **[markdown-renderer.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/ui/markdown-renderer.tsx)** - Replaced 11 `any` with `React.ComponentProps<'tag'>`
2. **[ExecutorConfigForm.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/ExecutorConfigForm.tsx)** - Used `unknown` for form data, `IChangeEvent<unknown>` for handlers
3. **[FormTemplate.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/rjsf/templates/FormTemplate.tsx)** - Replaced with `React.PropsWithChildren`
4. **[ArrayFieldTemplate.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/rjsf/templates/ArrayFieldTemplate.tsx)** - Created minimal `ArrayItemWithButtons` type for RJSF v6 beta
5. **[DiffsPanel.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/panels/DiffsPanel.tsx)** - Used `Diff[]` and typed `t` function properly
6. **[DiffCard.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/DiffCard.tsx)** - Used existing `ReviewComment` type from context
7. **[useGitOperations.ts](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/hooks/useGitOperations.ts)** - Properly narrowed `unknown` errors with type guards

`pnpm run check` passes 

* Cleanup script changes for task attempt 5fe86537-3bc1-4d78-96c0-95347fc7c05f

* Excellent! The build succeeds. Now let's create a summary:

##  Batch C Complete + RJSF Upgrade

Successfully fixed all medium-priority TypeScript `any` types **and** upgraded RJSF to stable 6.1.1:

### Type Fixes (7 files)
1. **[markdown-renderer.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/ui/markdown-renderer.tsx)** - Replaced 11 `any` with `React.ComponentProps<'tag'>`
2. **[ExecutorConfigForm.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/ExecutorConfigForm.tsx)** - Used `unknown` and `IChangeEvent<unknown>`
3. **[FormTemplate.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/rjsf/templates/FormTemplate.tsx)** - Used `React.PropsWithChildren`
4. **[ArrayFieldTemplate.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/rjsf/templates/ArrayFieldTemplate.tsx)** - Migrated to stable RJSF v6 API with `ArrayFieldItemTemplate`
5. **[DiffsPanel.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/panels/DiffsPanel.tsx)** - Used `Diff[]` and proper `t` function type
6. **[DiffCard.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/components/DiffCard.tsx)** - Used `ReviewComment` type from context
7. **[useGitOperations.ts](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/5fe8-batch-c-fix-medi/frontend/src/hooks/useGitOperations.ts)** - Properly narrowed `unknown` with type guards

### Dependency Upgrades
- `@rjsf/core`: 6.0.0-beta.11 → **6.1.1** (stable)
- `@rjsf/utils`: 6.0.0-beta.11 → **6.1.1** (stable)
- `@rjsf/validator-ajv8`: 6.0.0-beta.11 → **6.1.1** (stable)
- `@rjsf/shadcn`: 6.0.0-beta.10 → **6.1.1** (stable)

### RJSF Migration
Updated to v6 stable API:
- Removed workaround type (no longer needed)
- Added `ArrayFieldItemTemplate` for proper item rendering
- Updated to use `onRemoveItem` callback instead of deprecated `onDropIndexClick`

All checks pass 

* Cleanup script changes for task attempt 5fe86537-3bc1-4d78-96c0-95347fc7c05f
2025-11-17 22:35:20 +00:00