Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
fa936ab
Add website overhaul implementation plan
claude Aug 27, 2026
aadd9c9
Add DESIGN.md; settle design up front and drop private-path noindex r…
claude Aug 27, 2026
0789c6f
Clarify outline-button-on-photo and logo-mark color exemption in DESI…
claude Aug 27, 2026
4438f0d
Encode design-review decisions in DESIGN.md and plan
claude Aug 27, 2026
7ebe54c
Add atmosphere layer to DESIGN.md
claude Aug 27, 2026
67811cf
Tune atmosphere layer: page-ground grid, stronger devices, registrati…
claude Aug 27, 2026
b9c4204
Reject page-ground grid; ground stays smooth so pocket grid floors read
claude Aug 27, 2026
dd0dd98
Adopt the scribed register from the official t-shirt art
claude Aug 27, 2026
7b3cfbc
Add hand-markup register; ban pill UI
claude Aug 27, 2026
c5df66d
Markup variation rules, annotation hand, inline underlines, unified r…
claude Aug 27, 2026
12e5c6a
Switch implementation flow to GitHub stacked PRs
claude Aug 27, 2026
7c5fcd3
Reference PR #14 as the bottom of the stack
claude Aug 27, 2026
2166608
overhaul: foundation — legacy move, mise/pnpm, Astro scaffold, toolch…
CS-5 Aug 28, 2026
a268397
overhaul: give lychee a root dir so it can resolve Astro's asset links
CS-5 Aug 28, 2026
60c477c
overhaul: close review findings on the foundation toolchain
claude Aug 28, 2026
235aa2f
Manual cleanup
CS-5 Aug 28, 2026
3784c21
overhaul: green the foundation gate after the manual cleanup
claude Aug 28, 2026
e071210
overhaul: typecheck functions/ with TypeScript 7 (tsgo)
claude Aug 28, 2026
b5dc21a
overhaul: adopt the nkzw oxlint config, errors only; format coverage
claude Aug 28, 2026
349569d
overhaul: design system — tokens, fonts, program themes, styleguide
CS-5 Aug 28, 2026
32b3bd8
overhaul: close review findings on the design system
claude Aug 28, 2026
3c75cdc
overhaul: UI primitives, Tabler icons, and the shadcn-astro skill
CS-5 Aug 28, 2026
4aae3a1
overhaul: close review findings on the primitives
claude Aug 28, 2026
9afb09b
overhaul: content model — collections, schemas, and the data migration
CS-5 Aug 28, 2026
1963831
overhaul: close review findings on the content model
claude Aug 28, 2026
37cc8e7
overhaul: app shell — BaseLayout, Seo, JSON-LD, Navbar, Footer, 404
CS-5 Aug 28, 2026
837012d
overhaul: exclude not-yet-built routes from the link check, with a guard
CS-5 Aug 28, 2026
1e0d0d8
overhaul: close review findings on the app shell
claude Aug 28, 2026
2b2e93d
Add brand assets
CS-5 Aug 30, 2026
fab3411
overhaul: simplify pass over phases 01-05
CS-5 Aug 30, 2026
9e4e237
overhaul: fix defects surfaced by the visual design review
CS-5 Aug 30, 2026
1e2535f
overhaul: close code-review findings on the midpoint check-in
CS-5 Aug 30, 2026
f8f778d
overhaul: wire up the chrome-devtools MCP verification loop
CS-5 Aug 30, 2026
c410e0b
overhaul: fold the midpoint-review lessons into the plan
CS-5 Aug 30, 2026
818a1a9
overhaul: homepage + the composed section vocabulary
CS-5 Aug 30, 2026
1f9f14d
overhaul: about and sponsors pages
claude Aug 31, 2026
831ee98
overhaul: contact, donate, and get-involved
claude Aug 31, 2026
73b1bc8
overhaul: program pages and the robot history
claude Aug 31, 2026
2755a29
overhaul: calendar pages and the ICS proxy
claude Aug 31, 2026
1b64c91
overhaul: close the browser-verification findings on Phase 07
claude Aug 31, 2026
1c21aab
overhaul: record Phase 07's acceptance state
claude Aug 31, 2026
5c63be6
overhaul: the event landing pattern, /openhouse and /programs/frc/kic…
claude Aug 31, 2026
8fa2701
overhaul: media pipeline and enforced performance budgets
claude Sep 1, 2026
3d5fc01
overhaul: make the Lighthouse LCP aggregation explicit
claude Sep 1, 2026
dd6933b
overhaul: trim Inter's weight axis, and assert LCP on the median
claude Sep 1, 2026
d2ebf1c
overhaul: sitemap, robots, llms.txt, social cards, analytics
claude Sep 1, 2026
18a0842
overhaul: retire events on date, and settle the JS budget wording
claude Sep 1, 2026
f3414fa
misc cleanups
CS-5 Sep 1, 2026
7dda942
overhaul: one toolchain, TypeScript tools, leaner CI and docs
claude Sep 1, 2026
a828414
overhaul: run the vendored anti-slop rules under ESLint
claude Sep 1, 2026
1967e5d
Fix settings and node version
CS-5 Sep 1, 2026
e073f32
Start cleaning up text
CS-5 Sep 1, 2026
e0f92c8
overhaul: drop check:tokens, settle on TypeScript 6, finish the oxlin…
claude Sep 1, 2026
4feda18
overhaul: vendor the font files and drop the fontsource packages
claude Sep 2, 2026
fc1904b
overhaul: render social cards with Satori and resvg, no Python
claude Sep 2, 2026
7121d6c
overhaul: prepare source images with sharp-cli instead of a script
claude Sep 2, 2026
410372b
Cleanups
CS-5 Sep 2, 2026
ae0d8b0
rm `content-references` check
CS-5 Sep 2, 2026
cb6aaf5
design: grain the ground, lift the pools, raise the ghost numerals
CS-5 Sep 3, 2026
4e640f6
design: one identity mark per card
CS-5 Sep 3, 2026
2c58a39
design: an underline means a link, drawn by hand
CS-5 Sep 3, 2026
036e611
design: eight tweaks from the second review
CS-5 Sep 3, 2026
2aadd10
design: the link underline is one gentle hand-drawn curve
CS-5 Sep 3, 2026
05d2671
design: one underline curve per line, stretched to the link
CS-5 Sep 3, 2026
370eb81
ci: put the LCP waterfall behind a Lighthouse failure in the job log
claude Sep 7, 2026
1a5a9ad
perf: measure Lighthouse over HTTP/2, subset the fonts, add a 672px l…
claude Sep 7, 2026
97bb6cc
ci: tell knip that serve.ts calls the system openssl
claude Sep 7, 2026
76df13d
overhaul: cutover pre-flight, the parity pass and its records
claude Sep 6, 2026
5fbad8e
overhaul: delete legacy/ and every exclusion that guarded it
claude Sep 6, 2026
c1ced9a
perf: cache fingerprinted assets, reuse zone formatters, stop idle ti…
claude Sep 24, 2026
9549aaf
refactor: one source for program facts, photos and page headers
claude Sep 24, 2026
7e0fba4
fix: calendar dates, cancelled overrides, WKST, and form failure paths
claude Sep 24, 2026
a7b705a
design: eyebrow contrast, tagline wrap, section rhythm, and review fixes
claude Sep 24, 2026
1f1aa3e
design: FRC headline, donate and sponsor CTAs, tier layout, display s…
claude Sep 24, 2026
66114c6
design: ink bands, raised plates, keycap buttons, the Light lockup
claude Sep 24, 2026
3cb7f68
fix: anchor the Programs panel to its nav item
claude Sep 25, 2026
efea357
design: a stronger ground grain
claude Sep 25, 2026
57018a1
seo: noindex every scstem.org subdomain
claude Sep 25, 2026
f722729
content: a concision pass on every page's copy
claude Sep 25, 2026
769f008
Use agent browser
CS-5 Sep 26, 2026
3a20fb4
Replace cnfast with cn
CS-5 Sep 26, 2026
3af21ff
Drop adr directive
CS-5 Sep 26, 2026
8f72231
Merge pull request #28 from SCSTEM/overhaul/11-cutover
CS-5 Sep 26, 2026
baafd30
`mise upgrade --bump`
CS-5 Sep 26, 2026
213fbb0
Add dev command
CS-5 Sep 26, 2026
c9d5bf0
`/simplify` and `/code-review`
CS-5 Sep 26, 2026
eea9eb0
More cleanups
CS-5 Sep 26, 2026
9b87de5
Lint cleanups
CS-5 Sep 27, 2026
80fa421
Add hk
CS-5 Sep 27, 2026
1db8522
design: portable token file with finish, accent and register switches
claude Sep 27, 2026
78f454c
docs(design): lock in the 2026-09 design review
claude Sep 27, 2026
138e085
design: nine text roles, named spacing steps, Carbon icons
claude Sep 27, 2026
04e1f5e
design: grid bubbles, construction-line marks, lit pocket floors
claude Sep 27, 2026
320ba1f
design: felt-marker strokes, drifting underlines, new call-outs
claude Sep 27, 2026
7dc8eb1
design: the light finish
claude Sep 27, 2026
c9307a6
design: the blueprint register and its drawing frame, first on the 404
claude Sep 27, 2026
2ed37f6
fix: keep dark islands dark under the light: variant
claude Sep 27, 2026
94d21a8
docs: the design-language guide (noindex, unlinked)
claude Sep 27, 2026
42d6f9d
fix: the hero's light-finish photo filter compiles again
claude Sep 27, 2026
291c5ed
Fix comment
CS-5 Sep 27, 2026
5e5b43b
Package bumps and doc cleanups
CS-5 Oct 1, 2026
421d2c6
Fix up hooks and CI
CS-5 Oct 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
30 changes: 30 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"permissions": {
"allow": ["Bash(agent-browser:*)"]
},
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "cd \"$CLAUDE_PROJECT_DIR\" && f=\"$(jq -r .tool_input.file_path)\" && case \"$f\" in \"$CLAUDE_PROJECT_DIR\"/*) hk fix -q -n --no-stage \"$f\" >&2 || exit 2 ;; esac",
"timeout": 60
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "cd \"$CLAUDE_PROJECT_DIR\" && jq -e .stop_hook_active >/dev/null || hk fix --slow -q -n --no-stage >&2 || exit 2",
"timeout": 180
}
]
}
]
}
}
52 changes: 52 additions & 0 deletions .claude/skills/agent-browser/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: agent-browser
description: Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.
allowed-tools: Bash(agent-browser:*), Bash(npx agent-browser:*)
hidden: true
---

# agent-browser

Fast browser automation CLI for AI agents. Chrome/Chromium via CDP with accessibility-tree snapshots and compact `@eN` element refs.

Install: `npm i -g agent-browser && agent-browser install`

## Start here

This file is a discovery stub, not the usage guide. Before running any `agent-browser` command, load the actual workflow content from the CLI:

```bash
agent-browser skills get core # start here — workflows, common patterns, troubleshooting
agent-browser skills get core --full # include full command reference and templates
```

The CLI serves skill content that always matches the installed version, so instructions never go stale. The content in this stub cannot change between releases, which is why it just points at `skills get core`.

## Specialized skills

Load a specialized skill when the task falls outside browser web pages:

```bash
agent-browser skills get electron # Electron desktop apps (VS Code, Slack, Discord, Figma, ...)
agent-browser skills get slack # Slack workspace automation
agent-browser skills get dogfood # Exploratory testing / QA / bug hunts
agent-browser skills get derive-client # Record a HAR, derive a standalone API client for a site
agent-browser skills get vercel-sandbox # agent-browser inside Vercel Sandbox microVMs
agent-browser skills get protected-vercel-deployments # Access protected Vercel deployments
agent-browser skills get agentcore # AWS Bedrock AgentCore cloud browsers
```

Run `agent-browser skills list` to see everything available on the installed version.

## Why agent-browser

- Fast native Rust CLI, not a Node.js wrapper
- Works with any AI agent (Cursor, Claude Code, Codex, Continue, Windsurf, etc.)
- Chrome/Chromium via CDP with no Playwright or Puppeteer dependency
- Accessibility-tree snapshots with element refs for reliable interaction
- Sessions, authentication vault, state persistence, video recording
- Specialized skills for Electron apps, Slack, exploratory testing, cloud providers

## Observability Dashboard

The dashboard runs independently of browser sessions on port 4848 and can also be opened through a proxied or forwarded URL such as `https://dashboard.agent-browser.localhost`. Agents should stay on the dashboard origin: session tabs, status, and stream traffic are proxied internally, so session ports do not need to be exposed.
114 changes: 114 additions & 0 deletions .claude/skills/shadcn-astro/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
name: shadcn-astro
description: Port a shadcn/ui component to an Astro primitive in src/components/ui/primitives/. Use when a needed primitive does not exist yet, or when an existing one needs a variant or sub-part that shadcn already defines.
---

# Porting shadcn components to Astro primitives

This site ships **zero client framework runtime**. shadcn is React + Radix, so a port is a
re-implementation, not a copy — but the _design API_ comes across almost verbatim, and should.

## When to use this

A component you need is missing from `src/components/ui/primitives/`. Check first: the primitive
may exist under shadcn's name already.

Do **not** use this to add a variant to an existing primitive — edit its `*.variants.ts`.

## Process

### 1. Read the source

Fetch the component from the shadcn registry:

```
https://ui.shadcn.com/r/styles/default/<name>.json
```

Verify that URL still resolves before relying on it; the registry layout has changed before. If
it is unreachable, work from the documented anatomy on ui.shadcn.com instead — the goal is the
component's structure and variant vocabulary, not its exact source.

Note three things: its **anatomy** (which sub-parts exist and how they nest), its **CVA
variants**, and which behaviors come from **Radix** rather than from CSS.

### 2. Map the behavior down the interactivity ladder

This is the whole job. For each Radix behavior, find the lowest-cost equivalent:

| Radix provides | Astro equivalent |
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Accordion (roving focus, exclusive open) | `<details>` + the native `name` attribute — see `AccordionItem.astro` |
| Dialog (focus trap, Esc, inert background, portal) | native `<dialog>` + `showModal()` — see `Dialog.astro` |
| Tabs | `:target` or radio inputs, or a ~20-line script over `role="tablist"` |
| Popover / Dropdown | `:focus-within`, or the popover attribute — **must also work on tap and without JS**, so the trigger needs a real destination |
| Carousel (embla) | CSS scroll-snap track; buttons scroll by one slide — see `Carousel.astro` |
| Slot / `asChild` | an `as` prop, or infer from props (`Button` renders `<a>` given `href`) |

If a behavior cannot be reached without a framework, **drop it** and document the omission in
the component's `Props` JSDoc. Do not add a client framework to preserve a nicety.

### 3. Write the component

Follow `src/components/ui/primitives/README.md` — read it before writing. In short:

- CVA recipe in `<Name>.variants.ts`, component in `<Name>.astro`.
- Variant classes copied nearly verbatim from shadcn, with **token names swapped for ours**.
- `class` prop merged through `cn()`, `...rest` spread on the root.
- Local `Props` interface extending `HTMLAttributes<"element">` with `class` omitted.

### 4. Register it on /styleguide

Every variant, size, and state, under the default theme and both program themes. This is not
optional — `/styleguide` is the review artifact.

### 5. Verify

```sh
pnpm check && pnpm build
```

Then keyboard-test it: tab order, Enter/Space/Esc as appropriate, visible focus ring, and the
component still usable with JavaScript disabled.

## Rules

- **No React, Preact, or Radix dependencies. Ever.** Not as a devDependency either.
- **Token names must already exist in `src/styles/global.css`.** If a shadcn class needs a token
we do not have, stop: propose the addition to `DESIGN.md` via its §11 process and get owner
review. Do not invent a hex value in a component — raw hex in components is banned (§2).
- **Radii come from the three-value scale** (`radius-sm`/`md`/`lg`). shadcn's `rounded-full` has
no equivalent here: pill UI is banned (§10). A circled word is a `ChalkOval`.
- **No drop shadows.** shadcn leans on `shadow-*`; this system has no elevation, only inset
pocket depth (§4). Delete those classes rather than translating them.
- **Minimum touch target 44px** for anything tappable (§9), which is why `Button`'s `md` is
`h-11` and not shadcn's `h-10`.

## Worked example: Accordion

shadcn's Accordion is Radix `Accordion.Root`/`Item`/`Trigger`/`Content` — a controlled component
with roving focus, `data-state` attributes, and a height animation, plus `type="single"` for
exclusive open.

The Astro port is two files and no JavaScript:

- `Accordion.astro` — a layout wrapper, nothing more. Astro cannot push a prop into slotted
children, so a wrapper `name` prop could only be read back by script; the caller passes the
same `name` to each item instead.
- `AccordionItem.astro` — `<details name={name}>` with `<summary>` as the trigger.

What maps directly:

- `type="single"` ⇒ the native `name` attribute. Browsers close sibling `<details>` sharing a
name, which is exactly exclusive-open.
- `data-state="open"` styling ⇒ the `open` attribute, targeted with Tailwind's `group-open:`.
- Trigger keyboard handling ⇒ the browser's, for free.

What is dropped, and why it is fine:

- **Roving arrow-key focus between items.** Native `<summary>` elements are plain tab stops.
Tab still reaches every item, so nothing is unreachable.
- **The height transition.** Animating `<details>` open height needs `content-visibility`
tricks or JS. Motion here would be decoration, not confirmation (§6), so it goes.

Both omissions belong in the component's JSDoc, where the next reader will look.
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# For what Prettier does not format (toml, shell, gitignore-likes).
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
2 changes: 0 additions & 2 deletions .env.development

This file was deleted.

1 change: 0 additions & 1 deletion .env.production

This file was deleted.

26 changes: 26 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Setup
description: Install the mise-pinned toolchain and the pnpm dependencies, with both cached.
runs:
using: composite
steps:
# agent-browser in mise.toml is a local tool; CI installs only what the jobs run.
- uses: jdx/mise-action@v4
with:
version: 2026.9.14
install_args: node pnpm hk
cache: true

# mise-action caches tool binaries, not pnpm's content-addressable store.
- name: Locate pnpm store
shell: bash
run: echo "PNPM_STORE=$(pnpm store path --silent)" >>"$GITHUB_ENV"

- uses: actions/cache@v6
with:
path: ${{ env.PNPM_STORE }}
key: pnpm-store-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: pnpm-store-${{ runner.os }}-

- name: Install dependencies
shell: bash
run: pnpm install --frozen-lockfile --prefer-offline
32 changes: 32 additions & 0 deletions .github/typescript-matchers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"problemMatcher": [
{
"owner": "tsc",
"pattern": [
{
"regexp": "^([^\\s].*)[\\(:](\\d+)[,:](\\d+)(?:\\):\\s+|\\s+-\\s+)(error|warning|info)\\s+TS(\\d+)\\s*:\\s*(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"code": 5,
"message": 6
}
]
},
{
"owner": "astro-check",
"pattern": [
{
"regexp": "^(?:\u001b\\[[0-9;]*m)*([^\\s\u001b][^\u001b]*)(?:\u001b\\[[0-9;]*m)*:(?:\u001b\\[[0-9;]*m)*(\\d+)(?:\u001b\\[[0-9;]*m)*:(?:\u001b\\[[0-9;]*m)*(\\d+)(?:\u001b\\[[0-9;]*m)* - (?:\u001b\\[[0-9;]*m)*(error|warning)(?:\u001b\\[[0-9;]*m)* ts\\((\\d+)\\): (?:\u001b\\[[0-9;]*m)*(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"code": 5,
"message": 6
}
]
}
]
}
102 changes: 102 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: CI

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
push:
branches: [main, staging]

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
check:
name: Check
if: ${{ !github.event.pull_request.draft }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/setup

# Every hk.pkl step over every file, each reporting its findings as inline annotations on
# the PR diff.
- name: Check
run: |
echo "::add-matcher::.github/typescript-matchers.json"
pnpm check

build:
name: Build
if: ${{ !github.event.pull_request.draft }}
runs-on: ubuntu-latest
env:
LHCI_VERSION: 0.15.1
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/setup

- name: Build
id: build
run: pnpm build

# Title and description uniqueness, and whether every og:image resolves, are only
# answerable across the whole built site.
- name: Page metadata
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
run: pnpm check:meta

# --root-dir resolves the root-relative hrefs Astro emits. llms.txt is in scope because its
# links are hand-written paths that nothing else checks against the routes they name.
- name: Links
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
uses: lycheeverse/lychee-action@v2
with:
args: >-
--offline --include-fragments --no-progress
--root-dir ${{ github.workspace }}/dist
'dist/**/*.html' 'dist/llms.txt'
fail: true

# The build is deterministic, so a byte-identical dist/ measured with the same server,
# config, and lhci version has already passed; only the marker file is cached.
- name: Look up a previous Lighthouse pass
id: lighthouse-pass
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
uses: actions/cache/restore@v6
with:
path: .lighthouseci/passed
key: lighthouse-${{ env.LHCI_VERSION }}-${{ hashFiles('dist/**', 'tools/ci/**') }}
lookup-only: true

- name: Lighthouse CI
id: lighthouse
if: ${{ !cancelled() && steps.lighthouse-pass.outcome == 'success' && steps.lighthouse-pass.outputs.cache-hit != 'true' }}
run: |
pnpm dlx @lhci/cli@${{ env.LHCI_VERSION }} autorun --config=tools/ci/lighthouserc.json
touch .lighthouseci/passed

# Into the log as well as the summary, so the waterfall behind a failed LCP assertion is
# readable from the API without downloading the report artifact.
- name: Summarize Lighthouse
if: ${{ !cancelled() && steps.lighthouse.outcome != 'skipped' }}
run: node tools/ci/lighthouse-summary.ts | tee -a "$GITHUB_STEP_SUMMARY"

- name: Note the skipped Lighthouse run
if: ${{ steps.lighthouse-pass.outputs.cache-hit == 'true' }}
run: echo "Lighthouse skipped, this exact build already passed." >>"$GITHUB_STEP_SUMMARY"

- uses: actions/upload-artifact@v5
if: ${{ !cancelled() && steps.lighthouse.outcome != 'skipped' }}
with:
name: lighthouse-reports
path: .lighthouseci/reports/

- uses: actions/cache/save@v6
if: ${{ steps.lighthouse.outcome == 'success' }}
with:
path: .lighthouseci/passed
key: ${{ steps.lighthouse-pass.outputs.cache-primary-key }}
Loading