name: task-finish
description: Open a draft pull request for a work-item branch and post the PR link back on the item. Idempotent — an existing open PR is reported, never duplicated. Deliberately does NOT move the item's role; review state changes when the PR merges.
steps:
  - ask: { as: issueId, type: text, message: "Issue id?" }
  - ask: { as: branch, type: text, message: "Source branch?" }
  - ask: { as: title, type: text, message: "Pull request title?" }
  # A PR with an empty description makes the reviewer reconstruct the change from the diff. The skill
  # composes this (what changed + why); optional so a caller that truly has nothing to add can skip.
  - ask:
      as: body
      type: text
      message: "Pull request description (what changed and why)? Empty to skip."
      optional: true
  # Closing is the strongest thing a PR can say about an item, and it used to be said on every
  # caller's behalf — so a spike or the first of several PRs serving one item closed it on merge.
  - ask:
      as: relation
      type: text
      message: "Does this PR CLOSE the item or only RELATE to it? (closes/relates; empty = closes)"
      optional: true
  # Declared as an ask so it is DISCOVERABLE via baron_recipe_list — a hidden input nobody can find
  # was a real dogfood failure once. Optional: unanswered means "don't enable it".
  - ask:
      as: autoComplete
      type: text
      message: "Auto-complete: merge automatically once checks/policies pass? (yes/no)"
      optional: true
  # Idempotency probe: the engine (not the agent) decides create-vs-report (decision #19).
  - do: scm.pr.find
    as: existingPr
    with:
      sourceBranch: ${branch}
  - message: "PR already open for ${branch}: ${existingPr.url} — not duplicating."
    when:
      truthy: "${existingPr}"
  - do: scm.pr.create
    as: pr
    when:
      falsy: "${existingPr}"
    with:
      # targetBranch omitted — defaults to the repo's default branch, keeping the recipe portable.
      title: ${title}
      sourceBranch: ${branch}
      body: ${body}
      # Abstract: the adapter renders the provider's native linking keyword (GitHub `Closes #N`,
      # Azure `AB#N`), so the tracker really associates PR and item — not just a comment with a URL.
      linkedIssueKey: ${issueId}
      linkedIssueRelation: ${relation}
      # The person finishing the task owns the PR. Providers without PR assignees (Azure) negotiate
      # the gap instead of failing — you never have to add yourself in the UI afterwards.
      assignees: ["@me"]
      autoComplete: ${autoComplete}
      draft: true
  - do: scm.pr.thread
    when:
      falsy: "${existingPr}"
    with:
      pullRequestId: ${pr.id}
      body: "Opened for issue ${issueId}."
  # Give the card full context: reviewers/QA opening the work item see the PR without digging.
  - do: issue.comment
    when:
      falsy: "${existingPr}"
    with:
      id: ${issueId}
      body: "PR opened: ${pr.url} (from ${branch}). Baron leaves the role as it is; what happens at merge is your provider's — a provider that closes the linked item lands it in done, otherwise move it yourself (task-move) or let task-sync sweep the drift."
  - message: "Opened PR ${pr.url} for ${issueId}. Role unchanged — the merge outcome is the provider's; task-move or task-sync settles the rest."
    when:
      falsy: "${existingPr}"
