Skip to content

Commit 5e07adb

Browse files
committed
remove all non-flex-suite recipes
1 parent 02f8c6a commit 5e07adb

185 files changed

Lines changed: 35 additions & 11795 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/clear-pages-compose.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22
'@primer/brand-mcp': patch
33
---
44

5-
Improves guidance delivered through the `primer_brand_review` tool.
5+
Improves guidance and examples delivered through the Primer Brand MCP tools:
6+
7+
- Improves guidance delivered through the `primer_brand_review` tool.
8+
- Cleaner output from the `primer_brand_examples` tool.

packages/e2e/scripts/playwright/axe-clean.spec.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ const testsToSkip = [
4040
'components-videoplayer-features--with-poster', // video makes this too flakey
4141
'components-videoplayer-features--without-branding', // video makes this too flakey
4242
'components-videoplayer--playground', // video makes this too flakey
43-
'recipes-feature-previews-level-1--level-one-side-by-side-enterprise', // video makes this too flakey
44-
'recipes-feature-previews-level-1--level-one-side-by-side', // custom, unrelated background image
4543
'components-eyebrowbanner-features--on-custom-background-dark', // custom, unrelated background image
4644
'components-eyebrowbanner-features--on-custom-background-light', // custom, unrelated background image
4745
'components-subdomainnavbar--skip-to-main-tag', // contains main tag which is in conflict with the default role="main" element
@@ -60,7 +58,7 @@ const testsToSkip = [
6058

6159
const ignoreViolations = {
6260
'landmark-one-main': {except: []}, // on most of the stories we don't have a main landmark
63-
'page-has-heading-one': {except: ['components-hero', 'recipes-feature-previews']}, // on some stories we dont have a heading,
61+
'page-has-heading-one': {except: ['components-hero']}, // on some stories we dont have a heading,
6462
region: {except: []}, // on most of the stories we don't have a region landmark
6563
}
6664

packages/e2e/scripts/playwright/playwright.generate-tests.ts

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -65,41 +65,11 @@ const waitForTimeoutLookup = {
6565
'components-box-features--animation': 6000, // for the animation
6666
'components-ide--playground': 2000, // for the animation
6767
'components-ide--default': 2000, // for the animation
68-
'recipes-seo-article-page--playground': 5000, // for the animation
69-
'recipes-seo-article-page--all-headings': 5000, // for the animation
70-
'recipes-seo-article-page--ai-theme': 5000, // for the animation
71-
'recipes-seo-article-page--collaboration-theme': 5000, // for the animation
72-
'recipes-seo-article-page--enterprise-theme': 5000, // for the animation
73-
'recipes-seo-article-page--security-theme': 5000, // for the animation
74-
'recipes-seo-article-page--productivity-theme': 5000, // for the animation
75-
'recipes-seo-article-page--light-hero-image': 5000, // for the animation
76-
'recipes-seo-article-page--dark-hero-image': 5000, // for the animation
77-
'recipes-solutions-categorypage--light': 4000, // for the animation
78-
'recipes-solutions-categorypage--dark': 4000, // for the animation
79-
'recipes-solutions-solution-industry--maximum': 3500, // for the animation
80-
'recipes-solutions-solution-industry--maximum-dark': 3500, // for the animation
81-
'recipes-solutions-solution-industry--minimum': 3500, // for the animation
82-
'recipes-solutions-solution-industry--minimum-dark': 3500, // for the animation
83-
'recipes-solutions-solution-org-size--maximum': 3500, // for the animation
84-
'recipes-solutions-solution-org-size--maximum-dark': 3500, // for the animation
85-
'recipes-solutions-solution-org-size--minimum': 3500, // for the animation
86-
'recipes-solutions-solution-org-size--minimum-dark': 3500, // for the animation
87-
'recipes-solutions-solution-use-case--minimum': 2000, // for the footer logos
88-
'recipes-solutions-solution-use-case--minimum-dark': 2000, // for the footer logos
89-
'recipes-solutions-solution-use-case--maximum-dark': 2000, // for the footer logos
90-
'recipes-solutions-solution-use-case--maximum': 2000, // for the footer logos
91-
'recipes-solutions-overview--light': 3500, // for the animation
92-
'recipes-solutions-overview--dark': 3500, // for the animation
9368
'components-riverstoryscroll--default': 3500, // for the animation
9469
'components-riverstoryscroll-features--with-timeline': 3500, // for the animation
9570
'components-riverstoryscroll-features--with-timeline-narrow': 3500, // for the animation
9671
'components-riverstoryscroll-features--enterprise-example': 3500, // for the animation
9772
'components-riverstoryscroll-features--enterprise-example-narrow': 3500, // for the animation
98-
'recipes-feature-previews-level-2--level-two-playground': 4000, // for the animation
99-
'recipes-feature-previews-level-2--level-two-point-one': 4000, // for the animation
100-
'recipes-feature-previews-level-2--level-two-point-two': 4000, // for the animation
101-
'recipes-feature-previews-level-2--level-two-point-three': 4000, // for the animation
102-
'recipes-feature-previews-level-2--level-two-point-four': 4000, // for the animation
10373
'components-textrevealanimation--playground': 3000, // for the animation
10474
'components-textrevealanimation-examples--with-large-testimonial': 3000, // for the animation
10575
'components-textrevealanimation-examples--with-hero': 3000, // for the animation
@@ -131,9 +101,7 @@ const waitForTimeoutLookup = {
131101
'components-videoplayer-features--tooltip-visible-on-focus': 5000, // for video metadata to load
132102
'components-hero-features-images-and-videos--with-video-block-end-default': 5000, // for video metadata to load
133103
'components-hero-features-images-and-videos--with-video-inline-end': 5000, // for video metadata to load
134-
'recipes-flextemplate-flextemplate--default': 4000, // for video metadata to load
135104
'components-textcursoranimation--playground': 4000, // for the animation to complete
136-
'recipes-flextemplate-flexsection--default': 1000, // longer load time
137105
'components-subnav-features--delayed-active-link': 2000, // because the story sets an initial delay,
138106
'components-logosuite-features--grid-line-expressive-kitchen-sink': 3000, // for the animation to complete
139107
'components-logosuite-features--takeover-button': 3000, // for the animation to complete
@@ -177,7 +145,6 @@ const skipTestLookup = [
177145
'components-logosuite-features--mixed-width', // animation only
178146
'components-logosuite-features--following-hero', // animation only
179147
'components-logosuite-features--stacked', // animation only
180-
'recipes-feature-previews-level-1--level-one-side-by-side-enterprise', // video makes this too flakey
181148
'components-subdomainnavbar--overflow-menu-open', // flakey despite timeout
182149
'components-ide-features--editor-only', // animation too long
183150
'components-ide-features--editor-no-replay-button', // animation too long
@@ -187,7 +154,6 @@ const skipTestLookup = [
187154
'components-ide-features--perspective-example-light', // animation too long
188155
'components-ide-features--all-glass', // animation too long
189156
'components-ide-features--editor-custom-icons', // animation too long
190-
'recipes-seo-category-page--default', // template contains randomisation
191157
'components-statistic-features--animations', // animation only
192158
'components-riverstoryscroll-features--video-narrow', // video makes this too flakey
193159
'components-riverstoryscroll-features--video', // video makes this too flakey

packages/mcp/scripts/generate-catalog.mjs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* pages, installed icon packages, and built design tokens.
55
*/
66
import {existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync} from 'node:fs'
7-
import {dirname, join, resolve} from 'node:path'
7+
import {dirname, join, relative, resolve} from 'node:path'
88
import {fileURLToPath} from 'node:url'
99

1010
const scriptDir = dirname(fileURLToPath(import.meta.url))
@@ -581,8 +581,8 @@ function buildTokens() {
581581
// Recipes
582582
// ---------------------------------------------------------------------------
583583

584-
/** Search metadata for the page recipes. The composition itself has one source: the .tsx below. */
585-
const RECIPE_META = {
584+
/** An explicit allow-list to help discovery. */
585+
const RECIPE_SEARCH_OVERRIDES = {
586586
FlexSuiteAIOverview: {
587587
title: 'Product feature overview landing page',
588588
keywords: [
@@ -634,12 +634,18 @@ const RECIPE_META = {
634634

635635
// Copies the full recipe verbatim
636636
function buildRecipes() {
637-
const recipesRoot = join(reactSrc, 'recipes', 'Flexsuite')
637+
const recipesRoot = join(reactSrc, 'recipes')
638638
if (!existsSync(recipesRoot)) {
639639
// eslint-disable-next-line i18n-text/no-en
640-
writeStderrLog('Flexsuite recipes not found; skipping recipe templates')
640+
writeStderrLog('no recipes found; skipping recipe catalog.')
641641
return []
642642
}
643+
const sanitize = value =>
644+
value
645+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
646+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
647+
.replace(/[-_]+/g, ' ')
648+
.trim()
643649
const recipes = []
644650
const walk = dir => {
645651
for (const entry of readdirSync(dir, {withFileTypes: true})) {
@@ -650,7 +656,12 @@ function buildRecipes() {
650656
const name = entry.name.slice(0, -'.tsx'.length)
651657
const source = readFileOrNull(fullPath)
652658
if (!source) continue
653-
const meta = RECIPE_META[name] ?? {title: name, keywords: ['page', 'template', 'full page']}
659+
const relativeDirectory = relative(recipesRoot, dirname(fullPath))
660+
const inferredKeywords = relativeDirectory.split(/[\\/]/).map(sanitize).filter(Boolean)
661+
const meta = RECIPE_SEARCH_OVERRIDES[name] ?? {
662+
title: sanitize(name),
663+
keywords: [...inferredKeywords, 'page', 'template', 'full page'],
664+
}
654665
recipes.push({name, title: meta.title, keywords: meta.keywords, source: source.trim()})
655666
}
656667
}
@@ -676,7 +687,7 @@ function main() {
676687
writeStderrLog('WARNING: 0 design tokens — build @primer/brand-primitives (npm run build:lib) to include them')
677688
}
678689
if (recipes.length === 0) {
679-
writeStderrLog('Error: 0 recipe templates — check packages/react/src/recipes/Flexsuite')
690+
writeStderrLog('Error: 0 recipe templates — check packages/react/src/recipes')
680691
}
681692

682693
const generatedFromVersion = (() => {

packages/mcp/src/tools/primer-brand-examples/primer-brand-examples.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ describe('primer_brand_examples', () => {
2929

3030
it('leads page-level goals with the closest full-page template', async () => {
3131
const result = await primerBrandExamplesTool.run({goal: 'category page'}, makeContext())
32-
expect(result.text).toContain('Full-page template')
32+
expect(result.text).toContain('Full-page template — goal-matched recipe source')
3333
expect(result.text).toContain('category landing page')
3434
})
3535

3636
it('combines the general page recipe with goal-specific form examples', async () => {
3737
const result = await primerBrandExamplesTool.run({goal: 'early access form page'}, makeContext())
38-
expect(result.text).toContain('Full-page template — general composition reference')
38+
expect(result.text).toContain('Full-page template — default FlexSuite overview recipe source')
3939
expect(result.text).toContain('Product feature overview landing page')
4040
expect(result.text).toContain('overview recipe source')
4141
expect(result.text).toContain('### CTAForm')

packages/mcp/src/tools/primer-brand-examples/primer-brand-examples.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const inputSchema = z.object({
1616

1717
type Input = z.infer<typeof inputSchema>
1818

19-
const description = `Get ranked, copy-and-adapt examples of correct Primer Brand usage for a goal. Page goals include a current-brand Flexsuite recipe for overall composition, while independently ranked component examples provide goal-specific detail.
19+
const description = `Get ranked, copy-and-adapt examples of correct Primer Brand usage for a goal. Page goals include a current-brand full-page recipe for overall composition, while independently ranked component examples provide goal-specific detail.
2020
Pass a target use-case like "pricing section", "category page", or "education landing page"; unmatched page types use the general overview recipe, while unmatched component goals use a foundational set.
2121
Examples are real source, so they may carry demo scaffolding (a \`content\` object, internal fixture imports, CSS-module class names, repo-relative imports, \`{...args}\` spreads) — mirror the composition and props, then rebuild with your own content and \`@primer/react-brand\` imports. Don't paste verbatim.`
2222

@@ -101,9 +101,9 @@ export const primerBrandExamplesTool: ToolModule<Input> = {
101101
? rank(meaningfulGoal, ctx.catalog.recipes, recipeSearchFields).map(entry => entry.item)
102102
: []
103103
const defaultRecipe = ctx.catalog.recipes.find(recipe => recipe.name === 'FlexSuiteAIOverview')
104-
const usesGeneralRecipe = isPageGoal && specificRecipes.length === 0 && Boolean(defaultRecipe)
104+
const useDefaultRecipe = isPageGoal && specificRecipes.length === 0 && Boolean(defaultRecipe)
105105
const matchedRecipes =
106-
specificRecipes.length > 0 ? specificRecipes : usesGeneralRecipe && defaultRecipe ? [defaultRecipe] : []
106+
specificRecipes.length > 0 ? specificRecipes : useDefaultRecipe && defaultRecipe ? [defaultRecipe] : []
107107
const topRecipe = matchedRecipes[0]
108108

109109
const sections = [`# Examples for "${goal}"`]
@@ -114,9 +114,9 @@ export const primerBrandExamplesTool: ToolModule<Input> = {
114114
: ''
115115
sections.push(
116116
[
117-
`## Full-page template — ${usesGeneralRecipe ? 'general composition reference' : 'start here'}: ${
118-
topRecipe.title
119-
}`,
117+
`## Full-page template — ${
118+
useDefaultRecipe ? 'default FlexSuite overview recipe source' : 'goal-matched recipe source'
119+
}: ${topRecipe.title}`,
120120
`This is the **actual current-brand recipe source** from \`@primer/react-brand\`, wired for our demo harness: a \`content\` object supplies the copy, imagery comes from internal fixtures, styling uses internal CSS-module class names, and imports are repo-relative. Ignore that scaffolding — mirror the page structure and gridline composition, then use the goal-specific component examples below for deeper context.${also}`,
121121
`\`\`\`tsx\n${topRecipe.source}\n\`\`\``,
122122
].join('\n\n'),

packages/react/src/EyebrowBanner/EyebrowBanner.features.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {EyebrowBanner, EyebrowBannerIconColors, EyebrowBannerLabelColors} from '
44
import {Stack} from '../Stack'
55
import {MarkGithubIcon, SparkleFillIcon} from '@primer/octicons-react'
66
import backgroundImageDark from '../fixtures/images/background-stars.png'
7-
import backgroundImageLight from '../recipes/FeaturePreviewLPs/fixtures/images/other/light-bg.png'
7+
import backgroundImageLight from '../fixtures/images/eyebrow-banner-light-bg.png'
88
import {ThemeProvider} from '../ThemeProvider'
99
import {Box} from '../Box'
1010

packages/react/src/IDE/IDE.features.stories.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import {Box} from '../Box'
1010
import {Grid} from '../Grid'
1111
import {Heading} from '../Heading'
1212
import {Link} from '../Link'
13-
import backgroundImageDark from '../recipes/FeaturePreviewLPs/fixtures/images/productivity/river-bg-dark-1.png'
14-
import backgroundImageLight1 from '../recipes/FeaturePreviewLPs/fixtures/images/productivity/river-bg-light-1.png'
15-
import backgroundImageLight2 from '../recipes/FeaturePreviewLPs/fixtures/images/productivity/river-bg-light-2.png'
13+
import backgroundImageDark from '../fixtures/images/ide-river-bg-dark.png'
14+
import backgroundImageLight1 from '../fixtures/images/ide-river-bg-light-1.png'
15+
import backgroundImageLight2 from '../fixtures/images/ide-river-bg-light-2.png'
1616
import {River, RiverBreakout} from '../river'
1717
import {Text} from '../Text'
1818
import {ThemeProvider, useTheme} from '../ThemeProvider'

packages/react/src/recipes/FeaturePreviewLPs/fixtures/images/other/light-bg.png renamed to packages/react/src/fixtures/images/eyebrow-banner-light-bg.png

File renamed without changes.

packages/react/src/recipes/FeaturePreviewLPs/fixtures/images/productivity/river-bg-dark-1.png renamed to packages/react/src/fixtures/images/ide-river-bg-dark.png

File renamed without changes.

0 commit comments

Comments
 (0)