lhci-onboarding
A Claude Code skill for onboarding a repo to report its Lighthouse scores to a self-hosted
@lhci/server. It covers the two-step flow end to end: registering the repo as a project to get a
build token, then wiring that repo's own lighthouserc.js and CI to upload to it.
What it does
Given a repo you want to track, the skill walks through:
- Registering the repo as a project via the
lhci-toolkitCLI, passing the server's basicAuth credentials — registration itself sits behind the same gate as everything else on the server. - Saving the one-time admin token the registration prints, before it scrolls out of view.
- Adding
upload.basicAuth(not justupload.token) to the repo'slighthouserc.js. - Wiring three CI secrets — one project-specific build token, plus the server's two basicAuth credentials — into a GitHub Actions workflow.
- Registering a second
<repo>-liveproject, and a separate no-build workflow, for repos that also need (or can only do) a live-URL audit. - Setting
GITHUB_TOKENon the upload step so Lighthouse CI posts its score directly on the pull request, instead of only a link in the Actions log.
Why this exists
The gotcha this skill exists for is a load-bearing detail about how @lhci/server's basic auth is
wired: it's mounted with app.use() before every route, so it gates the build-upload endpoint
(POST /v1/projects/:id/builds) the exact same way it gates the dashboard. A lighthouserc.js
with only upload.token set — no upload.basicAuth — 401s in CI, even with a completely valid,
correctly-scoped build token. This was confirmed live: the identical upload request succeeds once
basicAuth is attached and 401s without it, token and all. The project's own build token proves
which project a build belongs to; it does nothing for the server-wide gate sitting in front of
it. Without this skill, that failure mode reads as "the token must be wrong," when the token was
never the problem.
Two related pieces of that same design turned out to matter enough to bake into the skill's other invariants:
- The two-token model. Registration returns two different credentials with two different jobs: a per-project build token for CI uploads, and a one-time admin token needed only to rename or delete that project later. The admin token is shown exactly once and doesn't overlap with either the build token or the server's own basicAuth pair — losing it means the only way to remove a project is a direct database delete against its row. Server-level basic auth gating the whole app, with per-project build tokens as a separate, per-repo write credential, is a deliberate two-layer design, not incidental overlap.
- The live-URL-vs-own-build project split. A repo that wants to audit its real deployed URL
(in addition to, or instead of, auditing its own CI build) needs a second registered project,
named
<repo>-live, with its own separate no-build workflow — never shared with the first. The server dedupes builds per(project, commit hash), so if an own-build workflow and a live-audit workflow both try to upload for the same commit into the same project, whichever upload lands second gets rejected. This also solves an unrelated real problem for free: a repo whose own build needs backend or CMS secrets that aren't available in CI can skip building in CI entirely for the live-audit path, since it collects against a real URL over the network instead of runningstartServerCommand.
Installation
This skill is published on npm as @houses/skill-lhci-onboarding. See
Alternative Installation Methods for the install
command.