@se-studio/contentful-cms 3.11.1 → 3.11.3

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/contentful/cma-user-agent.d.ts +1 -1
  3. package/dist/generated/help-topics.d.ts.map +1 -1
  4. package/dist/generated/help-topics.js +1 -1
  5. package/dist/generated/help-topics.js.map +1 -1
  6. package/dist/generated/hosted-guide.d.ts +1 -1
  7. package/dist/generated/hosted-guide.d.ts.map +1 -1
  8. package/dist/generated/hosted-guide.js +1 -1
  9. package/dist/generated/hosted-guide.js.map +1 -1
  10. package/dist/generated/version.d.ts +1 -1
  11. package/dist/generated/version.js +1 -1
  12. package/dist/hosted/next/routes/health.d.ts.map +1 -1
  13. package/dist/hosted/next/routes/health.js +4 -0
  14. package/dist/hosted/next/routes/health.js.map +1 -1
  15. package/dist/mcp/tools/cms-edit.d.ts +1 -1
  16. package/dist/mcp/tools/cms-edit.d.ts.map +1 -1
  17. package/dist/mcp/tools/cms-edit.js +1 -1
  18. package/dist/mcp/tools/media.d.ts.map +1 -1
  19. package/dist/mcp/tools/media.js +4 -2
  20. package/dist/mcp/tools/media.js.map +1 -1
  21. package/dist/mcp/tools/staged-upload.js +6 -6
  22. package/dist/mcp/tools/staged-upload.js.map +1 -1
  23. package/dist/media-pipeline/config.d.ts +21 -0
  24. package/dist/media-pipeline/config.d.ts.map +1 -1
  25. package/dist/media-pipeline/config.js +60 -0
  26. package/dist/media-pipeline/config.js.map +1 -1
  27. package/dist/media-pipeline/index.d.ts +1 -1
  28. package/dist/media-pipeline/index.d.ts.map +1 -1
  29. package/dist/media-pipeline/index.js +1 -1
  30. package/dist/media-pipeline/index.js.map +1 -1
  31. package/docs/editor-tasks/media-pipeline-prepare.md +4 -1
  32. package/docs/editor-tasks/media-reuse-and-upload.md +1 -1
  33. package/docs/help/create-from-json.md +1 -1
  34. package/docs/mcp/e2e-test-prompt.md +1 -0
  35. package/docs/mcp/hosted-guide.md +5 -2
  36. package/package.json +1 -1
  37. package/skills/core/SKILL.md +3 -4
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/media-pipeline/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,WAAW,EACX,SAAS,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,GAC7B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,KAAK,mBAAmB,EACxB,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,KAAK,eAAe,EACpB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/media-pipeline/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,WAAW,EACX,SAAS,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,GAC7B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EACvB,KAAK,mBAAmB,EACxB,8BAA8B,EAC9B,wBAAwB,EACxB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,KAAK,eAAe,EACpB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,aAAa,CAAC"}
@@ -1,6 +1,6 @@
1
1
  export { mediaCatalog, mediaImport, mediaPrepare, mediaStatus, mediaWait, } from './actions.js';
2
2
  export { MediaPipelineClient, MediaPipelineClientError, } from './client.js';
3
- export { loadMediaPipelineConfig, mediaPipelineConfiguredMessage, } from './config.js';
3
+ export { interpretStagedUploadGetProbe, loadMediaPipelineConfig, mediaPipelineConfiguredMessage, mediaPipelineHealthCheck, stagedUploadHealthCheck, stagedUploadHmacCheck, } from './config.js';
4
4
  export { createMemoryRedis, MediaJobStoreError, MediaPipelineJobStore, } from './job-store.js';
5
5
  export { MEDIA_DEFAULT_TTL_HOURS, MEDIA_JOB_BINDING_TTL_SECONDS, MEDIA_MAX_CONCURRENT_JOBS_PER_USER, MEDIA_PREPARE_RATE_LIMIT_PER_HOUR, } from './limits.js';
6
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/media-pipeline/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,WAAW,EACX,SAAS,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,GAIzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EAEvB,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EAEjB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/media-pipeline/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,WAAW,EACX,SAAS,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,GAIzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EAEvB,8BAA8B,EAC9B,wBAAwB,EACxB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EAEjB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,aAAa,CAAC"}
@@ -61,7 +61,7 @@ Drive:
61
61
  }
62
62
  ```
63
63
 
64
- Staged (after curl PUT/POST to each `uploadUrl`):
64
+ Staged (after curl POST to each `uploadUrl`):
65
65
 
66
66
  ```json
67
67
  {
@@ -115,6 +115,9 @@ or
115
115
  - Do **not** thrash prepares (rate limit **100**/hour, concurrent max typically **4** per user).
116
116
  - On `429` / too many concurrent: call `status` once on any stuck old `jobId` (to free slots if past grace), then prepare again **once**.
117
117
  - Prefer **reusing** a job that already reached `succeeded` + catalog over preparing again for the same Drive folder.
118
+ - If `gaps[].detail` contains **`staged GET failed 405`**: the cms-edit host is missing GET `/api/staged-upload` (old package). **Stop.** Bump `@se-studio/contentful-cms` on the host and redeploy. Do not retry, do not convert files locally, do not use the Contentful web UI.
119
+ - If `gaps[].detail` contains **`staged GET failed 404`**: the GET route exists; the slot is missing, expired, or not POSTed yet. Re-stage (POST) and prepare **once**. Do not treat 404 as a host bump.
120
+ - **Do not** ffmpeg GIFs/PNGs locally. Animated GIF → pipeline `gif-converted` MP4.
118
121
 
119
122
  ### 3. Catalog
120
123
 
@@ -42,7 +42,7 @@ Encode via **`task-media-pipeline-prepare`**. Intake can be:
42
42
 
43
43
  Then wait → catalog → **import** with `overrides[].alt`. Do **not** `asset upload --staged/--base64` for jpeg/png/webp/gif/mp4. Do **not** `asset upload --url` for **video** (import only). Raster `--url` only for pipeline ready image hosts.
44
44
 
45
- Animated GIFs become **MP4** (`gif-converted`) — attach as mute-loop Media / video visual, not `featuredImage`.
45
+ Animated GIFs become **MP4** (`gif-converted`) — attach as mute-loop Media / video visual, not `featuredImage`. **Do not** convert the GIF (or PNG) with local ffmpeg first; prepare the original file. If prepare gaps say `staged GET failed 405`, stop and report a cms-edit host bump — do not retry and do not use the Contentful web UI. If they say `staged GET failed 404`, re-stage (POST) and prepare once — the GET route exists.
46
46
 
47
47
  ### SVG, PDF, Lottie
48
48
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  `create from-json` creates a complete new page or article — including all components, collections, and CTA links — from `--json`, `--json-base64`, or **`--staged`** (hosted). It is the recommended way to create new pages on hosted MCP.
4
4
 
5
- **Agents:** do not use a local `cms-edit` binary, `--file`, or stdin. **Fields over ~8k must not go through `--json` / `--json-base64` / `--content`.** Hosted MCP rejects those over 8192 bytes. Write the JSON on disk → `cms_edit_request_staged_upload` with `kind=json` → curl → `create from-json --staged <id> --dry-run --strict`. Dry-run peeks without consuming the slot.
5
+ **Agents:** do not use a local `cms-edit` binary, `--file`, or stdin. **Fields over ~8k must not go through `--json` / `--json-base64` / `--content`.** Hosted MCP rejects those over 8192 bytes. Write the JSON on disk → `cms_edit_request_staged_upload` with `kind=json` → curl → `create from-json --staged <id> --dry-run --strict`. Dry-run peeks without consuming the slot. If the wrapper schema has no `kind`, use `cms_edit` `["staged-upload", "request", "--kind", "json", "--file-name", "...", "--mime", "application/json"]`, then curl, then `create from-json --staged`.
6
6
 
7
7
  Also: `export from-json` (open session → same JSON with `existingId` / `version`) and `apply from-json` (`--staged` supported).
8
8
 
@@ -72,6 +72,7 @@ Every E2E prompt should cover these phases (trim for smoke tests):
72
72
  | **4** Session | open → snapshot → read → diff | Homepage slug from routing |
73
73
  | **5** Schema | `schema colours`, `schema types`, `schema fields` | Any site-specific content types |
74
74
  | **6** Media | Read `task-media-review`; `asset review`, optional `--include-usage --usage-limit 5` | Skip if index empty; do not combine `--include-passing` + `--include-usage` without a limit on hosted MCP |
75
+ | **6b** Media pipeline (optional) | Karen-style: add a tiny GIF/PNG to unpublished `cms-edit-qa-media`. Expect prepare→import, not `asset upload`, not local ffmpeg. GIF must not land on `featuredImage`. | SE Studio: [`cms-edit/se2026/MCP-E2E-MEDIA.md`](../../../cms-edit/se2026/MCP-E2E-MEDIA.md). Skip if `checks.mediaPipeline.ok` is false. |
75
76
  | **7** Dry-run writes | set+discard, bulk-rtf dry-run, create from-json dry-run | Skip taxonomy if disabled |
76
77
  | **8** Preview | `preview url`, `preview showcase` | Real component type name |
77
78
  | **9** Negatives | Removed commands (sitemap, ensure, run, …) | Update when CLI changes |
@@ -13,7 +13,7 @@ cms-edit **cannot and will not**:
13
13
 
14
14
  All `save` operations create **drafts only**. A human must review and publish in Contentful.
15
15
 
16
- **Assets:** cms-edit **can upload** draft assets via **staged upload** (hosted) or `--url` (public HTTPS last resort). **`--base64` is not supported on hosted MCP.** Always **search and reuse existing assets first** (`index sync`, then `asset search` or `list --type media`). Use `--if-exists-by-filename` when uploading to avoid duplicates.
16
+ **Assets:** Always **search and reuse** first (`index sync`, then `asset search`). Raster/video go through **`cms_edit_media`** (staged upload or Drive → prepare → import). Never `asset upload` jpeg/png/webp/gif/mp4, and never convert those files with local ffmpeg. SVG/PDF/Lottie: staged upload then `asset upload --staged`. **`--base64` is not supported on hosted MCP.**
17
17
 
18
18
  ## MCP tools
19
19
 
@@ -167,7 +167,7 @@ Full workflow: `cms-edit://customer/task-media-reuse-and-upload`.
167
167
 
168
168
  Keeps binary **and large text/JSON** out of MCP tool args. The agent uploads via `curl`, then passes only a short `uploadId`.
169
169
 
170
- 1. `cms_edit_request_staged_upload` with `fileName`, `mimeType`, optional `kind` (`asset` \| `text` \| `json`), optional `byteLength`, optional `title`
170
+ 1. `cms_edit_request_staged_upload` with `fileName`, `mimeType`, optional `kind` (`asset` \| `text` \| `json`), optional `byteLength`, optional `title`. If the wrapper schema has no `kind`, use `cms_edit` `["staged-upload", "request", "--kind", "json", "--file-name", "...", "--mime", "application/json"]` (or `--kind text` for HtmlComponent fields).
171
171
  2. Run the returned `curlCommand` in a shell (POST multipart to `uploadUrl`)
172
172
  3. Follow `consumeArgs`:
173
173
  - **asset:** media prepare for jpeg/png/webp/gif/mp4; **asset upload --staged** for SVG/PDF/Lottie
@@ -327,6 +327,9 @@ OAuth is two steps: Grok obtains an MCP token, then you sign in with Contentful
327
327
  | **No active session** | Do not pass `--space` on hosted. Check `/api/health` — `redis` must be ok. MCP uses `_mcp` session automatically. Manual session: `["--session", "name", "open", "--page-slug", "/"]`. Fallback: `["read", "<entry-id>", "--id"]` |
328
328
  | **Wrong space** | Your Contentful account must have access to this deployment's space |
329
329
  | **Check version** | Call `cms_edit_version` or `curl /api/health` and read `cmsEdit` |
330
+ | **staged GET failed 405** | Pipeline cannot download staged files. Host must export GET `/api/staged-upload` (`@se-studio/contentful-cms` with staged GET). Bump + redeploy the host. Do not retry prepare or use the Contentful UI. |
331
+ | **staged GET failed 404** | GET is mounted; the slot is missing, expired, or not POSTed yet. Re-stage (POST) and prepare once. Not a host bump. |
332
+ | **pipeline_unconfigured** | `/api/health` `checks.mediaPipeline.ok` is false. Ops set `MEDIA_PIPELINE_*` on the host. Do not ask the user for a pipeline key. |
330
333
 
331
334
  ## Articles
332
335
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@se-studio/contentful-cms",
3
- "version": "3.11.1",
3
+ "version": "3.11.3",
4
4
  "description": "CLI tool for AI agents to read and edit Contentful draft content without publish permissions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,7 +33,7 @@ All `save` operations create **draft** versions. A human must review and publish
33
33
  **Assets:** Upload **is** supported (`asset upload`). Default workflow: **search and reuse** existing assets first (`index sync` → `asset search`). When uploading:
34
34
  - **Raster/video:** `cms_edit_request_staged_upload` → curl → `cms_edit_media` prepare (`stagedUploadIds`) → wait → catalog → import with real alt. Never `asset upload --staged/--url/--base64` for jpeg/png/webp/gif/mp4.
35
35
  - **SVG/PDF/Lottie:** `cms_edit_request_staged_upload` → curl → `asset upload --staged` (never `--base64`)
36
- - **HtmlComponent / large JSON:** `cms_edit_request_staged_upload` with `kind=text` or `kind=json` → curl → `set --staged`, `rtf --staged`, `create from-json --staged`, or `apply from-json --staged`. Hosted MCP rejects inline `--json`/`--content` over 8192 bytes.
36
+ - **HtmlComponent / large JSON:** `cms_edit_request_staged_upload` with `kind=text` or `kind=json` → curl → `set --staged`, `rtf --staged`, `create from-json --staged`, or `apply from-json --staged`. Hosted MCP rejects inline `--json`/`--content` over 8192 bytes. If the wrapper schema has no `kind`, use `cms_edit` `["staged-upload", "request", "--kind", "json", "--file-name", "...", "--mime", "application/json"]` (or `--kind text`), then curl, then `--staged`.
37
37
  - Use a **sensible fileName** and **descriptive title** (and alt text where the site uses it)
38
38
  - Avoid oversized images — width over **2000px** is usually wasteful for web (exact limits vary by project; check `asset audit` / media review guidance)
39
39
  - Prefer `--if-exists-by-filename` to avoid duplicates
@@ -374,11 +374,10 @@ cms-edit asset search --filename istockphoto-123.jpg
374
374
  cms-edit asset search --filename-match 'istockphoto-.*'
375
375
 
376
376
  # Raster/video: cms_edit_media prepare → wait → catalog → import (video: import only).
377
+ # Do not `asset upload` jpeg/png/webp/gif/mp4. Do not convert GIF/MP4 with local ffmpeg.
378
+ # Animated GIF: leave as GIF; pipeline emits gif-converted MP4 for Media mute-loop, not featuredImage.
377
379
  # SVG/PDF/Lottie: cms_edit_request_staged_upload → curl → asset upload --staged
378
380
 
379
- # Upload and create a Media wrapper in one step (--media-name defaults to asset title)
380
- cms-edit asset upload ./figure.png --with-media --media-position Middle
381
-
382
381
  # Create a Media wrapper for an existing asset (name defaults to asset title)
383
382
  cms-edit create media --asset-id <asset-id>
384
383