@tamsensedev/runner 0.13.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/LICENSE +5 -5
  2. package/README.md +76 -57
  3. package/dist/cli.js +757 -379
  4. package/dist/cli.js.map +1 -1
  5. package/dist/recorder.cjs.map +1 -1
  6. package/library/.claude-plugin/plugin.json +5 -5
  7. package/library/THIRD_PARTY_NOTICES.md +123 -123
  8. package/library/agents/code-architect.md +67 -67
  9. package/library/agents/code-explorer.md +61 -61
  10. package/library/agents/code-reviewer.md +73 -73
  11. package/library/agents/code-simplifier.md +62 -62
  12. package/library/agents/design-critic.md +52 -52
  13. package/library/agents/second-opinion.md +64 -64
  14. package/library/agents/security-auditor.md +86 -86
  15. package/library/agents/silent-failure-hunter.md +70 -70
  16. package/library/agents/test-coverage-analyzer.md +78 -78
  17. package/library/agents/test-runner.md +48 -48
  18. package/library/agents/ui-tester.md +50 -50
  19. package/library/licenses/Apache-2.0.txt +202 -202
  20. package/library/skills/accessibility/SKILL.md +144 -144
  21. package/library/skills/accessibility/references/wcag-checks.md +168 -168
  22. package/library/skills/addressing-review-feedback/SKILL.md +109 -109
  23. package/library/skills/app-screens/SKILL.md +96 -96
  24. package/library/skills/app-screens/references/shell-kpis-charts.md +108 -108
  25. package/library/skills/app-screens/references/states-density-phone.md +54 -54
  26. package/library/skills/app-screens/references/tables-forms-settings.md +104 -104
  27. package/library/skills/avoiding-generic-ai-design/SKILL.md +92 -92
  28. package/library/skills/avoiding-generic-ai-design/references/tells.md +112 -112
  29. package/library/skills/clean-commits/SKILL.md +85 -85
  30. package/library/skills/design-review/SKILL.md +107 -107
  31. package/library/skills/design-review/references/critique-passes.md +101 -101
  32. package/library/skills/design-review/references/screenshot-procedure.md +121 -121
  33. package/library/skills/differential-security-review/LICENSE +427 -427
  34. package/library/skills/differential-security-review/SKILL.md +105 -105
  35. package/library/skills/differential-security-review/references/adversarial.md +115 -115
  36. package/library/skills/differential-security-review/references/methodology.md +145 -145
  37. package/library/skills/differential-security-review/references/patterns.md +108 -108
  38. package/library/skills/false-positive-check/LICENSE +427 -427
  39. package/library/skills/false-positive-check/SKILL.md +95 -95
  40. package/library/skills/false-positive-check/references/bug-class-verification.md +128 -128
  41. package/library/skills/false-positive-check/references/deep-verification.md +113 -113
  42. package/library/skills/false-positive-check/references/evidence-templates.md +93 -93
  43. package/library/skills/false-positive-check/references/false-positive-patterns.md +122 -122
  44. package/library/skills/false-positive-check/references/gate-reviews.md +36 -36
  45. package/library/skills/false-positive-check/references/standard-verification.md +80 -80
  46. package/library/skills/focused-implementation/SKILL.md +104 -104
  47. package/library/skills/implementation-plan/SKILL.md +66 -66
  48. package/library/skills/interface-design/SKILL.md +144 -144
  49. package/library/skills/interface-design/references/craft-defaults.md +130 -130
  50. package/library/skills/interface-design/references/new-direction.md +62 -62
  51. package/library/skills/interface-design/references/writing.md +52 -52
  52. package/library/skills/interface-polish/SKILL.md +103 -103
  53. package/library/skills/interface-polish/references/detail-rules.md +154 -154
  54. package/library/skills/interface-polish/references/worst-case-data.md +158 -158
  55. package/library/skills/motion-design/SKILL.md +106 -106
  56. package/library/skills/motion-design/references/recipes.md +243 -243
  57. package/library/skills/postgres-performance/SKILL.md +97 -97
  58. package/library/skills/postgres-performance/references/rules.md +265 -265
  59. package/library/skills/project-orientation/SKILL.md +77 -77
  60. package/library/skills/reviewing-changes/SKILL.md +183 -183
  61. package/library/skills/safe-database-changes/SKILL.md +111 -111
  62. package/library/skills/safe-database-changes/references/backfills.md +75 -75
  63. package/library/skills/safe-database-changes/references/migration-tools.md +69 -69
  64. package/library/skills/safe-database-changes/references/postgres-ddl.md +199 -199
  65. package/library/skills/security-review/SKILL.md +132 -132
  66. package/library/skills/security-review/references/checks-by-area.md +107 -107
  67. package/library/skills/security-review/references/do-not-report.md +86 -86
  68. package/library/skills/spec-writing/SKILL.md +144 -144
  69. package/library/skills/systematic-debugging/SKILL.md +130 -130
  70. package/library/skills/systematic-debugging/references/flaky-tests.md +51 -51
  71. package/library/skills/systematic-debugging/references/root-cause-tracing.md +55 -55
  72. package/library/skills/task-interview/SKILL.md +84 -84
  73. package/library/skills/test-driven-development/SKILL.md +116 -116
  74. package/library/skills/test-driven-development/references/writing-good-tests.md +85 -85
  75. package/library/skills/ui-testing/SKILL.md +102 -102
  76. package/library/skills/ui-testing/references/headless-check.md +295 -295
  77. package/library/skills/ui-testing/references/local-stand.md +51 -51
  78. package/library/skills/ui-testing/references/playwright-patterns.md +134 -134
  79. package/library/skills/ui-testing/references/recording.md +61 -61
  80. package/library/skills/verification-before-completion/SKILL.md +113 -113
  81. package/library/skills/web-interface-guidelines/SKILL.md +202 -202
  82. package/package.json +46 -46
@@ -1,113 +1,113 @@
1
- ---
2
- name: verification-before-completion
3
- description: Use right before saying work is done, fixed or passing, before the final commit, and before writing the final report or verdict: run the project's checks fresh, read their output, re-read the diff, check each acceptance criterion, and report only what the evidence shows.
4
- ---
5
-
6
- # Verification before completion
7
-
8
- Evidence before claims. A claim about the state of the work ("tests pass", "bug fixed", "criterion met") is allowed only if you ran the command that proves it in this run, after your last change, and read its output.
9
-
10
- ```
11
- NO COMPLETION CLAIM WITHOUT FRESH EVIDENCE
12
- ```
13
-
14
- ## The gate, for every claim
15
-
16
- 1. **Identify** the command that proves the claim.
17
- 2. **Run** it in full, now, after your last edit.
18
- 3. **Read** the output: exit code, number of failures, warnings, skipped tests.
19
- 4. **Compare**: does the output actually support the claim?
20
- 5. **Only then** state it, with the evidence. If not, state the real status.
21
-
22
- | Claim | Needs | Not enough |
23
- |---|---|---|
24
- | Tests pass | Test run with 0 failures, exit code 0 | An earlier run, "should pass" |
25
- | Lint is clean | Linter output with 0 errors | Type check passing |
26
- | Build works | Build command, exit code 0 | Lint and tests passing |
27
- | Bug is fixed | The original reproduction now passes | "The code changed" |
28
- | Regression test works | Seen failing without the fix, passing with it | Passing once |
29
- | Criterion met | A specific check per criterion | All tests green |
30
- | A helper agent did it | The diff and a check you ran yourself | The agent's summary |
31
-
32
- ## Steps
33
-
34
- ### 1. Run the project's checks
35
-
36
- Use the commands found during `project-orientation` (CI order is a good default): build, type check, lint, tests. Run them in every repository you changed. The `test-runner` agent can run them and return a summary if the logs are long.
37
-
38
- - Keep exit codes visible. When trimming output with a pipe, use `set -o pipefail` or check `$?` of the real command, so `| tail` does not turn a failure into success.
39
- - Count results: "412 passed, 0 failed, 3 skipped", not "tests look fine".
40
- - Compare with the baseline. A failure that was there before your change is pre-existing: report it, do not hide it, do not fix unrelated code for it. A new failure is yours: fix it and run again.
41
- - Watch for new warnings, unhandled errors or skipped tests that your change introduced.
42
- - If a check cannot run here, say which and why. Never report a check you did not run as passing.
43
-
44
- ### 2. Re-read the full diff
45
-
46
- `git diff <base>...HEAD` plus `git diff` and `git status` for uncommitted work. Read it as a reviewer would:
47
-
48
- - Every changed line is needed for the task.
49
- - No debug output, `[DEBUG-` tags, commented-out code, stray files, temporary scripts.
50
- - No secrets, tokens, personal data, `.env` files or local paths.
51
- - Names, structure and style match the surrounding code and the project's rules.
52
- - Nothing unrelated slipped in (formatting churn, lock file changes you did not intend).
53
-
54
- ### 3. Check each acceptance criterion
55
-
56
- Go through the spec's criteria one by one. For each: met, partly met or not met, and how you know (test name, command output, file:line). "All tests pass" does not prove a criterion unless a test covers it.
57
-
58
- ### 4. Think about what you did not check
59
-
60
- Other callers of changed functions, migrations and their order, configuration and environment variables, permissions, empty and error states, narrow screens for UI. Check the risky ones; list the rest under "Not verified".
61
-
62
- ### 5. Make sure the work is committed
63
-
64
- In every repository you changed: `git status` is clean (or the leftovers are explained), and `git log --oneline <base>..HEAD` shows your commits. See `clean-commits`.
65
-
66
- ## The final report
67
-
68
- The report is evidence, not an impression. Use this shape and fill it with real commands and real results:
69
-
70
- ```
71
- Changes
72
- - src/billing/tax.ts: default to the shop's country when the customer has none
73
- - src/billing/tax.test.ts: test for customers without a country
74
-
75
- Checks (run after the last change)
76
- - pnpm typecheck: exit 0
77
- - pnpm lint: exit 0, 0 warnings
78
- - pnpm test -- --run: 213 passed, 1 failed (src/date.test.ts "formats in local time zone": failed in the baseline too, unrelated, not touched)
79
- - new test seen failing before the fix: "expected 0.2, received NaN"
80
-
81
- Acceptance criteria
82
- 1. Invoice is created for a customer without a country: met (tax.test.ts "no country")
83
- 2. VAT uses the shop's country: met (same test, rate 0.2 for DE shop)
84
-
85
- Not verified
86
- - Real payment provider (no sandbox credentials)
87
-
88
- Assumptions
89
- - Shop country comes from settings.shop.country; the spec does not name the field
90
-
91
- Noticed, not changed
92
- - src/billing/currency.ts rounds half-even, the rest of billing rounds half-up
93
- ```
94
-
95
- In review and test steps the same rules apply to the report you pass with the verdict: every statement about the code is backed by something you ran or read, with the command or file:line.
96
-
97
- ## Red flags
98
-
99
- - Words like "should", "probably", "seems to" about the state of the work.
100
- - Saying "done" or "all good" before running anything.
101
- - Relying on a run from before your last edit.
102
- - Trusting a helper agent's "success" without looking at the diff.
103
- - Running only the new test and calling the suite green.
104
- - Leaving a failure out of the report because it was not yours.
105
-
106
- | Excuse | Reality |
107
- |---|---|
108
- | "It should work now" | Run it. |
109
- | "I'm confident" | Confidence is not evidence. |
110
- | "The linter passed" | The linter does not compile or run the code. |
111
- | "Partial check is enough" | It proves the part you checked, nothing more. Say which part. |
112
-
113
- Sources: obra/superpowers (MIT, commit bb92a77) verification-before-completion and affaan-m/ECC (MIT, commit 30b6892) verification-loop. Changed: merged with our own checklist, report template added.
1
+ ---
2
+ name: verification-before-completion
3
+ description: Use right before saying work is done, fixed or passing, before the final commit, and before writing the final report or verdict: run the project's checks fresh, read their output, re-read the diff, check each acceptance criterion, and report only what the evidence shows.
4
+ ---
5
+
6
+ # Verification before completion
7
+
8
+ Evidence before claims. A claim about the state of the work ("tests pass", "bug fixed", "criterion met") is allowed only if you ran the command that proves it in this run, after your last change, and read its output.
9
+
10
+ ```
11
+ NO COMPLETION CLAIM WITHOUT FRESH EVIDENCE
12
+ ```
13
+
14
+ ## The gate, for every claim
15
+
16
+ 1. **Identify** the command that proves the claim.
17
+ 2. **Run** it in full, now, after your last edit.
18
+ 3. **Read** the output: exit code, number of failures, warnings, skipped tests.
19
+ 4. **Compare**: does the output actually support the claim?
20
+ 5. **Only then** state it, with the evidence. If not, state the real status.
21
+
22
+ | Claim | Needs | Not enough |
23
+ |---|---|---|
24
+ | Tests pass | Test run with 0 failures, exit code 0 | An earlier run, "should pass" |
25
+ | Lint is clean | Linter output with 0 errors | Type check passing |
26
+ | Build works | Build command, exit code 0 | Lint and tests passing |
27
+ | Bug is fixed | The original reproduction now passes | "The code changed" |
28
+ | Regression test works | Seen failing without the fix, passing with it | Passing once |
29
+ | Criterion met | A specific check per criterion | All tests green |
30
+ | A helper agent did it | The diff and a check you ran yourself | The agent's summary |
31
+
32
+ ## Steps
33
+
34
+ ### 1. Run the project's checks
35
+
36
+ Use the commands found during `project-orientation` (CI order is a good default): build, type check, lint, tests. Run them in every repository you changed. The `test-runner` agent can run them and return a summary if the logs are long.
37
+
38
+ - Keep exit codes visible. When trimming output with a pipe, use `set -o pipefail` or check `$?` of the real command, so `| tail` does not turn a failure into success.
39
+ - Count results: "412 passed, 0 failed, 3 skipped", not "tests look fine".
40
+ - Compare with the baseline. A failure that was there before your change is pre-existing: report it, do not hide it, do not fix unrelated code for it. A new failure is yours: fix it and run again.
41
+ - Watch for new warnings, unhandled errors or skipped tests that your change introduced.
42
+ - If a check cannot run here, say which and why. Never report a check you did not run as passing.
43
+
44
+ ### 2. Re-read the full diff
45
+
46
+ `git diff <base>...HEAD` plus `git diff` and `git status` for uncommitted work. Read it as a reviewer would:
47
+
48
+ - Every changed line is needed for the task.
49
+ - No debug output, `[DEBUG-` tags, commented-out code, stray files, temporary scripts.
50
+ - No secrets, tokens, personal data, `.env` files or local paths.
51
+ - Names, structure and style match the surrounding code and the project's rules.
52
+ - Nothing unrelated slipped in (formatting churn, lock file changes you did not intend).
53
+
54
+ ### 3. Check each acceptance criterion
55
+
56
+ Go through the spec's criteria one by one. For each: met, partly met or not met, and how you know (test name, command output, file:line). "All tests pass" does not prove a criterion unless a test covers it.
57
+
58
+ ### 4. Think about what you did not check
59
+
60
+ Other callers of changed functions, migrations and their order, configuration and environment variables, permissions, empty and error states, narrow screens for UI. Check the risky ones; list the rest under "Not verified".
61
+
62
+ ### 5. Make sure the work is committed
63
+
64
+ In every repository you changed: `git status` is clean (or the leftovers are explained), and `git log --oneline <base>..HEAD` shows your commits. See `clean-commits`.
65
+
66
+ ## The final report
67
+
68
+ The report is evidence, not an impression. Use this shape and fill it with real commands and real results:
69
+
70
+ ```
71
+ Changes
72
+ - src/billing/tax.ts: default to the shop's country when the customer has none
73
+ - src/billing/tax.test.ts: test for customers without a country
74
+
75
+ Checks (run after the last change)
76
+ - pnpm typecheck: exit 0
77
+ - pnpm lint: exit 0, 0 warnings
78
+ - pnpm test -- --run: 213 passed, 1 failed (src/date.test.ts "formats in local time zone": failed in the baseline too, unrelated, not touched)
79
+ - new test seen failing before the fix: "expected 0.2, received NaN"
80
+
81
+ Acceptance criteria
82
+ 1. Invoice is created for a customer without a country: met (tax.test.ts "no country")
83
+ 2. VAT uses the shop's country: met (same test, rate 0.2 for DE shop)
84
+
85
+ Not verified
86
+ - Real payment provider (no sandbox credentials)
87
+
88
+ Assumptions
89
+ - Shop country comes from settings.shop.country; the spec does not name the field
90
+
91
+ Noticed, not changed
92
+ - src/billing/currency.ts rounds half-even, the rest of billing rounds half-up
93
+ ```
94
+
95
+ In review and test steps the same rules apply to the report you pass with the verdict: every statement about the code is backed by something you ran or read, with the command or file:line.
96
+
97
+ ## Red flags
98
+
99
+ - Words like "should", "probably", "seems to" about the state of the work.
100
+ - Saying "done" or "all good" before running anything.
101
+ - Relying on a run from before your last edit.
102
+ - Trusting a helper agent's "success" without looking at the diff.
103
+ - Running only the new test and calling the suite green.
104
+ - Leaving a failure out of the report because it was not yours.
105
+
106
+ | Excuse | Reality |
107
+ |---|---|
108
+ | "It should work now" | Run it. |
109
+ | "I'm confident" | Confidence is not evidence. |
110
+ | "The linter passed" | The linter does not compile or run the code. |
111
+ | "Partial check is enough" | It proves the part you checked, nothing more. Say which part. |
112
+
113
+ Sources: obra/superpowers (MIT, commit bb92a77) verification-before-completion and affaan-m/ECC (MIT, commit 30b6892) verification-loop. Changed: merged with our own checklist, report template added.
@@ -1,202 +1,202 @@
1
- ---
2
- name: web-interface-guidelines
3
- description: Use when writing or reviewing web UI code for interaction and detail rules: accessibility basics, focus, forms, animation, typography details, long content, images, performance, URL state, touch, safe areas, dark mode, locale formatting, hover states and copy. A vendored checklist with file:line findings; project conventions override it.
4
- ---
5
-
6
- # Web interface guidelines
7
-
8
- A terse checklist of details that make web interfaces work well, vendored from Vercel's Web Interface Guidelines so it never changes under a run and needs no network. Use it in two ways:
9
-
10
- - **Code step:** after changing UI, check the files you touched against the rules and fix what applies.
11
- - **Review step:** check the changed UI files of the branch and report findings in the format below. Do not edit product code.
12
-
13
- ## How these rules sit with the project
14
-
15
- - The project's own conventions win: its CLAUDE.md / AGENTS.md, DESIGN.md, lint rules, component library and existing copy style.
16
- - **Capitalization:** the original list asks for Title Case on headings and buttons. Our default is sentence case, unless the project already uses Title Case. Match the existing strings.
17
- - **Placeholders ending with an ellipsis** and **`&` instead of "and"** are Vercel house style. Follow the project.
18
- - Rules marked **[React]** use React or Next.js APIs. In other frameworks apply the idea with the framework's equivalent (Vue `v-model`, Svelte `bind:`, Angular forms, `<RouterLink>`, `<NuxtLink>`), or skip it if it has no equivalent.
19
- - "Keyboard handlers" below means custom interactive elements. Native `<button>`, `<a href>` and form controls already handle the keyboard.
20
- - Deeper accessibility work lives in the `accessibility` skill; visual design in `interface-design`; motion values in `motion-design`.
21
-
22
- ## Rules
23
-
24
- ### Accessibility
25
-
26
- - Icon-only buttons need `aria-label`
27
- - Form controls need `<label>` or `aria-label`
28
- - Custom interactive elements need keyboard handlers (`onKeyDown`/`onKeyUp` or the framework's equivalent)
29
- - `<button>` for actions, `<a>`/`<Link>` for navigation (not `<div onClick>`)
30
- - Images need `alt` (or `alt=""` if decorative)
31
- - Decorative icons need `aria-hidden="true"`
32
- - Async updates (toasts, validation) need `aria-live="polite"`
33
- - Use semantic HTML (`<button>`, `<a>`, `<label>`, `<table>`) before ARIA
34
- - Headings hierarchical `<h1>` to `<h6>`; include skip link for main content
35
- - `scroll-margin-top` on heading anchors
36
- - Meaningful media needs captions, transcripts, or descriptions as applicable
37
- - Media controls need keyboard support; decorative media needs assistive-tech hiding
38
-
39
- ### Focus states
40
-
41
- - Interactive elements need visible focus: `focus-visible:ring-*` or equivalent
42
- - Never `outline-none` / `outline: none` without focus replacement
43
- - Use `:focus-visible` over `:focus` (avoid focus ring on click)
44
- - Group focus with `:focus-within` for compound controls
45
- - Sticky headers/footers/overlays must not cover the focused element
46
-
47
- ### Forms
48
-
49
- - Inputs need `autocomplete` and meaningful `name`
50
- - Use correct `type` (`email`, `tel`, `url`, `number`) and `inputmode`
51
- - Never block paste (`onPaste` + `preventDefault`)
52
- - Labels clickable (`htmlFor` [React] / `for`, or wrapping control)
53
- - Disable spellcheck on emails, codes, usernames (`spellCheck={false}` [React] / `spellcheck="false"`)
54
- - Checkboxes/radios: label + control share single hit target (no dead zones)
55
- - Submit button stays enabled until request starts; spinner during request
56
- - Errors inline next to fields; focus first error on submit
57
- - Placeholders show an example pattern (Vercel style also ends them with `…`; follow the project)
58
- - `autocomplete="off"` on non-auth fields to avoid password manager triggers
59
- - Warn before navigation with unsaved changes (`beforeunload` or router guard)
60
-
61
- ### Animation
62
-
63
- - Honor `prefers-reduced-motion` (provide reduced variant or disable)
64
- - Animate `transform`/`opacity` only (compositor-friendly)
65
- - Never `transition: all`; list properties explicitly
66
- - Set correct `transform-origin`
67
- - SVG: transforms on `<g>` wrapper with `transform-box: fill-box; transform-origin: center`
68
- - Animations interruptible: respond to user input mid-animation
69
- - Autoplay motion >5 seconds alongside other content needs pause, stop, or hide controls
70
- - Muted decorative loops must stop under `prefers-reduced-motion`
71
-
72
- ### Typography
73
-
74
- - `…` not `...`
75
- - Curly quotes `“` `”` not straight `"`
76
- - Non-breaking spaces: `10&nbsp;MB`, `⌘&nbsp;K`, brand names
77
- - Loading states end with `…`: `"Loading…"`, `"Saving…"`
78
- - `font-variant-numeric: tabular-nums` for number columns/comparisons
79
- - Use `text-wrap: balance` or `text-pretty` on headings (prevents widows)
80
-
81
- ### Content handling
82
-
83
- - Text containers handle long content: `truncate`, `line-clamp-*`, or `break-words`
84
- - Flex children need `min-w-0` to allow text truncation
85
- - Handle empty states: don't render broken UI for empty strings/arrays
86
- - User-generated content: anticipate short, average, and very long inputs
87
-
88
- ### Images
89
-
90
- - `<img>` needs explicit `width` and `height` (prevents CLS)
91
- - Below-fold images: `loading="lazy"`
92
- - Above-fold critical images: `priority` [Next.js] or `fetchpriority="high"`
93
-
94
- ### Performance
95
-
96
- - Large lists (>50 items): virtualize (`virtua` [React], `content-visibility: auto`, or the framework's virtual list)
97
- - No layout reads in render (`getBoundingClientRect`, `offsetHeight`, `offsetWidth`, `scrollTop`)
98
- - Batch DOM reads/writes; avoid interleaving
99
- - Prefer uncontrolled inputs; controlled inputs must be cheap per keystroke [React]
100
- - Add `<link rel="preconnect">` for CDN/asset domains
101
- - Critical fonts: `<link rel="preload" as="font">` with `font-display: swap`
102
- - Prefer `<video autoplay muted loop playsinline>` over animated GIF; provide a still alternative
103
- - Short non-essential loops: Safari H.264 MP4 `<picture>` source, `prefers-reduced-motion` media condition, and still fallback
104
-
105
- ### Navigation and state
106
-
107
- - URL reflects state: filters, tabs, pagination, expanded panels in query params
108
- - Links use `<a>`/`<Link>` (Cmd/Ctrl+click, middle-click support)
109
- - Deep-link all stateful UI (if uses `useState`, consider URL sync via nuqs or similar) [React]
110
- - Destructive actions need confirmation modal or undo window, never immediate
111
-
112
- ### Touch and interaction
113
-
114
- - `touch-action: manipulation` (prevents double-tap zoom delay)
115
- - `-webkit-tap-highlight-color` set intentionally
116
- - `overscroll-behavior: contain` in modals/drawers/sheets
117
- - Page rubber-band suppression: `overscroll-behavior: none` on `<html>` inside `@media (pointer: fine)`; keep coarse-pointer page defaults for pull-to-refresh. Test hybrid touch devices: `pointer` describes the primary input, and `none` also disables scroll chaining and native swipe navigation
118
- - During drag: disable text selection, `inert` on dragged elements
119
- - Drag/swipe/pinch/path gestures need tap/click and keyboard alternatives unless essential
120
- - `autoFocus` sparingly: desktop only, single primary input; avoid on mobile
121
-
122
- ### Safe areas and layout
123
-
124
- - Full-bleed layouts need `env(safe-area-inset-*)` for notches
125
- - Avoid unwanted scrollbars: `overflow-x-hidden` on containers, fix content overflow
126
- - Flex/grid over JS measurement for layout
127
-
128
- ### Dark mode and theming
129
-
130
- - `color-scheme: dark` on `<html>` for dark themes (fixes scrollbar, inputs)
131
- - `<meta name="theme-color">` matches page background
132
- - Native `<select>`: explicit `background-color` and `color` (Windows dark mode)
133
-
134
- ### Locale and i18n
135
-
136
- - Dates/times: use `Intl.DateTimeFormat` not hardcoded formats
137
- - Numbers/currency: use `Intl.NumberFormat` not hardcoded formats
138
- - Detect language via `Accept-Language` / `navigator.languages`, not IP
139
- - Brand names, code tokens, identifiers: wrap with `translate="no"` to prevent garbled auto-translation
140
-
141
- ### Hydration safety [React, other SSR frameworks have the same class of issue]
142
-
143
- - Inputs with `value` need `onChange` (or use `defaultValue` for uncontrolled)
144
- - Date/time rendering: guard against hydration mismatch (server vs client)
145
- - `suppressHydrationWarning` only where truly needed
146
-
147
- ### Hover and interactive states
148
-
149
- - Buttons/links need `hover:` state (visual feedback)
150
- - Interactive states increase contrast: hover/active/focus more prominent than rest
151
-
152
- ### Content and copy
153
-
154
- - Active voice: "Install the CLI" not "The CLI will be installed"
155
- - Sentence case for headings/buttons unless the project uses another style (Vercel's original: Title Case, Chicago style)
156
- - Numerals for counts: "8 deployments" not "eight"
157
- - Specific button labels: "Save API key" not "Continue"
158
- - Error messages include fix/next step, not just problem
159
- - Second person; avoid first person
160
- - `&` over "and" where space-constrained (house style; follow the project)
161
-
162
- ### Anti-patterns (flag these)
163
-
164
- - `user-scalable=no` or `maximum-scale=1` disabling zoom
165
- - `onPaste` with `preventDefault`
166
- - `transition: all`
167
- - `outline-none` without focus-visible replacement
168
- - Inline `onClick` navigation without `<a>`
169
- - `<div>` or `<span>` with click handlers (should be `<button>`)
170
- - Images without dimensions
171
- - Large arrays `.map()` without virtualization
172
- - Form inputs without labels
173
- - Icon buttons without `aria-label`
174
- - Hardcoded date/number formats (use `Intl.*`)
175
- - `autoFocus` without clear justification
176
- - Animated GIF when compressed video is suitable
177
- - Gesture-only action without tap/click and keyboard alternative
178
-
179
- ## Output format
180
-
181
- Group by file. Use `file:line`. Terse findings: the issue and the location; explain only when the fix is not obvious. No preamble.
182
-
183
- ```text
184
- ## src/Button.tsx
185
-
186
- src/Button.tsx:42 - icon button missing aria-label
187
- src/Button.tsx:55 - animation missing prefers-reduced-motion
188
- src/Button.tsx:67 - transition: all -> list properties
189
-
190
- ## src/Modal.tsx
191
-
192
- src/Modal.tsx:12 - missing overscroll-behavior: contain
193
- src/Modal.tsx:34 - "..." -> "…"
194
-
195
- ## src/Card.tsx
196
-
197
- pass
198
- ```
199
-
200
- Only report rules that apply to the changed code, and only where the project does not deliberately do otherwise.
201
-
202
- Sources: rules text from vercel-labs/web-interface-guidelines command.md (MIT, Copyright (c) 2025 Vercel Labs; changed: vendored instead of fetched, React-specific rules marked, Title Case replaced by sentence case as the default, house-style rules marked, dashes and symbols normalised, intro and precedence notes added).
1
+ ---
2
+ name: web-interface-guidelines
3
+ description: Use when writing or reviewing web UI code for interaction and detail rules: accessibility basics, focus, forms, animation, typography details, long content, images, performance, URL state, touch, safe areas, dark mode, locale formatting, hover states and copy. A vendored checklist with file:line findings; project conventions override it.
4
+ ---
5
+
6
+ # Web interface guidelines
7
+
8
+ A terse checklist of details that make web interfaces work well, vendored from Vercel's Web Interface Guidelines so it never changes under a run and needs no network. Use it in two ways:
9
+
10
+ - **Code step:** after changing UI, check the files you touched against the rules and fix what applies.
11
+ - **Review step:** check the changed UI files of the branch and report findings in the format below. Do not edit product code.
12
+
13
+ ## How these rules sit with the project
14
+
15
+ - The project's own conventions win: its CLAUDE.md / AGENTS.md, DESIGN.md, lint rules, component library and existing copy style.
16
+ - **Capitalization:** the original list asks for Title Case on headings and buttons. Our default is sentence case, unless the project already uses Title Case. Match the existing strings.
17
+ - **Placeholders ending with an ellipsis** and **`&` instead of "and"** are Vercel house style. Follow the project.
18
+ - Rules marked **[React]** use React or Next.js APIs. In other frameworks apply the idea with the framework's equivalent (Vue `v-model`, Svelte `bind:`, Angular forms, `<RouterLink>`, `<NuxtLink>`), or skip it if it has no equivalent.
19
+ - "Keyboard handlers" below means custom interactive elements. Native `<button>`, `<a href>` and form controls already handle the keyboard.
20
+ - Deeper accessibility work lives in the `accessibility` skill; visual design in `interface-design`; motion values in `motion-design`.
21
+
22
+ ## Rules
23
+
24
+ ### Accessibility
25
+
26
+ - Icon-only buttons need `aria-label`
27
+ - Form controls need `<label>` or `aria-label`
28
+ - Custom interactive elements need keyboard handlers (`onKeyDown`/`onKeyUp` or the framework's equivalent)
29
+ - `<button>` for actions, `<a>`/`<Link>` for navigation (not `<div onClick>`)
30
+ - Images need `alt` (or `alt=""` if decorative)
31
+ - Decorative icons need `aria-hidden="true"`
32
+ - Async updates (toasts, validation) need `aria-live="polite"`
33
+ - Use semantic HTML (`<button>`, `<a>`, `<label>`, `<table>`) before ARIA
34
+ - Headings hierarchical `<h1>` to `<h6>`; include skip link for main content
35
+ - `scroll-margin-top` on heading anchors
36
+ - Meaningful media needs captions, transcripts, or descriptions as applicable
37
+ - Media controls need keyboard support; decorative media needs assistive-tech hiding
38
+
39
+ ### Focus states
40
+
41
+ - Interactive elements need visible focus: `focus-visible:ring-*` or equivalent
42
+ - Never `outline-none` / `outline: none` without focus replacement
43
+ - Use `:focus-visible` over `:focus` (avoid focus ring on click)
44
+ - Group focus with `:focus-within` for compound controls
45
+ - Sticky headers/footers/overlays must not cover the focused element
46
+
47
+ ### Forms
48
+
49
+ - Inputs need `autocomplete` and meaningful `name`
50
+ - Use correct `type` (`email`, `tel`, `url`, `number`) and `inputmode`
51
+ - Never block paste (`onPaste` + `preventDefault`)
52
+ - Labels clickable (`htmlFor` [React] / `for`, or wrapping control)
53
+ - Disable spellcheck on emails, codes, usernames (`spellCheck={false}` [React] / `spellcheck="false"`)
54
+ - Checkboxes/radios: label + control share single hit target (no dead zones)
55
+ - Submit button stays enabled until request starts; spinner during request
56
+ - Errors inline next to fields; focus first error on submit
57
+ - Placeholders show an example pattern (Vercel style also ends them with `…`; follow the project)
58
+ - `autocomplete="off"` on non-auth fields to avoid password manager triggers
59
+ - Warn before navigation with unsaved changes (`beforeunload` or router guard)
60
+
61
+ ### Animation
62
+
63
+ - Honor `prefers-reduced-motion` (provide reduced variant or disable)
64
+ - Animate `transform`/`opacity` only (compositor-friendly)
65
+ - Never `transition: all`; list properties explicitly
66
+ - Set correct `transform-origin`
67
+ - SVG: transforms on `<g>` wrapper with `transform-box: fill-box; transform-origin: center`
68
+ - Animations interruptible: respond to user input mid-animation
69
+ - Autoplay motion >5 seconds alongside other content needs pause, stop, or hide controls
70
+ - Muted decorative loops must stop under `prefers-reduced-motion`
71
+
72
+ ### Typography
73
+
74
+ - `…` not `...`
75
+ - Curly quotes `“` `”` not straight `"`
76
+ - Non-breaking spaces: `10&nbsp;MB`, `⌘&nbsp;K`, brand names
77
+ - Loading states end with `…`: `"Loading…"`, `"Saving…"`
78
+ - `font-variant-numeric: tabular-nums` for number columns/comparisons
79
+ - Use `text-wrap: balance` or `text-pretty` on headings (prevents widows)
80
+
81
+ ### Content handling
82
+
83
+ - Text containers handle long content: `truncate`, `line-clamp-*`, or `break-words`
84
+ - Flex children need `min-w-0` to allow text truncation
85
+ - Handle empty states: don't render broken UI for empty strings/arrays
86
+ - User-generated content: anticipate short, average, and very long inputs
87
+
88
+ ### Images
89
+
90
+ - `<img>` needs explicit `width` and `height` (prevents CLS)
91
+ - Below-fold images: `loading="lazy"`
92
+ - Above-fold critical images: `priority` [Next.js] or `fetchpriority="high"`
93
+
94
+ ### Performance
95
+
96
+ - Large lists (>50 items): virtualize (`virtua` [React], `content-visibility: auto`, or the framework's virtual list)
97
+ - No layout reads in render (`getBoundingClientRect`, `offsetHeight`, `offsetWidth`, `scrollTop`)
98
+ - Batch DOM reads/writes; avoid interleaving
99
+ - Prefer uncontrolled inputs; controlled inputs must be cheap per keystroke [React]
100
+ - Add `<link rel="preconnect">` for CDN/asset domains
101
+ - Critical fonts: `<link rel="preload" as="font">` with `font-display: swap`
102
+ - Prefer `<video autoplay muted loop playsinline>` over animated GIF; provide a still alternative
103
+ - Short non-essential loops: Safari H.264 MP4 `<picture>` source, `prefers-reduced-motion` media condition, and still fallback
104
+
105
+ ### Navigation and state
106
+
107
+ - URL reflects state: filters, tabs, pagination, expanded panels in query params
108
+ - Links use `<a>`/`<Link>` (Cmd/Ctrl+click, middle-click support)
109
+ - Deep-link all stateful UI (if uses `useState`, consider URL sync via nuqs or similar) [React]
110
+ - Destructive actions need confirmation modal or undo window, never immediate
111
+
112
+ ### Touch and interaction
113
+
114
+ - `touch-action: manipulation` (prevents double-tap zoom delay)
115
+ - `-webkit-tap-highlight-color` set intentionally
116
+ - `overscroll-behavior: contain` in modals/drawers/sheets
117
+ - Page rubber-band suppression: `overscroll-behavior: none` on `<html>` inside `@media (pointer: fine)`; keep coarse-pointer page defaults for pull-to-refresh. Test hybrid touch devices: `pointer` describes the primary input, and `none` also disables scroll chaining and native swipe navigation
118
+ - During drag: disable text selection, `inert` on dragged elements
119
+ - Drag/swipe/pinch/path gestures need tap/click and keyboard alternatives unless essential
120
+ - `autoFocus` sparingly: desktop only, single primary input; avoid on mobile
121
+
122
+ ### Safe areas and layout
123
+
124
+ - Full-bleed layouts need `env(safe-area-inset-*)` for notches
125
+ - Avoid unwanted scrollbars: `overflow-x-hidden` on containers, fix content overflow
126
+ - Flex/grid over JS measurement for layout
127
+
128
+ ### Dark mode and theming
129
+
130
+ - `color-scheme: dark` on `<html>` for dark themes (fixes scrollbar, inputs)
131
+ - `<meta name="theme-color">` matches page background
132
+ - Native `<select>`: explicit `background-color` and `color` (Windows dark mode)
133
+
134
+ ### Locale and i18n
135
+
136
+ - Dates/times: use `Intl.DateTimeFormat` not hardcoded formats
137
+ - Numbers/currency: use `Intl.NumberFormat` not hardcoded formats
138
+ - Detect language via `Accept-Language` / `navigator.languages`, not IP
139
+ - Brand names, code tokens, identifiers: wrap with `translate="no"` to prevent garbled auto-translation
140
+
141
+ ### Hydration safety [React, other SSR frameworks have the same class of issue]
142
+
143
+ - Inputs with `value` need `onChange` (or use `defaultValue` for uncontrolled)
144
+ - Date/time rendering: guard against hydration mismatch (server vs client)
145
+ - `suppressHydrationWarning` only where truly needed
146
+
147
+ ### Hover and interactive states
148
+
149
+ - Buttons/links need `hover:` state (visual feedback)
150
+ - Interactive states increase contrast: hover/active/focus more prominent than rest
151
+
152
+ ### Content and copy
153
+
154
+ - Active voice: "Install the CLI" not "The CLI will be installed"
155
+ - Sentence case for headings/buttons unless the project uses another style (Vercel's original: Title Case, Chicago style)
156
+ - Numerals for counts: "8 deployments" not "eight"
157
+ - Specific button labels: "Save API key" not "Continue"
158
+ - Error messages include fix/next step, not just problem
159
+ - Second person; avoid first person
160
+ - `&` over "and" where space-constrained (house style; follow the project)
161
+
162
+ ### Anti-patterns (flag these)
163
+
164
+ - `user-scalable=no` or `maximum-scale=1` disabling zoom
165
+ - `onPaste` with `preventDefault`
166
+ - `transition: all`
167
+ - `outline-none` without focus-visible replacement
168
+ - Inline `onClick` navigation without `<a>`
169
+ - `<div>` or `<span>` with click handlers (should be `<button>`)
170
+ - Images without dimensions
171
+ - Large arrays `.map()` without virtualization
172
+ - Form inputs without labels
173
+ - Icon buttons without `aria-label`
174
+ - Hardcoded date/number formats (use `Intl.*`)
175
+ - `autoFocus` without clear justification
176
+ - Animated GIF when compressed video is suitable
177
+ - Gesture-only action without tap/click and keyboard alternative
178
+
179
+ ## Output format
180
+
181
+ Group by file. Use `file:line`. Terse findings: the issue and the location; explain only when the fix is not obvious. No preamble.
182
+
183
+ ```text
184
+ ## src/Button.tsx
185
+
186
+ src/Button.tsx:42 - icon button missing aria-label
187
+ src/Button.tsx:55 - animation missing prefers-reduced-motion
188
+ src/Button.tsx:67 - transition: all -> list properties
189
+
190
+ ## src/Modal.tsx
191
+
192
+ src/Modal.tsx:12 - missing overscroll-behavior: contain
193
+ src/Modal.tsx:34 - "..." -> "…"
194
+
195
+ ## src/Card.tsx
196
+
197
+ pass
198
+ ```
199
+
200
+ Only report rules that apply to the changed code, and only where the project does not deliberately do otherwise.
201
+
202
+ Sources: rules text from vercel-labs/web-interface-guidelines command.md (MIT, Copyright (c) 2025 Vercel Labs; changed: vendored instead of fetched, React-specific rules marked, Title Case replaced by sentence case as the default, house-style rules marked, dashes and symbols normalised, intro and precedence notes added).