capability_id: pr.merge
version: "1.0.0"
description: Execute a pull request merge.
input_schema:
  type: object
  required: [owner, name, prNumber]
  properties:
    owner: { type: string, minLength: 1 }
    name: { type: string, minLength: 1 }
    prNumber: { type: integer, minimum: 1 }
    method:
      type: string
      # Lowercase values are canonical; uppercase aliases are accepted so callers
      # familiar with GitHub's GraphQL enum (MERGE/SQUASH/REBASE) keep working.
      # Normalization happens in the GraphQL/CLI handlers.
      enum: [merge, squash, rebase, MERGE, SQUASH, REBASE]
    deleteBranch: { type: boolean }
    admin:
      type: boolean
      description: "Use administrator privileges to bypass branch protection. Routes to gh CLI --admin."
    auto:
      type: boolean
      description: "Enable auto-merge once branch protection requirements are satisfied. Routes to gh CLI --auto."
  additionalProperties: false
  not:
    type: object
    properties:
      admin: { const: true }
      auto: { const: true }
    required: [admin, auto]
output_schema:
  type: object
  required: [prNumber, method, isMethodAssumed, queued, deleteBranch]
  properties:
    prNumber: { type: integer, minimum: 1 }
    method: { type: string, enum: [merge, squash, rebase] }
    isMethodAssumed: { type: boolean, description: "true when method was not specified by the caller and defaults to merge" }
    queued: { type: boolean }
    deleteBranch: { type: boolean }
    admin: { type: boolean }
    auto: { type: boolean }
  additionalProperties: false
routing:
  preferred: graphql
  fallbacks: [cli]
  suitability:
    - when: params
      predicate: cli if deleteBranch == true
      reason: "gh CLI required for --delete-branch (mergePullRequest GraphQL cannot delete refs)"
    - when: params
      predicate: cli if admin == true
      reason: "gh CLI required for --admin (mergePullRequest GraphQL has no admin bypass)"
    - when: params
      predicate: cli if auto == true
      reason: "gh CLI required for --auto"
graphql:
  # GQL limitation: deleteBranch: true unsupported, triggers CLI fallback
  operationName: PrMerge
  operationType: mutation
  documentPath: src/gql/operations/pr-merge.graphql
  # Resolution maps the user-facing inputs to the GraphQL mutation variables:
  # - pullRequestId is the GraphQL node id, looked up from owner/name/prNumber.
  # - mergeMethod is the uppercase GraphQL enum, derived from the lower/mixed-case
  #   `method` input. The single-call path (capability-registry handler) does the
  #   same normalization, so chain and single-call paths agree.
  resolution:
    lookup:
      operationName: PrNodeId
      documentPath: src/gql/operations/pr-node-id.graphql
      vars:
        owner: owner
        name: name
        prNumber: prNumber
    inject:
      - target: pullRequestId
        source: scalar
        path: repository.pullRequest.id
      - target: mergeMethod
        source: input_upper
        from_input: method
cli:
  command: pr merge
