@elytracms/studio 0.0.100 → 0.0.101

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 (124) hide show
  1. package/convex/analytics-cost.test.ts +1 -1
  2. package/convex/redirect-migration.test.ts +1 -1
  3. package/convex/redirects.ts +2 -2
  4. package/convex/shared-capture.convex.test.ts +165 -0
  5. package/dist/components/ai/ai-chat-panel-lazy.js +7 -2
  6. package/dist/components/ai/ai-chat-panel-lazy.js.map +1 -1
  7. package/dist/components/ai/proposal-card.js +2 -1
  8. package/dist/components/ai/proposal-card.js.map +1 -1
  9. package/dist/components/ai/proposal-unfilled.d.ts +14 -0
  10. package/dist/components/ai/proposal-unfilled.js +33 -0
  11. package/dist/components/ai/proposal-unfilled.js.map +1 -0
  12. package/dist/components/ai/translate-document-action.js +8 -6
  13. package/dist/components/ai/translate-document-action.js.map +1 -1
  14. package/dist/components/app-views/studio-config.d.ts +12 -12
  15. package/dist/components/app-views/studio-config.js.map +1 -1
  16. package/dist/components/builder/builder-store.d.ts +37 -1
  17. package/dist/components/builder/builder-store.js +21 -6
  18. package/dist/components/builder/builder-store.js.map +1 -1
  19. package/dist/components/builder/canvas-chrome-css.d.ts +1 -1
  20. package/dist/components/builder/canvas-chrome-css.js +1 -1
  21. package/dist/components/builder/canvas-chrome-css.js.map +1 -1
  22. package/dist/components/builder/canvas-chrome.d.ts +1 -1
  23. package/dist/components/builder/canvas-chrome.js +1 -1
  24. package/dist/components/builder/canvas-chrome.js.map +1 -1
  25. package/dist/components/builder/canvas-rebase.d.ts +4 -4
  26. package/dist/components/builder/canvas-rebase.js +3 -2
  27. package/dist/components/builder/canvas-rebase.js.map +1 -1
  28. package/dist/components/builder/canvas-render-context.d.ts +1 -1
  29. package/dist/components/builder/canvas-render-context.js +1 -1
  30. package/dist/components/builder/canvas-render-context.js.map +1 -1
  31. package/dist/components/builder/composition-field-editor-lazy.js +2 -1
  32. package/dist/components/builder/composition-field-editor-lazy.js.map +1 -1
  33. package/dist/components/builder/reuse-context.d.ts +8 -2
  34. package/dist/components/builder/reuse-context.js +62 -7
  35. package/dist/components/builder/reuse-context.js.map +1 -1
  36. package/dist/components/builder/reuse.d.ts +106 -70
  37. package/dist/components/builder/reuse.js +125 -108
  38. package/dist/components/builder/reuse.js.map +1 -1
  39. package/dist/components/cms/cms-store.d.ts +9 -1
  40. package/dist/components/cms/cms-store.js +1 -0
  41. package/dist/components/cms/cms-store.js.map +1 -1
  42. package/dist/components/cms/detail-editor.js +13 -13
  43. package/dist/components/cms/detail-editor.js.map +1 -1
  44. package/dist/components/cms/prop-fields.js +1 -1
  45. package/dist/components/cms/prop-fields.js.map +1 -1
  46. package/dist/components/cms/rich-text/lazy.js +2 -1
  47. package/dist/components/cms/rich-text/lazy.js.map +1 -1
  48. package/dist/components/cms/rich-text/toolbar-state.d.ts +1 -1
  49. package/dist/components/cms/rich-text/toolbar-state.js +1 -1
  50. package/dist/components/cms/rich-text/toolbar-state.js.map +1 -1
  51. package/dist/components/cms/use-field-focus.js +3 -3
  52. package/dist/components/cms/use-field-focus.js.map +1 -1
  53. package/dist/components/cms/version-compare-lazy.js +2 -1
  54. package/dist/components/cms/version-compare-lazy.js.map +1 -1
  55. package/dist/components/components/components-index.js +1 -1
  56. package/dist/components/components/components-index.js.map +1 -1
  57. package/dist/components/deployment-setup-gate.d.ts +1 -1
  58. package/dist/components/deployment-setup-gate.js +1 -1
  59. package/dist/components/deployment-setup-gate.js.map +1 -1
  60. package/dist/components/load-failure.d.ts +62 -0
  61. package/dist/components/load-failure.js +110 -0
  62. package/dist/components/load-failure.js.map +1 -0
  63. package/dist/components/notifications/shell-findings.js +3 -3
  64. package/dist/components/notifications/shell-findings.js.map +1 -1
  65. package/dist/customization.d.ts +3 -3
  66. package/dist/customization.js.map +1 -1
  67. package/dist/lib/ai/apply-content.js +99 -28
  68. package/dist/lib/ai/apply-content.js.map +1 -1
  69. package/dist/lib/ai/chat-context.d.ts +73 -7
  70. package/dist/lib/ai/chat-context.js +133 -14
  71. package/dist/lib/ai/chat-context.js.map +1 -1
  72. package/dist/lib/ai/chat-state.d.ts +7 -1
  73. package/dist/lib/ai/chat-state.js.map +1 -1
  74. package/dist/lib/ai/constraints.d.ts +5 -0
  75. package/dist/lib/ai/constraints.js +21 -6
  76. package/dist/lib/ai/constraints.js.map +1 -1
  77. package/dist/lib/ai/fake-provider.d.ts +76 -26
  78. package/dist/lib/ai/fake-provider.js +210 -66
  79. package/dist/lib/ai/fake-provider.js.map +1 -1
  80. package/dist/lib/ai/index.d.ts +1 -0
  81. package/dist/lib/ai/index.js +1 -0
  82. package/dist/lib/ai/index.js.map +1 -1
  83. package/dist/lib/ai/keyless-assistant.d.ts +37 -0
  84. package/dist/lib/ai/keyless-assistant.js +193 -0
  85. package/dist/lib/ai/keyless-assistant.js.map +1 -0
  86. package/dist/lib/ai/shape.d.ts +25 -2
  87. package/dist/lib/ai/shape.js +58 -7
  88. package/dist/lib/ai/shape.js.map +1 -1
  89. package/dist/lib/ai/tools.d.ts +11 -1
  90. package/dist/lib/ai/tools.js +51 -6
  91. package/dist/lib/ai/tools.js.map +1 -1
  92. package/dist/lib/ai/translate-document.js +6 -5
  93. package/dist/lib/ai/translate-document.js.map +1 -1
  94. package/dist/lib/ai/types.d.ts +22 -7
  95. package/dist/lib/ai/types.js.map +1 -1
  96. package/dist/lib/ai/update-fields.js +9 -6
  97. package/dist/lib/ai/update-fields.js.map +1 -1
  98. package/dist/lib/ai/writer-form.d.ts +11 -3
  99. package/dist/lib/ai/writer-form.js +105 -18
  100. package/dist/lib/ai/writer-form.js.map +1 -1
  101. package/dist/lib/auth-errors.d.ts +1 -1
  102. package/dist/lib/auth-errors.js +1 -1
  103. package/dist/lib/auth-errors.js.map +1 -1
  104. package/dist/lib/engine-version.d.ts +1 -1
  105. package/dist/lib/engine-version.js +1 -1
  106. package/dist/lib/engine-version.js.map +1 -1
  107. package/dist/lib/i18n/messages.de.d.ts +1 -1
  108. package/dist/lib/i18n/messages.de.js +23 -7
  109. package/dist/lib/i18n/messages.de.js.map +1 -1
  110. package/dist/lib/i18n/messages.en.d.ts +18 -3
  111. package/dist/lib/i18n/messages.en.js +29 -9
  112. package/dist/lib/i18n/messages.en.js.map +1 -1
  113. package/dist/lib/operations/cms-persistence.d.ts +18 -0
  114. package/dist/lib/operations/cms-persistence.js +47 -0
  115. package/dist/lib/operations/cms-persistence.js.map +1 -1
  116. package/dist/lib/workspace/index.d.ts +3 -3
  117. package/dist/lib/workspace/index.js +3 -3
  118. package/dist/lib/workspace/index.js.map +1 -1
  119. package/dist/router/navigate-once.d.ts +1 -1
  120. package/dist/router/navigate-once.js.map +1 -1
  121. package/dist/router/root.d.ts +3 -2
  122. package/dist/router/root.js +25 -4
  123. package/dist/router/root.js.map +1 -1
  124. package/package.json +3 -3
@@ -111,6 +111,14 @@ declare const MESSAGES: {
111
111
  'shell.backToProjects': import("./types.js").SourceMessage;
112
112
  'shell.routeNotFound.title': import("./types.js").SourceMessage;
113
113
  'shell.routeNotFound.body': import("./types.js").SourceMessage;
114
+ 'shell.failure.module.title': import("./types.js").SourceMessage;
115
+ 'shell.failure.module.body': import("./types.js").SourceMessage;
116
+ 'shell.failure.module.restartHint': import("./types.js").SourceMessage;
117
+ 'shell.failure.error.title': import("./types.js").SourceMessage;
118
+ 'shell.failure.error.body': import("./types.js").SourceMessage;
119
+ 'shell.failure.back': import("./types.js").SourceMessage;
120
+ 'shell.failure.reload': import("./types.js").SourceMessage;
121
+ 'shell.failure.reloadCost': import("./types.js").SourceMessage;
114
122
  'shell.projectSwitcher.recent': import("./types.js").SourceMessage;
115
123
  'shell.projects': import("./types.js").SourceMessage;
116
124
  'shell.projectSwitcher.browseAll': import("./types.js").SourceMessage;
@@ -161,7 +169,6 @@ declare const MESSAGES: {
161
169
  'builder.reuse.config.ambiguousRelationProp': import("./types.js").SourceMessage;
162
170
  'builder.reuse.config.unknownCollection': import("./types.js").SourceMessage;
163
171
  'builder.reuse.config.noBlocksField': import("./types.js").SourceMessage;
164
- 'builder.reuse.config.ambiguousInference': import("./types.js").SourceMessage;
165
172
  'auth.signIn': import("./types.js").SourceMessage;
166
173
  'auth.signIn.heading': import("./types.js").SourceMessage;
167
174
  'auth.signIn.headingCreate': import("./types.js").SourceMessage;
@@ -852,8 +859,8 @@ declare const MESSAGES: {
852
859
  'components.index.guide.badge': import("./types.js").SourceMessage;
853
860
  'components.index.guide.intro': import("./types.js").SourceMessage;
854
861
  'components.index.guide.doc.authoring': import("./types.js").SourceMessage;
855
- 'components.index.guide.doc.fixtures': import("./types.js").SourceMessage;
856
- 'components.index.guide.doc.extensibility': import("./types.js").SourceMessage;
862
+ 'components.index.guide.doc.components': import("./types.js").SourceMessage;
863
+ 'components.index.guide.doc.guide': import("./types.js").SourceMessage;
857
864
  'components.index.guide.namespaceNote': import("./types.js").SourceMessage;
858
865
  'components.taxonomy.uncategorized': import("./types.js").SourceMessage;
859
866
  'components.detail.tab.preview': import("./types.js").SourceMessage;
@@ -956,6 +963,10 @@ declare const MESSAGES: {
956
963
  'builder.reuse.madeReusablePublished': import("./types.js").SourceMessage;
957
964
  'builder.reuse.madeReusablePublishFailed': import("./types.js").SourceMessage;
958
965
  'builder.reuse.madeReusableDraft': import("./types.js").SourceMessage;
966
+ 'builder.reuse.undoKeptPublished': import("./types.js").SourceMessage;
967
+ 'builder.reuse.undoKeptEdited': import("./types.js").SourceMessage;
968
+ 'builder.reuse.undoKeptReferenced': import("./types.js").SourceMessage;
969
+ 'builder.reuse.undoKeptFailed': import("./types.js").SourceMessage;
959
970
  'builder.reuse.noTargetToDetach': import("./types.js").SourceMessage;
960
971
  'builder.reuse.noContentToDetach': import("./types.js").SourceMessage;
961
972
  'builder.reuse.detachedToCopy': import("./types.js").SourceMessage;
@@ -1149,6 +1160,10 @@ declare const MESSAGES: {
1149
1160
  'ai.update.proposalTitle': import("./types.js").SourceMessage;
1150
1161
  'ai.update.diffBefore': import("./types.js").SourceMessage;
1151
1162
  'ai.update.diffAfter': import("./types.js").SourceMessage;
1163
+ 'ai.create.unfilledTitle': import("./types.js").SourceMessage;
1164
+ 'ai.create.unfilled.empty': import("./types.js").SourceMessage;
1165
+ 'ai.create.unfilled.noCandidates': import("./types.js").SourceMessage;
1166
+ 'ai.create.unfilled.dropped': import("./types.js").SourceMessage;
1152
1167
  'builder.roles.noStack': import("./types.js").SourceMessage;
1153
1168
  'builder.roles.noGrid': import("./types.js").SourceMessage;
1154
1169
  'builder.roles.noText': import("./types.js").SourceMessage;
@@ -126,6 +126,15 @@ const MESSAGES = {
126
126
  'shell.backToProjects': msg('Back to projects'),
127
127
  'shell.routeNotFound.title': msg('Page not found'),
128
128
  'shell.routeNotFound.body': msg('This studio URL doesn’t resolve to a section.'),
129
+ // EC-717 — the failure notice (the root catch-all and each lazily loaded surface).
130
+ 'shell.failure.module.title': msg('This part of the studio could not be loaded', 'Heading of the notice shown when a lazily loaded part of the studio failed to download.'),
131
+ 'shell.failure.module.body': msg('Its code failed to download, usually because the dev server rebuilt its dependency cache while this tab was open. Go back to keep working; this part stays unavailable until the page is reloaded.'),
132
+ 'shell.failure.module.restartHint': msg('If reloading does not help, restart the dev server.'),
133
+ 'shell.failure.error.title': msg('Something went wrong', 'Heading of the notice shown when the studio hit an unexpected error.'),
134
+ 'shell.failure.error.body': msg('The studio hit an unexpected error here. Reloading the page usually recovers.'),
135
+ 'shell.failure.back': msg('Back', 'Button on the failure notice: in-app navigation back, without reloading the page.'),
136
+ 'shell.failure.reload': msg('Reload', 'Button on the failure notice: a full page reload.'),
137
+ 'shell.failure.reloadCost': msg('Reloading empties the playground: everything created or changed in this tab is lost.', 'Shown under the Reload button in playground mode only.'),
129
138
  'shell.projectSwitcher.recent': msg('Recent'),
130
139
  'shell.projects': msg('Projects'),
131
140
  'shell.projectSwitcher.browseAll': msg('Browse all projects'),
@@ -195,16 +204,16 @@ const MESSAGES = {
195
204
  // something. {label} is the developer's own view label (project data, echoed).
196
205
  'customization.issue.derivedIdBuiltinCollision': msg('View "{label}" for "{point}" derives the id "{id}" from its label, which is the built-in "{id}" view — the built-in is kept and this view is ignored. Pass an explicit id to replace a built-in on purpose.', 'Config error at the rail foot (EC-476). {label} is the custom view’s label, {id} the derived id that collides with a built-in view id.'),
197
206
  'customization.issue.derivedIdCollectionCollision': msg('View id "{id}" for "{point}" is ambiguous: it joins the collections {collections} with "-", and a collection is literally named "{joined}" — its own lens derives the same id. Pass an explicit id to this group.', 'Config warning at the rail foot (EC-477). {collections} is a quoted, comma-separated id list; {joined} is those ids joined with "-".'),
198
- // EC-467 — the project's reusable-elements declaration (`defineStudio({ reuse })`).
199
- // "Reusable elements" is the product term for the feature; {component},
200
- // {relationProp}, {collection}, {props}, {components} are identifiers.
201
- 'builder.reuse.config.unknownComponent': msg('Reusable elements: studio config declares reuse.component "{component}", which is not a registered component. Fix the id, or remove the reuse block to let the studio infer the embed.'),
207
+ // EC-467 — the project's reusable-elements declaration (`defineStudio({ reuse })`);
208
+ // EC-728: the only source of the embed (declared, never inferred). "Reusable elements"
209
+ // is the product term for the feature; {component}, {relationProp}, {collection},
210
+ // {props} are identifiers.
211
+ 'builder.reuse.config.unknownComponent': msg('Reusable elements: studio config declares reuse.component "{component}", which is not a registered component. Fix the id to name your embed component — until then the reuse gestures are off.'),
202
212
  'builder.reuse.config.noRelationProp': msg('Reusable elements: the declared embed "{component}" has no single-document relation prop, so it cannot point at a reusable document. An embed needs one relation prop with cardinality one.'),
203
213
  'builder.reuse.config.unknownRelationProp': msg('Reusable elements: the declared embed "{component}" has no single-document relation prop named "{relationProp}". Its relation props are: {props}.', '{props} is a quoted, comma-separated prop-name list.'),
204
214
  'builder.reuse.config.ambiguousRelationProp': msg('Reusable elements: the declared embed "{component}" has {count} single-document relation props ({props}) — add reuse.relationProp to say which one points at the reusable document.', '{count} is a number; {props} a quoted, comma-separated prop-name list.'),
205
215
  'builder.reuse.config.unknownCollection': msg('Reusable elements: "{component}.{relationProp}" targets the collection "{collection}", which this project does not define.'),
206
216
  'builder.reuse.config.noBlocksField': msg('Reusable elements: the collection "{collection}" behind "{component}.{relationProp}" has no blocks (composition) field, so there is nothing for the embed to transclude.'),
207
- 'builder.reuse.config.ambiguousInference': msg('Reusable elements: {count} components have the reusable-embed shape ({components}). A project has exactly one reusable-element embed, so the studio will not guess — declare it in studio.config as reuse: { component: \'<id>\' }. Until then the reuse gestures are off.', 'Config warning at the rail foot. {count} is a number, {components} a quoted, comma-separated component-id list. The literal `reuse: { component: \'<id>\' }` is CODE — keep it verbatim.'),
208
217
  // ─────────────────────────────────────────────────────────────────────────
209
218
  // Auth / errors
210
219
  // ─────────────────────────────────────────────────────────────────────────
@@ -602,7 +611,7 @@ const MESSAGES = {
602
611
  'cms.issueMessage.relationStrictUnpublished': msg('Relation field "{field}" is strict: "{id}" in "{target}" is not published, so this document cannot be published until it is.'),
603
612
  'cms.issueMessage.assetNoAssetCollection': msg('Asset field "{field}" requires an asset collection, but none is registered.'),
604
613
  'cms.issueMessage.assetSingleValued': msg('Asset field "{field}" is single-valued but has {count} targets.'),
605
- 'cms.issueMessage.assetExpectsId': msg('Asset field "{field}" expects an asset id.'),
614
+ 'cms.issueMessage.assetExpectsId': msg("Asset field \"{field}\" expects an asset id, or { type: 'asset', id, …per-use fields } — an object needs type: 'asset'."),
606
615
  'cms.issueMessage.assetUnknown': msg('Asset field "{field}" references unknown asset "{asset}".'),
607
616
  'cms.issueMessage.assetNotAccepted': msg('Asset field "{field}" accepts only {accept}, but asset "{asset}" is {type}.'),
608
617
  'cms.issueMessage.requiredFieldMissing': msg('Required field "{field}" is missing.'),
@@ -1058,10 +1067,10 @@ const MESSAGES = {
1058
1067
  'components.index.byCategory': msg('By category'),
1059
1068
  'components.index.guide.title': msg('Registering & extending components'),
1060
1069
  'components.index.guide.badge': msg('for developers'),
1061
- 'components.index.guide.intro': msg('Components are code, owned by your repo. Register a manifest (prop schemas, defaults, inspector controls, slots, and preview fixtures) and the studio browses, inspects, and previews it. These in-repo guides cover the details:'),
1070
+ 'components.index.guide.intro': msg('Components are code, owned by your repo. Register a manifest (prop schemas, defaults, inspector controls, slots, and preview fixtures) and the studio browses, inspects, and previews it. These guides, in the Elytra engine repository’s docs, cover the details:'),
1062
1071
  'components.index.guide.doc.authoring': msg('How to declare and register a component so the studio can browse, inspect, and preview it.'),
1063
- 'components.index.guide.doc.fixtures': msg('Authoring deterministic preview fixtures — the states shown in this view’s live preview.'),
1064
- 'components.index.guide.doc.extensibility': msg('Extending the platform: custom field types, data sources, export targets, and plugins.'),
1072
+ 'components.index.guide.doc.components': msg('The guide’s components chapter: the manifest + implementation pair, registering the list, fixtures, reusable elements, styling.'),
1073
+ 'components.index.guide.doc.guide': msg('The guide’s overview and chapter index: setup, the config API, delivery, the CLI and environment reference.'),
1065
1074
  'components.index.guide.namespaceNote': msg('Components are the list in your config, with ids you choose (Heading, site.Hero). Elytra’s own components are the opt-in @elytracms/components package — list them, a subset, or none.'),
1066
1075
  'components.taxonomy.uncategorized': msg('Uncategorized'),
1067
1076
  'components.detail.tab.preview': msg('Preview'),
@@ -1181,6 +1190,12 @@ const MESSAGES = {
1181
1190
  'builder.reuse.madeReusablePublished': msg('Made “{name}” reusable and published it.'),
1182
1191
  'builder.reuse.madeReusablePublishFailed': msg('Made “{name}” reusable, but publishing failed — publish it from its document.'),
1183
1192
  'builder.reuse.madeReusableDraft': msg('Made “{name}” reusable (draft) — publish it to show on live pages.'),
1193
+ // EC-728 — Undo of "Make reusable" restored the block; the reusable document it created
1194
+ // stays, and the notice names it and why. {name} is the reusable's name (project data).
1195
+ 'builder.reuse.undoKeptPublished': msg('Undone — the reusable element “{name}” stays: it is published.'),
1196
+ 'builder.reuse.undoKeptEdited': msg('Undone — the reusable element “{name}” stays: it was edited since it was made.'),
1197
+ 'builder.reuse.undoKeptReferenced': msg('Undone — the reusable element “{name}” stays: it is embedded elsewhere.'),
1198
+ 'builder.reuse.undoKeptFailed': msg('Undone — the reusable element “{name}” stays: it could not be removed. Delete it from its collection if you do not need it.'),
1184
1199
  'builder.reuse.noTargetToDetach': msg('This element has no target to detach.'),
1185
1200
  'builder.reuse.noContentToDetach': msg('The referenced element has no content to detach.'),
1186
1201
  'builder.reuse.detachedToCopy': msg('Detached to an editable copy — the live link is broken.'),
@@ -1400,6 +1415,11 @@ const MESSAGES = {
1400
1415
  'ai.update.proposalTitle': msg('Changes to {collection}'),
1401
1416
  'ai.update.diffBefore': msg('Current'),
1402
1417
  'ai.update.diffAfter': msg('Proposed'),
1418
+ // EC-715 — what an AI create left empty, listed on its proposal card
1419
+ 'ai.create.unfilledTitle': msg('Left empty ({count})', '{count} is a number.'),
1420
+ 'ai.create.unfilled.empty': msg('the draft gave it no value'),
1421
+ 'ai.create.unfilled.noCandidates': msg('nothing the assistant searched for fits it'),
1422
+ 'ai.create.unfilled.dropped': msg('an id the assistant had not searched for was removed'),
1403
1423
  // EC-591 — canvas notices for roles nobody in the project's component list fills.
1404
1424
  // A role names what the canvas needs from the list; a missing one switches its
1405
1425
  // gesture off, and these say so instead of leaving a dead affordance.