Skip to content

Feat: Add ability to duplicate a feature and duplicate as a child#774

Open
gsxdsm wants to merge 1 commit intoAutoMaker-Org:v0.15.0rcfrom
gsxdsm:feat/duplicate-festure
Open

Feat: Add ability to duplicate a feature and duplicate as a child#774
gsxdsm wants to merge 1 commit intoAutoMaker-Org:v0.15.0rcfrom
gsxdsm:feat/duplicate-festure

Conversation

@gsxdsm
Copy link
Collaborator

@gsxdsm gsxdsm commented Feb 16, 2026

Add ability to duplicate a feature. Fixes an issue where pull and resolve conflicts fails the second time because a duplicate feature name exists.

This feature is useful for running a feature through multiple times, trying different models or to ensure correctness. A duplicate can be created as a child such that the feature can be run in a loop in auto mode (Ralph style)

Summary by CodeRabbit

  • New Features
    • Added feature duplication capability — duplicate features as siblings or as child items
    • Duplication options now available in kanban cards and list views via dropdown menus
    • Removed duplicate title validation for feature creation and updates, allowing features with matching titles

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @gsxdsm, 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 enhances the application by introducing robust feature duplication capabilities. Users can now create copies of existing features, either as independent entities or as child features that maintain a dependency on their parent. This addresses a previous limitation where duplicate feature names could cause issues during conflict resolution. The backend has been streamlined by removing redundant duplicate title validation, while the frontend provides intuitive access to these new duplication options across various board views.

Highlights

  • Feature Duplication: Added the ability to duplicate an existing feature, creating a new, identical feature.
  • Duplicate as Child: Introduced an option to duplicate a feature as a child, automatically setting the original feature as a dependency for the new child feature.
  • Backend Simplification: Removed the server-side duplicate title checks from the feature creation and update routes, allowing for features with identical titles.
  • UI Integration: Integrated 'Duplicate' and 'Duplicate as Child' options into the UI, accessible via dropdown menus on Kanban cards and list view rows.

🧠 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.

Changelog
  • apps/server/src/routes/features/routes/create.ts
    • Removed duplicate title validation logic from the feature creation handler.
  • apps/server/src/routes/features/routes/update.ts
    • Removed duplicate title validation logic from the feature update handler.
  • apps/ui/src/components/views/board-view.tsx
    • Integrated the new handleDuplicateFeature function.
    • Passed handleDuplicateFeature to KanbanCard and ListView components.
  • apps/ui/src/components/views/board-view/components/kanban-card/card-header.tsx
    • Added DropdownMenuSub, DropdownMenuSubContent, and DropdownMenuSubTrigger imports.
    • Imported the Copy icon from lucide-react.
    • Extended CardHeaderProps to include onDuplicate and onDuplicateAsChild callbacks.
    • Implemented new dropdown menu items for 'Duplicate' and 'Duplicate as Child' actions.
  • apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx
    • Extended KanbanCardProps to include onDuplicate and onDuplicateAsChild callbacks.
    • Passed onDuplicate and onDuplicateAsChild props to CardHeaderSection.
  • apps/ui/src/components/views/board-view/components/list-view/list-view.tsx
    • Extended ListViewActionHandlers to include onDuplicate and onDuplicateAsChild.
    • Updated the createRowActionHandlers call to pass duplicate and duplicateAsChild actions.
  • apps/ui/src/components/views/board-view/components/list-view/row-actions.tsx
    • Imported the Copy icon from lucide-react.
    • Added DropdownMenuSub, DropdownMenuSubContent, and DropdownMenuSubTrigger imports.
    • Extended RowActionHandlers to include onDuplicate and onDuplicateAsChild.
    • Implemented new dropdown menu items for 'Duplicate' and 'Duplicate as Child' actions in various contexts.
    • Extended createRowActionHandlers to include duplicate and duplicateAsChild actions.
  • apps/ui/src/components/views/board-view/hooks/use-board-actions.ts
    • Implemented a new handleDuplicateFeature useCallback hook.
    • The handleDuplicateFeature logic copies feature data and optionally sets dependencies for child duplication.
    • Added handleDuplicateFeature to the returned object of useBoardActions.
  • apps/ui/src/components/views/board-view/kanban-board.tsx
    • Extended KanbanBoardProps to include an optional onDuplicate handler.
    • Passed onDuplicate and onDuplicateAsChild handlers to KanbanCard components within the board.
Activity
  • Server-side feature creation and update logic was modified to remove duplicate title checks.
  • New UI components and logic were added to enable feature duplication and duplication as a child.
  • The useBoardActions hook was extended with a new function to handle the duplication process, including setting dependencies for child features.
  • Dropdown menus in both Kanban card headers and list view row actions were updated to expose the new duplication options.
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.

@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

📝 Walkthrough

Walkthrough

The PR removes duplicate title validation from the backend feature creation and update endpoints, then adds comprehensive UI support for duplicating features either as siblings or as children within the board view, kanban cards, and list views.

Changes

Cohort / File(s) Summary
Backend Duplicate Validation Removal
apps/server/src/routes/features/routes/create.ts, apps/server/src/routes/features/routes/update.ts
Removed pre-create and pre-update duplicate title checks, allowing features to be created/updated with duplicate titles and skipping 409 conflict responses.
Board View Duplication Integration
apps/ui/src/components/views/board-view.tsx
Exposed handleDuplicateFeature action handler from useBoardActions and wired duplication callbacks to both ListView and KanbanBoard with sibling/child variants.
Kanban Card Duplication Support
apps/ui/src/components/views/board-view/components/kanban-card/card-header.tsx, apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx, apps/ui/src/components/views/board-view/kanban-board.tsx
Added onDuplicate and onDuplicateAsChild props throughout kanban card hierarchy, integrated nested dropdown menus with Copy icon for duplication actions in card headers, and passed handlers through to card instances.
List View Duplication Support
apps/ui/src/components/views/board-view/components/list-view/list-view.tsx, apps/ui/src/components/views/board-view/components/list-view/row-actions.tsx
Added onDuplicate and onDuplicateAsChild handlers to row actions, created nested submenu UI with Copy and GitFork icons for sibling and child duplication across multiple status branches.
Duplication Feature Logic
apps/ui/src/components/views/board-view/hooks/use-board-actions.ts
Introduced handleDuplicateFeature method that creates feature copies via existing handleAddFeature logic, supporting both sibling duplication and child duplication modes with appropriate toast notifications.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

Enhancement, Testers-Requested

Poem

🐰 A rabbit's tale of features bright,
Copy-paste with pure delight!
Siblings born and children too,
Duplication magic through and through!
No title checks to slow us down,
Just springin' features all around! 🐇

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding the ability to duplicate features and duplicate them as children, which aligns with the primary objectives and all file changes.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into v0.15.0rc

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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 introduces the ability to duplicate features, either as a standalone copy or as a child of the original feature. This is achieved by removing the backend validation that prevented duplicate feature titles and adding the necessary UI elements and logic on the frontend. The core logic for duplication in use-board-actions.ts is well-implemented.

My main feedback is regarding the UI implementation in kanban-card/card-header.tsx and list-view/row-actions.tsx. In both files, the menu for duplicating features has been added in multiple places, leading to significant code duplication. I've left specific comments suggesting how to refactor this by creating a reusable component within each file to improve maintainability.

Comment on lines +120 to +152
{onDuplicate && (
<DropdownMenuSub>
<div className="flex items-center">
<DropdownMenuItem
onClick={(e) => {
e.stopPropagation();
onDuplicate();
}}
className="text-xs flex-1 pr-0 rounded-r-none"
>
<Copy className="w-3 h-3 mr-2" />
Duplicate
</DropdownMenuItem>
{onDuplicateAsChild && (
<DropdownMenuSubTrigger className="text-xs px-1 rounded-l-none border-l border-border/30 h-8" />
)}
</div>
{onDuplicateAsChild && (
<DropdownMenuSubContent>
<DropdownMenuItem
onClick={(e) => {
e.stopPropagation();
onDuplicateAsChild();
}}
className="text-xs"
>
<GitFork className="w-3 h-3 mr-2" />
Duplicate as Child
</DropdownMenuItem>
</DropdownMenuSubContent>
)}
</DropdownMenuSub>
)}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

There's significant code duplication for the 'Duplicate' feature menu. This same block of JSX is repeated four times in this file for different feature statuses (running, backlog, waiting/verified, and in-progress).

To improve maintainability and reduce redundancy, I suggest extracting this logic into a dedicated component within this file.

Here's an example of what that component could look like:

const DuplicateFeatureSubMenu = ({
  onDuplicate,
  onDuplicateAsChild,
}: {
  onDuplicate?: () => void;
  onDuplicateAsChild?: () => void;
}) => {
  if (!onDuplicate) {
    return null;
  }

  return (
    <DropdownMenuSub>
      <div className="flex items-center">
        <DropdownMenuItem
          onClick={(e) => {
            e.stopPropagation();
            onDuplicate();
          }}
          className="text-xs flex-1 pr-0 rounded-r-none"
        >
          <Copy className="w-3 h-3 mr-2" />
          Duplicate
        </DropdownMenuItem>
        {onDuplicateAsChild && (
          <DropdownMenuSubTrigger className="text-xs px-1 rounded-l-none border-l border-border/30 h-8" />
        )}
      </div>
      {onDuplicateAsChild && (
        <DropdownMenuSubContent>
          <DropdownMenuItem
            onClick={(e) => {
              e.stopPropagation();
              onDuplicateAsChild();
            }}
            className="text-xs"
          >
            <GitFork className="w-3 h-3 mr-2" />
            Duplicate as Child
          </DropdownMenuItem>
        </DropdownMenuSubContent>
      )}
    </DropdownMenuSub>
  );
};

You could then replace each duplicated block with:

<DuplicateFeatureSubMenu onDuplicate={onDuplicate} onDuplicateAsChild={onDuplicateAsChild} />

Comment on lines +414 to +438
{handlers.onDuplicate && (
<DropdownMenuSub>
<div className="flex items-center">
<DropdownMenuItem
onClick={withClose(handlers.onDuplicate)}
className="flex-1 pr-0 rounded-r-none"
>
<Copy className="w-4 h-4 mr-2" />
Duplicate
</DropdownMenuItem>
{handlers.onDuplicateAsChild && (
<DropdownMenuSubTrigger className="px-1 rounded-l-none border-l border-border/30 h-8" />
)}
</div>
{handlers.onDuplicateAsChild && (
<DropdownMenuSubContent>
<MenuItem
icon={GitFork}
label="Duplicate as Child"
onClick={withClose(handlers.onDuplicateAsChild)}
/>
</DropdownMenuSubContent>
)}
</DropdownMenuSub>
)}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Similar to the changes in kanban-card/card-header.tsx, the JSX for the 'Duplicate' feature menu is duplicated multiple times in this file (five times, to be exact). This makes the component harder to read and maintain.

I recommend refactoring this into a reusable component within this file. This will make the code cleaner and easier to manage if the duplicate menu ever needs to be changed.

Here's a possible implementation for the component:

const DuplicateFeatureSubMenu = ({
  handlers,
  withClose,
}: {
  handlers: { onDuplicate?: () => void; onDuplicateAsChild?: () => void };
  withClose: (handler: () => void) => () => void;
}) => {
  if (!handlers.onDuplicate) {
    return null;
  }

  return (
    <DropdownMenuSub>
      <div className="flex items-center">
        <DropdownMenuItem
          onClick={withClose(handlers.onDuplicate)}
          className="flex-1 pr-0 rounded-r-none"
        >
          <Copy className="w-4 h-4 mr-2" />
          Duplicate
        </DropdownMenuItem>
        {handlers.onDuplicateAsChild && (
          <DropdownMenuSubTrigger className="px-1 rounded-l-none border-l border-border/30 h-8" />
        )}
      </div>
      {handlers.onDuplicateAsChild && (
        <DropdownMenuSubContent>
          <MenuItem
            icon={GitFork}
            label="Duplicate as Child"
            onClick={withClose(handlers.onDuplicateAsChild)}
          />
        </DropdownMenuSubContent>
      )}
    </DropdownMenuSub>
  );
};

You can then use it like this in place of the repeated blocks:

<DuplicateFeatureSubMenu handlers={handlers} withClose={withClose} />

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.

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

1086-1104: Consider stripping run‑state fields when duplicating a feature.

Spreading the full Feature copies transient state (e.g., planSpec, startedAt, error, summary, passes), which can make the duplicate look pre-run. If that’s not intended, omit those fields before calling handleAddFeature.

♻️ Suggested refinement
-      const { id: _id, status: _status, ...featureData } = feature;
+      const {
+        id: _id,
+        status: _status,
+        startedAt: _startedAt,
+        justFinishedAt: _justFinishedAt,
+        planSpec: _planSpec,
+        error: _error,
+        summary: _summary,
+        passes: _passes,
+        titleGenerating: _titleGenerating,
+        descriptionHistory: _descriptionHistory,
+        ...featureData
+      } = feature;

Also applies to: 1126-1126

apps/ui/src/components/views/board-view/components/list-view/row-actions.tsx (1)

414-437: Optional: extract the duplicate submenu to reduce repetition.

The same DropdownMenuSub block is repeated across status branches; a small helper would cut maintenance overhead.

Also applies to: 491-515, 562-586, 638-662, 690-714

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant