@ecsplico/editor 2.1.1 → 3.0.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.
- package/CHANGELOG.md +74 -1
- package/README.md +39 -156
- package/dist/adapters/comments/drizzle.d.ts +1 -1
- package/dist/adapters/comments/{client.js → rest-model.js} +3 -3
- package/dist/adapters/comments/rest-model.js.map +1 -0
- package/dist/adapters/comments/types.d.ts +2 -2
- package/dist/adapters/document-state.d.ts +23 -0
- package/dist/adapters/document-state.js +66 -0
- package/dist/adapters/document-state.js.map +1 -0
- package/dist/adapters/documents.js +14 -11
- package/dist/adapters/documents.js.map +1 -1
- package/dist/adapters/drizzle.d.ts +2 -2
- package/dist/adapters/drizzle.js +97 -88
- package/dist/adapters/drizzle.js.map +1 -1
- package/dist/adapters/forge.d.ts +12 -7
- package/dist/adapters/forge.js +38 -45
- package/dist/adapters/forge.js.map +1 -1
- package/dist/adapters/http.d.ts +20 -0
- package/dist/adapters/http.js +68 -0
- package/dist/adapters/http.js.map +1 -0
- package/dist/adapters/index.d.ts +5 -5
- package/dist/adapters/json.d.ts +3 -3
- package/dist/adapters/json.js +58 -49
- package/dist/adapters/json.js.map +1 -1
- package/dist/adapters/memory.d.ts +21 -0
- package/dist/adapters/memory.js +53 -0
- package/dist/adapters/memory.js.map +1 -0
- package/dist/adapters/nitro.d.ts +23 -20
- package/dist/adapters/nitro.js +58 -163
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/react.d.ts +55 -0
- package/dist/adapters/react.js +209 -0
- package/dist/adapters/react.js.map +1 -0
- package/dist/adapters/shared.d.ts +15 -21
- package/dist/adapters/shared.js +10 -8
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/vue.d.ts +15 -30
- package/dist/adapters/vue.js +36 -87
- package/dist/adapters/vue.js.map +1 -1
- package/dist/code/CodeSurface.vue.d.ts +3 -3
- package/dist/config/index.d.ts +105 -0
- package/dist/config/index.js +95 -0
- package/dist/config/index.js.map +1 -0
- package/dist/core/abilities.js +1 -0
- package/dist/core/abilities.js.map +1 -1
- package/dist/{adapters/routes.js → core/api-routes.js} +5 -3
- package/dist/core/api-routes.js.map +1 -0
- package/dist/core/backend-capability.d.ts +7 -0
- package/dist/core/backend-capability.js +17 -0
- package/dist/core/backend-capability.js.map +1 -0
- package/dist/core/backend-types.d.ts +245 -0
- package/dist/core/backend-types.js +17 -0
- package/dist/core/backend-types.js.map +1 -0
- package/dist/core/backend.d.ts +108 -0
- package/dist/core/backend.js +14 -0
- package/dist/core/backend.js.map +1 -0
- package/dist/core/block-convert.d.ts +7 -5
- package/dist/core/block-convert.js +28 -5
- package/dist/core/block-convert.js.map +1 -1
- package/dist/core/command-types.d.ts +89 -0
- package/dist/core/commands.d.ts +40 -0
- package/dist/core/commands.js +151 -0
- package/dist/core/commands.js.map +1 -0
- package/dist/core/context.d.ts +17 -20
- package/dist/core/context.js +24 -21
- package/dist/core/context.js.map +1 -1
- package/dist/core/core-feature.d.ts +22 -7
- package/dist/core/core-feature.js +51 -18
- package/dist/core/core-feature.js.map +1 -1
- package/dist/core/define-editor.d.ts +4 -3
- package/dist/core/define-editor.js +14 -7
- package/dist/core/define-editor.js.map +1 -1
- package/dist/core/document-markdown.js +12 -3
- package/dist/core/document-markdown.js.map +1 -1
- package/dist/core/editor-ui.d.ts +8 -1
- package/dist/core/editor-ui.js +9 -8
- package/dist/core/editor-ui.js.map +1 -1
- package/dist/core/extension-points.d.ts +3 -15
- package/dist/core/feature-context.d.ts +8 -7
- package/dist/core/feature-context.js +12 -11
- package/dist/core/feature-context.js.map +1 -1
- package/dist/core/feature.d.ts +35 -19
- package/dist/core/feature.js.map +1 -1
- package/dist/core/fences.d.ts +2 -1
- package/dist/core/fences.js +3 -2
- package/dist/core/fences.js.map +1 -1
- package/dist/core/fetch-error.d.ts +1 -1
- package/dist/core/fetch-error.js +3 -1
- package/dist/core/fetch-error.js.map +1 -1
- package/dist/core/hash.d.ts +5 -0
- package/dist/core/hash.js +11 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/http-backend.d.ts +11 -0
- package/dist/core/http-backend.js +195 -0
- package/dist/core/http-backend.js.map +1 -0
- package/dist/core/index.d.ts +14 -9
- package/dist/core/index.js +12 -9
- package/dist/core/palette.d.ts +48 -0
- package/dist/core/palette.js +95 -0
- package/dist/core/palette.js.map +1 -0
- package/dist/core/schema/abilities.d.ts +2 -1
- package/dist/core/schema/abilities.js +5 -1
- package/dist/core/schema/abilities.js.map +1 -1
- package/dist/core/schema/index.d.ts +11 -5
- package/dist/core/schema/index.js +13 -8
- package/dist/core/schema/index.js.map +1 -1
- package/dist/core/schema/mark-flags.d.ts +8 -1
- package/dist/core/schema/of-features.d.ts +13 -0
- package/dist/core/schema/of-features.js +14 -0
- package/dist/core/schema/of-features.js.map +1 -0
- package/dist/core/slash.d.ts +8 -6
- package/dist/core/slash.js +24 -16
- package/dist/core/slash.js.map +1 -1
- package/dist/core/surface-session.js +13 -5
- package/dist/core/surface-session.js.map +1 -1
- package/dist/core/toolbar-items.d.ts +10 -4
- package/dist/core/toolbar-items.js +269 -195
- package/dist/core/toolbar-items.js.map +1 -1
- package/dist/core/util.js +11 -0
- package/dist/core/util.js.map +1 -0
- package/dist/document/DocumentSurface.d.ts +1 -1
- package/dist/document/DocumentSurface.vue.d.ts +3 -3
- package/dist/features/ai/agent-op-review.d.ts +1 -1
- package/dist/features/ai/agent-op-review.js +1 -1
- package/dist/features/ai/agent-ops.js +1 -1
- package/dist/features/ai/ai-apply.d.ts +2 -2
- package/dist/features/ai/ai-apply.js +1 -1
- package/dist/features/ai/ai-review.js +1 -1
- package/dist/features/ai/ai-sse.d.ts +6 -6
- package/dist/features/ai/ai-sse.js +20 -63
- package/dist/features/ai/ai-sse.js.map +1 -1
- package/dist/features/ai/assistant.d.ts +8 -7
- package/dist/features/ai/assistant.js +3 -3
- package/dist/features/ai/assistant.js.map +1 -1
- package/dist/features/ai/block-actions.d.ts +3 -2
- package/dist/features/ai/block-actions.js +3 -2
- package/dist/features/ai/block-actions.js.map +1 -1
- package/dist/features/ai/components/AiSelectionMenu.js +1 -1
- package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
- package/dist/features/ai/components/DocumentChatOps.vue.d.ts +1 -1
- package/dist/features/ai/components/SettingsModelProfiles.js +8 -8
- package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
- package/dist/features/ai/document-chat-model.d.ts +8 -7
- package/dist/features/ai/document-chat-model.js +5 -5
- package/dist/features/ai/document-chat-model.js.map +1 -1
- package/dist/features/ai/document-chat.js +1 -1
- package/dist/features/ai/feature.js +27 -14
- package/dist/features/ai/feature.js.map +1 -1
- package/dist/features/ai/ghost-autocomplete.d.ts +7 -6
- package/dist/features/ai/ghost-autocomplete.js +6 -9
- package/dist/features/ai/ghost-autocomplete.js.map +1 -1
- package/dist/features/ai/index.d.ts +4 -3
- package/dist/features/ai/index.js +10 -10
- package/dist/features/ai/model-profiles.d.ts +5 -4
- package/dist/features/ai/model-profiles.js +2 -2
- package/dist/features/ai/model-profiles.js.map +1 -1
- package/dist/features/ai/protocol/block-lines.js +1 -1
- package/dist/features/ai/protocol/block-lines.js.map +1 -1
- package/dist/features/ai/protocol/chat.js +4 -1
- package/dist/features/ai/protocol/chat.js.map +1 -1
- package/dist/features/ai/protocol/index.d.ts +3 -2
- package/dist/features/ai/protocol/models.d.ts +2 -16
- package/dist/features/ai/protocol/models.js.map +1 -1
- package/dist/features/ai/rate-limit.d.ts +1 -1
- package/dist/features/ai/rate-limit.js +3 -1
- package/dist/features/ai/rate-limit.js.map +1 -1
- package/dist/features/ai/react/AiSelectionMenu.js +2 -2
- package/dist/features/ai/react/AiSidebar.js +4 -4
- package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
- package/dist/features/ai/react/DocumentChatOps.d.ts +1 -1
- package/dist/features/ai/react/DocumentChatOps.js +1 -1
- package/dist/features/ai/react/SettingsModelProfiles.js +8 -10
- package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
- package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/react/use-ai-assistant.js +3 -3
- package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/react/use-document-chat.js +2 -2
- package/dist/features/ai/react/use-document-chat.js.map +1 -1
- package/dist/features/ai/react/use-model-profiles.d.ts +2 -1
- package/dist/features/ai/selection-flow.d.ts +1 -1
- package/dist/features/ai/selection-flow.js +1 -1
- package/dist/features/ai/sidebar-flow.d.ts +1 -1
- package/dist/features/ai/sidebar-flow.js +1 -1
- package/dist/features/ai/use-ai-assistant.d.ts +1 -1
- package/dist/features/ai/use-ai-assistant.js +3 -3
- package/dist/features/ai/use-ai-assistant.js.map +1 -1
- package/dist/features/ai/use-document-chat.js +2 -2
- package/dist/features/ai/use-document-chat.js.map +1 -1
- package/dist/features/ai/use-model-profiles.d.ts +2 -1
- package/dist/features/authors/attribution.d.ts +1 -1
- package/dist/features/authors/feature.js +12 -11
- package/dist/features/authors/feature.js.map +1 -1
- package/dist/features/block-ui/block-actions.d.ts +22 -1
- package/dist/features/block-ui/block-actions.js +26 -2
- package/dist/features/block-ui/block-actions.js.map +1 -1
- package/dist/features/block-ui/components/BlockActionsOverlay.js +33 -4
- package/dist/features/block-ui/components/BlockActionsOverlay.js.map +1 -1
- package/dist/features/block-ui/components/BlockActionsOverlay.vue.d.ts +4 -0
- package/dist/features/block-ui/components/BlockUi.js +1 -1
- package/dist/features/block-ui/feature.js +1 -0
- package/dist/features/block-ui/feature.js.map +1 -1
- package/dist/features/block-ui/index.d.ts +2 -2
- package/dist/features/block-ui/index.js +2 -2
- package/dist/features/block-ui/react/BlockActionsOverlay.d.ts +4 -0
- package/dist/features/block-ui/react/BlockActionsOverlay.js +38 -12
- package/dist/features/block-ui/react/BlockActionsOverlay.js.map +1 -1
- package/dist/features/block-ui/react/BlockUi.js +1 -1
- package/dist/features/collab/anchor-resolver.js +1 -1
- package/dist/features/collab/feature.js +2 -0
- package/dist/features/collab/feature.js.map +1 -1
- package/dist/features/comments/components/CommentThreadView.vue.d.ts +2 -1
- package/dist/features/comments/feature.js +12 -11
- package/dist/features/comments/feature.js.map +1 -1
- package/dist/features/comments/index.d.ts +3 -2
- package/dist/features/comments/index.js +1 -1
- package/dist/features/comments/margin-layout.d.ts +3 -2
- package/dist/features/comments/model.d.ts +3 -67
- package/dist/features/comments/model.js +2 -2
- package/dist/features/comments/model.js.map +1 -1
- package/dist/features/comments/react/CommentThreadView.d.ts +3 -2
- package/dist/features/comments/react/use-comments.d.ts +2 -1
- package/dist/features/comments/react.d.ts +1 -1
- package/dist/features/comments/schema.d.ts +2 -52
- package/dist/features/comments/schema.js.map +1 -1
- package/dist/features/comments/snapshot-equality.js.map +1 -1
- package/dist/features/comments/use-comments.d.ts +3 -2
- package/dist/features/comments/vue.d.ts +1 -1
- package/dist/features/composites/accepted-children.d.ts +1 -0
- package/dist/features/composites/accepted-children.js +16 -1
- package/dist/features/composites/accepted-children.js.map +1 -1
- package/dist/features/composites/ai-brief.js +31 -0
- package/dist/features/composites/ai-brief.js.map +1 -1
- package/dist/features/composites/bibliography-command.d.ts +11 -0
- package/dist/features/composites/bibliography-form.js +90 -0
- package/dist/features/composites/bibliography-form.js.map +1 -0
- package/dist/features/composites/bibliography.d.ts +33 -0
- package/dist/features/composites/bibliography.js +120 -0
- package/dist/features/composites/bibliography.js.map +1 -0
- package/dist/features/composites/components/BibliographyEditor.js +261 -0
- package/dist/features/composites/components/BibliographyEditor.js.map +1 -0
- package/dist/features/composites/components/CompositeChrome.js +75 -26
- package/dist/features/composites/components/CompositeChrome.js.map +1 -1
- package/dist/features/composites/components/CompositeDetails.js +46 -11
- package/dist/features/composites/components/CompositeDetails.js.map +1 -1
- package/dist/features/composites/components/CompositeDetails.vue.d.ts +2 -1
- package/dist/features/composites/components/CompositeFieldEditor.js +37 -4
- package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/components/CompositeInspector.js +17 -5
- package/dist/features/composites/components/CompositeInspector.js.map +1 -1
- package/dist/features/composites/components/CompositeTable.js +13 -4
- package/dist/features/composites/components/CompositeTable.js.map +1 -1
- package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
- package/dist/features/composites/components/CompositeView.js +11 -1
- package/dist/features/composites/components/CompositeView.js.map +1 -1
- package/dist/features/composites/components/DerivationBadge.js +103 -0
- package/dist/features/composites/components/DerivationBadge.js.map +1 -0
- package/dist/features/composites/components/ReferenceFieldSelect.js +60 -0
- package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -0
- package/dist/features/composites/components/ReferenceView.js +122 -0
- package/dist/features/composites/components/ReferenceView.js.map +1 -0
- package/dist/features/composites/components/ReferenceView.vue.d.ts +96 -0
- package/dist/features/composites/components/SettingsEditingTab.js +1 -1
- package/dist/features/composites/convert.js +2 -2
- package/dist/features/composites/convert.js.map +1 -1
- package/dist/features/composites/derivation.d.ts +61 -0
- package/dist/features/composites/derivation.js +98 -0
- package/dist/features/composites/derivation.js.map +1 -0
- package/dist/features/composites/derived-chrome.js +69 -0
- package/dist/features/composites/derived-chrome.js.map +1 -0
- package/dist/features/composites/feature.js +159 -109
- package/dist/features/composites/feature.js.map +1 -1
- package/dist/features/composites/fences.d.ts +4 -3
- package/dist/features/composites/fences.js +51 -7
- package/dist/features/composites/fences.js.map +1 -1
- package/dist/features/composites/index.d.ts +12 -3
- package/dist/features/composites/index.js +15 -6
- package/dist/features/composites/inspector-model.d.ts +4 -1
- package/dist/features/composites/inspector-model.js +8 -4
- package/dist/features/composites/inspector-model.js.map +1 -1
- package/dist/features/composites/kinds.d.ts +8 -1
- package/dist/features/composites/kinds.js +145 -6
- package/dist/features/composites/kinds.js.map +1 -1
- package/dist/features/composites/legacy.d.ts +4 -1
- package/dist/features/composites/legacy.js +56 -1
- package/dist/features/composites/legacy.js.map +1 -1
- package/dist/features/composites/meta-display.js +40 -1
- package/dist/features/composites/meta-display.js.map +1 -1
- package/dist/features/composites/meta-keys.d.ts +7 -0
- package/dist/features/composites/meta-keys.js +21 -0
- package/dist/features/composites/meta-keys.js.map +1 -0
- package/dist/features/composites/node-views.d.ts +6 -3
- package/dist/features/composites/node-views.js +7 -3
- package/dist/features/composites/node-views.js.map +1 -1
- package/dist/features/composites/nodes.d.ts +6 -1
- package/dist/features/composites/nodes.js +33 -7
- package/dist/features/composites/nodes.js.map +1 -1
- package/dist/features/composites/react/BibliographyEditor.js +229 -0
- package/dist/features/composites/react/BibliographyEditor.js.map +1 -0
- package/dist/features/composites/react/CompositeChrome.js +65 -17
- package/dist/features/composites/react/CompositeChrome.js.map +1 -1
- package/dist/features/composites/react/CompositeDetails.d.ts +2 -1
- package/dist/features/composites/react/CompositeDetails.js +45 -6
- package/dist/features/composites/react/CompositeDetails.js.map +1 -1
- package/dist/features/composites/react/CompositeFieldEditor.d.ts +1 -1
- package/dist/features/composites/react/CompositeFieldEditor.js +24 -1
- package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
- package/dist/features/composites/react/CompositeInspector.js +11 -5
- package/dist/features/composites/react/CompositeInspector.js.map +1 -1
- package/dist/features/composites/react/CompositeStatusMenu.js +1 -1
- package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
- package/dist/features/composites/react/CompositeTable.js +16 -2
- package/dist/features/composites/react/CompositeTable.js.map +1 -1
- package/dist/features/composites/react/CompositeTagsEditor.js +2 -2
- package/dist/features/composites/react/CompositeView.js +6 -1
- package/dist/features/composites/react/CompositeView.js.map +1 -1
- package/dist/features/composites/react/DerivationBadge.js +116 -0
- package/dist/features/composites/react/DerivationBadge.js.map +1 -0
- package/dist/features/composites/react/ReferenceFieldSelect.js +52 -0
- package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -0
- package/dist/features/composites/react/ReferenceView.d.ts +11 -0
- package/dist/features/composites/react/ReferenceView.js +115 -0
- package/dist/features/composites/react/ReferenceView.js.map +1 -0
- package/dist/features/composites/react/SettingsEditingTab.js +2 -2
- package/dist/features/composites/react.d.ts +2 -1
- package/dist/features/composites/react.js +7 -3
- package/dist/features/composites/react.js.map +1 -1
- package/dist/features/composites/reference-ai.js +16 -0
- package/dist/features/composites/reference-ai.js.map +1 -0
- package/dist/features/composites/reference-label.d.ts +19 -0
- package/dist/features/composites/reference-label.js +58 -0
- package/dist/features/composites/reference-label.js.map +1 -0
- package/dist/features/composites/reference-suggestion.d.ts +10 -0
- package/dist/features/composites/reference-suggestion.js +41 -0
- package/dist/features/composites/reference-suggestion.js.map +1 -0
- package/dist/features/composites/reference-text.d.ts +18 -0
- package/dist/features/composites/reference-text.js +89 -0
- package/dist/features/composites/reference-text.js.map +1 -0
- package/dist/features/composites/reference.d.ts +44 -0
- package/dist/features/composites/reference.js +148 -0
- package/dist/features/composites/reference.js.map +1 -0
- package/dist/features/composites/reveal-source.d.ts +32 -0
- package/dist/features/composites/reveal-source.js +89 -0
- package/dist/features/composites/reveal-source.js.map +1 -0
- package/dist/features/composites/rows.d.ts +21 -2
- package/dist/features/composites/rows.js +63 -9
- package/dist/features/composites/rows.js.map +1 -1
- package/dist/features/composites/schema.d.ts +9 -3
- package/dist/features/composites/schema.js +11 -4
- package/dist/features/composites/schema.js.map +1 -1
- package/dist/features/composites/table-model.js +12 -21
- package/dist/features/composites/table-model.js.map +1 -1
- package/dist/features/composites/vue.d.ts +3 -2
- package/dist/features/composites/vue.js +8 -4
- package/dist/features/composites/vue.js.map +1 -1
- package/dist/features/media/assets.d.ts +2 -0
- package/dist/features/media/assets.js +3 -2
- package/dist/features/media/assets.js.map +1 -1
- package/dist/features/media/components/FileView.js +13 -4
- package/dist/features/media/components/FileView.js.map +1 -1
- package/dist/features/media/feature.d.ts +3 -3
- package/dist/features/media/feature.js +21 -28
- package/dist/features/media/feature.js.map +1 -1
- package/dist/features/media/file-import.js +2 -2
- package/dist/features/media/file-import.js.map +1 -1
- package/dist/features/media/index.d.ts +2 -2
- package/dist/features/media/index.js +2 -2
- package/dist/features/media/react/FileView.js +19 -2
- package/dist/features/media/react/FileView.js.map +1 -1
- package/dist/features/media/schema.d.ts +8 -0
- package/dist/features/media/schema.js +126 -11
- package/dist/features/media/schema.js.map +1 -1
- package/dist/features/media/upload.d.ts +16 -14
- package/dist/features/media/upload.js +13 -19
- package/dist/features/media/upload.js.map +1 -1
- package/dist/features/mentions/index.d.ts +4 -3
- package/dist/features/mentions/index.js +4 -1
- package/dist/features/mentions/index.js.map +1 -1
- package/dist/features/mentions/mention-text.d.ts +1 -1
- package/dist/features/mentions/mention-text.js.map +1 -1
- package/dist/features/mentions/mention.d.ts +0 -6
- package/dist/features/mentions/mention.js.map +1 -1
- package/dist/features/mentions/metadata-defaults.d.ts +2 -2
- package/dist/features/mentions/metadata-defaults.js +3 -9
- package/dist/features/mentions/metadata-defaults.js.map +1 -1
- package/dist/features/mentions/schema.d.ts +2 -1
- package/dist/features/mentions/schema.js.map +1 -1
- package/dist/features/tables/feature.d.ts +2 -1
- package/dist/features/tables/feature.js +90 -70
- package/dist/features/tables/feature.js.map +1 -1
- package/dist/features/themes/components/SettingsAppearanceTab.js +6 -9
- package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/feature.js +2 -0
- package/dist/features/themes/feature.js.map +1 -1
- package/dist/features/themes/index.d.ts +2 -1
- package/dist/features/themes/react/SettingsAppearanceTab.js +7 -10
- package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
- package/dist/features/themes/schema.d.ts +2 -6
- package/dist/features/themes/schema.js.map +1 -1
- package/dist/features/themes/theme-runtime.d.ts +1 -1
- package/dist/features/themes/theme-runtime.js +4 -2
- package/dist/features/themes/theme-runtime.js.map +1 -1
- package/dist/features/transcript/TranscriptSegmentView.js +48 -28
- package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/feature.js +21 -19
- package/dist/features/transcript/feature.js.map +1 -1
- package/dist/features/transcript/react/TranscriptSegmentView.js +55 -36
- package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
- package/dist/features/transcript/segment-node.d.ts +2 -0
- package/dist/features/transcript/segment-node.js +35 -7
- package/dist/features/transcript/segment-node.js.map +1 -1
- package/dist/i18n/de/composites.js +91 -1
- package/dist/i18n/de/composites.js.map +1 -1
- package/dist/i18n/de/integrations.js +49 -8
- package/dist/i18n/de/integrations.js.map +1 -1
- package/dist/i18n/de/media.js +0 -1
- package/dist/i18n/de/media.js.map +1 -1
- package/dist/i18n/de/palette.js +22 -0
- package/dist/i18n/de/palette.js.map +1 -0
- package/dist/i18n/de/tables.js +0 -1
- package/dist/i18n/de/tables.js.map +1 -1
- package/dist/i18n/de/transcript.js +2 -1
- package/dist/i18n/de/transcript.js.map +1 -1
- package/dist/i18n/de/tree.js +3 -0
- package/dist/i18n/de/tree.js.map +1 -1
- package/dist/i18n/de.d.ts +157 -11
- package/dist/i18n/de.js +3 -1
- package/dist/i18n/de.js.map +1 -1
- package/dist/i18n/en/composites.js +89 -1
- package/dist/i18n/en/composites.js.map +1 -1
- package/dist/i18n/en/integrations.js +49 -8
- package/dist/i18n/en/integrations.js.map +1 -1
- package/dist/i18n/en/media.js +0 -1
- package/dist/i18n/en/media.js.map +1 -1
- package/dist/i18n/en/palette.js +22 -0
- package/dist/i18n/en/palette.js.map +1 -0
- package/dist/i18n/en/tables.js +0 -1
- package/dist/i18n/en/tables.js.map +1 -1
- package/dist/i18n/en/transcript.js +2 -1
- package/dist/i18n/en/transcript.js.map +1 -1
- package/dist/i18n/en/tree.js +3 -0
- package/dist/i18n/en/tree.js.map +1 -1
- package/dist/i18n/en.js +3 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/integrations/composite-ai/bibliography-fetch.d.ts +31 -0
- package/dist/integrations/composite-ai/bibliography-fetch.js +159 -0
- package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -0
- package/dist/integrations/composite-ai/composite-fill.d.ts +30 -8
- package/dist/integrations/composite-ai/composite-fill.js +97 -56
- package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
- package/dist/integrations/composite-ai/composite-summary.d.ts +4 -12
- package/dist/integrations/composite-ai/composite-summary.js +7 -26
- package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
- package/dist/integrations/composite-ai/derive.d.ts +29 -0
- package/dist/integrations/composite-ai/derive.js +173 -0
- package/dist/integrations/composite-ai/derive.js.map +1 -0
- package/dist/integrations/composite-ai/index.d.ts +11 -7
- package/dist/integrations/composite-ai/index.js +72 -14
- package/dist/integrations/composite-ai/index.js.map +1 -1
- package/dist/integrations/composite-ai/rendition.d.ts +45 -0
- package/dist/integrations/composite-ai/rendition.js +314 -0
- package/dist/integrations/composite-ai/rendition.js.map +1 -0
- package/dist/integrations/composite-media/index.d.ts +7 -5
- package/dist/integrations/composite-media/index.js +86 -13
- package/dist/integrations/composite-media/index.js.map +1 -1
- package/dist/integrations/transcript-ai/index.d.ts +1 -1
- package/dist/integrations/transcript-ai/index.js +5 -2
- package/dist/integrations/transcript-ai/index.js.map +1 -1
- package/dist/integrations/transcript-ai/protocol.d.ts +2 -12
- package/dist/integrations/transcript-ai/protocol.js +0 -2
- package/dist/integrations/transcript-ai/protocol.js.map +1 -1
- package/dist/integrations/transcript-ai/transcript-cleanup.d.ts +5 -5
- package/dist/integrations/transcript-ai/transcript-cleanup.js +7 -10
- package/dist/integrations/transcript-ai/transcript-cleanup.js.map +1 -1
- package/dist/markdown/MarkdownSurface.vue.d.ts +10 -9
- package/dist/markdown/MarkdownSurface2.js +3 -6
- package/dist/markdown/MarkdownSurface2.js.map +1 -1
- package/dist/markdown/document.js +1 -1
- package/dist/markdown/source-mode.d.ts +1 -1
- package/dist/nuxt/module.d.ts +1402 -54
- package/dist/nuxt/module.js +6 -49
- package/dist/nuxt/module.js.map +1 -1
- package/dist/nuxt/runtime/install-context.d.ts +7 -3
- package/dist/nuxt/runtime/install-context.js +14 -8
- package/dist/nuxt/runtime/install-context.js.map +1 -1
- package/dist/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts +2 -2
- package/dist/nuxt/runtime/server/plugins/editor-server.js +20 -12
- package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
- package/dist/presets/compose.d.ts +94 -0
- package/dist/presets/compose.js +164 -0
- package/dist/presets/compose.js.map +1 -0
- package/dist/react/AdvancedEditor.d.ts +15 -15
- package/dist/react/AdvancedEditor.js +15 -13
- package/dist/react/AdvancedEditor.js.map +1 -1
- package/dist/react/EditorCommandPalette.d.ts +13 -0
- package/dist/react/EditorCommandPalette.js +118 -0
- package/dist/react/EditorCommandPalette.js.map +1 -0
- package/dist/react/EditorSettingsModal.d.ts +5 -5
- package/dist/react/EditorSettingsModal.js +7 -4
- package/dist/react/EditorSettingsModal.js.map +1 -1
- package/dist/react/EditorSettingsPanel.d.ts +7 -7
- package/dist/react/EditorSettingsPanel.js +8 -5
- package/dist/react/EditorSettingsPanel.js.map +1 -1
- package/dist/react/EditorSurface.d.ts +7 -7
- package/dist/react/EditorSurface.js +10 -6
- package/dist/react/EditorSurface.js.map +1 -1
- package/dist/react/EditorToolbar.d.ts +4 -6
- package/dist/react/EditorToolbar.js +29 -37
- package/dist/react/EditorToolbar.js.map +1 -1
- package/dist/react/SimpleEditor.d.ts +22 -23
- package/dist/react/SimpleEditor.js +21 -7
- package/dist/react/SimpleEditor.js.map +1 -1
- package/dist/react/advanced.d.ts +4 -3
- package/dist/react/advanced.js +2 -2
- package/dist/react/compose.d.ts +20 -0
- package/dist/react/compose.js +49 -0
- package/dist/react/compose.js.map +1 -0
- package/dist/react/composed-surface.d.ts +39 -0
- package/dist/react/composed-surface.js +71 -0
- package/dist/react/composed-surface.js.map +1 -0
- package/dist/react/context.js +6 -2
- package/dist/react/context.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +2 -1
- package/dist/react/key-labels.js +15 -0
- package/dist/react/key-labels.js.map +1 -0
- package/dist/react/settings.d.ts +1 -1
- package/dist/react/simple.d.ts +2 -2
- package/dist/react/ui/command.js +36 -1
- package/dist/react/ui/command.js.map +1 -1
- package/dist/schema/advanced.d.ts +6 -6
- package/dist/schema/advanced.js +26 -29
- package/dist/schema/advanced.js.map +1 -1
- package/dist/server/ai.d.ts +5 -16
- package/dist/server/ai.js.map +1 -1
- package/dist/server/auth.d.ts +9 -0
- package/dist/server/collab-state.d.ts +1 -1
- package/dist/server/collab-state.js.map +1 -1
- package/dist/server/collab.d.ts +13 -13
- package/dist/server/collab.js +34 -18
- package/dist/server/collab.js.map +1 -1
- package/dist/server/crossref.js +78 -0
- package/dist/server/crossref.js.map +1 -0
- package/dist/server/errors.d.ts +1 -1
- package/dist/server/errors.js +1 -1
- package/dist/server/errors.js.map +1 -1
- package/dist/server/extract.js +308 -0
- package/dist/server/extract.js.map +1 -0
- package/dist/{nuxt/runtime/server/utils/editor-route.js → server/h3.js} +8 -16
- package/dist/server/h3.js.map +1 -0
- package/dist/server/handlers/ai.d.ts +30 -9
- package/dist/server/handlers/ai.js +170 -36
- package/dist/server/handlers/ai.js.map +1 -1
- package/dist/server/handlers/context.d.ts +12 -5
- package/dist/server/handlers/context.js +10 -4
- package/dist/server/handlers/context.js.map +1 -1
- package/dist/server/handlers/editor.d.ts +19 -13
- package/dist/server/handlers/editor.js +49 -38
- package/dist/server/handlers/editor.js.map +1 -1
- package/dist/server/handlers/index.d.ts +4 -4
- package/dist/server/handlers/index.js +4 -4
- package/dist/server/host.d.ts +16 -25
- package/dist/server/host.js +58 -41
- package/dist/server/host.js.map +1 -1
- package/dist/server/index.d.ts +6 -4
- package/dist/server/index.js +3 -2
- package/dist/server/pdf.js +97 -0
- package/dist/server/pdf.js.map +1 -0
- package/dist/server/{adapter.d.ts → ports.d.ts} +81 -30
- package/dist/server/ports.js +29 -0
- package/dist/server/ports.js.map +1 -0
- package/dist/server/routes.js +144 -0
- package/dist/server/routes.js.map +1 -0
- package/dist/settings/index.d.ts +1 -1
- package/dist/settings/index.js.map +1 -1
- package/dist/styles/composites.css +25 -0
- package/dist/tree/DocumentTree.js +56 -29
- package/dist/tree/DocumentTree.js.map +1 -1
- package/dist/tree/react/DocumentTree.js +23 -0
- package/dist/tree/react/DocumentTree.js.map +1 -1
- package/dist/tree/tree-host.js +1 -1
- package/dist/vue/AdvancedEditor.js +30 -9
- package/dist/vue/AdvancedEditor.js.map +1 -1
- package/dist/vue/AdvancedEditor.vue.d.ts +32 -12
- package/dist/vue/SimpleEditor.js +62 -16
- package/dist/vue/SimpleEditor.js.map +1 -1
- package/dist/vue/SimpleEditor.vue.d.ts +37 -7
- package/dist/vue/advanced.d.ts +3 -2
- package/dist/vue/advanced.js +2 -2
- package/dist/vue/components/EditorCommandPalette.js +91 -0
- package/dist/vue/components/EditorCommandPalette.js.map +1 -0
- package/dist/vue/components/EditorCommandPalette.vue.d.ts +15 -0
- package/dist/vue/components/EditorSettingsModal.js +10 -6
- package/dist/vue/components/EditorSettingsModal.js.map +1 -1
- package/dist/vue/components/EditorSettingsModal.vue.d.ts +4 -4
- package/dist/vue/components/EditorSettingsPanel.js +10 -6
- package/dist/vue/components/EditorSettingsPanel.js.map +1 -1
- package/dist/vue/components/EditorSettingsPanel.vue.d.ts +6 -6
- package/dist/vue/components/EditorSurface.js +11 -6
- package/dist/vue/components/EditorSurface.js.map +1 -1
- package/dist/vue/components/EditorSurface.vue.d.ts +11 -11
- package/dist/vue/components/EditorToolbar.js +41 -49
- package/dist/vue/components/EditorToolbar.js.map +1 -1
- package/dist/vue/components/EditorToolbar.vue.d.ts +2 -4
- package/dist/vue/compose.d.ts +17 -0
- package/dist/vue/compose.js +51 -0
- package/dist/vue/compose.js.map +1 -0
- package/dist/vue/context-key.d.ts +6 -0
- package/dist/vue/context-key.js +6 -0
- package/dist/vue/context-key.js.map +1 -0
- package/dist/vue/context.d.ts +8 -6
- package/dist/vue/context.js +6 -5
- package/dist/vue/context.js.map +1 -1
- package/dist/vue/index.d.ts +10 -8
- package/dist/vue/index.js +10 -8
- package/dist/vue/kit/index.d.ts +2 -2
- package/dist/vue/kit/nuxt-ui.js +23 -0
- package/dist/vue/kit/nuxt-ui.js.map +1 -1
- package/dist/vue/kit/types.d.ts +40 -1
- package/package.json +30 -16
- package/dist/adapters/comments/client.d.ts +0 -64
- package/dist/adapters/comments/client.js.map +0 -1
- package/dist/adapters/routes.js.map +0 -1
- package/dist/core/toolbar.d.ts +0 -74
- package/dist/core/toolbar.js +0 -45
- package/dist/core/toolbar.js.map +0 -1
- package/dist/integrations/composite-ai/document-transcribe.d.ts +0 -14
- package/dist/integrations/composite-ai/document-transcribe.js +0 -89
- package/dist/integrations/composite-ai/document-transcribe.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/chat.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/chat.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/chat.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/complete.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/complete.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/complete.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/generate.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/generate.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/generate.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/models.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/models.get.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/models.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/transcribe.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js +0 -8
- package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/settings.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/settings.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/settings.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/settings.put.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/settings.put.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/settings.put.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/tags.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/tags.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/tags.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/index.get.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/themes/index.post.js.map +0 -1
- package/dist/nuxt/runtime/server/api/editor/users.get.d.ts +0 -5
- package/dist/nuxt/runtime/server/api/editor/users.get.js +0 -8
- package/dist/nuxt/runtime/server/api/editor/users.get.js.map +0 -1
- package/dist/nuxt/runtime/server/plugins/collab.d.ts +0 -5
- package/dist/nuxt/runtime/server/plugins/collab.js +0 -10
- package/dist/nuxt/runtime/server/plugins/collab.js.map +0 -1
- package/dist/nuxt/runtime/server/routes/collab/[id].d.ts +0 -5
- package/dist/nuxt/runtime/server/routes/collab/[id].js +0 -35
- package/dist/nuxt/runtime/server/routes/collab/[id].js.map +0 -1
- package/dist/nuxt/runtime/server/utils/editor-route.d.ts +0 -11
- package/dist/nuxt/runtime/server/utils/editor-route.js.map +0 -1
- package/dist/presets/advanced.d.ts +0 -33
- package/dist/presets/advanced.js +0 -50
- package/dist/presets/advanced.js.map +0 -1
- package/dist/presets/simple.d.ts +0 -9
- package/dist/presets/simple.js +0 -12
- package/dist/presets/simple.js.map +0 -1
- package/dist/react/advanced-preset.d.ts +0 -11
- package/dist/react/advanced-preset.js +0 -31
- package/dist/react/advanced-preset.js.map +0 -1
- package/dist/vue/advanced-preset.d.ts +0 -13
- package/dist/vue/advanced-preset.js +0 -33
- package/dist/vue/advanced-preset.js.map +0 -1
- package/docs/extending.md +0 -538
- package/docs/integration.md +0 -630
- package/docs/llms.md +0 -383
- package/docs/usage.md +0 -1076
package/docs/llms.md
DELETED
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
# Guide for LLM coding agents
|
|
2
|
-
|
|
3
|
-
Task-oriented orientation for an agent that integrates, extends or verifies `@ecsplico/editor`. It states the invariants and the shortest correct path; every detail lives in the linked guides, which you should open only for the task at hand. The code below is checked against the source (`packages/editor/package.json#exports`, `src/**/index.ts`).
|
|
4
|
-
|
|
5
|
-
## What this package is
|
|
6
|
-
|
|
7
|
-
- A Vue and React editor library on TipTap v3 (`@ecsplico/editor`, workspace package `packages/editor`), published as built ESM with `.d.ts` (`bun run build:editor` → `dist/`; the source maps embed the sources, `src` is not published). In this repository the `skaile-source` export condition points the demo app and the examples at `src`, so development needs no build. Consume it through Vite (`@vitejs/plugin-vue` with `@nuxt/ui/vite`, or `@vitejs/plugin-react` with `@tailwindcss/vite`) or Nuxt. Layers: framework-free `/core`, Vue (`/vue`, Nuxt UI) and React (`/react`, shadcn/ui). Every advanced feature has three entries: framework-free `/<x>` (logic, models and the UI binding contract), `/<x>/vue` and `/<x>/react`; both surfaces offer the simple editor, the advanced editor and every feature.
|
|
8
|
-
- An editor is a **list of features** (`EditorFeature`) validated by `defineEditor` into an immutable `EditorPreset`, mounted by `EditorSurface`. Prebuilt presets: `simpleEditor()` (core only, no backend) and `advancedEditor()` (every feature plus the three integrations), each with a Vue and a React component (`SimpleEditor`, `AdvancedEditor`).
|
|
9
|
-
- Toolbar, settings panel/modal, outline, AI sidebar and file browser are **separate components** you place beside an editor and give the editor (or the preset).
|
|
10
|
-
- No runtime umbrella barrel and no global registration: importing an entry registers nothing. The root entry `@ecsplico/editor` is **type-only**.
|
|
11
|
-
- UI strings render from catalogs in `de` (default) and `en`: `locale: 'de' | 'en'` and partial `messages` overrides on `createEditorContext` / `createEditor` / the module option, `ctx.t(key, params?)` in features, `useEditorI18n()` in components (see "Language" below). Server error messages are German developer messages; docs and identifiers are English.
|
|
12
|
-
|
|
13
|
-
## Which entry to import
|
|
14
|
-
|
|
15
|
-
Every entry is an explicit subpath of `package.json#exports`; a path that is not listed there does not resolve. Full inventory with every exported name: [README, Public exports](../README.md#public-exports).
|
|
16
|
-
|
|
17
|
-
| You need | Import | Side |
|
|
18
|
-
|---|---|---|
|
|
19
|
-
| A ready simple editor component | `SimpleEditor` from `@ecsplico/editor/vue/simple` | browser |
|
|
20
|
-
| A ready advanced editor component | `AdvancedEditor` from `@ecsplico/editor/vue/advanced` | browser |
|
|
21
|
-
| A preset to pass to `EditorSurface`, `EditorToolbar`, `EditorSettingsPanel` | `simpleEditor` from `.../presets/simple`, `advancedEditor` from `.../vue/advanced` or `.../react/advanced` (the framework-free assembly behind the advanced one is `.../presets/advanced`: `advancedEditorCore`, `ADVANCED_FEATURE_IDS`) | browser |
|
|
22
|
-
| Vue chrome: `createEditor` (mandatory Vue app context), `EditorSurface`, `EditorToolbar`, `EditorSettingsPanel`, `EditorSettingsModal`, `SettingsSection`, `useEditorSettings`, `useEditorUi` | `@ecsplico/editor/vue` | browser (Vue) |
|
|
23
|
-
| React chrome: `EditorContextProvider` (mandatory React context from `createEditorContext()`), `EditorSurface`, `EditorToolbar`, `EditorSettingsPanel`, `EditorSettingsModal`, `SettingsSection`, `useEditorSettings`, `useEditorUi`, `Toaster`, `reactNotifier` | `@ecsplico/editor/react` | browser (React) |
|
|
24
|
-
| A ready simple editor component for React | `SimpleEditor` from `@ecsplico/editor/react/simple` | browser (React) |
|
|
25
|
-
| A ready advanced editor component for React | `AdvancedEditor`, `advancedEditor` from `@ecsplico/editor/react/advanced` (needs `EditorContextProvider` and `Toaster`) | browser (React) |
|
|
26
|
-
| shadcn token mapping for the feature CSS (React hosts) | `@ecsplico/editor/react/styles/ui-vars.css`; for the advanced editor `@ecsplico/editor/react/styles/advanced.css` (token mapping, `core.css`, every feature sheet, `themes.css` and the theme bridge in one import) | browser (React) |
|
|
27
|
-
| Framework-free core: `defineEditor`, `coreFeature`, `createEditorContext`, `commandItem`, `parseBlocks`, `createStore`, `Notifier`, extension-point types (`MenuItem`, `EditorFeature<C>`) | `@ecsplico/editor/core` | browser (no UI framework) |
|
|
28
|
-
| One feature | `<x>FeatureCore(ui)`, models and types from `.../<x>`; the Vue binding `<x>Feature()` and components from `.../<x>/vue`; the React binding and components from `.../<x>/react`; `<x>` is `media`, `mentions` (framework-free only), `transcript`, `authors`, `comments`, `composites`, `ai`, `collab`, `block-ui`, `themes` | browser |
|
|
29
|
-
| Markdown string as the document | `splitFrontmatter`, `joinFrontmatter`, `markdownToContent(editor, body, { policy })` → `{ content, diagnostics }` (raw HTML, unsafe URLs, unknown fences reported; `OpaqueFence` keeps unknown `::: kind` fences byte for byte), `contentToMarkdown(editor)`, `MarkdownClipboard` (paste/copy as Markdown), `createSourceMode({ getEditor })` (`state`, `enter`, `edit`, `commit` → false and editor untouched on a fatal diagnostic, `cancel`) from `.../markdown`; `MarkdownSurface` (`v-model` string, YAML frontmatter kept verbatim, props `policy` and `sourceMode`) from `.../markdown/vue` (React: `value`/`onChange`/`onDiagnostics`, prop `policy`, no source view, from `.../markdown/react`); GFM tables and task lists: `tablesFeature()` from `.../tables` (schema `.../tables/schema`, CSS `.../styles/tables.css`) | browser (`.../markdown`, `.../tables` also headless) |
|
|
30
|
-
| Edit a code, YAML, JSON or text file | `CodeSurface` from `.../code/vue` (`v-model`, `editable`, `language`, `wordWrap`, emits `save`, `ready`) or `.../code/react` (`value`, `onChange`, `onSave`, `onReady`); framework-free `createCodeEditor`, `setReadOnly`, `setWordWrap`, `setLanguage`, `loadLanguage`, `setDocument`, `formatJsonInEditor`, `kindOf(path, mime?)`, `languageOf(path)` from `.../code`. Language packs are yours: `registerLanguage('yaml', async () => (await import('@codemirror/lang-yaml')).yaml())` once at startup, id from `languageOf(path)`. Theme = `--sk-*` tokens (`.../styles/tokens.css`). Needs `@codemirror/{state,view,language,commands,search}` and `@lezer/highlight` installed (optional peers); no ProseMirror/TipTap in the bundle | browser |
|
|
31
|
-
| One surface for Markdown and code files | `DocumentSurface` from `.../document/vue` (`path`, `v-model`, `markdown` = props of `MarkdownSurface` incl. `preset`, `binary` slot) or `.../document/react` (`path`, `value`, `onChange`, `markdown`, `binary(path)`); chooses by `kindOf(path, mime)`; remount (`:key`/`key` = path) when the path changes. Reaches ProseMirror and CodeMirror both | browser |
|
|
32
|
-
| An integration (framework-free, works on both surfaces) | `compositeMediaFeature`, `compositeAiFeature`, `transcriptAiFeature` from `.../integrations/composite-media`, `/composite-ai`, `/transcript-ai` | browser |
|
|
33
|
-
| Heading outline, file browser | `EditorOutline` from `.../outline/vue` or `.../outline/react` (`headingOutline`, `revealBlockInEditor` from `.../outline`); `DocumentTree`, `useTreeView` from `.../tree/vue` or `.../tree/react`; `DocumentStore`, `createTreeView` from `.../tree` | browser |
|
|
34
|
-
| Settings type, defaults, validation | `EditorSettings`, `EDITOR_SETTINGS_DEFAULTS`, `parseEditorSettings`, `editorSettingsSchema` from `.../settings` | anywhere |
|
|
35
|
-
| ProseMirror schema for a server, validator or migration | `simpleSchemaExtensions` from `.../schema/simple`; `advancedSchemaExtensions` from `.../schema/advanced`; per-feature `.../<name>/schema`; base `coreSchemaExtensions`, `ROOT_ABILITIES`, `BlockId` helpers from `.../core/schema` | framework-free, Node-safe |
|
|
36
|
-
| Nitro side: register the adapter, forget a deleted document | `setEditorAdapter`, `EditorAdapter`, `forgetCollabDocument`, `liveContent`, `collabStats` from `.../server` | Nitro only |
|
|
37
|
-
| Server without Nitro: collab server, AI models, rate limiter, route handlers, websocket listener | `createCollabServer`, `createAiModels`, `createRateLimiter` from `.../server`; `chatPost`, `usersGet`, … and their body schemas from `.../server/handlers`; `listenCollab` from `.../server/node` | any Node process |
|
|
38
|
-
| Store documents as JSON files | `createJsonAdapter({ dir, authenticate?, authorize?, users?, schemaExtensions? })` from `@ecsplico/editor/adapters/json` | Node |
|
|
39
|
-
| Store documents in SQLite via drizzle (optional peer `drizzle-orm`) | `bootstrapEditorTables(db)`, `createDrizzleAdapter({ db, tables: editorTables() })` from `@ecsplico/editor/adapters/drizzle` | Node |
|
|
40
|
-
| Edit a host's Markdown files | `createForgeAdapter({ content, state, schema, authenticate, … })` from `@ecsplico/editor/adapters/forge` | Node |
|
|
41
|
-
| Mount the editor backend on Nitro (no Nuxt module) | `installEditorServer(nitroApp, { adapter, collab: {} \| false, ai?, rateLimit?, comments?: { store } })` from `@ecsplico/editor/server/nitro`, called from one Nitro plugin; needs `experimental: { websocket: true }` for `collab`; peer `h3` | Nitro only |
|
|
42
|
-
| Bind a Vue editor surface to a document | `useEditorDocument(id, { fetch, collaboration?, user?, canComment? })` → `{ modelValue, ready, dirty, save, reload, error, collaboration, comments, editor, bind, dispose }` from `@ecsplico/editor/adapters/vue` | browser (Vue) |
|
|
43
|
-
| Comment threads that survive edits | `captureAnchor`/`resolveAnchor`/`mapAnchor` from `.../anchors`; `createJsonCommentStore({ file })` from `.../comments/json`; `createDrizzleCommentStore({ db, tables: commentTables() })` from `.../comments/drizzle`; `handleCommentsRequest(store, { method, documentId, body })` from `.../comments/server`; `createRestCommentsModel({ fetch, documentId, user, canComment, getEditor })` from `.../comments/client` | `anchors`, `comments/client`: browser (no UI framework); the others: Node |
|
|
44
|
-
| Nuxt module (config key `tiptapEditor`) | `@ecsplico/editor/nuxt` in `modules` | build |
|
|
45
|
-
| CSS | `.../styles/core.css` (required) plus `/media.css`, `/mentions.css`, `/tables.css`, `/authors.css`, `/comments.css`, `/transcript.css`, `/composites.css`, `/ai.css`, `/collab.css`, `/block-ui.css`, `/themes.css` for the features you use | browser |
|
|
46
|
-
|
|
47
|
-
Rules that follow from this table:
|
|
48
|
-
|
|
49
|
-
- Import values from the subpath that owns them. The root entry `@ecsplico/editor` exports types only (`export type`), so `import { createEditor } from '@ecsplico/editor'` does not compile; use `@ecsplico/editor/vue` (Vue) or `@ecsplico/editor/react` (React). `/core` contains no `vue`, `@tiptap/vue-3`, `@nuxt/ui` or React module and no longer exports `createEditor`, `EditorSurface`, `EditorToolbar`, `EditorSettingsPanel`, `EditorSettingsModal`, `SettingsSection`, `useEditorSettings`, `useEditorUi`, `useEditorContext`: those come from `/vue` or `/react`. Feature entries follow the same rule: `/<x>` is framework-free, the components and the `<x>Feature()` binding live in `/<x>/vue` and `/<x>/react`. A React preset is `defineEditor({ features: [coreFeature(), mentionsFeature(), ...] })` with factories from `/<x>/react`; features with Vue components are not assignable to it.
|
|
50
|
-
- Never import a browser entry from server code, and never import `/server` or `/nuxt` from browser code. Servers use the framework-free `schema`/`protocol`/`types` entries (`/ai/protocol`, `/integrations/transcript-ai/protocol`, `/tree/types`, `/settings`).
|
|
51
|
-
|
|
52
|
-
## Minimal integration: Nuxt
|
|
53
|
-
|
|
54
|
-
1. Install the package from npmjs (`npm install @ecsplico/editor`, no token needed) and the peers in the consuming app (`vue`, `@nuxt/ui`, `@tiptap/core`, `@tiptap/pm`, `@tiptap/vue-3`, `yjs`, `@hocuspocus/provider`, plus `tailwindcss` and `@iconify-json/lucide`). Inside this repository declare `"@ecsplico/editor": "workspace:*"`.
|
|
55
|
-
2. Register the module **after** `@nuxt/ui` (it patches Nuxt UI's generated `ui.css` template and throws if that template is missing). The module adds every feature stylesheet to `css` (`themes.css` last), puts the package into `build.transpile` and Nitro's `externals.inline`, enables Nitro websockets, installs the client plugin `editor-context-nuxt-ui.client.ts` (`createEditor({ kit: nuxtUiKit(), settings: { remote: true } })`; the module has no `kit` option, the Vue binding is Nuxt UI) and scans the Nitro routes. It registers no component or composable.
|
|
56
|
-
|
|
57
|
-
```ts
|
|
58
|
-
// nuxt.config.ts
|
|
59
|
-
export default defineNuxtConfig({
|
|
60
|
-
ssr: false, // TipTap renders on the client only
|
|
61
|
-
modules: ['@nuxt/ui', '@ecsplico/editor/nuxt'],
|
|
62
|
-
tiptapEditor: { ai: { /* optional; presets, slots, rateLimit, transcription: integration guide §5 */ }, collab: { authenticateUpgrade: false /* true: refuse an unauthenticated /collab upgrade with HTTP 401 (cookie hosts only) */ } },
|
|
63
|
-
})
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
3. Register an `EditorAdapter` in a Nitro plugin. Every package route calls `useEditorAdapter()`, which throws without a registered adapter. This one keeps everything in memory and lets any visitor in; replace `authenticate` and the storage with the host's ([integration guide §3](./integration.md#3-editoradapter-auth-and-storage) lists every method, the routes that call it and the required results):
|
|
67
|
-
|
|
68
|
-
```ts
|
|
69
|
-
// server/plugins/editor-adapter.ts
|
|
70
|
-
import type { JSONContent } from '@tiptap/core'
|
|
71
|
-
import { type EditorAdapter, setEditorAdapter } from '@ecsplico/editor/server'
|
|
72
|
-
|
|
73
|
-
export default defineNitroPlugin(() => {
|
|
74
|
-
const contents = new Map<string, JSONContent>()
|
|
75
|
-
const states = new Map<string, Uint8Array>()
|
|
76
|
-
const assets = new Map<string, Parameters<EditorAdapter['storeAsset']>[1]>()
|
|
77
|
-
setEditorAdapter({
|
|
78
|
-
authenticate: async () => ({ id: 'demo', username: 'demo' }), // `null` = 401 on API routes; on /collab the socket is closed with 4401 (HTTP 401 at the upgrade with `collab.authenticateUpgrade`)
|
|
79
|
-
loadContent: async id => contents.get(id) ?? null,
|
|
80
|
-
storeContent: async (id, content) => { contents.set(id, content) },
|
|
81
|
-
listUsers: async () => [],
|
|
82
|
-
listContents: async () => [...contents].map(([id, content]) => ({ id, content })),
|
|
83
|
-
loadState: async id => states.get(id) ?? null,
|
|
84
|
-
storeState: async (id, state) => { states.set(id, state) },
|
|
85
|
-
removeState: async (id) => { states.delete(id) },
|
|
86
|
-
storeAsset: async (id, asset) => { assets.set(`${id}/${asset.name}`, asset) },
|
|
87
|
-
loadAsset: async (id, name) => {
|
|
88
|
-
const asset = assets.get(`${id}/${name}`)
|
|
89
|
-
if (!asset) return null
|
|
90
|
-
const { data, ...record } = asset
|
|
91
|
-
return { record, data }
|
|
92
|
-
},
|
|
93
|
-
// Omit loadSettings/storeSettings: settings stay in the browser (GET answers 204).
|
|
94
|
-
// Omit listThemes/loadTheme: the themes routes answer 501 and the standard look stays.
|
|
95
|
-
})
|
|
96
|
-
})
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
4. Mount the editor. `app.vue` must wrap pages in `<UApp>` (overlays, toasts, tooltips). The toolbar is a sibling that receives the editor from `ready`:
|
|
100
|
-
|
|
101
|
-
```vue
|
|
102
|
-
<script setup lang="ts">
|
|
103
|
-
import type { Editor, JSONContent } from '@tiptap/vue-3'
|
|
104
|
-
import { AdvancedEditor } from '@ecsplico/editor/vue/advanced'
|
|
105
|
-
import { EditorToolbar } from '@ecsplico/editor/vue'
|
|
106
|
-
import { ref, shallowRef } from 'vue'
|
|
107
|
-
|
|
108
|
-
const content = ref<JSONContent>()
|
|
109
|
-
const editor = shallowRef<Editor>()
|
|
110
|
-
</script>
|
|
111
|
-
|
|
112
|
-
<template>
|
|
113
|
-
<EditorToolbar :editor="editor" />
|
|
114
|
-
<AdvancedEditor v-model="content" @ready="editor = $event" />
|
|
115
|
-
</template>
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Without a `collaboration` prop the editor is standalone (JSON `v-model`, own undo history). Collaboration is a mode fixed at mount: pass `:collaboration="{ ydoc, provider, user }"` (connect the provider to `/collab/:id`, [integration guide §6](./integration.md#6-collaboration-on-the-client)).
|
|
119
|
-
|
|
120
|
-
`AdvancedEditor` pulls in every feature. For a smaller bundle use `SimpleEditor` or compose your own list (below). For the simple editor in plain Vue (no Nuxt, no backend) follow [usage guide, Simple editor in plain Vue](./usage.md#simple-editor-in-plain-vue); its pieces are:
|
|
121
|
-
|
|
122
|
-
```ts
|
|
123
|
-
// vite.config.ts: plugins: [vue(), ui({ router: false })]
|
|
124
|
-
// main.ts
|
|
125
|
-
import ui from '@nuxt/ui/vue-plugin'
|
|
126
|
-
import { createEditor } from '@ecsplico/editor/vue'
|
|
127
|
-
import { createApp } from 'vue'
|
|
128
|
-
import App from './App.vue'
|
|
129
|
-
import './style.css'
|
|
130
|
-
|
|
131
|
-
createApp(App).use(ui).use(createEditor()).mount('#app')
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
```css
|
|
135
|
-
/* style.css: core.css AFTER Tailwind and Nuxt UI; @source lets Tailwind scan the library (path relative to this file) */
|
|
136
|
-
@import "tailwindcss";
|
|
137
|
-
@import "@nuxt/ui";
|
|
138
|
-
@import "@ecsplico/editor/styles/core.css";
|
|
139
|
-
@source "../../../packages/editor/src";
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Choosing a preset or features
|
|
143
|
-
|
|
144
|
-
| Goal | Use |
|
|
145
|
-
|---|---|
|
|
146
|
-
| Rich text only, no backend, smallest bundle | `SimpleEditor` / `simpleEditor()` (feature `core`) |
|
|
147
|
-
| Everything, Nuxt module as the backend | `AdvancedEditor` / `advancedEditor({ compositeKinds? })` |
|
|
148
|
-
| Something in between, or the advanced set plus an own feature | `defineEditor({ features: [...] })` mounted with `EditorSurface` |
|
|
149
|
-
|
|
150
|
-
Advanced list in schema order: `core`, `media`, `transcript`, `composites`, `mentions`, `authors`, `comments`, `ai`, `collab`, `block-ui`, `composite-media`, `composite-ai`, `transcript-ai`, `themes`.
|
|
151
|
-
|
|
152
|
-
| Feature (factory, entries) | Needs (`requires`) | Backend |
|
|
153
|
-
|---|---|---|
|
|
154
|
-
| `coreFeature()` (`/core`) | none | none |
|
|
155
|
-
| `mediaFeature()` (`/media/vue`, `/media/react`; `mediaFeatureCore` in `/media`) | none | uploads (`/api/editor/assets/:id`) or a host `upload` function |
|
|
156
|
-
| `mentionsFeature()` (`/mentions`, no components: both surfaces) | none | `/api/editor/users`, `/api/editor/tags` or host `metadata` lists |
|
|
157
|
-
| `transcriptFeature()` (`/transcript/vue`, `/transcript/react`) | none | none |
|
|
158
|
-
| `authorsFeature()` (`/authors/vue`, `/authors/react`) | none | none (author comes from the collaboration session `user`) |
|
|
159
|
-
| `collabFeature()` (`/collab/vue`, `/collab/react`) | none | `/collab/:id` websocket; active only when `collaboration` is passed to the surface |
|
|
160
|
-
| `commentsFeature({ model? })` (`/comments/vue`, `/comments/react`) | `collab`, none with `model` | comments live in the Y.Doc, or in the host's `CommentsModel` (`model: getEditor => CommentsModel`) |
|
|
161
|
-
| `compositeFeature({ kinds? })` (`/composites/vue`, `/composites/react`) | none | none (also mounts the composite overlay: status/tag chips on each title line and, on the kind icon, a popover with the type dropdown (warns before `setCompositeKind`, naming the field values that would be lost), the kind's fields and the summary; also read-only: type as text, fields disabled; enforces the kinds' accepted children, `CompositeKind.accepts`: an edit that nests a Baustein into one that does not accept its kind is refused with the notice `composites.nesting.title` („Verschachtelung nicht möglich“)) |
|
|
162
|
-
| `aiFeature()` (`/ai/vue`, `/ai/react`; framework-free `aiFeatureCore` in `/ai`) | none | `/api/ai/{models,generate,chat,complete}` |
|
|
163
|
-
| `blockUiFeature()` (`/block-ui/vue`, `/block-ui/react`) | none | none (drag handle, hover actions) |
|
|
164
|
-
| `themesFeature()` (`/themes/vue`, `/themes/react`) | none | adapter `listThemes`/`loadTheme` |
|
|
165
|
-
| `compositeMediaFeature()` (`/integrations/composite-media`, both surfaces) | `composites`, `media` | uploads |
|
|
166
|
-
| `compositeAiFeature()` (`/integrations/composite-ai`, both surfaces) | `composites`, `ai`, `media` | AI plus `/api/ai/transcribe` |
|
|
167
|
-
| `transcriptAiFeature()` (`/integrations/transcript-ai`, both surfaces) | `transcript`, `ai` | AI plus `/api/ai/transcript-cleanup` |
|
|
168
|
-
|
|
169
|
-
```ts
|
|
170
|
-
import { coreFeature, defineEditor } from '@ecsplico/editor/core'
|
|
171
|
-
import { mediaFeature } from '@ecsplico/editor/media/vue' // or '/media/react' with a React surface
|
|
172
|
-
import { mentionsFeature } from '@ecsplico/editor/mentions'
|
|
173
|
-
|
|
174
|
-
// The models come from the app context, so no component setup is needed for the AI feature (themesFeature() of the Vue binding is the exception: call it in setup).
|
|
175
|
-
const preset = defineEditor({ features: [coreFeature(), mediaFeature(), mentionsFeature()] })
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
```vue
|
|
179
|
-
<EditorSurface v-model="content" :preset="preset" @ready="editor = $event" />
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
`defineEditor` keeps the given order (toolbar groups, menu entries, schema) and throws on a duplicate id, on a `requires` entry that is not in the list and on a second contributor of a singleton hook (`parseMarkdown`, `segment`, `structure`, `wrapImport`, `migrateContent`, `anchorResolver`, `formatAiResult`). It installs nothing for you. A Vue list takes the factories from `/<x>/vue`, a React list those from `/<x>/react`; mixing them is a type error (`VueFeature` is `EditorFeature<Component>`, `ReactFeature` is `EditorFeature<ComponentType<{ editor }>>`), while features without components (`coreFeature()`, `mentionsFeature()`, the integrations) fit both. A host that brings its own UI kit calls `<x>FeatureCore(ui)` with its own components ([integration guide §1](./integration.md#per-feature-entries-framework-free-vue-react)). When you use feature entries directly in a plain app, also import that feature's stylesheet. Per-feature usage: [usage guide](./usage.md); composition and entries: [integration guide §1](./integration.md#1-feature-composition-and-entries).
|
|
183
|
-
|
|
184
|
-
## Contributing a custom feature
|
|
185
|
-
|
|
186
|
-
A feature is an object whose optional members are the contribution points. Fill only what you need ([`EditorFeature`](../src/core/feature.ts)):
|
|
187
|
-
|
|
188
|
-
| Member | Contributes |
|
|
189
|
-
|---|---|
|
|
190
|
-
| `extensions(ctx)` | TipTap extensions (nodes, marks, plugins) |
|
|
191
|
-
| `toolbar(ctx)` | `ToolbarGroup[]`; groups of the same `id` from several features merge |
|
|
192
|
-
| `blockActions(ctx)`, `slashCommands(ctx)` | hover actions (shown by `block-ui`), `/` menu rows |
|
|
193
|
-
| `overlays` | framework components (`EditorFeature<C>`; Vue: `VueFeature`) mounted beside the content, receiving `{ editor }` |
|
|
194
|
-
| `setup(ctx)` | per-surface side effect when the surface mounts (runtime, listener, `<head>` element); returns an optional **teardown** the surface runs when it unmounts |
|
|
195
|
-
| `settingsTabs` | factory `(ctx: EditorContext) => SettingsTab<C>[]` for the tabs of `EditorSettingsPanel`/`EditorSettingsModal` (`SettingsTab<C>`: `label` is already translated, the `component` slot is the framework's component type) |
|
|
196
|
-
| `metadataDefaults(ctx)` | built-in `@`/`#`-style lists |
|
|
197
|
-
| `blocks`, `conversions` | block pipeline stages, „Umwandeln in …“ providers |
|
|
198
|
-
| `anchorResolver`, `aiContext`, `formatAiResult` | collaboration positions, what AI knows about the document, AI result formatting |
|
|
199
|
-
| `aiBlockData` | per-Baustein material for „Baustein füllen (KI)“ (additive; the host owns the fetch) |
|
|
200
|
-
| `requires` | ids of features that must also be listed |
|
|
201
|
-
|
|
202
|
-
```ts
|
|
203
|
-
// notes/feature.ts
|
|
204
|
-
import { commandItem } from '@ecsplico/editor/core'
|
|
205
|
-
import type { VueFeature } from '@ecsplico/editor/vue'
|
|
206
|
-
import SettingsNotesTab from './SettingsNotesTab.vue'
|
|
207
|
-
|
|
208
|
-
export function notesFeature(): VueFeature {
|
|
209
|
-
return {
|
|
210
|
-
id: 'notes',
|
|
211
|
-
// requires: ['block-ui'], // fail at composition time when a dependency is missing
|
|
212
|
-
toolbar: () => [{
|
|
213
|
-
id: 'notes',
|
|
214
|
-
order: 100,
|
|
215
|
-
items: [
|
|
216
|
-
commandItem({
|
|
217
|
-
id: 'dash',
|
|
218
|
-
icon: 'i-lucide-minus',
|
|
219
|
-
label: 'Gedankenstrich',
|
|
220
|
-
command: chain => chain.insertContent('\u2013'),
|
|
221
|
-
}),
|
|
222
|
-
],
|
|
223
|
-
}],
|
|
224
|
-
slashCommands: () => [{
|
|
225
|
-
id: 'strich',
|
|
226
|
-
label: 'Gedankenstrich',
|
|
227
|
-
icon: 'i-lucide-minus',
|
|
228
|
-
run: editor => editor.chain().focus().insertContent('\u2013').run(),
|
|
229
|
-
}],
|
|
230
|
-
// Runs in every mounted surface's setup and returns its teardown. Several surfaces of one app share state: dedupe per app
|
|
231
|
-
// inside and reference-count the release (the theme runtime keys a WeakSet by `ctx.settings`). Report problems with `ctx.notify({ title, kind })`.
|
|
232
|
-
setup: (ctx) => {
|
|
233
|
-
const onKey = (event: KeyboardEvent) => {
|
|
234
|
-
if (event.key === 'F2') ctx.ui.openSettings('notes')
|
|
235
|
-
}
|
|
236
|
-
document.addEventListener('keydown', onKey)
|
|
237
|
-
return () => document.removeEventListener('keydown', onKey)
|
|
238
|
-
},
|
|
239
|
-
// Tab ids must be unique across the preset; the panel renders nothing when no feature contributes a tab.
|
|
240
|
-
settingsTabs: ctx => [{ id: 'notes', label: ctx.t('notes.tab'), icon: 'i-lucide-notebook', component: SettingsNotesTab }],
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
```vue
|
|
246
|
-
<!-- notes/SettingsNotesTab.vue -->
|
|
247
|
-
<script setup lang="ts">
|
|
248
|
-
import USwitch from '@nuxt/ui/components/Switch.vue'
|
|
249
|
-
import { SettingsSection } from '@ecsplico/editor/vue'
|
|
250
|
-
import { ref } from 'vue'
|
|
251
|
-
|
|
252
|
-
const shout = ref(false) // local state; see the settings note below for persisted values
|
|
253
|
-
</script>
|
|
254
|
-
|
|
255
|
-
<template>
|
|
256
|
-
<SettingsSection title="Notizen">
|
|
257
|
-
<div class="py-3">
|
|
258
|
-
<USwitch v-model="shout" label="Hervorheben" />
|
|
259
|
-
</div>
|
|
260
|
-
</SettingsSection>
|
|
261
|
-
</template>
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
Compose it with the advanced list (or any list) and mount it with the same preset the toolbar and settings UI receive:
|
|
265
|
-
|
|
266
|
-
```ts
|
|
267
|
-
import { defineEditor } from '@ecsplico/editor/core'
|
|
268
|
-
import { advancedEditor } from '@ecsplico/editor/vue/advanced'
|
|
269
|
-
import { notesFeature } from './notes/feature'
|
|
270
|
-
|
|
271
|
-
const preset = defineEditor({ features: [...advancedEditor().features, notesFeature()] })
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
Things that bite:
|
|
275
|
-
|
|
276
|
-
- Items gated by an own `ability` (`commandItem({ ability })`, `SlashCommandItem.ability`, `BlockAction.ability`) stay inert until the ability exists at the caret. Grant custom abilities at root through the surface prop: `:abilities="{ root: [...ROOT_ABILITIES, MY_ABILITY] }"` (`ROOT_ABILITIES` from `/core/schema`).
|
|
277
|
-
- The hover bar of `BlockAction`s is right-aligned 8px inside the editor's right edge for every block and is hidden while the editor is read-only.
|
|
278
|
-
- A feature that adds a **node** must be known to every schema that touches the document. The Nuxt module's collab route builds its schema from `advancedSchemaExtensions()` plus the adapter's `schemaExtensions()`, so register the Vue-free node file there (`schemaExtensions: () => [YourNode]`, [extending guide, Collaboration and the server schema](./extending.md#collaboration-and-the-server-schema)); a custom Hocuspocus server builds `getSchema([...advancedSchemaExtensions(), YourNode])` itself. Standalone editors (JSON `v-model`) need none of this. `editorBlock: true` (via `NodeFlags`) gives an own node block IDs, also on the server.
|
|
279
|
-
- A tab component can bind only to fields that exist in `EditorSettings`: `parseEditorSettings` drops unknown keys, so new keys are neither stored locally nor sent to the server. The tab component runs inside the app, so it can call `useEditorSettings()` (from `/vue`: `{ settings, ready, synced }` as refs; from `/react`: the same names as values).
|
|
280
|
-
- Factories (`extensions`, `toolbar`, `slashCommands`, ...) receive the `FeatureContext`: `app`, `settings`, `metadata`, `ui`, `notify`, `fetch`, `ai`, `documentId`, `upload`, `collaboration`, `getEditor()`. `settings` is a framework-free store: read `ctx.settings.get()`, change it with `ctx.settings.update(s => { ... })` (or `set`), observe it with `ctx.settings.subscribe(listener)`. `ctx.notify({ id?, title, description?, kind?, icon?, duration? })` shows a user-facing notice (Nuxt UI toast or sonner toast, per surface; features never import a toast library). `ctx.app` is the app context that app-level models key on. Toolbar and block-action menus return core `MenuItem[]` (`type?: 'label' | 'separator'`, `label`, `description`, `icon`, `disabled`, `onSelect`). `getEditor()` is `undefined` while extensions are constructed; use it in event handlers only. Components in `overlays` and `component` toolbar items receive `{ editor }` as props.
|
|
281
|
-
|
|
282
|
-
Complete worked example with node, node view, conversions and AI description: [extending guide, Path B](./extending.md#path-b-a-feature) and the runnable `app/editor/callout/`. Lighter path without a feature (`extensions` and `slashCommands` props): [extending guide, Path A](./extending.md#path-a-extensions-and-slashcommands).
|
|
283
|
-
|
|
284
|
-
## Server side: `EditorAdapter`
|
|
285
|
-
|
|
286
|
-
- The package owns the routes (`/collab/:id`, `/api/ai/*`, `/api/editor/{users,tags,settings,assets,themes}`), the Hocuspocus server, rate limiting and wire formats. The host owns identity and storage and passes both in through the single `EditorAdapter` registered with `setEditorAdapter` in a Nitro plugin.
|
|
287
|
-
- Required methods: `authenticate`, `loadContent`, `storeContent`, `listUsers`, `listContents`, `loadState`, `storeState`, `removeState`, `storeAsset`, `loadAsset`. Optional: `authorize`, `contentVersion`, `schemaExtensions` (collab, below), `loadSettings`/`storeSettings` (omit both: settings stay in `localStorage`), `listThemes`/`loadTheme` (omit: themes routes answer 501), `storeTheme`/`removeTheme` (omit: upload and delete answer 501).
|
|
288
|
-
- Optional AI hooks: `languageModel(ref, user)` supplies the AI SDK model for a model reference (consulted before the environment presets; `null` falls through, then 400), `listModels(user)` what `GET /api/ai/models` lists (`null` lists the presets). A host whose agent chat lives elsewhere drives the review UI with `createAgentOpReview({ notify, t })` from `/ai` (`propose`, `decide`, `reveal`, `feedback`, `end`) and passes `send` instead of `chat` to `createAiSidebarFlow`.
|
|
289
|
-
- Model-facing agent texts of `/ai/protocol` (`checkAgentOps(raw, { …context, locale })`, `agentShownMessage(ops, dropped, { locale })`, `agentFeedbackText(feedback, { locale })`, `agentRetryMessage`, `agentOpSummary`) are German by default and English with `locale: 'en'`; the package's own `/api/ai/chat` prompts and results stay German.
|
|
290
|
-
- A host that exposes the edit operations under its own tool name builds the retry result with `agentRetryMessage(problems, scoped, { locale, tool, partial })`, so the text tells the model to call `tool` (default `edit_document`) again rather than the editor's tool. Without `partial` the text says nothing was applied and asks for the whole corrected list (the package's own all-or-nothing retry); a host that already shows the valid operations passes `partial: true`, and the text asks only for corrected versions of the listed operations.
|
|
291
|
-
- `authenticate` receives `{ headers, token }`: `token` is the client's `collaboration.token` (string or async function on the surface prop; `undefined` for HTTP routes and token-less clients). Without a session cookie `getUserSession` throws outside a main handler: map that to `null` (see `server/plugins/editor-adapter.ts` in this repository). `null` answers 401 on API routes. On `/collab/:id` the upgrade succeeds first (101) and an unauthenticated socket is closed with code 4401 afterwards; with the Nuxt module option `collab.authenticateUpgrade: true` the upgrade is authenticated from the headers alone and refused with HTTP 401 (clients that authenticate only by `collaboration.token` cannot connect then). Integration guide §4, Auth notes.
|
|
292
|
-
- Authorization per document: `authorize(user, id)` runs in Hocuspocus `onConnect` with the object `authenticate` returned; `null` rejects the connection, `{ readOnly: true }` lets it sync but applies none of its edits. Without `authorize` any authenticated user may edit any document name.
|
|
293
|
-
- `contentVersion(id)` (opaque string, e.g. mtime or hash) makes a document rewritten behind the editor's back safe: the server keeps the version next to the Yjs state (the bytes `storeState` receives carry a version prefix; state from earlier releases loads as version `null`). On load a differing version discards the state, calls `removeState` and re-seeds from `loadContent`; an open document is not written back over the rewrite but merged with it on its next store, or right away when the host calls `collabContentChanged(id)` after its write. The version is read right after every `storeContent`, so it must reflect that write.
|
|
294
|
-
- `schemaExtensions()` returns the host's own Vue-free node and mark extensions; the collab server appends them to `advancedSchemaExtensions()` so they survive the JSON↔Yjs conversion. `collabStats()` returns `{ connections, documents }` of the running server.
|
|
295
|
-
- Delete a document with `forgetCollabDocument(id)` **before** removing its JSON.
|
|
296
|
-
- This repository has no login: `server/middleware/demo-session.ts` signs every `/api/` request into a demo user and `server/api/auth/switch.post.ts` switches the demo user. That is demo plumbing, not part of the package.
|
|
297
|
-
- AI secrets come from environment variables only (`NUXT_TIPTAP_EDITOR_AI_API_KEY`, per-preset `NUXT_TIPTAP_EDITOR_AI_PRESETS_<ID>_API_KEY`, `NUXT_TIPTAP_EDITOR_AI_TRANSCRIPTION_API_KEY`); preset ids must be camelCase. See [integration guide §5](./integration.md#5-ai-configuration-and-secrets).
|
|
298
|
-
- Routes, status codes and the adapter table: [integration guide §3 and §4](./integration.md#3-editoradapter-auth-and-storage). Server-side schema for converting JSON and Yjs: [§8](./integration.md#8-vue-free-advanced-schema-for-servers).
|
|
299
|
-
|
|
300
|
-
## Language
|
|
301
|
-
|
|
302
|
-
- Every string the editor shows (toolbar, slash menu, hover actions, settings, AI task names, comments, notices) comes from the catalogs `src/i18n/{de,en}/*.ts`, keyed by stable dotted ids (`toolbar.bold`, `comments.tab`, `ai.task.translate.label`); `de` is the default and the source of the key set, `en` has exactly the same keys (a missing one is a type error). Catalog helpers are exported by `/core`: `createTranslator`, `CATALOGS`, `LOCALES`, `DEFAULT_LOCALE`, `isLocale`, `Locale`, `MessageKey`, `Messages`, `Translate`.
|
|
303
|
-
- Choose the language once per app: `createEditorContext({ locale: 'en', messages: { 'toolbar.bold': 'Strong' } })` (React and framework-free hosts), `app.use(createEditor({ locale, messages }))` (Vue), or the Nuxt module options `tiptapEditor: { locale: 'en', messages: { … } }` (JSON-serialisable; forwarded to the client plugin). `messages` is a partial catalog applied on top of `locale`; `{name}` placeholders take `params`. An unknown locale throws. The locale is fixed for the life of the context: a host that switches languages at run time recreates the context (Vue: remount the app or key it; React: new `EditorContextProvider` value).
|
|
304
|
-
- Features read `ctx.t` (`FeatureContext.t`, `EditorContext.t`, `ctx.locale`) in their factories: toolbar items, slash commands, block actions, conversion labels (`ConversionProvider.label(target, t)`) and `settingsTabs(ctx)` are built in the context's language. Components call `useEditorI18n()` (`/vue` and `/react`) and get `{ t, locale }`. A feature of your own adds its keys by passing its own strings or by extending the `messages` override; the shipped keys are the `MessageKey` union.
|
|
305
|
-
- Setting values stored as ids (`'margin'`, `'Deutsch'`, `'flat'`, …) never change with the language: only their display label comes from the catalog (`*_KEYS` tables mapping an id to a key; `authorStyleItems(t)`, `defaultCompositeKinds(t)`).
|
|
306
|
-
- Markdown: the source view of `MarkdownSurface` (aria label, Apply, Cancel; keys `markdown.source.*`; override through `messages`) and the `message` of every `MarkdownDiagnostic` (`markdown.diagnostic.*`) are in the context's language. `markdownToContent(editor, body, { policy, t })` and `createSourceMode({ getEditor, t })` take an explicit translator; without one they use the editor's registered surface, else the default locale.
|
|
307
|
-
- `bun run check:editor-i18n` (`packages/editor/checks/i18n.ts`) fails when a user-facing literal (label/description/placeholder/aria/alt/title properties and attributes, JSX and template text, German words) appears in `src` outside `src/i18n`, or when a catalog key is unused or missing in `en`. Text that is not UI (model prompts, stored ids, developer errors) is marked `// i18n-ignore: <reason>`; the run lists every honoured pragma.
|
|
308
|
-
|
|
309
|
-
## Settings and themes
|
|
310
|
-
|
|
311
|
-
- Settings are one versioned JSON object (`EditorSettings`, `version: 1`: `editing`, `ai`, `blocks`, `appearance`) shared by every editor, panel and tree of one app. `createEditor()` (Vue plugin around the framework-free `createEditorContext()` from `/core`; React: `EditorContextProvider` around the same context) keeps it in `localStorage` (`tiptap-editor:settings`); `createEditor({ settings: { remote: true } })` (what the Nuxt plugin installs; React: `createEditorContext({ settings: { remote: true } })`) syncs it per account through `GET`/`PUT /api/editor/settings`. Read and edit it with `useEditorSettings()` (`/vue` or `/react`); in features use the `ctx.settings` store. Validate with `parseEditorSettings` (drops unknown keys, replaces invalid values) or `editorSettingsSchema`. [Integration guide §11](./integration.md#11-settings-persistence-and-app-lifetime).
|
|
312
|
-
- Settings UI: tabs come from the features of a preset (`composites` `editing`, `ai`, `authors`, `comments`, `themes` `appearance`); the simple editor has none. `EditorSettingsPanel` (props `preset`, `contentClass?`, `v-model:tab`) places the tabs anywhere; `EditorSettingsModal` (props `preset`, `v-model:open`, `v-model:tab`) is the same panel in a fixed-width (`42rem`) popup with a blurred backdrop. Both render nothing when the preset has no tab.
|
|
313
|
-
- **`settingsUi`** (prop of `EditorSurface` and `AdvancedEditor`): `'internal'` (default) mounts the modal inside the surface and the toolbar's settings entry opens it. `'external'` mounts nothing and emits `settingsOpen(tab?)`; the host then shows its own `EditorSettingsPanel` or `EditorSettingsModal` for the same `preset`:
|
|
314
|
-
|
|
315
|
-
```vue
|
|
316
|
-
<script setup lang="ts">
|
|
317
|
-
import { EditorSettingsModal, EditorSurface } from '@ecsplico/editor/vue'
|
|
318
|
-
import { advancedEditor } from '@ecsplico/editor/vue/advanced'
|
|
319
|
-
import { ref } from 'vue'
|
|
320
|
-
|
|
321
|
-
const preset = advancedEditor() // in setup
|
|
322
|
-
const open = ref(false)
|
|
323
|
-
const tab = ref<string>()
|
|
324
|
-
</script>
|
|
325
|
-
|
|
326
|
-
<template>
|
|
327
|
-
<EditorSurface :preset="preset" settings-ui="external" @settings-open="(t) => { tab = t; open = true }" />
|
|
328
|
-
<EditorSettingsModal v-model:open="open" v-model:tab="tab" :preset="preset" />
|
|
329
|
-
</template>
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
- **Themes** (`themesFeature()`, part of `advancedEditor()` on both surfaces): the setting `appearance.theme` (`null` = standard look) names an Obsidian theme served by `GET /api/editor/themes/:id`. The feature's `setup` hook starts one runtime per app as soon as the first surface mounts (reference-counted, released by the teardown: on Vue it lives until the Vue app unmounts, on React until the last surface that started it unmounts), injects the scoped CSS as `<style data-tiptap-theme>` and sets `obsidian-theme theme-dark|theme-light` on `<html>` (following `html.dark`/`html.light`, else the system preference). `styles/themes.css` bridges Obsidian variables onto every `--ui-*` token (React: `react/styles/themes-bridge.css` onto the shadcn tokens), so the **whole site** is themed, not only the editor. Needs an adapter with `listThemes`/`loadTheme`. Builtin themes in this repository (`server/themes/<id>/`): `nord`, `things`, `minimal`, `catppuccin`, `border`, `blue-topaz`, `tokyo-night`. Details, mapping table, limits: [usage guide, Themes](./usage.md#themes-obsidian).
|
|
333
|
-
|
|
334
|
-
## Pitfalls and invariants
|
|
335
|
-
|
|
336
|
-
- **CSS order.** `core.css` after Tailwind and Nuxt UI, plus the CSS of every feature you use, `themes.css` last. Tailwind must see the library's classes (`@source` to `packages/editor/src` in plain Vue; the Nuxt module appends it to `ui.css` itself). Without this the editor renders unstyled or without utility classes.
|
|
337
|
-
- **Editor context is mandatory.** `EditorSurface`, `SimpleEditor`, `AdvancedEditor` and `EditorToolbar` throw without `app.use(createEditor())` (the Nuxt module does this in its client plugin); the React components throw without `<EditorContextProvider context={createEditorContext()}>`, and the React host owns (disposes) that context.
|
|
338
|
-
- **Notices.** Features send user-facing messages through `ctx.notify` / the context's `notify` (`Notifier`, `silentNotifier` drops them). Vue: the queued notifier hands them to Nuxt UI toasts once a surface mounted (needs `<UApp>`). React: pass `createEditorContext({ notify: reactNotifier })` and mount sonner's `<Toaster />` (exported by `/react`) once; without it no notice is visible.
|
|
339
|
-
- **UI provider.** Wrap the page in `<UApp>`; plain Vue also needs `app.use(ui)` (`@nuxt/ui/vue-plugin`) and the `ui({ router: false })` Vite plugin.
|
|
340
|
-
- **SSR.** Editors are client-only. Nuxt apps in this repository run `ssr: false`; with SSR enabled wrap editors in `<ClientOnly>`.
|
|
341
|
-
- **Mount-time props.** The preset (schema, features), `collaboration`, `abilities`, `extensions`, `slashCommands`, `blockActions`, `compositeKinds`, `documentId`, `upload` are read once at setup. Change them by remounting with a new `key`. `editable`, `metadata` and the model stay reactive. Build presets in `<script setup>` (Vue) or a component/`useMemo` (React), not on every render.
|
|
342
|
-
- **Stable props.** Pass `metadata`, `abilities` and `extensions` as constants; a new object per render replaces the lists each time.
|
|
343
|
-
- **Schema match.** A simple editor rejects advanced JSON through the `contentError` event (the last valid document stays). `collaboration` needs a preset containing `collab`; `commentsFeature()` needs `collab`.
|
|
344
|
-
- **Bundle isolation.** `core`/`settings` import no feature; a feature imports `core`, `settings` and its own `schema`/`protocol`, never another feature; integrations import only the features they connect; the `simple` bundle contains no feature code, Yjs, AI SDK, Nuxt or server modules. Keep it that way when adding code, and prove it with `check:editor-entries`. Rules: [integration guide §13](./integration.md#13-dependency-rules-and-bundle-proof).
|
|
345
|
-
- **Entries.** Server code imports only framework-free entries (`/schema`, `/protocol`, `/types`, `/settings`) or `/server`. A new public entry needs an explicit `package.json#exports` row; there is no wildcard.
|
|
346
|
-
- **Icons.** `i-lucide-*` names resolve at build time inside the Vite root; a workspace library lies outside it. Bundle them (see `examples/vue-simple/vite.config.ts`) to avoid Iconify API requests at runtime.
|
|
347
|
-
- **React hosts.** CSS: Tailwind, `tw-animate-css`, then either `.../react/styles/ui-vars.css`, `core.css` and the feature sheets, or for the advanced editor the single `.../react/styles/advanced.css`; the shadcn theme block, and `@source` to `packages/editor/src`; icons: `addCollection(lucide)` from `@iconify/react` before rendering; `<Toaster />` for notices. The preset, `metadata`, `abilities`, `extensions` and `slashCommands` are mount-time: keep them module constants (new objects per render replace the lists). `editor` from `onReady` goes in `useState`, and `EditorToolbar` takes it as `editor`. Examples: [usage guide, Simple editor in React](./usage.md#simple-editor-in-react) and [Advanced editor in React](./usage.md#advanced-editor-in-react).
|
|
348
|
-
- **Settings keys.** Only keys of `EditorSettings` persist; unknown ones are dropped on read and write.
|
|
349
|
-
- **Design tokens.** `@ecsplico/editor/styles/tokens.css` declares the shared `--sk-*` variables (`--sk-bg`, `--sk-fg`, `--sk-muted`, `--sk-border`, `--sk-primary`, `--sk-primary-fg`, `--sk-success`, `--sk-warning`, `--sk-danger`, `--sk-radius`, `--sk-font`) under `:where(:root)` (dark values under `:where(.dark)`). Later UI work in this package reads `--sk-*`; map them once in the host.
|
|
350
|
-
- **Module order.** `@nuxt/ui` before `@ecsplico/editor/nuxt` in `modules`.
|
|
351
|
-
- **Adapters tier.** Entries under `adapters/`, `anchors`, `comments/{server,json,drizzle,client}` and `server/nitro` supply storage and wiring; they import no application code. Vue is reachable only from `./adapters/vue`, Nitro (`h3`) only from `./server/nitro`, `drizzle-orm` only from the two drizzle entries, React from none; `./adapters` is types only. `./adapters/react`, `./server/nest` and `./adapters/prisma` are reserved and not exported. The Nitro host and `useEditorDocument` speak one wire contract: `GET`/`PUT /api/editor/documents/:id` (TipTap JSON, 404 = missing, `PUT` 204 and only for adapters that manage documents), `GET`/`POST /api/editor/comments/:id` (`handleCommentsRequest`, which trusts its caller), `/collab/:id` (Hocuspocus; `collaboration.url` is `ws://host/collab`). Every route authenticates through `adapter.authenticate({ headers, token })`; `null` answers 401; the default outside production is an anonymous dev user, in production nobody. The JSON and forge adapters and the JSON comment store are single-node. Mount the surface with `:key="id"` and `v-if="doc.ready.value"`, bind with `v-bind="doc.bind.value"`. Runnable reference: `examples/vue-nitro-json` (`bun run proto:vue-nitro-json`, port 3046).
|
|
352
|
-
|
|
353
|
-
## Verify
|
|
354
|
-
|
|
355
|
-
Run from the repository root after `bun install` (on a clean checkout build `examples/vue-simple` once before the editor typecheck: it prepares the Nuxt UI theme aliases the typecheck needs):
|
|
356
|
-
|
|
357
|
-
```sh
|
|
358
|
-
bun run --cwd examples/vue-simple build # once on a clean checkout
|
|
359
|
-
bun run typecheck:editor # vue-tsc --noEmit -p packages/editor/tsconfig.json (src/nuxt excluded)
|
|
360
|
-
bun run build:editor # tsdown: packages/editor/dist (ESM + .d.ts per export)
|
|
361
|
-
bun run check:editor-entries # builds the editor, then one production build per fixture + module-graph isolation, then the schema snapshot
|
|
362
|
-
bun run check:editor-composition # defineEditor rejects missing `requires`; accepted compositions; one formatAiResult
|
|
363
|
-
bun run test:editor # bun test: inspector model, AI selection flow, surface session on a mounted editor (happy-dom)
|
|
364
|
-
bun run typecheck # nuxt typecheck of the demo app
|
|
365
|
-
bun run --cwd examples/vue-simple typecheck # plain Vue consumer
|
|
366
|
-
bun run --cwd examples/react-simple typecheck # plain React consumer
|
|
367
|
-
bun run --cwd examples/react-advanced typecheck # React consumer of every feature
|
|
368
|
-
bun run dev # Nuxt demo, http://localhost:3031
|
|
369
|
-
bun run --cwd examples/vue-simple dev # plain Vue example, http://localhost:3040
|
|
370
|
-
bun run --cwd examples/react-simple dev # plain React example, http://localhost:3041
|
|
371
|
-
bun run --cwd examples/react-advanced dev # React advanced example (proxies /api and /collab to the Nuxt demo), http://localhost:3043
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
After adding a feature, add a fixture folder `packages/editor/checks/fixtures/<name>/` (an `index.html` plus `main.ts`/`App.vue` — or `main.tsx` for a React fixture — that mounts the surface with its toolbar) and one entry in `FIXTURES` in `packages/editor/checks/entries.ts` with `forbid`, `require` and `allowSource` patterns; features get a `<name>`, a `<name>-react` and a framework-free `headless-<name>` fixture. `check:editor-entries` also fails when the advanced or simple schema differs from the committed snapshot (`checks/fixtures/schema-node/schema.snapshot.json`); regenerate it deliberately with `bun packages/editor/checks/schema.ts --update`.
|
|
375
|
-
|
|
376
|
-
## Where to read next
|
|
377
|
-
|
|
378
|
-
| Task | Guide |
|
|
379
|
-
|---|---|
|
|
380
|
-
| Plain Vue setup, `SimpleEditor` props and events, React setup (`EditorContextProvider`, `EditorSurface`, `EditorToolbar`, `SimpleEditor`, the advanced editor in React), media/mentions/transcript, authors and comments, themes, composites, AI, file browser, the demo app | [Usage guide](./usage.md) |
|
|
381
|
-
| Own blocks and features (node, node view, toolbar, `/` command, conversions, AI description) | [Extending guide](./extending.md) |
|
|
382
|
-
| Nuxt module, `EditorAdapter`, routes, auth, AI secrets, per-feature entries and the UI binding contract, notices and `setup` teardown, collaboration, schema for servers, `DocumentStore`, production, dependency rules | [Integration guide](./integration.md) |
|
|
383
|
-
| Every exported name per entry | [README](../README.md) |
|