# Bitbucket

> Manage Bitbucket Cloud pull requests, comments, tasks, and pipelines from the command line, and inspect any Bitbucket repo read-only without cloning it. Use when working with PRs, reviewing code, leaving inline comments, resolving comment threads, creating PR tasks, checking whether a PR is green, listing PR reviewers or activity, triggering or inspecting Bitbucket Pipelines, or looking up reviewer account IDs. Also use to read a file, browse a directory, list branches/tags/commits, or diff two refs on a remote Bitbucket repository you have not cloned.

- Skill: `avantmedialtd/bitbucket` (Agent Skill)
- Install (CLI): `npx skillmds@latest add avantmedialtd/bitbucket`
- Raw SKILL.md: https://api.skillmd.com/api/skills/avantmedialtd/bitbucket/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: avantmedialtd (https://skillmd.com/u/avantmedialtd)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/avantmedialtd/bitbucket

---


# Bitbucket Cloud CLI

Command-line tool for managing Bitbucket Cloud via `af bitbucket` (alias `af bb`).

## Setup

Bitbucket Cloud authentication is **separate from Jira/Confluence**. Atlassian API tokens scoped for Jira do not authenticate against Bitbucket Cloud — they return 401. Add the following to your project's `.env`:

- `BITBUCKET_USERNAME` — Bitbucket username or workspace token label (falls back to `ATLASSIAN_EMAIL` / `JIRA_EMAIL`)
- `BITBUCKET_API_TOKEN` — Workspace API token or app password (`BITBUCKET_APP_PASSWORD` is also accepted as a legacy alias)

Generate credentials:

- **Workspace API token (recommended for automation)** — `https://bitbucket.org/<workspace>/workspace/settings/api-tokens`
- **App password** — `https://bitbucket.org/account/settings/app-passwords/`

Verify credentials with `af bb whoami` — it prints the authenticated account (and its account ID). If that fails, nothing else will.

## Workspace and Repo Resolution

The target workspace and repo are resolved in this order:

1. `--workspace W --repo R` flags (highest priority)
2. `af.json`:
    ```json
    {
        "bitbucket": {
            "workspace": "myws",
            "repo": "myrepo"
        }
    }
    ```
3. The git `origin` remote, if it points at `bitbucket.org`
4. Error with help text

## Read-Only Inspection (No Clone Needed)

**Reach for this before you clone.** `af bb` can read a remote Bitbucket repo directly over the API — file contents, directory listings, branches, tags, commits, and diffs — at any ref. If you only need to *look* at code (answer a question about a file, check whether a branch exists, see what changed between two refs), do it here rather than cloning or fetching. Everything in this section is read-only and safe to run speculatively.

### Account and Repository

- `af bb whoami` — the authenticated account
- `af bb repo list [--query Q] [--role R] [--sort S]` — repos in the workspace; needs only a workspace, so it works **outside** a Bitbucket clone
- `af bb repo get` — the resolved repository (`repo` alone defaults to `get`)

### Branches and Tags

- `af bb branch list [--query Q] [--sort S]` / `af bb branch get <name>`
- `af bb tag list [--query Q] [--sort S]` / `af bb tag get <name>`

`branch` and `tag` alone default to `list`. Both drain all pages.

### Commits

- `af bb commit list [--branch B] [--include REF] [--exclude REF] [--limit N]`
    - `--include` / `--exclude` are repeatable; `--limit` must be a positive integer (default 25)
- `af bb commit get <sha> [--diff | --diffstat | --patch]` — pick at most one; bare form prints commit metadata

### Source and Diffs

- `af bb src read <path> [--ref REF]` — raw file content straight to stdout
- `af bb src ls [path] [--ref REF] [--recursive]` — browse a directory at a ref
- `af bb diff <spec> [--stat]` — diff a revspec, e.g. `main..feature`

`--ref` defaults to the repository's main branch. `src` has no default sub-action — you must say `read` or `ls`. `diff` requires a revspec.

## Quick Reference

There is **no per-subcommand help**. `af bb pr --help` prints the single full command and flag listing — as does bare `af bb` or `af bb help`. Both `af bb --help` and `af bitbucket --help` are intercepted by af's router and print only a short stub, so reach for one of the others.

### Pull Requests

- `af bb pr list [--state OPEN|MERGED|DECLINED|SUPERSEDED|ALL] [--mine | --author Q]`
- `af bb pr get <id>`
- `af bb pr diff <id>`
- `af bb pr create --title T [--from B] [--to B] [--description / --description-file F] [--reviewers a,b] [--draft]`
    - `--from` also accepts `--source` / `--src`; `--to` also accepts `--destination` / `--dest` (af's own README uses the alias spelling)
- `af bb pr update <id> [--title T] [--description / --description-file F] [--reviewers a,b]`
- `af bb pr approve <id>`
- `af bb pr unapprove <id>`
- `af bb pr request-changes <id>`
- `af bb pr merge <id> [--strategy merge_commit|squash|fast_forward] [--close-source]`
- `af bb pr decline <id>`
- `af bb pr status <id>` — build/commit statuses, grouped by commit ("is this PR green?")
- `af bb pr reviewers <id> [--pending]` — reviewers and their approval state; `--pending` narrows to those who have not responded
- `af bb pr activity <id> [--limit N]` — chronological feed of approvals, updates, and comments (`--limit` is a positive integer, default 25)

Reviewers must be passed as Bitbucket Cloud **account IDs** (not usernames). Use `af bb members --query <name>` to look them up.

`pr status` is informational and **always exits 0**, even when a status is `FAILED`. Never gate a script on its exit code — parse `--json` instead.

### PR Comments

Comment body shape is determined by flags on `add`:

- `af bb pr comment list <pr-id> [--resolved | --unresolved]`
    - The two flags are mutually exclusive. Resolution is a **thread** property: the filter keeps or drops whole threads by their root comment's state, so the replies of a matching thread are retained. It narrows `--json` output too.
- `af bb pr comment get <pr-id> <cid>`
- `af bb pr comment add <pr-id> --body / --body-file [--file PATH --line N] [--reply-to CID]`
    - `--file PATH --line N` makes the comment an inline anchor
    - `--reply-to CID` threads the comment as a reply
- `af bb pr comment update <pr-id> <cid> --body / --body-file`
- `af bb pr comment delete <pr-id> <cid>`
- `af bb pr comment resolve <pr-id> <cid>` — resolve a comment thread
- `af bb pr comment reopen <pr-id> <cid>` — reopen a resolved thread

### PR Tasks

Tasks can stand alone or be anchored to a comment:

- `af bb pr task list <pr-id> [--resolved | --unresolved]`
    - Mutually exclusive, and unlike the thread-rooted comment filter this is a flat match on the task's own state
- `af bb pr task add <pr-id> --body / --body-file [--on-comment CID]`
- `af bb pr task update <pr-id> <tid> [--body / --body-file] [--resolved | --unresolved]`
- `af bb pr task delete <pr-id> <tid>`

### Pipelines

- `af bb pipeline list [--branch B] [--status PENDING|IN_PROGRESS|SUCCESSFUL|FAILED|...]`
- `af bb pipeline get <uuid|build-number>`
- `af bb pipeline trigger [--branch B] [--commit SHA] [--custom NAME] [--var k=v]`
- `af bb pipeline stop <uuid>`
- `af bb pipeline steps <uuid>`
- `af bb pipeline logs <pipeline-uuid> <step-uuid> [--follow]`

### Member Lookup

- `af bb members [--query Q]` — Look up account IDs for use with `--reviewers`

## Output Formats

- Default: Markdown
- JSON: Add `--json` to any subcommand for raw API responses

Six commands emit raw text **by design** and ignore `--json`, because their payload is already a file, a diff, or a log:

- `af bb src read` (raw file bytes)
- `af bb diff <spec>` without `--stat` (raw unified diff)
- `af bb commit get --diff` and `af bb commit get --patch`
- `af bb pr diff <id>` (raw unified diff)
- `af bb pipeline logs` (raw step log)

Their `--stat` / `--diffstat` counterparts do honour `--json`.

## Common Workflows

### Inspect a remote repo without cloning it

```bash
# What repos are in the workspace? (works outside a Bitbucket clone)
af bb repo list --query payments

# What branches exist, and what landed recently?
af bb branch list --query release
af bb commit list --branch main --limit 10

# Read a file at a ref, and browse around it
af bb src read src/auth/login.ts --ref release/2.1
af bb src ls src/auth --ref release/2.1 --recursive

# What changed between two refs?
af bb diff main..feature/sso --stat   # summary first
af bb diff main..feature/sso          # then the full diff
```

### Review a PR

```bash
af bb pr get 42
af bb pr status 42            # is it green?
af bb pr reviewers 42 --pending
af bb pr diff 42
af bb pr comment list 42 --unresolved
af bb pr task list 42 --unresolved
af bb pr activity 42 --limit 20
```

### Triage what is still outstanding

```bash
# Only the threads and tasks still open — the fast pre-merge sweep
af bb pr comment list 42 --unresolved
af bb pr task list 42 --unresolved

# Resolve a thread once you've addressed it (reopen if it wasn't really fixed)
af bb pr comment resolve 42 9876543
af bb pr comment reopen 42 9876543
```

### Create a PR from current branch

```bash
af bb pr create --title "Add SonarQube support" \
  --description-file ./PR_DESCRIPTION.md \
  --reviewers 557058:abc-123,557058:def-456
```

### Leave an inline review comment

```bash
# Anchor a comment to a specific line of a file in the diff
af bb pr comment add 42 \
  --file src/auth/login.ts --line 87 \
  --body "This branch isn't covered by tests — can we add one?"

# Thread a reply
af bb pr comment add 42 --reply-to 9876543 --body "Good catch, fixing."
```

### Add and resolve PR tasks

```bash
# Standalone task
af bb pr task add 42 --body "Update CHANGELOG before merge"

# Task anchored to an existing comment
af bb pr task add 42 --on-comment 9876543 --body "Rename this variable"

# Resolve when done
af bb pr task update 42 12345 --resolved
```

### Approve and merge

```bash
af bb pr approve 42
af bb pr merge 42 --strategy squash --close-source
```

### Trigger and watch a pipeline

```bash
# Trigger a custom pipeline with variables
af bb pipeline trigger --branch main --custom deploy-prod --var ENV=prod

# Watch logs as the step runs
af bb pipeline list --branch main --status IN_PROGRESS
af bb pipeline steps <pipeline-uuid>
af bb pipeline logs <pipeline-uuid> <step-uuid> --follow
```

### Look up reviewer account IDs

```bash
# Reviewers must be account IDs, not usernames
af bb members --query "Jane"
af bb pr update 42 --reviewers 557058:abc-123
```

## Tips

- **Use the alias `af bb`** — every subcommand below also works under `af bitbucket`
- **Don't clone to read** — `af bb src read` / `src ls` / `diff` answer most "what's in this file / what changed" questions straight off the remote
- **Reviewers are account IDs only** — usernames silently fail; always resolve via `af bb members`
- **Workspace tokens beat app passwords** — they're scoped per-workspace and easier to rotate
- **`--json` for scripting** — pipe through `jq` for automation
- **PR descriptions from files** — `--description-file ./PR_BODY.md` avoids quoting hell in the shell

## Error Handling

- Errors always print as plain text to stderr. `--json` does **not** wrap them in a JSON envelope — there is no `{"error": ...}` output, and the flag is not consulted on any error path.
- Exit codes are only ever `0` (success) or `1` (any error, auth failures included). `401` is an HTTP status, never a process exit code — if you see one, it typically means Bitbucket-Cloud-specific credentials are missing or a Jira-scoped Atlassian token was supplied. Check with `af bb whoami`.
- `af bb pr status` exits `0` even when a build status is `FAILED`. Gate on its `--json` payload, not on `$?`.

