Skip to main content
ClaudeWave
Skill82.2k repo starsupdated 3d ago

ux-audit

Audit a page / surface against the Designing Interfaces pattern language + the ux skill checklists, then land findings. Three layers — static (code), visual (screenshots), dynamic (automated user journey + perf). Use to run a repeatable, standards-based UX review of one screen.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/lobehub/lobehub /tmp/ux-audit && cp -r /tmp/ux-audit/.agents/skills/ux-audit ~/.claude/skills/ux-audit
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# UX Audit

A repeatable, standards-based UX review of **one surface at a time**. The benchmark is
two things together:

1. **Jenifer Tidwell, _Designing Interfaces_** — the pattern language for what a good
   interface is _made of_. See [`references/pattern-catalog.md`](references/pattern-catalog.md).
2. **The [`ux`](../ux/SKILL.md) skill** — LobeHub's execution checklists for how a flow
   should _behave_.

The audit answers: **which patterns does the surface use** (and how well), and **where is
the experience weak** (each gap tied to a checklist item). Recurring gaps feed back as new
`ux` checklist items; the audit itself becomes a worked-example reference.

Do **one surface per run** — a full-app sweep is too much for a single pass. Re-run per
page as the product grows; that's the "continuous" part.

## Three layers — pick by what you need to catch

An audit is not one activity. A finding is only trustworthy from a layer that can actually
_see_ it. Each layer has its own procedure file; run the ones the surface needs.

| Layer          | File                                                | What it does                                                | Catches                                                                                                                                                              | Cost                             |
| -------------- | --------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| **L1 Static**  | [layer-1-static.md](references/layer-1-static.md)   | Read the code                                               | Missing states/branches (empty/error/retry), no draft persist, absent patterns, structural issues                                                                    | cheap, offline, **every audit**  |
| **L2 Visual**  | [layer-2-visual.md](references/layer-2-visual.md)   | Screenshots of the rendered surface                         | Real visual hierarchy & dominant control, spacing/contrast/alignment, truncation/overflow, how empty/loading/error actually look, responsive breakpoints, dark/light | medium; needs a render           |
| **L3 Dynamic** | [layer-3-dynamic.md](references/layer-3-dynamic.md) | Drive the real user journey via **acceptance** + instrument | In-progress/locked states, forced error/empty states, does step N lead to N+1, focus/keyboard, **quantified CLS / LCP / INP / long-tasks**                           | high; needs a running env + auth |

### Coverage matrix — which layer can conclude what

The core rule: **a verdict must come from a layer that can see it.** Don't tick a visual or
runtime verdict off the code.

| Finding type                                                              |     L1      |        L2        |       L3        |
| ------------------------------------------------------------------------- | :---------: | :--------------: | :-------------: |
| Missing empty/error branch, no retry, draft not persisted, absent pattern |     ✅      |        —         |        —        |
| Real visual hierarchy / is the dominant control the primary action        | ❌ misleads |        ✅        |       ✅        |
| Spacing / alignment / contrast / truncation / overflow / dark mode        |     ❌      |        ✅        |        —        |
| Off-screen selection; what empty/loading/error actually render as         |     ❌      |        ✅        |       ✅        |
| Responsive breakpoints (narrow / mobile)                                  |     ❌      |        ✅        |       ✅        |
| In-progress / locked states; forced error / empty; capability-gated       |     ❌      |        ❌        |       ✅        |
| Journey stitching (forward momentum across steps)                         |    weak     |       weak       |       ✅        |
| Focus order / keyboard reachability                                       |     ❌      |        ❌        |       ✅        |
| **CLS / LCP / INP / long-task numbers**                                   |     ❌      | qualitative only |       ✅        |
| **Which of two variants is _better_ (A/B winner)**                        | ❌ misleads |   ❌ misleads    | ✅ (+analytics) |

> ⚠️ The recurring trap this prevents: ticking "one primary button" or "empty is a real
> page" from a `variant` prop in the code. Those are **L2** verdicts — confirm them on the
> render, never from L1 alone.

### Tiering — don't run all three every time

- **L1 always** — fast, complete-coverage baseline for every surface.
- **Add L2** when the findings are about layout, hierarchy, rendered states, or responsive.
- **Add L3** when you need to walk a journey, force states L1/L2 can't reach, or measure
  performance (CLS etc.).

`--l1 / --l2 / --l3` scopes a run to one layer; default is L1 (+ L2 if screenshots are
supplied).

## Ground rule: evidence, not vibes

Every finding cites its evidence — `file:line` (L1), a screenshot you **verified with the
Read tool** (L2), or a captured value / snapshot (L3). Before asserting a load-bearing
claim, confirm it in the layer that owns it; a wrong "it's missing" is worse than no
finding.

## Ground rule: benchmark the surface _class_, not just our own artifact

Reading our code can only surface flaws in **what we built** — it is structurally blind to a
capability we **never built at all**, because an entirely-absent affordance leaves no
`file:line`, no dead branch, no half-wired button to grep for. The checklists guard the
_quality of the states that exist_; they do **not** tell you which states a surface of this
_class_ is expected to have.

So before (or alongside) reading code, name the surface's **class** and its domain
conventions: how do the mature, comparable products build this exact screen, and wha
add-provider-docSkill

Add documentation for a new AI provider — usage docs, env vars, Docker config, image resources.

add-setting-envSkill

Add server-side environment variables that control default values for user settings.

agent-runtime-hooksSkill

Agent runtime lifecycle hooks. Use for before/after tool or step hooks, tool mocks, human intervention, sub-agent calls, context compression, evals, callAgent, or lifecycle events.

agent-signalSkill

Build or extend LobeHub Agent Signal pipelines. Use for signal sources, signal/action types, policies, middleware, workflow handoff, dedupe, scope behavior, or observability.

agent-tracingSkill

Agent tracing CLI for execution snapshots. Use for agent-tracing, traces, snapshots, LLM call inspection, context engine data, agent step analysis, execution debugging, or pulling remote/production traces ("拉线上 tracing") by operation id. Also the first stop for debugging agent tool calls — wrong or missing tool_calls, unexpected tool arguments or results, which tools were available at a step, or why a tool ran where it did.

builtin-toolSkill

Build LobeHub builtin tool packages. Use when adding agent-callable tools, manifests, executors, runtimes, inspectors, renders, placeholders, streaming, interventions, portals, or tool registries.

chat-sdkSkill

Build multi-platform chat bots with the chat SDK. Use for Slack, Teams, Google Chat, Discord, GitHub, Linear bots, webhooks, mentions, slash commands, cards, modals, or streaming responses.

cli-backend-testingSkill

>