@se-studio/skills 1.5.4 → 1.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/references/contentful-cms-editor-playbooks/PATTERNS.md +160 -0
- package/references/contentful-cms-editor-playbooks/PROJECT-ROLLOUT.md +225 -0
- package/references/deps-update/projects.registry.json +4 -0
- package/skills/contentful-cms-core/SKILL.md +26 -14
- package/skills/contentful-cms-create-editor-playbooks/SKILL.md +266 -0
- package/skills/contentful-cms-media-review/SKILL.md +6 -4
- package/skills/contentful-cms-regenerate-editor-pack/SKILL.md +1 -0
- package/skills/contentful-cms-rich-text/SKILL.md +5 -8
- package/skills/contentful-cms-schema-org/SKILL.md +45 -19
- package/skills/contentful-cms-setup/SKILL.md +39 -3
- package/skills/se-marketing-sites-markdown-accuracy-review/SKILL.md +69 -0
- package/skills/se-marketing-sites-smoke-test-setup/SKILL.md +18 -2
- package/skills/site-workflows-deps-update/SKILL.md +37 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @se-studio/skills
|
|
2
2
|
|
|
3
|
+
## 1.5.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Media wrapper entries now default their `name` (Contentful list label) to the linked asset's title when created via `create media` or `visualAssetFilename` shorthands. Document the convention in editor playbooks and skills; avoid migration-style `Wrapper for {assetId}` labels.
|
|
8
|
+
|
|
9
|
+
## 1.5.5
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- d1a119c: Add `contentful-cms-create-editor-playbooks` skill and reference docs for customer editor playbook rollouts (Pedestal, OM1, PointMe, SE website).
|
|
14
|
+
|
|
3
15
|
## 1.5.4
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Editor playbook patterns (Brightline reference)
|
|
2
|
+
|
|
3
|
+
Patterns from the Brightline + BrightLife Kids rollout (`brightline-sites` `docs/cms-editor/`). Use as templates when authoring playbooks for other customers.
|
|
4
|
+
|
|
5
|
+
## Two-file pattern
|
|
6
|
+
|
|
7
|
+
Every **specialized page category** gets two files:
|
|
8
|
+
|
|
9
|
+
| File | Role |
|
|
10
|
+
|------|------|
|
|
11
|
+
| `docs/cms-editor/<projectKey>/<topic>.md` | Full playbook — URL patterns, content stack, reference pages, component mapping |
|
|
12
|
+
| `docs/cms-editor/<projectKey>/tasks/<topic>.md` | Short **capability task** — intent phrases + step checklist for `tasks-index` |
|
|
13
|
+
|
|
14
|
+
Example (Brightline condition pages):
|
|
15
|
+
|
|
16
|
+
- `brightline/condition-program-pages.md` → `cms-edit://customer/condition-program-pages`
|
|
17
|
+
- `brightline/tasks/condition-program-pages.md` → `cms-edit://customer/task-condition-program-pages`
|
|
18
|
+
|
|
19
|
+
Task stubs are **not** copies of the full playbook — they route agents to read the full resource first.
|
|
20
|
+
|
|
21
|
+
## Task stub format
|
|
22
|
+
|
|
23
|
+
```markdown
|
|
24
|
+
# Capability: Condition & therapy program pages
|
|
25
|
+
|
|
26
|
+
## Intent phrases
|
|
27
|
+
|
|
28
|
+
- edit a condition page
|
|
29
|
+
- new therapy program page
|
|
30
|
+
|
|
31
|
+
## Requires capabilities
|
|
32
|
+
|
|
33
|
+
`pages`
|
|
34
|
+
|
|
35
|
+
## Prerequisites
|
|
36
|
+
|
|
37
|
+
- Read `cms-edit://customer/condition-program-pages` (full playbook)
|
|
38
|
+
- Read `cms-edit://customer/pages` for general page rules
|
|
39
|
+
- `cms_edit ["index", "sync"]` when cloning from templates
|
|
40
|
+
|
|
41
|
+
## Steps
|
|
42
|
+
|
|
43
|
+
1. Identify URL under `/what-we-treat/` or `/care/therapy-programs/`
|
|
44
|
+
2. Clone reference page (`task-clone-page`)
|
|
45
|
+
3. Update Hero, FAQ collection, CTAs
|
|
46
|
+
4. `preview urls` on staging
|
|
47
|
+
5. `diff` → `save` → `task-publish-handoff`
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Parser rules** (`packages/contentful-cms/src/editor-pack/capabilities.ts`):
|
|
51
|
+
|
|
52
|
+
- Title from `# Capability: <text>`
|
|
53
|
+
- Intent phrases from bullet list under `## Intent phrases`
|
|
54
|
+
- Resource name = `task-` + filename slug (without `.md`)
|
|
55
|
+
|
|
56
|
+
## `pages.md` hub pattern
|
|
57
|
+
|
|
58
|
+
General `pages.md` is the **router** — not a duplicate of every specialized playbook.
|
|
59
|
+
|
|
60
|
+
Include:
|
|
61
|
+
|
|
62
|
+
1. **Table** linking page types → `cms-edit://customer/<topic>` resources
|
|
63
|
+
2. **When to use** — path prefixes, clone vs net-new
|
|
64
|
+
3. **Templates** — `cms-edit list --type template` table
|
|
65
|
+
4. **Reference pages** — 4–8 canonical clone sources with notes
|
|
66
|
+
5. **Doc section → component mapping** — brief headings to registered types
|
|
67
|
+
6. **Creating pages** — `task-create-page`, `task-create-from-document`, dry-run
|
|
68
|
+
7. **Preview / publish handoff**
|
|
69
|
+
|
|
70
|
+
Brightline excerpt:
|
|
71
|
+
|
|
72
|
+
```markdown
|
|
73
|
+
| Page type | Playbook |
|
|
74
|
+
|-----------|----------|
|
|
75
|
+
| Condition or therapy program | `cms-edit://customer/condition-program-pages` |
|
|
76
|
+
| Insurance / pricing / cost | `cms-edit://customer/insurance-pricing-pages` |
|
|
77
|
+
| Blog article | `cms-edit://customer/articles` |
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Specialized playbook sections
|
|
81
|
+
|
|
82
|
+
| Section | Purpose |
|
|
83
|
+
|---------|---------|
|
|
84
|
+
| URL patterns | Prefix table with 2+ real examples |
|
|
85
|
+
| Typical content stack | Ordered component/collection list |
|
|
86
|
+
| Reference pages | "Clone when" column |
|
|
87
|
+
| Hero / template guidance | Site-specific design rules |
|
|
88
|
+
| FAQ / SEO / schema notes | When clinically or legally sensitive |
|
|
89
|
+
| Workflow | Numbered steps |
|
|
90
|
+
| Out of scope | Prevents wrong template or duplicate blocks |
|
|
91
|
+
|
|
92
|
+
Fetch live markdown when `website.markdownAccess` is enabled: `https://<prod><path>.md`
|
|
93
|
+
|
|
94
|
+
## Tier system (Brightline)
|
|
95
|
+
|
|
96
|
+
### P0 — ship first
|
|
97
|
+
|
|
98
|
+
| Brightline | BLK |
|
|
99
|
+
|------------|-----|
|
|
100
|
+
| `pages.md` | `pages.md` |
|
|
101
|
+
| `ARTICLES.md` | `articles.md` |
|
|
102
|
+
| `condition-program-pages` | `parent-coaching-topic-pages` |
|
|
103
|
+
| `insurance-pricing-pages` | — |
|
|
104
|
+
| `landing-pages-paid-media` | — |
|
|
105
|
+
|
|
106
|
+
### P1
|
|
107
|
+
|
|
108
|
+
| Brightline | BLK |
|
|
109
|
+
|------------|-----|
|
|
110
|
+
| `provider-pages` | `bilingual-locale-pages` |
|
|
111
|
+
| `location-pages` | `resources-hub-pages` |
|
|
112
|
+
| `partner-pages` | — |
|
|
113
|
+
|
|
114
|
+
### P2
|
|
115
|
+
|
|
116
|
+
| Brightline | BLK |
|
|
117
|
+
|------------|-----|
|
|
118
|
+
| `legal-policy-pages` | `legal-policy-pages` |
|
|
119
|
+
| `learning-hub-hub-pages` | — |
|
|
120
|
+
|
|
121
|
+
### Skipped (both sites)
|
|
122
|
+
|
|
123
|
+
- `people.md` — `enablePerson=false`; clinicians covered by `provider-pages.md` on Brightline
|
|
124
|
+
|
|
125
|
+
## Other playbook types
|
|
126
|
+
|
|
127
|
+
| File | When |
|
|
128
|
+
|------|------|
|
|
129
|
+
| `articles.md` / `ARTICLES.md` | Article types, tag rules, featuredImage vs visuals |
|
|
130
|
+
| `people.md` | `enablePerson=true` — team profiles, author import |
|
|
131
|
+
| `blog-tag-matrix.md` | Complex tag governance (Brightline) |
|
|
132
|
+
| `site-facts.json` | Canonical support email, phone — becomes `site-facts` resource |
|
|
133
|
+
| `tasks/*.md` only | Overrides for core tasks (e.g. `import-blog-tag-matrix`) |
|
|
134
|
+
|
|
135
|
+
## Generator behaviour
|
|
136
|
+
|
|
137
|
+
From `packages/contentful-cms/src/editor-pack/generate.ts`:
|
|
138
|
+
|
|
139
|
+
- `articles.md` and `ARTICLES.md` → `articles` resource (not duplicated as separate basename)
|
|
140
|
+
- `pages.md` → sets `hasPagesPlaybook` in capabilities
|
|
141
|
+
- Other `*.md` in project root → resource name = kebab-case basename
|
|
142
|
+
- `tasks/*.md` → `task-<slug>` merged into `tasks-index.md`
|
|
143
|
+
|
|
144
|
+
## Naming conventions
|
|
145
|
+
|
|
146
|
+
- **Filenames:** kebab-case, match URL family (`legal-policy-pages`, `resources-hub-pages`)
|
|
147
|
+
- **Resource URIs:** `cms-edit://customer/<basename>` — no `.md` suffix
|
|
148
|
+
- **projectKey:** must match `project.json` `projectKey` exactly (`brightline`, not `brightline-website`)
|
|
149
|
+
|
|
150
|
+
## Commit message pattern
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
docs(cms-editor): add Brightline P0 editor playbooks
|
|
154
|
+
|
|
155
|
+
- pages.md hub + condition/insurance/landing playbooks
|
|
156
|
+
- task stubs for tasks-index
|
|
157
|
+
- regenerate editor-pack
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Split P1/P2 into separate commits for easier review.
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Editor playbook rollout — project queue
|
|
2
|
+
|
|
3
|
+
Suggested order after Brightline + BLK completion. Each project: audit → P0 → regen → doctor → push `develop` → P1 → P2.
|
|
4
|
+
|
|
5
|
+
Skill: **`contentful-cms-create-editor-playbooks`**
|
|
6
|
+
|
|
7
|
+
## Rollout order
|
|
8
|
+
|
|
9
|
+
| # | Project | Repo path | Branch | Hosted MCP |
|
|
10
|
+
|---|---------|-----------|--------|------------|
|
|
11
|
+
| 1 | Pedestal Health | `~/source/customers/pedestal/pedestal-sites` | `develop` | `pedestal.content.se.studio` (verify in repo) |
|
|
12
|
+
| 1b | Headwater Science | same monorepo | `develop` | separate space — second pass |
|
|
13
|
+
| 2 | OM1 | `~/source/customers/om1/om1-website` | `develop` | `om1.content.se.studio` |
|
|
14
|
+
| 3 | PointMe | `~/source/customers/pointme/develop-marketing-site` | `develop` | `pointme.content.se.studio` |
|
|
15
|
+
| 4 | SE Studio | `~/source/se/se-website-2026` | `develop` | `se-website-2026.content.se.studio` |
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 1. Pedestal (`pedestal-sites`)
|
|
20
|
+
|
|
21
|
+
**Config:** `cms-edit/pedestal-health/project.json` → `projectKey: pedestal-health`, `appDir: apps/pedestal-website`
|
|
22
|
+
|
|
23
|
+
**Current state:** `docs/cms-editor/pedestal-health/ARTICLES.md` only — no `pages.md`, no specialized playbooks.
|
|
24
|
+
|
|
25
|
+
**Routing signals** (`apps/pedestal-website/src/lib/constants.ts`):
|
|
26
|
+
|
|
27
|
+
| Flag | Value |
|
|
28
|
+
|------|-------|
|
|
29
|
+
| `enablePerson` | `true` → need `people.md` |
|
|
30
|
+
| `ARTICLES_BASE` | `''` (root-relative article URLs) |
|
|
31
|
+
| `markdownArticleTypeSlugs` | `resources/publications`, `resources/news` |
|
|
32
|
+
| `enablePrimaryTagPartOfSlug` | `true` |
|
|
33
|
+
| Homepage | `index` (standard — omit `website.homepageSlug` in `project.json`) |
|
|
34
|
+
|
|
35
|
+
### Suggested tiers
|
|
36
|
+
|
|
37
|
+
**P0**
|
|
38
|
+
|
|
39
|
+
| Playbook | Rationale |
|
|
40
|
+
|----------|-----------|
|
|
41
|
+
| `pages.md` | Doctor requires when pages enabled |
|
|
42
|
+
| `articles.md` | Rename/normalize from `ARTICLES.md` (either filename works; pick one) |
|
|
43
|
+
| `people.md` | Persons enabled + `/people/` routes |
|
|
44
|
+
| `publications-pages.md` | Core product — publications with poster/download rules |
|
|
45
|
+
| `news-pages.md` | Press/news article type patterns |
|
|
46
|
+
|
|
47
|
+
**P1**
|
|
48
|
+
|
|
49
|
+
| Playbook | Rationale |
|
|
50
|
+
|----------|-----------|
|
|
51
|
+
| `therapeutic-area-pages.md` | Disease/TA landing pages if distinct URL prefix |
|
|
52
|
+
| `solutions-pages.md` | Product/solution family pages |
|
|
53
|
+
| `resources-hub-pages.md` | `/resources/` index behaviour |
|
|
54
|
+
|
|
55
|
+
**P2**
|
|
56
|
+
|
|
57
|
+
| Playbook | Rationale |
|
|
58
|
+
|----------|-----------|
|
|
59
|
+
| `legal-policy-pages.md` | Privacy, terms, compliance |
|
|
60
|
+
|
|
61
|
+
**Headwater (`headwater-science`):** Repeat audit separately — same monorepo patterns but different content model and `projectKey`. Only `ARTICLES.md` exists today.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 2. OM1 (`om1-website`)
|
|
66
|
+
|
|
67
|
+
**Config:** `cms-edit/project.json` → `projectKey: om1`, single-site layout
|
|
68
|
+
|
|
69
|
+
**Current state:** No `docs/cms-editor/` files — start from scratch.
|
|
70
|
+
|
|
71
|
+
**Routing signals:**
|
|
72
|
+
|
|
73
|
+
| Flag | Value |
|
|
74
|
+
|------|-------|
|
|
75
|
+
| `enablePerson` | `true` → `people.md` |
|
|
76
|
+
| `ARTICLES_BASE` | `/resources` |
|
|
77
|
+
| `PEOPLE_BASE` | `/team` |
|
|
78
|
+
| `enableArticleTypeIndex` | `true` |
|
|
79
|
+
| `enablePrimaryTagPartOfSlug` | `true` |
|
|
80
|
+
| `TOPICLESS_ARTICLE_TYPE_SLUGS` | `ebooks` — document in articles playbook |
|
|
81
|
+
|
|
82
|
+
### Suggested tiers
|
|
83
|
+
|
|
84
|
+
**P0**
|
|
85
|
+
|
|
86
|
+
| Playbook | Rationale |
|
|
87
|
+
|----------|-----------|
|
|
88
|
+
| `pages.md` | General marketing pages |
|
|
89
|
+
| `articles.md` | Resources hub — blog, ebooks, publications |
|
|
90
|
+
| `people.md` | Team profiles at `/team/` |
|
|
91
|
+
| `resource-article-pages.md` | Standard `/resources/{type}/{topic}/{slug}/` articles |
|
|
92
|
+
|
|
93
|
+
**P1**
|
|
94
|
+
|
|
95
|
+
| Playbook | Rationale |
|
|
96
|
+
|----------|-----------|
|
|
97
|
+
| `ebook-pages.md` | Topicless URL shape for ebooks |
|
|
98
|
+
| `solutions-pages.md` | Product/solution pages if distinct prefix |
|
|
99
|
+
| `events-webinars-pages.md` | If event content type exists |
|
|
100
|
+
|
|
101
|
+
**P2**
|
|
102
|
+
|
|
103
|
+
| Playbook | Rationale |
|
|
104
|
+
|----------|-----------|
|
|
105
|
+
| `legal-policy-pages.md` | Compliance |
|
|
106
|
+
|
|
107
|
+
**Audit tip:** Inventory `/resources/` paths from sitemap; peek top-traffic solution and resource pages before writing component stacks.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 3. PointMe (`develop-marketing-site`)
|
|
112
|
+
|
|
113
|
+
**Config:** `cms-edit/project.json` → `projectKey: pointme`
|
|
114
|
+
|
|
115
|
+
**Current state:** No `docs/cms-editor/` — start from scratch.
|
|
116
|
+
|
|
117
|
+
**Routing signals:**
|
|
118
|
+
|
|
119
|
+
| Flag | Value |
|
|
120
|
+
|------|-------|
|
|
121
|
+
| `enablePerson` | `true` |
|
|
122
|
+
| `ARTICLES_SLUG` | `insights` |
|
|
123
|
+
| `PEOPLE_BASE` | `/insights/author` (authors under insights, not `/people/`) |
|
|
124
|
+
| `enableArticleTypeIndex` | `true` |
|
|
125
|
+
| `enableTagsIndex` | `false` — tag pages under `/insights/{tag}/` |
|
|
126
|
+
| `enablePrimaryTagPartOfSlug` | `false` |
|
|
127
|
+
|
|
128
|
+
**Note:** Marketing site only — product app (`/home`, `/search`) is AWS; playbooks cover Vercel marketing routes only.
|
|
129
|
+
|
|
130
|
+
### Suggested tiers
|
|
131
|
+
|
|
132
|
+
**P0**
|
|
133
|
+
|
|
134
|
+
| Playbook | Rationale |
|
|
135
|
+
|----------|-----------|
|
|
136
|
+
| `pages.md` | About, concierge, marketing LPs |
|
|
137
|
+
| `articles.md` | Insights blog — primary content type |
|
|
138
|
+
| `insights-author-pages.md` | Author profiles at `/insights/author/{slug}/` (not generic `people.md` — custom PEOPLE_BASE) |
|
|
139
|
+
| `insights-hub-pages.md` | `/insights/` index and tag landing pages |
|
|
140
|
+
|
|
141
|
+
**P1**
|
|
142
|
+
|
|
143
|
+
| Playbook | Rationale |
|
|
144
|
+
|----------|-----------|
|
|
145
|
+
| `concierge-pages.md` | If `/concierge/` is a distinct template family |
|
|
146
|
+
| `landing-pages-paid-media.md` | Campaign LPs if `indexed: false` pattern exists |
|
|
147
|
+
|
|
148
|
+
**P2**
|
|
149
|
+
|
|
150
|
+
| Playbook | Rationale |
|
|
151
|
+
|----------|-----------|
|
|
152
|
+
| `legal-policy-pages.md` | Privacy, terms |
|
|
153
|
+
|
|
154
|
+
**Audit tip:** Map CloudFront-routed marketing paths only; exclude AWS product URLs from page inventory.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 4. SE Studio (`se-website-2026`) — hard mode
|
|
159
|
+
|
|
160
|
+
**Config:** `cms-edit/project.json` → `projectKey: se2026`
|
|
161
|
+
|
|
162
|
+
**Current state:** `docs/cms-editor/se2026/pages.md` and `articles.md` exist — **extend, don't replace blindly**.
|
|
163
|
+
|
|
164
|
+
**Why hard:** Site is **not designed for arbitrary custom marketing pages**. Page model is a small set of reference layouts (home, about, services, demo landing) using **General Page** template with `topContent` + `content`. New pages should **clone references**, not invent new component families.
|
|
165
|
+
|
|
166
|
+
**Routing signals:**
|
|
167
|
+
|
|
168
|
+
| Flag | Value |
|
|
169
|
+
|------|-------|
|
|
170
|
+
| `enablePerson` | `false` — **no `people.md`** |
|
|
171
|
+
| Team content | **Person** entries in **Team grid** collection |
|
|
172
|
+
| `enableTag` | `false` — simpler article model |
|
|
173
|
+
| `ARTICLES_BASE` | `''` — work/video/blog article types |
|
|
174
|
+
| `enableArticleTypeIndex` | `false` |
|
|
175
|
+
|
|
176
|
+
### Suggested work (not traditional P0/P1/P2)
|
|
177
|
+
|
|
178
|
+
| Action | Rationale |
|
|
179
|
+
|--------|-----------|
|
|
180
|
+
| **Tighten** existing `pages.md` | Ensure reference table, component mapping, and out-of-scope are current |
|
|
181
|
+
| **Tighten** `articles.md` | Work / video / blog rules, case study picks in **Article browser** collections |
|
|
182
|
+
| **Avoid** many specialized page playbooks | No `/providers/`-style families |
|
|
183
|
+
| Optional `work-case-study-pages.md` | If editors frequently add case studies |
|
|
184
|
+
| Optional `demo-landing-pages.md` | Campaign clones from `/demo-landing` |
|
|
185
|
+
| **Do not** add `people.md` | Use articles + Team grid Person guidance inside `pages.md` |
|
|
186
|
+
|
|
187
|
+
### SE website editor guardrails (put in `pages.md`)
|
|
188
|
+
|
|
189
|
+
- New marketing pages: clone `/about`, `/services`, or `/demo-landing` — not blank canvas
|
|
190
|
+
- Homepage slug `index` (URL `/`)
|
|
191
|
+
- Agent test pages: `indexed: false`
|
|
192
|
+
- Component gaps → **Generic** fallback + engineering flag
|
|
193
|
+
- Read `cms-edit://customer/brand` for voice
|
|
194
|
+
|
|
195
|
+
**Audit tip:** `cms-edit peek --page-slug /about` and `/services` — document exact collection nesting before any new playbook.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Per-project audit checklist
|
|
200
|
+
|
|
201
|
+
Copy into working notes for each site:
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
[ ] project.json validated
|
|
205
|
+
[ ] constants.ts flags recorded
|
|
206
|
+
[ ] sitemap categories table
|
|
207
|
+
[ ] templates listed (cms-edit list --type template)
|
|
208
|
+
[ ] 3+ reference pages peek'd
|
|
209
|
+
[ ] capabilities.json reviewed
|
|
210
|
+
[ ] P0 playbook list approved by user
|
|
211
|
+
[ ] pages.md hub links all specialized playbooks
|
|
212
|
+
[ ] task stub per specialized playbook
|
|
213
|
+
[ ] editor-pack regenerated
|
|
214
|
+
[ ] project doctor clean
|
|
215
|
+
[ ] pushed to develop
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Completed reference
|
|
219
|
+
|
|
220
|
+
**Brightline + BLK** (`brightline-sites`) — full P0–P2 shipped. Use as gold standard:
|
|
221
|
+
|
|
222
|
+
- `docs/cms-editor/brightline/` — 8 specialized + hub + articles + blog-tag-matrix
|
|
223
|
+
- `docs/cms-editor/brightlifekids/` — 6 specialized + hub + articles
|
|
224
|
+
|
|
225
|
+
See `PATTERNS.md` for tier tables.
|
|
@@ -30,6 +30,8 @@ Use this skill when you need to read or edit content in Contentful CMS using the
|
|
|
30
30
|
All `save` operations create **draft** versions. A human must review and publish in Contentful.
|
|
31
31
|
|
|
32
32
|
**Assets:** Upload **is** supported (`asset upload`). Default workflow: **search and reuse** existing assets first (`index sync` → `asset search`). When uploading:
|
|
33
|
+
- **Hosted MCP:** always `cms_edit_request_staged_upload` → curl → `asset upload --staged` (never `--base64`)
|
|
34
|
+
- **Local CLI:** `--base64` or `--url` when user approves local CLI
|
|
33
35
|
- Use a **sensible fileName** and **descriptive title** (and alt text where the site uses it)
|
|
34
36
|
- Avoid oversized images — width over **2000px** is usually wasteful for web (exact limits vary by project; check `asset audit` / media review guidance)
|
|
35
37
|
- Prefer `--if-exists-by-filename` to avoid duplicates
|
|
@@ -120,7 +122,7 @@ cms-edit set @c0 anchor "hero-section"
|
|
|
120
122
|
cms-edit set @c1:cmsLabel="Hero — School avoidance" @c2:cmsLabel="What is school avoidance?" @c3:cmsLabel="Signs of school avoidance"
|
|
121
123
|
cms-edit set @c1:heading="Title A" @c2:heading="Title B"
|
|
122
124
|
```
|
|
123
|
-
Each token is `@ref:fieldName=value`. All values are scalar (string, boolean, number). Flags like `--link`, `--links`, `--
|
|
125
|
+
Each token is `@ref:fieldName=value`. All values are scalar (string, boolean, number). Flags like `--link`, `--links`, `--json` do not apply in multi mode.
|
|
124
126
|
|
|
125
127
|
**Entry link fields** (template, articleType, etc. — value is the linked entry ID):
|
|
126
128
|
```bash
|
|
@@ -158,7 +160,7 @@ For any content with multiple paragraphs or newlines, use `printf` piped to stdi
|
|
|
158
160
|
printf '## Why it matters\n\nOur platform helps teams **move faster**.\n\n- Instant setup\n- No code required\n' | cms-edit rtf @c1 body --markdown -
|
|
159
161
|
|
|
160
162
|
# Also correct — file input
|
|
161
|
-
cms-edit rtf @c1 body --markdown --
|
|
163
|
+
cms-edit rtf @c1 body --markdown --content "# Heading\n\nBody."
|
|
162
164
|
cms-edit rtf @c1 body --markdown - < path/to/file.md
|
|
163
165
|
```
|
|
164
166
|
|
|
@@ -170,7 +172,7 @@ cms-edit rtf @c1 body --markdown "Simple single-paragraph body text with **bold*
|
|
|
170
172
|
|
|
171
173
|
**Surgical rich text replace** (compliance / quidget tokens — does not re-import the whole field):
|
|
172
174
|
|
|
173
|
-
- Matching is **per Contentful text node** only. If the author split a phrase with bold (e.g. `**Annual fee: **$95`), the string `Annual fee: $95` will **not** match as one piece; use a shorter `--find` or full `rtf … --
|
|
175
|
+
- Matching is **per Contentful text node** only. If the author split a phrase with bold (e.g. `**Annual fee: **$95`), the string `Annual fee: $95` will **not** match as one piece; use a shorter `--find` or full `rtf … --content`.
|
|
174
176
|
- Quidget strings contain `*`, which Markdown would treat as italic — use **`--replace-plain`**, not `--replace`.
|
|
175
177
|
|
|
176
178
|
```bash
|
|
@@ -246,7 +248,7 @@ Same as Component plus:
|
|
|
246
248
|
When adding body content and a CTA (e.g. PDF download) to an article:
|
|
247
249
|
|
|
248
250
|
1. `cms-edit open --article-slug <slug>` (or `open --id <id>`)
|
|
249
|
-
2. Set body: `cms-edit rtf @<ref> body --markdown "..."` or `--
|
|
251
|
+
2. Set body: `cms-edit rtf @<ref> body --markdown "..."` or `--content` / `--base64`. If you need to add a body component first, use `add` then `rtf`.
|
|
250
252
|
3. `cms-edit add CTA --target bottomContent`
|
|
251
253
|
4. Set CTA links: use `--type external --label "Download PDF" --href <url>` for an external PDF URL, or `--type download --label "Download PDF" --asset-id <asset-id>` for a Contentful asset (get the ID from `cms-edit asset search "..."` or `asset info <id>`).
|
|
252
254
|
5. `cms-edit save`
|
|
@@ -369,13 +371,23 @@ cms-edit asset search "hero background"
|
|
|
369
371
|
cms-edit asset search --filename istockphoto-123.jpg
|
|
370
372
|
cms-edit asset search --filename-match 'istockphoto-.*'
|
|
371
373
|
|
|
372
|
-
#
|
|
373
|
-
cms-edit asset upload ./poster.jpg --title "Poster"
|
|
374
|
+
# Local CLI — URL or base64 (hosted MCP rejects --base64)
|
|
374
375
|
cms-edit asset upload --url https://example.com/image.jpg --if-exists-by-filename
|
|
375
376
|
cms-edit asset upload --base64 "$B64" --mime image/png --file-name poster.png
|
|
376
377
|
|
|
377
|
-
#
|
|
378
|
-
|
|
378
|
+
# Hosted MCP — always staged upload for binary files
|
|
379
|
+
# cms_edit_request_staged_upload → curl uploadUrl → consumeArgs
|
|
380
|
+
# cms_edit ["asset", "upload", "--staged", "<uploadId>", "--mime", "image/png", "--file-name", "photo.png"]
|
|
381
|
+
|
|
382
|
+
# Upload and create a Media wrapper in one step (--media-name defaults to asset title)
|
|
383
|
+
cms-edit asset upload ./figure.png --with-media --media-position Middle
|
|
384
|
+
|
|
385
|
+
# Create a Media wrapper for an existing asset (name defaults to asset title)
|
|
386
|
+
cms-edit create media --asset-id <asset-id>
|
|
387
|
+
|
|
388
|
+
# Fix a badly labelled Media wrapper (migration "Wrapper for …" labels)
|
|
389
|
+
cms-edit batch set <media-entry-id>:name=<asset-title>
|
|
390
|
+
cms-edit batch save
|
|
379
391
|
|
|
380
392
|
# Get asset details
|
|
381
393
|
cms-edit asset info 5xKj2abcDef
|
|
@@ -430,10 +442,10 @@ cms-edit create tag --slug easl-congress-2026 --name "EASL Congress 2026" --tag-
|
|
|
430
442
|
--description "Research presented at EASL Congress 2026." --featured-image <logoAssetId>
|
|
431
443
|
|
|
432
444
|
# Full fields via JSON
|
|
433
|
-
cms-edit create tag --json
|
|
445
|
+
cms-edit create tag --json '{"slug":"presentation"}' --tag-type presentation-type --if-not-exists
|
|
434
446
|
|
|
435
447
|
# Batch bootstrap
|
|
436
|
-
cms-edit create taxonomy-from-json --
|
|
448
|
+
cms-edit create taxonomy-from-json --json '{"tagTypes":[...]}' --if-not-exists
|
|
437
449
|
|
|
438
450
|
# Idempotent single-entry creates
|
|
439
451
|
cms-edit create tag-type --slug conference-venue --name "Conference Venue" --if-not-exists
|
|
@@ -664,9 +676,9 @@ cms-edit peek --id <entryId> # Look up by entry ID
|
|
|
664
676
|
Run a sequence of operations from a JSON file or stdin.
|
|
665
677
|
|
|
666
678
|
```bash
|
|
667
|
-
cms-edit batch run --
|
|
679
|
+
cms-edit batch run --json '[...]' # Run batch ops from inline JSON
|
|
668
680
|
echo '[...]' | cms-edit batch run # Pipe from stdin
|
|
669
|
-
cms-edit batch run --
|
|
681
|
+
cms-edit batch run --json '[...]' --dry-run # Validate without saving
|
|
670
682
|
```
|
|
671
683
|
|
|
672
684
|
Supported ops: `open`, `set`, `rtf`, `rtf-replace`, `save`, `add`, `links-add`.
|
|
@@ -700,8 +712,8 @@ Example `ops.json` — update an existing page with a new CTA that has two butto
|
|
|
700
712
|
Create a complete page or article — including all components, fields, and CTA links — from a single declarative JSON file. This is the recommended approach for creating multiple pages or articles in bulk.
|
|
701
713
|
|
|
702
714
|
```bash
|
|
703
|
-
cms-edit create from-json --
|
|
704
|
-
cms-edit create from-json --
|
|
715
|
+
cms-edit create from-json --json '{...}' # Create from inline JSON
|
|
716
|
+
cms-edit create from-json --json '{...}' --dry-run # Preview without writing
|
|
705
717
|
cat page.json | cms-edit create from-json # Pipe from stdin
|
|
706
718
|
```
|
|
707
719
|
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: contentful-cms-create-editor-playbooks
|
|
3
|
+
description: "Create and ship cms-editor playbooks for customer sites (audit page inventory, tier P0/P1/P2 playbooks, task stubs, regenerate editor-pack). Use for Pedestal, OM1, PointMe, SE website, or repeating the Brightline playbook rollout."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Create cms-editor playbooks
|
|
7
|
+
|
|
8
|
+
Use this skill when a customer site needs **hosted MCP editor playbooks** — the `docs/cms-editor/<projectKey>/` handbooks that become `cms-edit://customer/*` resources after editor-pack generation.
|
|
9
|
+
|
|
10
|
+
**Reference files** (read when drafting playbooks):
|
|
11
|
+
|
|
12
|
+
| File | Purpose |
|
|
13
|
+
|------|---------|
|
|
14
|
+
| `.agents/references/contentful-cms-editor-playbooks/PATTERNS.md` | Two-file pattern, sections, naming, Brightline examples |
|
|
15
|
+
| `.agents/references/contentful-cms-editor-playbooks/PROJECT-ROLLOUT.md` | Rollout queue (Pedestal → OM1 → PointMe → SE website) and per-site audit hints |
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
| Situation | Action |
|
|
20
|
+
|-----------|--------|
|
|
21
|
+
| New site with only `ARTICLES.md` or no playbooks | Full rollout (audit → P0 → regen → doctor) |
|
|
22
|
+
| Site has page categories editors ask about repeatedly | Add specialized playbook + task stub |
|
|
23
|
+
| After Brightline-style rollout on another customer | Follow this skill end-to-end |
|
|
24
|
+
| User says "playbooks for Pedestal / OM1 / PointMe / SE website" | Read `PROJECT-ROLLOUT.md` first |
|
|
25
|
+
|
|
26
|
+
**Precursor (optional but recommended):** If `docs/cms-guidelines/**` is stale or missing screenshots, run **`contentful-cms-update-cms-guidelines`** (`sync` or `fresh`) **before** playbooks so `components-index` and guideline snippets are accurate.
|
|
27
|
+
|
|
28
|
+
## Pit-of-success order
|
|
29
|
+
|
|
30
|
+
1. **Locate** customer repo + `cms-edit/<site>/project.json` → note `projectKey`, `appDir`
|
|
31
|
+
2. **Audit** routing, page inventory, capabilities (Phase 1)
|
|
32
|
+
3. **Plan** playbook set by tier (Phase 2) — propose to user before writing P1/P2
|
|
33
|
+
4. **Write** playbooks + task stubs (Phase 3)
|
|
34
|
+
5. **Regenerate** editor pack + doctor (Phase 4) — skill **`contentful-cms-regenerate-editor-pack`**
|
|
35
|
+
6. **Commit + push** customer `develop` (never manual Vercel deploy)
|
|
36
|
+
|
|
37
|
+
Editors consume playbooks via skill **`contentful-cms-editor-tasks`** (`tasks-index` → `task-*` → specialized playbook).
|
|
38
|
+
|
|
39
|
+
## Phase 1 — Site audit
|
|
40
|
+
|
|
41
|
+
Run from the **customer repo root**. Record findings in your working notes before writing files.
|
|
42
|
+
|
|
43
|
+
### Config and routing
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# projectKey must match docs/cms-editor/<projectKey>/
|
|
47
|
+
cat cms-edit/<site>/project.json # or cms-edit/project.json (single-site)
|
|
48
|
+
|
|
49
|
+
# Routing flags and URL bases
|
|
50
|
+
cat <appDir>/src/lib/constants.ts
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Check:
|
|
54
|
+
|
|
55
|
+
| Signal | Source | Playbook impact |
|
|
56
|
+
|--------|--------|-----------------|
|
|
57
|
+
| `projectKey` | `project.json` | Directory name under `docs/cms-editor/` |
|
|
58
|
+
| `enablePerson` | `constants.ts` | `people.md` when true (doctor warns if missing) |
|
|
59
|
+
| `enableArticleTypeIndex` / article routes | `constants.ts` | `articles.md` depth |
|
|
60
|
+
| `ARTICLES_BASE`, `TAGS_BASE`, `PEOPLE_BASE` | `constants.ts` | URL patterns in playbooks |
|
|
61
|
+
| `homepageSlug` | `project.json` `website` (default `index`) | Routing examples |
|
|
62
|
+
| `markdownArticleTypeSlugs` | `constants.ts` | Article URL shapes (Pedestal) |
|
|
63
|
+
|
|
64
|
+
### Page inventory
|
|
65
|
+
|
|
66
|
+
Build a **category table** (URL prefix → human label → clone reference slug):
|
|
67
|
+
|
|
68
|
+
1. Production sitemap: `curl -s https://<prod>/sitemap.xml` or app's `pnpm sitemap-validate` config
|
|
69
|
+
2. Group paths by prefix (`/resources/`, `/insights/`, `/what-we-treat/`, etc.)
|
|
70
|
+
3. Pick 1–3 **canonical clone sources** per category (`peek --page-slug`, live `.md` URLs)
|
|
71
|
+
|
|
72
|
+
### CMS capabilities
|
|
73
|
+
|
|
74
|
+
With dev server + tokens in `.env.local`:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
cms-edit project validate --project-config cms-edit/<site>/project.json
|
|
78
|
+
cms-edit editor-pack generate --project-config cms-edit/<site>/project.json # dry run if pack exists
|
|
79
|
+
cms-edit list --type template
|
|
80
|
+
cms-edit peek --page-slug /about # adjust per site
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Read generated `capabilities.json` (or editor-pack copy) for `content.pages`, `content.articles`, `content.persons`.
|
|
84
|
+
|
|
85
|
+
### Skip rules
|
|
86
|
+
|
|
87
|
+
| Condition | Skip |
|
|
88
|
+
|-----------|------|
|
|
89
|
+
| `enablePerson === false` | `people.md` (SE website — team via **Person** entries in collections, not `/people/` routes) |
|
|
90
|
+
| No distinct URL category with ≥3 pages | Specialized playbook — fold into `pages.md` |
|
|
91
|
+
| Page type is engineering-only | Document in `pages.md` "out of scope" instead |
|
|
92
|
+
|
|
93
|
+
## Phase 2 — Plan playbook tiers
|
|
94
|
+
|
|
95
|
+
Propose a tier list to the user. Ship **P0 first**, regen + doctor, then P1/P2 in follow-up commits.
|
|
96
|
+
|
|
97
|
+
### P0 (always aim to ship first)
|
|
98
|
+
|
|
99
|
+
| File | When |
|
|
100
|
+
|------|------|
|
|
101
|
+
| `pages.md` | Site has `content.pages` — **required** (doctor + checklist) |
|
|
102
|
+
| `articles.md` or `ARTICLES.md` | Site has articles — either filename works |
|
|
103
|
+
| `people.md` | `enablePerson === true` |
|
|
104
|
+
| 1–3 **specialized** playbooks | Highest editor traffic (see `PROJECT-ROLLOUT.md` per site) |
|
|
105
|
+
|
|
106
|
+
### P1 — Secondary page families
|
|
107
|
+
|
|
108
|
+
Specialized playbooks for distinct URL families (provider, location, resources hub, bilingual locale, etc.).
|
|
109
|
+
|
|
110
|
+
### P2 — Low-frequency / compliance
|
|
111
|
+
|
|
112
|
+
Legal/policy, niche hub indexes, partner microsites.
|
|
113
|
+
|
|
114
|
+
### `pages.md` as hub
|
|
115
|
+
|
|
116
|
+
The general `pages.md` must link to every specialized playbook:
|
|
117
|
+
|
|
118
|
+
```markdown
|
|
119
|
+
| Page type | Playbook |
|
|
120
|
+
|-----------|----------|
|
|
121
|
+
| Condition or therapy program | `cms-edit://customer/condition-program-pages` |
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
See `PATTERNS.md` for the full Brightline hub example.
|
|
125
|
+
|
|
126
|
+
## Phase 3 — Write playbooks
|
|
127
|
+
|
|
128
|
+
**Authoring path:** `docs/cms-editor/<projectKey>/`
|
|
129
|
+
|
|
130
|
+
### File types
|
|
131
|
+
|
|
132
|
+
| Path | Becomes | Notes |
|
|
133
|
+
|------|---------|-------|
|
|
134
|
+
| `pages.md` | `cms-edit://customer/pages` | Sets `hasPagesPlaybook`; checklist auto-links |
|
|
135
|
+
| `articles.md` or `ARTICLES.md` | `cms-edit://customer/articles` | Special-cased in generator |
|
|
136
|
+
| `people.md` | `cms-edit://customer/people` | When persons enabled |
|
|
137
|
+
| `<topic>.md` | `cms-edit://customer/<topic>` | kebab-case basename = resource name |
|
|
138
|
+
| `tasks/<slug>.md` | `cms-edit://customer/task-<slug>` | Appears in `tasks-index` |
|
|
139
|
+
|
|
140
|
+
**Do not** put task stubs in the root — only under `tasks/`.
|
|
141
|
+
|
|
142
|
+
### Specialized playbook sections
|
|
143
|
+
|
|
144
|
+
Each `<topic>.md` should include:
|
|
145
|
+
|
|
146
|
+
1. **Title** — `# <Human name> — <Site>`
|
|
147
|
+
2. **URL patterns** — table with examples
|
|
148
|
+
3. **Typical content stack** — component/collection order
|
|
149
|
+
4. **Reference pages** — clone sources with public paths
|
|
150
|
+
5. **Template** — which Contentful template label
|
|
151
|
+
6. **Workflow** — numbered steps ending in preview → diff → save → publish handoff
|
|
152
|
+
7. **Out of scope** — what editors must not do
|
|
153
|
+
|
|
154
|
+
Start from template: `packages/contentful-cms/docs/cms-edit-project-template/docs/cms-editor/example/pages.md`
|
|
155
|
+
|
|
156
|
+
### Task stub (required for tasks-index)
|
|
157
|
+
|
|
158
|
+
For each specialized playbook, add `tasks/<topic>.md`:
|
|
159
|
+
|
|
160
|
+
```markdown
|
|
161
|
+
# Capability: <Short title>
|
|
162
|
+
|
|
163
|
+
## Intent phrases
|
|
164
|
+
|
|
165
|
+
- <phrase editors might say>
|
|
166
|
+
- ...
|
|
167
|
+
|
|
168
|
+
## Requires capabilities
|
|
169
|
+
|
|
170
|
+
`pages` # or `articles`, `persons`
|
|
171
|
+
|
|
172
|
+
## Prerequisites
|
|
173
|
+
|
|
174
|
+
- Read `cms-edit://customer/<topic>`
|
|
175
|
+
- Read `cms-edit://customer/pages`
|
|
176
|
+
|
|
177
|
+
## Steps
|
|
178
|
+
|
|
179
|
+
1. ...
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Parser reads `# Capability:` title and `## Intent phrases` bullets for `tasks-index.md`. See `PATTERNS.md`.
|
|
183
|
+
|
|
184
|
+
### SE website constraint
|
|
185
|
+
|
|
186
|
+
`se-website-2026` is **not** a free-form marketing site. Playbooks must:
|
|
187
|
+
|
|
188
|
+
- Emphasize **clone from reference pages** (`/index`, `/about`, `/services`, `/demo-landing`)
|
|
189
|
+
- Document **General Page** template + `topContent` / `content` regions (existing `pages.md`)
|
|
190
|
+
- Treat new page types as **exceptions** — flag component gaps, use **Generic** fallback
|
|
191
|
+
- **No** `people.md` — `enablePerson=false`; team content is **Person** entries inside **Team grid**
|
|
192
|
+
- Article playbooks cover work/video/blog — not arbitrary landing pages
|
|
193
|
+
|
|
194
|
+
Read existing `docs/cms-editor/se2026/pages.md` before extending; prefer tightening scope over adding many specialized playbooks.
|
|
195
|
+
|
|
196
|
+
## Phase 4 — Regenerate and validate
|
|
197
|
+
|
|
198
|
+
Follow **`contentful-cms-regenerate-editor-pack`**:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
cms-edit project validate --project-config cms-edit/<site>/project.json
|
|
202
|
+
cms-edit editor-pack generate --project-config cms-edit/<site>/project.json
|
|
203
|
+
cms-edit project doctor --project-config cms-edit/<site>/project.json
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Doctor checks:
|
|
207
|
+
|
|
208
|
+
- `pages.md` present when pages capability on
|
|
209
|
+
- `articles.md` when articles capability on
|
|
210
|
+
- `people.md` when persons capability on
|
|
211
|
+
- Editor-pack resources match hand-authored files
|
|
212
|
+
|
|
213
|
+
Review diff:
|
|
214
|
+
|
|
215
|
+
- `tasks-index.md` lists new `task-*` entries with intent phrases
|
|
216
|
+
- `checklist.md` links `pages` / `articles` playbooks
|
|
217
|
+
- `manifest.json` includes new resource names
|
|
218
|
+
- `overview.md` references new playbooks
|
|
219
|
+
|
|
220
|
+
## Phase 5 — Commit and publish
|
|
221
|
+
|
|
222
|
+
In the **customer repo** (not se-core-product):
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
git add docs/cms-editor/<projectKey>/ cms-edit/<site>/editor-pack/
|
|
226
|
+
git commit -m "docs(cms-editor): add <site> editor playbooks (P0)"
|
|
227
|
+
git push origin develop
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Hosted MCP rebuilds from git push — **do not** run `vercel deploy` or `cms-edit:deploy`.
|
|
231
|
+
|
|
232
|
+
## Multi-site monorepos
|
|
233
|
+
|
|
234
|
+
| Repo | Sites | `projectKey` folders |
|
|
235
|
+
|------|-------|----------------------|
|
|
236
|
+
| `pedestal-sites` | Pedestal Health, Headwater | `pedestal-health`, `headwater-science` |
|
|
237
|
+
| `brightline-sites` | Brightline, BLK | `brightline`, `brightlifekids` |
|
|
238
|
+
|
|
239
|
+
Each site has its own `cms-edit/<site>/project.json` and `docs/cms-editor/<projectKey>/`. Roll out **one site at a time**.
|
|
240
|
+
|
|
241
|
+
## Suggested rollout queue
|
|
242
|
+
|
|
243
|
+
See **`PROJECT-ROLLOUT.md`** for per-site P0/P1/P2 checklists. Default order:
|
|
244
|
+
|
|
245
|
+
1. **Pedestal** (`pedestal-health`, then `headwater-science`)
|
|
246
|
+
2. **OM1**
|
|
247
|
+
3. **PointMe**
|
|
248
|
+
4. **SE website** (`se2026`) — hardest; extend existing playbooks cautiously
|
|
249
|
+
|
|
250
|
+
## Related skills
|
|
251
|
+
|
|
252
|
+
| Skill | When |
|
|
253
|
+
|-------|------|
|
|
254
|
+
| `contentful-cms-regenerate-editor-pack` | After any playbook change |
|
|
255
|
+
| `contentful-cms-editor-tasks` | How editors consume playbooks |
|
|
256
|
+
| `contentful-cms-update-cms-guidelines` | Refresh guidelines/screenshots first |
|
|
257
|
+
| `contentful-cms-core` | `peek`, `list`, `create from-json` during audit |
|
|
258
|
+
| `se-marketing-sites-curate-showcase-mocks` | Showcase data before screenshot refresh |
|
|
259
|
+
|
|
260
|
+
## Related docs
|
|
261
|
+
|
|
262
|
+
| Doc | Purpose |
|
|
263
|
+
|-----|---------|
|
|
264
|
+
| `docs/RELATED_PROJECTS.md` | Repo paths, Contentful spaces |
|
|
265
|
+
| `packages/contentful-cms/docs/cms-edit-project-template/README.md` | `project.json`, playbook stubs |
|
|
266
|
+
| `packages/contentful-cms/docs/mcp/hosted-guide.md` | MCP resource URIs |
|
|
@@ -28,9 +28,9 @@ The playbook defines phases, hosted vs local limits, and confirmation gates. Thi
|
|
|
28
28
|
|
|
29
29
|
| Goal | Command |
|
|
30
30
|
|------|---------|
|
|
31
|
-
| Failures JSON | `cms-edit --json asset review` |
|
|
32
|
-
| Full + usage (local) | `cms-edit --json asset review --include-passing --include-usage --usage-limit 0` |
|
|
33
|
-
| Usage sample (hosted) | `cms-edit --json asset review --include-usage --usage-limit 50` |
|
|
31
|
+
| Failures JSON | `cms-edit --json-output asset review` |
|
|
32
|
+
| Full + usage (local) | `cms-edit --json-output asset review --include-passing --include-usage --usage-limit 0` |
|
|
33
|
+
| Usage sample (hosted) | `cms-edit --json-output asset review --include-usage --usage-limit 50` |
|
|
34
34
|
|
|
35
35
|
Hosted MCP: **no `--space`**. Do not use `--usage-limit 0` with `--include-passing` on hosted MCP.
|
|
36
36
|
|
|
@@ -75,6 +75,8 @@ Summarize: totals, top `issueCounts`, quick wins (alt, GIFs, stock filenames).
|
|
|
75
75
|
|
|
76
76
|
**Fixes (user-approved only):** `cms-edit asset set-description <id> "…"` — drafts only, no publish.
|
|
77
77
|
|
|
78
|
+
**Media entry labels:** The Contentful list label for a **Media** wrapper is its `name` field — **set it to the linked asset's `title`**, not `visual-{assetId}`, `Wrapper for {assetId}`, or the filename. When creating wrappers: `cms-edit create media --asset-id <id>` (name defaults to asset title) or `asset upload --with-media` (use `--media-name` only when you need a distinct label for multiple wrappers on the same asset). To fix existing entries: `cms-edit batch set <media-entry-id>:name=<asset-title>` then `batch save`.
|
|
79
|
+
|
|
78
80
|
For per-page alt work: **`contentful-cms-alt-text-audit`**.
|
|
79
81
|
|
|
80
82
|
## Image guide (optional extension)
|
|
@@ -82,7 +84,7 @@ For per-page alt work: **`contentful-cms-alt-text-audit`**.
|
|
|
82
84
|
When the client wants a **reference guide** (not just remediation):
|
|
83
85
|
|
|
84
86
|
```bash
|
|
85
|
-
cms-edit --json asset review --include-passing --include-usage --usage-limit 0 > docs/image-inventory.json
|
|
87
|
+
cms-edit --json-output asset review --include-passing --include-usage --usage-limit 0 > docs/image-inventory.json
|
|
86
88
|
```
|
|
87
89
|
|
|
88
90
|
- Cache AI descriptions: `docs/descriptions/{assetId}.json` (write-through per image)
|
|
@@ -125,6 +125,7 @@ In Claude Desktop (hosted integration): ask to read `cms-edit://customer/routing
|
|
|
125
125
|
|
|
126
126
|
| Prior work | Skill |
|
|
127
127
|
|------------|-------|
|
|
128
|
+
| New hand-authored playbooks | `contentful-cms-create-editor-playbooks` |
|
|
128
129
|
| Guidelines changed | `contentful-cms-update-cms-guidelines` |
|
|
129
130
|
| New registration | `se-marketing-sites-register-cms-features` |
|
|
130
131
|
| Editor Integrations setup | `contentful-cms-setup` (hosted path) |
|
|
@@ -10,11 +10,11 @@ Use this skill when editing **rich text** fields (body, additionalCopy) and inse
|
|
|
10
10
|
## Rich text (rtf)
|
|
11
11
|
|
|
12
12
|
- **Replace** body with Markdown (single paragraph, no newlines): `cms-edit rtf @c1 body --markdown "Simple body with **bold** and [link](https://example.com)."`
|
|
13
|
-
- **Multiline content** — use `
|
|
13
|
+
- **Multiline content** — use `--content` or `--base64` (hosted MCP has no filesystem):
|
|
14
14
|
```bash
|
|
15
|
-
|
|
15
|
+
cms-edit rtf @c1 body --markdown --content "## Heading\n\nParagraph with **bold**."
|
|
16
16
|
```
|
|
17
|
-
-
|
|
17
|
+
- For large payloads via MCP: `--base64 <encoded-markdown>`.
|
|
18
18
|
- Markdown supported: headings, bold/italic, links, lists, blockquote, inline code, `---`.
|
|
19
19
|
|
|
20
20
|
Use **set** for scalar and link fields; use **rtf** only for rich text fields.
|
|
@@ -56,11 +56,8 @@ cms-edit rtf replace @c1 body \
|
|
|
56
56
|
Apply multiple find/replace operations in a single call. All ops are validated before any write.
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
# From stdin
|
|
63
|
-
echo '[{"find":"old","replaceWith":"new","mode":"exactlyOne"}]' | cms-edit rtf patch @c0 body
|
|
59
|
+
cms-edit rtf patch @c0 body --json '[{"find":"old","replaceWith":"new","mode":"exactlyOne"}]'
|
|
60
|
+
# Or --json-base64 for large patch arrays
|
|
64
61
|
```
|
|
65
62
|
|
|
66
63
|
Each op in the JSON array supports:
|
|
@@ -25,8 +25,8 @@ If no brand context is available, ask the user for these details.
|
|
|
25
25
|
| About | AboutPage + Organization |
|
|
26
26
|
| Service/Product | Service or Product |
|
|
27
27
|
| Pricing | Product with Offer |
|
|
28
|
-
| Blog listing | CollectionPage |
|
|
29
|
-
| Article |
|
|
28
|
+
| Blog listing | CollectionPage + Blog + ItemList |
|
|
29
|
+
| Article | BlogPosting |
|
|
30
30
|
| FAQ | FAQPage with Question/Answer |
|
|
31
31
|
| Contact | ContactPage |
|
|
32
32
|
| Team/People | ProfilePage or Person |
|
|
@@ -35,33 +35,59 @@ If no brand context is available, ask the user for these details.
|
|
|
35
35
|
|
|
36
36
|
## Phase 2: Generate Mustache Templates
|
|
37
37
|
|
|
38
|
-
Create JSON-LD templates using
|
|
38
|
+
Create JSON-LD templates using runtime variables from `buildStructuredDataContext()` in `@se-studio/core-ui` (see `packages/core-ui/src/utils/structuredDataUtils.ts`).
|
|
39
39
|
|
|
40
|
-
- `
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- `{{
|
|
45
|
-
- `{{
|
|
46
|
-
- `{{
|
|
47
|
-
- `{{
|
|
48
|
-
- `{{
|
|
49
|
-
- `{{
|
|
40
|
+
Reference markup generators in `@se-studio/cms-seo` (`breadcrumbListMarkup`, `blogPostingMarkup`, `itemListMarkup`, etc.).
|
|
41
|
+
|
|
42
|
+
### URLs and page
|
|
43
|
+
|
|
44
|
+
- `{{baseUrl}}` — site origin with trailing slash (e.g. `https://www.example.com/`)
|
|
45
|
+
- `{{{baseUrl}}}` — same, triple-brace for JSON-safe URLs in `@id` fields
|
|
46
|
+
- `{{currentUrl}}` / `{{{currentUrl}}}` — full canonical URL of the current page
|
|
47
|
+
- `{{page.title}}` — page or content title
|
|
48
|
+
- `{{page.description}}` — SEO meta description
|
|
49
|
+
- `{{page.slug}}` — content slug
|
|
50
|
+
- `{{{page.imageUrl}}}` — OG image URL when featured image is set
|
|
51
|
+
- `{{#page.breadcrumbs}}` — breadcrumb segments: `position`, `name`, optional `url`, `last`
|
|
52
|
+
|
|
53
|
+
### Articles
|
|
54
|
+
|
|
55
|
+
- `{{article.title}}`, `{{article.description}}`
|
|
56
|
+
- `{{article.datePublished}}`, `{{article.dateModified}}` — ISO 8601 (not `article.date`)
|
|
57
|
+
- `{{article.authorName}}`, `{{{article.authorUrl}}}` — primary author
|
|
58
|
+
- `{{#article.authors}}` — multi-author: `name`, optional `url` per author
|
|
59
|
+
- `{{{article.imageUrl}}}` — featured image URL
|
|
60
|
+
|
|
61
|
+
### Person pages
|
|
62
|
+
|
|
63
|
+
- `{{person.name}}`, `{{person.jobTitle}}`, `{{{person.imageUrl}}}`
|
|
64
|
+
|
|
65
|
+
### Listing pages (ItemList)
|
|
66
|
+
|
|
67
|
+
When the app wires `buildListingItems()` / `buildListingStructuredDataContext()` from `@se-studio/core-ui/server`:
|
|
68
|
+
|
|
69
|
+
- `{{#listing.items}}` — `position`, `name`, `{{{url}}}`, `last` (for Mustache comma separation)
|
|
70
|
+
|
|
71
|
+
Static brand data (organization address, social URLs, logo) belongs **in the CMS template**, not in code.
|
|
50
72
|
|
|
51
73
|
## Phase 3: Upload via cms-edit
|
|
52
74
|
|
|
53
75
|
1. Check available fields:
|
|
54
76
|
- `cms-edit schema page` — page content type fields
|
|
55
77
|
- `cms-edit schema template` — template content type fields
|
|
56
|
-
- Look for `
|
|
57
|
-
2. For **template-level** schemas (Organization, WebSite — shared): `cms-edit list --type template` → open → set
|
|
58
|
-
3. For **
|
|
59
|
-
4.
|
|
78
|
+
- Look for `structuredData` or `indexPageStructuredData`
|
|
79
|
+
2. For **template-level** schemas (Organization, WebSite, BreadcrumbList — shared): `cms-edit list --type template` → open → set
|
|
80
|
+
3. For **article type** schemas (BlogPosting on `structuredData`, Blog/CollectionPage/ItemList on `indexPageStructuredData`): link on articleType entry
|
|
81
|
+
4. For **page-level** subtype overrides (FAQPage, Product, Service): link on the page entry only
|
|
82
|
+
5. `cms-edit diff` then `cms-edit save`
|
|
60
83
|
|
|
61
84
|
## Best Practices
|
|
62
85
|
|
|
63
86
|
- Don't duplicate — template-level Organization schema covers all pages
|
|
64
|
-
-
|
|
87
|
+
- Link schema on **templates and types**, not on every article
|
|
88
|
+
- Use specific types where they apply — `BlogPosting` for blog posts, `ProfilePage` for authors
|
|
89
|
+
- BreadcrumbList `item` property: output only when `{{#url}}` is present on a segment
|
|
90
|
+
- One FAQPage per URL — do not duplicate component-level and CMS-level FAQPage on the same page
|
|
65
91
|
- Validate all required properties are present
|
|
66
92
|
- Schema must reflect actual page content
|
|
67
93
|
|
|
@@ -72,4 +98,4 @@ Create JSON-LD templates using these standard Mustache variables:
|
|
|
72
98
|
|
|
73
99
|
## Related skills
|
|
74
100
|
|
|
75
|
-
See the **core** skill for the full cms-edit workflow. See the **seo-descriptions** skill for meta description generation. For bulk audit/apply across all entries, schema linking, publish phases, and production verification, see **cms-seo-audit**.
|
|
101
|
+
See the **core** skill for the full cms-edit workflow. See the **seo-descriptions** skill for meta description generation. For bulk audit/apply across all entries, schema linking, publish phases, and production verification, see **cms-seo-audit**.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: contentful-cms-setup
|
|
3
|
-
description: "Guide a user through connecting hosted cms-edit MCP for Claude
|
|
3
|
+
description: "Guide a user through connecting hosted cms-edit MCP for Claude or Grok (OAuth)."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Skill: cms-edit Setup
|
|
7
7
|
|
|
8
|
-
Use this skill when the user wants to connect Claude to their Contentful site via **hosted cms-edit MCP**.
|
|
8
|
+
Use this skill when the user wants to connect Claude or Grok to their Contentful site via **hosted cms-edit MCP**.
|
|
9
9
|
|
|
10
10
|
Local stdio MCP and the setup wizard are **not supported**. Editors connect through the site's `/cms-edit` onboarding flow.
|
|
11
11
|
|
|
@@ -35,6 +35,39 @@ Use skill **`contentful-cms-editor-tasks`** for the tasks-index → capability p
|
|
|
35
35
|
|
|
36
36
|
---
|
|
37
37
|
|
|
38
|
+
## Hosted setup (Grok Build)
|
|
39
|
+
|
|
40
|
+
Use when the user wants cms-edit in **Grok Build** (not local stdio MCP).
|
|
41
|
+
|
|
42
|
+
### Step 1: Configure Grok
|
|
43
|
+
|
|
44
|
+
Add to `~/.grok/config.toml`:
|
|
45
|
+
|
|
46
|
+
```toml
|
|
47
|
+
[mcp_servers.cms-edit-<projectKey>]
|
|
48
|
+
url = "https://<host>/api/mcp"
|
|
49
|
+
enabled = true
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The URL **must** end with `/api/mcp`. Use the MCP URL from the site's `/cms-edit` page.
|
|
53
|
+
|
|
54
|
+
### Step 2: Connect
|
|
55
|
+
|
|
56
|
+
1. In Grok, run `/mcps`
|
|
57
|
+
2. Select the cms-edit server
|
|
58
|
+
3. Press **`i`** to initiate OAuth (not just enable)
|
|
59
|
+
4. Sign in with Contentful when prompted
|
|
60
|
+
|
|
61
|
+
### Step 3: Verify
|
|
62
|
+
|
|
63
|
+
Run `grok mcp doctor cms-edit-<projectKey>` or call `cms_edit_version` in a Grok session.
|
|
64
|
+
|
|
65
|
+
**Reconnect:** `/mcps` → press `i` again if OAuth expires.
|
|
66
|
+
|
|
67
|
+
Full guide: `packages/contentful-cms/docs/mcp/hosted-guide.md` (Grok Build section).
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
38
71
|
## Developers (CLI + skills, not local MCP)
|
|
39
72
|
|
|
40
73
|
For engineering work in a site repo (Cursor, Grok, terminal):
|
|
@@ -51,7 +84,10 @@ Do **not** register a local `mcpServers.cms-edit` entry in Claude Desktop — us
|
|
|
51
84
|
## Troubleshooting
|
|
52
85
|
|
|
53
86
|
**OAuth / sign-in fails**
|
|
54
|
-
→ Confirm the user was invited to the Contentful space and is signing in with the correct account.
|
|
87
|
+
→ Confirm the user was invited to the Contentful space and is signing in with the correct account. In Grok, use `/mcps` → press `i` (not just toggle). Confirm config URL ends with `/api/mcp`.
|
|
88
|
+
|
|
89
|
+
**Grok browser flashes and closes**
|
|
90
|
+
→ Usually a redirect_uri mismatch before cms-edit v2.7.7+; upgrade the hosted deployment and retry OAuth.
|
|
55
91
|
|
|
56
92
|
**`cms_edit` tool not available**
|
|
57
93
|
→ Reconnect via `/cms-edit` or Claude Integrations. Remove any legacy local MCP or `.mcpb` extension entries.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: se-marketing-sites-markdown-accuracy-review
|
|
3
|
+
description: "LLM review of production markdown exports vs HTML pages. Use when auditing .md accuracy, running markdown-accuracy-audit artifacts, or writing docs/reports/markdown-accuracy-audit.md."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Markdown accuracy review (LLM)
|
|
7
|
+
|
|
8
|
+
Compare production **HTML** pages with their **`.md`** exports to judge whether markdown is an accurate representation of CMS content. Metrics collection is automated; **verdicts are written by the agent** using this rubric.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
|
|
12
|
+
1. Run the collector from monorepo root:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
node packages/site-check/markdown-accuracy-audit.mjs --site se2026 --path /about/ --dry-run
|
|
16
|
+
node packages/site-check/markdown-accuracy-audit.mjs --delay-ms 500
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. Read artifacts under `docs/reports/.markdown-audit-artifacts/<site>/<slug>/`:
|
|
20
|
+
- `meta.json` — URLs, metrics, cache headers
|
|
21
|
+
- `page.html` — full HTML (`<script>` / `<style>` removed only)
|
|
22
|
+
- `page.md` — full markdown, verbatim
|
|
23
|
+
|
|
24
|
+
**Do not truncate** HTML or markdown when reviewing. Read complete files.
|
|
25
|
+
|
|
26
|
+
## Review rubric
|
|
27
|
+
|
|
28
|
+
For each URL, assess:
|
|
29
|
+
|
|
30
|
+
| Dimension | Question |
|
|
31
|
+
|-----------|----------|
|
|
32
|
+
| **Coverage** | Are substantive CMS blocks (headings, body, lists, link text, image alt text) present in markdown? |
|
|
33
|
+
| **Fidelity** | Do title, H1, and key facts match HTML? Any wrong or invented content? |
|
|
34
|
+
| **Expected omissions** | Nav, footer, cookie banners, forms, carousels, video players, and interactive widgets may be absent — note explicitly. |
|
|
35
|
+
| **Markdown quality** | Sensible structure, working link hrefs, frontmatter completeness, canonical alignment. |
|
|
36
|
+
| **Fetch health** | Check `meta.json` metrics — non-2xx or empty bodies are `Error`, not content verdicts. |
|
|
37
|
+
|
|
38
|
+
## Verdicts
|
|
39
|
+
|
|
40
|
+
Use exactly one:
|
|
41
|
+
|
|
42
|
+
- **Accurate** — CMS content fully represented; omissions are only expected chrome/interactivity.
|
|
43
|
+
- **Mostly accurate** — Core content matches; minor gaps (eyebrow text, secondary metadata, non-critical visuals).
|
|
44
|
+
- **Partial** — Important sections missing or materially different, but primary message partly preserved.
|
|
45
|
+
- **Inaccurate** — Wrong headings/facts, major missing blocks, or misleading representation.
|
|
46
|
+
- **Error** — Fetch failed or empty response (see `meta.json` metrics).
|
|
47
|
+
|
|
48
|
+
## Review column format
|
|
49
|
+
|
|
50
|
+
2–4 sentences in the final report table:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
**Mostly accurate** — H1 and body copy match. Markdown omits the team photo grid and contact form (expected). Pre-heading eyebrow in HTML not exported.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Report assembly
|
|
57
|
+
|
|
58
|
+
Write [`docs/reports/markdown-accuracy-audit.md`](../../../../docs/reports/markdown-accuracy-audit.md):
|
|
59
|
+
|
|
60
|
+
1. Run metadata (timestamp, site count, URL count).
|
|
61
|
+
2. Summary table of verdict counts.
|
|
62
|
+
3. Per-site sections with table columns: **URL | HTML size | MD size | HTML ms | MD ms | Cache | Review**.
|
|
63
|
+
4. JSON sidecar [`docs/reports/markdown-accuracy-audit.json`](../../../../docs/reports/markdown-accuracy-audit.json) merging metrics + verdict + review text.
|
|
64
|
+
|
|
65
|
+
Review in site batches (~6–13 URLs). Commit `.md` and `.json` to `dev`; artifacts dir stays gitignored.
|
|
66
|
+
|
|
67
|
+
## Dry-run gate
|
|
68
|
+
|
|
69
|
+
When asked for a dry run, collect **one** case (default: SE Studio `/about/`), perform the LLM review, and present a **single sample table row** for format approval before running all 51 smoke URLs.
|
|
@@ -87,12 +87,28 @@ jobs:
|
|
|
87
87
|
VERCEL_PROTECTION_BYPASS_TOKEN: ${{ secrets.VERCEL_PROTECTION_BYPASS_TOKEN }}
|
|
88
88
|
run: pnpm smoke-test:live
|
|
89
89
|
- name: Report Deployment Check status
|
|
90
|
-
if: always()
|
|
91
|
-
uses: vercel/repository-dispatch/actions/status@
|
|
90
|
+
if: always() && github.event_name == 'repository_dispatch'
|
|
91
|
+
uses: vercel/repository-dispatch/actions/status@44f4d342ebc265c58167a2aa77d5a0d5a6eb20fd
|
|
92
92
|
with:
|
|
93
93
|
name: "Vercel - <vercel-project-name>: deployment smoke"
|
|
94
|
+
# Vercel can miss the first GitHub status webhook; re-post after a short delay.
|
|
95
|
+
- name: Retry Deployment Check status for Vercel reconciliation
|
|
96
|
+
if: always() && github.event_name == 'repository_dispatch'
|
|
97
|
+
env:
|
|
98
|
+
CHECK_NAME: "Vercel - <vercel-project-name>: deployment smoke"
|
|
99
|
+
DEPLOYMENT_SHA: ${{ github.event.client_payload.git.sha }}
|
|
100
|
+
CHECK_STATE: ${{ job.status == 'success' && 'success' || 'failure' }}
|
|
101
|
+
GH_TOKEN: ${{ github.token }}
|
|
102
|
+
run: |
|
|
103
|
+
sleep 30
|
|
104
|
+
gh api "repos/${GITHUB_REPOSITORY}/statuses/${DEPLOYMENT_SHA}" \
|
|
105
|
+
-f state="${CHECK_STATE}" \
|
|
106
|
+
-f context="${CHECK_NAME}" \
|
|
107
|
+
-f target_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
|
|
94
108
|
```
|
|
95
109
|
|
|
110
|
+
Use the deployment commit SHA from `client_payload.git.sha`, not `github.sha`. Repeat the retry block in each job when a workflow has multiple Vercel projects (monorepos).
|
|
111
|
+
|
|
96
112
|
GitHub secret: `VERCEL_PROTECTION_BYPASS_TOKEN` (Vercel → Deployment Protection → Protection Bypass for Automation). Set `SMOKE_TEST_IGNORE=true` to bypass smoke in an emergency.
|
|
97
113
|
|
|
98
114
|
Or from the app directory without a per-app script: `node ../../scripts/smoke-test-preview.mjs` (loads `.env.local` and calls `runPreviewStaticSmokeTest`).
|
|
@@ -11,7 +11,7 @@ Update npm dependencies to **latest** in se-core-product and consumer repos that
|
|
|
11
11
|
|
|
12
12
|
**Default:** Process **one repo per invocation**. At the end, summarize changes and offer the next project.
|
|
13
13
|
|
|
14
|
-
**Never:** push to `main`/`master`; bump Next to 16; bump Node to 25+; use `pnpm patch` / `patchedDependencies` / `patches
|
|
14
|
+
**Never:** push to `main`/`master`; bump Next to 16; bump Node to 25+; use `pnpm patch` / `patchedDependencies` / `patches/`; bypass or remove `minimumReleaseAge`.
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
@@ -61,17 +61,27 @@ Commit the bootstrap copy as part of the deps update commit when you add it.
|
|
|
61
61
|
|
|
62
62
|
---
|
|
63
63
|
|
|
64
|
-
## Step 3 —
|
|
64
|
+
## Step 3 — Supply-chain policy + pin overrides
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
Every repo **must** have this block in `pnpm-workspace.yaml` (merge into existing file — do not remove other keys such as `allowBuilds`, repo-specific excludes, or PointMe's extra overrides):
|
|
67
67
|
|
|
68
68
|
```yaml
|
|
69
|
+
minimumReleaseAge: 1440
|
|
70
|
+
minimumReleaseAgeExclude:
|
|
71
|
+
- '@se-studio/*'
|
|
72
|
+
|
|
69
73
|
overrides:
|
|
70
74
|
next: ^15.5.19
|
|
71
75
|
'@types/node': ^24.13.2
|
|
72
76
|
```
|
|
73
77
|
|
|
74
|
-
|
|
78
|
+
- **`minimumReleaseAge: 1440`** — do not install packages published in the last 24 hours (supply-chain guard).
|
|
79
|
+
- **`@se-studio/*` exclude** — our own packages may update immediately after npm publish.
|
|
80
|
+
- **Keep repo-specific additional excludes** when present (e.g. vitest pins in se-core-product, `@emnapi/runtime` in se-website-2026, PointMe `mapbox-gl` / `react-day-picker` overrides).
|
|
81
|
+
|
|
82
|
+
`pnpm update -r --latest` would bump `next` → 16 and `@types/node` → 26 without the overrides block. The overrides prevent that.
|
|
83
|
+
|
|
84
|
+
**Never bypass `minimumReleaseAge`** during dependency updates. Do not remove the block, comment it out, or use undocumented pnpm flags. If a non-`@se-studio` package was published within 24 hours, it stays at the current version until it ages out — note that in the report and re-run later if needed.
|
|
75
85
|
|
|
76
86
|
---
|
|
77
87
|
|
|
@@ -80,14 +90,15 @@ Skip if `hasPinOverrides` is already true and values match. Idempotent — merge
|
|
|
80
90
|
Bump the package manager to the **latest pnpm 11.x** in root `package.json`:
|
|
81
91
|
|
|
82
92
|
```bash
|
|
83
|
-
|
|
84
|
-
#
|
|
85
|
-
corepack use pnpm@${LATEST_PNPM}
|
|
93
|
+
corepack use pnpm@11.9.0
|
|
94
|
+
# Or: LATEST=$(npm view pnpm@11.9.0 version) && corepack use pnpm@${LATEST}
|
|
86
95
|
pnpm -v # confirm matches packageManager
|
|
87
96
|
```
|
|
88
97
|
|
|
89
98
|
Keep `engines.pnpm` at `11.x` (do not jump to pnpm 12). If `engines.pnpm` is missing, add `"pnpm": "11.x"` alongside `"node": "24.x"`.
|
|
90
99
|
|
|
100
|
+
Align nested `packageManager` fields (e.g. `apps/*/package.json`) with the root version when validate fails on a version mismatch.
|
|
101
|
+
|
|
91
102
|
---
|
|
92
103
|
|
|
93
104
|
## Step 5 — Update dependencies
|
|
@@ -96,12 +107,26 @@ Keep `engines.pnpm` at `11.x` (do not jump to pnpm 12). If `engines.pnpm` is mis
|
|
|
96
107
|
pnpm update -r --latest
|
|
97
108
|
```
|
|
98
109
|
|
|
99
|
-
|
|
110
|
+
Then explicitly align `@se-studio/*` where the repo uses them (omit packages the repo does not depend on):
|
|
100
111
|
|
|
101
112
|
```bash
|
|
102
|
-
pnpm update -r
|
|
113
|
+
pnpm update -r \
|
|
114
|
+
@se-studio/ab-testing \
|
|
115
|
+
@se-studio/cms-seo \
|
|
116
|
+
@se-studio/contentful-cms@^3.0.1 \
|
|
117
|
+
@se-studio/contentful-rest-api \
|
|
118
|
+
@se-studio/core-data-types \
|
|
119
|
+
@se-studio/core-ui \
|
|
120
|
+
@se-studio/hubspot \
|
|
121
|
+
@se-studio/markdown-renderer \
|
|
122
|
+
@se-studio/project-build \
|
|
123
|
+
@se-studio/search \
|
|
124
|
+
@se-studio/site-check \
|
|
125
|
+
@se-studio/skills
|
|
103
126
|
```
|
|
104
127
|
|
|
128
|
+
`@se-studio/*` resolves immediately via `minimumReleaseAgeExclude`. Other packages respect the 24-hour window.
|
|
129
|
+
|
|
105
130
|
Safety re-pin after update:
|
|
106
131
|
|
|
107
132
|
```bash
|
|
@@ -155,6 +180,8 @@ Include in the summary:
|
|
|
155
180
|
- Major dependency bumps (from the Step 1 audit diff)
|
|
156
181
|
- pnpm version: before → after
|
|
157
182
|
- Confirmed pins: Next 15.x, Node 24, `@types/node` ^24
|
|
183
|
+
- Confirmed `minimumReleaseAge: 1440` and `@se-studio/*` exclude present
|
|
184
|
+
- Packages still outdated because they are inside the 24-hour release window (if any)
|
|
158
185
|
- Patches check bootstrapped (yes/no)
|
|
159
186
|
- Remaining projects not yet updated
|
|
160
187
|
|
|
@@ -179,6 +206,7 @@ This is optional follow-up — the skill workflow always runs the check regardle
|
|
|
179
206
|
| Issue | Action |
|
|
180
207
|
|-------|--------|
|
|
181
208
|
| `next` or `@types/node` still outdated to wrong major | Re-run overrides + safety re-pin; check `pnpm-workspace.yaml` overrides |
|
|
209
|
+
| Non-`@se-studio` package still outdated after update | Likely within 24h of npm publish — wait and re-run; **do not** bypass `minimumReleaseAge` |
|
|
182
210
|
| `corepack use` fails | Run `corepack enable` once, retry |
|
|
183
211
|
| Validate fails after major bump | Check breaking-change release notes; fix or revert |
|
|
184
212
|
| Repo path missing | Skip; note in report — see `docs/RELATED_PROJECTS.md` |
|