magic:done
This skill should be used when the user says "the PR is merged", "la PR est mergée", "close the ticket", "fermer le ticket", "finalize the task", "finaliser la tâche", "task is done", "tâche terminée", "mark as done", "marquer comme terminé", or indicates the PR has already been merged and they want to close out the task. Do NOT use this skill if the user just finished coding and wants to create a PR — use /magic:pr instead.
References
references/messages.md— All user-facing message templates (EN/FR)
magic-slash v0.42.4 - /done
The steps below must be executed in order because each one depends on the previous result — for example, cleanup must only happen after confirming the merge, and the Jira transition must happen before the summary so it can reflect the actual state.
You are an assistant that finalizes a task after the PR has been merged. The goal is to close the loop cleanly: confirm nothing is left dangling (unmerged PRs, open tickets, stale branches). This matters because abandoned worktrees and forgotten Jira tickets accumulate quickly and create confusion for the whole team.
The flow is: verify merge → update tracker → update desktop → clean up → report. Each step feeds into the next — the merge check determines whether to proceed at all, the tracker update captures the PR links, the cleanup removes local artifacts, and the summary reflects what actually happened.
Fire-and-forget commands: Every bash command in this skill is fire-and-forget. Run the command, read its output, and move to the next step immediately. Never re-run a command to verify a previous command succeeded. Never run
git worktree listto confirm a worktree was removed — the command's exit code and output are sufficient.No improvised commands: Execute only the exact bash commands specified in each step. Do not substitute alternative commands (e.g., do not replace
ls -dwithgit worktree list). Do not add diagnostic or verification commands between steps.When in doubt, ask: If a command produces unexpected output or fails in an unclear way, use AskUserQuestion to ask the user how to proceed. Never loop or retry silently — asking is always better than guessing.
Configuration
Read ~/.config/magic-slash/config.json and determine the parameters based on the current repo:
- Identify the current repo by comparing
$PWDwith the paths in.repositories - For each parameter, check the repo config
- If no value is defined, use the default value
Language parameters
| Parameter | Repo path | Default |
|---|---|---|
| Jira language | .repositories.<name>.languages.jiraComment | "en" |
| Discussion language | .repositories.<name>.languages.discussion | "en" |
Issues parameters
| Parameter | Repo path | Default | Description |
|---|---|---|---|
| Comment on PR | .repositories.<name>.issues.commentOnPR | true | Add a comment on the ticket |
Step 0: Check configuration
Before starting, verify that the Magic Slash configuration exists:
CONFIG_FILE=~/.config/magic-slash/config.json
if [ ! -f "$CONFIG_FILE" ]; then
# Display error based on system language
fi
If the config does not exist
Display MSG_CONFIG_ERROR (see references/messages.md).
Step 1: Extract the ticket ID
Determine whether you are inside a worktree or the main repo, then extract the ticket ID accordingly.
Case A: Inside a worktree
Get the current directory name:
basename "$PWD"
The worktree name follows the pattern {repo-name}-{TICKET-ID} (e.g.: my-api-PROJ-123, my-web-PROJ-123).
Extract the TICKET-ID using the pattern:
- Jira: Extract the last
[A-Z]+-\d+match from the directory name. This avoids false positives when the repo name itself contains uppercase segments (e.g.:my-API-PROJ-123→PROJ-123, notAPI-PROJ). You can also cross-reference with the repo name fromconfig.jsonto strip it and isolate the ticket ID. - GitHub: the last numeric segment after the repo name (e.g.:
123inmy-api-123)
Case B: Inside the main repo (not a worktree)
If the current directory matches a repo path from config.json directly (no ticket ID in the directory name), extract the ticket ID from the branch name:
git branch --show-current
Branch patterns: feature/PROJ-123, feature/my-api-123, PROJ-123-some-description, etc.
Fallback
If still no ticket ID found from either case, ask the user.
Step 2: Find the associated PR(s)
Read the config to identify all configured repos and search for associated worktrees (multi-repo support):
cat ~/.config/magic-slash/config.json
For each configured repo, build the expected worktree path and check if it exists. The worktree is always a sibling of the repo directory, named {repo-dir-name}-{TICKET-ID}:
REPO_PARENT=$(dirname {REPO_PATH})
REPO_DIR=$(basename {REPO_PATH})
WORKTREE_PATH="$REPO_PARENT/${REPO_DIR}-{TICKET_ID}"
[ -d "$WORKTREE_PATH" ] && echo "$WORKTREE_PATH"
Use only
[ -d ]for worktree detection — do not usegit worktree list. The naming convention is sufficient and avoids confusion with stale git worktree metadata.
If the current directory is itself a worktree for this ticket (Case A from Step 1), include it in the list.
No worktrees found (Case B from Step 1)
If no worktrees exist for this ticket, the user is working directly in the main repo on a feature branch. Find the PR from the current branch:
- Get the branch name:
git branch --show-current - Use
mcp__github__list_pull_requeststo find the PR (search by head branch, state: all) - If no match, search by title containing the ticket ID
- If no PR is found, ask the user for the PR number or URL
Then skip directly to Step 3 (there are no worktrees to clean up later — Step 5.5 will be skipped).
With worktrees found
For each found worktree, find the associated PR:
- Get the branch name:
git -C {WORKTREE_PATH} branch --show-current - Use
mcp__github__list_pull_requeststo find the PR (search by head branch, state: all) - If no match by branch, search by title containing the ticket ID
- If still no match, search by recent commit messages containing the ticket ID
- If no PR is found after all attempts, ask the user for the PR number or URL
Step 3: Verify PR is merged
For each found PR, use mcp__github__get_pull_request and check the merged field.
If the PR is NOT merged
Display MSG_PR_NOT_MERGED (see references/messages.md) and stop.
If the PR IS merged
Continue to the next steps.
Multi-repo: partial merge
If some PRs are merged and others are not, display a warning listing which PRs are still open, and only proceed with the merged ones. Do not transition Jira to "Done" unless ALL associated PRs are merged — the ticket should stay in its current state until the full work is complete. Continue with cleanup only for the merged worktrees.
Step 4: Update the Jira/GitHub ticket
Check Atlassian integration
Read integrations.atlassian from ~/.config/magic-slash/config.json. Default: true.
If integrations.atlassian is false, skip the entire "For Jira tickets" section below. Only execute "For GitHub issues".
For Jira tickets
If a Jira ticket ID is found, use the MCP Atlassian tools:
Note: If you don't know the cloudId, first use mcp__atlassian__getAccessibleAtlassianResources to obtain it.
- Retrieve available transitions with
mcp__atlassian__getTransitionsForJiraIssue - Transition to "Done": Find the transition matching "Done" / "Terminé" / "Closed" / "Fermé" and apply it with
mcp__atlassian__transitionJiraIssue - Add a final comment with
mcp__atlassian__addCommentToJiraIssue(unlesscommentOnPRisfalse)
Jira comment format based on .languages.jiraComment
Use MSG_JIRA_DONE_COMMENT (see references/messages.md).
If the "Done" transition doesn't exist, try:
- "Closed"
- "Fermé"
- "Resolved"
- "Terminé"
- "Complete"
Edge cases
- Ticket already in "Done"/"Closed": Skip the transition silently — just add the comment (if enabled). Do not treat this as an error.
- Transition fails (permissions, custom workflow): Display a warning with the error, add the comment anyway, and continue to cleanup. The user can manually transition the ticket later.
- No Jira/GitHub issue found: Skip this step entirely and continue to cleanup. Warn the user that no ticket was updated.
For GitHub issues
If the ticket is a GitHub issue, add a comment using MSG_GITHUB_DONE_COMMENT (see references/messages.md). Do NOT close the issue — let the PR auto-close handle it.
Step 5: Update Magic Slash metadata (desktop app only)
This step only applies when the Magic Slash desktop app is running (the environment variables MAGIC_SLASH_PORT and MAGIC_SLASH_TERMINAL_ID are set). If they are not set, skip this step silently.
[ -n "$MAGIC_SLASH_PORT" ] && [ -n "$MAGIC_SLASH_TERMINAL_ID" ] && curl -s "http://127.0.0.1:$MAGIC_SLASH_PORT/metadata?id=$MAGIC_SLASH_TERMINAL_ID&title=$(echo -n 'Done - {TICKET_ID}' | jq -sRr @uri)&status=PR%20merged" > /dev/null 2>&1 || true
Replace {TICKET_ID} with the actual ticket ID.
Step 5.5: Clean up worktrees and branches
If no worktrees were found at Step 2 (Case B — working directly in the main repo), skip this entire step and go to Step 6.
Before proceeding, check each worktree for uncommitted changes:
git -C {WORKTREE_PATH} status --porcelain
If there are uncommitted changes, warn the user and ask for confirmation before removing that worktree. List the dirty files so the user can decide. If the user declines, skip cleanup for that worktree and continue with the others.
For each worktree found at Step 2 (that the user confirmed or that is clean), perform the following cleanup. If any sub-step fails, display a warning and continue — never block the skill.
Track the cleanup outcome for each worktree (success / skipped / failed) — this will be used in the summary.
Execute steps 5.5.1 through 5.5.5 as a single linear pass. Run each command once and move to the next — do not verify the result of any sub-step before proceeding. If a command fails (non-zero exit code), capture the error, record the worktree as "failed", and skip to the next worktree. Do not re-run git worktree remove, do not run git worktree list, and do not add any verification commands between sub-steps.
5.5.1: Navigate to the main repo
You must leave the worktree directory before removing it:
cd {REPO_PATH}
5.5.2: Remove the worktree
git worktree remove --force {WORKTREE_PATH}
(--force because untracked files like .env, node_modules, etc. may remain)
5.5.3: Delete the local branch
git branch -D {BRANCH_NAME} 2>/dev/null || true
5.5.4: Delete the remote branch (best-effort)
git push origin --delete {BRANCH_NAME} 2>/dev/null || true
(Silent if already deleted by GitHub auto-delete)
5.5.5: Prune stale worktree references
git worktree prune
Alternatively, you may run all cleanup commands for one worktree as a single block:
cd {REPO_PATH} && \
git worktree remove --force {WORKTREE_PATH}; \
git branch -D {BRANCH_NAME} 2>/dev/null || true; \
git push origin --delete {BRANCH_NAME} 2>/dev/null || true; \
git worktree prune
Either way, do not insert any verification commands (such as git worktree list) between them.
Error handling
If the git worktree remove fails, display MSG_WORKTREE_REMOVE_FAILED (see references/messages.md) based on .languages.discussion and continue.
After displaying the warning, immediately proceed to the next worktree (or to Step 6 if this was the last one). Do not retry the failed command or run diagnostic commands. If the failure is unclear or unexpected, use AskUserQuestion to let the user decide how to proceed.
Multi-repo
Repeat steps 5.5.1→5.5.5 for each worktree, navigating (cd) to the corresponding main repo each time. After completing cleanup for all worktrees, move directly to Step 6. Do not run any global verification command (such as git worktree list) between worktrees or after the final cleanup.
Step 6: Summary
Display a summary based on .languages.discussion. The summary must reflect what actually happened — adapt each line based on the real outcome of the previous steps.
Dynamic fields
| Field | Success | Skipped / Partial | Failed |
|---|---|---|---|
| Ticket | {TICKET-ID} → Done | {TICKET-ID} → already Done or {TICKET-ID} → ⚠️ transition skipped | {TICKET-ID} → ⚠️ transition failed |
| Cleanup | Worktree removed, branch deleted | ⚠️ Skipped (uncommitted changes) or N/A (no worktree) | ⚠️ Failed (see warning above) |
Display MSG_DONE_SUMMARY (see references/messages.md) based on .languages.discussion, replacing the dynamic fields from the table above.
Step 7: Multi-repo summary (if applicable)
If multiple PRs were found across worktrees, display a combined summary based on .languages.discussion:
Adapt the cleanup and ticket lines using the same dynamic fields from Step 6.
Display MSG_DONE_SUMMARY_FULLSTACK (see references/messages.md) based on .languages.discussion, replacing the dynamic fields accordingly.