@se-studio/contentful-cms 3.11.2 → 3.12.0

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 (85) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/dist/cli/local-cli-allowed.d.ts +1 -1
  4. package/dist/cli/local-cli-allowed.d.ts.map +1 -1
  5. package/dist/cli/local-cli-allowed.js +1 -0
  6. package/dist/cli/local-cli-allowed.js.map +1 -1
  7. package/dist/cli/program.d.ts.map +1 -1
  8. package/dist/cli/program.js +2 -0
  9. package/dist/cli/program.js.map +1 -1
  10. package/dist/commands/patterns.d.ts +4 -0
  11. package/dist/commands/patterns.d.ts.map +1 -0
  12. package/dist/commands/patterns.js +107 -0
  13. package/dist/commands/patterns.js.map +1 -0
  14. package/dist/contentful/cda-page.d.ts +27 -0
  15. package/dist/contentful/cda-page.d.ts.map +1 -0
  16. package/dist/contentful/cda-page.js +111 -0
  17. package/dist/contentful/cda-page.js.map +1 -0
  18. package/dist/contentful/cma-user-agent.d.ts +1 -1
  19. package/dist/editor-pack/capabilities.d.ts +2 -0
  20. package/dist/editor-pack/capabilities.d.ts.map +1 -1
  21. package/dist/editor-pack/capabilities.js +4 -0
  22. package/dist/editor-pack/capabilities.js.map +1 -1
  23. package/dist/editor-pack/generate.d.ts.map +1 -1
  24. package/dist/editor-pack/generate.js +10 -0
  25. package/dist/editor-pack/generate.js.map +1 -1
  26. package/dist/generated/help-topics.d.ts +1 -1
  27. package/dist/generated/help-topics.d.ts.map +1 -1
  28. package/dist/generated/help-topics.js +2 -2
  29. package/dist/generated/help-topics.js.map +1 -1
  30. package/dist/generated/hosted-guide.d.ts +1 -1
  31. package/dist/generated/hosted-guide.d.ts.map +1 -1
  32. package/dist/generated/hosted-guide.js +1 -1
  33. package/dist/generated/hosted-guide.js.map +1 -1
  34. package/dist/generated/version.d.ts +1 -1
  35. package/dist/generated/version.js +1 -1
  36. package/dist/hosted/next/routes/health.d.ts.map +1 -1
  37. package/dist/hosted/next/routes/health.js +4 -0
  38. package/dist/hosted/next/routes/health.js.map +1 -1
  39. package/dist/mcp/tools/cms-edit.d.ts +1 -1
  40. package/dist/mcp/tools/cms-edit.d.ts.map +1 -1
  41. package/dist/mcp/tools/cms-edit.js +1 -1
  42. package/dist/mcp/tools/media.d.ts.map +1 -1
  43. package/dist/mcp/tools/media.js +4 -2
  44. package/dist/mcp/tools/media.js.map +1 -1
  45. package/dist/media-pipeline/config.d.ts +21 -0
  46. package/dist/media-pipeline/config.d.ts.map +1 -1
  47. package/dist/media-pipeline/config.js +60 -0
  48. package/dist/media-pipeline/config.js.map +1 -1
  49. package/dist/media-pipeline/index.d.ts +1 -1
  50. package/dist/media-pipeline/index.d.ts.map +1 -1
  51. package/dist/media-pipeline/index.js +1 -1
  52. package/dist/media-pipeline/index.js.map +1 -1
  53. package/dist/patterns/census.d.ts +8 -0
  54. package/dist/patterns/census.d.ts.map +1 -0
  55. package/dist/patterns/census.js +197 -0
  56. package/dist/patterns/census.js.map +1 -0
  57. package/dist/patterns/cluster.d.ts +19 -0
  58. package/dist/patterns/cluster.d.ts.map +1 -0
  59. package/dist/patterns/cluster.js +353 -0
  60. package/dist/patterns/cluster.js.map +1 -0
  61. package/dist/patterns/markdown.d.ts +3 -0
  62. package/dist/patterns/markdown.d.ts.map +1 -0
  63. package/dist/patterns/markdown.js +88 -0
  64. package/dist/patterns/markdown.js.map +1 -0
  65. package/dist/patterns/types.d.ts +70 -0
  66. package/dist/patterns/types.d.ts.map +1 -0
  67. package/dist/patterns/types.js +2 -0
  68. package/dist/patterns/types.js.map +1 -0
  69. package/dist/patterns/write.d.ts +7 -0
  70. package/dist/patterns/write.d.ts.map +1 -0
  71. package/dist/patterns/write.js +16 -0
  72. package/dist/patterns/write.js.map +1 -0
  73. package/dist/project/doctor.d.ts.map +1 -1
  74. package/dist/project/doctor.js +8 -0
  75. package/dist/project/doctor.js.map +1 -1
  76. package/docs/editor-tasks/clone-page.md +2 -0
  77. package/docs/editor-tasks/media-pipeline-prepare.md +4 -1
  78. package/docs/editor-tasks/media-reuse-and-upload.md +1 -1
  79. package/docs/help/index.md +1 -0
  80. package/docs/help/patterns.md +33 -0
  81. package/docs/mcp/e2e-test-prompt.md +1 -0
  82. package/docs/mcp/hosted-guide.md +4 -1
  83. package/package.json +1 -1
  84. package/skills/core/SKILL.md +5 -4
  85. package/skills/editor-tasks/SKILL.md +4 -2
@@ -0,0 +1,88 @@
1
+ function pct(share) {
2
+ return `${Math.round(share * 100)}%`;
3
+ }
4
+ function familyLines(family, depth) {
5
+ const indent = ' '.repeat(depth);
6
+ const heading = `${indent}- **${family.id}** (${family.kind}, n=${String(family.n)})`;
7
+ const lines = [
8
+ heading,
9
+ `${indent} - URL: \`${family.urlPattern}\``,
10
+ `${indent} - Template: ${family.template} (${pct(family.templateShare)})`,
11
+ `${indent} - Majority stack (${pct(family.majorityShare)}, ${String(family.variantCount)} variants): \`${family.majorityFingerprint}\``,
12
+ ];
13
+ if (family.skeleton.required.length > 0) {
14
+ lines.push(`${indent} - Required: ${family.skeleton.required.join(' → ')}`);
15
+ }
16
+ if (family.skeleton.optional.length > 0) {
17
+ lines.push(`${indent} - Optional: ${family.skeleton.optional.join(', ')}`);
18
+ }
19
+ if (family.cloneSlug) {
20
+ lines.push(`${indent} - Clone: \`${family.cloneSlug}\``);
21
+ }
22
+ if (family.sharedBlocks.length > 0) {
23
+ const shared = family.sharedBlocks
24
+ .slice(0, 6)
25
+ .map((block) => `${block.cmsLabel ?? block.id} (${block.type}×${String(block.n)})`)
26
+ .join('; ');
27
+ lines.push(`${indent} - Shared blocks (do not fork): ${shared}`);
28
+ }
29
+ if (family.notes.length > 0) {
30
+ lines.push(`${indent} - Flags: ${family.notes.join(', ')}`);
31
+ }
32
+ if (family.topTags && family.topTags.length > 0) {
33
+ const tags = family.topTags
34
+ .slice(0, 8)
35
+ .map((tag) => `${tag.slug} (${String(tag.n)})`)
36
+ .join(', ');
37
+ lines.push(`${indent} - Top tags: ${tags}`);
38
+ }
39
+ if (family.outliers.length > 0) {
40
+ lines.push(`${indent} - Outliers: ${family.outliers.map((s) => `\`${s}\``).join(', ')}`);
41
+ }
42
+ for (const child of family.children) {
43
+ lines.push(...familyLines(child, depth + 1));
44
+ }
45
+ return lines;
46
+ }
47
+ export function renderPagePatternsMarkdown(doc) {
48
+ const lines = [
49
+ '# Page patterns',
50
+ '',
51
+ 'Published Delivery census of how this site is actually built. Read before cloning or creating a page or article.',
52
+ '',
53
+ `- **Project:** \`${doc.projectKey}\``,
54
+ `- **Shape:** ${doc.shape}`,
55
+ `- **Generated:** ${doc.generatedAt}`,
56
+ `- **Space:** \`${doc.spaceId}\` / \`${doc.environment}\``,
57
+ '',
58
+ 'Match the URL or article type to a family. Clone `cloneSlug`. Reuse shared blocks; do not fork them.',
59
+ '',
60
+ '## Families',
61
+ '',
62
+ ];
63
+ if (doc.families.length === 0) {
64
+ lines.push('_No families detected._', '');
65
+ }
66
+ else {
67
+ for (const family of doc.families) {
68
+ lines.push(...familyLines(family, 0));
69
+ }
70
+ lines.push('');
71
+ }
72
+ if (doc.uncategorizedPages.length > 0) {
73
+ lines.push('## Uncategorized pages', '');
74
+ lines.push('| Slug | Template | Depth | Stack |');
75
+ lines.push('|------|----------|------:|-------|');
76
+ const rows = doc.uncategorizedPages.slice(0, 40);
77
+ for (const page of rows) {
78
+ const stack = page.fingerprint.replace(/\|/g, '\\|');
79
+ lines.push(`| \`${page.slug}\` | ${page.template} | ${String(page.depth)} | \`${stack}\` |`);
80
+ }
81
+ if (doc.uncategorizedPages.length > 40) {
82
+ lines.push('', `_…${String(doc.uncategorizedPages.length - 40)} more_`);
83
+ }
84
+ lines.push('');
85
+ }
86
+ return `${lines.join('\n')}\n`;
87
+ }
88
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/patterns/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ export declare const PAGE_PATTERNS_VERSION: 1;
2
+ export type PatternKind = 'page-prefix' | 'article-type' | 'location' | 'template-thin';
3
+ export type PatternNote = 'empty-body' | 'template-owned' | 'low-majority-campaign' | 'unique-compositions';
4
+ export type SiteShape = 'hierarchical' | 'flat' | 'mixed';
5
+ export interface PatternSharedBlock {
6
+ id: string;
7
+ cmsLabel: string | null;
8
+ type: string;
9
+ n: number;
10
+ }
11
+ export interface PatternSkeleton {
12
+ required: string[];
13
+ optional: string[];
14
+ }
15
+ export interface PatternFamily {
16
+ id: string;
17
+ kind: PatternKind;
18
+ urlPattern: string;
19
+ n: number;
20
+ template: string;
21
+ templateShare: number;
22
+ skeleton: PatternSkeleton;
23
+ majorityFingerprint: string;
24
+ majorityShare: number;
25
+ variantCount: number;
26
+ cloneSlug: string | null;
27
+ sharedBlocks: PatternSharedBlock[];
28
+ outliers: string[];
29
+ children: PatternFamily[];
30
+ notes: PatternNote[];
31
+ topTags?: {
32
+ slug: string;
33
+ n: number;
34
+ }[];
35
+ }
36
+ export interface UncategorizedPage {
37
+ slug: string;
38
+ template: string;
39
+ fingerprint: string;
40
+ depth: number;
41
+ }
42
+ export interface PagePatternsDocument {
43
+ version: typeof PAGE_PATTERNS_VERSION;
44
+ generatedAt: string;
45
+ spaceId: string;
46
+ environment: string;
47
+ projectKey: string;
48
+ shape: SiteShape;
49
+ families: PatternFamily[];
50
+ uncategorizedPages: UncategorizedPage[];
51
+ }
52
+ export interface CensusStackMember {
53
+ id: string;
54
+ slug: string;
55
+ hidden: boolean;
56
+ template: string;
57
+ stack: string[];
58
+ stackIds: string[];
59
+ blockLabels: Record<string, string>;
60
+ }
61
+ export interface CensusArticle extends CensusStackMember {
62
+ articleTypeSlug: string;
63
+ tagSlugs: string[];
64
+ }
65
+ export interface PatternCensus {
66
+ pages: CensusStackMember[];
67
+ articles: CensusArticle[];
68
+ locations: CensusStackMember[];
69
+ }
70
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/patterns/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,EAAG,CAAU,CAAC;AAEhD,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,cAAc,GAAG,UAAU,GAAG,eAAe,CAAC;AAExF,MAAM,MAAM,WAAW,GACnB,YAAY,GACZ,gBAAgB,GAChB,uBAAuB,GACvB,qBAAqB,CAAC;AAE1B,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,eAAe,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,kBAAkB,EAAE,CAAC;IACnC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,qBAAqB,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACtD,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,SAAS,EAAE,iBAAiB,EAAE,CAAC;CAChC"}
@@ -0,0 +1,2 @@
1
+ export const PAGE_PATTERNS_VERSION = 1;
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/patterns/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAU,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { PagePatternsDocument } from './types.js';
2
+ export declare function writePagePatternsFiles(outDir: string, doc: PagePatternsDocument): {
3
+ jsonPath: string;
4
+ mdPath: string;
5
+ };
6
+ export declare function readPagePatternsJson(filePath: string): PagePatternsDocument;
7
+ //# sourceMappingURL=write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/patterns/write.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,oBAAoB,GACxB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAOtC;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,CAG3E"}
@@ -0,0 +1,16 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { renderPagePatternsMarkdown } from './markdown.js';
4
+ export function writePagePatternsFiles(outDir, doc) {
5
+ fs.mkdirSync(outDir, { recursive: true });
6
+ const jsonPath = path.join(outDir, 'page-patterns.json');
7
+ const mdPath = path.join(outDir, 'page-patterns.md');
8
+ fs.writeFileSync(jsonPath, `${JSON.stringify(doc, null, 2)}\n`);
9
+ fs.writeFileSync(mdPath, renderPagePatternsMarkdown(doc));
10
+ return { jsonPath, mdPath };
11
+ }
12
+ export function readPagePatternsJson(filePath) {
13
+ const raw = fs.readFileSync(filePath, 'utf8');
14
+ return JSON.parse(raw);
15
+ }
16
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/patterns/write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAG3D,MAAM,UAAU,sBAAsB,CACpC,MAAc,EACd,GAAyB;IAEzB,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACrD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAChE,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAyB,CAAC;AACjD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/project/doctor.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOjD,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE1D,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAiDD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,aAAa,EAAE,CAmJ7F"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/project/doctor.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOjD,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE1D,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAiDD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,aAAa,EAAE,CA8J7F"}
@@ -121,6 +121,14 @@ export function runProjectDoctor(configPath, project) {
121
121
  message: 'editor-pack has no articles.md — regenerate after adding articles playbook',
122
122
  });
123
123
  }
124
+ if (!hasSiteHandbook(repoRoot, project.projectKey, 'page-patterns.md') &&
125
+ !fs.existsSync(path.join(packDir, 'page-patterns.md'))) {
126
+ findings.push({
127
+ severity: 'warning',
128
+ code: 'page_patterns_missing',
129
+ message: `Add live family stacks with: cms-edit patterns generate --project-config ${resolvedConfig}`,
130
+ });
131
+ }
124
132
  if (!hasSiteHandbook(repoRoot, project.projectKey, 'pages.md')) {
125
133
  findings.push({
126
134
  severity: 'info',
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/project/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/project/doctor.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,8 @@
12
12
 
13
13
  ## Prerequisites
14
14
 
15
+ - Read `cms-edit://customer/page-patterns` and match the URL to a family
16
+ - Clone that family's `cloneSlug` unless the user named another source
15
17
  - Identify source page slug and target slug/title
16
18
  - Read `cms-edit://customer/components-index`
17
19
 
@@ -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
 
@@ -33,6 +33,7 @@ Available topics for `cms-edit help <topic>`:
33
33
  | `fields-collection` | All fields on a `collection` entry |
34
34
  | `fields-taxonomy` | All fields on `tagType`, `articleType`, and `tag` entries |
35
35
  | `index-sync` | Build and use the local content index (CDA sync) |
36
+ | `patterns` | Census published page/article stacks (Delivery API) |
36
37
  | `asset-review` | Visual asset quality review (filename, alt, size, dimensions) |
37
38
  | `lookup` | Flat flags for `open`, `resolve`, and `nav open` |
38
39
 
@@ -0,0 +1,33 @@
1
+ # Help: patterns
2
+
3
+ Census **published** page and article construction from the Contentful Delivery API. Writes `page-patterns.json` and `page-patterns.md` for editor-pack and agents.
4
+
5
+ Local CLI only (same class as `editor-pack`). Hosted agents **read** `cms-edit://customer/page-patterns` after the pack is regenerated — they do not run generate.
6
+
7
+ ## Commands
8
+
9
+ ```bash
10
+ cms-edit patterns generate --project-config cms-edit/<site>/project.json
11
+ cms-edit patterns show --project-config cms-edit/<site>/project.json
12
+ ```
13
+
14
+ Requires `CONTENTFUL_ACCESS_TOKEN` (Delivery token) in the app `.env.local`. Uses `spaceId` / `environment` from `project.json`.
15
+
16
+ Default output: `docs/cms-editor/<projectKey>/`. Then:
17
+
18
+ ```bash
19
+ cms-edit editor-pack generate --project-config cms-edit/<site>/project.json
20
+ ```
21
+
22
+ ## What it captures
23
+
24
+ - Slug-prefix page families (nested splits when a child prefix has ≥3 pages)
25
+ - Article types (empty body vs chained rich text)
26
+ - Location entries (even when `content` is empty)
27
+ - Required/optional stack types, shared block IDs, clone slug
28
+
29
+ Does **not** rewrite brand playbooks. Structure only.
30
+
31
+ ## Agents
32
+
33
+ After the pack includes `page-patterns.md`, read `cms-edit://customer/page-patterns` before `task-clone-page` or creating a page/article in a known family.
@@ -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
 
@@ -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.2",
3
+ "version": "3.12.0",
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",
@@ -7,7 +7,9 @@ description: "Edit Contentful drafts via hosted cms-edit MCP (open → snapshot
7
7
 
8
8
  Use this skill when you need to read or edit content in Contentful using **hosted cms-edit MCP** (`cms_edit` with an `args` array). Command names match the old CLI (`open` → `snapshot` → `read` → `set`/`rtf` → `diff` → `save`).
9
9
 
10
- **Do not** run the local `cms-edit` binary for content. It refuses `open`, `save`, `set`, and other content commands. Local CLI is only for `host`, `editor-pack`, `project`, `schema`, and `guide`.
10
+ **Do not** run the local `cms-edit` binary for content. It refuses `open`, `save`, `set`, and other content commands. Local CLI is only for `host`, `editor-pack`, `patterns`, `project`, `schema`, and `guide`.
11
+
12
+ **Page patterns (local):** `cms-edit patterns generate --project-config cms-edit/<site>/project.json` writes live family stacks from the Delivery API. Hosted agents read `cms-edit://customer/page-patterns` after editor-pack generate.
11
13
 
12
14
  **Before editing:** use skill **`contentful-cms-editor-tasks`** to read `tasks-index` and the matching capability playbook for this site (hosted MCP or local `cms-edit/<site>/editor-pack/`).
13
15
 
@@ -374,11 +376,10 @@ cms-edit asset search --filename istockphoto-123.jpg
374
376
  cms-edit asset search --filename-match 'istockphoto-.*'
375
377
 
376
378
  # Raster/video: cms_edit_media prepare → wait → catalog → import (video: import only).
379
+ # Do not `asset upload` jpeg/png/webp/gif/mp4. Do not convert GIF/MP4 with local ffmpeg.
380
+ # Animated GIF: leave as GIF; pipeline emits gif-converted MP4 for Media mute-loop, not featuredImage.
377
381
  # SVG/PDF/Lottie: cms_edit_request_staged_upload → curl → asset upload --staged
378
382
 
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
383
  # Create a Media wrapper for an existing asset (name defaults to asset title)
383
384
  cms-edit create media --asset-id <asset-id>
384
385
 
@@ -13,8 +13,9 @@ Use this skill **before any Contentful edit** to pick the right capability playb
13
13
  2. **capabilities** — what content types and bulk mechanisms exist
14
14
  3. **checklist** — pre-flight checks
15
15
  4. **overview** + **routing** — site rules and URL shapes
16
- 5. **task-*** playbook — steps, confirmation gates, out-of-scope
17
- 6. **components-index** — when creating or editing page content
16
+ 5. **page-patterns** — live slug/article-type families, clone slugs, shared blocks (`cms-edit://customer/page-patterns`)
17
+ 6. **task-*** playbook — steps, confirmation gates, out-of-scope
18
+ 7. **components-index** — when creating or editing page content
18
19
 
19
20
  ## Hosted (Claude Integrations + OAuth)
20
21
 
@@ -47,6 +48,7 @@ Minimum reads:
47
48
  - `capabilities.json`
48
49
  - `tasks-index.md`
49
50
  - `checklist.md`
51
+ - `page-patterns.md` (match the URL or article type to a family before clone)
50
52
  - Matching `task-*.md` for the user's intent
51
53
 
52
54
  Then use **`contentful-cms-core`** for `cms-edit` CLI commands.