Investigate GitLab CI pipeline failures and extract diagnostics. Use when watching MR CI, branch builds, or specific pipelines.
Scanned 5/28/2026
Install to Claude Code
npx -y skills add bendrucker/claude --skill ci-monitor --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Ci Monitor?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/bendrucker-ci-monitor)More formats (shields.io, HTML) on the badges page.
---
name: gitlab:ci-monitor
description: Investigate GitLab CI pipeline failures and extract diagnostics. Use when watching MR CI, branch builds, or specific pipelines.
allowed-tools:
- Monitor
- TaskStop
- Agent
- Bash(bun:*)
- Bash(glab ci:*)
- Bash(glab api:*)
- Bash(glab mr view:*)
- Bash(git remote:*)
- Bash(jq:*)
---
# CI Monitor
Watch a GitLab pipeline (for an MR, a branch, or a specific pipeline ID), reacting to failures by dispatching the `gitlab:logs` agent for diagnostics. Exits cleanly when the pipeline is green, the MR is closed, a pipeline-id target reaches a terminal status, or the wall-clock cap is hit.
## Target
$ARGUMENTS
Accepts an MR URL, a branch name, a pipeline ID, or derives one from the current branch:
- MR mode: pass a URL like `https://gitlab.com/group/project/-/merge_requests/123`.
- Branch mode: pass a branch name (e.g. `main`, a release branch). Project path `group/project` is inferred from `git remote get-url origin` in the current directory; pass `--project <group/project>` to override.
- Pipeline-id mode: pass a pipeline ID (e.g. from a manually-triggered pipeline or a re-run). Project is inferred from the git remote; override with `--project <group/project>`.
- If no argument is given, derive an MR URL from the current branch: `glab mr view --output json | jq -r '.web_url'`.
## Workflow
#### Start the monitor
Launch the watch script via the `Monitor` tool with `persistent: true`:
- MR mode: `bun ${CLAUDE_SKILL_DIR}/scripts/watch.ts --mr <mr-url>`
- Branch mode: `bun ${CLAUDE_SKILL_DIR}/scripts/watch.ts --branch <name> [--project <group/project>]`
- Pipeline-id mode: `bun ${CLAUDE_SKILL_DIR}/scripts/watch.ts --pipeline-id <id> [--project <group/project>]`
- Optional flags: `--interval <seconds>`, `--max-minutes <N>`, `--queued-timeout <minutes>`, `--api-error-threshold <N>`.
Exactly one of `--mr`, `--branch`, or `--pipeline-id` is required. In branch and pipeline-id modes, `--project` is inferred from the current git remote when omitted. Pipeline-id mode queries `glab api projects/:id/pipelines/:pid` directly; if the pipeline does not exist the watcher exits non-zero on the first call.
The script emits one JSON object per line on stdout. When the first probe is already green, it emits a single `status: success` event and exits, so there is no separate initial-green path to handle. In pipeline-id mode the script also exits after emitting `status: failing`, because a specific pipeline has a finite lifetime and will not restart on its own.
#### Event schema
Each line is one of:
- `{"type":"status","state":"running|failing|success","sha":"...","run_id":"..."}`: `run_id` is the GitLab pipeline ID.
- `{"type":"conflicts","sha":"..."}`: MR reports merge conflicts against the target branch. MR mode only.
- `{"type":"queued-timeout","minutes":N}`: pipeline has been queued longer than the threshold.
- `{"type":"api-error","consecutive":N}`: consecutive `glab` failures crossed the threshold.
- `{"type":"rate-limited","retry_after":"..."}`: emitted only when `glab` surfaces structured rate-limit data.
- `{"type":"pr-closed"}`: MR was merged, closed, or the source branch was deleted. MR mode only. The script exits after emitting.
- `{"type":"max-time-reached","minutes":60}`: wall-clock cap hit. The script exits after emitting.
In branch and pipeline-id modes, `conflicts` and `pr-closed` are never emitted (there is no MR metadata to derive them from).
The script exits on `status: success` in every mode. In pipeline-id mode it also exits on `status: failing` (the pipeline is terminal).
#### React to events
On `status: failing`, invoke the `gitlab:logs` agent via the `Agent` tool with the pipeline ID from `run_id`. This applies to all three modes; the logs agent accepts a pipeline ID, so pipeline-id mode fits naturally:
```
Agent(
subagent_type="gitlab:logs",
model="haiku",
prompt="Fetch failing-job logs for pipeline <run_id>. Return the JSON summary described in the logs agent definition."
)
```
Surface the summary to the parent conversation. Do not attempt fixes; `pull-request:babysit` owns that decision.
On `conflicts`, report the SHA with conflicts and stop watching; conflict resolution belongs to the caller.
On `queued-timeout`, `api-error`, or `rate-limited`, surface the event once and keep the monitor running. Consecutive rate-limit or api-error events indicate the monitor should be stopped manually.
On `pr-closed` or `max-time-reached`, the monitor has already exited. Report and finish.
#### Stopping
The monitor exits on its own for `status: success`, `pr-closed`, and `max-time-reached`. In pipeline-id mode it also exits on `status: failing`. To stop earlier (for example after surfacing a failure summary to the user), call `TaskStop` on the monitor task.
## Reference
See [references/log-parsing.md](references/log-parsing.md) for how the `gitlab:logs` agent narrows long job traces via ANSI `section_start`/`section_end` markers.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!