@dxos/plugin-deck 0.8.4-main.b97322e → 0.8.4-main.bc674ce

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 (277) hide show
  1. package/dist/lib/browser/app-graph-builder-DTVCULQ4.mjs +120 -0
  2. package/dist/lib/browser/app-graph-builder-DTVCULQ4.mjs.map +7 -0
  3. package/dist/lib/browser/{check-app-scheme-57U62A3A.mjs → check-app-scheme-JSRXXIYF.mjs} +9 -9
  4. package/dist/lib/browser/check-app-scheme-JSRXXIYF.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-F5BQOOEG.mjs → chunk-ATFPDN6J.mjs} +155 -23
  6. package/dist/lib/browser/chunk-ATFPDN6J.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-CNTGBCMK.mjs → chunk-NHABISX2.mjs} +40 -33
  8. package/dist/lib/browser/chunk-NHABISX2.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-S4A5UO4K.mjs +1448 -0
  10. package/dist/lib/browser/chunk-S4A5UO4K.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-UNG4CLLP.mjs +161 -0
  12. package/dist/lib/browser/chunk-UNG4CLLP.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +79 -67
  14. package/dist/lib/browser/index.mjs.map +4 -4
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/operation-resolver-CDYBLZJ4.mjs +595 -0
  17. package/dist/lib/browser/operation-resolver-CDYBLZJ4.mjs.map +7 -0
  18. package/dist/lib/browser/react-root-XDCMNENQ.mjs +47 -0
  19. package/dist/lib/browser/react-root-XDCMNENQ.mjs.map +7 -0
  20. package/dist/lib/browser/react-surface-HODERLOL.mjs +42 -0
  21. package/dist/lib/browser/react-surface-HODERLOL.mjs.map +7 -0
  22. package/dist/lib/browser/settings-OMHVGZ6V.mjs +37 -0
  23. package/dist/lib/browser/settings-OMHVGZ6V.mjs.map +7 -0
  24. package/dist/lib/browser/state-OC3BSB6E.mjs +103 -0
  25. package/dist/lib/browser/state-OC3BSB6E.mjs.map +7 -0
  26. package/dist/lib/browser/toolkit-R53LD3EA.mjs +53 -0
  27. package/dist/lib/browser/toolkit-R53LD3EA.mjs.map +7 -0
  28. package/dist/lib/browser/types/index.mjs +11 -4
  29. package/dist/lib/browser/url-handler-53TE6JZO.mjs +93 -0
  30. package/dist/lib/browser/url-handler-53TE6JZO.mjs.map +7 -0
  31. package/dist/lib/node-esm/app-graph-builder-473BNZDJ.mjs +121 -0
  32. package/dist/lib/node-esm/app-graph-builder-473BNZDJ.mjs.map +7 -0
  33. package/dist/lib/node-esm/check-app-scheme-IVYRHKRH.mjs +33 -0
  34. package/dist/lib/node-esm/check-app-scheme-IVYRHKRH.mjs.map +7 -0
  35. package/dist/lib/node-esm/chunk-ADPMWKLL.mjs +154 -0
  36. package/dist/lib/node-esm/chunk-ADPMWKLL.mjs.map +7 -0
  37. package/dist/lib/node-esm/chunk-D34L3ECT.mjs +1449 -0
  38. package/dist/lib/node-esm/chunk-D34L3ECT.mjs.map +7 -0
  39. package/dist/lib/node-esm/chunk-SKEVPQ7E.mjs +162 -0
  40. package/dist/lib/node-esm/chunk-SKEVPQ7E.mjs.map +7 -0
  41. package/dist/lib/node-esm/chunk-XAKTY3EB.mjs +294 -0
  42. package/dist/lib/node-esm/chunk-XAKTY3EB.mjs.map +7 -0
  43. package/dist/lib/node-esm/index.mjs +181 -0
  44. package/dist/lib/node-esm/index.mjs.map +7 -0
  45. package/dist/lib/node-esm/meta.json +1 -0
  46. package/dist/lib/node-esm/operation-resolver-WUOE33ID.mjs +596 -0
  47. package/dist/lib/node-esm/operation-resolver-WUOE33ID.mjs.map +7 -0
  48. package/dist/lib/node-esm/react-root-O6GZO62Z.mjs +48 -0
  49. package/dist/lib/node-esm/react-root-O6GZO62Z.mjs.map +7 -0
  50. package/dist/lib/node-esm/react-surface-IHDJDGC5.mjs +43 -0
  51. package/dist/lib/node-esm/react-surface-IHDJDGC5.mjs.map +7 -0
  52. package/dist/lib/node-esm/settings-2HB6FKIK.mjs +38 -0
  53. package/dist/lib/node-esm/settings-2HB6FKIK.mjs.map +7 -0
  54. package/dist/lib/node-esm/state-JRQ45ACJ.mjs +104 -0
  55. package/dist/lib/node-esm/state-JRQ45ACJ.mjs.map +7 -0
  56. package/dist/lib/node-esm/toolkit-JLPZNNKB.mjs +54 -0
  57. package/dist/lib/node-esm/toolkit-JLPZNNKB.mjs.map +7 -0
  58. package/dist/lib/node-esm/types/index.mjs +40 -0
  59. package/dist/lib/node-esm/url-handler-QGF2R24T.mjs +94 -0
  60. package/dist/lib/node-esm/url-handler-QGF2R24T.mjs.map +7 -0
  61. package/dist/types/src/DeckPlugin.d.ts +2 -1
  62. package/dist/types/src/DeckPlugin.d.ts.map +1 -1
  63. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +6 -0
  64. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -0
  65. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +3 -0
  66. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +1 -0
  67. package/dist/types/src/capabilities/check-app-scheme/check-app-scheme.d.ts +5 -0
  68. package/dist/types/src/capabilities/check-app-scheme/check-app-scheme.d.ts.map +1 -0
  69. package/dist/types/src/capabilities/check-app-scheme/index.d.ts +3 -0
  70. package/dist/types/src/capabilities/check-app-scheme/index.d.ts.map +1 -0
  71. package/dist/types/src/capabilities/index.d.ts +8 -13
  72. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  73. package/dist/types/src/capabilities/operation-resolver/index.d.ts +3 -0
  74. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -0
  75. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +5 -0
  76. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -0
  77. package/dist/types/src/capabilities/react-root/index.d.ts +6 -0
  78. package/dist/types/src/capabilities/react-root/index.d.ts.map +1 -0
  79. package/dist/types/src/capabilities/react-root/react-root.d.ts +9 -0
  80. package/dist/types/src/capabilities/react-root/react-root.d.ts.map +1 -0
  81. package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
  82. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
  83. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
  84. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
  85. package/dist/types/src/capabilities/settings/index.d.ts +19 -0
  86. package/dist/types/src/capabilities/settings/index.d.ts.map +1 -0
  87. package/dist/types/src/capabilities/settings/settings.d.ts +21 -0
  88. package/dist/types/src/capabilities/settings/settings.d.ts.map +1 -0
  89. package/dist/types/src/capabilities/state/index.d.ts +172 -0
  90. package/dist/types/src/capabilities/state/index.d.ts.map +1 -0
  91. package/dist/types/src/capabilities/state/state.d.ts +175 -0
  92. package/dist/types/src/capabilities/state/state.d.ts.map +1 -0
  93. package/dist/types/src/capabilities/toolkit/index.d.ts +3 -0
  94. package/dist/types/src/capabilities/toolkit/index.d.ts.map +1 -0
  95. package/dist/types/src/capabilities/toolkit/toolkit.d.ts +26 -0
  96. package/dist/types/src/capabilities/toolkit/toolkit.d.ts.map +1 -0
  97. package/dist/types/src/capabilities/tools/index.d.ts +3 -0
  98. package/dist/types/src/capabilities/tools/index.d.ts.map +1 -0
  99. package/dist/types/src/capabilities/tools/tools.d.ts +12 -0
  100. package/dist/types/src/capabilities/tools/tools.d.ts.map +1 -0
  101. package/dist/types/src/capabilities/url-handler/index.d.ts +3 -0
  102. package/dist/types/src/capabilities/url-handler/index.d.ts.map +1 -0
  103. package/dist/types/src/capabilities/url-handler/url-handler.d.ts +5 -0
  104. package/dist/types/src/capabilities/url-handler/url-handler.d.ts.map +1 -0
  105. package/dist/types/src/components/DeckLayout/Banner.d.ts.map +1 -1
  106. package/dist/types/src/components/DeckLayout/ContentEmpty.d.ts.map +1 -1
  107. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts +2 -3
  108. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
  109. package/dist/types/src/components/DeckLayout/DeckLayout.stories.d.ts +74 -0
  110. package/dist/types/src/components/DeckLayout/DeckLayout.stories.d.ts.map +1 -0
  111. package/dist/types/src/components/DeckLayout/DeckMain.d.ts +3 -0
  112. package/dist/types/src/components/DeckLayout/DeckMain.d.ts.map +1 -0
  113. package/dist/types/src/components/DeckLayout/Dialog.d.ts.map +1 -1
  114. package/dist/types/src/components/DeckLayout/Popover.d.ts.map +1 -1
  115. package/dist/types/src/components/DeckLayout/Toast.d.ts +7 -2
  116. package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
  117. package/dist/types/src/components/DeckSettings/DeckSettings.d.ts +4 -2
  118. package/dist/types/src/components/DeckSettings/DeckSettings.d.ts.map +1 -1
  119. package/dist/types/src/components/Plank/Plank.d.ts +4 -4
  120. package/dist/types/src/components/Plank/Plank.d.ts.map +1 -1
  121. package/dist/types/src/components/Plank/Plank.stories.d.ts +104 -5
  122. package/dist/types/src/components/Plank/Plank.stories.d.ts.map +1 -1
  123. package/dist/types/src/components/Plank/PlankControls.d.ts +1 -1
  124. package/dist/types/src/components/Plank/PlankControls.d.ts.map +1 -1
  125. package/dist/types/src/components/Plank/PlankError.d.ts +1 -1
  126. package/dist/types/src/components/Plank/PlankError.d.ts.map +1 -1
  127. package/dist/types/src/components/Plank/PlankHeading.d.ts +3 -3
  128. package/dist/types/src/components/Plank/PlankHeading.d.ts.map +1 -1
  129. package/dist/types/src/components/Sidebar/ComplementarySidebar.d.ts.map +1 -1
  130. package/dist/types/src/components/Sidebar/Sidebar.d.ts.map +1 -1
  131. package/dist/types/src/components/Sidebar/SidebarButton.d.ts.map +1 -1
  132. package/dist/types/src/hooks/index.d.ts +1 -0
  133. package/dist/types/src/hooks/index.d.ts.map +1 -1
  134. package/dist/types/src/hooks/useDeckCompanions.d.ts +3 -3
  135. package/dist/types/src/hooks/useDeckCompanions.d.ts.map +1 -1
  136. package/dist/types/src/hooks/useDeckState.d.ts +17 -0
  137. package/dist/types/src/hooks/useDeckState.d.ts.map +1 -0
  138. package/dist/types/src/hooks/useHoistStatusbar.d.ts +1 -1
  139. package/dist/types/src/hooks/useHoistStatusbar.d.ts.map +1 -1
  140. package/dist/types/src/hooks/useNodeActionExpander.d.ts +1 -1
  141. package/dist/types/src/hooks/useNodeActionExpander.d.ts.map +1 -1
  142. package/dist/types/src/index.d.ts +1 -2
  143. package/dist/types/src/index.d.ts.map +1 -1
  144. package/dist/types/src/meta.d.ts +2 -3
  145. package/dist/types/src/meta.d.ts.map +1 -1
  146. package/dist/types/src/translations.d.ts +3 -1
  147. package/dist/types/src/translations.d.ts.map +1 -1
  148. package/dist/types/src/{capabilities → types}/capabilities.d.ts +96 -90
  149. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  150. package/dist/types/src/types/events.d.ts +7 -0
  151. package/dist/types/src/types/events.d.ts.map +1 -0
  152. package/dist/types/src/types/index.d.ts +2 -0
  153. package/dist/types/src/types/index.d.ts.map +1 -1
  154. package/dist/types/src/types/schema.d.ts +90 -30
  155. package/dist/types/src/types/schema.d.ts.map +1 -1
  156. package/dist/types/src/util/set-active.d.ts +18 -3
  157. package/dist/types/src/util/set-active.d.ts.map +1 -1
  158. package/dist/types/tsconfig.tsbuildinfo +1 -1
  159. package/package.json +56 -46
  160. package/src/DeckPlugin.ts +45 -61
  161. package/src/capabilities/app-graph-builder/app-graph-builder.ts +118 -0
  162. package/src/capabilities/app-graph-builder/index.ts +7 -0
  163. package/src/capabilities/{check-app-scheme.ts → check-app-scheme/check-app-scheme.ts} +12 -11
  164. package/src/capabilities/check-app-scheme/index.ts +7 -0
  165. package/src/capabilities/index.ts +9 -13
  166. package/src/capabilities/operation-resolver/index.ts +10 -0
  167. package/src/capabilities/operation-resolver/operation-resolver.ts +555 -0
  168. package/src/capabilities/react-root/index.ts +7 -0
  169. package/src/capabilities/react-root/react-root.tsx +47 -0
  170. package/src/capabilities/react-surface/index.ts +7 -0
  171. package/src/capabilities/react-surface/react-surface.tsx +37 -0
  172. package/src/capabilities/settings/index.ts +7 -0
  173. package/src/capabilities/settings/settings.ts +38 -0
  174. package/src/capabilities/state/index.ts +7 -0
  175. package/src/capabilities/state/state.ts +104 -0
  176. package/src/capabilities/toolkit/index.ts +7 -0
  177. package/src/capabilities/toolkit/toolkit.ts +63 -0
  178. package/src/capabilities/tools/index.ts +7 -0
  179. package/src/capabilities/tools/tools.ts +92 -0
  180. package/src/capabilities/url-handler/index.ts +7 -0
  181. package/src/capabilities/url-handler/url-handler.ts +95 -0
  182. package/src/components/DeckLayout/ActiveNode.tsx +1 -1
  183. package/src/components/DeckLayout/Banner.tsx +6 -6
  184. package/src/components/DeckLayout/ContentEmpty.tsx +4 -5
  185. package/src/components/DeckLayout/DeckLayout.stories.tsx +51 -0
  186. package/src/components/DeckLayout/DeckLayout.tsx +18 -285
  187. package/src/components/DeckLayout/DeckMain.tsx +286 -0
  188. package/src/components/DeckLayout/Dialog.tsx +13 -10
  189. package/src/components/DeckLayout/Fallback.tsx +4 -4
  190. package/src/components/DeckLayout/Popover.tsx +44 -32
  191. package/src/components/DeckLayout/StatusBar.tsx +1 -1
  192. package/src/components/DeckLayout/Toast.tsx +30 -5
  193. package/src/components/DeckSettings/DeckSettings.tsx +91 -66
  194. package/src/components/Plank/Plank.stories.tsx +23 -16
  195. package/src/components/Plank/Plank.tsx +89 -56
  196. package/src/components/Plank/PlankControls.tsx +9 -9
  197. package/src/components/Plank/PlankError.tsx +5 -4
  198. package/src/components/Plank/PlankHeading.tsx +38 -42
  199. package/src/components/Sidebar/ComplementarySidebar.tsx +61 -33
  200. package/src/components/Sidebar/Sidebar.tsx +6 -6
  201. package/src/components/Sidebar/SidebarButton.tsx +39 -32
  202. package/src/components/fragments.ts +1 -1
  203. package/src/hooks/index.ts +1 -0
  204. package/src/hooks/useCompanions.ts +1 -1
  205. package/src/hooks/useDeckCompanions.ts +7 -5
  206. package/src/hooks/useDeckState.ts +82 -0
  207. package/src/hooks/useHoistStatusbar.ts +4 -5
  208. package/src/hooks/useNodeActionExpander.ts +4 -4
  209. package/src/index.ts +1 -2
  210. package/src/meta.ts +8 -5
  211. package/src/translations.ts +3 -1
  212. package/src/types/capabilities.ts +33 -0
  213. package/src/types/events.ts +20 -0
  214. package/src/types/index.ts +2 -0
  215. package/src/types/schema.ts +86 -14
  216. package/src/util/layoutAppliesTopbar.ts +1 -1
  217. package/src/util/set-active.ts +49 -29
  218. package/dist/lib/browser/app-graph-builder-JTFSDT2I.mjs +0 -152
  219. package/dist/lib/browser/app-graph-builder-JTFSDT2I.mjs.map +0 -7
  220. package/dist/lib/browser/check-app-scheme-57U62A3A.mjs.map +0 -7
  221. package/dist/lib/browser/chunk-CNTGBCMK.mjs.map +0 -7
  222. package/dist/lib/browser/chunk-D7KTFCUV.mjs +0 -1494
  223. package/dist/lib/browser/chunk-D7KTFCUV.mjs.map +0 -7
  224. package/dist/lib/browser/chunk-F5BQOOEG.mjs.map +0 -7
  225. package/dist/lib/browser/chunk-JFTXENFN.mjs +0 -129
  226. package/dist/lib/browser/chunk-JFTXENFN.mjs.map +0 -7
  227. package/dist/lib/browser/chunk-M57WD3V6.mjs +0 -16
  228. package/dist/lib/browser/chunk-M57WD3V6.mjs.map +0 -7
  229. package/dist/lib/browser/chunk-QDZO4AJ4.mjs +0 -127
  230. package/dist/lib/browser/chunk-QDZO4AJ4.mjs.map +0 -7
  231. package/dist/lib/browser/chunk-Z5KITAZW.mjs +0 -13
  232. package/dist/lib/browser/chunk-Z5KITAZW.mjs.map +0 -7
  233. package/dist/lib/browser/intent-resolver-P2OBK5HK.mjs +0 -521
  234. package/dist/lib/browser/intent-resolver-P2OBK5HK.mjs.map +0 -7
  235. package/dist/lib/browser/react-root-PO64J7ML.mjs +0 -43
  236. package/dist/lib/browser/react-root-PO64J7ML.mjs.map +0 -7
  237. package/dist/lib/browser/react-surface-E45YOVF5.mjs +0 -40
  238. package/dist/lib/browser/react-surface-E45YOVF5.mjs.map +0 -7
  239. package/dist/lib/browser/settings-6AJZPZPM.mjs +0 -29
  240. package/dist/lib/browser/settings-6AJZPZPM.mjs.map +0 -7
  241. package/dist/lib/browser/state-MVDYX77Y.mjs +0 -12
  242. package/dist/lib/browser/tools-TKQDPCHJ.mjs +0 -88
  243. package/dist/lib/browser/tools-TKQDPCHJ.mjs.map +0 -7
  244. package/dist/lib/browser/url-handler-7L7M6IKH.mjs +0 -70
  245. package/dist/lib/browser/url-handler-7L7M6IKH.mjs.map +0 -7
  246. package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
  247. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
  248. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  249. package/dist/types/src/capabilities/check-app-scheme.d.ts +0 -4
  250. package/dist/types/src/capabilities/check-app-scheme.d.ts.map +0 -1
  251. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  252. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  253. package/dist/types/src/capabilities/react-root.d.ts +0 -7
  254. package/dist/types/src/capabilities/react-root.d.ts.map +0 -1
  255. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  256. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  257. package/dist/types/src/capabilities/settings.d.ts +0 -4
  258. package/dist/types/src/capabilities/settings.d.ts.map +0 -1
  259. package/dist/types/src/capabilities/state.d.ts +0 -101
  260. package/dist/types/src/capabilities/state.d.ts.map +0 -1
  261. package/dist/types/src/capabilities/tools.d.ts +0 -11
  262. package/dist/types/src/capabilities/tools.d.ts.map +0 -1
  263. package/dist/types/src/capabilities/url-handler.d.ts +0 -4
  264. package/dist/types/src/capabilities/url-handler.d.ts.map +0 -1
  265. package/dist/types/src/events.d.ts +0 -4
  266. package/dist/types/src/events.d.ts.map +0 -1
  267. package/src/capabilities/app-graph-builder.ts +0 -141
  268. package/src/capabilities/capabilities.ts +0 -14
  269. package/src/capabilities/intent-resolver.ts +0 -468
  270. package/src/capabilities/react-root.tsx +0 -38
  271. package/src/capabilities/react-surface.tsx +0 -30
  272. package/src/capabilities/settings.ts +0 -26
  273. package/src/capabilities/state.ts +0 -104
  274. package/src/capabilities/tools.ts +0 -81
  275. package/src/capabilities/url-handler.ts +0 -59
  276. package/src/events.ts +0 -11
  277. /package/dist/lib/{browser/state-MVDYX77Y.mjs.map → node-esm/types/index.mjs.map} +0 -0
@@ -0,0 +1,38 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability, Common } from '@dxos/app-framework';
8
+ import { createKvsStore } from '@dxos/effect';
9
+
10
+ import { meta } from '../../meta';
11
+ import { DeckCapabilities, DeckSettingsSchema } from '../../types';
12
+
13
+ export default Capability.makeModule(() =>
14
+ Effect.sync(() => {
15
+ const settingsAtom = createKvsStore({
16
+ key: meta.id,
17
+ schema: DeckSettingsSchema,
18
+ defaultValue: () => ({
19
+ showHints: false,
20
+ enableDeck: false,
21
+ enableStatusbar: false,
22
+ enableNativeRedirect: false,
23
+ newPlankPositioning: 'start' as const,
24
+ overscroll: 'none' as const,
25
+ encapsulatedPlanks: false,
26
+ }),
27
+ });
28
+
29
+ return [
30
+ Capability.contributes(DeckCapabilities.Settings, settingsAtom),
31
+ Capability.contributes(Common.Capability.Settings, {
32
+ prefix: meta.id,
33
+ schema: DeckSettingsSchema,
34
+ atom: settingsAtom,
35
+ }),
36
+ ];
37
+ }),
38
+ );
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capability } from '@dxos/app-framework';
6
+
7
+ export const DeckState = Capability.lazy('DeckState', () => import('./state'));
@@ -0,0 +1,104 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Atom } from '@effect-atom/atom-react';
6
+ import * as Effect from 'effect/Effect';
7
+
8
+ import { Capability, Common } from '@dxos/app-framework';
9
+ import { createKvsStore } from '@dxos/effect';
10
+ import { invariant } from '@dxos/invariant';
11
+
12
+ import { meta } from '../../meta';
13
+ import {
14
+ DeckCapabilities,
15
+ type DeckEphemeralStateProps,
16
+ type DeckStateProps,
17
+ DeckStateSchema,
18
+ defaultDeck,
19
+ getMode,
20
+ } from '../../types';
21
+
22
+ /** Default persisted state. */
23
+ const defaultDeckState: DeckStateProps = {
24
+ sidebarState: 'expanded',
25
+ complementarySidebarState: 'collapsed',
26
+ complementarySidebarPanel: undefined,
27
+ activeDeck: 'default',
28
+ previousDeck: 'default',
29
+ decks: {
30
+ default: { ...defaultDeck },
31
+ },
32
+ previousMode: {},
33
+ };
34
+
35
+ /** Default ephemeral state. */
36
+ const defaultDeckEphemeralState: DeckEphemeralStateProps = {
37
+ dialogContent: null,
38
+ dialogOpen: false,
39
+ dialogBlockAlign: undefined,
40
+ dialogType: undefined,
41
+ popoverContent: null,
42
+ popoverAnchor: undefined,
43
+ popoverAnchorId: undefined,
44
+ popoverOpen: false,
45
+ toasts: [],
46
+ currentUndoId: undefined,
47
+ scrollIntoView: undefined,
48
+ };
49
+
50
+ export default Capability.makeModule(
51
+ Effect.fnUntraced(function* () {
52
+ const registry = yield* Capability.get(Common.Capability.AtomRegistry);
53
+
54
+ // Persisted state using KVS store.
55
+ const stateAtom = createKvsStore({
56
+ key: `${meta.id}/state`,
57
+ schema: DeckStateSchema,
58
+ defaultValue: () => ({ ...defaultDeckState }),
59
+ });
60
+
61
+ // Ephemeral state (not persisted, but kept alive to prevent GC resets).
62
+ const ephemeralAtom = Atom.make<DeckEphemeralStateProps>({ ...defaultDeckEphemeralState }).pipe(Atom.keepAlive);
63
+
64
+ // Don't allow fullscreen mode to be persisted to prevent getting stuck in it.
65
+ const currentState = registry.get(stateAtom);
66
+ const currentDeck = currentState.decks[currentState.activeDeck];
67
+ if (currentDeck?.fullscreen) {
68
+ registry.set(stateAtom, {
69
+ ...currentState,
70
+ decks: {
71
+ ...currentState.decks,
72
+ [currentState.activeDeck]: {
73
+ ...currentDeck,
74
+ fullscreen: false,
75
+ },
76
+ },
77
+ });
78
+ }
79
+
80
+ // Create derived layout atom (read-only) from both state atoms.
81
+ const layoutAtom = Atom.make((get) => {
82
+ const state = get(stateAtom);
83
+ const ephemeral = get(ephemeralAtom);
84
+ const deck = state.decks[state.activeDeck];
85
+ invariant(deck, `Deck not found: ${state.activeDeck}`);
86
+ return {
87
+ mode: getMode(deck),
88
+ dialogOpen: ephemeral.dialogOpen,
89
+ sidebarOpen: state.sidebarState === 'expanded',
90
+ complementarySidebarOpen: state.complementarySidebarState === 'expanded',
91
+ workspace: state.activeDeck,
92
+ active: deck.solo ? [deck.solo] : deck.active,
93
+ inactive: deck.inactive,
94
+ scrollIntoView: ephemeral.scrollIntoView,
95
+ } satisfies Common.Capability.Layout;
96
+ }).pipe(Atom.keepAlive);
97
+
98
+ return [
99
+ Capability.contributes(DeckCapabilities.State, stateAtom),
100
+ Capability.contributes(DeckCapabilities.EphemeralState, ephemeralAtom),
101
+ Capability.contributes(Common.Capability.Layout, layoutAtom),
102
+ ];
103
+ }),
104
+ );
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capability } from '@dxos/app-framework';
6
+
7
+ export const Toolkit = Capability.lazy('Toolkit', () => import('./toolkit'));
@@ -0,0 +1,63 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Tool from '@effect/ai/Tool';
6
+ import * as Toolkit from '@effect/ai/Toolkit';
7
+ import * as Effect from 'effect/Effect';
8
+ import * as Schema from 'effect/Schema';
9
+
10
+ import { Capability, type CapabilityManager, Common } from '@dxos/app-framework';
11
+ import { GenericToolkit } from '@dxos/assistant';
12
+ import { ArtifactId } from '@dxos/assistant';
13
+ import { type SpaceId } from '@dxos/keys';
14
+ import { trim } from '@dxos/util';
15
+
16
+ import { DeckCapabilities } from '../../types';
17
+
18
+ const Toolkit$ = Toolkit.make(
19
+ Tool.make('open-item', {
20
+ description: trim`
21
+ Opens an item in the application.
22
+ `,
23
+ parameters: {
24
+ id: ArtifactId,
25
+ },
26
+ success: Schema.Any,
27
+ failure: Schema.Never,
28
+ }),
29
+ );
30
+
31
+ export namespace DeckToolkit {
32
+ export const Toolkit = Toolkit$;
33
+
34
+ export const createLayer = (capabilityManager: CapabilityManager.CapabilityManager) =>
35
+ Toolkit$.toLayer({
36
+ 'open-item': ({ id }) =>
37
+ Effect.gen(function* () {
38
+ const registry = capabilityManager.get(Common.Capability.AtomRegistry);
39
+ const stateAtom = capabilityManager.get(DeckCapabilities.State);
40
+ const state = registry.get(stateAtom);
41
+ const dxn = ArtifactId.toDXN(id, state.activeDeck as SpaceId).asEchoDXN();
42
+ if (!dxn) {
43
+ // TODO(wittjosiah): Support other variants.
44
+ throw new Error(`Invalid object ID: ${id}`);
45
+ }
46
+
47
+ // TODO(wittjosiah): Get capabilities via layers.
48
+ const { invoke } = capabilityManager.get(Common.Capability.OperationInvoker);
49
+ yield* invoke(Common.LayoutOperation.Open, { subject: [`${dxn.spaceId!}:${dxn.echoId}`] });
50
+ }).pipe(Effect.orDie),
51
+ });
52
+ }
53
+
54
+ export default Capability.makeModule(
55
+ Effect.fnUntraced(function* () {
56
+ const capabilityManager = yield* Capability.Service;
57
+
58
+ return Capability.contributes(
59
+ Common.Capability.Toolkit,
60
+ GenericToolkit.make(DeckToolkit.Toolkit, DeckToolkit.createLayer(capabilityManager)),
61
+ );
62
+ }),
63
+ );
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capability } from '@dxos/app-framework';
6
+
7
+ export const Tools = Capability.lazy('Tools', () => import('./tools'));
@@ -0,0 +1,92 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ // ISSUE(burdon): tools
6
+ // @ts-nocheck
7
+
8
+ import * as Effect from 'effect/Effect';
9
+ import * as Schema from 'effect/Schema';
10
+
11
+ import {
12
+ Capabilities,
13
+ Capability,
14
+ LayoutAction,
15
+ type PromiseIntentDispatcher,
16
+ createIntent,
17
+ } from '@dxos/app-framework';
18
+ import { type OperationInvoker } from '@dxos/app-framework/plugin-operation/invoker';
19
+ import { invariant } from '@dxos/invariant';
20
+ import { trim } from '@dxos/util';
21
+
22
+ import { meta } from '../../meta';
23
+ import { DeckOperation } from '../../types';
24
+
25
+ // TODO(burdon): Factor out.
26
+ declare global {
27
+ interface ToolContextExtensions {
28
+ dispatch?: PromiseIntentDispatcher;
29
+ pivotId?: string;
30
+ part?: 'deck' | 'dialog';
31
+ }
32
+ }
33
+
34
+ export default Capability.makeModule(() =>
35
+ Effect.succeed(
36
+ Capability.contributes(Capabilities.Tools, [
37
+ createTool(meta.id, {
38
+ name: 'show',
39
+ description: trim`
40
+ Show an item as a companion to an existing plank.
41
+ When supplying IDs, they must be fully qualified like this: space-key:object-id
42
+ `,
43
+ caption: 'Showing item...',
44
+ // TODO(wittjosiah): Refactor Layout/Navigation/Deck actions so that they can be used directly.
45
+ schema: Schema.Struct({
46
+ id: Schema.String.annotations({
47
+ description: 'The ID of the item to show.',
48
+ }),
49
+ }),
50
+ execute: async ({ id }, { extensions }) => {
51
+ invariant(extensions);
52
+ const { pivotId, dispatch, invokePromise, part } = extensions as {
53
+ pivotId: string;
54
+ dispatch: PromiseIntentDispatcher;
55
+ invokePromise: OperationInvoker['invokePromise'];
56
+ part: string;
57
+ };
58
+ invariant(pivotId, 'No pivot ID');
59
+ invariant(invokePromise, 'No operation invoker');
60
+
61
+ if (part === 'deck') {
62
+ const { error } = await invokePromise(DeckOperation.ChangeCompanion, {
63
+ primary: pivotId,
64
+ companion: id,
65
+ });
66
+ if (error) {
67
+ return ToolResult.Error(error.message);
68
+ }
69
+
70
+ return ToolResult.Success({});
71
+ } else {
72
+ const { data, error } = await dispatch(
73
+ createIntent(LayoutAction.Open, {
74
+ subject: [id],
75
+ part: 'main',
76
+ options: {
77
+ pivotId,
78
+ positioning: 'end',
79
+ },
80
+ }),
81
+ );
82
+ if (error) {
83
+ return ToolResult.Error(error.message);
84
+ }
85
+
86
+ return ToolResult.Success(data);
87
+ }
88
+ },
89
+ }),
90
+ ]),
91
+ ),
92
+ );
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capability } from '@dxos/app-framework';
6
+
7
+ export const UrlHandler = Capability.lazy('UrlHandler', () => import('./url-handler'));
@@ -0,0 +1,95 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability, Common } from '@dxos/app-framework';
8
+ import { invariant } from '@dxos/invariant';
9
+
10
+ import { DeckCapabilities, type DeckStateProps, defaultDeck } from '../../types';
11
+
12
+ // TODO(wittjosiah): Cleanup the url handling. May justify introducing routing capabilities.
13
+ export default Capability.makeModule(
14
+ Effect.fnUntraced(function* () {
15
+ const { invokeSync } = yield* Capability.get(Common.Capability.OperationInvoker);
16
+ const registry = yield* Capability.get(Common.Capability.AtomRegistry);
17
+ const stateAtom = yield* Capability.get(DeckCapabilities.State);
18
+
19
+ // Helper to get state.
20
+ const getState = () => registry.get(stateAtom);
21
+
22
+ // Helper to get computed deck from state.
23
+ const getDeck = () => {
24
+ const state = getState();
25
+ const deck = state.decks[state.activeDeck];
26
+ invariant(deck, `Deck not found: ${state.activeDeck}`);
27
+ return deck;
28
+ };
29
+
30
+ // Helper to update state.
31
+ const updateState = (fn: (current: DeckStateProps) => DeckStateProps) => {
32
+ registry.set(stateAtom, fn(getState()));
33
+ };
34
+
35
+ const handleNavigation = () => {
36
+ const pathname = window.location.pathname;
37
+ const state = getState();
38
+ if (pathname === '/reset') {
39
+ updateState((s) => ({
40
+ ...s,
41
+ activeDeck: 'default',
42
+ decks: {
43
+ default: { ...defaultDeck },
44
+ },
45
+ }));
46
+ window.location.pathname = '/';
47
+ return;
48
+ }
49
+
50
+ const [_, nextDeck, nextSolo] = pathname.split('/');
51
+ if (nextDeck && nextDeck !== state.activeDeck) {
52
+ invokeSync(Common.LayoutOperation.SwitchWorkspace, { subject: nextDeck });
53
+ }
54
+
55
+ const deck = getDeck();
56
+ if (nextSolo && nextSolo !== deck.solo) {
57
+ invokeSync(Common.LayoutOperation.SetLayoutMode, { subject: nextSolo, mode: 'solo' });
58
+ } else if (!nextSolo && deck.solo) {
59
+ invokeSync(Common.LayoutOperation.SetLayoutMode, { mode: 'deck' });
60
+ }
61
+ };
62
+
63
+ yield* Effect.sync(() => handleNavigation());
64
+ window.addEventListener('popstate', handleNavigation);
65
+
66
+ // Subscribe to state changes to update the URL.
67
+ let lastSolo: string | undefined;
68
+ let lastActiveDeck: string | undefined;
69
+ const unsubscribe = registry.subscribe(stateAtom, () => {
70
+ const state = getState();
71
+ const deck = getDeck();
72
+ const solo = deck.solo;
73
+ const activeDeck = state.activeDeck;
74
+
75
+ // Only update URL if relevant state changed.
76
+ if (solo !== lastSolo || activeDeck !== lastActiveDeck) {
77
+ lastSolo = solo;
78
+ lastActiveDeck = activeDeck;
79
+
80
+ const path = solo ? `/${activeDeck}/${solo}` : `/${activeDeck}`;
81
+ if (window.location.pathname !== path) {
82
+ // TODO(thure): In some browsers, this only preserves the most recent state change, even though this is not `history.replace`…
83
+ history.pushState(null, '', `${path}${window.location.search}`);
84
+ }
85
+ }
86
+ });
87
+
88
+ return Capability.contributes(Common.Capability.Null, null, () =>
89
+ Effect.sync(() => {
90
+ window.removeEventListener('popstate', handleNavigation);
91
+ unsubscribe();
92
+ }),
93
+ );
94
+ }),
95
+ );
@@ -4,7 +4,7 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { Surface, useAppGraph } from '@dxos/app-framework';
7
+ import { Surface, useAppGraph } from '@dxos/app-framework/react';
8
8
  import { useNode } from '@dxos/plugin-graph';
9
9
  import { useAttended } from '@dxos/react-ui-attention';
10
10
 
@@ -4,15 +4,15 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { Surface } from '@dxos/app-framework';
8
- import { useTranslation, type ThemedClassName } from '@dxos/react-ui';
9
- import { mx } from '@dxos/react-ui-theme';
7
+ import { Surface } from '@dxos/app-framework/react';
8
+ import { type ThemedClassName, useTranslation } from '@dxos/react-ui';
9
+ import { mx, osTranslations } from '@dxos/ui-theme';
10
10
 
11
- import { DECK_PLUGIN } from '../../meta';
11
+ import { meta } from '../../meta';
12
12
  import { CloseSidebarButton, ToggleSidebarButton } from '../Sidebar';
13
13
 
14
14
  export const Banner = ({ variant, classNames }: ThemedClassName<{ variant?: 'topbar' | 'sidebar' }>) => {
15
- const { t } = useTranslation(DECK_PLUGIN);
15
+ const { t } = useTranslation(meta.id);
16
16
  return (
17
17
  <header
18
18
  className={mx(
@@ -23,7 +23,7 @@ export const Banner = ({ variant, classNames }: ThemedClassName<{ variant?: 'top
23
23
  )}
24
24
  >
25
25
  {variant === 'sidebar' ? <CloseSidebarButton /> : <ToggleSidebarButton />}
26
- <span className='self-center grow mis-1'>{t('current app name', { ns: 'appkit' })}</span>
26
+ <span className='self-center grow mis-1'>{t('current app name', { ns: osTranslations })}</span>
27
27
  {variant === 'topbar' && (
28
28
  <div role='none' className='absolute inset-0 pointer-events-none'>
29
29
  <div role='none' className='grid bs-full pointer-fine:p-1 max-is-md mli-auto pointer-events-auto'>
@@ -4,18 +4,17 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { Surface, useCapability } from '@dxos/app-framework';
7
+ import { Surface } from '@dxos/app-framework/react';
8
8
 
9
- import { DeckCapabilities } from '../../capabilities';
10
- import { useBreakpoints } from '../../hooks';
9
+ import { useBreakpoints, useDeckState } from '../../hooks';
11
10
  import { getMode } from '../../types';
12
11
  import { layoutAppliesTopbar } from '../../util';
13
- import { ToggleSidebarButton } from '../Sidebar';
14
12
  import { fixedSidebarToggleStyles } from '../fragments';
13
+ import { ToggleSidebarButton } from '../Sidebar';
15
14
 
16
15
  export const ContentEmpty = () => {
17
16
  const breakpoint = useBreakpoints();
18
- const { deck } = useCapability(DeckCapabilities.MutableDeckState);
17
+ const { deck } = useDeckState();
19
18
  const layoutMode = getMode(deck);
20
19
  const topbar = layoutAppliesTopbar(breakpoint, layoutMode);
21
20
  return (
@@ -0,0 +1,51 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React from 'react';
7
+
8
+ import { Capability, Common, Plugin } from '@dxos/app-framework';
9
+ import { withPluginManager } from '@dxos/app-framework/testing';
10
+ import { corePlugins } from '@dxos/plugin-testing';
11
+ import { withTheme } from '@dxos/react-ui/testing';
12
+
13
+ import { DeckState, LayoutOperationResolver } from '../../capabilities';
14
+ import { meta as pluginMeta } from '../../meta';
15
+ import { translations } from '../../translations';
16
+
17
+ import { DeckLayout } from './DeckLayout';
18
+
19
+ const TestPlugin = Plugin.define(pluginMeta).pipe(
20
+ Plugin.addModule({
21
+ id: Capability.getModuleTag(DeckState),
22
+ activatesOn: Common.ActivationEvent.AppGraphReady,
23
+ activate: () => DeckState(),
24
+ }),
25
+ Common.Plugin.addOperationResolverModule({
26
+ activate: LayoutOperationResolver,
27
+ }),
28
+ Plugin.make,
29
+ );
30
+
31
+ const meta = {
32
+ title: 'plugins/plugin-deck/DeckLayout',
33
+ component: DeckLayout,
34
+ render: (args) => <DeckLayout {...args} />,
35
+ decorators: [
36
+ withTheme,
37
+ withPluginManager({
38
+ plugins: [...corePlugins(), TestPlugin()],
39
+ }),
40
+ ],
41
+ parameters: {
42
+ layout: 'fullscreen',
43
+ translations,
44
+ },
45
+ } satisfies Meta<typeof DeckLayout>;
46
+
47
+ export default meta;
48
+
49
+ type Story = StoryObj<typeof meta>;
50
+
51
+ export const Default: Story = {};