@se-studio/skills 1.5.5 → 1.5.7

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,17 @@
1
1
  # @se-studio/skills
2
2
 
3
+ ## 1.5.7
4
+
5
+ ### Patch Changes
6
+
7
+ - c29c4c8: Add `site-workflows-agent-session` skill and agent-session reference files for cross-repo work sessions, placement checklist, and parallel feature isolation.
8
+
9
+ ## 1.5.6
10
+
11
+ ### Patch Changes
12
+
13
+ - 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.
14
+
3
15
  ## 1.5.5
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@se-studio/skills",
3
- "version": "1.5.5",
3
+ "version": "1.5.7",
4
4
  "description": "SE Studio agent skills for marketing site development with Contentful CMS",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,45 @@
1
+ ## Agent session workflow
2
+
3
+ **Load skill `site-workflows-agent-session` at the start of every coding session.**
4
+
5
+ Default mode for this repo: **site-first**.
6
+
7
+ ### Branch policy
8
+
9
+ - Agents may commit and push **`develop`** and **`feature/*`** only.
10
+ - **Never** push to `main`, `master`, or production — human-only.
11
+ - Prefer **draft PRs** to `develop` over direct pushes when `gh` is available.
12
+
13
+ ### Core vs customer placement
14
+
15
+ Before non-trivial code, run the placement checklist (in the skill). Summary:
16
+
17
+ | Belongs in… | Examples |
18
+ |-------------|----------|
19
+ | **This repo** (`src/project/*`, `cms-edit/**`) | Brand components, styling, site routing, editor-pack |
20
+ | **Customer shared package** (if monorepo) | Consent/analytics shared across sites in this customer |
21
+ | **`se-core-product`** (`@se-studio/*`) | Fixes/features needed by 2+ sites, CMS infrastructure |
22
+
23
+ If the checklist says **core**, stop and switch to core-first mode — do not patch `@se-studio` behaviour in this repo.
24
+
25
+ ### Core release order
26
+
27
+ When work depends on a new `@se-studio/*` npm release:
28
+
29
+ 1. Release from `se-core-product` (`dev` → CI publish)
30
+ 2. Confirm version on npm
31
+ 3. `pnpm update @se-studio/<package>@<version> -r` in this repo
32
+ 4. Then push `develop`
33
+
34
+ Never hand-edit `package.json` dependency versions.
35
+
36
+ ### Parallel features
37
+
38
+ - One feature = one `feature/<scope>/<slug>` branch
39
+ - Use a **git worktree** when multiple features touch this repo at once
40
+ - CMS edits: `--session <feature-slug>` (isolate cms-edit sessions)
41
+ - Track in-flight work: manifest at `~/source/se/se-core-product/work/active/<feature>.yaml` (or `work/active/` in this repo if core checkout unavailable)
42
+
43
+ ### Production handoff
44
+
45
+ When ready for production, agents **stop** and deliver a handoff note — they do not merge to `main`. See skill Step 8.
@@ -0,0 +1,32 @@
1
+ # Copy to work/active/<feature>.yaml — one file per in-flight feature.
2
+ # Canonical location: se-core-product/work/active/ (cross-repo visibility).
3
+
4
+ feature: my-feature-slug
5
+ mode: site-first # core-first | site-first
6
+ project_key: om1
7
+ primary_repo: ~/source/customers/om1/om1-website
8
+ branch: feature/om1/my-feature-slug
9
+ worktree: null # e.g. ~/source/worktrees/om1-my-feature-slug — required when parallel features share a repo
10
+ integration_branch: develop
11
+
12
+ related_repos:
13
+ - repo: se-core-product
14
+ path: ~/source/se/se-core-product
15
+ role: read-only # read-only | pending-extract | active
16
+
17
+ placement:
18
+ decision: customer # core | customer | customer-shared | defer-extract
19
+ rationale: One-site hero layout tied to OM1 Figma
20
+ extract_to_core: null # pending | null
21
+ extract_rationale: null
22
+
23
+ blocked_on: null # e.g. "@se-studio/core-ui@2.1.0"
24
+ cms_session: null # set to feature slug when doing parallel CMS edits
25
+
26
+ status: in_progress # in_progress | blocked | parked | ready_for_review
27
+ started_at: 2026-07-05
28
+ updated_at: 2026-07-05
29
+
30
+ validation: []
31
+
32
+ handoff: null
@@ -0,0 +1,86 @@
1
+ {
2
+ "manifestPath": "work/active/<feature>.yaml",
3
+ "integrationBranches": {
4
+ "core": "dev",
5
+ "customer": "develop"
6
+ },
7
+ "branchPattern": "feature/<scope>/<short-slug>",
8
+ "projects": [
9
+ {
10
+ "key": "se-core-product",
11
+ "displayName": "SE Core Product",
12
+ "path": "~/source/se/se-core-product",
13
+ "branch": "dev",
14
+ "type": "core",
15
+ "validate": "pnpm validate",
16
+ "exampleApps": [
17
+ "example-om1",
18
+ "example-se2026",
19
+ "example-brightline",
20
+ "example-brightlifekids",
21
+ "example-empty"
22
+ ]
23
+ },
24
+ {
25
+ "key": "se2026",
26
+ "displayName": "SE Studio Site",
27
+ "path": "~/source/se/se-website-2026",
28
+ "branch": "develop",
29
+ "type": "customer",
30
+ "contentfulSpaceId": "g0pw3n92bre6",
31
+ "hostedMcp": "cms-edit-se-website",
32
+ "validate": "pnpm check && pnpm type-check"
33
+ },
34
+ {
35
+ "key": "brightline",
36
+ "displayName": "Brightline Sites",
37
+ "path": "~/source/customers/brightline/brightline-sites",
38
+ "branch": "develop",
39
+ "type": "customer-monorepo",
40
+ "sharedPackage": "@brightline/shared",
41
+ "contentfulSpaceIds": ["96gdpqkm7elu", "c27ds9epot4n"],
42
+ "hostedMcp": "cms-edit-brightline",
43
+ "validate": "pnpm -r validate"
44
+ },
45
+ {
46
+ "key": "om1",
47
+ "displayName": "OM1 Website",
48
+ "path": "~/source/customers/om1/om1-website",
49
+ "branch": "develop",
50
+ "type": "customer",
51
+ "contentfulSpaceId": "ddhe5ahaolzf",
52
+ "hostedMcp": "cms-edit-om1",
53
+ "validate": "pnpm check && pnpm type-check && pnpm validate:routes"
54
+ },
55
+ {
56
+ "key": "pointme",
57
+ "displayName": "PointMe Marketing Site",
58
+ "path": "~/source/customers/pointme/develop-marketing-site",
59
+ "branch": "develop",
60
+ "type": "customer",
61
+ "contentfulSpaceId": "alwdzgjlz5qv",
62
+ "contentfulEnvironment": "marketing-master-2025-04-15",
63
+ "validate": "pnpm check && pnpm type-check"
64
+ },
65
+ {
66
+ "key": "pedestal",
67
+ "displayName": "Pedestal Sites",
68
+ "path": "~/source/customers/pedestal/pedestal-sites",
69
+ "branch": "develop",
70
+ "type": "customer-monorepo",
71
+ "sharedPackage": "@pedestal/site-common",
72
+ "contentfulSpaceIds": ["h4s3ip99qawo", "fea4lj2cdgl5"],
73
+ "hostedMcp": ["cms-edit-pedestal", "cms-edit-headwater"],
74
+ "validate": "pnpm -r validate"
75
+ },
76
+ {
77
+ "key": "hsd-extended-port",
78
+ "displayName": "HopSkipDrive Extended Port",
79
+ "path": "~/source/customers/hopskipdrive/hsd-extended-port",
80
+ "branch": "extended-port",
81
+ "type": "customer",
82
+ "wip": true,
83
+ "validate": "pnpm validate"
84
+ }
85
+ ]
86
+ }
@@ -66,6 +66,17 @@
66
66
  "validate": "pnpm -r validate",
67
67
  "workspace": true,
68
68
  "hasPinOverrides": false
69
+ },
70
+ {
71
+ "key": "hsd-extended-port",
72
+ "displayName": "HopSkipDrive Extended Port",
73
+ "path": "~/source/customers/hopskipdrive/hsd-extended-port",
74
+ "branch": "extended-port",
75
+ "wip": true,
76
+ "wipNote": "Parity port from legacy GraphQL/Netlify site onto @se-studio packages. Work on extended-port only — not develop/production. Defer routine deps bumps until parity snags are under control unless explicitly requested.",
77
+ "validate": "pnpm validate",
78
+ "workspace": false,
79
+ "hasPinOverrides": false
69
80
  }
70
81
  ]
71
82
  }
@@ -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
@@ -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
- # Upload from local file, URL, or base64
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
- # Upload and create a Media wrapper in one step
378
- cms-edit asset upload ./figure.png --with-media --media-name "Figure 1" --media-position Middle
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
@@ -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)
@@ -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 | Article or BlogPosting |
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 these standard Mustache variables:
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
- - `{{title}}` — page/article title
41
- - `{{seoDescription}}` — SEO meta description
42
- - `{{slug}}` — page slug
43
- - `{{publishDate}}` — article publish date
44
- - `{{updatedAt}}` — last modification date
45
- - `{{authorName}}` — primary article author name (first in `authors`)
46
- - `{{#article.authors}}` — multi-author JSON-LD (`name`, `url` per author)
47
- - `{{heroImageUrl}}` — primary image URL
48
- - `{{customerName}}` — from brand context
49
- - `{{siteUrl}}` — from brand context
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 `schemaOrg`, `jsonLd`, `structuredData`, or similar
57
- 2. For **template-level** schemas (Organization, WebSite — shared): `cms-edit list --type template` → open → set
58
- 3. For **page-level** schemas: open each page → set its schema field
59
- 4. `cms-edit diff` then `cms-edit save`
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
- - Use specific types — `MedicalBusiness` over `LocalBusiness` if applicable
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**.
@@ -7,7 +7,7 @@ description: "Set up or regenerate smoke.cases.json for local smoke tests from t
7
7
 
8
8
  Local smoke tests use curated HTTP cases in **`smoke.cases.json`**. Optionally enable **`cmsIntegrity`** for a local-only Contentful article-link check (no `cms-server` import in smoke scripts).
9
9
 
10
- Requires `@se-studio/site-check` **^2.6.1** when using `cmsIntegrity` or `pnpm smoke-test` with integrity enabled; **2.1.2+** for cache log audit; **2.0.0+** for HTTP-only static smoke.
10
+ Requires `@se-studio/site-check` **^2.9.0** when using `discovery` endpoint checks; **^2.6.1** when using `cmsIntegrity` or `pnpm smoke-test` with integrity enabled; **2.1.2+** for cache log audit; **2.0.0+** for HTTP-only static smoke.
11
11
 
12
12
  Preview / `DRAFT_ONLY` Contentful access in local dev is expected and not a smoke failure. **Deployment / live smoke stays HTTP-only** — do not enable `cmsIntegrity` on Vercel deployment checks.
13
13
 
@@ -204,6 +204,12 @@ curl -sI "http://localhost:<port>/some-path.md"
204
204
  {
205
205
  "siteName": "my-app",
206
206
  "port": 3012,
207
+ "discovery": {
208
+ "llmsTxt": true,
209
+ "markdownIndexTxt": true,
210
+ "cmsTxt": true,
211
+ "siteInfoMd": true
212
+ },
207
213
  "cases": [
208
214
  { "category": "home", "label": "Home", "path": "/", "expectMarkdown": true },
209
215
  { "category": "page", "label": "About", "path": "/about/", "expectMarkdown": true },
@@ -218,6 +224,19 @@ curl -sI "http://localhost:<port>/some-path.md"
218
224
  }
219
225
  ```
220
226
 
227
+ **Discovery endpoints** (`discovery` block) — requires `@se-studio/site-check@^2.9.0`:
228
+
229
+ | Path | Flag | Checks when `true` |
230
+ |------|------|-------------------|
231
+ | `/llms.txt` | `llmsTxt` | 200, `text/plain`, llmstxt.org structure, spot-check Key pages `.md` links |
232
+ | `/markdown-index.txt` | `markdownIndexTxt` | 200, same-origin `.md` URL list |
233
+ | `/cms.txt` | `cmsTxt` | 200, `text/markdown`, mentions llms + markdown-index |
234
+ | `/site-info.md` | `siteInfoMd` | 200, `text/markdown`, title + minimum body |
235
+
236
+ Omit a key or set `true` to require the endpoint. Set `false` to skip (not a failure). **PointMe:** set all four to `false` until CloudFront routes these paths to Vercel.
237
+
238
+ Add `/llms.txt`, `/markdown-index.txt`, and `/site-info.md` to `route-build-policy.json` → `mustBeSsgOrStatic` (commit beside `smoke.cases.json`).
239
+
221
240
  `expectHtmlStatus` requires `@se-studio/site-check@^2.7.2`. Omit for normal 2xx HTML checks.
222
241
 
223
242
  Optional `cmsIntegrity` (local only — see section below):
@@ -0,0 +1,279 @@
1
+ ---
2
+ name: site-workflows-agent-session
3
+ description: "Start and manage agent work sessions across se-core-product and customer sites. Declares work mode, feature branch, placement (core vs customer), parallel isolation, and production handoff. Load at the beginning of every coding session."
4
+ ---
5
+
6
+ # Agent session workflow
7
+
8
+ Orchestrates **where** to work, **where code belongs**, and **how to isolate parallel features**. Human merges to `main` / production — agents stop at handoff.
9
+
10
+ **Registry:** [`packages/skills/references/agent-session/projects.registry.json`](../../references/agent-session/projects.registry.json) — repo paths, integration branches, hosted MCP keys.
11
+
12
+ **Manifest template:** [`packages/skills/references/agent-session/manifest.template.yaml`](../../references/agent-session/manifest.template.yaml)
13
+
14
+ **Human guide:** `docs/WORKFLOW.md` in se-core-product.
15
+
16
+ ---
17
+
18
+ ## When to load this skill
19
+
20
+ Load **at the start of every coding session** — before reading code or making edits.
21
+
22
+ Triggers:
23
+
24
+ - User pastes a session opener (`Mode: site-first`, `Feature: …`)
25
+ - User asks to work on a customer site or core package
26
+ - User starts parallel work on another feature (new manifest, new branch)
27
+ - User asks "where should this live?" (run placement checklist)
28
+
29
+ ---
30
+
31
+ ## Step 1 — Resolve session context
32
+
33
+ Collect or infer:
34
+
35
+ | Field | Required | Notes |
36
+ |-------|----------|-------|
37
+ | `mode` | Yes | `core-first` or `site-first` |
38
+ | `feature` | Yes | Short slug, kebab-case (e.g. `om1-hero-redesign`) |
39
+ | `project_key` | Yes | From registry (`om1`, `se-core-product`, `pedestal`, …) |
40
+ | `primary_repo` | Yes | Absolute path from registry |
41
+ | `branch` | Yes | `feature/<scope>/<slug>` — see naming below |
42
+ | `worktree` | Optional | Separate checkout path when parallel features share a repo |
43
+
44
+ **Default mode if unclear:** ask once. Site-specific UI/content → `site-first`. Package/framework/multi-site → `core-first`.
45
+
46
+ **Branch naming:**
47
+
48
+ ```
49
+ feature/<scope>/<short-slug>
50
+ ```
51
+
52
+ | Scope | Example |
53
+ |-------|---------|
54
+ | Core work | `feature/core/search-webhook-fix` |
55
+ | Customer site | `feature/om1/hero-redesign` |
56
+ | Customer monorepo shared | `feature/brightline/consent-v2` |
57
+
58
+ Integration branches (agents push feature branches here via PR or merge — **never `main`**):
59
+
60
+ | Repo type | Integration branch |
61
+ |-----------|-------------------|
62
+ | `se-core-product` | `dev` |
63
+ | Customer sites | `develop` (or registry override, e.g. `extended-port`) |
64
+
65
+ ---
66
+
67
+ ## Step 2 — Write or update manifest
68
+
69
+ Path in **se-core-product** (canonical ledger for cross-repo visibility):
70
+
71
+ ```
72
+ work/active/<feature>.yaml
73
+ ```
74
+
75
+ Copy from `manifest.template.yaml`, fill all fields, set `status: in_progress`, `started_at` to today (ISO date).
76
+
77
+ If the user works only in a customer repo with no core checkout, still create/update the manifest in se-core-product when that repo is available; otherwise create `work/active/<feature>.yaml` in the customer repo and note `manifest_location: customer` in the file.
78
+
79
+ **One feature = one manifest.** Do not append unrelated work to an existing manifest.
80
+
81
+ ---
82
+
83
+ ## Step 3 — Placement checklist (before non-trivial code)
84
+
85
+ Run before implementing anything beyond a one-line fix. Record results in manifest `placement:`.
86
+
87
+ | Question | If yes → lean |
88
+ |----------|----------------|
89
+ | Will **2+ sites** need this within ~6 months? | **core** (`packages/*`) |
90
+ | Is it CMS infrastructure (converter, shared renderer, cms-edit, search webhook)? | **core** |
91
+ | Is it tied to **one brand** (Figma, copy, colours, one-off layout)? | **customer** (`src/project/*`) |
92
+ | Shared only within **one customer monorepo** (e.g. `@brightline/shared`)? | **customer-shared** |
93
+ | Bug in published `@se-studio/*` behaviour? | **core** — never fork in customer |
94
+
95
+ **Outcomes** — set `placement.decision`:
96
+
97
+ | Decision | Action |
98
+ |----------|--------|
99
+ | `core` | Edit `se-core-product` only; changeset before push to `dev`; customer waits for npm |
100
+ | `customer` | Edit customer repo only; do not touch core |
101
+ | `customer-shared` | Edit customer's shared package; not `@se-studio/*` |
102
+ | `defer-extract` | Implement in customer now; set `extract_to_core: pending` + `extract_rationale` |
103
+
104
+ **Site-first guard:** If checklist says `core` but mode is `site-first`, **stop** and ask whether to switch mode or record `defer-extract`.
105
+
106
+ **Core-first guard:** If checklist says `customer`, implement in customer repo (read-only probe in core example apps only if useful).
107
+
108
+ ---
109
+
110
+ ## Step 4 — Git isolation
111
+
112
+ ### Single feature in repo
113
+
114
+ ```bash
115
+ cd <primary_repo>
116
+ git fetch origin
117
+ git checkout -b <branch> origin/<integration-branch>
118
+ ```
119
+
120
+ ### Parallel features in same repo
121
+
122
+ Use a **git worktree** per feature:
123
+
124
+ ```bash
125
+ git worktree add <worktree-path> -b <branch> origin/<integration-branch>
126
+ ```
127
+
128
+ Record `worktree` in manifest. Do not commit unrelated features on the same branch.
129
+
130
+ ### CMS parallel sessions
131
+
132
+ When editing Contentful in parallel on the same space, use distinct cms-edit sessions:
133
+
134
+ ```bash
135
+ --session <feature-slug>
136
+ # or CONTENTFUL_CMS_SESSION=<feature-slug>
137
+ ```
138
+
139
+ Record `cms_session: <feature-slug>` in manifest when doing CMS work.
140
+
141
+ ---
142
+
143
+ ## Step 5 — Work execution rules
144
+
145
+ ### core-first
146
+
147
+ - Primary edits: `packages/*`, optionally `apps/example-*` to validate
148
+ - Compare customer implementations **read-only** unless user approves commits there
149
+ - Release train before customer push (see `AGENTS.md` **Client repos — wait for core**)
150
+
151
+ ### site-first
152
+
153
+ - Primary edits: customer `src/project/*`, `cms-edit/**`, site config
154
+ - **Do not** edit `se-core-product` unless placement is `core` and user approves mode switch
155
+ - Consume `@se-studio/*` from npm — not monorepo workspace links
156
+
157
+ ### Blocked work
158
+
159
+ If manifest has `blocked_on: "@se-studio/foo@1.2.3"`, do not push customer `develop` until npm publish is confirmed. Update manifest when unblocked.
160
+
161
+ ---
162
+
163
+ ## Step 6 — Validate before push
164
+
165
+ Minimum per repo type (see registry `validate` for full command):
166
+
167
+ | Repo | Typical |
168
+ |------|---------|
169
+ | se-core-product | `pnpm validate` or targeted `pnpm type-check` + tests |
170
+ | Customer | registry `validate` field |
171
+
172
+ Record commands run in manifest `validation:` before push.
173
+
174
+ ---
175
+
176
+ ## Step 7 — Push and PR policy
177
+
178
+ Agents may push to:
179
+
180
+ - `dev` / `develop` (via feature branch merge or direct if user prefers)
181
+ - `feature/*` branches
182
+
183
+ Agents must **never** push to `main`, `master`, or production branches.
184
+
185
+ **Preferred:** open a **draft PR** targeting the integration branch:
186
+
187
+ ```bash
188
+ gh pr create --base <integration-branch> --head <branch> --draft --title "<feature>: <summary>"
189
+ ```
190
+
191
+ If `gh` is unavailable or user prefers direct push, push `feature/*` and note in handoff.
192
+
193
+ ---
194
+
195
+ ## Step 8 — Handoff (production-ready)
196
+
197
+ When work is ready for human review / production promotion, **stop** — do not merge to `main`.
198
+
199
+ 1. Set manifest `status: ready_for_review`
200
+ 2. Deliver handoff using template below
201
+ 3. If core release was part of the work, list published package versions needed for customer bump
202
+
203
+ ### Handoff template
204
+
205
+ ```markdown
206
+ ## Handoff: <feature>
207
+
208
+ **Mode:** <core-first | site-first>
209
+ **Manifest:** work/active/<feature>.yaml
210
+
211
+ ### Repos and branches
212
+ - <repo>: `<branch>` → merge to `<integration-branch>`
213
+
214
+ ### Placement
215
+ - Decision: <core | customer | customer-shared | defer-extract>
216
+ - Core release required: <yes — packages + versions | no>
217
+
218
+ ### Changes
219
+ - <bullet summary>
220
+
221
+ ### Validation
222
+ - <commands run>
223
+
224
+ ### Merge order (if multi-repo)
225
+ 1. <core PR / npm publish>
226
+ 2. <customer pnpm update @se-studio/...>
227
+ 3. <customer PR>
228
+
229
+ ### Production
230
+ Ready for you to merge to `main` / promote Vercel. Agent will not push production.
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Step 9 — Complete or park
236
+
237
+ | Outcome | Manifest update |
238
+ |---------|-----------------|
239
+ | Merged / done | Move to `work/completed/<feature>.yaml` or delete from `work/active/` |
240
+ | Blocked | `status: blocked`, set `blocked_on` |
241
+ | Parked | `status: parked`, add `parked_reason` |
242
+
243
+ Remove worktree when done:
244
+
245
+ ```bash
246
+ git worktree remove <worktree-path>
247
+ ```
248
+
249
+ ---
250
+
251
+ ## Session opener (user control surface)
252
+
253
+ User can paste:
254
+
255
+ ```
256
+ Load skill: site-workflows-agent-session
257
+ Mode: site-first
258
+ Project: om1
259
+ Feature: hero-redesign
260
+ Branch: feature/om1/hero-redesign
261
+ ```
262
+
263
+ Agent must load this skill, write manifest, run placement checklist, confirm branch/worktree, then proceed.
264
+
265
+ ---
266
+
267
+ ## Quick reference — project keys
268
+
269
+ | key | Integration branch | Type |
270
+ |-----|-------------------|------|
271
+ | `se-core-product` | `dev` | core monorepo |
272
+ | `se2026` | `develop` | customer |
273
+ | `brightline` | `develop` | customer monorepo |
274
+ | `om1` | `develop` | customer |
275
+ | `pointme` | `develop` | customer |
276
+ | `pedestal` | `develop` | customer monorepo |
277
+ | `hsd-extended-port` | `extended-port` | customer (WIP) |
278
+
279
+ Full paths and MCP keys: `projects.registry.json`.
@@ -11,7 +11,31 @@ 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/`; bypass or remove `minimumReleaseAge`.
14
+ **Never:** push to `main`/`master`; bump Next to 16; bump Node to 25+; use `pnpm patch` / `patchedDependencies` / `patches/`; bypass or remove `minimumReleaseAge`; **hand-edit `package.json` dependency versions** (use `pnpm update` instead).
15
+
16
+ ---
17
+
18
+ ## Bumping packages (all repos — agents must follow)
19
+
20
+ **Do not** edit `package.json` version strings by hand. Always run `pnpm update` from the repo root so `pnpm-lock.yaml` stays aligned.
21
+
22
+ ```bash
23
+ # One package after a core npm release
24
+ pnpm update @se-studio/contentful-rest-api@<version> -r
25
+
26
+ # Several @se-studio packages
27
+ pnpm update -r @se-studio/contentful-rest-api @se-studio/core-ui
28
+ ```
29
+
30
+ **`pnpm-workspace.yaml` overrides:** many customer repos pin packages under `overrides` (e.g. Point.me: `@se-studio/contentful-rest-api`, `mapbox-gl`). `pnpm update` does **not** update those lines. After updating a pinned package, set the matching override to the same range or `pnpm install --frozen-lockfile` fails.
31
+
32
+ **cms-edit host repos** (`cms-edit/host` in `pnpm-workspace.yaml`): Vercel install is:
33
+
34
+ ```bash
35
+ pnpm install --frozen-lockfile --config.node-linker=hoisted
36
+ ```
37
+
38
+ Run that locally **before push** whenever `package.json`, lockfile, or overrides change. A mismatch surfaces as `ERR_PNPM_OUTDATED_LOCKFILE` (manifest vs lockfile specifiers).
15
39
 
16
40
  ---
17
41
 
@@ -25,9 +49,12 @@ Update npm dependencies to **latest** in se-core-product and consumer repos that
25
49
  | `om1` | OM1 Website | `develop` |
26
50
  | `pointme` | PointMe Marketing Site | `develop` |
27
51
  | `pedestal` | Pedestal Sites | `develop` |
52
+ | `hsd-extended-port` | HopSkipDrive Extended Port **(WIP)** | `extended-port` |
28
53
 
29
54
  User may name a key (`update deps in om1`) or ask to run through all projects sequentially.
30
55
 
56
+ **WIP:** `hsd-extended-port` is an active parity port — branch `extended-port`, not `develop`. Prefer standards alignment and targeted `@se-studio/*` catch-up over full `pnpm update -r --latest` until the snag list is stable.
57
+
31
58
  ---
32
59
 
33
60
  ## Step 1 — Preflight
@@ -103,6 +130,8 @@ Align nested `packageManager` fields (e.g. `apps/*/package.json`) with the root
103
130
 
104
131
  ## Step 5 — Update dependencies
105
132
 
133
+ Use CLI updates only — do not StrReplace version strings in `package.json`.
134
+
106
135
  ```bash
107
136
  pnpm update -r --latest
108
137
  ```
@@ -147,6 +176,12 @@ rg '"node"' package.json apps/*/package.json packages/*/package.json 2>/dev/null
147
176
 
148
177
  ## Step 6 — Validate (unified for all repos)
149
178
 
179
+ If the registry project has `cms-edit/host` in `pnpm-workspace.yaml`, run the frozen hoisted install check first:
180
+
181
+ ```bash
182
+ pnpm install --frozen-lockfile --config.node-linker=hoisted
183
+ ```
184
+
150
185
  Always run the patches check **once**, then the project validate from the registry:
151
186
 
152
187
  ```bash
@@ -205,6 +240,7 @@ This is optional follow-up — the skill workflow always runs the check regardle
205
240
 
206
241
  | Issue | Action |
207
242
  |-------|--------|
243
+ | `ERR_PNPM_OUTDATED_LOCKFILE` on frozen/hoisted install | `package.json` and `pnpm-workspace.yaml` overrides out of sync with lockfile — re-run `pnpm update` for the package and align `overrides` |
208
244
  | `next` or `@types/node` still outdated to wrong major | Re-run overrides + safety re-pin; check `pnpm-workspace.yaml` overrides |
209
245
  | Non-`@se-studio` package still outdated after update | Likely within 24h of npm publish — wait and re-run; **do not** bypass `minimumReleaseAge` |
210
246
  | `corepack use` fails | Run `corepack enable` once, retry |
@@ -71,19 +71,53 @@ Write `CLAUDE.md` at the project root:
71
71
 
72
72
  ## Step 6 — Create `AGENTS.md`
73
73
 
74
- Write `AGENTS.md` at the project root. Fill in the user's email address (from memory if known, otherwise ask) and today's date:
74
+ Write `AGENTS.md` at the project root. Fill in the user's email address (from memory if known, otherwise ask) and today's date.
75
+
76
+ Include the **agent session workflow block** from [`packages/skills/references/agent-session/customer-agents-block.md`](../../references/agent-session/customer-agents-block.md) (branch policy, placement, parallel features, handoff).
75
77
 
76
78
  ```markdown
77
79
  # Next.js: ALWAYS read docs before coding
78
80
 
79
81
  Before any Next.js work, find and read the relevant doc in `node_modules/next/dist/docs/`. Your training data is outdated — the docs are the source of truth.
80
82
 
83
+ # @se-studio packages: ALWAYS read docs before coding
84
+
85
+ Before using any `@se-studio/*` package, read the relevant `node_modules/@se-studio/<package>/docs/llms.md`.
86
+
81
87
  # userEmail
82
88
  The user's email address is [USER_EMAIL].
83
89
 
84
90
  # currentDate
85
91
  Today's date is [CURRENT_DATE].
86
92
 
93
+ ## Agent session workflow
94
+
95
+ **Load skill `site-workflows-agent-session` at the start of every coding session.**
96
+
97
+ Default mode for this repo: **site-first**.
98
+
99
+ ### Branch policy
100
+
101
+ - Agents may commit and push **`develop`** and **`feature/*`** only.
102
+ - **Never** push to `main`, `master`, or production — human-only.
103
+ - Prefer **draft PRs** to `develop` over direct pushes when `gh` is available.
104
+
105
+ ### Core vs customer placement
106
+
107
+ Before non-trivial code, run the placement checklist (skill `site-workflows-agent-session`). If the checklist says **core**, stop — do not patch `@se-studio` behaviour in this repo.
108
+
109
+ ### Core release order
110
+
111
+ When work depends on a new `@se-studio/*` npm release: release from `se-core-product` first, confirm npm, then `pnpm update @se-studio/<package>@<version> -r` here, then push `develop`. Never hand-edit dependency versions.
112
+
113
+ ### Parallel features
114
+
115
+ One feature = one `feature/<scope>/<slug>` branch. Use git worktrees for parallel work on this repo. CMS: `--session <feature-slug>`. Manifest: `~/source/se/se-core-product/work/active/<feature>.yaml`.
116
+
117
+ ### Production handoff
118
+
119
+ Agents stop at handoff — they do not merge to `main`. See skill `site-workflows-agent-session` Step 8.
120
+
87
121
  ## CMS editing (cms-edit)
88
122
 
89
123
  Before any Contentful content edit: