@elytracms/studio 0.0.91 → 0.0.93

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 (353) hide show
  1. package/convex/asset-alt-migration.test.ts +127 -0
  2. package/convex/asset-replace.test.ts +168 -0
  3. package/convex/asset-revalidate.test.ts +6 -6
  4. package/convex/assets.ts +41 -5
  5. package/convex/cms.ts +537 -177
  6. package/convex/contract-parity.test.ts +173 -19
  7. package/convex/delivery.ts +26 -13
  8. package/convex/document-revalidate.test.ts +17 -16
  9. package/convex/orphan-hydration.test.ts +116 -0
  10. package/convex/presence-cost.test.ts +89 -0
  11. package/convex/rail-write-parity.test.ts +17 -14
  12. package/convex/referenceMaintenance.ts +15 -15
  13. package/convex/schema.ts +70 -5
  14. package/convex/triggers.ts +21 -8
  15. package/convex/write-limits.ts +1 -1
  16. package/dist/components/ai/ai-chat-panel.js +33 -22
  17. package/dist/components/ai/ai-chat-panel.js.map +1 -1
  18. package/dist/components/ai/proposal-card.js +2 -1
  19. package/dist/components/ai/proposal-card.js.map +1 -1
  20. package/dist/components/ai/translate-document-action.d.ts +8 -2
  21. package/dist/components/ai/translate-document-action.js.map +1 -1
  22. package/dist/components/ai/translate-document-dialog.d.ts +1 -1
  23. package/dist/components/ai/translate-document-dialog.js +14 -8
  24. package/dist/components/ai/translate-document-dialog.js.map +1 -1
  25. package/dist/components/ai/translate-skipped.d.ts +19 -0
  26. package/dist/components/ai/translate-skipped.js +46 -0
  27. package/dist/components/ai/translate-skipped.js.map +1 -0
  28. package/dist/components/app-views/default-modules.d.ts +23 -6
  29. package/dist/components/app-views/default-modules.js +33 -14
  30. package/dist/components/app-views/default-modules.js.map +1 -1
  31. package/dist/components/assets/asset-detail.js +18 -8
  32. package/dist/components/assets/asset-detail.js.map +1 -1
  33. package/dist/components/assets/asset-metadata.d.ts +15 -4
  34. package/dist/components/assets/asset-metadata.js +15 -2
  35. package/dist/components/assets/asset-metadata.js.map +1 -1
  36. package/dist/components/assets/asset-search.js +4 -1
  37. package/dist/components/assets/asset-search.js.map +1 -1
  38. package/dist/components/assets/asset-selection.d.ts +0 -8
  39. package/dist/components/assets/asset-selection.js +4 -23
  40. package/dist/components/assets/asset-selection.js.map +1 -1
  41. package/dist/components/assets/asset-thumb.js +3 -2
  42. package/dist/components/assets/asset-thumb.js.map +1 -1
  43. package/dist/components/assets/assets-collection-view-source.d.ts +3 -3
  44. package/dist/components/assets/assets-collection-view-source.js +9 -5
  45. package/dist/components/assets/assets-collection-view-source.js.map +1 -1
  46. package/dist/components/assets/assets-store.d.ts +14 -0
  47. package/dist/components/assets/assets-store.js +23 -1
  48. package/dist/components/assets/assets-store.js.map +1 -1
  49. package/dist/components/assets/replace-file.d.ts +22 -0
  50. package/dist/components/assets/replace-file.js +59 -0
  51. package/dist/components/assets/replace-file.js.map +1 -0
  52. package/dist/components/builder/blocks-model.d.ts +14 -26
  53. package/dist/components/builder/blocks-model.js +35 -41
  54. package/dist/components/builder/blocks-model.js.map +1 -1
  55. package/dist/components/builder/blocks-panel.d.ts +7 -3
  56. package/dist/components/builder/blocks-panel.js +6 -5
  57. package/dist/components/builder/blocks-panel.js.map +1 -1
  58. package/dist/components/builder/builder-store.d.ts +126 -30
  59. package/dist/components/builder/builder-store.js +169 -67
  60. package/dist/components/builder/builder-store.js.map +1 -1
  61. package/dist/components/builder/canvas-body.d.ts +30 -0
  62. package/dist/components/builder/canvas-body.js +38 -0
  63. package/dist/components/builder/canvas-body.js.map +1 -0
  64. package/dist/components/builder/canvas-chrome-css.js +7 -0
  65. package/dist/components/builder/canvas-chrome-css.js.map +1 -1
  66. package/dist/components/builder/canvas-dnd.d.ts +7 -7
  67. package/dist/components/builder/canvas-dnd.js +5 -5
  68. package/dist/components/builder/canvas-dnd.js.map +1 -1
  69. package/dist/components/builder/canvas-render-context.d.ts +30 -22
  70. package/dist/components/builder/canvas-render-context.js +44 -44
  71. package/dist/components/builder/canvas-render-context.js.map +1 -1
  72. package/dist/components/builder/canvas-runs.d.ts +45 -0
  73. package/dist/components/builder/canvas-runs.js +51 -0
  74. package/dist/components/builder/canvas-runs.js.map +1 -0
  75. package/dist/components/builder/canvas.d.ts +5 -4
  76. package/dist/components/builder/canvas.js +34 -6
  77. package/dist/components/builder/canvas.js.map +1 -1
  78. package/dist/components/builder/clipboard-actions.d.ts +15 -0
  79. package/dist/components/builder/clipboard-actions.js +50 -13
  80. package/dist/components/builder/clipboard-actions.js.map +1 -1
  81. package/dist/components/builder/composition-field-editor.d.ts +10 -16
  82. package/dist/components/builder/composition-field-editor.js +30 -40
  83. package/dist/components/builder/composition-field-editor.js.map +1 -1
  84. package/dist/components/builder/composition-patches.d.ts +7 -0
  85. package/dist/components/builder/composition-patches.js +256 -0
  86. package/dist/components/builder/composition-patches.js.map +1 -0
  87. package/dist/components/builder/delete-key.d.ts +5 -0
  88. package/dist/components/builder/delete-key.js +4 -0
  89. package/dist/components/builder/delete-key.js.map +1 -1
  90. package/dist/components/builder/insert-context.d.ts +17 -25
  91. package/dist/components/builder/insert-context.js +45 -92
  92. package/dist/components/builder/insert-context.js.map +1 -1
  93. package/dist/components/builder/page-tree.d.ts +3 -3
  94. package/dist/components/builder/page-tree.js +3 -3
  95. package/dist/components/builder/page-tree.js.map +1 -1
  96. package/dist/components/builder/placement-refusal.d.ts +18 -0
  97. package/dist/components/builder/placement-refusal.js +46 -0
  98. package/dist/components/builder/placement-refusal.js.map +1 -0
  99. package/dist/components/builder/property-inspector.js +4 -0
  100. package/dist/components/builder/property-inspector.js.map +1 -1
  101. package/dist/components/builder/reuse-context.js +65 -26
  102. package/dist/components/builder/reuse-context.js.map +1 -1
  103. package/dist/components/builder/reuse.d.ts +79 -8
  104. package/dist/components/builder/reuse.js +71 -23
  105. package/dist/components/builder/reuse.js.map +1 -1
  106. package/dist/components/builder/run-inspector.d.ts +11 -0
  107. package/dist/components/builder/run-inspector.js +33 -0
  108. package/dist/components/builder/run-inspector.js.map +1 -0
  109. package/dist/components/cms/asset-field.d.ts +38 -1
  110. package/dist/components/cms/asset-field.js +182 -58
  111. package/dist/components/cms/asset-field.js.map +1 -1
  112. package/dist/components/cms/asset-picker-core.d.ts +16 -0
  113. package/dist/components/cms/asset-picker-core.js +20 -0
  114. package/dist/components/cms/asset-picker-core.js.map +1 -1
  115. package/dist/components/cms/asset-picker.js +12 -18
  116. package/dist/components/cms/asset-picker.js.map +1 -1
  117. package/dist/components/cms/bulk-actions.d.ts +4 -20
  118. package/dist/components/cms/bulk-actions.js +3 -24
  119. package/dist/components/cms/bulk-actions.js.map +1 -1
  120. package/dist/components/cms/cell-edit.d.ts +5 -5
  121. package/dist/components/cms/cell-edit.js.map +1 -1
  122. package/dist/components/cms/cell.js.map +1 -1
  123. package/dist/components/cms/cms-store.d.ts +87 -45
  124. package/dist/components/cms/cms-store.js +347 -203
  125. package/dist/components/cms/cms-store.js.map +1 -1
  126. package/dist/components/cms/collection-table.js +7 -2
  127. package/dist/components/cms/collection-table.js.map +1 -1
  128. package/dist/components/cms/commit-policy.d.ts +24 -0
  129. package/dist/components/cms/commit-policy.js +37 -0
  130. package/dist/components/cms/commit-policy.js.map +1 -0
  131. package/dist/components/cms/detail-editor.js +83 -137
  132. package/dist/components/cms/detail-editor.js.map +1 -1
  133. package/dist/components/cms/document-diff-view.d.ts +3 -1
  134. package/dist/components/cms/document-diff-view.js +12 -7
  135. package/dist/components/cms/document-diff-view.js.map +1 -1
  136. package/dist/components/cms/draft-commit.d.ts +70 -0
  137. package/dist/components/cms/draft-commit.js +82 -0
  138. package/dist/components/cms/draft-commit.js.map +1 -0
  139. package/dist/components/cms/duplicate-document.d.ts +11 -13
  140. package/dist/components/cms/duplicate-document.js +26 -34
  141. package/dist/components/cms/duplicate-document.js.map +1 -1
  142. package/dist/components/cms/field-anchors.d.ts +7 -4
  143. package/dist/components/cms/field-anchors.js +9 -7
  144. package/dist/components/cms/field-anchors.js.map +1 -1
  145. package/dist/components/cms/field-collaboration.d.ts +47 -0
  146. package/dist/components/cms/field-collaboration.js +87 -0
  147. package/dist/components/cms/field-collaboration.js.map +1 -0
  148. package/dist/components/cms/field-control-lib.d.ts +22 -1
  149. package/dist/components/cms/field-control-lib.js +33 -4
  150. package/dist/components/cms/field-control-lib.js.map +1 -1
  151. package/dist/components/cms/field-control.js +17 -14
  152. package/dist/components/cms/field-control.js.map +1 -1
  153. package/dist/components/cms/gate-validation.d.ts +21 -30
  154. package/dist/components/cms/gate-validation.js +11 -22
  155. package/dist/components/cms/gate-validation.js.map +1 -1
  156. package/dist/components/cms/object-array-field.js +4 -4
  157. package/dist/components/cms/object-array-field.js.map +1 -1
  158. package/dist/components/cms/prop-fields.d.ts +7 -2
  159. package/dist/components/cms/prop-fields.js +13 -6
  160. package/dist/components/cms/prop-fields.js.map +1 -1
  161. package/dist/components/cms/reference-confirm.js +10 -4
  162. package/dist/components/cms/reference-confirm.js.map +1 -1
  163. package/dist/components/cms/rich-text/embed-picker.d.ts +1 -1
  164. package/dist/components/cms/rich-text/embed-picker.js.map +1 -1
  165. package/dist/components/cms/rich-text/insert.d.ts +20 -9
  166. package/dist/components/cms/rich-text/insert.js +25 -17
  167. package/dist/components/cms/rich-text/insert.js.map +1 -1
  168. package/dist/components/cms/use-document-draft.d.ts +96 -0
  169. package/dist/components/cms/use-document-draft.js +283 -0
  170. package/dist/components/cms/use-document-draft.js.map +1 -0
  171. package/dist/components/cms/use-document-versions.js +2 -2
  172. package/dist/components/cms/use-document-versions.js.map +1 -1
  173. package/dist/components/cms/use-live-url.d.ts +6 -12
  174. package/dist/components/cms/use-live-url.js +16 -15
  175. package/dist/components/cms/use-live-url.js.map +1 -1
  176. package/dist/components/cms/use-publish-controller.d.ts +13 -18
  177. package/dist/components/cms/use-publish-controller.js +24 -41
  178. package/dist/components/cms/use-publish-controller.js.map +1 -1
  179. package/dist/components/cms/use-published-perspective.d.ts +2 -3
  180. package/dist/components/cms/use-published-perspective.js +4 -3
  181. package/dist/components/cms/use-published-perspective.js.map +1 -1
  182. package/dist/components/cms/versions-pane.js +8 -1
  183. package/dist/components/cms/versions-pane.js.map +1 -1
  184. package/dist/components/collection-view/cms-collection-view-source.js +24 -7
  185. package/dist/components/collection-view/cms-collection-view-source.js.map +1 -1
  186. package/dist/components/components/transfer-dialog.js +28 -23
  187. package/dist/components/components/transfer-dialog.js.map +1 -1
  188. package/dist/components/components/transfer.d.ts +31 -21
  189. package/dist/components/components/transfer.js +49 -35
  190. package/dist/components/components/transfer.js.map +1 -1
  191. package/dist/components/project-list.js.map +1 -1
  192. package/dist/components/project-session.d.ts +6 -3
  193. package/dist/components/project-session.js +14 -8
  194. package/dist/components/project-session.js.map +1 -1
  195. package/dist/components/project-switcher.js.map +1 -1
  196. package/dist/components/rail-view-source.js +2 -1
  197. package/dist/components/rail-view-source.js.map +1 -1
  198. package/dist/components/section-nav.js +1 -1
  199. package/dist/components/section-nav.js.map +1 -1
  200. package/dist/lib/ai/apply-content.js +56 -116
  201. package/dist/lib/ai/apply-content.js.map +1 -1
  202. package/dist/lib/ai/chat-context.d.ts +8 -0
  203. package/dist/lib/ai/chat-context.js +37 -6
  204. package/dist/lib/ai/chat-context.js.map +1 -1
  205. package/dist/lib/ai/chat-state.d.ts +14 -1
  206. package/dist/lib/ai/chat-state.js.map +1 -1
  207. package/dist/lib/ai/constraints.d.ts +20 -5
  208. package/dist/lib/ai/constraints.js +125 -33
  209. package/dist/lib/ai/constraints.js.map +1 -1
  210. package/dist/lib/ai/fake-provider.d.ts +16 -3
  211. package/dist/lib/ai/fake-provider.js +22 -6
  212. package/dist/lib/ai/fake-provider.js.map +1 -1
  213. package/dist/lib/ai/index.d.ts +2 -0
  214. package/dist/lib/ai/index.js +2 -0
  215. package/dist/lib/ai/index.js.map +1 -1
  216. package/dist/lib/ai/leash.d.ts +34 -0
  217. package/dist/lib/ai/leash.js +28 -0
  218. package/dist/lib/ai/leash.js.map +1 -0
  219. package/dist/lib/ai/provenance.d.ts +1 -1
  220. package/dist/lib/ai/provenance.js.map +1 -1
  221. package/dist/lib/ai/rich-text-input.d.ts +8 -8
  222. package/dist/lib/ai/rich-text-input.js +2 -1
  223. package/dist/lib/ai/rich-text-input.js.map +1 -1
  224. package/dist/lib/ai/rich-text-translate.d.ts +27 -4
  225. package/dist/lib/ai/rich-text-translate.js +28 -10
  226. package/dist/lib/ai/rich-text-translate.js.map +1 -1
  227. package/dist/lib/ai/shape.d.ts +13 -13
  228. package/dist/lib/ai/shape.js +69 -93
  229. package/dist/lib/ai/shape.js.map +1 -1
  230. package/dist/lib/ai/tools.d.ts +36 -41
  231. package/dist/lib/ai/tools.js +85 -87
  232. package/dist/lib/ai/tools.js.map +1 -1
  233. package/dist/lib/ai/translate-document.d.ts +39 -5
  234. package/dist/lib/ai/translate-document.js +160 -51
  235. package/dist/lib/ai/translate-document.js.map +1 -1
  236. package/dist/lib/ai/types.d.ts +34 -23
  237. package/dist/lib/ai/types.js.map +1 -1
  238. package/dist/lib/ai/update-fields.d.ts +21 -12
  239. package/dist/lib/ai/update-fields.js +118 -177
  240. package/dist/lib/ai/update-fields.js.map +1 -1
  241. package/dist/lib/ai/writer-form.d.ts +116 -0
  242. package/dist/lib/ai/writer-form.js +429 -0
  243. package/dist/lib/ai/writer-form.js.map +1 -0
  244. package/dist/lib/ai-current-document.d.ts +11 -11
  245. package/dist/lib/ai-current-document.js +4 -4
  246. package/dist/lib/ai-current-document.js.map +1 -1
  247. package/dist/lib/assets/upload.d.ts +31 -2
  248. package/dist/lib/assets/upload.js +61 -6
  249. package/dist/lib/assets/upload.js.map +1 -1
  250. package/dist/lib/clipboard/os-clipboard.d.ts +10 -2
  251. package/dist/lib/clipboard/os-clipboard.js +8 -4
  252. package/dist/lib/clipboard/os-clipboard.js.map +1 -1
  253. package/dist/lib/clipboard/paste-target.d.ts +18 -9
  254. package/dist/lib/clipboard/paste-target.js +8 -7
  255. package/dist/lib/clipboard/paste-target.js.map +1 -1
  256. package/dist/lib/cms/field-patch.d.ts +15 -0
  257. package/dist/lib/cms/field-patch.js +25 -0
  258. package/dist/lib/cms/field-patch.js.map +1 -0
  259. package/dist/lib/cms/published-documents.d.ts +1 -1
  260. package/dist/lib/cms/published-documents.js +1 -1
  261. package/dist/lib/cms/published-documents.js.map +1 -1
  262. package/dist/lib/cms-views/view-model.d.ts +3 -3
  263. package/dist/lib/collection-view/__fixtures__/document-writes.d.ts +6 -0
  264. package/dist/lib/collection-view/__fixtures__/document-writes.js +23 -0
  265. package/dist/lib/collection-view/__fixtures__/document-writes.js.map +1 -0
  266. package/dist/lib/collection-view/collection-view-source.d.ts +69 -6
  267. package/dist/lib/collection-view/collection-view-source.js.map +1 -1
  268. package/dist/lib/data/collection-content.d.ts +4 -13
  269. package/dist/lib/data/collection-content.js +11 -5
  270. package/dist/lib/data/collection-content.js.map +1 -1
  271. package/dist/lib/dnd/drop-rules.d.ts +25 -31
  272. package/dist/lib/dnd/drop-rules.js +53 -59
  273. package/dist/lib/dnd/drop-rules.js.map +1 -1
  274. package/dist/lib/engine-version.d.ts +1 -1
  275. package/dist/lib/engine-version.js +1 -1
  276. package/dist/lib/engine-version.js.map +1 -1
  277. package/dist/lib/i18n/messages.de.js +72 -15
  278. package/dist/lib/i18n/messages.de.js.map +1 -1
  279. package/dist/lib/i18n/messages.en.d.ts +61 -12
  280. package/dist/lib/i18n/messages.en.js +76 -16
  281. package/dist/lib/i18n/messages.en.js.map +1 -1
  282. package/dist/lib/operations/__fixtures__/write-document.d.ts +30 -0
  283. package/dist/lib/operations/__fixtures__/write-document.js +16 -0
  284. package/dist/lib/operations/__fixtures__/write-document.js.map +1 -0
  285. package/dist/lib/operations/cms-persistence.d.ts +124 -31
  286. package/dist/lib/operations/cms-persistence.js +447 -68
  287. package/dist/lib/operations/cms-persistence.js.map +1 -1
  288. package/dist/lib/operations/config-manifest-lookup.d.ts +35 -0
  289. package/dist/lib/operations/config-manifest-lookup.js +56 -0
  290. package/dist/lib/operations/config-manifest-lookup.js.map +1 -0
  291. package/dist/lib/operations/project-runtime-config.d.ts +39 -0
  292. package/dist/lib/operations/project-runtime-config.js +54 -0
  293. package/dist/lib/operations/project-runtime-config.js.map +1 -0
  294. package/dist/lib/operations/publish-with-revision.d.ts +64 -0
  295. package/dist/lib/operations/publish-with-revision.js +66 -0
  296. package/dist/lib/operations/publish-with-revision.js.map +1 -0
  297. package/dist/lib/operations/runtime-validator.d.ts +32 -0
  298. package/dist/lib/operations/runtime-validator.js +18 -0
  299. package/dist/lib/operations/runtime-validator.js.map +1 -0
  300. package/dist/lib/operations/session-hydration.d.ts +31 -14
  301. package/dist/lib/operations/session-hydration.js +12 -16
  302. package/dist/lib/operations/session-hydration.js.map +1 -1
  303. package/dist/lib/operations/studio-operations.d.ts +59 -2
  304. package/dist/lib/operations/studio-operations.js +76 -14
  305. package/dist/lib/operations/studio-operations.js.map +1 -1
  306. package/dist/lib/persistence/convex-adapter.d.ts +13 -5
  307. package/dist/lib/persistence/convex-adapter.js +189 -74
  308. package/dist/lib/persistence/convex-adapter.js.map +1 -1
  309. package/dist/lib/persistence/convex-client.d.ts +65 -5
  310. package/dist/lib/persistence/convex-client.js +106 -3
  311. package/dist/lib/persistence/convex-client.js.map +1 -1
  312. package/dist/lib/persistence/index.js +17 -18
  313. package/dist/lib/persistence/index.js.map +1 -1
  314. package/dist/lib/persona/labels.js +4 -1
  315. package/dist/lib/persona/labels.js.map +1 -1
  316. package/dist/lib/query/operations-query.d.ts +1 -1
  317. package/dist/lib/query/operations-query.js +1 -1
  318. package/dist/lib/query/operations-query.js.map +1 -1
  319. package/dist/lib/references/impact.d.ts +21 -15
  320. package/dist/lib/references/impact.js +13 -26
  321. package/dist/lib/references/impact.js.map +1 -1
  322. package/dist/lib/references/references-store.d.ts +9 -0
  323. package/dist/lib/references/references-store.js +24 -4
  324. package/dist/lib/references/references-store.js.map +1 -1
  325. package/dist/lib/routes/route-issues.d.ts +6 -6
  326. package/dist/lib/routes/route-issues.js +26 -80
  327. package/dist/lib/routes/route-issues.js.map +1 -1
  328. package/dist/lib/workspace/config-issues.js +2 -1
  329. package/dist/lib/workspace/config-issues.js.map +1 -1
  330. package/dist/lib/workspace/index.d.ts +31 -1
  331. package/dist/lib/workspace/index.js +64 -17
  332. package/dist/lib/workspace/index.js.map +1 -1
  333. package/dist/lib/workspace/switcher-source.d.ts +3 -3
  334. package/dist/lib/workspace/switcher-source.js.map +1 -1
  335. package/dist/lib/workspace/workspace-source.d.ts +2 -2
  336. package/dist/lib/workspace/workspace-source.js +2 -1
  337. package/dist/lib/workspace/workspace-source.js.map +1 -1
  338. package/package.json +3 -3
  339. package/dist/components/cms/cms-composition-validators.d.ts +0 -16
  340. package/dist/components/cms/cms-composition-validators.js +0 -133
  341. package/dist/components/cms/cms-composition-validators.js.map +0 -1
  342. package/dist/components/cms/publish-clean.d.ts +0 -28
  343. package/dist/components/cms/publish-clean.js +0 -38
  344. package/dist/components/cms/publish-clean.js.map +0 -1
  345. package/dist/components/cms/use-save-mode.d.ts +0 -35
  346. package/dist/components/cms/use-save-mode.js +0 -54
  347. package/dist/components/cms/use-save-mode.js.map +0 -1
  348. package/dist/lib/assets/asset-placements.d.ts +0 -28
  349. package/dist/lib/assets/asset-placements.js +0 -83
  350. package/dist/lib/assets/asset-placements.js.map +0 -1
  351. package/dist/lib/cms/document-gate.d.ts +0 -47
  352. package/dist/lib/cms/document-gate.js +0 -61
  353. package/dist/lib/cms/document-gate.js.map +0 -1
@@ -188,6 +188,12 @@ declare const MESSAGES: {
188
188
  'operations.error.invalidInput': import("./types.js").SourceMessage;
189
189
  'operations.error.notFound': import("./types.js").SourceMessage;
190
190
  'operations.error.conflict': import("./types.js").SourceMessage;
191
+ 'operations.error.revisionConflict': import("./types.js").SourceMessage;
192
+ 'operations.error.revisionConflictGone': import("./types.js").SourceMessage;
193
+ 'operations.error.documentExists': import("./types.js").SourceMessage;
194
+ 'operations.error.singletonExists': import("./types.js").SourceMessage;
195
+ 'operations.error.patchConflictOne': import("./types.js").SourceMessage;
196
+ 'operations.error.patchConflict': import("./types.js").SourceMessage;
191
197
  'operations.error.backendUnavailable': import("./types.js").SourceMessage;
192
198
  'operations.error.unauthorized': import("./types.js").SourceMessage;
193
199
  'operations.error.unknown': import("./types.js").SourceMessage;
@@ -196,6 +202,10 @@ declare const MESSAGES: {
196
202
  'operations.error.strictReferencesBlockDeleteOne': import("./types.js").SourceMessage;
197
203
  'operations.error.strictReferencesBlockUnpublish': import("./types.js").SourceMessage;
198
204
  'operations.error.strictReferencesBlockUnpublishOne': import("./types.js").SourceMessage;
205
+ 'operations.error.strictTargetsUnpublishedOne': import("./types.js").SourceMessage;
206
+ 'operations.error.strictTargetsUnpublished': import("./types.js").SourceMessage;
207
+ 'operations.error.publishNeedsLocales': import("./types.js").SourceMessage;
208
+ 'operations.error.versionNotPinnable': import("./types.js").SourceMessage;
199
209
  'operations.errorDetail.andMore': import("./types.js").SourceMessage;
200
210
  'content.queryError.nonFilterableField': import("./types.js").SourceMessage;
201
211
  'content.queryError.unknownField': import("./types.js").SourceMessage;
@@ -328,7 +338,6 @@ declare const MESSAGES: {
328
338
  'cms.editor.saveFailed': import("./types.js").SourceMessage;
329
339
  'cms.editor.unsavedChanges': import("./types.js").SourceMessage;
330
340
  'cms.editor.saved': import("./types.js").SourceMessage;
331
- 'cms.editor.saving': import("./types.js").SourceMessage;
332
341
  'cms.editor.openLiveUrl': import("./types.js").SourceMessage;
333
342
  'cms.editor.loadingLiveUrl': import("./types.js").SourceMessage;
334
343
  'cms.editor.publishToViewLive': import("./types.js").SourceMessage;
@@ -359,11 +368,6 @@ declare const MESSAGES: {
359
368
  'cms.editor.loadingPublishedVersion': import("./types.js").SourceMessage;
360
369
  'cms.editor.noPublishedVersion': import("./types.js").SourceMessage;
361
370
  'cms.editor.unsavedChangesGuard': import("./types.js").SourceMessage;
362
- 'cms.editor.publishUnpublishedRefsTitle': import("./types.js").SourceMessage;
363
- 'cms.editor.publishUnpublishedRefsDescription': import("./types.js").SourceMessage;
364
- 'cms.editor.publishAlsoHasIssues.one': import("./types.js").SourceMessage;
365
- 'cms.editor.publishAlsoHasIssues.other': import("./types.js").SourceMessage;
366
- 'cms.editor.publishAnyway': import("./types.js").SourceMessage;
367
371
  'cms.editor.readOnlyBadge': import("./types.js").SourceMessage;
368
372
  'cms.editor.localeFollowsBase': import("./types.js").SourceMessage;
369
373
  'cms.editor.localeFollowsHint': import("./types.js").SourceMessage;
@@ -378,8 +382,6 @@ declare const MESSAGES: {
378
382
  'cms.editor.detailsPane': import("./types.js").SourceMessage;
379
383
  'cms.editor.servedAt': import("./types.js").SourceMessage;
380
384
  'cms.editor.slugUrlHint': import("./types.js").SourceMessage;
381
- 'cms.editor.embedUnpublishedIssue': import("./types.js").SourceMessage;
382
- 'cms.editor.embedMissingIssue': import("./types.js").SourceMessage;
383
385
  'cms.editor.defaultGroup': import("./types.js").SourceMessage;
384
386
  'cms.issues.none': import("./types.js").SourceMessage;
385
387
  'cms.issues.satisfied': import("./types.js").SourceMessage;
@@ -402,6 +404,7 @@ declare const MESSAGES: {
402
404
  'cms.issue.missing-localized-value': import("./types.js").SourceMessage;
403
405
  'cms.issue.route-conflict': import("./types.js").SourceMessage;
404
406
  'cms.issue.redirect-loop': import("./types.js").SourceMessage;
407
+ 'cms.issue.invalid-redirect': import("./types.js").SourceMessage;
405
408
  'cms.issue.unknown-route-target': import("./types.js").SourceMessage;
406
409
  'cms.issue.hierarchy-cycle': import("./types.js").SourceMessage;
407
410
  'cms.issue.document-nesting-depth': import("./types.js").SourceMessage;
@@ -413,6 +416,7 @@ declare const MESSAGES: {
413
416
  'cms.issue.hidden-predicate-error': import("./types.js").SourceMessage;
414
417
  'cms.issue.unaddressable-url': import("./types.js").SourceMessage;
415
418
  'cms.issue.unknown-version': import("./types.js").SourceMessage;
419
+ 'cms.issue.invalid-stored-document': import("./types.js").SourceMessage;
416
420
  'cms.issueBody.missing-required-field': import("./types.js").SourceMessage;
417
421
  'cms.issueBody.missing-localized-value.default': import("./types.js").SourceMessage;
418
422
  'cms.issueBody.missing-localized-value.fallback': import("./types.js").SourceMessage;
@@ -431,6 +435,7 @@ declare const MESSAGES: {
431
435
  'cms.issueMessage.relationWrongCollection': import("./types.js").SourceMessage;
432
436
  'cms.issueMessage.relationMissingDocument': import("./types.js").SourceMessage;
433
437
  'cms.issueMessage.relationUnpublishedDocument': import("./types.js").SourceMessage;
438
+ 'cms.issueMessage.relationStrictUnpublished': import("./types.js").SourceMessage;
434
439
  'cms.issueMessage.assetNoAssetCollection': import("./types.js").SourceMessage;
435
440
  'cms.issueMessage.assetSingleValued': import("./types.js").SourceMessage;
436
441
  'cms.issueMessage.assetExpectsId': import("./types.js").SourceMessage;
@@ -443,7 +448,22 @@ declare const MESSAGES: {
443
448
  'cms.issueMessage.preConvergenceV1': import("./types.js").SourceMessage;
444
449
  'cms.issueMessage.preConvergenceBareBlocks': import("./types.js").SourceMessage;
445
450
  'cms.issueMessage.preConvergencePlaintext': import("./types.js").SourceMessage;
446
- 'cms.issueMessage.noValidationSession': import("./types.js").SourceMessage;
451
+ 'cms.issueMessage.gateUnknownCollection': import("./types.js").SourceMessage;
452
+ 'cms.issueMessage.gateAssetLibraryUnready': import("./types.js").SourceMessage;
453
+ 'cms.issueMessage.gateNoLocales': import("./types.js").SourceMessage;
454
+ 'cms.conflict.changedBy': import("./types.js").SourceMessage;
455
+ 'cms.conflict.removedBy': import("./types.js").SourceMessage;
456
+ 'cms.conflict.theirs': import("./types.js").SourceMessage;
457
+ 'cms.conflict.takeTheirs': import("./types.js").SourceMessage;
458
+ 'cms.conflict.keepMine': import("./types.js").SourceMessage;
459
+ 'cms.conflict.someoneElse': import("./types.js").SourceMessage;
460
+ 'cms.conflict.youInAnotherTab': import("./types.js").SourceMessage;
461
+ 'cms.conflict.empty': import("./types.js").SourceMessage;
462
+ 'cms.conflict.structured': import("./types.js").SourceMessage;
463
+ 'cms.conflict.cellRefused': import("./types.js").SourceMessage;
464
+ 'cms.presence.inField': import("./types.js").SourceMessage;
465
+ 'cms.presence.inFieldMany': import("./types.js").SourceMessage;
466
+ 'cms.presence.someone': import("./types.js").SourceMessage;
447
467
  'cms.issueMessage.richTextHoldsObject': import("./types.js").SourceMessage;
448
468
  'cms.issueMessage.unknownCollectionForDocument': import("./types.js").SourceMessage;
449
469
  'cms.issueMessage.localizedPlainValue': import("./types.js").SourceMessage;
@@ -470,6 +490,7 @@ declare const MESSAGES: {
470
490
  'cms.issueMessage.unknownVersion': import("./types.js").SourceMessage;
471
491
  'cms.issueMessage.routeConflict': import("./types.js").SourceMessage;
472
492
  'cms.issueMessage.redirectLoop': import("./types.js").SourceMessage;
493
+ 'cms.issueMessage.duplicateRedirect': import("./types.js").SourceMessage;
473
494
  'cms.issueMessage.allDynamicShadowsMount': import("./types.js").SourceMessage;
474
495
  'cms.issueMessage.mountCannotServe': import("./types.js").SourceMessage;
475
496
  'cms.issueMessage.deadCatchAll': import("./types.js").SourceMessage;
@@ -477,6 +498,7 @@ declare const MESSAGES: {
477
498
  'cms.issueMessage.routeBoundDocumentNotFound': import("./types.js").SourceMessage;
478
499
  'cms.issueMessage.routeParamNotCaptured': import("./types.js").SourceMessage;
479
500
  'cms.issueMessage.collectionNotDefined': import("./types.js").SourceMessage;
501
+ 'cms.issueMessage.storedDocumentUnreadable': import("./types.js").SourceMessage;
480
502
  'cms.issueMessage.unaddressableLocaleCollision': import("./types.js").SourceMessage;
481
503
  'cms.issueDetail.expectsString': import("./types.js").SourceMessage;
482
504
  'cms.issueDetail.expectsRichText': import("./types.js").SourceMessage;
@@ -508,7 +530,6 @@ declare const MESSAGES: {
508
530
  'cms.issueDetail.mountCollectionNotDeclared': import("./types.js").SourceMessage;
509
531
  'cms.issueDetail.mountCollectionNotHierarchical': import("./types.js").SourceMessage;
510
532
  'cms.issueDetail.mountsSamePath': import("./types.js").SourceMessage;
511
- 'cms.issueDetail.mountsNested': import("./types.js").SourceMessage;
512
533
  'cms.details.slot': import("./types.js").SourceMessage;
513
534
  'cms.details.noSlot': import("./types.js").SourceMessage;
514
535
  'cms.details.slotInUse': import("./types.js").SourceMessage;
@@ -546,6 +567,8 @@ declare const MESSAGES: {
546
567
  'cms.version.textUnchanged': import("./types.js").SourceMessage;
547
568
  'cms.version.restoreBlock': import("./types.js").SourceMessage;
548
569
  'cms.version.nestedContentChanged': import("./types.js").SourceMessage;
570
+ 'cms.version.nestedInProse': import("./types.js").SourceMessage;
571
+ 'cms.version.nestedIn': import("./types.js").SourceMessage;
549
572
  'cms.version.blockAdded': import("./types.js").SourceMessage;
550
573
  'cms.version.blockRemoved': import("./types.js").SourceMessage;
551
574
  'cms.version.emptyValue': import("./types.js").SourceMessage;
@@ -632,6 +655,16 @@ declare const MESSAGES: {
632
655
  'cms.asset.notSet': import("./types.js").SourceMessage;
633
656
  'cms.asset.imageOptions.title': import("./types.js").SourceMessage;
634
657
  'cms.asset.imageOptions.description': import("./types.js").SourceMessage;
658
+ 'cms.asset.imageOptions.placementTitle': import("./types.js").SourceMessage;
659
+ 'cms.asset.imageOptions.placementHint': import("./types.js").SourceMessage;
660
+ 'cms.asset.imageOptions.assetTitle': import("./types.js").SourceMessage;
661
+ 'cms.asset.imageOptions.assetHint': import("./types.js").SourceMessage;
662
+ 'cms.asset.imageOptions.whereUsed': import("./types.js").SourceMessage;
663
+ 'cms.asset.replaceFile': import("./types.js").SourceMessage;
664
+ 'cms.asset.replacing': import("./types.js").SourceMessage;
665
+ 'cms.asset.replaceWrongKind': import("./types.js").SourceMessage;
666
+ 'cms.asset.replaceSaveFirst': import("./types.js").SourceMessage;
667
+ 'cms.asset.replacedCheckFocal': import("./types.js").SourceMessage;
635
668
  'cms.asset.focalPoint': import("./types.js").SourceMessage;
636
669
  'cms.asset.resetToCentre': import("./types.js").SourceMessage;
637
670
  'cms.asset.focalPointHint': import("./types.js").SourceMessage;
@@ -859,6 +892,10 @@ declare const MESSAGES: {
859
892
  'builder.clipboard.notAllowed': import("./types.js").SourceMessage;
860
893
  'builder.clipboard.notAllowedByField': import("./types.js").SourceMessage;
861
894
  'builder.clipboard.issueComponent': import("./types.js").SourceMessage;
895
+ 'builder.placement.notAllowedByField': import("./types.js").SourceMessage;
896
+ 'builder.placement.notAllowedInSlot': import("./types.js").SourceMessage;
897
+ 'builder.placement.serverOnly': import("./types.js").SourceMessage;
898
+ 'builder.placement.dismiss': import("./types.js").SourceMessage;
862
899
  'builder.clipboard.error.corruptJson': import("./types.js").SourceMessage;
863
900
  'builder.clipboard.error.notEnvelope': import("./types.js").SourceMessage;
864
901
  'builder.clipboard.error.foreignFormat': import("./types.js").SourceMessage;
@@ -895,7 +932,6 @@ declare const MESSAGES: {
895
932
  'builder.inspector.slots': import("./types.js").SourceMessage;
896
933
  'builder.inspector.slotsHint': import("./types.js").SourceMessage;
897
934
  'builder.inspector.propertiesPane': import("./types.js").SourceMessage;
898
- 'builder.inspector.invalidValue': import("./types.js").SourceMessage;
899
935
  'builder.inspector.invalidJson': import("./types.js").SourceMessage;
900
936
  'builder.layout.title': import("./types.js").SourceMessage;
901
937
  'builder.layout.direction': import("./types.js").SourceMessage;
@@ -939,7 +975,10 @@ declare const MESSAGES: {
939
975
  'builder.canvasTheme.stylesheetErrorNotice': import("./types.js").SourceMessage;
940
976
  'builder.canvasTheme.noThemeTokensNotice': import("./types.js").SourceMessage;
941
977
  'builder.canvasTheme.noStylesheetNotice': import("./types.js").SourceMessage;
942
- 'builder.composition.preservedNotice': import("./types.js").SourceMessage;
978
+ 'builder.run.title': import("./types.js").SourceMessage;
979
+ 'builder.run.items': import("./types.js").SourceMessage;
980
+ 'builder.run.hint': import("./types.js").SourceMessage;
981
+ 'builder.run.delete': import("./types.js").SourceMessage;
943
982
  'builder.spacing.gapAfterChild': import("./types.js").SourceMessage;
944
983
  'builder.richText.toolbarLabel': import("./types.js").SourceMessage;
945
984
  'builder.richText.linkPlaceholder': import("./types.js").SourceMessage;
@@ -1062,6 +1101,10 @@ declare const MESSAGES: {
1062
1101
  'ai.translate.proposalTitle': import("./types.js").SourceMessage;
1063
1102
  'ai.translate.diffBefore': import("./types.js").SourceMessage;
1064
1103
  'ai.translate.diffAfter': import("./types.js").SourceMessage;
1104
+ 'ai.translate.skippedTitle': import("./types.js").SourceMessage;
1105
+ 'ai.translate.skipped.unreadable': import("./types.js").SourceMessage;
1106
+ 'ai.translate.skipped.notReturned': import("./types.js").SourceMessage;
1107
+ 'ai.translate.skipped.structureChanged': import("./types.js").SourceMessage;
1065
1108
  'ai.update.proposalTitle': import("./types.js").SourceMessage;
1066
1109
  'ai.update.diffBefore': import("./types.js").SourceMessage;
1067
1110
  'ai.update.diffAfter': import("./types.js").SourceMessage;
@@ -1072,7 +1115,13 @@ declare const MESSAGES: {
1072
1115
  'builder.inspector.unsetWithHint': import("./types.js").SourceMessage;
1073
1116
  'cms.issueMessage.nonCanonicalValue': import("./types.js").SourceMessage;
1074
1117
  'cms.issueMessage.assetHoldsUrl': import("./types.js").SourceMessage;
1118
+ 'cms.issueMessage.emptyAllow': import("./types.js").SourceMessage;
1119
+ 'cms.issueMessage.unknownAllowComponent': import("./types.js").SourceMessage;
1075
1120
  'cms.issueMessage.blocksNotTopLevel': import("./types.js").SourceMessage;
1121
+ 'cms.issueMessage.placementKeyReserved': import("./types.js").SourceMessage;
1122
+ 'cms.issueMessage.placementNotScalar': import("./types.js").SourceMessage;
1123
+ 'cms.issueMessage.sourceNotOnAssetCollection': import("./types.js").SourceMessage;
1124
+ 'cms.issueMessage.sourceTypeMismatch': import("./types.js").SourceMessage;
1076
1125
  'cms.issueMessage.uniqueNotTopLevel': import("./types.js").SourceMessage;
1077
1126
  'cms.issueMessage.localizedOnProp': import("./types.js").SourceMessage;
1078
1127
  'cms.issueMessage.localizedOnSubField': import("./types.js").SourceMessage;
@@ -243,13 +243,19 @@ const MESSAGES = {
243
243
  // a localized body under an unlocalized badge is the same defect, inverted.
244
244
  'operations.errorLabel.validation': msg("Couldn't save"),
245
245
  'operations.errorLabel.not-found': msg('Not found'),
246
- 'operations.errorLabel.conflict': msg('Already exists'),
246
+ 'operations.errorLabel.conflict': msg('Conflict', 'EC-595: a conflict is a revision clash, an existing id, or a strict-reference block — not only "already exists".'),
247
247
  'operations.errorLabel.backend-unavailable': msg('Connection problem'),
248
248
  'operations.errorLabel.unauthorized': msg('Not allowed'),
249
249
  'operations.errorLabel.unknown': msg('Something went wrong'),
250
- 'operations.error.invalidInput': msg('Input for “{operation}” is invalid.', '{operation} is a dotted operation name, e.g. documents.upsert.'),
250
+ 'operations.error.invalidInput': msg('Input for “{operation}” is invalid.', '{operation} is a dotted operation name, e.g. documents.patch.'),
251
251
  'operations.error.notFound': msg('No {entity} found for “{target}”.', '{entity} is a machine kind (project/page/cms-document); {target} is its key.'),
252
252
  'operations.error.conflict': msg('“{target}” conflicts with an existing record.'),
253
+ 'operations.error.revisionConflict': msg('“{target}” changed since you loaded it (now at revision {revision}) — reload it and apply your change again.', 'EC-595: a whole-document write or a publish met a newer revision; {revision} is a number.'),
254
+ 'operations.error.revisionConflictGone': msg('“{target}” no longer exists — it was deleted since you loaded it.'),
255
+ 'operations.error.documentExists': msg('“{target}” already exists — creating a document never overwrites one.', 'EC-578: a create (insert-if-absent) found the id taken.'),
256
+ 'operations.error.singletonExists': msg('“{collection}” already has its document “{target}” — open it instead of creating another.', 'EC-595: two sessions opened an empty singleton; the other one created it first.'),
257
+ 'operations.error.patchConflictOne': msg('{count} change to “{target}” was refused: the same field was changed since you loaded the document.', 'EC-595: per-field refusal; the rest of the save applied.'),
258
+ 'operations.error.patchConflict': msg('{count} changes to “{target}” were refused: the same fields were changed since you loaded the document.'),
253
259
  'operations.error.backendUnavailable': msg('The persistence backend is unavailable.'),
254
260
  'operations.error.unauthorized': msg('Operation “{operation}” was denied by the authorization hook.'),
255
261
  'operations.error.unknown': msg('An unknown operation failure occurred.'),
@@ -258,6 +264,11 @@ const MESSAGES = {
258
264
  'operations.error.strictReferencesBlockDeleteOne': msg('Cannot delete “{target}”: {count} document references it through strict relation fields — {named}. Remove these references first.'),
259
265
  'operations.error.strictReferencesBlockUnpublish': msg('Cannot unpublish “{target}”: {count} documents reference it through strict relation fields — {named}{more}. Remove these references first.'),
260
266
  'operations.error.strictReferencesBlockUnpublishOne': msg('Cannot unpublish “{target}”: {count} document references it through strict relation fields — {named}. Remove these references first.'),
267
+ // EC-589 — the referrer direction of `strict: true`: publish refused while a strict target is missing or unpublished.
268
+ 'operations.error.strictTargetsUnpublishedOne': msg('Document “{target}” cannot be published: a strict relation target is missing or unpublished — publish it first.'),
269
+ 'operations.error.strictTargetsUnpublished': msg('Document “{target}” cannot be published: strict relation targets are missing or unpublished — publish them first.'),
270
+ 'operations.error.publishNeedsLocales': msg('“{target}” cannot be published: its collection declares localized fields ({fields}), and no locale config was given to judge their hidden values in.', 'EC-585: a headless runtime publishing a localized collection without the project locale config; {fields} is a comma-separated list of field names.'),
271
+ 'operations.error.versionNotPinnable': msg('Version {version} of “{target}” was not recorded by a publish, so it cannot be pinned live — restore it into the draft and publish that instead.', 'EC-585: only a version a publish recorded can be re-pinned; {version} is a number.'),
261
272
  'operations.errorDetail.andMore': msg(', and {count} more', 'Truncation fragment spliced into the strict-reference sentences; keeps its leading comma and space.'),
262
273
  // EC-494 — content-query errors (`core/content`'s validateWhere/validateSort/
263
274
  // validateLimit). Two studio surfaces render them: the filter builder's per-clause
@@ -419,7 +430,6 @@ const MESSAGES = {
419
430
  'cms.editor.saveFailed': msg('Save failed'),
420
431
  'cms.editor.unsavedChanges': msg('Unsaved changes'),
421
432
  'cms.editor.saved': msg('Saved'),
422
- 'cms.editor.saving': msg('Saving…'),
423
433
  // 0.0.42 (round 3): the standalone "View live" button is retired — opening the live
424
434
  // page now hangs off the header URL row's leaf segment. These strings still drive the
425
435
  // leaf's tooltip (open-live target + the published-gating reasons).
@@ -456,11 +466,6 @@ const MESSAGES = {
456
466
  'cms.editor.loadingPublishedVersion': msg('Loading the published version…'),
457
467
  'cms.editor.noPublishedVersion': msg('No published version found for this document.'),
458
468
  'cms.editor.unsavedChangesGuard': msg('You have unsaved changes to this record. Save them before leaving, or discard them.'),
459
- 'cms.editor.publishUnpublishedRefsTitle': msg('Publish with unpublished references?'),
460
- 'cms.editor.publishUnpublishedRefsDescription': msg('This page references content that isn’t published yet — those sections will be empty on the live site until you publish it too.'),
461
- 'cms.editor.publishAlsoHasIssues.one': msg('This page also has {count} other unresolved issue — see the Issues tab.'),
462
- 'cms.editor.publishAlsoHasIssues.other': msg('This page also has {count} other unresolved issues — see the Issues tab.'),
463
- 'cms.editor.publishAnyway': msg('Publish anyway'),
464
469
  'cms.editor.readOnlyBadge': msg('read-only'),
465
470
  // EC-318 — connected fields: the per-field localization connection affordance that
466
471
  // replaces EC-176's passive "showing EN" text. Shown only on a localized field in a
@@ -478,8 +483,6 @@ const MESSAGES = {
478
483
  'cms.editor.detailsPane': msg('Details'),
479
484
  'cms.editor.servedAt': msg('Served at {path}'),
480
485
  'cms.editor.slugUrlHint': msg('The URL is derived from the slug (and parent) — set a slug to define it.'),
481
- 'cms.editor.embedUnpublishedIssue': msg('Embeds the reusable “{title}”, which isn’t published — it will be empty on the live site until you publish it.'),
482
- 'cms.editor.embedMissingIssue': msg('Embeds a reusable that no longer exists (“{id}”) — fix or remove the embed.'),
483
486
  'cms.editor.defaultGroup': msg('Fields', 'Title of the implicit fieldset that holds ungrouped fields.'),
484
487
  // ─────────────────────────────────────────────────────────────────────────
485
488
  // CMS — issues pane (validation)
@@ -508,6 +511,7 @@ const MESSAGES = {
508
511
  'cms.issue.missing-localized-value': msg('Missing translation'),
509
512
  'cms.issue.route-conflict': msg('Conflicting URL'),
510
513
  'cms.issue.redirect-loop': msg('Redirect loop'),
514
+ 'cms.issue.invalid-redirect': msg('Duplicate redirect'),
511
515
  'cms.issue.unknown-route-target': msg('Missing page'),
512
516
  'cms.issue.hierarchy-cycle': msg('Page nesting loop'),
513
517
  'cms.issue.document-nesting-depth': msg('Content nested too deeply'),
@@ -519,6 +523,7 @@ const MESSAGES = {
519
523
  'cms.issue.hidden-predicate-error': msg('Broken visibility rule'),
520
524
  'cms.issue.unaddressable-url': msg('Unreachable URL'),
521
525
  'cms.issue.unknown-version': msg('Unknown version'),
526
+ 'cms.issue.invalid-stored-document': msg('Unreadable stored document', 'EC-585: a stored row the delivery snapshot shipped is not a valid document, so it is not delivered.'),
522
527
  // EC-443 — issue-card BODY templates, only for codes whose full body derives
523
528
  // from `code` + `path`/`meta` (`issue-copy.ts`); every other code shows the
524
529
  // raw English core message (honest fallback).
@@ -560,6 +565,8 @@ const MESSAGES = {
560
565
  'cms.issueMessage.relationWrongCollection': msg('Relation field "{field}" points at collection "{got}" but targets "{target}".'),
561
566
  'cms.issueMessage.relationMissingDocument': msg('Relation field "{field}" references missing document "{id}" in "{target}".'),
562
567
  'cms.issueMessage.relationUnpublishedDocument': msg('Relation field "{field}" references unpublished document "{id}" in "{target}" — the published site shows a fallback there.'),
568
+ // EC-589 — a strict relation (field, sub-field or prop) to an unpublished target blocks publishing the referrer.
569
+ 'cms.issueMessage.relationStrictUnpublished': msg('Relation field "{field}" is strict: "{id}" in "{target}" is not published, so this document cannot be published until it is.'),
563
570
  'cms.issueMessage.assetNoAssetCollection': msg('Asset field "{field}" requires an asset collection, but none is registered.'),
564
571
  'cms.issueMessage.assetSingleValued': msg('Asset field "{field}" is single-valued but has {count} targets.'),
565
572
  'cms.issueMessage.assetExpectsId': msg('Asset field "{field}" expects an asset id.'),
@@ -572,7 +579,23 @@ const MESSAGES = {
572
579
  'cms.issueMessage.preConvergenceV1': msg('Field "{field}" holds a pre-convergence content shape (the v1 "{ version, doc }" envelope) — the engine reads only the converged "{ version: 2, content }" sequence. Re-seed this content.'),
573
580
  'cms.issueMessage.preConvergenceBareBlocks': msg('Field "{field}" holds a pre-convergence content shape (a bare composition node list) — the engine reads only the converged "{ version: 2, content }" sequence. Re-seed this content.'),
574
581
  'cms.issueMessage.preConvergencePlaintext': msg('Field "{field}" holds a pre-convergence content shape (legacy plain text) — the engine reads only the converged "{ version: 2, content }" sequence. Re-seed this content.'),
575
- 'cms.issueMessage.noValidationSession': msg('No validation session is mounted — refusing to publish unvalidated.', 'EC-546: the publish gate\'s refusal when no CMS session is mounted to validate with; a host-level rule, not a finding about the document.'),
582
+ 'cms.issueMessage.gateUnknownCollection': msg('The project declares no collection “{collection}” — there are no rules to publish it by.', 'EC-595 A2 (F23): the publish gate refuses a document of a collection the project config does not declare. {collection} is the collection id.'),
583
+ 'cms.issueMessage.gateAssetLibraryUnready': msg('The asset library could not be read — refusing to publish unverified asset references. Try again.', 'EC-595 A2 (EC-588, ruled 1f): the publish gate could not read the asset library, so a document that references assets is refused instead of published with the asset checks off.'),
584
+ 'cms.issueMessage.gateNoLocales': msg('The project declares no locales — refusing to publish without them.', 'EC-595 A2: the publish gate refuses when the project config declares no locales (the storage key of every localized value).'),
585
+ // EC-595 A2 — the per-field conflict and the thin field presence.
586
+ 'cms.conflict.changedBy': msg('Changed by {name} since you started editing — your text is kept here until you choose.', 'EC-595 A2: a field this session changed was changed by someone else first; the store refused only this field. {name} is a colleague\'s name, or "someone else" / "you (in another tab)".'),
587
+ 'cms.conflict.removedBy': msg('Removed by {name} since you started editing — your change has nothing to apply to.', 'EC-595 A2: the element (a canvas block) this session changed was removed by someone else first. {name} as above.'),
588
+ 'cms.conflict.theirs': msg('Theirs: {value}', 'EC-595 A2: a preview of the value now stored in the conflicted field. {value} is the value or a placeholder ("empty", "a structured value").'),
589
+ 'cms.conflict.takeTheirs': msg('Take theirs', 'EC-595 A2: button — drop your change of this field and show the stored value.'),
590
+ 'cms.conflict.keepMine': msg('Keep mine', 'EC-595 A2: button — write your value of this field again, over theirs, deliberately.'),
591
+ 'cms.conflict.someoneElse': msg('someone else', 'EC-595 A2: {name} when the colleague who changed a field is not known by name.'),
592
+ 'cms.conflict.youInAnotherTab': msg('you (in another tab)', 'EC-595 A2: {name} when the change came from the same user in another browser tab.'),
593
+ 'cms.conflict.empty': msg('(empty)', 'EC-595 A2: {value} when the stored value is empty.'),
594
+ 'cms.conflict.structured': msg('a structured value', 'EC-595 A2: {value} when the stored value is not plain text (an object, a list, rich text).'),
595
+ 'cms.conflict.cellRefused': msg('This field was changed by someone else since you loaded it — their value is shown.', 'EC-595 A2: a table cell or bulk edit refused because the field changed meanwhile; the stored value is kept.'),
596
+ 'cms.presence.inField': msg('{name} is in this field', 'EC-595 A2 thin presence: another session has this field focused. {name} is their name.'),
597
+ 'cms.presence.inFieldMany': msg('{names} are in this field', 'EC-595 A2 thin presence: several sessions have this field focused. {names} is a comma-separated list of names.'),
598
+ 'cms.presence.someone': msg('Someone', 'EC-595 A2 thin presence: the name of a present session that carries no name.'),
576
599
  'cms.issueMessage.richTextHoldsObject': msg('Rich-text field "{field}" expects a rich-text value ("{ version: 2, content }") but holds an object with keys "{keys}".'),
577
600
  'cms.issueMessage.unknownCollectionForDocument': msg('Document "{id}" references unknown collection "{collection}".'),
578
601
  'cms.issueMessage.localizedPlainValue': msg('Localized field "{field}" holds a plain value in the shared "values" bag — expected per-locale values under "localized.<locale>.{field}". The plain value serves only as a last-resort fallback.'),
@@ -599,13 +622,15 @@ const MESSAGES = {
599
622
  'cms.issueMessage.unknownVersion': msg('No version {version} recorded for document "{id}".'),
600
623
  'cms.issueMessage.routeConflict': msg('Routes "{first}" and "{second}" both match the same URLs (pattern "{pattern}").'),
601
624
  'cms.issueMessage.redirectLoop': msg('Redirect chain starting at "{from}" loops (…{chain}).'),
625
+ 'cms.issueMessage.duplicateRedirect': msg('Redirect "{redirect}" (from "{redirectFrom}") duplicates redirect "{kept}" (from "{keptFrom}") — both are "{from}" once trailing slashes are ignored. "{kept}" applies; delete or change the other.'),
602
626
  'cms.issueMessage.allDynamicShadowsMount': msg('Route "{route}" ("{pattern}") has only dynamic segments, so it matches EVERY {depth}-segment URL — hierarchy mount "{mountRoute}" ("{mountPattern}") is consulted at that depth only where the route resolves no document. Nothing is unconditionally unreachable, but precedence there is decided by CONTENT rather than by the routes: {shadowed} are silently shadowed wherever a composed path collides with {claimed}, and neither side is told. Give the route a static prefix ("/blog/:slug") so it claims a namespace instead of a whole depth.'),
603
627
  'cms.issueMessage.mountCannotServe': msg('Hierarchy mount "{route}" ("{pattern}") can never serve a document: {why}. The resolver skips such a mount silently, so every URL under "{space}" 404s with no issue raised.'),
604
628
  'cms.issueMessage.deadCatchAll': msg('Route "{route}" ("{pattern}") serves nothing in either direction: it ends in a catch-all, so every router drops it, but its prefix has a dynamic segment ({dynamic}), so no hierarchy mount is built for it either. A mount\'s prefix must be static — declare one mount per locale (`{ pattern: \'/de/:path*\', locale: \'de\' }`), or drop the route.'),
605
- 'cms.issueMessage.mountConflict': msg('{opening} — mounts resolve in declaration order, not by specificity, so "{earlier}" (collection "{earlierCollection}") claims every URL there its own tree resolves, and "{laterCollection}" documents at those URLs are unreachable.'),
629
+ 'cms.issueMessage.mountConflict': msg('{opening} — an exact tie, separated only by declaration order, so "{earlier}" (collection "{earlierCollection}") claims every URL there its own tree resolves, and "{laterCollection}" documents at those URLs are unreachable.'),
606
630
  'cms.issueMessage.routeBoundDocumentNotFound': msg('Route-bound document "{collection}:{id}" was not found.'),
607
631
  'cms.issueMessage.routeParamNotCaptured': msg('Route "{route}" binds its document to URL parameter ":{param}", which pattern "{pattern}" does not capture.'),
608
632
  'cms.issueMessage.collectionNotDefined': msg('Collection "{collection}" is not defined.'),
633
+ 'cms.issueMessage.storedDocumentUnreadable': msg('Stored document {document} could not be read and is not delivered ({reason}).', 'EC-585 (Codex F12): {document} is collection:id (or #index), {reason} the schema findings in English.'),
609
634
  'cms.issueMessage.unaddressableLocaleCollision': msg('No URL reaches "{id}" in locale "{locale}": its address would be "{url}", but the first segment "{segment}" is a declared locale code, so the site reads that URL as locale "{segment}", path "{readPath}". Rename that segment — on this document or on the ancestor that owns it — so it does not collide with a locale code.'),
610
635
  'cms.issueDetail.expectsString': msg('expects a string'),
611
636
  'cms.issueDetail.expectsRichText': msg('expects rich-text content (a string or a rich-text value)'),
@@ -637,7 +662,6 @@ const MESSAGES = {
637
662
  'cms.issueDetail.mountCollectionNotDeclared': msg('collection "{collection}" is not declared'),
638
663
  'cms.issueDetail.mountCollectionNotHierarchical': msg('collection "{collection}" has no `parent` self-relation, so it has no nested paths to compose'),
639
664
  'cms.issueDetail.mountsSamePath': msg('Hierarchy mounts "{earlier}" ("{earlierPattern}") and "{later}" ("{laterPattern}") are both mounted at "{space}"'),
640
- 'cms.issueDetail.mountsNested': msg('Hierarchy mount "{later}" ("{laterPattern}") is nested inside "{earlier}" ("{earlierPattern}"), which is declared first and claims all of "{space}" too'),
641
665
  // ─────────────────────────────────────────────────────────────────────────
642
666
  // CMS — details pane (slot + sidebar fields)
643
667
  // ─────────────────────────────────────────────────────────────────────────
@@ -688,6 +712,9 @@ const MESSAGES = {
688
712
  'cms.version.textUnchanged': msg('Text unchanged — formatting or whitespace differs.'),
689
713
  'cms.version.restoreBlock': msg('Restore this block from v{version}'),
690
714
  'cms.version.nestedContentChanged': msg('Nested content changed.'),
715
+ // EC-593 — where a nested component's diff row sits.
716
+ 'cms.version.nestedInProse': msg('in the text'),
717
+ 'cms.version.nestedIn': msg('inside {path}', '{path} lists component names, e.g. "Section › Grid".'),
691
718
  'cms.version.blockAdded': msg('Block added.'),
692
719
  'cms.version.blockRemoved': msg('Block removed.'),
693
720
  'cms.version.emptyValue': msg('empty'),
@@ -788,7 +815,17 @@ const MESSAGES = {
788
815
  'cms.asset.altLabel': msg('Alt:', 'Inline label prefixing an image’s alt text.'),
789
816
  'cms.asset.notSet': msg('not set'),
790
817
  'cms.asset.imageOptions.title': msg('Image options'),
791
- 'cms.asset.imageOptions.description': msg('Focal point and metadata — shared across every use of this image.'),
818
+ 'cms.asset.imageOptions.description': msg('What belongs to this use of the image, apart from what is true of the image everywhere.'),
819
+ 'cms.asset.imageOptions.placementTitle': msg('In this place', 'Image options dialog: the section of per-use (placement) fields, e.g. a caption.'),
820
+ 'cms.asset.imageOptions.placementHint': msg('Only this use of the image — another page can show it differently.'),
821
+ 'cms.asset.imageOptions.assetTitle': msg('About this image', 'Image options dialog: the section of the asset’s own facts (alt text, credit, focal point).'),
822
+ 'cms.asset.imageOptions.assetHint': msg('Applies everywhere this image is used — a change here changes every use.'),
823
+ 'cms.asset.imageOptions.whereUsed': msg('Where it is used'),
824
+ 'cms.asset.replaceFile': msg('Replace file', 'Asset action: upload new bytes into the SAME asset — every use shows the new file.'),
825
+ 'cms.asset.replacing': msg('Replacing…'),
826
+ 'cms.asset.replaceWrongKind': msg('“{name}” not used — a replacement must be {types}, like the current file.'),
827
+ 'cms.asset.replaceSaveFirst': msg('Save or discard the metadata changes first.'),
828
+ 'cms.asset.replacedCheckFocal': msg('The file was replaced — check that the focal point still frames the subject.'),
792
829
  'cms.asset.focalPoint': msg('Focal point'),
793
830
  'cms.asset.resetToCentre': msg('Reset to centre'),
794
831
  'cms.asset.focalPointHint': msg('Click or drag on the image to set the focal point used when it’s cropped.'),
@@ -1066,6 +1103,12 @@ const MESSAGES = {
1066
1103
  // EC-554 — the composition FIELD's top-level `allow` refuses the pasted root.
1067
1104
  'builder.clipboard.notAllowedByField': msg('{component} cannot be pasted at the top level of "{field}" — the field does not allow it.', '{component} is the pasted root’s short component name (e.g. “Container”); {field} is the composition field’s label (e.g. “Canvas”).'),
1068
1105
  'builder.clipboard.issueComponent': msg('component'),
1106
+ // EC-584 — a refused placement: the builder reducer ran the one placement judge and
1107
+ // left the composition unchanged. Shown above the canvas (and for a refused paste).
1108
+ 'builder.placement.notAllowedByField': msg('{component} is not allowed at the top level of "{field}" — the field does not allow it. Nothing changed.', '{component} is the component’s short name (e.g. “Hero”); {field} is the composition field’s label (e.g. “Canvas”).'),
1109
+ 'builder.placement.notAllowedInSlot': msg('{component} is not allowed in {destination} — the slot does not allow it. Nothing changed.', '{component} is the component’s short name; {destination} is “Parent · slot” (e.g. “Section · body”).'),
1110
+ 'builder.placement.serverOnly': msg('{component} renders on the server only and cannot be placed on the canvas. Nothing changed.', 'EC-191: a component declared clientRenderable: false — usable in page/layout code, not in an editor composition.'),
1111
+ 'builder.placement.dismiss': msg('Dismiss'),
1069
1112
  // EC-494 — the engine-built clipboard failures (`core/clipboard`), which carry a
1070
1113
  // catalog ref because that subpath may not import this catalog, plus the studio-side
1071
1114
  // paste diff and its summary (translated in place — it already holds the locale).
@@ -1105,7 +1148,6 @@ const MESSAGES = {
1105
1148
  'builder.inspector.slots': msg('Slots'),
1106
1149
  'builder.inspector.slotsHint': msg('Add or reorder slot children from the page tree.'),
1107
1150
  'builder.inspector.propertiesPane': msg('Properties'),
1108
- 'builder.inspector.invalidValue': msg('Value doesn’t match the prop schema — the component renders its own default until it is fixed.'),
1109
1151
  'builder.inspector.invalidJson': msg('Invalid JSON'),
1110
1152
  'builder.layout.title': msg('Layout'),
1111
1153
  'builder.layout.direction': msg('Direction'),
@@ -1156,7 +1198,13 @@ const MESSAGES = {
1156
1198
  // Mixed-sequence honesty notice (EC-549 interim): a blocks value carrying
1157
1199
  // typography items the canvas cannot render yet must SAY so — count + pointer,
1158
1200
  // never silence (EC-500 D3's canvas contract, scope item 3).
1159
- 'builder.composition.preservedNotice': msg('This composition carries {count} text item(s) the canvas can’t display yet. They keep their position between the blocks, are untouched by canvas edits, and publish normally.', '{count} is the number of preserved non-component sequence items (prose paragraphs, quotes, …).'),
1201
+ // EC-549 — a typography run of a canvas value (loose prose between blocks): selected,
1202
+ // edited in the inspector's rich-text editor, deleted like a block. It replaced the
1203
+ // count-only `builder.composition.preservedNotice`.
1204
+ 'builder.run.title': msg('Text', 'Inspector title for a selected run of loose prose (paragraphs, quotes, lists) between blocks.'),
1205
+ 'builder.run.items': msg('{count} item(s)', '{count} is the number of typography items (paragraphs, headings, quotes…) in the run.'),
1206
+ 'builder.run.hint': msg('Written text between the blocks — edit it here; it keeps its place between the blocks and publishes as it reads.'),
1207
+ 'builder.run.delete': msg('Delete text'),
1160
1208
  'builder.spacing.gapAfterChild': msg('Gap after child {index}'),
1161
1209
  'builder.richText.toolbarLabel': msg('Text formatting'),
1162
1210
  'builder.richText.linkPlaceholder': msg('https://… (empty removes)'),
@@ -1293,6 +1341,11 @@ const MESSAGES = {
1293
1341
  'ai.translate.proposalTitle': msg('Translation of {collection}'),
1294
1342
  'ai.translate.diffBefore': msg('Current'),
1295
1343
  'ai.translate.diffAfter': msg('Translated'),
1344
+ // EC-593 — what a translation run could not translate is reported, never skipped silently.
1345
+ 'ai.translate.skippedTitle': msg('Not translated ({count})', '{count} is a number.'),
1346
+ 'ai.translate.skipped.unreadable': msg('its stored value could not be read'),
1347
+ 'ai.translate.skipped.notReturned': msg('the assistant returned no text for it'),
1348
+ 'ai.translate.skipped.structureChanged': msg('the translation lost formatting, links or embedded items — the original was kept'),
1296
1349
  // EC-378 — the update (edit-existing) proposal
1297
1350
  'ai.update.proposalTitle': msg('Changes to {collection}'),
1298
1351
  'ai.update.diffBefore': msg('Current'),
@@ -1309,7 +1362,14 @@ const MESSAGES = {
1309
1362
  // EC-586 / EC-581 (wave-0092, zone A) — canonical values and the per-FieldType definition
1310
1363
  'cms.issueMessage.nonCanonicalValue': msg('Field "{field}" is stored in a non-canonical form for a "{type}" field — it was written past the write path that stores one form per field type. It still reads correctly; saving the document again stores the canonical form.'),
1311
1364
  'cms.issueMessage.assetHoldsUrl': msg('Asset field "{field}" holds a URL — an asset value is a library asset, never a URL. Upload the image to the library and pick it, or give a component a literal src for an external image.'),
1365
+ // EC-584 — the AllowList parse (config load / registration).
1366
+ 'cms.issueMessage.emptyAllow': msg('Field "{field}" declares an empty "allow" — a list permits exactly the ids it names, so an empty one permits nothing. Omit "allow" for the type\'s default vocabulary, or list the component ids.'),
1367
+ 'cms.issueMessage.unknownAllowComponent': msg('Field "{field}" allows "{component}", which is not a component of this project — check the id, or remove it from "allow".', '{component} is the component id as declared in the field\'s allow list.'),
1312
1368
  'cms.issueMessage.blocksNotTopLevel': msg('Field "{field}" is a "blocks" field inside an object — a blocks field is top-level only (a canvas inside a repeater breaks the form, the validator positions and the delivery type). Declare another top-level blocks field, or give a component a blocks prop (a slot).'),
1369
+ 'cms.issueMessage.placementKeyReserved': msg('Asset field "{asset}" declares the per-use sub-field "{field}", a name the asset itself owns — it would never reach a component (the asset\'s own "{field}" wins). Rename it; an image\'s alt, credit or AI fact belongs on the asset collection.'),
1370
+ 'cms.issueMessage.placementNotScalar': msg('Asset field "{asset}" declares the per-use sub-field "{field}" of type "{type}" — a placement holds data about this use of the image (a caption, a layout), never a reference or rich text.'),
1371
+ 'cms.issueMessage.sourceNotOnAssetCollection': msg('Field "{field}" declares source "{source}" — an embedded-metadata source fills a top-level field of the asset collection only.'),
1372
+ 'cms.issueMessage.sourceTypeMismatch': msg('Field "{field}" declares source "{source}", which cannot fill a "{type}" field (every source fills text; iptc:digitalSourceType also a boolean).'),
1313
1373
  'cms.issueMessage.uniqueNotTopLevel': msg('Sub-field "{field}" declares "unique" — uniqueness is judged across a collection\'s documents, so it applies to top-level fields only.'),
1314
1374
  'cms.issueMessage.localizedOnProp': msg('Component prop "{field}" declares "localized" — a localized value is stored per locale under the document, so only a top-level document field can be localized (localize the field that holds the composition).'),
1315
1375
  'cms.issueMessage.localizedOnSubField': msg('Sub-field "{field}" declares "localized" — a localized value is stored per locale under the document, so only a top-level field can be localized (localize the field that holds it).'),