@dxos/plugin-registry 0.9.0 → 0.9.1-staging.ee54ba693a

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 (145) hide show
  1. package/dist/lib/neutral/RegistryPlugin.node.mjs +709 -18
  2. package/dist/lib/neutral/RegistryPlugin.node.mjs.map +4 -4
  3. package/dist/lib/neutral/chunk-ZY37XLVF.mjs +46 -0
  4. package/dist/lib/neutral/chunk-ZY37XLVF.mjs.map +7 -0
  5. package/dist/lib/neutral/index.mjs +1 -1
  6. package/dist/lib/neutral/meta.json +1 -1
  7. package/dist/lib/neutral/{open-plugin-registry-II735N76.mjs → open-plugin-registry-ID7LV3SF.mjs} +3 -3
  8. package/dist/lib/neutral/open-plugin-registry-ID7LV3SF.mjs.map +7 -0
  9. package/dist/lib/neutral/plugin.mjs +2 -2
  10. package/dist/lib/neutral/translations.mjs +6 -6
  11. package/dist/lib/neutral/translations.mjs.map +3 -3
  12. package/dist/types/dx.config.d.ts +28 -0
  13. package/dist/types/dx.config.d.ts.map +1 -0
  14. package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -2
  15. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  16. package/dist/types/src/capabilities/index.d.ts +4 -12
  17. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  18. package/dist/types/src/capabilities/react-surface.d.ts +2 -2
  19. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  20. package/dist/types/src/capabilities/settings.d.ts +1 -10
  21. package/dist/types/src/capabilities/settings.d.ts.map +1 -1
  22. package/dist/types/src/categories.d.ts.map +1 -1
  23. package/dist/types/src/commands/index.d.ts +2 -2
  24. package/dist/types/src/commands/index.d.ts.map +1 -1
  25. package/dist/types/src/commands/plugin/disable.d.ts.map +1 -0
  26. package/dist/types/src/commands/plugin/enable.d.ts.map +1 -0
  27. package/dist/types/src/commands/plugin/index.d.ts +3 -0
  28. package/dist/types/src/commands/plugin/index.d.ts.map +1 -0
  29. package/dist/types/src/commands/plugin/list.d.ts.map +1 -0
  30. package/dist/types/src/commands/plugin/util.d.ts.map +1 -0
  31. package/dist/types/src/commands/registry/index.d.ts +16 -0
  32. package/dist/types/src/commands/registry/index.d.ts.map +1 -0
  33. package/dist/types/src/commands/registry/publish-package.d.ts +29 -0
  34. package/dist/types/src/commands/registry/publish-package.d.ts.map +1 -0
  35. package/dist/types/src/commands/registry/publish-publisher.d.ts +19 -0
  36. package/dist/types/src/commands/registry/publish-publisher.d.ts.map +1 -0
  37. package/dist/types/src/commands/registry/publish.d.ts +25 -0
  38. package/dist/types/src/commands/registry/publish.d.ts.map +1 -0
  39. package/dist/types/src/commands/registry/records.d.ts +14 -0
  40. package/dist/types/src/commands/registry/records.d.ts.map +1 -0
  41. package/dist/types/src/commands/registry/unpublish.d.ts +15 -0
  42. package/dist/types/src/commands/registry/unpublish.d.ts.map +1 -0
  43. package/dist/types/src/commands/registry/util.d.ts +113 -0
  44. package/dist/types/src/commands/registry/util.d.ts.map +1 -0
  45. package/dist/types/src/commands/registry/verify.d.ts +20 -0
  46. package/dist/types/src/commands/registry/verify.d.ts.map +1 -0
  47. package/dist/types/src/components/PluginDetail/PluginDetail.d.ts +2 -2
  48. package/dist/types/src/components/PluginDetail/PluginDetail.d.ts.map +1 -1
  49. package/dist/types/src/components/PluginDetail/PluginDetail.stories.d.ts +6 -5
  50. package/dist/types/src/components/PluginDetail/PluginDetail.stories.d.ts.map +1 -1
  51. package/dist/types/src/components/PluginFailureBadge/PluginFailureBadge.d.ts +1 -3
  52. package/dist/types/src/components/PluginFailureBadge/PluginFailureBadge.d.ts.map +1 -1
  53. package/dist/types/src/components/PluginList/PluginItem.d.ts.map +1 -1
  54. package/dist/types/src/components/PluginList/PluginList.d.ts.map +1 -1
  55. package/dist/types/src/components/PluginList/PluginList.stories.d.ts +5 -5
  56. package/dist/types/src/components/PluginList/PluginList.stories.d.ts.map +1 -1
  57. package/dist/types/src/components/RegistrySettings/RegistrySettings.d.ts +5 -1
  58. package/dist/types/src/components/RegistrySettings/RegistrySettings.d.ts.map +1 -1
  59. package/dist/types/src/components/RegistrySettings/RegistrySettings.stories.d.ts +78 -0
  60. package/dist/types/src/components/RegistrySettings/RegistrySettings.stories.d.ts.map +1 -0
  61. package/dist/types/src/containers/LoadPluginDialog/LoadPluginDialog.d.ts.map +1 -1
  62. package/dist/types/src/containers/PluginArticle/PluginArticle.d.ts.map +1 -1
  63. package/dist/types/src/containers/PublicRegistryArticle/PublicRegistryArticle.d.ts.map +1 -1
  64. package/dist/types/src/containers/PublicRegistryArticle/index.d.ts +1 -1
  65. package/dist/types/src/containers/PublicRegistryArticle/index.d.ts.map +1 -1
  66. package/dist/types/src/containers/RegistryArticle/index.d.ts +1 -1
  67. package/dist/types/src/containers/RegistryArticle/index.d.ts.map +1 -1
  68. package/dist/types/src/hooks/useAutoTags.d.ts +2 -2
  69. package/dist/types/src/hooks/useAutoTags.d.ts.map +1 -1
  70. package/dist/types/src/hooks/useCatalogEntry.d.ts +4 -5
  71. package/dist/types/src/hooks/useCatalogEntry.d.ts.map +1 -1
  72. package/dist/types/src/hooks/usePluginActions.d.ts +3 -3
  73. package/dist/types/src/hooks/usePluginActions.d.ts.map +1 -1
  74. package/dist/types/src/hooks/useUpdateAvailable.d.ts +2 -2
  75. package/dist/types/src/hooks/useUpdateAvailable.d.ts.map +1 -1
  76. package/dist/types/src/hooks/useVersionPicker.d.ts +7 -8
  77. package/dist/types/src/hooks/useVersionPicker.d.ts.map +1 -1
  78. package/dist/types/src/meta.d.ts +32 -2
  79. package/dist/types/src/meta.d.ts.map +1 -1
  80. package/dist/types/src/operations/open-plugin-registry.d.ts.map +1 -1
  81. package/dist/types/src/translations.d.ts +5 -5
  82. package/dist/types/src/translations.d.ts.map +1 -1
  83. package/dist/types/src/types.d.ts.map +1 -1
  84. package/dist/types/tsconfig.tsbuildinfo +1 -1
  85. package/dx.config.ts +20 -0
  86. package/package.json +40 -33
  87. package/src/RegistryPlugin.node.ts +2 -2
  88. package/src/RegistryPlugin.test.ts +1 -1
  89. package/src/capabilities/app-graph-builder.ts +46 -41
  90. package/src/capabilities/dev-plugin-loader.ts +1 -1
  91. package/src/capabilities/react-surface.tsx +1 -4
  92. package/src/capabilities/settings.ts +2 -2
  93. package/src/categories.ts +5 -4
  94. package/src/commands/index.ts +2 -10
  95. package/src/commands/{disable.ts → plugin/disable.ts} +3 -3
  96. package/src/commands/{enable.ts → plugin/enable.ts} +3 -3
  97. package/src/commands/plugin/index.ts +14 -0
  98. package/src/commands/{list.ts → plugin/list.ts} +4 -4
  99. package/src/commands/registry/index.ts +30 -0
  100. package/src/commands/registry/publish-package.ts +119 -0
  101. package/src/commands/registry/publish-publisher.ts +73 -0
  102. package/src/commands/registry/publish.ts +278 -0
  103. package/src/commands/registry/records.ts +73 -0
  104. package/src/commands/registry/unpublish.ts +70 -0
  105. package/src/commands/registry/util.ts +395 -0
  106. package/src/commands/registry/verify.ts +76 -0
  107. package/src/components/DisableDependentsAlert/DisableDependentsAlert.tsx +1 -1
  108. package/src/components/PluginDetail/PluginDetail.stories.tsx +31 -15
  109. package/src/components/PluginDetail/PluginDetail.tsx +21 -23
  110. package/src/components/PluginFailureBadge/PluginFailureBadge.tsx +21 -24
  111. package/src/components/PluginList/PluginItem.tsx +16 -11
  112. package/src/components/PluginList/PluginList.stories.tsx +1 -2
  113. package/src/components/PluginList/PluginList.tsx +18 -13
  114. package/src/components/RegistrySettings/RegistrySettings.stories.tsx +45 -0
  115. package/src/components/RegistrySettings/RegistrySettings.tsx +44 -33
  116. package/src/containers/BaseRegistryArticle/BaseRegistryArticle.tsx +2 -2
  117. package/src/containers/LoadPluginDialog/LoadPluginDialog.tsx +3 -3
  118. package/src/containers/PluginArticle/PluginArticle.tsx +8 -6
  119. package/src/containers/PublicRegistryArticle/PublicRegistryArticle.tsx +35 -28
  120. package/src/containers/PublicRegistryArticle/index.ts +1 -1
  121. package/src/containers/RegistryArticle/RegistryArticle.tsx +1 -1
  122. package/src/containers/RegistryArticle/index.ts +1 -1
  123. package/src/containers/RegistrySettingsContainer/RegistrySettingsContainer.tsx +2 -2
  124. package/src/hooks/useAutoTags.ts +3 -3
  125. package/src/hooks/useCatalogEntry.ts +6 -7
  126. package/src/hooks/useDisableConfirmation.ts +1 -1
  127. package/src/hooks/usePluginActions.ts +13 -11
  128. package/src/hooks/useUpdateAvailable.ts +5 -5
  129. package/src/hooks/useVersionPicker.ts +22 -30
  130. package/src/meta.ts +6 -15
  131. package/src/operations/open-plugin-registry.ts +2 -2
  132. package/src/translations.ts +6 -6
  133. package/src/types.ts +3 -1
  134. package/dist/lib/neutral/chunk-GRQI6MLI.mjs +0 -36
  135. package/dist/lib/neutral/chunk-GRQI6MLI.mjs.map +0 -7
  136. package/dist/lib/neutral/open-plugin-registry-II735N76.mjs.map +0 -7
  137. package/dist/types/src/commands/disable.d.ts.map +0 -1
  138. package/dist/types/src/commands/enable.d.ts.map +0 -1
  139. package/dist/types/src/commands/list.d.ts.map +0 -1
  140. package/dist/types/src/commands/util.d.ts.map +0 -1
  141. /package/dist/types/src/commands/{disable.d.ts → plugin/disable.d.ts} +0 -0
  142. /package/dist/types/src/commands/{enable.d.ts → plugin/enable.d.ts} +0 -0
  143. /package/dist/types/src/commands/{list.d.ts → plugin/list.d.ts} +0 -0
  144. /package/dist/types/src/commands/{util.d.ts → plugin/util.d.ts} +0 -0
  145. /package/src/commands/{util.ts → plugin/util.ts} +0 -0
package/dx.config.ts ADDED
@@ -0,0 +1,20 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Config2 } from '@dxos/app-framework/config';
6
+ import { trim } from '@dxos/util';
7
+
8
+ export default Config2.make({
9
+ plugin: {
10
+ key: 'org.dxos.plugin.registry',
11
+ name: 'Plugins',
12
+ author: 'DXOS',
13
+ description: trim`
14
+ Plugin management system for discovering, installing, and configuring workspace extensions.
15
+ Browse available plugins and customize your workspace capabilities.
16
+ `,
17
+ icon: { key: 'ph--squares-four--regular' },
18
+ tags: ['system'],
19
+ },
20
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-registry",
3
- "version": "0.9.0",
3
+ "version": "0.9.1-staging.ee54ba693a",
4
4
  "description": "Braneframe plugin gallery",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -52,52 +52,59 @@
52
52
  "types": "dist/types/src/index.d.ts",
53
53
  "files": [
54
54
  "dist",
55
+ "dx.config.ts",
55
56
  "src"
56
57
  ],
57
58
  "dependencies": {
58
59
  "@effect-atom/atom-react": "^0.5.0",
59
60
  "@effect/cli": "0.75.2",
60
61
  "yaml": "^2.8.2",
61
- "@dxos/app-toolkit": "0.9.0",
62
- "@dxos/cli-util": "0.9.0",
63
- "@dxos/compute": "0.9.0",
64
- "@dxos/effect": "0.9.0",
65
- "@dxos/client-protocol": "0.9.0",
66
- "@dxos/invariant": "0.9.0",
67
- "@dxos/keys": "0.9.0",
68
- "@dxos/plugin-graph": "0.9.0",
69
- "@dxos/plugin-observability": "0.9.0",
70
- "@dxos/react-ui-form": "0.9.0",
71
- "@dxos/app-framework": "0.9.0",
72
- "@dxos/react-ui-markdown": "0.9.0",
73
- "@dxos/react-ui-mosaic": "0.9.0",
74
- "@dxos/react-ui-stack": "0.9.0",
75
- "@dxos/util": "0.9.0",
76
- "@dxos/log": "0.9.0"
62
+ "@dxos/app-framework": "0.9.1-staging.ee54ba693a",
63
+ "@dxos/cli-util": "0.9.1-staging.ee54ba693a",
64
+ "@dxos/client": "0.9.1-staging.ee54ba693a",
65
+ "@dxos/app-toolkit": "0.9.1-staging.ee54ba693a",
66
+ "@dxos/client-protocol": "0.9.1-staging.ee54ba693a",
67
+ "@dxos/compute": "0.9.1-staging.ee54ba693a",
68
+ "@dxos/context": "0.9.1-staging.ee54ba693a",
69
+ "@dxos/edge-client": "0.9.1-staging.ee54ba693a",
70
+ "@dxos/echo": "0.9.1-staging.ee54ba693a",
71
+ "@dxos/invariant": "0.9.1-staging.ee54ba693a",
72
+ "@dxos/effect": "0.9.1-staging.ee54ba693a",
73
+ "@dxos/log": "0.9.1-staging.ee54ba693a",
74
+ "@dxos/plugin-graph": "0.9.1-staging.ee54ba693a",
75
+ "@dxos/keys": "0.9.1-staging.ee54ba693a",
76
+ "@dxos/protocols": "0.9.1-staging.ee54ba693a",
77
+ "@dxos/plugin-observability": "0.9.1-staging.ee54ba693a",
78
+ "@dxos/react-ui-form": "0.9.1-staging.ee54ba693a",
79
+ "@dxos/react-ui-markdown": "0.9.1-staging.ee54ba693a",
80
+ "@dxos/types": "0.9.1-staging.ee54ba693a",
81
+ "@dxos/react-ui-mosaic": "0.9.1-staging.ee54ba693a",
82
+ "@dxos/react-ui-list": "0.9.1-staging.ee54ba693a",
83
+ "@dxos/util": "0.9.1-staging.ee54ba693a"
77
84
  },
78
85
  "devDependencies": {
79
86
  "@effect-atom/atom-react": "^0.5.0",
80
- "@effect/platform": "0.96.1",
81
- "@types/react": "~19.2.7",
87
+ "@effect/platform": "0.96.2",
88
+ "@types/react": "~19.2.17",
82
89
  "@types/react-dom": "~19.2.3",
83
- "effect": "3.21.3",
84
- "react": "~19.2.3",
85
- "react-dom": "~19.2.3",
90
+ "effect": "3.21.4",
91
+ "react": "~19.2.7",
92
+ "react-dom": "~19.2.7",
86
93
  "vite": "^8.0.16",
87
- "@dxos/random": "0.9.0",
88
- "@dxos/plugin-testing": "0.9.0",
89
- "@dxos/react-ui": "0.9.0",
90
- "@dxos/storybook-utils": "0.9.0",
91
- "@dxos/ui-theme": "0.9.0"
94
+ "@dxos/random": "0.9.1-staging.ee54ba693a",
95
+ "@dxos/plugin-testing": "0.9.1-staging.ee54ba693a",
96
+ "@dxos/ui-theme": "0.9.1-staging.ee54ba693a",
97
+ "@dxos/react-ui": "0.9.1-staging.ee54ba693a",
98
+ "@dxos/storybook-utils": "0.9.1-staging.ee54ba693a"
92
99
  },
93
100
  "peerDependencies": {
94
101
  "@effect-atom/atom-react": "^0.5.0",
95
- "@effect/platform": "0.96.1",
96
- "effect": "3.21.3",
97
- "react": "~19.2.3",
98
- "react-dom": "~19.2.3",
99
- "@dxos/react-ui": "0.9.0",
100
- "@dxos/ui-theme": "0.9.0"
102
+ "@effect/platform": "0.96.2",
103
+ "effect": "3.21.4",
104
+ "react": "~19.2.7",
105
+ "react-dom": "~19.2.7",
106
+ "@dxos/react-ui": "0.9.1-staging.ee54ba693a",
107
+ "@dxos/ui-theme": "0.9.1-staging.ee54ba693a"
101
108
  },
102
109
  "publishConfig": {
103
110
  "access": "public"
@@ -7,11 +7,11 @@ import { AppPlugin } from '@dxos/app-toolkit';
7
7
 
8
8
  import { meta } from '#meta';
9
9
 
10
- import { plugin } from './commands';
10
+ import { plugin, registry } from './commands';
11
11
 
12
12
  export const RegistryPlugin = Plugin.define(meta).pipe(
13
13
  AppPlugin.addCommandModule({
14
- commands: [plugin],
14
+ commands: [plugin, registry],
15
15
  }),
16
16
  Plugin.make,
17
17
  );
@@ -10,7 +10,7 @@ import { RegistryPlugin } from '#plugin';
10
10
 
11
11
  import { meta } from './meta';
12
12
 
13
- const moduleId = (name: string) => `${meta.id}.module.${name}`;
13
+ const moduleId = (name: string) => `${meta.profile.key}.module.${name}`;
14
14
 
15
15
  describe('RegistryPlugin', () => {
16
16
  test('modules activate on the expected events', async ({ expect }) => {
@@ -4,13 +4,14 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { Capabilities, Capability, type Registry, Plugin } from '@dxos/app-framework';
7
+ import { Capabilities, Capability, Plugin } from '@dxos/app-framework';
8
8
  import { AppCapabilities, LayoutOperation, SettingsOperation } from '@dxos/app-toolkit';
9
9
  import { Operation } from '@dxos/compute';
10
10
  import { DXN } from '@dxos/keys';
11
11
  import { GraphBuilder, Node, NodeMatcher } from '@dxos/plugin-graph';
12
+ import { Position } from '@dxos/util';
12
13
 
13
- import { REGISTRY_ID, REGISTRY_KEY, registryCategoryId, meta } from '#meta';
14
+ import { REGISTRY_ID, REGISTRY_KEY, meta, registryCategoryId } from '#meta';
14
15
 
15
16
  import { getCategoryPredicate, getRemotePluginIds } from '../categories';
16
17
  import { LOAD_PLUGIN_DIALOG } from '../containers';
@@ -21,19 +22,19 @@ import { LOAD_PLUGIN_DIALOG } from '../containers';
21
22
  * modules and only exists so the article surface can render details for
22
23
  * registry plugins that haven't been installed yet.
23
24
  */
24
- const toDisplayPlugin = (entry: Registry.Plugin): Plugin.Plugin =>
25
+ const toDisplayPlugin = (entry: Plugin.Meta): Plugin.Plugin =>
25
26
  ({
26
27
  [Plugin.PluginTypeId]: Plugin.PluginTypeId,
27
28
  meta: Plugin.makeMeta({
28
- key: DXN.make(entry.id),
29
- name: entry.name,
30
- description: entry.description,
31
- homePage: entry.homePage,
32
- source: entry.source,
33
- screenshots: entry.screenshots,
34
- tags: entry.tags,
35
- icon: entry.icon,
36
- iconHue: entry.iconHue,
29
+ key: DXN.make(entry.profile.key),
30
+ name: entry.profile.name,
31
+ description: entry.profile.description,
32
+ homePage: entry.profile.homePage,
33
+ source: entry.profile.source,
34
+ screenshots: entry.profile.screenshots,
35
+ tags: entry.profile.tags,
36
+ icon: entry.profile.icon,
37
+ author: entry.profile.author,
37
38
  }),
38
39
  modules: [],
39
40
  }) as Plugin.Plugin;
@@ -52,7 +53,7 @@ export default Capability.makeModule(
52
53
  id: 'openRegistry',
53
54
  data: () => Operation.invoke(SettingsOperation.OpenPluginRegistry),
54
55
  properties: {
55
- label: ['open-plugin-registry.label', { ns: meta.id }],
56
+ label: ['open-plugin-registry.label', { ns: meta.profile.key }],
56
57
  icon: 'ph--squares-four--regular',
57
58
  disposition: 'menu',
58
59
  },
@@ -77,12 +78,12 @@ export default Capability.makeModule(
77
78
  return Effect.succeed([
78
79
  Node.make({
79
80
  id: REGISTRY_ID,
80
- type: meta.id,
81
+ type: meta.profile.key,
81
82
  properties: {
82
- label: ['plugin-registry.label', { ns: meta.id }],
83
+ label: ['plugin-registry.label', { ns: meta.profile.key }],
83
84
  icon: 'ph--squares-four--regular',
84
85
  disposition: 'pin-end',
85
- position: 'first',
86
+ position: Position.first,
86
87
  testId: 'treeView.pluginRegistry',
87
88
  },
88
89
  nodes: [
@@ -91,7 +92,7 @@ export default Capability.makeModule(
91
92
  type: 'category',
92
93
  data: registryCategoryId('bundled'),
93
94
  properties: {
94
- label: ['bundled-plugins.label', { ns: meta.id }],
95
+ label: ['bundled-plugins.label', { ns: meta.profile.key }],
95
96
  icon: 'ph--squares-four--regular',
96
97
  key: REGISTRY_KEY,
97
98
  testId: 'pluginRegistry.bundled',
@@ -103,7 +104,7 @@ export default Capability.makeModule(
103
104
  type: 'category',
104
105
  data: registryCategoryId('installed'),
105
106
  properties: {
106
- label: ['installed-plugins.label', { ns: meta.id }],
107
+ label: ['installed-plugins.label', { ns: meta.profile.key }],
107
108
  icon: 'ph--check--regular',
108
109
  key: REGISTRY_KEY,
109
110
  testId: 'pluginRegistry.installed',
@@ -115,7 +116,7 @@ export default Capability.makeModule(
115
116
  type: 'category',
116
117
  data: registryCategoryId('recommended'),
117
118
  properties: {
118
- label: ['recommended-plugins.label', { ns: meta.id }],
119
+ label: ['recommended-plugins.label', { ns: meta.profile.key }],
119
120
  icon: 'ph--star--regular',
120
121
  key: REGISTRY_KEY,
121
122
  testId: 'pluginRegistry.recommended',
@@ -127,25 +128,29 @@ export default Capability.makeModule(
127
128
  type: 'category',
128
129
  data: registryCategoryId('labs'),
129
130
  properties: {
130
- label: ['labs-plugins.label', { ns: meta.id }],
131
+ label: ['labs-plugins.label', { ns: meta.profile.key }],
131
132
  icon: 'ph--flask--regular',
132
133
  key: REGISTRY_KEY,
133
134
  testId: 'pluginRegistry.labs',
134
135
  count: categoryCount(registryCategoryId('labs')),
135
136
  },
136
137
  }),
137
- Node.make({
138
- id: registryCategoryId('registry'),
139
- type: 'category',
140
- data: registryCategoryId('registry'),
141
- properties: {
142
- label: ['registry-plugins.label', { ns: meta.id }],
143
- icon: 'ph--users-three--regular',
144
- key: REGISTRY_KEY,
145
- testId: 'pluginRegistry.registry',
146
- count: registryCount,
147
- },
148
- }),
138
+ ...(registryCount > 0
139
+ ? [
140
+ Node.make({
141
+ id: registryCategoryId('registry'),
142
+ type: 'category',
143
+ data: registryCategoryId('registry'),
144
+ properties: {
145
+ label: ['registry-plugins.label', { ns: meta.profile.key }],
146
+ icon: 'ph--users-three--regular',
147
+ key: REGISTRY_KEY,
148
+ testId: 'pluginRegistry.registry',
149
+ count: registryCount,
150
+ },
151
+ }),
152
+ ]
153
+ : []),
149
154
  ],
150
155
  }),
151
156
  ]);
@@ -165,7 +170,7 @@ export default Capability.makeModule(
165
170
  });
166
171
  }),
167
172
  properties: {
168
- label: ['load-by-url.label', { ns: meta.id }],
173
+ label: ['load-by-url.label', { ns: meta.profile.key }],
169
174
  icon: 'ph--cloud-arrow-down--regular',
170
175
  disposition: 'list-item-primary',
171
176
  },
@@ -177,16 +182,16 @@ export default Capability.makeModule(
177
182
  match: NodeMatcher.whenId(`root/${REGISTRY_ID}`),
178
183
  connector: (_node, get) => {
179
184
  const manager = capabilities.get(Capabilities.PluginManager);
180
- const installedIds = new Set(manager.getPlugins().map((plugin) => plugin.meta.id));
185
+ const installedIds = new Set(manager.getPlugins().map((plugin) => plugin.meta.profile.key));
181
186
 
182
187
  const installedNodes = manager.getPlugins().map((plugin) =>
183
188
  Node.make({
184
- id: plugin.meta.id,
189
+ id: plugin.meta.profile.key,
185
190
  type: 'org.dxos.plugin',
186
191
  data: plugin,
187
192
  properties: {
188
- label: plugin.meta.name ?? plugin.meta.id,
189
- icon: plugin.meta.icon ?? 'ph--circle--regular',
193
+ label: plugin.meta.profile.name ?? plugin.meta.profile.key,
194
+ icon: plugin.meta.profile.icon?.key ?? 'ph--circle--regular',
190
195
  disposition: 'hidden',
191
196
  },
192
197
  }),
@@ -194,16 +199,16 @@ export default Capability.makeModule(
194
199
 
195
200
  const registryEntries = get(manager.pluginRegistry.plugins).entries;
196
201
  const registryNodes = registryEntries
197
- .filter((entry) => !installedIds.has(DXN.make(entry.id)))
202
+ .filter((entry) => !installedIds.has(DXN.make(entry.profile.key)))
198
203
  .map((entry) => {
199
204
  const plugin = toDisplayPlugin(entry);
200
205
  return Node.make({
201
- id: plugin.meta.id,
206
+ id: plugin.meta.profile.key,
202
207
  type: 'org.dxos.plugin',
203
208
  data: plugin,
204
209
  properties: {
205
- label: plugin.meta.name ?? plugin.meta.id,
206
- icon: plugin.meta.icon ?? 'ph--circle--regular',
210
+ label: plugin.meta.profile.name ?? plugin.meta.profile.key,
211
+ icon: plugin.meta.profile.icon?.key ?? 'ph--circle--regular',
207
212
  disposition: 'hidden',
208
213
  },
209
214
  });
@@ -29,7 +29,7 @@ export default Capability.makeModule(
29
29
 
30
30
  log.info('loading dev plugin from registry settings', { url });
31
31
  yield* manager.add(url).pipe(
32
- Effect.flatMap((plugin) => manager.enable(plugin.meta.id)),
32
+ Effect.flatMap((plugin) => manager.enable(plugin.meta.profile.key)),
33
33
  Effect.tapError((error) => Effect.sync(() => log.warn('dev plugin auto-load failed', { url, error }))),
34
34
  Effect.ignore,
35
35
  );
@@ -7,7 +7,6 @@ import React, { type ComponentProps, 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';
11
10
  import { AppSurface } from '@dxos/app-toolkit/ui';
12
11
 
13
12
  import { DisableDependentsAlert } from '#components';
@@ -86,9 +85,7 @@ export default Capability.makeModule(() =>
86
85
  }),
87
86
  Surface.create({
88
87
  id: 'pluginSettings',
89
- role: 'article',
90
- filter: (data): data is { subject: AppCapabilities.Settings } =>
91
- AppCapabilities.isSettings(data.subject) && data.subject.prefix === meta.id,
88
+ filter: AppSurface.settings(AppSurface.Article, meta.profile.key),
92
89
  component: ({ data: { subject } }) => <RegistrySettingsContainer subject={subject} />,
93
90
  }),
94
91
  ]),
@@ -17,7 +17,7 @@ const DEFAULT_DEV_PLUGIN_URL = `http://localhost:${PLUGIN_DEV_SERVER_PORT}/manif
17
17
  export default Capability.makeModule(() =>
18
18
  Effect.sync(() => {
19
19
  const settingsAtom = createKvsStore({
20
- key: meta.id,
20
+ key: meta.profile.key,
21
21
  schema: RegistrySettingsSchema,
22
22
  defaultValue: () => ({ devPluginUrl: DEFAULT_DEV_PLUGIN_URL }),
23
23
  });
@@ -25,7 +25,7 @@ export default Capability.makeModule(() =>
25
25
  return [
26
26
  Capability.contributes(RegistryCapabilities.Settings, settingsAtom),
27
27
  Capability.contributes(AppCapabilities.Settings, {
28
- prefix: meta.id,
28
+ prefix: meta.profile.key,
29
29
  schema: RegistrySettingsSchema,
30
30
  atom: settingsAtom,
31
31
  }),
package/src/categories.ts CHANGED
@@ -27,13 +27,14 @@ export const getCategoryPredicate = (
27
27
  ): PluginPredicate => {
28
28
  switch (category) {
29
29
  case registryCategoryId('bundled'):
30
- return ({ meta }) => !core.includes(meta.id) && !remoteIds.has(meta.id);
30
+ return ({ meta }) => !core.includes(meta.profile.key) && !remoteIds.has(meta.profile.key);
31
31
  case registryCategoryId('installed'):
32
- return ({ meta }) => !core.includes(meta.id) && enabled.includes(meta.id);
32
+ return ({ meta }) => !core.includes(meta.profile.key) && enabled.includes(meta.profile.key);
33
33
  case registryCategoryId('recommended'):
34
- return ({ meta }) => !core.includes(meta.id) && !remoteIds.has(meta.id) && !meta.tags?.includes('labs');
34
+ return ({ meta }) =>
35
+ !core.includes(meta.profile.key) && !remoteIds.has(meta.profile.key) && !meta.profile.tags?.includes('labs');
35
36
  case registryCategoryId('labs'):
36
- return ({ meta }) => meta.tags?.includes('labs') ?? false;
37
+ return ({ meta }) => meta.profile.tags?.includes('labs') ?? false;
37
38
  default:
38
39
  return () => false;
39
40
  }
@@ -2,13 +2,5 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
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
- );
5
+ export * from './plugin';
6
+ export * from './registry';
@@ -11,14 +11,14 @@ import { Plugin } from '@dxos/app-framework';
11
11
  import { CommandConfig } from '@dxos/cli-util';
12
12
  import { invariant } from '@dxos/invariant';
13
13
 
14
- import { saveEnabledPlugins } from '../storage';
14
+ import { saveEnabledPlugins } from '../../storage';
15
15
 
16
16
  export const handler = Effect.fn(function* ({ id }: { id: string }) {
17
17
  const { json, profile } = yield* CommandConfig;
18
18
  const manager = yield* Plugin.Service;
19
19
 
20
20
  const plugins = manager.getPlugins();
21
- const plugin = plugins.find((p: Plugin.Plugin) => p.meta.id === id);
21
+ const plugin = plugins.find((p: Plugin.Plugin) => p.meta.profile.key === id);
22
22
  invariant(plugin, `Plugin not found: ${id}`);
23
23
 
24
24
  const core = manager.getCore();
@@ -34,7 +34,7 @@ export const handler = Effect.fn(function* ({ id }: { id: string }) {
34
34
  if (json) {
35
35
  yield* Console.log(JSON.stringify({ id, enabled: false }, null, 2));
36
36
  } else {
37
- yield* Console.log(`Plugin "${plugin.meta.name ?? id}" disabled.`);
37
+ yield* Console.log(`Plugin "${plugin.meta.profile.name ?? id}" disabled.`);
38
38
  }
39
39
  });
40
40
 
@@ -11,14 +11,14 @@ import { Plugin } from '@dxos/app-framework';
11
11
  import { CommandConfig } from '@dxos/cli-util';
12
12
  import { invariant } from '@dxos/invariant';
13
13
 
14
- import { saveEnabledPlugins } from '../storage';
14
+ import { saveEnabledPlugins } from '../../storage';
15
15
 
16
16
  export const handler = Effect.fn(function* ({ id }: { id: string }) {
17
17
  const { json, profile } = yield* CommandConfig;
18
18
  const manager = yield* Plugin.Service;
19
19
 
20
20
  const plugins = manager.getPlugins();
21
- const plugin = plugins.find((p: Plugin.Plugin) => p.meta.id === id);
21
+ const plugin = plugins.find((p: Plugin.Plugin) => p.meta.profile.key === id);
22
22
  invariant(plugin, `Plugin not found: ${id}`);
23
23
 
24
24
  const enabled = yield* manager.enable(id);
@@ -31,7 +31,7 @@ export const handler = Effect.fn(function* ({ id }: { id: string }) {
31
31
  if (json) {
32
32
  yield* Console.log(JSON.stringify({ id, enabled: true }, null, 2));
33
33
  } else {
34
- yield* Console.log(`Plugin "${plugin.meta.name ?? id}" enabled.`);
34
+ yield* Console.log(`Plugin "${plugin.meta.profile.name ?? id}" enabled.`);
35
35
  }
36
36
  });
37
37
 
@@ -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
+ );
@@ -20,11 +20,11 @@ export const handler = Effect.fn(function* () {
20
20
  const core = manager.getCore();
21
21
 
22
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);
23
+ const isEnabled = enabled.includes(plugin.meta.profile.key);
24
+ const isCore = core.includes(plugin.meta.profile.key);
25
25
  return {
26
- id: plugin.meta.id,
27
- name: plugin.meta.name ?? plugin.meta.id,
26
+ id: plugin.meta.profile.key,
27
+ name: plugin.meta.profile.name ?? plugin.meta.profile.key,
28
28
  enabled: isEnabled,
29
29
  core: isCore,
30
30
  };
@@ -0,0 +1,30 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Command from '@effect/cli/Command';
6
+
7
+ import { publish } from './publish';
8
+ import { publishPackage } from './publish-package';
9
+ import { publishPublisher } from './publish-publisher';
10
+ import { records } from './records';
11
+ import { unpublish } from './unpublish';
12
+ import { verify } from './verify';
13
+
14
+ /**
15
+ * `dx registry *` — commands for publishing and inspecting records that the
16
+ * DXOS plugin registry indexes from AT Protocol. Auth uses an App Password
17
+ * (per-user secret minted at https://bsky.app/settings/app-passwords); OAuth
18
+ * support is a follow-up.
19
+ *
20
+ * - `publish` — config-driven: build from dx.yml, host the bundle, write records.
21
+ * - `publish-package` — low-level: write profile + release records from flags.
22
+ * - `publish-publisher` — write the publisher's own profile record.
23
+ * - `unpublish` — remove a package (profile + releases) from your PDS.
24
+ * - `verify` — write a publisher.verification record (indexed only from the configured verifier).
25
+ * - `records` — list everything the authenticated repo has published under `org.dxos.experimental.*`.
26
+ */
27
+ export const registry: Command.Command<any, any, any, any> = Command.make('registry').pipe(
28
+ Command.withDescription('Publish to and inspect the AT Protocol-backed DXOS plugin registry.'),
29
+ Command.withSubcommands([publish, publishPackage, publishPublisher, unpublish, verify, records]),
30
+ );