CI control room for watching and unsticking Buildkite builds

One screen for every build in flight, the logs behind the failures, and the retry, cancel, and unblock buttons your platform team reaches for all day.

App
BuildkiteSlack BotEngineeringOperationsResearch & Monitoring
PromptCreate

I want a CI control room app that my platform team keeps open all day to watch and unstick builds without living in the Buildkite web interface. Build it as an app backed by Buildkite for everything about builds and agents, and Slack Bot for handing a build off to a teammate. This is a hands-on console, not an alerting workflow: nothing runs on a schedule, a person sits in front of it and presses buttons.

Resolve the Buildkite organization first with List Organizations, because almost every other path is scoped by organization slug. Then use List Pipelines to populate a settings view where someone picks which pipelines the board watches, how far back recent builds go (default the last 24 hours), and how often the board refreshes itself. Persist that configuration for the whole app so the team opens the same board. Keep the refresh interval sensible, around 20 to 30 seconds, because Buildkite rate limits per organization over a rolling 60 second window and this app sits open all day; back off politely when a request comes back rate limited rather than hammering, and always offer a manual refresh control too.

The main tab is a live board of in-flight and recent builds, grouped under their pipeline, loaded with List Builds for an Organization and filtered to the watched pipelines. Sort so anything still running or scheduled floats to the top, then finished builds newest first. Each row shows the build state as a coloured badge, the branch, who kicked it off, and elapsed time. For who kicked it off, use the build creator when there is one and fall back to the commit author, since builds started by a schedule or by the API often have no creator. For elapsed time, count from the start time for a running build and show total duration for a finished one; a build that is scheduled but has not started yet should read as queued with the time since it was created. Put a failed-only toggle in the header that narrows the board to failed and cancelled builds.

Flag builds that are running noticeably longer than normal for their pipeline. Work out a baseline per pipeline in the handler by taking recent finished builds that passed and computing the median of their durations, then flag any in-flight build whose elapsed time exceeds that baseline by a configurable multiplier, defaulting to 1.5 times. Show the flag as a clear visual marker on the row with the comparison spelled out, something like "running 22m, usually 9m". When a pipeline has too little history to have a meaningful median, skip the flag for it rather than guessing. Make the multiplier editable in settings so a noisy pipeline can be tuned down.

Clicking a row opens a build detail panel. Important: Buildkite builds are addressed by their per-pipeline sequential number, not by their UUID, so the detail route has to carry both the pipeline slug and the build number. Load the full record with Get a Build, which includes the per-job breakdown. Identify the failing job or jobs from that breakdown and pull the log with Get a Job's Log Output, but render only the tail, roughly the last 200 lines, in a monospaced scrolling block; build logs get enormous and the whole thing should never be loaded into the page. Alongside the log, show the build's annotations using List Annotations for a Build, rendering each one according to its style so errors and warnings read differently from information.

The detail panel is where the work happens, so wire up the action buttons. Retry Failed Jobs in a Build retries everything that failed in one press. Retry a Job sits on each individual job row for retrying just that step. Cancel a Build appears on builds still running or scheduled. Rebuild a Build appears on finished builds. Unblock a Job appears on any job that is a block step sitting waiting, so approvals can be released without switching tabs. Optionally add Reprioritize a Job for bumping a job up the queue when something urgent is stuck behind a backlog. Ask for confirmation before cancelling, refetch that build right after any action so the panel reflects the new state, and record which signed-in user pressed which button so the team can see who did what.

A second tab shows the agent fleet from List Agents. Give each agent a row with its name and hostname, connection state, the job it is currently running (linked through to that job's build when there is one), the queue it serves, and its agent version. Let the list be filtered by queue and by connection state, since finding the one wedged agent among many is the whole point. Put Pause an Agent and Stop an Agent buttons on each row, and Resume an Agent on any agent that is already paused, because pausing without a way back is a trap. Explain the difference inline: pausing stops an agent taking new jobs while it finishes its current one, which is what draining looks like, while stopping ends it outright. Confirm before stopping.

Add a share button on every build, both on the board row and inside the detail panel. It opens a dialog with a Slack channel picker populated by List Channels and an editable preview of the message, then posts with Send a Message. The message should be a formatted summary rather than a link dump: pipeline name, build number, state, branch, who triggered it, how long it ran, the name of the failing job, a short excerpt from the end of that job's log, and the Buildkite link to the build taken from the build's own web URL. Remember the last channel used and offer it as the default next time, and let the sender add a line of their own before posting, since handing off usually comes with context.

On permissions: viewing the board needs only read access to builds, pipelines, agents, and build logs, while every action button needs a token with write access. When the connected token cannot write, keep the action buttons visible but disabled with a short inline explanation rather than hiding them, so nobody wonders where the buttons went. One thing to avoid: do not build artifact downloading into this app, because those download links are short-lived redirects that expire in about a minute and are not worth storing or reusing.

What does this prompt do?

  • Shows a live board of running and recent builds grouped by pipeline, each row with its state, branch, who kicked it off, and how long it has been going, plus a failed-only filter and a flag on anything running much longer than that pipeline normally takes
  • Opens any build to the tail of the failing step's log and the notes the build left behind, with buttons to retry every failure, retry a single step, cancel, rebuild, or release a step waiting on approval
  • Gives the build machines their own tab: which are connected, what each is working on right now, which queue it serves, and pause, resume, or stop buttons for one that is wedged or being drained
  • Puts a share button on every build that posts a tidy summary and the build link straight into a Slack channel, so handing triage to someone else takes one click instead of copy-paste

What do I need to use this?

  • A Buildkite account containing the pipelines your team runs
  • A Buildkite access token that can start and cancel work, not just read it. Read-only access still shows the entire board, but the action buttons stay visible and disabled
  • A Slack workspace, plus the channel where you want build handoffs to land
  • Nothing installed on your build machines. Everything is read through Buildkite itself

How can I customize it?

  • Choose which pipelines appear on the board, how far back recent builds go, and how often the board refreshes itself while it sits open all day
  • Tune how much slower than usual a build has to be running before it gets flagged as suspicious, so noisy pipelines do not cry wolf
  • Pick the default Slack channel for handoffs and how much of the failing log gets pasted into the shared summary

FAQs

Does this replace the Buildkite website?
No. It reads live from Buildkite and every button does the real thing there, so your pipelines, steps, and notifications keep working exactly as they do today. It is a faster front door for the handful of things a platform team does over and over.
How does it know a build is stuck?
It learns what normal looks like for each pipeline by measuring how long recent successful builds took, then flags anything currently running well past that mark. It is a nudge rather than a hard timeout, so a genuinely slow build is highlighted, never killed automatically.
Is retrying from here different from retrying in Buildkite?
It is the same retry. Retrying failed steps, cancelling, rebuilding, and releasing an approval step all happen in Buildkite, so anyone watching there sees exactly what you would expect.
Can everyone on the team press the action buttons?
That depends on the Buildkite access the app is connected with. If it can only read, the whole board still works and the action buttons appear greyed out with a short note explaining why, rather than quietly disappearing.
We have dozens of pipelines. Will the board be a mess?
You choose which pipelines the board watches, and builds are grouped under their pipeline rather than dumped into one list. The failed-only filter narrows it to what needs attention when something is on fire.
What do the pause and stop buttons do to a build machine?
Pausing tells an agent to stop picking up new work while it finishes what it has, which is what you want when draining a machine. Stopping ends it. Paused agents get a resume button so you can put them back to work.

Related templates

Share of voice dashboard for your brand and competitors

See how your brand's news coverage and sentiment stack up against four competitors, then let an assistant write the weekly report for you.

GDELT
Notion
Slack Bot
App
Approval war room for every social post awaiting sign-off

One screen showing every social post waiting on approval, sorted by deadline, so reviewers can approve or reject without leaving the page.

Hootsuite
Slack Bot
App
Turn champion job changes into new pipeline in Attio

Every Monday, find the past champions and closed-won contacts who changed jobs, update Attio, and get the moves worth chasing in Slack.

Boomerang
Attio
Slack Bot
Agentic Task
Collect social post requests and schedule them in Hootsuite

Staff submit what happened, your social manager edits the copy, picks the accounts and puts it on the calendar without a single spreadsheet.

Hootsuite
Slack Bot
General Input Database
App
Voice agent QA review board for your Hume EVI calls

Open one board each morning, see which voice calls went badly, replay the exact moment the caller got frustrated, and file the fix.

Hume
Linear
Slack Bot
App
Clear your Guru verification backlog in one weekly app

A personal queue of every overdue Guru card, sorted by how late it is, with one-click verify, reassign, comment, and an agent that drafts the refresh for you.

Guru
Slack Bot
App

Stop living in the Buildkite tab.

Give your platform team one screen to watch every build, unstick the broken ones, and hand off triage without copy-paste.