| name | css-style-sync |
|---|---|
| description | Use this skill whenever a user wants to compare CSS computed styles between two webapps (e.g. a legacy app and its replacement, a staging vs. production build, or any "old vs. new" pair) and fix style discrepancies. Triggers when the user mentions comparing styles between two URLs, fixing visual regressions after a migration or rewrite, or syncing CSS from an old site to a new one. Also triggers for phrases like "same styles as legacy", "match the original design", "computed style diff", "CSS doesn't match", or any request to extract and compare computed styles between two pages/selectors. Always use this skill — it runs Playwright automatically to extract styles without the user needing to open DevTools. This skill is app-agnostic: it never assumes a specific framework, port, or URL, and always interviews the user for both targets before running. |
CSS Style Sync Skill
Compares computed CSS between two webapps ("legacy"/source and "new"/target) using Playwrigh
| // More than a decade ago, I adopted jQuery-style formatting, and I still use it in my JavaScript today. | |
| // I find that common style like fn(1,[1,2,{a:1}]) is less readable than fn( 1, [ 1, 2, { a: 1 } ] ). | |
| // Below are examples of code that will trigger ESLint warnings about missing surrounding spaces. | |
| const array = [1,2,3]; // should report missing space after '[' and before ']' | |
| const obj = {a:1,b:2}; // should report missing space after '{' and before '}' | |
| const arrayNested = [[ 1 ], { a: 1 }]; // however, nested array should report only inner brackets (this statement is correct) | |
| if(foo){ return; } // missing spaces |
| import React from "react"; | |
| import http from "http"; | |
| import fs from "fs"; | |
| import { join } from "path"; | |
| import express from "express"; | |
| import bodyParser from "body-parser"; | |
| import { default as Busboy } from "busboy"; | |
| const app = express(), |
| /** | |
| * @returns Image[] | |
| */ | |
| function getIncompleteImages() { | |
| return Array.from( document.querySelectorAll( "img" ) ) | |
| .filter( img => !img.complete || img.naturalWidth === 0 ); | |
| } | |
| /** | |
| * Execute the given callback when all the images in the document loaded | |
| * We call this function when markup with images is rendered but images are still loading |
| #! /bin/bash | |
| version=`git diff HEAD^..HEAD -- "$(git rev-parse --show-toplevel)"/package.json | grep -m 1 '^\+.*version' | sed -s 's/[^A-Z0-9\.\-]//g'` | |
| if [[ ! $version =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(\-[A-Z]+\.[0-9]+)?$ ]]; then | |
| echo -e "Skip tag: invalid version '$version'" | |
| exit 1 | |
| fi | |
| git tag -a "v$version" -m "`git log -1 --format=%s`" | |
| echo "Created a new tag, v$version" |
| function loadJs(url){ | |
| return new Promise( (resolve, reject) => { | |
| if (document.querySelector(`head > script[src="${src}"]`) !== null) return resolve() | |
| const script = document.createElement("script") | |
| script.src = url | |
| script.onload = resolve | |
| script.onerror = reject | |
| document.head.appendChild(script) | |
| }); | |
| } |
| function getCookie( name ) { | |
| const value = "; " + document.cookie, | |
| parts = value.split( "; " + name + "=" ); | |
| if ( parts.length === 2 ) { | |
| return parts.pop().split( ";" ).shift(); | |
| } | |
| return null; | |
| } |
| /* | |
| Usage: | |
| <If exp={ true }> components to render </If> | |
| <If exp={ false }> components not to render </If> | |
| */ | |
| import React from "react"; | |
| import PropTypes from "prop-types"; | |
| export default class If extends React.Component { |
| function isPrivateMode() { | |
| return new Promise((resolve) => { | |
| const on = function(){ resolve( true ); } | |
| const off = function(){ resolve(false); } | |
| const testLocalStorage = function(){ | |
| try { | |
| if ( localStorage.length ) { | |
| off(); | |
| return; | |
| } |
| #!/bin/bash | |
| STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep ".*Marketplace.*\.js$") | |
| if [[ "$STAGED_FILES" = "" ]]; then | |
| exit 0 | |
| fi | |
| PASS=true |