$npx -y skills add educlopez/ui-craft --skill unhappyState-first design pass — inventories and implements all non-happy states (loading, empty, error, partial, conflict, offline) before the happy path, and refactors impossible boolean state to proper state machines. Use when starting a new screen, reviewing an existing one for edge
| 1 | <!-- HARNESS MIRROR — do not edit here. Canonical source: skills/ or commands/. After editing source, copy into cli/assets/<harness>/ and repo-root harness mirrors. --> |
| 2 | |
| 3 | **Context:** this sub-skill is one lens of the broader `ui-craft` skill. If the `ui-craft` skill is also installed, read its SKILL.md first for Discovery + Anti-Slop + Craft Test, then apply the specific lens below. |
| 4 | |
| 5 | Design every non-happy state for the UI at the target the user described. Load the `ui-craft` skill and read `references/state-design.md`. |
| 6 | |
| 7 | **Step 1 — Inventory.** List every data source and interactive surface in the target. For each, enumerate its states: |
| 8 | |
| 9 | | Surface | idle | loading | empty | error | partial | conflict | offline | |
| 10 | |---------|------|---------|-------|-------|---------|----------|---------| |
| 11 | |
| 12 | Mark each cell as **designed** (exists in code), **missing** (must add), or **N/A** (not applicable — e.g., a read-only view has no conflict state). |
| 13 | |
| 14 | **Step 2 — Fill the missing states.** For each missing state, either stub it inline or add a follow-up task comment. Use `references/state-design.md` for: |
| 15 | - Skeleton sizing (match final layout, 200ms delay, 5s upper bound) |
| 16 | - Empty-state copy (why empty + next action + visual) |
| 17 | - Error-state contract (specific cause + one-click recovery + support ID) |
| 18 | - Offline handling (queue writes + reconcile on reconnect) |
| 19 | |
| 20 | **Step 3 — Audit the happy path.** Flag every spot where the happy path assumes resource presence without checking. Fix with early-returns, state guards, or discriminated-union state handling. Booleans like `isLoading && !error && data` that allow impossible states are findings — refactor to a proper state machine or reducer. |
| 21 | |
| 22 | **Step 4 — Optimistic UI + reconciliation.** For offline-likely actions (saves, sends, edits, toggles), implement optimistic UI with reconciliation on reconnect. Queue writes locally. Surface any rejected writes — never swallow them. |
| 23 | |
| 24 | **Knob gating (CRAFT_LEVEL):** |
| 25 | |
| 26 | | CRAFT_LEVEL | Required states to stub | |
| 27 | |-------------|-------------------------| |
| 28 | | ≤ 4 | idle, loading, error | |
| 29 | | 5-7 | idle, loading, empty, error, success | |
| 30 | | 8+ | all six — add partial, conflict, offline | |
| 31 | |
| 32 | If `CRAFT_LEVEL` is unknown, default to 7. |
| 33 | |
| 34 | **Convergence note:** To iterate until all required states are present, load `skills/ui-craft/references/loops.md` and run preset `state-coverage` (budget = the default loop budget defined in loops.md): after stubbing the highest-priority missing required state, re-inventory until all knob-required states are present or budget exhausted. Emit the pre-flight cost notice before iteration 1. |
| 35 | |
| 36 | **Output:** edit the code directly. After each file, print the Review Format table from SKILL.md: |
| 37 | |
| 38 | | Before | After | Why | |
| 39 | | --- | --- | --- | |
| 40 | | no loading state on `<ProjectList>` | skeleton rows matching final layout, 200ms delay | prevents "is it broken?" perception; avoids CLS | |
| 41 | | generic "Error" toast | inline error with specific cause + retry + support ID | recoverability (heuristic 9) | |
| 42 | |
| 43 | One row per state added. No full diffs. |