@se-studio/skills 1.5.4 → 1.5.5

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @se-studio/skills
2
2
 
3
+ ## 1.5.5
4
+
5
+ ### Patch Changes
6
+
7
+ - d1a119c: Add `contentful-cms-create-editor-playbooks` skill and reference docs for customer editor playbook rollouts (Pedestal, OM1, PointMe, SE website).
8
+
3
9
  ## 1.5.4
4
10
 
5
11
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@se-studio/skills",
3
- "version": "1.5.4",
3
+ "version": "1.5.5",
4
4
  "description": "SE Studio agent skills for marketing site development with Contentful CMS",
5
5
  "repository": {
6
6
  "type": "git",
@@ -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.
@@ -8,6 +8,10 @@
8
8
  "major": 11,
9
9
  "engines": "11.x"
10
10
  },
11
+ "minimumReleaseAge": {
12
+ "minutes": 1440,
13
+ "exclude": ["@se-studio/*"]
14
+ },
11
15
  "projects": [
12
16
  {
13
17
  "key": "se-core-product",
@@ -120,7 +120,7 @@ cms-edit set @c0 anchor "hero-section"
120
120
  cms-edit set @c1:cmsLabel="Hero — School avoidance" @c2:cmsLabel="What is school avoidance?" @c3:cmsLabel="Signs of school avoidance"
121
121
  cms-edit set @c1:heading="Title A" @c2:heading="Title B"
122
122
  ```
123
- Each token is `@ref:fieldName=value`. All values are scalar (string, boolean, number). Flags like `--link`, `--links`, `--file` do not apply in multi mode.
123
+ 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
124
 
125
125
  **Entry link fields** (template, articleType, etc. — value is the linked entry ID):
126
126
  ```bash
@@ -158,7 +158,7 @@ For any content with multiple paragraphs or newlines, use `printf` piped to stdi
158
158
  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
159
 
160
160
  # Also correct — file input
161
- cms-edit rtf @c1 body --markdown --file path/to/file.md
161
+ cms-edit rtf @c1 body --markdown --content "# Heading\n\nBody."
162
162
  cms-edit rtf @c1 body --markdown - < path/to/file.md
163
163
  ```
164
164
 
@@ -170,7 +170,7 @@ cms-edit rtf @c1 body --markdown "Simple single-paragraph body text with **bold*
170
170
 
171
171
  **Surgical rich text replace** (compliance / quidget tokens — does not re-import the whole field):
172
172
 
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 … --file`.
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 … --content`.
174
174
  - Quidget strings contain `*`, which Markdown would treat as italic — use **`--replace-plain`**, not `--replace`.
175
175
 
176
176
  ```bash
@@ -246,7 +246,7 @@ Same as Component plus:
246
246
  When adding body content and a CTA (e.g. PDF download) to an article:
247
247
 
248
248
  1. `cms-edit open --article-slug <slug>` (or `open --id <id>`)
249
- 2. Set body: `cms-edit rtf @<ref> body --markdown "..."` or `--markdown --file path/to.md`. If you need to add a body component first, use `add` then `rtf`.
249
+ 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
250
  3. `cms-edit add CTA --target bottomContent`
251
251
  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
252
  5. `cms-edit save`
@@ -430,10 +430,10 @@ cms-edit create tag --slug easl-congress-2026 --name "EASL Congress 2026" --tag-
430
430
  --description "Research presented at EASL Congress 2026." --featured-image <logoAssetId>
431
431
 
432
432
  # Full fields via JSON
433
- cms-edit create tag --json-file tag.json --tag-type presentation-type --if-not-exists
433
+ cms-edit create tag --json '{"slug":"presentation"}' --tag-type presentation-type --if-not-exists
434
434
 
435
435
  # Batch bootstrap
436
- cms-edit create taxonomy-from-json --file taxonomy.json --if-not-exists
436
+ cms-edit create taxonomy-from-json --json '{"tagTypes":[...]}' --if-not-exists
437
437
 
438
438
  # Idempotent single-entry creates
439
439
  cms-edit create tag-type --slug conference-venue --name "Conference Venue" --if-not-exists
@@ -664,9 +664,9 @@ cms-edit peek --id <entryId> # Look up by entry ID
664
664
  Run a sequence of operations from a JSON file or stdin.
665
665
 
666
666
  ```bash
667
- cms-edit batch run --file ops.json # Run batch ops from file
667
+ cms-edit batch run --json '[...]' # Run batch ops from inline JSON
668
668
  echo '[...]' | cms-edit batch run # Pipe from stdin
669
- cms-edit batch run --file ops.json --dry-run # Validate without saving
669
+ cms-edit batch run --json '[...]' --dry-run # Validate without saving
670
670
  ```
671
671
 
672
672
  Supported ops: `open`, `set`, `rtf`, `rtf-replace`, `save`, `add`, `links-add`.
@@ -700,8 +700,8 @@ Example `ops.json` — update an existing page with a new CTA that has two butto
700
700
  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
701
 
702
702
  ```bash
703
- cms-edit create from-json --file page.json # Create from file
704
- cms-edit create from-json --file page.json --dry-run # Preview without writing
703
+ cms-edit create from-json --json '{...}' # Create from inline JSON
704
+ cms-edit create from-json --json '{...}' --dry-run # Preview without writing
705
705
  cat page.json | cms-edit create from-json # Pipe from stdin
706
706
  ```
707
707
 
@@ -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
 
@@ -82,7 +82,7 @@ For per-page alt work: **`contentful-cms-alt-text-audit`**.
82
82
  When the client wants a **reference guide** (not just remediation):
83
83
 
84
84
  ```bash
85
- cms-edit --json asset review --include-passing --include-usage --usage-limit 0 > docs/image-inventory.json
85
+ cms-edit --json-output asset review --include-passing --include-usage --usage-limit 0 > docs/image-inventory.json
86
86
  ```
87
87
 
88
88
  - 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 `printf` piped to stdin; `\n` in a double-quoted shell string is **not** a newline in bash:
13
+ - **Multiline content** — use `--content` or `--base64` (hosted MCP has no filesystem):
14
14
  ```bash
15
- printf '## Heading\n\nParagraph with **bold** and [link](https://example.com).\n' | cms-edit rtf @c1 body --markdown -
15
+ cms-edit rtf @c1 body --markdown --content "## Heading\n\nParagraph with **bold**."
16
16
  ```
17
- - Use `--file path/to/file.md` or stdin (`-`) for long content.
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
- # From file
60
- cms-edit rtf patch @c0 body --file patch.json
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:
@@ -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 (Integrations + OAuth)."
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@v1
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 — Pin overrides (before `--latest`)
64
+ ## Step 3 — Supply-chain policy + pin overrides
65
65
 
66
- `pnpm update -r --latest` would bump `next` → 16 and `@types/node` → 26. Add or verify this block in `pnpm-workspace.yaml` (values from registry `pinOverrides`):
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
- Skip if `hasPinOverrides` is already true and values match. Idempotent — merge into existing `pnpm-workspace.yaml` without removing other keys (`minimumReleaseAge`, `allowBuilds`, etc.).
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
- LATEST_PNPM=$(npm view pnpm@11 version)
84
- # Set "packageManager": "pnpm@<LATEST_PNPM>" in package.json
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
- If brightline or pedestal repos block fresh packages (`minimumReleaseAge: 1440`), retry with:
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 --latest --no-minimum-release-age
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` |