@dxos/plugin-markdown 0.8.2-staging.7ac8446 → 0.8.2

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 (227) hide show
  1. package/dist/lib/browser/MarkdownContainer-5IEINNQB.mjs +588 -0
  2. package/dist/lib/browser/MarkdownContainer-5IEINNQB.mjs.map +7 -0
  3. package/dist/lib/browser/MarkdownPreview-YW5CS3ID.mjs +87 -0
  4. package/dist/lib/browser/MarkdownPreview-YW5CS3ID.mjs.map +7 -0
  5. package/dist/lib/browser/anchor-sort-VS4OZVPP.mjs +32 -0
  6. package/dist/lib/browser/anchor-sort-VS4OZVPP.mjs.map +7 -0
  7. package/dist/lib/browser/{app-graph-serializer-NOXI4IQ5.mjs → app-graph-serializer-V6RLEHVY.mjs} +5 -6
  8. package/dist/lib/browser/app-graph-serializer-V6RLEHVY.mjs.map +7 -0
  9. package/dist/lib/browser/{artifact-definition-CE6J6NY4.mjs → artifact-definition-5NAODQLG.mjs} +65 -17
  10. package/dist/lib/browser/artifact-definition-5NAODQLG.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-3ULJ4FIJ.mjs → chunk-77NGW7EO.mjs} +12 -26
  12. package/dist/lib/browser/chunk-77NGW7EO.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-ACAID3XF.mjs +20 -0
  14. package/dist/lib/browser/chunk-ACAID3XF.mjs.map +7 -0
  15. package/dist/lib/browser/{chunk-QXDKFACU.mjs → chunk-C5RABVIX.mjs} +6 -5
  16. package/dist/lib/browser/chunk-C5RABVIX.mjs.map +7 -0
  17. package/dist/lib/browser/chunk-ECSM56YC.mjs +80 -0
  18. package/dist/lib/browser/chunk-ECSM56YC.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-NAGMSX77.mjs → chunk-QVJETNGS.mjs} +2 -2
  20. package/dist/lib/{node-esm/chunk-ETXPC5VP.mjs.map → browser/chunk-QVJETNGS.mjs.map} +1 -1
  21. package/dist/lib/browser/index.mjs +34 -18
  22. package/dist/lib/browser/index.mjs.map +3 -3
  23. package/dist/lib/browser/intent-resolver-4GDYST4Y.mjs +65 -0
  24. package/dist/lib/browser/intent-resolver-4GDYST4Y.mjs.map +7 -0
  25. package/dist/lib/browser/meta.json +1 -1
  26. package/dist/lib/browser/react-surface-QE4SKXBT.mjs +200 -0
  27. package/dist/lib/browser/react-surface-QE4SKXBT.mjs.map +7 -0
  28. package/dist/lib/browser/{settings-GCSS3Y4Z.mjs → settings-W5CK4PXP.mjs} +4 -4
  29. package/dist/lib/browser/settings-W5CK4PXP.mjs.map +7 -0
  30. package/dist/lib/browser/{state-O7P5JDIH.mjs → state-KI6PJ6DT.mjs} +3 -3
  31. package/dist/lib/browser/state-KI6PJ6DT.mjs.map +7 -0
  32. package/dist/lib/browser/types/index.mjs +3 -1
  33. package/dist/lib/node/MarkdownContainer-LSNNPNRB.cjs +601 -0
  34. package/dist/lib/node/MarkdownContainer-LSNNPNRB.cjs.map +7 -0
  35. package/dist/lib/node/MarkdownPreview-G34HSQEB.cjs +110 -0
  36. package/dist/lib/node/MarkdownPreview-G34HSQEB.cjs.map +7 -0
  37. package/dist/lib/node/{thread-42R57L4K.cjs → anchor-sort-NHVF23EU.cjs} +15 -20
  38. package/dist/lib/node/anchor-sort-NHVF23EU.cjs.map +7 -0
  39. package/dist/lib/node/{app-graph-serializer-HKK3SEDN.cjs → app-graph-serializer-CLALIYN3.cjs} +10 -11
  40. package/dist/lib/node/app-graph-serializer-CLALIYN3.cjs.map +7 -0
  41. package/dist/lib/node/{artifact-definition-XGADFWCQ.cjs → artifact-definition-VEAHK7BX.cjs} +68 -21
  42. package/dist/lib/node/artifact-definition-VEAHK7BX.cjs.map +7 -0
  43. package/dist/lib/node/chunk-C4HR7UXE.cjs +58 -0
  44. package/dist/lib/node/chunk-C4HR7UXE.cjs.map +7 -0
  45. package/dist/lib/node/{chunk-7QVONRSI.cjs → chunk-G7RBJX22.cjs} +13 -41
  46. package/dist/lib/node/chunk-G7RBJX22.cjs.map +7 -0
  47. package/dist/lib/node/{chunk-DZXTXSXX.cjs → chunk-IFYSBQE5.cjs} +5 -5
  48. package/dist/lib/node/{chunk-DZXTXSXX.cjs.map → chunk-IFYSBQE5.cjs.map} +1 -1
  49. package/dist/lib/node/{chunk-UEXGNGSS.cjs → chunk-RQS4KBMG.cjs} +45 -39
  50. package/dist/lib/node/chunk-RQS4KBMG.cjs.map +7 -0
  51. package/dist/lib/node/{chunk-H5MYVP6F.cjs → chunk-ZDTL47I7.cjs} +9 -8
  52. package/dist/lib/node/chunk-ZDTL47I7.cjs.map +7 -0
  53. package/dist/lib/node/index.cjs +43 -28
  54. package/dist/lib/node/index.cjs.map +3 -3
  55. package/dist/lib/node/intent-resolver-AUZVK3NZ.cjs +78 -0
  56. package/dist/lib/node/intent-resolver-AUZVK3NZ.cjs.map +7 -0
  57. package/dist/lib/node/meta.json +1 -1
  58. package/dist/lib/node/react-surface-WJZTEBYO.cjs +213 -0
  59. package/dist/lib/node/react-surface-WJZTEBYO.cjs.map +7 -0
  60. package/dist/lib/node/{settings-S2ISUVIH.cjs → settings-IRKU3WPM.cjs} +7 -7
  61. package/dist/lib/node/settings-IRKU3WPM.cjs.map +7 -0
  62. package/dist/lib/node/{state-L44SG3ZM.cjs → state-KKDRAG7X.cjs} +7 -7
  63. package/dist/lib/node/state-KKDRAG7X.cjs.map +7 -0
  64. package/dist/lib/node/types/index.cjs +8 -6
  65. package/dist/lib/node/types/index.cjs.map +2 -2
  66. package/dist/lib/node-esm/MarkdownContainer-UZSLXMWO.mjs +589 -0
  67. package/dist/lib/node-esm/MarkdownContainer-UZSLXMWO.mjs.map +7 -0
  68. package/dist/lib/node-esm/MarkdownPreview-TCV7BI32.mjs +88 -0
  69. package/dist/lib/node-esm/MarkdownPreview-TCV7BI32.mjs.map +7 -0
  70. package/dist/lib/node-esm/anchor-sort-G2HLCYFK.mjs +33 -0
  71. package/dist/lib/node-esm/anchor-sort-G2HLCYFK.mjs.map +7 -0
  72. package/dist/lib/node-esm/{app-graph-serializer-QQ2CTHOQ.mjs → app-graph-serializer-C3RNTQGM.mjs} +5 -6
  73. package/dist/lib/node-esm/app-graph-serializer-C3RNTQGM.mjs.map +7 -0
  74. package/dist/lib/node-esm/{artifact-definition-WRG5ZRN5.mjs → artifact-definition-7TIJW2CO.mjs} +65 -17
  75. package/dist/lib/node-esm/artifact-definition-7TIJW2CO.mjs.map +7 -0
  76. package/dist/lib/node-esm/{chunk-F6UHVLH7.mjs → chunk-6RPARLIK.mjs} +12 -26
  77. package/dist/lib/node-esm/chunk-6RPARLIK.mjs.map +7 -0
  78. package/dist/lib/node-esm/chunk-EIUTPXGL.mjs +22 -0
  79. package/dist/lib/node-esm/chunk-EIUTPXGL.mjs.map +7 -0
  80. package/dist/lib/node-esm/{chunk-ETXPC5VP.mjs → chunk-JXXDCSMW.mjs} +2 -2
  81. package/dist/lib/{browser/chunk-NAGMSX77.mjs.map → node-esm/chunk-JXXDCSMW.mjs.map} +1 -1
  82. package/dist/lib/node-esm/chunk-NCMPVEXO.mjs +81 -0
  83. package/dist/lib/node-esm/chunk-NCMPVEXO.mjs.map +7 -0
  84. package/dist/lib/node-esm/{chunk-JAVD67QP.mjs → chunk-TCFJNUAE.mjs} +6 -5
  85. package/dist/lib/node-esm/chunk-TCFJNUAE.mjs.map +7 -0
  86. package/dist/lib/node-esm/index.mjs +34 -18
  87. package/dist/lib/node-esm/index.mjs.map +3 -3
  88. package/dist/lib/node-esm/intent-resolver-FTNXUNI2.mjs +66 -0
  89. package/dist/lib/node-esm/intent-resolver-FTNXUNI2.mjs.map +7 -0
  90. package/dist/lib/node-esm/meta.json +1 -1
  91. package/dist/lib/node-esm/react-surface-XNM3YDFB.mjs +201 -0
  92. package/dist/lib/node-esm/react-surface-XNM3YDFB.mjs.map +7 -0
  93. package/dist/lib/node-esm/{settings-ZDIFTK4N.mjs → settings-MK7D7LHQ.mjs} +4 -4
  94. package/dist/lib/node-esm/settings-MK7D7LHQ.mjs.map +7 -0
  95. package/dist/lib/node-esm/{state-DWPOKLEY.mjs → state-LLGVRYKL.mjs} +3 -3
  96. package/dist/lib/node-esm/state-LLGVRYKL.mjs.map +7 -0
  97. package/dist/lib/node-esm/types/index.mjs +3 -1
  98. package/dist/types/src/MarkdownPlugin.d.ts.map +1 -1
  99. package/dist/types/src/capabilities/anchor-sort.d.ts +6 -0
  100. package/dist/types/src/capabilities/anchor-sort.d.ts.map +1 -0
  101. package/dist/types/src/capabilities/app-graph-serializer.d.ts +2 -2
  102. package/dist/types/src/capabilities/app-graph-serializer.d.ts.map +1 -1
  103. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  104. package/dist/types/src/capabilities/index.d.ts +7 -7
  105. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  106. package/dist/types/src/capabilities/intent-resolver.d.ts +2 -2
  107. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  108. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  109. package/dist/types/src/capabilities/state.d.ts +2 -2
  110. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  111. package/dist/types/src/components/MarkdownContainer.d.ts +5 -3
  112. package/dist/types/src/components/MarkdownContainer.d.ts.map +1 -1
  113. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.d.ts +24 -0
  114. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.d.ts.map +1 -0
  115. package/dist/types/src/components/{MarkdownEditor.stories.d.ts → MarkdownEditor/MarkdownEditor.stories.d.ts} +3 -3
  116. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.stories.d.ts.map +1 -0
  117. package/dist/types/src/components/MarkdownEditor/index.d.ts +2 -0
  118. package/dist/types/src/components/MarkdownEditor/index.d.ts.map +1 -0
  119. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.d.ts +6 -0
  120. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.d.ts.map +1 -0
  121. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts +23 -0
  122. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts.map +1 -0
  123. package/dist/types/src/components/MarkdownPreview/index.d.ts +4 -0
  124. package/dist/types/src/components/MarkdownPreview/index.d.ts.map +1 -0
  125. package/dist/types/src/components/{MarkdownSettings.d.ts → MarkdownSettings/MarkdownSettings.d.ts} +1 -1
  126. package/dist/types/src/components/MarkdownSettings/MarkdownSettings.d.ts.map +1 -0
  127. package/dist/types/src/components/MarkdownSettings/index.d.ts +2 -0
  128. package/dist/types/src/components/MarkdownSettings/index.d.ts.map +1 -0
  129. package/dist/types/src/components/Suggestions.stories.d.ts +12 -0
  130. package/dist/types/src/components/Suggestions.stories.d.ts.map +1 -0
  131. package/dist/types/src/components/Toolbar.stories.d.ts +2 -2
  132. package/dist/types/src/components/Toolbar.stories.d.ts.map +1 -1
  133. package/dist/types/src/components/index.d.ts +2 -1
  134. package/dist/types/src/components/index.d.ts.map +1 -1
  135. package/dist/types/src/extensions.d.ts +8 -5
  136. package/dist/types/src/extensions.d.ts.map +1 -1
  137. package/dist/types/src/hooks/useSelectCurrentThread.d.ts.map +1 -1
  138. package/dist/types/src/translations.d.ts +4 -42
  139. package/dist/types/src/translations.d.ts.map +1 -1
  140. package/dist/types/src/types/schema.d.ts +29 -129
  141. package/dist/types/src/types/schema.d.ts.map +1 -1
  142. package/dist/types/src/types/types.d.ts +40 -88
  143. package/dist/types/src/types/types.d.ts.map +1 -1
  144. package/dist/types/src/util.d.ts +1 -0
  145. package/dist/types/src/util.d.ts.map +1 -1
  146. package/dist/types/tsconfig.tsbuildinfo +1 -1
  147. package/package.json +48 -34
  148. package/src/MarkdownPlugin.tsx +22 -12
  149. package/src/capabilities/anchor-sort.ts +30 -0
  150. package/src/capabilities/app-graph-serializer.ts +4 -5
  151. package/src/capabilities/artifact-definition.ts +48 -10
  152. package/src/capabilities/index.ts +1 -1
  153. package/src/capabilities/intent-resolver.ts +40 -12
  154. package/src/capabilities/react-surface.tsx +20 -5
  155. package/src/capabilities/settings.ts +2 -2
  156. package/src/capabilities/state.ts +4 -4
  157. package/src/components/MarkdownContainer.tsx +20 -7
  158. package/src/components/{MarkdownEditor.stories.tsx → MarkdownEditor/MarkdownEditor.stories.tsx} +22 -35
  159. package/src/components/{MarkdownEditor.tsx → MarkdownEditor/MarkdownEditor.tsx} +32 -73
  160. package/src/components/MarkdownEditor/index.ts +5 -0
  161. package/src/components/MarkdownPreview/MarkdownPreview.stories.tsx +73 -0
  162. package/src/components/MarkdownPreview/MarkdownPreview.tsx +85 -0
  163. package/src/components/MarkdownPreview/index.ts +9 -0
  164. package/src/components/{MarkdownSettings.tsx → MarkdownSettings/MarkdownSettings.tsx} +2 -2
  165. package/src/components/MarkdownSettings/index.ts +5 -0
  166. package/src/components/Suggestions.stories.tsx +216 -0
  167. package/src/components/Toolbar.stories.tsx +29 -29
  168. package/src/components/index.ts +1 -0
  169. package/src/extensions.tsx +82 -48
  170. package/src/hooks/useSelectCurrentThread.tsx +2 -2
  171. package/src/translations.ts +3 -3
  172. package/src/types/schema.ts +22 -15
  173. package/src/types/types.ts +23 -21
  174. package/src/util.tsx +8 -4
  175. package/dist/lib/browser/MarkdownContainer-T3HU27RE.mjs +0 -563
  176. package/dist/lib/browser/MarkdownContainer-T3HU27RE.mjs.map +0 -7
  177. package/dist/lib/browser/app-graph-serializer-NOXI4IQ5.mjs.map +0 -7
  178. package/dist/lib/browser/artifact-definition-CE6J6NY4.mjs.map +0 -7
  179. package/dist/lib/browser/chunk-3ULJ4FIJ.mjs.map +0 -7
  180. package/dist/lib/browser/chunk-QXDKFACU.mjs.map +0 -7
  181. package/dist/lib/browser/chunk-YCJNW2RU.mjs +0 -75
  182. package/dist/lib/browser/chunk-YCJNW2RU.mjs.map +0 -7
  183. package/dist/lib/browser/intent-resolver-42GQ6HNZ.mjs +0 -50
  184. package/dist/lib/browser/intent-resolver-42GQ6HNZ.mjs.map +0 -7
  185. package/dist/lib/browser/react-surface-RQX3CPFV.mjs +0 -176
  186. package/dist/lib/browser/react-surface-RQX3CPFV.mjs.map +0 -7
  187. package/dist/lib/browser/settings-GCSS3Y4Z.mjs.map +0 -7
  188. package/dist/lib/browser/state-O7P5JDIH.mjs.map +0 -7
  189. package/dist/lib/browser/thread-3QGCFNVZ.mjs +0 -37
  190. package/dist/lib/browser/thread-3QGCFNVZ.mjs.map +0 -7
  191. package/dist/lib/node/MarkdownContainer-6ZJIFAP6.cjs +0 -576
  192. package/dist/lib/node/MarkdownContainer-6ZJIFAP6.cjs.map +0 -7
  193. package/dist/lib/node/app-graph-serializer-HKK3SEDN.cjs.map +0 -7
  194. package/dist/lib/node/artifact-definition-XGADFWCQ.cjs.map +0 -7
  195. package/dist/lib/node/chunk-7QVONRSI.cjs.map +0 -7
  196. package/dist/lib/node/chunk-H5MYVP6F.cjs.map +0 -7
  197. package/dist/lib/node/chunk-UEXGNGSS.cjs.map +0 -7
  198. package/dist/lib/node/intent-resolver-NW27BF3W.cjs +0 -63
  199. package/dist/lib/node/intent-resolver-NW27BF3W.cjs.map +0 -7
  200. package/dist/lib/node/react-surface-5X3SMHGI.cjs +0 -189
  201. package/dist/lib/node/react-surface-5X3SMHGI.cjs.map +0 -7
  202. package/dist/lib/node/settings-S2ISUVIH.cjs.map +0 -7
  203. package/dist/lib/node/state-L44SG3ZM.cjs.map +0 -7
  204. package/dist/lib/node/thread-42R57L4K.cjs.map +0 -7
  205. package/dist/lib/node-esm/MarkdownContainer-URAPTO37.mjs +0 -564
  206. package/dist/lib/node-esm/MarkdownContainer-URAPTO37.mjs.map +0 -7
  207. package/dist/lib/node-esm/app-graph-serializer-QQ2CTHOQ.mjs.map +0 -7
  208. package/dist/lib/node-esm/artifact-definition-WRG5ZRN5.mjs.map +0 -7
  209. package/dist/lib/node-esm/chunk-4AM4VU3Y.mjs +0 -76
  210. package/dist/lib/node-esm/chunk-4AM4VU3Y.mjs.map +0 -7
  211. package/dist/lib/node-esm/chunk-F6UHVLH7.mjs.map +0 -7
  212. package/dist/lib/node-esm/chunk-JAVD67QP.mjs.map +0 -7
  213. package/dist/lib/node-esm/intent-resolver-7HOMUVHR.mjs +0 -51
  214. package/dist/lib/node-esm/intent-resolver-7HOMUVHR.mjs.map +0 -7
  215. package/dist/lib/node-esm/react-surface-6IKC3G46.mjs +0 -177
  216. package/dist/lib/node-esm/react-surface-6IKC3G46.mjs.map +0 -7
  217. package/dist/lib/node-esm/settings-ZDIFTK4N.mjs.map +0 -7
  218. package/dist/lib/node-esm/state-DWPOKLEY.mjs.map +0 -7
  219. package/dist/lib/node-esm/thread-R2KHZD6V.mjs +0 -38
  220. package/dist/lib/node-esm/thread-R2KHZD6V.mjs.map +0 -7
  221. package/dist/types/src/capabilities/thread.d.ts +0 -6
  222. package/dist/types/src/capabilities/thread.d.ts.map +0 -1
  223. package/dist/types/src/components/MarkdownEditor.d.ts +0 -39
  224. package/dist/types/src/components/MarkdownEditor.d.ts.map +0 -1
  225. package/dist/types/src/components/MarkdownEditor.stories.d.ts.map +0 -1
  226. package/dist/types/src/components/MarkdownSettings.d.ts.map +0 -1
  227. package/src/capabilities/thread.ts +0 -35
@@ -2,14 +2,19 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, contributes, type PromiseIntentDispatcher } from '@dxos/app-framework';
6
- import { ArtifactId, defineArtifact, defineTool, ToolResult } from '@dxos/artifact';
7
- import { isInstanceOf, S } from '@dxos/echo-schema';
5
+ import { pipe, Schema } from 'effect';
6
+
7
+ import { createTool, ToolResult } from '@dxos/ai';
8
+ import { Capabilities, chain, contributes, createIntent, type PromiseIntentDispatcher } from '@dxos/app-framework';
9
+ import { ArtifactId, defineArtifact } from '@dxos/artifact';
10
+ import { createArtifactElement } from '@dxos/assistant';
11
+ import { isInstanceOf } from '@dxos/echo-schema';
8
12
  import { invariant, assertArgument } from '@dxos/invariant';
13
+ import { SpaceAction } from '@dxos/plugin-space/types';
9
14
  import { Filter, fullyQualifiedId, type Space } from '@dxos/react-client/echo';
10
15
 
11
16
  import { meta } from '../meta';
12
- import { DocumentType } from '../types';
17
+ import { DocumentType, MarkdownAction } from '../types';
13
18
 
14
19
  // TODO(burdon): Factor out.
15
20
  declare global {
@@ -30,15 +35,48 @@ export default () => {
30
35
  `,
31
36
  schema: DocumentType,
32
37
  tools: [
33
- defineTool(meta.id, {
38
+ createTool(meta.id, {
39
+ name: 'create',
40
+ description: 'Create a new markdown document',
41
+ caption: 'Creating document...',
42
+ schema: Schema.Struct({
43
+ name: Schema.optional(Schema.String).annotations({
44
+ description: 'Optional name for the document.',
45
+ }),
46
+ content: Schema.String.annotations({
47
+ description: 'The content of the document.',
48
+ }),
49
+ }),
50
+ execute: async ({ name, content }, { extensions }) => {
51
+ invariant(extensions?.space, 'No space');
52
+ invariant(extensions?.dispatch, 'No intent dispatcher');
53
+
54
+ const intent = pipe(
55
+ createIntent(MarkdownAction.Create, {
56
+ spaceId: extensions.space.id,
57
+ name,
58
+ content,
59
+ }),
60
+ chain(SpaceAction.AddObject, { target: extensions.space }),
61
+ );
62
+
63
+ const { data, error } = await extensions.dispatch(intent);
64
+ if (!data || error) {
65
+ return ToolResult.Error(error?.message ?? 'Failed to create document');
66
+ }
67
+
68
+ return ToolResult.Success(createArtifactElement(data.id));
69
+ },
70
+ }),
71
+ createTool(meta.id, {
34
72
  name: 'list',
35
73
  description: 'List all markdown documents in the current space.',
36
74
  caption: 'Listing markdown documents...',
37
- schema: S.Struct({}),
75
+ schema: Schema.Struct({}),
38
76
  execute: async (_input, { extensions }) => {
39
77
  invariant(extensions?.space, 'No space');
40
78
  const space = extensions.space;
41
- const { objects: documents } = await space.db.query(Filter.schema(DocumentType)).run();
79
+ const { objects: documents } = await space.db.query(Filter.type(DocumentType)).run();
42
80
  const documentInfo = documents.map((doc) => {
43
81
  invariant(isInstanceOf(DocumentType, doc));
44
82
  return {
@@ -51,16 +89,16 @@ export default () => {
51
89
  return ToolResult.Success(documentInfo);
52
90
  },
53
91
  }),
54
- defineTool(meta.id, {
92
+ createTool(meta.id, {
55
93
  name: 'inspect',
56
94
  description: 'Read the content of a markdown document.',
57
95
  caption: 'Inspecting markdown document...',
58
- schema: S.Struct({
96
+ schema: Schema.Struct({
59
97
  id: ArtifactId,
60
98
  }),
61
99
  execute: async ({ id }, { extensions }) => {
62
100
  invariant(extensions?.space, 'No space');
63
- const document = await extensions.space.db.query({ id: ArtifactId.toDXN(id).toString() }).first();
101
+ const document = await extensions.space.db.query(Filter.ids(ArtifactId.toDXN(id).toString())).first();
64
102
  assertArgument(isInstanceOf(DocumentType, document), 'Invalid type');
65
103
 
66
104
  const { content } = await document.content?.load();
@@ -4,12 +4,12 @@
4
4
 
5
5
  import { lazy } from '@dxos/app-framework';
6
6
 
7
+ export const AnchorSort = lazy(() => import('./anchor-sort'));
7
8
  export const AppGraphSerializer = lazy(() => import('./app-graph-serializer'));
8
9
  export const ArtifactDefinition = lazy(() => import('./artifact-definition'));
9
10
  export const IntentResolver = lazy(() => import('./intent-resolver'));
10
11
  export const ReactSurface = lazy(() => import('./react-surface'));
11
12
  export const MarkdownSettings = lazy(() => import('./settings'));
12
13
  export const MarkdownState = lazy(() => import('./state'));
13
- export const Thread = lazy(() => import('./thread'));
14
14
 
15
15
  export * from './capabilities';
@@ -2,25 +2,32 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, contributes, createResolver, type PluginsContext } from '@dxos/app-framework';
6
- import { ObjectId } from '@dxos/echo-schema';
7
- import { DXN, QueueSubspaceTags } from '@dxos/keys';
8
- import { makeRef, create, refFromDXN } from '@dxos/live-object';
9
- import { TextType } from '@dxos/schema';
5
+ import { next as A } from '@automerge/automerge';
6
+ import { Option, pipe, type Schema } from 'effect';
7
+
8
+ import {
9
+ Capabilities,
10
+ CollaborationActions,
11
+ contributes,
12
+ createResolver,
13
+ type PluginContext,
14
+ } from '@dxos/app-framework';
15
+ import { isInstanceOf } from '@dxos/echo-schema';
16
+ import { live } from '@dxos/live-object';
17
+ import { createDocAccessor, getRangeFromCursor, Ref } from '@dxos/react-client/echo';
18
+ import { DataType } from '@dxos/schema';
10
19
 
11
20
  import { MarkdownCapabilities } from './capabilities';
12
21
  import { DocumentType, MarkdownAction } from '../types';
13
22
 
14
- export default (context: PluginsContext) =>
23
+ export default (context: PluginContext) =>
15
24
  contributes(Capabilities.IntentResolver, [
16
25
  createResolver({
17
26
  intent: MarkdownAction.Create,
18
- resolve: ({ name, spaceId, content }) => {
19
- const doc = create(DocumentType, {
27
+ resolve: ({ name, content }) => {
28
+ const doc = live(DocumentType, {
20
29
  name,
21
- content: makeRef(create(TextType, { content: content ?? '' })),
22
- assistantChatQueue: refFromDXN(new DXN(DXN.kind.QUEUE, [QueueSubspaceTags.DATA, spaceId, ObjectId.random()])),
23
- threads: [],
30
+ content: Ref.make(live(DataType.Text, { content: content ?? '' })),
24
31
  });
25
32
 
26
33
  return { data: { object: doc } };
@@ -29,8 +36,29 @@ export default (context: PluginsContext) =>
29
36
  createResolver({
30
37
  intent: MarkdownAction.SetViewMode,
31
38
  resolve: ({ id, viewMode }) => {
32
- const { state } = context.requestCapability(MarkdownCapabilities.State);
39
+ const { state } = context.getCapability(MarkdownCapabilities.State);
33
40
  state.viewMode[id] = viewMode;
34
41
  },
35
42
  }),
43
+ createResolver({
44
+ intent: CollaborationActions.InsertContent,
45
+ filter: (
46
+ data,
47
+ ): data is Omit<Schema.Schema.Type<typeof CollaborationActions.InsertContent.fields.input>, 'target'> & {
48
+ target: DocumentType;
49
+ } => isInstanceOf(DocumentType, data.target),
50
+ resolve: async ({ target, object: objectRef, at, label }) => {
51
+ const text = await target.content.load();
52
+ const accessor = createDocAccessor(text, ['content']);
53
+ const { start, end } = pipe(
54
+ Option.fromNullable(at),
55
+ Option.flatMap((at) => Option.fromNullable(getRangeFromCursor(accessor, at))),
56
+ Option.getOrElse(() => ({ start: text.content.length - 1, end: text.content.length - 1 })),
57
+ );
58
+ accessor.handle.change((doc) => {
59
+ const ref = `[${label ?? 'Generated content'}]](${objectRef.dxn.toString()})\n`;
60
+ A.splice(doc, accessor.path.slice(), start, end - start, ref);
61
+ });
62
+ },
63
+ }),
36
64
  ]);
@@ -7,11 +7,12 @@ import React from 'react';
7
7
  import { createSurface, contributes, Capabilities, useCapability } from '@dxos/app-framework';
8
8
  import { isInstanceOf } from '@dxos/echo-schema';
9
9
  import { SettingsStore } from '@dxos/local-storage';
10
+ import { AttentionCapabilities } from '@dxos/plugin-attention';
10
11
  import { fullyQualifiedId } from '@dxos/react-client/echo';
11
- import { TextType } from '@dxos/schema';
12
+ import { DataType } from '@dxos/schema';
12
13
 
13
14
  import { MarkdownCapabilities } from './capabilities';
14
- import { MarkdownContainer, MarkdownSettings } from '../components';
15
+ import { MarkdownContainer, MarkdownSettings, MarkdownPreview } from '../components';
15
16
  import { MARKDOWN_PLUGIN } from '../meta';
16
17
  import { DocumentType, isEditorModel, type MarkdownSettingsProps } from '../types';
17
18
 
@@ -23,9 +24,11 @@ export default () =>
23
24
  filter: (data): data is { subject: DocumentType; variant: undefined } =>
24
25
  isInstanceOf(DocumentType, data.subject) && !data.variant,
25
26
  component: ({ data, role }) => {
27
+ const selectionManager = useCapability(AttentionCapabilities.Selection);
26
28
  const settingsStore = useCapability(Capabilities.SettingsStore);
27
29
  const settings = settingsStore.getStore<MarkdownSettingsProps>(MARKDOWN_PLUGIN)!.value;
28
30
  const { state, editorState, getViewMode, setViewMode } = useCapability(MarkdownCapabilities.State);
31
+ const viewMode = getViewMode(fullyQualifiedId(data.subject));
29
32
 
30
33
  return (
31
34
  <MarkdownContainer
@@ -33,8 +36,9 @@ export default () =>
33
36
  object={data.subject}
34
37
  role={role}
35
38
  settings={settings}
39
+ selectionManager={selectionManager}
36
40
  extensionProviders={state.extensionProviders}
37
- viewMode={getViewMode(fullyQualifiedId(data.subject))}
41
+ viewMode={viewMode}
38
42
  editorStateStore={editorState}
39
43
  onViewModeChange={setViewMode}
40
44
  />
@@ -44,9 +48,10 @@ export default () =>
44
48
  createSurface({
45
49
  id: `${MARKDOWN_PLUGIN}/text`,
46
50
  role: ['article', 'section', 'tabpanel'],
47
- filter: (data): data is { id: string; subject: TextType } =>
48
- typeof data.id === 'string' && isInstanceOf(TextType, data.subject),
51
+ filter: (data): data is { id: string; subject: DataType.Text } =>
52
+ typeof data.id === 'string' && isInstanceOf(DataType.Text, data.subject),
49
53
  component: ({ data, role }) => {
54
+ const selectionManager = useCapability(AttentionCapabilities.Selection);
50
55
  const settingsStore = useCapability(Capabilities.SettingsStore);
51
56
  const settings = settingsStore.getStore<MarkdownSettingsProps>(MARKDOWN_PLUGIN)!.value;
52
57
  const { state, editorState, getViewMode, setViewMode } = useCapability(MarkdownCapabilities.State);
@@ -57,6 +62,7 @@ export default () =>
57
62
  object={data.subject}
58
63
  role={role}
59
64
  settings={settings}
65
+ selectionManager={selectionManager}
60
66
  extensionProviders={state.extensionProviders}
61
67
  viewMode={getViewMode(data.id)}
62
68
  editorStateStore={editorState}
@@ -70,6 +76,7 @@ export default () =>
70
76
  role: ['article', 'section'],
71
77
  filter: (data): data is { subject: { id: string; text: string } } => isEditorModel(data.subject),
72
78
  component: ({ data, role }) => {
79
+ const selectionManager = useCapability(AttentionCapabilities.Selection);
73
80
  const settingsStore = useCapability(Capabilities.SettingsStore);
74
81
  const settings = settingsStore.getStore<MarkdownSettingsProps>(MARKDOWN_PLUGIN)!.value;
75
82
  const { state, editorState, getViewMode, setViewMode } = useCapability(MarkdownCapabilities.State);
@@ -80,6 +87,7 @@ export default () =>
80
87
  object={data.subject}
81
88
  role={role}
82
89
  settings={settings}
90
+ selectionManager={selectionManager}
83
91
  extensionProviders={state.extensionProviders}
84
92
  viewMode={getViewMode(data.subject.id)}
85
93
  editorStateStore={editorState}
@@ -95,4 +103,11 @@ export default () =>
95
103
  data.subject instanceof SettingsStore && data.subject.prefix === MARKDOWN_PLUGIN,
96
104
  component: ({ data: { subject } }) => <MarkdownSettings settings={subject.value} />,
97
105
  }),
106
+ createSurface({
107
+ id: `${MARKDOWN_PLUGIN}/preview`,
108
+ role: 'popover',
109
+ filter: (data): data is { subject: DocumentType | DataType.Text } =>
110
+ isInstanceOf(DocumentType, data.subject) || isInstanceOf(DataType.Text, data.subject),
111
+ component: ({ data, role }) => <MarkdownPreview {...data} role={role} />,
112
+ }),
98
113
  ]);
@@ -3,13 +3,13 @@
3
3
  //
4
4
 
5
5
  import { Capabilities, contributes } from '@dxos/app-framework';
6
- import { create } from '@dxos/live-object';
6
+ import { live } from '@dxos/live-object';
7
7
 
8
8
  import { MARKDOWN_PLUGIN } from '../meta';
9
9
  import { type MarkdownSettingsProps, MarkdownSettingsSchema } from '../types';
10
10
 
11
11
  export default () => {
12
- const settings = create<MarkdownSettingsProps>({
12
+ const settings = live<MarkdownSettingsProps>({
13
13
  defaultViewMode: 'preview',
14
14
  toolbar: true,
15
15
  numberedHeadings: true,
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, contributes, type PluginsContext } from '@dxos/app-framework';
5
+ import { Capabilities, contributes, type PluginContext } from '@dxos/app-framework';
6
6
  import { LocalStorageStore } from '@dxos/local-storage';
7
7
  import { type EditorViewMode, createEditorStateStore } from '@dxos/react-ui-editor';
8
8
 
@@ -10,9 +10,8 @@ import { MarkdownCapabilities } from './capabilities';
10
10
  import { MARKDOWN_PLUGIN } from '../meta';
11
11
  import { type MarkdownPluginState, type MarkdownSettingsProps } from '../types';
12
12
 
13
- export default (context: PluginsContext) => {
13
+ export default (context: PluginContext) => {
14
14
  const state = new LocalStorageStore<MarkdownPluginState>(MARKDOWN_PLUGIN, { extensionProviders: [], viewMode: {} });
15
-
16
15
  state.prop({ key: 'viewMode', type: LocalStorageStore.json<{ [key: string]: EditorViewMode }>() });
17
16
 
18
17
  // TODO(wittjosiah): Fold into state.
@@ -20,12 +19,13 @@ export default (context: PluginsContext) => {
20
19
 
21
20
  const getViewMode = (id: string) => {
22
21
  const defaultViewMode = context
23
- .requestCapability(Capabilities.SettingsStore)
22
+ .getCapability(Capabilities.SettingsStore)
24
23
  .getStore<MarkdownSettingsProps>(MARKDOWN_PLUGIN)!.value.defaultViewMode;
25
24
  return (id && state.values.viewMode[id]) || defaultViewMode;
26
25
  };
27
26
 
28
27
  const setViewMode = (id: string, viewMode: EditorViewMode) => (state.values.viewMode[id] = viewMode);
29
28
 
29
+ // Return object with methods.
30
30
  return contributes(MarkdownCapabilities.State, { state: state.values, editorState, getViewMode, setViewMode });
31
31
  };
@@ -2,12 +2,14 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { Rx } from '@effect-rx/rx-react';
5
6
  import React, { useEffect, useMemo } from 'react';
6
7
 
7
- import { Capabilities, useCapabilities } from '@dxos/app-framework';
8
+ import { Capabilities, useAppGraph, useCapabilities } from '@dxos/app-framework';
8
9
  import { isInstanceOf } from '@dxos/echo-schema';
9
10
  import { fullyQualifiedId, getSpace } from '@dxos/react-client/echo';
10
- import { TextType } from '@dxos/schema';
11
+ import { type SelectionManager } from '@dxos/react-ui-attention';
12
+ import { DataType } from '@dxos/schema';
11
13
 
12
14
  import { MarkdownEditor, type MarkdownEditorProps } from './MarkdownEditor';
13
15
  import { useExtensions } from '../extensions';
@@ -19,25 +21,26 @@ export type MarkdownContainerProps = Pick<
19
21
  'role' | 'extensionProviders' | 'viewMode' | 'editorStateStore' | 'onViewModeChange'
20
22
  > & {
21
23
  id: string;
22
- object: DocumentType | TextType | any;
24
+ object: DocumentType | DataType.Text | any;
23
25
  settings: MarkdownSettingsProps;
26
+ selectionManager?: SelectionManager;
24
27
  };
25
28
 
26
- // TODO(burdon): Move toolbar here.
27
29
  // TODO(burdon): Factor out difference for ECHO and non-ECHO objects; i.e., single component.
28
30
  const MarkdownContainer = ({
29
31
  id,
30
32
  role,
31
33
  object,
32
34
  settings,
35
+ selectionManager,
33
36
  viewMode,
34
37
  editorStateStore,
35
38
  onViewModeChange,
36
39
  }: MarkdownContainerProps) => {
37
40
  const scrollPastEnd = role === 'article';
38
41
  const doc = isInstanceOf(DocumentType, object) ? object : undefined;
39
- const text = isInstanceOf(TextType, object) ? object : undefined;
40
- const extensions = useExtensions({ document: doc, text, id, settings, viewMode, editorStateStore });
42
+ const text = isInstanceOf(DataType.Text, object) ? object : undefined;
43
+ const extensions = useExtensions({ document: doc, text, id, settings, selectionManager, viewMode, editorStateStore });
41
44
 
42
45
  if (doc) {
43
46
  return (
@@ -61,13 +64,13 @@ const MarkdownContainer = ({
61
64
  extensions={extensions}
62
65
  viewMode={viewMode}
63
66
  toolbar={settings.toolbar}
64
- comment={false}
65
67
  inputMode={settings.editorInputMode}
66
68
  scrollPastEnd={scrollPastEnd}
67
69
  onViewModeChange={onViewModeChange}
68
70
  />
69
71
  );
70
72
  } else {
73
+ // TODO(burdon): Normalize with above.
71
74
  return (
72
75
  <MarkdownEditor
73
76
  id={id}
@@ -115,12 +118,22 @@ export const DocumentEditor = ({ id, document: doc, settings, viewMode, ...props
115
118
  return async (file: File) => upload!(file, space);
116
119
  }, [space, upload]);
117
120
 
121
+ const { graph } = useAppGraph();
122
+ const customActions = useMemo(() => {
123
+ return Rx.make((get) => {
124
+ const actions = get(graph.actions(id));
125
+ const nodes = actions.filter((action) => action.properties.disposition === 'toolbar');
126
+ return { nodes, edges: nodes.map((node) => ({ source: 'root', target: node.id })) };
127
+ });
128
+ }, [graph]);
129
+
118
130
  return (
119
131
  <MarkdownEditor
120
132
  id={id}
121
133
  initialValue={doc.content?.target?.content}
122
134
  viewMode={viewMode}
123
135
  toolbar={settings.toolbar}
136
+ customActions={customActions}
124
137
  inputMode={settings.editorInputMode}
125
138
  onFileUpload={handleFileUpload}
126
139
  {...props}
@@ -10,19 +10,14 @@ import React, { useMemo } from 'react';
10
10
  import { IntentPlugin } from '@dxos/app-framework';
11
11
  import { withPluginManager } from '@dxos/app-framework/testing';
12
12
  import { createDocAccessor, createObject } from '@dxos/react-client/echo';
13
- import { Main } from '@dxos/react-ui';
14
- import { AttendableContainer } from '@dxos/react-ui-attention';
15
13
  import { withAttention } from '@dxos/react-ui-attention/testing';
16
- import { editorWithToolbarLayout, automerge, translations as editorTranslations } from '@dxos/react-ui-editor';
17
- import { topbarBlockPaddingStart } from '@dxos/react-ui-theme';
14
+ import { automerge, translations as editorTranslations } from '@dxos/react-ui-editor';
18
15
  import { withLayout, withTheme } from '@dxos/storybook-utils';
19
16
 
20
17
  import { MarkdownEditor, type MarkdownEditorProps } from './MarkdownEditor';
21
- import translations from '../translations';
18
+ import translations from '../../translations';
22
19
 
23
- const content = Array.from({ length: 100 })
24
- .map((_, i) => `Line ${i + 1}`)
25
- .join('\n');
20
+ const content = Array.from({ length: 100 }, (_, i) => `Line ${i + 1}`).join('\n');
26
21
 
27
22
  type StoryProps = MarkdownEditorProps & {
28
23
  content?: string;
@@ -32,43 +27,35 @@ type StoryProps = MarkdownEditorProps & {
32
27
  const DefaultStory = ({ content = '# Test', toolbar }: StoryProps) => {
33
28
  const doc = useMemo(() => createObject({ content }), [content]);
34
29
  const extensions = useMemo(() => [automerge(createDocAccessor(doc, ['content']))], [doc]);
35
- return (
36
- <Main.Content
37
- bounce
38
- data-toolbar={toolbar ? 'enabled' : 'disabled'}
39
- classNames={[topbarBlockPaddingStart, editorWithToolbarLayout]}
40
- >
41
- <AttendableContainer id='test'>
42
- <MarkdownEditor id='test' initialValue={doc.content} extensions={extensions} toolbar={toolbar} />
43
- </AttendableContainer>
44
- </Main.Content>
45
- );
46
- };
47
-
48
- export const Default = {
49
- args: {
50
- content,
51
- },
52
- };
53
-
54
- export const WithToolbar = {
55
- args: {
56
- content,
57
- toolbar: true,
58
- },
30
+ return <MarkdownEditor id='test' initialValue={doc.content} extensions={extensions} toolbar={toolbar} />;
59
31
  };
60
32
 
61
33
  const meta: Meta<typeof MarkdownEditor> = {
62
- title: 'plugins/plugin-markdown/EditorMain',
34
+ title: 'plugins/plugin-markdown/MarkdownEditor',
63
35
  component: MarkdownEditor,
64
36
  render: DefaultStory,
65
37
  decorators: [
66
38
  withTheme,
67
- withLayout({ tooltips: true }),
39
+ withLayout({ fullscreen: true }),
68
40
  withAttention,
69
41
  withPluginManager({ plugins: [IntentPlugin()] }),
70
42
  ],
71
- parameters: { layout: 'fullscreen', translations: [...translations, ...editorTranslations] },
43
+ parameters: {
44
+ translations: [...translations, ...editorTranslations],
45
+ },
72
46
  };
73
47
 
74
48
  export default meta;
49
+
50
+ export const Default = {
51
+ args: {
52
+ content,
53
+ },
54
+ };
55
+
56
+ export const WithToolbar = {
57
+ args: {
58
+ toolbar: true,
59
+ content,
60
+ },
61
+ };