diff --git a/packages/@n8n/stylelint-config/src/rules/css-var-naming.test.ts b/packages/@n8n/stylelint-config/src/rules/css-var-naming.test.ts index 54b92db4752..f3fbb8e8a8b 100644 --- a/packages/@n8n/stylelint-config/src/rules/css-var-naming.test.ts +++ b/packages/@n8n/stylelint-config/src/rules/css-var-naming.test.ts @@ -22,9 +22,9 @@ describe('css-var-naming rule', () => { const namespacePattern = ` :root { --n8n--color--primary: #0d6efd; - --n8n--button--background--primary: #0d6efd; - --n8n--button--background--primary--hover: #0b5ed7; - --n8n--text-color--muted: #888; + --n8n--button--color--background--primary: #0d6efd; + --n8n--button--color--background--primary--hover: #0b5ed7; + --n8n--color--text--muted: #888; } `; const result = await lintCSS(namespacePattern); @@ -35,8 +35,8 @@ describe('css-var-naming rule', () => { const namespacePattern = ` :root { --chat--color--primary: #0d6efd; - --chat--button--background--primary: #0d6efd; - --chat--text-color--base: #333; + --chat--button--color--background--primary: #0d6efd; + --chat--color--text--base: #333; } `; const result = await lintCSS(namespacePattern); @@ -60,7 +60,7 @@ describe('css-var-naming rule', () => { const noNamespace = ` :root { --color--primary: #0d6efd; - --button--background--primary: #0d6efd; + --button--color--background--primary: #0d6efd; } `; const result = await lintCSS(noNamespace); @@ -73,7 +73,7 @@ describe('css-var-naming rule', () => { // Other first groups are treated as components, which is valid const componentFirst = ` :root { - --button--background--primary: #0d6efd; + --button--color--background--primary: #0d6efd; --tabs--tab--color--base: #333; } `; @@ -84,7 +84,7 @@ describe('css-var-naming rule', () => { it('should accept namespace with component and states', async () => { const complexNamespace = ` :root { - --n8n--button--background--primary--solid--hover: #0b5ed7; + --n8n--button--color--background--primary--solid--hover: #0b5ed7; --chat--input--border-color--primary--focus: blue; } `; @@ -95,7 +95,7 @@ describe('css-var-naming rule', () => { it('should accept namespace with all 8 groups', async () => { const maxGroups = ` :root { - --n8n--button--part--text-color--primary--solid--hover--dark: #000; + --n8n--button--part--color--text--primary--solid--hover--dark: #000; } `; const result = await lintCSS(maxGroups); @@ -108,8 +108,8 @@ describe('css-var-naming rule', () => { const validPatterns = ` :root { --color--primary: #0d6efd; - --text-color--muted: #5b6270; - --background--surface: #ffffff; + --color--text--muted: #5b6270; + --color--background--surface: #ffffff; --spacing--md: 20px; --font-size--lg: 18px; } @@ -204,10 +204,10 @@ describe('css-var-naming rule', () => { expect(result.warnings.length).toBeGreaterThan(0); }); - it('should reject patterns with more than 8 groups', async () => { + it('should reject patterns with more than 10 groups', async () => { const invalidPattern = ` :root { - --a--b--c--d--e--f--g--h--i: value; + --a--b--c--d--e--f--g--h--i--j--k: value; } `; const result = await lintCSS(invalidPattern); @@ -237,14 +237,16 @@ describe('css-var-naming rule', () => { const validProperties = ` :root { --color--primary: #0d6efd; - --text-color--base: #333; - --background--light: #fff; + --color--text--base: #333; + --color--background--light: #fff; + --color--foreground--light: #f5f5f5; --border-color--primary: #ddd; - --border-width--thin: 1px; + --border-left-width--thin: 1px; --icon-color--muted: #888; --radius--md: 4px; --shadow--sm: 0 1px 2px rgba(0,0,0,0.1); --spacing--lg: 24px; + --padding--lg: 24px; --font-size--md: 16px; --font-weight--bold: 600; --line-height--normal: 1.5; @@ -281,18 +283,238 @@ describe('css-var-naming rule', () => { const result = await lintCSS(invalidProperty); expect(result.warnings.length).toBeGreaterThan(0); }); + + it('should reject primary semantic value before property', async () => { + const invalidOrder = ` + :root { + --primary--color: #0d6efd; + } + `; + const result = await lintCSS(invalidOrder); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject secondary semantic value before property', async () => { + const invalidOrder = ` + :root { + --secondary--color: #6c757d; + } + `; + const result = await lintCSS(invalidOrder); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject success semantic value before property', async () => { + const invalidOrder = ` + :root { + --success--color: #28a745; + } + `; + const result = await lintCSS(invalidOrder); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject danger semantic value before property', async () => { + const invalidOrder = ` + :root { + --danger--color: #dc3545; + } + `; + const result = await lintCSS(invalidOrder); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject md scale value before property', async () => { + const invalidOrder = ` + :root { + --md--spacing: 20px; + } + `; + const result = await lintCSS(invalidOrder); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject lg scale value before property', async () => { + const invalidOrder = ` + :root { + --lg--font-size: 18px; + } + `; + const result = await lintCSS(invalidOrder); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject xl scale value before property', async () => { + const invalidOrder = ` + :root { + --xl--radius: 12px; + } + `; + const result = await lintCSS(invalidOrder); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject component with primary value before color property', async () => { + const invalidOrder = ` + :root { + --button--primary--color: #0d6efd; + } + `; + const result = await lintCSS(invalidOrder); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject component with surface value before color--background property', async () => { + const invalidOrder = ` + :root { + --card--surface--color--background: #fff; + } + `; + const result = await lintCSS(invalidOrder); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject namespace with primary value before color property', async () => { + const invalidOrder = ` + :root { + --n8n--primary--color: #0d6efd; + } + `; + const result = await lintCSS(invalidOrder); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject namespace with muted value before color--text property', async () => { + const invalidOrder = ` + :root { + --chat--muted--color--text: #888; + } + `; + const result = await lintCSS(invalidOrder); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject invalid single-dash color-text format', async () => { + const invalidFormat = ` + :root { + --color-text--primary: #0d6efd; + } + `; + const result = await lintCSS(invalidFormat); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('Must include a valid property from vocabulary'), + }); + }); + + it('should reject invalid single-dash color-background format', async () => { + const invalidFormat = ` + :root { + --color-background--surface: #fff; + } + `; + const result = await lintCSS(invalidFormat); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('Must include a valid property from vocabulary'), + }); + }); + + it('should reject invalid single-dash color-foreground format', async () => { + const invalidFormat = ` + :root { + --color-foreground--light: #f5f5f5; + } + `; + const result = await lintCSS(invalidFormat); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('Must include a valid property from vocabulary'), + }); + }); + + it('should reject component with invalid single-dash color-text format', async () => { + const invalidFormat = ` + :root { + --button--color-text--primary: #0d6efd; + } + `; + const result = await lintCSS(invalidFormat); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('Must include a valid property from vocabulary'), + }); + }); + + it('should reject component with invalid single-dash color-background format', async () => { + const invalidFormat = ` + :root { + --card--color-background--surface: #fff; + } + `; + const result = await lintCSS(invalidFormat); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('Must include a valid property from vocabulary'), + }); + }); + + it('should accept valid double-dash format for color properties', async () => { + const validFormat = ` + :root { + --color--text--primary: #0d6efd; + --color--background--surface: #fff; + --color--foreground--light: #f5f5f5; + } + `; + const result = await lintCSS(validFormat); + expect(result.warnings).toHaveLength(0); + }); }); describe('component tokens', () => { it('should accept component-level tokens', async () => { const componentTokens = ` :root { - --button--background--primary: #0d6efd; - --button--text-color--on-primary: #fff; + --button--color--background--primary: #0d6efd; + --button--color--text--on-primary: #fff; --button--border-color--outline: #ddd; --card--radius--md: 8px; - --tabs--tab--text-color--muted: #888; - --select--menu--background--dark: #000; + --tabs--tab--color--text--muted: #888; + --select--menu--color--background--dark: #000; --tooltip--arrow--color--primary: #333; } `; @@ -303,7 +525,7 @@ describe('css-var-naming rule', () => { it('should accept component with part tokens', async () => { const componentPartTokens = ` :root { - --tabs--tab--background--surface: #fff; + --tabs--tab--color--background--surface: #fff; --select--menu--shadow--lg: 0 4px 8px rgba(0,0,0,0.1); --tooltip--arrow--border-color--primary: #ddd; } @@ -311,22 +533,59 @@ describe('css-var-naming rule', () => { const result = await lintCSS(componentPartTokens); expect(result.warnings).toHaveLength(0); }); + + it('should reject callout with secondary before icon-color property', async () => { + const invalidCalloutTokens = ` + :root { + --callout--secondary--icon-color: #0d6efd; + } + `; + const result = await lintCSS(invalidCalloutTokens); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should reject callout with secondary before color--text property', async () => { + const invalidCalloutTokens = ` + :root { + --callout--secondary--color--text: #888; + } + `; + const result = await lintCSS(invalidCalloutTokens); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('appears before the property'), + }); + }); + + it('should accept callout component tokens with property before value', async () => { + const validCalloutTokens = ` + :root { + --callout--icon-color--secondary: #0d6efd; + --callout--color--text--secondary: #888; + } + `; + const result = await lintCSS(validCalloutTokens); + expect(result.warnings).toHaveLength(0); + }); }); describe('states validation', () => { it('should accept valid state modifiers', async () => { const stateModifiers = ` :root { - --button--background--primary--hover: #0b5ed7; - --button--background--primary--active: #0a58ca; - --button--background--primary--focus: #0d6efd; - --button--background--primary--focus-visible: #0d6efd; - --button--background--primary--disabled: #ccc; + --button--color--background--primary--hover: #0b5ed7; + --button--color--background--primary--active: #0a58ca; + --button--color--background--primary--focus: #0d6efd; + --button--color--background--primary--focus-visible: #0d6efd; + --button--color--background--primary--disabled: #ccc; --input--border-color--primary--invalid: red; - --checkbox--background--primary--checked: #0d6efd; - --select--background--surface--opened: #fff; - --accordion--background--surface--closed: #f5f5f5; - --button--background--primary--loading: #999; + --checkbox--color--background--primary--checked: #0d6efd; + --select--color--background--surface--opened: #fff; + --accordion--color--background--surface--closed: #f5f5f5; + --button--color--background--primary--loading: #999; } `; const result = await lintCSS(stateModifiers); @@ -336,8 +595,8 @@ describe('css-var-naming rule', () => { it('should accept link-specific states', async () => { const linkStates = ` :root { - --link--text-color--primary--visited: purple; - --link--text-color--primary--hover: blue; + --link--color--text--primary--visited: purple; + --link--color--text--primary--hover: blue; } `; const result = await lintCSS(linkStates); @@ -349,12 +608,12 @@ describe('css-var-naming rule', () => { it('should accept valid variant modifiers', async () => { const variantModifiers = ` :root { - --button--background--primary--solid: #0d6efd; - --button--background--primary--outline: transparent; - --button--background--primary--ghost: transparent; - --button--background--primary--link: transparent; - --button--background--primary--soft: #e7f1ff; - --button--background--primary--subtle: #f0f8ff; + --button--color--background--primary--solid: #0d6efd; + --button--color--background--primary--outline: transparent; + --button--color--background--primary--ghost: transparent; + --button--color--background--primary--link: transparent; + --button--color--background--primary--soft: #e7f1ff; + --button--color--background--primary--subtle: #f0f8ff; } `; const result = await lintCSS(variantModifiers); @@ -364,9 +623,9 @@ describe('css-var-naming rule', () => { it('should accept variants with states (variant before state)', async () => { const variantWithState = ` :root { - --button--background--primary--solid--hover: #0b5ed7; - --button--background--primary--outline--active: #0a58ca; - --button--background--primary--ghost--focus: rgba(13, 110, 253, 0.1); + --button--color--background--primary--solid--hover: #0b5ed7; + --button--color--background--primary--outline--active: #0a58ca; + --button--color--background--primary--ghost--focus: rgba(13, 110, 253, 0.1); } `; const result = await lintCSS(variantWithState); @@ -376,7 +635,7 @@ describe('css-var-naming rule', () => { it('should reject when state comes before variant', async () => { const invalidOrder = ` :root { - --button--background--primary--hover--solid: #0b5ed7; + --button--color--background--primary--hover--solid: #0b5ed7; } `; const result = await lintCSS(invalidOrder); @@ -393,9 +652,9 @@ describe('css-var-naming rule', () => { :root { --color--primary--dark: #66a3ff; --color--primary--light: #0d6efd; - --background--surface--dark: #000; - --background--surface--light: #fff; - --text-color--base--hc: #000; + --color--background--surface--dark: #000; + --color--background--surface--light: #fff; + --color--text--base--hc: #000; --spacing--md--rtl: 20px; --color--primary--print: #000; } @@ -479,14 +738,15 @@ describe('css-var-naming rule', () => { expect(result.warnings).toHaveLength(0); }); - it('should accept descriptive value names (4+ chars)', async () => { + it('should accept descriptive value names (3+ chars)', async () => { const descriptiveValues = ` :root { --color--purple: #800080; - --text-color--base: #333; - --border-width--thin: 1px; + --color--text--base: #333; + --border-left-width--thin: 1px; --z--modal: 1000; --duration--fast: 200ms; + --spacing--med: 20px; } `; const result = await lintCSS(descriptiveValues); @@ -520,10 +780,10 @@ describe('css-var-naming rule', () => { }); }); - it('should reject very short value names (<4 chars)', async () => { + it('should reject very short value names (<3 chars)', async () => { const shortValue = ` :root { - --spacing--xxx: 20px; + --spacing--xx: 20px; } `; const result = await lintCSS(shortValue); @@ -548,21 +808,202 @@ describe('css-var-naming rule', () => { it('should accept component names as values', async () => { const componentValues = ` :root { - --button--background--surface: #fff; - --tooltip--text-color--on-surface: #000; + --button--color--background--surface: #fff; + --tooltip--color--text--on-surface: #000; } `; const result = await lintCSS(componentValues); expect(result.warnings).toHaveLength(0); }); + + it('should accept HSL color component values (h, s, l)', async () => { + const hslValues = ` + :root { + --color--primary--h: 220; + --color--primary--s: 90%; + --color--primary--l: 50%; + --color--background--surface--h: 0; + --color--background--surface--s: 0%; + --color--background--surface--l: 100%; + } + `; + const result = await lintCSS(hslValues); + expect(result.warnings).toHaveLength(0); + }); + + it('should accept HSL color components with component names', async () => { + const hslComponentValues = ` + :root { + --node-type--color--background--l: 50%; + --node-type--color--h: 220; + --button--color--background--s: 90%; + } + `; + const result = await lintCSS(hslComponentValues); + expect(result.warnings).toHaveLength(0); + }); + + it('should reject HSL component h in middle position', async () => { + const invalidHsl = ` + :root { + --color--h--primary: 220; + } + `; + const result = await lintCSS(invalidHsl); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('HSL component'), + }); + }); + + it('should reject HSL component s in middle position', async () => { + const invalidHsl = ` + :root { + --color--s--primary: 90%; + } + `; + const result = await lintCSS(invalidHsl); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('HSL component'), + }); + }); + + it('should reject HSL component l in middle position', async () => { + const invalidHsl = ` + :root { + --color--l--primary: 50%; + } + `; + const result = await lintCSS(invalidHsl); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('HSL component'), + }); + }); + + it('should reject HSL component in middle with component name', async () => { + const invalidHsl = ` + :root { + --button--color--h--primary: 220; + } + `; + const result = await lintCSS(invalidHsl); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('HSL component'), + }); + }); + + it('should reject HSL component in middle with state', async () => { + const invalidHsl = ` + :root { + --button--color--l--primary--hover: 50%; + } + `; + const result = await lintCSS(invalidHsl); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('HSL component'), + }); + }); + + it('should accept HSL components at the end with states', async () => { + const validHsl = ` + :root { + --button--color--background--primary--hover--l: 50%; + --button--color--background--primary--h: 220; + } + `; + const result = await lintCSS(validHsl); + expect(result.warnings).toHaveLength(0); + }); + + it('should reject group ending with -h in middle position', async () => { + const invalidHsl = ` + :root { + --color--primary-h--base: 220; + } + `; + const result = await lintCSS(invalidHsl); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('HSL component'), + }); + }); + + it('should reject group ending with -s in middle position', async () => { + const invalidHsl = ` + :root { + --color--primary-s--base: 90%; + } + `; + const result = await lintCSS(invalidHsl); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('HSL component'), + }); + }); + + it('should reject group ending with -l in middle position', async () => { + const invalidHsl = ` + :root { + --color--primary-l--base: 50%; + } + `; + const result = await lintCSS(invalidHsl); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('HSL component'), + }); + }); + + it('should reject component with group ending with -h in middle', async () => { + const invalidHsl = ` + :root { + --button--color--primary-h--hover: 220; + } + `; + const result = await lintCSS(invalidHsl); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('HSL component'), + }); + }); + + it('should reject group ending with -h at the end', async () => { + const invalidHsl = ` + :root { + --color--primary-h: 220; + } + `; + const result = await lintCSS(invalidHsl); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('HSL component'), + }); + }); + + it('should reject component with group ending with -h at the end', async () => { + const invalidHsl = ` + :root { + --button--color--primary-h: 220; + } + `; + const result = await lintCSS(invalidHsl); + expect(result.warnings.length).toBeGreaterThan(0); + expect(result.warnings[0]).toMatchObject({ + text: expect.stringContaining('HSL component'), + }); + }); }); describe('var() references validation', () => { it('should validate CSS variables in var() references', async () => { const varReferences = ` .button { - background: var(--button--background--primary); - color: var(--button--text-color--on-primary); + background: var(--button--color--background--primary); + color: var(--button--color--text--on-primary); border-color: var(--button--border-color--outline); } `; @@ -573,13 +1014,13 @@ describe('css-var-naming rule', () => { it('should reject invalid CSS variables in var() references', async () => { const invalidVarReferences = ` .button { - background: var(--button-background); + background: var(--button-color--background); } `; const result = await lintCSS(invalidVarReferences); expect(result.warnings.length).toBeGreaterThan(0); expect(result.warnings[0]).toMatchObject({ - text: expect.stringContaining('Must have at least 2 groups'), + text: expect.stringContaining('Must include a valid property'), }); }); @@ -599,7 +1040,7 @@ describe('css-var-naming rule', () => { it('should reject invalid CSS variables with mixed order in var() references', async () => { const invalidVarReferences = ` .button { - background: var(--button--background--primary--hover--solid); + background: var(--button--color--background--primary--hover--solid); } `; const result = await lintCSS(invalidVarReferences); @@ -612,7 +1053,7 @@ describe('css-var-naming rule', () => { it('should accept var() with fallback values', async () => { const varWithFallback = ` .button { - background: var(--button--background--primary, var(--color--primary)); + background: var(--button--color--background--primary, var(--color--primary)); border-radius: var(--button--radius--md, var(--radius--md)); } `; @@ -625,15 +1066,15 @@ describe('css-var-naming rule', () => { it('should accept all examples from proposal section 6', async () => { const proposalExamples = ` .button { - background: var(--button--background--primary); - color: var(--button--text-color--on-primary); + background: var(--button--color--background--primary); + color: var(--button--color--text--on-primary); border-color: var(--button--border-color--ghost); border-radius: var(--button--radius--md, var(--radius--md)); box-shadow: var(--button--shadow--sm, var(--shadow--sm)); } .button:hover { - background: var(--button--background--primary--hover); + background: var(--button--color--background--primary--hover); } .input:focus-visible { @@ -641,7 +1082,7 @@ describe('css-var-naming rule', () => { } .card { - background: var(--card--background--surface, var(--color--surface)); + background: var(--card--color--background--surface, var(--color--surface)); box-shadow: var(--card--shadow--lg, var(--shadow--lg)); } `; @@ -654,15 +1095,15 @@ describe('css-var-naming rule', () => { :root { --color--primary: #0d6efd; --color--surface: #ffffff; - --text-color--muted: #5b6270; - --button--background--primary: var(--color--primary); - --button--text-color--on-primary: #ffffff; + --color--text--muted: #5b6270; + --button--color--background--primary: var(--color--primary); + --button--color--text--on-primary: #ffffff; } :root[data-theme="dark"] { --color--primary: #66a3ff; --color--surface: #0f1115; - --text-color--muted: #9aa3b2; + --color--text--muted: #9aa3b2; } `; const result = await lintCSS(themingExample); @@ -696,7 +1137,8 @@ describe('css-var-naming rule', () => { --menu--tab--radius: 4px; --card--shadow: 0 2px 4px rgba(0, 0, 0, 0.1); --input--border-style: solid; - --input--border-width: 1px; + --input--border-left-width: 1px; + --button--padding--md: 12px; } `; const result = await lintCSS(componentShorthand); @@ -720,7 +1162,7 @@ describe('css-var-naming rule', () => { it('should accept kebab-case within groups', async () => { const kebabCase = ` :root { - --text-color--on-primary: #fff; + --color--text--on-primary: #fff; --outline-color--focus-visible: blue; --font-weight--semi-bold: 600; } @@ -743,7 +1185,7 @@ describe('css-var-naming rule', () => { it('should accept maximum valid pattern (8 groups)', async () => { const maximumPattern = ` :root { - --namespace--component--part--text-color--primary--solid--hover--dark: #000; + --namespace--component--part--color--text--primary--solid--hover--dark: #000; } `; const result = await lintCSS(maximumPattern); diff --git a/packages/@n8n/stylelint-config/src/rules/css-var-naming.ts b/packages/@n8n/stylelint-config/src/rules/css-var-naming.ts index 6fd6eb06289..d19c2de2883 100644 --- a/packages/@n8n/stylelint-config/src/rules/css-var-naming.ts +++ b/packages/@n8n/stylelint-config/src/rules/css-var-naming.ts @@ -12,18 +12,26 @@ const meta = { }; // Reserved vocabulary from proposal.md +// NOTE: color--text, color--background, color--foreground use double dashes +// to separate "color" from the subtype (text/background/foreground) const PROPERTY_VOCABULARY = new Set([ 'color', - 'text-color', - 'background', + 'color--text', + 'color--background', + 'color--foreground', 'border-color', - 'border-width', + 'border-top-color', + 'border-bottom-color', + 'border-right-color', + 'border-left-width', 'border-style', 'border', + 'height', 'icon-color', 'radius', 'shadow', 'spacing', + 'padding', 'font-size', 'font-weight', 'font-family', @@ -104,7 +112,8 @@ const SCALE_VALUES = new Set([ const FONT_WEIGHT_VALUES = new Set(['regular', 'medium', 'semibold', 'bold']); // Regex for basic validation -const BASIC_PATTERN = /^--[a-z0-9]+(?:-[a-z0-9]+)*(?:--[a-z0-9]+(?:-[a-z0-9]+)*){1,7}$/; +// Allows 2-10 groups to accommodate double-dash properties like color--text +const BASIC_PATTERN = /^--[a-z0-9]+(?:-[a-z0-9]+)*(?:--[a-z0-9]+(?:-[a-z0-9]+)*){1,9}$/; interface ValidationResult { valid: boolean; @@ -137,7 +146,7 @@ function validateCssVariable(variable: string): ValidationResult { }; } - // Check group count (2-8 groups) + // Check group count (2-10 groups to accommodate double-dash properties like color--text) if (groups.length < 2) { return { valid: false, @@ -145,10 +154,10 @@ function validateCssVariable(variable: string): ValidationResult { }; } - if (groups.length > 8) { + if (groups.length > 10) { return { valid: false, - reason: 'Must have at most 8 groups (too many segments)', + reason: 'Must have at most 10 groups (too many segments)', }; } @@ -186,9 +195,50 @@ function validateCssVariable(variable: string): ValidationResult { .findIndex((group) => PROPERTY_VOCABULARY.has(group)); const absolutePropertyIndex = startIndex + propertyIndex; + // Check if any semantic or scale values appear before the property + const groupsBeforeProperty = groups.slice(startIndex, absolutePropertyIndex); + for (const group of groupsBeforeProperty) { + // Check if this group is a semantic value, scale value, or font-weight value + if (SEMANTIC_VALUES.has(group) || SCALE_VALUES.has(group) || FONT_WEIGHT_VALUES.has(group)) { + return { + valid: false, + reason: `Value "${group}" appears before the property. Values must come after the property (e.g., --color--${group}, not --${group}--color)`, + }; + } + } + // Get the property name to validate specific property-value combinations const propertyName = groups[absolutePropertyIndex]; + // Check if HSL components (h, s, l) appear in non-final positions or as suffixes + const hslComponents = new Set(['h', 's', 'l']); + + // Check all groups after property for HSL-related issues + for (let i = absolutePropertyIndex + 1; i < groups.length; i++) { + const group = groups[i]; + const isLastGroup = i === groups.length - 1; + + // Check if group is exactly h, s, or l (allowed only at the end) + if (hslComponents.has(group)) { + if (!isLastGroup) { + return { + valid: false, + reason: `HSL component "${group}" must be at the end of the variable name (e.g., --color--primary--${group}, not --color--${group}--primary)`, + }; + } + // If it's the last group and exactly h/s/l, it's valid + continue; + } + + // Check if group ends with -h, -s, or -l (never allowed) + if (group.endsWith('-h') || group.endsWith('-s') || group.endsWith('-l')) { + return { + valid: false, + reason: `HSL component suffix in "${group}" is not allowed. Use standalone HSL components instead (e.g., --color--primary--h, not --color--primary-h)`, + }; + } + } + // The group after property should be a value (semantic or scale) if (absolutePropertyIndex + 1 < groups.length) { const valueGroup = groups[absolutePropertyIndex + 1]; @@ -220,8 +270,10 @@ function validateCssVariable(variable: string): ValidationResult { FONT_WEIGHT_VALUES.has(valueGroup) || // Allow color shades like "primary-500", "shade-50", "tint-50" /^[a-z]+-\d+$/.test(valueGroup) || - // Allow descriptive names (4+ chars) - these are likely intentional semantic names - valueGroup.length >= 4; + // Allow descriptive names (3+ chars) - these are likely intentional semantic names + valueGroup.length >= 3 || + // Support hsl css variables (only allowed at the end, checked above) + hslComponents.has(valueGroup); if (!isValidValue) { return { diff --git a/packages/frontend/@n8n/chat/package.json b/packages/frontend/@n8n/chat/package.json index 0a036e964ef..964196da41d 100644 --- a/packages/frontend/@n8n/chat/package.json +++ b/packages/frontend/@n8n/chat/package.json @@ -12,8 +12,8 @@ "typecheck": "vue-tsc --noEmit", "lint": "eslint src --quiet", "lint:fix": "eslint src --fix", - "lint:styles": "stylelint \"src/**/*.{scss,sass,vue}\" --cache --custom-formatter ../../../../packages/@n8n/stylelint-config/dist/formatter-summary.js", - "lint:styles:fix": "stylelint \"src/**/*.{scss,sass,vue}\" --fix --cache --custom-formatter $(pwd)/../../../../packages/@n8n/stylelint-config/dist/formatter-summary.js", + "lint:styles": "stylelint \"src/**/*.{scss,sass,vue}\" --cache", + "lint:styles:fix": "stylelint \"src/**/*.{scss,sass,vue}\" --fix --cache", "format": "biome format --write src .storybook && prettier --write src/ --ignore-path ../../../../.prettierignore", "format:check": "biome ci src .storybook && prettier --check src/ --ignore-path ../../../../.prettierignore", "storybook": "storybook dev -p 6006 --no-open", diff --git a/packages/frontend/@n8n/chat/stylelint.config.mjs b/packages/frontend/@n8n/chat/stylelint.config.mjs index a86e148c672..13a9b07ab57 100644 --- a/packages/frontend/@n8n/chat/stylelint.config.mjs +++ b/packages/frontend/@n8n/chat/stylelint.config.mjs @@ -1,3 +1,13 @@ import { baseConfig } from '@n8n/stylelint-config/base'; -export default baseConfig; +export default { + ...baseConfig, + rules: { + ...baseConfig.rules, + // Disable css-var-naming rule for chat package + // Because most var names seem to be breaking + // And it needs to continue to be backwards compatible + // As users could be using it directly on websites and customizing css variables + '@n8n/css-var-naming': null, + }, +}; diff --git a/scripts/replace-css-tokens.sh b/scripts/replace-css-tokens.sh index 09ef054c943..83fe5488576 100644 --- a/scripts/replace-css-tokens.sh +++ b/scripts/replace-css-tokens.sh @@ -10,8 +10,11 @@ FRONTEND_DIR="./packages/frontend" echo "Finding files to process..." files=$(find "$FRONTEND_DIR" -type f \( -name "*.css" -o -name "*.scss" -o -name "*.vue" -o -name "*.ts" -o -name "*.snap" -o -name "*.test.ts" -o -name "*.js" -o -name "*.md" \) ! -path "*/node_modules/*" ! -path "*/dist/*" ! -path "*/.vite/*" ! -path "*/_tokens.scss" ! -path "*/_tokens.dark.scss" ! -path "*/_tokens.deprecated.scss" ! -path "*/_tokens.dark.deprecated.scss") +# _tokens file only +#files=$(find "$FRONTEND_DIR" -type f \( -name "_tokens.scss" \)) + file_count=$(echo "$files" | wc -l | xargs) -echo "Found $file_count files to process" +echo "Found $file_count files to process test $files" echo "" echo "Starting token replacements..." echo "" @@ -22,9 +25,12 @@ echo "$files" | xargs perl -pi -e 's/--color-primary-shade-1/--color--primary--s echo "$files" | xargs perl -pi -e 's/--color-primary-tint-3/--color--primary--tint-3/g' echo "$files" | xargs perl -pi -e 's/--color-primary-tint-2/--color--primary--tint-2/g' echo "$files" | xargs perl -pi -e 's/--color-primary-tint-1/--color--primary--tint-1/g' -echo "$files" | xargs perl -pi -e 's/--color-primary-h/--color--primary-h/g' -echo "$files" | xargs perl -pi -e 's/--color-primary-s/--color--primary-s/g' -echo "$files" | xargs perl -pi -e 's/--color-primary-l/--color--primary-l/g' +echo "$files" | xargs perl -pi -e 's/--color--primary-h/--color--primary--h/g' +echo "$files" | xargs perl -pi -e 's/--color--primary-s/--color--primary--s/g' +echo "$files" | xargs perl -pi -e 's/--color--primary-l/--color--primary--l/g' +echo "$files" | xargs perl -pi -e 's/--color-primary-h/--color--primary--h/g' +echo "$files" | xargs perl -pi -e 's/--color-primary-s/--color--primary--s/g' +echo "$files" | xargs perl -pi -e 's/--color-primary-l/--color--primary--l/g' echo "$files" | xargs perl -pi -e 's/--color-primary(?!-)/--color--primary/g' echo "✓ Primary color tokens replaced" echo "" @@ -184,9 +190,562 @@ echo "$files" | xargs perl -pi -e 's/--font-size-s/--font-size--sm/g' echo "✓ Font size tokens replaced" echo "" -echo "[17] Verifying replacements..." -remaining=$(echo "$files" | xargs grep -l "--color-primary\|--color-secondary\|--color-success\|--color-warning\|--color-danger\|--color-text\|--color-foreground\|--color-background" 2>/dev/null | xargs grep "--color-primary\|--color-secondary\|--color-success\|--color-warning\|--color-danger\|--color-text\|--color-foreground\|--color-background" 2>/dev/null | grep -v "\-\-color\-\-" | wc -l | xargs) -echo "Remaining old tokens found: $remaining" +# Canvas tokens +echo "[17] Replacing canvas tokens..." +echo "$files" | xargs perl -pi -e 's/--color-canvas-background-h/--canvas--color--background--h/g' +echo "$files" | xargs perl -pi -e 's/--color-canvas-background-s/--canvas--color--background--s/g' +echo "$files" | xargs perl -pi -e 's/--color-canvas-background-l/--canvas--color--background--l/g' +echo "$files" | xargs perl -pi -e 's/--color-canvas-background/--canvas--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-canvas-dot/--canvas--dot--color/g' +echo "$files" | xargs perl -pi -e 's/--color-canvas-read-only-line/--canvas--read-only-line--color/g' +echo "$files" | xargs perl -pi -e 's/--color-canvas-selected-transparent/--canvas--color--selected-transparent/g' +echo "$files" | xargs perl -pi -e 's/--color-canvas-selected/--canvas--color--selected/g' +echo "$files" | xargs perl -pi -e 's/--color-canvas-label-background/--canvas--label--color--background/g' +echo "✓ Canvas tokens replaced" +echo "" + +# Node tokens +echo "[18] Replacing node tokens..." +echo "$files" | xargs perl -pi -e 's/--color-node-background/--node--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-node-executing-background/--node--color--background--executing/g' +echo "$files" | xargs perl -pi -e 's/--color-node-executing-other-background/--node--color--background--executing-1/g' +echo "$files" | xargs perl -pi -e 's/--color-node-pinned-border/--node--border-color--pinned/g' +echo "$files" | xargs perl -pi -e 's/--color-node-running-border/--node--border-color--running/g' +echo "$files" | xargs perl -pi -e 's/--node-type-main-color/--node--type-main--color/g' + +echo "✓ Node tokens replaced" +echo "" + +# Sticky note tokens +echo "[19] Replacing sticky note tokens..." +echo "$files" | xargs perl -pi -e 's/--color-sticky-background-1/--sticky--color--background--variant-1/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-border-1/--sticky--border-color--variant-1/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-background-2/--sticky--color--background--variant-2/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-border-2/--sticky--border-color--variant-2/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-background-3/--sticky--color--background--variant-3/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-border-3/--sticky--border-color--variant-3/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-background-4/--sticky--color--background--variant-4/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-border-4/--sticky--border-color--variant-4/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-background-5/--sticky--color--background--variant-5/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-border-5/--sticky--border-color--variant-5/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-background-6/--sticky--color--background--variant-6/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-border-6/--sticky--border-color--variant-6/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-background-7/--sticky--color--background--variant-7/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-border-7/--sticky--border-color--variant-7/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-code-background/--sticky--code--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-code-font/--sticky--code--color--text/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-background/--sticky--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-border/--sticky--border-color/g' +echo "$files" | xargs perl -pi -e 's/--color-sticky-font/--sticky--color--text/g' +echo "✓ Sticky note tokens replaced" +echo "" + +# AI Assistant tokens +echo "[20] Replacing AI assistant tokens..." +echo "$files" | xargs perl -pi -e 's/--color-askAssistant-button-background-gradient-active/--assistant--button--color--background--gradient--active/g' +echo "$files" | xargs perl -pi -e 's/--color-askAssistant-button-background-gradient-hover/--assistant--button--color--background--gradient--hover/g' +echo "$files" | xargs perl -pi -e 's/--color-askAssistant-button-background-gradient/--assistant--button--color--background--gradient/g' +echo "$files" | xargs perl -pi -e 's/--color-assistant-highlight-1/--assistant--color--highlight-1/g' +echo "$files" | xargs perl -pi -e 's/--color-assistant-highlight-2/--assistant--color--highlight-2/g' +echo "$files" | xargs perl -pi -e 's/--color-assistant-highlight-3/--assistant--color--highlight-3/g' +echo "$files" | xargs perl -pi -e 's/--color-assistant-highlight-gradient/--assistant--color--highlight-gradient/g' +echo "$files" | xargs perl -pi -e 's/--color-assistant-highlight-reverse/--assistant--color--highlight-gradient--reverse/g' +echo "$files" | xargs perl -pi -e 's/--color-assistant-inner-highlight-hover/--assistant--button--color--background--hover/g' +echo "$files" | xargs perl -pi -e 's/--color-assistant-inner-highlight-active/--assistant--button--color--background--active/g' +echo "✓ AI assistant tokens replaced" +echo "" + +# Chat tokens +echo "[21] Replacing chat tokens..." +echo "$files" | xargs perl -pi -e 's/--color-lm-chat-messages-background/--lm-chat--messages--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-lm-chat-bot-background/--lm-chat--bot--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-lm-chat-user-background/--lm-chat--user--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-lm-chat-user-color/--lm-chat--user--color/g' +echo "✓ Chat tokens replaced" +echo "" + +# Node icon tokens +echo "[22] Replacing node icon tokens..." +echo "$files" | xargs perl -pi -e 's/--color-node-icon-light-blue/--node--icon--color--light-blue/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-dark-blue/--node--icon--color--dark-blue/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-orange-red/--node--icon--color--orange-red/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-pink-red/--node--icon--color--pink-red/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-light-green/--node--icon--color--light-green/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-dark-green/--node--icon--color--dark-green/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-gray/--node--icon--color--gray/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-black/--node--icon--color--black/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-blue/--node--icon--color--blue/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-orange/--node--icon--color--orange/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-red/--node--icon--color--red/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-green/--node--icon--color--green/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-azure/--node--icon--color--azure/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-purple/--node--icon--color--purple/g' +echo "$files" | xargs perl -pi -e 's/--color-node-icon-crimson/--node--icon--color--crimson/g' +echo "✓ Node icon tokens replaced" +echo "" + +# Expression editor tokens +echo "[23] Replacing expression editor tokens..." +echo "$files" | xargs perl -pi -e 's/--color-valid-resolvable-foreground/--expression-editor--resolvable--color--foreground--valid/g' +echo "$files" | xargs perl -pi -e 's/--color-valid-resolvable-background/--expression-editor--resolvable--color--background--valid/g' +echo "$files" | xargs perl -pi -e 's/--color-invalid-resolvable-foreground/--expression-editor--resolvable--color--foreground--invalid/g' +echo "$files" | xargs perl -pi -e 's/--color-invalid-resolvable-background/--expression-editor--resolvable--color--background--invalid/g' +echo "$files" | xargs perl -pi -e 's/--color-pending-resolvable-foreground/--expression-editor--resolvable--color--foreground--pending/g' +echo "$files" | xargs perl -pi -e 's/--color-pending-resolvable-background/--expression-editor--resolvable--color--background--pending/g' +echo "$files" | xargs perl -pi -e 's/--color-expression-editor-modal-background/--expression-editor--modal--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-expression-editor-background/--expression-editor--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-expression-syntax-example/--expression-editor--syntax-example--color/g' + +## autocomplete +echo "$files" | xargs perl -pi -e 's/--color-autocomplete-section-header-border/--autocomplete--section-header--border-color/g' +echo "$files" | xargs perl -pi -e 's/--color-autocomplete-item-selected/--autocomplete--item--color--selected/g' +echo "$files" | xargs perl -pi -e 's/--color-infobox-examples-border-color/--autocomplete--infobox--examples--border-color/g' +echo "$files" | xargs perl -pi -e 's/--color-infobox-background/--autocomplete--infobox--color--background/g' +echo "✓ Expression editor tokens replaced" +echo "" + +# Code syntax tokens +echo "[24] Replacing code syntax tokens..." +echo "$files" | xargs perl -pi -e 's/--color-code-tags-string/--code-tags--string--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-regex/--code-tags--regex--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-primitive/--code-tags--primitive--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-keyword/--code-tags--keyword--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-variable/--code-tags--variable--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-parameter/--code-tags--parameter--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-function/--code-tags--function--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-constant/--code-tags--constant--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-property/--code-tags--property--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-type/--code-tags--type--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-class/--code-tags--class--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-heading/--code-tags--heading--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-invalid/--code-tags--invalid--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-tags-comment/--code-tags--comment--color/g' +echo "✓ Code syntax tokens replaced" +echo "" + +# JSON tokens +echo "[25] Replacing JSON tokens..." +echo "$files" | xargs perl -pi -e 's/--color-json-brackets-hover/--json--brackets--color--hover/g' +echo "$files" | xargs perl -pi -e 's/--color-json-null/--json--null--color/g' +echo "$files" | xargs perl -pi -e 's/--color-json-boolean/--json--boolean--color/g' +echo "$files" | xargs perl -pi -e 's/--color-json-number/--json--number--color/g' +echo "$files" | xargs perl -pi -e 's/--color-json-string/--json--string--color/g' +echo "$files" | xargs perl -pi -e 's/--color-json-key/--json--key--color/g' +echo "$files" | xargs perl -pi -e 's/--color-json-brackets/--json--brackets--color/g' +echo "$files" | xargs perl -pi -e 's/--color-json-line/--json--line--color/g' +echo "$files" | xargs perl -pi -e 's/--color-json-highlight/--json--highlight--color/g' +echo "$files" | xargs perl -pi -e 's/--color-json-default/--json--color/g' +echo "✓ JSON tokens replaced" +echo "" + +# Code editor tokens +echo "[26] Replacing code editor tokens..." +echo "$files" | xargs perl -pi -e 's/--color-code-background-readonly/--code--color--background--readonly/g' +echo "$files" | xargs perl -pi -e 's/--color-code-background/--code--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-code-lineHighlight/--code--line-highlight--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-foreground/--code--color--foreground/g' +echo "$files" | xargs perl -pi -e 's/--color-code-caret/--code--caret--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-selection-highlight/--code--selection--color--highlight/g' +echo "$files" | xargs perl -pi -e 's/--color-code-selection/--code--selection--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-gutter-foreground-active/--code--gutter--color--foreground--active/g' +echo "$files" | xargs perl -pi -e 's/--color-code-gutter-background/--code--gutter--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-code-gutter-foreground/--code--gutter--color--foreground/g' +echo "$files" | xargs perl -pi -e 's/--color-code-indentation-marker-active/--code--indentation-marker--color--active/g' +echo "$files" | xargs perl -pi -e 's/--color-code-indentation-marker/--code--indentation-marker--color/g' +echo "$files" | xargs perl -pi -e 's/--color-code-line-break/--code--line-break--color/g' +echo "$files" | xargs perl -pi -e 's/--color-line-break/--code--line-break--color/g' +echo "✓ Code editor tokens replaced" +echo "" + +# Tag tokens +echo "[27] Replacing tag tokens..." +echo "$files" | xargs perl -pi -e 's/--tag-background-hover-color/--tag--color--background--hover/g' +echo "$files" | xargs perl -pi -e 's/--tag-background-color/--tag--color--background/g' +echo "$files" | xargs perl -pi -e 's/--tag-border-hover-color/--tag--border-color--hover/g' +echo "$files" | xargs perl -pi -e 's/--tag-border-color/--tag--border-color/g' +echo "$files" | xargs perl -pi -e 's/--tag-border-radius/--tag--radius/g' +echo "$files" | xargs perl -pi -e 's/--tag-text-color/--tag--color--text/g' +echo "$files" | xargs perl -pi -e 's/--tag-font-size/--tag--font-size/g' +echo "$files" | xargs perl -pi -e 's/--tag-font-weight/--tag--font-weight/g' +echo "$files" | xargs perl -pi -e 's/--tag-line-height/--tag--line-height/g' +echo "$files" | xargs perl -pi -e 's/--tag-height/--tag--height/g' +echo "$files" | xargs perl -pi -e 's/--tag-padding/--tag--padding/g' +echo "✓ Tag tokens replaced" +echo "" + +# Variables usage tokens +echo "[28] Replacing variables usage tokens..." +echo "$files" | xargs perl -pi -e 's/--color-variables-usage-syntax-bg/--variables-usage--syntax--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-variables-usage-font/--variables-usage--color--text/g' +echo "✓ Variables usage tokens replaced" +echo "" + +# Button primary tokens +echo "[29] Replacing button primary tokens..." +echo "$files" | xargs perl -pi -e 's/--color-button-primary-hover-active-focus-background/--button--color--background--primary--hover-active-focus/g' +echo "$files" | xargs perl -pi -e 's/--color-button-primary-hover-active-border/--button--border-color--primary--hover-active/g' +echo "$files" | xargs perl -pi -e 's/--color-button-primary-disabled-background/--button--color--background--primary--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-primary-disabled-border/--button--border-color--primary--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-primary-disabled-font/--button--color--text--primary--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-primary-focus-outline/--button--outline-color--primary--focus/g' +echo "$files" | xargs perl -pi -e 's/--color-button-primary-background/--button--color--background--primary/g' +echo "$files" | xargs perl -pi -e 's/--color-button-primary-border/--button--border-color--primary/g' +echo "$files" | xargs perl -pi -e 's/--color-button-primary-font/--button--color--text--primary/g' +echo "✓ Button primary tokens replaced" +echo "" + +# Button secondary tokens +echo "[30] Replacing button secondary tokens..." +echo "$files" | xargs perl -pi -e 's/--color-button-secondary-hover-active-focus-border/--button--border-color--secondary--hover-active-focus/g' +echo "$files" | xargs perl -pi -e 's/--color-button-secondary-hover-active-focus-font/--button--color--text--secondary--hover-active-focus/g' +echo "$files" | xargs perl -pi -e 's/--color-button-secondary-active-focus-background/--button--color--background--secondary--active-focus/g' +echo "$files" | xargs perl -pi -e 's/--color-button-secondary-disabled-background/--button--color--background--secondary--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-secondary-disabled-border/--button--border-color--secondary--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-secondary-disabled-font/--button--color--text--secondary--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-secondary-hover-background/--button--color--background--secondary--hover/g' +echo "$files" | xargs perl -pi -e 's/--color-button-secondary-background/--button--color--background--secondary/g' +echo "$files" | xargs perl -pi -e 's/--color-button-secondary-border/--button--border-color--secondary/g' +echo "$files" | xargs perl -pi -e 's/--color-button-secondary-font/--button--color--text--secondary/g' +echo "$files" | xargs perl -pi -e 's/--color-button-secondary-focus-outline/--button--outline-color--secondary--focus/g' +echo "✓ Button secondary tokens replaced" +echo "" + +# Input tokens +echo "[31] Replacing input tokens..." +echo "$files" | xargs perl -pi -e 's/--input-border-bottom-color/--input--border-bottom-color/g' +echo "$files" | xargs perl -pi -e 's/--input-border-top-color/--input--border-top-color/g' +echo "$files" | xargs perl -pi -e 's/--input-border-right-color/--input--border-right-color/g' +echo "$files" | xargs perl -pi -e 's/--input-border-left-color/--input--border-left-color/g' +echo "$files" | xargs perl -pi -e 's/--input-focus-border-color/--input--border-color--focus/g' +echo "$files" | xargs perl -pi -e 's/--input-hover-border-color/--input--border-color--hover/g' +echo "$files" | xargs perl -pi -e 's/--input-disabled-placeholder/--input--placeholder--color--disabled/g' +echo "$files" | xargs perl -pi -e 's/--input-disabled-background/--input--color--background--disabled/g' +echo "$files" | xargs perl -pi -e 's/--input-disabled-border/--input--border-color--disabled/g' +echo "$files" | xargs perl -pi -e 's/--input-disabled-color/--input--color--disabled/g' +echo "$files" | xargs perl -pi -e 's/--input-placeholder-color/--input--placeholder--color/g' +echo "$files" | xargs perl -pi -e 's/--input-background-color/--input--color--background/g' +echo "$files" | xargs perl -pi -e 's/--input-border-radius/--input--radius/g' +echo "$files" | xargs perl -pi -e 's/--input-border-color/--input--border-color/g' +echo "$files" | xargs perl -pi -e 's/--input-label-color/--input--label--color/g' +echo "$files" | xargs perl -pi -e 's/--input-font-size/--input--font-size/g' +echo "$files" | xargs perl -pi -e 's/--input-height/--input--height/g' +echo "✓ Input tokens replaced" +echo "" + +# Button highlight tokens +echo "[33] Replacing button highlight tokens..." +echo "$files" | xargs perl -pi -e 's/--color-button-highlight-hover-active-focus-font/--button--color--text--highlight--hover-active-focus/g' +echo "$files" | xargs perl -pi -e 's/--color-button-highlight-hover-active-focus-border/--button--border-color--highlight--hover-active-focus/g' +echo "$files" | xargs perl -pi -e 's/--color-button-highlight-hover-background/--button--color--background--highlight--hover/g' +echo "$files" | xargs perl -pi -e 's/--color-button-highlight-active-focus-background/--button--color--background--highlight--active-focus/g' +echo "$files" | xargs perl -pi -e 's/--color-button-highlight-focus-outline/--button--outline-color--highlight--focus/g' +echo "$files" | xargs perl -pi -e 's/--color-button-highlight-disabled-font/--button--color--text--highlight--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-highlight-disabled-border/--button--border-color--highlight--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-highlight-disabled-background/--button--color--background--highlight--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-highlight-font/--button--color--text--highlight/g' +echo "$files" | xargs perl -pi -e 's/--color-button-highlight-border/--button--border-color--highlight/g' +echo "$files" | xargs perl -pi -e 's/--color-button-highlight-background/--button--color--background--highlight/g' +echo "✓ Button highlight tokens replaced" +echo "" + +# Button success, warning, danger tokens +echo "[34] Replacing button success, warning, danger tokens..." +echo "$files" | xargs perl -pi -e 's/--color-button-success-disabled-font/--button--color--text--success--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-success-font/--button--color--text--success/g' +echo "$files" | xargs perl -pi -e 's/--color-button-warning-disabled-font/--button--color--text--warning--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-warning-font/--button--color--text--warning/g' +echo "$files" | xargs perl -pi -e 's/--color-button-danger-focus-outline/--button--outline-color--danger--focus/g' +echo "$files" | xargs perl -pi -e 's/--color-button-danger-disabled-background/--button--color--background--danger--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-danger-disabled-border/--button--border-color--danger--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-danger-disabled-font/--button--color--text--danger--disabled/g' +echo "$files" | xargs perl -pi -e 's/--color-button-danger-border/--button--border-color--danger/g' +echo "$files" | xargs perl -pi -e 's/--color-button-danger-font/--button--color--text--danger/g' +echo "✓ Button success, warning, danger tokens replaced" +echo "" + +# Text button tokens +echo "[35] Replacing text button tokens..." +echo "$files" | xargs perl -pi -e 's/--color-text-button-secondary-font/--text-button--color--text--secondary/g' +echo "✓ Text button tokens replaced" +echo "" + +# Node Creator Button tokens +echo "[36] Replacing node creator button tokens..." +echo "$files" | xargs perl -pi -e 's/--color-button-node-creator-hover-border/--node-creator--button--border-color--hover/g' +echo "$files" | xargs perl -pi -e 's/--color-button-node-creator-hover-font/--node-creator--button--color--text--hover/g' +echo "$files" | xargs perl -pi -e 's/--color-button-node-creator-border-font/--node-creator--button--color--text/g' +echo "$files" | xargs perl -pi -e 's/--color-button-node-creator-background/--node-creator--button--color--background/g' +echo "✓ Node Creator Button tokens replaced" +echo "" + +# Table tokens +echo "[37] Replacing table tokens..." +echo "$files" | xargs perl -pi -e 's/--color-table-row-highlight-background/--table--row--color--background--highlight/g' +echo "$files" | xargs perl -pi -e 's/--color-table-row-hover-background/--table--row--color--background--hover/g' +echo "$files" | xargs perl -pi -e 's/--color-table-row-even-background/--table--row--color--background--even/g' +echo "$files" | xargs perl -pi -e 's/--color-table-row-background/--table--row--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-table-header-background/--table--header--color--background/g' +echo "✓ Table tokens replaced" +echo "" + +# Notification tokens +echo "[38] Replacing notification tokens..." +echo "$files" | xargs perl -pi -e 's/--color-notification-background/--notification--color--background/g' +echo "✓ Notification tokens replaced" +echo "" + +# Execution tokens +echo "[39] Replacing execution tokens..." +echo "$files" | xargs perl -pi -e 's/--execution-card-background-hover/--execution-card--color--background--hover/g' +echo "$files" | xargs perl -pi -e 's/--execution-card-background/--execution-card--color--background/g' +echo "$files" | xargs perl -pi -e 's/--execution-card-border-unknown/--execution-card--border-color--unknown/g' +echo "$files" | xargs perl -pi -e 's/--execution-card-border-running/--execution-card--border-color--running/g' +echo "$files" | xargs perl -pi -e 's/--execution-card-border-waiting/--execution-card--border-color--waiting/g' +echo "$files" | xargs perl -pi -e 's/--execution-card-border-error/--execution-card--border-color--error/g' +echo "$files" | xargs perl -pi -e 's/--execution-card-border-success/--execution-card--border-color--success/g' +echo "$files" | xargs perl -pi -e 's/--execution-card-border-new/--execution-card--border-color--new/g' +echo "$files" | xargs perl -pi -e 's/--execution-card-text-waiting/--execution-card--color--text--waiting/g' +echo "$files" | xargs perl -pi -e 's/--execution-selector-background/--execution-selector--color--background/g' +echo "$files" | xargs perl -pi -e 's/--execution-selector-text/--execution-selector--color--text/g' +echo "$files" | xargs perl -pi -e 's/--execution-select-all-text/--execution-select-all--color--text/g' +echo "✓ Execution tokens replaced" +echo "" + +# NDV tokens +echo "[40] Replacing NDV tokens..." +echo "$files" | xargs perl -pi -e 's/--color-ndv-droppable-parameter-active-background/--ndv--droppable-parameter--color--background--active/g' +echo "$files" | xargs perl -pi -e 's/--color-ndv-droppable-parameter-background/--ndv--droppable-parameter--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-ndv-droppable-parameter/--ndv--droppable-parameter--color/g' +echo "$files" | xargs perl -pi -e 's/--color-ndvv2-run-data-background/--ndvv2--run-data--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-run-data-background/--run-data--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-ndv-back-font/--ndv--back--color--text/g' +echo "✓ NDV tokens replaced" +echo "" + +# Notice tokens +echo "[41] Replacing notice tokens..." +echo "$files" | xargs perl -pi -e 's/--color-notice-warning-background/--notice--color--background--warning/g' +echo "$files" | xargs perl -pi -e 's/--color-notice-warning-border/--notice--border-color--warning/g' +echo "$files" | xargs perl -pi -e 's/--color-notice-font/--notice--color--text/g' +echo "✓ Notice tokens replaced" +echo "" + +# Callout tokens +echo "[42] Replacing callout tokens..." +echo "$files" | xargs perl -pi -e 's/--color-callout-info-background/--callout--color--background--info/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-info-border/--callout--border-color--info/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-info-font/--callout--color--text--info/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-info-icon/--callout--icon-color--info/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-success-background/--callout--color--background--success/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-success-border/--callout--border-color--success/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-success-font/--callout--color--text--success/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-success-icon/--callout--icon-color--success/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-warning-background/--callout--color--background--warning/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-warning-border/--callout--border-color--warning/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-warning-font/--callout--color--text--warning/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-warning-icon/--callout--icon-color--warning/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-danger-background/--callout--color--background--danger/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-danger-border/--callout--border-color--danger/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-danger-font/--callout--color--text--danger/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-danger-icon/--callout--icon-color--danger/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-secondary-background/--callout--color--background--secondary/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-secondary-border/--callout--border-color--secondary/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-secondary-font/--callout--color--text--secondary/g' +echo "$files" | xargs perl -pi -e 's/--color-callout-secondary-icon/--callout--icon-color--secondary/g' +echo "✓ Callout tokens replaced" +echo "" + +# Dialog and overlay tokens +echo "[43] Replacing dialog and overlay tokens..." +echo "$files" | xargs perl -pi -e 's/--color-dialog-overlay-background-dark/--dialog--overlay--color--background--dark/g' +echo "$files" | xargs perl -pi -e 's/--color-dialog-overlay-background/--dialog--overlay--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-dialog-background/--dialog--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-block-ui-overlay/--block-ui--overlay--color/g' +echo "✓ Dialog and overlay tokens replaced" +echo "" + +# Avatar tokens +echo "[44] Replacing avatar tokens..." +echo "$files" | xargs perl -pi -e 's/--color-avatar-font/--avatar--color--text/g' +echo "✓ Avatar tokens replaced" +echo "" + +# NPS Survey tokens +echo "[45] Replacing NPS Survey tokens..." +echo "$files" | xargs perl -pi -e 's/--color-nps-survey-background/--nps-survey--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-nps-survey-font/--nps-survey--color--text/g' +echo "✓ NPS Survey tokens replaced" +echo "" + +# Action Dropdown tokens +echo "[46] Replacing Action Dropdown tokens..." +echo "$files" | xargs perl -pi -e 's/--color-action-dropdown-item-active-background/--action-dropdown--item--color--background--active/g' +echo "✓ Action Dropdown tokens replaced" +echo "" + +# Switch tokens +echo "[47] Replacing Switch tokens..." +echo "$files" | xargs perl -pi -e 's/--color-switch-active-background/--switch--color--background--active/g' +echo "$files" | xargs perl -pi -e 's/--color-switch-background/--switch--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-switch-border-color/--switch--border-color/g' +echo "$files" | xargs perl -pi -e 's/--color-switch-toggle/--switch--toggle--color/g' +echo "✓ Switch tokens replaced" +echo "" + +# Feature Request tokens +echo "[48] Replacing Feature Request tokens..." +echo "$files" | xargs perl -pi -e 's/--color-feature-request-font/--feature-request--color--text/g' +echo "✓ Feature Request tokens replaced" +echo "" + +# Input Triple tokens +echo "[49] Replacing Input Triple tokens..." +echo "$files" | xargs perl -pi -e 's/--color-background-input-triple/--input-triple--color--background/g' +echo "✓ Input Triple tokens replaced" +echo "" + +# Node error tokens +echo "[50] Replacing Node error tokens..." +echo "$files" | xargs perl -pi -e 's/--color-node-error-output-text-color/--node--error-output--color--text/g' +echo "✓ Node error tokens replaced" +echo "" + +# MFA tokens +echo "[51] Replacing MFA tokens..." +echo "$files" | xargs perl -pi -e 's/--color-mfa-recovery-code-background/--mfa--recovery-code--color--background/g' +echo "$files" | xargs perl -pi -e 's/--color-mfa-recovery-code-color/--mfa--recovery-code--color/g' +echo "$files" | xargs perl -pi -e 's/--color-mfa-lose-access-text-color/--mfa--lose-access--color--text/g' +echo "$files" | xargs perl -pi -e 's/--color-qr-code-border/--qr-code--border-color/g' +echo "✓ MFA tokens replaced" +echo "" + +# Text highlight tokens +echo "[52] Replacing text highlight tokens..." +echo "$files" | xargs perl -pi -e 's/--color-text-highlight-background/--text-highlight--color--background/g' +echo "✓ Text highlight tokens replaced" +echo "" + +# AI Node type tokens (these are special - need to keep underscores in node type names) +echo "[53] Replacing AI Node type tokens..." +echo "$files" | xargs perl -pi -e 's/--node-type-background-l/--node-type--color--background--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-supplemental-label-color-h/--node-type--supplemental--label--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-supplemental-label-color-s/--node-type--supplemental--label--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-supplemental-label-color-l/--node-type--supplemental--label--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-supplemental-color-h/--node-type--supplemental--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-supplemental-color-s/--node-type--supplemental--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-supplemental-color-l/--node-type--supplemental--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-supplemental-label-color/--node-type--supplemental--label--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-supplemental-icon/--node-type--supplemental--icon--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-supplemental-color/--node-type--supplemental--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-supplemental-background/--node-type--supplemental--color--background/g' +echo "$files" | xargs perl -pi -e 's/--node-type-supplemental-connector-color/--node-type--supplemental--connector--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_chain-color-h/--node-type--ai-chain--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_chain-color-s/--node-type--ai-chain--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_chain-color-l/--node-type--ai-chain--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_chain-color/--node-type--ai-chain--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-chain-background/--node-type--chain--color--background/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_document-color-h/--node-type--ai-document--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_document-color-s/--node-type--ai-document--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_document-color-l/--node-type--ai-document--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_document-color/--node-type--ai-document--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_document-background/--node-type--ai-document--color--background/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_embedding-color-h/--node-type--ai-embedding--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_embedding-color-s/--node-type--ai-embedding--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_embedding-color-l/--node-type--ai-embedding--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_embedding-color/--node-type--ai-embedding--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_embedding-background/--node-type--ai-embedding--color--background/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_languageModel-color-h/--node-type--ai-language-model--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_languageModel-color-s/--node-type--ai-language-model--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_languageModel-color-l/--node-type--ai-language-model--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_languageModel-color/--node-type--ai-language-model--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_languageModel-background/--node-type--ai-language-model--color--background/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_memory-color-h/--node-type--ai-memory--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_memory-color-s/--node-type--ai-memory--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_memory-color-l/--node-type--ai-memory--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_memory-color/--node-type--ai-memory--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_memory-background/--node-type--ai-memory--color--background/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_outputParser-color-h/--node-type--ai-output-parser--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_outputParser-color-s/--node-type--ai-output-parser--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_outputParser-color-l/--node-type--ai-output-parser--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_outputParser-color/--node-type--ai-output-parser--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_outputParser-background/--node-type--ai-output-parser--color--background/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_tool-color-h/--node-type--ai-tool--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_tool-color-s/--node-type--ai-tool--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_tool-color-l/--node-type--ai-tool--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_tool-color/--node-type--ai-tool--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_tool-background/--node-type--ai-tool--color--background/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_retriever-color-h/--node-type--ai-retriever--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_retriever-color-s/--node-type--ai-retriever--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_retriever-color-l/--node-type--ai-retriever--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_retriever-color/--node-type--ai-retriever--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_retriever-background/--node-type--ai-retriever--color--background/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_textSplitter-color-h/--node-type--ai-text-splitter--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_textSplitter-color-s/--node-type--ai-text-splitter--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_textSplitter-color-l/--node-type--ai-text-splitter--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_textSplitter-color/--node-type--ai-text-splitter--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_textSplitter-background/--node-type--ai-text-splitter--color--background/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_vectorRetriever-color-h/--node-type--ai-vector-retriever--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_vectorRetriever-color-s/--node-type--ai-vector-retriever--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_vectorRetriever-color-l/--node-type--ai-vector-retriever--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_vectorRetriever-color/--node-type--ai-vector-retriever--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_vectorRetriever-background/--node-type--ai-vector-retriever--color--background/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_vectorStore-color-h/--node-type--ai-vector-store--color--h/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_vectorStore-color-s/--node-type--ai-vector-store--color--s/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_vectorStore-color-l/--node-type--ai-vector-store--color--l/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_vectorStore-color/--node-type--ai-vector-store--color/g' +echo "$files" | xargs perl -pi -e 's/--node-type-ai_vectorStore-background/--node-type--ai-vector-store--color--background/g' +echo "✓ AI Node type tokens replaced" +echo "" + +# Diff color tokens +echo "[54] Replacing diff color tokens..." +echo "$files" | xargs perl -pi -e 's/--diff-modified-light/--diff--color--modified--light/g' +echo "$files" | xargs perl -pi -e 's/--diff-modified-faint/--diff--color--modified--faint/g' +echo "$files" | xargs perl -pi -e 's/--diff-modified/--diff--color--modified/g' +echo "$files" | xargs perl -pi -e 's/--diff-new-light/--diff--color--new--light/g' +echo "$files" | xargs perl -pi -e 's/--diff-new-faint/--diff--color--new--faint/g' +echo "$files" | xargs perl -pi -e 's/--diff-new/--diff--color--new/g' +echo "$files" | xargs perl -pi -e 's/--diff-del-light/--diff--color--deleted--light/g' +echo "$files" | xargs perl -pi -e 's/--diff-del-faint/--diff--color--deleted--faint/g' +echo "$files" | xargs perl -pi -e 's/--diff-del/--diff--color--deleted/g' +echo "✓ Diff color tokens replaced" +echo "" + +# Various color tokens +echo "[55] Replacing various color tokens..." +echo "$files" | xargs perl -pi -e 's/--color-avatar-accent-1/--avatar--color--accent-1/g' +echo "$files" | xargs perl -pi -e 's/--color-avatar-accent-2/--avatar--color--accent-2/g' +echo "$files" | xargs perl -pi -e 's/--color-info-tint-2/--color--info--tint-2/g' +echo "$files" | xargs perl -pi -e 's/--color-info-tint-1/--color--info--tint-1/g' +echo "$files" | xargs perl -pi -e 's/--color-info/--color--info/g' +echo "$files" | xargs perl -pi -e 's/--color-light-grey/--color--gray--light/g' +echo "$files" | xargs perl -pi -e 's/--color-grey/--color--gray/g' +echo "$files" | xargs perl -pi -e 's/--color-configurable-node-name/--node--configurable-name--color/g' +echo "$files" | xargs perl -pi -e 's/--color-secondary-link-hover/--link--color--secondary--hover/g' +echo "$files" | xargs perl -pi -e 's/--color-secondary-link/--link--color--secondary/g' +echo "✓ Various color tokens replaced" +echo "" + +# Menu tokens +echo "[56] Replacing menu tokens..." +echo "$files" | xargs perl -pi -e 's/--color-menu-hover-background/--menu--color--background--hover/g' +echo "$files" | xargs perl -pi -e 's/--color-menu-active-background/--menu--color--background--active/g' +echo "$files" | xargs perl -pi -e 's/--color-menu-background/--menu--color--background/g' +echo "✓ Menu tokens replaced" +echo "" + +# Icon tokens +echo "[57] Replacing icon tokens..." +echo "$files" | xargs perl -pi -e 's/--color-icon-hover/--icon--color--hover/g' +echo "$files" | xargs perl -pi -e 's/--color-icon-base/--icon--color/g' +echo "✓ Icon tokens replaced" +echo "" + +# Grid tokens +echo "[58] Replacing grid tokens..." +echo "$files" | xargs perl -pi -e 's/--grid-row-selected-background/--grid--row--color--background--selected/g' +echo "$files" | xargs perl -pi -e 's/--grid-cell-editing-border/--grid--cell--border-color--editing/g' +echo "✓ Grid tokens replaced" echo "" echo "✓ Token replacements complete!"