@se-studio/skills 1.0.6 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,474 @@
1
+ ---
2
+ name: site-workflows-project-cleanup
3
+ description: Strip an existing SE Studio Next.js/Contentful project to a bare-bones baseline — black/white color system, system font, only Generic Component, Generic Collection, and Related Articles Collection registered, with minimal navigation and footer stubs. Run this when you need to clean a customer project down to a reusable template.
4
+ license: MIT
5
+ metadata:
6
+ author: se-studio
7
+ version: "1.0.0"
8
+ ---
9
+
10
+ # SE Project Cleanup
11
+
12
+ Strips an existing SE Studio project to a bare-bones baseline. After this skill runs you will have:
13
+ - **Colors**: White (`Light`) and Black (`Dark`) only
14
+ - **Font**: system-ui (no custom or Google fonts)
15
+ - **Components**: Generic Component only
16
+ - **Collections**: Generic Collection + Related Articles Collection
17
+ - **Nav/Footer**: Minimal HTML stubs
18
+ - **Contentful schema**: `componentType` and `collectionType` enums trimmed to match
19
+
20
+ Run `pnpm validate` at the end to confirm a clean TypeScript build.
21
+
22
+ ---
23
+
24
+ ## Step 1 — Update `tailwind.config.json`
25
+
26
+ Replace `colorOptions` with black and white only, update font family, and remove OpenType feature settings:
27
+
28
+ ```json
29
+ {
30
+ "colorOptions": {
31
+ "Light": "#FFFFFF",
32
+ "Dark": "#000000"
33
+ },
34
+ "colorFile": "./colors.ts",
35
+ "foregroundColors": ["Dark", "Light"],
36
+ "colorOpposites": {
37
+ "Light": "Dark",
38
+ "Dark": "Light"
39
+ },
40
+ "sizes": { /* keep existing sizes unchanged */ },
41
+ "fontTable": {
42
+ "font": "system-ui",
43
+ "weight": 400,
44
+ "lineHeight": 1.2,
45
+ "styles": { /* see below */ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ In `fontTable.styles`:
51
+ - Remove the top-level `"additional"` block (which has `font-feature-settings`)
52
+ - For every style that has an `"additional"` block containing `font-feature-settings`, remove that `additional` block entirely
53
+ - Keep any `"additional"` blocks that contain only `text-transform` (those are still valid with system fonts)
54
+ - Keep all size values, weight overrides, lineHeight, and letterSpacing values unchanged
55
+
56
+ After this change the font table will reference `system-ui` but retain all the responsive size scales.
57
+
58
+ ---
59
+
60
+ ## Step 2 — Remove fonts (file + binaries)
61
+
62
+ Delete the entire `src/project/font.ts` file. It exports `noiVariableFlex` (local font) and `ibmPlexMono` (Google font) — both unused after cleanup.
63
+
64
+ Also remove any local font binaries that the template may ship alongside the loader. These are referenced by the now-deleted `font.ts` and otherwise linger as dead assets:
65
+
66
+ ```bash
67
+ rm -rf src/fonts/
68
+ ```
69
+
70
+ (If `src/fonts/` does not exist on this template, the command is a no-op — safe to run unconditionally.)
71
+
72
+ ---
73
+
74
+ ## Step 3 — Update `src/app/layout.tsx`
75
+
76
+ 1. Remove the import line: `import { ibmPlexMono, noiVariableFlex } from '@/project/font';`
77
+ 2. In the `html` element's `className`, remove `noiVariableFlex.variable` and `ibmPlexMono.variable`
78
+
79
+ The html element should look like:
80
+ ```tsx
81
+ <html
82
+ lang="en"
83
+ suppressHydrationWarning
84
+ className={cn(
85
+ 'antialiased',
86
+ process.env.DEBUG_TAILWIND === 'true' && 'debug-screens',
87
+ process.env.SHOW_SECTION_OUTLINE === 'true' && 'show-section-outline',
88
+ )}
89
+ >
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Step 4 — Update `src/app/globals.css`
95
+
96
+ ### In the `@theme` block, make these changes:
97
+
98
+ **Replace** the `--font-sans` and `--font-serif` lines with:
99
+ ```css
100
+ --font-sans: system-ui, ui-sans-serif, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
101
+ --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
102
+ ```
103
+
104
+ **Remove** all `--animate-*` custom properties:
105
+ ```
106
+ --animate-cardRotate
107
+ --animate-linkRotate
108
+ --animate-ticker
109
+ --animate-fadeInGrow
110
+ --animate-shapeShiftClip
111
+ --animate-shapeShiftSpin
112
+ --animate-clipReveal
113
+ --animate-filmGrainShift
114
+ ```
115
+
116
+ ### Remove these `@utility` blocks entirely:
117
+ - `animate-ticker`
118
+ - `animate-fade-in-grow`
119
+ - `animate-shape-shift`
120
+ - `animate-card-rotate`
121
+ - `animate-clip-reveal`
122
+ - `film-grain`
123
+ - `image-item-h` (ArticleBrowser-specific)
124
+ - `visual-cols` (VisualsCollection-specific)
125
+ - `visual-width` (VisualsCollection-specific)
126
+
127
+ ### Remove all `@keyframes` blocks:
128
+ - `cardRotate`
129
+ - `linkRotate`
130
+ - `ticker`
131
+ - `growFade`
132
+ - `shapeShiftClip`
133
+ - `shapeShiftSpin`
134
+ - `clipReveal`
135
+ - `filmGrainShift`
136
+
137
+ ### Remove the view transition media query block:
138
+ ```css
139
+ @media (prefers-reduced-motion: no-preference) {
140
+ ::view-transition-group(*) { ... }
141
+ ::view-transition-old(root) { ... }
142
+ ::view-transition-new(root) { ... }
143
+ }
144
+ ```
145
+
146
+ ### In the RTF classes, replace `bg-yellow/20` with `bg-dark/10`:
147
+ Three occurrences — in `.rtf-standard > blockquote`, `.rtf-article > blockquote`, and `.rtf-legal > blockquote`.
148
+
149
+ ### Remove the dead-code block at the bottom:
150
+ ```css
151
+ .dark-component .standard-rtf { ... }
152
+ .light-component .standard-rtf { ... }
153
+ ```
154
+
155
+ ### Remove the Orejime scroll-lock workaround if not using Orejime consent:
156
+ The block starting with `.orejimeHtml-WithModalOpen.orejimeHtml-WithModalOpen body { ... }` — remove if the project does not use the Orejime consent banner.
157
+
158
+ ---
159
+
160
+ ## Step 5 — Update `src/lib/registrations.ts`
161
+
162
+ Keep only these three registrations:
163
+
164
+ ```typescript
165
+ import { GenericComponentRegistration } from '@/project/components/TemplateComponent';
166
+ import { GenericCollectionRegistration } from '@/project/collections/TemplateCollection';
167
+ import { RelatedArticlesCollectionRegistration } from '@/project/collections/RelatedArticlesCollection';
168
+
169
+ export const componentRegistrationsList = [
170
+ GenericComponentRegistration,
171
+ ] as const;
172
+
173
+ export const collectionRegistrationsList = [
174
+ GenericCollectionRegistration,
175
+ RelatedArticlesCollectionRegistration,
176
+ ] as const;
177
+
178
+ export const externalComponentRegistrationsList = [] as const;
179
+ ```
180
+
181
+ Remove all other imports and registrations.
182
+
183
+ ---
184
+
185
+ ## Step 6 — Delete component files
186
+
187
+ Delete these files from `src/project/components/`:
188
+ - `ArticleDescription.tsx`
189
+ - `ArticleHero.tsx`
190
+ - `ArticleRichText.tsx`
191
+ - `Quote.tsx`
192
+ - `SimpleParagraph.tsx`
193
+ - `TwoColumnRichText.tsx`
194
+ - `ViewTransitionTrackedLink.tsx`
195
+
196
+ Also delete these files from `src/project/components/Navigation/`:
197
+ - `NavMenu.tsx`
198
+ - `MobileNav.tsx`
199
+ - `ContactNavItem.tsx`
200
+
201
+ Keep: `TemplateComponent.tsx`, `Navigation/index.tsx` (will be replaced in Step 8), `Navigation/types.ts`, `Footer/index.tsx` (will be replaced in Step 9), `Footer/types.ts`
202
+
203
+ ---
204
+
205
+ ## Step 7 — Delete collection files
206
+
207
+ Delete these from `src/project/collections/`:
208
+ - `ArticleBrowser/` (entire directory)
209
+ - `ProcessListCollection.tsx`
210
+ - `SeparatedVisualsCollection.tsx`
211
+ - `TeamGridCollection.tsx`
212
+ - `TextAndCarouselCollection.tsx`
213
+ - `TextAndCarouselCarousel.tsx`
214
+ - `VisualsCollection.tsx`
215
+
216
+ Keep: `TemplateCollection.tsx`, `LinkCard.tsx` (used internally by TemplateCollection), `RelatedArticlesCollection.tsx`
217
+
218
+ ---
219
+
220
+ ## Step 8 — Delete external component files
221
+
222
+ Delete all files in `src/project/externalComponents/` (IFrame and Pardot integrations).
223
+
224
+ ---
225
+
226
+ ## Step 9 — Replace Navigation with minimal stub
227
+
228
+ Replace `src/project/components/Navigation/index.tsx` with:
229
+
230
+ ```tsx
231
+ 'use client';
232
+ import type { INavigation } from '@se-studio/core-data-types';
233
+ import type { NavigationProps } from './types';
234
+
235
+ export const Navigation: React.FC<NavigationProps> = ({ navigation: _navigation }) => {
236
+ return (
237
+ <header className="fixed top-0 left-0 right-0 z-50 h-[var(--nav-height)] bg-light border-b border-dark/10 flex items-center px-4">
238
+ <nav>
239
+ <span className="p2 font-semibold">Site Name</span>
240
+ </nav>
241
+ </header>
242
+ );
243
+ };
244
+
245
+ export default Navigation;
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Step 10 — Replace Footer with minimal stub
251
+
252
+ Replace `src/project/components/Footer/index.tsx` with:
253
+
254
+ ```tsx
255
+ 'use client';
256
+ import type { FooterProps } from './types';
257
+
258
+ export const Footer: React.FC<FooterProps> = ({ navigation: _navigation }) => {
259
+ return (
260
+ <footer className="bg-dark text-light py-8 px-4 text-center">
261
+ <p className="p3">&copy; {new Date().getFullYear()} Site Name</p>
262
+ </footer>
263
+ );
264
+ };
265
+
266
+ export default Footer;
267
+ ```
268
+
269
+ Delete `src/project/components/Footer/MobileFooter.tsx` if it exists.
270
+
271
+ ---
272
+
273
+ ## Step 11 — Clean up Contentful schema
274
+
275
+ Create `scripts/clean-schema.js` (or update it if it already exists):
276
+
277
+ > The `scripts/` directory in the SE Studio template ships with `{ "type": "module" }` in its own `package.json`, so the script below is **ESM** (`import` syntax, not `require`). Do not add `'use strict'` — it is a no-op in ES modules.
278
+
279
+ ```js
280
+ #!/usr/bin/env node
281
+ import fs from 'node:fs';
282
+
283
+ const inputPath = 'scripts/master-schema.json';
284
+ const outputPath = 'scripts/clean-schema.json';
285
+
286
+ if (!fs.existsSync(inputPath)) {
287
+ console.error(`Input file not found: ${inputPath}`);
288
+ console.error(
289
+ 'Export the schema first: contentful space export --skip-content --skip-webhooks --content-file scripts/master-schema.json',
290
+ );
291
+ process.exit(1);
292
+ }
293
+
294
+ const schema = JSON.parse(fs.readFileSync(inputPath, 'utf8'));
295
+
296
+ // Trim componentType to bare-bones set
297
+ const component = schema.contentTypes?.find((ct) => ct.sys.id === 'component');
298
+ if (component) {
299
+ const field = component.fields.find((f) => f.id === 'componentType');
300
+ if (field?.validations) {
301
+ field.validations = field.validations.map((v) => (v.in ? { in: ['Generic'] } : v));
302
+ }
303
+ }
304
+
305
+ // Trim collectionType to bare-bones set
306
+ const collection = schema.contentTypes?.find((ct) => ct.sys.id === 'collection');
307
+ if (collection) {
308
+ const field = collection.fields.find((f) => f.id === 'collectionType');
309
+ if (field?.validations) {
310
+ field.validations = field.validations.map((v) =>
311
+ v.in ? { in: ['Generic', 'Related articles'] } : v,
312
+ );
313
+ }
314
+ }
315
+
316
+ // Drop the `in` validation on externalComponentType entirely.
317
+ // Replacing it with `{ in: [] }` is rejected by Contentful's Management API
318
+ // ("Expected at least one choice"), so we filter the validation out instead
319
+ // and leave any non-`in` validations untouched.
320
+ const ext = schema.contentTypes?.find((ct) => ct.sys.id === 'externalComponent');
321
+ if (ext) {
322
+ const field = ext.fields.find((f) => f.id === 'externalComponentType');
323
+ if (field?.validations) {
324
+ field.validations = field.validations.filter((v) => !v.in);
325
+ }
326
+ }
327
+
328
+ // Strip webhooks from the export. `contentful space import` will otherwise
329
+ // try to CREATE every webhook in the target space and 409 on conflicts when
330
+ // they already exist (e.g. revalidation webhook auto-provisioned by Vercel),
331
+ // causing the import to exit non-zero even though content types succeeded.
332
+ delete schema.webhooks;
333
+
334
+ fs.writeFileSync(outputPath, JSON.stringify(schema, null, 2));
335
+ console.log(`Clean schema written to ${outputPath}`);
336
+ console.log('Component types kept:', ['Generic']);
337
+ console.log('Collection types kept:', ['Generic', 'Related articles']);
338
+ console.log('Webhooks: stripped from output');
339
+ ```
340
+
341
+ Run it:
342
+ ```bash
343
+ node scripts/clean-schema.js
344
+ ```
345
+
346
+ Then import to the target Contentful space (use the space ID from `.env.local`):
347
+ ```bash
348
+ contentful space import \
349
+ --space-id <TARGET_SPACE_ID> \
350
+ --environment-id master \
351
+ --content-file scripts/clean-schema.json
352
+ ```
353
+
354
+ > If cleaning an **existing** space (not a new one), use the Contentful Management API or UI to update the `componentType` and `collectionType` field validations directly, rather than importing. Importing to an existing space with live content can cause conflicts.
355
+
356
+ ---
357
+
358
+ ## Step 12 — Regenerate and validate
359
+
360
+ ```bash
361
+ pnpm codegen
362
+ ```
363
+
364
+ This regenerates `src/generated/colors.ts` (now only `Light` and `Dark`) and `src/generated/setailwind.css` (system font, updated color variables).
365
+
366
+ ```bash
367
+ pnpm validate
368
+ ```
369
+
370
+ Fix any TypeScript errors that surface from the removed imports. Common issues:
371
+ - References to deleted components in other files (check `src/lib/` for any direct imports)
372
+ - `viewTransitions.ts` may import from `ViewTransitionTrackedLink` — remove those imports
373
+ - Any analytics wrappers that reference removed component names
374
+
375
+ ---
376
+
377
+ ## Step 13 — Clean up `docs/cms-guidelines/`
378
+
379
+ Templates that have already had CMS guidelines generated will ship `docs/cms-guidelines/` files for components and collections that no longer exist after this cleanup. Trim it down to only the three kept types (Generic component, Generic collection, Related articles), then regenerate the merged docs.
380
+
381
+ ### 1. Delete obsolete component / collection / external markdown
382
+
383
+ Remove every file under `docs/cms-guidelines/components/`, `docs/cms-guidelines/collections/`, and `docs/cms-guidelines/externals/` **except**:
384
+
385
+ - `docs/cms-guidelines/components/generic.md`
386
+ - `docs/cms-guidelines/collections/generic.md`
387
+ - `docs/cms-guidelines/collections/related-articles.md`
388
+
389
+ ```bash
390
+ # Components: keep only generic.md
391
+ find docs/cms-guidelines/components -type f -name '*.md' ! -name 'generic.md' -delete 2>/dev/null || true
392
+
393
+ # Collections: keep only generic.md and related-articles.md
394
+ find docs/cms-guidelines/collections -type f -name '*.md' \
395
+ ! -name 'generic.md' ! -name 'related-articles.md' -delete 2>/dev/null || true
396
+
397
+ # Externals: nothing kept
398
+ rm -rf docs/cms-guidelines/externals 2>/dev/null || true
399
+ ```
400
+
401
+ ### 2. Trim `docs/cms-guidelines/screenshots/`
402
+
403
+ Delete every PNG under `docs/cms-guidelines/screenshots/` that is not for `generic` (component or collection) or `related-articles` (collection):
404
+
405
+ ```bash
406
+ # Component screenshots: keep generic-*.png only
407
+ find docs/cms-guidelines/screenshots/components -type f \
408
+ ! -name 'generic-*.png' -delete 2>/dev/null || true
409
+
410
+ # Collection screenshots: keep generic-*.png and related-articles-*.png
411
+ find docs/cms-guidelines/screenshots/collections -type f \
412
+ ! -name 'generic-*.png' ! -name 'related-articles-*.png' -delete 2>/dev/null || true
413
+
414
+ # Externals screenshots: drop entirely
415
+ rm -rf docs/cms-guidelines/screenshots/externals 2>/dev/null || true
416
+ ```
417
+
418
+ ### 3. Trim `docs/cms-guidelines/screenshots/index.json`
419
+
420
+ If it exists, edit `docs/cms-guidelines/screenshots/index.json` so it contains only entries for the three kept types — `Generic` (component), `Generic` (collection), and `Related articles` (collection). All other entries must be removed; otherwise the merged guidelines will reference deleted screenshots.
421
+
422
+ ### 4. Regenerate the merged guidelines
423
+
424
+ ```bash
425
+ pnpm cms-guidelines:merge
426
+ pnpm cms-generate-html-style-guide
427
+ ```
428
+
429
+ This rewrites `docs/cms-guidelines/COMPONENT_GUIDELINES_FOR_LLM.md` and `docs/cms-guidelines/html-component-style-guide.md` against the trimmed inputs.
430
+
431
+ ---
432
+
433
+ ## Step 14 — Clean up `src/generated/cms-discovery/accepted-variants/`
434
+
435
+ The same component/collection types are referenced by JSON discovery files under `src/generated/cms-discovery/accepted-variants/`. Stale entries for removed types must be deleted, otherwise `generate-showcase-mocks` and the CMS guideline skills will repopulate guidelines for components that no longer exist in code.
436
+
437
+ Delete everything in `accepted-variants/` **except**:
438
+
439
+ - `accepted-variants/generic.json` (if present at the top level)
440
+ - `accepted-variants/related-articles.json` (if present at the top level)
441
+ - `accepted-variants/components/generic.json`
442
+ - `accepted-variants/collections/generic.json`
443
+ - `accepted-variants/collections/related-articles.json`
444
+
445
+ ```bash
446
+ DISCOVERY=src/generated/cms-discovery/accepted-variants
447
+
448
+ # Top-level legacy files (older templates): keep generic.json + related-articles.json only
449
+ find "$DISCOVERY" -maxdepth 1 -type f -name '*.json' \
450
+ ! -name 'generic.json' ! -name 'related-articles.json' -delete 2>/dev/null || true
451
+
452
+ # Components: keep generic.json only
453
+ find "$DISCOVERY/components" -type f -name '*.json' \
454
+ ! -name 'generic.json' -delete 2>/dev/null || true
455
+
456
+ # Collections: keep generic.json + related-articles.json
457
+ find "$DISCOVERY/collections" -type f -name '*.json' \
458
+ ! -name 'generic.json' ! -name 'related-articles.json' -delete 2>/dev/null || true
459
+
460
+ # Externals: drop entirely
461
+ rm -rf "$DISCOVERY/externals" 2>/dev/null || true
462
+ ```
463
+
464
+ If the project also ships top-level showcase outputs (`src/generated/showcase-examples.json`, `src/generated/showcase-mocks-draft.json`), delete those too — they are regenerated by `pnpm generate-showcase-mocks`. Leave `src/generated/showcase-mocks.json` (it is committed and will be re-curated via the **curate-showcase-mocks** skill on demand).
465
+
466
+ ---
467
+
468
+ ## What is deliberately left untouched
469
+
470
+ - `src/app/(cms-routes)/` — all routing is left as-is; the CMS routes work with whatever is registered
471
+ - `src/lib/constants.ts` — site title/description stays as-is for cleanup; update manually for new projects
472
+ - `src/project/STYLING.md` and `src/project/ANIMATION.md` — left for human review; update to reflect the new bare-bones system
473
+ - `src/project/font.ts` and `src/fonts/` — deleted (step 2 above)
474
+ - `scripts/master-schema.json` — never modified, always kept as the original export