@dxos/plugin-registry 0.8.4-main.422d1c7879 → 0.8.4-main.4f23b4e393

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 (193) hide show
  1. package/dist/lib/neutral/RegistryPlugin.mjs +27 -0
  2. package/dist/lib/neutral/RegistryPlugin.mjs.map +7 -0
  3. package/dist/lib/{browser/cli/index.mjs → neutral/RegistryPlugin.node.mjs} +29 -95
  4. package/dist/lib/neutral/RegistryPlugin.node.mjs.map +7 -0
  5. package/dist/lib/neutral/chunk-XK2JMH3H.mjs +33 -0
  6. package/dist/lib/neutral/chunk-XK2JMH3H.mjs.map +7 -0
  7. package/dist/lib/neutral/chunk-YV7A523U.mjs +29 -0
  8. package/dist/lib/neutral/chunk-YV7A523U.mjs.map +7 -0
  9. package/dist/lib/neutral/index.mjs +21 -0
  10. package/dist/lib/neutral/index.mjs.map +7 -0
  11. package/dist/lib/neutral/meta.json +1 -0
  12. package/dist/lib/neutral/open-plugin-registry-II735N76.mjs +15 -0
  13. package/dist/lib/neutral/open-plugin-registry-II735N76.mjs.map +7 -0
  14. package/dist/lib/neutral/plugin.mjs +18 -0
  15. package/dist/lib/neutral/plugin.mjs.map +7 -0
  16. package/dist/lib/neutral/translations.mjs +61 -0
  17. package/dist/lib/neutral/translations.mjs.map +7 -0
  18. package/dist/types/src/RegistryPlugin.d.ts +1 -0
  19. package/dist/types/src/RegistryPlugin.d.ts.map +1 -1
  20. package/dist/types/src/{cli/plugin.d.ts → RegistryPlugin.node.d.ts} +2 -1
  21. package/dist/types/src/RegistryPlugin.node.d.ts.map +1 -0
  22. package/dist/types/src/RegistryPlugin.test.d.ts +2 -0
  23. package/dist/types/src/RegistryPlugin.test.d.ts.map +1 -0
  24. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  25. package/dist/types/src/capabilities/dev-plugin-loader.d.ts +11 -0
  26. package/dist/types/src/capabilities/dev-plugin-loader.d.ts.map +1 -0
  27. package/dist/types/src/capabilities/index.d.ts +11 -2
  28. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  29. package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
  30. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -1
  31. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  32. package/dist/types/src/capabilities/settings.d.ts +14 -0
  33. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  34. package/dist/types/src/{cli/commands → commands}/disable.d.ts +2 -2
  35. package/dist/types/src/commands/disable.d.ts.map +1 -0
  36. package/dist/types/src/{cli/commands → commands}/enable.d.ts +2 -2
  37. package/dist/types/src/commands/enable.d.ts.map +1 -0
  38. package/dist/types/src/commands/index.d.ts.map +1 -0
  39. package/dist/types/src/commands/list.d.ts +7 -0
  40. package/dist/types/src/commands/list.d.ts.map +1 -0
  41. package/dist/types/src/commands/util.d.ts.map +1 -0
  42. package/dist/types/src/components/PluginDetail/PluginDetail.d.ts +26 -2
  43. package/dist/types/src/components/PluginDetail/PluginDetail.d.ts.map +1 -1
  44. package/dist/types/src/components/PluginDetail/PluginDetail.stories.d.ts +49 -23
  45. package/dist/types/src/components/PluginDetail/PluginDetail.stories.d.ts.map +1 -1
  46. package/dist/types/src/components/PluginFailureBadge/PluginFailureBadge.d.ts +20 -0
  47. package/dist/types/src/components/PluginFailureBadge/PluginFailureBadge.d.ts.map +1 -0
  48. package/dist/types/src/components/PluginFailureBadge/index.d.ts +2 -0
  49. package/dist/types/src/components/PluginFailureBadge/index.d.ts.map +1 -0
  50. package/dist/types/src/components/PluginList/PluginItem.d.ts +17 -3
  51. package/dist/types/src/components/PluginList/PluginItem.d.ts.map +1 -1
  52. package/dist/types/src/components/PluginList/PluginList.d.ts +14 -4
  53. package/dist/types/src/components/PluginList/PluginList.d.ts.map +1 -1
  54. package/dist/types/src/components/PluginList/PluginList.stories.d.ts +49 -23
  55. package/dist/types/src/components/PluginList/PluginList.stories.d.ts.map +1 -1
  56. package/dist/types/src/components/RegistrySettings/RegistrySettings.d.ts +18 -0
  57. package/dist/types/src/components/RegistrySettings/RegistrySettings.d.ts.map +1 -0
  58. package/dist/types/src/components/RegistrySettings/index.d.ts +2 -0
  59. package/dist/types/src/components/RegistrySettings/index.d.ts.map +1 -0
  60. package/dist/types/src/components/index.d.ts +2 -0
  61. package/dist/types/src/components/index.d.ts.map +1 -1
  62. package/dist/types/src/containers/BaseRegistryArticle/BaseRegistryArticle.d.ts +20 -0
  63. package/dist/types/src/containers/BaseRegistryArticle/BaseRegistryArticle.d.ts.map +1 -0
  64. package/dist/types/src/containers/BaseRegistryArticle/index.d.ts +2 -0
  65. package/dist/types/src/containers/BaseRegistryArticle/index.d.ts.map +1 -0
  66. package/dist/types/src/containers/LoadPluginDialog/LoadPluginDialog.d.ts.map +1 -1
  67. package/dist/types/src/containers/PluginArticle/PluginArticle.d.ts.map +1 -1
  68. package/dist/types/src/containers/PublicRegistryArticle/PublicRegistryArticle.d.ts +8 -0
  69. package/dist/types/src/containers/PublicRegistryArticle/PublicRegistryArticle.d.ts.map +1 -0
  70. package/dist/types/src/containers/PublicRegistryArticle/index.d.ts +2 -0
  71. package/dist/types/src/containers/PublicRegistryArticle/index.d.ts.map +1 -0
  72. package/dist/types/src/containers/RegistryArticle/RegistryArticle.d.ts +14 -0
  73. package/dist/types/src/containers/RegistryArticle/RegistryArticle.d.ts.map +1 -0
  74. package/dist/types/src/containers/RegistryArticle/index.d.ts +2 -0
  75. package/dist/types/src/containers/RegistryArticle/index.d.ts.map +1 -0
  76. package/dist/types/src/containers/RegistrySettingsContainer/RegistrySettingsContainer.d.ts +13 -0
  77. package/dist/types/src/containers/RegistrySettingsContainer/RegistrySettingsContainer.d.ts.map +1 -0
  78. package/dist/types/src/containers/RegistrySettingsContainer/index.d.ts +2 -0
  79. package/dist/types/src/containers/RegistrySettingsContainer/index.d.ts.map +1 -0
  80. package/dist/types/src/containers/index.d.ts +3 -2
  81. package/dist/types/src/containers/index.d.ts.map +1 -1
  82. package/dist/types/src/hooks/index.d.ts +2 -1
  83. package/dist/types/src/hooks/index.d.ts.map +1 -1
  84. package/dist/types/src/hooks/use-auto-tags.d.ts +4 -4
  85. package/dist/types/src/hooks/use-auto-tags.d.ts.map +1 -1
  86. package/dist/types/src/hooks/use-registry-plugins.d.ts +15 -0
  87. package/dist/types/src/hooks/use-registry-plugins.d.ts.map +1 -0
  88. package/dist/types/src/hooks/use-update-available.d.ts +18 -0
  89. package/dist/types/src/hooks/use-update-available.d.ts.map +1 -0
  90. package/dist/types/src/index.d.ts +1 -1
  91. package/dist/types/src/index.d.ts.map +1 -1
  92. package/dist/types/src/meta.d.ts.map +1 -1
  93. package/dist/types/src/operations/index.d.ts +1 -1
  94. package/dist/types/src/operations/index.d.ts.map +1 -1
  95. package/dist/types/src/operations/open-plugin-registry.d.ts +1 -1
  96. package/dist/types/src/operations/open-plugin-registry.d.ts.map +1 -1
  97. package/dist/types/src/plugin.d.ts +4 -0
  98. package/dist/types/src/plugin.d.ts.map +1 -0
  99. package/dist/types/src/{cli/storage.d.ts → storage.d.ts} +1 -1
  100. package/dist/types/src/storage.d.ts.map +1 -0
  101. package/dist/types/src/translations.d.ts +48 -23
  102. package/dist/types/src/translations.d.ts.map +1 -1
  103. package/dist/types/src/types.d.ts +28 -10
  104. package/dist/types/src/types.d.ts.map +1 -1
  105. package/dist/types/tsconfig.tsbuildinfo +1 -1
  106. package/package.json +46 -36
  107. package/src/{cli/plugin.ts → RegistryPlugin.node.ts} +2 -0
  108. package/src/RegistryPlugin.test.ts +24 -0
  109. package/src/RegistryPlugin.tsx +9 -7
  110. package/src/capabilities/app-graph-builder.ts +25 -17
  111. package/src/capabilities/dev-plugin-loader.ts +39 -0
  112. package/src/capabilities/index.ts +3 -2
  113. package/src/capabilities/operation-handler.ts +1 -1
  114. package/src/capabilities/react-surface.tsx +63 -47
  115. package/src/capabilities/settings.ts +34 -0
  116. package/src/components/PluginDetail/PluginDetail.stories.tsx +3 -2
  117. package/src/components/PluginDetail/PluginDetail.tsx +105 -15
  118. package/src/components/PluginFailureBadge/PluginFailureBadge.tsx +68 -0
  119. package/src/components/PluginFailureBadge/index.ts +5 -0
  120. package/src/components/PluginList/PluginItem.tsx +46 -7
  121. package/src/components/PluginList/PluginList.stories.tsx +1 -1
  122. package/src/components/PluginList/PluginList.tsx +28 -5
  123. package/src/components/RegistrySettings/RegistrySettings.tsx +120 -0
  124. package/src/components/RegistrySettings/index.ts +5 -0
  125. package/src/components/index.ts +2 -0
  126. package/src/containers/BaseRegistryArticle/BaseRegistryArticle.tsx +163 -0
  127. package/src/containers/BaseRegistryArticle/index.ts +5 -0
  128. package/src/containers/LoadPluginDialog/LoadPluginDialog.tsx +4 -3
  129. package/src/containers/PluginArticle/PluginArticle.tsx +296 -32
  130. package/src/containers/PublicRegistryArticle/PublicRegistryArticle.tsx +192 -0
  131. package/src/containers/PublicRegistryArticle/index.ts +5 -0
  132. package/src/containers/RegistryArticle/RegistryArticle.tsx +53 -0
  133. package/src/containers/RegistryArticle/index.ts +5 -0
  134. package/src/containers/RegistrySettingsContainer/RegistrySettingsContainer.tsx +59 -0
  135. package/src/containers/RegistrySettingsContainer/index.ts +5 -0
  136. package/src/containers/index.ts +3 -2
  137. package/src/hooks/index.ts +2 -1
  138. package/src/hooks/use-auto-tags.ts +7 -8
  139. package/src/hooks/use-registry-plugins.ts +29 -0
  140. package/src/hooks/use-update-available.ts +31 -0
  141. package/src/index.ts +1 -1
  142. package/src/meta.ts +2 -0
  143. package/src/operations/index.ts +1 -1
  144. package/src/operations/open-plugin-registry.ts +1 -1
  145. package/src/plugin.ts +11 -0
  146. package/src/translations.ts +33 -3
  147. package/src/types.ts +21 -14
  148. package/dist/lib/browser/cli/index.mjs.map +0 -7
  149. package/dist/lib/browser/index.mjs +0 -78
  150. package/dist/lib/browser/index.mjs.map +0 -7
  151. package/dist/lib/browser/meta.json +0 -1
  152. package/dist/lib/node-esm/cli/index.mjs +0 -221
  153. package/dist/lib/node-esm/cli/index.mjs.map +0 -7
  154. package/dist/lib/node-esm/index.mjs +0 -80
  155. package/dist/lib/node-esm/index.mjs.map +0 -7
  156. package/dist/lib/node-esm/meta.json +0 -1
  157. package/dist/types/src/capabilities/state.d.ts +0 -7
  158. package/dist/types/src/capabilities/state.d.ts.map +0 -1
  159. package/dist/types/src/cli/commands/disable.d.ts.map +0 -1
  160. package/dist/types/src/cli/commands/enable.d.ts.map +0 -1
  161. package/dist/types/src/cli/commands/index.d.ts.map +0 -1
  162. package/dist/types/src/cli/commands/list.d.ts +0 -7
  163. package/dist/types/src/cli/commands/list.d.ts.map +0 -1
  164. package/dist/types/src/cli/commands/util.d.ts.map +0 -1
  165. package/dist/types/src/cli/index.d.ts +0 -3
  166. package/dist/types/src/cli/index.d.ts.map +0 -1
  167. package/dist/types/src/cli/plugin.d.ts.map +0 -1
  168. package/dist/types/src/cli/storage.d.ts.map +0 -1
  169. package/dist/types/src/containers/CommunityRegistry/CommunityRegistry.d.ts +0 -8
  170. package/dist/types/src/containers/CommunityRegistry/CommunityRegistry.d.ts.map +0 -1
  171. package/dist/types/src/containers/CommunityRegistry/index.d.ts +0 -2
  172. package/dist/types/src/containers/CommunityRegistry/index.d.ts.map +0 -1
  173. package/dist/types/src/containers/PluginRegistry/PluginRegistry.d.ts +0 -14
  174. package/dist/types/src/containers/PluginRegistry/PluginRegistry.d.ts.map +0 -1
  175. package/dist/types/src/containers/PluginRegistry/index.d.ts +0 -2
  176. package/dist/types/src/containers/PluginRegistry/index.d.ts.map +0 -1
  177. package/dist/types/src/hooks/use-community-plugins.d.ts +0 -16
  178. package/dist/types/src/hooks/use-community-plugins.d.ts.map +0 -1
  179. package/src/capabilities/state.ts +0 -40
  180. package/src/cli/index.ts +0 -6
  181. package/src/containers/CommunityRegistry/CommunityRegistry.tsx +0 -181
  182. package/src/containers/CommunityRegistry/index.ts +0 -5
  183. package/src/containers/PluginRegistry/PluginRegistry.tsx +0 -98
  184. package/src/containers/PluginRegistry/index.ts +0 -5
  185. package/src/hooks/use-community-plugins.ts +0 -35
  186. /package/dist/types/src/{cli/commands → commands}/index.d.ts +0 -0
  187. /package/dist/types/src/{cli/commands → commands}/util.d.ts +0 -0
  188. /package/src/{cli/commands → commands}/disable.ts +0 -0
  189. /package/src/{cli/commands → commands}/enable.ts +0 -0
  190. /package/src/{cli/commands → commands}/index.ts +0 -0
  191. /package/src/{cli/commands → commands}/list.ts +0 -0
  192. /package/src/{cli/commands → commands}/util.ts +0 -0
  193. /package/src/{cli/storage.ts → storage.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-registry",
3
- "version": "0.8.4-main.422d1c7879",
3
+ "version": "0.8.4-main.4f23b4e393",
4
4
  "description": "Braneframe plugin gallery",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -18,20 +18,33 @@
18
18
  "#containers": "./src/containers/index.ts",
19
19
  "#meta": "./src/meta.ts",
20
20
  "#operations": "./src/operations/index.ts",
21
+ "#plugin": {
22
+ "source": {
23
+ "node": "./src/RegistryPlugin.node.ts",
24
+ "default": "./src/RegistryPlugin.tsx"
25
+ },
26
+ "types": "./dist/types/src/RegistryPlugin.d.ts",
27
+ "node": "./dist/lib/neutral/RegistryPlugin.node.mjs",
28
+ "default": "./dist/lib/neutral/RegistryPlugin.mjs"
29
+ },
30
+ "#translations": "./src/translations.ts",
21
31
  "#types": "./src/types.ts"
22
32
  },
23
33
  "exports": {
24
34
  ".": {
25
35
  "source": "./src/index.ts",
26
- "browser": "./dist/lib/browser/index.mjs",
27
- "node": "./dist/lib/node-esm/index.mjs",
28
- "types": "./dist/types/src/index.d.ts"
36
+ "types": "./dist/types/src/index.d.ts",
37
+ "default": "./dist/lib/neutral/index.mjs"
38
+ },
39
+ "./plugin": {
40
+ "source": "./src/plugin.ts",
41
+ "types": "./dist/types/src/plugin.d.ts",
42
+ "default": "./dist/lib/neutral/plugin.mjs"
29
43
  },
30
- "./cli": {
31
- "source": "./src/cli/index.ts",
32
- "browser": "./dist/lib/browser/cli/index.mjs",
33
- "node": "./dist/lib/node-esm/cli/index.mjs",
34
- "types": "./dist/types/src/cli/index.d.ts"
44
+ "./translations": {
45
+ "source": "./src/translations.ts",
46
+ "types": "./dist/types/src/translations.d.ts",
47
+ "default": "./dist/lib/neutral/translations.mjs"
35
48
  }
36
49
  },
37
50
  "types": "dist/types/src/index.d.ts",
@@ -43,26 +56,22 @@
43
56
  "@effect-atom/atom-react": "^0.5.0",
44
57
  "@effect/cli": "0.73.2",
45
58
  "yaml": "^2.8.2",
46
- "@dxos/app-framework": "0.8.4-main.422d1c7879",
47
- "@dxos/cli-util": "0.8.4-main.422d1c7879",
48
- "@dxos/app-toolkit": "0.8.4-main.422d1c7879",
49
- "@dxos/context": "0.8.4-main.422d1c7879",
50
- "@dxos/echo": "0.8.4-main.422d1c7879",
51
- "@dxos/client-protocol": "0.8.4-main.422d1c7879",
52
- "@dxos/effect": "0.8.4-main.422d1c7879",
53
- "@dxos/edge-client": "0.8.4-main.422d1c7879",
54
- "@dxos/operation": "0.8.4-main.422d1c7879",
55
- "@dxos/invariant": "0.8.4-main.422d1c7879",
56
- "@dxos/plugin-graph": "0.8.4-main.422d1c7879",
57
- "@dxos/log": "0.8.4-main.422d1c7879",
58
- "@dxos/protocols": "0.8.4-main.422d1c7879",
59
- "@dxos/plugin-observability": "0.8.4-main.422d1c7879",
60
- "@dxos/react-edge-client": "0.8.4-main.422d1c7879",
61
- "@dxos/react-ui-form": "0.8.4-main.422d1c7879",
62
- "@dxos/plugin-client": "0.8.4-main.422d1c7879",
63
- "@dxos/react-ui-mosaic": "0.8.4-main.422d1c7879",
64
- "@dxos/react-ui-stack": "0.8.4-main.422d1c7879",
65
- "@dxos/util": "0.8.4-main.422d1c7879"
59
+ "@dxos/app-framework": "0.8.4-main.4f23b4e393",
60
+ "@dxos/cli-util": "0.8.4-main.4f23b4e393",
61
+ "@dxos/app-toolkit": "0.8.4-main.4f23b4e393",
62
+ "@dxos/compute": "0.8.4-main.4f23b4e393",
63
+ "@dxos/context": "0.8.4-main.4f23b4e393",
64
+ "@dxos/invariant": "0.8.4-main.4f23b4e393",
65
+ "@dxos/echo": "0.8.4-main.4f23b4e393",
66
+ "@dxos/effect": "0.8.4-main.4f23b4e393",
67
+ "@dxos/log": "0.8.4-main.4f23b4e393",
68
+ "@dxos/plugin-graph": "0.8.4-main.4f23b4e393",
69
+ "@dxos/client-protocol": "0.8.4-main.4f23b4e393",
70
+ "@dxos/plugin-observability": "0.8.4-main.4f23b4e393",
71
+ "@dxos/react-ui-form": "0.8.4-main.4f23b4e393",
72
+ "@dxos/react-ui-mosaic": "0.8.4-main.4f23b4e393",
73
+ "@dxos/react-ui-stack": "0.8.4-main.4f23b4e393",
74
+ "@dxos/util": "0.8.4-main.4f23b4e393"
66
75
  },
67
76
  "devDependencies": {
68
77
  "@effect-atom/atom-react": "^0.5.0",
@@ -72,11 +81,12 @@
72
81
  "effect": "3.20.0",
73
82
  "react": "~19.2.3",
74
83
  "react-dom": "~19.2.3",
75
- "vite": "^7.1.11",
76
- "@dxos/random": "0.8.4-main.422d1c7879",
77
- "@dxos/react-ui": "0.8.4-main.422d1c7879",
78
- "@dxos/storybook-utils": "0.8.4-main.422d1c7879",
79
- "@dxos/ui-theme": "0.8.4-main.422d1c7879"
84
+ "vite": "^8.0.10",
85
+ "@dxos/plugin-testing": "0.8.4-main.4f23b4e393",
86
+ "@dxos/random": "0.8.4-main.4f23b4e393",
87
+ "@dxos/react-ui": "0.8.4-main.4f23b4e393",
88
+ "@dxos/ui-theme": "0.8.4-main.4f23b4e393",
89
+ "@dxos/storybook-utils": "0.8.4-main.4f23b4e393"
80
90
  },
81
91
  "peerDependencies": {
82
92
  "@effect-atom/atom-react": "^0.5.0",
@@ -84,8 +94,8 @@
84
94
  "effect": "3.20.0",
85
95
  "react": "~19.2.3",
86
96
  "react-dom": "~19.2.3",
87
- "@dxos/react-ui": "0.8.4-main.422d1c7879",
88
- "@dxos/ui-theme": "0.8.4-main.422d1c7879"
97
+ "@dxos/react-ui": "0.8.4-main.4f23b4e393",
98
+ "@dxos/ui-theme": "0.8.4-main.4f23b4e393"
89
99
  },
90
100
  "publishConfig": {
91
101
  "access": "public"
@@ -15,3 +15,5 @@ export const RegistryPlugin = Plugin.define(meta).pipe(
15
15
  }),
16
16
  Plugin.make,
17
17
  );
18
+
19
+ export default RegistryPlugin;
@@ -0,0 +1,24 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { describe, test } from 'vitest';
6
+
7
+ import { createComposerTestApp } from '@dxos/plugin-testing/harness';
8
+
9
+ import { RegistryPlugin } from '#plugin';
10
+
11
+ import { meta } from './meta';
12
+
13
+ const moduleId = (name: string) => `${meta.id}.module.${name}`;
14
+
15
+ describe('RegistryPlugin', () => {
16
+ test('modules activate on the expected events', async ({ expect }) => {
17
+ await using harness = await createComposerTestApp({
18
+ plugins: [RegistryPlugin()],
19
+ });
20
+
21
+ // CLI commands activate on startup.
22
+ expect(harness.manager.getActive()).toContain(moduleId('cli-commands'));
23
+ });
24
+ });
@@ -2,23 +2,25 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { Plugin } from '@dxos/app-framework';
5
+ import { ActivationEvents, Plugin } from '@dxos/app-framework';
6
6
  import { AppPlugin } from '@dxos/app-toolkit';
7
- import { ClientEvents } from '@dxos/plugin-client/types';
8
7
 
9
- import { AppGraphBuilder, OperationHandler, ReactSurface, RegistryState } from '#capabilities';
8
+ import { AppGraphBuilder, DevPluginLoader, OperationHandler, ReactSurface, RegistrySettings } from '#capabilities';
10
9
  import { meta } from '#meta';
11
-
12
- import { translations } from './translations';
10
+ import { translations } from '#translations';
13
11
 
14
12
  export const RegistryPlugin = Plugin.define(meta).pipe(
15
13
  AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }),
16
14
  AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
15
+ AppPlugin.addSettingsModule({ activate: RegistrySettings }),
17
16
  AppPlugin.addSurfaceModule({ activate: ReactSurface }),
18
17
  AppPlugin.addTranslationsModule({ translations }),
19
18
  Plugin.addModule({
20
- activatesOn: ClientEvents.ClientReady,
21
- activate: RegistryState,
19
+ id: 'dev-plugin-loader',
20
+ activatesOn: ActivationEvents.Startup,
21
+ activate: DevPluginLoader,
22
22
  }),
23
23
  Plugin.make,
24
24
  );
25
+
26
+ export default RegistryPlugin;
@@ -4,27 +4,35 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { Capabilities, Capability, Plugin } from '@dxos/app-framework';
7
+ import { Capabilities, Capability, type Registry, Plugin } from '@dxos/app-framework';
8
8
  import { AppCapabilities, LayoutOperation, SettingsOperation } from '@dxos/app-toolkit';
9
- import { Operation } from '@dxos/operation';
9
+ import { Operation } from '@dxos/compute';
10
10
  import { GraphBuilder, Node, NodeMatcher } from '@dxos/plugin-graph';
11
- import { type PluginEntry } from '@dxos/protocols';
12
11
 
13
12
  import { REGISTRY_ID, REGISTRY_KEY, registryCategoryId, meta } from '#meta';
14
- import { RegistryCapabilities } from '#types';
15
13
 
16
14
  import { LOAD_PLUGIN_DIALOG } from '../containers';
17
15
 
18
16
  /**
19
- * Turns a community manifest entry into a minimal {@link Plugin.Plugin} so it
17
+ * Turns a registry catalog entry into a minimal {@link Plugin.Plugin} so it
20
18
  * can be attached as the graph node's `data`. The synthesized plugin has no
21
19
  * modules and only exists so the article surface can render details for
22
- * community plugins that haven't been installed yet.
20
+ * registry plugins that haven't been installed yet.
23
21
  */
24
- const toDisplayPlugin = (entry: PluginEntry): Plugin.Plugin =>
22
+ const toDisplayPlugin = (entry: Registry.Plugin): Plugin.Plugin =>
25
23
  ({
26
24
  [Plugin.PluginTypeId]: Plugin.PluginTypeId,
27
- meta: entry.meta,
25
+ meta: {
26
+ id: entry.id,
27
+ name: entry.name,
28
+ description: entry.description,
29
+ homePage: entry.homePage,
30
+ source: entry.source,
31
+ screenshots: entry.screenshots,
32
+ tags: entry.tags,
33
+ icon: entry.icon,
34
+ iconHue: entry.iconHue,
35
+ },
28
36
  modules: [],
29
37
  }) as Plugin.Plugin;
30
38
 
@@ -61,6 +69,7 @@ export default Capability.makeModule(
61
69
  label: ['plugin-registry.label', { ns: meta.id }],
62
70
  icon: 'ph--squares-four--regular',
63
71
  disposition: 'pin-end',
72
+ position: 'hoist',
64
73
  testId: 'treeView.pluginRegistry',
65
74
  },
66
75
  nodes: [
@@ -109,14 +118,14 @@ export default Capability.makeModule(
109
118
  },
110
119
  }),
111
120
  Node.make({
112
- id: registryCategoryId('community'),
121
+ id: registryCategoryId('registry'),
113
122
  type: 'category',
114
- data: registryCategoryId('community'),
123
+ data: registryCategoryId('registry'),
115
124
  properties: {
116
- label: ['community-plugins.label', { ns: meta.id }],
125
+ label: ['registry-plugins.label', { ns: meta.id }],
117
126
  icon: 'ph--users-three--regular',
118
127
  key: REGISTRY_KEY,
119
- testId: 'pluginRegistry.community',
128
+ testId: 'pluginRegistry.registry',
120
129
  },
121
130
  }),
122
131
  ],
@@ -150,7 +159,6 @@ export default Capability.makeModule(
150
159
  connector: (_node, get) => {
151
160
  const manager = capabilities.get(Capabilities.PluginManager);
152
161
  const installedIds = new Set(manager.getPlugins().map((plugin) => plugin.meta.id));
153
- const stateAtom = capabilities.getAll(RegistryCapabilities.State).at(0);
154
162
 
155
163
  const installedNodes = manager.getPlugins().map((plugin) =>
156
164
  Node.make({
@@ -165,9 +173,9 @@ export default Capability.makeModule(
165
173
  }),
166
174
  );
167
175
 
168
- const communityEntries = stateAtom ? get(stateAtom).entries : [];
169
- const communityNodes = communityEntries
170
- .filter((entry) => !installedIds.has(entry.meta.id))
176
+ const registryEntries = get(manager.pluginRegistry.plugins).entries;
177
+ const registryNodes = registryEntries
178
+ .filter((entry) => !installedIds.has(entry.id))
171
179
  .map((entry) => {
172
180
  const plugin = toDisplayPlugin(entry);
173
181
  return Node.make({
@@ -182,7 +190,7 @@ export default Capability.makeModule(
182
190
  });
183
191
  });
184
192
 
185
- return Effect.succeed([...installedNodes, ...communityNodes]);
193
+ return Effect.succeed([...installedNodes, ...registryNodes]);
186
194
  },
187
195
  }),
188
196
  ]);
@@ -0,0 +1,39 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capabilities, Capability } from '@dxos/app-framework';
8
+ import { log } from '@dxos/log';
9
+
10
+ import { RegistryCapabilities } from '../types';
11
+
12
+ /**
13
+ * Startup module that auto-loads a locally-served dev plugin when the user has
14
+ * the toggle enabled in registry settings. Failures (dev server offline, 404,
15
+ * timeout) are logged and swallowed so a stale dev URL never blocks app boot —
16
+ * the toggle stays on, the next reload retries.
17
+ */
18
+ export default Capability.makeModule(
19
+ Effect.fnUntraced(function* () {
20
+ const manager = yield* Capability.get(Capabilities.PluginManager);
21
+ const registry = yield* Capability.get(Capabilities.AtomRegistry);
22
+ const settingsAtom = yield* Capability.get(RegistryCapabilities.Settings);
23
+
24
+ const settings = registry.get(settingsAtom);
25
+ const url = settings.devPluginUrl?.trim();
26
+ if (!settings.devPluginEnabled || !url) {
27
+ return [];
28
+ }
29
+
30
+ log.info('loading dev plugin from registry settings', { url });
31
+ yield* manager.add(url).pipe(
32
+ Effect.flatMap((plugin) => manager.enable(plugin.meta.id)),
33
+ Effect.tapError((error) => Effect.sync(() => log.warn('dev plugin auto-load failed', { url, error }))),
34
+ Effect.ignore,
35
+ );
36
+
37
+ return [];
38
+ }),
39
+ );
@@ -3,12 +3,13 @@
3
3
  //
4
4
 
5
5
  import { Capability } from '@dxos/app-framework';
6
- import { OperationHandlerSet } from '@dxos/operation';
6
+ import { OperationHandlerSet } from '@dxos/compute';
7
7
 
8
8
  export const AppGraphBuilder = Capability.lazy('AppGraphBuilder', () => import('./app-graph-builder'));
9
+ export const DevPluginLoader = Capability.lazy('DevPluginLoader', () => import('./dev-plugin-loader'));
9
10
  export const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(
10
11
  'OperationHandler',
11
12
  () => import('./operation-handler'),
12
13
  );
13
14
  export const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));
14
- export const RegistryState = Capability.lazy('RegistryState', () => import('./state'));
15
+ export const RegistrySettings = Capability.lazy('RegistrySettings', () => import('./settings'));
@@ -5,7 +5,7 @@
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
7
  import { Capabilities, Capability } from '@dxos/app-framework';
8
- import type { OperationHandlerSet } from '@dxos/operation';
8
+ import type { OperationHandlerSet } from '@dxos/compute';
9
9
 
10
10
  import { RegistryOperationHandlerSet } from '#operations';
11
11
 
@@ -7,12 +7,20 @@ import React, { useMemo } from 'react';
7
7
 
8
8
  import { Capabilities, Capability, Plugin } from '@dxos/app-framework';
9
9
  import { Surface, usePluginManager } from '@dxos/app-framework/ui';
10
+ import { AppCapabilities } from '@dxos/app-toolkit';
10
11
  import { AppSurface } from '@dxos/app-toolkit/ui';
11
12
 
12
- import { CommunityRegistry, LOAD_PLUGIN_DIALOG, LoadPluginDialog, PluginArticle, PluginRegistry } from '#containers';
13
- import { registryCategoryId } from '#meta';
13
+ import {
14
+ LOAD_PLUGIN_DIALOG,
15
+ LoadPluginDialog,
16
+ PluginArticle,
17
+ PublicRegistryArticle,
18
+ RegistryArticle,
19
+ RegistrySettingsContainer,
20
+ } from '#containers';
21
+ import { meta, registryCategoryId } from '#meta';
14
22
 
15
- import { useAutoTags, useCommunityPlugins, useRemotePluginIds } from '../hooks';
23
+ import { useAutoTags, useRegistryPlugins, useRemotePluginIds } from '../hooks';
16
24
 
17
25
  export default Capability.makeModule(() =>
18
26
  Effect.succeed(
@@ -23,20 +31,15 @@ export default Capability.makeModule(() =>
23
31
  component: () => {
24
32
  const manager = usePluginManager();
25
33
  const remoteIds = useRemotePluginIds();
26
- const { entries } = useCommunityPlugins();
27
- const extraTagsById = useAutoTags(entries);
28
- const filtered = useMemo(
34
+ const core = useMemo(() => manager.getCore(), [manager]);
35
+ const predicate = useMemo<PluginPredicate>(
29
36
  () =>
30
- manager
31
- .getPlugins()
32
- .filter(({ meta }) => !manager.getCore().includes(meta.id))
33
- .filter(({ meta }) => !remoteIds.has(meta.id)),
34
- [manager, remoteIds],
37
+ ({ meta }) =>
38
+ !core.includes(meta.id) && !remoteIds.has(meta.id),
39
+ [core, remoteIds],
35
40
  );
36
41
 
37
- return (
38
- <PluginRegistry id={registryCategoryId('official')} plugins={filtered} extraTagsById={extraTagsById} />
39
- );
42
+ return <FilteredRegistryArticle id={registryCategoryId('official')} filter={predicate} />;
40
43
  },
41
44
  }),
42
45
  Surface.create({
@@ -44,20 +47,16 @@ export default Capability.makeModule(() =>
44
47
  filter: AppSurface.literal(AppSurface.Article, registryCategoryId('installed')),
45
48
  component: () => {
46
49
  const manager = usePluginManager();
47
- const { entries } = useCommunityPlugins();
48
- const extraTagsById = useAutoTags(entries);
49
- const filtered = useMemo(
50
+ const core = useMemo(() => manager.getCore(), [manager]);
51
+ const enabled = useMemo(() => manager.getEnabled(), [manager]);
52
+ const predicate = useMemo<PluginPredicate>(
50
53
  () =>
51
- manager
52
- .getPlugins()
53
- .filter(({ meta }) => !manager.getCore().includes(meta.id))
54
- .filter(({ meta }) => manager.getEnabled().includes(meta.id)),
55
- [manager],
54
+ ({ meta }) =>
55
+ !core.includes(meta.id) && enabled.includes(meta.id),
56
+ [core, enabled],
56
57
  );
57
58
 
58
- return (
59
- <PluginRegistry id={registryCategoryId('installed')} plugins={filtered} extraTagsById={extraTagsById} />
60
- );
59
+ return <FilteredRegistryArticle id={registryCategoryId('installed')} filter={predicate} />;
61
60
  },
62
61
  }),
63
62
  Surface.create({
@@ -66,42 +65,35 @@ export default Capability.makeModule(() =>
66
65
  component: () => {
67
66
  const manager = usePluginManager();
68
67
  const remoteIds = useRemotePluginIds();
69
- const { entries } = useCommunityPlugins();
70
- const extraTagsById = useAutoTags(entries);
71
- const filtered = useMemo(
68
+ const core = useMemo(() => manager.getCore(), [manager]);
69
+ const predicate = useMemo<PluginPredicate>(
72
70
  () =>
73
- manager
74
- .getPlugins()
75
- .filter(({ meta }) => !manager.getCore().includes(meta.id))
76
- .filter(({ meta }) => !remoteIds.has(meta.id))
77
- .filter(({ meta }) => !meta.tags?.includes('labs')),
78
- [manager, remoteIds],
71
+ ({ meta }) =>
72
+ !core.includes(meta.id) && !remoteIds.has(meta.id) && !meta.tags?.includes('labs'),
73
+ [core, remoteIds],
79
74
  );
80
75
 
81
- return (
82
- <PluginRegistry id={registryCategoryId('recommended')} plugins={filtered} extraTagsById={extraTagsById} />
83
- );
76
+ return <FilteredRegistryArticle id={registryCategoryId('recommended')} filter={predicate} />;
84
77
  },
85
78
  }),
86
79
  Surface.create({
87
80
  id: 'labs',
88
81
  filter: AppSurface.literal(AppSurface.Article, registryCategoryId('labs')),
89
82
  component: () => {
90
- const manager = usePluginManager();
91
- const { entries } = useCommunityPlugins();
92
- const extraTagsById = useAutoTags(entries);
93
- const filtered = useMemo(
94
- () => manager.getPlugins().filter(({ meta }) => meta.tags?.includes('labs')),
95
- [manager],
83
+ const predicate = useMemo<PluginPredicate>(
84
+ () =>
85
+ ({ meta }) =>
86
+ meta.tags?.includes('labs') ?? false,
87
+ [],
96
88
  );
97
89
 
98
- return <PluginRegistry id={registryCategoryId('labs')} plugins={filtered} extraTagsById={extraTagsById} />;
90
+ return <FilteredRegistryArticle id={registryCategoryId('labs')} filter={predicate} />;
99
91
  },
100
92
  }),
101
93
  Surface.create({
102
- id: 'community',
103
- filter: AppSurface.literal(AppSurface.Article, registryCategoryId('community')),
104
- component: () => <CommunityRegistry id={registryCategoryId('community')} />,
94
+ id: 'registry',
95
+ filter: AppSurface.literal(AppSurface.Article, registryCategoryId('registry')),
96
+ component: () => <PublicRegistryArticle id={registryCategoryId('registry')} />,
105
97
  }),
106
98
  Surface.create({
107
99
  id: 'plugin-details',
@@ -115,6 +107,30 @@ export default Capability.makeModule(() =>
115
107
  filter: AppSurface.component(AppSurface.Dialog, LOAD_PLUGIN_DIALOG),
116
108
  component: () => <LoadPluginDialog />,
117
109
  }),
110
+ Surface.create({
111
+ id: 'plugin-settings',
112
+ role: 'article',
113
+ filter: (data): data is { subject: AppCapabilities.Settings } =>
114
+ AppCapabilities.isSettings(data.subject) && data.subject.prefix === meta.id,
115
+ component: ({ data: { subject } }) => <RegistrySettingsContainer subject={subject} />,
116
+ }),
118
117
  ]),
119
118
  ),
120
119
  );
120
+
121
+ type PluginPredicate = (plugin: Plugin.Plugin) => boolean;
122
+
123
+ /**
124
+ * Renders the {@link RegistryArticle} surface filtered by an arbitrary
125
+ * predicate computed against the live plugin list. Centralises the
126
+ * `usePluginManager` + `useRegistryPlugins` + `useAutoTags` wiring shared
127
+ * by every category surface.
128
+ */
129
+ const FilteredRegistryArticle = ({ id, filter }: { id: string; filter: PluginPredicate }) => {
130
+ const manager = usePluginManager();
131
+ const { entries } = useRegistryPlugins();
132
+ const extraTagsById = useAutoTags(entries);
133
+ const filtered = useMemo(() => manager.getPlugins().filter(filter), [manager, filter]);
134
+
135
+ return <RegistryArticle id={id} plugins={filtered} extraTagsById={extraTagsById} />;
136
+ };
@@ -0,0 +1,34 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability, PLUGIN_DEV_SERVER_PORT } from '@dxos/app-framework';
8
+ import { AppCapabilities } from '@dxos/app-toolkit';
9
+ import { createKvsStore } from '@dxos/effect';
10
+
11
+ import { meta } from '#meta';
12
+
13
+ import { RegistryCapabilities, RegistrySettingsSchema } from '../types';
14
+
15
+ const DEFAULT_DEV_PLUGIN_URL = `http://localhost:${PLUGIN_DEV_SERVER_PORT}/manifest.json`;
16
+
17
+ export default Capability.makeModule(() =>
18
+ Effect.sync(() => {
19
+ const settingsAtom = createKvsStore({
20
+ key: meta.id,
21
+ schema: RegistrySettingsSchema,
22
+ defaultValue: () => ({ devPluginUrl: DEFAULT_DEV_PLUGIN_URL }),
23
+ });
24
+
25
+ return [
26
+ Capability.contributes(RegistryCapabilities.Settings, settingsAtom),
27
+ Capability.contributes(AppCapabilities.Settings, {
28
+ prefix: meta.id,
29
+ schema: RegistrySettingsSchema,
30
+ atom: settingsAtom,
31
+ }),
32
+ ];
33
+ }),
34
+ );
@@ -8,7 +8,8 @@ import { Plugin } from '@dxos/app-framework';
8
8
  import { random } from '@dxos/random';
9
9
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
10
10
 
11
- import { translations } from '../../translations';
11
+ import { translations } from '#translations';
12
+
12
13
  import { PluginDetail } from './PluginDetail';
13
14
 
14
15
  const meta = {
@@ -28,7 +29,7 @@ type Story = StoryObj<typeof meta>;
28
29
  export const Default: Story = {
29
30
  args: {
30
31
  plugin: Plugin.define({
31
- id: 'example.com/plugin/test-plugin',
32
+ id: 'com.example.plugin.test',
32
33
  name: 'Test Plugin',
33
34
  description: random.lorem.paragraphs(2),
34
35
  icon: 'ph--bug--regular',