Skip to main content
Generalbendrucker

gitlab:ci-monitor

Investigate GitLab CI pipeline failures and extract diagnostics. Use when watching MR CI, branch builds, or specific pipelines.

Stars
13
Source
bendrucker/claude
Updated
2026-05-31
Slug
bendrucker--claude--ci-monitor
View on GitHubRaw SKILL.md

// install — copy + paste into any project

mkdir -p .claude/skills && curl -fsSL https://raw.githubusercontent.com/bendrucker/claude/HEAD/plugins/gitlab/skills/ci-monitor/SKILL.md -o .claude/skills/ci-monitor.md

Drops the SKILL.md into .claude/skills/ci-monitor.md. Works with Claude Code, Cursor, and any agent that loads SKILL.md files from .claude/skills/.

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 for how the gitlab:logs agent narrows long job traces via ANSI section_start/section_end markers.