oh-my-opencode 5.1.51 → 5.1.55
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/dist/agents/atlas/agent.d.ts +5 -5
- package/dist/agents/dynamic-agent-core-sections.d.ts +0 -1
- package/dist/agents/dynamic-agent-prompt-builder.d.ts +1 -1
- package/dist/agents/gpt-apply-patch-guard.d.ts +0 -1
- package/dist/agents/hephaestus/agent.d.ts +3 -7
- package/dist/agents/hephaestus/model-support.d.ts +6 -0
- package/dist/agents/metis.d.ts +0 -15
- package/dist/agents/native-model-prompt.d.ts +9 -0
- package/dist/agents/native-prompt-frame.d.ts +20 -0
- package/dist/agents/native-tool-snippet.d.ts +6 -0
- package/dist/agents/sisyphus/default.d.ts +0 -1
- package/dist/agents/sisyphus-agent-factory.d.ts +2 -11
- package/dist/agents/sisyphus-junior/agent.d.ts +2 -20
- package/dist/agents/sisyphus-junior/index.d.ts +1 -11
- package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +6 -0
- package/dist/agents/types.d.ts +2 -2
- package/dist/cli/index.js +1174 -394
- package/dist/cli/service-auth/credential-lock.d.ts +11 -0
- package/dist/cli/service-auth/credential-owner.d.ts +10 -0
- package/dist/cli/service-auth/index.d.ts +3 -1
- package/dist/cli/service-auth/keystore.d.ts +8 -1
- package/dist/cli/service-auth/owned-refresh.d.ts +21 -0
- package/dist/cli/service-auth/protocol-v2.d.ts +27 -0
- package/dist/cli/service-auth/protocol.d.ts +26 -2
- package/dist/cli/service-auth/recovery-clock.d.ts +7 -0
- package/dist/cli/service-auth/refresh-attempt.d.ts +34 -0
- package/dist/cli/service-auth/session.d.ts +9 -2
- package/dist/cli-node/index.js +1174 -394
- package/dist/config/schema/agent-overrides.d.ts +64 -0
- package/dist/config/schema/categories.d.ts +8 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +64 -0
- package/dist/hooks/native-edition-nudge/hook.d.ts +3 -4
- package/dist/index.js +15625 -8841
- package/dist/oh-my-opencode.schema.json +112 -0
- package/dist/plugin/session-tool-permissions.d.ts +10 -0
- package/dist/plugin/system-transform.d.ts +2 -1
- package/dist/plugin/tool-definition.d.ts +1 -0
- package/dist/shared/bun-ffi-shim.d.ts +29 -0
- package/dist/shared/json-file-cache-store.d.ts +11 -0
- package/dist/skills/browser/runtime/omowright/index.js +24 -33
- package/dist/skills/browser/runtime/omowright/manifest.json +3 -3
- package/dist/skills/frontend/ATTRIBUTION.md +104 -1
- package/dist/skills/frontend/SKILL.md +7 -3
- package/dist/skills/frontend/references/design/design-system-architecture.md +3 -3
- package/dist/skills/frontend/references/perfection/craft-floor.md +59 -0
- package/dist/skills/frontend/references/perfection/detect.md +52 -0
- package/dist/skills/frontend/scripts/detect/cli.ts +70 -0
- package/dist/skills/frontend/scripts/detect/config.test.ts +26 -0
- package/dist/skills/frontend/scripts/detect/config.ts +53 -0
- package/dist/skills/frontend/scripts/detect/core/characters.ts +2 -0
- package/dist/skills/frontend/scripts/detect/core/color.test.ts +29 -0
- package/dist/skills/frontend/scripts/detect/core/color.ts +150 -0
- package/dist/skills/frontend/scripts/detect/core/page.ts +84 -0
- package/dist/skills/frontend/scripts/detect/core/shadow.ts +40 -0
- package/dist/skills/frontend/scripts/detect/core/source.ts +33 -0
- package/dist/skills/frontend/scripts/detect/detect.ts +77 -0
- package/dist/skills/frontend/scripts/detect/index.ts +23 -0
- package/dist/skills/frontend/scripts/detect/lint.test.ts +27 -0
- package/dist/skills/frontend/scripts/detect/lint.ts +98 -0
- package/dist/skills/frontend/scripts/detect/render/probe-placement.test.ts +19 -0
- package/dist/skills/frontend/scripts/detect/render/probe-placement.ts +50 -0
- package/dist/skills/frontend/scripts/detect/render/renderer.ts +37 -0
- package/dist/skills/frontend/scripts/detect/render/webview.ts +71 -0
- package/dist/skills/frontend/scripts/detect/report.ts +29 -0
- package/dist/skills/frontend/scripts/detect/rule.ts +42 -0
- package/dist/skills/frontend/scripts/detect/rules/color/ai-color-palette.test.ts +74 -0
- package/dist/skills/frontend/scripts/detect/rules/color/ai-color-palette.ts +83 -0
- package/dist/skills/frontend/scripts/detect/rules/color/cream-palette.test.ts +24 -0
- package/dist/skills/frontend/scripts/detect/rules/color/cream-palette.ts +35 -0
- package/dist/skills/frontend/scripts/detect/rules/color/dark-glow.test.ts +47 -0
- package/dist/skills/frontend/scripts/detect/rules/color/dark-glow.ts +44 -0
- package/dist/skills/frontend/scripts/detect/rules/color/design-system-color.test.ts +26 -0
- package/dist/skills/frontend/scripts/detect/rules/color/design-system-color.ts +35 -0
- package/dist/skills/frontend/scripts/detect/rules/color/gradient-text.test.ts +24 -0
- package/dist/skills/frontend/scripts/detect/rules/color/gradient-text.ts +59 -0
- package/dist/skills/frontend/scripts/detect/rules/color/gray-on-color.test.ts +39 -0
- package/dist/skills/frontend/scripts/detect/rules/color/gray-on-color.ts +38 -0
- package/dist/skills/frontend/scripts/detect/rules/color/index.ts +15 -0
- package/dist/skills/frontend/scripts/detect/rules/color/low-contrast.test.ts +209 -0
- package/dist/skills/frontend/scripts/detect/rules/color/low-contrast.ts +57 -0
- package/dist/skills/frontend/scripts/detect/rules/color/placeholder-contrast.test.ts +62 -0
- package/dist/skills/frontend/scripts/detect/rules/color/radial-halo.test.ts +40 -0
- package/dist/skills/frontend/scripts/detect/rules/color/radial-halo.ts +31 -0
- package/dist/skills/frontend/scripts/detect/rules/color/radial-spotlight-glow.test.ts +27 -0
- package/dist/skills/frontend/scripts/detect/rules/color/radial-spotlight-glow.ts +33 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/animation-opacity.ts +78 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/color-path.ts +15 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/contrast-pairs.ts +54 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/contrast-role.ts +76 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/glow-forms.ts +56 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/gradient-samples.ts +134 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/gradients.ts +91 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/mockup-roots.ts +63 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/page-ignore.ts +7 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/painted-text.ts +141 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/palette-roles.ts +58 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/placeholder-contrast.ts +25 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/stock-accent.ts +31 -0
- package/dist/skills/frontend/scripts/detect/rules/color/support/text-colors.ts +80 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/aphoristic-cadence.test.ts +18 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/aphoristic-cadence.ts +20 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/broken-image.test.ts +25 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/broken-image.ts +17 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/em-dash-overuse.test.ts +39 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/em-dash-overuse.ts +46 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/index.ts +15 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/marketing-buzzword.test.ts +18 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/marketing-buzzword.ts +33 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/numbered-section-labels.test.ts +58 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/numbered-section-labels.ts +34 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/repeated-container-text.test.ts +43 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/repeated-container-text.ts +56 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/script-error.test.ts +48 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/script-error.ts +38 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/skipped-heading.test.ts +49 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/skipped-heading.ts +81 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/support/numbered-label.ts +94 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/support/page-text.ts +37 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/theater-slop-phrase.test.ts +17 -0
- package/dist/skills/frontend/scripts/detect/rules/copy/theater-slop-phrase.ts +21 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/blinking-cursor.test.ts +43 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/blinking-cursor.ts +48 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/border-accent-on-rounded.test.ts +33 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/border-accent-on-rounded.ts +14 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/bounce-easing.test.ts +72 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/bounce-easing.ts +83 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/buried-raster.test.ts +95 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/buried-raster.ts +72 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/codex-grid-background.test.ts +28 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/codex-grid-background.ts +34 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/design-system-radius.test.ts +37 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/design-system-radius.ts +31 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/gpt-thin-border-wide-shadow.test.ts +59 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/gpt-thin-border-wide-shadow.ts +66 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/hard-offset-shadow.test.ts +45 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/hard-offset-shadow.ts +31 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/hero-eyebrow-chip.test.ts +76 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/hero-eyebrow-chip.ts +19 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/icon-tile-stack.test.ts +67 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/icon-tile-stack.ts +92 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/index.ts +38 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/kicker-above-heading.test.ts +126 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/kicker-above-heading.ts +69 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/marquee.test.ts +63 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/marquee.ts +51 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/organic-clip-path.test.ts +67 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/organic-clip-path.ts +41 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/pulsing-dot.test.ts +58 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/pulsing-dot.ts +72 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/repeating-stripes-gradient.test.ts +26 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/repeating-stripes-gradient.ts +25 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/shape-assembled-illustration.test.ts +59 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/shape-assembled-illustration.ts +58 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/side-tab.test.ts +91 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/side-tab.ts +17 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/support/appearance.ts +110 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/support/assert-cases.ts +25 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/support/borders.ts +150 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/support/clip-geometry.ts +151 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/support/css-candidates.ts +66 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/support/curve-samples.ts +55 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/support/gradient-pattern.ts +40 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/support/keyframes.ts +134 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/support/labels.ts +85 -0
- package/dist/skills/frontend/scripts/detect/rules/decoration/support/raster-state.ts +51 -0
- package/dist/skills/frontend/scripts/detect/rules/index.ts +16 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/body-text-viewport-edge.test.ts +64 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/body-text-viewport-edge.ts +62 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/clipped-overflow-container.test.ts +40 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/clipped-overflow-container.ts +15 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/content-hidden-at-rest.test.ts +62 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/content-hidden-at-rest.ts +63 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/cramped-padding.test.ts +61 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/cramped-padding.ts +97 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/edge-flush-cards.test.ts +43 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/edge-flush-cards.ts +47 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/first-viewport-column-overflow.test.ts +28 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/first-viewport-column-overflow.ts +43 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/heading-rhythm.test.ts +67 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/heading-rhythm.ts +30 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/index.ts +21 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/monotonous-spacing.test.ts +19 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/monotonous-spacing.ts +32 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/nested-cards.test.ts +60 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/nested-cards.ts +38 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/straggler.test.ts +33 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/straggler.ts +28 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/support/cards.ts +114 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/support/clipping.ts +71 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/support/declared-mockups.ts +46 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/support/geometry.ts +73 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/support/hidden-interface.ts +35 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/support/layout-cases.ts +23 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/support/line-breaks.ts +32 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/support/motion.ts +77 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/support/padding.ts +93 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/support/rhythm.ts +161 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/text-occlusion.test.ts +37 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/text-occlusion.ts +84 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/text-overflow.test.ts +83 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/text-overflow.ts +72 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/unbalanced-heading.test.ts +22 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/unbalanced-heading.ts +22 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/viewport-reflow.test.ts +34 -0
- package/dist/skills/frontend/scripts/detect/rules/layout/viewport-reflow.ts +33 -0
- package/dist/skills/frontend/scripts/detect/rules/source/ai-color-palette.test.ts +13 -0
- package/dist/skills/frontend/scripts/detect/rules/source/ai-color-palette.ts +11 -0
- package/dist/skills/frontend/scripts/detect/rules/source/aphoristic-cadence.test.ts +12 -0
- package/dist/skills/frontend/scripts/detect/rules/source/aphoristic-cadence.ts +14 -0
- package/dist/skills/frontend/scripts/detect/rules/source/border-accent-on-rounded.test.ts +14 -0
- package/dist/skills/frontend/scripts/detect/rules/source/border-accent-on-rounded.ts +20 -0
- package/dist/skills/frontend/scripts/detect/rules/source/bounce-easing.test.ts +19 -0
- package/dist/skills/frontend/scripts/detect/rules/source/bounce-easing.ts +21 -0
- package/dist/skills/frontend/scripts/detect/rules/source/broken-image.test.ts +27 -0
- package/dist/skills/frontend/scripts/detect/rules/source/broken-image.ts +16 -0
- package/dist/skills/frontend/scripts/detect/rules/source/codex-grid-background.test.ts +11 -0
- package/dist/skills/frontend/scripts/detect/rules/source/codex-grid-background.ts +18 -0
- package/dist/skills/frontend/scripts/detect/rules/source/dark-glow.test.ts +15 -0
- package/dist/skills/frontend/scripts/detect/rules/source/dark-glow.ts +21 -0
- package/dist/skills/frontend/scripts/detect/rules/source/em-dash-overuse.test.ts +13 -0
- package/dist/skills/frontend/scripts/detect/rules/source/em-dash-overuse.ts +15 -0
- package/dist/skills/frontend/scripts/detect/rules/source/gradient-text.test.ts +12 -0
- package/dist/skills/frontend/scripts/detect/rules/source/gradient-text.ts +11 -0
- package/dist/skills/frontend/scripts/detect/rules/source/gray-on-color.test.ts +20 -0
- package/dist/skills/frontend/scripts/detect/rules/source/gray-on-color.ts +13 -0
- package/dist/skills/frontend/scripts/detect/rules/source/index.ts +19 -0
- package/dist/skills/frontend/scripts/detect/rules/source/marketing-buzzword.test.ts +12 -0
- package/dist/skills/frontend/scripts/detect/rules/source/marketing-buzzword.ts +17 -0
- package/dist/skills/frontend/scripts/detect/rules/source/marquee.test.ts +12 -0
- package/dist/skills/frontend/scripts/detect/rules/source/marquee.ts +12 -0
- package/dist/skills/frontend/scripts/detect/rules/source/monotonous-spacing.test.ts +13 -0
- package/dist/skills/frontend/scripts/detect/rules/source/monotonous-spacing.ts +22 -0
- package/dist/skills/frontend/scripts/detect/rules/source/overused-font.test.ts +21 -0
- package/dist/skills/frontend/scripts/detect/rules/source/overused-font.ts +16 -0
- package/dist/skills/frontend/scripts/detect/rules/source/radial-halo.test.ts +16 -0
- package/dist/skills/frontend/scripts/detect/rules/source/radial-halo.ts +14 -0
- package/dist/skills/frontend/scripts/detect/rules/source/side-tab.test.ts +29 -0
- package/dist/skills/frontend/scripts/detect/rules/source/side-tab.ts +58 -0
- package/dist/skills/frontend/scripts/detect/rules/source/support/accent-scans.ts +78 -0
- package/dist/skills/frontend/scripts/detect/rules/source/support/check-source.ts +6 -0
- package/dist/skills/frontend/scripts/detect/rules/source/support/corners.ts +105 -0
- package/dist/skills/frontend/scripts/detect/rules/source/support/css-effects.ts +81 -0
- package/dist/skills/frontend/scripts/detect/rules/source/support/css-scopes.ts +131 -0
- package/dist/skills/frontend/scripts/detect/rules/source/support/image-tags.ts +113 -0
- package/dist/skills/frontend/scripts/detect/rules/source/support/js-punctuation.ts +34 -0
- package/dist/skills/frontend/scripts/detect/rules/source/support/markup-scope.ts +44 -0
- package/dist/skills/frontend/scripts/detect/rules/source/support/source-color.ts +42 -0
- package/dist/skills/frontend/scripts/detect/rules/source/support/source-shadow.ts +15 -0
- package/dist/skills/frontend/scripts/detect/rules/source/support/source-text.ts +110 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/all-caps-body.test.ts +24 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/all-caps-body.ts +15 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/design-system-font-size.test.ts +21 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/design-system-font-size.ts +23 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/design-system-font.test.ts +22 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/design-system-font.ts +24 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/extreme-negative-tracking.test.ts +23 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/extreme-negative-tracking.ts +18 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/flat-type-hierarchy.test.ts +33 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/flat-type-hierarchy.ts +26 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/index.ts +21 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/italic-serif-display.test.ts +24 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/italic-serif-display.ts +24 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/justified-text.test.ts +31 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/justified-text.ts +32 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/line-length.test.ts +43 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/line-length.ts +28 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/oversized-h1.test.ts +26 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/oversized-h1.ts +20 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/overused-font.test.ts +35 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/overused-font.ts +45 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/support/drawn-enlargement.ts +48 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/support/fading-text.ts +48 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/support/flex-runs.ts +16 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/support/font-family.ts +28 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/support/painted-text.test.ts +63 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/support/painted-text.ts +81 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/support/svg-size.ts +57 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/support/text-context.ts +112 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/support/text-lines.ts +43 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/support/type-hierarchy.ts +48 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/tight-leading.test.ts +54 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/tight-leading.ts +47 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/tiny-text.test.ts +60 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/tiny-text.ts +23 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/undersized-ui-text.test.ts +98 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/undersized-ui-text.ts +28 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/wide-tracking.test.ts +26 -0
- package/dist/skills/frontend/scripts/detect/rules/typography/wide-tracking.ts +26 -0
- package/dist/skills/frontend/scripts/detect/snapshot/collect.ts +158 -0
- package/dist/skills/frontend/scripts/detect/snapshot/style-props.ts +25 -0
- package/dist/skills/frontend/scripts/detect/testing/build-snapshot.ts +78 -0
- package/dist/skills/frontend/scripts/detect/tsconfig.json +19 -0
- package/dist/skills/frontend/scripts/detect/types.ts +124 -0
- package/dist/skills/programming/SKILL.md +17 -74
- package/dist/skills/programming/references/go/README.md +1 -1
- package/dist/skills/programming/references/go/bootstrap.md +2 -2
- package/dist/skills/programming/references/python/README.md +4 -4
- package/dist/skills/programming/references/python/one-liners.md +5 -5
- package/dist/skills/programming/references/testing/README.md +82 -0
- package/dist/skills/programming/references/testing/junk-classes.md +56 -0
- package/dist/skills/programming/references/typescript/README.md +1 -2
- package/dist/skills/programming/scripts/go/new-project.ts +197 -0
- package/dist/skills/programming/scripts/python/new-project.ts +231 -0
- package/dist/skills/programming/scripts/python/new-script.ts +134 -0
- package/dist/skills/programming/scripts/rust/new-project.ts +215 -0
- package/dist/skills/programming/scripts/scaffolders.test.ts +96 -0
- package/dist/skills/programming/scripts/shared/run-tool.ts +19 -0
- package/dist/skills/programming/scripts/typescript/check-test-junk-rules.ts +140 -0
- package/dist/skills/programming/scripts/typescript/check-test-junk.test.ts +125 -0
- package/dist/skills/programming/scripts/typescript/check-test-junk.ts +148 -0
- package/dist/skills/programming/scripts/typescript/mutation-proof.test.ts +43 -0
- package/dist/skills/programming/scripts/typescript/mutation-proof.ts +179 -0
- package/dist/skills/remove-ai-slops/SKILL.md +32 -20
- package/dist/skills/ulw-research/scripts/source-commands.mjs +3 -1
- package/dist/skills/ulw-research/scripts/source-integrity.test.ts +39 -2
- package/dist/skills/visual-qa/SKILL.md +12 -1
- package/dist/tools/delegate-task/models-distribution.d.ts +1 -0
- package/dist/tui.js +142 -42
- package/package.json +22 -19
- package/packages/lsp-core/src/lsp/config-loader.ts +18 -2
- package/packages/lsp-core/src/lsp/host-js-runtime.test.ts +150 -0
- package/packages/lsp-core/src/lsp/host-js-runtime.ts +57 -0
- package/packages/lsp-core/src/lsp/server-definitions.ts +10 -0
- package/packages/lsp-core/src/lsp/server-resolution.ts +9 -1
- package/packages/lsp-core/src/lsp/typescript-server-defaults.test.ts +84 -0
- package/packages/lsp-daemon/dist/cli.js +81 -15
- package/packages/lsp-daemon/dist/client.js +74 -8
- package/packages/lsp-daemon/dist/index.js +76 -10
- package/packages/lsp-tools-mcp/dist/cli.js +74 -8
- package/packages/lsp-tools-mcp/dist/mcp.js +74 -8
- package/packages/lsp-tools-mcp/dist/tools.js +74 -8
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +22 -4
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +77 -13
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +34 -2
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +34 -2
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/test/codex-hook.test.ts +14 -1
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +12 -12
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +16 -1
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/index.js +24 -33
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +3 -3
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +104 -1
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +7 -3
- package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +3 -3
- package/packages/omo-codex/plugin/skills/frontend/references/perfection/craft-floor.md +59 -0
- package/packages/omo-codex/plugin/skills/frontend/references/perfection/detect.md +52 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/cli.ts +70 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/config.ts +53 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/core/characters.ts +2 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/core/color.ts +150 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/core/page.ts +84 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/core/shadow.ts +40 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/core/source.ts +33 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/detect.ts +77 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/index.ts +23 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/lint.ts +98 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/render/probe-placement.ts +50 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/render/renderer.ts +37 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/render/webview.ts +71 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/report.ts +29 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rule.ts +42 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/ai-color-palette.ts +83 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/cream-palette.ts +35 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/dark-glow.ts +44 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/design-system-color.ts +35 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/gradient-text.ts +59 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/gray-on-color.ts +38 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/index.ts +15 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/low-contrast.ts +57 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/radial-halo.ts +31 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/radial-spotlight-glow.ts +33 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/animation-opacity.ts +78 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/color-path.ts +15 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/contrast-pairs.ts +54 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/contrast-role.ts +76 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/glow-forms.ts +56 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/gradient-samples.ts +134 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/gradients.ts +91 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/mockup-roots.ts +63 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/page-ignore.ts +7 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/painted-text.ts +141 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/palette-roles.ts +58 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/placeholder-contrast.ts +25 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/stock-accent.ts +31 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/text-colors.ts +80 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/aphoristic-cadence.ts +20 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/broken-image.ts +17 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/em-dash-overuse.ts +46 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/index.ts +15 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/marketing-buzzword.ts +33 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/numbered-section-labels.ts +34 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/repeated-container-text.ts +56 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/script-error.ts +38 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/skipped-heading.ts +81 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/support/numbered-label.ts +94 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/support/page-text.ts +37 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/theater-slop-phrase.ts +21 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/blinking-cursor.ts +48 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/border-accent-on-rounded.ts +14 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/bounce-easing.ts +83 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/buried-raster.ts +72 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/codex-grid-background.ts +34 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/design-system-radius.ts +31 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/gpt-thin-border-wide-shadow.ts +66 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/hard-offset-shadow.ts +31 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/hero-eyebrow-chip.ts +19 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/icon-tile-stack.ts +92 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/index.ts +38 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/kicker-above-heading.ts +69 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/marquee.ts +51 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/organic-clip-path.ts +41 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/pulsing-dot.ts +72 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/repeating-stripes-gradient.ts +25 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/shape-assembled-illustration.ts +58 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/side-tab.ts +17 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/appearance.ts +110 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/assert-cases.ts +25 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/borders.ts +150 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/clip-geometry.ts +151 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/css-candidates.ts +66 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/curve-samples.ts +55 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/gradient-pattern.ts +40 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/keyframes.ts +134 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/labels.ts +85 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/raster-state.ts +51 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/index.ts +16 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/body-text-viewport-edge.ts +62 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/clipped-overflow-container.ts +15 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/content-hidden-at-rest.ts +63 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/cramped-padding.ts +97 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/edge-flush-cards.ts +47 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/first-viewport-column-overflow.ts +43 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/heading-rhythm.ts +30 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/index.ts +21 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/monotonous-spacing.ts +32 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/nested-cards.ts +38 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/straggler.ts +28 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/cards.ts +114 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/clipping.ts +71 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/declared-mockups.ts +46 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/geometry.ts +73 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/hidden-interface.ts +35 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/layout-cases.ts +23 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/line-breaks.ts +32 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/motion.ts +77 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/padding.ts +93 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/rhythm.ts +161 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/text-occlusion.ts +84 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/text-overflow.ts +72 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/unbalanced-heading.ts +22 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/viewport-reflow.ts +33 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/ai-color-palette.ts +11 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/aphoristic-cadence.ts +14 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/border-accent-on-rounded.ts +20 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/bounce-easing.ts +21 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/broken-image.ts +16 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/codex-grid-background.ts +18 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/dark-glow.ts +21 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/em-dash-overuse.ts +15 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/gradient-text.ts +11 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/gray-on-color.ts +13 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/index.ts +19 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/marketing-buzzword.ts +17 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/marquee.ts +12 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/monotonous-spacing.ts +22 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/overused-font.ts +16 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/radial-halo.ts +14 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/side-tab.ts +58 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/accent-scans.ts +78 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/check-source.ts +6 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/corners.ts +105 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/css-effects.ts +81 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/css-scopes.ts +131 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/image-tags.ts +113 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/js-punctuation.ts +34 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/markup-scope.ts +44 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/source-color.ts +42 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/source-shadow.ts +15 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/source-text.ts +110 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/all-caps-body.ts +15 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/design-system-font-size.ts +23 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/design-system-font.ts +24 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/extreme-negative-tracking.ts +18 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/flat-type-hierarchy.ts +26 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/index.ts +21 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/italic-serif-display.ts +24 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/justified-text.ts +32 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/line-length.ts +28 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/oversized-h1.ts +20 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/overused-font.ts +45 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/drawn-enlargement.ts +48 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/fading-text.ts +48 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/flex-runs.ts +16 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/font-family.ts +28 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/painted-text.ts +81 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/svg-size.ts +57 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/text-context.ts +112 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/text-lines.ts +43 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/type-hierarchy.ts +48 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/tight-leading.ts +47 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/tiny-text.ts +23 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/undersized-ui-text.ts +28 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/wide-tracking.ts +26 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/snapshot/collect.ts +158 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/snapshot/style-props.ts +25 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/testing/build-snapshot.ts +78 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/tsconfig.json +19 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/detect/types.ts +124 -0
- package/packages/omo-codex/plugin/skills/programming/SKILL.md +17 -74
- package/packages/omo-codex/plugin/skills/programming/references/go/README.md +1 -1
- package/packages/omo-codex/plugin/skills/programming/references/go/bootstrap.md +2 -2
- package/packages/omo-codex/plugin/skills/programming/references/python/README.md +4 -4
- package/packages/omo-codex/plugin/skills/programming/references/python/one-liners.md +5 -5
- package/packages/omo-codex/plugin/skills/programming/references/testing/README.md +82 -0
- package/packages/omo-codex/plugin/skills/programming/references/testing/junk-classes.md +56 -0
- package/packages/omo-codex/plugin/skills/programming/references/typescript/README.md +1 -2
- package/packages/omo-codex/plugin/skills/programming/scripts/go/new-project.ts +197 -0
- package/packages/omo-codex/plugin/skills/programming/scripts/python/new-project.ts +231 -0
- package/packages/omo-codex/plugin/skills/programming/scripts/python/new-script.ts +134 -0
- package/packages/omo-codex/plugin/skills/programming/scripts/rust/new-project.ts +215 -0
- package/packages/omo-codex/plugin/skills/programming/scripts/shared/run-tool.ts +19 -0
- package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-test-junk-rules.ts +140 -0
- package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-test-junk.ts +148 -0
- package/packages/omo-codex/plugin/skills/programming/scripts/typescript/mutation-proof.ts +179 -0
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +32 -20
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-commands.mjs +3 -1
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +12 -1
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +62 -0
- package/packages/omo-codex/plugin/test/payload-equivalence.test.mjs +12 -2
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +79 -10
- package/packages/shared-skills/skills/browser/runtime/omowright/index.js +24 -33
- package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +3 -3
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +104 -1
- package/packages/shared-skills/skills/frontend/SKILL.md +7 -3
- package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +3 -3
- package/packages/shared-skills/skills/frontend/references/perfection/craft-floor.md +59 -0
- package/packages/shared-skills/skills/frontend/references/perfection/detect.md +52 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/cli.ts +70 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/config.test.ts +26 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/config.ts +53 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/core/characters.ts +2 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/core/color.test.ts +29 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/core/color.ts +150 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/core/page.ts +84 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/core/shadow.ts +40 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/core/source.ts +33 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/detect.ts +77 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/index.ts +23 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/lint.test.ts +27 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/lint.ts +98 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/render/probe-placement.test.ts +19 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/render/probe-placement.ts +50 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/render/renderer.ts +37 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/render/webview.ts +71 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/report.ts +29 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rule.ts +42 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/ai-color-palette.test.ts +74 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/ai-color-palette.ts +83 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/cream-palette.test.ts +24 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/cream-palette.ts +35 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/dark-glow.test.ts +47 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/dark-glow.ts +44 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/design-system-color.test.ts +26 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/design-system-color.ts +35 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/gradient-text.test.ts +24 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/gradient-text.ts +59 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/gray-on-color.test.ts +39 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/gray-on-color.ts +38 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/index.ts +15 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/low-contrast.test.ts +209 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/low-contrast.ts +57 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/placeholder-contrast.test.ts +62 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/radial-halo.test.ts +40 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/radial-halo.ts +31 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/radial-spotlight-glow.test.ts +27 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/radial-spotlight-glow.ts +33 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/animation-opacity.ts +78 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/color-path.ts +15 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/contrast-pairs.ts +54 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/contrast-role.ts +76 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/glow-forms.ts +56 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/gradient-samples.ts +134 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/gradients.ts +91 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/mockup-roots.ts +63 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/page-ignore.ts +7 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/painted-text.ts +141 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/palette-roles.ts +58 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/placeholder-contrast.ts +25 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/stock-accent.ts +31 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/text-colors.ts +80 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/aphoristic-cadence.test.ts +18 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/aphoristic-cadence.ts +20 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/broken-image.test.ts +25 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/broken-image.ts +17 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/em-dash-overuse.test.ts +39 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/em-dash-overuse.ts +46 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/index.ts +15 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/marketing-buzzword.test.ts +18 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/marketing-buzzword.ts +33 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/numbered-section-labels.test.ts +58 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/numbered-section-labels.ts +34 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/repeated-container-text.test.ts +43 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/repeated-container-text.ts +56 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/script-error.test.ts +48 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/script-error.ts +38 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/skipped-heading.test.ts +49 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/skipped-heading.ts +81 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/support/numbered-label.ts +94 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/support/page-text.ts +37 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/theater-slop-phrase.test.ts +17 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/theater-slop-phrase.ts +21 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/blinking-cursor.test.ts +43 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/blinking-cursor.ts +48 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/border-accent-on-rounded.test.ts +33 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/border-accent-on-rounded.ts +14 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/bounce-easing.test.ts +72 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/bounce-easing.ts +83 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/buried-raster.test.ts +95 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/buried-raster.ts +72 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/codex-grid-background.test.ts +28 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/codex-grid-background.ts +34 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/design-system-radius.test.ts +37 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/design-system-radius.ts +31 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/gpt-thin-border-wide-shadow.test.ts +59 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/gpt-thin-border-wide-shadow.ts +66 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/hard-offset-shadow.test.ts +45 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/hard-offset-shadow.ts +31 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/hero-eyebrow-chip.test.ts +76 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/hero-eyebrow-chip.ts +19 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/icon-tile-stack.test.ts +67 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/icon-tile-stack.ts +92 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/index.ts +38 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/kicker-above-heading.test.ts +126 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/kicker-above-heading.ts +69 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/marquee.test.ts +63 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/marquee.ts +51 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/organic-clip-path.test.ts +67 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/organic-clip-path.ts +41 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/pulsing-dot.test.ts +58 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/pulsing-dot.ts +72 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/repeating-stripes-gradient.test.ts +26 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/repeating-stripes-gradient.ts +25 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/shape-assembled-illustration.test.ts +59 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/shape-assembled-illustration.ts +58 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/side-tab.test.ts +91 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/side-tab.ts +17 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/appearance.ts +110 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/assert-cases.ts +25 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/borders.ts +150 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/clip-geometry.ts +151 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/css-candidates.ts +66 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/curve-samples.ts +55 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/gradient-pattern.ts +40 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/keyframes.ts +134 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/labels.ts +85 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/raster-state.ts +51 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/index.ts +16 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/body-text-viewport-edge.test.ts +64 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/body-text-viewport-edge.ts +62 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/clipped-overflow-container.test.ts +40 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/clipped-overflow-container.ts +15 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/content-hidden-at-rest.test.ts +62 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/content-hidden-at-rest.ts +63 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/cramped-padding.test.ts +61 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/cramped-padding.ts +97 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/edge-flush-cards.test.ts +43 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/edge-flush-cards.ts +47 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/first-viewport-column-overflow.test.ts +28 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/first-viewport-column-overflow.ts +43 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/heading-rhythm.test.ts +67 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/heading-rhythm.ts +30 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/index.ts +21 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/monotonous-spacing.test.ts +19 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/monotonous-spacing.ts +32 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/nested-cards.test.ts +60 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/nested-cards.ts +38 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/straggler.test.ts +33 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/straggler.ts +28 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/cards.ts +114 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/clipping.ts +71 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/declared-mockups.ts +46 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/geometry.ts +73 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/hidden-interface.ts +35 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/layout-cases.ts +23 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/line-breaks.ts +32 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/motion.ts +77 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/padding.ts +93 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/rhythm.ts +161 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/text-occlusion.test.ts +37 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/text-occlusion.ts +84 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/text-overflow.test.ts +83 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/text-overflow.ts +72 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/unbalanced-heading.test.ts +22 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/unbalanced-heading.ts +22 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/viewport-reflow.test.ts +34 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/viewport-reflow.ts +33 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/ai-color-palette.test.ts +13 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/ai-color-palette.ts +11 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/aphoristic-cadence.test.ts +12 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/aphoristic-cadence.ts +14 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/border-accent-on-rounded.test.ts +14 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/border-accent-on-rounded.ts +20 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/bounce-easing.test.ts +19 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/bounce-easing.ts +21 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/broken-image.test.ts +27 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/broken-image.ts +16 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/codex-grid-background.test.ts +11 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/codex-grid-background.ts +18 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/dark-glow.test.ts +15 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/dark-glow.ts +21 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/em-dash-overuse.test.ts +13 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/em-dash-overuse.ts +15 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/gradient-text.test.ts +12 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/gradient-text.ts +11 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/gray-on-color.test.ts +20 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/gray-on-color.ts +13 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/index.ts +19 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/marketing-buzzword.test.ts +12 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/marketing-buzzword.ts +17 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/marquee.test.ts +12 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/marquee.ts +12 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/monotonous-spacing.test.ts +13 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/monotonous-spacing.ts +22 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/overused-font.test.ts +21 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/overused-font.ts +16 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/radial-halo.test.ts +16 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/radial-halo.ts +14 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/side-tab.test.ts +29 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/side-tab.ts +58 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/accent-scans.ts +78 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/check-source.ts +6 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/corners.ts +105 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/css-effects.ts +81 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/css-scopes.ts +131 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/image-tags.ts +113 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/js-punctuation.ts +34 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/markup-scope.ts +44 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/source-color.ts +42 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/source-shadow.ts +15 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/source-text.ts +110 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/all-caps-body.test.ts +24 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/all-caps-body.ts +15 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/design-system-font-size.test.ts +21 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/design-system-font-size.ts +23 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/design-system-font.test.ts +22 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/design-system-font.ts +24 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/extreme-negative-tracking.test.ts +23 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/extreme-negative-tracking.ts +18 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/flat-type-hierarchy.test.ts +33 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/flat-type-hierarchy.ts +26 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/index.ts +21 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/italic-serif-display.test.ts +24 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/italic-serif-display.ts +24 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/justified-text.test.ts +31 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/justified-text.ts +32 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/line-length.test.ts +43 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/line-length.ts +28 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/oversized-h1.test.ts +26 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/oversized-h1.ts +20 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/overused-font.test.ts +35 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/overused-font.ts +45 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/drawn-enlargement.ts +48 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/fading-text.ts +48 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/flex-runs.ts +16 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/font-family.ts +28 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/painted-text.test.ts +63 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/painted-text.ts +81 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/svg-size.ts +57 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/text-context.ts +112 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/text-lines.ts +43 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/type-hierarchy.ts +48 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/tight-leading.test.ts +54 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/tight-leading.ts +47 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/tiny-text.test.ts +60 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/tiny-text.ts +23 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/undersized-ui-text.test.ts +98 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/undersized-ui-text.ts +28 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/wide-tracking.test.ts +26 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/wide-tracking.ts +26 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/snapshot/collect.ts +158 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/snapshot/style-props.ts +25 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/testing/build-snapshot.ts +78 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/tsconfig.json +19 -0
- package/packages/shared-skills/skills/frontend/scripts/detect/types.ts +124 -0
- package/packages/shared-skills/skills/programming/SKILL.md +17 -74
- package/packages/shared-skills/skills/programming/references/go/README.md +1 -1
- package/packages/shared-skills/skills/programming/references/go/bootstrap.md +2 -2
- package/packages/shared-skills/skills/programming/references/python/README.md +4 -4
- package/packages/shared-skills/skills/programming/references/python/one-liners.md +5 -5
- package/packages/shared-skills/skills/programming/references/testing/README.md +82 -0
- package/packages/shared-skills/skills/programming/references/testing/junk-classes.md +56 -0
- package/packages/shared-skills/skills/programming/references/typescript/README.md +1 -2
- package/packages/shared-skills/skills/programming/scripts/go/new-project.ts +197 -0
- package/packages/shared-skills/skills/programming/scripts/python/new-project.ts +231 -0
- package/packages/shared-skills/skills/programming/scripts/python/new-script.ts +134 -0
- package/packages/shared-skills/skills/programming/scripts/rust/new-project.ts +215 -0
- package/packages/shared-skills/skills/programming/scripts/scaffolders.test.ts +96 -0
- package/packages/shared-skills/skills/programming/scripts/shared/run-tool.ts +19 -0
- package/packages/shared-skills/skills/programming/scripts/typescript/check-test-junk-rules.ts +140 -0
- package/packages/shared-skills/skills/programming/scripts/typescript/check-test-junk.test.ts +125 -0
- package/packages/shared-skills/skills/programming/scripts/typescript/check-test-junk.ts +148 -0
- package/packages/shared-skills/skills/programming/scripts/typescript/mutation-proof.test.ts +43 -0
- package/packages/shared-skills/skills/programming/scripts/typescript/mutation-proof.ts +179 -0
- package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +32 -20
- package/packages/shared-skills/skills/ulw-research/scripts/source-commands.mjs +3 -1
- package/packages/shared-skills/skills/ulw-research/scripts/source-integrity.test.ts +39 -2
- package/packages/shared-skills/skills/visual-qa/SKILL.md +12 -1
- package/dist/agents/gpt-prompt-identity.d.ts +0 -3
- package/dist/agents/hephaestus/gpt-5-4.d.ts +0 -24
- package/dist/agents/hephaestus/gpt-5-5.d.ts +0 -2
- package/dist/agents/hephaestus/gpt-5-6.d.ts +0 -2
- package/dist/agents/kimi-tool-loop-guard.d.ts +0 -1
- package/dist/agents/sisyphus/claude-fable-5.d.ts +0 -19
- package/dist/agents/sisyphus/claude-opus-4-7.d.ts +0 -22
- package/dist/agents/sisyphus/claude-opus-4-8.d.ts +0 -19
- package/dist/agents/sisyphus/claude-opus-5.d.ts +0 -33
- package/dist/agents/sisyphus/gemini.d.ts +0 -20
- package/dist/agents/sisyphus/glm-5-2.d.ts +0 -4
- package/dist/agents/sisyphus/gpt-5-4.d.ts +0 -26
- package/dist/agents/sisyphus/gpt-5-5.d.ts +0 -6
- package/dist/agents/sisyphus/gpt-task-system-guide.d.ts +0 -1
- package/dist/agents/sisyphus/grok-4.d.ts +0 -21
- package/dist/agents/sisyphus/index.d.ts +0 -31
- package/dist/agents/sisyphus/kimi-k2-6.d.ts +0 -32
- package/dist/agents/sisyphus/kimi-k2-7.d.ts +0 -17
- package/dist/agents/sisyphus/kimi-k3-1.d.ts +0 -9
- package/dist/agents/sisyphus/kimi-k3.d.ts +0 -19
- package/dist/agents/sisyphus-dynamic-prompt-builder.d.ts +0 -2
- package/dist/agents/sisyphus-dynamic-prompt-execution.d.ts +0 -2
- package/dist/agents/sisyphus-dynamic-prompt-exploration.d.ts +0 -2
- package/dist/agents/sisyphus-dynamic-prompt-role.d.ts +0 -2
- package/dist/agents/sisyphus-dynamic-prompt-sections.d.ts +0 -18
- package/dist/agents/sisyphus-dynamic-prompt-style.d.ts +0 -2
- package/dist/agents/sisyphus-dynamic-prompt.d.ts +0 -3
- package/dist/agents/sisyphus-gemini-fallback-overrides.d.ts +0 -1
- package/dist/agents/sisyphus-junior/gemini.d.ts +0 -10
- package/dist/agents/sisyphus-junior/glm-5-2.d.ts +0 -1
- package/dist/agents/sisyphus-junior/gpt-5-4.d.ts +0 -11
- package/dist/agents/sisyphus-junior/gpt-5-5.d.ts +0 -5
- package/dist/agents/sisyphus-junior/gpt.d.ts +0 -9
- package/dist/agents/sisyphus-junior/kimi-k2-6.d.ts +0 -13
- package/dist/agents/sisyphus-junior/kimi-k2-7.d.ts +0 -11
- package/dist/agents/sisyphus-junior/kimi-k3-1.d.ts +0 -6
- package/dist/agents/sisyphus-junior/kimi-k3.d.ts +0 -12
- package/dist/features/claude-code-agent-loader/opencode-config-agents-reader.d.ts +0 -1
- package/dist/features/claude-code-command-loader/loader-cache.d.ts +0 -1
- package/dist/features/claude-code-command-loader/loader.d.ts +0 -1
- package/dist/features/opencode-skill-loader/config-source-discovery.d.ts +0 -1
- package/dist/features/opencode-skill-loader/merger/config-skill-entry-loader.d.ts +0 -1
- package/dist/features/opencode-skill-loader/opencode-config-skills-reader.d.ts +0 -1
- package/dist/features/team-mode/team-layout-tmux/resolve-caller-tmux-session.d.ts +0 -1
- package/dist/features/team-mode/team-registry/team-spec-input-normalizer.d.ts +0 -1
- package/dist/shared/git-worktree/collect-git-diff-stats.d.ts +0 -1
- package/dist/shared/git-worktree/parse-status-porcelain-line.d.ts +0 -1
- package/dist/shared/migration/agent-names.d.ts +0 -1
- package/dist/shared/migration/migrations-sidecar.d.ts +0 -1
- package/dist/shared/skill-path-resolver.d.ts +0 -1
- package/dist/shared/zip-entry-listing/powershell-zip-entry-listing.d.ts +0 -1
- package/dist/shared/zip-entry-listing/zipinfo-zip-entry-listing.d.ts +0 -1
- package/dist/skills/programming/scripts/go/new-project.py +0 -138
- package/dist/skills/programming/scripts/python/new-project.py +0 -172
- package/dist/skills/programming/scripts/python/new-script.py +0 -116
- package/dist/skills/programming/scripts/rust/new-project.py +0 -178
- package/packages/omo-codex/plugin/skills/programming/scripts/go/new-project.py +0 -138
- package/packages/omo-codex/plugin/skills/programming/scripts/python/new-project.py +0 -172
- package/packages/omo-codex/plugin/skills/programming/scripts/python/new-script.py +0 -116
- package/packages/omo-codex/plugin/skills/programming/scripts/rust/new-project.py +0 -178
- package/packages/shared-skills/skills/programming/scripts/go/new-project.py +0 -138
- package/packages/shared-skills/skills/programming/scripts/python/new-project.py +0 -172
- package/packages/shared-skills/skills/programming/scripts/python/new-script.py +0 -116
- package/packages/shared-skills/skills/programming/scripts/rust/new-project.py +0 -178
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { splitTop } from "./appearance"
|
|
2
|
+
import { arc, cubic, lerp, type Point } from "./curve-samples"
|
|
3
|
+
export function geometricPolygon(body: string): boolean {
|
|
4
|
+
const points = splitTop(body)
|
|
5
|
+
.filter((p) => !/^nonzero$|^evenodd$/.test(p))
|
|
6
|
+
.map((p) => splitTop(p, /\s/))
|
|
7
|
+
const key = (v: string): string => (/^[-+]?0(?:\.0+)?(?:%|px)?$/.test(v) ? "0" : v.replace(/\s/g, ""))
|
|
8
|
+
if (
|
|
9
|
+
points.every((p, i) => {
|
|
10
|
+
const next = points[(i + 1) % points.length]
|
|
11
|
+
return p.length === 2 && next !== undefined && (key(p[0] ?? "") === key(next[0] ?? "") || key(p[1] ?? "") === key(next[1] ?? ""))
|
|
12
|
+
})
|
|
13
|
+
)
|
|
14
|
+
return true
|
|
15
|
+
const numeric = points.map((p) => p.map((v) => (/^[-+]?[\d.]+(?:px|%)?$/.test(v) ? Number.parseFloat(v) : Number.NaN)))
|
|
16
|
+
if (numeric.some((p) => p.length !== 2 || p.some((n) => !Number.isFinite(n)))) return false
|
|
17
|
+
const xs = numeric.map((p) => p[0] ?? 0),
|
|
18
|
+
ys = numeric.map((p) => p[1] ?? 0)
|
|
19
|
+
const distinct = (vs: readonly number[]): number[] => [...new Set(vs)].sort((a, b) => a - b)
|
|
20
|
+
const teeth = (along: readonly number[], across: readonly number[]): boolean => {
|
|
21
|
+
const d = distinct(along),
|
|
22
|
+
step = (d[1] ?? 0) - (d[0] ?? 0)
|
|
23
|
+
if (d.length < 3 || step <= 0 || d.slice(1).some((v, i) => Math.abs(v - (d[i] ?? 0) - step) > 0.5)) return false
|
|
24
|
+
let last: number | null = null,
|
|
25
|
+
swings = 0
|
|
26
|
+
for (let i = 0; i < along.length; i++) {
|
|
27
|
+
const j = (i + 1) % along.length
|
|
28
|
+
if (Math.abs(Math.abs((along[j] ?? 0) - (along[i] ?? 0)) - step) > 0.5) {
|
|
29
|
+
last = null
|
|
30
|
+
continue
|
|
31
|
+
}
|
|
32
|
+
const swing = (across[j] ?? 0) - (across[i] ?? 0)
|
|
33
|
+
if (Math.abs(swing) < 0.01) continue
|
|
34
|
+
if (last !== null && (Math.sign(last) === Math.sign(swing) || Math.abs(Math.abs(last) - Math.abs(swing)) > 0.5)) return false
|
|
35
|
+
last = swing
|
|
36
|
+
swings++
|
|
37
|
+
}
|
|
38
|
+
return swings >= 3
|
|
39
|
+
}
|
|
40
|
+
return (
|
|
41
|
+
(distinct(xs).length >= 2 && distinct(xs).length <= 4 && teeth(ys, xs)) ||
|
|
42
|
+
(distinct(ys).length >= 2 && distinct(ys).length <= 4 && teeth(xs, ys))
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
export function roundedPath(body: string): boolean {
|
|
46
|
+
const tokens = body.replace(/^["']|["']$/g, "").match(/[A-Za-z]|[-+]?(?:[0-9]+\.?[0-9]*|\.[0-9]+)(?:[eE][-+]?[0-9]+)?/g) ?? []
|
|
47
|
+
const segments: { a: Point; b: Point; line: boolean }[] = [],
|
|
48
|
+
points: Point[] = []
|
|
49
|
+
let at: Point = [0, 0],
|
|
50
|
+
start: Point = [0, 0],
|
|
51
|
+
cmd = "",
|
|
52
|
+
i = 0
|
|
53
|
+
let lastCubic: Point | null = null,
|
|
54
|
+
lastQuad: Point | null = null
|
|
55
|
+
while (i < tokens.length) {
|
|
56
|
+
const token = tokens[i] ?? ""
|
|
57
|
+
if (/^[a-z]$/i.test(token)) {
|
|
58
|
+
cmd = token
|
|
59
|
+
i++
|
|
60
|
+
if (cmd.toLowerCase() === "z") {
|
|
61
|
+
if (at[0] !== start[0] || at[1] !== start[1]) segments.push({ a: at, b: start, line: true })
|
|
62
|
+
at = start
|
|
63
|
+
cmd = ""
|
|
64
|
+
}
|
|
65
|
+
continue
|
|
66
|
+
}
|
|
67
|
+
const upper = cmd.toUpperCase(),
|
|
68
|
+
arity =
|
|
69
|
+
upper === "H" || upper === "V"
|
|
70
|
+
? 1
|
|
71
|
+
: upper === "C"
|
|
72
|
+
? 6
|
|
73
|
+
: upper === "A"
|
|
74
|
+
? 7
|
|
75
|
+
: upper === "S" || upper === "Q"
|
|
76
|
+
? 4
|
|
77
|
+
: ["M", "L", "T"].includes(upper)
|
|
78
|
+
? 2
|
|
79
|
+
: 0
|
|
80
|
+
if (arity === 0 || i + arity > tokens.length) return false
|
|
81
|
+
const args = tokens.slice(i, i + arity).map(Number)
|
|
82
|
+
if (args.some((n) => !Number.isFinite(n))) return false
|
|
83
|
+
i += arity
|
|
84
|
+
const rel = cmd !== upper,
|
|
85
|
+
base: Point = rel ? at : [0, 0]
|
|
86
|
+
const end: Point =
|
|
87
|
+
upper === "H"
|
|
88
|
+
? [base[0] + (args[0] ?? 0), at[1]]
|
|
89
|
+
: upper === "V"
|
|
90
|
+
? [at[0], base[1] + (args[0] ?? 0)]
|
|
91
|
+
: [base[0] + (args[arity - 2] ?? 0), base[1] + (args[arity - 1] ?? 0)]
|
|
92
|
+
const point = (k: number): Point => [base[0] + (args[k] ?? 0), base[1] + (args[k + 1] ?? 0)]
|
|
93
|
+
const reflect = (p: Point | null): Point => (p ? [2 * at[0] - p[0], 2 * at[1] - p[1]] : at)
|
|
94
|
+
let nextCubic: Point | null = null,
|
|
95
|
+
nextQuad: Point | null = null
|
|
96
|
+
if (upper === "C" || upper === "S") {
|
|
97
|
+
const c1 = upper === "C" ? point(0) : reflect(lastCubic),
|
|
98
|
+
c2 = point(upper === "C" ? 2 : 0)
|
|
99
|
+
points.push(...cubic(at, c1, c2, end))
|
|
100
|
+
nextCubic = c2
|
|
101
|
+
} else if (upper === "Q" || upper === "T") {
|
|
102
|
+
const c: Point = upper === "Q" ? point(0) : reflect(lastQuad)
|
|
103
|
+
points.push(...cubic(at, lerp(at, c, 2 / 3), lerp(end, c, 2 / 3), end))
|
|
104
|
+
nextQuad = c
|
|
105
|
+
} else if (upper === "A")
|
|
106
|
+
points.push(...arc(at, args[0] ?? 0, args[1] ?? 0, args[2] ?? 0, (args[3] ?? 0) !== 0, (args[4] ?? 0) !== 0, end))
|
|
107
|
+
lastCubic = nextCubic
|
|
108
|
+
lastQuad = nextQuad
|
|
109
|
+
if (upper === "M") {
|
|
110
|
+
start = end
|
|
111
|
+
cmd = rel ? "l" : "L"
|
|
112
|
+
} else segments.push({ a: at, b: end, line: ["L", "H", "V"].includes(upper) })
|
|
113
|
+
points.push(end)
|
|
114
|
+
at = end
|
|
115
|
+
}
|
|
116
|
+
const lines = segments.filter((s) => s.line)
|
|
117
|
+
if (lines.length < 4) return false
|
|
118
|
+
const xs = points.map((p) => p[0]),
|
|
119
|
+
ys = points.map((p) => p[1]),
|
|
120
|
+
minX = Math.min(...xs),
|
|
121
|
+
maxX = Math.max(...xs),
|
|
122
|
+
minY = Math.min(...ys),
|
|
123
|
+
maxY = Math.max(...ys)
|
|
124
|
+
const tol = Math.max(1, maxX - minX, maxY - minY) * 0.01,
|
|
125
|
+
near = (a: number, b: number): boolean => Math.abs(a - b) <= tol
|
|
126
|
+
const edges = (p: Point): number[] =>
|
|
127
|
+
[near(p[1], minY) ? 0 : -1, near(p[0], maxX) ? 1 : -1, near(p[1], maxY) ? 2 : -1, near(p[0], minX) ? 3 : -1].filter((i) => i >= 0)
|
|
128
|
+
const reached = new Set<number>()
|
|
129
|
+
for (const l of lines) {
|
|
130
|
+
const edge = edges(l.a).find((i) => edges(l.b).includes(i))
|
|
131
|
+
if (edge === undefined) return false
|
|
132
|
+
reached.add(edge)
|
|
133
|
+
}
|
|
134
|
+
if (reached.size !== 4) return false
|
|
135
|
+
const first = segments.findIndex((s) => s.line)
|
|
136
|
+
const run: Point[] = []
|
|
137
|
+
for (let k = 1; k <= segments.length; k++) {
|
|
138
|
+
const segment = segments[(first + k) % segments.length]
|
|
139
|
+
if (!segment) continue
|
|
140
|
+
const a = run[0],
|
|
141
|
+
b = run[1]
|
|
142
|
+
if (segment.line) {
|
|
143
|
+
if (a && b && !edges(a).some((x) => edges(b).some((y) => x % 2 !== y % 2))) return false
|
|
144
|
+
run.length = 0
|
|
145
|
+
} else {
|
|
146
|
+
run[0] = a ?? segment.a
|
|
147
|
+
run[1] = segment.b
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return true
|
|
151
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { ancestors, parentOf } from "../../../core/page"
|
|
2
|
+
import { cssBlocks } from "../../../core/source"
|
|
3
|
+
import type { ElementSnapshot, PageSnapshot } from "../../../types"
|
|
4
|
+
|
|
5
|
+
function compound(e: ElementSnapshot, selector: string): boolean {
|
|
6
|
+
const tag = /^[a-z][\w-]*|^\*/i.exec(selector)?.[0]
|
|
7
|
+
if (tag && tag !== "*" && e.tag !== tag.toLowerCase()) return false
|
|
8
|
+
let rest = selector.slice(tag?.length ?? 0)
|
|
9
|
+
for (const m of rest.matchAll(/([.#])([\w-]+)|\[([\w-]+)(?:=["']?([^"'\]]*)["']?)?\]/g)) {
|
|
10
|
+
if (m[1] === "#" && e.attributes["id"] !== m[2]) return false
|
|
11
|
+
if (m[1] === "." && !(e.attributes["class"] ?? "").split(/\s+/).includes(m[2] ?? "")) return false
|
|
12
|
+
if (m[3] && (e.attributes[m[3]] === undefined || (m[4] !== undefined && e.attributes[m[3]] !== m[4]))) return false
|
|
13
|
+
}
|
|
14
|
+
rest = rest.replace(/([.#])[\w-]+|\[[^\]]+\]/g, "")
|
|
15
|
+
return rest === ""
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function matchesSelector(s: PageSnapshot, e: ElementSnapshot, selector: string): boolean {
|
|
19
|
+
const pieces = selector.trim().replace(/\s*>\s*/g, " > ").split(/\s+/)
|
|
20
|
+
const last = pieces.pop()
|
|
21
|
+
if (!last || !compound(e, last)) return false
|
|
22
|
+
let current = e
|
|
23
|
+
while (pieces.length > 0) {
|
|
24
|
+
const part = pieces.pop()
|
|
25
|
+
if (part === ">") {
|
|
26
|
+
const parent = parentOf(s, current)
|
|
27
|
+
const wanted = pieces.pop()
|
|
28
|
+
if (!parent || !wanted || !compound(parent, wanted)) return false
|
|
29
|
+
current = parent
|
|
30
|
+
} else {
|
|
31
|
+
const match = [...ancestors(s, current)].find(a => compound(a, part ?? ""))
|
|
32
|
+
if (!match) return false
|
|
33
|
+
current = match
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return true
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function cssCandidates(s: PageSnapshot): ReadonlyMap<string, Readonly<Record<string, string>>> {
|
|
40
|
+
const merged = new Map<string, Record<string, string>>()
|
|
41
|
+
for (const css of s.cssText) {
|
|
42
|
+
let text = css
|
|
43
|
+
for (const match of css.matchAll(/@media[^{]*prefers-reduced-motion\s*:\s*reduce\s*\)[^{]*\{/g)) {
|
|
44
|
+
let end = (match.index ?? 0) + match[0].length
|
|
45
|
+
let depth = 1
|
|
46
|
+
const start = match.index ?? 0
|
|
47
|
+
while (end < css.length && depth > 0) {
|
|
48
|
+
if (css[end] === "{") depth++
|
|
49
|
+
if (css[end] === "}") depth--
|
|
50
|
+
end++
|
|
51
|
+
}
|
|
52
|
+
text = text.replace(css.slice(start, end), "")
|
|
53
|
+
}
|
|
54
|
+
for (const block of cssBlocks(text)) {
|
|
55
|
+
for (const selector of block.selector.split(",").map(v => v.trim()).filter(v => v !== "" && !v.startsWith("@"))) {
|
|
56
|
+
const declarations = merged.get(selector) ?? {}
|
|
57
|
+
for (const entry of block.body.split(";")) {
|
|
58
|
+
const colon = entry.indexOf(":")
|
|
59
|
+
if (colon >= 0) declarations[entry.slice(0, colon).trim().toLowerCase()] = entry.slice(colon + 1).trim()
|
|
60
|
+
}
|
|
61
|
+
merged.set(selector, declarations)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return merged
|
|
66
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type Point = readonly [number, number]
|
|
2
|
+
export const lerp = (a: Point, b: Point, t: number): Point => [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t]
|
|
3
|
+
export function cubic(p0: Point, p1: Point, p2: Point, p3: Point): readonly Point[] {
|
|
4
|
+
return Array.from({ length: 15 }, (_, i) => {
|
|
5
|
+
const t = (i + 1) / 16,
|
|
6
|
+
u = 1 - t,
|
|
7
|
+
a = u * u * u,
|
|
8
|
+
b = 3 * u * u * t,
|
|
9
|
+
c = 3 * u * t * t,
|
|
10
|
+
d = t * t * t
|
|
11
|
+
return [a * p0[0] + b * p1[0] + c * p2[0] + d * p3[0], a * p0[1] + b * p1[1] + c * p2[1] + d * p3[1]] satisfies Point
|
|
12
|
+
})
|
|
13
|
+
}
|
|
14
|
+
export function arc(
|
|
15
|
+
from: Point,
|
|
16
|
+
rxInput: number,
|
|
17
|
+
ryInput: number,
|
|
18
|
+
rotation: number,
|
|
19
|
+
large: boolean,
|
|
20
|
+
sweep: boolean,
|
|
21
|
+
to: Point,
|
|
22
|
+
): readonly Point[] {
|
|
23
|
+
let rx = Math.abs(rxInput),
|
|
24
|
+
ry = Math.abs(ryInput)
|
|
25
|
+
if ((from[0] === to[0] && from[1] === to[1]) || rx === 0 || ry === 0) return []
|
|
26
|
+
const phi = (rotation * Math.PI) / 180,
|
|
27
|
+
sin = Math.sin(phi),
|
|
28
|
+
cos = Math.cos(phi),
|
|
29
|
+
dx = (from[0] - to[0]) / 2,
|
|
30
|
+
dy = (from[1] - to[1]) / 2
|
|
31
|
+
const x1 = cos * dx + sin * dy,
|
|
32
|
+
y1 = -sin * dx + cos * dy,
|
|
33
|
+
lambda = (x1 * x1) / (rx * rx) + (y1 * y1) / (ry * ry)
|
|
34
|
+
if (lambda > 1) {
|
|
35
|
+
rx *= Math.sqrt(lambda)
|
|
36
|
+
ry *= Math.sqrt(lambda)
|
|
37
|
+
}
|
|
38
|
+
const num = rx * rx * ry * ry - rx * rx * y1 * y1 - ry * ry * x1 * x1,
|
|
39
|
+
den = rx * rx * y1 * y1 + ry * ry * x1 * x1
|
|
40
|
+
const coef = (den === 0 ? 0 : Math.sqrt(Math.max(0, num / den))) * (large === sweep ? -1 : 1)
|
|
41
|
+
const cx1 = (coef * rx * y1) / ry,
|
|
42
|
+
cy1 = (-coef * ry * x1) / rx,
|
|
43
|
+
cx = cos * cx1 - sin * cy1 + (from[0] + to[0]) / 2,
|
|
44
|
+
cy = sin * cx1 + cos * cy1 + (from[1] + to[1]) / 2
|
|
45
|
+
const theta = Math.atan2((y1 - cy1) / ry, (x1 - cx1) / rx)
|
|
46
|
+
let delta = Math.atan2((-y1 - cy1) / ry, (-x1 - cx1) / rx) - theta
|
|
47
|
+
if (sweep && delta < 0) delta += Math.PI * 2
|
|
48
|
+
else if (!sweep && delta > 0) delta -= Math.PI * 2
|
|
49
|
+
return Array.from({ length: 15 }, (_, i) => {
|
|
50
|
+
const t = theta + (delta * (i + 1)) / 16,
|
|
51
|
+
ex = rx * Math.cos(t),
|
|
52
|
+
ey = ry * Math.sin(t)
|
|
53
|
+
return [cos * ex - sin * ey + cx, sin * ex + cos * ey + cy] satisfies Point
|
|
54
|
+
})
|
|
55
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { parseColor } from "../../../core/color"
|
|
2
|
+
import { splitTop } from "./appearance"
|
|
3
|
+
const position = (value: string): number | null => {
|
|
4
|
+
const token = value
|
|
5
|
+
.replace(/\s/g, "")
|
|
6
|
+
.replace(/^(?:calc\()+/, "")
|
|
7
|
+
.replace(/\)+$/, "")
|
|
8
|
+
const match = /^([-+]?[\d.]+)(%|deg|grad|turn|px)?$/.exec(token)
|
|
9
|
+
if (!match) return null
|
|
10
|
+
const n = Number(match[1])
|
|
11
|
+
if (n === 0) return 0
|
|
12
|
+
return match[2] === "%" ? n / 100 : match[2] === "deg" ? n / 360 : match[2] === "grad" ? n / 400 : match[2] === "turn" ? n : null
|
|
13
|
+
}
|
|
14
|
+
export function repeats(value: string): boolean {
|
|
15
|
+
for (const layer of splitTop(value)) {
|
|
16
|
+
const m = /^repeating-(linear|radial)-gradient\(([\s\S]*)\)$/i.exec(layer)
|
|
17
|
+
if (!m) continue
|
|
18
|
+
const stops = splitTop(m[2] ?? ""),
|
|
19
|
+
first = splitTop(stops[0] ?? "", /\s/),
|
|
20
|
+
token = first[0] ?? ""
|
|
21
|
+
if (token.includes("var(")) return true
|
|
22
|
+
const start =
|
|
23
|
+
parseColor(token) !== null ||
|
|
24
|
+
(/^(?:transparent|currentcolor|[a-z]+)$/i.test(token) && !/^(?:circle|ellipse|to|at|in|closest|farthest)/i.test(token))
|
|
25
|
+
? 0
|
|
26
|
+
: 1
|
|
27
|
+
if (stops.length < start + 2) return true
|
|
28
|
+
if (m[1]?.toLowerCase() === "radial" && start === 1) {
|
|
29
|
+
const prelude = (stops[0] ?? "").split(/\bat\b|\bin\b/)[0] ?? ""
|
|
30
|
+
if (/closest-|farthest-side|[0-9]/.test(prelude)) return true
|
|
31
|
+
}
|
|
32
|
+
const a = splitTop(stops[start] ?? "", /\s/),
|
|
33
|
+
b = splitTop(stops.at(-1) ?? "", /\s/)
|
|
34
|
+
if (b.length === 1 && b[0]?.includes("var(")) return true
|
|
35
|
+
const zero = a[1] === undefined || position(a[1]) === 0,
|
|
36
|
+
full = b.length === 1 || position(b.at(-1) ?? "") === 1
|
|
37
|
+
if (!(zero && full)) return true
|
|
38
|
+
}
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { ComputedStyle, PageSnapshot } from "../../../types"
|
|
2
|
+
import { splitTop } from "./appearance"
|
|
3
|
+
export type Frame = Readonly<Record<string, string>>
|
|
4
|
+
export type KeyframeStep = { readonly key: string; readonly declarations: Frame }
|
|
5
|
+
export function keyframeSteps(s: PageSnapshot, name: string): readonly KeyframeStep[] | null {
|
|
6
|
+
const frames: KeyframeStep[] = []
|
|
7
|
+
let found = false
|
|
8
|
+
for (const css of s.cssText) {
|
|
9
|
+
const text = css.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
10
|
+
for (const m of text.matchAll(/@(?:-webkit-)?keyframes\s+([\w-]+)\s*\{/g)) {
|
|
11
|
+
if (m[1] !== name) continue
|
|
12
|
+
found = true
|
|
13
|
+
let end = (m.index ?? 0) + m[0].length,
|
|
14
|
+
depth = 1
|
|
15
|
+
const start = end
|
|
16
|
+
while (end < text.length && depth > 0) {
|
|
17
|
+
if (text[end] === "{") depth++
|
|
18
|
+
if (text[end] === "}") depth--
|
|
19
|
+
end++
|
|
20
|
+
}
|
|
21
|
+
for (const step of text.slice(start, end - 1).matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
|
|
22
|
+
const entries = (step[2] ?? "").split(";").flatMap((d) => {
|
|
23
|
+
const i = d.indexOf(":")
|
|
24
|
+
return i < 0 ? [] : [[d.slice(0, i).trim().toLowerCase(), d.slice(i + 1).trim()]]
|
|
25
|
+
})
|
|
26
|
+
frames.push({ key: (step[1] ?? "").trim(), declarations: Object.fromEntries(entries) })
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return found ? frames : null
|
|
31
|
+
}
|
|
32
|
+
export function keyframes(s: PageSnapshot, name: string): readonly Frame[] | null {
|
|
33
|
+
return keyframeSteps(s, name)?.map(step => step.declarations) ?? null
|
|
34
|
+
}
|
|
35
|
+
export function infiniteNames(style: ComputedStyle): readonly string[] {
|
|
36
|
+
const iterations = splitTop(style["animation-iteration-count"] ?? "")
|
|
37
|
+
return splitTop(style["animation-name"] ?? "").filter((n, i) => n !== "none" && iterations[i % iterations.length] === "infinite")
|
|
38
|
+
}
|
|
39
|
+
export function onlyUnitPulse(frames: readonly Frame[]): boolean {
|
|
40
|
+
return (
|
|
41
|
+
frames.length > 0 &&
|
|
42
|
+
frames.every((f) =>
|
|
43
|
+
Object.entries(f).every(([p, v]) => {
|
|
44
|
+
if (p === "opacity") return true
|
|
45
|
+
if (p === "animation-timing-function") return !/linear\(|var\(/.test(v) && !overshoot(v)
|
|
46
|
+
if (p !== "scale" && p !== "transform") return false
|
|
47
|
+
if (v === "none") return true
|
|
48
|
+
const rest = p === "scale" ? v : v.replace(/scale(?:[XYZ]|3d)?\(([^)]*)\)/gi, "$1")
|
|
49
|
+
return (
|
|
50
|
+
/^[\s,0-9.+-]+$/.test(rest) &&
|
|
51
|
+
rest
|
|
52
|
+
.split(/[\s,]+/)
|
|
53
|
+
.filter(Boolean)
|
|
54
|
+
.every((n) => Number(n) >= 0 && Number(n) <= 1)
|
|
55
|
+
)
|
|
56
|
+
}),
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
export const overshoot = (v: string): boolean =>
|
|
61
|
+
[...v.matchAll(/cubic-bezier\(\s*([\d.+-]+)\s*,\s*([\d.+-]+)\s*,\s*([\d.+-]+)\s*,\s*([\d.+-]+)\s*\)/g)].some((m) =>
|
|
62
|
+
[Number(m[2]), Number(m[4])].some((y) => y < -0.1 || y > 1.1),
|
|
63
|
+
)
|
|
64
|
+
const scalar = (v: string): number | null => (/^[-+]?(?:\d*\.)?\d+(?:px)?$/.test(v) ? Number.parseFloat(v) : null)
|
|
65
|
+
const differs = (a: string | undefined, b: string | undefined): boolean => {
|
|
66
|
+
if (a === undefined || b === undefined) return false
|
|
67
|
+
const x = scalar(a),
|
|
68
|
+
y = scalar(b)
|
|
69
|
+
return x !== null && y !== null ? Math.abs(x - y) >= 4 : a.replace(/\s/g, "") !== b.replace(/\s/g, "")
|
|
70
|
+
}
|
|
71
|
+
function translation(f: Frame): readonly string[] | null {
|
|
72
|
+
const t = f["transform"]
|
|
73
|
+
if (t === undefined && f["translate"] === undefined) return null
|
|
74
|
+
if (t?.includes("matrix")) return []
|
|
75
|
+
const axes = ["0", "0", "0"]
|
|
76
|
+
for (const m of (t ?? "").matchAll(/translate([XYZ]|3d)?\(([^)]*)\)/gi)) {
|
|
77
|
+
const suffix = m[1]?.toLowerCase(),
|
|
78
|
+
args = (m[2] ?? "").split(/,\s*/).map((x) => x.trim())
|
|
79
|
+
if (suffix === "x" || suffix === "y" || suffix === "z") axes[suffix === "x" ? 0 : suffix === "y" ? 1 : 2] = args[0] ?? "0"
|
|
80
|
+
else
|
|
81
|
+
args.forEach((v, i) => {
|
|
82
|
+
axes[i] = v
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
if (f["translate"])
|
|
86
|
+
f["translate"].split(/\s+/).forEach((v, i) => {
|
|
87
|
+
axes[i] = v
|
|
88
|
+
})
|
|
89
|
+
return axes
|
|
90
|
+
}
|
|
91
|
+
export function dotPulse(frames: readonly Frame[]): boolean {
|
|
92
|
+
const declarations = frames.flatMap((f) => Object.entries(f))
|
|
93
|
+
const scales = declarations
|
|
94
|
+
.filter(([p]) => p === "transform")
|
|
95
|
+
.flatMap(([, v]) => [...v.matchAll(/scale([XY]|3d)?\(/gi)].map((m) => m[1] ?? "both"))
|
|
96
|
+
const oneAxis =
|
|
97
|
+
scales.length > 0 &&
|
|
98
|
+
new Set(scales).size === 1 &&
|
|
99
|
+
["X", "Y", "x", "y"].includes(scales[0] ?? "") &&
|
|
100
|
+
!declarations.some(([p]) => p === "scale")
|
|
101
|
+
const signal = declarations.some(
|
|
102
|
+
([p, v]) => p === "opacity" || p === "box-shadow" || p === "scale" || (p === "transform" && /scale/i.test(v) && !oneAxis),
|
|
103
|
+
)
|
|
104
|
+
if (!signal) return false
|
|
105
|
+
const translations = frames.map(translation).filter((t): t is readonly string[] => t !== null)
|
|
106
|
+
for (const a of translations)
|
|
107
|
+
for (const b of translations)
|
|
108
|
+
for (let i = 0; i < 3; i++) {
|
|
109
|
+
const x = a[i] ?? "0",
|
|
110
|
+
y = b[i] ?? "0"
|
|
111
|
+
if (!x.includes("%") && !y.includes("%") && differs(x, y)) return false
|
|
112
|
+
}
|
|
113
|
+
const sizes = frames.filter((f) => f["height"] !== undefined)
|
|
114
|
+
if (sizes.some((f) => f["height"] !== sizes[0]?.["height"]) && sizes.every((f) => f["width"] === sizes[0]?.["width"])) return false
|
|
115
|
+
const pairs = [
|
|
116
|
+
["left", "right"],
|
|
117
|
+
["top", "bottom"],
|
|
118
|
+
["inset-inline-start", "inset-inline-end"],
|
|
119
|
+
["inset-block-start", "inset-block-end"],
|
|
120
|
+
["margin-left", "margin-right"],
|
|
121
|
+
["margin-top", "margin-bottom"],
|
|
122
|
+
["margin-inline-start", "margin-inline-end"],
|
|
123
|
+
["margin-block-start", "margin-block-end"],
|
|
124
|
+
]
|
|
125
|
+
for (const a of frames)
|
|
126
|
+
for (const b of frames) {
|
|
127
|
+
if (differs(a["width"], b["width"]) || differs(a["height"], b["height"])) continue
|
|
128
|
+
for (const [x = "", y = ""] of pairs) if (differs(a[x], b[x]) !== differs(a[y], b[y])) return false
|
|
129
|
+
}
|
|
130
|
+
return true
|
|
131
|
+
}
|
|
132
|
+
export const toggles = (frames: readonly Frame[]): boolean =>
|
|
133
|
+
frames.some((f) => Number(f["opacity"] ?? 1) <= 0.15 || f["visibility"] === "hidden") &&
|
|
134
|
+
frames.every((f) => Object.keys(f).every((p) => ["opacity", "visibility", "animation-timing-function"].includes(p)))
|
package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/labels.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ancestors, childrenOf, descendants, fontSizePx, isHeading, parentOf, styleOf } from "../../../core/page"
|
|
2
|
+
import { parseColor } from "../../../core/color"
|
|
3
|
+
import type { ElementSnapshot, PageSnapshot } from "../../../types"
|
|
4
|
+
import { chroma, context, length, radii, visible } from "./appearance"
|
|
5
|
+
function previous(s: PageSnapshot, e: ElementSnapshot): ElementSnapshot | null {
|
|
6
|
+
const p = parentOf(s, e)
|
|
7
|
+
if (!p) return null
|
|
8
|
+
const siblings = childrenOf(s, p),
|
|
9
|
+
at = siblings.findIndex((n) => n.index === e.index)
|
|
10
|
+
return siblings[at - 1] ?? null
|
|
11
|
+
}
|
|
12
|
+
export function labelBefore(s: PageSnapshot, h: ElementSnapshot): { label: ElementSnapshot; levels: number } | null {
|
|
13
|
+
let at = h
|
|
14
|
+
for (let levels = 0; levels <= 4; levels++) {
|
|
15
|
+
const label = previous(s, at)
|
|
16
|
+
if (label) return { label, levels }
|
|
17
|
+
const p = parentOf(s, at)
|
|
18
|
+
if (!p || ["body", "html"].includes(p.tag)) return null
|
|
19
|
+
at = p
|
|
20
|
+
}
|
|
21
|
+
return null
|
|
22
|
+
}
|
|
23
|
+
export function labelType(s: PageSnapshot, e: ElementSnapshot): ElementSnapshot {
|
|
24
|
+
let at = e
|
|
25
|
+
for (let i = 0; i < 3; i++) {
|
|
26
|
+
if (at.ownText.trim() !== "") return at
|
|
27
|
+
const children = childrenOf(s, at).filter((c) => c.text.trim() !== "")
|
|
28
|
+
const only = children[0]
|
|
29
|
+
if (children.length !== 1 || !only) return at
|
|
30
|
+
at = only
|
|
31
|
+
}
|
|
32
|
+
return at
|
|
33
|
+
}
|
|
34
|
+
export const application = (s: PageSnapshot, e: ElementSnapshot): boolean =>
|
|
35
|
+
context(s, e, (a) => a.tag === "dialog" || ["tabpanel", "dialog", "application"].includes(a.attributes["role"] ?? ""))
|
|
36
|
+
export const caps = (e: ElementSnapshot): boolean =>
|
|
37
|
+
styleOf(e, "text-transform") === "uppercase" || (/[A-Z]/.test(e.text) && !/[a-z]/.test(e.text))
|
|
38
|
+
export function heroLabel(s: PageSnapshot, h: ElementSnapshot): ElementSnapshot | null {
|
|
39
|
+
if (h.tag !== "h1" || fontSizePx(h) < 48 || application(s, h) || !visible(s, h)) return null
|
|
40
|
+
const e = previous(s, h)
|
|
41
|
+
if (!e || isHeading(e) || e.text.trim().length < 2 || e.text.trim().length > 60 || !visible(s, e)) return null
|
|
42
|
+
const ty = labelType(s, e),
|
|
43
|
+
size = fontSizePx(ty),
|
|
44
|
+
spacing = length(styleOf(ty, "letter-spacing"))
|
|
45
|
+
if (size <= 0 || size > 14) return null
|
|
46
|
+
const dated =
|
|
47
|
+
(e.tag === "time" || [...descendants(s, e)].some((c) => c.tag === "time") || /\b(?:19|20)\d{2}\b/.test(e.text)) && spacing < 1.6
|
|
48
|
+
const tracked = caps(ty) && !dated && (spacing >= 1.6 || spacing >= size * 0.08)
|
|
49
|
+
const bold = Number(styleOf(ty, "font-weight")) >= 700 && chroma(styleOf(ty, "color"), 40)
|
|
50
|
+
const dash = [e.before, e.after].some(
|
|
51
|
+
(p) =>
|
|
52
|
+
p &&
|
|
53
|
+
length(p.style["width"] ?? "") >= 8 &&
|
|
54
|
+
length(p.style["width"] ?? "") <= 80 &&
|
|
55
|
+
length(p.style["height"] ?? "") >= 1 &&
|
|
56
|
+
length(p.style["height"] ?? "") <= 6 &&
|
|
57
|
+
chroma(p.style["background-color"] ?? ""),
|
|
58
|
+
)
|
|
59
|
+
return tracked || bold || dash ? e : null
|
|
60
|
+
}
|
|
61
|
+
export const headingLevel = (e: ElementSnapshot): number =>
|
|
62
|
+
isHeading(e) ? Number(e.tag.slice(1)) : e.attributes["role"] === "heading" ? Number(e.attributes["aria-level"] ?? 2) : 0
|
|
63
|
+
export function cardContext(s: PageSnapshot, h: ElementSnapshot, label: ElementSnapshot): boolean {
|
|
64
|
+
for (const a of ancestors(s, h)) {
|
|
65
|
+
if (a.tag === "body") break
|
|
66
|
+
if (![...descendants(s, a)].some((n) => n.index === label.index)) continue
|
|
67
|
+
if (["article", "li", "a", "button"].includes(a.tag) && a.rect.height <= s.viewport.height * 2) return true
|
|
68
|
+
if (headingLevel(h) < 3 || a.rect.height >= s.viewport.height) continue
|
|
69
|
+
const bg = parseColor(styleOf(a, "background-color")),
|
|
70
|
+
framed = radii(a).some((r) => r > 0) && bg !== null && bg.a >= 0.9
|
|
71
|
+
if (!framed) continue
|
|
72
|
+
const own = parseColor(styleOf(label, "background-color"))
|
|
73
|
+
const badge =
|
|
74
|
+
styleOf(label, "position") === "absolute" &&
|
|
75
|
+
(label.rect.y <= a.rect.y + 2 ||
|
|
76
|
+
(own !== null && own.a >= 0.9 && Math.max(Math.abs(own.r - bg.r), Math.abs(own.g - bg.g), Math.abs(own.b - bg.b)) > 3))
|
|
77
|
+
return fontSizePx(h) < 24 || badge
|
|
78
|
+
}
|
|
79
|
+
return false
|
|
80
|
+
}
|
|
81
|
+
export const nearAbove = (label: ElementSnapshot, h: ElementSnapshot): boolean =>
|
|
82
|
+
label.rect.y + label.rect.height <= h.rect.y + 4 &&
|
|
83
|
+
h.rect.y - label.rect.y - label.rect.height <= Math.max(64, fontSizePx(h) * 2) &&
|
|
84
|
+
label.rect.x < h.rect.x + h.rect.width &&
|
|
85
|
+
label.rect.x + label.rect.width > h.rect.x
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ancestors, childrenOf, parentOf, styleOf } from "../../../core/page"
|
|
2
|
+
import type { ElementSnapshot, PageSnapshot } from "../../../types"
|
|
3
|
+
|
|
4
|
+
const tokens = (e: ElementSnapshot): readonly string[] => [...new Set((e.attributes["class"] ?? "").toLowerCase().split(/\s+/).filter(Boolean))]
|
|
5
|
+
const opacity = (s: PageSnapshot, e: ElementSnapshot): number =>
|
|
6
|
+
[e, ...ancestors(s, e)].reduce((value, n) => {
|
|
7
|
+
const own = Number.parseFloat(styleOf(n, "opacity"))
|
|
8
|
+
return value * (Number.isFinite(own) ? own : 1)
|
|
9
|
+
}, 1)
|
|
10
|
+
const transitionsOpacity = (e: ElementSnapshot): boolean => {
|
|
11
|
+
const times = styleOf(e, "transition-duration").split(",")
|
|
12
|
+
return styleOf(e, "transition-property").split(",").some((p, i) =>
|
|
13
|
+
["opacity", "all"].includes(p.trim()) && Number.parseFloat(times[i % times.length] ?? "0") > 0)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function pendingRaster(s: PageSnapshot, e: ElementSnapshot): boolean {
|
|
17
|
+
if (e.motion.includes("opacity")) return true
|
|
18
|
+
const chain = [e, ...ancestors(s, e)]
|
|
19
|
+
if (chain.slice(1).some(n => Number.parseFloat(styleOf(n, "opacity")) <= 0.02) ||
|
|
20
|
+
chain.some(n => styleOf(n, "display") === "none" || styleOf(n, "visibility") === "hidden")) return true
|
|
21
|
+
const attrs = e.attributes
|
|
22
|
+
if (attrs["data-loaded"]?.trim().toLowerCase() === "false" ||
|
|
23
|
+
(attrs["data-ll-status"] !== undefined && attrs["data-ll-status"].trim().toLowerCase() !== "loaded")) return true
|
|
24
|
+
if (["data-src", "data-srcset", "data-lazy", "data-lazy-src", "data-lazy-srcset", "data-original", "data-original-src"]
|
|
25
|
+
.some(name => attrs[name] !== undefined) && (attrs["src"] ?? "").trim() === "") return true
|
|
26
|
+
const parent = parentOf(s, e)
|
|
27
|
+
const classes = [e, ...(parent ? [parent] : [])].flatMap(tokens)
|
|
28
|
+
if (classes.some(t => t.includes("lazy")) && !classes.some(t => t.includes("loaded")) &&
|
|
29
|
+
(opacity(s, e) <= 0.02 || /(?:^|;)\s*opacity\s*:/i.test(attrs["style"] ?? ""))) return true
|
|
30
|
+
if (parent && opacity(s, e) <= 0.02) {
|
|
31
|
+
const videoOver = (n: ElementSnapshot, depth: number): boolean => {
|
|
32
|
+
const w = Math.min(e.rect.x + e.rect.width, n.rect.x + n.rect.width) - Math.max(e.rect.x, n.rect.x)
|
|
33
|
+
const h = Math.min(e.rect.y + e.rect.height, n.rect.y + n.rect.height) - Math.max(e.rect.y, n.rect.y)
|
|
34
|
+
if (n.tag === "video" && opacity(s, n) > 0.02 && [n, ...ancestors(s, n)].every(a =>
|
|
35
|
+
styleOf(a, "display") !== "none" && styleOf(a, "visibility") !== "hidden") &&
|
|
36
|
+
w > 0 && h > 0 && w * h >= e.rect.width * e.rect.height * 0.5) return true
|
|
37
|
+
return depth > 0 && childrenOf(s, n).some(child => videoOver(child, depth - 1))
|
|
38
|
+
}
|
|
39
|
+
if (parent.tag === "video" || childrenOf(s, parent).some(n => n.index !== e.index && videoOver(n, 3))) return true
|
|
40
|
+
}
|
|
41
|
+
if (e.tag !== "img" || opacity(s, e) > 0.02) return false
|
|
42
|
+
const own = tokens(e)
|
|
43
|
+
const peers = s.elements.filter(other => {
|
|
44
|
+
if (other.index === e.index || other.tag !== "img" || Number.parseFloat(styleOf(other, "opacity")) < 0.5 ||
|
|
45
|
+
opacity(s, other) <= 0.02 || !transitionsOpacity(other)) return false
|
|
46
|
+
const theirs = tokens(other)
|
|
47
|
+
const shared = own.filter(t => theirs.includes(t)).length
|
|
48
|
+
return shared > 0 && own.length - shared <= 1 && theirs.filter(t => !own.includes(t)).length === 1
|
|
49
|
+
})
|
|
50
|
+
return peers.length >= 2
|
|
51
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Rule } from "../rule"
|
|
2
|
+
import { COLOR_RULES } from "./color"
|
|
3
|
+
import { TYPOGRAPHY_RULES } from "./typography"
|
|
4
|
+
import { LAYOUT_RULES } from "./layout"
|
|
5
|
+
import { DECORATION_RULES } from "./decoration"
|
|
6
|
+
import { COPY_RULES } from "./copy"
|
|
7
|
+
import { SOURCE_RULES } from "./source"
|
|
8
|
+
|
|
9
|
+
export const ALL_RULES: readonly Rule[] = [
|
|
10
|
+
...COLOR_RULES,
|
|
11
|
+
...TYPOGRAPHY_RULES,
|
|
12
|
+
...LAYOUT_RULES,
|
|
13
|
+
...DECORATION_RULES,
|
|
14
|
+
...COPY_RULES,
|
|
15
|
+
...SOURCE_RULES,
|
|
16
|
+
]
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { childrenOf, fontSizePx, isIgnored, shortSnippet, styleOf } from "../../core/page"
|
|
2
|
+
import type { PageHit, PageRule } from "../../rule"
|
|
3
|
+
import { alpha, bounds, chain, clipsX, length, outOfFlow, painted, right, scrollsX, textLines } from "./support/geometry"
|
|
4
|
+
import { trackCuts } from "./support/clipping"
|
|
5
|
+
import { ridesRunningTrack } from "./support/motion"
|
|
6
|
+
|
|
7
|
+
export const bodyTextViewportEdge: PageRule = {
|
|
8
|
+
meta: {
|
|
9
|
+
id: "body-text-viewport-edge", name: "Body text touching viewport edge", category: "quality", severity: "warning", engine: "page",
|
|
10
|
+
description: "Reading text touches the viewport edge without a usable gutter.",
|
|
11
|
+
fixHint: "Keep at least 12px of horizontal space on phones and 16px on wider screens; constrain overflowing columns.",
|
|
12
|
+
},
|
|
13
|
+
check: ({ snapshot }) => {
|
|
14
|
+
const width = snapshot.viewport.width
|
|
15
|
+
const floor = width <= 480 ? 12 : 16
|
|
16
|
+
const hits: PageHit[] = []
|
|
17
|
+
let overflow = false
|
|
18
|
+
for (const el of snapshot.elements) {
|
|
19
|
+
if (isIgnored(snapshot, el, "body-text-viewport-edge")) continue
|
|
20
|
+
const prose = ["p", "li"].includes(el.tag)
|
|
21
|
+
const generic = ["div", "section", "article", "aside", "main"].includes(el.tag) &&
|
|
22
|
+
el.ownText !== "" && fontSizePx(el) < 28 && ["block", "flow-root"].includes(styleOf(el, "display")) &&
|
|
23
|
+
childrenOf(snapshot, el).every((c) => styleOf(c, "display") === "inline")
|
|
24
|
+
if (!(prose || generic) || el.text.length <= 40 || !painted(snapshot, el) || outOfFlow(el) ||
|
|
25
|
+
el.rect.width <= width * 0.5 || alpha(el, "background-color") > 0) continue
|
|
26
|
+
if (ridesRunningTrack(snapshot, el)) continue
|
|
27
|
+
const path = chain(snapshot, el)
|
|
28
|
+
if (generic && path.some((n) => /^(a|button|label|summary|select|textarea)$/.test(n.tag) ||
|
|
29
|
+
/^(button|link|tab|menuitem|option)$/.test(n.attributes["role"] ?? "") || n.attributes["contenteditable"] !== undefined)) continue
|
|
30
|
+
if (path.some((n) => n.tag === "nav" || n.tag === "header" && n.rect.height <= snapshot.viewport.height ||
|
|
31
|
+
scrollsX(n) || /^(pre|pre-wrap)$/.test(styleOf(n, "white-space")))) continue
|
|
32
|
+
const lines = textLines(snapshot, el)
|
|
33
|
+
const text = bounds(lines)
|
|
34
|
+
if (!text && generic) continue
|
|
35
|
+
if (text && trackCuts(snapshot, el, text)) continue
|
|
36
|
+
let left = text?.x ?? el.rect.x
|
|
37
|
+
let end = text ? right(text) : right(el.rect)
|
|
38
|
+
if (clipsX(el) && !["", "clip"].includes(styleOf(el, "text-overflow"))) {
|
|
39
|
+
left = Math.max(left, el.rect.x)
|
|
40
|
+
end = Math.min(end, right(el.rect))
|
|
41
|
+
}
|
|
42
|
+
const contentLeft = el.rect.x + length(el, "padding-left") + length(el, "border-left-width")
|
|
43
|
+
const contentEnd = right(el.rect) - length(el, "padding-right") - length(el, "border-right-width")
|
|
44
|
+
if (text && lines.length >= 2 && text.width >= (contentEnd - contentLeft) * 0.9 &&
|
|
45
|
+
!(styleOf(el, "text-align") !== "justify" && left >= 16 && end <= width - 16)) {
|
|
46
|
+
left = contentLeft
|
|
47
|
+
end = contentEnd
|
|
48
|
+
} else if (styleOf(el, "display") === "list-item") {
|
|
49
|
+
left = Math.min(left, contentLeft)
|
|
50
|
+
}
|
|
51
|
+
if (end <= 0 || left >= width) continue
|
|
52
|
+
if (path.slice(1).some((n) => styleOf(n, "position") === "fixed" && n.rect.height < snapshot.viewport.height / 2) && Math.min(left, width - end) >= 4) continue
|
|
53
|
+
if (Math.round(-left) > 0 || Math.round(end - width) > 0) overflow = true
|
|
54
|
+
if (Math.round(left) >= 0 && left < floor || Math.round(width - end) >= 0 && width - end < floor) hits.push({ element: el, message: `Body copy keeps less than ${floor}px from the viewport edge.`, snippet: shortSnippet(el) })
|
|
55
|
+
}
|
|
56
|
+
if (overflow) {
|
|
57
|
+
const widest = snapshot.elements.filter((el) => painted(snapshot, el) && !chain(snapshot, el).some(scrollsX)).sort((a, b) => right(b.rect) - right(a.rect))[0]
|
|
58
|
+
hits.push({ element: null, message: `Body text runs outside the viewport${widest ? `; widest element ${widest.selector} ends at ${right(widest.rect)}px` : ""}.`, snippet: widest ? shortSnippet(widest) : "Page overflow" })
|
|
59
|
+
}
|
|
60
|
+
return hits
|
|
61
|
+
},
|
|
62
|
+
}
|