Deep Duplicate
Relevant source files
The following files were used as context for generating this wiki page:
Deep Duplicate is a high-fidelity cloning feature within the Refined GitHub Projects extension that addresses the limitations of GitHub's native "duplicate" functionality. While GitHub natively only copies an issue's title, Deep Duplicate clones the full issue context, including the body description, project-specific custom fields, assignees, labels, and complex issue relationships such as parent-child (sub-issue) links and dependencies (blocked by/blocking).
Sources: README.md:46-46, README.md:120-123
The system follows a guided workflow that allows users to review and modify every aspect of the item before the duplication process begins. It utilizes a background queue system to fire sequential GraphQL and REST API mutations, ensuring compliance with GitHub's rate limits and preventing Personal Access Token (PAT) bans.
Sources: src/components/bulk/bulk-duplicate-modal.tsx:431-443, src/entries/background/handlers/duplicate-handlers.ts:161-291
User Interface and Interaction Flow
The frontend implementation of Deep Duplicate is managed by the BulkDuplicateModal component. This component implements a three-step wizard to guide the user through the cloning process.
Duplication Wizard Steps
| Step | Name | Description |
|---|---|---|
| 1 | Select Sections | Users choose which specific data points (Title, Body, Labels, Field Values, etc.) to carry over. |
| 2 | Edit Values | Users can modify the content of the selected sections (e.g., editing the title or changing a custom field value) before duplication. |
| 3 | Review & Apply | A final summary of the duplication plan is shown before triggering the background process. |
Sources: src/components/bulk/bulk-duplicate-modal.tsx:40-40, src/components/bulk/bulk-duplicate-modal.tsx:185-288, src/components/bulk/bulk-duplicate-modal.tsx:327-356
Selection Logic
The modal pre-populates the selection by fetching a preview of the source item. It identifies all supported field types including TEXT, SINGLE_SELECT, ITERATION, NUMBER, and DATE.
Sources: src/components/bulk/bulk-duplicate-modal.tsx:455-484, src/entries/background/handlers/hierarchy-handlers.ts:70-76
The following diagram illustrates the UI state transition:
Architecture and Data Flow
Deep Duplicate utilizes a split architecture between the Content Script (UI) and the Background Service Worker (API logic) to maintain security and reliability.
Request Resolution
Before duplication, the system must resolve DOM-extracted item IDs (e.g., issue:123) into real GitHub GraphQL Node IDs. This is handled by the resolveProjectItemIds helper, which paginates through project items to find matching database IDs.
Sources: src/entries/background/helpers.ts:515-594, src/entries/background/handlers/hierarchy-handlers.ts:50-58
Duplication Sequence
The background process, triggered via runDeepDuplicate, constructs a QueueTask array. These tasks are executed sequentially with a mandatory 1-second delay (sleep(1000)) between mutations to avoid 403 Abuse rate limits.
Field and Relationship Handling
Deep Duplicate specifically handles complex metadata that standard cloning tools often miss.
Supported Data Structures
| Category | Logic | API Method |
|---|---|---|
| Project Fields | Clones custom fields (Single Select, Iterations, etc.) | GraphQL updateProjectV2ItemFieldValue |
| Labels & Assignees | Applies multiple IDs during or immediately after creation | GraphQL addLabelsToLabelable |
| Issue Type | Preserves the specific GitHub Issue Type | GraphQL updateIssue |
| Sub-issues | Re-links the new issue to the original parent | GraphQL addSubIssues |
| Dependencies | Copies "Blocked by" and "Blocking" relationships | GitHub REST API (v3) |
Sources: src/entries/background/handlers/duplicate-handlers.ts:161-267, src/entries/background/handlers/duplicate-handlers.ts:12-22
Relationship Preservation
The system distinguishes between internal project fields and repository-level relationships. For dependencies, it uses the GitHub REST API to manage blocked_by and blocking links, as these features often require REST endpoints for specific dependency operations.
Sources: src/entries/background/handlers/duplicate-handlers.ts:237-279, src/entries/background/helpers.ts:182-205
Concurrency and Performance
To prevent overwhelming the browser or the GitHub API, Deep Duplicate implements strict concurrency controls:
- Concurrent Limit: Only 3 duplication processes can run simultaneously across all tabs.
- Semaphore Control: The system uses
acquireDuplicate()andreleaseDuplicate()to manage state. If the limit is reached, the UI displays a warning: "3 duplications are already in progress." - Rate Limit Backoff: If a 403 or 429 error is encountered, the
withRateLimitRetryhelper automatically pauses the queue and waits for the duration specified in theRetry-Afterheader.
Sources: src/entries/background/handlers/duplicate-handlers.ts:32-38, src/components/bulk/bulk-duplicate-modal.tsx:431-435, src/entries/background/helpers.ts:696-716
Implementation Details
Data Mapping
The function buildFieldValueFromSource converts raw GraphQL response data into the input format required for mutations.
export function buildFieldValueFromSource(fieldValue: FieldValue): Record<string, unknown> | null {
if ('text' in fieldValue) return { text: fieldValue.text }
if ('optionId' in fieldValue) return { singleSelectOptionId: fieldValue.optionId }
if ('iterationId' in fieldValue) return { iterationId: fieldValue.iterationId }
if ('number' in fieldValue) return { number: fieldValue.number }
if ('date' in fieldValue) return { date: fieldValue.date }
return null
}
Sources: src/entries/background/helpers.ts:413-420
Queue Reporting
Progress is communicated back to the UI in real-time via broadcastQueue. This updates the "Live Queue Tracker" with human-readable status messages such as "Cloning issue..." or "Applying duplicate plan...".
Sources: src/entries/background/handlers/duplicate-handlers.ts:293-308, src/entries/background/helpers.ts:672-689
Deep Duplicate ensures that complex GitHub Project items can be reproduced accurately while maintaining the integrity of project-level and repository-level metadata.
Sources: README.md:120-123