@ecsplico/editor 2.1.2 → 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.
Files changed (692) hide show
  1. package/CHANGELOG.md +68 -1
  2. package/README.md +39 -156
  3. package/dist/adapters/comments/drizzle.d.ts +1 -1
  4. package/dist/adapters/comments/{client.js → rest-model.js} +3 -3
  5. package/dist/adapters/comments/rest-model.js.map +1 -0
  6. package/dist/adapters/comments/types.d.ts +2 -2
  7. package/dist/adapters/document-state.d.ts +23 -0
  8. package/dist/adapters/document-state.js +66 -0
  9. package/dist/adapters/document-state.js.map +1 -0
  10. package/dist/adapters/documents.js +14 -11
  11. package/dist/adapters/documents.js.map +1 -1
  12. package/dist/adapters/drizzle.d.ts +2 -2
  13. package/dist/adapters/drizzle.js +97 -88
  14. package/dist/adapters/drizzle.js.map +1 -1
  15. package/dist/adapters/forge.d.ts +12 -7
  16. package/dist/adapters/forge.js +38 -45
  17. package/dist/adapters/forge.js.map +1 -1
  18. package/dist/adapters/http.d.ts +20 -0
  19. package/dist/adapters/http.js +68 -0
  20. package/dist/adapters/http.js.map +1 -0
  21. package/dist/adapters/index.d.ts +5 -5
  22. package/dist/adapters/json.d.ts +3 -3
  23. package/dist/adapters/json.js +58 -49
  24. package/dist/adapters/json.js.map +1 -1
  25. package/dist/adapters/memory.d.ts +21 -0
  26. package/dist/adapters/memory.js +53 -0
  27. package/dist/adapters/memory.js.map +1 -0
  28. package/dist/adapters/nitro.d.ts +23 -20
  29. package/dist/adapters/nitro.js +58 -163
  30. package/dist/adapters/nitro.js.map +1 -1
  31. package/dist/adapters/react.d.ts +55 -0
  32. package/dist/adapters/react.js +209 -0
  33. package/dist/adapters/react.js.map +1 -0
  34. package/dist/adapters/shared.d.ts +15 -21
  35. package/dist/adapters/shared.js +10 -8
  36. package/dist/adapters/shared.js.map +1 -1
  37. package/dist/adapters/vue.d.ts +15 -30
  38. package/dist/adapters/vue.js +36 -87
  39. package/dist/adapters/vue.js.map +1 -1
  40. package/dist/config/index.d.ts +105 -0
  41. package/dist/config/index.js +95 -0
  42. package/dist/config/index.js.map +1 -0
  43. package/dist/core/abilities.js +1 -0
  44. package/dist/core/abilities.js.map +1 -1
  45. package/dist/{adapters/routes.js → core/api-routes.js} +5 -3
  46. package/dist/core/api-routes.js.map +1 -0
  47. package/dist/core/backend-capability.d.ts +7 -0
  48. package/dist/core/backend-capability.js +17 -0
  49. package/dist/core/backend-capability.js.map +1 -0
  50. package/dist/core/backend-types.d.ts +245 -0
  51. package/dist/core/backend-types.js +17 -0
  52. package/dist/core/backend-types.js.map +1 -0
  53. package/dist/core/backend.d.ts +108 -0
  54. package/dist/core/backend.js +14 -0
  55. package/dist/core/backend.js.map +1 -0
  56. package/dist/core/block-convert.d.ts +7 -5
  57. package/dist/core/block-convert.js +28 -5
  58. package/dist/core/block-convert.js.map +1 -1
  59. package/dist/core/command-types.d.ts +89 -0
  60. package/dist/core/commands.d.ts +40 -0
  61. package/dist/core/commands.js +151 -0
  62. package/dist/core/commands.js.map +1 -0
  63. package/dist/core/context.d.ts +17 -20
  64. package/dist/core/context.js +24 -21
  65. package/dist/core/context.js.map +1 -1
  66. package/dist/core/core-feature.d.ts +22 -7
  67. package/dist/core/core-feature.js +51 -18
  68. package/dist/core/core-feature.js.map +1 -1
  69. package/dist/core/define-editor.d.ts +4 -3
  70. package/dist/core/define-editor.js +14 -7
  71. package/dist/core/define-editor.js.map +1 -1
  72. package/dist/core/document-markdown.js +12 -3
  73. package/dist/core/document-markdown.js.map +1 -1
  74. package/dist/core/editor-ui.d.ts +8 -1
  75. package/dist/core/editor-ui.js +9 -8
  76. package/dist/core/editor-ui.js.map +1 -1
  77. package/dist/core/extension-points.d.ts +3 -15
  78. package/dist/core/feature-context.d.ts +8 -7
  79. package/dist/core/feature-context.js +12 -11
  80. package/dist/core/feature-context.js.map +1 -1
  81. package/dist/core/feature.d.ts +35 -19
  82. package/dist/core/feature.js.map +1 -1
  83. package/dist/core/fences.d.ts +2 -1
  84. package/dist/core/fences.js +3 -2
  85. package/dist/core/fences.js.map +1 -1
  86. package/dist/core/fetch-error.d.ts +1 -1
  87. package/dist/core/fetch-error.js +3 -1
  88. package/dist/core/fetch-error.js.map +1 -1
  89. package/dist/core/hash.d.ts +5 -0
  90. package/dist/core/hash.js +11 -0
  91. package/dist/core/hash.js.map +1 -0
  92. package/dist/core/http-backend.d.ts +11 -0
  93. package/dist/core/http-backend.js +195 -0
  94. package/dist/core/http-backend.js.map +1 -0
  95. package/dist/core/index.d.ts +14 -9
  96. package/dist/core/index.js +12 -9
  97. package/dist/core/palette.d.ts +48 -0
  98. package/dist/core/palette.js +95 -0
  99. package/dist/core/palette.js.map +1 -0
  100. package/dist/core/schema/abilities.d.ts +2 -1
  101. package/dist/core/schema/abilities.js +5 -1
  102. package/dist/core/schema/abilities.js.map +1 -1
  103. package/dist/core/schema/index.d.ts +11 -5
  104. package/dist/core/schema/index.js +13 -8
  105. package/dist/core/schema/index.js.map +1 -1
  106. package/dist/core/schema/mark-flags.d.ts +8 -1
  107. package/dist/core/schema/of-features.d.ts +13 -0
  108. package/dist/core/schema/of-features.js +14 -0
  109. package/dist/core/schema/of-features.js.map +1 -0
  110. package/dist/core/slash.d.ts +8 -6
  111. package/dist/core/slash.js +24 -16
  112. package/dist/core/slash.js.map +1 -1
  113. package/dist/core/surface-session.js +13 -5
  114. package/dist/core/surface-session.js.map +1 -1
  115. package/dist/core/toolbar-items.d.ts +10 -4
  116. package/dist/core/toolbar-items.js +269 -195
  117. package/dist/core/toolbar-items.js.map +1 -1
  118. package/dist/core/util.js +11 -0
  119. package/dist/core/util.js.map +1 -0
  120. package/dist/document/DocumentSurface.d.ts +1 -1
  121. package/dist/features/ai/agent-op-review.d.ts +1 -1
  122. package/dist/features/ai/agent-op-review.js +1 -1
  123. package/dist/features/ai/agent-ops.js +1 -1
  124. package/dist/features/ai/ai-apply.d.ts +2 -2
  125. package/dist/features/ai/ai-apply.js +1 -1
  126. package/dist/features/ai/ai-review.js +1 -1
  127. package/dist/features/ai/ai-sse.d.ts +6 -6
  128. package/dist/features/ai/ai-sse.js +20 -63
  129. package/dist/features/ai/ai-sse.js.map +1 -1
  130. package/dist/features/ai/assistant.d.ts +8 -7
  131. package/dist/features/ai/assistant.js +3 -3
  132. package/dist/features/ai/assistant.js.map +1 -1
  133. package/dist/features/ai/block-actions.d.ts +3 -2
  134. package/dist/features/ai/block-actions.js +3 -2
  135. package/dist/features/ai/block-actions.js.map +1 -1
  136. package/dist/features/ai/components/AiSelectionMenu.js +1 -1
  137. package/dist/features/ai/components/DocumentChatAnswer.js +1 -1
  138. package/dist/features/ai/components/DocumentChatOps.vue.d.ts +1 -1
  139. package/dist/features/ai/components/SettingsModelProfiles.js +8 -8
  140. package/dist/features/ai/components/SettingsModelProfiles.js.map +1 -1
  141. package/dist/features/ai/document-chat-model.d.ts +8 -7
  142. package/dist/features/ai/document-chat-model.js +5 -5
  143. package/dist/features/ai/document-chat-model.js.map +1 -1
  144. package/dist/features/ai/document-chat.js +1 -1
  145. package/dist/features/ai/feature.js +27 -14
  146. package/dist/features/ai/feature.js.map +1 -1
  147. package/dist/features/ai/ghost-autocomplete.d.ts +7 -6
  148. package/dist/features/ai/ghost-autocomplete.js +6 -9
  149. package/dist/features/ai/ghost-autocomplete.js.map +1 -1
  150. package/dist/features/ai/index.d.ts +4 -3
  151. package/dist/features/ai/index.js +10 -10
  152. package/dist/features/ai/model-profiles.d.ts +5 -4
  153. package/dist/features/ai/model-profiles.js +2 -2
  154. package/dist/features/ai/model-profiles.js.map +1 -1
  155. package/dist/features/ai/protocol/block-lines.js +1 -1
  156. package/dist/features/ai/protocol/block-lines.js.map +1 -1
  157. package/dist/features/ai/protocol/chat.js +4 -1
  158. package/dist/features/ai/protocol/chat.js.map +1 -1
  159. package/dist/features/ai/protocol/index.d.ts +3 -2
  160. package/dist/features/ai/protocol/models.d.ts +2 -16
  161. package/dist/features/ai/protocol/models.js.map +1 -1
  162. package/dist/features/ai/rate-limit.d.ts +1 -1
  163. package/dist/features/ai/rate-limit.js +3 -1
  164. package/dist/features/ai/rate-limit.js.map +1 -1
  165. package/dist/features/ai/react/AiSelectionMenu.js +2 -2
  166. package/dist/features/ai/react/AiSidebar.js +4 -4
  167. package/dist/features/ai/react/DocumentChatAnswer.js +1 -1
  168. package/dist/features/ai/react/DocumentChatOps.d.ts +1 -1
  169. package/dist/features/ai/react/DocumentChatOps.js +1 -1
  170. package/dist/features/ai/react/SettingsModelProfiles.js +8 -10
  171. package/dist/features/ai/react/SettingsModelProfiles.js.map +1 -1
  172. package/dist/features/ai/react/use-ai-assistant.d.ts +1 -1
  173. package/dist/features/ai/react/use-ai-assistant.js +3 -3
  174. package/dist/features/ai/react/use-ai-assistant.js.map +1 -1
  175. package/dist/features/ai/react/use-document-chat.js +2 -2
  176. package/dist/features/ai/react/use-document-chat.js.map +1 -1
  177. package/dist/features/ai/react/use-model-profiles.d.ts +2 -1
  178. package/dist/features/ai/selection-flow.d.ts +1 -1
  179. package/dist/features/ai/selection-flow.js +1 -1
  180. package/dist/features/ai/sidebar-flow.d.ts +1 -1
  181. package/dist/features/ai/sidebar-flow.js +1 -1
  182. package/dist/features/ai/use-ai-assistant.d.ts +1 -1
  183. package/dist/features/ai/use-ai-assistant.js +3 -3
  184. package/dist/features/ai/use-ai-assistant.js.map +1 -1
  185. package/dist/features/ai/use-document-chat.js +2 -2
  186. package/dist/features/ai/use-document-chat.js.map +1 -1
  187. package/dist/features/ai/use-model-profiles.d.ts +2 -1
  188. package/dist/features/authors/attribution.d.ts +1 -1
  189. package/dist/features/authors/feature.js +12 -11
  190. package/dist/features/authors/feature.js.map +1 -1
  191. package/dist/features/block-ui/block-actions.d.ts +1 -1
  192. package/dist/features/block-ui/block-actions.js +1 -1
  193. package/dist/features/block-ui/block-actions.js.map +1 -1
  194. package/dist/features/block-ui/components/BlockUi.js +1 -1
  195. package/dist/features/block-ui/feature.js +1 -0
  196. package/dist/features/block-ui/feature.js.map +1 -1
  197. package/dist/features/block-ui/react/BlockUi.js +1 -1
  198. package/dist/features/collab/anchor-resolver.js +1 -1
  199. package/dist/features/collab/feature.js +2 -0
  200. package/dist/features/collab/feature.js.map +1 -1
  201. package/dist/features/comments/components/CommentThreadView.vue.d.ts +2 -1
  202. package/dist/features/comments/feature.js +12 -11
  203. package/dist/features/comments/feature.js.map +1 -1
  204. package/dist/features/comments/index.d.ts +3 -2
  205. package/dist/features/comments/index.js +1 -1
  206. package/dist/features/comments/margin-layout.d.ts +3 -2
  207. package/dist/features/comments/model.d.ts +3 -67
  208. package/dist/features/comments/model.js +2 -2
  209. package/dist/features/comments/model.js.map +1 -1
  210. package/dist/features/comments/react/CommentThreadView.d.ts +3 -2
  211. package/dist/features/comments/react/use-comments.d.ts +2 -1
  212. package/dist/features/comments/react.d.ts +1 -1
  213. package/dist/features/comments/schema.d.ts +2 -52
  214. package/dist/features/comments/schema.js.map +1 -1
  215. package/dist/features/comments/snapshot-equality.js.map +1 -1
  216. package/dist/features/comments/use-comments.d.ts +3 -2
  217. package/dist/features/comments/vue.d.ts +1 -1
  218. package/dist/features/composites/accepted-children.d.ts +1 -0
  219. package/dist/features/composites/accepted-children.js +16 -1
  220. package/dist/features/composites/accepted-children.js.map +1 -1
  221. package/dist/features/composites/ai-brief.js +31 -0
  222. package/dist/features/composites/ai-brief.js.map +1 -1
  223. package/dist/features/composites/bibliography-command.d.ts +11 -0
  224. package/dist/features/composites/bibliography-form.js +90 -0
  225. package/dist/features/composites/bibliography-form.js.map +1 -0
  226. package/dist/features/composites/bibliography.d.ts +33 -0
  227. package/dist/features/composites/bibliography.js +120 -0
  228. package/dist/features/composites/bibliography.js.map +1 -0
  229. package/dist/features/composites/components/BibliographyEditor.js +261 -0
  230. package/dist/features/composites/components/BibliographyEditor.js.map +1 -0
  231. package/dist/features/composites/components/CompositeChrome.js +75 -26
  232. package/dist/features/composites/components/CompositeChrome.js.map +1 -1
  233. package/dist/features/composites/components/CompositeDetails.js +46 -11
  234. package/dist/features/composites/components/CompositeDetails.js.map +1 -1
  235. package/dist/features/composites/components/CompositeDetails.vue.d.ts +2 -1
  236. package/dist/features/composites/components/CompositeFieldEditor.js +37 -4
  237. package/dist/features/composites/components/CompositeFieldEditor.js.map +1 -1
  238. package/dist/features/composites/components/CompositeInspector.js +17 -5
  239. package/dist/features/composites/components/CompositeInspector.js.map +1 -1
  240. package/dist/features/composites/components/CompositeTable.js +13 -4
  241. package/dist/features/composites/components/CompositeTable.js.map +1 -1
  242. package/dist/features/composites/components/CompositeTagsEditor.js +1 -1
  243. package/dist/features/composites/components/CompositeView.js +11 -1
  244. package/dist/features/composites/components/CompositeView.js.map +1 -1
  245. package/dist/features/composites/components/DerivationBadge.js +103 -0
  246. package/dist/features/composites/components/DerivationBadge.js.map +1 -0
  247. package/dist/features/composites/components/ReferenceFieldSelect.js +60 -0
  248. package/dist/features/composites/components/ReferenceFieldSelect.js.map +1 -0
  249. package/dist/features/composites/components/ReferenceView.js +122 -0
  250. package/dist/features/composites/components/ReferenceView.js.map +1 -0
  251. package/dist/features/composites/components/ReferenceView.vue.d.ts +96 -0
  252. package/dist/features/composites/components/SettingsEditingTab.js +1 -1
  253. package/dist/features/composites/convert.js +2 -2
  254. package/dist/features/composites/convert.js.map +1 -1
  255. package/dist/features/composites/derivation.d.ts +61 -0
  256. package/dist/features/composites/derivation.js +98 -0
  257. package/dist/features/composites/derivation.js.map +1 -0
  258. package/dist/features/composites/derived-chrome.js +69 -0
  259. package/dist/features/composites/derived-chrome.js.map +1 -0
  260. package/dist/features/composites/feature.js +159 -109
  261. package/dist/features/composites/feature.js.map +1 -1
  262. package/dist/features/composites/fences.d.ts +4 -3
  263. package/dist/features/composites/fences.js +51 -7
  264. package/dist/features/composites/fences.js.map +1 -1
  265. package/dist/features/composites/index.d.ts +12 -3
  266. package/dist/features/composites/index.js +15 -6
  267. package/dist/features/composites/inspector-model.d.ts +4 -1
  268. package/dist/features/composites/inspector-model.js +8 -4
  269. package/dist/features/composites/inspector-model.js.map +1 -1
  270. package/dist/features/composites/kinds.d.ts +8 -1
  271. package/dist/features/composites/kinds.js +145 -6
  272. package/dist/features/composites/kinds.js.map +1 -1
  273. package/dist/features/composites/legacy.d.ts +4 -1
  274. package/dist/features/composites/legacy.js +56 -1
  275. package/dist/features/composites/legacy.js.map +1 -1
  276. package/dist/features/composites/meta-display.js +40 -1
  277. package/dist/features/composites/meta-display.js.map +1 -1
  278. package/dist/features/composites/meta-keys.d.ts +7 -0
  279. package/dist/features/composites/meta-keys.js +21 -0
  280. package/dist/features/composites/meta-keys.js.map +1 -0
  281. package/dist/features/composites/node-views.d.ts +6 -3
  282. package/dist/features/composites/node-views.js +7 -3
  283. package/dist/features/composites/node-views.js.map +1 -1
  284. package/dist/features/composites/nodes.d.ts +6 -1
  285. package/dist/features/composites/nodes.js +33 -7
  286. package/dist/features/composites/nodes.js.map +1 -1
  287. package/dist/features/composites/react/BibliographyEditor.js +229 -0
  288. package/dist/features/composites/react/BibliographyEditor.js.map +1 -0
  289. package/dist/features/composites/react/CompositeChrome.js +65 -17
  290. package/dist/features/composites/react/CompositeChrome.js.map +1 -1
  291. package/dist/features/composites/react/CompositeDetails.d.ts +2 -1
  292. package/dist/features/composites/react/CompositeDetails.js +45 -6
  293. package/dist/features/composites/react/CompositeDetails.js.map +1 -1
  294. package/dist/features/composites/react/CompositeFieldEditor.d.ts +1 -1
  295. package/dist/features/composites/react/CompositeFieldEditor.js +24 -1
  296. package/dist/features/composites/react/CompositeFieldEditor.js.map +1 -1
  297. package/dist/features/composites/react/CompositeInspector.js +11 -5
  298. package/dist/features/composites/react/CompositeInspector.js.map +1 -1
  299. package/dist/features/composites/react/CompositeStatusMenu.js +1 -1
  300. package/dist/features/composites/react/CompositeSummaryEditor.js +1 -1
  301. package/dist/features/composites/react/CompositeTable.js +16 -2
  302. package/dist/features/composites/react/CompositeTable.js.map +1 -1
  303. package/dist/features/composites/react/CompositeTagsEditor.js +2 -2
  304. package/dist/features/composites/react/CompositeView.js +6 -1
  305. package/dist/features/composites/react/CompositeView.js.map +1 -1
  306. package/dist/features/composites/react/DerivationBadge.js +116 -0
  307. package/dist/features/composites/react/DerivationBadge.js.map +1 -0
  308. package/dist/features/composites/react/ReferenceFieldSelect.js +52 -0
  309. package/dist/features/composites/react/ReferenceFieldSelect.js.map +1 -0
  310. package/dist/features/composites/react/ReferenceView.d.ts +11 -0
  311. package/dist/features/composites/react/ReferenceView.js +115 -0
  312. package/dist/features/composites/react/ReferenceView.js.map +1 -0
  313. package/dist/features/composites/react/SettingsEditingTab.js +2 -2
  314. package/dist/features/composites/react.d.ts +2 -1
  315. package/dist/features/composites/react.js +7 -3
  316. package/dist/features/composites/react.js.map +1 -1
  317. package/dist/features/composites/reference-ai.js +16 -0
  318. package/dist/features/composites/reference-ai.js.map +1 -0
  319. package/dist/features/composites/reference-label.d.ts +19 -0
  320. package/dist/features/composites/reference-label.js +58 -0
  321. package/dist/features/composites/reference-label.js.map +1 -0
  322. package/dist/features/composites/reference-suggestion.d.ts +10 -0
  323. package/dist/features/composites/reference-suggestion.js +41 -0
  324. package/dist/features/composites/reference-suggestion.js.map +1 -0
  325. package/dist/features/composites/reference-text.d.ts +18 -0
  326. package/dist/features/composites/reference-text.js +89 -0
  327. package/dist/features/composites/reference-text.js.map +1 -0
  328. package/dist/features/composites/reference.d.ts +44 -0
  329. package/dist/features/composites/reference.js +148 -0
  330. package/dist/features/composites/reference.js.map +1 -0
  331. package/dist/features/composites/reveal-source.d.ts +32 -0
  332. package/dist/features/composites/reveal-source.js +89 -0
  333. package/dist/features/composites/reveal-source.js.map +1 -0
  334. package/dist/features/composites/rows.d.ts +21 -2
  335. package/dist/features/composites/rows.js +63 -9
  336. package/dist/features/composites/rows.js.map +1 -1
  337. package/dist/features/composites/schema.d.ts +9 -3
  338. package/dist/features/composites/schema.js +11 -4
  339. package/dist/features/composites/schema.js.map +1 -1
  340. package/dist/features/composites/table-model.js +12 -21
  341. package/dist/features/composites/table-model.js.map +1 -1
  342. package/dist/features/composites/vue.d.ts +3 -2
  343. package/dist/features/composites/vue.js +8 -4
  344. package/dist/features/composites/vue.js.map +1 -1
  345. package/dist/features/media/assets.d.ts +2 -0
  346. package/dist/features/media/assets.js +3 -2
  347. package/dist/features/media/assets.js.map +1 -1
  348. package/dist/features/media/components/FileView.js +13 -4
  349. package/dist/features/media/components/FileView.js.map +1 -1
  350. package/dist/features/media/feature.d.ts +3 -3
  351. package/dist/features/media/feature.js +21 -28
  352. package/dist/features/media/feature.js.map +1 -1
  353. package/dist/features/media/file-import.js +2 -2
  354. package/dist/features/media/file-import.js.map +1 -1
  355. package/dist/features/media/index.d.ts +2 -2
  356. package/dist/features/media/index.js +2 -2
  357. package/dist/features/media/react/FileView.js +19 -2
  358. package/dist/features/media/react/FileView.js.map +1 -1
  359. package/dist/features/media/schema.d.ts +8 -0
  360. package/dist/features/media/schema.js +126 -11
  361. package/dist/features/media/schema.js.map +1 -1
  362. package/dist/features/media/upload.d.ts +16 -14
  363. package/dist/features/media/upload.js +13 -19
  364. package/dist/features/media/upload.js.map +1 -1
  365. package/dist/features/mentions/index.d.ts +4 -3
  366. package/dist/features/mentions/index.js +4 -1
  367. package/dist/features/mentions/index.js.map +1 -1
  368. package/dist/features/mentions/mention-text.d.ts +1 -1
  369. package/dist/features/mentions/mention-text.js.map +1 -1
  370. package/dist/features/mentions/mention.d.ts +0 -6
  371. package/dist/features/mentions/mention.js.map +1 -1
  372. package/dist/features/mentions/metadata-defaults.d.ts +2 -2
  373. package/dist/features/mentions/metadata-defaults.js +3 -9
  374. package/dist/features/mentions/metadata-defaults.js.map +1 -1
  375. package/dist/features/mentions/schema.d.ts +2 -1
  376. package/dist/features/mentions/schema.js.map +1 -1
  377. package/dist/features/tables/feature.d.ts +2 -1
  378. package/dist/features/tables/feature.js +90 -70
  379. package/dist/features/tables/feature.js.map +1 -1
  380. package/dist/features/themes/components/SettingsAppearanceTab.js +6 -9
  381. package/dist/features/themes/components/SettingsAppearanceTab.js.map +1 -1
  382. package/dist/features/themes/feature.js +2 -0
  383. package/dist/features/themes/feature.js.map +1 -1
  384. package/dist/features/themes/index.d.ts +2 -1
  385. package/dist/features/themes/react/SettingsAppearanceTab.js +7 -10
  386. package/dist/features/themes/react/SettingsAppearanceTab.js.map +1 -1
  387. package/dist/features/themes/schema.d.ts +2 -6
  388. package/dist/features/themes/schema.js.map +1 -1
  389. package/dist/features/themes/theme-runtime.d.ts +1 -1
  390. package/dist/features/themes/theme-runtime.js +4 -2
  391. package/dist/features/themes/theme-runtime.js.map +1 -1
  392. package/dist/features/transcript/TranscriptSegmentView.js +48 -28
  393. package/dist/features/transcript/TranscriptSegmentView.js.map +1 -1
  394. package/dist/features/transcript/feature.js +21 -19
  395. package/dist/features/transcript/feature.js.map +1 -1
  396. package/dist/features/transcript/react/TranscriptSegmentView.js +55 -36
  397. package/dist/features/transcript/react/TranscriptSegmentView.js.map +1 -1
  398. package/dist/features/transcript/segment-node.d.ts +2 -0
  399. package/dist/features/transcript/segment-node.js +35 -7
  400. package/dist/features/transcript/segment-node.js.map +1 -1
  401. package/dist/i18n/de/composites.js +91 -1
  402. package/dist/i18n/de/composites.js.map +1 -1
  403. package/dist/i18n/de/integrations.js +49 -8
  404. package/dist/i18n/de/integrations.js.map +1 -1
  405. package/dist/i18n/de/media.js +0 -1
  406. package/dist/i18n/de/media.js.map +1 -1
  407. package/dist/i18n/de/palette.js +22 -0
  408. package/dist/i18n/de/palette.js.map +1 -0
  409. package/dist/i18n/de/tables.js +0 -1
  410. package/dist/i18n/de/tables.js.map +1 -1
  411. package/dist/i18n/de/transcript.js +2 -1
  412. package/dist/i18n/de/transcript.js.map +1 -1
  413. package/dist/i18n/de/tree.js +3 -0
  414. package/dist/i18n/de/tree.js.map +1 -1
  415. package/dist/i18n/de.d.ts +157 -11
  416. package/dist/i18n/de.js +3 -1
  417. package/dist/i18n/de.js.map +1 -1
  418. package/dist/i18n/en/composites.js +89 -1
  419. package/dist/i18n/en/composites.js.map +1 -1
  420. package/dist/i18n/en/integrations.js +49 -8
  421. package/dist/i18n/en/integrations.js.map +1 -1
  422. package/dist/i18n/en/media.js +0 -1
  423. package/dist/i18n/en/media.js.map +1 -1
  424. package/dist/i18n/en/palette.js +22 -0
  425. package/dist/i18n/en/palette.js.map +1 -0
  426. package/dist/i18n/en/tables.js +0 -1
  427. package/dist/i18n/en/tables.js.map +1 -1
  428. package/dist/i18n/en/transcript.js +2 -1
  429. package/dist/i18n/en/transcript.js.map +1 -1
  430. package/dist/i18n/en/tree.js +3 -0
  431. package/dist/i18n/en/tree.js.map +1 -1
  432. package/dist/i18n/en.js +3 -1
  433. package/dist/i18n/en.js.map +1 -1
  434. package/dist/index.d.ts +4 -3
  435. package/dist/integrations/composite-ai/bibliography-fetch.d.ts +31 -0
  436. package/dist/integrations/composite-ai/bibliography-fetch.js +159 -0
  437. package/dist/integrations/composite-ai/bibliography-fetch.js.map +1 -0
  438. package/dist/integrations/composite-ai/composite-fill.d.ts +30 -8
  439. package/dist/integrations/composite-ai/composite-fill.js +97 -56
  440. package/dist/integrations/composite-ai/composite-fill.js.map +1 -1
  441. package/dist/integrations/composite-ai/composite-summary.d.ts +4 -12
  442. package/dist/integrations/composite-ai/composite-summary.js +7 -26
  443. package/dist/integrations/composite-ai/composite-summary.js.map +1 -1
  444. package/dist/integrations/composite-ai/derive.d.ts +29 -0
  445. package/dist/integrations/composite-ai/derive.js +173 -0
  446. package/dist/integrations/composite-ai/derive.js.map +1 -0
  447. package/dist/integrations/composite-ai/index.d.ts +11 -7
  448. package/dist/integrations/composite-ai/index.js +72 -14
  449. package/dist/integrations/composite-ai/index.js.map +1 -1
  450. package/dist/integrations/composite-ai/rendition.d.ts +45 -0
  451. package/dist/integrations/composite-ai/rendition.js +314 -0
  452. package/dist/integrations/composite-ai/rendition.js.map +1 -0
  453. package/dist/integrations/composite-media/index.d.ts +7 -5
  454. package/dist/integrations/composite-media/index.js +86 -13
  455. package/dist/integrations/composite-media/index.js.map +1 -1
  456. package/dist/integrations/transcript-ai/index.d.ts +1 -1
  457. package/dist/integrations/transcript-ai/index.js +5 -2
  458. package/dist/integrations/transcript-ai/index.js.map +1 -1
  459. package/dist/integrations/transcript-ai/protocol.d.ts +2 -12
  460. package/dist/integrations/transcript-ai/protocol.js +0 -2
  461. package/dist/integrations/transcript-ai/protocol.js.map +1 -1
  462. package/dist/integrations/transcript-ai/transcript-cleanup.d.ts +5 -5
  463. package/dist/integrations/transcript-ai/transcript-cleanup.js +7 -10
  464. package/dist/integrations/transcript-ai/transcript-cleanup.js.map +1 -1
  465. package/dist/markdown/MarkdownSurface.vue.d.ts +6 -5
  466. package/dist/markdown/MarkdownSurface2.js +3 -6
  467. package/dist/markdown/MarkdownSurface2.js.map +1 -1
  468. package/dist/markdown/document.js +1 -1
  469. package/dist/markdown/source-mode.d.ts +1 -1
  470. package/dist/nuxt/module.d.ts +1402 -54
  471. package/dist/nuxt/module.js +6 -49
  472. package/dist/nuxt/module.js.map +1 -1
  473. package/dist/nuxt/runtime/install-context.d.ts +7 -3
  474. package/dist/nuxt/runtime/install-context.js +14 -8
  475. package/dist/nuxt/runtime/install-context.js.map +1 -1
  476. package/dist/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts +2 -2
  477. package/dist/nuxt/runtime/server/plugins/editor-server.js +20 -12
  478. package/dist/nuxt/runtime/server/plugins/editor-server.js.map +1 -1
  479. package/dist/presets/compose.d.ts +94 -0
  480. package/dist/presets/compose.js +164 -0
  481. package/dist/presets/compose.js.map +1 -0
  482. package/dist/react/AdvancedEditor.d.ts +15 -15
  483. package/dist/react/AdvancedEditor.js +15 -13
  484. package/dist/react/AdvancedEditor.js.map +1 -1
  485. package/dist/react/EditorCommandPalette.d.ts +13 -0
  486. package/dist/react/EditorCommandPalette.js +118 -0
  487. package/dist/react/EditorCommandPalette.js.map +1 -0
  488. package/dist/react/EditorSettingsModal.d.ts +5 -5
  489. package/dist/react/EditorSettingsModal.js +7 -4
  490. package/dist/react/EditorSettingsModal.js.map +1 -1
  491. package/dist/react/EditorSettingsPanel.d.ts +7 -7
  492. package/dist/react/EditorSettingsPanel.js +8 -5
  493. package/dist/react/EditorSettingsPanel.js.map +1 -1
  494. package/dist/react/EditorSurface.d.ts +7 -7
  495. package/dist/react/EditorSurface.js +10 -6
  496. package/dist/react/EditorSurface.js.map +1 -1
  497. package/dist/react/EditorToolbar.d.ts +4 -6
  498. package/dist/react/EditorToolbar.js +29 -37
  499. package/dist/react/EditorToolbar.js.map +1 -1
  500. package/dist/react/SimpleEditor.d.ts +22 -23
  501. package/dist/react/SimpleEditor.js +21 -7
  502. package/dist/react/SimpleEditor.js.map +1 -1
  503. package/dist/react/advanced.d.ts +4 -3
  504. package/dist/react/advanced.js +2 -2
  505. package/dist/react/compose.d.ts +20 -0
  506. package/dist/react/compose.js +49 -0
  507. package/dist/react/compose.js.map +1 -0
  508. package/dist/react/composed-surface.d.ts +39 -0
  509. package/dist/react/composed-surface.js +71 -0
  510. package/dist/react/composed-surface.js.map +1 -0
  511. package/dist/react/context.js +6 -2
  512. package/dist/react/context.js.map +1 -1
  513. package/dist/react/index.d.ts +2 -1
  514. package/dist/react/index.js +2 -1
  515. package/dist/react/key-labels.js +15 -0
  516. package/dist/react/key-labels.js.map +1 -0
  517. package/dist/react/settings.d.ts +1 -1
  518. package/dist/react/simple.d.ts +2 -2
  519. package/dist/react/ui/command.js +36 -1
  520. package/dist/react/ui/command.js.map +1 -1
  521. package/dist/schema/advanced.d.ts +6 -6
  522. package/dist/schema/advanced.js +26 -29
  523. package/dist/schema/advanced.js.map +1 -1
  524. package/dist/server/ai.d.ts +5 -16
  525. package/dist/server/ai.js.map +1 -1
  526. package/dist/server/auth.d.ts +9 -0
  527. package/dist/server/collab-state.d.ts +1 -1
  528. package/dist/server/collab-state.js.map +1 -1
  529. package/dist/server/collab.d.ts +13 -13
  530. package/dist/server/collab.js +34 -18
  531. package/dist/server/collab.js.map +1 -1
  532. package/dist/server/crossref.js +78 -0
  533. package/dist/server/crossref.js.map +1 -0
  534. package/dist/server/errors.d.ts +1 -1
  535. package/dist/server/errors.js +1 -1
  536. package/dist/server/errors.js.map +1 -1
  537. package/dist/server/extract.js +308 -0
  538. package/dist/server/extract.js.map +1 -0
  539. package/dist/{nuxt/runtime/server/utils/editor-route.js → server/h3.js} +8 -16
  540. package/dist/server/h3.js.map +1 -0
  541. package/dist/server/handlers/ai.d.ts +30 -9
  542. package/dist/server/handlers/ai.js +170 -36
  543. package/dist/server/handlers/ai.js.map +1 -1
  544. package/dist/server/handlers/context.d.ts +12 -5
  545. package/dist/server/handlers/context.js +10 -4
  546. package/dist/server/handlers/context.js.map +1 -1
  547. package/dist/server/handlers/editor.d.ts +19 -13
  548. package/dist/server/handlers/editor.js +49 -38
  549. package/dist/server/handlers/editor.js.map +1 -1
  550. package/dist/server/handlers/index.d.ts +4 -4
  551. package/dist/server/handlers/index.js +4 -4
  552. package/dist/server/host.d.ts +16 -25
  553. package/dist/server/host.js +58 -41
  554. package/dist/server/host.js.map +1 -1
  555. package/dist/server/index.d.ts +6 -4
  556. package/dist/server/index.js +3 -2
  557. package/dist/server/pdf.js +97 -0
  558. package/dist/server/pdf.js.map +1 -0
  559. package/dist/server/{adapter.d.ts → ports.d.ts} +81 -30
  560. package/dist/server/ports.js +29 -0
  561. package/dist/server/ports.js.map +1 -0
  562. package/dist/server/routes.js +144 -0
  563. package/dist/server/routes.js.map +1 -0
  564. package/dist/settings/index.d.ts +1 -1
  565. package/dist/settings/index.js.map +1 -1
  566. package/dist/styles/composites.css +25 -0
  567. package/dist/tree/DocumentTree.js +56 -29
  568. package/dist/tree/DocumentTree.js.map +1 -1
  569. package/dist/tree/react/DocumentTree.js +23 -0
  570. package/dist/tree/react/DocumentTree.js.map +1 -1
  571. package/dist/tree/tree-host.js +2 -2
  572. package/dist/tree/tree-items.js +1 -1
  573. package/dist/vue/AdvancedEditor.js +30 -9
  574. package/dist/vue/AdvancedEditor.js.map +1 -1
  575. package/dist/vue/AdvancedEditor.vue.d.ts +28 -8
  576. package/dist/vue/SimpleEditor.js +62 -16
  577. package/dist/vue/SimpleEditor.js.map +1 -1
  578. package/dist/vue/SimpleEditor.vue.d.ts +37 -7
  579. package/dist/vue/advanced.d.ts +3 -2
  580. package/dist/vue/advanced.js +2 -2
  581. package/dist/vue/components/EditorCommandPalette.js +91 -0
  582. package/dist/vue/components/EditorCommandPalette.js.map +1 -0
  583. package/dist/vue/components/EditorCommandPalette.vue.d.ts +15 -0
  584. package/dist/vue/components/EditorSettingsModal.js +10 -6
  585. package/dist/vue/components/EditorSettingsModal.js.map +1 -1
  586. package/dist/vue/components/EditorSettingsModal.vue.d.ts +4 -4
  587. package/dist/vue/components/EditorSettingsPanel.js +10 -6
  588. package/dist/vue/components/EditorSettingsPanel.js.map +1 -1
  589. package/dist/vue/components/EditorSettingsPanel.vue.d.ts +6 -6
  590. package/dist/vue/components/EditorSurface.js +11 -6
  591. package/dist/vue/components/EditorSurface.js.map +1 -1
  592. package/dist/vue/components/EditorSurface.vue.d.ts +7 -7
  593. package/dist/vue/components/EditorToolbar.js +41 -49
  594. package/dist/vue/components/EditorToolbar.js.map +1 -1
  595. package/dist/vue/components/EditorToolbar.vue.d.ts +2 -4
  596. package/dist/vue/compose.d.ts +17 -0
  597. package/dist/vue/compose.js +51 -0
  598. package/dist/vue/compose.js.map +1 -0
  599. package/dist/vue/context-key.d.ts +6 -0
  600. package/dist/vue/context-key.js +6 -0
  601. package/dist/vue/context-key.js.map +1 -0
  602. package/dist/vue/context.d.ts +8 -6
  603. package/dist/vue/context.js +6 -5
  604. package/dist/vue/context.js.map +1 -1
  605. package/dist/vue/index.d.ts +10 -8
  606. package/dist/vue/index.js +10 -8
  607. package/dist/vue/kit/index.d.ts +2 -2
  608. package/dist/vue/kit/nuxt-ui.js +23 -0
  609. package/dist/vue/kit/nuxt-ui.js.map +1 -1
  610. package/dist/vue/kit/types.d.ts +40 -1
  611. package/package.json +30 -16
  612. package/dist/adapters/comments/client.d.ts +0 -64
  613. package/dist/adapters/comments/client.js.map +0 -1
  614. package/dist/adapters/routes.js.map +0 -1
  615. package/dist/core/toolbar.d.ts +0 -74
  616. package/dist/core/toolbar.js +0 -45
  617. package/dist/core/toolbar.js.map +0 -1
  618. package/dist/integrations/composite-ai/document-transcribe.d.ts +0 -14
  619. package/dist/integrations/composite-ai/document-transcribe.js +0 -89
  620. package/dist/integrations/composite-ai/document-transcribe.js.map +0 -1
  621. package/dist/nuxt/runtime/server/api/ai/chat.post.d.ts +0 -5
  622. package/dist/nuxt/runtime/server/api/ai/chat.post.js +0 -8
  623. package/dist/nuxt/runtime/server/api/ai/chat.post.js.map +0 -1
  624. package/dist/nuxt/runtime/server/api/ai/complete.post.d.ts +0 -5
  625. package/dist/nuxt/runtime/server/api/ai/complete.post.js +0 -8
  626. package/dist/nuxt/runtime/server/api/ai/complete.post.js.map +0 -1
  627. package/dist/nuxt/runtime/server/api/ai/generate.post.d.ts +0 -5
  628. package/dist/nuxt/runtime/server/api/ai/generate.post.js +0 -8
  629. package/dist/nuxt/runtime/server/api/ai/generate.post.js.map +0 -1
  630. package/dist/nuxt/runtime/server/api/ai/models.get.d.ts +0 -5
  631. package/dist/nuxt/runtime/server/api/ai/models.get.js +0 -8
  632. package/dist/nuxt/runtime/server/api/ai/models.get.js.map +0 -1
  633. package/dist/nuxt/runtime/server/api/ai/transcribe.post.d.ts +0 -5
  634. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js +0 -8
  635. package/dist/nuxt/runtime/server/api/ai/transcribe.post.js.map +0 -1
  636. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.d.ts +0 -5
  637. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js +0 -8
  638. package/dist/nuxt/runtime/server/api/ai/transcript-cleanup.post.js.map +0 -1
  639. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.d.ts +0 -5
  640. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js +0 -8
  641. package/dist/nuxt/runtime/server/api/editor/assets/[id]/[name].get.js.map +0 -1
  642. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.d.ts +0 -5
  643. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js +0 -8
  644. package/dist/nuxt/runtime/server/api/editor/assets/[id].post.js.map +0 -1
  645. package/dist/nuxt/runtime/server/api/editor/settings.get.d.ts +0 -5
  646. package/dist/nuxt/runtime/server/api/editor/settings.get.js +0 -8
  647. package/dist/nuxt/runtime/server/api/editor/settings.get.js.map +0 -1
  648. package/dist/nuxt/runtime/server/api/editor/settings.put.d.ts +0 -5
  649. package/dist/nuxt/runtime/server/api/editor/settings.put.js +0 -8
  650. package/dist/nuxt/runtime/server/api/editor/settings.put.js.map +0 -1
  651. package/dist/nuxt/runtime/server/api/editor/tags.get.d.ts +0 -5
  652. package/dist/nuxt/runtime/server/api/editor/tags.get.js +0 -8
  653. package/dist/nuxt/runtime/server/api/editor/tags.get.js.map +0 -1
  654. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.d.ts +0 -5
  655. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js +0 -8
  656. package/dist/nuxt/runtime/server/api/editor/themes/[id].delete.js.map +0 -1
  657. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.d.ts +0 -5
  658. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js +0 -8
  659. package/dist/nuxt/runtime/server/api/editor/themes/[id].get.js.map +0 -1
  660. package/dist/nuxt/runtime/server/api/editor/themes/index.get.d.ts +0 -5
  661. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js +0 -8
  662. package/dist/nuxt/runtime/server/api/editor/themes/index.get.js.map +0 -1
  663. package/dist/nuxt/runtime/server/api/editor/themes/index.post.d.ts +0 -5
  664. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js +0 -8
  665. package/dist/nuxt/runtime/server/api/editor/themes/index.post.js.map +0 -1
  666. package/dist/nuxt/runtime/server/api/editor/users.get.d.ts +0 -5
  667. package/dist/nuxt/runtime/server/api/editor/users.get.js +0 -8
  668. package/dist/nuxt/runtime/server/api/editor/users.get.js.map +0 -1
  669. package/dist/nuxt/runtime/server/plugins/collab.d.ts +0 -5
  670. package/dist/nuxt/runtime/server/plugins/collab.js +0 -10
  671. package/dist/nuxt/runtime/server/plugins/collab.js.map +0 -1
  672. package/dist/nuxt/runtime/server/routes/collab/[id].d.ts +0 -5
  673. package/dist/nuxt/runtime/server/routes/collab/[id].js +0 -35
  674. package/dist/nuxt/runtime/server/routes/collab/[id].js.map +0 -1
  675. package/dist/nuxt/runtime/server/utils/editor-route.d.ts +0 -11
  676. package/dist/nuxt/runtime/server/utils/editor-route.js.map +0 -1
  677. package/dist/presets/advanced.d.ts +0 -33
  678. package/dist/presets/advanced.js +0 -50
  679. package/dist/presets/advanced.js.map +0 -1
  680. package/dist/presets/simple.d.ts +0 -9
  681. package/dist/presets/simple.js +0 -12
  682. package/dist/presets/simple.js.map +0 -1
  683. package/dist/react/advanced-preset.d.ts +0 -11
  684. package/dist/react/advanced-preset.js +0 -31
  685. package/dist/react/advanced-preset.js.map +0 -1
  686. package/dist/vue/advanced-preset.d.ts +0 -13
  687. package/dist/vue/advanced-preset.js +0 -33
  688. package/dist/vue/advanced-preset.js.map +0 -1
  689. package/docs/extending.md +0 -538
  690. package/docs/integration.md +0 -632
  691. package/docs/llms.md +0 -383
  692. package/docs/usage.md +0 -1076
@@ -1 +1 @@
1
- {"version":3,"file":"composite-fill.js","names":[],"sources":["../../../src/integrations/composite-ai/composite-fill.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport type { $Fetch } from 'ofetch'\nimport { aiApplyFailure, AI_LIMITS, type AiBlockInput, documentMarkdown, type ModelRef, notifyAiRateLimited, postAiSse, startAiReview } from '../../features/ai'\nimport { aiBlockDataOf, aiContextOf, captureRange, releaseRanges, resolveRange } from '../../core'\nimport type { Translate } from '../../i18n'\nimport type { Notifier } from '../../core/notify'\nimport { COMPOSITE_CHROME_COUNT, compositeAiBrief } from '../../features/composites/schema'\n\n/** Entries of `aiBlockData` that travel with a request (the server accepts at most as many). */\nconst MAX_BLOCK_DATA = 10\n\n/**\n * Fills the body of the composite at `pos`: its brief (`compositeAiBrief`) plus the preset's `aiBlockData` → task\n * `fill-block` (`generate` slot); the result opens the in-document diff review over the body (`startAiReview`), so\n * nothing is written until accepted. The body range is anchored when the run starts, so edits while the data loads or\n * the result streams do not misplace it. A contributor that rejects cancels the run before any request is sent. Title,\n * fields and the other chrome stay untouched. Notices go through `notify`, in the language of `t`.\n */\nexport async function fillComposite(editor: Editor, pos: number, fetch: $Fetch, modelRef: (slot: 'generate') => ModelRef, notify: Notifier, t: Translate): Promise<void> {\n const brief = compositeAiBrief(editor, pos)\n const node = editor.state.doc.nodeAt(pos)\n if (!brief || !node) return\n\n const from = pos + 1 + node.child(0).nodeSize + node.child(1).nodeSize + node.child(2).nodeSize\n const anchor = captureRange(editor, { from, to: pos + node.nodeSize - 1 }, { startInside: true })\n\n const controller = new AbortController()\n const abort = () => controller.abort()\n editor.on('destroy', abort)\n let output = ''\n try {\n let data: AiBlockInput['data']\n try {\n const material = await aiBlockDataOf(editor)({ editor, node, pos, signal: controller.signal })\n data = material.slice(0, MAX_BLOCK_DATA).map(({ label, text }) => ({ label, text: text.slice(0, AI_LIMITS.block.data) }))\n }\n catch (error) {\n if (controller.signal.aborted || editor.isDestroyed) return\n notify({ title: t('integrations.compositeFill.dataMissing'), description: error instanceof Error ? error.message : String(error), kind: 'error' })\n return\n }\n if (controller.signal.aborted || editor.isDestroyed) return\n\n const block: AiBlockInput = {\n kind: brief.kind,\n path: brief.path,\n title: brief.title,\n description: brief.description,\n fields: brief.fields.map(({ label, value }) => ({ label, value })),\n instructions: brief.instructions,\n skeleton: brief.skeleton,\n body: brief.body,\n data,\n }\n const outcome = await postAiSse(fetch, '/api/ai/generate', {\n task: 'fill-block',\n prompt: '',\n selection: '',\n context: documentMarkdown(editor),\n blocks: aiContextOf(editor).blocks,\n block,\n model: modelRef('generate'),\n }, { signal: controller.signal, t, onDelta: (text) => { output += text } })\n\n if (outcome.status === 'aborted' || editor.isDestroyed) return\n if (outcome.status === 'rate-limited') {\n notifyAiRateLimited(notify, t)\n return\n }\n if (outcome.status === 'error') {\n notify({ title: t('integrations.compositeFill.failed'), description: outcome.message, kind: 'error' })\n return\n }\n if (!output.trim()) {\n notify({ title: t('integrations.compositeFill.empty.title'), description: t('integrations.compositeFill.empty.description'), kind: 'error' })\n return\n }\n\n // The body must still be where it was: a range directly inside a composite, after its chrome.\n const range = resolveRange(editor.state, anchor)\n const $from = range && editor.state.doc.resolve(range.from)\n if (!range || !$from || $from.parent.type.name !== 'composite' || $from.index() < COMPOSITE_CHROME_COUNT || !$from.sameParent(editor.state.doc.resolve(range.to))) {\n notify({ title: t('integrations.compositeFill.gone.title'), description: t('integrations.compositeFill.gone.description'), kind: 'error' })\n return\n }\n const review = startAiReview(editor, [{ id: 'fill', range: anchor, markdown: output }])\n if (review.hunks === 0) notify(aiApplyFailure(review.skipped[0]?.reason ?? 'unchanged', t))\n }\n finally {\n editor.off('destroy', abort)\n releaseRanges(editor, [anchor])\n }\n}\n"],"mappings":";;;;;;;;;;;AASA,MAAM,iBAAiB;;;;;;;;AASvB,eAAsB,cAAc,QAAgB,KAAa,OAAe,UAA0C,QAAkB,GAA6B;CACvK,MAAM,QAAQ,iBAAiB,QAAQ,GAAG;CAC1C,MAAM,OAAO,OAAO,MAAM,IAAI,OAAO,GAAG;CACxC,IAAI,CAAC,SAAS,CAAC,MAAM;CAErB,MAAM,OAAO,MAAM,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC;CACvF,MAAM,SAAS,aAAa,QAAQ;EAAE;EAAM,IAAI,MAAM,KAAK,WAAW;CAAE,GAAG,EAAE,aAAa,KAAK,CAAC;CAEhG,MAAM,aAAa,IAAI,gBAAgB;CACvC,MAAM,cAAc,WAAW,MAAM;CACrC,OAAO,GAAG,WAAW,KAAK;CAC1B,IAAI,SAAS;CACb,IAAI;EACF,IAAI;EACJ,IAAI;GAEF,QAAO,MADgB,cAAc,MAAM,CAAC,CAAC;IAAE;IAAQ;IAAM;IAAK,QAAQ,WAAW;GAAO,CAAC,EAAA,CAC7E,MAAM,GAAG,cAAc,CAAC,CAAC,KAAK,EAAE,OAAO,YAAY;IAAE;IAAO,MAAM,KAAK,MAAM,GAAG,UAAU,MAAM,IAAI;GAAE,EAAE;EAC1H,SACO,OAAO;GACZ,IAAI,WAAW,OAAO,WAAW,OAAO,aAAa;GACrD,OAAO;IAAE,OAAO,EAAE,wCAAwC;IAAG,aAAa,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IAAG,MAAM;GAAQ,CAAC;GACjJ;EACF;EACA,IAAI,WAAW,OAAO,WAAW,OAAO,aAAa;EAErD,MAAM,QAAsB;GAC1B,MAAM,MAAM;GACZ,MAAM,MAAM;GACZ,OAAO,MAAM;GACb,aAAa,MAAM;GACnB,QAAQ,MAAM,OAAO,KAAK,EAAE,OAAO,aAAa;IAAE;IAAO;GAAM,EAAE;GACjE,cAAc,MAAM;GACpB,UAAU,MAAM;GAChB,MAAM,MAAM;GACZ;EACF;EACA,MAAM,UAAU,MAAM,UAAU,OAAO,oBAAoB;GACzD,MAAM;GACN,QAAQ;GACR,WAAW;GACX,SAAS,iBAAiB,MAAM;GAChC,QAAQ,YAAY,MAAM,CAAC,CAAC;GAC5B;GACA,OAAO,SAAS,UAAU;EAC5B,GAAG;GAAE,QAAQ,WAAW;GAAQ;GAAG,UAAU,SAAS;IAAE,UAAU;GAAK;EAAE,CAAC;EAE1E,IAAI,QAAQ,WAAW,aAAa,OAAO,aAAa;EACxD,IAAI,QAAQ,WAAW,gBAAgB;GACrC,oBAAoB,QAAQ,CAAC;GAC7B;EACF;EACA,IAAI,QAAQ,WAAW,SAAS;GAC9B,OAAO;IAAE,OAAO,EAAE,mCAAmC;IAAG,aAAa,QAAQ;IAAS,MAAM;GAAQ,CAAC;GACrG;EACF;EACA,IAAI,CAAC,OAAO,KAAK,GAAG;GAClB,OAAO;IAAE,OAAO,EAAE,wCAAwC;IAAG,aAAa,EAAE,8CAA8C;IAAG,MAAM;GAAQ,CAAC;GAC5I;EACF;EAGA,MAAM,QAAQ,aAAa,OAAO,OAAO,MAAM;EAC/C,MAAM,QAAQ,SAAS,OAAO,MAAM,IAAI,QAAQ,MAAM,IAAI;EAC1D,IAAI,CAAC,SAAS,CAAC,SAAS,MAAM,OAAO,KAAK,SAAS,eAAe,MAAM,MAAM,IAAA,KAA8B,CAAC,MAAM,WAAW,OAAO,MAAM,IAAI,QAAQ,MAAM,EAAE,CAAC,GAAG;GACjK,OAAO;IAAE,OAAO,EAAE,uCAAuC;IAAG,aAAa,EAAE,6CAA6C;IAAG,MAAM;GAAQ,CAAC;GAC1I;EACF;EACA,MAAM,SAAS,cAAc,QAAQ,CAAC;GAAE,IAAI;GAAQ,OAAO;GAAQ,UAAU;EAAO,CAAC,CAAC;EACtF,IAAI,OAAO,UAAU,GAAG,OAAO,eAAe,OAAO,QAAQ,EAAE,EAAE,UAAU,aAAa,CAAC,CAAC;CAC5F,UACQ;EACN,OAAO,IAAI,WAAW,KAAK;EAC3B,cAAc,QAAQ,CAAC,MAAM,CAAC;CAChC;AACF"}
1
+ {"version":3,"file":"composite-fill.js","names":[],"sources":["../../../src/integrations/composite-ai/composite-fill.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport type { EditorBackend } from '../../core/backend'\nimport { aiApplyFailure, AI_LIMITS, type AiBlockInput, type AiSseOutcome, documentMarkdown, type ModelRef, notifyAiRateLimited, postAiSse, startAiReview } from '../../features/ai'\nimport { aiBlockDataOf, aiContextOf, captureRange, releaseRanges, resolveRange } from '../../core'\nimport type { Translate } from '../../i18n'\nimport type { Notifier } from '../../core/notify'\nimport { COMPOSITE_CHROME_COUNT, compositeAiBrief } from '../../features/composites/schema'\n\n/** Entries of `aiBlockData` that travel with a request (the server accepts at most as many). */\nconst MAX_BLOCK_DATA = 10\n\n/**\n * How `generateCompositeBody` ended. `done` carries the streamed Markdown (possibly empty); `data-error`: a\n * contributor of `aiBlockData` rejected, before any request was sent (`message`); `error`: the request failed\n * (`message`); `aborted` also covers a destroyed editor and a node that is no composite of an `ai` kind.\n */\nexport type CompositeBodyResult =\n | { status: 'done', output: string }\n | { status: 'rate-limited' | 'aborted', output: string }\n | { status: 'data-error' | 'error', output: string, message: string }\n\n/**\n * The request half of „Baustein füllen (KI)“: the brief (`compositeAiBrief`) of the composite at `pos` plus the preset's\n * `aiBlockData` → task `fill-block` (`generate` slot), streamed to completion. Writes nothing; `fillComposite` opens\n * the diff review with the result, `deriveComposite` writes it into a new Baustein. A contributor that rejects cancels\n * the run before any request is sent. Never throws.\n */\nexport async function generateCompositeBody(editor: Editor, pos: number, ai: NonNullable<EditorBackend['ai']>, modelRef: (slot: 'generate') => ModelRef, t: Translate, signal: AbortSignal): Promise<CompositeBodyResult> {\n const brief = compositeAiBrief(editor, pos)\n const node = editor.state.doc.nodeAt(pos)\n if (!brief || !node) return { status: 'aborted', output: '' }\n\n let data: AiBlockInput['data']\n try {\n const material = await aiBlockDataOf(editor)({ editor, node, pos, signal })\n data = material.slice(0, MAX_BLOCK_DATA).map(({ label, text }) => ({ label, text: text.slice(0, AI_LIMITS.block.data) }))\n }\n catch (error) {\n if (signal.aborted || editor.isDestroyed) return { status: 'aborted', output: '' }\n return { status: 'data-error', output: '', message: error instanceof Error ? error.message : String(error) }\n }\n if (signal.aborted || editor.isDestroyed) return { status: 'aborted', output: '' }\n\n const block: AiBlockInput = {\n kind: brief.kind,\n path: brief.path,\n title: brief.title,\n description: brief.description,\n fields: brief.fields.map(({ label, value }) => ({ label, value })),\n instructions: brief.instructions,\n skeleton: brief.skeleton,\n body: brief.body,\n data,\n }\n let output = ''\n const outcome: AiSseOutcome = await postAiSse(ai, 'generate', {\n task: 'fill-block',\n prompt: '',\n selection: '',\n context: documentMarkdown(editor),\n blocks: aiContextOf(editor).blocks,\n block,\n model: modelRef('generate'),\n }, { signal, t, onDelta: (text) => { output += text } })\n\n if (outcome.status === 'aborted' || editor.isDestroyed) return { status: 'aborted', output }\n if (outcome.status === 'error') return { status: 'error', output, message: outcome.message }\n return { status: outcome.status, output }\n}\n\n/**\n * Fills the body of the composite at `pos` (`generateCompositeBody`); the result opens the in-document diff review over\n * the body (`startAiReview`), so nothing is written until accepted. The body range is anchored when the run starts, so\n * edits while the data loads or the result streams do not misplace it. Title, fields and the other chrome stay\n * untouched. Notices go through `notify`, in the language of `t`.\n */\nexport async function fillComposite(editor: Editor, pos: number, ai: NonNullable<EditorBackend['ai']>, modelRef: (slot: 'generate') => ModelRef, notify: Notifier, t: Translate): Promise<void> {\n const brief = compositeAiBrief(editor, pos)\n const node = editor.state.doc.nodeAt(pos)\n if (!brief || !node) return\n\n const from = pos + 1 + node.child(0).nodeSize + node.child(1).nodeSize + node.child(2).nodeSize\n const anchor = captureRange(editor, { from, to: pos + node.nodeSize - 1 }, { startInside: true })\n\n const controller = new AbortController()\n const abort = () => controller.abort()\n editor.on('destroy', abort)\n try {\n const result = await generateCompositeBody(editor, pos, ai, modelRef, t, controller.signal)\n if (result.status === 'aborted') return\n if (result.status === 'data-error') {\n notify({ title: t('integrations.compositeFill.dataMissing'), description: result.message, kind: 'error' })\n return\n }\n if (result.status === 'rate-limited') {\n notifyAiRateLimited(notify, t)\n return\n }\n if (result.status === 'error') {\n notify({ title: t('integrations.compositeFill.failed'), description: result.message, kind: 'error' })\n return\n }\n const { output } = result\n if (!output.trim()) {\n notify({ title: t('integrations.compositeFill.empty.title'), description: t('integrations.compositeFill.empty.description'), kind: 'error' })\n return\n }\n\n // The body must still be where it was: a range directly inside a composite, after its chrome.\n const range = resolveRange(editor.state, anchor)\n const $from = range && editor.state.doc.resolve(range.from)\n if (!range || !$from || $from.parent.type.name !== 'composite' || $from.index() < COMPOSITE_CHROME_COUNT || !$from.sameParent(editor.state.doc.resolve(range.to))) {\n notify({ title: t('integrations.compositeFill.gone.title'), description: t('integrations.compositeFill.gone.description'), kind: 'error' })\n return\n }\n const review = startAiReview(editor, [{ id: 'fill', range: anchor, markdown: output }])\n if (review.hunks === 0) notify(aiApplyFailure(review.skipped[0]?.reason ?? 'unchanged', t))\n }\n finally {\n editor.off('destroy', abort)\n releaseRanges(editor, [anchor])\n }\n}\n"],"mappings":"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"}
@@ -1,28 +1,20 @@
1
1
  import { Translate } from "../../i18n/index.js";
2
+ import { EditorBackend } from "../../core/backend.js";
2
3
  import { Notifier } from "../../core/notify.js";
3
- import { ModelRef } from "../../features/ai/protocol/models.js";
4
+ import { ModelRef } from "../../core/backend-types.js";
4
5
  import "../../features/ai/index.js";
5
6
  import { Editor } from "@tiptap/core";
6
7
  import { Node as Node$1 } from "@tiptap/pm/model";
7
- import { $Fetch } from "ofetch";
8
8
  //#region src/integrations/composite-ai/composite-summary.d.ts
9
9
  /** Index of a composite's first body block, after `compositeTitle`, `compositeDescription` and `compositeTags`. */
10
10
  export declare const COMPOSITE_BODY_START = 3;
11
- /**
12
- * What a summary is made from: the text of a composite's body blocks, or, when the body holds no text (an audio or
13
- * video `document`), its `meta.transcript`. Empty for other nodes.
14
- */
11
+ /** What a summary is made from: the text of a composite's body blocks (renditions included). Empty for other nodes. */
15
12
  export declare function compositeSourceText(composite: Node$1): string;
16
- /** The stored asset behind a composite's first `audio`/`video` body block; null when it has none. */
17
- export declare function mediaAssetOf(composite: Node$1): {
18
- documentId: string;
19
- name: string;
20
- } | null;
21
13
  /**
22
14
  * Streams an AI summary of the composite at `pos` (its body as Markdown, task `summarize`, `rewrite` model slot) into
23
15
  * the composite's description, replacing what it held, and shows description and tags. The description is anchored
24
16
  * when the request starts, so edits while it streams do not misplace the result. Notices go through `notify`, in the language of `t`.
25
17
  */
26
- export declare function summarizeComposite(editor: Editor, pos: number, fetch: $Fetch, modelRef: (slot: 'rewrite') => ModelRef, notify: Notifier, t: Translate): Promise<void>;
18
+ export declare function summarizeComposite(editor: Editor, pos: number, ai: NonNullable<EditorBackend['ai']>, modelRef: (slot: 'rewrite') => ModelRef, notify: Notifier, t: Translate): Promise<void>;
27
19
  //#endregion
28
20
  //# sourceMappingURL=composite-summary.d.ts.map
@@ -1,7 +1,6 @@
1
1
  import { parseBlocks } from "../../core/pipeline.js";
2
2
  import { captureRange, releaseRanges, resolveRange } from "../../core/doc-anchors.js";
3
3
  import "../../features/composites/nodes.js";
4
- import { assetRefOf } from "../../features/media/assets.js";
5
4
  import { AI_LIMITS } from "../../features/ai/protocol/tasks.js";
6
5
  import { notifyAiRateLimited } from "../../features/ai/rate-limit.js";
7
6
  import { postAiSse } from "../../features/ai/ai-sse.js";
@@ -17,27 +16,9 @@ function compositeBody(composite) {
17
16
  });
18
17
  return body;
19
18
  }
20
- /** Text of a composite's body blocks (empty for other nodes). */
21
- function compositeBodyText(composite) {
22
- return compositeBody(composite).map((child) => child.textContent).join("\n");
23
- }
24
- /**
25
- * What a summary is made from: the text of a composite's body blocks, or, when the body holds no text (an audio or
26
- * video `document`), its `meta.transcript`. Empty for other nodes.
27
- */
19
+ /** What a summary is made from: the text of a composite's body blocks (renditions included). Empty for other nodes. */
28
20
  function compositeSourceText(composite) {
29
- if (composite.type.name !== "composite") return "";
30
- const text = compositeBodyText(composite);
31
- return text.trim() ? text : String(composite.attrs.meta?.transcript ?? "");
32
- }
33
- /** The stored asset behind a composite's first `audio`/`video` body block; null when it has none. */
34
- function mediaAssetOf(composite) {
35
- for (const child of compositeBody(composite)) {
36
- if (child.type.name !== "audio" && child.type.name !== "video") continue;
37
- const ref = assetRefOf(String(child.attrs.src ?? ""));
38
- if (ref) return ref;
39
- }
40
- return null;
21
+ return compositeBody(composite).map((child) => child.textContent).join("\n");
41
22
  }
42
23
  /** Inline content of the first textblock of a parsed AI result. */
43
24
  function firstInlineContent(editor, parsed) {
@@ -60,16 +41,16 @@ function firstInlineContent(editor, parsed) {
60
41
  * the composite's description, replacing what it held, and shows description and tags. The description is anchored
61
42
  * when the request starts, so edits while it streams do not misplace the result. Notices go through `notify`, in the language of `t`.
62
43
  */
63
- async function summarizeComposite(editor, pos, fetch, modelRef, notify, t) {
44
+ async function summarizeComposite(editor, pos, ai, modelRef, notify, t) {
64
45
  const composite = editor.state.doc.nodeAt(pos);
65
46
  if (composite?.type.name !== "composite" || composite.childCount <= COMPOSITE_BODY_START) return;
66
47
  const title = composite.child(0);
67
48
  const description = composite.child(1);
68
49
  const body = compositeBody(composite).map((child) => child.toJSON());
69
- const bodyMarkdown = compositeBodyText(composite).trim() ? editor.markdown.serialize({
50
+ const bodyMarkdown = compositeSourceText(composite).trim() ? editor.markdown.serialize({
70
51
  type: "doc",
71
52
  content: body
72
- }) : compositeSourceText(composite);
53
+ }) : "";
73
54
  const descriptionPos = pos + 1 + title.nodeSize;
74
55
  const anchor = captureRange(editor, {
75
56
  from: descriptionPos + 1,
@@ -81,7 +62,7 @@ async function summarizeComposite(editor, pos, fetch, modelRef, notify, t) {
81
62
  editor.on("destroy", abort);
82
63
  let output = "";
83
64
  try {
84
- const outcome = await postAiSse(fetch, "/api/ai/generate", {
65
+ const outcome = await postAiSse(ai, "generate", {
85
66
  task: "summarize",
86
67
  prompt: "",
87
68
  selection: bodyMarkdown.slice(0, AI_LIMITS.selection),
@@ -138,6 +119,6 @@ async function summarizeComposite(editor, pos, fetch, modelRef, notify, t) {
138
119
  }
139
120
  }
140
121
  //#endregion
141
- export { COMPOSITE_BODY_START, compositeSourceText, mediaAssetOf, summarizeComposite };
122
+ export { COMPOSITE_BODY_START, compositeSourceText, summarizeComposite };
142
123
 
143
124
  //# sourceMappingURL=composite-summary.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"composite-summary.js","names":[],"sources":["../../../src/integrations/composite-ai/composite-summary.ts"],"sourcesContent":["import type { Editor, JSONContent } from '@tiptap/core'\nimport { Fragment, type Node as PMNode } from '@tiptap/pm/model'\nimport type { $Fetch } from 'ofetch'\nimport { AI_LIMITS, type ModelRef, notifyAiRateLimited, postAiSse } from '../../features/ai'\nimport { COMPOSITE_CHROME_COUNT } from '../../features/composites/schema'\nimport { assetRefOf } from '../../features/media/schema'\nimport { captureRange, parseBlocks, releaseRanges, resolveRange } from '../../core'\nimport type { Translate } from '../../i18n'\nimport type { Notifier } from '../../core/notify'\n\n/** Index of a composite's first body block, after `compositeTitle`, `compositeDescription` and `compositeTags`. */\nexport const COMPOSITE_BODY_START = COMPOSITE_CHROME_COUNT\n\nfunction compositeBody(composite: PMNode): PMNode[] {\n if (composite.type.name !== 'composite') return []\n const body: PMNode[] = []\n composite.forEach((child, _offset, index) => {\n if (index >= COMPOSITE_BODY_START) body.push(child)\n })\n return body\n}\n\n/** Text of a composite's body blocks (empty for other nodes). */\nfunction compositeBodyText(composite: PMNode): string {\n return compositeBody(composite).map(child => child.textContent).join('\\n')\n}\n\n/**\n * What a summary is made from: the text of a composite's body blocks, or, when the body holds no text (an audio or\n * video `document`), its `meta.transcript`. Empty for other nodes.\n */\nexport function compositeSourceText(composite: PMNode): string {\n if (composite.type.name !== 'composite') return ''\n const text = compositeBodyText(composite)\n return text.trim() ? text : String(composite.attrs.meta?.transcript ?? '')\n}\n\n/** The stored asset behind a composite's first `audio`/`video` body block; null when it has none. */\nexport function mediaAssetOf(composite: PMNode): { documentId: string, name: string } | null {\n for (const child of compositeBody(composite)) {\n if (child.type.name !== 'audio' && child.type.name !== 'video') continue\n const ref = assetRefOf(String(child.attrs.src ?? ''))\n if (ref) return ref\n }\n return null\n}\n\n/** Inline content of the first textblock of a parsed AI result. */\nfunction firstInlineContent(editor: Editor, parsed: JSONContent): Fragment | null {\n let doc: PMNode\n try {\n doc = editor.schema.nodeFromJSON(parsed)\n }\n catch {\n return null\n }\n let inline: Fragment | null = null\n doc.descendants((node) => {\n if (inline) return false\n if (node.isTextblock && node.content.size) inline = node.content\n return !inline\n })\n return inline\n}\n\n/**\n * Streams an AI summary of the composite at `pos` (its body as Markdown, task `summarize`, `rewrite` model slot) into\n * the composite's description, replacing what it held, and shows description and tags. The description is anchored\n * when the request starts, so edits while it streams do not misplace the result. Notices go through `notify`, in the language of `t`.\n */\nexport async function summarizeComposite(editor: Editor, pos: number, fetch: $Fetch, modelRef: (slot: 'rewrite') => ModelRef, notify: Notifier, t: Translate): Promise<void> {\n const composite = editor.state.doc.nodeAt(pos)\n if (composite?.type.name !== 'composite' || composite.childCount <= COMPOSITE_BODY_START) return\n const title = composite.child(0)\n const description = composite.child(1)\n const body = compositeBody(composite).map(child => child.toJSON() as JSONContent)\n const bodyMarkdown = compositeBodyText(composite).trim()\n ? editor.markdown!.serialize({ type: 'doc', content: body })\n : compositeSourceText(composite)\n const descriptionPos = pos + 1 + title.nodeSize\n const anchor = captureRange(editor, { from: descriptionPos + 1, to: descriptionPos + 1 + description.content.size })\n const model = modelRef('rewrite')\n\n const controller = new AbortController()\n const abort = () => controller.abort()\n editor.on('destroy', abort)\n let output = ''\n try {\n const outcome = await postAiSse(fetch, '/api/ai/generate', {\n task: 'summarize',\n prompt: '',\n selection: bodyMarkdown.slice(0, AI_LIMITS.selection),\n context: '',\n model,\n }, { signal: controller.signal, t, onDelta: (text) => { output += text } })\n\n if (outcome.status === 'aborted' || editor.isDestroyed) return\n if (outcome.status === 'rate-limited') {\n notifyAiRateLimited(notify, t)\n return\n }\n if (outcome.status === 'error') {\n notify({ title: t('integrations.compositeSummary.failed'), description: outcome.message, kind: 'error' })\n return\n }\n if (!output.trim()) {\n notify({ title: t('integrations.compositeSummary.empty.title'), description: t('integrations.compositeSummary.empty.description'), kind: 'error' })\n return\n }\n\n const range = resolveRange(editor.state, anchor)\n const $from = range && editor.state.doc.resolve(range.from)\n if (!range || !$from || $from.parent.type.name !== 'compositeDescription' || !$from.sameParent(editor.state.doc.resolve(range.to))) {\n notify({ title: t('integrations.compositeSummary.gone.title'), description: t('integrations.compositeSummary.gone.description'), kind: 'error' })\n return\n }\n const inline = firstInlineContent(editor, parseBlocks(editor, output).parsed) ?? Fragment.from(editor.schema.text(output.trim()))\n editor.view.dispatch(editor.state.tr.replaceWith(range.from, range.to, inline))\n notify({ title: t('integrations.compositeSummary.done'), kind: 'success', icon: 'i-lucide-text-quote' })\n }\n finally {\n editor.off('destroy', abort)\n releaseRanges(editor, [anchor])\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"composite-summary.js","names":[],"sources":["../../../src/integrations/composite-ai/composite-summary.ts"],"sourcesContent":["import type { Editor, JSONContent } from '@tiptap/core'\nimport { Fragment, type Node as PMNode } from '@tiptap/pm/model'\nimport type { EditorBackend } from '../../core/backend'\nimport { AI_LIMITS, type ModelRef, notifyAiRateLimited, postAiSse } from '../../features/ai'\nimport { COMPOSITE_CHROME_COUNT } from '../../features/composites/schema'\nimport { captureRange, parseBlocks, releaseRanges, resolveRange } from '../../core'\nimport type { Translate } from '../../i18n'\nimport type { Notifier } from '../../core/notify'\n\n/** Index of a composite's first body block, after `compositeTitle`, `compositeDescription` and `compositeTags`. */\nexport const COMPOSITE_BODY_START = COMPOSITE_CHROME_COUNT\n\nfunction compositeBody(composite: PMNode): PMNode[] {\n if (composite.type.name !== 'composite') return []\n const body: PMNode[] = []\n composite.forEach((child, _offset, index) => {\n if (index >= COMPOSITE_BODY_START) body.push(child)\n })\n return body\n}\n\n/** What a summary is made from: the text of a composite's body blocks (renditions included). Empty for other nodes. */\nexport function compositeSourceText(composite: PMNode): string {\n return compositeBody(composite).map(child => child.textContent).join('\\n')\n}\n\n/** Inline content of the first textblock of a parsed AI result. */\nfunction firstInlineContent(editor: Editor, parsed: JSONContent): Fragment | null {\n let doc: PMNode\n try {\n doc = editor.schema.nodeFromJSON(parsed)\n }\n catch {\n return null\n }\n let inline: Fragment | null = null\n doc.descendants((node) => {\n if (inline) return false\n if (node.isTextblock && node.content.size) inline = node.content\n return !inline\n })\n return inline\n}\n\n/**\n * Streams an AI summary of the composite at `pos` (its body as Markdown, task `summarize`, `rewrite` model slot) into\n * the composite's description, replacing what it held, and shows description and tags. The description is anchored\n * when the request starts, so edits while it streams do not misplace the result. Notices go through `notify`, in the language of `t`.\n */\nexport async function summarizeComposite(editor: Editor, pos: number, ai: NonNullable<EditorBackend['ai']>, modelRef: (slot: 'rewrite') => ModelRef, notify: Notifier, t: Translate): Promise<void> {\n const composite = editor.state.doc.nodeAt(pos)\n if (composite?.type.name !== 'composite' || composite.childCount <= COMPOSITE_BODY_START) return\n const title = composite.child(0)\n const description = composite.child(1)\n const body = compositeBody(composite).map(child => child.toJSON() as JSONContent)\n const bodyMarkdown = compositeSourceText(composite).trim()\n ? editor.markdown!.serialize({ type: 'doc', content: body })\n : ''\n const descriptionPos = pos + 1 + title.nodeSize\n const anchor = captureRange(editor, { from: descriptionPos + 1, to: descriptionPos + 1 + description.content.size })\n const model = modelRef('rewrite')\n\n const controller = new AbortController()\n const abort = () => controller.abort()\n editor.on('destroy', abort)\n let output = ''\n try {\n const outcome = await postAiSse(ai, 'generate', {\n task: 'summarize',\n prompt: '',\n selection: bodyMarkdown.slice(0, AI_LIMITS.selection),\n context: '',\n model,\n }, { signal: controller.signal, t, onDelta: (text) => { output += text } })\n\n if (outcome.status === 'aborted' || editor.isDestroyed) return\n if (outcome.status === 'rate-limited') {\n notifyAiRateLimited(notify, t)\n return\n }\n if (outcome.status === 'error') {\n notify({ title: t('integrations.compositeSummary.failed'), description: outcome.message, kind: 'error' })\n return\n }\n if (!output.trim()) {\n notify({ title: t('integrations.compositeSummary.empty.title'), description: t('integrations.compositeSummary.empty.description'), kind: 'error' })\n return\n }\n\n const range = resolveRange(editor.state, anchor)\n const $from = range && editor.state.doc.resolve(range.from)\n if (!range || !$from || $from.parent.type.name !== 'compositeDescription' || !$from.sameParent(editor.state.doc.resolve(range.to))) {\n notify({ title: t('integrations.compositeSummary.gone.title'), description: t('integrations.compositeSummary.gone.description'), kind: 'error' })\n return\n }\n const inline = firstInlineContent(editor, parseBlocks(editor, output).parsed) ?? Fragment.from(editor.schema.text(output.trim()))\n editor.view.dispatch(editor.state.tr.replaceWith(range.from, range.to, inline))\n notify({ title: t('integrations.compositeSummary.done'), kind: 'success', icon: 'i-lucide-text-quote' })\n }\n finally {\n editor.off('destroy', abort)\n releaseRanges(editor, [anchor])\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { Translate } from "../../i18n/index.js";
2
+ import { EditorBackend } from "../../core/backend.js";
3
+ import { Notifier } from "../../core/notify.js";
4
+ import { ModelRef } from "../../core/backend-types.js";
5
+ import "../../features/ai/index.js";
6
+ import { CompositeKind } from "../../features/composites/kinds.js";
7
+ import "../../features/composites/index.js";
8
+ import { Editor } from "@tiptap/core";
9
+ import { Node as Node$1 } from "@tiptap/pm/model";
10
+ //#region src/integrations/composite-ai/derive.d.ts
11
+ /** Kinds a Baustein can be derived into: the ones with an `ai` configuration (their brief drives the generation). */
12
+ export declare const derivableKindsOf: (editor: Editor) => CompositeKind[];
13
+ /** Whether the Baustein `node` can be the source of a derivation: a composite with a block id (the derivation points at it by id). */
14
+ export declare const isDerivableSource: (editor: Editor, node: Node$1) => boolean;
15
+ /** Whether a Baustein of `kindId` may be inserted right after the Baustein at `pos` (the same guards as creating it there). */
16
+ export declare function canDeriveAfter(editor: Editor, pos: number, kindId: string): boolean;
17
+ /**
18
+ * „Ableiten (KI) → <Art>“: inserts a sibling Baustein of kind `kindId` right after the Baustein at `pos`, titled
19
+ * „<Art>: <Quelle>“, whose `meta.derivation` points back at the source block (`from.block`, method `ai:<kindId>`, the
20
+ * Markdown hash of the source's body as `inputHash`), generates its body from the source (`generateCompositeBody`; the
21
+ * `aiBlockData` of composites hands the model the source's Markdown) and writes the result directly into the new
22
+ * Baustein — no review, the new Baustein is the proposal. The hash of the written body becomes `outputHash`, so a later
23
+ * edit shows as „bearbeitet“ and a later edit of the source as „Quelle geändert“. The new Baustein is found again by its
24
+ * block id after every await, so edits while the model runs do not misplace the result. When the run fails or yields
25
+ * nothing the still-empty Baustein is removed again. Notices go through `notify`, in the language of `t`.
26
+ */
27
+ export declare function deriveComposite(editor: Editor, pos: number, kindId: string, ai: NonNullable<EditorBackend['ai']>, modelRef: (slot: 'generate') => ModelRef, notify: Notifier, t: Translate): Promise<void>;
28
+ //#endregion
29
+ //# sourceMappingURL=derive.d.ts.map
@@ -0,0 +1,173 @@
1
+ import { parseBlocks } from "../../core/pipeline.js";
2
+ import { guardsAccept } from "../../core/commands.js";
3
+ import { blockIdOf, findBlockById, newBlockId } from "../../core/schema/block-ids.js";
4
+ import { sha256Hex } from "../../core/hash.js";
5
+ import { compositeKind } from "../../features/composites/kinds.js";
6
+ import { DERIVATION_KEY } from "../../features/composites/meta-keys.js";
7
+ import { bodyMarkdown, derivationOf } from "../../features/composites/derivation.js";
8
+ import { compositeJSON, compositeKindsOf } from "../../features/composites/nodes.js";
9
+ import { notifyAiRateLimited } from "../../features/ai/rate-limit.js";
10
+ import { generateCompositeBody } from "./composite-fill.js";
11
+ import { Fragment } from "@tiptap/pm/model";
12
+ //#region src/integrations/composite-ai/derive.ts
13
+ /** Kinds a Baustein can be derived into: the ones with an `ai` configuration (their brief drives the generation). */
14
+ const derivableKindsOf = (editor) => compositeKindsOf(editor).filter((kind) => kind.ai !== void 0);
15
+ /** Whether the Baustein `node` can be the source of a derivation: a composite with a block id (the derivation points at it by id). */
16
+ const isDerivableSource = (editor, node) => node.type.name === "composite" && blockIdOf(node) !== null && derivableKindsOf(editor).length > 0;
17
+ /** Whether a Baustein of `kindId` may be inserted right after the Baustein at `pos` (the same guards as creating it there). */
18
+ function canDeriveAfter(editor, pos, kindId) {
19
+ const source = editor.state.doc.nodeAt(pos);
20
+ if (!source) return false;
21
+ const $at = editor.state.doc.resolve(pos + source.nodeSize);
22
+ return guardsAccept(editor, $at, {
23
+ type: "composite",
24
+ attrs: { kind: kindId }
25
+ });
26
+ }
27
+ /**
28
+ * „Ableiten (KI) → <Art>“: inserts a sibling Baustein of kind `kindId` right after the Baustein at `pos`, titled
29
+ * „<Art>: <Quelle>“, whose `meta.derivation` points back at the source block (`from.block`, method `ai:<kindId>`, the
30
+ * Markdown hash of the source's body as `inputHash`), generates its body from the source (`generateCompositeBody`; the
31
+ * `aiBlockData` of composites hands the model the source's Markdown) and writes the result directly into the new
32
+ * Baustein — no review, the new Baustein is the proposal. The hash of the written body becomes `outputHash`, so a later
33
+ * edit shows as „bearbeitet“ and a later edit of the source as „Quelle geändert“. The new Baustein is found again by its
34
+ * block id after every await, so edits while the model runs do not misplace the result. When the run fails or yields
35
+ * nothing the still-empty Baustein is removed again. Notices go through `notify`, in the language of `t`.
36
+ */
37
+ async function deriveComposite(editor, pos, kindId, ai, modelRef, notify, t) {
38
+ const source = editor.state.doc.nodeAt(pos);
39
+ const sourceId = source && blockIdOf(source);
40
+ const kind = compositeKindsOf(editor).find((candidate) => candidate.id === kindId);
41
+ if (source?.type.name !== "composite" || !sourceId || !kind?.ai) return;
42
+ if (!canDeriveAfter(editor, pos, kindId)) {
43
+ notify({
44
+ title: t("integrations.compositeDerive.notAccepted"),
45
+ kind: "error"
46
+ });
47
+ return;
48
+ }
49
+ const sourceKind = compositeKind(compositeKindsOf(editor), String(source.attrs.kind));
50
+ const derivation = {
51
+ from: { block: sourceId },
52
+ method: `ai:${kindId}`,
53
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
54
+ inputHash: sha256Hex(bodyMarkdown(editor, source)),
55
+ outputHash: ""
56
+ };
57
+ const id = newBlockId();
58
+ const json = compositeJSON(kindId);
59
+ const [title, ...rest] = json.content;
60
+ const text = `${kind.label}: ${source.child(0).textContent.trim() || sourceKind.label}`;
61
+ const created = {
62
+ ...json,
63
+ attrs: {
64
+ ...json.attrs,
65
+ id,
66
+ meta: { [DERIVATION_KEY]: derivation }
67
+ },
68
+ content: [{
69
+ ...title,
70
+ content: [{
71
+ type: "text",
72
+ text
73
+ }]
74
+ }, ...rest]
75
+ };
76
+ editor.view.dispatch(editor.state.tr.insert(pos + source.nodeSize, editor.schema.nodeFromJSON(created)));
77
+ const toastId = `derive-${id}`;
78
+ const controller = new AbortController();
79
+ const abort = () => controller.abort();
80
+ editor.on("destroy", abort);
81
+ notify({
82
+ id: toastId,
83
+ title: t("integrations.compositeDerive.running", { kind: kind.label }),
84
+ kind: "info",
85
+ icon: "i-lucide-loader-circle",
86
+ duration: 0
87
+ });
88
+ /** Drops the new Baustein again, unless its body got content meanwhile (the user may have started writing in it). */
89
+ const discard = () => {
90
+ const found = editor.isDestroyed ? null : findBlockById(editor.state.doc, id);
91
+ if (!found) return;
92
+ if (Array.from({ length: found.node.childCount - 3 }, (_, index) => found.node.child(3 + index)).some((child) => child.textContent.trim() || child.type.name !== "paragraph")) return;
93
+ editor.view.dispatch(editor.state.tr.delete(found.pos, found.pos + found.node.nodeSize));
94
+ };
95
+ try {
96
+ const target = findBlockById(editor.state.doc, id);
97
+ const result = target ? await generateCompositeBody(editor, target.pos, ai, modelRef, t, controller.signal) : null;
98
+ if (!result || result.status === "aborted" || editor.isDestroyed) {
99
+ if (!editor.isDestroyed) discard();
100
+ return;
101
+ }
102
+ if (result.status === "rate-limited") {
103
+ discard();
104
+ notifyAiRateLimited(notify, t);
105
+ return;
106
+ }
107
+ if (result.status === "data-error") {
108
+ discard();
109
+ notify({
110
+ title: t("integrations.compositeFill.dataMissing"),
111
+ description: result.message,
112
+ kind: "error"
113
+ });
114
+ return;
115
+ }
116
+ if (result.status === "error") {
117
+ discard();
118
+ notify({
119
+ title: t("integrations.compositeDerive.failed"),
120
+ description: result.message,
121
+ kind: "error"
122
+ });
123
+ return;
124
+ }
125
+ const blocks = result.output.trim() ? parseBlocks(editor, result.output).blocks.map((block) => editor.schema.nodeFromJSON(block)) : [];
126
+ if (!blocks.length) {
127
+ discard();
128
+ notify({
129
+ title: t("integrations.compositeDerive.empty.title"),
130
+ description: t("integrations.compositeDerive.empty.description"),
131
+ kind: "error"
132
+ });
133
+ return;
134
+ }
135
+ const found = findBlockById(editor.state.doc, id);
136
+ if (!found || !found.node.canReplace(3, found.node.childCount, Fragment.from(blocks))) {
137
+ notify({
138
+ title: t("integrations.compositeDerive.gone.title"),
139
+ description: t("integrations.compositeDerive.gone.description"),
140
+ kind: "error"
141
+ });
142
+ return;
143
+ }
144
+ const chromeSize = Array.from({ length: 3 }, (_, index) => found.node.child(index).nodeSize).reduce((sum, size) => sum + size, 0);
145
+ const tr = editor.state.tr.replaceWith(found.pos + 1 + chromeSize, found.pos + found.node.nodeSize - 1, blocks);
146
+ const written = findBlockById(tr.doc, id);
147
+ const stored = derivationOf(written.node) ?? derivation;
148
+ tr.setNodeMarkup(written.pos, void 0, {
149
+ ...written.node.attrs,
150
+ meta: {
151
+ ...written.node.attrs.meta,
152
+ [DERIVATION_KEY]: {
153
+ ...stored,
154
+ outputHash: sha256Hex(bodyMarkdown(editor, written.node))
155
+ }
156
+ }
157
+ });
158
+ editor.view.dispatch(tr);
159
+ editor.commands.revealBlock(id);
160
+ notify({
161
+ title: t("integrations.compositeDerive.done", { kind: kind.label }),
162
+ kind: "success",
163
+ icon: "i-lucide-git-branch"
164
+ });
165
+ } finally {
166
+ notify.dismiss?.(toastId);
167
+ editor.off("destroy", abort);
168
+ }
169
+ }
170
+ //#endregion
171
+ export { canDeriveAfter, derivableKindsOf, deriveComposite, isDerivableSource };
172
+
173
+ //# sourceMappingURL=derive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derive.js","names":[],"sources":["../../../src/integrations/composite-ai/derive.ts"],"sourcesContent":["import type { Editor, JSONContent } from '@tiptap/core'\nimport { Fragment, type Node as PMNode } from '@tiptap/pm/model'\nimport type { EditorBackend } from '../../core/backend'\nimport { guardsAccept, parseBlocks, sha256Hex } from '../../core'\nimport type { Notifier } from '../../core/notify'\nimport { blockIdOf, findBlockById, newBlockId } from '../../core/schema'\nimport type { Translate } from '../../i18n'\nimport { type ModelRef, notifyAiRateLimited } from '../../features/ai'\nimport { bodyMarkdown, COMPOSITE_CHROME_COUNT, compositeJSON, compositeKind, compositeKindsOf, DERIVATION_KEY, type Derivation, derivationOf } from '../../features/composites/schema'\nimport { generateCompositeBody } from './composite-fill'\n\n/** Kinds a Baustein can be derived into: the ones with an `ai` configuration (their brief drives the generation). */\nexport const derivableKindsOf = (editor: Editor) => compositeKindsOf(editor).filter(kind => kind.ai !== undefined)\n\n/** Whether the Baustein `node` can be the source of a derivation: a composite with a block id (the derivation points at it by id). */\nexport const isDerivableSource = (editor: Editor, node: PMNode) => node.type.name === 'composite' && blockIdOf(node) !== null && derivableKindsOf(editor).length > 0\n\n/** Whether a Baustein of `kindId` may be inserted right after the Baustein at `pos` (the same guards as creating it there). */\nexport function canDeriveAfter(editor: Editor, pos: number, kindId: string): boolean {\n const source = editor.state.doc.nodeAt(pos)\n if (!source) return false\n const $at = editor.state.doc.resolve(pos + source.nodeSize)\n return guardsAccept(editor, $at, { type: 'composite', attrs: { kind: kindId } })\n}\n\n/**\n * „Ableiten (KI) → <Art>“: inserts a sibling Baustein of kind `kindId` right after the Baustein at `pos`, titled\n * „<Art>: <Quelle>“, whose `meta.derivation` points back at the source block (`from.block`, method `ai:<kindId>`, the\n * Markdown hash of the source's body as `inputHash`), generates its body from the source (`generateCompositeBody`; the\n * `aiBlockData` of composites hands the model the source's Markdown) and writes the result directly into the new\n * Baustein — no review, the new Baustein is the proposal. The hash of the written body becomes `outputHash`, so a later\n * edit shows as „bearbeitet“ and a later edit of the source as „Quelle geändert“. The new Baustein is found again by its\n * block id after every await, so edits while the model runs do not misplace the result. When the run fails or yields\n * nothing the still-empty Baustein is removed again. Notices go through `notify`, in the language of `t`.\n */\nexport async function deriveComposite(editor: Editor, pos: number, kindId: string, ai: NonNullable<EditorBackend['ai']>, modelRef: (slot: 'generate') => ModelRef, notify: Notifier, t: Translate): Promise<void> {\n const source = editor.state.doc.nodeAt(pos)\n const sourceId = source && blockIdOf(source)\n const kind = compositeKindsOf(editor).find(candidate => candidate.id === kindId)\n if (source?.type.name !== 'composite' || !sourceId || !kind?.ai) return\n if (!canDeriveAfter(editor, pos, kindId)) {\n notify({ title: t('integrations.compositeDerive.notAccepted'), kind: 'error' })\n return\n }\n\n const sourceKind = compositeKind(compositeKindsOf(editor), String(source.attrs.kind))\n const derivation: Derivation = {\n from: { block: sourceId },\n method: `ai:${kindId}`,\n createdAt: new Date().toISOString(),\n inputHash: sha256Hex(bodyMarkdown(editor, source)),\n outputHash: '',\n }\n const id = newBlockId()\n const json = compositeJSON(kindId)\n const [title, ...rest] = json.content as JSONContent[]\n const text = `${kind.label}: ${source.child(0).textContent.trim() || sourceKind.label}`\n const created: JSONContent = {\n ...json,\n attrs: { ...json.attrs, id, meta: { [DERIVATION_KEY]: derivation } },\n content: [{ ...title!, content: [{ type: 'text', text }] }, ...rest],\n }\n editor.view.dispatch(editor.state.tr.insert(pos + source.nodeSize, editor.schema.nodeFromJSON(created)))\n\n const toastId = `derive-${id}`\n const controller = new AbortController()\n const abort = () => controller.abort()\n editor.on('destroy', abort)\n notify({ id: toastId, title: t('integrations.compositeDerive.running', { kind: kind.label }), kind: 'info', icon: 'i-lucide-loader-circle', duration: 0 })\n\n /** Drops the new Baustein again, unless its body got content meanwhile (the user may have started writing in it). */\n const discard = () => {\n const found = editor.isDestroyed ? null : findBlockById(editor.state.doc, id)\n if (!found) return\n const body = Array.from({ length: found.node.childCount - COMPOSITE_CHROME_COUNT }, (_, index) => found.node.child(COMPOSITE_CHROME_COUNT + index))\n if (body.some(child => child.textContent.trim() || child.type.name !== 'paragraph')) return\n editor.view.dispatch(editor.state.tr.delete(found.pos, found.pos + found.node.nodeSize))\n }\n\n try {\n const target = findBlockById(editor.state.doc, id)\n const result = target ? await generateCompositeBody(editor, target.pos, ai, modelRef, t, controller.signal) : null\n if (!result || result.status === 'aborted' || editor.isDestroyed) {\n if (!editor.isDestroyed) discard()\n return\n }\n if (result.status === 'rate-limited') {\n discard()\n notifyAiRateLimited(notify, t)\n return\n }\n if (result.status === 'data-error') {\n discard()\n notify({ title: t('integrations.compositeFill.dataMissing'), description: result.message, kind: 'error' })\n return\n }\n if (result.status === 'error') {\n discard()\n notify({ title: t('integrations.compositeDerive.failed'), description: result.message, kind: 'error' })\n return\n }\n\n const blocks = result.output.trim() ? parseBlocks(editor, result.output).blocks.map(block => editor.schema.nodeFromJSON(block)) : []\n if (!blocks.length) {\n discard()\n notify({ title: t('integrations.compositeDerive.empty.title'), description: t('integrations.compositeDerive.empty.description'), kind: 'error' })\n return\n }\n const found = findBlockById(editor.state.doc, id)\n if (!found || !found.node.canReplace(COMPOSITE_CHROME_COUNT, found.node.childCount, Fragment.from(blocks))) {\n notify({ title: t('integrations.compositeDerive.gone.title'), description: t('integrations.compositeDerive.gone.description'), kind: 'error' })\n return\n }\n\n // One transaction: body and the hash of exactly that body, so one undo step removes both.\n const chromeSize = Array.from({ length: COMPOSITE_CHROME_COUNT }, (_, index) => found.node.child(index).nodeSize).reduce((sum, size) => sum + size, 0)\n const tr = editor.state.tr.replaceWith(found.pos + 1 + chromeSize, found.pos + found.node.nodeSize - 1, blocks)\n const written = findBlockById(tr.doc, id)!\n const stored = derivationOf(written.node) ?? derivation\n tr.setNodeMarkup(written.pos, undefined, {\n ...written.node.attrs,\n meta: { ...written.node.attrs.meta, [DERIVATION_KEY]: { ...stored, outputHash: sha256Hex(bodyMarkdown(editor, written.node)) } },\n })\n editor.view.dispatch(tr)\n editor.commands.revealBlock(id)\n notify({ title: t('integrations.compositeDerive.done', { kind: kind.label }), kind: 'success', icon: 'i-lucide-git-branch' })\n }\n finally {\n notify.dismiss?.(toastId)\n editor.off('destroy', abort)\n }\n}\n"],"mappings":"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"}
@@ -1,16 +1,20 @@
1
1
  import { EditorFeature } from "../../core/feature.js";
2
2
  import "../../core/index.js";
3
- import { fillComposite } from "./composite-fill.js";
4
- import { COMPOSITE_BODY_START, compositeSourceText, mediaAssetOf, summarizeComposite } from "./composite-summary.js";
5
- import { transcribeDocument } from "./document-transcribe.js";
3
+ import "../../features/composites/bibliography-command.js";
4
+ import { CompositeBodyResult, fillComposite, generateCompositeBody } from "./composite-fill.js";
5
+ import { COMPOSITE_BODY_START, compositeSourceText, summarizeComposite } from "./composite-summary.js";
6
+ import { RenditionOptions, canCreateRendition, canRegenerateRendition, createRendition, regenerateRendition } from "./rendition.js";
7
+ import { canDeriveAfter, derivableKindsOf, deriveComposite, isDerivableSource } from "./derive.js";
8
+ import { canFetchBibliography, doiOf, fetchBibliography } from "./bibliography-fetch.js";
6
9
  //#region src/integrations/composite-ai/index.d.ts
7
10
  /**
8
11
  * AI on composites (requires `composites`, `ai`, `media`): the „Baustein füllen (KI)“ block action (on composites of
9
12
  * kinds with an `ai` configuration: brief + document → task `fill-block`, the result opens the diff review over the
10
13
  * body), the „Zusammenfassung erzeugen“ block action (streams a
11
- * summary of a composite's body or transcript into its description), the „Transkribieren“ action of a `document`
12
- * composite with an audio/video asset (`POST /api/ai/transcribe`, shown only when the app's public AI configuration
13
- * enables transcription), and the composite-structure form of AI results: with `composite` structure an AI result that
14
+ * summary of a composite's body into its description), the „Lesefassung erzeugen“ / „Neu erzeugen (ersetzen)“
15
+ * actions of source-holding Bausteine (`ai.extract`: a rendition child with the transcript, full text or description of
16
+ * the source; a recording needs the app's public AI configuration to enable transcription),
17
+ * and the composite-structure form of AI results: with `composite` structure an AI result that
14
18
  * has a heading is inserted as a `section` composite fence, otherwise (and in flat structure) the base AI heading
15
19
  * is used. It is the preset's single `formatAiResult` contributor. The base AI feature and the composites feature do
16
20
  * not know it. Framework-free: notices go through the surface's `ctx.notify`, the model through the app's
@@ -18,5 +22,5 @@ import { transcribeDocument } from "./document-transcribe.js";
18
22
  */
19
23
  export declare function compositeAiFeature(): EditorFeature<never>;
20
24
  //#endregion
21
- export { COMPOSITE_BODY_START, compositeSourceText, fillComposite, mediaAssetOf, summarizeComposite, transcribeDocument };
25
+ export { COMPOSITE_BODY_START, type CompositeBodyResult, type RenditionOptions, canCreateRendition, canDeriveAfter, canFetchBibliography, canRegenerateRendition, compositeSourceText, createRendition, derivableKindsOf, deriveComposite, doiOf, fetchBibliography, fillComposite, generateCompositeBody, isDerivableSource, regenerateRendition, summarizeComposite };
22
26
  //# sourceMappingURL=index.d.ts.map
@@ -5,11 +5,28 @@ import { compositeKindsOf } from "../../features/composites/nodes.js";
5
5
  import { withHeading } from "../../features/ai/protocol/tasks.js";
6
6
  import { modelProfiles } from "../../features/ai/model-profiles.js";
7
7
  import { structureOf } from "../../features/composites/structure.js";
8
- import { fillComposite } from "./composite-fill.js";
9
- import { COMPOSITE_BODY_START, compositeSourceText, mediaAssetOf, summarizeComposite } from "./composite-summary.js";
10
- import { transcribeDocument } from "./document-transcribe.js";
8
+ import { fillComposite, generateCompositeBody } from "./composite-fill.js";
9
+ import { canDeriveAfter, derivableKindsOf, deriveComposite, isDerivableSource } from "./derive.js";
10
+ import { canFetchBibliography, doiOf, fetchBibliography } from "./bibliography-fetch.js";
11
+ import { COMPOSITE_BODY_START, compositeSourceText, summarizeComposite } from "./composite-summary.js";
12
+ import { canCreateRendition, canRegenerateRendition, createRendition, regenerateRendition } from "./rendition.js";
13
+ import { Extension } from "@tiptap/core";
11
14
  //#region src/integrations/composite-ai/index.ts
15
+ /** The editor command `fetchCompositeBibliography` (declared by composites) behind the bibliography editor's „DOI abrufen“ button; absent without the AI capability. */
16
+ function bibliographyFetchExtensions(ctx) {
17
+ const ai = ctx.backend.ai;
18
+ if (!ai) return [];
19
+ return [Extension.create({
20
+ name: "compositeBibliographyFetch",
21
+ addCommands: () => ({ fetchCompositeBibliography: (pos) => ({ editor }) => {
22
+ fetchBibliography(editor, pos, ai, modelProfiles(ctx.app).modelRef, ctx.notify, ctx.t, ctx.documentId);
23
+ return true;
24
+ } })
25
+ })];
26
+ }
12
27
  function compositeAiActions(ctx) {
28
+ const ai = ctx.backend.ai;
29
+ if (!ai) return [];
13
30
  return [
14
31
  {
15
32
  id: "composite-fill",
@@ -19,7 +36,7 @@ function compositeAiActions(ctx) {
19
36
  order: 25,
20
37
  isVisible: ({ editor, node }) => node.type.name === "composite" && compositeKind(compositeKindsOf(editor), String(node.attrs.kind)).ai !== void 0,
21
38
  run: ({ editor, pos }) => {
22
- fillComposite(editor, pos, ctx.fetch, modelProfiles(ctx.app).modelRef, ctx.notify, ctx.t);
39
+ fillComposite(editor, pos, ai, modelProfiles(ctx.app).modelRef, ctx.notify, ctx.t);
23
40
  }
24
41
  },
25
42
  {
@@ -30,18 +47,56 @@ function compositeAiActions(ctx) {
30
47
  order: 30,
31
48
  isVisible: ({ node }) => compositeSourceText(node).trim().length > 0,
32
49
  run: ({ editor, pos }) => {
33
- summarizeComposite(editor, pos, ctx.fetch, modelProfiles(ctx.app).modelRef, ctx.notify, ctx.t);
50
+ summarizeComposite(editor, pos, ai, modelProfiles(ctx.app).modelRef, ctx.notify, ctx.t);
34
51
  }
35
52
  },
36
53
  {
37
- id: "document-transcribe",
38
- label: ctx.t("integrations.documentTranscribe.action"),
54
+ id: "composite-derive",
55
+ label: ctx.t("integrations.compositeDerive.action"),
56
+ icon: "i-lucide-git-branch",
57
+ ability: ABILITY.compositeDerive,
58
+ order: 452,
59
+ isVisible: ({ editor, node }) => isDerivableSource(editor, node),
60
+ menu: ({ editor, pos }) => derivableKindsOf(editor).map((kind) => ({
61
+ label: kind.label,
62
+ icon: kind.icon,
63
+ disabled: !canDeriveAfter(editor, pos, kind.id),
64
+ onSelect: () => {
65
+ deriveComposite(editor, pos, kind.id, ai, modelProfiles(ctx.app).modelRef, ctx.notify, ctx.t);
66
+ }
67
+ }))
68
+ },
69
+ {
70
+ id: "bibliography-fetch",
71
+ label: ctx.t("integrations.bibliographyFetch.action"),
72
+ icon: "i-lucide-book-marked",
73
+ ability: ABILITY.compositeDerive,
74
+ order: 453,
75
+ isVisible: ({ editor, node }) => canFetchBibliography(editor, node),
76
+ run: ({ editor, pos }) => {
77
+ fetchBibliography(editor, pos, ai, modelProfiles(ctx.app).modelRef, ctx.notify, ctx.t, ctx.documentId);
78
+ }
79
+ },
80
+ {
81
+ id: "rendition-create",
82
+ label: ctx.t("integrations.rendition.action"),
39
83
  icon: "i-lucide-captions",
40
- ability: ABILITY.compositeTranscribe,
84
+ ability: ABILITY.compositeDerive,
41
85
  order: 450,
42
- isVisible: ({ node }) => node.attrs.kind === "document" && !!ctx.ai?.transcription && mediaAssetOf(node) !== null,
86
+ isVisible: ({ editor, node }) => canCreateRendition(editor, node, !!ctx.ai?.transcription),
87
+ run: ({ editor, pos }) => {
88
+ createRendition(editor, pos, ai, modelProfiles(ctx.app).modelRef, ctx.notify, ctx.t);
89
+ }
90
+ },
91
+ {
92
+ id: "rendition-regenerate",
93
+ label: ctx.t("integrations.rendition.regenerate"),
94
+ icon: "i-lucide-refresh-cw",
95
+ ability: ABILITY.compositeDerive,
96
+ order: 451,
97
+ isVisible: ({ editor, node, pos }) => canRegenerateRendition(editor, node, pos, !!ctx.ai?.transcription),
43
98
  run: ({ editor, pos }) => {
44
- transcribeDocument(editor, pos, ctx.fetch, ctx.notify, ctx.t);
99
+ regenerateRendition(editor, pos, ai, modelProfiles(ctx.app).modelRef, ctx.notify, ctx.t);
45
100
  }
46
101
  }
47
102
  ];
@@ -50,9 +105,10 @@ function compositeAiActions(ctx) {
50
105
  * AI on composites (requires `composites`, `ai`, `media`): the „Baustein füllen (KI)“ block action (on composites of
51
106
  * kinds with an `ai` configuration: brief + document → task `fill-block`, the result opens the diff review over the
52
107
  * body), the „Zusammenfassung erzeugen“ block action (streams a
53
- * summary of a composite's body or transcript into its description), the „Transkribieren“ action of a `document`
54
- * composite with an audio/video asset (`POST /api/ai/transcribe`, shown only when the app's public AI configuration
55
- * enables transcription), and the composite-structure form of AI results: with `composite` structure an AI result that
108
+ * summary of a composite's body into its description), the „Lesefassung erzeugen“ / „Neu erzeugen (ersetzen)“
109
+ * actions of source-holding Bausteine (`ai.extract`: a rendition child with the transcript, full text or description of
110
+ * the source; a recording needs the app's public AI configuration to enable transcription),
111
+ * and the composite-structure form of AI results: with `composite` structure an AI result that
56
112
  * has a heading is inserted as a `section` composite fence, otherwise (and in flat structure) the base AI heading
57
113
  * is used. It is the preset's single `formatAiResult` contributor. The base AI feature and the composites feature do
58
114
  * not know it. Framework-free: notices go through the surface's `ctx.notify`, the model through the app's
@@ -61,12 +117,14 @@ function compositeAiActions(ctx) {
61
117
  function compositeAiFeature() {
62
118
  return {
63
119
  id: "composite-ai",
120
+ dimension: "ai",
64
121
  requires: [
65
122
  "composites",
66
123
  "ai",
67
124
  "media"
68
125
  ],
69
126
  blockActions: compositeAiActions,
127
+ extensions: bibliographyFetchExtensions,
70
128
  formatAiResult: (editor, markdown, heading) => {
71
129
  if (!heading) return markdown;
72
130
  const text = withHeading(heading, markdown);
@@ -75,6 +133,6 @@ function compositeAiFeature() {
75
133
  };
76
134
  }
77
135
  //#endregion
78
- export { COMPOSITE_BODY_START, compositeAiFeature, compositeSourceText, fillComposite, mediaAssetOf, summarizeComposite, transcribeDocument };
136
+ export { COMPOSITE_BODY_START, canCreateRendition, canDeriveAfter, canFetchBibliography, canRegenerateRendition, compositeAiFeature, compositeSourceText, createRendition, derivableKindsOf, deriveComposite, doiOf, fetchBibliography, fillComposite, generateCompositeBody, isDerivableSource, regenerateRendition, summarizeComposite };
79
137
 
80
138
  //# sourceMappingURL=index.js.map