@dxos/plugin-registry 0.8.4-main.ae835ea → 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 (112) hide show
  1. package/dist/lib/browser/app-graph-builder-P3ZGGFAR.mjs +166 -0
  2. package/dist/lib/browser/app-graph-builder-P3ZGGFAR.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-XPEFEID2.mjs → chunk-VOAOTNGS.mjs} +1 -1
  4. package/dist/lib/browser/chunk-VOAOTNGS.mjs.map +7 -0
  5. package/dist/lib/browser/cli/index.mjs +223 -0
  6. package/dist/lib/browser/cli/index.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +22 -29
  8. package/dist/lib/browser/index.mjs.map +4 -4
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/operation-resolver-P5PKLPRT.mjs +24 -0
  11. package/dist/lib/browser/operation-resolver-P5PKLPRT.mjs.map +7 -0
  12. package/dist/lib/browser/react-surface-IIM6T7IA.mjs +337 -0
  13. package/dist/lib/browser/react-surface-IIM6T7IA.mjs.map +7 -0
  14. package/dist/lib/node-esm/app-graph-builder-56JXLOGZ.mjs +167 -0
  15. package/dist/lib/node-esm/app-graph-builder-56JXLOGZ.mjs.map +7 -0
  16. package/dist/lib/node-esm/chunk-SALMIZ2W.mjs +21 -0
  17. package/dist/lib/node-esm/chunk-SALMIZ2W.mjs.map +7 -0
  18. package/dist/lib/node-esm/cli/index.mjs +224 -0
  19. package/dist/lib/node-esm/cli/index.mjs.map +7 -0
  20. package/dist/lib/node-esm/index.mjs +63 -0
  21. package/dist/lib/node-esm/index.mjs.map +7 -0
  22. package/dist/lib/node-esm/meta.json +1 -0
  23. package/dist/lib/node-esm/operation-resolver-3ZB5W3T3.mjs +25 -0
  24. package/dist/lib/node-esm/operation-resolver-3ZB5W3T3.mjs.map +7 -0
  25. package/dist/lib/node-esm/react-surface-F67P7RC3.mjs +338 -0
  26. package/dist/lib/node-esm/react-surface-F67P7RC3.mjs.map +7 -0
  27. package/dist/types/src/RegistryPlugin.d.ts +2 -1
  28. package/dist/types/src/RegistryPlugin.d.ts.map +1 -1
  29. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +6 -0
  30. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -0
  31. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +3 -0
  32. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +1 -0
  33. package/dist/types/src/capabilities/index.d.ts +3 -3
  34. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  35. package/dist/types/src/capabilities/operation-resolver/index.d.ts +3 -0
  36. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -0
  37. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +5 -0
  38. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -0
  39. package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
  40. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
  41. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
  42. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
  43. package/dist/types/src/cli/commands/disable.d.ts +11 -0
  44. package/dist/types/src/cli/commands/disable.d.ts.map +1 -0
  45. package/dist/types/src/cli/commands/enable.d.ts +11 -0
  46. package/dist/types/src/cli/commands/enable.d.ts.map +1 -0
  47. package/dist/types/src/cli/commands/index.d.ts +3 -0
  48. package/dist/types/src/cli/commands/index.d.ts.map +1 -0
  49. package/dist/types/src/cli/commands/list.d.ts +7 -0
  50. package/dist/types/src/cli/commands/list.d.ts.map +1 -0
  51. package/dist/types/src/cli/commands/util.d.ts +11 -0
  52. package/dist/types/src/cli/commands/util.d.ts.map +1 -0
  53. package/dist/types/src/cli/index.d.ts +3 -0
  54. package/dist/types/src/cli/index.d.ts.map +1 -0
  55. package/dist/types/src/cli/plugin.d.ts +3 -0
  56. package/dist/types/src/cli/plugin.d.ts.map +1 -0
  57. package/dist/types/src/cli/storage.d.ts +18 -0
  58. package/dist/types/src/cli/storage.d.ts.map +1 -0
  59. package/dist/types/src/components/PluginDetail.d.ts +3 -3
  60. package/dist/types/src/components/PluginDetail.d.ts.map +1 -1
  61. package/dist/types/src/components/PluginDetail.stories.d.ts +1 -1
  62. package/dist/types/src/components/PluginDetail.stories.d.ts.map +1 -1
  63. package/dist/types/src/components/PluginItem.d.ts +2 -2
  64. package/dist/types/src/components/PluginItem.d.ts.map +1 -1
  65. package/dist/types/src/components/PluginList.d.ts +1 -1
  66. package/dist/types/src/components/PluginList.d.ts.map +1 -1
  67. package/dist/types/src/components/PluginList.stories.d.ts.map +1 -1
  68. package/dist/types/src/components/RegistryContainer.d.ts +4 -3
  69. package/dist/types/src/components/RegistryContainer.d.ts.map +1 -1
  70. package/dist/types/src/meta.d.ts +2 -2
  71. package/dist/types/src/meta.d.ts.map +1 -1
  72. package/dist/types/tsconfig.tsbuildinfo +1 -1
  73. package/package.json +47 -31
  74. package/src/RegistryPlugin.tsx +9 -24
  75. package/src/capabilities/app-graph-builder/app-graph-builder.ts +136 -0
  76. package/src/capabilities/app-graph-builder/index.ts +7 -0
  77. package/src/capabilities/index.ts +3 -5
  78. package/src/capabilities/operation-resolver/index.ts +7 -0
  79. package/src/capabilities/operation-resolver/operation-resolver.ts +23 -0
  80. package/src/capabilities/react-surface/index.ts +7 -0
  81. package/src/capabilities/react-surface/react-surface.tsx +99 -0
  82. package/src/cli/commands/disable.ts +47 -0
  83. package/src/cli/commands/enable.ts +44 -0
  84. package/src/cli/commands/index.ts +14 -0
  85. package/src/cli/commands/list.ts +41 -0
  86. package/src/cli/commands/util.ts +24 -0
  87. package/src/cli/index.ts +6 -0
  88. package/src/cli/plugin.ts +16 -0
  89. package/src/cli/storage.ts +57 -0
  90. package/src/components/PluginDetail.stories.tsx +14 -16
  91. package/src/components/PluginDetail.tsx +8 -11
  92. package/src/components/PluginItem.tsx +5 -5
  93. package/src/components/PluginList.stories.tsx +14 -17
  94. package/src/components/PluginList.tsx +2 -2
  95. package/src/components/RegistryContainer.tsx +43 -44
  96. package/src/meta.ts +2 -2
  97. package/dist/lib/browser/app-graph-builder-AOIN4N2Q.mjs +0 -162
  98. package/dist/lib/browser/app-graph-builder-AOIN4N2Q.mjs.map +0 -7
  99. package/dist/lib/browser/chunk-XPEFEID2.mjs.map +0 -7
  100. package/dist/lib/browser/intent-resolver-LKNUYBTN.mjs +0 -23
  101. package/dist/lib/browser/intent-resolver-LKNUYBTN.mjs.map +0 -7
  102. package/dist/lib/browser/react-surface-KP3NX4UD.mjs +0 -357
  103. package/dist/lib/browser/react-surface-KP3NX4UD.mjs.map +0 -7
  104. package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
  105. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
  106. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  107. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  108. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  109. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  110. package/src/capabilities/app-graph-builder.ts +0 -156
  111. package/src/capabilities/intent-resolver.ts +0 -27
  112. package/src/capabilities/react-surface.tsx +0 -85
package/package.json CHANGED
@@ -1,18 +1,29 @@
1
1
  {
2
2
  "name": "@dxos/plugin-registry",
3
- "version": "0.8.4-main.ae835ea",
3
+ "version": "0.8.4-main.bc674ce",
4
4
  "description": "Braneframe plugin gallery",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
7
11
  "license": "MIT",
8
12
  "author": "DXOS.org",
9
13
  "sideEffects": true,
10
14
  "type": "module",
11
15
  "exports": {
12
16
  ".": {
17
+ "browser": "./dist/lib/browser/index.mjs",
18
+ "node": "./dist/lib/node-esm/index.mjs",
13
19
  "source": "./src/index.ts",
14
- "types": "./dist/types/src/index.d.ts",
15
- "browser": "./dist/lib/browser/index.mjs"
20
+ "types": "./dist/types/src/index.d.ts"
21
+ },
22
+ "./cli": {
23
+ "browser": "./dist/lib/browser/cli/index.mjs",
24
+ "node": "./dist/lib/node-esm/cli/index.mjs",
25
+ "source": "./src/cli/index.ts",
26
+ "types": "./dist/types/src/cli/index.d.ts"
16
27
  }
17
28
  },
18
29
  "types": "dist/types/src/index.d.ts",
@@ -24,39 +35,44 @@
24
35
  "src"
25
36
  ],
26
37
  "dependencies": {
27
- "@preact-signals/safe-react": "^0.9.0",
28
- "@dxos/echo": "0.8.4-main.ae835ea",
29
- "@dxos/live-object": "0.8.4-main.ae835ea",
30
- "@dxos/app-framework": "0.8.4-main.ae835ea",
31
- "@dxos/plugin-observability": "0.8.4-main.ae835ea",
32
- "@dxos/plugin-graph": "0.8.4-main.ae835ea",
33
- "@dxos/react-ui-stack": "0.8.4-main.ae835ea",
34
- "@dxos/invariant": "0.8.4-main.ae835ea",
35
- "@dxos/util": "0.8.4-main.ae835ea",
36
- "@dxos/react-ui-form": "0.8.4-main.ae835ea"
38
+ "@effect-atom/atom-react": "^0.4.6",
39
+ "@effect/cli": "0.72.1",
40
+ "@dxos/app-framework": "0.8.4-main.bc674ce",
41
+ "@dxos/client-protocol": "0.8.4-main.bc674ce",
42
+ "@dxos/cli-util": "0.8.4-main.bc674ce",
43
+ "@dxos/echo": "0.8.4-main.bc674ce",
44
+ "@dxos/invariant": "0.8.4-main.bc674ce",
45
+ "@dxos/operation": "0.8.4-main.bc674ce",
46
+ "@dxos/plugin-graph": "0.8.4-main.bc674ce",
47
+ "@dxos/plugin-observability": "0.8.4-main.bc674ce",
48
+ "@dxos/react-ui-form": "0.8.4-main.bc674ce",
49
+ "@dxos/effect": "0.8.4-main.bc674ce",
50
+ "@dxos/react-ui-stack": "0.8.4-main.bc674ce",
51
+ "@dxos/react-ui-mosaic": "0.8.4-main.bc674ce",
52
+ "@dxos/util": "0.8.4-main.bc674ce"
37
53
  },
38
54
  "devDependencies": {
39
- "@effect-rx/rx-react": "0.42.4",
40
- "@effect/platform": "0.92.1",
41
- "@types/react": "~19.2.2",
42
- "@types/react-dom": "~19.2.2",
43
- "effect": "3.18.3",
44
- "react": "~19.2.0",
45
- "react-dom": "~19.2.0",
55
+ "@effect-atom/atom-react": "^0.4.6",
56
+ "@effect/platform": "0.93.6",
57
+ "@types/react": "~19.2.7",
58
+ "@types/react-dom": "~19.2.3",
59
+ "effect": "3.19.11",
60
+ "react": "~19.2.3",
61
+ "react-dom": "~19.2.3",
46
62
  "vite": "7.1.9",
47
- "@dxos/react-ui": "0.8.4-main.ae835ea",
48
- "@dxos/random": "0.8.4-main.ae835ea",
49
- "@dxos/react-ui-theme": "0.8.4-main.ae835ea",
50
- "@dxos/storybook-utils": "0.8.4-main.ae835ea"
63
+ "@dxos/react-ui": "0.8.4-main.bc674ce",
64
+ "@dxos/random": "0.8.4-main.bc674ce",
65
+ "@dxos/storybook-utils": "0.8.4-main.bc674ce",
66
+ "@dxos/ui-theme": "0.8.4-main.bc674ce"
51
67
  },
52
68
  "peerDependencies": {
53
- "@effect-rx/rx-react": "^0.34.1",
54
- "@effect/platform": "^0.80.12",
55
- "effect": "^3.13.3",
56
- "react": "^19.0.0",
57
- "react-dom": "^19.0.0",
58
- "@dxos/react-ui": "0.8.4-main.ae835ea",
59
- "@dxos/react-ui-theme": "0.8.4-main.ae835ea"
69
+ "@effect-atom/atom-react": "^0.4.6",
70
+ "@effect/platform": "0.93.6",
71
+ "effect": "3.19.11",
72
+ "react": "~19.2.3",
73
+ "react-dom": "~19.2.3",
74
+ "@dxos/react-ui": "0.8.4-main.bc674ce",
75
+ "@dxos/ui-theme": "0.8.4-main.bc674ce"
60
76
  },
61
77
  "publishConfig": {
62
78
  "access": "public"
@@ -2,31 +2,16 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, Events, contributes, defineModule, definePlugin } from '@dxos/app-framework';
5
+ import { Common, Plugin } from '@dxos/app-framework';
6
6
 
7
- import { AppGraphBuilder, IntentResolver, ReactSurface } from './capabilities';
7
+ import { AppGraphBuilder, OperationResolver, ReactSurface } from './capabilities';
8
8
  import { meta } from './meta';
9
9
  import { translations } from './translations';
10
10
 
11
- export const RegistryPlugin = definePlugin(meta, () => [
12
- defineModule({
13
- id: `${meta.id}/module/translations`,
14
- activatesOn: Events.SetupTranslations,
15
- activate: () => contributes(Capabilities.Translations, translations),
16
- }),
17
- defineModule({
18
- id: `${meta.id}/module/react-surface`,
19
- activatesOn: Events.SetupReactSurface,
20
- activate: ReactSurface,
21
- }),
22
- defineModule({
23
- id: `${meta.id}/module/intent-resolver`,
24
- activatesOn: Events.SetupIntentResolver,
25
- activate: IntentResolver,
26
- }),
27
- defineModule({
28
- id: `${meta.id}/module/app-graph-builder`,
29
- activatesOn: Events.SetupAppGraph,
30
- activate: AppGraphBuilder,
31
- }),
32
- ]);
11
+ export const RegistryPlugin = Plugin.define(meta).pipe(
12
+ Common.Plugin.addTranslationsModule({ translations }),
13
+ Common.Plugin.addSurfaceModule({ activate: ReactSurface }),
14
+ Common.Plugin.addOperationResolverModule({ activate: OperationResolver }),
15
+ Common.Plugin.addAppGraphModule({ activate: AppGraphBuilder }),
16
+ Plugin.make,
17
+ );
@@ -0,0 +1,136 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability, Common, SettingsOperation } from '@dxos/app-framework';
8
+ import { Operation } from '@dxos/operation';
9
+ import { GraphBuilder, NodeMatcher } from '@dxos/plugin-graph';
10
+
11
+ import { REGISTRY_ID, REGISTRY_KEY, meta } from '../../meta';
12
+
13
+ export default Capability.makeModule(
14
+ Effect.fnUntraced(function* () {
15
+ const capabilities = yield* Capability.Service;
16
+
17
+ const extensions = yield* Effect.all([
18
+ GraphBuilder.createExtension({
19
+ id: meta.id,
20
+ match: NodeMatcher.whenRoot,
21
+ actions: () =>
22
+ Effect.succeed([
23
+ {
24
+ id: meta.id,
25
+ data: () => Operation.invoke(SettingsOperation.OpenPluginRegistry),
26
+ properties: {
27
+ label: ['open plugin registry label', { ns: meta.id }],
28
+ icon: 'ph--squares-four--regular',
29
+ disposition: 'menu',
30
+ },
31
+ },
32
+ ]),
33
+ }),
34
+ GraphBuilder.createExtension({
35
+ id: meta.id,
36
+ match: NodeMatcher.whenRoot,
37
+ connector: () =>
38
+ Effect.succeed([
39
+ {
40
+ id: REGISTRY_ID,
41
+ type: meta.id,
42
+ properties: {
43
+ label: ['plugin registry label', { ns: meta.id }],
44
+ icon: 'ph--squares-four--regular',
45
+ disposition: 'pin-end',
46
+ testId: 'treeView.pluginRegistry',
47
+ },
48
+ nodes: [
49
+ {
50
+ id: `${REGISTRY_KEY}+all`,
51
+ type: 'category',
52
+ data: `${REGISTRY_KEY}+all`,
53
+ properties: {
54
+ label: ['all plugins label', { ns: meta.id }],
55
+ icon: 'ph--squares-four--regular',
56
+ key: REGISTRY_KEY,
57
+ testId: 'pluginRegistry.all',
58
+ },
59
+ },
60
+ {
61
+ id: `${REGISTRY_KEY}+installed`,
62
+ type: 'category',
63
+ data: `${REGISTRY_KEY}+installed`,
64
+ properties: {
65
+ label: ['installed plugins label', { ns: meta.id }],
66
+ icon: 'ph--check--regular',
67
+ key: REGISTRY_KEY,
68
+ testId: 'pluginRegistry.installed',
69
+ },
70
+ },
71
+ {
72
+ id: `${REGISTRY_KEY}+recommended`,
73
+ type: 'category',
74
+ data: `${REGISTRY_KEY}+recommended`,
75
+ properties: {
76
+ label: ['recommended plugins label', { ns: meta.id }],
77
+ icon: 'ph--star--regular',
78
+ key: REGISTRY_KEY,
79
+ testId: 'pluginRegistry.recommended',
80
+ },
81
+ },
82
+ {
83
+ id: `${REGISTRY_KEY}+labs`,
84
+ type: 'category',
85
+ data: `${REGISTRY_KEY}+labs`,
86
+ properties: {
87
+ label: ['labs plugins label', { ns: meta.id }],
88
+ icon: 'ph--flask--regular',
89
+ key: REGISTRY_KEY,
90
+ testId: 'pluginRegistry.labs',
91
+ },
92
+ },
93
+ ],
94
+ },
95
+ ]),
96
+ }),
97
+ GraphBuilder.createExtension({
98
+ id: `${meta.id}/actions`,
99
+ match: NodeMatcher.whenId(REGISTRY_ID),
100
+ actions: () =>
101
+ Effect.succeed([
102
+ {
103
+ id: `${meta.id}/load-by-url`,
104
+ data: Effect.fnUntraced(function* () {}),
105
+ properties: {
106
+ label: ['load by url label', { ns: meta.id }],
107
+ icon: 'ph--cloud-arrow-down--regular',
108
+ disabled: true,
109
+ },
110
+ },
111
+ ]),
112
+ }),
113
+ GraphBuilder.createExtension({
114
+ id: `${meta.id}/plugins`,
115
+ match: NodeMatcher.whenId(REGISTRY_ID),
116
+ connector: () => {
117
+ const manager = capabilities.get(Common.Capability.PluginManager);
118
+ return Effect.succeed(
119
+ manager.getPlugins().map((plugin) => ({
120
+ id: plugin.meta.id.replaceAll('/', ':'),
121
+ type: 'dxos.org/plugin',
122
+ data: plugin,
123
+ properties: {
124
+ label: plugin.meta.name ?? plugin.meta.id,
125
+ icon: plugin.meta.icon ?? 'ph--circle--regular',
126
+ disposition: 'hidden',
127
+ },
128
+ })),
129
+ );
130
+ },
131
+ }),
132
+ ]);
133
+
134
+ return Capability.contributes(Common.Capability.AppGraphBuilder, extensions);
135
+ }),
136
+ );
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capability } from '@dxos/app-framework';
6
+
7
+ export const AppGraphBuilder = Capability.lazy('AppGraphBuilder', () => import('./app-graph-builder'));
@@ -2,8 +2,6 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { lazy } from '@dxos/app-framework';
6
-
7
- export const AppGraphBuilder = lazy(() => import('./app-graph-builder'));
8
- export const IntentResolver = lazy(() => import('./intent-resolver'));
9
- export const ReactSurface = lazy(() => import('./react-surface'));
5
+ export * from './app-graph-builder';
6
+ export * from './operation-resolver';
7
+ export * from './react-surface';
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capability } from '@dxos/app-framework';
6
+
7
+ export const OperationResolver = Capability.lazy('OperationResolver', () => import('./operation-resolver'));
@@ -0,0 +1,23 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability, Common, SettingsOperation } from '@dxos/app-framework';
8
+ import { Operation, OperationResolver } from '@dxos/operation';
9
+
10
+ import { REGISTRY_ID } from '../../meta';
11
+
12
+ export default Capability.makeModule(
13
+ Effect.fnUntraced(function* () {
14
+ return Capability.contributes(Common.Capability.OperationResolver, [
15
+ OperationResolver.make({
16
+ operation: SettingsOperation.OpenPluginRegistry,
17
+ handler: Effect.fnUntraced(function* () {
18
+ yield* Operation.invoke(Common.LayoutOperation.SwitchWorkspace, { subject: REGISTRY_ID });
19
+ }),
20
+ }),
21
+ ]);
22
+ }),
23
+ );
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capability } from '@dxos/app-framework';
6
+
7
+ export const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));
@@ -0,0 +1,99 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import React, { useCallback, useMemo } from 'react';
7
+
8
+ import { Capability, Common, Plugin } from '@dxos/app-framework';
9
+ import { usePluginManager } from '@dxos/app-framework/react';
10
+ import { runAndForwardErrors } from '@dxos/effect';
11
+
12
+ import { PluginDetail, RegistryContainer } from '../../components';
13
+ import { REGISTRY_KEY, meta } from '../../meta';
14
+
15
+ export default Capability.makeModule(() =>
16
+ Effect.succeed(
17
+ Capability.contributes(Common.Capability.ReactSurface, [
18
+ Common.createSurface({
19
+ id: `${meta.id}/all`,
20
+ role: 'article',
21
+ filter: (data): data is any => data.subject === `${REGISTRY_KEY}+all`,
22
+ component: () => {
23
+ const manager = usePluginManager();
24
+ const filtered = useMemo(
25
+ () => manager.getPlugins().filter(({ meta }) => !manager.getCore().includes(meta.id)),
26
+ [],
27
+ );
28
+
29
+ return <RegistryContainer id={`${REGISTRY_KEY}+all`} plugins={filtered} />;
30
+ },
31
+ }),
32
+ Common.createSurface({
33
+ id: `${meta.id}/installed`,
34
+ role: 'article',
35
+ filter: (data): data is any => data.subject === `${REGISTRY_KEY}+installed`,
36
+ component: () => {
37
+ const manager = usePluginManager();
38
+ const filtered = useMemo(
39
+ () =>
40
+ manager
41
+ .getPlugins()
42
+ .filter(({ meta }) => !manager.getCore().includes(meta.id))
43
+ .filter(({ meta }) => manager.getEnabled().includes(meta.id)),
44
+ [],
45
+ );
46
+
47
+ return <RegistryContainer id={`${REGISTRY_KEY}+installed`} plugins={filtered} />;
48
+ },
49
+ }),
50
+ Common.createSurface({
51
+ id: `${meta.id}/recommended`,
52
+ role: 'article',
53
+ filter: (data): data is any => data.subject === `${REGISTRY_KEY}+recommended`,
54
+ component: () => {
55
+ const manager = usePluginManager();
56
+ const filtered = useMemo(
57
+ () =>
58
+ manager
59
+ .getPlugins()
60
+ .filter(({ meta }) => !manager.getCore().includes(meta.id))
61
+ .filter(({ meta }) => !meta.tags?.includes('labs')),
62
+ [],
63
+ );
64
+
65
+ return <RegistryContainer id={`${REGISTRY_KEY}+recommended`} plugins={filtered} />;
66
+ },
67
+ }),
68
+ Common.createSurface({
69
+ id: `${meta.id}/labs`,
70
+ role: 'article',
71
+ filter: (data): data is any => data.subject === `${REGISTRY_KEY}+labs`,
72
+ component: () => {
73
+ const manager = usePluginManager();
74
+ const filtered = useMemo(() => manager.getPlugins().filter(({ meta }) => meta.tags?.includes('labs')), []);
75
+
76
+ return <RegistryContainer id={`${REGISTRY_KEY}+labs`} plugins={filtered} />;
77
+ },
78
+ }),
79
+ Common.createSurface({
80
+ id: `${meta.id}/plugin-details`,
81
+ role: 'article',
82
+ filter: (data): data is { subject: Plugin.Plugin } => Plugin.isPlugin(data.subject),
83
+ component: ({ data: { subject } }) => {
84
+ const manager = usePluginManager();
85
+ const enabled = manager.getEnabled().includes(subject.meta.id);
86
+ const handleEnableChange = useCallback(
87
+ (enabled: boolean) =>
88
+ enabled
89
+ ? runAndForwardErrors(manager.enable(subject.meta.id))
90
+ : runAndForwardErrors(manager.disable(subject.meta.id)),
91
+ [manager, subject.meta.id],
92
+ );
93
+
94
+ return <PluginDetail plugin={subject} enabled={enabled} onEnabledChange={handleEnableChange} />;
95
+ },
96
+ }),
97
+ ]),
98
+ ),
99
+ );
@@ -0,0 +1,47 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Args from '@effect/cli/Args';
6
+ import * as Command from '@effect/cli/Command';
7
+ import * as Console from 'effect/Console';
8
+ import * as Effect from 'effect/Effect';
9
+
10
+ import { Plugin } from '@dxos/app-framework';
11
+ import { CommandConfig } from '@dxos/cli-util';
12
+ import { invariant } from '@dxos/invariant';
13
+
14
+ import { saveEnabledPlugins } from '../storage';
15
+
16
+ export const handler = Effect.fn(function* ({ id }: { id: string }) {
17
+ const { json, profile } = yield* CommandConfig;
18
+ const manager = yield* Plugin.Service;
19
+
20
+ const plugins = manager.getPlugins();
21
+ const plugin = plugins.find((p: Plugin.Plugin) => p.meta.id === id);
22
+ invariant(plugin, `Plugin not found: ${id}`);
23
+
24
+ const core = manager.getCore();
25
+ invariant(!core.includes(id), `Cannot disable core plugin: ${id}`);
26
+
27
+ const disabled = yield* manager.disable(id);
28
+ invariant(disabled, `Failed to disable plugin: ${id}`);
29
+
30
+ // Save enabled plugins to storage
31
+ const enabledPlugins = manager.getEnabled();
32
+ yield* saveEnabledPlugins({ profile, enabled: [...enabledPlugins] });
33
+
34
+ if (json) {
35
+ yield* Console.log(JSON.stringify({ id, enabled: false }, null, 2));
36
+ } else {
37
+ yield* Console.log(`Plugin "${plugin.meta.name ?? id}" disabled.`);
38
+ }
39
+ });
40
+
41
+ export const disable = Command.make(
42
+ 'disable',
43
+ {
44
+ id: Args.text({ name: 'id' }).pipe(Args.withDescription('The ID of the plugin to disable.')),
45
+ },
46
+ handler,
47
+ ).pipe(Command.withDescription('Disable a plugin.'));
@@ -0,0 +1,44 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Args from '@effect/cli/Args';
6
+ import * as Command from '@effect/cli/Command';
7
+ import * as Console from 'effect/Console';
8
+ import * as Effect from 'effect/Effect';
9
+
10
+ import { Plugin } from '@dxos/app-framework';
11
+ import { CommandConfig } from '@dxos/cli-util';
12
+ import { invariant } from '@dxos/invariant';
13
+
14
+ import { saveEnabledPlugins } from '../storage';
15
+
16
+ export const handler = Effect.fn(function* ({ id }: { id: string }) {
17
+ const { json, profile } = yield* CommandConfig;
18
+ const manager = yield* Plugin.Service;
19
+
20
+ const plugins = manager.getPlugins();
21
+ const plugin = plugins.find((p: Plugin.Plugin) => p.meta.id === id);
22
+ invariant(plugin, `Plugin not found: ${id}`);
23
+
24
+ const enabled = yield* manager.enable(id);
25
+ invariant(enabled, `Failed to enable plugin: ${id}`);
26
+
27
+ // Save enabled plugins to storage
28
+ const enabledPlugins = manager.getEnabled();
29
+ yield* saveEnabledPlugins({ profile, enabled: [...enabledPlugins] });
30
+
31
+ if (json) {
32
+ yield* Console.log(JSON.stringify({ id, enabled: true }, null, 2));
33
+ } else {
34
+ yield* Console.log(`Plugin "${plugin.meta.name ?? id}" enabled.`);
35
+ }
36
+ });
37
+
38
+ export const enable = Command.make(
39
+ 'enable',
40
+ {
41
+ id: Args.text({ name: 'id' }).pipe(Args.withDescription('The ID of the plugin to enable.')),
42
+ },
43
+ handler,
44
+ ).pipe(Command.withDescription('Enable a plugin.'));
@@ -0,0 +1,14 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Command from '@effect/cli/Command';
6
+
7
+ import { disable } from './disable';
8
+ import { enable } from './enable';
9
+ import { list } from './list';
10
+
11
+ export const plugin: Command.Command<any, any, any, any> = Command.make('plugin').pipe(
12
+ Command.withDescription('Manage plugins.'),
13
+ Command.withSubcommands([enable, disable, list]),
14
+ );
@@ -0,0 +1,41 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Command from '@effect/cli/Command';
6
+ import * as Console from 'effect/Console';
7
+ import * as Effect from 'effect/Effect';
8
+
9
+ import { Plugin } from '@dxos/app-framework';
10
+ import { CommandConfig, printList } from '@dxos/cli-util';
11
+
12
+ import { type FormattedPlugin, printPlugin } from './util';
13
+
14
+ export const handler = Effect.fn(function* () {
15
+ const { json } = yield* CommandConfig;
16
+ const manager = yield* Plugin.Service;
17
+
18
+ const plugins = manager.getPlugins();
19
+ const enabled = manager.getEnabled();
20
+ const core = manager.getCore();
21
+
22
+ const formattedPlugins: FormattedPlugin[] = plugins.map((plugin: Plugin.Plugin) => {
23
+ const isEnabled = enabled.includes(plugin.meta.id);
24
+ const isCore = core.includes(plugin.meta.id);
25
+ return {
26
+ id: plugin.meta.id,
27
+ name: plugin.meta.name ?? plugin.meta.id,
28
+ enabled: isEnabled,
29
+ core: isCore,
30
+ };
31
+ });
32
+
33
+ if (json) {
34
+ yield* Console.log(JSON.stringify(formattedPlugins, null, 2));
35
+ } else {
36
+ const formatted = formattedPlugins.map(printPlugin);
37
+ yield* Console.log(printList(formatted));
38
+ }
39
+ });
40
+
41
+ export const list = Command.make('list', {}, handler).pipe(Command.withDescription('List all available plugins.'));
@@ -0,0 +1,24 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { FormBuilder } from '@dxos/cli-util';
6
+
7
+ export type FormattedPlugin = {
8
+ id: string;
9
+ name: string;
10
+ enabled: boolean;
11
+ core: boolean;
12
+ };
13
+
14
+ /**
15
+ * Pretty prints a plugin with ANSI colors.
16
+ */
17
+ export const printPlugin = (plugin: FormattedPlugin) => {
18
+ const status = plugin.core ? 'core' : plugin.enabled ? 'enabled' : 'disabled';
19
+ return FormBuilder.make({ title: plugin.name }).pipe(
20
+ FormBuilder.set('id', plugin.id),
21
+ FormBuilder.set('status', status),
22
+ FormBuilder.build,
23
+ );
24
+ };
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './plugin';
6
+ export * from './storage';
@@ -0,0 +1,16 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Common, Plugin } from '@dxos/app-framework';
6
+
7
+ import { meta } from '../meta';
8
+
9
+ import { plugin } from './commands';
10
+
11
+ export const RegistryPlugin = Plugin.define(meta).pipe(
12
+ Common.Plugin.addCommandModule({
13
+ commands: [plugin],
14
+ }),
15
+ Plugin.make,
16
+ );