Skip to content
Development
Skill

/loop-bb-pr

Compose a /loop that monitors a Bitbucket PR for activity (new comments, review state changes, merge, decline) via the bb-api wrapper. Use when the user says "watch bitbucket PR", "monitor BB PR", "loop-bb-pr", "слідкуй за PR", "поллі bb pr", or pastes a

From plugin
lets-workflow
1725 skills15 agents26 commands

Claude Code

$ npx -y skills add restarter/lets-workflow --skill loop-bb-pr --agent claude-code

SKILL.md

loop-bb-pr.SKILL.md
name: loop-bb-pr
description: Compose a /loop that monitors a Bitbucket PR for activity (new comments, review state changes, merge, decline) via the bb-api wrapper. Use when the user says "watch bitbucket PR", "monitor BB PR", "loop-bb-pr", "слідкуй за PR", "поллі bb pr", or pastes a bitbucket.org/<workspace>/<repo>/pull-requests/<id> URL and wants periodic check-ins. Composes a paste-ready /loop block — does NOT invoke /loop (UI command). Local test skill.

loop-bb-pr

Compose a `/loop` that periodically polls a Bitbucket PR via the `bb-api` wrapper and surfaces changes (new comments, review state, merge, decline).

The skill **never invokes `/loop` itself** at initial start — Claude Code's `/loop` is a UI command. It composes the prompt and presents for paste; once active, the autonomous run uses `ScheduleWakeup` directly per tick (that part is model-callable).

> **IMPORTANT:** If the spec below invokes any deferred tool (e.g. `AskUserQuestion`), you MUST load and call it as specified.

Step 1: Resolve PR URL

Parse `args` parameter for URL. If not provided, AskUserQuestion:

AskUserQuestion(
  questions=[{
    question: "Bitbucket PR URL to watch?",
    header: "PR URL",
    options: [
      { label: "I'll paste it", description: "Send the bitbucket.org/.../pull-requests/N URL in your next message" },
      { label: "Cancel", description: "Abort composition" }
    ],
    multiSelect: false
  }]
)

If user picks "I'll paste it", wait for URL in their next message.

**Normalize then validate** — real BB URLs often have query strings (`?at=branch&type=...`) or trailing slashes. Strip before regex match:

URL="<from input>"
URL="${URL%%\?*}"   # strip query string (everything from ? onward)
URL="${URL%#*}"     # strip fragment (everything from # onward)
URL="${URL%/}"      # strip trailing slash

Then **strict validation** — normalized URL must match exactly:

^https://bitbucket\.org/[a-zA-Z0-9_-]+/[a-zA-Z0-9_.-]+/pull-requests/[0-9]+$

If validation fails: surface error, exit. Do NOT proceed with malformed URL — the composed prompt may persist (if user switches to interval mode in v1.1) and we don't want arbitrary input in `.claude/scheduled_tasks.json`.

Extract via regex or sed (from normalized URL):

  • `WORKSPACE` — first segment after `bitbucket.org/`
  • `REPO` — second segment
  • `PR_ID` — final numeric segment

Step 2: Verify bb-api availability

which bb-api 2>/dev/null

If `bb-api` not found in PATH:

┌─ LETS ─────────────────────────────────┐
│  bb-api not available.                 │
│  Install bb-api wrapper first.         │
│  (curl fallback planned for v1.1.)     │
└────────────────────────────────────────┘

Exit. v0 hard-requires bb-api.

Step 3: Verify access (always run)

Default-on pre-flight: confirm bb-api auth + URL points at a real PR before composing a 1200s loop. Cheaper to fail here than to ship a /loop the autonomous run immediately rejects.

bb-api get "/repositories/$WORKSPACE/$REPO/pullrequests/$PR_ID" 2>&1 | head -20

Always surface the result to the user as a short summary (title, state, comment count) — confirms what they're about to watch.

If error:

  • **401/403 (auth)** → surface "Bitbucket auth failed — check bb-api credentials" and exit
  • **404** → surface "PR not found at <URL> — check URL" and exit
  • **other errors** → surface verbatim error and exit

Never proceed to compose a /loop if Step 3 fails.

Step 4: Compose /loop

Substitute slots:

  • `<URL>` — validated URL from Step 1
  • `<WS>` `<REPO>` `<ID>` — parsed components
  • `<STATE_FILE>` — `.lets/loop-state/bb-pr-<ID>.json` (relative to project root)

Template (dynamic mode — model self-paces via ScheduleWakeup):

/loop check Bitbucket PR <URL> for activity since baseline.

State file: .lets/loop-state/bb-pr-<ID>.json (workspace=<WS>, repo=<REPO>, id=<ID>)

Use bb-api to fetch (READ-ONLY):
- `bb-api get /repositories/<WS>/<REPO>/pullrequests/<ID>` → state, title, participants
- `bb-api get /repositories/<WS>/<REPO>/pullrequests/<ID>/comments` → count, latest activity timestamp

On FIRST tick (state file does not exist):
- Create .lets/loop-state/ directory if missing
- Write baseline to .lets/loop-state/bb-pr-<ID>.json as JSON: {state, comment_count, latest_activity, approver_count, title, captured_at}
- Report "baseline established for PR #<ID> (<title>): state=<X>, comments=<N>, approvers=<M>"
- Reschedule via ScheduleWakeup(delaySeconds=1200, prompt=<this entire /loop prompt verbatim>, reason="watching BB PR <ID> — baseline")

On SUBSEQUENT ticks (state file exists):
- Read baseline from .lets/loop-state/bb-pr-<ID>.json
- Fetch current state via bb-api (both endpoints above)
- Compare:
  - If state changed to DECLINED or MERGED → report final state and STOP (do NOT call ScheduleWakeup)
  - If comment_count increased → report "N new comments since last check, latest from <user> at <time>" and STOP
  - If approver_count increased → report "approver added: <username>" and STOP
  - If nothing changed → report "no change (T+<minutes>m since baseline)" and reschedule via ScheduleWakeup(1200, verbatim, "watching BB PR <ID> — no change")

Hard constraints (READ-ONLY enforcement):
- Loop must NOT call bb-api with POST/PUT/DELETE
- Loop must NOT comment, approve, decline, merge, or change PR state
- Loop must NOT push to the PR's branch
- On bb-api auth error (401/403): report "Bitbucket auth failed" and STOP (do NOT retry blind — user must investigate)
- On 404 (PR not found / deleted): report "PR not accessible" and STOP
- On other transient errors (timeout, 5xx): log error and reschedule ONCE. If second consecutive error of same type, STOP and surface.
- Never re-baseline silently — the baseline is captured ONCE on first tick

Termination (each STOP surfaces a single-paragraph summary in assistant text):
- state-change-final: PR closed/merged/declined
- comment-detected: new comments since baseline
- approver-change: app
Read more
@restarter
Ships withlets-workflow

A development workflow plugin for Claude Code Stop babysitting your AI. Start shipping with it.

1725 skills15 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
17
Star history of restarter/lets-workflow on GitHub, a chart by star-history.com

Other skills on lets-workflow.

goal-test

goal-test

Local sandbox for experimenting with Claude Code's /goal command (stop-hook condition + LLM-evaluator driving autonomous work…

loop-gh-pr

loop-gh-pr

Compose a /loop that watches all open GitHub PRs for activity (new PRs, new commits, new comments) and auto-prepares a READ-ONLY…

loop-test

loop-test

Local sandbox for experimenting with Claude Code's /loop command (interval + dynamic/self-paced scheduling) applied to LETS…

agent-report

agent-report

Internal skill for commands. The file transport for agent reports - hand every Task-dispatched agent a REPORT_FILE, then collect…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about loop-bb-pr.

Which coding agents can use loop-bb-pr?
loop-bb-pr installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.