Claude
Skills
Sign in
Back

recce-review

Included with Lifetime
$97 forever

Review dbt model data changes using Recce. Triggers when: user asks to review data changes, check data impact, run recce review, validate model changes before committing, review a Recce Cloud PR session, connect MCP to a cloud session, pastes a GitHub PR / GitLab MR URL, or pastes a Recce Cloud session/launch URL for cloud-mode review.

Cloud & DevOpsscripts

What this skill does


# /recce-review — Data Review Orchestration

This skill orchestrates tracked-model handoff, sub-agent dispatch, post-review cleanup, and risk-based next-step suggestions.

It also handles **cloud-mode flips** from any of:

- a **PR URL** (GitHub) or **MR URL** (GitLab, incl. self-hosted) — the skill fetches PR/MR comments and extracts the Recce Cloud session ID
- a **Recce Cloud session URL** (`.../sessions/<UUID>`) or **launch URL** (`.../launch/<UUID>`) — the skill extracts the session ID directly, no SCM access required (useful for any Cloud host: production, staging, localhost dev)
- a **bare session ID** (UUID)

In all cases the skill verifies cloud authentication and flips the running MCP server into cloud mode by calling its `set_backend` tool — no reconnect, no restart.

Claude Code launches `recce mcp-server` (stdio) at session start in **local mode** and the same server stays alive for the whole session. Mode switching happens **inside** that running server via MCP tool calls.

Follow these steps in order.

---

## Step 0: Cloud-mode resolution (only if user provided a relevant URL or asked for cloud review)

> Skip this step if the user did not provide a PR/MR URL, a Cloud session/launch URL, a bare UUID, and did not mention "cloud", "cloud session", or "Recce Cloud".

### 0.1 Classify the input and resolve the session ID

Examine the user's input and pick the matching path. The session-ID UUID format used below is `[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`.

**Path A — Recce Cloud URL (fast path, no SCM access needed):**

If the input matches either of these path shapes (any host — `cloud.reccehq.com`, `staging.cloud.reccehq.com`, `localhost:3000`, etc.):

- `<scheme>://<host>/launch/<UUID>`
- `<scheme>://<host>/sessions/<UUID>`

…extract the UUID, set `SESSION_ID` to it, and **skip directly to Step 0.4**. The session ID under `/launch/` and `/sessions/` is the same identifier consumed by `set_backend(session_id=...)`.

**Path B — Bare UUID:**

If the input is just a UUID matching the regex above, set `SESSION_ID` to it and **skip directly to Step 0.4**.

**Path C — PR/MR URL:**

If the input is a GitHub PR URL (`https://github.com/<owner>/<repo>/pull/<n>`), a GitHub PR number (when the working directory is already a GitHub repo), or a GitLab MR URL (`https://<host>/<group>[/<subgroup>...]/<project>/-/merge_requests/<iid>`, works for `gitlab.com` and self-hosted hosts), continue to Step 0.2.

**Path D — Nothing matched:**

Ask: "Which session should I review? Paste a Recce Cloud session URL (e.g., `https://cloud.reccehq.com/launch/<UUID>`), a GitHub PR URL, a GitLab MR URL, or a session UUID."

### 0.2 Detect the SCM and verify access

> Steps 0.2 and 0.3 run **only for Path C** (PR/MR URL). If you arrived here from Path A or Path B in 0.1 with a `SESSION_ID` already in hand, skip to Step 0.4.

First identify which source-control host owns the URL:

```bash
bash ${CLAUDE_PLUGIN_ROOT}/skills/recce-review/scripts/scm/detect.sh "<PR_OR_MR_URL>"
```

The script prints exactly one of `SCM=github`, `SCM=gitlab`, `SCM=bitbucket`, or `SCM=unknown`. Detection is path-based (recognizes `/pull/`, `/-/merge_requests/`, `/pull-requests/`) so it works for self-hosted hosts.

Then run the matching readiness check:

**If `SCM=github`:**

```bash
bash ${CLAUDE_PLUGIN_ROOT}/skills/recce-review/scripts/scm/github-ready.sh
```

The script prints `GITHUB=ready` (with `GITHUB_VIA=cli`) or `GITHUB=unavailable`. If unavailable, tell the user: "GitHub CLI is not authenticated. Run `gh auth login` and re-run /recce-review." Stop.

**If `SCM=gitlab`:**

```bash
bash ${CLAUDE_PLUGIN_ROOT}/skills/recce-review/scripts/scm/gitlab-ready.sh
```

GitLab access works via either the `glab` CLI **or** a `GITLAB_TOKEN` environment variable (either is sufficient; both work for self-hosted GitLab). The script prints `GITLAB=ready` (with `GITLAB_VIA=cli` when `glab auth status` succeeds, otherwise `GITLAB_VIA=token`) or `GITLAB=unavailable`.

If unavailable, tell the user: "No GitLab credentials found. Either run `glab auth login` (for self-hosted, use `glab auth login --hostname <host>`) or export `GITLAB_TOKEN=<your-personal-access-token>` (with `read_api` scope), then re-run /recce-review."

Stop on unavailable.

**If `SCM=bitbucket` or `SCM=unknown`:** tell the user the URL's source-control host is not yet supported by this skill (Bitbucket support is planned). Stop.

### 0.3 Fetch PR/MR comments and parse the session ID

Run the comments fetcher matching the detected SCM:

**If `SCM=github`:**

```bash
bash ${CLAUDE_PLUGIN_ROOT}/skills/recce-review/scripts/scm/github-comments.sh "<PR_REF>"
```

`<PR_REF>` is the PR URL or PR number.

**If `SCM=gitlab`:**

```bash
bash ${CLAUDE_PLUGIN_ROOT}/skills/recce-review/scripts/scm/gitlab-comments.sh "<MR_URL>"
```

`<MR_URL>` must be the full URL (the script parses host, project path, and IID from it). The script prefers `glab api` when available (which already knows about self-hosted host config), falling back to `curl` against `https://<host>/api/v4` with `GITLAB_TOKEN`.

Both scripts print one comment/note body per record on stdout. Search those bodies for a Recce Cloud session URL of the form `<scheme>://<host>/(sessions|launch)/<UUID>`. Production comments use `cloud.reccehq.com`, but other hosts (`staging.cloud.reccehq.com`, `localhost:3000`) and the `/launch/` path variant are also valid — accept any host and either path. `<UUID>` is `[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`.

- Exactly one match — show it and confirm with the user.
- Multiple distinct matches — list each match with the surrounding comment body so the user can identify which session is the relevant one (typically the most recent Recce Cloud bot comment after a force-push). Ask the user to choose. The fetcher scripts return only comment bodies, not author/timestamp metadata — disambiguation is done by visible content.
- No match — tell the user: "No Recce Cloud session URL found in PR/MR comments. Run `recce-cloud list --type pr` to find an existing session, or `recce-cloud upload` from the PR/MR branch to create one — then paste the session ID (UUID) here." Wait for input and validate against the UUID regex.

### 0.4 Verify Recce Cloud authentication

Recce Cloud credentials live in **`~/.recce/profile.yml`** (key: `api_token`) or in the **`RECCE_API_TOKEN`** environment variable. Either is sufficient; `RECCE_API_TOKEN` takes precedence.

Run:

```bash
bash ${CLAUDE_PLUGIN_ROOT}/skills/recce-review/scripts/check-recce-auth.sh
```

The script prints exactly one of `AUTH=env`, `AUTH=file`, or `AUTH=missing`. It does not print or transmit the token itself — it only reports which source supplied it.

- `AUTH=env` or `AUTH=file` — proceed to Step 0.5.
- `AUTH=missing` — offer to run the OAuth flow inline. Ask the user, verbatim:

  > Recce Cloud credentials not found in `~/.recce/profile.yml` and `RECCE_API_TOKEN` is not set.
  >
  > Would you like me to run `recce connect-to-cloud` now? It opens your browser for the OAuth flow and writes `api_token` back into `~/.recce/profile.yml` on success. (Typically ~30s. The command starts a short-lived local HTTP server on a random port to receive the OAuth callback — make sure no firewall blocks loopback callbacks and that the browser it opens is on this machine. On a headless/remote shell, the command will print the URL and wait; you can open that URL on your host machine to complete the flow.)

  Then handle the user's reply:

  **If the user says yes** — run the command via Bash with a generous timeout (the user must click through the OAuth flow in a browser):

  ```bash
  recce connect-to-cloud
  ```

  Pass `timeout: 600000` (10 minutes) to the Bash tool so the command isn't killed mid-flow. Stream the command's stdout to the user — if it prints a URL ("Please visit ..."), the user may need to open it manually.

  After the command exits (regardless of how), re-run the auth 

Related in Cloud & DevOps