feat: add pr-update command to edit a PR title and/or description#43
Conversation
Adds `bb pr-update` (bash) + `bb_ops.pr_update` (Python) + the `pr_update`
MCP tool, closing a parity gap: the CLI could create, view, approve,
merge, decline, diff, and comment on PRs but had no way to edit an open
PR's title or body. Editing metadata previously required the Bitbucket
web UI.
The Bitbucket Cloud contract is a PUT to the same path pr_show GETs
(/repositories/{ws}/{slug}/pullrequests/{id}); there is no PATCH for the
pullrequests resource. Only the supplied fields go in the body, so the
PUT merges them into the existing PR, preserving the source/destination
branches and reviewers. This mirrors repo_update, which PUTs the same
path repo_show GETs for the analogous repo mutation.
Contract details, symmetric across both surfaces:
- title: omit = leave unchanged; a non-empty/non-whitespace string sets
it. An empty/whitespace title is rejected at the boundary (a PR must
have a title; Bitbucket rejects a blank one).
- description: three-way like repo_update -- omit = leave unchanged,
"" = clear the body, any other string = set it. A deliberate clear is
not collapsed into a no-op.
- At least one of title/description must be supplied; an empty-body PUT
is rejected before any network IO.
Bash surface adds `--title`, `--description`, and `--description-file`
(the last for large multiline bodies); `--description` and
`--description-file` are mutually exclusive. Positionals resolve
[repo] <pr-id> via the shared _resolve_pr_args heuristic, safe under
`set -u` on bash 3.2. Aliases: pr-update, pr-edit.
Tests: 15 new cases across bb_ops (PUT method + URL + body shape, the
three-way description contract, boundary rejections asserting no network
IO) and the MCP wrapper (field forwarding, None-vs-"" preservation, error
pr_id threading). pr_update added to the every-PR-op bad-id matrix and the
MCP tool-registry drift guard (count 41 -> 42). Full suite: 582 passing.
Docs: inline `bb help`, README PR section, and agents/bitbucket.md tool
surface updated together per CONTRIBUTING.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011tybd7wdRdZaaQvQRJEV3d
|
Claude finished @daniel-pittman's task in 2m 3s —— View job Review:
|
Reviewer noted the user-facing signature 'bb pr-update [repo] <id> --title T [--description D | --description-file F]' presents --title as required, but description-only updates are valid (the prose below correctly says 'at least one of'). Bracket --title too so the shape matches the actual contract. Four sites updated: - cmd_pr_update usage error when neither --title nor --description supplied (bb:1175) - cmd_pr_update usage error when pr_id missing (bb:1203) - cmd_help NOTES section (bb:2860) - README.md pr-update section The internal cmd_pr_update comment (bb:1111) already had the correct bracketing; user-facing strings now match it.
Semgrep (OSS): no findingsClean scan. Posted before the Claude review. |
CI Tests✅ Tests passed: the pytest suite across Python 3.10/3.11/3.12 (and bash syntax checks) is green on Posted before the Claude review so the test outcome is folded into the review. |
|
Claude finished @daniel-pittman's task in 1m 12s —— View job Review:
|
Review Gate✅ Gate: PASS — Review reported no HIGH/CRITICAL findings. |
Summary
Adds
bb pr-update(bash) +bb_ops.pr_update(Python) + thepr_updateMCP tool, closing a parity gap: the CLI could create, view, approve, merge, decline, diff, and comment on PRs but had no way to edit an open PR's title or body. Editing metadata previously meant the Bitbucket web UI.API contract
Bitbucket Cloud's PR mutation is a PUT to the same path
pr_showGETs (/repositories/{ws}/{slug}/pullrequests/{id}) — there is no PATCH for the pullrequests resource. Only the supplied fields go in the body, so the PUT merges them into the existing PR, preserving the source/destination branches and reviewers. This mirrorsrepo_update, which PUTs the same pathrepo_showGETs for the analogous repo mutation.Symmetric across the bash and Python surfaces:
repo_update— omit = leave unchanged,""= clear the body, any other string = set it. A deliberate clear is not collapsed into a no-op.title/descriptionmust be supplied; an empty-body PUT is rejected before any network IO.Bash surface
--description-filehandles large multiline bodies;--descriptionand--description-fileare mutually exclusive. Positionals resolve[repo] <pr-id>via the shared_resolve_pr_argsheuristic, safe underset -uon bash 3.2. Aliases:pr-update,pr-edit.Tests
15 new cases across
bb_ops(PUT method + URL + body shape, the three-way description contract, boundary rejections assertingopener.calls == []) and the MCP wrapper (field forwarding, None-vs-""preservation, errorpr_idthreading).pr_updateadded to the every-PR-op bad-id matrix and the MCP tool-registry drift guard (count 41 → 42). Full suite: 582 passing;bash -n bbclean.Docs
Inline
bb help, README PR section, andagents/bitbucket.mdtool surface updated together per CONTRIBUTING.🤖 Generated with Claude Code
https://claude.ai/code/session_011tybd7wdRdZaaQvQRJEV3d