Skip to content

Conversation

@Shironex
Copy link
Collaborator

@Shironex Shironex commented Dec 23, 2025

UI Feedback

image

Resolve

Summary by CodeRabbit

  • New Features

    • Git operations (checkout, commit, list branches, merge, pull, push, switch) now respect repository state and are gated when unavailable.
    • UI shows status indicators, a global warning in the actions dropdown, and tooltips explaining why Git actions are disabled.
    • Hook exposes repository status so tabs and actions render accordingly.
  • Bug Fixes

    • Git actions fail gracefully with clearer, user-facing messages for non-repositories and repos with no commits.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 23, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds server-side Git validation (is-repo and has-commits) as middleware for worktree routes and exposes a new hasCommits utility. UI gains a GitRepoStatus type and propagates repo state to disable/tooltip Git actions; hooks and action handlers surface friendly messages for NOT_GIT_REPO/NO_COMMITS.

Changes

Cohort / File(s) Summary
Server: Git helpers
apps/server/src/routes/worktree/common.ts
New exported hasCommits(repoPath: string): Promise<boolean> that checks git rev-parse --verify HEAD.
Server: Validation middleware
apps/server/src/routes/worktree/middleware.ts
New requireValidGitRepo(options) factory and preconfigured requireValidWorktree, requireValidProject, requireGitRepoOnly that validate repo presence and optionally commits; respond 400 with `code: 'NOT_GIT_REPO'
Server: Route wiring
apps/server/src/routes/worktree/index.ts
Added imports and applied new middleware to /merge, /commit, /push, /pull, /checkout-branch, /list-branches, /switch-branch routes.
Server: Minor docs
apps/server/src/routes/worktree/routes/*.ts
Endpoint headers updated to note repo validation is handled by middleware (no functional changes).
UI: Types
apps/ui/src/components/views/board-view/worktree-panel/types.ts, apps/ui/src/types/electron.d.ts
Added export interface GitRepoStatus { isGitRepo: boolean; hasCommits: boolean }. IPC return shapes extended to include optional `code?: 'NOT_GIT_REPO'
UI: Hooks / data flow
apps/ui/src/components/views/board-view/worktree-panel/hooks/use-branches.ts, apps/ui/src/components/views/board-view/worktree-panel/hooks/use-worktree-actions.ts
useBranches() now tracks/returns gitRepoStatus and clears branch state on NOT_GIT_REPO/NO_COMMITS; useWorktreeActions() maps NOT_GIT_REPO/NO_COMMITS to friendly toasts and early-exits.
UI: Components
apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx, .../worktree-tab.tsx, .../tooltip-wrapper.tsx, apps/ui/src/components/views/board-view/worktree-panel/worktree-panel.tsx
Components accept and propagate gitRepoStatus; actions (Pull/Push/Commit/Resolve/Create PR) gated with canPerformGitOps, tooltips and inline status indicators added; new TooltipWrapper component introduced.

Sequence Diagram(s)

sequenceDiagram
  participant UI as Client UI
  participant IPC as WorktreeAPI (renderer→main)
  participant Server as Server Route
  participant MW as requireValidGitRepo (middleware)
  participant Git as Git CLI

  UI->>IPC: call listBranches / pull / push / commit / switch
  IPC->>Server: POST /api/worktree/<action> (worktreePath/projectPath)
  Server->>MW: run requireValidGitRepo
  MW->>Git: isGitRepo? (git rev-parse --is-inside-work-tree)
  alt not a git repo
    Git-->>MW: error
    MW-->>Server: respond 400 { success:false, code: NOT_GIT_REPO }
    Server-->>IPC: 400 response
    IPC-->>UI: return { code: NOT_GIT_REPO }
  else is git repo
    Git-->>MW: ok
    MW->>Git: hasCommits? (git rev-parse --verify HEAD)  %[green]%
    alt no commits and commits required
      Git-->>MW: error
      MW-->>Server: respond 400 { success:false, code: NO_COMMITS }
      Server-->>IPC: 400 response
      IPC-->>UI: return { code: NO_COMMITS }
    else commits OK
      MW-->>Server: next()
      Server->>Git: perform requested git operation
      Git-->>Server: result/success
      Server-->>IPC: 200 response
      IPC-->>UI: return success payload
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

Ready-To-Merge

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.78% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: branch list issue and improve ui feedback' is directly related to the main changes: fixing the branch list error (#175) and adding UI feedback when git repo validation fails.
Linked Issues check ✅ Passed The PR addresses issue #175 by adding validation middleware (requireValidWorktree, requireValidProject, requireGitRepoOnly) that checks git repo state before executing commands, preventing 500 errors; UI components display appropriate feedback (GitRepoStatus) when git operations are unavailable.
Out of Scope Changes check ✅ Passed All changes are in-scope: new hasCommits() utility function, validation middleware, error code handling in WorktreeAPI, GitRepoStatus type, and UI components for git status feedback directly support the fix for issue #175.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/list-branch-issue-on-fresh-repo

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Shironex, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the robustness and user experience of Git operations within the application. It addresses potential issues when interacting with Git repositories that are either not initialized or lack initial commits, by implementing comprehensive server-side validation. Concurrently, the user interface has been updated to reflect these Git repository states, providing users with clear, actionable feedback and preventing them from attempting operations that would otherwise fail, thereby streamlining their workflow.

Highlights

  • Server-Side Git Validation: Introduced new server-side checks to verify if a given path is a valid Git repository and if it contains any commits before executing Git commands. This prevents errors when interacting with uninitialized or non-Git directories.
  • Enhanced UI Feedback: Improved the user interface to provide clear feedback when Git operations are not possible. Actions like Pull, Push, Commit, and Create PR are now conditionally disabled, accompanied by informative tooltips explaining why they are unavailable (e.g., 'Not a git repository' or 'Repository has no commits yet').
  • Fix for Fresh Repositories: Resolved an issue where the branch list might not display correctly for freshly initialized Git repositories that do not yet have any commits, ensuring a more robust user experience from the start.
  • New hasCommits Utility: Added a new utility function hasCommits in common.ts to programmatically check for the existence of commits in a Git repository, which is leveraged across various Git-related API routes.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@Shironex Shironex self-assigned this Dec 23, 2025
@Shironex Shironex added Bug Something isn't working Work-In-Progress Currently being addressed. Do Not Merge Use this label if something should not be merged. labels Dec 23, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively addresses the issue of handling freshly initialized git repositories with no commits by adding checks on the backend and providing clear feedback on the UI. The introduction of hasCommits and the associated UI changes to disable actions and show tooltips are great improvements.

My review focuses on several opportunities to improve maintainability by reducing code duplication. On the backend, the validation logic added to multiple routes could be centralized into an Express middleware. On the frontend, I've suggested creating a reusable component for the tooltip-wrapped dropdown items and extracting repeated error-handling and state-resetting logic into helper functions. I also noticed that some TypeScript type definitions for the Electron API are incomplete.

Overall, these are solid changes that improve the application's robustness. Addressing the feedback will make the new code more maintainable and scalable.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
apps/ui/src/components/views/board-view/worktree-panel/hooks/use-worktree-actions.ts (1)

41-49: Consider extracting duplicated error handling logic.

The same git-status error handling pattern is repeated verbatim across handleSwitchBranch, handlePull, and handlePush. This could be extracted into a helper function to reduce duplication and ensure consistency.

🔎 Proposed refactor
// Add helper function near the top of the file
function handleGitStatusError(result: { code?: string; error?: string }): boolean {
  const errorCode = result.code;
  if (
    errorCode &&
    GIT_STATUS_ERROR_CODES.includes(errorCode as (typeof GIT_STATUS_ERROR_CODES)[number])
  ) {
    toast.info(GIT_STATUS_ERROR_MESSAGES[errorCode] || result.error);
    return true;
  }
  return false;
}

// Then use in each handler:
} else {
  if (handleGitStatusError(result)) return;
  toast.error(result.error || 'Failed to switch branch');
}

Also applies to: 77-85, 114-122

apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx (1)

149-176: Consider hoisting TooltipProvider to reduce nesting.

Each tooltip-wrapped menu item creates its own TooltipProvider. While functional, hoisting a single TooltipProvider wrapper around the dropdown content would simplify the JSX structure.

🔎 Example refactor pattern
<DropdownMenuContent align="start" className="w-56">
  <TooltipProvider>
    {/* Warning label */}
    {!canPerformGitOps && (
      <>
        <DropdownMenuLabel ...>...</DropdownMenuLabel>
        <DropdownMenuSeparator />
      </>
    )}
    {/* Dev server section */}
    ...
    {/* Pull item */}
    <Tooltip>
      <TooltipTrigger asChild>
        <div>
          <DropdownMenuItem ...>...</DropdownMenuItem>
        </div>
      </TooltipTrigger>
      {gitOpsDisabledReason && <TooltipContent>...</TooltipContent>}
    </Tooltip>
    {/* Push item, etc. */}
  </TooltipProvider>
</DropdownMenuContent>
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 629b7e7 and 4958ee1.

📒 Files selected for processing (15)
  • apps/server/src/routes/worktree/common.ts
  • apps/server/src/routes/worktree/routes/checkout-branch.ts
  • apps/server/src/routes/worktree/routes/commit.ts
  • apps/server/src/routes/worktree/routes/list-branches.ts
  • apps/server/src/routes/worktree/routes/merge.ts
  • apps/server/src/routes/worktree/routes/pull.ts
  • apps/server/src/routes/worktree/routes/push.ts
  • apps/server/src/routes/worktree/routes/switch-branch.ts
  • apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx
  • apps/ui/src/components/views/board-view/worktree-panel/components/worktree-tab.tsx
  • apps/ui/src/components/views/board-view/worktree-panel/hooks/use-branches.ts
  • apps/ui/src/components/views/board-view/worktree-panel/hooks/use-worktree-actions.ts
  • apps/ui/src/components/views/board-view/worktree-panel/types.ts
  • apps/ui/src/components/views/board-view/worktree-panel/worktree-panel.tsx
  • apps/ui/src/types/electron.d.ts
🧰 Additional context used
🧬 Code graph analysis (10)
apps/server/src/routes/worktree/routes/push.ts (1)
apps/server/src/routes/worktree/common.ts (2)
  • isGitRepo (105-112)
  • hasCommits (118-125)
apps/server/src/routes/worktree/routes/switch-branch.ts (1)
apps/server/src/routes/worktree/common.ts (2)
  • isGitRepo (105-112)
  • hasCommits (118-125)
apps/server/src/routes/worktree/routes/commit.ts (1)
apps/server/src/routes/worktree/common.ts (1)
  • isGitRepo (105-112)
apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx (2)
apps/ui/src/components/views/board-view/worktree-panel/types.ts (1)
  • GitRepoStatus (26-29)
apps/ui/src/lib/utils.ts (1)
  • cn (5-7)
apps/server/src/routes/worktree/routes/pull.ts (1)
apps/server/src/routes/worktree/common.ts (2)
  • isGitRepo (105-112)
  • hasCommits (118-125)
apps/server/src/routes/worktree/routes/list-branches.ts (1)
apps/server/src/routes/worktree/common.ts (2)
  • isGitRepo (105-112)
  • hasCommits (118-125)
apps/server/src/routes/worktree/routes/merge.ts (1)
apps/server/src/routes/worktree/common.ts (2)
  • isGitRepo (105-112)
  • hasCommits (118-125)
apps/ui/src/components/views/board-view/worktree-panel/hooks/use-branches.ts (1)
apps/ui/src/components/views/board-view/worktree-panel/types.ts (2)
  • BranchInfo (20-24)
  • GitRepoStatus (26-29)
apps/server/src/routes/worktree/routes/checkout-branch.ts (1)
apps/server/src/routes/worktree/common.ts (2)
  • isGitRepo (105-112)
  • hasCommits (118-125)
apps/ui/src/components/views/board-view/worktree-panel/components/worktree-tab.tsx (1)
apps/ui/src/components/views/board-view/worktree-panel/types.ts (1)
  • GitRepoStatus (26-29)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (17)
apps/server/src/routes/worktree/routes/checkout-branch.ts (1)

46-64: LGTM! Excellent defensive validation.

The pre-flight checks for repository validity and commit presence are well-positioned before the git rev-parse --abbrev-ref HEAD command on line 67, which requires HEAD to exist. The error codes (NOT_GIT_REPO, NO_COMMITS) are clear and consistent with other routes in this PR.

apps/server/src/routes/worktree/common.ts (1)

114-125: LGTM! Well-implemented utility function.

The hasCommits() function follows the established pattern of isGitRepo() and uses the standard git rev-parse --verify HEAD command to check for commit presence. The JSDoc clearly explains its purpose and behavior for fresh repos.

apps/ui/src/components/views/board-view/worktree-panel/types.ts (1)

26-29: LGTM! Clean type definition.

The GitRepoStatus interface clearly captures the repository validation state with self-documenting property names.

apps/server/src/routes/worktree/routes/list-branches.ts (1)

33-51: LGTM! Consistent validation pattern.

The pre-flight checks appropriately guard the git rev-parse --abbrev-ref HEAD command on line 54. Listing branches requires HEAD to exist, so the hasCommits validation is essential here.

apps/ui/src/components/views/board-view/worktree-panel/worktree-panel.tsx (1)

64-64: LGTM! Consistent prop threading.

The gitRepoStatus value from useBranches() is correctly threaded to both main and non-main WorktreeTab instances. This enables repository-state-aware UI behavior throughout the worktree panel.

Also applies to: 214-214, 269-269

apps/server/src/routes/worktree/routes/switch-branch.ts (1)

86-104: LGTM! Appropriate validation for branch switching.

The pre-flight checks correctly validate repository state before attempting to get the current branch on line 107. Branch switching operations require HEAD to exist, making the hasCommits check essential.

apps/server/src/routes/worktree/routes/commit.ts (1)

28-36: LGTM! Intentionally allows commits on fresh repositories.

This route correctly validates only isGitRepo and not hasCommits, unlike other routes in this PR. This is the right choice because commit operations should work on freshly initialized repositories to create the initial commit. The subsequent git status, git add, and git commit commands (lines 39-60) all work correctly without an existing HEAD.

apps/server/src/routes/worktree/routes/push.ts (1)

28-46: LGTM! Essential validation for push operations.

Both pre-flight checks are appropriate here. The hasCommits validation is particularly important for push operations since there's nothing to push without at least one commit. The checks correctly execute before retrieving the branch name on line 49.

apps/ui/src/components/views/board-view/worktree-panel/hooks/use-worktree-actions.ts (1)

6-13: LGTM! Well-structured error code constants.

The as const assertion and the mapping object provide good type safety and clear user-friendly messages.

apps/server/src/routes/worktree/routes/merge.ts (1)

30-48: LGTM! Proper pre-flight validation for merge operations.

The validation order is correct—checking isGitRepo before hasCommits and returning early with appropriate error codes and HTTP 400 status. This prevents confusing errors from git commands failing on invalid repositories.

apps/server/src/routes/worktree/routes/pull.ts (1)

27-45: LGTM! Consistent validation pattern.

The pre-flight checks correctly use worktreePath (since pull operates on the worktree) and follow the same validation order as other routes.

apps/ui/src/components/views/board-view/worktree-panel/hooks/use-branches.ts (2)

11-14: Good default state for gitRepoStatus.

Starting with {isGitRepo: true, hasCommits: true} is a reasonable optimistic default that avoids disabling UI elements before the first fetch completes.


29-47: LGTM! Clean error code handling.

The logic correctly differentiates between success, NOT_GIT_REPO, NO_COMMITS, and other errors, updating both branch state and gitRepoStatus appropriately for each case.

apps/ui/src/components/views/board-view/worktree-panel/components/worktree-tab.tsx (1)

30-30: LGTM! Clean prop threading.

The gitRepoStatus prop is correctly added to the interface and passed through to WorktreeActionsDropdown for action gating.

Also applies to: 71-71, 325-325

apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx (3)

83-89: LGTM! Well-designed derived state for git operations.

The canPerformGitOps and gitOpsDisabledReason derivation cleanly encapsulates the gating logic and provides clear reasons for disabled states.


107-116: Nice UX addition with the warning label.

The prominent warning at the top of the dropdown clearly communicates why certain operations are unavailable.


247-249: Intentional: Commit uses isGitRepo only, not canPerformGitOps.

This correctly allows committing when hasCommits is false (creating the initial commit), unlike Pull/Push/PR which require existing commits. Good design decision.

@Shironex Shironex added Enhancement Improvements to existing functionality or UI. Ready-To-Merge A feature or bug has been improved/fixed and a final review is requested before merging. and removed Work-In-Progress Currently being addressed. Do Not Merge Use this label if something should not be merged. labels Dec 23, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx (1)

150-151: Consider removing redundant condition checks in onClick handlers.

The onClick handlers include conditions like canPerformGitOps && onPull(worktree), but since disabled is already set when !canPerformGitOps, the click event won't fire on disabled items. These guards are harmless but redundant.

🔎 Proposed simplification (example for Pull)
 <DropdownMenuItem
-  onClick={() => canPerformGitOps && onPull(worktree)}
+  onClick={() => onPull(worktree)}
   disabled={isPulling || !canPerformGitOps}
   className={cn('text-xs', !canPerformGitOps && 'opacity-50 cursor-not-allowed')}
 >

Also applies to: 167-167, 187-187, 214-214, 233-233

apps/server/src/routes/worktree/middleware.ts (1)

27-34: Consider requiring the path field to be present.

The middleware delegates to next() when repoPath is missing (lines 30-34), expecting route handlers to validate path presence. However, this creates a potential gap: if a handler forgets to validate, it could lead to undefined behavior.

Since all routes using this middleware in index.ts now have explicit validatePathParams, consider whether the middleware should instead return a 400 error for missing paths to enforce validation at the middleware layer and prevent accidental bypasses.

🔎 Alternative approach
     const repoPath = req.body[pathField] as string | undefined;
 
     if (!repoPath) {
-      // Let the route handler deal with missing path validation
-      next();
+      res.status(400).json({
+        success: false,
+        error: `Missing required field: ${pathField}`,
+        code: 'MISSING_PATH',
+      });
       return;
     }

Note: This would require handlers to rely solely on this middleware for path presence validation, which may or may not align with your architecture.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4958ee1 and e0c5f55.

📒 Files selected for processing (14)
  • apps/server/src/routes/worktree/index.ts
  • apps/server/src/routes/worktree/middleware.ts
  • apps/server/src/routes/worktree/routes/checkout-branch.ts
  • apps/server/src/routes/worktree/routes/commit.ts
  • apps/server/src/routes/worktree/routes/list-branches.ts
  • apps/server/src/routes/worktree/routes/merge.ts
  • apps/server/src/routes/worktree/routes/pull.ts
  • apps/server/src/routes/worktree/routes/push.ts
  • apps/server/src/routes/worktree/routes/switch-branch.ts
  • apps/ui/src/components/views/board-view/worktree-panel/components/tooltip-wrapper.tsx
  • apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx
  • apps/ui/src/components/views/board-view/worktree-panel/hooks/use-branches.ts
  • apps/ui/src/components/views/board-view/worktree-panel/hooks/use-worktree-actions.ts
  • apps/ui/src/types/electron.d.ts
✅ Files skipped from review due to trivial changes (2)
  • apps/server/src/routes/worktree/routes/switch-branch.ts
  • apps/server/src/routes/worktree/routes/checkout-branch.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • apps/server/src/routes/worktree/routes/list-branches.ts
  • apps/server/src/routes/worktree/routes/push.ts
  • apps/ui/src/components/views/board-view/worktree-panel/hooks/use-worktree-actions.ts
  • apps/server/src/routes/worktree/routes/merge.ts
  • apps/server/src/routes/worktree/routes/commit.ts
  • apps/server/src/routes/worktree/routes/pull.ts
🧰 Additional context used
🧬 Code graph analysis (3)
apps/server/src/routes/worktree/middleware.ts (1)
apps/server/src/routes/worktree/common.ts (1)
  • hasCommits (118-125)
apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx (3)
apps/ui/src/components/views/board-view/worktree-panel/types.ts (1)
  • GitRepoStatus (26-29)
apps/ui/src/components/views/board-view/worktree-panel/components/tooltip-wrapper.tsx (1)
  • TooltipWrapper (21-44)
apps/ui/src/lib/utils.ts (1)
  • cn (5-7)
apps/server/src/routes/worktree/index.ts (2)
apps/server/src/middleware/validate-paths.ts (1)
  • validatePathParams (22-69)
apps/server/src/routes/worktree/middleware.ts (3)
  • requireValidProject (66-66)
  • requireGitRepoOnly (71-74)
  • requireValidWorktree (61-61)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e
🔇 Additional comments (13)
apps/ui/src/components/views/board-view/worktree-panel/components/tooltip-wrapper.tsx (1)

1-43: Well-structured reusable component.

The TooltipWrapper component is cleanly implemented with proper TypeScript types, JSDoc documentation, and the correct pattern for enabling tooltips on disabled elements via the div wrapper. This effectively addresses the code duplication previously flagged in the dropdown component.

apps/ui/src/components/views/board-view/worktree-panel/hooks/use-branches.ts (1)

16-21: Good implementation addressing previous feedback.

The resetBranchState helper effectively eliminates the code duplication flagged in previous reviews. The catch block now properly resets gitRepoStatus as previously requested. The error handling logic for NOT_GIT_REPO and NO_COMMITS codes aligns well with the PR objective of gracefully handling non-git directories.

Also applies to: 38-55

apps/ui/src/types/electron.d.ts (1)

736-736: Type definitions now correctly include all error codes.

The updates address previous feedback by adding 'NOT_GIT_REPO' | 'NO_COMMITS' to push, pull, checkoutBranch, and listBranches. The switchBranch method appropriately includes 'UNCOMMITTED_CHANGES' as an additional code. This ensures type safety when the UI handles these error conditions.

Also applies to: 787-787, 802-802, 819-819, 834-834

apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx (2)

83-89: Clean derivation of git operation availability.

The canPerformGitOps and gitOpsDisabledReason logic is well-structured. The warning label at the top of the dropdown provides clear user feedback when git operations are unavailable, which aligns well with the PR's UI feedback improvements objective.

Also applies to: 107-116


149-164: TooltipWrapper adoption addresses previous duplication feedback.

The repeated tooltip pattern flagged in previous reviews is now cleanly handled via the TooltipWrapper component. The guarded actions correctly differentiate between canPerformGitOps (requires both repo and commits) for most operations, while "Commit Changes" appropriately only checks isGitRepo since it can create the initial commit.

Also applies to: 165-180, 181-201, 208-244

apps/server/src/routes/worktree/index.ts (5)

7-7: LGTM! Middleware imports are clean.

The three middleware helpers are properly imported and utilized throughout the route definitions.


42-47: LGTM! Merge route validation is correctly layered.

Path validation followed by Git repository validation ensures proper security and error handling for the merge operation.


52-57: LGTM! Commit route correctly uses requireGitRepoOnly.

Using requireGitRepoOnly (which skips the commits check) is the right choice here, as this route may be used to create the initial commit in a fresh repository.


58-69: LGTM! Push and pull routes properly validated.

Both routes correctly apply requireValidWorktree, which ensures the repository has commits before attempting push/pull operations.


71-76: LGTM! This fixes issue #175.

The added requireValidWorktree middleware will now catch the "not a git repository" error reported in issue #175 and return a proper 400 response with error code NOT_GIT_REPO or NO_COMMITS instead of the 500 server error caused by the unhandled git command failure.

apps/server/src/routes/worktree/middleware.ts (3)

8-15: LGTM! Well-typed interface with clear documentation.

The ValidationOptions interface is properly documented and the union type for pathField ensures type safety by restricting to known field names.


36-52: LGTM! Git validation logic is sound.

The middleware correctly:

  • Returns 400 (Bad Request) for client errors, which is more appropriate than the 500 errors that would have occurred from unhandled git command failures
  • Provides structured error responses with machine-readable error codes (NOT_GIT_REPO, NO_COMMITS) that the UI can consume
  • Uses proper async validation checks

This directly addresses the root cause of issue #175.


58-74: LGTM! Well-designed preconfigured middleware.

The three exported variants provide a clean API:

  • requireValidWorktree and requireValidProject distinguish by field name
  • requireGitRepoOnly appropriately relaxes the commits requirement for operations like initial commits

Clear JSDoc comments document the purpose of each variant.

requireValidWorktree,
createPullHandler()
);
router.post('/checkout-branch', requireValidWorktree, createCheckoutBranchHandler());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add validatePathParams for security.

The /checkout-branch route is missing validatePathParams('worktreePath') before requireValidWorktree. All other routes in this file apply path validation first to prevent path traversal attacks.

🔎 Suggested fix
-  router.post('/checkout-branch', requireValidWorktree, createCheckoutBranchHandler());
+  router.post(
+    '/checkout-branch',
+    validatePathParams('worktreePath'),
+    requireValidWorktree,
+    createCheckoutBranchHandler()
+  );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
router.post('/checkout-branch', requireValidWorktree, createCheckoutBranchHandler());
router.post(
'/checkout-branch',
validatePathParams('worktreePath'),
requireValidWorktree,
createCheckoutBranchHandler()
);
🤖 Prompt for AI Agents
In apps/server/src/routes/worktree/index.ts around line 70, the POST
/checkout-branch route is missing path validation; add
validatePathParams('worktreePath') before requireValidWorktree in the middleware
chain for router.post('/checkout-branch', ...). Ensure the order is
validatePathParams('worktreePath'), requireValidWorktree, then
createCheckoutBranchHandler() so path traversal is prevented consistently with
other routes.

requireValidWorktree,
createListBranchesHandler()
);
router.post('/switch-branch', requireValidWorktree, createSwitchBranchHandler());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add validatePathParams for security.

The /switch-branch route is missing validatePathParams('worktreePath') before requireValidWorktree. All other routes in this file apply path validation first to prevent path traversal attacks.

🔎 Suggested fix
-  router.post('/switch-branch', requireValidWorktree, createSwitchBranchHandler());
+  router.post(
+    '/switch-branch',
+    validatePathParams('worktreePath'),
+    requireValidWorktree,
+    createSwitchBranchHandler()
+  );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
router.post('/switch-branch', requireValidWorktree, createSwitchBranchHandler());
router.post(
'/switch-branch',
validatePathParams('worktreePath'),
requireValidWorktree,
createSwitchBranchHandler()
);
🤖 Prompt for AI Agents
In apps/server/src/routes/worktree/index.ts around line 77, the POST
/switch-branch route is missing path validation; add
validatePathParams('worktreePath') before requireValidWorktree so path
parameters are validated first to prevent path traversal attacks, i.e., insert
the validatePathParams middleware as the first validator middleware in the
router.post call keeping the existing requireValidWorktree and
createSwitchBranchHandler() order.

@webdevcody webdevcody merged commit 172f1a7 into main Dec 23, 2025
9 checks passed
@webdevcody webdevcody deleted the fix/list-branch-issue-on-fresh-repo branch December 23, 2025 20:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working Enhancement Improvements to existing functionality or UI. Ready-To-Merge A feature or bug has been improved/fixed and a final review is requested before merging.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] [Server Error] [Worktree] ❌ List branches failed

3 participants