@dxos/plugin-script 0.8.4-main.5ea62a8 → 0.8.4-main.ae835ea

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 (275) hide show
  1. package/dist/lib/browser/DeploymentDialog-E5NXT4UQ.mjs +14 -0
  2. package/dist/lib/browser/NotebookContainer-C36N7AFF.mjs +817 -0
  3. package/dist/lib/browser/NotebookContainer-C36N7AFF.mjs.map +7 -0
  4. package/dist/lib/browser/ScriptContainer-4YPRUM3C.mjs +148 -0
  5. package/dist/lib/browser/ScriptContainer-4YPRUM3C.mjs.map +7 -0
  6. package/dist/lib/browser/{app-graph-builder-IABOSTBK.mjs → app-graph-builder-LEOPGBJD.mjs} +10 -8
  7. package/dist/lib/browser/app-graph-builder-LEOPGBJD.mjs.map +7 -0
  8. package/dist/lib/browser/{blueprint-definition-AR7ITBCD.mjs → blueprint-definition-6PZWZM2Y.mjs} +5 -3
  9. package/dist/lib/{node-esm/blueprint-definition-TJY4TX6S.mjs.map → browser/blueprint-definition-6PZWZM2Y.mjs.map} +1 -1
  10. package/dist/lib/browser/chunk-5S5YQNJZ.mjs +304 -0
  11. package/dist/lib/browser/chunk-5S5YQNJZ.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-6CAH7VIE.mjs → chunk-A5K3TXYA.mjs} +20 -34
  13. package/dist/lib/browser/chunk-A5K3TXYA.mjs.map +7 -0
  14. package/dist/lib/browser/{chunk-QYAREHGH.mjs → chunk-EB6AXFXO.mjs} +8 -5
  15. package/dist/lib/browser/chunk-EB6AXFXO.mjs.map +7 -0
  16. package/dist/lib/browser/chunk-HCURXADW.mjs +102 -0
  17. package/dist/lib/browser/chunk-HCURXADW.mjs.map +7 -0
  18. package/dist/lib/browser/{chunk-TH7GXPE3.mjs → chunk-HHTOAI2J.mjs} +126 -38
  19. package/dist/lib/browser/chunk-HHTOAI2J.mjs.map +7 -0
  20. package/dist/lib/browser/{chunk-YCZPTTFO.mjs → chunk-IQMYIWHG.mjs} +14 -14
  21. package/dist/lib/browser/chunk-IQMYIWHG.mjs.map +7 -0
  22. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  23. package/dist/lib/browser/chunk-LI4P25M5.mjs +111 -0
  24. package/dist/lib/browser/chunk-LI4P25M5.mjs.map +7 -0
  25. package/dist/lib/browser/{chunk-NXKU3BNX.mjs → chunk-Q2DGRQRN.mjs} +47 -14
  26. package/dist/lib/browser/chunk-Q2DGRQRN.mjs.map +7 -0
  27. package/dist/lib/browser/chunk-ST3ACVUC.mjs +88 -0
  28. package/dist/lib/browser/chunk-ST3ACVUC.mjs.map +7 -0
  29. package/dist/lib/browser/{chunk-5TVBECWH.mjs → chunk-UOQ6NCH3.mjs} +2 -2
  30. package/dist/lib/browser/{compiler-2HJH34GM.mjs → compiler-Q4UY2COU.mjs} +12 -24
  31. package/dist/lib/{node-esm/compiler-7SP27RA6.mjs.map → browser/compiler-Q4UY2COU.mjs.map} +2 -2
  32. package/dist/lib/browser/index.mjs +105 -41
  33. package/dist/lib/browser/index.mjs.map +3 -3
  34. package/dist/lib/browser/{intent-resolver-YMK5SXVC.mjs → intent-resolver-AMMHATM7.mjs} +39 -23
  35. package/dist/lib/browser/intent-resolver-AMMHATM7.mjs.map +7 -0
  36. package/dist/lib/browser/meta.json +1 -1
  37. package/dist/lib/browser/{react-surface-FEM5WWFH.mjs → react-surface-X4NATU6B.mjs} +43 -19
  38. package/dist/lib/browser/react-surface-X4NATU6B.mjs.map +7 -0
  39. package/dist/lib/browser/{settings-KCTBK5TY.mjs → settings-6UXY7F7D.mjs} +10 -8
  40. package/dist/lib/browser/settings-6UXY7F7D.mjs.map +7 -0
  41. package/dist/lib/browser/templates/index.mjs +2 -1
  42. package/dist/lib/browser/types/index.mjs +8 -4
  43. package/dist/lib/node-esm/DeploymentDialog-OSHHSEBH.mjs +15 -0
  44. package/dist/lib/node-esm/DeploymentDialog-OSHHSEBH.mjs.map +7 -0
  45. package/dist/lib/node-esm/NotebookContainer-FOVFGJQR.mjs +818 -0
  46. package/dist/lib/node-esm/NotebookContainer-FOVFGJQR.mjs.map +7 -0
  47. package/dist/lib/node-esm/ScriptContainer-EW24D5II.mjs +149 -0
  48. package/dist/lib/node-esm/ScriptContainer-EW24D5II.mjs.map +7 -0
  49. package/dist/lib/node-esm/{app-graph-builder-CQTTAYHP.mjs → app-graph-builder-XJ3MY5BM.mjs} +10 -8
  50. package/dist/lib/node-esm/app-graph-builder-XJ3MY5BM.mjs.map +7 -0
  51. package/dist/lib/node-esm/{blueprint-definition-TJY4TX6S.mjs → blueprint-definition-5R6YCSZZ.mjs} +4 -3
  52. package/dist/lib/{browser/blueprint-definition-AR7ITBCD.mjs.map → node-esm/blueprint-definition-5R6YCSZZ.mjs.map} +1 -1
  53. package/dist/lib/node-esm/chunk-2GVTWESW.mjs +90 -0
  54. package/dist/lib/node-esm/chunk-2GVTWESW.mjs.map +7 -0
  55. package/dist/lib/node-esm/{chunk-35M3CHYE.mjs → chunk-55JZVM6K.mjs} +2 -2
  56. package/dist/lib/node-esm/chunk-EJLYOSD7.mjs +113 -0
  57. package/dist/lib/node-esm/chunk-EJLYOSD7.mjs.map +7 -0
  58. package/dist/lib/node-esm/{chunk-2GBESIHU.mjs → chunk-GA27XSEY.mjs} +20 -34
  59. package/dist/lib/node-esm/chunk-GA27XSEY.mjs.map +7 -0
  60. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  61. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  62. package/dist/lib/node-esm/{chunk-AHXJ6NQU.mjs → chunk-IBV2DR36.mjs} +8 -5
  63. package/dist/lib/node-esm/chunk-IBV2DR36.mjs.map +7 -0
  64. package/dist/lib/node-esm/chunk-N2XLVOFB.mjs +103 -0
  65. package/dist/lib/node-esm/chunk-N2XLVOFB.mjs.map +7 -0
  66. package/dist/lib/node-esm/{chunk-M642JUOZ.mjs → chunk-O7HXE72S.mjs} +47 -14
  67. package/dist/lib/node-esm/chunk-O7HXE72S.mjs.map +7 -0
  68. package/dist/lib/node-esm/{chunk-6M2R2FQF.mjs → chunk-OZ6LCME4.mjs} +126 -38
  69. package/dist/lib/node-esm/chunk-OZ6LCME4.mjs.map +7 -0
  70. package/dist/lib/node-esm/chunk-TUGLYZDT.mjs +305 -0
  71. package/dist/lib/node-esm/chunk-TUGLYZDT.mjs.map +7 -0
  72. package/dist/lib/node-esm/{chunk-ZA36GO4T.mjs → chunk-UEGPBCSF.mjs} +14 -14
  73. package/dist/lib/node-esm/chunk-UEGPBCSF.mjs.map +7 -0
  74. package/dist/lib/node-esm/{compiler-7SP27RA6.mjs → compiler-I6A4KE6E.mjs} +12 -24
  75. package/dist/lib/{browser/compiler-2HJH34GM.mjs.map → node-esm/compiler-I6A4KE6E.mjs.map} +2 -2
  76. package/dist/lib/node-esm/index.mjs +105 -41
  77. package/dist/lib/node-esm/index.mjs.map +3 -3
  78. package/dist/lib/node-esm/{intent-resolver-SKRDYQCZ.mjs → intent-resolver-YKLZQR7U.mjs} +39 -23
  79. package/dist/lib/node-esm/intent-resolver-YKLZQR7U.mjs.map +7 -0
  80. package/dist/lib/node-esm/meta.json +1 -1
  81. package/dist/lib/node-esm/{react-surface-AOKMDJR4.mjs → react-surface-LVGLBSTE.mjs} +43 -19
  82. package/dist/lib/node-esm/react-surface-LVGLBSTE.mjs.map +7 -0
  83. package/dist/lib/node-esm/{settings-DXZ334A3.mjs → settings-O4EZPUE3.mjs} +10 -8
  84. package/dist/lib/node-esm/settings-O4EZPUE3.mjs.map +7 -0
  85. package/dist/lib/node-esm/templates/index.mjs +2 -1
  86. package/dist/lib/node-esm/types/index.mjs +8 -4
  87. package/dist/types/src/ScriptPlugin.d.ts +1 -1
  88. package/dist/types/src/ScriptPlugin.d.ts.map +1 -1
  89. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  90. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  91. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  92. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.d.ts +1 -1
  93. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.d.ts.map +1 -1
  94. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.stories.d.ts +110 -7
  95. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.stories.d.ts.map +1 -1
  96. package/dist/types/src/components/NotebookContainer.d.ts +10 -0
  97. package/dist/types/src/components/NotebookContainer.d.ts.map +1 -0
  98. package/dist/types/src/components/NotebookContainer.stories.d.ts +251 -0
  99. package/dist/types/src/components/NotebookContainer.stories.d.ts.map +1 -0
  100. package/dist/types/src/components/NotebookStack/NotebookCell.d.ts +15 -0
  101. package/dist/types/src/components/NotebookStack/NotebookCell.d.ts.map +1 -0
  102. package/dist/types/src/components/NotebookStack/NotebookMenu.d.ts +9 -0
  103. package/dist/types/src/components/NotebookStack/NotebookMenu.d.ts.map +1 -0
  104. package/dist/types/src/components/NotebookStack/NotebookStack.d.ts +14 -0
  105. package/dist/types/src/components/NotebookStack/NotebookStack.d.ts.map +1 -0
  106. package/dist/types/src/components/NotebookStack/NotebookStack.stories.d.ts +245 -0
  107. package/dist/types/src/components/NotebookStack/NotebookStack.stories.d.ts.map +1 -0
  108. package/dist/types/src/components/NotebookStack/index.d.ts +3 -0
  109. package/dist/types/src/components/NotebookStack/index.d.ts.map +1 -0
  110. package/dist/types/src/components/ScriptContainer.d.ts +4 -4
  111. package/dist/types/src/components/ScriptContainer.d.ts.map +1 -1
  112. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts +5 -6
  113. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts.map +1 -1
  114. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.stories.d.ts +237 -2
  115. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.stories.d.ts.map +1 -1
  116. package/dist/types/src/components/Settings/ScriptObjectSettings.d.ts +2 -2
  117. package/dist/types/src/components/Settings/ScriptObjectSettings.d.ts.map +1 -1
  118. package/dist/types/src/components/Settings/ScriptPluginSettings.d.ts +2 -2
  119. package/dist/types/src/components/Settings/ScriptPluginSettings.d.ts.map +1 -1
  120. package/dist/types/src/components/TestPanel/TestContainer.d.ts +2 -2
  121. package/dist/types/src/components/TestPanel/TestContainer.d.ts.map +1 -1
  122. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts +4 -2
  123. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts.map +1 -1
  124. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts +3 -3
  125. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts.map +1 -1
  126. package/dist/types/src/components/index.d.ts +2 -0
  127. package/dist/types/src/components/index.d.ts.map +1 -1
  128. package/dist/types/src/events.d.ts.map +1 -1
  129. package/dist/types/src/hooks/deploy.d.ts +11 -11
  130. package/dist/types/src/hooks/deploy.d.ts.map +1 -1
  131. package/dist/types/src/hooks/format.d.ts +2 -2
  132. package/dist/types/src/hooks/format.d.ts.map +1 -1
  133. package/dist/types/src/hooks/template.d.ts +4 -14
  134. package/dist/types/src/hooks/template.d.ts.map +1 -1
  135. package/dist/types/src/index.d.ts +1 -0
  136. package/dist/types/src/index.d.ts.map +1 -1
  137. package/dist/types/src/meta.d.ts +0 -1
  138. package/dist/types/src/meta.d.ts.map +1 -1
  139. package/dist/types/src/notebook/compute-graph.d.ts +45 -0
  140. package/dist/types/src/notebook/compute-graph.d.ts.map +1 -0
  141. package/dist/types/src/notebook/compute-graph.test.d.ts +2 -0
  142. package/dist/types/src/notebook/compute-graph.test.d.ts.map +1 -0
  143. package/dist/types/src/notebook/eval.d.ts +13 -0
  144. package/dist/types/src/notebook/eval.d.ts.map +1 -0
  145. package/dist/types/src/notebook/index.d.ts +2 -0
  146. package/dist/types/src/notebook/index.d.ts.map +1 -0
  147. package/dist/types/src/notebook/vfs-parser.d.ts +74 -0
  148. package/dist/types/src/notebook/vfs-parser.d.ts.map +1 -0
  149. package/dist/types/src/notebook/vfs-parser.test.d.ts +2 -0
  150. package/dist/types/src/notebook/vfs-parser.test.d.ts.map +1 -0
  151. package/dist/types/src/templates/chess.d.ts.map +1 -1
  152. package/dist/types/src/templates/data-generator.d.ts.map +1 -1
  153. package/dist/types/src/templates/discord.d.ts.map +1 -1
  154. package/dist/types/src/templates/forex-effect.d.ts.map +1 -1
  155. package/dist/types/src/templates/forex.d.ts.map +1 -1
  156. package/dist/types/src/templates/gmail.d.ts.map +1 -1
  157. package/dist/types/src/templates/index.d.ts +43 -1
  158. package/dist/types/src/templates/index.d.ts.map +1 -1
  159. package/dist/types/src/templates/{echo.d.ts → ping.d.ts} +1 -1
  160. package/dist/types/src/templates/ping.d.ts.map +1 -0
  161. package/dist/types/src/testing/data.d.ts +3 -0
  162. package/dist/types/src/testing/data.d.ts.map +1 -0
  163. package/dist/types/src/testing/index.d.ts +2 -0
  164. package/dist/types/src/testing/index.d.ts.map +1 -0
  165. package/dist/types/src/translations.d.ts +29 -5
  166. package/dist/types/src/translations.d.ts.map +1 -1
  167. package/dist/types/src/types/Notebook.d.ts +31 -0
  168. package/dist/types/src/types/Notebook.d.ts.map +1 -0
  169. package/dist/types/src/types/actions.d.ts +54 -0
  170. package/dist/types/src/types/actions.d.ts.map +1 -0
  171. package/dist/types/src/types/index.d.ts +3 -1
  172. package/dist/types/src/types/index.d.ts.map +1 -1
  173. package/dist/types/src/types/types.d.ts +6 -0
  174. package/dist/types/src/types/types.d.ts.map +1 -0
  175. package/dist/types/src/util/deploy.d.ts +4 -4
  176. package/dist/types/src/util/deploy.d.ts.map +1 -1
  177. package/dist/types/src/util/functions.d.ts +6 -3
  178. package/dist/types/src/util/functions.d.ts.map +1 -1
  179. package/dist/types/tsconfig.tsbuildinfo +1 -1
  180. package/package.json +75 -68
  181. package/src/ScriptPlugin.tsx +88 -69
  182. package/src/capabilities/app-graph-builder.ts +7 -6
  183. package/src/capabilities/artifact-definition.ts +1 -1
  184. package/src/capabilities/intent-resolver.ts +20 -11
  185. package/src/capabilities/react-surface.tsx +25 -13
  186. package/src/capabilities/settings.ts +3 -3
  187. package/src/components/DeploymentDialog/DeploymentDialog.stories.tsx +11 -4
  188. package/src/components/DeploymentDialog/DeploymentDialog.tsx +11 -17
  189. package/src/components/NotebookContainer.stories.tsx +83 -0
  190. package/src/components/NotebookContainer.tsx +263 -0
  191. package/src/components/NotebookStack/NotebookCell.tsx +208 -0
  192. package/src/components/NotebookStack/NotebookMenu.tsx +47 -0
  193. package/src/components/NotebookStack/NotebookStack.stories.tsx +54 -0
  194. package/src/components/NotebookStack/NotebookStack.tsx +86 -0
  195. package/src/components/NotebookStack/index.ts +6 -0
  196. package/src/components/ScriptContainer.tsx +5 -5
  197. package/src/components/ScriptToolbar/ScriptToolbar.stories.tsx +22 -10
  198. package/src/components/ScriptToolbar/ScriptToolbar.tsx +24 -27
  199. package/src/components/Settings/ScriptObjectSettings.tsx +95 -11
  200. package/src/components/Settings/ScriptPluginSettings.tsx +4 -19
  201. package/src/components/TestPanel/TestContainer.tsx +2 -2
  202. package/src/components/TestPanel/TestPanel.tsx +7 -7
  203. package/src/components/TypescriptEditor/TypescriptEditor.stories.tsx +71 -16
  204. package/src/components/TypescriptEditor/TypescriptEditor.tsx +36 -34
  205. package/src/components/index.ts +3 -0
  206. package/src/events.ts +2 -2
  207. package/src/hooks/deploy.ts +14 -15
  208. package/src/hooks/format.ts +4 -4
  209. package/src/hooks/template.ts +6 -15
  210. package/src/hooks/useCreateAndDeployScriptTemplates.ts +5 -5
  211. package/src/index.ts +1 -0
  212. package/src/meta.ts +7 -5
  213. package/src/notebook/compute-graph.test.ts +70 -0
  214. package/src/notebook/compute-graph.ts +206 -0
  215. package/src/notebook/eval.ts +105 -0
  216. package/src/notebook/index.ts +5 -0
  217. package/src/notebook/vfs-parser.test.ts +149 -0
  218. package/src/notebook/vfs-parser.ts +451 -0
  219. package/src/templates/chess.ts +2 -0
  220. package/src/templates/data-generator.ts +2 -0
  221. package/src/templates/discord.ts +9 -1
  222. package/src/templates/forex-effect.ts +5 -1
  223. package/src/templates/forex.ts +2 -0
  224. package/src/templates/gmail.ts +21 -9
  225. package/src/templates/index.ts +6 -6
  226. package/src/testing/data.ts +72 -0
  227. package/src/testing/index.ts +5 -0
  228. package/src/translations.ts +32 -7
  229. package/src/types/Notebook.ts +41 -0
  230. package/src/types/actions.ts +53 -0
  231. package/src/types/index.ts +3 -1
  232. package/src/types/types.ts +15 -0
  233. package/src/util/deploy.ts +11 -15
  234. package/src/util/functions.ts +33 -4
  235. package/dist/lib/browser/DeploymentDialog-QZSTVNIS.mjs +0 -12
  236. package/dist/lib/browser/ScriptContainer-JUPCBUCP.mjs +0 -263
  237. package/dist/lib/browser/ScriptContainer-JUPCBUCP.mjs.map +0 -7
  238. package/dist/lib/browser/app-graph-builder-IABOSTBK.mjs.map +0 -7
  239. package/dist/lib/browser/chunk-6CAH7VIE.mjs.map +0 -7
  240. package/dist/lib/browser/chunk-IS4OG2UW.mjs +0 -39
  241. package/dist/lib/browser/chunk-IS4OG2UW.mjs.map +0 -7
  242. package/dist/lib/browser/chunk-NXKU3BNX.mjs.map +0 -7
  243. package/dist/lib/browser/chunk-QYAREHGH.mjs.map +0 -7
  244. package/dist/lib/browser/chunk-RNGIQIEJ.mjs +0 -88
  245. package/dist/lib/browser/chunk-RNGIQIEJ.mjs.map +0 -7
  246. package/dist/lib/browser/chunk-TH7GXPE3.mjs.map +0 -7
  247. package/dist/lib/browser/chunk-YCZPTTFO.mjs.map +0 -7
  248. package/dist/lib/browser/intent-resolver-YMK5SXVC.mjs.map +0 -7
  249. package/dist/lib/browser/react-surface-FEM5WWFH.mjs.map +0 -7
  250. package/dist/lib/browser/settings-KCTBK5TY.mjs.map +0 -7
  251. package/dist/lib/node-esm/DeploymentDialog-G6EHEPXN.mjs +0 -13
  252. package/dist/lib/node-esm/ScriptContainer-UXZUDQF6.mjs +0 -264
  253. package/dist/lib/node-esm/ScriptContainer-UXZUDQF6.mjs.map +0 -7
  254. package/dist/lib/node-esm/app-graph-builder-CQTTAYHP.mjs.map +0 -7
  255. package/dist/lib/node-esm/chunk-2GBESIHU.mjs.map +0 -7
  256. package/dist/lib/node-esm/chunk-6M2R2FQF.mjs.map +0 -7
  257. package/dist/lib/node-esm/chunk-AHXJ6NQU.mjs.map +0 -7
  258. package/dist/lib/node-esm/chunk-GWHLP5LM.mjs +0 -90
  259. package/dist/lib/node-esm/chunk-GWHLP5LM.mjs.map +0 -7
  260. package/dist/lib/node-esm/chunk-JIPFLBYA.mjs +0 -40
  261. package/dist/lib/node-esm/chunk-JIPFLBYA.mjs.map +0 -7
  262. package/dist/lib/node-esm/chunk-M642JUOZ.mjs.map +0 -7
  263. package/dist/lib/node-esm/chunk-ZA36GO4T.mjs.map +0 -7
  264. package/dist/lib/node-esm/intent-resolver-SKRDYQCZ.mjs.map +0 -7
  265. package/dist/lib/node-esm/react-surface-AOKMDJR4.mjs.map +0 -7
  266. package/dist/lib/node-esm/settings-DXZ334A3.mjs.map +0 -7
  267. package/dist/types/src/templates/echo.d.ts.map +0 -1
  268. package/dist/types/src/types/schema.d.ts +0 -38
  269. package/dist/types/src/types/schema.d.ts.map +0 -1
  270. package/src/types/schema.ts +0 -37
  271. /package/dist/lib/browser/{DeploymentDialog-QZSTVNIS.mjs.map → DeploymentDialog-E5NXT4UQ.mjs.map} +0 -0
  272. /package/dist/lib/{node-esm/DeploymentDialog-G6EHEPXN.mjs.map → browser/chunk-J5LGTIGS.mjs.map} +0 -0
  273. /package/dist/lib/browser/{chunk-5TVBECWH.mjs.map → chunk-UOQ6NCH3.mjs.map} +0 -0
  274. /package/dist/lib/node-esm/{chunk-35M3CHYE.mjs.map → chunk-55JZVM6K.mjs.map} +0 -0
  275. /package/src/templates/{echo.ts → ping.ts} +0 -0
@@ -10,10 +10,10 @@ import { Button, Dialog, Icon, useTranslation } from '@dxos/react-ui';
10
10
  import { type DataType } from '@dxos/schema';
11
11
 
12
12
  import { useCreateAndDeployScriptTemplates } from '../../hooks/useCreateAndDeployScriptTemplates';
13
- import { SCRIPT_PLUGIN } from '../../meta';
13
+ import { meta } from '../../meta';
14
14
  import { type Template } from '../../templates';
15
15
 
16
- export const DEPLOYMENT_DIALOG = `${SCRIPT_PLUGIN}/deployment/dialog`;
16
+ export const DEPLOYMENT_DIALOG = `${meta.id}/deployment/dialog`;
17
17
 
18
18
  // TODO(ZaymonFC):
19
19
  // - Show activity and feedback to the user.
@@ -26,7 +26,7 @@ export type DeploymentDialogProps = {
26
26
  };
27
27
 
28
28
  export const DeploymentDialog = ({ accessToken, scriptTemplates }: DeploymentDialogProps) => {
29
- const { t } = useTranslation(SCRIPT_PLUGIN);
29
+ const { t } = useTranslation(meta.id);
30
30
  const space = useMemo(() => getSpace(accessToken), [accessToken]);
31
31
 
32
32
  // TODO(ZaymonFC): Thinking further. All of this should get moved to intents to run async in the background.
@@ -41,12 +41,12 @@ export const DeploymentDialog = ({ accessToken, scriptTemplates }: DeploymentDia
41
41
  createIntent(LayoutAction.AddToast, {
42
42
  part: 'toast',
43
43
  subject: {
44
- id: `${SCRIPT_PLUGIN}/deployment-success`,
44
+ id: `${meta.id}/deployment-success`,
45
45
  icon: 'ph--check--regular',
46
46
  duration: Infinity,
47
- title: ['script deployment toast label', { ns: SCRIPT_PLUGIN, count: scriptTemplates.length }],
48
- description: ['script deployment toast description', { ns: SCRIPT_PLUGIN, count: scriptTemplates.length }],
49
- closeLabel: ['script deployment toast close label', { ns: SCRIPT_PLUGIN, count: scriptTemplates.length }],
47
+ title: ['script deployment toast label', { ns: meta.id, count: scriptTemplates.length }],
48
+ description: ['script deployment toast description', { ns: meta.id, count: scriptTemplates.length }],
49
+ closeLabel: ['script deployment toast close label', { ns: meta.id, count: scriptTemplates.length }],
50
50
  },
51
51
  }),
52
52
  );
@@ -58,18 +58,12 @@ export const DeploymentDialog = ({ accessToken, scriptTemplates }: DeploymentDia
58
58
  createIntent(LayoutAction.AddToast, {
59
59
  part: 'toast',
60
60
  subject: {
61
- id: `${SCRIPT_PLUGIN}/deployment-error`,
61
+ id: `${meta.id}/deployment-error`,
62
62
  icon: 'ph--warning--regular',
63
63
  duration: Infinity,
64
- title: ['script deployment error toast label', { ns: SCRIPT_PLUGIN, count: scriptTemplates.length }],
65
- description: [
66
- 'script deployment error toast description',
67
- { ns: SCRIPT_PLUGIN, count: scriptTemplates.length },
68
- ],
69
- closeLabel: [
70
- 'script deployment error toast close label',
71
- { ns: SCRIPT_PLUGIN, count: scriptTemplates.length },
72
- ],
64
+ title: ['script deployment error toast label', { ns: meta.id, count: scriptTemplates.length }],
65
+ description: ['script deployment error toast description', { ns: meta.id, count: scriptTemplates.length }],
66
+ closeLabel: ['script deployment error toast close label', { ns: meta.id, count: scriptTemplates.length }],
73
67
  },
74
68
  }),
75
69
  );
@@ -0,0 +1,83 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React from 'react';
7
+
8
+ import { SERVICES_CONFIG } from '@dxos/ai/testing';
9
+ import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
10
+ import { withPluginManager } from '@dxos/app-framework/testing';
11
+ import { Agent } from '@dxos/assistant-toolkit';
12
+ import { Filter } from '@dxos/echo';
13
+ import { Function, serializeFunction } from '@dxos/functions';
14
+ import { AssistantPlugin } from '@dxos/plugin-assistant';
15
+ import { AutomationPlugin } from '@dxos/plugin-automation';
16
+ import { ClientPlugin } from '@dxos/plugin-client';
17
+ import { ExplorerPlugin } from '@dxos/plugin-explorer';
18
+ import { Markdown, MarkdownPlugin } from '@dxos/plugin-markdown';
19
+ import { SpacePlugin } from '@dxos/plugin-space';
20
+ import { Config, useClient } from '@dxos/react-client';
21
+ import { useQuery } from '@dxos/react-client/echo';
22
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
23
+ import { DataTypes } from '@dxos/schema';
24
+
25
+ import { createNotebook } from '../testing';
26
+ import { translations } from '../translations';
27
+ import { Notebook } from '../types';
28
+
29
+ import { NotebookContainer } from './NotebookContainer';
30
+
31
+ const meta = {
32
+ title: 'plugins/plugin-script/NotebookContainer',
33
+ component: NotebookContainer,
34
+ render: (args) => {
35
+ const client = useClient();
36
+ const space = client.spaces.default;
37
+ const notebooks = useQuery(space?.db, Filter.type(Notebook.Notebook));
38
+ return <NotebookContainer {...args} notebook={notebooks[0]} />;
39
+ },
40
+ decorators: [
41
+ withTheme,
42
+ withLayout({ container: 'column', classNames: 'is-prose' }),
43
+ withPluginManager({
44
+ plugins: [
45
+ ClientPlugin({
46
+ // TODO(wittjosiah): ComputeRuntime requires edge to be configured or it will throw.
47
+ config: new Config({
48
+ runtime: {
49
+ services: SERVICES_CONFIG.REMOTE,
50
+ },
51
+ }),
52
+ types: [...DataTypes, Notebook.Notebook, Function.Function, Markdown.Document],
53
+ onClientInitialized: async ({ client }) => {
54
+ await client.halo.createIdentity();
55
+ await client.spaces.waitUntilReady();
56
+ const space = client.spaces.default;
57
+ await space.waitUntilReady();
58
+
59
+ space.db.add(createNotebook());
60
+ space.db.add(Markdown.makeDocument({ content: '# Hello World' }));
61
+ space.db.add(serializeFunction(Agent.prompt));
62
+ },
63
+ }),
64
+ SpacePlugin({}),
65
+ SettingsPlugin(),
66
+ IntentPlugin(),
67
+ AssistantPlugin(),
68
+ AutomationPlugin(),
69
+ ExplorerPlugin(),
70
+ MarkdownPlugin(),
71
+ ],
72
+ }),
73
+ ],
74
+ parameters: {
75
+ translations,
76
+ },
77
+ } satisfies Meta<typeof NotebookContainer>;
78
+
79
+ export default meta;
80
+
81
+ type Story = StoryObj<typeof meta>;
82
+
83
+ export const Default: Story = {};
@@ -0,0 +1,263 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Cause from 'effect/Cause';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Exit from 'effect/Exit';
8
+ import * as Layer from 'effect/Layer';
9
+ import React, { useCallback, useMemo, useState } from 'react';
10
+
11
+ import { Agent } from '@dxos/assistant-toolkit';
12
+ import { Blueprint, Prompt } from '@dxos/blueprints';
13
+ import { Filter, Obj, Query, Ref } from '@dxos/echo';
14
+ import { QueryBuilder } from '@dxos/echo-query';
15
+ import {
16
+ ComputeEventLogger,
17
+ type FunctionDefinition,
18
+ FunctionInvocationService,
19
+ InvocationTracer,
20
+ TracingService,
21
+ } from '@dxos/functions';
22
+ import { invariant } from '@dxos/invariant';
23
+ import { log } from '@dxos/log';
24
+ import { useComputeRuntimeCallback } from '@dxos/plugin-automation';
25
+ import { Graph } from '@dxos/plugin-explorer/types';
26
+ import { fullyQualifiedId } from '@dxos/react-client/echo';
27
+ import { getSpace } from '@dxos/react-client/echo';
28
+ import { DropdownMenu, IconButton, Toolbar, useTranslation } from '@dxos/react-ui';
29
+ import { useAttention } from '@dxos/react-ui-attention';
30
+ import { StackItem } from '@dxos/react-ui-stack';
31
+ import { DataType } from '@dxos/schema';
32
+ import { isNonNullable } from '@dxos/util';
33
+
34
+ import { meta } from '../meta';
35
+ import { ComputeGraph } from '../notebook';
36
+ import { type Notebook } from '../types';
37
+
38
+ import { NotebookMenu, NotebookStack, type NotebookStackProps } from './NotebookStack';
39
+ import { type TypescriptEditorProps } from './TypescriptEditor';
40
+
41
+ const INCLUDE_BLUEPRINTS = ['dxos.org/blueprint/assistant', 'dxos.org/blueprint/markdown'];
42
+
43
+ // TODO(burdon): Support calling named deployed functions (as with sheet).
44
+
45
+ export type NotebookContainerProps = {
46
+ role?: string;
47
+ notebook?: Notebook.Notebook;
48
+ } & Pick<TypescriptEditorProps, 'env'>;
49
+
50
+ export const NotebookContainer = ({ notebook, env }: NotebookContainerProps) => {
51
+ const { t } = useTranslation(meta.id);
52
+ const space = getSpace(notebook);
53
+ const attendableId = fullyQualifiedId(notebook);
54
+ const { hasAttention } = useAttention(attendableId);
55
+
56
+ // TODO(burdon): Consolidate execution and state (with graph).
57
+ // Generalize ComputeGraph evaluation function (using effects).
58
+ const graph = useMemo(() => notebook && new ComputeGraph(notebook), [notebook]);
59
+
60
+ const [queryValues, setQueryValues] = useState<Record<string, any>>({});
61
+ const handleExecQueries = useCallback(async () => {
62
+ invariant(space);
63
+
64
+ const builder = new QueryBuilder();
65
+ for (const cell of notebook?.cells ?? []) {
66
+ if (cell.type === 'query') {
67
+ if (cell.source?.target) {
68
+ const source = cell.source.target.content;
69
+ const { name, filter } = builder.build(source);
70
+ if (filter) {
71
+ const ast = Query.select(filter).ast;
72
+ const view = cell.view?.target;
73
+ if (!view) {
74
+ const graph = Graph.make({ query: { ast } });
75
+ const { view } = await Graph.makeView({ space, presentation: graph });
76
+ cell.view = Ref.make(view);
77
+ cell.name = name;
78
+ } else {
79
+ view.query.ast = ast;
80
+ }
81
+ }
82
+ }
83
+
84
+ if (cell.name && cell.view?.target) {
85
+ const view = Obj.getSnapshot(cell.view?.target);
86
+ const query = Query.fromAst(view.query.ast);
87
+ const result = await space?.db.query(query).run();
88
+ const objectIds = result?.objects?.map((obj) => obj.id);
89
+ setQueryValues((prev) => ({ ...prev, [cell.name!]: objectIds }));
90
+ }
91
+ }
92
+ }
93
+ }, [space, notebook, graph]);
94
+
95
+ const [promptResults, setPromptResults] = useState<Record<string, string>>({});
96
+ const handleExecPrompts = useComputeRuntimeCallback(
97
+ space,
98
+ Effect.fnUntraced(function* () {
99
+ invariant(graph);
100
+
101
+ const prompts =
102
+ notebook?.cells
103
+ .filter((cell) => cell.type === 'prompt')
104
+ .map((cell) => cell.prompt)
105
+ .filter(isNonNullable) ?? [];
106
+
107
+ for (const prompt of prompts) {
108
+ yield* runPrompt({
109
+ prompt,
110
+ input: { ...queryValues, ...graph.valuesByName.value },
111
+ onResult: (result) => setPromptResults((prev) => ({ ...prev, [prompt.dxn.toString()]: result })),
112
+ });
113
+ }
114
+ }),
115
+ [notebook, graph, queryValues],
116
+ );
117
+
118
+ // TODO(burdon): Cache values in context (preserve when switched).
119
+ const handleCompute = useCallback(async () => {
120
+ // TODO(burdon): Generalize executors (dependencies).
121
+ await graph?.evaluate();
122
+ await handleExecQueries();
123
+ await handleExecPrompts();
124
+ }, [graph, handleExecQueries, handleExecPrompts]);
125
+
126
+ const handleRearrange = useCallback<NonNullable<NotebookStackProps['onRearrange']>>(
127
+ (source, target) => {
128
+ invariant(notebook);
129
+ const from = notebook.cells.findIndex((cell) => cell.id === source.id);
130
+ const to = notebook.cells.findIndex((cell) => cell.id === target.id);
131
+ if (from != null && to != null) {
132
+ const cell = notebook.cells.splice(from, 1)[0];
133
+ if (cell) {
134
+ notebook.cells.splice(to, 0, cell);
135
+ }
136
+ }
137
+ },
138
+ [notebook],
139
+ );
140
+
141
+ const handleCellInsert = useCallback<NonNullable<NotebookStackProps['onCellInsert']>>(
142
+ async (type, after) => {
143
+ invariant(notebook);
144
+ const cell: Notebook.Cell = { id: crypto.randomUUID(), type };
145
+ switch (type) {
146
+ case 'markdown':
147
+ case 'script':
148
+ case 'query': {
149
+ cell.source = Ref.make(DataType.makeText());
150
+ break;
151
+ }
152
+
153
+ case 'prompt': {
154
+ if (space) {
155
+ const result = await space.db.query(Query.select(Filter.type(Blueprint.Blueprint))).run();
156
+ const blueprints = result.objects
157
+ .filter((blueprint) => INCLUDE_BLUEPRINTS.includes(blueprint.key))
158
+ .map((blueprint) => Ref.make(blueprint));
159
+ cell.prompt = Ref.make(Prompt.make({ instructions: '', blueprints }));
160
+ }
161
+ break;
162
+ }
163
+ }
164
+
165
+ const idx = after ? notebook.cells.findIndex((cell) => cell.id === after) : notebook.cells.length;
166
+ notebook.cells.splice(idx, 0, cell);
167
+ },
168
+ [space, notebook],
169
+ );
170
+
171
+ const handleCellDelete = useCallback<NonNullable<NotebookStackProps['onCellDelete']>>(
172
+ (id) => {
173
+ invariant(notebook);
174
+ const idx = notebook.cells.findIndex((cell) => cell.id === id);
175
+ if (idx !== -1) {
176
+ notebook.cells.splice(idx, 1);
177
+ }
178
+ },
179
+ [notebook],
180
+ );
181
+
182
+ return (
183
+ <StackItem.Content toolbar>
184
+ <Toolbar.Root disabled={!hasAttention} textBlockWidth>
185
+ <DropdownMenu.Root>
186
+ <DropdownMenu.Trigger asChild>
187
+ <IconButton icon='ph--plus--regular' iconOnly label={t('notebook cell insert label')} />
188
+ </DropdownMenu.Trigger>
189
+ <NotebookMenu onCellInsert={handleCellInsert} />
190
+ </DropdownMenu.Root>
191
+ <Toolbar.IconButton
192
+ icon='ph--play--fill'
193
+ iconOnly
194
+ label={t('compute label')}
195
+ classNames='text-green-500'
196
+ onClick={handleCompute}
197
+ />
198
+ </Toolbar.Root>
199
+ <div role='none' className='flex bs-full overflow-hidden -mis-[1px] -mie-[1px]'>
200
+ <NotebookStack
201
+ classNames='container-max-width border-l border-r border-subduedSeparator'
202
+ space={space}
203
+ notebook={notebook}
204
+ graph={graph}
205
+ env={env}
206
+ promptResults={promptResults}
207
+ onRearrange={handleRearrange}
208
+ onCellInsert={handleCellInsert}
209
+ onCellDelete={handleCellDelete}
210
+ />
211
+ </div>
212
+ </StackItem.Content>
213
+ );
214
+ };
215
+
216
+ export default NotebookContainer;
217
+
218
+ // TODO(wittjosiah): Factor out. Copied from PromptContainer in stories-assistant.
219
+ const runPrompt = Effect.fn(function* ({
220
+ prompt,
221
+ input,
222
+ onResult,
223
+ }: {
224
+ prompt: Ref.Ref<Prompt.Prompt>;
225
+ input: Record<string, any>;
226
+ onResult: (result: string) => void;
227
+ }) {
228
+ const inputData: FunctionDefinition.Input<typeof Agent.prompt> = { prompt, input };
229
+ const tracer = yield* InvocationTracer;
230
+ const trace = yield* tracer.traceInvocationStart({
231
+ target: undefined,
232
+ payload: {
233
+ data: {},
234
+ },
235
+ });
236
+
237
+ // Invoke the function.
238
+ const result = yield* FunctionInvocationService.invokeFunction(Agent.prompt, inputData).pipe(
239
+ Effect.provide(
240
+ ComputeEventLogger.layerFromTracing.pipe(
241
+ Layer.provideMerge(TracingService.layerQueue(trace.invocationTraceQueue)),
242
+ ),
243
+ ),
244
+ Effect.exit,
245
+ );
246
+
247
+ Exit.match(result, {
248
+ onFailure: (cause) => {
249
+ const error = Cause.prettyErrors(cause)[0];
250
+ log.error(error.message, error.cause ?? error.stack);
251
+ onResult(error.message);
252
+ },
253
+ onSuccess: (result: any) => {
254
+ onResult(result.note);
255
+ },
256
+ });
257
+
258
+ yield* tracer.traceInvocationEnd({
259
+ trace,
260
+ // TODO(dmaretskyi): Might miss errors.
261
+ exception: Exit.isFailure(result) ? Cause.prettyErrors(result.cause)[0] : undefined,
262
+ });
263
+ });
@@ -0,0 +1,208 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React, { useCallback, useMemo } from 'react';
6
+
7
+ import { Surface } from '@dxos/app-framework';
8
+ import { invariant } from '@dxos/invariant';
9
+ import { TemplateEditor } from '@dxos/plugin-assistant';
10
+ import { createDocAccessor } from '@dxos/react-client/echo';
11
+ import { type Space } from '@dxos/react-client/echo';
12
+ import { useThemeContext, useTranslation } from '@dxos/react-ui';
13
+ import { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-components';
14
+ import {
15
+ type BasicExtensionsOptions,
16
+ Editor,
17
+ type EditorProps,
18
+ createBasicExtensions,
19
+ createDataExtensions,
20
+ createMarkdownExtensions,
21
+ createThemeExtensions,
22
+ decorateMarkdown,
23
+ } from '@dxos/react-ui-editor';
24
+ import { mx } from '@dxos/react-ui-theme';
25
+ import { isNonNullable } from '@dxos/util';
26
+
27
+ import { meta } from '../../meta';
28
+ import { type ComputeGraph } from '../../notebook';
29
+ import { type Notebook } from '../../types';
30
+ import { TypescriptEditor, type TypescriptEditorProps } from '../TypescriptEditor';
31
+
32
+ import { type NotebookMenuProps } from './NotebookMenu';
33
+
34
+ const editorStyles = 'p-2 pis-3';
35
+ const valueStyles = 'p-1 pis-3';
36
+
37
+ export type NotebookCellProps = {
38
+ space?: Space;
39
+ graph?: ComputeGraph;
40
+ dragging?: boolean;
41
+ cell: Notebook.Cell;
42
+ promptResults?: Record<string, string>;
43
+ } & (Pick<NotebookMenuProps, 'onCellInsert' | 'onCellDelete'> & Pick<TypescriptEditorProps, 'env'>);
44
+
45
+ // TODO(burdon): Show evaluation errors.
46
+ export const NotebookCell = ({ space, graph, dragging, cell, promptResults, env }: NotebookCellProps) => {
47
+ const { t } = useTranslation(meta.id);
48
+
49
+ const extensions = useMemo(() => {
50
+ return cell.source?.target
51
+ ? [createDataExtensions({ id: cell.id, text: createDocAccessor(cell.source.target, ['content']) })].filter(
52
+ isNonNullable,
53
+ )
54
+ : [];
55
+ }, [cell.source?.target]);
56
+
57
+ const view = cell.view?.target;
58
+
59
+ const handleQueryChange = useCallback<NonNullable<QueryEditorProps['onChange']>>(
60
+ (value: string) => {
61
+ invariant(cell.source?.target);
62
+ cell.source.target.content = value;
63
+ },
64
+ [cell],
65
+ );
66
+
67
+ switch (cell.type) {
68
+ case 'markdown':
69
+ if (!cell.source?.target) {
70
+ return null;
71
+ }
72
+
73
+ return (
74
+ <NotebookTextEditor
75
+ id={cell.id}
76
+ classNames={editorStyles}
77
+ initialValue={cell.source.target.content}
78
+ extensions={extensions}
79
+ />
80
+ );
81
+
82
+ case 'script':
83
+ if (!cell.source?.target) {
84
+ return null;
85
+ }
86
+
87
+ return (
88
+ <>
89
+ <TypescriptEditor
90
+ id={cell.id}
91
+ role='section'
92
+ classNames={editorStyles}
93
+ initialValue={cell.source.target.content}
94
+ extensions={extensions}
95
+ env={env}
96
+ options={{
97
+ placeholder: t('notebook cell placeholder'),
98
+ highlightActiveLine: false,
99
+ lineNumbers: false,
100
+ }}
101
+ />
102
+ <NotebookCellValue cell={cell} graph={graph} />
103
+ </>
104
+ );
105
+
106
+ case 'query':
107
+ if (!cell.source?.target) {
108
+ return null;
109
+ }
110
+
111
+ // TODO(burdon): Remove app-framework deps (via render prop).
112
+ return (
113
+ <div className={mx('bs-full overflow-hidden grid', view && !dragging && 'grid-rows-[min-content_1fr]')}>
114
+ <QueryEditor
115
+ id={cell.id}
116
+ classNames={[editorStyles, 'border-b border-subduedSeparator']}
117
+ db={space?.db}
118
+ value={cell.source.target.content}
119
+ onChange={handleQueryChange}
120
+ />
121
+ {view && !dragging && <Surface role='section' limit={1} data={{ subject: view }} />}
122
+ </div>
123
+ );
124
+
125
+ // TODO(burdon): Use streaming response from Chat.
126
+ case 'prompt':
127
+ if (!cell.prompt?.target) {
128
+ return null;
129
+ }
130
+
131
+ return (
132
+ <>
133
+ <TemplateEditor
134
+ id={cell.id}
135
+ template={cell.prompt.target.instructions}
136
+ lineNumbers={false}
137
+ classNames={editorStyles}
138
+ />
139
+ <NotebookPromptResult cell={cell} promptResults={promptResults} />
140
+ </>
141
+ );
142
+
143
+ default:
144
+ return null;
145
+ }
146
+ };
147
+
148
+ const NotebookCellValue = ({ cell, graph }: NotebookCellProps) => {
149
+ const name = graph?.expressions.value[cell.id]?.name;
150
+ const value = graph?.getValue(cell.id);
151
+ if (value == null) {
152
+ return null;
153
+ }
154
+
155
+ return (
156
+ <div
157
+ className={mx(
158
+ 'flex is-full bg-groupSurface border-t border-subduedSeparator text-description font-mono',
159
+ valueStyles,
160
+ )}
161
+ >
162
+ {name && (
163
+ <>
164
+ <span className='text-successText'>{name}</span>
165
+ <span className='text-description'>&nbsp;=&nbsp;</span>
166
+ </>
167
+ )}
168
+ <span>{value}</span>
169
+ </div>
170
+ );
171
+ };
172
+
173
+ const NotebookPromptResult = ({ cell, promptResults }: NotebookCellProps) => {
174
+ if (!cell.prompt) {
175
+ return null;
176
+ }
177
+
178
+ const value = promptResults?.[cell.prompt.dxn.toString()];
179
+ if (value == null) {
180
+ return null;
181
+ }
182
+
183
+ return (
184
+ <div className={mx('flex is-full bg-groupSurface text-description border-t border-subduedSeparator', valueStyles)}>
185
+ <NotebookTextEditor readOnly value={value} />
186
+ </div>
187
+ );
188
+ };
189
+
190
+ const NotebookTextEditor = ({
191
+ extensions: extensionsParam,
192
+ readOnly,
193
+ ...props
194
+ }: EditorProps & Pick<BasicExtensionsOptions, 'readOnly'>) => {
195
+ const { t } = useTranslation(meta.id);
196
+ const { themeMode } = useThemeContext();
197
+ const extensions = useMemo(() => {
198
+ return [
199
+ createBasicExtensions({ placeholder: t('notebook markdown placeholder'), readOnly }),
200
+ createThemeExtensions({ themeMode, syntaxHighlighting: true }),
201
+ createMarkdownExtensions(),
202
+ decorateMarkdown(),
203
+ extensionsParam,
204
+ ].filter(isNonNullable);
205
+ }, [extensionsParam]);
206
+
207
+ return <Editor {...props} extensions={extensions} moveToEnd />;
208
+ };
@@ -0,0 +1,47 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { DropdownMenu, useTranslation } from '@dxos/react-ui';
8
+
9
+ import { meta } from '../../meta';
10
+ import { type Notebook } from '../../types';
11
+
12
+ export type NotebookMenuProps = {
13
+ cell?: Notebook.Cell;
14
+ onCellInsert?: (type: Notebook.CellType, after: string | undefined) => void;
15
+ onCellDelete?: (id: string) => void;
16
+ };
17
+
18
+ // TODO(burdon): Better way to organize menu?
19
+ export const NotebookMenu = ({ cell, onCellInsert, onCellDelete }: NotebookMenuProps) => {
20
+ const { t } = useTranslation(meta.id);
21
+ return (
22
+ <DropdownMenu.Portal>
23
+ <DropdownMenu.Content>
24
+ <DropdownMenu.Viewport>
25
+ <DropdownMenu.Item onClick={() => onCellInsert?.('script', cell?.id)}>
26
+ {t('notebook cell insert script label')}
27
+ </DropdownMenu.Item>
28
+ <DropdownMenu.Item onClick={() => onCellInsert?.('prompt', cell?.id)}>
29
+ {t('notebook cell insert prompt label')}
30
+ </DropdownMenu.Item>
31
+ <DropdownMenu.Item onClick={() => onCellInsert?.('query', cell?.id)}>
32
+ {t('notebook cell insert query label')}
33
+ </DropdownMenu.Item>
34
+ <DropdownMenu.Item onClick={() => onCellInsert?.('markdown', cell?.id)}>
35
+ {t('notebook cell insert markdown label')}
36
+ </DropdownMenu.Item>
37
+ {cell && onCellDelete && (
38
+ <DropdownMenu.Item onClick={() => onCellDelete?.(cell.id)}>
39
+ {t('notebook cell delete label')}
40
+ </DropdownMenu.Item>
41
+ )}
42
+ </DropdownMenu.Viewport>
43
+ <DropdownMenu.Arrow />
44
+ </DropdownMenu.Content>
45
+ </DropdownMenu.Portal>
46
+ );
47
+ };