@dxos/plugin-client 0.8.4-main.1da679c → 0.8.4-main.21d9917

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 (400) hide show
  1. package/dist/lib/browser/app-graph-builder-3FGBMLTF.mjs +118 -0
  2. package/dist/lib/browser/app-graph-builder-3FGBMLTF.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-4BZGRIFS.mjs +293 -0
  4. package/dist/lib/browser/chunk-4BZGRIFS.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-F7H2Y3Z2.mjs +18 -0
  6. package/dist/lib/browser/chunk-F7H2Y3Z2.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-G7C3S2BE.mjs +15 -0
  8. package/dist/lib/browser/chunk-G7C3S2BE.mjs.map +7 -0
  9. package/dist/lib/browser/cli/index.mjs +1048 -0
  10. package/dist/lib/browser/cli/index.mjs.map +7 -0
  11. package/dist/lib/browser/client-IX5LMWV4.mjs +86 -0
  12. package/dist/lib/browser/client-IX5LMWV4.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +75 -81
  14. package/dist/lib/browser/index.mjs.map +4 -4
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/migrations-3EBTAW3N.mjs +24 -0
  17. package/dist/lib/browser/migrations-3EBTAW3N.mjs.map +7 -0
  18. package/dist/lib/browser/operation-resolver-2NT3ISVP.mjs +298 -0
  19. package/dist/lib/browser/operation-resolver-2NT3ISVP.mjs.map +7 -0
  20. package/dist/lib/browser/react-context-4UABG3GP.mjs +24 -0
  21. package/dist/lib/browser/react-context-4UABG3GP.mjs.map +7 -0
  22. package/dist/lib/browser/react-surface-RSQ74XCT.mjs +675 -0
  23. package/dist/lib/browser/react-surface-RSQ74XCT.mjs.map +7 -0
  24. package/dist/lib/browser/schema-defs-O7VLP745.mjs +26 -0
  25. package/dist/lib/browser/schema-defs-O7VLP745.mjs.map +7 -0
  26. package/dist/lib/browser/types/index.mjs +9 -4
  27. package/dist/lib/node-esm/app-graph-builder-2PIYVUNC.mjs +119 -0
  28. package/dist/lib/node-esm/app-graph-builder-2PIYVUNC.mjs.map +7 -0
  29. package/dist/lib/node-esm/chunk-BCELGXRI.mjs +20 -0
  30. package/dist/lib/node-esm/chunk-BCELGXRI.mjs.map +7 -0
  31. package/dist/lib/node-esm/chunk-JAF64TFQ.mjs +295 -0
  32. package/dist/lib/node-esm/chunk-JAF64TFQ.mjs.map +7 -0
  33. package/dist/lib/node-esm/chunk-PRAFFO54.mjs +16 -0
  34. package/dist/lib/node-esm/chunk-PRAFFO54.mjs.map +7 -0
  35. package/dist/lib/node-esm/cli/index.mjs +1049 -0
  36. package/dist/lib/node-esm/cli/index.mjs.map +7 -0
  37. package/dist/lib/node-esm/client-FFPK5UFP.mjs +87 -0
  38. package/dist/lib/node-esm/client-FFPK5UFP.mjs.map +7 -0
  39. package/dist/lib/node-esm/index.mjs +75 -81
  40. package/dist/lib/node-esm/index.mjs.map +4 -4
  41. package/dist/lib/node-esm/meta.json +1 -1
  42. package/dist/lib/node-esm/migrations-WSZSFGDK.mjs +25 -0
  43. package/dist/lib/node-esm/migrations-WSZSFGDK.mjs.map +7 -0
  44. package/dist/lib/node-esm/operation-resolver-VW5R2BE4.mjs +299 -0
  45. package/dist/lib/node-esm/operation-resolver-VW5R2BE4.mjs.map +7 -0
  46. package/dist/lib/node-esm/react-context-UVXMGPW4.mjs +25 -0
  47. package/dist/lib/node-esm/react-context-UVXMGPW4.mjs.map +7 -0
  48. package/dist/lib/node-esm/react-surface-KBHANGGC.mjs +676 -0
  49. package/dist/lib/node-esm/react-surface-KBHANGGC.mjs.map +7 -0
  50. package/dist/lib/node-esm/schema-defs-QLRGBIKY.mjs +27 -0
  51. package/dist/lib/node-esm/schema-defs-QLRGBIKY.mjs.map +7 -0
  52. package/dist/lib/node-esm/types/index.mjs +9 -4
  53. package/dist/types/src/ClientPlugin.d.ts +2 -1
  54. package/dist/types/src/ClientPlugin.d.ts.map +1 -1
  55. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +6 -0
  56. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -0
  57. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +3 -0
  58. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +1 -0
  59. package/dist/types/src/capabilities/client/client.d.ts +8 -0
  60. package/dist/types/src/capabilities/client/client.d.ts.map +1 -0
  61. package/dist/types/src/capabilities/client/index.d.ts +17 -0
  62. package/dist/types/src/capabilities/client/index.d.ts.map +1 -0
  63. package/dist/types/src/capabilities/index.d.ts +7 -19
  64. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  65. package/dist/types/src/capabilities/migrations/index.d.ts +3 -0
  66. package/dist/types/src/capabilities/migrations/index.d.ts.map +1 -0
  67. package/dist/types/src/capabilities/migrations/migrations.d.ts +5 -0
  68. package/dist/types/src/capabilities/migrations/migrations.d.ts.map +1 -0
  69. package/dist/types/src/capabilities/operation-resolver/index.d.ts +5 -0
  70. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -0
  71. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +8 -0
  72. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -0
  73. package/dist/types/src/capabilities/react-context/index.d.ts +7 -0
  74. package/dist/types/src/capabilities/react-context/index.d.ts.map +1 -0
  75. package/dist/types/src/capabilities/react-context/react-context.d.ts +10 -0
  76. package/dist/types/src/capabilities/react-context/react-context.d.ts.map +1 -0
  77. package/dist/types/src/capabilities/react-surface/index.d.ts +5 -0
  78. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
  79. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +9 -0
  80. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
  81. package/dist/types/src/capabilities/schema-defs/index.d.ts +3 -0
  82. package/dist/types/src/capabilities/schema-defs/index.d.ts.map +1 -0
  83. package/dist/types/src/capabilities/schema-defs/schema-defs.d.ts +5 -0
  84. package/dist/types/src/capabilities/schema-defs/schema-defs.d.ts.map +1 -0
  85. package/dist/types/src/cli/commands/config/index.d.ts +5 -0
  86. package/dist/types/src/cli/commands/config/index.d.ts.map +1 -0
  87. package/dist/types/src/cli/commands/config/view.d.ts +5 -0
  88. package/dist/types/src/cli/commands/config/view.d.ts.map +1 -0
  89. package/dist/types/src/cli/commands/device/index.d.ts +7 -0
  90. package/dist/types/src/cli/commands/device/index.d.ts.map +1 -0
  91. package/dist/types/src/cli/commands/device/info/index.d.ts +2 -0
  92. package/dist/types/src/cli/commands/device/info/index.d.ts.map +1 -0
  93. package/dist/types/src/cli/commands/device/info/info.d.ts +7 -0
  94. package/dist/types/src/cli/commands/device/info/info.d.ts.map +1 -0
  95. package/dist/types/src/cli/commands/device/info/info.test.d.ts +2 -0
  96. package/dist/types/src/cli/commands/device/info/info.test.d.ts.map +1 -0
  97. package/dist/types/src/cli/commands/device/list/index.d.ts +2 -0
  98. package/dist/types/src/cli/commands/device/list/index.d.ts.map +1 -0
  99. package/dist/types/src/cli/commands/device/list/list.d.ts +7 -0
  100. package/dist/types/src/cli/commands/device/list/list.d.ts.map +1 -0
  101. package/dist/types/src/cli/commands/device/list/list.test.d.ts +2 -0
  102. package/dist/types/src/cli/commands/device/list/list.test.d.ts.map +1 -0
  103. package/dist/types/src/cli/commands/device/update/index.d.ts +2 -0
  104. package/dist/types/src/cli/commands/device/update/index.d.ts.map +1 -0
  105. package/dist/types/src/cli/commands/device/update/update.d.ts +11 -0
  106. package/dist/types/src/cli/commands/device/update/update.d.ts.map +1 -0
  107. package/dist/types/src/cli/commands/device/util.d.ts +16 -0
  108. package/dist/types/src/cli/commands/device/util.d.ts.map +1 -0
  109. package/dist/types/src/cli/commands/edge/index.d.ts +5 -0
  110. package/dist/types/src/cli/commands/edge/index.d.ts.map +1 -0
  111. package/dist/types/src/cli/commands/edge/status.d.ts +7 -0
  112. package/dist/types/src/cli/commands/edge/status.d.ts.map +1 -0
  113. package/dist/types/src/cli/commands/halo/create/create.d.ts +15 -0
  114. package/dist/types/src/cli/commands/halo/create/create.d.ts.map +1 -0
  115. package/dist/types/src/cli/commands/halo/create/create.test.d.ts +2 -0
  116. package/dist/types/src/cli/commands/halo/create/create.test.d.ts.map +1 -0
  117. package/dist/types/src/cli/commands/halo/create/index.d.ts +2 -0
  118. package/dist/types/src/cli/commands/halo/create/index.d.ts.map +1 -0
  119. package/dist/types/src/cli/commands/halo/credential/add/add.d.ts +13 -0
  120. package/dist/types/src/cli/commands/halo/credential/add/add.d.ts.map +1 -0
  121. package/dist/types/src/cli/commands/halo/credential/add/index.d.ts +2 -0
  122. package/dist/types/src/cli/commands/halo/credential/add/index.d.ts.map +1 -0
  123. package/dist/types/src/cli/commands/halo/credential/index.d.ts +12 -0
  124. package/dist/types/src/cli/commands/halo/credential/index.d.ts.map +1 -0
  125. package/dist/types/src/cli/commands/halo/credential/list/index.d.ts +2 -0
  126. package/dist/types/src/cli/commands/halo/credential/list/index.d.ts.map +1 -0
  127. package/dist/types/src/cli/commands/halo/credential/list/list.d.ts +19 -0
  128. package/dist/types/src/cli/commands/halo/credential/list/list.d.ts.map +1 -0
  129. package/dist/types/src/cli/commands/halo/credential/list/list.test.d.ts +2 -0
  130. package/dist/types/src/cli/commands/halo/credential/list/list.test.d.ts.map +1 -0
  131. package/dist/types/src/cli/commands/halo/identity/identity.d.ts +7 -0
  132. package/dist/types/src/cli/commands/halo/identity/identity.d.ts.map +1 -0
  133. package/dist/types/src/cli/commands/halo/identity/identity.test.d.ts +2 -0
  134. package/dist/types/src/cli/commands/halo/identity/identity.test.d.ts.map +1 -0
  135. package/dist/types/src/cli/commands/halo/identity/index.d.ts +2 -0
  136. package/dist/types/src/cli/commands/halo/identity/index.d.ts.map +1 -0
  137. package/dist/types/src/cli/commands/halo/index.d.ts +3 -0
  138. package/dist/types/src/cli/commands/halo/index.d.ts.map +1 -0
  139. package/dist/types/src/cli/commands/halo/join/index.d.ts +2 -0
  140. package/dist/types/src/cli/commands/halo/join/index.d.ts.map +1 -0
  141. package/dist/types/src/cli/commands/halo/join/join.d.ts +8 -0
  142. package/dist/types/src/cli/commands/halo/join/join.d.ts.map +1 -0
  143. package/dist/types/src/cli/commands/halo/join/join.test.d.ts +2 -0
  144. package/dist/types/src/cli/commands/halo/join/join.test.d.ts.map +1 -0
  145. package/dist/types/src/cli/commands/halo/keys/index.d.ts +2 -0
  146. package/dist/types/src/cli/commands/halo/keys/index.d.ts.map +1 -0
  147. package/dist/types/src/cli/commands/halo/keys/keys.d.ts +7 -0
  148. package/dist/types/src/cli/commands/halo/keys/keys.d.ts.map +1 -0
  149. package/dist/types/src/cli/commands/halo/keys/keys.test.d.ts +2 -0
  150. package/dist/types/src/cli/commands/halo/keys/keys.test.d.ts.map +1 -0
  151. package/dist/types/src/cli/commands/halo/recover/index.d.ts +2 -0
  152. package/dist/types/src/cli/commands/halo/recover/index.d.ts.map +1 -0
  153. package/dist/types/src/cli/commands/halo/recover/recover.d.ts +7 -0
  154. package/dist/types/src/cli/commands/halo/recover/recover.d.ts.map +1 -0
  155. package/dist/types/src/cli/commands/halo/recover/recover.test.d.ts +2 -0
  156. package/dist/types/src/cli/commands/halo/recover/recover.test.d.ts.map +1 -0
  157. package/dist/types/src/cli/commands/halo/seed/index.d.ts +2 -0
  158. package/dist/types/src/cli/commands/halo/seed/index.d.ts.map +1 -0
  159. package/dist/types/src/cli/commands/halo/seed/seed.d.ts +7 -0
  160. package/dist/types/src/cli/commands/halo/seed/seed.d.ts.map +1 -0
  161. package/dist/types/src/cli/commands/halo/share/index.d.ts +2 -0
  162. package/dist/types/src/cli/commands/halo/share/index.d.ts.map +1 -0
  163. package/dist/types/src/cli/commands/halo/share/share.d.ts +15 -0
  164. package/dist/types/src/cli/commands/halo/share/share.d.ts.map +1 -0
  165. package/dist/types/src/cli/commands/halo/update/index.d.ts +2 -0
  166. package/dist/types/src/cli/commands/halo/update/index.d.ts.map +1 -0
  167. package/dist/types/src/cli/commands/halo/update/update.d.ts +11 -0
  168. package/dist/types/src/cli/commands/halo/update/update.d.ts.map +1 -0
  169. package/dist/types/src/cli/commands/halo/update/update.test.d.ts +2 -0
  170. package/dist/types/src/cli/commands/halo/update/update.test.d.ts.map +1 -0
  171. package/dist/types/src/cli/commands/halo/util.d.ts +13 -0
  172. package/dist/types/src/cli/commands/halo/util.d.ts.map +1 -0
  173. package/dist/types/src/cli/commands/index.d.ts +6 -0
  174. package/dist/types/src/cli/commands/index.d.ts.map +1 -0
  175. package/dist/types/src/cli/commands/profile/create.d.ts +9 -0
  176. package/dist/types/src/cli/commands/profile/create.d.ts.map +1 -0
  177. package/dist/types/src/cli/commands/profile/delete.d.ts +8 -0
  178. package/dist/types/src/cli/commands/profile/delete.d.ts.map +1 -0
  179. package/dist/types/src/cli/commands/profile/import.d.ts +17 -0
  180. package/dist/types/src/cli/commands/profile/import.d.ts.map +1 -0
  181. package/dist/types/src/cli/commands/profile/index.d.ts +19 -0
  182. package/dist/types/src/cli/commands/profile/index.d.ts.map +1 -0
  183. package/dist/types/src/cli/commands/profile/inspect.d.ts +13 -0
  184. package/dist/types/src/cli/commands/profile/inspect.d.ts.map +1 -0
  185. package/dist/types/src/cli/commands/profile/list.d.ts +6 -0
  186. package/dist/types/src/cli/commands/profile/list.d.ts.map +1 -0
  187. package/dist/types/src/cli/commands/profile/reset.d.ts +8 -0
  188. package/dist/types/src/cli/commands/profile/reset.d.ts.map +1 -0
  189. package/dist/types/src/cli/commands/profile/util.d.ts +24 -0
  190. package/dist/types/src/cli/commands/profile/util.d.ts.map +1 -0
  191. package/dist/types/src/cli/index.d.ts +2 -0
  192. package/dist/types/src/cli/index.d.ts.map +1 -0
  193. package/dist/types/src/cli/plugin.d.ts +4 -0
  194. package/dist/types/src/cli/plugin.d.ts.map +1 -0
  195. package/dist/types/src/cli/testing/test-console.d.ts +37 -0
  196. package/dist/types/src/cli/testing/test-console.d.ts.map +1 -0
  197. package/dist/types/src/components/DevicesContainer.d.ts.map +1 -1
  198. package/dist/types/src/components/DevicesContainer.stories.d.ts +2 -50
  199. package/dist/types/src/components/DevicesContainer.stories.d.ts.map +1 -1
  200. package/dist/types/src/components/JoinDialog.d.ts +0 -1
  201. package/dist/types/src/components/JoinDialog.d.ts.map +1 -1
  202. package/dist/types/src/components/ProfileContainer.d.ts.map +1 -1
  203. package/dist/types/src/components/ProfileContainer.stories.d.ts +1 -48
  204. package/dist/types/src/components/ProfileContainer.stories.d.ts.map +1 -1
  205. package/dist/types/src/components/RecoveryCodeDialog.d.ts +0 -1
  206. package/dist/types/src/components/RecoveryCodeDialog.d.ts.map +1 -1
  207. package/dist/types/src/components/RecoveryCodeDialog.stories.d.ts +1 -48
  208. package/dist/types/src/components/RecoveryCodeDialog.stories.d.ts.map +1 -1
  209. package/dist/types/src/components/RecoveryCredentialsContainer.d.ts +1 -1
  210. package/dist/types/src/components/RecoveryCredentialsContainer.d.ts.map +1 -1
  211. package/dist/types/src/components/RecoveryCredentialsContainer.stories.d.ts +1 -49
  212. package/dist/types/src/components/RecoveryCredentialsContainer.stories.d.ts.map +1 -1
  213. package/dist/types/src/components/ResetDialog.d.ts +5 -3
  214. package/dist/types/src/components/ResetDialog.d.ts.map +1 -1
  215. package/dist/types/src/components/ResetDialog.stories.d.ts +3 -50
  216. package/dist/types/src/components/ResetDialog.stories.d.ts.map +1 -1
  217. package/dist/types/src/constants.d.ts +4 -0
  218. package/dist/types/src/constants.d.ts.map +1 -0
  219. package/dist/types/src/index.d.ts +3 -3
  220. package/dist/types/src/index.d.ts.map +1 -1
  221. package/dist/types/src/meta.d.ts +2 -3
  222. package/dist/types/src/meta.d.ts.map +1 -1
  223. package/dist/types/src/translations.d.ts +2 -48
  224. package/dist/types/src/translations.d.ts.map +1 -1
  225. package/dist/types/src/types/capabilities.d.ts +10 -0
  226. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  227. package/dist/types/src/types/events.d.ts +9 -0
  228. package/dist/types/src/types/events.d.ts.map +1 -0
  229. package/dist/types/src/types/index.d.ts +2 -0
  230. package/dist/types/src/types/index.d.ts.map +1 -1
  231. package/dist/types/src/types/schema.d.ts +164 -10
  232. package/dist/types/src/types/schema.d.ts.map +1 -1
  233. package/dist/types/tsconfig.tsbuildinfo +1 -1
  234. package/package.json +53 -39
  235. package/src/ClientPlugin.ts +39 -59
  236. package/src/capabilities/app-graph-builder/app-graph-builder.ts +95 -0
  237. package/src/capabilities/app-graph-builder/index.ts +7 -0
  238. package/src/capabilities/client/client.ts +75 -0
  239. package/src/capabilities/client/index.ts +7 -0
  240. package/src/capabilities/index.ts +7 -11
  241. package/src/capabilities/migrations/index.ts +7 -0
  242. package/src/capabilities/migrations/migrations.ts +30 -0
  243. package/src/capabilities/operation-resolver/index.ts +7 -0
  244. package/src/capabilities/operation-resolver/operation-resolver.ts +248 -0
  245. package/src/capabilities/react-context/index.ts +7 -0
  246. package/src/capabilities/react-context/react-context.tsx +25 -0
  247. package/src/capabilities/react-surface/index.ts +7 -0
  248. package/src/capabilities/react-surface/react-surface.tsx +74 -0
  249. package/src/capabilities/schema-defs/index.ts +7 -0
  250. package/src/capabilities/schema-defs/schema-defs.ts +35 -0
  251. package/src/cli/commands/config/index.ts +12 -0
  252. package/src/cli/commands/config/view.ts +26 -0
  253. package/src/cli/commands/device/index.ts +14 -0
  254. package/src/cli/commands/device/info/index.ts +5 -0
  255. package/src/cli/commands/device/info/info.test.ts +29 -0
  256. package/src/cli/commands/device/info/info.ts +50 -0
  257. package/src/cli/commands/device/list/index.ts +5 -0
  258. package/src/cli/commands/device/list/list.test.ts +31 -0
  259. package/src/cli/commands/device/list/list.ts +30 -0
  260. package/src/cli/commands/device/update/index.ts +5 -0
  261. package/src/cli/commands/device/update/update.ts +70 -0
  262. package/src/cli/commands/device/util.ts +55 -0
  263. package/src/cli/commands/edge/index.ts +12 -0
  264. package/src/cli/commands/edge/status.ts +45 -0
  265. package/src/cli/commands/halo/create/create.test.ts +52 -0
  266. package/src/cli/commands/halo/create/create.ts +75 -0
  267. package/src/cli/commands/halo/create/index.ts +5 -0
  268. package/src/cli/commands/halo/credential/add/add.ts +97 -0
  269. package/src/cli/commands/halo/credential/add/index.ts +5 -0
  270. package/src/cli/commands/halo/credential/index.ts +13 -0
  271. package/src/cli/commands/halo/credential/list/index.ts +5 -0
  272. package/src/cli/commands/halo/credential/list/list.test.ts +28 -0
  273. package/src/cli/commands/halo/credential/list/list.ts +118 -0
  274. package/src/cli/commands/halo/identity/identity.test.ts +40 -0
  275. package/src/cli/commands/halo/identity/identity.ts +46 -0
  276. package/src/cli/commands/halo/identity/index.ts +5 -0
  277. package/src/cli/commands/halo/index.ts +21 -0
  278. package/src/cli/commands/halo/join/index.ts +5 -0
  279. package/src/cli/commands/halo/join/join.test.ts +10 -0
  280. package/src/cli/commands/halo/join/join.ts +87 -0
  281. package/src/cli/commands/halo/keys/index.ts +5 -0
  282. package/src/cli/commands/halo/keys/keys.test.ts +29 -0
  283. package/src/cli/commands/halo/keys/keys.ts +42 -0
  284. package/src/cli/commands/halo/recover/index.ts +5 -0
  285. package/src/cli/commands/halo/recover/recover.test.ts +10 -0
  286. package/src/cli/commands/halo/recover/recover.ts +44 -0
  287. package/src/cli/commands/halo/seed/index.ts +5 -0
  288. package/src/cli/commands/halo/seed/seed.ts +38 -0
  289. package/src/cli/commands/halo/share/index.ts +5 -0
  290. package/src/cli/commands/halo/share/share.ts +97 -0
  291. package/src/cli/commands/halo/update/index.ts +5 -0
  292. package/src/cli/commands/halo/update/update.test.ts +29 -0
  293. package/src/cli/commands/halo/update/update.ts +69 -0
  294. package/src/cli/commands/halo/util.ts +18 -0
  295. package/src/cli/commands/index.ts +9 -0
  296. package/src/cli/commands/profile/create.ts +87 -0
  297. package/src/cli/commands/profile/delete.ts +33 -0
  298. package/src/cli/commands/profile/import.ts +101 -0
  299. package/src/cli/commands/profile/index.ts +17 -0
  300. package/src/cli/commands/profile/inspect.ts +64 -0
  301. package/src/cli/commands/profile/list.ts +54 -0
  302. package/src/cli/commands/profile/reset.ts +45 -0
  303. package/src/cli/commands/profile/util.ts +48 -0
  304. package/src/cli/index.ts +5 -0
  305. package/src/cli/plugin.ts +33 -0
  306. package/src/cli/testing/test-console.ts +88 -0
  307. package/src/components/DevicesContainer.stories.tsx +9 -10
  308. package/src/components/DevicesContainer.tsx +24 -25
  309. package/src/components/JoinDialog.tsx +15 -17
  310. package/src/components/ProfileContainer.stories.tsx +2 -4
  311. package/src/components/ProfileContainer.tsx +51 -37
  312. package/src/components/RecoveryCodeDialog.stories.tsx +2 -4
  313. package/src/components/RecoveryCodeDialog.tsx +5 -7
  314. package/src/components/RecoveryCredentialsContainer.stories.tsx +9 -10
  315. package/src/components/RecoveryCredentialsContainer.tsx +9 -11
  316. package/src/components/ResetDialog.stories.tsx +19 -13
  317. package/src/components/ResetDialog.tsx +19 -18
  318. package/src/constants.ts +9 -0
  319. package/src/index.ts +3 -3
  320. package/src/meta.ts +8 -5
  321. package/src/translations.ts +5 -2
  322. package/src/types/capabilities.ts +16 -0
  323. package/src/types/events.ts +15 -0
  324. package/src/types/index.ts +2 -0
  325. package/src/types/schema.ts +121 -8
  326. package/dist/lib/browser/app-graph-builder-MCGM4PFO.mjs +0 -123
  327. package/dist/lib/browser/app-graph-builder-MCGM4PFO.mjs.map +0 -7
  328. package/dist/lib/browser/chunk-3F2Q2RKC.mjs +0 -18
  329. package/dist/lib/browser/chunk-3F2Q2RKC.mjs.map +0 -7
  330. package/dist/lib/browser/chunk-CAF2COXW.mjs +0 -19
  331. package/dist/lib/browser/chunk-CAF2COXW.mjs.map +0 -7
  332. package/dist/lib/browser/chunk-FOCQEA72.mjs +0 -686
  333. package/dist/lib/browser/chunk-FOCQEA72.mjs.map +0 -7
  334. package/dist/lib/browser/chunk-GS3LDHYD.mjs +0 -12
  335. package/dist/lib/browser/chunk-GS3LDHYD.mjs.map +0 -7
  336. package/dist/lib/browser/chunk-HLWIF3AW.mjs +0 -110
  337. package/dist/lib/browser/chunk-HLWIF3AW.mjs.map +0 -7
  338. package/dist/lib/browser/client-H2RZI6UX.mjs +0 -43
  339. package/dist/lib/browser/client-H2RZI6UX.mjs.map +0 -7
  340. package/dist/lib/browser/intent-resolver-IE7KHWIY.mjs +0 -305
  341. package/dist/lib/browser/intent-resolver-IE7KHWIY.mjs.map +0 -7
  342. package/dist/lib/browser/migrations-CJY2LQHD.mjs +0 -23
  343. package/dist/lib/browser/migrations-CJY2LQHD.mjs.map +0 -7
  344. package/dist/lib/browser/react-context-TSUCH5YS.mjs +0 -24
  345. package/dist/lib/browser/react-context-TSUCH5YS.mjs.map +0 -7
  346. package/dist/lib/browser/react-surface-WQD43JR7.mjs +0 -66
  347. package/dist/lib/browser/react-surface-WQD43JR7.mjs.map +0 -7
  348. package/dist/lib/browser/schema-defs-TLXADNLY.mjs +0 -25
  349. package/dist/lib/browser/schema-defs-TLXADNLY.mjs.map +0 -7
  350. package/dist/lib/node-esm/app-graph-builder-BJPS5RD7.mjs +0 -124
  351. package/dist/lib/node-esm/app-graph-builder-BJPS5RD7.mjs.map +0 -7
  352. package/dist/lib/node-esm/chunk-IOGTQFLM.mjs +0 -19
  353. package/dist/lib/node-esm/chunk-IOGTQFLM.mjs.map +0 -7
  354. package/dist/lib/node-esm/chunk-JG6AFSFU.mjs +0 -111
  355. package/dist/lib/node-esm/chunk-JG6AFSFU.mjs.map +0 -7
  356. package/dist/lib/node-esm/chunk-MUWDSQ65.mjs +0 -687
  357. package/dist/lib/node-esm/chunk-MUWDSQ65.mjs.map +0 -7
  358. package/dist/lib/node-esm/chunk-SZLX4BVJ.mjs +0 -14
  359. package/dist/lib/node-esm/chunk-SZLX4BVJ.mjs.map +0 -7
  360. package/dist/lib/node-esm/chunk-UMO3ETDV.mjs +0 -20
  361. package/dist/lib/node-esm/chunk-UMO3ETDV.mjs.map +0 -7
  362. package/dist/lib/node-esm/client-AWF6PE6V.mjs +0 -44
  363. package/dist/lib/node-esm/client-AWF6PE6V.mjs.map +0 -7
  364. package/dist/lib/node-esm/intent-resolver-ZJ4E3NNT.mjs +0 -306
  365. package/dist/lib/node-esm/intent-resolver-ZJ4E3NNT.mjs.map +0 -7
  366. package/dist/lib/node-esm/migrations-X6RLWYR2.mjs +0 -24
  367. package/dist/lib/node-esm/migrations-X6RLWYR2.mjs.map +0 -7
  368. package/dist/lib/node-esm/react-context-M6G62KT3.mjs +0 -25
  369. package/dist/lib/node-esm/react-context-M6G62KT3.mjs.map +0 -7
  370. package/dist/lib/node-esm/react-surface-TXSWRGX7.mjs +0 -67
  371. package/dist/lib/node-esm/react-surface-TXSWRGX7.mjs.map +0 -7
  372. package/dist/lib/node-esm/schema-defs-4PGAJ4RQ.mjs +0 -26
  373. package/dist/lib/node-esm/schema-defs-4PGAJ4RQ.mjs.map +0 -7
  374. package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
  375. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
  376. package/dist/types/src/capabilities/capabilities.d.ts +0 -9
  377. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  378. package/dist/types/src/capabilities/client.d.ts +0 -9
  379. package/dist/types/src/capabilities/client.d.ts.map +0 -1
  380. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -8
  381. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  382. package/dist/types/src/capabilities/migrations.d.ts +0 -4
  383. package/dist/types/src/capabilities/migrations.d.ts.map +0 -1
  384. package/dist/types/src/capabilities/react-context.d.ts +0 -8
  385. package/dist/types/src/capabilities/react-context.d.ts.map +0 -1
  386. package/dist/types/src/capabilities/react-surface.d.ts +0 -8
  387. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  388. package/dist/types/src/capabilities/schema-defs.d.ts +0 -4
  389. package/dist/types/src/capabilities/schema-defs.d.ts.map +0 -1
  390. package/dist/types/src/events.d.ts +0 -8
  391. package/dist/types/src/events.d.ts.map +0 -1
  392. package/src/capabilities/app-graph-builder.ts +0 -114
  393. package/src/capabilities/capabilities.ts +0 -18
  394. package/src/capabilities/client.ts +0 -43
  395. package/src/capabilities/intent-resolver.ts +0 -251
  396. package/src/capabilities/migrations.ts +0 -25
  397. package/src/capabilities/react-context.tsx +0 -21
  398. package/src/capabilities/react-surface.tsx +0 -67
  399. package/src/capabilities/schema-defs.ts +0 -29
  400. package/src/events.ts +0 -15
@@ -0,0 +1,33 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Command from '@effect/cli/Command';
6
+ import * as Options from '@effect/cli/Options';
7
+ import * as FileSystem from '@effect/platform/FileSystem';
8
+ import * as Console from 'effect/Console';
9
+ import * as Effect from 'effect/Effect';
10
+ import * as Option from 'effect/Option';
11
+
12
+ import { CommandConfig, print } from '@dxos/cli-util';
13
+ import { DX_CONFIG, getProfilePath } from '@dxos/client-protocol';
14
+
15
+ import { printProfileDeleted } from './util';
16
+
17
+ export const del = Command.make(
18
+ 'delete',
19
+ {
20
+ name: Options.text('name').pipe(Options.withDescription('Profile name'), Options.optional),
21
+ },
22
+ Effect.fnUntraced(function* ({ name }) {
23
+ const { json } = yield* CommandConfig;
24
+ const fs = yield* FileSystem.FileSystem;
25
+ const profileName = name.pipe(Option.getOrElse(() => 'default'));
26
+ yield* fs.remove(`${getProfilePath(DX_CONFIG, profileName)}.yml`);
27
+ if (json) {
28
+ yield* Console.log(JSON.stringify({ name: profileName, deleted: true }, null, 2));
29
+ } else {
30
+ yield* Console.log(print(printProfileDeleted(profileName)));
31
+ }
32
+ }),
33
+ );
@@ -0,0 +1,101 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Command from '@effect/cli/Command';
6
+ import * as Options from '@effect/cli/Options';
7
+ import * as Prompt from '@effect/cli/Prompt';
8
+ import * as FileSystem from '@effect/platform/FileSystem';
9
+ import * as Path from '@effect/platform/Path';
10
+ import * as Console from 'effect/Console';
11
+ import * as Effect from 'effect/Effect';
12
+ import * as Option from 'effect/Option';
13
+
14
+ import { CommandConfig } from '@dxos/cli-util';
15
+ import { ConfigService } from '@dxos/config';
16
+ import { log } from '@dxos/log';
17
+ import type { Runtime } from '@dxos/protocols/proto/dxos/config';
18
+
19
+ export const handler = Effect.fn(function* ({
20
+ file,
21
+ dataDir,
22
+ force,
23
+ }: {
24
+ file: string;
25
+ dataDir: Option.Option<string>;
26
+ force: boolean;
27
+ }) {
28
+ const dataDirValue = Option.getOrUndefined(dataDir);
29
+ const { json, profile } = yield* CommandConfig;
30
+ const fs = yield* FileSystem.FileSystem;
31
+ const path = yield* Path.Path;
32
+ const config = yield* ConfigService;
33
+
34
+ const { createLevel, createStorageObjects, importProfileData, decodeProfileArchive } = yield* Effect.promise(
35
+ () => import('@dxos/client-services'),
36
+ );
37
+
38
+ let storageConfig: Runtime.Client.Storage;
39
+ if (!dataDirValue) {
40
+ if (!force) {
41
+ yield* Console.log(`Will overwrite profile: ${profile}`);
42
+ const confirmed = yield* Prompt.confirm({
43
+ message: `Delete all data? (Profile: ${profile})`,
44
+ initial: false,
45
+ }).pipe(Prompt.run);
46
+ if (!confirmed) {
47
+ return;
48
+ }
49
+ }
50
+ storageConfig = config.values.runtime!.client!.storage!;
51
+ } else {
52
+ const fullPath = path.resolve(dataDirValue);
53
+ yield* Console.log(`Importing into: ${fullPath}`);
54
+ storageConfig = {
55
+ persistent: true,
56
+ dataRoot: fullPath,
57
+ };
58
+ }
59
+
60
+ if (yield* fs.exists(storageConfig.dataRoot!)) {
61
+ log.error('data directory already exists', { path: storageConfig.dataRoot! });
62
+ if (json) {
63
+ yield* Console.log(JSON.stringify({ error: 'Data directory already exists' }, null, 2));
64
+ } else {
65
+ yield* Console.log('Data directory already exists.');
66
+ }
67
+ return;
68
+ }
69
+
70
+ const data = yield* fs.readFile(file);
71
+
72
+ const archive = decodeProfileArchive(data);
73
+ yield* Console.log(`Importing archive with ${archive.storage.length} entries`);
74
+
75
+ const { storage } = createStorageObjects(storageConfig);
76
+ const level = yield* Effect.tryPromise({
77
+ try: () => createLevel(storageConfig),
78
+ catch: (error) => new Error(`Failed to create level: ${error}`),
79
+ });
80
+
81
+ yield* Console.log('Beginning profile import...');
82
+ yield* Effect.tryPromise({
83
+ try: () => importProfileData({ storage, level }, archive),
84
+ catch: (error) => new Error(`Failed to import profile data: ${error}`),
85
+ });
86
+ yield* Console.log('Profile import complete');
87
+
88
+ if (json) {
89
+ yield* Console.log(JSON.stringify({ success: true, profile, entries: archive.storage.length }, null, 2));
90
+ }
91
+ });
92
+
93
+ export const importCommand = Command.make(
94
+ 'import',
95
+ {
96
+ file: Options.text('file').pipe(Options.withDescription('Archive filename.'), Options.withAlias('f')),
97
+ dataDir: Options.text('data-dir').pipe(Options.withDescription('Storage directory.'), Options.optional),
98
+ force: Options.boolean('force', { ifPresent: true }).pipe(Options.withDescription('Skip confirmation prompt.')),
99
+ },
100
+ handler,
101
+ ).pipe(Command.withDescription('Import profile.'));
@@ -0,0 +1,17 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Command from '@effect/cli/Command';
6
+
7
+ import { create } from './create';
8
+ import { del } from './delete';
9
+ import { importCommand } from './import';
10
+ import { inspect } from './inspect';
11
+ import { list } from './list';
12
+ import { reset } from './reset';
13
+
14
+ export const profile = Command.make('profile').pipe(
15
+ Command.withDescription('Profile commands.'),
16
+ Command.withSubcommands([create, del, importCommand, inspect, list, reset]),
17
+ );
@@ -0,0 +1,64 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Command from '@effect/cli/Command';
6
+ import * as Options from '@effect/cli/Options';
7
+ import * as FileSystem from '@effect/platform/FileSystem';
8
+ import * as Console from 'effect/Console';
9
+ import * as Effect from 'effect/Effect';
10
+
11
+ import { CommandConfig, FormBuilder, print } from '@dxos/cli-util';
12
+ import { ProfileArchiveEntryType } from '@dxos/protocols';
13
+ import { arrayToBuffer } from '@dxos/util';
14
+
15
+ export const handler = Effect.fn(function* ({ file, storage }: { file: string; storage: boolean }) {
16
+ const { json } = yield* CommandConfig;
17
+ const fs = yield* FileSystem.FileSystem;
18
+
19
+ const { decodeProfileArchive } = yield* Effect.promise(() => import('@dxos/client-services'));
20
+
21
+ const data = yield* fs.readFile(file);
22
+
23
+ const archive = decodeProfileArchive(data);
24
+
25
+ if (json) {
26
+ yield* Console.log(
27
+ JSON.stringify(
28
+ {
29
+ meta: archive.meta,
30
+ ...(storage ? { storage: archive.storage } : {}),
31
+ },
32
+ null,
33
+ 2,
34
+ ),
35
+ );
36
+ } else {
37
+ const builder = FormBuilder.make({ title: 'Profile Archive' }).pipe(
38
+ FormBuilder.when(
39
+ archive.meta,
40
+ FormBuilder.each(Object.entries(archive.meta ?? {}), ([key, value]) => FormBuilder.set(key, String(value))),
41
+ ),
42
+ FormBuilder.build,
43
+ );
44
+ yield* Console.log(print(builder));
45
+
46
+ if (storage) {
47
+ yield* Console.log('\nStorage entries:\n');
48
+ for (const entry of archive.storage) {
49
+ const key =
50
+ typeof entry.key === 'string' ? entry.key : JSON.stringify(arrayToBuffer(entry.key).toString()).slice(1, -1);
51
+ yield* Console.log(` ${ProfileArchiveEntryType[entry.type]} ${key}`);
52
+ }
53
+ }
54
+ }
55
+ });
56
+
57
+ export const inspect = Command.make(
58
+ 'inspect',
59
+ {
60
+ file: Options.text('file').pipe(Options.withDescription('Archive filename.'), Options.withAlias('f')),
61
+ storage: Options.boolean('storage', { ifPresent: true }).pipe(Options.withDescription('List storage entries.')),
62
+ },
63
+ handler,
64
+ ).pipe(Command.withDescription('Inspect profile archive.'));
@@ -0,0 +1,54 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Command from '@effect/cli/Command';
6
+ import * as FileSystem from '@effect/platform/FileSystem';
7
+ import * as Path from '@effect/platform/Path';
8
+ import * as Console from 'effect/Console';
9
+ import * as Effect from 'effect/Effect';
10
+ import * as Yaml from 'yaml';
11
+
12
+ import { CommandConfig, printList } from '@dxos/cli-util';
13
+ import { Config } from '@dxos/client';
14
+ import { DX_CONFIG, DX_DATA, getProfilePath } from '@dxos/client-protocol';
15
+
16
+ import { printProfile } from './util';
17
+
18
+ export const list = Command.make(
19
+ 'list',
20
+ {},
21
+ Effect.fnUntraced(function* () {
22
+ const { profile: currentProfile } = yield* CommandConfig;
23
+ const fs = yield* FileSystem.FileSystem;
24
+ const path = yield* Path.Path;
25
+ const profileDir = path.join(DX_CONFIG, 'profile');
26
+ const files = yield* fs.readDirectory(profileDir);
27
+ const profiles = yield* Effect.forEach(
28
+ files,
29
+ Effect.fnUntraced(function* (filename) {
30
+ const ext = path.extname(filename);
31
+ const name = filename.slice(0, -ext.length);
32
+ const fullPath = path.join(DX_CONFIG, 'profile', filename);
33
+ const configContent = yield* fs.readFileString(fullPath);
34
+ const configValues = Yaml.parse(configContent);
35
+ const config = new Config(configValues);
36
+ return {
37
+ name,
38
+ isCurrent: name === currentProfile,
39
+ fullPath,
40
+ storagePath: getProfilePath(configValues?.runtime?.client?.storage.dataRoot ?? DX_DATA, name),
41
+ edge: config.values.runtime?.services?.edge?.url,
42
+ };
43
+ }),
44
+ );
45
+
46
+ const { json } = yield* CommandConfig;
47
+ if (json) {
48
+ yield* Console.log(JSON.stringify(profiles, null, 2));
49
+ } else {
50
+ const formatted = profiles.map(printProfile);
51
+ yield* Console.log(printList(formatted));
52
+ }
53
+ }),
54
+ );
@@ -0,0 +1,45 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Command from '@effect/cli/Command';
6
+ import * as Options from '@effect/cli/Options';
7
+ import * as Prompt from '@effect/cli/Prompt';
8
+ import * as FileSystem from '@effect/platform/FileSystem';
9
+ import * as Console from 'effect/Console';
10
+ import * as Effect from 'effect/Effect';
11
+
12
+ import { CommandConfig, print } from '@dxos/cli-util';
13
+ import { DX_DATA, getProfilePath } from '@dxos/client-protocol';
14
+ import { ConfigService } from '@dxos/config';
15
+
16
+ import { printProfileReset } from './util';
17
+
18
+ export const reset = Command.make(
19
+ 'reset',
20
+ {
21
+ force: Options.boolean('force', { ifPresent: true }).pipe(Options.withDescription('Skip confirmation prompt')),
22
+ },
23
+ Effect.fnUntraced(function* ({ force }) {
24
+ const fs = yield* FileSystem.FileSystem;
25
+ const config = yield* ConfigService;
26
+ const { json, profile } = yield* CommandConfig;
27
+ const path = config.values.runtime?.client?.storage?.dataRoot ?? getProfilePath(DX_DATA, profile);
28
+ if (!force) {
29
+ const confirmed = yield* Prompt.confirm({
30
+ message: `Are you sure you want to reset the profile (${profile})?`,
31
+ initial: false,
32
+ });
33
+ if (!confirmed) {
34
+ return;
35
+ }
36
+ }
37
+
38
+ yield* fs.remove(path, { recursive: true });
39
+ if (json) {
40
+ yield* Console.log(JSON.stringify({ profile, reset: true }, null, 2));
41
+ } else {
42
+ yield* Console.log(print(printProfileReset(profile)));
43
+ }
44
+ }),
45
+ );
@@ -0,0 +1,48 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { FormBuilder } from '@dxos/cli-util';
6
+
7
+ export type ProfileInfo = {
8
+ name: string;
9
+ isCurrent: boolean;
10
+ fullPath: string;
11
+ storagePath: string;
12
+ edge?: string;
13
+ };
14
+
15
+ /**
16
+ * Pretty prints profile creation result with ANSI colors.
17
+ */
18
+ export const printProfileCreated = (name: string, path: string) =>
19
+ FormBuilder.make({ title: 'Profile created' }).pipe(
20
+ FormBuilder.set('name', name),
21
+ FormBuilder.set('path', path),
22
+ FormBuilder.build,
23
+ );
24
+
25
+ /**
26
+ * Pretty prints profile deletion result with ANSI colors.
27
+ */
28
+ export const printProfileDeleted = (name: string) =>
29
+ FormBuilder.make({ title: 'Profile deleted' }).pipe(FormBuilder.set('name', name), FormBuilder.build);
30
+
31
+ /**
32
+ * Pretty prints profile reset result with ANSI colors.
33
+ */
34
+ export const printProfileReset = (profile: string) =>
35
+ FormBuilder.make({ title: 'Profile reset' }).pipe(FormBuilder.set('profile', profile), FormBuilder.build);
36
+
37
+ /**
38
+ * Pretty prints a profile with ANSI colors.
39
+ */
40
+ export const printProfile = (profile: ProfileInfo) => {
41
+ const title = profile.isCurrent ? `${profile.name} (current)` : profile.name;
42
+ return FormBuilder.make({ title }).pipe(
43
+ FormBuilder.set('fullPath', profile.fullPath),
44
+ FormBuilder.set('storagePath', profile.storagePath),
45
+ FormBuilder.set('edge', profile.edge ?? '<none>'),
46
+ FormBuilder.build,
47
+ );
48
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './plugin';
@@ -0,0 +1,33 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capability, Common, Plugin } from '@dxos/app-framework';
6
+
7
+ // NOTE: Must not import from index to avoid pulling in react dependencies.
8
+ import { Client } from '../capabilities/client';
9
+ import { OperationResolver } from '../capabilities/operation-resolver';
10
+ import { SchemaDefs } from '../capabilities/schema-defs';
11
+ import { meta } from '../meta';
12
+ import { ClientEvents } from '../types';
13
+ import { type ClientPluginOptions } from '../types';
14
+
15
+ import { config, device, edge, halo, profile } from './commands';
16
+
17
+ export const ClientPlugin = Plugin.define<ClientPluginOptions>(meta).pipe(
18
+ Plugin.addModule((options) => ({
19
+ id: Capability.getModuleTag(Client),
20
+ activatesOn: Common.ActivationEvent.Startup,
21
+ activatesAfter: [ClientEvents.ClientReady],
22
+ activate: () => Client(options),
23
+ })),
24
+ Plugin.addModule({
25
+ activatesOn: ClientEvents.ClientReady,
26
+ activatesBefore: [Common.ActivationEvent.SetupSchema],
27
+ activate: SchemaDefs,
28
+ }),
29
+ // TODO(wittjosiah): Could some of these commands make use of operations?
30
+ Common.Plugin.addCommandModule({ commands: [config, device, edge, halo, profile] }),
31
+ Common.Plugin.addOperationResolverModule({ activate: () => OperationResolver() }),
32
+ Plugin.make,
33
+ );
@@ -0,0 +1,88 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { inspect } from 'node:util';
6
+
7
+ import * as Console from 'effect/Console';
8
+ import * as Context from 'effect/Context';
9
+ import * as Effect from 'effect/Effect';
10
+ import * as Layer from 'effect/Layer';
11
+
12
+ function logToString(...args: any[]): string {
13
+ return args
14
+ .map((arg) => {
15
+ if (typeof arg === 'string') {
16
+ return arg;
17
+ }
18
+
19
+ return inspect(arg, { colors: false, depth: null });
20
+ })
21
+ .join(' ');
22
+ }
23
+
24
+ class TestConsoleService {
25
+ private _logs: Array<{ level: string; args: unknown; message: string }> = [];
26
+
27
+ readonly console: Console.Console;
28
+
29
+ constructor(console: Console.Console) {
30
+ const pusher =
31
+ (level: string) =>
32
+ (...args: readonly any[]) => {
33
+ this._logs.push({ level, args, message: logToString(...args) });
34
+ };
35
+
36
+ this.console = {
37
+ ...console,
38
+ log: (...args: readonly any[]) => Effect.sync(() => pusher('log')(...args)),
39
+ };
40
+ }
41
+
42
+ get logs() {
43
+ return [...this._logs];
44
+ }
45
+
46
+ clear() {
47
+ this._logs.length = 0;
48
+ }
49
+ }
50
+
51
+ // TODO(burdon): We could have a single namespace "Testing" with all test utilities.
52
+ export namespace TestConsole {
53
+ export class TestConsole extends Context.Tag('TestConsole')<TestConsole, TestConsoleService>() {}
54
+
55
+ /**
56
+ * Extract JSON string from log arguments.
57
+ * Handles both array and string argument formats.
58
+ */
59
+ export const extractJsonString = (log: { args: unknown }): string => {
60
+ if (Array.isArray(log.args) && log.args.length > 0) {
61
+ return String(log.args[0]);
62
+ }
63
+ return log.args as string;
64
+ };
65
+
66
+ /**
67
+ * Parse JSON from log arguments.
68
+ * Handles both array and string argument formats.
69
+ */
70
+ export const parseJson = <T = unknown>(log: { args: unknown }): T => {
71
+ const jsonString = extractJsonString(log);
72
+ return JSON.parse(jsonString) as T;
73
+ };
74
+
75
+ const testConsole = Layer.effect(
76
+ TestConsole,
77
+ Effect.gen(function* () {
78
+ return new TestConsoleService(yield* Effect.console);
79
+ }),
80
+ );
81
+
82
+ const setConsole = Effect.gen(function* () {
83
+ const { console } = yield* TestConsole;
84
+ return Console.setConsole(console);
85
+ }).pipe(Layer.unwrapEffect);
86
+
87
+ export const layer = Layer.provideMerge(setConsole, testConsole);
88
+ }
@@ -2,14 +2,13 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import * as Effect from 'effect/Effect';
8
7
 
9
- import { IntentPlugin } from '@dxos/app-framework';
8
+ import { OperationPlugin } from '@dxos/app-framework';
10
9
  import { withPluginManager } from '@dxos/app-framework/testing';
10
+ import { withTheme } from '@dxos/react-ui/testing';
11
11
  import { translations as shellTranslations } from '@dxos/shell/react';
12
- import { withLayout, withTheme } from '@dxos/storybook-utils';
13
12
 
14
13
  import { ClientPlugin } from '../ClientPlugin';
15
14
  import { translations } from '../translations';
@@ -20,18 +19,18 @@ const meta = {
20
19
  title: 'plugins/plugin-client/DevicesContainer',
21
20
  component: DevicesContainer,
22
21
  decorators: [
22
+ withTheme,
23
23
  withPluginManager({
24
24
  plugins: [
25
25
  ClientPlugin({
26
- onClientInitialized: async ({ client }) => {
27
- await client.halo.createIdentity();
28
- },
26
+ onClientInitialized: ({ client }) =>
27
+ Effect.gen(function* () {
28
+ yield* Effect.promise(() => client.halo.createIdentity());
29
+ }),
29
30
  }),
30
- IntentPlugin(),
31
+ OperationPlugin(),
31
32
  ],
32
33
  }),
33
- withTheme,
34
- withLayout(),
35
34
  ],
36
35
  parameters: {
37
36
  layout: 'fullscreen',
@@ -5,7 +5,7 @@
5
5
  import React, { useCallback, useEffect, useState } from 'react';
6
6
  import { QR } from 'react-qr-rounded';
7
7
 
8
- import { createIntent, useIntentDispatcher } from '@dxos/app-framework';
8
+ import { useOperationInvoker } from '@dxos/app-framework/react';
9
9
  import { log } from '@dxos/log';
10
10
  import { useClient, useMulticastObservable } from '@dxos/react-client';
11
11
  import { type Device, useDevices } from '@dxos/react-client/halo';
@@ -20,43 +20,45 @@ import {
20
20
  ControlPage,
21
21
  ControlSection,
22
22
  } from '@dxos/react-ui-form';
23
+ import { translationKey } from '@dxos/shell/react';
23
24
  import { AuthCode, Centered, DeviceListItem, Emoji, Viewport } from '@dxos/shell/react';
25
+ import { osTranslations } from '@dxos/ui-theme';
24
26
  import { hexToEmoji } from '@dxos/util';
25
27
 
26
- import { CLIENT_PLUGIN } from '../meta';
27
- import { ClientAction } from '../types';
28
+ import { meta } from '../meta';
29
+ import { ClientOperation } from '../types';
28
30
 
29
31
  export type DevicesContainerProps = {
30
32
  createInvitationUrl?: (invitationCode: string) => string;
31
33
  };
32
34
 
33
35
  export const DevicesContainer = ({ createInvitationUrl }: DevicesContainerProps) => {
34
- const { t } = useTranslation('os');
35
- const { dispatchPromise: dispatch } = useIntentDispatcher();
36
+ const { t } = useTranslation(translationKey);
37
+ const { invokePromise } = useOperationInvoker();
36
38
  const devices = useDevices();
37
39
  const { swarm: connectionState } = useNetworkStatus();
38
40
 
39
- const handleResetStorage = useCallback(() => dispatch(createIntent(ClientAction.ResetStorage)), [dispatch]);
41
+ const handleResetStorage = useCallback(() => invokePromise(ClientOperation.ResetStorage, {}), [invokePromise]);
40
42
 
41
43
  const handleRecover = useCallback(
42
- () => dispatch(createIntent(ClientAction.ResetStorage, { mode: 'recover' })),
43
- [dispatch],
44
+ () => invokePromise(ClientOperation.ResetStorage, { mode: 'recover' }),
45
+ [invokePromise],
44
46
  );
45
47
 
46
48
  const handleJoinNewIdentity = useCallback(
47
- () => dispatch(createIntent(ClientAction.ResetStorage, { mode: 'join new identity' })),
48
- [dispatch],
49
+ () => invokePromise(ClientOperation.ResetStorage, { mode: 'join new identity' }),
50
+ [invokePromise],
49
51
  );
50
52
 
51
53
  return (
52
54
  <Clipboard.Provider>
53
55
  <ControlPage>
54
56
  <ControlSection
55
- title={t('devices verbose label', { ns: CLIENT_PLUGIN })}
56
- description={t('devices description', { ns: CLIENT_PLUGIN })}
57
+ title={t('devices verbose label', { ns: meta.id })}
58
+ description={t('devices description', { ns: meta.id })}
57
59
  >
58
60
  <ControlFrame>
59
- <ControlFrameItem title={t('devices label', { ns: CLIENT_PLUGIN })}>
61
+ <ControlFrameItem title={t('devices label', { ns: meta.id })}>
60
62
  <List>
61
63
  {devices.map((device: Device) => {
62
64
  return (
@@ -73,21 +75,18 @@ export const DevicesContainer = ({ createInvitationUrl }: DevicesContainerProps)
73
75
  </ControlFrame>
74
76
  </ControlSection>
75
77
  <ControlSection
76
- title={t('danger zone title', { ns: CLIENT_PLUGIN })}
77
- description={t('danger zone description', { ns: CLIENT_PLUGIN })}
78
+ title={t('danger zone title', { ns: meta.id })}
79
+ description={t('danger zone description', { ns: meta.id })}
78
80
  >
79
81
  <ControlGroup>
80
- <ControlItem
81
- title={t('reset device label')}
82
- description={t('reset device description', { ns: CLIENT_PLUGIN })}
83
- >
82
+ <ControlItem title={t('reset device label')} description={t('reset device description', { ns: meta.id })}>
84
83
  <Button variant='destructive' onClick={handleResetStorage} data-testid='devicesContainer.reset'>
85
84
  {t('reset device label')}
86
85
  </Button>
87
86
  </ControlItem>
88
87
  <ControlItem
89
88
  title={t('recover identity label')}
90
- description={t('recover identity description', { ns: CLIENT_PLUGIN })}
89
+ description={t('recover identity description', { ns: meta.id })}
91
90
  >
92
91
  <Button variant='destructive' onClick={handleRecover} data-testid='devicesContainer.recover'>
93
92
  {t('recover identity label')}
@@ -95,7 +94,7 @@ export const DevicesContainer = ({ createInvitationUrl }: DevicesContainerProps)
95
94
  </ControlItem>
96
95
  <ControlItem
97
96
  title={t('join new identity label')}
98
- description={t('join new identity description', { ns: CLIENT_PLUGIN })}
97
+ description={t('join new identity description', { ns: meta.id })}
99
98
  >
100
99
  <Button variant='destructive' onClick={handleJoinNewIdentity} data-testid='devicesContainer.joinExisting'>
101
100
  {t('join new identity label')}
@@ -178,7 +177,7 @@ const InvitationSection = ({
178
177
  onInvitationDone = () => {},
179
178
  onInvitationCreate = () => {},
180
179
  }: InvitationComponentProps) => {
181
- const { t } = useTranslation(CLIENT_PLUGIN);
180
+ const { t } = useTranslation(meta.id);
182
181
  const activeView =
183
182
  state < 0
184
183
  ? 'init'
@@ -220,12 +219,12 @@ const InvitationSection = ({
220
219
  };
221
220
 
222
221
  const InvitationQR = ({ id, url, onCancel }: { id: string; url: string; onCancel: () => void }) => {
223
- const { t } = useTranslation('os');
222
+ const { t } = useTranslation(osTranslations);
224
223
  const qrLabel = useId('devices-container__qr-code');
225
224
  const emoji = hexToEmoji(id);
226
225
  return (
227
226
  <>
228
- <p className='text-description'>{t('qr code description', { ns: CLIENT_PLUGIN })}</p>
227
+ <p className='text-description'>{t('qr code description', { ns: meta.id })}</p>
229
228
  <div role='group' className='grid grid-cols-[1fr_min-content] mlb-2 gap-2'>
230
229
  <div role='none' className='is-full aspect-square relative text-description'>
231
230
  <QR
@@ -260,7 +259,7 @@ const InvitationQR = ({ id, url, onCancel }: { id: string; url: string; onCancel
260
259
  };
261
260
 
262
261
  const InvitationAuthCode = ({ id, code, onCancel }: { id: string; code: string; onCancel: () => void }) => {
263
- const { t } = useTranslation('os');
262
+ const { t } = useTranslation(osTranslations);
264
263
  const emoji = hexToEmoji(id);
265
264
 
266
265
  return (