@se-studio/contentful-cms 3.2.1 → 3.4.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 (104) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +4 -2
  3. package/dist/cli/program.d.ts.map +1 -1
  4. package/dist/cli/program.js +2 -0
  5. package/dist/cli/program.js.map +1 -1
  6. package/dist/commands/add.d.ts.map +1 -1
  7. package/dist/commands/add.js +4 -1
  8. package/dist/commands/add.js.map +1 -1
  9. package/dist/commands/batch-assignments.d.ts +4 -4
  10. package/dist/commands/batch-assignments.d.ts.map +1 -1
  11. package/dist/commands/batch-assignments.js +42 -5
  12. package/dist/commands/batch-assignments.js.map +1 -1
  13. package/dist/commands/batch.d.ts.map +1 -1
  14. package/dist/commands/batch.js +36 -17
  15. package/dist/commands/batch.js.map +1 -1
  16. package/dist/commands/media.d.ts +4 -0
  17. package/dist/commands/media.d.ts.map +1 -0
  18. package/dist/commands/media.js +124 -0
  19. package/dist/commands/media.js.map +1 -0
  20. package/dist/commands/open.d.ts.map +1 -1
  21. package/dist/commands/open.js +40 -4
  22. package/dist/commands/open.js.map +1 -1
  23. package/dist/commands/set.d.ts.map +1 -1
  24. package/dist/commands/set.js +148 -27
  25. package/dist/commands/set.js.map +1 -1
  26. package/dist/contentful/set-field-schema.d.ts +5 -0
  27. package/dist/contentful/set-field-schema.d.ts.map +1 -1
  28. package/dist/contentful/set-field-schema.js +30 -1
  29. package/dist/contentful/set-field-schema.js.map +1 -1
  30. package/dist/generated/version.d.ts +1 -1
  31. package/dist/generated/version.js +1 -1
  32. package/dist/hosted/index.d.ts +1 -0
  33. package/dist/hosted/index.d.ts.map +1 -1
  34. package/dist/hosted/index.js +1 -0
  35. package/dist/hosted/index.js.map +1 -1
  36. package/dist/hosted/next/routes/mcp.d.ts.map +1 -1
  37. package/dist/hosted/next/routes/mcp.js +3 -0
  38. package/dist/hosted/next/routes/mcp.js.map +1 -1
  39. package/dist/mcp/prompts/onboarding.d.ts.map +1 -1
  40. package/dist/mcp/prompts/onboarding.js +11 -8
  41. package/dist/mcp/prompts/onboarding.js.map +1 -1
  42. package/dist/mcp/server.d.ts.map +1 -1
  43. package/dist/mcp/server.js +2 -0
  44. package/dist/mcp/server.js.map +1 -1
  45. package/dist/mcp/tools/cms-edit.d.ts +1 -1
  46. package/dist/mcp/tools/cms-edit.d.ts.map +1 -1
  47. package/dist/mcp/tools/cms-edit.js +14 -1
  48. package/dist/mcp/tools/cms-edit.js.map +1 -1
  49. package/dist/mcp/tools/media.d.ts +4 -0
  50. package/dist/mcp/tools/media.d.ts.map +1 -0
  51. package/dist/mcp/tools/media.js +138 -0
  52. package/dist/mcp/tools/media.js.map +1 -0
  53. package/dist/media-pipeline/actions.d.ts +30 -0
  54. package/dist/media-pipeline/actions.d.ts.map +1 -0
  55. package/dist/media-pipeline/actions.js +257 -0
  56. package/dist/media-pipeline/actions.js.map +1 -0
  57. package/dist/media-pipeline/client.d.ts +67 -0
  58. package/dist/media-pipeline/client.d.ts.map +1 -0
  59. package/dist/media-pipeline/client.js +75 -0
  60. package/dist/media-pipeline/client.js.map +1 -0
  61. package/dist/media-pipeline/config.d.ts +17 -0
  62. package/dist/media-pipeline/config.d.ts.map +1 -0
  63. package/dist/media-pipeline/config.js +52 -0
  64. package/dist/media-pipeline/config.js.map +1 -0
  65. package/dist/media-pipeline/import.d.ts +19 -0
  66. package/dist/media-pipeline/import.d.ts.map +1 -0
  67. package/dist/media-pipeline/import.js +198 -0
  68. package/dist/media-pipeline/import.js.map +1 -0
  69. package/dist/media-pipeline/index.d.ts +6 -0
  70. package/dist/media-pipeline/index.d.ts.map +1 -0
  71. package/dist/media-pipeline/index.js +6 -0
  72. package/dist/media-pipeline/index.js.map +1 -0
  73. package/dist/media-pipeline/job-store.d.ts +41 -0
  74. package/dist/media-pipeline/job-store.d.ts.map +1 -0
  75. package/dist/media-pipeline/job-store.js +172 -0
  76. package/dist/media-pipeline/job-store.js.map +1 -0
  77. package/dist/media-pipeline/limits.d.ts +14 -0
  78. package/dist/media-pipeline/limits.d.ts.map +1 -0
  79. package/dist/media-pipeline/limits.js +14 -0
  80. package/dist/media-pipeline/limits.js.map +1 -0
  81. package/dist/media-pipeline/log.d.ts +3 -0
  82. package/dist/media-pipeline/log.d.ts.map +1 -0
  83. package/dist/media-pipeline/log.js +12 -0
  84. package/dist/media-pipeline/log.js.map +1 -0
  85. package/dist/media-pipeline/validate.d.ts +18 -0
  86. package/dist/media-pipeline/validate.d.ts.map +1 -0
  87. package/dist/media-pipeline/validate.js +38 -0
  88. package/dist/media-pipeline/validate.js.map +1 -0
  89. package/dist/output/print.d.ts +2 -2
  90. package/dist/output/print.d.ts.map +1 -1
  91. package/dist/output/print.js +3 -3
  92. package/dist/output/print.js.map +1 -1
  93. package/dist/runtime/context.d.ts +5 -0
  94. package/dist/runtime/context.d.ts.map +1 -1
  95. package/dist/runtime/context.js.map +1 -1
  96. package/dist/session/dirty.d.ts +20 -0
  97. package/dist/session/dirty.d.ts.map +1 -0
  98. package/dist/session/dirty.js +44 -0
  99. package/dist/session/dirty.js.map +1 -0
  100. package/docs/editor-tasks/media-pipeline-prepare.md +65 -69
  101. package/docs/help/batch.md +29 -13
  102. package/docs/help/index.md +5 -1
  103. package/docs/help/workflow.md +47 -0
  104. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"print.js","sourceRoot":"","sources":["../../src/output/print.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,UAAU,WAAW,CAAC,MAAmB;IAC7C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW;YACd,OAAO,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACjC,KAAK,OAAO;YACV,OAAO,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5B,KAAK,SAAS;YACZ,OAAO,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAChC,KAAK,SAAS;YACZ,OAAO,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,IAAI,UAAU,EAAE,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,IAAI,UAAU,EAAE,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,IAAI,UAAU,EAAE,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;IACpC,CAAC;AACH,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAE,GAAW;IACxC,OAAO,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"print.js","sourceRoot":"","sources":["../../src/output/print.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import type { CmsEditConfig } from '../config/types.js';
3
3
  import type { IndexCacheStore } from '../index/cache-store.js';
4
+ import type { MediaPipelineJobStore } from '../media-pipeline/job-store.js';
4
5
  import type { SessionStore } from '../session/session-store.js';
5
6
  import type { StagedUploadStore } from '../staged-upload/store.js';
6
7
  export interface ContentfulUserIdentity {
@@ -18,6 +19,10 @@ export interface CmsEditRuntimeContext {
18
19
  user?: ContentfulUserIdentity;
19
20
  /** Staged file uploads for hosted asset upload (Redis). */
20
21
  stagedUploadStore?: StagedUploadStore;
22
+ /** Media pipeline job ownership + rate limits (Redis on hosted). */
23
+ mediaPipelineJobStore?: MediaPipelineJobStore;
24
+ /** Hosted project key (e.g. se2026) for media job bindings / logs. */
25
+ projectKey?: string;
21
26
  }
22
27
  export declare const cmsEditContext: AsyncLocalStorage<CmsEditRuntimeContext>;
23
28
  export declare function getRuntimeContext(): CmsEditRuntimeContext | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,sEAAsE;IACtE,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,qEAAqE;IACrE,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,2EAA2E;IAC3E,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,gEAAgE;IAChE,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,eAAO,MAAM,cAAc,0CAAiD,CAAC;AAE7E,wBAAgB,iBAAiB,IAAI,qBAAqB,GAAG,SAAS,CAErE;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,OAAO,EAAE,qBAAqB,EAC9B,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvB,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAEhB"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,sEAAsE;IACtE,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,qEAAqE;IACrE,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,2EAA2E;IAC3E,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,gEAAgE;IAChE,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,oEAAoE;IACpE,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAC9C,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,0CAAiD,CAAC;AAE7E,wBAAgB,iBAAiB,IAAI,qBAAqB,GAAG,SAAS,CAErE;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,OAAO,EAAE,qBAAqB,EAC9B,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvB,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAEhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAwBrD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,iBAAiB,EAAyB,CAAC;AAE7E,MAAM,UAAU,iBAAiB;IAC/B,OAAO,cAAc,CAAC,QAAQ,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,OAA8B,EAC9B,EAAwB;IAExB,OAAO,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AA6BrD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,iBAAiB,EAAyB,CAAC;AAE7E,MAAM,UAAU,iBAAiB;IAC/B,OAAO,cAAc,CAAC,QAAQ,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,OAA8B,EAC9B,EAAwB;IAExB,OAAO,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { SessionState } from './state.js';
2
+ /** True when the session has staged field edits or pending deletions. */
3
+ export declare function isSessionDirty(session: SessionState): boolean;
4
+ export interface DirtyOpenErrorPayload {
5
+ code: 'SESSION_DIRTY';
6
+ unsavedChanges: number;
7
+ pendingDeletions: number;
8
+ rootEntryId: string;
9
+ rootEntryType: string;
10
+ actions: string[];
11
+ }
12
+ export interface DirtyOpenError {
13
+ message: string;
14
+ payload: DirtyOpenErrorPayload;
15
+ }
16
+ /**
17
+ * Agent-facing hard-fail when `open` would replace a session that still has local work.
18
+ */
19
+ export declare function formatDirtyOpenError(session: SessionState): DirtyOpenError;
20
+ //# sourceMappingURL=dirty.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dirty.d.ts","sourceRoot":"","sources":["../../src/session/dirty.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAE7D;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,eAAe,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,qBAAqB,CAAC;CAChC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG,cAAc,CAsC1E"}
@@ -0,0 +1,44 @@
1
+ /** True when the session has staged field edits or pending deletions. */
2
+ export function isSessionDirty(session) {
3
+ return session.modifiedEntryIds.length > 0 || session.pendingDeletions.length > 0;
4
+ }
5
+ /**
6
+ * Agent-facing hard-fail when `open` would replace a session that still has local work.
7
+ */
8
+ export function formatDirtyOpenError(session) {
9
+ const unsavedChanges = session.modifiedEntryIds.length;
10
+ const pendingDeletions = session.pendingDeletions.length;
11
+ const rootEntryId = session.rootEntryId;
12
+ const rootEntryType = session.rootEntryType;
13
+ const actions = [
14
+ 'cms-edit open --resume',
15
+ 'cms-edit diff',
16
+ 'cms-edit save',
17
+ 'cms-edit discard',
18
+ 'cms-edit open --overwrite --id <entryId>',
19
+ ];
20
+ const message = [
21
+ `Cannot open: session has ${unsavedChanges} unsaved entry change(s) and ${pendingDeletions} pending deletion(s).`,
22
+ `Root: ${rootEntryId} (${rootEntryType}) — continue this work, or explicitly abandon it.`,
23
+ '',
24
+ ' Continue current work: cms-edit open --resume',
25
+ ' Review changes: cms-edit diff',
26
+ ' Save drafts: cms-edit save',
27
+ ' Abandon all staged: cms-edit discard',
28
+ ' Abandon and open new: cms-edit open --overwrite --id <entryId>',
29
+ '',
30
+ 'Do not re-run open without --overwrite while changes are staged — that previously wiped session field edits.',
31
+ ].join('\n');
32
+ return {
33
+ message,
34
+ payload: {
35
+ code: 'SESSION_DIRTY',
36
+ unsavedChanges,
37
+ pendingDeletions,
38
+ rootEntryId,
39
+ rootEntryType,
40
+ actions,
41
+ },
42
+ };
43
+ }
44
+ //# sourceMappingURL=dirty.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dirty.js","sourceRoot":"","sources":["../../src/session/dirty.ts"],"names":[],"mappings":"AAEA,yEAAyE;AACzE,MAAM,UAAU,cAAc,CAAC,OAAqB;IAClD,OAAO,OAAO,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;AACpF,CAAC;AAgBD;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAqB;IACxD,MAAM,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC;IACvD,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC;IACzD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACxC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAE5C,MAAM,OAAO,GAAG;QACd,wBAAwB;QACxB,eAAe;QACf,eAAe;QACf,kBAAkB;QAClB,0CAA0C;KAC3C,CAAC;IAEF,MAAM,OAAO,GAAG;QACd,4BAA4B,cAAc,gCAAgC,gBAAgB,uBAAuB;QACjH,SAAS,WAAW,KAAK,aAAa,mDAAmD;QACzF,EAAE;QACF,kDAAkD;QAClD,yCAAyC;QACzC,yCAAyC;QACzC,4CAA4C;QAC5C,oEAAoE;QACpE,EAAE;QACF,8GAA8G;KAC/G,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO;QACL,OAAO;QACP,OAAO,EAAE;YACP,IAAI,EAAE,eAAe;YACrB,cAAc;YACd,gBAAgB;YAChB,WAAW;YACX,aAAa;YACb,OAAO;SACR;KACF,CAAC;AACJ,CAAC"}
@@ -1,8 +1,8 @@
1
1
  # Capability: Media pipeline — prepare pack
2
2
 
3
- Normalize a **folder of designer masters** (or inline files) into short-lived **public HTTPS URLs** under cms-edit upload limits, then import into Contentful with reuse-first.
3
+ Normalize a **folder of designer masters** into short-lived **public HTTPS URLs** under cms-edit upload limits, then import into Contentful with reuse-first.
4
4
 
5
- **Never** expect this service to write Contentful. Pipeline → ready URLs only. **cms-edit** owns assets/entries.
5
+ **Never** expect the media pipeline service to write Contentful. Pipeline → ready URLs only. **cms-edit** owns assets/entries.
6
6
 
7
7
  ## Intent phrases
8
8
 
@@ -19,13 +19,14 @@ Normalize a **folder of designer masters** (or inline files) into short-lived **
19
19
 
20
20
  ## Prerequisites
21
21
 
22
- - Media pipeline base URL (ops default for SE Studio: `https://se-media-pipeline.vercel.app`)
23
- - API bearer key (ops secret — e.g. env `MEDIA_PIPELINE_API_KEY` or site runbook; never invent)
24
- - Tenant id: `se` | `om1` | … (explicit; never infer only from Drive URL)
25
- - Drive folder **shared Viewer** with pipeline service account
22
+ - Hosted cms-edit with media pipeline **configured on the host** (ops env):
23
+ - `MEDIA_PIPELINE_BASE_URL`
24
+ - `MEDIA_PIPELINE_SERVICE_KEY` (server-only — **never ask the agent/user for this**)
25
+ - `MEDIA_PIPELINE_TENANT` (e.g. `se`, not the cms-edit projectKey)
26
+ - Drive folder shared **Viewer** with pipeline service account
26
27
  `media-pipeline-reader@se-media-pipeline.iam.gserviceaccount.com`
27
- (or “anyone with the link” if using API-key-only mode)
28
- - Profile default: `case-study-v1` (images ≤ ~3.5MB, videos H.264 mp4 ≤ ~8MB)
28
+ (or “anyone with the link” if using API-key Drive mode on the pipeline)
29
+ - Profile default: `case-study-v1`
29
30
 
30
31
  ## When to use
31
32
 
@@ -35,94 +36,89 @@ Normalize a **folder of designer masters** (or inline files) into short-lived **
35
36
  | Single small image already in library | `task-media-reuse-and-upload` only |
36
37
  | Masters already under limits and catalogued | Reuse search only |
37
38
 
38
- ## Steps
39
+ ## Steps (agent — single auth)
39
40
 
40
- ### 1. Confirm job inputs
41
+ ### 1. Prepare
41
42
 
42
- 1. Tenant (`se`, `om1`, …)
43
- 2. Profile (`case-study-v1` unless overridden)
44
- 3. Source:
45
- - **Preferred:** `google_drive_folder` + folder URL
46
- - **Dev/test:** `inline_files` with base64 (small files only)
47
- 4. Optional: `ttlHours` (1–24, default 24), `namingPrefix` (defaults from tenant)
48
-
49
- ### 2. Start the pack job
50
-
51
- ```http
52
- POST {MEDIA_PIPELINE_BASE}/api/v1/jobs
53
- Authorization: Bearer {MEDIA_PIPELINE_API_KEY}
54
- Content-Type: application/json
43
+ Call MCP tool **`cms_edit_media`**:
55
44
 
45
+ ```json
56
46
  {
57
- "tenant": "se",
58
- "profile": "case-study-v1",
59
- "source": {
60
- "type": "google_drive_folder",
61
- "url": "https://drive.google.com/drive/folders/…"
62
- },
63
- "options": { "ttlHours": 24 }
47
+ "action": "prepare",
48
+ "driveFolderUrl": "https://drive.google.com/drive/folders/…",
49
+ "profile": "case-study-v1"
64
50
  }
65
51
  ```
66
52
 
67
- Expect **202** with `jobId`, `runId`, `statusUrl` / poll path.
53
+ CLI: `cms-edit media prepare --drive-folder "https://drive.google.com/drive/folders/…"`
54
+
55
+ Expect `{ ok: true, jobId, status: "queued", pollHint }`.
56
+
57
+ If `{ ok: false, code: "pipeline_unconfigured" }` → host ops must set env vars. **Do not** ask the user for a pipeline API key.
58
+
59
+ ### 2. Wait / status
60
+
61
+ ```json
62
+ { "action": "wait", "jobId": "<jobId>" }
63
+ ```
68
64
 
69
- ### 3. Poll until terminal
65
+ or
70
66
 
71
- ```http
72
- GET {MEDIA_PIPELINE_BASE}/api/v1/jobs/{jobId}?tenant={tenant}
73
- Authorization: Bearer {MEDIA_PIPELINE_API_KEY}
67
+ ```json
68
+ { "action": "status", "jobId": "<jobId>" }
74
69
  ```
75
70
 
76
71
  Statuses: `queued` → `running` → `succeeded` | `partial` | `failed`.
77
72
 
78
73
  - **succeeded** — all files ready
79
- - **partial** — some ready; `gaps[]` lists failures (e.g. quality floor)
74
+ - **partial** — some ready; `gaps[]` lists failures
80
75
  - **failed** — nothing usable; stop and report gaps
81
76
 
82
- **Do not** invent assets for gaps. Carry gaps into source-readiness / GO-WITH-GAPS.
77
+ **Do not** invent assets for gaps.
83
78
 
84
- ### 4. Map pack → Contentful (reuse-first)
85
-
86
- For **each** ready asset in `assets[]`:
87
-
88
- 1. `cms_edit ["index", "sync"]` once per session if catalog may be stale
89
- 2. Search: `asset search` / `--filename-match` using `fileName` or source stem
90
- 3. If no match: **prefer URL upload** (ready URLs are already under limits):
79
+ ### 3. Catalog
91
80
 
81
+ ```json
82
+ { "action": "catalog", "jobId": "<jobId>" }
92
83
  ```
93
- cms_edit ["asset", "upload", "--url", "<assets[i].url>", "--mime", "<mime>", "--file-name", "<fileName>", "--title", "<titleDraft>", "--if-exists-by-filename"]
94
- ```
95
84
 
96
- Hosted MCP: `--url` is preferred for pipeline packs. Staged upload only if URL fetch fails (then download is unnecessary — pipeline already normalized).
85
+ Each asset includes:
86
+
87
+ | Field | Use |
88
+ |-------|-----|
89
+ | `readyUrl` | `asset upload --url` into Contentful |
90
+ | `previewUrl` / `posterUrl` | Agent vision for **title / fileName / alt** (when present) |
91
+ | `altDraft` / `titleDraft` | Filename seeds only — improve before save |
97
92
 
98
- 4. Set alt / description from `altDraft` when the site workflow requires it (`asset set` / asset fields per site)
99
- 5. Create **Media** wrappers only when needed; **reuse** existing Media entries by asset id
100
- 6. Record map: `sourceName` → `{ assetId, mediaId?, readyUrl }` for the article/page build
93
+ ### 4. Import into Contentful (reuse-first)
101
94
 
102
- ### 5. Hand off to structure build
95
+ After drafting titles/alts from **previewUrl** / **posterUrl**:
103
96
 
104
- Return to:
97
+ ```json
98
+ {
99
+ "action": "import",
100
+ "jobId": "<jobId>",
101
+ "withMedia": true,
102
+ "overrides": [
103
+ { "sourceName": "OM1_Hero.jpg", "title": "OM1 hero", "alt": "…" }
104
+ ]
105
+ }
106
+ ```
105
107
 
106
- - `task-create-from-document` / `task-create-article` / customer case-study task
107
- - Soft-proof component order with **real** asset/media ids in the plan
108
+ Optional: `"dryRun": true` to preview the map without writing.
108
109
 
109
- ## Confirmation gates
110
+ CLI: `cms-edit media import --job <id> [--dry-run] [--with-media] [--overrides-json '[…]']`
110
111
 
111
- 1. Report pipeline `status` + asset count + `gaps` before CMS uploads
112
- 2. Report reuse hits vs new uploads
113
- 3. Do not start multi-block article create until the pack map is complete (or gaps accepted as GO-WITH-GAPS)
112
+ Import:
114
113
 
115
- ## Out of scope
114
+ 1. Searches existing assets by fileName
115
+ 2. Else uploads from `readyUrl` as the authenticated Contentful user
116
+ 3. Returns `map: { sourceName → { assetId, mediaId?, … } }` for page build
116
117
 
117
- - Contentful publish
118
- - Copy rewrite
119
- - Pipeline writing CMA (forbidden permanently)
120
- - Video/image creative edits beyond normalize
118
+ Manual `asset upload --url` remains available for one-offs.
121
119
 
122
- ## Related resources
120
+ ### Hardening notes (for agents)
123
121
 
124
- - `task-media-reuse-and-upload`
125
- - `task-source-readiness-review`
126
- - `task-create-from-document`
127
- - `task-create-article`
128
- - `task-preview-verify`
122
+ - Jobs are **owned by the OAuth user** who prepared them — you cannot poll another user’s `jobId`.
123
+ - Rate limits apply (prepares/hour, concurrent jobs).
124
+ - Never document or request `MEDIA_PIPELINE_API_KEY` in chat.
@@ -1,8 +1,22 @@
1
1
  # Batch edit by entry ID
2
2
 
3
- Edit multiple unrelated Contentful entries without opening a page tree. Useful for link variant sweeps, navigation item tweaks, and other standalone entry updates.
3
+ Edit multiple Contentful entries by ID with scalar field updates. Useful for link variant sweeps, media flags (`autoplay`/`loop`), navigation tweaks, and other standalone updates.
4
4
 
5
- Batch commands use session name **`batch`** by default (override with `--session`). Page sessions from `cms-edit open` are not affected.
5
+ ## Sessions
6
+
7
+ | Context | What happens |
8
+ |---------|----------------|
9
+ | Default CLI (`--session` omitted) | Uses session name **`batch`** (does not touch a separate page session) |
10
+ | Page session already open (e.g. MCP `_mcp`) | `batch set` **stages into that page session** — same `diff` / `save` as article work. Do **not** re-`open`. Do **not** `batch discard` (use `cms-edit discard` only if abandoning everything). |
11
+ | Explicit isolation | `cms-edit --session link-sweep batch set …` |
12
+
13
+ You can also stay on the page session without `batch`:
14
+
15
+ ```bash
16
+ cms-edit set <entryId>:autoplay=true <entryId>:loop=true
17
+ # or
18
+ cms-edit set <entryId> autoplay true
19
+ ```
6
20
 
7
21
  ## Workflow
8
22
 
@@ -16,17 +30,25 @@ cms-edit batch diff
16
30
  # Write all changes as drafts (single save)
17
31
  cms-edit batch save
18
32
 
19
- # Or discard without saving
33
+ # Or discard without saving (pure batch sessions only)
20
34
  cms-edit batch discard
21
35
  ```
22
36
 
37
+ Mid-page (MCP / open article session):
38
+
39
+ ```bash
40
+ cms-edit batch set 5uMh54rIsJRFRQSXDuJiG:autoplay=true
41
+ cms-edit diff
42
+ cms-edit save
43
+ ```
44
+
23
45
  ## Token format
24
46
 
25
47
  ```
26
48
  <entryId>:<fieldId>=<value>
27
49
  ```
28
50
 
29
- - **entryId** — 22-character Contentful entry ID (no `@` prefix)
51
+ - **entryId** — Contentful entry ID (alphanumeric, optional `_`/`-`, length 1–64; **not** fixed at 22 characters)
30
52
  - **fieldId** — field name on that entry's content type
31
53
  - **value** — literal token (no shell quotes needed for simple strings). Coercion follows the field type from Contentful:
32
54
  - **Symbol** / **Text** — always stored as strings (e.g. `order=42` stays `"42"`)
@@ -39,6 +61,7 @@ Examples:
39
61
 
40
62
  ```bash
41
63
  cms-edit batch set abcdefghijklmnopqrstuv:variant=link
64
+ cms-edit batch set 5uMh54rIsJRFRQSXDuJiG:autoplay=true
42
65
  cms-edit batch set abcdefghijklmnopqrstuv:cmsLabel=Footer CTA
43
66
  ```
44
67
 
@@ -60,7 +83,7 @@ When a page is already open, prefer `cms-edit links set @cN <index> variant link
60
83
 
61
84
  Field types and enum validations are loaded from the Contentful Management API. Results are cached:
62
85
 
63
- - In the **batch session file** (`contentTypes` on the session) so `batch set` → `batch save` reuse schema without extra API calls
86
+ - In the **session file** (`contentTypes` on the session) so `batch set` → save reuse schema without extra API calls
64
87
  - On disk at `~/.contentful-cms/content-types/<spaceId>/<environment>/` (24-hour TTL)
65
88
 
66
89
  ## v1 limits
@@ -68,11 +91,4 @@ Field types and enum validations are loaded from the Contentful Management API.
68
91
  - **Scalar fields only** — no rich text, entry links, asset links, or link arrays
69
92
  - **Draft-only** — same as `cms-edit save`; never publishes
70
93
  - **No cross-entry link arrays** — use page session + `cms-edit set --links` for parent arrays
71
- - **Partial save on failure** — if one entry fails during `batch save`, earlier entries may already be saved; the CLI lists failures and reminds you to run `cms-edit batch diff` for remaining changes
72
-
73
- ## Named sessions
74
-
75
- ```bash
76
- cms-edit --session link-sweep batch set idOne123456789012345678:variant=link
77
- cms-edit --session link-sweep batch save
78
- ```
94
+ - **Partial save on failure** — if one entry fails during `batch save`, earlier entries may already be saved; the CLI lists failures and reminds you to run diff for remaining changes
@@ -84,6 +84,10 @@ cms-edit batch run --json '[...]'
84
84
  | Command | Description |
85
85
  |---|---|
86
86
  | `open --page-slug <slug>` | Load a page into the session (see `help lookup`) |
87
+ | `open --resume` | Re-print active session; **keeps** staged edits (no refetch) |
88
+ | `open --overwrite …` | Replace session even if dirty (discards staged field edits) |
89
+ | `set <ref\|id> <field> <value>` | Set field; bare entry IDs allowed mid-session |
90
+ | `set <id>:field=value …` | Scalar multi-set by entry ID (stays on current session) |
87
91
  | `open --id <id>` | Load by Contentful entry ID |
88
92
  | `peek --page-slug <slug>` | Print content tree + root field values without creating a session |
89
93
  | `peek --id <id>` | Same by Contentful entry ID |
@@ -137,7 +141,7 @@ cms-edit batch run --json '[...]'
137
141
  ### Batch Operations
138
142
  | Command | Description |
139
143
  |---|---|
140
- | `batch set <entryId>:field=value …` | Queue scalar updates on multiple entries by ID |
144
+ | `batch set <entryId>:field=value …` | Queue scalar updates by ID (page session OK mid-edit; then `save`) |
141
145
  | `batch diff` / `batch save` / `batch discard` | Review and commit batch session |
142
146
  | `batch run --json <json> or --json-base64 <encoded>` | Execute a JSON batch of operations |
143
147
 
@@ -26,6 +26,25 @@ cms-edit open --id 4xKpzQ2abc123
26
26
 
27
27
  `open` fetches the full entry tree and saves it to a local session file. All subsequent commands operate on this session without re-fetching from Contentful until you `save`.
28
28
 
29
+ ### Critical: do not re-open while edits are staged
30
+
31
+ `set` / `rtf` / parent links from `add` stay in the session until `save`. Calling `open` again **replaces** the session.
32
+
33
+ | Situation | Command |
34
+ |-----------|---------|
35
+ | Session has unsaved changes, need tree again | `cms-edit open --resume` (no refetch; keeps staged edits) |
36
+ | Intentionally abandon staged work and load another entry | `cms-edit open --overwrite --id <id>` (or `discard` then `open`) |
37
+ | Plain `open` while dirty | **Hard fail** with remediation steps |
38
+
39
+ ```bash
40
+ cms-edit open --resume
41
+ cms-edit diff
42
+ cms-edit save
43
+ # or abandon:
44
+ cms-edit discard
45
+ cms-edit open --id <other>
46
+ ```
47
+
29
48
  **Output:**
30
49
  ```
31
50
  ✓ Opened /solutions/hepatology (12 entries)
@@ -72,6 +91,34 @@ cms-edit set @c2 heading "New Heading"
72
91
  cms-edit set @c2 backgroundColour "Navy"
73
92
  ```
74
93
 
94
+ ### Mid-session by Contentful entry ID (e.g. media autoplay)
95
+
96
+ You do **not** need to leave the page session:
97
+
98
+ ```bash
99
+ # Bare entry ID (fetched into the session if not in the tree)
100
+ cms-edit set 5uMh54rIsJRFRQSXDuJiG autoplay true
101
+
102
+ # Same shape as batch set — stays on the current page session
103
+ cms-edit set 5uMh54rIsJRFRQSXDuJiG:autoplay=true 5uMh54rIsJRFRQSXDuJiG:loop=true
104
+ # or: cms-edit batch set … (also allowed mid-page; then cms-edit save)
105
+ ```
106
+
107
+ ### Entry links: `--link` vs `--links` (strict)
108
+
109
+ | Field shape | Flag | Notes |
110
+ |-------------|------|--------|
111
+ | Single Entry link | `--link` | Exactly one id |
112
+ | Array of Entry links | `--links` | Full replace of the array |
113
+ | Append to array | `--links --append` | Add ids |
114
+ | Wrong flag | hard error | Never silently coerces |
115
+
116
+ ```bash
117
+ cms-edit set @c1 visual <mediaEntryId> --link
118
+ cms-edit set @c2 contents <id1>,<id2> --links
119
+ # To change one array item: read the array, edit the list, write all ids back with --links
120
+ ```
121
+
75
122
  ### Rich text fields
76
123
  ```bash
77
124
  # Inline markdown (short content)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@se-studio/contentful-cms",
3
- "version": "3.2.1",
3
+ "version": "3.4.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",