quiver-cli 0.7.0 → 1.0.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.
- package/README.md +110 -45
- package/bin/quiver-cli.mjs +3 -1
- package/dist/cli.js +733 -499
- package/package.json +2 -2
- package/template/.agents/AGENTS.md +4 -3
- package/template/.agents/config.json +7 -0
- package/template/.agents/plugins/opencode/rtk.ts +34 -0
- package/template/.agents/skills/agent-browser/SKILL.md +1 -0
- package/template/.agents/skills/apps/skybridge/SKILL.md +4 -0
- package/template/.agents/skills/design/impeccable/SKILL.md +36 -118
- package/template/.agents/skills/design/impeccable/reference/adapt.md +1 -0
- package/template/.agents/skills/design/impeccable/reference/adapt.native.md +58 -0
- package/template/.agents/skills/design/impeccable/reference/android.md +40 -0
- package/template/.agents/skills/design/impeccable/reference/animate.md +73 -188
- package/template/.agents/skills/design/impeccable/reference/audit.md +12 -9
- package/template/.agents/skills/design/impeccable/reference/audit.native.md +139 -0
- package/template/.agents/skills/design/impeccable/reference/bolder.md +19 -101
- package/template/.agents/skills/design/impeccable/reference/clarify.md +59 -253
- package/template/.agents/skills/design/impeccable/reference/colorize.md +51 -222
- package/template/.agents/skills/design/impeccable/reference/craft-floor.md +42 -0
- package/template/.agents/skills/design/impeccable/reference/craft.md +3 -121
- package/template/.agents/skills/design/impeccable/reference/critique.md +44 -23
- package/template/.agents/skills/design/impeccable/reference/degraded/asset-producer.md +90 -0
- package/template/.agents/skills/design/impeccable/reference/degraded/documenter.md +24 -0
- package/template/.agents/skills/design/impeccable/reference/degraded/finish-reviewer.md +37 -0
- package/template/.agents/skills/design/impeccable/reference/degraded/manual-edit-applier.md +92 -0
- package/template/.agents/skills/design/impeccable/reference/delight.md +47 -279
- package/template/.agents/skills/design/impeccable/reference/distill.md +2 -2
- package/template/.agents/skills/design/impeccable/reference/doctor.md +53 -0
- package/template/.agents/skills/design/impeccable/reference/document.md +60 -73
- package/template/.agents/skills/design/impeccable/reference/harden.md +1 -12
- package/template/.agents/skills/design/impeccable/reference/hooks.md +20 -5
- package/template/.agents/skills/design/impeccable/reference/init.md +72 -119
- package/template/.agents/skills/design/impeccable/reference/ios.md +45 -0
- package/template/.agents/skills/design/impeccable/reference/layout.md +54 -131
- package/template/.agents/skills/design/impeccable/reference/live-setup.md +102 -0
- package/template/.agents/skills/design/impeccable/reference/live.md +116 -511
- package/template/.agents/skills/design/impeccable/reference/new-work.md +105 -0
- package/template/.agents/skills/design/impeccable/reference/{product.md → operate.md} +6 -5
- package/template/.agents/skills/design/impeccable/reference/optimize.md +4 -4
- package/template/.agents/skills/design/impeccable/reference/overdrive.md +1 -4
- package/template/.agents/skills/design/impeccable/reference/polish.md +68 -212
- package/template/.agents/skills/design/impeccable/reference/quieter.md +3 -3
- package/template/.agents/skills/design/impeccable/reference/routing.md +18 -0
- package/template/.agents/skills/design/impeccable/reference/shape.md +38 -144
- package/template/.agents/skills/design/impeccable/reference/typeset.md +51 -250
- package/template/.agents/skills/design/impeccable/reference/visualize.md +47 -0
- package/template/.agents/skills/design/impeccable/scripts/command-metadata.json +1 -1
- package/template/.agents/skills/design/impeccable/scripts/concept-seed.mjs +558 -0
- package/template/.agents/skills/design/impeccable/scripts/context-signals.mjs +119 -10
- package/template/.agents/skills/design/impeccable/scripts/context.mjs +534 -45
- package/template/.agents/skills/design/impeccable/scripts/critique-storage.mjs +18 -47
- package/template/.agents/skills/design/impeccable/scripts/detector/browser/injected/index.mjs +96 -10
- package/template/.agents/skills/design/impeccable/scripts/detector/cli/main.mjs +174 -26
- package/template/.agents/skills/design/impeccable/scripts/detector/design-system.mjs +233 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns-browser.js +3348 -203
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/browser/detect-url.mjs +102 -7
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/regex/detect-text.mjs +297 -97
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +187 -16
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/detect-html.mjs +41 -11
- package/template/.agents/skills/design/impeccable/scripts/detector/findings.mjs +7 -1
- package/template/.agents/skills/design/impeccable/scripts/detector/node/file-system.mjs +16 -2
- package/template/.agents/skills/design/impeccable/scripts/detector/registry/antipatterns.mjs +207 -38
- package/template/.agents/skills/design/impeccable/scripts/detector/rules/checks.mjs +3082 -173
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/constants.mjs +11 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/fonts.mjs +30 -0
- package/template/.agents/skills/design/impeccable/scripts/doctor.mjs +336 -0
- package/template/.agents/skills/design/impeccable/scripts/embed-prompt.mjs +133 -0
- package/template/.agents/skills/design/impeccable/scripts/generate-image.mjs +240 -0
- package/template/.agents/skills/design/impeccable/scripts/hook-admin.mjs +98 -18
- package/template/.agents/skills/design/impeccable/scripts/hook-before-edit.mjs +46 -6
- package/template/.agents/skills/design/impeccable/scripts/hook-lib.mjs +518 -50
- package/template/.agents/skills/design/impeccable/scripts/hook.mjs +25 -8
- package/template/.agents/skills/design/impeccable/scripts/lib/artifact-schema.mjs +93 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/composition-catalog.mjs +200 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/concept-catalog.mjs +357 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-config.mjs +27 -7
- package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-paths.mjs +17 -8
- package/template/.agents/skills/design/impeccable/scripts/lib/provider.mjs +5 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/roll-selection.mjs +362 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness-deep.mjs +457 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness-notice.mjs +169 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness.mjs +457 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/surface-briefs.mjs +151 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/target-slug.mjs +33 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/template-extensions.mjs +146 -0
- package/template/.agents/skills/design/impeccable/scripts/live/accept-css.mjs +617 -0
- package/template/.agents/skills/design/impeccable/scripts/live/accept-verify.mjs +60 -0
- package/template/.agents/skills/design/impeccable/scripts/live/browser-script-parts.mjs +7 -1
- package/template/.agents/skills/design/impeccable/scripts/live/completion.mjs +10 -1
- package/template/.agents/skills/design/impeccable/scripts/live/event-validation.mjs +67 -5
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/astro.mjs +47 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/detect-utils.mjs +73 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/index.mjs +143 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/journal.mjs +197 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nextjs.mjs +49 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nuxt.mjs +161 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/script-src.mjs +17 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/static-html.mjs +26 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/sveltekit.mjs +71 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tag-strategy.mjs +247 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tanstack-start.mjs +70 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/vite-generic.mjs +42 -0
- package/template/.agents/skills/design/impeccable/scripts/live/generation-preflight.mjs +149 -0
- package/template/.agents/skills/design/impeccable/scripts/live/instructions.mjs +142 -0
- package/template/.agents/skills/design/impeccable/scripts/live/poll-lanes.mjs +14 -0
- package/template/.agents/skills/design/impeccable/scripts/live/roots.mjs +508 -0
- package/template/.agents/skills/design/impeccable/scripts/live/session-store.mjs +324 -50
- package/template/.agents/skills/design/impeccable/scripts/live/source-lock.mjs +105 -0
- package/template/.agents/skills/design/impeccable/scripts/live/source-search.mjs +105 -0
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-ast.mjs +961 -0
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-component.mjs +588 -72
- package/template/.agents/skills/design/impeccable/scripts/live/sveltekit-adapter.mjs +59 -17
- package/template/.agents/skills/design/impeccable/scripts/live/tanstack-adapter.mjs +280 -0
- package/template/.agents/skills/design/impeccable/scripts/live/vocabulary.mjs +135 -0
- package/template/.agents/skills/design/impeccable/scripts/live-accept.mjs +210 -68
- package/template/.agents/skills/design/impeccable/scripts/live-browser.js +1562 -223
- package/template/.agents/skills/design/impeccable/scripts/live-commit-manual-edits.mjs +3 -0
- package/template/.agents/skills/design/impeccable/scripts/live-complete.mjs +33 -1
- package/template/.agents/skills/design/impeccable/scripts/live-inject.mjs +175 -255
- package/template/.agents/skills/design/impeccable/scripts/live-insert.mjs +26 -6
- package/template/.agents/skills/design/impeccable/scripts/live-manual-edit-evidence.mjs +6 -1
- package/template/.agents/skills/design/impeccable/scripts/live-poll.mjs +61 -16
- package/template/.agents/skills/design/impeccable/scripts/live-resume.mjs +39 -10
- package/template/.agents/skills/design/impeccable/scripts/live-server.mjs +573 -47
- package/template/.agents/skills/design/impeccable/scripts/live-status.mjs +17 -7
- package/template/.agents/skills/design/impeccable/scripts/live-wrap.mjs +124 -91
- package/template/.agents/skills/design/impeccable/scripts/live.mjs +88 -26
- package/template/.agents/skills/design/impeccable/scripts/palette.mjs +76 -81
- package/template/.agents/skills/design/impeccable/scripts/pin.mjs +18 -11
- package/template/.agents/skills/design/impeccable/scripts/serve-question.mjs +932 -0
- package/template/.agents/skills/design/impeccable/scripts/surface-brief.mjs +74 -0
- package/template/.agents/skills/design/shadcn/SKILL.md +46 -11
- package/template/.agents/skills/design/shadcn/cli.md +49 -16
- package/template/.agents/skills/design/shadcn/customization.md +14 -7
- package/template/.agents/skills/design/shadcn/evals/evals.json +30 -0
- package/template/.agents/skills/design/shadcn/mcp.md +27 -16
- package/template/.agents/skills/design/shadcn/registry.md +277 -0
- package/template/.agents/skills/design/shadcn/rules/chat.md +224 -0
- package/template/.agents/skills/design/shadcn/rules/composition.md +20 -2
- package/template/.agents/skills/design/shadcn/rules/styling.md +23 -0
- package/template/.agents/skills/find-skills/SKILL.md +2 -3
- package/template/.agents/skills/hono/SKILL.md +579 -0
- package/template/.agents/skills/integrations/langfuse/SKILL.md +10 -6
- package/template/.agents/skills/integrations/langfuse/references/ci-cd.md +41 -0
- package/template/.agents/skills/integrations/langfuse/references/cli.md +8 -0
- package/template/.agents/skills/integrations/langfuse/references/error-analysis.md +15 -27
- package/template/.agents/skills/integrations/langfuse/references/instrumentation.md +39 -52
- package/template/.agents/skills/integrations/langfuse/references/judge-calibration.md +5 -2
- package/template/.agents/skills/integrations/langfuse/references/prompt-engineering.md +35 -0
- package/template/.agents/skills/integrations/langfuse/references/prompt-migration.md +41 -196
- package/template/.agents/skills/integrations/langfuse/references/skill-feedback.md +3 -0
- package/template/.agents/skills/integrations/langfuse/references/trace-evaluator-upgrade.md +76 -0
- package/template/.agents/skills/integrations/langfuse/references/user-feedback.md +4 -0
- package/template/.agents/skills/integrations/langfuse/references/v4-project-migration.md +73 -0
- package/template/.agents/skills/supabase/CHANGELOG.md +71 -0
- package/template/.agents/skills/supabase/SKILL.md +145 -0
- package/template/.agents/skills/supabase/assets/feedback-issue-template.md +17 -0
- package/template/.agents/skills/supabase/references/skill-feedback.md +17 -0
- package/template/.agents/skills/supabase-postgres-best-practices/CHANGELOG.md +73 -0
- package/template/.agents/skills/supabase-postgres-best-practices/SKILL.md +64 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/_sections.md +39 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/_template.md +34 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
- package/template/.agents/upstreams.json +34 -12
- package/template/.agents/skills/design/impeccable/reference/brand.md +0 -108
- package/template/.agents/skills/design/impeccable/reference/codex.md +0 -105
- package/template/.agents/skills/design/impeccable/reference/interaction-design.md +0 -189
- package/template/.agents/skills/integrations/langfuse/references/sdk-upgrade.md +0 -175
package/template/.agents/skills/design/impeccable/scripts/detector/registry/antipatterns.mjs
CHANGED
|
@@ -21,24 +21,17 @@ const ANTIPATTERNS = [
|
|
|
21
21
|
{
|
|
22
22
|
id: 'overused-font',
|
|
23
23
|
category: 'slop',
|
|
24
|
+
scopes: ['type'],
|
|
24
25
|
name: 'Overused font',
|
|
25
26
|
description:
|
|
26
27
|
'Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.',
|
|
27
28
|
skillSection: 'Typography',
|
|
28
29
|
skillGuideline: 'overused fonts like Inter',
|
|
29
30
|
},
|
|
30
|
-
{
|
|
31
|
-
id: 'single-font',
|
|
32
|
-
category: 'slop',
|
|
33
|
-
name: 'Single font for everything',
|
|
34
|
-
description:
|
|
35
|
-
'Only one font family is used for the entire page. Pair a distinctive display font with a refined body font to create typographic hierarchy.',
|
|
36
|
-
skillSection: 'Typography',
|
|
37
|
-
skillGuideline: 'only one font family for the entire page',
|
|
38
|
-
},
|
|
39
31
|
{
|
|
40
32
|
id: 'flat-type-hierarchy',
|
|
41
33
|
category: 'slop',
|
|
34
|
+
scopes: ['type'],
|
|
42
35
|
name: 'Flat type hierarchy',
|
|
43
36
|
description:
|
|
44
37
|
'Font sizes are too close together — no clear visual hierarchy. Use fewer sizes with more contrast (aim for at least a 1.25 ratio between steps).',
|
|
@@ -75,6 +68,7 @@ const ANTIPATTERNS = [
|
|
|
75
68
|
{
|
|
76
69
|
id: 'nested-cards',
|
|
77
70
|
category: 'slop',
|
|
71
|
+
scopes: ['layout'],
|
|
78
72
|
name: 'Nested cards',
|
|
79
73
|
description:
|
|
80
74
|
'Cards inside cards create visual noise and excessive depth. Flatten the hierarchy — use spacing, typography, and dividers instead of nesting containers.',
|
|
@@ -84,6 +78,7 @@ const ANTIPATTERNS = [
|
|
|
84
78
|
{
|
|
85
79
|
id: 'monotonous-spacing',
|
|
86
80
|
category: 'slop',
|
|
81
|
+
scopes: ['layout'],
|
|
87
82
|
name: 'Monotonous spacing',
|
|
88
83
|
description:
|
|
89
84
|
'The same spacing value used everywhere — no rhythm, no variation. Use tight groupings for related items and generous separations between sections.',
|
|
@@ -99,18 +94,73 @@ const ANTIPATTERNS = [
|
|
|
99
94
|
skillSection: 'Motion',
|
|
100
95
|
skillGuideline: 'bounce or elastic easing',
|
|
101
96
|
},
|
|
97
|
+
{
|
|
98
|
+
id: 'pulsing-dot',
|
|
99
|
+
category: 'slop',
|
|
100
|
+
name: 'Pulsing status dot',
|
|
101
|
+
description:
|
|
102
|
+
'Small pulsing status dots simulate liveness decoratively. Reserve pulse animation for indicators tied to genuinely live, changing data; a static indicator with clear labeling is honest and calmer.',
|
|
103
|
+
skillSection: 'Motion',
|
|
104
|
+
skillGuideline: 'decorative pulsing status dot',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: 'blinking-cursor',
|
|
108
|
+
category: 'slop',
|
|
109
|
+
severity: 'advisory',
|
|
110
|
+
name: 'Decorative blinking cursor',
|
|
111
|
+
description:
|
|
112
|
+
'A blinking text cursor animated into a hero or landing section simulates typing where no input exists. It borrows the dev-tool aesthetic as decoration. Real editable fields draw their own caret; anywhere else, let the composition hold attention without a fake prompt.',
|
|
113
|
+
skillSection: 'Motion',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: 'shape-assembled-illustration',
|
|
117
|
+
category: 'slop',
|
|
118
|
+
severity: 'advisory',
|
|
119
|
+
name: 'Shape-assembled illustration',
|
|
120
|
+
description:
|
|
121
|
+
'A large inline SVG that builds a pictorial scene from a pile of primitive shapes reads as placeholder clip art, not illustration. Icons, logos, and data graphics are fine at their scale; a hero-sized visual deserves real artwork, a photograph, or a deliberately drawn graphic.',
|
|
122
|
+
skillSection: 'Imagery',
|
|
123
|
+
},
|
|
102
124
|
{
|
|
103
125
|
id: 'dark-glow',
|
|
104
126
|
category: 'slop',
|
|
105
|
-
name: '
|
|
127
|
+
name: 'Glowing shadow accents',
|
|
128
|
+
description:
|
|
129
|
+
'Colored glow shadows — a zero-offset chromatic halo (box- or text-shadow) on any background, or any colored blurred shadow on a dark background — are the default "cool" look of AI-generated UIs. Use neutral elevation shadows and subtle, purposeful lighting instead.',
|
|
130
|
+
skillSection: 'Color & Contrast',
|
|
131
|
+
skillGuideline: 'dark mode with glowing accents',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 'radial-halo',
|
|
135
|
+
category: 'slop',
|
|
136
|
+
name: 'Radial-gradient background halo',
|
|
137
|
+
description:
|
|
138
|
+
'A chromatic radial-gradient wash — saturated at the center, fading to transparent — used as a decorative background glow on a dark page. Same tell as glowing shadows, drawn with a gradient instead of a shadow. Ground the surface with a solid or subtly shifted background instead.',
|
|
139
|
+
skillSection: 'Color & Contrast',
|
|
140
|
+
skillGuideline: 'dark mode with glowing accents',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: 'radial-spotlight-glow',
|
|
144
|
+
category: 'slop',
|
|
145
|
+
name: 'Decorative radial spotlight glow',
|
|
106
146
|
description:
|
|
107
|
-
'
|
|
147
|
+
'A soft, low-opacity accent-colored radial gradient fading to transparent, dropped behind a hero or section as a "spotlight." It is a reflex AI decoration — the translucent cousin of the saturated radial halo. Let the surface stand on its own, or light the composition with a deliberate material accent rather than a floating colored haze.',
|
|
108
148
|
skillSection: 'Color & Contrast',
|
|
109
149
|
skillGuideline: 'dark mode with glowing accents',
|
|
110
150
|
},
|
|
151
|
+
{
|
|
152
|
+
id: 'marquee',
|
|
153
|
+
category: 'slop',
|
|
154
|
+
name: 'Auto-scrolling marquee',
|
|
155
|
+
description:
|
|
156
|
+
'Continuously auto-scrolling content demands attention it has not earned and hides half its content at any moment. Reserve motion for content that changes; let readers move at their own pace.',
|
|
157
|
+
skillSection: 'Motion',
|
|
158
|
+
skillGuideline: 'auto-scrolling marquee',
|
|
159
|
+
},
|
|
111
160
|
{
|
|
112
161
|
id: 'icon-tile-stack',
|
|
113
162
|
category: 'slop',
|
|
163
|
+
scopes: ['layout'],
|
|
114
164
|
name: 'Icon tile stacked above heading',
|
|
115
165
|
description:
|
|
116
166
|
'A small rounded-square icon container above a heading is the universal AI feature-card template — every generator outputs this exact shape. Try a side-by-side icon and heading, or let the icon sit in flow without its own container.',
|
|
@@ -120,6 +170,7 @@ const ANTIPATTERNS = [
|
|
|
120
170
|
{
|
|
121
171
|
id: 'italic-serif-display',
|
|
122
172
|
category: 'slop',
|
|
173
|
+
scopes: ['type'],
|
|
123
174
|
name: 'Italic serif display headline',
|
|
124
175
|
description:
|
|
125
176
|
'Oversized italic serif (Fraunces, Recoleta, Playfair, Newsreader-italic) as the primary hero headline reads as taste in isolation but has become the universal AI-startup landing page hero. Set roman, or move to a non-serif display face. Editorial / magazine register may legitimately want this — judge by context.',
|
|
@@ -129,6 +180,7 @@ const ANTIPATTERNS = [
|
|
|
129
180
|
{
|
|
130
181
|
id: 'hero-eyebrow-chip',
|
|
131
182
|
category: 'slop',
|
|
183
|
+
scopes: ['type'],
|
|
132
184
|
name: 'Hero eyebrow / pill chip',
|
|
133
185
|
description:
|
|
134
186
|
'A tiny uppercase letter-spaced label sitting immediately above an oversized hero headline — or the same shape rendered as a pill chip — is now the default AI SaaS hero. Drop the eyebrow, integrate the kicker into the headline, or run it as a navigation breadcrumb instead.',
|
|
@@ -136,31 +188,37 @@ const ANTIPATTERNS = [
|
|
|
136
188
|
skillGuideline: 'tiny uppercase tracked label above the hero headline',
|
|
137
189
|
},
|
|
138
190
|
{
|
|
139
|
-
id: '
|
|
191
|
+
id: 'kicker-above-heading',
|
|
140
192
|
category: 'slop',
|
|
141
|
-
|
|
142
|
-
name: '
|
|
193
|
+
scopes: ['type'],
|
|
194
|
+
name: 'Kicker / eyebrow label above heading',
|
|
143
195
|
description:
|
|
144
|
-
'
|
|
196
|
+
'A tiny tracked uppercase or small-caps label sitting as its own block directly above a heading is banned outright, repeated or not. Generated kickers never earn their place: the heading carries its own weight. Delete the label and let the heading speak; if the words matter, work them into the heading or the body.',
|
|
145
197
|
skillSection: 'Typography',
|
|
146
|
-
skillGuideline: '
|
|
198
|
+
skillGuideline: 'kicker or eyebrow labels above headings',
|
|
147
199
|
},
|
|
148
200
|
{
|
|
149
|
-
id: 'numbered-section-
|
|
201
|
+
id: 'numbered-section-labels',
|
|
150
202
|
category: 'slop',
|
|
203
|
+
scopes: ['type'],
|
|
151
204
|
severity: 'advisory',
|
|
152
|
-
name: '
|
|
205
|
+
name: 'Tiny numbered section labels',
|
|
153
206
|
description:
|
|
154
|
-
'
|
|
207
|
+
'Small numeric index labels riding next to section headings, repeated section after section, are AI editorial scaffolding — a page numbering its own chapters instead of earning structure. Let hierarchy, content, and rhythm carry the sequence.',
|
|
155
208
|
skillSection: 'Layout & Space',
|
|
156
209
|
skillGuideline: 'numbered section markers',
|
|
157
210
|
},
|
|
158
211
|
{
|
|
159
212
|
id: 'em-dash-overuse',
|
|
160
213
|
category: 'slop',
|
|
214
|
+
// Advisory: humans use em-dashes legitimately, so this rule is opt-in noise
|
|
215
|
+
// rather than a failure. It fires only on the AI saturation pattern, not on
|
|
216
|
+
// ordinary prose. Advisory findings are surfaced separately, never counted
|
|
217
|
+
// as failures, and skipped by the design hook unless a project opts in.
|
|
218
|
+
advisory: true,
|
|
161
219
|
name: 'Em-dash overuse',
|
|
162
220
|
description:
|
|
163
|
-
'
|
|
221
|
+
'Em-dash saturation in body copy is an AI cadence tell. Advisory only: humans use em-dashes legitimately, so this fires only on saturation — at least 8 em-dashes (— or --) at a density near one per 500 characters of body text — never on a long article that uses a few. Prefer commas, colons, periods, or parentheses.',
|
|
164
222
|
skillSection: 'Copy',
|
|
165
223
|
skillGuideline: 'no em dashes',
|
|
166
224
|
},
|
|
@@ -185,6 +243,7 @@ const ANTIPATTERNS = [
|
|
|
185
243
|
{
|
|
186
244
|
id: 'oversized-h1',
|
|
187
245
|
category: 'slop',
|
|
246
|
+
scopes: ['type'],
|
|
188
247
|
name: 'Oversized hero headline',
|
|
189
248
|
description:
|
|
190
249
|
'A full-sentence headline set at display size ends up dominating the viewport, leaving no room for anything else above the fold. A punchy one- or two-word headline at that size is fine — the problem is a long headline blown up too large. Set long headlines smaller, or tighten the copy.',
|
|
@@ -194,6 +253,7 @@ const ANTIPATTERNS = [
|
|
|
194
253
|
{
|
|
195
254
|
id: 'extreme-negative-tracking',
|
|
196
255
|
category: 'slop',
|
|
256
|
+
scopes: ['type'],
|
|
197
257
|
name: 'Crushed letter spacing',
|
|
198
258
|
description:
|
|
199
259
|
'Letter-spacing pulled tighter than the point where characters keep their own shapes costs legibility. Tighten display type optically, not destructively.',
|
|
@@ -211,6 +271,49 @@ const ANTIPATTERNS = [
|
|
|
211
271
|
},
|
|
212
272
|
|
|
213
273
|
// ── Quality: general design and accessibility issues ──
|
|
274
|
+
{
|
|
275
|
+
id: 'script-error',
|
|
276
|
+
category: 'quality',
|
|
277
|
+
severity: 'error',
|
|
278
|
+
name: 'Uncaught script error on load',
|
|
279
|
+
description:
|
|
280
|
+
'A script threw an uncaught exception or failed to parse while the page loaded. Broken JavaScript silently kills reveals, interactions, and dynamic content, and can leave most of a page invisible. Fix the error before judging anything else.',
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
id: 'content-hidden-at-rest',
|
|
284
|
+
category: 'quality',
|
|
285
|
+
severity: 'error',
|
|
286
|
+
scopes: ['layout'],
|
|
287
|
+
name: 'Content invisible at rest',
|
|
288
|
+
description:
|
|
289
|
+
'A large share of the page text sits at opacity 0 or visibility hidden even after every reveal handler had a chance to run. This is the failed-reveal signature: the content shipped but never becomes visible. Make content visible by default and let JavaScript enhance its entrance instead of gating its existence.',
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
id: 'edge-flush-cards',
|
|
293
|
+
category: 'quality',
|
|
294
|
+
scopes: ['layout'],
|
|
295
|
+
name: 'Cards flush against the scroller edge',
|
|
296
|
+
description:
|
|
297
|
+
'Cards inside a horizontal scroller or tab panel sit flush against the container edge at rest while keeping a gutter on the other side, so their edges and rounded corners get cut off. Usually the panel is sized wider than its clip box. Keep a consistent inset on both sides.',
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
id: 'text-occlusion',
|
|
301
|
+
category: 'quality',
|
|
302
|
+
scopes: ['layout'],
|
|
303
|
+
name: 'Text occluded by an overlapping element',
|
|
304
|
+
description:
|
|
305
|
+
'Text is painted under an opaque element or a second text run, so part of it cannot be read. A decorative box, a stacked layer, or an inline element with leaked padding lands on the words instead of beside them. Give overlapping layers room, or move the text out from under the layer above it.',
|
|
306
|
+
skillSection: 'Layout & Space',
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
id: 'first-viewport-column-overflow',
|
|
310
|
+
category: 'quality',
|
|
311
|
+
scopes: ['layout'],
|
|
312
|
+
name: 'One column stretches the first viewport',
|
|
313
|
+
description:
|
|
314
|
+
'A multi-column opening section lets one column run far past the fold while its sibling fits in a single viewport, so the short column floats in dead space and the fold falls deep inside one section. Balance the columns, cap the tall one, or let the long content flow below the opening row.',
|
|
315
|
+
skillSection: 'Layout & Space',
|
|
316
|
+
},
|
|
214
317
|
{
|
|
215
318
|
id: 'gray-on-color',
|
|
216
319
|
category: 'quality',
|
|
@@ -239,6 +342,7 @@ const ANTIPATTERNS = [
|
|
|
239
342
|
{
|
|
240
343
|
id: 'line-length',
|
|
241
344
|
category: 'quality',
|
|
345
|
+
scopes: ['type', 'layout'],
|
|
242
346
|
name: 'Line length too long',
|
|
243
347
|
description:
|
|
244
348
|
'Text lines wider than ~80 characters are hard to read. The eye loses its place tracking back to the start of the next line. Add a max-width (65ch to 75ch) to text containers.',
|
|
@@ -248,6 +352,7 @@ const ANTIPATTERNS = [
|
|
|
248
352
|
{
|
|
249
353
|
id: 'cramped-padding',
|
|
250
354
|
category: 'quality',
|
|
355
|
+
scopes: ['layout'],
|
|
251
356
|
name: 'Cramped padding',
|
|
252
357
|
description:
|
|
253
358
|
'Text is too close to the edge of its container. Two shapes: (1) an element with its own text where the padding is too low for the font size, and (2) a wrapper with text-bearing children and near-zero padding against a visible boundary (border, outline, or non-transparent background) — children land flush against the boundary line. Add at least 8px (ideally 12–16px) of padding inside bordered, outlined, or colored containers.',
|
|
@@ -257,6 +362,7 @@ const ANTIPATTERNS = [
|
|
|
257
362
|
{
|
|
258
363
|
id: 'body-text-viewport-edge',
|
|
259
364
|
category: 'quality',
|
|
365
|
+
scopes: ['layout'],
|
|
260
366
|
name: 'Body text touching viewport edge',
|
|
261
367
|
description:
|
|
262
368
|
'Body paragraphs render flush against the left or right viewport edge with no container providing horizontal padding. Wrap content in a container with at least 16px (ideally 24-32px) of horizontal padding, or apply max-width with mx-auto.',
|
|
@@ -264,6 +370,7 @@ const ANTIPATTERNS = [
|
|
|
264
370
|
{
|
|
265
371
|
id: 'tight-leading',
|
|
266
372
|
category: 'quality',
|
|
373
|
+
scopes: ['type'],
|
|
267
374
|
name: 'Tight line height',
|
|
268
375
|
description:
|
|
269
376
|
'Line height below 1.3x the font size makes multi-line text hard to read. Use 1.5 to 1.7 for body text so lines have room to breathe.',
|
|
@@ -271,13 +378,24 @@ const ANTIPATTERNS = [
|
|
|
271
378
|
{
|
|
272
379
|
id: 'skipped-heading',
|
|
273
380
|
category: 'quality',
|
|
381
|
+
scopes: ['type'],
|
|
274
382
|
name: 'Skipped heading level',
|
|
275
383
|
description:
|
|
276
384
|
'Heading levels should not skip (e.g. h1 then h3 with no h2). Screen readers use heading hierarchy for navigation. Skipping levels breaks the document outline.',
|
|
277
385
|
},
|
|
386
|
+
{
|
|
387
|
+
id: 'heading-rhythm',
|
|
388
|
+
category: 'quality',
|
|
389
|
+
scopes: ['layout', 'type'],
|
|
390
|
+
name: 'Heading crowded against the previous block',
|
|
391
|
+
description:
|
|
392
|
+
'A heading binds to the content it introduces, so the rendered space above it should exceed the space below it. When headings across a page sit as close or closer to the block above than to their own content, every section reads as if it captions the previous one. Open up the space above each heading.',
|
|
393
|
+
skillSection: 'Layout & Space',
|
|
394
|
+
},
|
|
278
395
|
{
|
|
279
396
|
id: 'justified-text',
|
|
280
397
|
category: 'quality',
|
|
398
|
+
scopes: ['type'],
|
|
281
399
|
name: 'Justified text',
|
|
282
400
|
description:
|
|
283
401
|
'Justified text without hyphenation creates uneven word spacing ("rivers of white"). Use text-align: left for body text, or enable hyphens: auto if you must justify.',
|
|
@@ -285,13 +403,23 @@ const ANTIPATTERNS = [
|
|
|
285
403
|
{
|
|
286
404
|
id: 'tiny-text',
|
|
287
405
|
category: 'quality',
|
|
406
|
+
scopes: ['type'],
|
|
288
407
|
name: 'Tiny body text',
|
|
289
408
|
description:
|
|
290
409
|
'Body text below 12px is hard to read, especially on high-DPI screens. Use at least 14px for body content, 16px is ideal.',
|
|
291
410
|
},
|
|
411
|
+
{
|
|
412
|
+
id: 'undersized-ui-text',
|
|
413
|
+
category: 'quality',
|
|
414
|
+
scopes: ['type'],
|
|
415
|
+
name: 'Undersized functional text',
|
|
416
|
+
description:
|
|
417
|
+
'Interactive and content-bearing UI text (links, buttons, nav items, labels, table cells, meta rows, timecodes) below 11px is a legibility failure, not a style choice. WCAG sets no absolute pixel floor, but functional text under 11px is a defensible quality bar: it fails on high-DPI and small viewports and it degrades tap and read targets. The 11px floor holds even inside a footer; only non-interactive legal smallprint gets the softer 10px floor. Being ON the DESIGN.md size ramp does not exempt a value here: adding 8px to the ramp launders the token but not the legibility problem, and that is exactly the escape hatch this rule closes. Exempts sup/sub, visually-hidden (sr-only) text, and code/terminal contexts. Decorative letterspaced micro-labels are still functional and stay in scope.',
|
|
418
|
+
},
|
|
292
419
|
{
|
|
293
420
|
id: 'all-caps-body',
|
|
294
421
|
category: 'quality',
|
|
422
|
+
scopes: ['type'],
|
|
295
423
|
name: 'All-caps body text',
|
|
296
424
|
description:
|
|
297
425
|
'Long passages in uppercase are hard to read. We recognize words by shape (ascenders and descenders), which all-caps removes. Reserve uppercase for short labels and headings.',
|
|
@@ -301,6 +429,7 @@ const ANTIPATTERNS = [
|
|
|
301
429
|
{
|
|
302
430
|
id: 'wide-tracking',
|
|
303
431
|
category: 'quality',
|
|
432
|
+
scopes: ['type'],
|
|
304
433
|
name: 'Wide letter spacing on body text',
|
|
305
434
|
description:
|
|
306
435
|
'Letter spacing above 0.05em on body text disrupts natural character groupings and slows reading. Reserve wide tracking for short uppercase labels only.',
|
|
@@ -308,15 +437,24 @@ const ANTIPATTERNS = [
|
|
|
308
437
|
{
|
|
309
438
|
id: 'text-overflow',
|
|
310
439
|
category: 'quality',
|
|
440
|
+
scopes: ['layout'],
|
|
311
441
|
name: 'Content overflowing its container',
|
|
312
442
|
description:
|
|
313
443
|
'Content renders wider than its container, spilling out or forcing a horizontal scrollbar. Let text wrap, constrain widths, or give the region a deliberate scroll affordance.',
|
|
314
444
|
skillSection: 'Layout & Space',
|
|
315
445
|
skillGuideline: 'content wider than its container',
|
|
316
446
|
},
|
|
447
|
+
{
|
|
448
|
+
id: 'repeated-container-text',
|
|
449
|
+
category: 'quality',
|
|
450
|
+
name: 'Same text repeated inside one container',
|
|
451
|
+
description:
|
|
452
|
+
'The same literal text rendered three or more times in structurally different spots inside a single card or panel is redundant messaging — usually a status or label wired into every slot of a template. Say it once, in the slot where it matters most.',
|
|
453
|
+
},
|
|
317
454
|
{
|
|
318
455
|
id: 'clipped-overflow-container',
|
|
319
456
|
category: 'quality',
|
|
457
|
+
scopes: ['layout'],
|
|
320
458
|
name: 'Positioned child clipped by overflow container',
|
|
321
459
|
description:
|
|
322
460
|
'A clipping container (overflow hidden or clip) wrapping an absolutely-positioned child cuts off tooltips, menus, and popovers that need to escape. Let the overflow be visible, or move the positioned layer out of the clip.',
|
|
@@ -326,6 +464,7 @@ const ANTIPATTERNS = [
|
|
|
326
464
|
{
|
|
327
465
|
id: 'design-system-font',
|
|
328
466
|
category: 'quality',
|
|
467
|
+
scopes: ['type'],
|
|
329
468
|
name: 'Font outside DESIGN.md',
|
|
330
469
|
description:
|
|
331
470
|
'A font is used that is not declared in DESIGN.md typography. Use the documented type system or update DESIGN.md if this is an intentional brand addition.',
|
|
@@ -352,13 +491,23 @@ const ANTIPATTERNS = [
|
|
|
352
491
|
skillSection: 'Visual Details',
|
|
353
492
|
skillGuideline: 'border radius outside the project design system',
|
|
354
493
|
},
|
|
494
|
+
{
|
|
495
|
+
id: 'design-system-font-size',
|
|
496
|
+
category: 'quality',
|
|
497
|
+
severity: 'advisory',
|
|
498
|
+
scopes: ['type'],
|
|
499
|
+
name: 'Font size outside DESIGN.md',
|
|
500
|
+
description:
|
|
501
|
+
'A literal font-size is off the type ramp documented in DESIGN.md typography. Use a documented size step or update the design system if the new step is intentional.',
|
|
502
|
+
skillSection: 'Typography',
|
|
503
|
+
skillGuideline: 'font size outside the project design system',
|
|
504
|
+
},
|
|
355
505
|
|
|
356
|
-
// ──
|
|
506
|
+
// ── Common generated-UI tells ───────────────────────────────────────────
|
|
357
507
|
{
|
|
358
508
|
id: 'gpt-thin-border-wide-shadow',
|
|
359
509
|
category: 'slop',
|
|
360
510
|
severity: 'advisory',
|
|
361
|
-
gated: 'gpt',
|
|
362
511
|
name: 'Hairline border with wide shadow',
|
|
363
512
|
description:
|
|
364
513
|
'A hairline border paired with a wide, diffuse shadow is a recurring generated-UI signature. Commit to one — a defined edge or a soft elevation — rather than both at once.',
|
|
@@ -369,18 +518,26 @@ const ANTIPATTERNS = [
|
|
|
369
518
|
id: 'repeating-stripes-gradient',
|
|
370
519
|
category: 'slop',
|
|
371
520
|
severity: 'advisory',
|
|
372
|
-
gated: 'gpt',
|
|
373
521
|
name: 'Repeating-gradient stripes',
|
|
374
522
|
description:
|
|
375
523
|
'Repeating-gradient stripes used as surface decoration are a recurring generated-UI signature. Reach for a deliberate texture or leave the surface plain.',
|
|
376
524
|
skillSection: 'Visual Details',
|
|
377
525
|
skillGuideline: 'repeating-gradient decorative stripes',
|
|
378
526
|
},
|
|
527
|
+
{
|
|
528
|
+
id: 'codex-grid-background',
|
|
529
|
+
category: 'slop',
|
|
530
|
+
severity: 'advisory',
|
|
531
|
+
name: 'Decorative grid-line background',
|
|
532
|
+
description:
|
|
533
|
+
'A decorative grid or line-field background drawn with hairline linear-gradient layers tiled by a fixed pixel cell is a recurring generated-UI signature. Reserve grid overlays for actual canvas, map, blueprint, or measurement surfaces; elsewhere use product structure or a plain surface.',
|
|
534
|
+
skillSection: 'Visual Details',
|
|
535
|
+
skillGuideline: 'two-axis grid-line gradient background',
|
|
536
|
+
},
|
|
379
537
|
{
|
|
380
538
|
id: 'theater-slop-phrase',
|
|
381
539
|
category: 'slop',
|
|
382
540
|
severity: 'advisory',
|
|
383
|
-
gated: 'gpt',
|
|
384
541
|
name: 'Theater framing copy',
|
|
385
542
|
description:
|
|
386
543
|
'Dismissing something as "theater" is a recurring generated-copy tic. Say plainly what the thing does or does not do.',
|
|
@@ -391,7 +548,6 @@ const ANTIPATTERNS = [
|
|
|
391
548
|
id: 'image-hover-transform',
|
|
392
549
|
category: 'slop',
|
|
393
550
|
severity: 'advisory',
|
|
394
|
-
gated: 'gemini',
|
|
395
551
|
name: 'Image hover transform',
|
|
396
552
|
description:
|
|
397
553
|
'Scaling or rotating an image on hover is a recurring generated-UI signature. Let imagery sit still, or use a subtler, purposeful interaction.',
|
|
@@ -411,6 +567,18 @@ function getAntipattern(id) {
|
|
|
411
567
|
return ANTIPATTERNS.find(rule => rule.id === id);
|
|
412
568
|
}
|
|
413
569
|
|
|
570
|
+
// Advisory rules are detected and reported, but never treated as failures:
|
|
571
|
+
// the CLI lists them under a separate "Advisory" section, they do not affect
|
|
572
|
+
// exit codes or the failure count, and the design hook skips them by default.
|
|
573
|
+
// The set is derived from the registry so a rule only needs `advisory: true`.
|
|
574
|
+
const ADVISORY_RULE_IDS = new Set(
|
|
575
|
+
ANTIPATTERNS.filter(rule => rule.advisory === true).map(rule => rule.id),
|
|
576
|
+
);
|
|
577
|
+
|
|
578
|
+
function isAdvisoryRule(id) {
|
|
579
|
+
return ADVISORY_RULE_IDS.has(id);
|
|
580
|
+
}
|
|
581
|
+
|
|
414
582
|
function getRulesForCategory(category) {
|
|
415
583
|
return ANTIPATTERNS.filter(rule => rule.category === category);
|
|
416
584
|
}
|
|
@@ -419,30 +587,31 @@ function getRuleEngineSupport(engine) {
|
|
|
419
587
|
return RULE_ENGINE_SUPPORT[engine] || new Set();
|
|
420
588
|
}
|
|
421
589
|
|
|
422
|
-
// Set of
|
|
423
|
-
|
|
424
|
-
|
|
590
|
+
// Set of scope tags rules can declare (e.g. 'type', 'layout'). Used by the
|
|
591
|
+
// CLI --scope flag to narrow output to one design domain.
|
|
592
|
+
const RULE_SCOPES = new Set(
|
|
593
|
+
ANTIPATTERNS.flatMap(rule => rule.scopes || []),
|
|
425
594
|
);
|
|
426
595
|
|
|
427
|
-
//
|
|
428
|
-
//
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const enabled = new Set(
|
|
432
|
-
if (!GATED_PROVIDERS.size) return findings;
|
|
596
|
+
// Keep only findings whose rule declares at least one of the requested
|
|
597
|
+
// scopes. An empty scope list means no filtering (default CLI behavior).
|
|
598
|
+
function filterByScopes(findings, scopes = []) {
|
|
599
|
+
if (!scopes || scopes.length === 0) return findings;
|
|
600
|
+
const enabled = new Set(scopes);
|
|
433
601
|
return findings.filter(f => {
|
|
434
602
|
const rule = getAntipattern(f.antipattern);
|
|
435
|
-
|
|
436
|
-
return enabled.has(rule.gated);
|
|
603
|
+
return (rule?.scopes || []).some(scope => enabled.has(scope));
|
|
437
604
|
});
|
|
438
605
|
}
|
|
439
606
|
|
|
440
607
|
export {
|
|
441
608
|
ANTIPATTERNS,
|
|
609
|
+
RULE_SCOPES,
|
|
442
610
|
RULE_ENGINE_SUPPORT,
|
|
443
|
-
|
|
611
|
+
ADVISORY_RULE_IDS,
|
|
444
612
|
getAntipattern,
|
|
445
613
|
getRulesForCategory,
|
|
446
614
|
getRuleEngineSupport,
|
|
447
|
-
|
|
615
|
+
isAdvisoryRule,
|
|
616
|
+
filterByScopes,
|
|
448
617
|
};
|