@dxos/app-framework 0.8.4-staging.60fe92afc8 → 0.9.1-main.c7dcc2e112

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 (208) hide show
  1. package/dist/lib/browser/{capability-BOPAKKWG.mjs → capability-Z4MRP3CP.mjs} +9 -9
  2. package/dist/lib/browser/{chunk-CO3XLNUX.mjs → chunk-37PG7XJC.mjs} +18 -18
  3. package/dist/lib/browser/chunk-37PG7XJC.mjs.map +7 -0
  4. package/dist/lib/browser/{chunk-66IXTIVK.mjs → chunk-3NQLTQCP.mjs} +6 -7
  5. package/dist/lib/browser/chunk-3NQLTQCP.mjs.map +7 -0
  6. package/dist/lib/browser/{chunk-KZUDO43J.mjs → chunk-3UTDRCKX.mjs} +31 -23
  7. package/dist/lib/browser/chunk-3UTDRCKX.mjs.map +7 -0
  8. package/dist/lib/browser/chunk-53HJHMS5.mjs +7 -0
  9. package/dist/lib/browser/chunk-53HJHMS5.mjs.map +7 -0
  10. package/dist/lib/browser/{chunk-IW44C7UL.mjs → chunk-CMINFVA5.mjs} +1 -1
  11. package/dist/lib/browser/chunk-CMINFVA5.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-Y66ELD4U.mjs → chunk-DFVSOBV2.mjs} +17 -7
  13. package/dist/lib/browser/chunk-DFVSOBV2.mjs.map +7 -0
  14. package/dist/lib/browser/{chunk-DC3WRPBV.mjs → chunk-S2ZBYQPI.mjs} +45 -12
  15. package/dist/lib/browser/chunk-S2ZBYQPI.mjs.map +7 -0
  16. package/dist/lib/browser/{chunk-HFLKXMT7.mjs → chunk-SWECIICH.mjs} +57 -41
  17. package/dist/lib/browser/chunk-SWECIICH.mjs.map +7 -0
  18. package/dist/lib/browser/{chunk-5GY3YOEL.mjs → chunk-VF37YTXJ.mjs} +5 -5
  19. package/dist/lib/browser/chunk-VF37YTXJ.mjs.map +7 -0
  20. package/dist/lib/browser/{chunk-XHS5KDNX.mjs → chunk-W4BHZING.mjs} +25 -25
  21. package/dist/lib/browser/chunk-W4BHZING.mjs.map +7 -0
  22. package/dist/lib/browser/{chunk-FO3IYSLV.mjs → chunk-YUVQIOTB.mjs} +29 -37
  23. package/dist/lib/browser/chunk-YUVQIOTB.mjs.map +7 -0
  24. package/dist/lib/browser/cli/index.mjs +9 -9
  25. package/dist/lib/browser/cli/index.mjs.map +2 -2
  26. package/dist/lib/browser/common/activation-events.mjs +7 -7
  27. package/dist/lib/browser/common/capabilities.mjs +7 -7
  28. package/dist/lib/browser/config/index.mjs +8 -0
  29. package/dist/lib/browser/config/index.mjs.map +7 -0
  30. package/dist/lib/browser/core/activation-event.mjs +1 -1
  31. package/dist/lib/browser/core/capability.mjs +1 -1
  32. package/dist/lib/browser/core/plugin-manager.mjs +4 -4
  33. package/dist/lib/browser/core/plugin.mjs +12 -2
  34. package/dist/lib/browser/core/url-loader.mjs +3 -3
  35. package/dist/lib/browser/index.mjs +14 -10
  36. package/dist/lib/browser/index.mjs.map +1 -1
  37. package/dist/lib/browser/meta.json +1 -1
  38. package/dist/lib/browser/{process-manager-capability-GXNUO7AR.mjs → process-manager-capability-RDROCCQD.mjs} +9 -9
  39. package/dist/lib/browser/testing/index.mjs +15 -15
  40. package/dist/lib/browser/testing/index.mjs.map +3 -3
  41. package/dist/lib/browser/testing/react.mjs +11 -11
  42. package/dist/lib/browser/testing/react.mjs.map +3 -3
  43. package/dist/lib/browser/ui/index.mjs +16 -10
  44. package/dist/lib/node-esm/{capability-KZWRTX7R.mjs → capability-34Z6NPVR.mjs} +9 -9
  45. package/dist/lib/node-esm/chunk-2UPUZXGU.mjs +9 -0
  46. package/dist/lib/node-esm/chunk-2UPUZXGU.mjs.map +7 -0
  47. package/dist/lib/node-esm/{chunk-FSVGKTF6.mjs → chunk-A4O42ZO3.mjs} +17 -7
  48. package/dist/lib/node-esm/chunk-A4O42ZO3.mjs.map +7 -0
  49. package/dist/lib/node-esm/{chunk-CTKEZHKF.mjs → chunk-AIDZMJ3U.mjs} +1 -1
  50. package/dist/lib/node-esm/chunk-AIDZMJ3U.mjs.map +7 -0
  51. package/dist/lib/node-esm/{chunk-XOCUANHO.mjs → chunk-BMW6P6QA.mjs} +6 -7
  52. package/dist/lib/node-esm/chunk-BMW6P6QA.mjs.map +7 -0
  53. package/dist/lib/node-esm/{chunk-A5CHGAZE.mjs → chunk-H7T7XXLS.mjs} +57 -41
  54. package/dist/lib/node-esm/chunk-H7T7XXLS.mjs.map +7 -0
  55. package/dist/lib/node-esm/{chunk-NULBHQYS.mjs → chunk-LUK3FCTH.mjs} +18 -18
  56. package/dist/lib/node-esm/chunk-LUK3FCTH.mjs.map +7 -0
  57. package/dist/lib/node-esm/{chunk-XGBUKRCK.mjs → chunk-TEQSMP2O.mjs} +31 -23
  58. package/dist/lib/node-esm/chunk-TEQSMP2O.mjs.map +7 -0
  59. package/dist/lib/node-esm/{chunk-KFZEB6BV.mjs → chunk-TLKYZKPW.mjs} +5 -5
  60. package/dist/lib/node-esm/chunk-TLKYZKPW.mjs.map +7 -0
  61. package/dist/lib/node-esm/{chunk-WK7OIQKI.mjs → chunk-VCPGX7WN.mjs} +29 -37
  62. package/dist/lib/node-esm/chunk-VCPGX7WN.mjs.map +7 -0
  63. package/dist/lib/node-esm/{chunk-XIGPWXCQ.mjs → chunk-WERVO5EK.mjs} +45 -12
  64. package/dist/lib/node-esm/chunk-WERVO5EK.mjs.map +7 -0
  65. package/dist/lib/node-esm/{chunk-SX5NVETP.mjs → chunk-ZRTG4TSS.mjs} +25 -25
  66. package/dist/lib/node-esm/chunk-ZRTG4TSS.mjs.map +7 -0
  67. package/dist/lib/node-esm/cli/index.mjs +9 -9
  68. package/dist/lib/node-esm/cli/index.mjs.map +2 -2
  69. package/dist/lib/node-esm/common/activation-events.mjs +7 -7
  70. package/dist/lib/node-esm/common/capabilities.mjs +7 -7
  71. package/dist/lib/node-esm/config/index.mjs +9 -0
  72. package/dist/lib/node-esm/config/index.mjs.map +7 -0
  73. package/dist/lib/node-esm/core/activation-event.mjs +1 -1
  74. package/dist/lib/node-esm/core/capability.mjs +1 -1
  75. package/dist/lib/node-esm/core/plugin-manager.mjs +4 -4
  76. package/dist/lib/node-esm/core/plugin.mjs +12 -2
  77. package/dist/lib/node-esm/core/url-loader.mjs +3 -3
  78. package/dist/lib/node-esm/index.mjs +14 -10
  79. package/dist/lib/node-esm/index.mjs.map +1 -1
  80. package/dist/lib/node-esm/meta.json +1 -1
  81. package/dist/lib/node-esm/{process-manager-capability-TX5TA6YN.mjs → process-manager-capability-6OCXSKUW.mjs} +9 -9
  82. package/dist/lib/node-esm/testing/index.mjs +15 -15
  83. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  84. package/dist/lib/node-esm/testing/react.mjs +11 -11
  85. package/dist/lib/node-esm/testing/react.mjs.map +3 -3
  86. package/dist/lib/node-esm/ui/index.mjs +16 -10
  87. package/dist/plugin/node-esm/index.mjs +406 -71
  88. package/dist/plugin/node-esm/index.mjs.map +4 -4
  89. package/dist/plugin/node-esm/meta.json +1 -1
  90. package/dist/types/src/cli/cli.d.ts +1 -1
  91. package/dist/types/src/common/activation-events.d.ts.map +1 -1
  92. package/dist/types/src/common/capabilities.d.ts.map +1 -1
  93. package/dist/types/src/config/index.d.ts +2 -0
  94. package/dist/types/src/config/index.d.ts.map +1 -0
  95. package/dist/types/src/core/activation-event.d.ts +9 -6
  96. package/dist/types/src/core/activation-event.d.ts.map +1 -1
  97. package/dist/types/src/core/capability.d.ts +6 -2
  98. package/dist/types/src/core/capability.d.ts.map +1 -1
  99. package/dist/types/src/core/edge-registry-plugin-provider.d.ts +6 -11
  100. package/dist/types/src/core/edge-registry-plugin-provider.d.ts.map +1 -1
  101. package/dist/types/src/core/plugin-manager.d.ts.map +1 -1
  102. package/dist/types/src/core/plugin-manifest.d.ts +25 -7
  103. package/dist/types/src/core/plugin-manifest.d.ts.map +1 -1
  104. package/dist/types/src/core/plugin.d.ts +81 -91
  105. package/dist/types/src/core/plugin.d.ts.map +1 -1
  106. package/dist/types/src/core/registry.d.ts +17 -57
  107. package/dist/types/src/core/registry.d.ts.map +1 -1
  108. package/dist/types/src/core/url-loader.d.ts +2 -2
  109. package/dist/types/src/core/url-loader.d.ts.map +1 -1
  110. package/dist/types/src/index.d.ts +1 -0
  111. package/dist/types/src/index.d.ts.map +1 -1
  112. package/dist/types/src/plugin-process-manager/meta.d.ts +28 -2
  113. package/dist/types/src/plugin-process-manager/meta.d.ts.map +1 -1
  114. package/dist/types/src/testing/harness.d.ts +1 -1
  115. package/dist/types/src/testing/harness.d.ts.map +1 -1
  116. package/dist/types/src/testing/react.d.ts +6 -5
  117. package/dist/types/src/testing/react.d.ts.map +1 -1
  118. package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
  119. package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
  120. package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts +6 -0
  121. package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -1
  122. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +6 -10
  123. package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -1
  124. package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -1
  125. package/dist/types/src/ui/components/Surface/context.d.ts +6 -2
  126. package/dist/types/src/ui/components/Surface/context.d.ts.map +1 -1
  127. package/dist/types/src/ui/components/Surface/index.d.ts +10 -3
  128. package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -1
  129. package/dist/types/src/ui/components/Surface/types.d.ts +50 -70
  130. package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -1
  131. package/dist/types/src/ui/hooks/useApp.d.ts +1 -1
  132. package/dist/types/src/ui/hooks/useCapabilities.d.ts +11 -1
  133. package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -1
  134. package/dist/types/src/vite-plugin/composer/index.d.ts +11 -4
  135. package/dist/types/src/vite-plugin/composer/index.d.ts.map +1 -1
  136. package/dist/types/src/vite-plugin/index.d.ts +1 -0
  137. package/dist/types/src/vite-plugin/index.d.ts.map +1 -1
  138. package/dist/types/src/vite-plugin/load.d.ts +16 -0
  139. package/dist/types/src/vite-plugin/load.d.ts.map +1 -0
  140. package/dist/types/src/vite-plugin/manifest.d.ts +16 -4
  141. package/dist/types/src/vite-plugin/manifest.d.ts.map +1 -1
  142. package/dist/types/src/vite-plugin/packages.d.ts.map +1 -1
  143. package/dist/types/tsconfig.tsbuildinfo +1 -1
  144. package/docs/registry-spec.md +331 -0
  145. package/moon.yml +1 -0
  146. package/package.json +32 -27
  147. package/src/cli/cli.ts +2 -2
  148. package/src/common/activation-events.ts +3 -3
  149. package/src/common/capabilities.ts +16 -16
  150. package/src/config/index.ts +5 -0
  151. package/src/core/activation-event.ts +15 -8
  152. package/src/core/capability.ts +15 -4
  153. package/src/core/edge-registry-plugin-provider.ts +41 -42
  154. package/src/core/plugin-manager.test.ts +133 -137
  155. package/src/core/plugin-manager.ts +25 -19
  156. package/src/core/plugin-manifest.test.ts +5 -5
  157. package/src/core/plugin-manifest.ts +13 -10
  158. package/src/core/plugin.ts +58 -114
  159. package/src/core/registry.ts +20 -60
  160. package/src/core/url-loader.test.ts +2 -2
  161. package/src/core/url-loader.ts +23 -19
  162. package/src/index.ts +1 -0
  163. package/src/testing/harness.ts +5 -3
  164. package/src/testing/react.test.tsx +4 -2
  165. package/src/testing/react.tsx +9 -8
  166. package/src/testing/service.ts +2 -2
  167. package/src/testing/withPluginManager.stories.tsx +4 -2
  168. package/src/testing/withPluginManager.tsx +3 -1
  169. package/src/ui/components/PluginManager/PluginManagerProvider.ts +7 -0
  170. package/src/ui/components/Surface/SurfaceComponent.stories.tsx +11 -14
  171. package/src/ui/components/Surface/SurfaceComponent.tsx +84 -74
  172. package/src/ui/components/Surface/context.ts +6 -3
  173. package/src/ui/components/Surface/index.ts +12 -1
  174. package/src/ui/components/Surface/types.test.ts +39 -49
  175. package/src/ui/components/Surface/types.ts +95 -60
  176. package/src/ui/hooks/useApp.test.tsx +1 -1
  177. package/src/ui/hooks/useApp.tsx +2 -2
  178. package/src/ui/hooks/useCapabilities.ts +24 -2
  179. package/src/vite-plugin/composer/index.ts +134 -61
  180. package/src/vite-plugin/index.ts +1 -0
  181. package/src/vite-plugin/load.ts +57 -0
  182. package/src/vite-plugin/manifest.test.ts +3 -3
  183. package/src/vite-plugin/manifest.ts +21 -10
  184. package/src/vite-plugin/packages.ts +0 -1
  185. package/dist/lib/browser/chunk-5GY3YOEL.mjs.map +0 -7
  186. package/dist/lib/browser/chunk-66IXTIVK.mjs.map +0 -7
  187. package/dist/lib/browser/chunk-CO3XLNUX.mjs.map +0 -7
  188. package/dist/lib/browser/chunk-DC3WRPBV.mjs.map +0 -7
  189. package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +0 -7
  190. package/dist/lib/browser/chunk-HFLKXMT7.mjs.map +0 -7
  191. package/dist/lib/browser/chunk-IW44C7UL.mjs.map +0 -7
  192. package/dist/lib/browser/chunk-KZUDO43J.mjs.map +0 -7
  193. package/dist/lib/browser/chunk-XHS5KDNX.mjs.map +0 -7
  194. package/dist/lib/browser/chunk-Y66ELD4U.mjs.map +0 -7
  195. package/dist/lib/node-esm/chunk-A5CHGAZE.mjs.map +0 -7
  196. package/dist/lib/node-esm/chunk-CTKEZHKF.mjs.map +0 -7
  197. package/dist/lib/node-esm/chunk-FSVGKTF6.mjs.map +0 -7
  198. package/dist/lib/node-esm/chunk-KFZEB6BV.mjs.map +0 -7
  199. package/dist/lib/node-esm/chunk-NULBHQYS.mjs.map +0 -7
  200. package/dist/lib/node-esm/chunk-SX5NVETP.mjs.map +0 -7
  201. package/dist/lib/node-esm/chunk-WK7OIQKI.mjs.map +0 -7
  202. package/dist/lib/node-esm/chunk-XGBUKRCK.mjs.map +0 -7
  203. package/dist/lib/node-esm/chunk-XIGPWXCQ.mjs.map +0 -7
  204. package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +0 -7
  205. /package/dist/lib/browser/{capability-BOPAKKWG.mjs.map → capability-Z4MRP3CP.mjs.map} +0 -0
  206. /package/dist/lib/browser/{process-manager-capability-GXNUO7AR.mjs.map → process-manager-capability-RDROCCQD.mjs.map} +0 -0
  207. /package/dist/lib/node-esm/{capability-KZWRTX7R.mjs.map → capability-34Z6NPVR.mjs.map} +0 -0
  208. /package/dist/lib/node-esm/{process-manager-capability-TX5TA6YN.mjs.map → process-manager-capability-6OCXSKUW.mjs.map} +0 -0
@@ -0,0 +1,331 @@
1
+ # Plugin Registry Spec
2
+
3
+ ## Overview
4
+
5
+ The DXOS plugin registry is **AT Protocol-native**: there is no central registry database that
6
+ authors submit to. Instead, each publisher writes a small set of records to **their own** AT
7
+ Protocol repository (PDS), and a DXOS-operated **app-view** (in AT Protocol terms — the edge service
8
+ that indexes the firehose and serves a derived view) ingests those records, gates them by trust
9
+ attestations, and serves the resulting catalog to Composer.
10
+
11
+ This document specifies the four lexicons that make up the registry, the rkey conventions, the
12
+ trust/curation model, the integrity model, and the data flow from authoring to discovery. It is the
13
+ design reference for the machine-readable lexicons and the implementations that produce and consume
14
+ them.
15
+
16
+ Goals:
17
+
18
+ - **Publisher-owned data.** Records live in the publisher's repo; updating or removing a plugin is a
19
+ record write or delete on their side, not a request to DXOS.
20
+ - **Curated discovery.** Only publishers a trusted verifier has vouched for are surfaced, keeping
21
+ the catalog trustworthy without DXOS owning the data.
22
+ - **Standard tooling.** Records are plain AT Protocol records, readable by any ATProto client and
23
+ written via standard XRPC (`com.atproto.repo.*`).
24
+
25
+ ## Status
26
+
27
+ Experimental. The `experimental` segment in every NSID is intentional — these schemas are unstable
28
+ and will be renamed to a final namespace before promotion (see [Versioning](#versioning)).
29
+
30
+ ## Source of truth
31
+
32
+ The machine-readable lexicons are the canonical definition:
33
+
34
+ - **Lexicon JSON** — `packages/sdk/edge-protocol/lexicons/org.dxos.experimental/*.json` (edge repo).
35
+ These are the source of truth.
36
+ - **Effect-Schema validators** — `packages/sdk/edge-protocol/src/registry.ts`
37
+ (edge repo). Decoders used at the indexing/validation seam to reject malformed records before they
38
+ enter the store. These mirror the JSON lexicons and live alongside them in the protocol package.
39
+ - **`PluginView`** — `packages/core/protocols/src/edge/registry.ts` (dxos repo). The catalog shape
40
+ the indexer serves to Composer.
41
+ - **CLI writers** — `packages/plugins/plugin-registry/src/commands/registry/` (dxos repo). The `dx`
42
+ CLI assembles record bodies and writes them via XRPC.
43
+ - **App-view / indexer** — `packages/services/registry-service/src/registry/atproto/{indexer,curator,backfill}.ts`
44
+ (edge repo). The `RegistryIndexer` Durable Object is the registry app-view: it ingests records,
45
+ enforces what the registry serves, and returns the catalog.
46
+
47
+ ## Architecture
48
+
49
+ ```
50
+ ┌──────────────────┐ putRecord/ ┌─────────────┐ Jetstream ┌──────────────────┐ GET /registry ┌──────────┐
51
+ │ dx CLI │ deleteRecord │ Publisher │ firehose + │ RegistryIndexer │ /plugins │ Composer │
52
+ │ (plugin-registry)│──────XRPC──────▶│ PDS (repo) │───backfill────▶│ DO (edge) │─────────────────▶│ │
53
+ └──────────────────┘ └─────────────┘ └──────────────────┘ └──────────┘
54
+ ▲ │
55
+ verifier│verification verified-DID gate
56
+ │ │
57
+ ┌─────────────┐ │
58
+ │ Verifier PDS│────────────────────────┘
59
+ └─────────────┘
60
+ ```
61
+
62
+ 1. A publisher writes `package.profile` / `package.release` records (and a one-time
63
+ `publisher.profile`) to their own PDS using the `dx` CLI.
64
+ 2. A verifier writes `publisher.verification` records, one per trusted DID, to their own PDS.
65
+ 3. The indexer learns the verified-DID set, then ingests matching records from verified publishers —
66
+ live via the Jetstream firehose and via periodic backfill sweeps.
67
+ 4. Composer queries the indexer for the catalog and loads each plugin's bundle on demand from its
68
+ `moduleUrl`.
69
+
70
+ ## Records
71
+
72
+ | NSID | rkey | Author | Purpose |
73
+ | ---------------------------------------------- | ----------------- | --------- | -------------------------------------- |
74
+ | `org.dxos.experimental.publisher.profile` | `self` | publisher | Identity-level publisher metadata. |
75
+ | `org.dxos.experimental.publisher.verification` | `<verified DID>` | verifier | A trust attestation about a publisher. |
76
+ | `org.dxos.experimental.package.profile` | `<key>` | publisher | Plugin metadata (one per key per DID). |
77
+ | `org.dxos.experimental.package.release` | `<key>:<version>` | publisher | A versioned artifact of a package. |
78
+
79
+ All record bodies carry a `$type` field set to the NSID (standard ATProto convention; stamped by
80
+ the CLI on write). All records live in the author's own repo and are therefore mutable by that
81
+ author at the AT Protocol level; the **app-view** enforces immutability for what it serves (see
82
+ [Integrity & tamper detection](#integrity--tamper-detection)).
83
+
84
+ ### `publisher.profile`
85
+
86
+ Identity-level metadata about a publisher. One record per DID, `rkey = self`.
87
+
88
+ | Field | Required | Type | Constraints | Notes |
89
+ | ------------- | -------- | ------------ | ----------- | ----------------------------------------- |
90
+ | `displayName` | yes | string | 1–128 chars | Shown alongside the publisher's packages. |
91
+ | `bio` | no | string | ≤512 chars | Short description. |
92
+ | `homepageUrl` | no | string (uri) | | Canonical homepage. |
93
+ | `contact` | no | string | ≤256 chars | Contact channel (email, handle, etc.). |
94
+
95
+ Written by `dx registry publish-publisher`.
96
+
97
+ ### `publisher.verification`
98
+
99
+ A trust attestation that one identity (the verifier) vouches for a publisher. `rkey = <verified DID>`
100
+ by convention; `subject` is the authoritative field.
101
+
102
+ **Anyone can author verification records** — they are ordinary public AT Protocol records. Trust is a
103
+ policy applied at indexing time, not a write-time restriction (see [Trust model](#trust-model)).
104
+
105
+ | Field | Required | Type | Constraints | Notes |
106
+ | ------------- | -------- | ----------------- | ----------- | ----------------------------------------------------------------------------------------- |
107
+ | `subject` | yes | string (did) | | DID of the verified publisher. Should match the rkey. |
108
+ | `handle` | yes | string (handle) | | Publisher's handle at verification time; re-issued on change. Display-only, may be stale. |
109
+ | `displayName` | yes | string | 1–128 chars | Display name bound by this verification. |
110
+ | `createdAt` | yes | string (datetime) | | |
111
+
112
+ Written by `dx registry verify`.
113
+
114
+ ### `package.profile`
115
+
116
+ Mutable metadata for a discoverable plugin. `rkey = <key>` (reverse-domain NSID, e.g.
117
+ `org.dxos.plugin.excalidraw`). The `key` field is the plugin's globally-unique identifier and
118
+ matches the `key` in `dx.config.ts`.
119
+
120
+ | Field | Required | Type | Constraints | Notes |
121
+ | ------------- | -------- | --------------------- | ------------------------- | ------------------------------------------------------------------------------------------------- |
122
+ | `key` | yes | string | 1–63 chars | Reverse-domain NSID; equals the rkey (e.g. `org.dxos.plugin.excalidraw`). |
123
+ | `name` | yes | string | 1–128 chars | Display name. |
124
+ | `description` | no | string | ≤512 chars | Shown in listings. |
125
+ | `homePage` | no | string (uri) | | Canonical homepage or documentation URL. |
126
+ | `source` | no | string (uri) | | Public source repository. |
127
+ | `tags` | no | string[] | ≤16 items, item ≤32 chars | Discovery tags. |
128
+ | `screenshots` | no | `{ light?, dark? }[]` | item urls | Preview images; each entry is a record of theme-specific URLs. |
129
+ | `icon` | no | `{ key, hue? }` | | [Phosphor](https://phosphoricons.com) icon name (e.g. `ph--compass-tool--regular`) + palette hue. |
130
+ | `dependsOn` | no | string[] | | Plugin keys this plugin depends on at runtime (author-declared, version-independent NSIDs). |
131
+ | `spec` | no | string | | Relative path inside the bundle to a bundled MDL spec file (e.g. `PLUGIN.mdl`). |
132
+ | `createdAt` | yes | string (datetime) | | |
133
+
134
+ Written by `dx registry publish` (from the manifest emitted by `composerPlugin` reading `dx.config.ts`)
135
+ or `dx registry publish-package`.
136
+
137
+ ### `package.release`
138
+
139
+ A record for one version of a package. `rkey = <key>:<version>`. Conceptually append-only: a new
140
+ version is a new record, and the registry treats the first release seen per `(did, key, version)`
141
+ as canonical — but the author technically retains write access to it (see
142
+ [Integrity & tamper detection](#integrity--tamper-detection)).
143
+
144
+ | Field | Required | Type | Constraints | Notes |
145
+ | -------------- | -------- | ----------------- | ----------- | ----------------------------------------------------------------------------------------------------------------- |
146
+ | `package` | yes | string | ≤63 chars | Key of the parent `package.profile` authored by the same DID. |
147
+ | `version` | yes | string | ≤32 chars | Semver subset without build metadata; pre-release suffixes allowed (`1.2.3-rc.1`). Taken from `package.json`. |
148
+ | `moduleUrl` | yes | string (uri) | non-empty | HTTPS URL of the module entrypoint / `manifest.json`. v0 trusts the publisher; content addressing is a follow-on. |
149
+ | `manifestHash` | no | string | ≤256 chars | Integrity hash of the module manifest, e.g. `sha256-<base64>`. |
150
+ | `createdAt` | yes | string (datetime) | | |
151
+
152
+ Written by `dx registry publish`.
153
+
154
+ > The release rkey uses `<key>:<version>` (colon), matching the emdash prior art. `:` is a legal
155
+ > record-key character per the AT Protocol record-key grammar, and the key (a reverse-domain NSID
156
+ > using only `[a-z0-9.]`) and version charset do not contain it, so the separator is unambiguous.
157
+
158
+ ## Trust model
159
+
160
+ Verification records are public and unrestricted — anyone may author a `publisher.verification`. What
161
+ makes the catalog trustworthy is the **indexing policy**, not a write gate:
162
+
163
+ - **Today (single verifier).** The indexer is configured with one trusted verifier DID
164
+ (`REGISTRY_CURATOR_DID`) and honors `publisher.verification` records **only** from that DID. The
165
+ verified-DID set is the set of `subject`s across that verifier's records. A `package.*` or
166
+ `publisher.profile` record is indexed only if its author DID is in the verified set. This is a
167
+ deliberate moderation simplification while the registry is young — not a protocol restriction.
168
+ - **Revocation.** Deleting the verification record removes the publisher from the verified set on the
169
+ next backfill sweep; the indexer unindexes their records.
170
+ - **Later (multiple verifiers / moderation).** The single-verifier gate is intended to generalize to
171
+ multiple independent verifiers and moderation labels, similar to Bluesky's labeler model: clients
172
+ (or the indexer) subscribe to a set of verifiers/labelers they trust, and a publisher is shown if
173
+ any trusted verifier vouches for them. Until that moderation surface exists, DXOS only indexes
174
+ records from publishers DXOS itself has verified.
175
+
176
+ A publisher may write their records before being verified — they simply won't appear in Composer
177
+ until a trusted verifier vouches for them.
178
+
179
+ ## Integrity & tamper detection
180
+
181
+ Immutability is an **app-view guarantee, not an AT Protocol one.** Like every AT Protocol repo, a
182
+ publisher owns their PDS records and can mutate or delete any of them — including `package.release` —
183
+ and no protocol mechanism makes a record cryptographically immutable. Enforcement therefore lives at
184
+ the **registry app-view** (the edge service that indexes the firehose and serves the catalog to
185
+ Composer): the PDS is the mutable source, and the app-view is the canonical, immutable view of what
186
+ the registry serves.
187
+
188
+ What the app-view enforces:
189
+
190
+ - **Hosted bundles are immutable (enforced today).** Edge's `/registry/upload` rejects re-uploading an
191
+ existing `(slug, version)` with a `409` (outside dev), so the code/assets behind a published version
192
+ cannot be overwritten. A publisher self-hosting via `--asset-base-url` opts out of this guarantee.
193
+ - **First-seen release pinning (enforced today).** The app-view pins the first `(did, slug:version)`
194
+ release it observes and ignores subsequent mutations to that record (`RegistryIndexer._writeRecord`),
195
+ so a publisher who repoints or rewrites a published release on their PDS cannot change what the
196
+ registry serves. A delete unindexes (clears the pin); a later recreate at the same rkey re-pins to the
197
+ new value. The pin lives in DO storage — a full DO eviction re-pins from current PDS state on the next
198
+ backfill (durable cross-eviction pinning is a follow-on).
199
+
200
+ What stays mutable (the AT Protocol layer):
201
+
202
+ - The PDS `package.release` record is written with `putRecord` (upsert), and the publisher can change
203
+ its `moduleUrl` / `manifestHash` at will. That is fine — the app-view's pin means such a change is not
204
+ re-served (the PDS is the mutable source; the app-view is the canonical view).
205
+
206
+ Detectability (planned):
207
+
208
+ - **Client-side verification.** Composer should verify the bundle it loads against the app-view's
209
+ pinned `manifestHash` and refuse to load on mismatch.
210
+ - **Content addressing & signatures.** Longer term, address bundles by content hash and/or sign
211
+ release records so any party can verify integrity independently of the app-view.
212
+
213
+ Until first-seen pinning and client-side verification land, treat a release's `moduleUrl` as
214
+ publisher-trusted at the record level (the hosted bundle itself is already immutable).
215
+
216
+ ## Indexing
217
+
218
+ - **Bootstrap / backfill.** On first run (and periodically), the indexer walks the verifier's repo
219
+ for verification records to compute the verified-DID set, then lists each verified publisher's repo
220
+ for `package.*` records (`runBackfill`). The catalog (`GET /registry/plugins`) collects releases
221
+ per `(authorDid, package-key)` — grouped by the release's `package` field, **not** by parsing the
222
+ rkey — newest-first, anchored by `at://<authorDid>/org.dxos.experimental.package.profile/<key>`.
223
+ - **Live updates.** The indexer subscribes to the Jetstream firehose; commits for the four NSIDs are
224
+ validated (Effect-Schema) and written/deleted in DO storage, keyed by `record:<nsid>|<did>|<rkey>`.
225
+ - **Validation seam.** Malformed records are rejected at ingestion against the Effect-Schema mirrors
226
+ of the JSON lexicons; they never enter the store.
227
+
228
+ ## Authoring
229
+
230
+ The `dx` CLI writes records to the publisher's PDS over standard XRPC (`com.atproto.repo.putRecord`,
231
+ `deleteRecord`, `listRecords`). It supports two auth modes (see
232
+ [Publishing a Plugin](/docs/composer/publishing-plugins) for the user-facing flow):
233
+
234
+ - **Logged-in identity (default).** After `dx account login`, writes are DPoP-signed by DXOS edge
235
+ using the AT Protocol account connected to the user's identity (the "Atmosphere" integration in
236
+ their personal space) — no app password.
237
+ - **App password (headless).** `--handle` / `--app-password` (or `$ATPROTO_HANDLE` /
238
+ `$ATPROTO_APP_PASSWORD`) authenticate directly against the PDS.
239
+
240
+ ## Versioning
241
+
242
+ Every NSID is under `org.dxos.experimental.*`. The namespace is deliberately marked unstable: fields
243
+ and record shapes may change without migration guarantees. A final namespace
244
+ (`org.dxos.registry.*` or similar) will be minted before promotion, at which point the experimental
245
+ lexicons are frozen and the indexer dual-reads during a migration window.
246
+
247
+ Package and publisher profiles are mutable (last-write-wins per rkey). Releases are conceptually
248
+ single-write per version but not enforced (see [Integrity & tamper detection](#integrity--tamper-detection)).
249
+ There is no in-band schema-version field on records — the NSID encodes the version.
250
+
251
+ ## SDK compatibility & the upgrade train
252
+
253
+ Composer plugins **externalize `@dxos/*`** — at runtime they use the host's copy, so a plugin only
254
+ works if it was built against an SDK compatible with what Composer ships. DXOS ships all `@dxos/*` as
255
+ **one unit at one version** (`DXOS_VERSION`).
256
+
257
+ **Mechanism — the manifest dependency snapshot.** The build (`composerPlugin`) auto-populates a
258
+ `dependencies` map into the plugin's `manifest.json`: every declared dependency resolved to its
259
+ concrete installed version (`{ "@dxos/app-framework": "0.8.3", "react": "19.2.0", … }`). This flows
260
+ into the `package.release` record and the catalog (`PluginRelease.dependencies`). The host computes
261
+ compatibility from the **subset it shares with the plugin** — the externalized `@dxos/*` packages —
262
+ comparing each against its own shipped version under a policy (pre-1.0: **same minor**; post-1.0:
263
+ caret). The remaining (bundled) deps are recorded for transparency/audit. A release with no
264
+ `dependencies` is treated as "unknown" (legacy) and not gated.
265
+
266
+ **Rollout-decoupling.** Because each release records the SDK it built against, a **stable Composer
267
+ ignores plugin versions built for a newer SDK** — they don't surface as available upgrades. This lets
268
+ plugin authors publish new versions _ahead_ of the stable Composer release without breaking users on
269
+ the current version; those users pick the new versions up only once their Composer catches up.
270
+
271
+ **The upgrade train** (operationalized in the plugins monorepo's `RELEASING.md`):
272
+
273
+ 1. **Continuous tracking (never released).** A nightly job points the monorepo's SDK catalog at the
274
+ latest DXOS `main` via `pkg.pr.new` and opens/updates an "SDK upgrade" PR; CI builds all plugins.
275
+ These prerelease pins may land on `main` to keep pace, but a **release guard forbids publishing**
276
+ against a non-released SDK.
277
+ 2. **On a cut SDK npm release.** A separate job bumps the catalog to the npm version, a **Composer
278
+ beta** ships on it, and new plugin versions are published against it (their manifests now declare
279
+ the new SDK).
280
+ 3. **Migration window (risk-scaled).** Hold before promoting the new SDK/Composer to stable; the
281
+ window scales with risk (longer for breaking changes) so authors can migrate, while the
282
+ compatibility gate keeps old and new users on the right versions. Exact windows are TBD.
283
+
284
+ ## Prior art
285
+
286
+ These lexicons are modeled on the emdash RFC:
287
+
288
+ - RFC: [emdash-cms/emdash#694](https://github.com/emdash-cms/emdash/pull/694) — design rationale,
289
+ trust-model trade-offs, rkey conventions, and the `experimental` namespace strategy.
290
+ - Implementation: [emdash-cms/emdash#923](https://github.com/emdash-cms/emdash/pull/923).
291
+
292
+ Difference from emdash's `com.emdashcms.experimental.*`: `releaseExtension` / `declaredAccess`
293
+ records (sandbox manifest, granular permissions) are **not** in v0; they are a follow-on once the
294
+ runtime sandbox surface is defined. (rkey conventions now match emdash, including `<slug>:<version>`.)
295
+
296
+ ## Schema reconciliation
297
+
298
+ The JSON lexicons, the Effect-Schema validators, `PluginView`, and the CLI previously had field-level
299
+ drift on `package.profile`. All items listed here are resolved.
300
+
301
+ - **`slug` → `key`** — the identity field on `package.profile` is now named `key` everywhere: the
302
+ lexicon, the Effect-Schema validator, `PluginProfileSchema` in `@dxos/protocols`, the CLI flags
303
+ (`--key`), and the runtime `Plugin.Meta.profile.key`.
304
+ - **`homepage` → `homePage`** — camelCase alignment across the lexicon, validator, `PluginProfileSchema`,
305
+ and `dx.config.ts`.
306
+ - **`icon`** — unified as `{ key, hue? }` (object form) across `dx.config.ts`, `PluginProfileSchema`,
307
+ the validator, and the indexer projection. The CLI writes and the indexer stores the structured object.
308
+ - **`screenshots`** — unified as `{ light?, dark? }[]` (object-only form) across `dx.config.ts`,
309
+ `PluginProfileSchema`, the validator, and the indexer projection. Plain URL strings are no longer
310
+ accepted at authoring time; use `{ dark: 'url' }` or `{ light: 'url', dark: 'url' }`.
311
+ - **`dependsOn`** — added to `package.profile` (author-declared runtime plugin deps, NSIDs),
312
+ `PluginProfileSchema`, the validator, and `dx.config.ts`.
313
+ - **`spec`** — added to `package.profile` (relative path to a bundled MDL spec),
314
+ `PluginProfileSchema`, the validator, and `dx.config.ts`.
315
+ - **`dependencies`** (SDK-compat snapshot on `package.release`) — `composerPlugin` emits the full
316
+ resolved dependency map into `manifest.json`; the CLI writes it into the `package.release` record;
317
+ the validator preserves it in storage; `PluginReleaseSchema` in `@dxos/protocols` types it.
318
+
319
+ ## Open questions & follow-ons
320
+
321
+ - **Integrity / tamper detection** — first-seen release pinning is enforced at the app-view; still to
322
+ do (see [Integrity & tamper detection](#integrity--tamper-detection)): client-side `manifestHash`
323
+ verification, durable pinning across full DO eviction, and longer term content addressing + signed
324
+ release records.
325
+ - **Multiple verifiers / moderation** — generalize the single-verifier gate to a trusted-verifier set
326
+ / labeler model.
327
+ - **Sandbox & permissions** — `releaseExtension` / `declaredAccess` lexicons, deferred until the
328
+ plugin runtime sandbox and permission model are defined.
329
+ - **Namespace promotion** — finalize the stable namespace and the dual-read migration plan.
330
+ - **Production proxy auth** — the edge `/atproto/proxy` route used by the logged-in DPoP write path
331
+ currently runs `skipAuth` in dev; production must require the caller's verifiable presentation.
package/moon.yml CHANGED
@@ -22,6 +22,7 @@ tasks:
22
22
  - '--entryPoint=src/testing/index.ts'
23
23
  - '--entryPoint=src/testing/react.tsx'
24
24
  - '--entryPoint=src/core/url-loader.ts'
25
+ - '--entryPoint=src/config/index.ts'
25
26
  deps:
26
27
  - compile-plugin
27
28
  compile-plugin:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/app-framework",
3
- "version": "0.8.4-staging.60fe92afc8",
3
+ "version": "0.9.1-main.c7dcc2e112",
4
4
  "description": "A framework for building applications from composible plugins.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -61,6 +61,11 @@
61
61
  "node": "./dist/lib/node-esm/url-loader/index.mjs",
62
62
  "types": "./dist/types/src/url-loader/index.d.ts"
63
63
  },
64
+ "./config": {
65
+ "browser": "./dist/lib/browser/config/index.mjs",
66
+ "node": "./dist/lib/node-esm/config/index.mjs",
67
+ "types": "./dist/types/src/config/index.d.ts"
68
+ },
64
69
  "./vite-plugin": {
65
70
  "import": "./dist/plugin/node-esm/index.mjs",
66
71
  "types": "./dist/types/src/vite-plugin/index.d.ts"
@@ -99,29 +104,29 @@
99
104
  "@effect/platform": "0.96.1",
100
105
  "babel-preset-solid": "^1.9.9",
101
106
  "cjs-module-lexer": "^2.2.0",
102
- "esbuild": "0.28.0",
107
+ "esbuild": "0.28.1",
103
108
  "idb-keyval": "^6.2.1",
104
109
  "solid-js": "^1.9.11",
105
- "@dxos/async": "0.8.4-staging.60fe92afc8",
106
- "@dxos/compute-runtime": "0.8.4-staging.60fe92afc8",
107
- "@dxos/context": "0.8.4-staging.60fe92afc8",
108
- "@dxos/debug": "0.8.4-staging.60fe92afc8",
109
- "@dxos/effect": "0.8.4-staging.60fe92afc8",
110
- "@dxos/errors": "0.8.4-staging.60fe92afc8",
111
- "@dxos/edge-client": "0.8.4-staging.60fe92afc8",
112
- "@dxos/invariant": "0.8.4-staging.60fe92afc8",
113
- "@dxos/keys": "0.8.4-staging.60fe92afc8",
114
- "@dxos/log": "0.8.4-staging.60fe92afc8",
115
- "@dxos/operation": "0.8.4-staging.60fe92afc8",
116
- "@dxos/react-error-boundary": "0.8.4-staging.60fe92afc8",
117
- "@dxos/protocols": "0.8.4-staging.60fe92afc8",
118
- "@dxos/react-hooks": "0.8.4-staging.60fe92afc8",
119
- "@dxos/ui-theme": "0.8.4-staging.60fe92afc8",
120
- "@dxos/util": "0.8.4-staging.60fe92afc8",
121
- "@dxos/react-ui": "0.8.4-staging.60fe92afc8",
122
- "@dxos/web-context": "0.8.4-staging.60fe92afc8",
123
- "@dxos/web-context-react": "0.8.4-staging.60fe92afc8",
124
- "@dxos/compute": "0.8.4-staging.60fe92afc8"
110
+ "@dxos/async": "0.9.1-main.c7dcc2e112",
111
+ "@dxos/compute-runtime": "0.9.1-main.c7dcc2e112",
112
+ "@dxos/compute": "0.9.1-main.c7dcc2e112",
113
+ "@dxos/context": "0.9.1-main.c7dcc2e112",
114
+ "@dxos/debug": "0.9.1-main.c7dcc2e112",
115
+ "@dxos/edge-client": "0.9.1-main.c7dcc2e112",
116
+ "@dxos/effect": "0.9.1-main.c7dcc2e112",
117
+ "@dxos/errors": "0.9.1-main.c7dcc2e112",
118
+ "@dxos/operation": "0.9.1-main.c7dcc2e112",
119
+ "@dxos/invariant": "0.9.1-main.c7dcc2e112",
120
+ "@dxos/keys": "0.9.1-main.c7dcc2e112",
121
+ "@dxos/log": "0.9.1-main.c7dcc2e112",
122
+ "@dxos/protocols": "0.9.1-main.c7dcc2e112",
123
+ "@dxos/react-error-boundary": "0.9.1-main.c7dcc2e112",
124
+ "@dxos/react-hooks": "0.9.1-main.c7dcc2e112",
125
+ "@dxos/react-ui": "0.9.1-main.c7dcc2e112",
126
+ "@dxos/util": "0.9.1-main.c7dcc2e112",
127
+ "@dxos/ui-theme": "0.9.1-main.c7dcc2e112",
128
+ "@dxos/web-context": "0.9.1-main.c7dcc2e112",
129
+ "@dxos/web-context-react": "0.9.1-main.c7dcc2e112"
125
130
  },
126
131
  "devDependencies": {
127
132
  "@effect-atom/atom-react": "^0.5.0",
@@ -135,11 +140,11 @@
135
140
  "typedoc": "0.28.1",
136
141
  "vite": "^8.0.16",
137
142
  "vite-plugin-solid": "^2.11.12",
138
- "@dxos/echo-client": "0.8.4-staging.60fe92afc8",
139
- "@dxos/random": "0.8.4-staging.60fe92afc8",
140
- "@dxos/storybook-utils": "0.8.4-staging.60fe92afc8",
141
- "@dxos/brand": "0.8.4-staging.60fe92afc8",
142
- "@dxos/test-utils": "0.8.4-staging.60fe92afc8"
143
+ "@dxos/brand": "0.9.1-main.c7dcc2e112",
144
+ "@dxos/echo-client": "0.9.1-main.c7dcc2e112",
145
+ "@dxos/random": "0.9.1-main.c7dcc2e112",
146
+ "@dxos/test-utils": "0.9.1-main.c7dcc2e112",
147
+ "@dxos/storybook-utils": "0.9.1-main.c7dcc2e112"
143
148
  },
144
149
  "peerDependencies": {
145
150
  "@effect-atom/atom-react": "^0.5.0",
package/src/cli/cli.ts CHANGED
@@ -15,7 +15,7 @@ const defaultPluginLoader =
15
15
  (plugins: Plugin.Plugin[]): PluginManager.ManagerOptions['pluginLoader'] =>
16
16
  (id: string) =>
17
17
  Effect.sync(() => {
18
- const plugin = plugins.find((plugin) => plugin.meta.id === id);
18
+ const plugin = plugins.find((plugin) => plugin.meta.profile.key === id);
19
19
  invariant(plugin, `Plugin not found: ${id}`);
20
20
  return { plugin };
21
21
  });
@@ -43,7 +43,7 @@ export type CreateCliAppOptions = {
43
43
  *
44
44
  * @param options.pluginManager Optional existing PluginManager instance.
45
45
  * @param options.pluginLoader Function to load plugins by ID.
46
- * @param options.plugins All plugins available to the application. Plugins whose `meta.tags` includes `'system'` are treated as core.
46
+ * @param options.plugins All plugins available to the application. Plugins whose `meta.profile.tags` includes `'system'` are treated as core.
47
47
  * @param options.enabled Enabled plugins.
48
48
  * @param options.safeMode Whether to enable safe mode, which disables optional plugins.
49
49
  */
@@ -16,7 +16,7 @@ export const Startup = ActivationEvent$.make('org.dxos.app-framework.event.start
16
16
  /**
17
17
  * Fired to load any newly available surfaces.
18
18
  */
19
- export const SetupReactSurface = ActivationEvent$.make('org.dxos.app-framework.event.setup-react-surface');
19
+ export const SetupReactSurface = ActivationEvent$.make('org.dxos.app-framework.event.setupReactSurface');
20
20
 
21
21
  /**
22
22
  * Fired before the process manager is created.
@@ -25,7 +25,7 @@ export const SetupReactSurface = ActivationEvent$.make('org.dxos.app-framework.e
25
25
  * process manager's {@link ServiceResolver} and {@link OperationInvoker} pick
26
26
  * them up at construction time.
27
27
  */
28
- export const SetupProcessManager = ActivationEvent$.make('org.dxos.app-framework.event.setup-process-manager');
28
+ export const SetupProcessManager = ActivationEvent$.make('org.dxos.app-framework.event.setupProcessManager');
29
29
 
30
30
  //
31
31
  // Triggered Events
@@ -36,4 +36,4 @@ export const SetupProcessManager = ActivationEvent$.make('org.dxos.app-framework
36
36
  * (`ProcessManagerRuntime`, `ServiceResolver`, `ProcessMonitor`, `OperationInvoker`)
37
37
  * have been contributed.
38
38
  */
39
- export const ProcessManagerReady = ActivationEvent$.make('org.dxos.app-framework.event.process-manager-ready');
39
+ export const ProcessManagerReady = ActivationEvent$.make('org.dxos.app-framework.event.processManagerReady');
@@ -41,13 +41,13 @@ export const Null = Capability$.make<null>('org.dxos.app-framework.capability.nu
41
41
  * @category Capability
42
42
  */
43
43
  export const PluginManager = Capability$.make<PluginManager$.PluginManager>(
44
- 'org.dxos.app-framework.capability.plugin-manager',
44
+ 'org.dxos.app-framework.capability.pluginManager',
45
45
  );
46
46
 
47
47
  /**
48
48
  * @category Capability
49
49
  */
50
- export const AtomRegistry = Capability$.make<Registry.Registry>('org.dxos.app-framework.capability.atom-registry');
50
+ export const AtomRegistry = Capability$.make<Registry.Registry>('org.dxos.app-framework.capability.atomRegistry');
51
51
 
52
52
  export type ReactContext = Readonly<{
53
53
  id: string;
@@ -58,14 +58,14 @@ export type ReactContext = Readonly<{
58
58
  /**
59
59
  * @category Capability
60
60
  */
61
- export const ReactContext = Capability$.make<ReactContext>('org.dxos.app-framework.capability.react-context');
61
+ export const ReactContext = Capability$.make<ReactContext>('org.dxos.app-framework.capability.reactContext');
62
62
 
63
63
  export type ReactRoot = Readonly<{ id: string; root: FC<PropsWithChildren> }>;
64
64
 
65
65
  /**
66
66
  * @category Capability
67
67
  */
68
- export const ReactRoot = Capability$.make<ReactRoot>('org.dxos.app-framework.capability.react-root');
68
+ export const ReactRoot = Capability$.make<ReactRoot>('org.dxos.app-framework.capability.reactRoot');
69
69
 
70
70
  /**
71
71
  * Surface definitions that can be either React components or Web Components.
@@ -75,7 +75,7 @@ export type ReactSurface = Surface.Definition | readonly Surface.Definition[];
75
75
  /**
76
76
  * @category Capability
77
77
  */
78
- export const ReactSurface = Capability$.make<ReactSurface>('org.dxos.app-framework.common.react-surface');
78
+ export const ReactSurface = Capability$.make<ReactSurface>('org.dxos.app-framework.capability.reactSurface');
79
79
 
80
80
  export type AnyCommand = Command$.Command<any, any, any, any>;
81
81
 
@@ -98,7 +98,7 @@ export const Layer = Capability$.make<Layer$.Layer<any, any, any>>('org.dxos.app
98
98
  *
99
99
  * @category Capability
100
100
  */
101
- export const LayerSpec = Capability$.make<LayerSpec$.LayerSpec>('org.dxos.app-framework.capability.layer-spec');
101
+ export const LayerSpec = Capability$.make<LayerSpec$.LayerSpec>('org.dxos.app-framework.capability.layerSpec');
102
102
 
103
103
  /**
104
104
  * Context passed to {@link TraceSinkFactory} implementations when the
@@ -133,7 +133,7 @@ export type TraceSinkFactory = (ctx: TraceSinkFactoryContext) => Trace$.Sink;
133
133
  *
134
134
  * @category Capability
135
135
  */
136
- export const TraceSink = Capability$.make<TraceSinkFactory>('org.dxos.app-framework.capability.trace-sink');
136
+ export const TraceSink = Capability$.make<TraceSinkFactory>('org.dxos.app-framework.capability.traceSink');
137
137
 
138
138
  /**
139
139
  * Service resolver backing the shared {@link ProcessManagerRuntime}.
@@ -157,7 +157,7 @@ export const TraceSink = Capability$.make<TraceSinkFactory>('org.dxos.app-framew
157
157
  * @category Capability
158
158
  */
159
159
  export const ServiceResolver = Capability$.make<ServiceResolver$.ServiceResolver>(
160
- 'org.dxos.app-framework.capability.service-resolver',
160
+ 'org.dxos.app-framework.capability.serviceResolver',
161
161
  );
162
162
 
163
163
  /**
@@ -167,7 +167,7 @@ export const ServiceResolver = Capability$.make<ServiceResolver$.ServiceResolver
167
167
  *
168
168
  * @category Capability
169
169
  */
170
- export const ProcessMonitor = Capability$.make<Process$.Monitor>('org.dxos.app-framework.capability.process-monitor');
170
+ export const ProcessMonitor = Capability$.make<Process$.Monitor>('org.dxos.app-framework.capability.processMonitor');
171
171
 
172
172
  /**
173
173
  * Services that are always available when running effects through a {@link ProcessManagerRuntime}.
@@ -207,7 +207,7 @@ export interface ProcessManagerRuntime {
207
207
  * @category Capability
208
208
  */
209
209
  export const ProcessManagerRuntime = Capability$.make<ProcessManagerRuntime>(
210
- 'org.dxos.app-framework.capability.process-manager-runtime',
210
+ 'org.dxos.app-framework.capability.processManagerRuntime',
211
211
  );
212
212
 
213
213
  export type ManagedRuntime = ManagedRuntime$.ManagedRuntime<any, any>;
@@ -215,14 +215,14 @@ export type ManagedRuntime = ManagedRuntime$.ManagedRuntime<any, any>;
215
215
  /**
216
216
  * @category Capability
217
217
  */
218
- export const ManagedRuntime = Capability$.make<ManagedRuntime>('org.dxos.app-framework.capability.managed-runtime');
218
+ export const ManagedRuntime = Capability$.make<ManagedRuntime>('org.dxos.app-framework.capability.managedRuntime');
219
219
 
220
220
  //
221
221
  // Operation System Capabilities
222
222
  //
223
223
 
224
224
  export const OperationHandler = Capability$.make<OperationHandlerSet.OperationHandlerSet>(
225
- 'org.dxos.app-framework.capability.operation-handler',
225
+ 'org.dxos.app-framework.capability.operationHandler',
226
226
  );
227
227
 
228
228
  export type UndoMapping = UndoMapping$.UndoMapping;
@@ -231,7 +231,7 @@ export type UndoMapping = UndoMapping$.UndoMapping;
231
231
  * Undo mapping registration - contributed by plugins.
232
232
  * @category Capability
233
233
  */
234
- export const UndoMapping = Capability$.make<UndoMapping[]>('org.dxos.app-framework.capability.undo-mapping');
234
+ export const UndoMapping = Capability$.make<UndoMapping[]>('org.dxos.app-framework.capability.undoMapping');
235
235
 
236
236
  /**
237
237
  * Operation invoker backed by the process manager. Spawns a process per
@@ -244,7 +244,7 @@ export type OperationInvoker = OperationInvoker$.OperationInvoker;
244
244
  * @category Capability
245
245
  */
246
246
  export const OperationInvoker = Capability$.make<OperationInvoker>(
247
- 'org.dxos.app-framework.capability.operation-invoker',
247
+ 'org.dxos.app-framework.capability.operationInvoker',
248
248
  );
249
249
 
250
250
  export type UndoRegistry = UndoRegistry$.UndoRegistry;
@@ -253,7 +253,7 @@ export type UndoRegistry = UndoRegistry$.UndoRegistry;
253
253
  * Undo registry - provided by ProcessManagerPlugin.
254
254
  * @category Capability
255
255
  */
256
- export const UndoRegistry = Capability$.make<UndoRegistry>('org.dxos.app-framework.capability.undo-registry');
256
+ export const UndoRegistry = Capability$.make<UndoRegistry>('org.dxos.app-framework.capability.undoRegistry');
257
257
 
258
258
  export type HistoryTracker = HistoryTracker$.HistoryTracker;
259
259
 
@@ -261,7 +261,7 @@ export type HistoryTracker = HistoryTracker$.HistoryTracker;
261
261
  * History tracker - provided by ProcessManagerPlugin.
262
262
  * @category Capability
263
263
  */
264
- export const HistoryTracker = Capability$.make<HistoryTracker>('org.dxos.app-framework.capability.history-tracker');
264
+ export const HistoryTracker = Capability$.make<HistoryTracker>('org.dxos.app-framework.capability.historyTracker');
265
265
 
266
266
  //
267
267
  // Atom Capability Helpers
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export { Config2 } from '@dxos/protocols';