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.
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.
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 installerWindows 10 / 11 x64 · installs and updates itself