Sheet F — Build a client

Your app, wearing your build’s colour

Greenlight already polls Azure DevOps and GitHub, holds the tokens, and works out what colour the day is. The SDK hands your app that verdict, live, over a named pipe on the same machine — so whatever you build talks to Greenlight, and never to a provider.

No token of your own. No API to authenticate against. No polling. MIT licensed, no dependencies, net8.0 and net10.0.

Read the full spec Get the package

F.1 — The whole integration

Construct, subscribe, start

There is no connect step to sequence, no retry loop to write, and no error path for “Greenlight isn’t running”. This is not an excerpt — it is the entire contract being exercised.

dotnet add package MeddlingIdiot.Greenlight.Sdk

await using var greenlight = new GreenlightClient();

greenlight.Changed += (_, e) => Paint(e.Snapshot.Status, e.Snapshot.IsBuilding);
greenlight.AvailabilityChanged += (_, e) => ShowConnectionState(e.Availability);

await greenlight.StartAsync();

The spec carries a complete console client, top to bottom, that compiles exactly as printed — it is built from a clean feed, so the copy you paste is the copy that was tested.

F.2 — The four states

One colour, already decided

The same verdict the tray icon, the header dot and the hardware lamp are wearing. You never re-derive it.

Green

Every pipeline’s last completed run passed, and no pull request is waiting on you.

Yellow

A build is queued, a pipeline has no result yet, or a pull request wants your review.

Red

At least one pipeline’s last completed build failed. It stays red while it rebuilds — it does not go hopefully yellow.

Unknown

Nothing polled yet, or every connection’s last poll failed. Greenlight’s grey.

  • IsBuilding is separate from the colour. Something running right now is said by that flag — so flash the colour you have rather than changing it.
  • Reason is Greenlight’s own words: “2 pipelines’ last completed builds failed.” Show it, and your app stays right when the rules change.

F.3 — The two things that actually catch people

Both are code you should not write

01

Greenlight being absent is normal

Not an error, not a startup ordering problem, and not yours to retry. Nothing throws because Greenlight is missing. Render a disabled state and wait — the client reconnects on its own, forever, and tells you when it is back.

So: no connect-with-retry loop, and don’t block startup probing for it.

02

Events arrive off the UI thread

Both of them. Marshal before touching anything the UI owns — the failure is an exception from deep inside your UI framework that says nothing about Greenlight.

Snapshots are immutable, so handing one to another thread is safe.

F.4 — Start from something that runs

An evening is enough

CarsClient is a complete, released app built on this package: little cars that drive along your taskbar, flow on green, crawl and honk on yellow, and pile up at a red light when a pipeline breaks. It was vibe-coded in one evening.

Clone it, delete the three drawing files, and what is left is the integration — about twenty lines, plus a tray icon. Then draw whatever you like.

The full spec Fork CarsClient SDK source

Writing something other than .NET? The spec’s appendix documents the pipe itself — name derivation, newline-delimited JSON, the handshake, and what a client must ignore.

You’ll need a Greenlight to build against

The local API is on by default, with a second switch for whether attached apps may act as well as read.

Get the installer

Windows 10 / 11 x64 · installs and updates itself

An unhandled error has occurred. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.