@se-studio/contentful-cms 3.10.0 → 3.10.2
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/dist/commands/discard.d.ts +3 -0
- package/dist/commands/discard.d.ts.map +1 -1
- package/dist/commands/discard.js +16 -2
- package/dist/commands/discard.js.map +1 -1
- package/dist/commands/entry-lookup-target.d.ts +18 -0
- package/dist/commands/entry-lookup-target.d.ts.map +1 -1
- package/dist/commands/entry-lookup-target.js +14 -1
- package/dist/commands/entry-lookup-target.js.map +1 -1
- package/dist/commands/nav.d.ts.map +1 -1
- package/dist/commands/nav.js +46 -30
- package/dist/commands/nav.js.map +1 -1
- package/dist/commands/preview.d.ts.map +1 -1
- package/dist/commands/preview.js +23 -8
- package/dist/commands/preview.js.map +1 -1
- package/dist/commands/set.d.ts.map +1 -1
- package/dist/commands/set.js +11 -2
- package/dist/commands/set.js.map +1 -1
- package/dist/contentful/cma-user-agent.d.ts +1 -1
- package/dist/contentful/set-field-schema.d.ts +9 -1
- package/dist/contentful/set-field-schema.d.ts.map +1 -1
- package/dist/contentful/set-field-schema.js +21 -1
- package/dist/contentful/set-field-schema.js.map +1 -1
- package/dist/editor-pack/capabilities.d.ts.map +1 -1
- package/dist/editor-pack/capabilities.js +16 -0
- package/dist/editor-pack/capabilities.js.map +1 -1
- package/dist/generated/help-topics.d.ts +1 -1
- package/dist/generated/help-topics.d.ts.map +1 -1
- package/dist/generated/help-topics.js +2 -2
- package/dist/generated/help-topics.js.map +1 -1
- package/dist/generated/hosted-guide.d.ts +1 -1
- package/dist/generated/hosted-guide.d.ts.map +1 -1
- package/dist/generated/hosted-guide.js +1 -1
- package/dist/generated/hosted-guide.js.map +1 -1
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/mcp/tools/cms-edit.d.ts +1 -1
- package/dist/mcp/tools/cms-edit.d.ts.map +1 -1
- package/dist/mcp/tools/cms-edit.js +7 -3
- package/dist/mcp/tools/cms-edit.js.map +1 -1
- package/dist/preview/resolve-preview-entry.d.ts +18 -0
- package/dist/preview/resolve-preview-entry.d.ts.map +1 -0
- package/dist/preview/resolve-preview-entry.js +30 -0
- package/dist/preview/resolve-preview-entry.js.map +1 -0
- package/dist/session/navigation-fields.d.ts +21 -0
- package/dist/session/navigation-fields.d.ts.map +1 -0
- package/dist/session/navigation-fields.js +79 -0
- package/dist/session/navigation-fields.js.map +1 -0
- package/dist/session/refs.d.ts +3 -3
- package/dist/session/refs.d.ts.map +1 -1
- package/dist/session/refs.js +6 -15
- package/dist/session/refs.js.map +1 -1
- package/docs/editor-tasks/create-from-document.md +3 -3
- package/docs/editor-tasks/create-html-component.md +135 -0
- package/docs/editor-tasks/navigation.md +11 -6
- package/docs/editor-tasks/source-readiness-review.md +3 -3
- package/docs/help/create-from-json.md +27 -1
- package/docs/help/fields-html-component.md +78 -0
- package/docs/help/fields.md +2 -1
- package/docs/help/index.md +1 -0
- package/docs/help/lookup.md +6 -3
- package/docs/mcp/hosted-guide.md +4 -3
- package/package.json +1 -1
- package/skills/core/SKILL.md +10 -3
package/dist/session/refs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refs.js","sourceRoot":"","sources":["../../src/session/refs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"refs.js","sourceRoot":"","sources":["../../src/session/refs.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
- Fetch package materials (Google Drive MCP, paste, Figma link, zip, production ref, **or designer HTML**)
|
|
18
18
|
- Read `cms-edit://customer/components-index`, `routing`, and for articles **`articles`**
|
|
19
|
-
- **Designer HTML / interactive prototype:**
|
|
19
|
+
- **Designer HTML / interactive prototype / vendor JS:** switch to `cms-edit://customer/task-create-html-component` and stop this one. Do not flatten custom CSS/JS/scroll into registered cards. Libraries go on `externalScripts`, never `<script src>` or `createElement('script')`.
|
|
20
20
|
- **Non-trivial packages:** complete **`task-source-readiness-review`** first (inventory → beat sheet → verdict → light human yes)
|
|
21
21
|
|
|
22
22
|
## Steps
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
- If the source is custom HTML/JS, sticky/scroll, diagrams, or a private layout shell, and this space has `htmlComponent`, map that beat to **`htmlComponent`** — not cards/lists that only match the copy.
|
|
45
45
|
- Mixed pages are expected. Merge consecutive custom sections that share CSS/JS/sticky into **one** HtmlComponent. Do not emit one HtmlComponent per `<section>`.
|
|
46
46
|
- Prefer **source order** over CMS convenience (do not invent side-by-side pairs unless the source is a true pair).
|
|
47
|
-
3. **Propose plan** (can reuse the soft-proof): slug, title, template/article type, ordered component list (registered **and** `htmlComponent` where needed), gap/placeholder list, **asset map** — **ask user to confirm** with a light **yes** if not already confirmed. For HtmlComponent beats: extract `data:` media first; run `schema htmlComponent` for this space’s field IDs (`html` vs `htmlContent`).
|
|
47
|
+
3. **Propose plan** (can reuse the soft-proof): slug, title, template/article type, ordered component list (registered **and** `htmlComponent` where needed), gap/placeholder list, **asset map** — **ask user to confirm** with a light **yes** if not already confirmed. For HtmlComponent beats: extract `data:` media first; run `schema htmlComponent` for this space’s field IDs (`html` vs `htmlContent`); list vendor URLs for `externalScripts` (see `task-create-html-component`).
|
|
48
48
|
4. For pages: `list --type template` — pick template; check template `preContent` / `postContent` so heroes are not duplicated.
|
|
49
49
|
5. For articles: resolve `articleType`; apply site SEO and lab rules from `articles` playbook.
|
|
50
50
|
6. Build `create from-json` payload **or** prefer incremental `open` → `add` / `set` / `rtf` for large multi-block work. Link visuals using the pack map from Phase 1.
|
|
@@ -81,4 +81,4 @@ Use MCP prompts `cms_edit_create_from_doc` or `cms_edit_create_article_from_doc`
|
|
|
81
81
|
- `task-create-page`
|
|
82
82
|
- `task-media-reuse-and-upload`
|
|
83
83
|
- `task-preview-verify`
|
|
84
|
-
-
|
|
84
|
+
- `cms-edit://customer/task-create-html-component`
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Capability: Create from designer HTML (HtmlComponent)
|
|
2
|
+
|
|
3
|
+
## Intent phrases
|
|
4
|
+
|
|
5
|
+
- build from designer HTML
|
|
6
|
+
- HTML dump
|
|
7
|
+
- create from HTML prototype
|
|
8
|
+
- import HTML landing page
|
|
9
|
+
- HtmlComponent from HTML
|
|
10
|
+
- custom HTML page
|
|
11
|
+
- load HtmlComponent external scripts
|
|
12
|
+
|
|
13
|
+
## Requires capabilities
|
|
14
|
+
|
|
15
|
+
`pages` or `articles`
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
- Read `cms-edit://customer/pages` (or `articles`) and `cms-edit://customer/components-index`
|
|
20
|
+
- `cms_edit ["schema", "htmlComponent"]` — use this space’s field IDs (`rawHtml` vs `htmlContent`, `customJs` vs `jsContent`). **`externalScripts` is the same field id on every space.**
|
|
21
|
+
- Designer HTML / prototype available (file, paste, or Drive). **Do not** paste a multi-megabyte dump with `data:` URIs into Contentful.
|
|
22
|
+
- For ordinary Google Doc / Figma-to-registered-stack briefs with no custom CSS/JS, use `task-create-from-document` instead.
|
|
23
|
+
|
|
24
|
+
## When to use this playbook
|
|
25
|
+
|
|
26
|
+
Use this when the source is a **designer HTML dump**, interactive prototype, or a block that needs a **third-party JS library**. Do not flatten custom CSS/JS/scroll into registered cards because the copy looks like a card grid.
|
|
27
|
+
|
|
28
|
+
## Per-section decision
|
|
29
|
+
|
|
30
|
+
For **each** source section, ask: do **layout and interaction** match a registered type?
|
|
31
|
+
|
|
32
|
+
| Fit | Action |
|
|
33
|
+
|-----|--------|
|
|
34
|
+
| Strong (same pattern) | Use the registered type. |
|
|
35
|
+
| Medium (copy matches, chrome differs) | Ask the human: site chrome vs keep HtmlComponent. |
|
|
36
|
+
| Weak / none | HtmlComponent. Custom sticky scroll, diagrams, widgets, vendor JS. |
|
|
37
|
+
|
|
38
|
+
Mock **nav and footer** in the HTML: strip. The page **template** supplies chrome.
|
|
39
|
+
|
|
40
|
+
## Split HtmlComponents (mixed pages)
|
|
41
|
+
|
|
42
|
+
Mixed pages are expected: registered types **plus** one or more `htmlComponent` entries.
|
|
43
|
+
|
|
44
|
+
**Do split** when a section matches a registered type, remaining HTML would exceed field limits, or adjacent custom blocks **do not share** JS/CSS/sticky state.
|
|
45
|
+
|
|
46
|
+
**Do not split** when one behaviour spans the markup (sticky rail + stacked cards) or several sections share one stylesheet / SVG sprite / library.
|
|
47
|
+
|
|
48
|
+
Rules:
|
|
49
|
+
|
|
50
|
+
1. Registered match → registered type.
|
|
51
|
+
2. Merge consecutive custom sections that share CSS/JS into **one** HtmlComponent.
|
|
52
|
+
3. Start a new HtmlComponent only at a clean boundary (no shared script, no sticky parent).
|
|
53
|
+
4. Never one HtmlComponent per `<section>` by default.
|
|
54
|
+
|
|
55
|
+
## External scripts (non-negotiable)
|
|
56
|
+
|
|
57
|
+
Put third-party libraries in **`externalScripts`**, not `<script src>` in HTML and not `createElement('script')` inside `customJs`.
|
|
58
|
+
|
|
59
|
+
Allowed values:
|
|
60
|
+
|
|
61
|
+
- Same-origin paths under `/html-components/` that end in `.js` (no `..`, no query, no hash). Prefer files in the site repo at `public/html-components/<feature>/….js`.
|
|
62
|
+
- HTTPS URLs whose hostname is already listed on the site’s `CmsRendererConfig.htmlComponentExternalScriptHosts`. If the site sets CSP, that host must also be in `script-src`.
|
|
63
|
+
|
|
64
|
+
If the host is **not** allowlisted, **stop** — do not invent a CDN load and do not patch renderer config without a human.
|
|
65
|
+
|
|
66
|
+
Rejected (renderer drops these; preview/dev may warn): `http:`, `javascript:`, protocol-relative `//…`, path `..`, query/hash on same-origin paths.
|
|
67
|
+
|
|
68
|
+
Max **10** URLs per entry. Duplicate URLs on one page share one `next/script` id. Externals load with `scriptStrategy` (default `afterInteractive`). **`customJs` runs only after every listed src is ready**; if any src fails, inline JS is not injected.
|
|
69
|
+
|
|
70
|
+
### How to set `externalScripts`
|
|
71
|
+
|
|
72
|
+
It is an **Array of Symbol**, not a string. Scalar `set` is rejected.
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
cms_edit ["set", "@cN", "externalScripts", "--json", "[\"/html-components/feature/lib.js\"]"]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
On `create from-json`, put the same array under `fields.externalScripts`. Run `schema htmlComponent` first — unknown keys fail (`html` vs `htmlContent`).
|
|
79
|
+
|
|
80
|
+
Then set HTML/CSS/JS with `--content` / `--content-base64` on `rawHtml`/`customCss`/`customJs` (or this space’s dual-write ids).
|
|
81
|
+
|
|
82
|
+
## Media first (mandatory)
|
|
83
|
+
|
|
84
|
+
1. Extract binary media from `data:` URIs and local files. Upload via `task-media-reuse-and-upload` (search/reuse first).
|
|
85
|
+
2. Rewrite HTML `src` / `poster` to Contentful or CDN URLs. Never leave base64 in the field.
|
|
86
|
+
3. `markdownContent` = user-visible copy and structure. Omit layout chrome and JS behaviour.
|
|
87
|
+
|
|
88
|
+
## HtmlComponent authoring
|
|
89
|
+
|
|
90
|
+
1. Follow the site HTML style guide (`docs/cms-guidelines/html-component-style-guide.md` when available).
|
|
91
|
+
2. Scope all JS queries to injected `hcRoot`.
|
|
92
|
+
3. `isHero` — `true` if this block contains the page `<h1>`. `fullWidth` — as needed for full-bleed sections.
|
|
93
|
+
4. Set `cmsLabel` immediately (never leave “New Generic”).
|
|
94
|
+
5. Dual-write legacy + core field IDs when `schema htmlComponent` shows both.
|
|
95
|
+
6. Draft only — never publish unless the human explicitly asks.
|
|
96
|
+
|
|
97
|
+
## Steps
|
|
98
|
+
|
|
99
|
+
1. Inventory sections. For each: registered / ask / HtmlComponent. Merge custom blocks that share CSS/JS.
|
|
100
|
+
2. List vendor libraries. Copy same-origin files into `public/html-components/<feature>/` or confirm the HTTPS host is already allowlisted.
|
|
101
|
+
3. Post a soft-proof (ordered stack + `externalScripts` URLs) and get a light human **yes**.
|
|
102
|
+
4. Media pipeline: extract, upload, rewrite URLs.
|
|
103
|
+
5. Create or open the page/article. Add registered components where decided.
|
|
104
|
+
6. For each HtmlComponent: `add htmlComponent` (or `create from-json --dry-run --strict` with this space’s field keys).
|
|
105
|
+
7. Set `externalScripts` with `--json`. Set HTML/CSS/JS. Set `cmsLabel`.
|
|
106
|
+
8. `diff` → `save` (draft).
|
|
107
|
+
9. `cms_edit ["preview", "urls", "<slug>"]` — follow `task-preview-verify`. Confirm libraries load (no `createElement('script')`, no dropped-URL warnings).
|
|
108
|
+
|
|
109
|
+
## Confirmation gates
|
|
110
|
+
|
|
111
|
+
1. Soft-proof (mixed stack + script URLs) + human yes
|
|
112
|
+
2. Media extracted (no `data:` in saved HTML)
|
|
113
|
+
3. `schema htmlComponent` field IDs used
|
|
114
|
+
4. Libraries only via `externalScripts`
|
|
115
|
+
5. `diff` before `save`
|
|
116
|
+
|
|
117
|
+
## Out of scope
|
|
118
|
+
|
|
119
|
+
- Publish
|
|
120
|
+
- Flattening custom interaction into cards/lists because copy looks similar
|
|
121
|
+
- One HtmlComponent per `<section>` by default
|
|
122
|
+
- Rewriting source copy
|
|
123
|
+
- Pasting the raw designer file into HTML
|
|
124
|
+
- Adding a new CDN host to `htmlComponentExternalScriptHosts` without a human
|
|
125
|
+
- Scalar `set` of a single URL string onto `externalScripts`
|
|
126
|
+
|
|
127
|
+
## Related resources
|
|
128
|
+
|
|
129
|
+
- `cms-edit://customer/pages`
|
|
130
|
+
- `cms-edit://customer/task-create-from-document`
|
|
131
|
+
- `cms-edit://customer/task-create-page`
|
|
132
|
+
- `cms-edit://customer/task-media-reuse-and-upload`
|
|
133
|
+
- `cms-edit://customer/task-preview-verify`
|
|
134
|
+
- `cms-edit://customer/task-publish-handoff`
|
|
135
|
+
- `cms_edit ["help", "fields-html-component"]`
|
|
@@ -18,16 +18,21 @@
|
|
|
18
18
|
## Steps
|
|
19
19
|
|
|
20
20
|
1. `cms_edit ["list", "--type", "navigation"]` — find nav entry
|
|
21
|
-
2. `cms_edit ["nav", "open", "--id", "<navigationId>"]` or
|
|
22
|
-
3. `snapshot` — inspect nav items
|
|
23
|
-
4.
|
|
24
|
-
|
|
21
|
+
2. `cms_edit ["nav", "open", "--nav-id", "<navigationId>"]` or `["nav", "open", "--nav-name", "Main menu"]` — **not** `--id`
|
|
22
|
+
3. `snapshot` — inspect nav items (array field may be `entries`, `items`, or `navigationItems`)
|
|
23
|
+
4. **Ask** whether the change is **global** (template `menu`) or **page-specific** (`page.menu` override). Nested children (often the last header CTA) are usually **shared**.
|
|
24
|
+
- Global: `set` on the existing NavigationItem
|
|
25
|
+
- Page-specific: new NavigationItem + cloned/new menu, then `set` `page.menu` — do not mutate the shared item
|
|
26
|
+
5. Add/clone/link items per navigation commands. `nav clone` is **shallow** for nested `navigationItems`.
|
|
27
|
+
6. `diff` → `save`
|
|
28
|
+
|
|
29
|
+
`peek` is one-shot. `open` / `nav open` persist. `preview urls /slug` follows that slug even if session `_mcp` is another page.
|
|
25
30
|
|
|
26
31
|
See `contentful-cms-navigation` skill for full command reference in dev environments.
|
|
27
32
|
|
|
28
33
|
## Confirmation gates
|
|
29
34
|
|
|
30
|
-
1. Confirm which menu (header/footer) and
|
|
35
|
+
1. Confirm which menu (header/footer) and whether the edit is global vs this page
|
|
31
36
|
2. `diff` before `save`
|
|
32
37
|
|
|
33
38
|
## Out of scope
|
|
@@ -36,4 +41,4 @@ See `contentful-cms-navigation` skill for full command reference in dev environm
|
|
|
36
41
|
|
|
37
42
|
## Related resources
|
|
38
43
|
|
|
39
|
-
- `cms-edit://customer/routing`
|
|
44
|
+
- `cms-edit://customer/routing`
|
|
@@ -45,11 +45,11 @@ If title, order, or hero asset **conflict** and the user has not decided → **N
|
|
|
45
45
|
|---|------|-------------------|-----------------------------------|----------------------|
|
|
46
46
|
| 1 | … | … | … | … |
|
|
47
47
|
|
|
48
|
-
3. **Build beat sheet** — ordered narrative + visual beats. For each beat: use a **registered** component/collection type when **layout and interaction** match (`components-index` / site playbook). If the source is designer HTML, custom CSS/JS, sticky/scroll, or a diagram that no registered type can reproduce, map to **`htmlComponent`** when that type exists in the space
|
|
48
|
+
3. **Build beat sheet** — ordered narrative + visual beats. For each beat: use a **registered** component/collection type when **layout and interaction** match (`components-index` / site playbook). If the source is designer HTML, custom CSS/JS, sticky/scroll, or a diagram that no registered type can reproduce, map to **`htmlComponent`** when that type exists in the space and follow **`task-create-html-component`**. Mixed stacks are valid. Merge consecutive custom HTML beats that share CSS/JS. Prefer **source order** over CMS convenience. Vendor libraries belong on `externalScripts`.
|
|
49
49
|
4. **Score verdict** using the threshold below.
|
|
50
50
|
5. **Post one-screen soft-proof** — numbered final `content` (or page stack) order + gap list + verdict.
|
|
51
51
|
6. **Ask for a light human confirm** — accept **yes** / **go** / **proceed** (or equivalent). Do not build on silence if the package is non-trivial.
|
|
52
|
-
7. On **GO** or **GO-WITH-GAPS** + yes → hand off to `task-create-html-component`
|
|
52
|
+
7. On **GO** or **GO-WITH-GAPS** + yes → hand off to `task-create-html-component` when the source is designer HTML / vendor JS, otherwise `task-create-from-document` / `task-create-article` / `task-create-page` with the soft-proof as the plan.
|
|
53
53
|
8. On **NO-GO** → stop; list what is blocking (do not invent structure to unblock).
|
|
54
54
|
|
|
55
55
|
## Gap threshold
|
|
@@ -114,4 +114,4 @@ Copy: unchanged from source (list any human decisions only)
|
|
|
114
114
|
- `task-media-pipeline-prepare`
|
|
115
115
|
- `task-media-reuse-and-upload`
|
|
116
116
|
- `task-preview-verify`
|
|
117
|
-
-
|
|
117
|
+
- `task-create-html-component`
|
|
@@ -17,7 +17,7 @@ cms_edit ["create", "from-json", "--json", "{...}", "--dry-run", "--strict"]
|
|
|
17
17
|
- Nested tree key is **`components`**, not `content` (`content` is a page field — empty page).
|
|
18
18
|
- Discriminator is **`type`**, not `componentType` / `collectionType`.
|
|
19
19
|
- **`components` must be non-empty**.
|
|
20
|
-
- Unknown nested keys fail (`html` vs `htmlContent` — run `schema htmlComponent` for this space).
|
|
20
|
+
- Unknown nested keys fail (`html` vs `htmlContent` — run `schema htmlComponent` for this space). Put vendor libraries on `fields.externalScripts` (string array), not inside HTML.
|
|
21
21
|
- CTA text is **`label`**, not `linkText`.
|
|
22
22
|
- Quoted `set @c1:field="value"` is rejected (quotes would be stored). Use `["set", "@c1", "field", "value"]`.
|
|
23
23
|
|
|
@@ -403,3 +403,29 @@ Once created:
|
|
|
403
403
|
3. Publish in the Contentful web app when ready.
|
|
404
404
|
|
|
405
405
|
The tool prints the Contentful web app URL for the new entry after creation.
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## HtmlComponent example
|
|
410
|
+
|
|
411
|
+
Run `schema htmlComponent` first. Field ids below are the core names; some spaces use `htmlContent` / `cssContent` / `jsContent` instead (or dual-write both). Vendor libraries belong on `externalScripts`, not inside HTML.
|
|
412
|
+
|
|
413
|
+
```json
|
|
414
|
+
{
|
|
415
|
+
"type": "page",
|
|
416
|
+
"slug": "/lab/html-widget",
|
|
417
|
+
"title": "HTML widget",
|
|
418
|
+
"components": [
|
|
419
|
+
{
|
|
420
|
+
"contentType": "htmlComponent",
|
|
421
|
+
"cmsLabel": "Widget — jsPDF demo",
|
|
422
|
+
"fields": {
|
|
423
|
+
"rawHtml": "<div class=\"widget\"><button type=\"button\" class=\"export\">Export</button></div>",
|
|
424
|
+
"customJs": "hcRoot.querySelector('.export').addEventListener('click', function () { window.jspdf.jsPDF(); });",
|
|
425
|
+
"externalScripts": ["/html-components/widget/jspdf.umd.min.js"],
|
|
426
|
+
"markdownContent": "Export widget"
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
]
|
|
430
|
+
}
|
|
431
|
+
```
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# cms-edit — HtmlComponent Field Reference
|
|
2
|
+
|
|
3
|
+
An `htmlComponent` entry is developer-authored HTML, optional scoped CSS, optional inline JS, and optional **external script URLs**. It is not a registered `component` variant.
|
|
4
|
+
|
|
5
|
+
Run `cms-edit schema htmlComponent` for this space’s field IDs. Some spaces dual-write legacy names (`htmlContent` / `cssContent` / `jsContent`) plus core ids (`rawHtml` / `customCss` / `customJs`). **`externalScripts` is the same id on every space.** Unknown JSON keys fail (`html` vs `htmlContent`).
|
|
6
|
+
|
|
7
|
+
See `cms-edit://customer/task-create-html-component` for the full create playbook.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Fields
|
|
12
|
+
|
|
13
|
+
| Field | Type | Required | Description |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| `cmsLabel` | Symbol | Yes | Internal label. Set immediately. |
|
|
16
|
+
| `rawHtml` / `htmlContent` | Text | Yes | Markup. No `<script src>`. |
|
|
17
|
+
| `customCss` / `cssContent` | Text | No | Auto-scoped to `[data-hc-id]`. |
|
|
18
|
+
| `customJs` / `jsContent` | Text | No | Inline JS via `next/script`. Scope queries to injected `hcRoot`. |
|
|
19
|
+
| `externalScripts` | Array of Symbol | No | Allowlisted script URLs loaded **before** `customJs`. Max 10. |
|
|
20
|
+
| `markdownContent` | Text | No | Plain text for search / markdown export. |
|
|
21
|
+
| `scriptStrategy` | Symbol | No | `afterInteractive` (default), `lazyOnload`, `beforeInteractive`. Applies to externals and inline JS. |
|
|
22
|
+
| `isHero` | Boolean | No | `true` when the HTML contains the page `<h1>`. |
|
|
23
|
+
| `fullWidth` | Boolean | No | Viewport-breakout layout when the site renderer supports it. |
|
|
24
|
+
| `excludeFromSearch` | Boolean | No | Skip search even if `markdownContent` is set. |
|
|
25
|
+
| `loadScriptOnce` | Boolean | No | Dedupe inline script id per entry (default true). External URLs already share one `next/script` id per URL. |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## `externalScripts` allowlist
|
|
30
|
+
|
|
31
|
+
Always allowed: same-origin paths matching `/html-components/` + a `.js` filename (no `..`, no query, no hash). Prefer files in the site repo at `public/html-components/<feature>/….js`.
|
|
32
|
+
|
|
33
|
+
HTTPS URLs are allowed only when the hostname is in `CmsRendererConfig.htmlComponentExternalScriptHosts`. If the site has CSP, that host must also be in `script-src`. If the host is not allowlisted, **stop** — do not invent a CDN load.
|
|
34
|
+
|
|
35
|
+
Rejected: `http:`, `javascript:`, `//…`, path traversal, query/hash on same-origin paths. Disallowed URLs are not loaded (preview/dev may warn). Duplicates are dropped at render. `customJs` waits until every listed src is ready; a failed src skips inline JS.
|
|
36
|
+
|
|
37
|
+
Do **not** put libraries in HTML `<script>` tags or `createElement('script')` inside `customJs`.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Setting fields
|
|
42
|
+
|
|
43
|
+
HTML/CSS/JS (long text):
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
cms_edit ["set", "@cN", "rawHtml", "--content-base64", "<b64>"]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`externalScripts` is an array — **not** a scalar string. Scalar `set` is rejected.
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
cms_edit ["set", "@cN", "externalScripts", "--json", "[\"/html-components/feature/lib.js\"]"]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
On `create from-json`:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"contentType": "htmlComponent",
|
|
60
|
+
"cmsLabel": "Pricing grid",
|
|
61
|
+
"fields": {
|
|
62
|
+
"rawHtml": "<div class=\"hc-root\">…</div>",
|
|
63
|
+
"customJs": "hcRoot.querySelector('.buy')",
|
|
64
|
+
"externalScripts": ["/html-components/pricing-grid/lib.js"],
|
|
65
|
+
"markdownContent": "Pricing grid"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Use this space’s field ids from `schema htmlComponent` (`rawHtml` vs `htmlContent`). Dual-write both when the schema shows both.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Related
|
|
75
|
+
|
|
76
|
+
- `cms-edit://customer/task-create-html-component`
|
|
77
|
+
- `cms-edit help create-from-json`
|
|
78
|
+
- `cms-edit schema htmlComponent`
|
package/docs/help/fields.md
CHANGED
|
@@ -10,7 +10,7 @@ This page lists the content types managed by `cms-edit` and links to their field
|
|
|
10
10
|
|---|---|---|
|
|
11
11
|
| `page` | Web pages with a slug and content tree | `cms-edit help fields-page` |
|
|
12
12
|
| `article` | Blog posts and news items | `cms-edit help fields-article` |
|
|
13
|
-
| `
|
|
13
|
+
| `htmlComponent` | Developer-authored HTML / CSS / JS blocks | `cms-edit help fields-html-component` |
|
|
14
14
|
| `collection` | Groups of components (card grids, timelines, etc.) | `cms-edit help fields-collection` |
|
|
15
15
|
| `link` | CTA button entries | Managed via `cms-edit links` |
|
|
16
16
|
| `template` | Reusable page shell (header, footer slots) | Used via `templateId` in `create from-json` |
|
|
@@ -57,4 +57,5 @@ Run `cms-edit snapshot` to see current refs.
|
|
|
57
57
|
- `cms-edit help fields-page` — page entry fields
|
|
58
58
|
- `cms-edit help fields-article` — article entry fields
|
|
59
59
|
- `cms-edit help fields-component` — component entry fields
|
|
60
|
+
- `cms-edit help fields-html-component` — HtmlComponent (raw HTML, `externalScripts`)
|
|
60
61
|
- `cms-edit help fields-collection` — collection entry fields
|
package/docs/help/index.md
CHANGED
|
@@ -29,6 +29,7 @@ Available topics for `cms-edit help <topic>`:
|
|
|
29
29
|
| `fields-page` | All fields on a `page` entry |
|
|
30
30
|
| `fields-article` | All fields on an `article` entry |
|
|
31
31
|
| `fields-component` | All fields on a `component` entry |
|
|
32
|
+
| `fields-html-component` | HtmlComponent fields including `externalScripts` |
|
|
32
33
|
| `fields-collection` | All fields on a `collection` entry |
|
|
33
34
|
| `fields-taxonomy` | All fields on `tagType`, `articleType`, and `tag` entries |
|
|
34
35
|
| `index-sync` | Build and use the local content index (CDA sync) |
|
package/docs/help/lookup.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
# Flat lookup flags (`open`, `
|
|
1
|
+
# Flat lookup flags (`open`, `peek`, `resolve`)
|
|
2
2
|
|
|
3
|
-
cms-edit resolves entries using **explicit flags** — not positional slugs. Provide **exactly one** primary lookup flag per command. Scope flags (for example `--tag-type-name` with `--tag-name`) do not count as a second primary.
|
|
3
|
+
cms-edit resolves entries using **explicit flags** — not positional slugs. Provide **exactly one** primary lookup flag per command. Scope flags (for example `--tag-type-name` with `--tag-name`, or `--nav-id` with `--nav-item-title`) do not count as a second primary.
|
|
4
|
+
|
|
5
|
+
`cms-edit nav open` is separate: pass **`--nav-id` or `--nav-name`**, never `--id`. `--nav-id` alone is not a `resolve` primary.
|
|
4
6
|
|
|
5
7
|
Run `cms-edit index sync` once per space (or let commands auto-sync) so catalog types resolve from the local index.
|
|
6
8
|
|
|
@@ -98,9 +100,10 @@ Navigation entries use the **`name`** field (not slug).
|
|
|
98
100
|
| `--nav-item-id` | `navigationItem` entry ID |
|
|
99
101
|
| `--nav-item-title` | `navigationItem.fields.title` |
|
|
100
102
|
|
|
101
|
-
When multiple nav items share a title, add **`--nav-id`** to scope:
|
|
103
|
+
When multiple nav items share a title, add **`--nav-id`** to scope `resolve` (do not use `--nav-id` alone on `resolve`):
|
|
102
104
|
|
|
103
105
|
```bash
|
|
106
|
+
cms-edit nav open --nav-id <navigation-entry-id>
|
|
104
107
|
cms-edit nav open --nav-name "Main header"
|
|
105
108
|
cms-edit resolve --nav-item-title "Contact" --nav-id <navigation-entry-id>
|
|
106
109
|
```
|
package/docs/mcp/hosted-guide.md
CHANGED
|
@@ -22,7 +22,7 @@ All `save` operations create **drafts only**. A human must review and publish in
|
|
|
22
22
|
| `cms_edit` | Run any cms-edit command via an `args` array |
|
|
23
23
|
| `cms_edit_request_staged_upload` | Presigned URL for binaries. Raster/video: then `cms_edit_media` prepare. SVG/PDF/Lottie: then `asset upload --staged` |
|
|
24
24
|
| `cms_edit_version` | Check the installed cms-edit version (no session required) |
|
|
25
|
-
| `cms_edit_help` | Guide topics (`overview`, `workflow`, `commands`, `troubleshooting`, `hosted`) **or** playbooks (`create-from-json`, `fields-component`, …) |
|
|
25
|
+
| `cms_edit_help` | Guide topics (`overview`, `workflow`, `commands`, `troubleshooting`, `hosted`) **or** playbooks (`create-from-json`, `fields-html-component`, `fields-component`, …) |
|
|
26
26
|
|
|
27
27
|
## Customer editor pack (read first)
|
|
28
28
|
|
|
@@ -88,7 +88,7 @@ Each step is a separate `cms_edit` call. Sessions persist in Redis between calls
|
|
|
88
88
|
["open", "--include-chrome", "--page-slug", "/pricing"]
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
Default `open` / `peek` fetch the page or article tree and the template entry, but **not** template menu/footer/navigation. Edit nav with `nav open
|
|
91
|
+
Default `open` / `peek` fetch the page or article tree and the template entry, but **not** template menu/footer/navigation. Edit nav with `["nav", "open", "--nav-id", "<id>"]` or `--nav-name` (not `--id`). Use `--include-chrome` only when you need those trees. Template `menu` is site-wide; `page.menu` overrides one page. Nested nav items are often shared — ask global vs page-specific before `set`.
|
|
92
92
|
|
|
93
93
|
**Homepage (all SE Studio sites):** Contentful stores the marketing homepage slug as `index`. The live site URL is `/`. In cms-edit, `--page-slug /` and `--page-slug /index` are equivalent (both resolve to `index`). Read `cms-edit://customer/routing` for site-specific exceptions (e.g. Pedestal uses `home`).
|
|
94
94
|
|
|
@@ -311,7 +311,8 @@ OAuth is two steps: Grok obtains an MCP token, then you sign in with Contentful
|
|
|
311
311
|
| Debug session persistence | `["diagnose"]` — reports store, userId, active session key |
|
|
312
312
|
|
|
313
313
|
- **`peek` is one-shot** — prints tree and **root field values** (`rootFields` in JSON). No session is created; do not chain `read @ref` afterward.
|
|
314
|
-
-
|
|
314
|
+
- **`open` / `nav open` persist** the session. `preview urls /slug` follows that slug even if leftover `_mcp` is another page (JSON may include `sessionRootIgnored`).
|
|
315
|
+
- **Use flat lookup flags** for `open` and `peek` — same as CLI (`--page-slug`, `--id`, etc.). See `help lookup`. `nav open` uses `--nav-id` or `--nav-name` only.
|
|
315
316
|
- **`read @root`** only works after `open` (uses the active session). The hint in peek output is for terminal users who already ran `open`.
|
|
316
317
|
- **Do not invent flags** — there is no `--read`, `--then`, or chained peek+read syntax. One command per `cms_edit` call.
|
|
317
318
|
|
package/package.json
CHANGED
package/skills/core/SKILL.md
CHANGED
|
@@ -70,7 +70,7 @@ cms-edit open --include-chrome --page-slug /pricing
|
|
|
70
70
|
|
|
71
71
|
`open` / `peek` fetch the page (or article) tree and the template entry, but **not** template `menu` / `footer` / navigation. Edit nav with `nav open`. Pass `--include-chrome` only when you need those trees.
|
|
72
72
|
|
|
73
|
-
**Flat lookup flags:** provide **exactly one** primary flag per `open` / `
|
|
73
|
+
**Flat lookup flags:** provide **exactly one** primary flag per `open` / `peek` / `resolve`. `nav open` uses **`--nav-id` or `--nav-name` only** (not `--id`). See `cms-edit help lookup`. Run `cms-edit index sync` so catalog types resolve from the local index.
|
|
74
74
|
|
|
75
75
|
### Step 2: Read the snapshot
|
|
76
76
|
|
|
@@ -399,8 +399,9 @@ JSON output for upload (`CMS_EDIT_JSON=1`): `{ ok, id, fileName, url, mediaId?,
|
|
|
399
399
|
## Navigation
|
|
400
400
|
|
|
401
401
|
```bash
|
|
402
|
-
# Open a navigation entry (
|
|
402
|
+
# Open a navigation entry (not --id). Navigation uses `name`, not slug.
|
|
403
403
|
cms-edit nav open --nav-name "Main navigation"
|
|
404
|
+
cms-edit nav open --nav-id <navigation-entry-id>
|
|
404
405
|
|
|
405
406
|
# Add a new item
|
|
406
407
|
cms-edit nav add --label "Pricing" --slug /pricing
|
|
@@ -409,11 +410,17 @@ cms-edit nav add --label "Docs" --href https://docs.example.com --after @c1
|
|
|
409
410
|
# Link an existing NavigationItem (share items across navigations)
|
|
410
411
|
cms-edit nav add --existing-id <navigationItem-entry-id>
|
|
411
412
|
|
|
412
|
-
# Clone a navigation (
|
|
413
|
+
# Clone a navigation (first-level items only; nested children stay shared)
|
|
413
414
|
cms-edit nav clone <source-nav-id>
|
|
414
415
|
cms-edit nav clone <source-nav-id> --label "LP Nav" --slug lp-nav
|
|
415
416
|
```
|
|
416
417
|
|
|
418
|
+
Template **`menu`** is site-wide. **`page.menu`** overrides one page. Header CTAs are often nested under a wrapper and **shared**. Before `set` on a nav item, ask whether the change is global or page-specific. Page-specific: new NavigationItem + cloned/new menu on `page.menu` — do not mutate the shared entry.
|
|
419
|
+
|
|
420
|
+
`peek` is one-shot. `open` / `nav open` persist. `preview urls /slug` follows that slug even if session `_mcp` is another page.
|
|
421
|
+
|
|
422
|
+
The items array field may be `entries`, `items`, or `navigationItems` — inspect `read @root` before `set @root … --links`.
|
|
423
|
+
|
|
417
424
|
## Create New Entries
|
|
418
425
|
|
|
419
426
|
```bash
|