feat: Drive Bitbucket from the terminal with the twg CLI - #81
Merged
Conversation
The GitHub track had `gh` wired end to end; the Jira track described PR content but never opened or merged anything, so every Bitbucket PR ended with someone clicking through the web UI. This closes that asymmetry. - create-pr now opens the PR with `twg bb prs create --description-file`, and finalize-pr reads status, replies to and resolves review comments, and merges with `twg bb prs merge` behind an explicit confirmation. - New `bitbucket-integration.md` partial and `bitbucket-review-management` skill, the counterparts to the GitHub ones, both scoped to the jira tracker in the install filter. - New docs/cli-setup.md covering both CLIs end to end, linked from the README's Requirements section. Two things the docs make loud because the symptom is misleading: `twg bb` needs a Bitbucket token that `twg login` does not create -- OAuth login covers Jira and Confluence only, and `twg setup bitbucket` adds the rest. Skipping it leaves `twg whoami` working and every `twg bb` call failing, which reads like a permissions problem and is not. The prompts degrade instead of stopping: with no CLI they still push the branch and hand over the title, description file and create-PR URL. What they must not do is report "no Bitbucket access" without checking, since twg authenticates from its own saved profile rather than the environment. Verified by running the real installer both ways: --tracker jira installs the two Bitbucket assets and no GitHub ones, --tracker github the inverse. Full `npm run check` green (88 tests, markdownlint clean). Also corrected while touching these inventories: both partials indexes were missing three pre-existing entries, README's skill count was stale at 13, and docs/ was not in package.json files, so the new guide would not have shipped to npm consumers.
Found while running the new finalize-pr flow against a real PR: `twg bb prs get` in text mode prints the payload twice -- the description raw and again as rendered HTML -- which measured 62 KB on an ordinary docs PR against ~600 bytes for the CLI's own compact agent view. An agent that follows the previous wording burns its context on a duplicated HTML blob for the same six fields it needed. Both the partial and the skill now lead with the compact form and keep the full payload as the exception, for when the description body is genuinely what you want.
The Jira track could not finish a ticketless PR. create-pr hard-stopped
when {ticket-id} was still a placeholder, and both prompts treated the
Jira comment and transition as mandatory -- so a docs/* or chore/*
branch, which legitimately has no ticket, forced you to invent one. That
is exactly what happened trying to finalize the boilerplate docs PR.
Both prompts now derive the ticket from the branch name and skip every
Jira step when there is none, reporting the skip explicitly rather than
leaving a checklist line ambiguous. When a ticket is present the Jira
steps are still non-blocking: a failed comment or a forbidden transition
gets reported, never stops the flow. The PR or the merge is the
deliverable; the Jira update is bookkeeping a human finishes in seconds.
Three design calls behind it:
Detection matches the ticket-ID pattern, not a branch-prefix list. A
prefix list fails closed on every prefix nobody enumerated -- refactor/,
ci/, release/, spike/ -- while the pattern covers them all. The prefix
check stays where it belongs, as the separate "does this branch follow
convention" step, since a branch can follow the convention and still
carry no ticket.
No project-key alternation is hardcoded. .agents-toolkit.json already
carries jira.projectKey per repo, and baking a fixed set into a shared
toolkit would mean a release every time a new key appears -- there are
already more in circulation than a short list would cover. A key that
differs from the configured one warns rather than fails.
An explicit {ticket-id} argument that disagrees with the branch stops and
asks. That mismatch almost always means the wrong branch is checked out,
and guessing writes a comment on the wrong ticket.
Two tests pin the behavior, and both were mutation-checked: breaking the
prompt content makes them fail.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The GitHub track has
ghwired end to end —create-github-propens the PR,finalize-github-prmerges it,resolve-github-reviewsclears threads. The Jira track described PR content and stopped there:create-prproduced a description, and a human clicked through the Bitbucket web UI to actually open it.That asymmetry has a second, worse failure mode. Because nothing named a Bitbucket CLI, an agent looking for credentials finds no
BITBUCKET_*environment variable and concludes there is no access — whiletwgsits installed, authenticated from its own profile. That happened in a real session: a finished branch sat unopened because the tool to open it was never considered.What changed
Prompts now act.
create-propens the PR withtwg bb prs create --description-file.finalize-prreads status and pipeline state, replies to and resolves review comments, and merges withtwg bb prs merge— behind an explicit user confirmation, since merging is irreversible.Two new assets, mirroring the GitHub ones, both scoped to the
jiratracker:_partials/bitbucket-integration.md— the counterpart togithub-integration.md.skills/bitbucket-review-management/— the counterpart togithub-review-management.Developer docs: new
docs/cli-setup.mdcovers installing, authenticating and verifying both CLIs, linked from the README's Requirements section.The two things worth reading
twg bbneeds a Bitbucket token thattwg logindoes not create. OAuth login covers Jira and Confluence;twg setup bitbucketadds the rest. Skip it andtwg whoamiworks while everytwg bbcall fails — a symptom that reads like a permissions problem and is not. Every asset here says so.The prompts degrade, they do not stop. With no CLI they still push the branch and hand over the title, the description file and a create-PR URL. What they must not do is report "no Bitbucket access" without checking first.
Verification
--tracker jirainstallsbitbucket-integration.md+bitbucket-review-managementand neither GitHub asset;--tracker githubthe exact inverse. This is what proves the filter registration, not just the tests.twg --helprather than written from memory — three were wrong on the first pass and corrected (comment createtakes--textnot--content,branch createtakes--branchnot--name,diff-linetakes--textnot--line).npm run checkgreen: 88 tests, markdownlint clean, typecheck, build, eslint.twg upgrade; that command does not exist in the shipped CLI (verified on 1.2.7), so the guide documentstwg update.Incidental fixes
Touching these inventories surfaced pre-existing drift, fixed here rather than left to read as new:
_partials/README.mdandprompts/README.md) were missinggithub-integration.md,release-node.mdandrelease-wordpress.md.docs/was not inpackage.jsonfiles, so the new guide would not have shipped to npm consumers and the README link would have dangled.