Ship Task

Merge the open PR for the current branch and close the related ticket (Linear or Jira). Always confirm the exact actions with the human before executing anything.


Step 1 — Discover the PR

gh pr view --json number,title,url,state,isDraft,baseRefName,headRefName,mergeable,mergeStateStatus,statusCheckRollup

Handle each case:


Step 2 — Discover the ticket

Look for a ticket reference in this order:

  1. Branch name — parse the current branch for a ticket ID pattern [A-Z]+-[0-9]+ (e.g. ENG-123, PLT-42)
  2. PR title / bodygh pr view --json title,body and scan for the same pattern
  3. Recent commitsgit log --oneline -20 and scan commit messages
  4. Human — if no ticket ID is found, ask the human to provide one. If they confirm there is none, set TICKET_ID=none and skip Steps 5b onward.

Once a candidate ID is found, determine the tracker:

Record the resolved TRACKER (Linear Jira none) and TICKET_ID — carry these values into all subsequent steps.

Step 3 — Confirm with the human

Before doing anything irreversible, present a clear confirmation summary. Use the values gathered in Steps 1–2:

Here's what I'm about to do — confirm or reject each item:

  [1] Merge PR #<number> "<title>"
        Branch:    <headRefName> → <baseRefName>
        URL:       <url>
        Method:    squash merge  (preferred; will re-confirm if repo requires a different method)
        After merge: delete branch <headRefName>

  [2] Transition ticket <TICKET_ID> "<ticket title>"   ← omit this block if TICKET_ID=none
        Tracker:   <Linear | Jira>
        From:      <current status>
        To:        Done  (or equivalent terminal state in your workflow)

Type YES to proceed, NO to abort, or tell me what to change.

Do not proceed until the human types YES (exact word, case-insensitive). Treat any other response as a change request or abort.


Step 4 — Merge the PR

Use gh to merge with squash as the default:

gh pr merge <number> --squash --delete-branch

If --squash is rejected by the repo (squash merges disabled), stop and re-confirm with the human before retrying with --merge. Do not silently fall through to a different merge strategy — the human approved squash specifically.

Capture the merge commit SHA from the output (look for the SHA line in gh pr merge stdout or run gh pr view <number> --json mergeCommit --jq '.mergeCommit.oid' after the merge).

If the merge fails for any reason: stop, report the full error, and do not attempt the ticket transition.


Step 5 — Transition the ticket

Skip this step entirely if TICKET_ID=none.

Linear

Discover Linear MCP tools at runtime. Look for tools matching get_issue, list_workflow_states (or equivalent), and save_issue / update_issue.

Fetch the issue to get the teamId. Then fetch available workflow states for that team and find the terminal state whose name matches “Done”, “Completed”, “Shipped”, or “Closed” (exact match first, then case-insensitive substring).

Idempotency: If the issue is already in a terminal state, skip the transition and inform the human.

Use the discovered save/update tool to apply the state change, passing the issue ID and the matched state ID.

Jira

Use the Atlassian MCP to fetch available transitions. Discover tool names at runtime (search for getTransitionsForJiraIssue or equivalent). Find the transition whose name matches “Done”, “Closed”, or “Resolved” (exact match first, then case-insensitive substring). If ambiguous, surface all candidates to the human to choose.

Idempotency: Fetch the current issue status first. If it is already in a terminal state, skip the transition and inform the human.

Execute using transitionJiraIssue (or equivalent discovered tool).

Fallback

If neither MCP tool is available or the transition fails, print the direct ticket URL and instruct the human to close it manually.


Step 6 — Report

Print a brief summary:

✓ PR #<number> merged  (SHA: <merge-sha>)
✓ Branch <headRefName> deleted
✓ Ticket <TICKET_ID> transitioned → Done

Omit the ticket line if TICKET_ID=none. If the ticket transition was not possible, call that out clearly so the human can finish manually.