@dxos/plugin-registry 0.8.4-main.bc674ce → 0.8.4-main.c351d160a8

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 (122) hide show
  1. package/dist/lib/browser/PluginArticle-N2ITBUGD.mjs +29 -0
  2. package/dist/lib/browser/PluginArticle-N2ITBUGD.mjs.map +7 -0
  3. package/dist/lib/browser/PluginRegistry-DKO4UEYH.mjs +78 -0
  4. package/dist/lib/browser/PluginRegistry-DKO4UEYH.mjs.map +7 -0
  5. package/dist/lib/browser/{app-graph-builder-P3ZGGFAR.mjs → app-graph-builder-AHS5BI4Y.mjs} +21 -20
  6. package/dist/lib/browser/app-graph-builder-AHS5BI4Y.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-2YWVCU2W.mjs +191 -0
  8. package/dist/lib/browser/chunk-2YWVCU2W.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-VOAOTNGS.mjs → chunk-KMUDYITM.mjs} +4 -2
  10. package/dist/lib/browser/chunk-KMUDYITM.mjs.map +7 -0
  11. package/dist/lib/browser/cli/index.mjs +15 -16
  12. package/dist/lib/browser/cli/index.mjs.map +3 -3
  13. package/dist/lib/browser/index.mjs +15 -12
  14. package/dist/lib/browser/index.mjs.map +3 -3
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/{operation-resolver-P5PKLPRT.mjs → operation-resolver-PK4B2BZQ.mjs} +7 -6
  17. package/dist/lib/browser/operation-resolver-PK4B2BZQ.mjs.map +7 -0
  18. package/dist/lib/browser/react-surface-ZBP7YXKO.mjs +85 -0
  19. package/dist/lib/browser/react-surface-ZBP7YXKO.mjs.map +7 -0
  20. package/dist/lib/node-esm/PluginArticle-3NEYDKN5.mjs +30 -0
  21. package/dist/lib/node-esm/PluginArticle-3NEYDKN5.mjs.map +7 -0
  22. package/dist/lib/node-esm/PluginRegistry-BYKWC732.mjs +79 -0
  23. package/dist/lib/node-esm/PluginRegistry-BYKWC732.mjs.map +7 -0
  24. package/dist/lib/node-esm/{app-graph-builder-56JXLOGZ.mjs → app-graph-builder-DBDL5WWF.mjs} +21 -20
  25. package/dist/lib/node-esm/app-graph-builder-DBDL5WWF.mjs.map +7 -0
  26. package/dist/lib/node-esm/chunk-BOCFM775.mjs +192 -0
  27. package/dist/lib/node-esm/chunk-BOCFM775.mjs.map +7 -0
  28. package/dist/lib/node-esm/{chunk-SALMIZ2W.mjs → chunk-ENSNUFQK.mjs} +4 -2
  29. package/dist/lib/node-esm/chunk-ENSNUFQK.mjs.map +7 -0
  30. package/dist/lib/node-esm/cli/index.mjs +15 -16
  31. package/dist/lib/node-esm/cli/index.mjs.map +3 -3
  32. package/dist/lib/node-esm/index.mjs +15 -12
  33. package/dist/lib/node-esm/index.mjs.map +3 -3
  34. package/dist/lib/node-esm/meta.json +1 -1
  35. package/dist/lib/node-esm/{operation-resolver-3ZB5W3T3.mjs → operation-resolver-CCHN4NBP.mjs} +7 -6
  36. package/dist/lib/node-esm/operation-resolver-CCHN4NBP.mjs.map +7 -0
  37. package/dist/lib/node-esm/react-surface-FJHMLGZF.mjs +86 -0
  38. package/dist/lib/node-esm/react-surface-FJHMLGZF.mjs.map +7 -0
  39. package/dist/types/src/RegistryPlugin.d.ts.map +1 -1
  40. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +1 -1
  41. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -1
  42. package/dist/types/src/capabilities/operation-resolver/index.d.ts +1 -1
  43. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -1
  44. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +2 -2
  45. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -1
  46. package/dist/types/src/capabilities/react-surface/index.d.ts +1 -1
  47. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -1
  48. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +2 -2
  49. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -1
  50. package/dist/types/src/cli/commands/disable.d.ts +2 -2
  51. package/dist/types/src/cli/commands/enable.d.ts +2 -2
  52. package/dist/types/src/cli/plugin.d.ts.map +1 -1
  53. package/dist/types/src/cli/storage.d.ts +4 -4
  54. package/dist/types/src/cli/storage.d.ts.map +1 -1
  55. package/dist/types/src/components/PluginDetail/PluginDetail.d.ts.map +1 -0
  56. package/dist/types/src/components/{PluginDetail.stories.d.ts → PluginDetail/PluginDetail.stories.d.ts} +1 -0
  57. package/dist/types/src/components/PluginDetail/PluginDetail.stories.d.ts.map +1 -0
  58. package/dist/types/src/components/PluginDetail/index.d.ts +2 -0
  59. package/dist/types/src/components/PluginDetail/index.d.ts.map +1 -0
  60. package/dist/types/src/components/PluginList/PluginItem.d.ts.map +1 -0
  61. package/dist/types/src/components/PluginList/PluginList.d.ts.map +1 -0
  62. package/dist/types/src/components/PluginList/PluginList.stories.d.ts.map +1 -0
  63. package/dist/types/src/components/PluginList/index.d.ts +2 -0
  64. package/dist/types/src/components/PluginList/index.d.ts.map +1 -0
  65. package/dist/types/src/components/index.d.ts +0 -1
  66. package/dist/types/src/components/index.d.ts.map +1 -1
  67. package/dist/types/src/containers/PluginArticle/PluginArticle.d.ts +7 -0
  68. package/dist/types/src/containers/PluginArticle/PluginArticle.d.ts.map +1 -0
  69. package/dist/types/src/containers/PluginArticle/index.d.ts +3 -0
  70. package/dist/types/src/containers/PluginArticle/index.d.ts.map +1 -0
  71. package/dist/types/src/containers/PluginRegistry/PluginRegistry.d.ts +8 -0
  72. package/dist/types/src/containers/PluginRegistry/PluginRegistry.d.ts.map +1 -0
  73. package/dist/types/src/containers/PluginRegistry/index.d.ts +3 -0
  74. package/dist/types/src/containers/PluginRegistry/index.d.ts.map +1 -0
  75. package/dist/types/src/containers/index.d.ts +4 -0
  76. package/dist/types/src/containers/index.d.ts.map +1 -0
  77. package/dist/types/src/meta.d.ts +2 -0
  78. package/dist/types/src/meta.d.ts.map +1 -1
  79. package/dist/types/tsconfig.tsbuildinfo +1 -1
  80. package/package.json +33 -31
  81. package/src/RegistryPlugin.tsx +6 -5
  82. package/src/capabilities/app-graph-builder/app-graph-builder.ts +23 -22
  83. package/src/capabilities/operation-resolver/operation-resolver.ts +4 -3
  84. package/src/capabilities/react-surface/react-surface.tsx +24 -35
  85. package/src/cli/plugin.ts +3 -2
  86. package/src/cli/storage.ts +14 -21
  87. package/src/components/{PluginDetail.stories.tsx → PluginDetail/PluginDetail.stories.tsx} +4 -3
  88. package/src/components/PluginDetail/PluginDetail.tsx +81 -0
  89. package/src/components/PluginDetail/index.ts +5 -0
  90. package/src/components/{PluginItem.tsx → PluginList/PluginItem.tsx} +14 -10
  91. package/src/components/{PluginList.stories.tsx → PluginList/PluginList.stories.tsx} +14 -7
  92. package/src/components/PluginList/index.ts +5 -0
  93. package/src/components/index.ts +0 -1
  94. package/src/containers/PluginArticle/PluginArticle.tsx +28 -0
  95. package/src/containers/PluginArticle/index.ts +7 -0
  96. package/src/{components/RegistryContainer.tsx → containers/PluginRegistry/PluginRegistry.tsx} +23 -20
  97. package/src/containers/PluginRegistry/index.ts +7 -0
  98. package/src/containers/index.ts +8 -0
  99. package/src/meta.ts +4 -4
  100. package/dist/lib/browser/app-graph-builder-P3ZGGFAR.mjs.map +0 -7
  101. package/dist/lib/browser/chunk-VOAOTNGS.mjs.map +0 -7
  102. package/dist/lib/browser/operation-resolver-P5PKLPRT.mjs.map +0 -7
  103. package/dist/lib/browser/react-surface-IIM6T7IA.mjs +0 -337
  104. package/dist/lib/browser/react-surface-IIM6T7IA.mjs.map +0 -7
  105. package/dist/lib/node-esm/app-graph-builder-56JXLOGZ.mjs.map +0 -7
  106. package/dist/lib/node-esm/chunk-SALMIZ2W.mjs.map +0 -7
  107. package/dist/lib/node-esm/operation-resolver-3ZB5W3T3.mjs.map +0 -7
  108. package/dist/lib/node-esm/react-surface-F67P7RC3.mjs +0 -338
  109. package/dist/lib/node-esm/react-surface-F67P7RC3.mjs.map +0 -7
  110. package/dist/types/src/components/PluginDetail.d.ts.map +0 -1
  111. package/dist/types/src/components/PluginDetail.stories.d.ts.map +0 -1
  112. package/dist/types/src/components/PluginItem.d.ts.map +0 -1
  113. package/dist/types/src/components/PluginList.d.ts.map +0 -1
  114. package/dist/types/src/components/PluginList.stories.d.ts.map +0 -1
  115. package/dist/types/src/components/RegistryContainer.d.ts +0 -8
  116. package/dist/types/src/components/RegistryContainer.d.ts.map +0 -1
  117. package/src/components/PluginDetail.tsx +0 -79
  118. /package/dist/types/src/components/{PluginDetail.d.ts → PluginDetail/PluginDetail.d.ts} +0 -0
  119. /package/dist/types/src/components/{PluginItem.d.ts → PluginList/PluginItem.d.ts} +0 -0
  120. /package/dist/types/src/components/{PluginList.d.ts → PluginList/PluginList.d.ts} +0 -0
  121. /package/dist/types/src/components/{PluginList.stories.d.ts → PluginList/PluginList.stories.d.ts} +0 -0
  122. /package/src/components/{PluginList.tsx → PluginList/PluginList.tsx} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-registry",
3
- "version": "0.8.4-main.bc674ce",
3
+ "version": "0.8.4-main.c351d160a8",
4
4
  "description": "Braneframe plugin gallery",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -14,15 +14,15 @@
14
14
  "type": "module",
15
15
  "exports": {
16
16
  ".": {
17
+ "source": "./src/index.ts",
17
18
  "browser": "./dist/lib/browser/index.mjs",
18
19
  "node": "./dist/lib/node-esm/index.mjs",
19
- "source": "./src/index.ts",
20
20
  "types": "./dist/types/src/index.d.ts"
21
21
  },
22
22
  "./cli": {
23
+ "source": "./src/cli/index.ts",
23
24
  "browser": "./dist/lib/browser/cli/index.mjs",
24
25
  "node": "./dist/lib/node-esm/cli/index.mjs",
25
- "source": "./src/cli/index.ts",
26
26
  "types": "./dist/types/src/cli/index.d.ts"
27
27
  }
28
28
  },
@@ -35,44 +35,46 @@
35
35
  "src"
36
36
  ],
37
37
  "dependencies": {
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"
38
+ "@effect-atom/atom-react": "^0.5.0",
39
+ "@effect/cli": "0.73.2",
40
+ "yaml": "^2.7.0",
41
+ "@dxos/app-toolkit": "0.8.4-main.c351d160a8",
42
+ "@dxos/app-framework": "0.8.4-main.c351d160a8",
43
+ "@dxos/client-protocol": "0.8.4-main.c351d160a8",
44
+ "@dxos/echo": "0.8.4-main.c351d160a8",
45
+ "@dxos/effect": "0.8.4-main.c351d160a8",
46
+ "@dxos/invariant": "0.8.4-main.c351d160a8",
47
+ "@dxos/cli-util": "0.8.4-main.c351d160a8",
48
+ "@dxos/plugin-graph": "0.8.4-main.c351d160a8",
49
+ "@dxos/operation": "0.8.4-main.c351d160a8",
50
+ "@dxos/plugin-observability": "0.8.4-main.c351d160a8",
51
+ "@dxos/react-ui-form": "0.8.4-main.c351d160a8",
52
+ "@dxos/react-ui-mosaic": "0.8.4-main.c351d160a8",
53
+ "@dxos/react-ui-stack": "0.8.4-main.c351d160a8",
54
+ "@dxos/util": "0.8.4-main.c351d160a8"
53
55
  },
54
56
  "devDependencies": {
55
- "@effect-atom/atom-react": "^0.4.6",
56
- "@effect/platform": "0.93.6",
57
+ "@effect-atom/atom-react": "^0.5.0",
58
+ "@effect/platform": "0.94.4",
57
59
  "@types/react": "~19.2.7",
58
60
  "@types/react-dom": "~19.2.3",
59
- "effect": "3.19.11",
61
+ "effect": "3.19.16",
60
62
  "react": "~19.2.3",
61
63
  "react-dom": "~19.2.3",
62
- "vite": "7.1.9",
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"
64
+ "vite": "^7.1.11",
65
+ "@dxos/random": "0.8.4-main.c351d160a8",
66
+ "@dxos/react-ui": "0.8.4-main.c351d160a8",
67
+ "@dxos/ui-theme": "0.8.4-main.c351d160a8",
68
+ "@dxos/storybook-utils": "0.8.4-main.c351d160a8"
67
69
  },
68
70
  "peerDependencies": {
69
- "@effect-atom/atom-react": "^0.4.6",
70
- "@effect/platform": "0.93.6",
71
- "effect": "3.19.11",
71
+ "@effect-atom/atom-react": "^0.5.0",
72
+ "@effect/platform": "0.94.4",
73
+ "effect": "3.19.16",
72
74
  "react": "~19.2.3",
73
75
  "react-dom": "~19.2.3",
74
- "@dxos/react-ui": "0.8.4-main.bc674ce",
75
- "@dxos/ui-theme": "0.8.4-main.bc674ce"
76
+ "@dxos/react-ui": "0.8.4-main.c351d160a8",
77
+ "@dxos/ui-theme": "0.8.4-main.c351d160a8"
76
78
  },
77
79
  "publishConfig": {
78
80
  "access": "public"
@@ -2,16 +2,17 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { Common, Plugin } from '@dxos/app-framework';
5
+ import { Plugin } from '@dxos/app-framework';
6
+ import { AppPlugin } from '@dxos/app-toolkit';
6
7
 
7
8
  import { AppGraphBuilder, OperationResolver, ReactSurface } from './capabilities';
8
9
  import { meta } from './meta';
9
10
  import { translations } from './translations';
10
11
 
11
12
  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 }),
13
+ AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }),
14
+ AppPlugin.addOperationResolverModule({ activate: OperationResolver }),
15
+ AppPlugin.addSurfaceModule({ activate: ReactSurface }),
16
+ AppPlugin.addTranslationsModule({ translations }),
16
17
  Plugin.make,
17
18
  );
@@ -4,7 +4,8 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { Capability, Common, SettingsOperation } from '@dxos/app-framework';
7
+ import { Capabilities, Capability } from '@dxos/app-framework';
8
+ import { AppCapabilities, SettingsOperation } from '@dxos/app-toolkit';
8
9
  import { Operation } from '@dxos/operation';
9
10
  import { GraphBuilder, NodeMatcher } from '@dxos/plugin-graph';
10
11
 
@@ -47,9 +48,9 @@ export default Capability.makeModule(
47
48
  },
48
49
  nodes: [
49
50
  {
50
- id: `${REGISTRY_KEY}+all`,
51
- type: 'category',
52
- data: `${REGISTRY_KEY}+all`,
51
+ id: `${REGISTRY_KEY}>all`,
52
+ type: 'category' as const,
53
+ data: `${REGISTRY_KEY}>all`,
53
54
  properties: {
54
55
  label: ['all plugins label', { ns: meta.id }],
55
56
  icon: 'ph--squares-four--regular',
@@ -58,9 +59,9 @@ export default Capability.makeModule(
58
59
  },
59
60
  },
60
61
  {
61
- id: `${REGISTRY_KEY}+installed`,
62
- type: 'category',
63
- data: `${REGISTRY_KEY}+installed`,
62
+ id: `${REGISTRY_KEY}>installed`,
63
+ type: 'category' as const,
64
+ data: `${REGISTRY_KEY}>installed`,
64
65
  properties: {
65
66
  label: ['installed plugins label', { ns: meta.id }],
66
67
  icon: 'ph--check--regular',
@@ -69,9 +70,9 @@ export default Capability.makeModule(
69
70
  },
70
71
  },
71
72
  {
72
- id: `${REGISTRY_KEY}+recommended`,
73
- type: 'category',
74
- data: `${REGISTRY_KEY}+recommended`,
73
+ id: `${REGISTRY_KEY}>recommended`,
74
+ type: 'category' as const,
75
+ data: `${REGISTRY_KEY}>recommended`,
75
76
  properties: {
76
77
  label: ['recommended plugins label', { ns: meta.id }],
77
78
  icon: 'ph--star--regular',
@@ -80,9 +81,9 @@ export default Capability.makeModule(
80
81
  },
81
82
  },
82
83
  {
83
- id: `${REGISTRY_KEY}+labs`,
84
- type: 'category',
85
- data: `${REGISTRY_KEY}+labs`,
84
+ id: `${REGISTRY_KEY}>labs`,
85
+ type: 'category' as const,
86
+ data: `${REGISTRY_KEY}>labs`,
86
87
  properties: {
87
88
  label: ['labs plugins label', { ns: meta.id }],
88
89
  icon: 'ph--flask--regular',
@@ -95,12 +96,12 @@ export default Capability.makeModule(
95
96
  ]),
96
97
  }),
97
98
  GraphBuilder.createExtension({
98
- id: `${meta.id}/actions`,
99
- match: NodeMatcher.whenId(REGISTRY_ID),
99
+ id: `${meta.id}.actions`,
100
+ match: NodeMatcher.whenId(`root/${REGISTRY_ID}`),
100
101
  actions: () =>
101
102
  Effect.succeed([
102
103
  {
103
- id: `${meta.id}/load-by-url`,
104
+ id: `${meta.id}.load-by-url`,
104
105
  data: Effect.fnUntraced(function* () {}),
105
106
  properties: {
106
107
  label: ['load by url label', { ns: meta.id }],
@@ -111,14 +112,14 @@ export default Capability.makeModule(
111
112
  ]),
112
113
  }),
113
114
  GraphBuilder.createExtension({
114
- id: `${meta.id}/plugins`,
115
- match: NodeMatcher.whenId(REGISTRY_ID),
115
+ id: `${meta.id}.plugins`,
116
+ match: NodeMatcher.whenId(`root/${REGISTRY_ID}`),
116
117
  connector: () => {
117
- const manager = capabilities.get(Common.Capability.PluginManager);
118
+ const manager = capabilities.get(Capabilities.PluginManager);
118
119
  return Effect.succeed(
119
120
  manager.getPlugins().map((plugin) => ({
120
- id: plugin.meta.id.replaceAll('/', ':'),
121
- type: 'dxos.org/plugin',
121
+ id: plugin.meta.id,
122
+ type: 'org.dxos.plugin',
122
123
  data: plugin,
123
124
  properties: {
124
125
  label: plugin.meta.name ?? plugin.meta.id,
@@ -131,6 +132,6 @@ export default Capability.makeModule(
131
132
  }),
132
133
  ]);
133
134
 
134
- return Capability.contributes(Common.Capability.AppGraphBuilder, extensions);
135
+ return Capability.contributes(AppCapabilities.AppGraphBuilder, extensions);
135
136
  }),
136
137
  );
@@ -4,18 +4,19 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { Capability, Common, SettingsOperation } from '@dxos/app-framework';
7
+ import { Capabilities, Capability } from '@dxos/app-framework';
8
+ import { LayoutOperation, SettingsOperation, getSpacePath } from '@dxos/app-toolkit';
8
9
  import { Operation, OperationResolver } from '@dxos/operation';
9
10
 
10
11
  import { REGISTRY_ID } from '../../meta';
11
12
 
12
13
  export default Capability.makeModule(
13
14
  Effect.fnUntraced(function* () {
14
- return Capability.contributes(Common.Capability.OperationResolver, [
15
+ return Capability.contributes(Capabilities.OperationResolver, [
15
16
  OperationResolver.make({
16
17
  operation: SettingsOperation.OpenPluginRegistry,
17
18
  handler: Effect.fnUntraced(function* () {
18
- yield* Operation.invoke(Common.LayoutOperation.SwitchWorkspace, { subject: REGISTRY_ID });
19
+ yield* Operation.invoke(LayoutOperation.SwitchWorkspace, { subject: getSpacePath(REGISTRY_ID) });
19
20
  }),
20
21
  }),
21
22
  ]);
@@ -3,22 +3,21 @@
3
3
  //
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
- import React, { useCallback, useMemo } from 'react';
6
+ import React, { useMemo } from 'react';
7
7
 
8
- import { Capability, Common, Plugin } from '@dxos/app-framework';
9
- import { usePluginManager } from '@dxos/app-framework/react';
10
- import { runAndForwardErrors } from '@dxos/effect';
8
+ import { Capabilities, Capability, Plugin } from '@dxos/app-framework';
9
+ import { Surface, usePluginManager } from '@dxos/app-framework/ui';
11
10
 
12
- import { PluginDetail, RegistryContainer } from '../../components';
11
+ import { PluginArticle, PluginRegistry } from '../../containers';
13
12
  import { REGISTRY_KEY, meta } from '../../meta';
14
13
 
15
14
  export default Capability.makeModule(() =>
16
15
  Effect.succeed(
17
- Capability.contributes(Common.Capability.ReactSurface, [
18
- Common.createSurface({
19
- id: `${meta.id}/all`,
16
+ Capability.contributes(Capabilities.ReactSurface, [
17
+ Surface.create({
18
+ id: `${meta.id}.all`,
20
19
  role: 'article',
21
- filter: (data): data is any => data.subject === `${REGISTRY_KEY}+all`,
20
+ filter: (data): data is any => data.subject === `${REGISTRY_KEY}>all`,
22
21
  component: () => {
23
22
  const manager = usePluginManager();
24
23
  const filtered = useMemo(
@@ -26,13 +25,13 @@ export default Capability.makeModule(() =>
26
25
  [],
27
26
  );
28
27
 
29
- return <RegistryContainer id={`${REGISTRY_KEY}+all`} plugins={filtered} />;
28
+ return <PluginRegistry id={`${REGISTRY_KEY}>all`} plugins={filtered} />;
30
29
  },
31
30
  }),
32
- Common.createSurface({
33
- id: `${meta.id}/installed`,
31
+ Surface.create({
32
+ id: `${meta.id}.installed`,
34
33
  role: 'article',
35
- filter: (data): data is any => data.subject === `${REGISTRY_KEY}+installed`,
34
+ filter: (data): data is any => data.subject === `${REGISTRY_KEY}>installed`,
36
35
  component: () => {
37
36
  const manager = usePluginManager();
38
37
  const filtered = useMemo(
@@ -44,13 +43,13 @@ export default Capability.makeModule(() =>
44
43
  [],
45
44
  );
46
45
 
47
- return <RegistryContainer id={`${REGISTRY_KEY}+installed`} plugins={filtered} />;
46
+ return <PluginRegistry id={`${REGISTRY_KEY}>installed`} plugins={filtered} />;
48
47
  },
49
48
  }),
50
- Common.createSurface({
51
- id: `${meta.id}/recommended`,
49
+ Surface.create({
50
+ id: `${meta.id}.recommended`,
52
51
  role: 'article',
53
- filter: (data): data is any => data.subject === `${REGISTRY_KEY}+recommended`,
52
+ filter: (data): data is any => data.subject === `${REGISTRY_KEY}>recommended`,
54
53
  component: () => {
55
54
  const manager = usePluginManager();
56
55
  const filtered = useMemo(
@@ -62,36 +61,26 @@ export default Capability.makeModule(() =>
62
61
  [],
63
62
  );
64
63
 
65
- return <RegistryContainer id={`${REGISTRY_KEY}+recommended`} plugins={filtered} />;
64
+ return <PluginRegistry id={`${REGISTRY_KEY}>recommended`} plugins={filtered} />;
66
65
  },
67
66
  }),
68
- Common.createSurface({
69
- id: `${meta.id}/labs`,
67
+ Surface.create({
68
+ id: `${meta.id}.labs`,
70
69
  role: 'article',
71
- filter: (data): data is any => data.subject === `${REGISTRY_KEY}+labs`,
70
+ filter: (data): data is any => data.subject === `${REGISTRY_KEY}>labs`,
72
71
  component: () => {
73
72
  const manager = usePluginManager();
74
73
  const filtered = useMemo(() => manager.getPlugins().filter(({ meta }) => meta.tags?.includes('labs')), []);
75
74
 
76
- return <RegistryContainer id={`${REGISTRY_KEY}+labs`} plugins={filtered} />;
75
+ return <PluginRegistry id={`${REGISTRY_KEY}>labs`} plugins={filtered} />;
77
76
  },
78
77
  }),
79
- Common.createSurface({
80
- id: `${meta.id}/plugin-details`,
78
+ Surface.create({
79
+ id: `${meta.id}.plugin-details`,
81
80
  role: 'article',
82
81
  filter: (data): data is { subject: Plugin.Plugin } => Plugin.isPlugin(data.subject),
83
82
  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} />;
83
+ return <PluginArticle subject={subject} />;
95
84
  },
96
85
  }),
97
86
  ]),
package/src/cli/plugin.ts CHANGED
@@ -2,14 +2,15 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Common, Plugin } from '@dxos/app-framework';
5
+ import { Plugin } from '@dxos/app-framework';
6
+ import { AppPlugin } from '@dxos/app-toolkit';
6
7
 
7
8
  import { meta } from '../meta';
8
9
 
9
10
  import { plugin } from './commands';
10
11
 
11
12
  export const RegistryPlugin = Plugin.define(meta).pipe(
12
- Common.Plugin.addCommandModule({
13
+ AppPlugin.addCommandModule({
13
14
  commands: [plugin],
14
15
  }),
15
16
  Plugin.make,
@@ -6,37 +6,31 @@ import * as FileSystem from '@effect/platform/FileSystem';
6
6
  import * as Path from '@effect/platform/Path';
7
7
  import * as Effect from 'effect/Effect';
8
8
  import * as Schema from 'effect/Schema';
9
+ import * as Yaml from 'yaml';
9
10
 
10
- import { DX_CONFIG, getProfilePath } from '@dxos/client-protocol';
11
+ import { DX_CONFIG } from '@dxos/client-protocol';
11
12
 
12
13
  // TODO(wittjosiah): Factor out to app-framework?
13
14
 
14
- const PLUGINS_FILE = 'plugins.json';
15
-
16
15
  const PluginsSchema = Schema.Array(Schema.String);
17
16
 
18
- /**
19
- * Get the path to the plugins configuration file for a profile.
20
- */
21
- const getPluginsPath = (profile: string): Effect.Effect<string, never, Path.Path> =>
22
- Effect.gen(function* () {
23
- const path = yield* Path.Path;
24
- return path.join(getProfilePath(DX_CONFIG, profile), PLUGINS_FILE);
25
- });
17
+ /** CLI-only: path to plugins/<profile>.yml (sibling to profile/). */
18
+ const getPluginsConfigPath = (profile: string) => `${DX_CONFIG}/plugins/${profile}.yml`;
26
19
 
27
20
  /**
28
- * Load enabled plugins from profile storage.
21
+ * Load enabled plugins from plugins/<profile>.yml (sibling to profile/).
29
22
  * Returns the list of enabled plugin IDs, or an empty array if the file doesn't exist.
30
23
  */
31
24
  export const loadEnabledPlugins = Effect.fn(function* ({ profile }: { profile: string }) {
32
25
  const fs = yield* FileSystem.FileSystem;
33
- const pluginsPath = yield* getPluginsPath(profile);
26
+ const pluginsPath = getPluginsConfigPath(profile);
34
27
 
35
28
  const content = yield* fs
36
29
  .readFileString(pluginsPath)
37
30
  .pipe(Effect.catchTag('SystemError', () => Effect.succeed('[]')));
38
31
 
39
- const parsed = yield* Schema.decodeUnknown(Schema.parseJson(PluginsSchema))(content).pipe(
32
+ const raw = Yaml.parse(content);
33
+ const parsed = yield* Schema.decodeUnknown(PluginsSchema)(raw ?? []).pipe(
40
34
  Effect.catchAll(() => Effect.succeed([] as string[])),
41
35
  );
42
36
 
@@ -44,14 +38,13 @@ export const loadEnabledPlugins = Effect.fn(function* ({ profile }: { profile: s
44
38
  });
45
39
 
46
40
  /**
47
- * Save enabled plugins to profile storage.
41
+ * Save enabled plugins to plugins/<profile>.yml.
48
42
  */
49
43
  export const saveEnabledPlugins = Effect.fn(function* ({ profile, enabled }: { profile: string; enabled: string[] }) {
50
44
  const fs = yield* FileSystem.FileSystem;
51
- const pluginsPath = yield* getPluginsPath(profile);
52
- const profileDir = getProfilePath(DX_CONFIG, profile);
53
-
54
- yield* fs.makeDirectory(profileDir, { recursive: true });
55
- const encoded = Schema.encodeSync(Schema.parseJson(PluginsSchema))(enabled);
56
- yield* fs.writeFileString(pluginsPath, encoded + '\n');
45
+ const path = yield* Path.Path;
46
+ const pluginsPath = getPluginsConfigPath(profile);
47
+ yield* fs.makeDirectory(path.dirname(pluginsPath), { recursive: true });
48
+ const encoded = Yaml.stringify(enabled);
49
+ yield* fs.writeFileString(pluginsPath, encoded);
57
50
  });
@@ -8,15 +8,16 @@ import { Plugin } from '@dxos/app-framework';
8
8
  import { faker } 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
13
  import { PluginDetail } from './PluginDetail';
14
14
 
15
15
  const meta = {
16
- title: 'plugins/plugin-registry/PluginDetail',
16
+ title: 'plugins/plugin-registry/components/PluginDetail',
17
17
  component: PluginDetail,
18
- decorators: [withTheme, withLayout({ layout: 'column' })],
18
+ decorators: [withTheme(), withLayout({ layout: 'column' })],
19
19
  parameters: {
20
+ layout: 'fullscreen',
20
21
  translations,
21
22
  },
22
23
  } satisfies Meta<typeof PluginDetail>;
@@ -0,0 +1,81 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { type Plugin } from '@dxos/app-framework';
8
+ import { Icon, Input, Link, useTranslation } from '@dxos/react-ui';
9
+ import { ScrollArea } from '@dxos/react-ui';
10
+ import { getStyles, mx } from '@dxos/ui-theme';
11
+
12
+ import { meta } from '../../meta';
13
+
14
+ export type PluginDetailProps = {
15
+ plugin: Plugin.Plugin;
16
+ enabled?: boolean;
17
+ onEnabledChange?: (enabled: boolean) => void;
18
+ };
19
+
20
+ export const PluginDetail = ({ plugin, enabled, onEnabledChange }: PluginDetailProps) => {
21
+ const { t } = useTranslation(meta.id);
22
+ const {
23
+ id,
24
+ name,
25
+ description,
26
+ homePage,
27
+ source,
28
+ screenshots,
29
+ icon = 'ph--circle--regular',
30
+ iconHue = 'neutral',
31
+ } = plugin.meta;
32
+ const styles = getStyles(iconHue);
33
+
34
+ return (
35
+ <ScrollArea.Root orientation='vertical'>
36
+ <ScrollArea.Viewport>
37
+ <div role='none' className='dx-document grid grid-cols-[min-content_1fr] gap-4 p-4'>
38
+ <div role='none'>
39
+ <Icon classNames={mx('p-1 rounded-md', styles.fill, styles.surfaceText)} icon={icon} size={14} />
40
+ </div>
41
+ <div role='none' className='flex flex-col gap-6'>
42
+ <div role='none' className='grid grid-cols-[1fr_min-content] gap-x-3 w-full pt-1'>
43
+ <h2 className='text-xl'>{name}</h2>
44
+ <Input.Root>
45
+ <Input.Switch classNames='self-center' checked={enabled} onCheckedChange={onEnabledChange} />
46
+ </Input.Root>
47
+ <p className='pt-0.5 text-sm text-description'>{id}</p>
48
+ </div>
49
+ <div role='none'>
50
+ <p className='text-description'>{description}</p>
51
+ </div>
52
+ {screenshots && screenshots.length > 0 && (
53
+ <div role='none' className='flex flex-col gap-2'>
54
+ <h2>Preview</h2>
55
+ <img src={screenshots[0]} alt={name} className='aspect-video object-fit' />
56
+ </div>
57
+ )}
58
+ <div role='none' className='flex flex-col gap-2'>
59
+ <h2>Resources</h2>
60
+ <div className='flex gap-2'>
61
+ {homePage && (
62
+ <Link href={homePage} target='_blank' rel='noreferrer' classNames='text-sm text-description'>
63
+ {t('home page label')}
64
+ <Icon icon='ph--arrow-square-out--bold' size={3} classNames='inline-block leading-none mx-1' />
65
+ </Link>
66
+ )}
67
+
68
+ {source && (
69
+ <Link href={source} target='_blank' rel='noreferrer' classNames='text-sm text-description'>
70
+ {t('source label')}
71
+ <Icon icon='ph--arrow-square-out--bold' size={3} classNames='inline-block leading-none mx-1' />
72
+ </Link>
73
+ )}
74
+ </div>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </ScrollArea.Viewport>
79
+ </ScrollArea.Root>
80
+ );
81
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './PluginDetail';
@@ -6,11 +6,11 @@ import React, { type MouseEvent, useCallback } from 'react';
6
6
 
7
7
  import { type Plugin } from '@dxos/app-framework';
8
8
  import { type ChromaticPalette, Icon, IconButton, Input, Link, ListItem, Tag, useTranslation } from '@dxos/react-ui';
9
- import { descriptionText, mx } from '@dxos/ui-theme';
9
+ import { mx } from '@dxos/ui-theme';
10
10
  import { getStyles } from '@dxos/ui-theme';
11
11
 
12
- import { meta } from '../meta';
13
- import { type RegistryTagType } from '../types';
12
+ import { meta } from '../../meta';
13
+ import { type RegistryTagType } from '../../types';
14
14
 
15
15
  export type PluginItemProps = {
16
16
  plugin: Plugin.Plugin;
@@ -58,11 +58,15 @@ export const PluginItem = ({
58
58
  labelId={labelId}
59
59
  data-testid={`pluginList.${id}`}
60
60
  aria-describedby={descriptionId}
61
- classNames={mx(gridCols, 'bs-[12rem] is-full gap-3 pie-2 border border-separator rounded-md overflow-hidden')}
61
+ classNames={mx(gridCols, 'h-[12rem] w-full gap-3 pe-2 bg-modal-surface rounded-md overflow-hidden')}
62
62
  >
63
- <div className={mx(gridRows, 'justify-center rounded-l-md', styles.bg)}>
64
- <div />
65
- <Icon classNames={mx('cursor-pointer', styles.icon)} icon={icon} size={14} onClick={handleClick} />
63
+ <div className={mx(gridRows, 'justify-center rounded-l-md', styles.surface)}>
64
+ <Icon
65
+ classNames={mx('row-start-2 cursor-pointer', styles.surfaceText)}
66
+ icon={icon}
67
+ size={14}
68
+ onClick={handleClick}
69
+ />
66
70
  </div>
67
71
 
68
72
  <div className={mx(gridRows)}>
@@ -71,10 +75,10 @@ export const PluginItem = ({
71
75
  </div>
72
76
 
73
77
  <div>
74
- <p className={mx(descriptionText, 'line-clamp-4 min-is-0')}>{description}</p>
78
+ <p className={mx('text-description', 'line-clamp-4 min-w-0')}>{description}</p>
75
79
  </div>
76
80
 
77
- <div className='flex -mis-0.5 overflow-x-auto scrollbar-none'>
81
+ <div className='flex -ms-0.5 overflow-x-auto scrollbar-none'>
78
82
  {tags?.map((tag) => (
79
83
  <Tag key={tag} palette={tagColors[tag as RegistryTagType]} classNames='text-xs uppercase font-thin'>
80
84
  {tag}
@@ -99,7 +103,7 @@ export const PluginItem = ({
99
103
  </Link>
100
104
 
101
105
  <div className='grow' />
102
- <div className='pie-1'>
106
+ <div className='pe-1'>
103
107
  <Input.Root id={inputId}>
104
108
  <Input.Switch classNames='self-center' checked={isEnabled} onClick={handleChange} />
105
109
  </Input.Root>