@dxos/protocols 0.9.0 → 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.
- package/dist/src/Config2.d.ts +91 -0
- package/dist/src/Config2.d.ts.map +1 -0
- package/dist/src/Config2.js +56 -0
- package/dist/src/Config2.js.map +1 -0
- package/dist/src/edge/edge.d.ts +82 -0
- package/dist/src/edge/edge.d.ts.map +1 -1
- package/dist/src/edge/edge.js +50 -0
- package/dist/src/edge/edge.js.map +1 -1
- package/dist/src/edge/registry.d.ts +231 -144
- package/dist/src/edge/registry.d.ts.map +1 -1
- package/dist/src/edge/registry.js +126 -87
- package/dist/src/edge/registry.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/proto/gen/dxos/client/services.d.ts +162 -162
- package/dist/src/proto/gen/dxos/client/services.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/client/services.js.map +1 -1
- package/dist/src/proto/gen/google/protobuf.d.ts +27 -27
- package/dist/src/proto/gen/google/protobuf.d.ts.map +1 -1
- package/dist/src/proto/gen/google/protobuf.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -9
- package/src/Config2.ts +68 -0
- package/src/edge/edge.ts +62 -0
- package/src/edge/registry.ts +142 -101
- package/src/index.ts +1 -0
- package/src/lexicons/org.dxos.experimental/README.md +29 -0
- package/src/lexicons/org.dxos.experimental/package.profile.json +87 -0
- package/src/lexicons/org.dxos.experimental/package.release.json +45 -0
- package/src/lexicons/org.dxos.experimental/publisher.profile.json +37 -0
- package/src/lexicons/org.dxos.experimental/publisher.verification.json +36 -0
- package/src/proto/gen/dxos/client/services.ts +162 -162
- package/src/proto/gen/google/protobuf.ts +27 -27
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/protocols",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1-main.c7dcc2e112",
|
|
4
4
|
"description": "Protobuf definitions for DXOS protocols.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"./buf/*": {
|
|
38
38
|
"browser": "./dist/src/buf/proto/gen/*.js",
|
|
39
39
|
"import": "./dist/src/buf/proto/gen/*.js"
|
|
40
|
-
}
|
|
40
|
+
},
|
|
41
|
+
"./lexicons/*": "./src/lexicons/*"
|
|
41
42
|
},
|
|
42
43
|
"types": "dist/src/index.d.ts",
|
|
43
44
|
"files": [
|
|
@@ -46,18 +47,18 @@
|
|
|
46
47
|
],
|
|
47
48
|
"dependencies": {
|
|
48
49
|
"@bufbuild/protobuf": "2.11.0",
|
|
49
|
-
"@dxos/codec-protobuf": "0.9.
|
|
50
|
-
"@dxos/effect": "0.9.
|
|
51
|
-
"@dxos/errors": "0.9.
|
|
52
|
-
"@dxos/invariant": "0.9.
|
|
53
|
-
"@dxos/keys": "0.9.
|
|
54
|
-
"@dxos/timeframe": "0.9.
|
|
50
|
+
"@dxos/codec-protobuf": "0.9.1-main.c7dcc2e112",
|
|
51
|
+
"@dxos/effect": "0.9.1-main.c7dcc2e112",
|
|
52
|
+
"@dxos/errors": "0.9.1-main.c7dcc2e112",
|
|
53
|
+
"@dxos/invariant": "0.9.1-main.c7dcc2e112",
|
|
54
|
+
"@dxos/keys": "0.9.1-main.c7dcc2e112",
|
|
55
|
+
"@dxos/timeframe": "0.9.1-main.c7dcc2e112"
|
|
55
56
|
},
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@bufbuild/buf": "1.65.0",
|
|
58
59
|
"@bufbuild/protoc-gen-es": "2.11.0",
|
|
59
60
|
"effect": "3.21.3",
|
|
60
|
-
"@dxos/protobuf-compiler": "0.9.
|
|
61
|
+
"@dxos/protobuf-compiler": "0.9.1-main.c7dcc2e112"
|
|
61
62
|
},
|
|
62
63
|
"peerDependencies": {
|
|
63
64
|
"effect": "3.21.3"
|
package/src/Config2.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
// @import-as-namespace
|
|
6
|
+
|
|
7
|
+
import * as Schema from 'effect/Schema';
|
|
8
|
+
|
|
9
|
+
/** A plugin preview image with optional theme-specific URLs (`light` / `dark`). */
|
|
10
|
+
export const Screenshot = Schema.Struct({
|
|
11
|
+
light: Schema.optional(Schema.String),
|
|
12
|
+
dark: Schema.optional(Schema.String),
|
|
13
|
+
});
|
|
14
|
+
export type Screenshot = Schema.Schema.Type<typeof Screenshot>;
|
|
15
|
+
|
|
16
|
+
/** Icon reference: Phosphor icon key with an optional theme hue. */
|
|
17
|
+
export const Icon = Schema.Struct({
|
|
18
|
+
key: Schema.String.pipe(Schema.nonEmptyString()),
|
|
19
|
+
hue: Schema.optional(Schema.String),
|
|
20
|
+
});
|
|
21
|
+
export type Icon = Schema.Schema.Type<typeof Icon>;
|
|
22
|
+
|
|
23
|
+
export const Plugin = Schema.Struct({
|
|
24
|
+
/** Reverse-domain NSID — the plugin's globally-unique key (e.g. `org.dxos.plugin.excalidraw`). */
|
|
25
|
+
key: Schema.String.pipe(Schema.nonEmptyString()),
|
|
26
|
+
name: Schema.String.pipe(Schema.nonEmptyString()),
|
|
27
|
+
description: Schema.optional(Schema.String),
|
|
28
|
+
/**
|
|
29
|
+
* Author or organization name. Only used for bundled plugins. For plugins published to the
|
|
30
|
+
* registry this field is ignored — the verified publisher (handle ?? did) is used instead.
|
|
31
|
+
*/
|
|
32
|
+
author: Schema.optional(Schema.String),
|
|
33
|
+
homePage: Schema.optional(Schema.String),
|
|
34
|
+
source: Schema.optional(Schema.String),
|
|
35
|
+
screenshots: Schema.optional(Schema.Array(Screenshot)),
|
|
36
|
+
tags: Schema.optional(Schema.Array(Schema.String)),
|
|
37
|
+
icon: Schema.optional(Icon),
|
|
38
|
+
spec: Schema.optional(Schema.String),
|
|
39
|
+
/** Composer plugin ids this plugin depends on at runtime (NSIDs). */
|
|
40
|
+
dependsOn: Schema.optional(Schema.Array(Schema.String)),
|
|
41
|
+
});
|
|
42
|
+
export type Plugin = Schema.Schema.Type<typeof Plugin>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Publish orchestration for `dx registry publish`: build command, output directory, and optional
|
|
46
|
+
* hosting override. All three are consumed together — they are a single workflow, not separate concerns.
|
|
47
|
+
*/
|
|
48
|
+
export const Publish = Schema.Struct({
|
|
49
|
+
buildCommand: Schema.optional(Schema.String),
|
|
50
|
+
outputDirectory: Schema.optional(Schema.String),
|
|
51
|
+
assetBaseUrl: Schema.optional(Schema.String),
|
|
52
|
+
});
|
|
53
|
+
export type Publish = Schema.Schema.Type<typeof Publish>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The `dx.config.ts` schema: the TypeScript-authored replacement for the
|
|
57
|
+
* plugin section of `dx.yml`. v1 carries one plugin's self-declared `meta` plus optional publish
|
|
58
|
+
* orchestration; it will grow to absorb the rest of the (currently proto-based) config over time and
|
|
59
|
+
* eventually become the canonical config.
|
|
60
|
+
*/
|
|
61
|
+
export const Config = Schema.Struct({
|
|
62
|
+
plugin: Plugin,
|
|
63
|
+
publish: Schema.optional(Publish),
|
|
64
|
+
});
|
|
65
|
+
export type Config = Schema.Schema.Type<typeof Config>;
|
|
66
|
+
|
|
67
|
+
/** Identity helper: authors a typed `dx.config.ts`. Validation runs at load time, not here. */
|
|
68
|
+
export const make = (config: Config): Config => config;
|
package/src/edge/edge.ts
CHANGED
|
@@ -339,6 +339,9 @@ export enum OAuthProvider {
|
|
|
339
339
|
TRELLO = 'trello',
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
+
/** atproto OAuth scopes for the Atmosphere integration and account-recovery flows. */
|
|
343
|
+
export const ATPROTO_OAUTH_SCOPES = ['atproto', 'transition:generic', 'transition:email'] as const;
|
|
344
|
+
|
|
342
345
|
export const InitiateOAuthFlowRequestSchema = Schema.Struct({
|
|
343
346
|
provider: Schema.Enums(OAuthProvider),
|
|
344
347
|
spaceId: Schema.String.pipe(Schema.filter(SpaceId.isValid)), // TODO(burdon): Use SpaceId.
|
|
@@ -761,6 +764,65 @@ export const RequestAccessRequestSchema = Schema.Struct({
|
|
|
761
764
|
export type RequestAccessRequest = Schema.Schema.Type<typeof RequestAccessRequestSchema>;
|
|
762
765
|
export type RequestAccessResponse = { received: boolean };
|
|
763
766
|
|
|
767
|
+
//
|
|
768
|
+
// Metering (VP auth)
|
|
769
|
+
//
|
|
770
|
+
|
|
771
|
+
/** Structured usage key aligned with {@link MeteringLimitSchema} (without cap/window fields). */
|
|
772
|
+
export const MeteringUsageKeySchema = Schema.Struct({
|
|
773
|
+
/** Event type (e.g. `ai`). */
|
|
774
|
+
eventType: Schema.String,
|
|
775
|
+
/** Value key being metered (e.g. `outputTokens`). */
|
|
776
|
+
valueKey: Schema.String,
|
|
777
|
+
/**
|
|
778
|
+
* Positional match against the event's subtype segments (e.g. model); `*` matches any
|
|
779
|
+
* segment, and positions beyond the pattern are unconstrained.
|
|
780
|
+
*/
|
|
781
|
+
subtypePattern: Schema.Array(Schema.String),
|
|
782
|
+
});
|
|
783
|
+
export type MeteringUsageKey = Schema.Schema.Type<typeof MeteringUsageKeySchema>;
|
|
784
|
+
|
|
785
|
+
/** Rolling-window usage total for a structured key. */
|
|
786
|
+
export const MeteringUsageItemSchema = Schema.Struct({
|
|
787
|
+
...MeteringUsageKeySchema.fields,
|
|
788
|
+
amount: Schema.Number,
|
|
789
|
+
});
|
|
790
|
+
export type MeteringUsageItem = Schema.Schema.Type<typeof MeteringUsageItemSchema>;
|
|
791
|
+
|
|
792
|
+
/** A single raw usage bucket (1h resolution) for a structured key. */
|
|
793
|
+
export const MeteringUsageBucketSchema = Schema.Struct({
|
|
794
|
+
...MeteringUsageKeySchema.fields,
|
|
795
|
+
/** Bucket start timestamp (epoch ms, floored to the hour). */
|
|
796
|
+
bucketStart: Schema.Number,
|
|
797
|
+
amount: Schema.Number,
|
|
798
|
+
});
|
|
799
|
+
export type MeteringUsageBucket = Schema.Schema.Type<typeof MeteringUsageBucketSchema>;
|
|
800
|
+
|
|
801
|
+
export const MeteringLimitSchema = Schema.Struct({
|
|
802
|
+
/** Event type the limit applies to (e.g. `ai`). */
|
|
803
|
+
eventType: Schema.String,
|
|
804
|
+
/** Value key being limited (e.g. `outputTokens`). */
|
|
805
|
+
valueKey: Schema.String,
|
|
806
|
+
/**
|
|
807
|
+
* Positional match against the event's subtype segments (e.g. model); `*` matches any
|
|
808
|
+
* segment, and positions beyond the pattern are unconstrained.
|
|
809
|
+
*/
|
|
810
|
+
subtypePattern: Schema.Array(Schema.String),
|
|
811
|
+
/** Rolling-window cap; `null` means unlimited. */
|
|
812
|
+
limit: Schema.NullOr(Schema.Number),
|
|
813
|
+
/** Window duration in seconds. */
|
|
814
|
+
windowDuration: Schema.Number,
|
|
815
|
+
});
|
|
816
|
+
export type MeteringLimit = Schema.Schema.Type<typeof MeteringLimitSchema>;
|
|
817
|
+
|
|
818
|
+
export const GetProfileUsageResponseSchema = Schema.Struct({
|
|
819
|
+
profileId: Schema.String,
|
|
820
|
+
usage: Schema.Array(MeteringUsageItemSchema),
|
|
821
|
+
limits: Schema.Array(MeteringLimitSchema),
|
|
822
|
+
buckets: Schema.Array(MeteringUsageBucketSchema),
|
|
823
|
+
});
|
|
824
|
+
export type GetProfileUsageResponse = Schema.Schema.Type<typeof GetProfileUsageResponseSchema>;
|
|
825
|
+
|
|
764
826
|
//
|
|
765
827
|
// Admin (X-API-KEY)
|
|
766
828
|
//
|
package/src/edge/registry.ts
CHANGED
|
@@ -4,33 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Schema from 'effect/Schema';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
* Hydrated plugin metadata, mirroring the @dxos/app-framework `Plugin.Meta` shape.
|
|
9
|
-
*
|
|
10
|
-
* Defined locally rather than imported from @dxos/app-framework to keep the protocols
|
|
11
|
-
* package free of UI/runtime dependencies. Consumers can treat decoded values as
|
|
12
|
-
* `Plugin.Meta` directly.
|
|
13
|
-
*/
|
|
14
|
-
export const PluginMetaSchema = Schema.Struct({
|
|
15
|
-
id: Schema.String.pipe(Schema.nonEmptyString()),
|
|
16
|
-
name: Schema.String.pipe(Schema.nonEmptyString()),
|
|
17
|
-
description: Schema.optional(Schema.String),
|
|
18
|
-
author: Schema.optional(Schema.String),
|
|
19
|
-
homePage: Schema.optional(Schema.String),
|
|
20
|
-
source: Schema.optional(Schema.String),
|
|
21
|
-
screenshots: Schema.optional(Schema.Array(Schema.String)),
|
|
22
|
-
tags: Schema.optional(Schema.Array(Schema.String)),
|
|
23
|
-
icon: Schema.optional(Schema.String),
|
|
24
|
-
iconHue: Schema.optional(Schema.String),
|
|
25
|
-
});
|
|
26
|
-
export type PluginMeta = Schema.Schema.Type<typeof PluginMetaSchema>;
|
|
7
|
+
import * as Config2 from '../Config2.ts';
|
|
27
8
|
|
|
28
9
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
10
|
+
* A snapshot of a plugin's declared dependencies resolved to concrete installed versions at build
|
|
11
|
+
* time (`{ "@dxos/app-framework": "0.8.3", "react": "19.2.0", … }`). The host derives SDK
|
|
12
|
+
* compatibility from the subset it shares with the plugin (the externalized `@dxos/*` packages).
|
|
31
13
|
*/
|
|
32
|
-
export const
|
|
33
|
-
export type
|
|
14
|
+
export const DependencyMapSchema = Schema.Record({ key: Schema.String, value: Schema.String });
|
|
15
|
+
export type DependencyMap = Schema.Schema.Type<typeof DependencyMapSchema>;
|
|
34
16
|
|
|
35
17
|
/**
|
|
36
18
|
* Filename of the entry module every plugin must publish at the root of its bundle.
|
|
@@ -50,7 +32,7 @@ export const PLUGIN_ENTRY_FILENAME = 'index.mjs';
|
|
|
50
32
|
* Paths in `assets` are relative to the manifest's URL.
|
|
51
33
|
*/
|
|
52
34
|
export const PluginManifestSchema = Schema.Struct({
|
|
53
|
-
...
|
|
35
|
+
...Config2.Plugin.fields,
|
|
54
36
|
/** Plugin version (semver). Sourced from the publishing project's `package.json`. */
|
|
55
37
|
version: Schema.String.pipe(Schema.nonEmptyString()),
|
|
56
38
|
/**
|
|
@@ -58,107 +40,166 @@ export const PluginManifestSchema = Schema.Struct({
|
|
|
58
40
|
* Must include {@link PLUGIN_ENTRY_FILENAME}; consumers verify on parse.
|
|
59
41
|
*/
|
|
60
42
|
assets: Schema.Array(Schema.String).pipe(Schema.minItems(1)),
|
|
43
|
+
/** Declared dependencies resolved to installed versions at build time (SDK-compat source). */
|
|
44
|
+
dependencies: Schema.optional(DependencyMapSchema),
|
|
61
45
|
});
|
|
62
46
|
export type PluginManifest = Schema.Schema.Type<typeof PluginManifestSchema>;
|
|
63
47
|
|
|
48
|
+
// ─── ATProto-native registry view ────────────────────────────────────────────
|
|
49
|
+
|
|
64
50
|
/**
|
|
65
|
-
*
|
|
51
|
+
* A single installable release of a plugin, projected from a `package.release`
|
|
52
|
+
* ATProto record.
|
|
66
53
|
*/
|
|
67
|
-
export const
|
|
68
|
-
/**
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
|
|
54
|
+
export const PluginReleaseSchema = Schema.Struct({
|
|
55
|
+
/** Semver version string, e.g. `0.8.3`. */
|
|
56
|
+
version: Schema.String.pipe(Schema.nonEmptyString()),
|
|
57
|
+
/** URL the host dynamic-imports to install this specific version. */
|
|
58
|
+
moduleUrl: Schema.String.pipe(Schema.nonEmptyString()),
|
|
72
59
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* The URL must be CORS-safe and have its declared assets reachable as siblings.
|
|
60
|
+
* Dependencies this release was built against, resolved to installed versions. The host derives
|
|
61
|
+
* SDK compatibility from the `@dxos/*` subset to decide whether to offer this release.
|
|
76
62
|
*/
|
|
77
|
-
|
|
78
|
-
/** Release tag the entry was resolved from (e.g. `v0.1.0`). Empty string for `manifestUrl` entries. */
|
|
79
|
-
releaseTag: Schema.String,
|
|
80
|
-
/** Health signal set by the service when an entry fails to refresh. */
|
|
81
|
-
health: PluginHealthSchema,
|
|
82
|
-
/** Unix ms when this entry was last successfully hydrated. */
|
|
83
|
-
hydratedAt: Schema.Number,
|
|
63
|
+
dependencies: Schema.optional(DependencyMapSchema),
|
|
84
64
|
});
|
|
85
|
-
export type
|
|
65
|
+
export type PluginRelease = Schema.Schema.Type<typeof PluginReleaseSchema>;
|
|
86
66
|
|
|
87
67
|
/**
|
|
88
|
-
*
|
|
68
|
+
* Verbatim content of a `package.profile` ATProto record. `key` is the record's rkey (a reverse-domain
|
|
69
|
+
* NSID), denormalized into the body. Version-independent identity + display metadata; provenance
|
|
70
|
+
* (`author`) is resolved separately from the publisher DID/handle.
|
|
89
71
|
*/
|
|
90
|
-
export const
|
|
91
|
-
/**
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
|
|
72
|
+
export const PluginProfileSchema = Schema.Struct({
|
|
73
|
+
/** Reverse-domain NSID — the plugin's globally-unique key and the `package.profile` rkey (e.g. `org.dxos.plugin.excalidraw`). */
|
|
74
|
+
key: Schema.String.pipe(Schema.nonEmptyString()),
|
|
75
|
+
/** Plugin display name. */
|
|
76
|
+
name: Schema.String.pipe(Schema.nonEmptyString()),
|
|
77
|
+
/** Short description of plugin functionality. */
|
|
78
|
+
description: Schema.optional(Schema.String),
|
|
79
|
+
/** Publisher's homepage or plugin documentation URL. */
|
|
80
|
+
homePage: Schema.optional(Schema.String),
|
|
81
|
+
/** Source repository URL. */
|
|
82
|
+
source: Schema.optional(Schema.String),
|
|
83
|
+
/** Tags to help categorize the plugin. */
|
|
84
|
+
tags: Schema.optional(Schema.Array(Schema.String)),
|
|
85
|
+
/** Preview images — theme-keyed screenshot URLs shown on the plugin's card. */
|
|
86
|
+
screenshots: Schema.optional(Schema.Array(Config2.Screenshot)),
|
|
87
|
+
/** Icon identifier resolvable by `@ch-ui/icons` (e.g. `ph--sparkle--regular`), with an optional palette hue. */
|
|
88
|
+
icon: Schema.optional(Config2.Icon),
|
|
89
|
+
/** Composer plugin ids this plugin depends on at runtime (NSIDs). Author-declared, version-independent. */
|
|
90
|
+
dependsOn: Schema.optional(Schema.Array(Schema.String)),
|
|
91
|
+
/** Relative path inside the package to a bundled MDL spec (consumed by plugin-code). */
|
|
92
|
+
spec: Schema.optional(Schema.String),
|
|
97
93
|
});
|
|
98
|
-
export type
|
|
94
|
+
export type PluginProfile = Schema.Schema.Type<typeof PluginProfileSchema>;
|
|
99
95
|
|
|
100
96
|
/**
|
|
101
|
-
* A single
|
|
102
|
-
* versions endpoint. Sourced from the publishing project's GitHub releases.
|
|
97
|
+
* A single hydrated plugin entry returned by `GET /registry/plugins`.
|
|
103
98
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
99
|
+
* This is an indexer-assembled *view* — analogous to emdash's `PackageView` — projected
|
|
100
|
+
* from four ATProto record types: `package.profile`, `package.release`,
|
|
101
|
+
* `publisher.profile`, and `publisher.verification`. It is NOT a direct serialization
|
|
102
|
+
* of any single ATProto record.
|
|
103
|
+
*
|
|
104
|
+
* Design notes:
|
|
105
|
+
* - `profile.key` is required to be a valid NSID (e.g. `org.dxos.plugin.excalidraw`), making it
|
|
106
|
+
* the single identifier for both PDS addressing and the composer runtime plugin id.
|
|
107
|
+
* `DXN.make(profile.key, latestVersion)` reconstructs the canonical plugin DXN.
|
|
108
|
+
* - `releases` inlines all known versions, eliminating a separate versions round-trip for
|
|
109
|
+
* the version picker. Ordered newest-first.
|
|
110
|
+
* - `latestVersion` is a convenience pointer into `releases` indicating the recommended
|
|
111
|
+
* install target.
|
|
106
112
|
*/
|
|
107
|
-
export const
|
|
108
|
-
|
|
109
|
-
tag: Schema.String.pipe(Schema.nonEmptyString()),
|
|
113
|
+
export const PluginViewSchema = Schema.Struct({
|
|
114
|
+
// ── Addressing / provenance (indexer-derived) ────────────────────────────
|
|
110
115
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* this when the user installs / rolls back to this version.
|
|
116
|
+
* `at://` URI of the source `package.profile` record.
|
|
117
|
+
* Globally unique and stable — never changes after the record is published.
|
|
114
118
|
*/
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
|
|
119
|
+
uri: Schema.String.pipe(Schema.nonEmptyString()),
|
|
120
|
+
/** Publisher DID, e.g. `did:plc:abc…`. Cryptographic identity; never changes. */
|
|
121
|
+
did: Schema.String.pipe(Schema.nonEmptyString()),
|
|
122
|
+
/**
|
|
123
|
+
* Publisher AT Protocol handle at index time, e.g. `alice.bsky.social`.
|
|
124
|
+
* Display-only — handles can be reassigned; never use as a stable key.
|
|
125
|
+
*/
|
|
126
|
+
handle: Schema.optional(Schema.String),
|
|
127
|
+
/** Unix ms when the indexer last assembled this entry. */
|
|
128
|
+
indexedAt: Schema.Number,
|
|
129
|
+
/**
|
|
130
|
+
* Trust labels derived from curator `publisher.verification` records.
|
|
131
|
+
* An empty array means the entry has no verification signal.
|
|
132
|
+
*/
|
|
133
|
+
labels: Schema.Array(Schema.String),
|
|
134
|
+
|
|
135
|
+
// ── Verbatim profile record content ─────────────────────────────────────
|
|
136
|
+
profile: PluginProfileSchema,
|
|
137
|
+
|
|
138
|
+
// ── Releases (projected from package.release records) ───────────────────
|
|
139
|
+
/**
|
|
140
|
+
* All known releases for this package, ordered newest-first.
|
|
141
|
+
* Powers the version picker directly — no separate endpoint needed.
|
|
142
|
+
*/
|
|
143
|
+
releases: Schema.Array(PluginReleaseSchema),
|
|
144
|
+
/**
|
|
145
|
+
* The latest (recommended) release version. Always references an entry in `releases`.
|
|
146
|
+
* Used by the host to determine whether an update is available.
|
|
147
|
+
*/
|
|
148
|
+
latestVersion: Schema.String.pipe(Schema.nonEmptyString()),
|
|
118
149
|
});
|
|
119
|
-
export type
|
|
150
|
+
export type PluginView = Schema.Schema.Type<typeof PluginViewSchema>;
|
|
120
151
|
|
|
121
152
|
/**
|
|
122
|
-
* Response body of `GET /registry/plugins
|
|
123
|
-
*
|
|
124
|
-
* `:repo` is the GitHub `owner/name` form, URL-encoded (so `/` is escaped).
|
|
125
|
-
* Returns all hydratable releases for the repo, newest first; clients display them
|
|
126
|
-
* in the version picker for install / roll-back. Unauthenticated; same surface area
|
|
127
|
-
* as `GET /registry/plugins`.
|
|
153
|
+
* Response body of `GET /registry/plugins`.
|
|
128
154
|
*/
|
|
129
|
-
export const
|
|
130
|
-
/** Wire-format schema version, pinned to
|
|
131
|
-
version: Schema.Literal(
|
|
132
|
-
/**
|
|
133
|
-
|
|
134
|
-
/** Unix ms timestamp of the most recent successful
|
|
155
|
+
export const GetPluginsResponseBodySchema = Schema.Struct({
|
|
156
|
+
/** Wire-format schema version, pinned to 2. */
|
|
157
|
+
version: Schema.Literal(2),
|
|
158
|
+
/** Hydrated entries. */
|
|
159
|
+
plugins: Schema.Array(PluginViewSchema),
|
|
160
|
+
/** Unix ms timestamp of the most recent successful index cycle. */
|
|
135
161
|
refreshedAt: Schema.Number,
|
|
136
162
|
});
|
|
137
|
-
export type
|
|
163
|
+
export type GetPluginsResponseBody = Schema.Schema.Type<typeof GetPluginsResponseBodySchema>;
|
|
138
164
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
Schema.Struct({ manifestUrl: Schema.String.pipe(Schema.nonEmptyString()) }),
|
|
150
|
-
);
|
|
151
|
-
export type RegistryEntry = Schema.Schema.Type<typeof RegistryEntrySchema>;
|
|
165
|
+
// ─── Publisher records ────────────────────────────────────────────────────────
|
|
166
|
+
|
|
167
|
+
/** Content of a `publisher.profile` ATProto record. Display metadata for a publisher DID. */
|
|
168
|
+
export const PublisherProfileSchema = Schema.Struct({
|
|
169
|
+
displayName: Schema.String.pipe(Schema.nonEmptyString()),
|
|
170
|
+
bio: Schema.optional(Schema.String),
|
|
171
|
+
homepageUrl: Schema.optional(Schema.String),
|
|
172
|
+
contact: Schema.optional(Schema.String),
|
|
173
|
+
});
|
|
174
|
+
export type PublisherProfile = Schema.Schema.Type<typeof PublisherProfileSchema>;
|
|
152
175
|
|
|
153
176
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
177
|
+
* Content of a `publisher.verification` record written by the curator DID.
|
|
178
|
+
* Links a publisher DID to a trusted AT Protocol handle.
|
|
156
179
|
*/
|
|
157
|
-
export const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
180
|
+
export const PublisherVerificationSchema = Schema.Struct({
|
|
181
|
+
subject: Schema.String.pipe(Schema.nonEmptyString()),
|
|
182
|
+
handle: Schema.String.pipe(Schema.nonEmptyString()),
|
|
183
|
+
displayName: Schema.String.pipe(Schema.nonEmptyString()),
|
|
184
|
+
createdAt: Schema.String.pipe(Schema.nonEmptyString()),
|
|
185
|
+
});
|
|
186
|
+
export type PublisherVerification = Schema.Schema.Type<typeof PublisherVerificationSchema>;
|
|
187
|
+
|
|
188
|
+
// ─── NSID constants ───────────────────────────────────────────────────────────
|
|
189
|
+
|
|
190
|
+
/** NSID constants for the four `org.dxos.experimental.*` record collections. */
|
|
191
|
+
export const NSID = {
|
|
192
|
+
PackageProfile: 'org.dxos.experimental.package.profile',
|
|
193
|
+
PackageRelease: 'org.dxos.experimental.package.release',
|
|
194
|
+
PublisherProfile: 'org.dxos.experimental.publisher.profile',
|
|
195
|
+
PublisherVerification: 'org.dxos.experimental.publisher.verification',
|
|
196
|
+
} as const;
|
|
197
|
+
|
|
198
|
+
export type RegistryNsid = (typeof NSID)[keyof typeof NSID];
|
|
199
|
+
|
|
200
|
+
export const ALL_NSIDS: readonly RegistryNsid[] = [
|
|
201
|
+
NSID.PackageProfile,
|
|
202
|
+
NSID.PackageRelease,
|
|
203
|
+
NSID.PublisherProfile,
|
|
204
|
+
NSID.PublisherVerification,
|
|
205
|
+
];
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * from './profile-archive.ts';
|
|
|
11
11
|
export * from './space-archive.ts';
|
|
12
12
|
export * from './storage.ts';
|
|
13
13
|
export type * from './types.ts';
|
|
14
|
+
export * as Config2 from './Config2.ts';
|
|
14
15
|
export * as FunctionProtocol from './FunctionProtocol.ts';
|
|
15
16
|
export * as FeedProtocol from './FeedProtocol.ts';
|
|
16
17
|
export * as TraceProtocol from './TraceProtocol.ts';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# `org.dxos.experimental.*` lexicons
|
|
2
|
+
|
|
3
|
+
Experimental AT Protocol lexicons for the DXOS plugin registry. The `experimental` segment is intentional — these schemas are unstable and will be renamed to a final namespace before promotion.
|
|
4
|
+
|
|
5
|
+
## Records
|
|
6
|
+
|
|
7
|
+
| NSID | rkey | Purpose |
|
|
8
|
+
| ---------------------------------------------- | ------------------ | ----------------------------------------------------- |
|
|
9
|
+
| `org.dxos.experimental.package.profile` | `<key>` | Mutable package metadata (one per key per DID). |
|
|
10
|
+
| `org.dxos.experimental.package.release` | `<key>:<version>` | Versioned artifact record (conceptually single-write).|
|
|
11
|
+
| `org.dxos.experimental.publisher.profile` | `self` | Identity-level publisher metadata. |
|
|
12
|
+
| `org.dxos.experimental.publisher.verification` | `<verified DID>` | Trust attestation about a publisher. |
|
|
13
|
+
|
|
14
|
+
## Trust model
|
|
15
|
+
|
|
16
|
+
`publisher.verification` records are public and unrestricted — anyone may author one. Trust is an indexing policy, not a write gate. Today the indexer honors verification records **only** from a single configured verifier DID (`REGISTRY_CURATOR_DID`) and indexes a publisher's records only if that verifier has vouched for the author DID. Revocation is achieved by deleting the verification record — the indexer unindexes that publisher on the next backfill sweep. This single-verifier gate is intended to generalize to multiple verifiers / moderation labels (à la Bluesky labelers) once that surface exists.
|
|
17
|
+
|
|
18
|
+
See `packages/sdk/app-framework/docs/registry-spec.md` for the full design, including the integrity / tamper-detection model.
|
|
19
|
+
|
|
20
|
+
## Prior art
|
|
21
|
+
|
|
22
|
+
These lexicons are modeled on the emdash RFC:
|
|
23
|
+
|
|
24
|
+
- RFC: [emdash-cms/emdash#694](https://github.com/emdash-cms/emdash/pull/694) — design rationale, trust model trade-offs, rkey conventions, and the `experimental` namespace strategy.
|
|
25
|
+
- Implementation: [emdash-cms/emdash#923](https://github.com/emdash-cms/emdash/pull/923) — client, CLI, and lexicon bindings.
|
|
26
|
+
|
|
27
|
+
Differences from emdash's `com.emdashcms.experimental.*`:
|
|
28
|
+
|
|
29
|
+
- `releaseExtension` / `declaredAccess` records (sandbox manifest, granular permissions) are **not** included in v0; they will be added in a follow-on once the runtime sandbox surface is defined.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lexicon": 1,
|
|
3
|
+
"id": "org.dxos.experimental.package.profile",
|
|
4
|
+
"defs": {
|
|
5
|
+
"main": {
|
|
6
|
+
"type": "record",
|
|
7
|
+
"key": "literal:key",
|
|
8
|
+
"description": "Mutable metadata for a discoverable plugin/module published on the DXOS experimental registry. The rkey is the plugin key (reverse-domain NSID, e.g. org.dxos.plugin.excalidraw). Companion org.dxos.experimental.package.release records carry versioned artifacts.",
|
|
9
|
+
"record": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"required": ["key", "name", "createdAt"],
|
|
12
|
+
"properties": {
|
|
13
|
+
"key": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "Reverse-domain NSID — the plugin's globally-unique key and the profile rkey (e.g. org.dxos.plugin.excalidraw).",
|
|
16
|
+
"maxLength": 63,
|
|
17
|
+
"minLength": 1
|
|
18
|
+
},
|
|
19
|
+
"name": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Human-readable display name.",
|
|
22
|
+
"maxLength": 128
|
|
23
|
+
},
|
|
24
|
+
"description": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"description": "Short description shown in registry listings.",
|
|
27
|
+
"maxLength": 512
|
|
28
|
+
},
|
|
29
|
+
"homePage": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"format": "uri",
|
|
32
|
+
"description": "Optional canonical homepage."
|
|
33
|
+
},
|
|
34
|
+
"source": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"format": "uri",
|
|
37
|
+
"description": "Optional public source repository URL."
|
|
38
|
+
},
|
|
39
|
+
"tags": {
|
|
40
|
+
"type": "array",
|
|
41
|
+
"description": "Optional discovery tags.",
|
|
42
|
+
"maxLength": 16,
|
|
43
|
+
"items": { "type": "string", "maxLength": 32 }
|
|
44
|
+
},
|
|
45
|
+
"screenshots": {
|
|
46
|
+
"type": "array",
|
|
47
|
+
"description": "Optional preview images. Each item has optional light/dark theme URLs.",
|
|
48
|
+
"maxLength": 8,
|
|
49
|
+
"items": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"properties": {
|
|
52
|
+
"light": { "type": "string", "format": "uri" },
|
|
53
|
+
"dark": { "type": "string", "format": "uri" }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"icon": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"description": "Optional icon reference: Phosphor icon key with an optional theme hue.",
|
|
60
|
+
"required": ["key"],
|
|
61
|
+
"properties": {
|
|
62
|
+
"key": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"description": "Phosphor icon name (e.g. ph--compass-tool--regular).",
|
|
65
|
+
"maxLength": 64
|
|
66
|
+
},
|
|
67
|
+
"hue": { "type": "string", "description": "Theme hue hint (e.g. blue, amber).", "maxLength": 32 }
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"dependsOn": {
|
|
71
|
+
"type": "array",
|
|
72
|
+
"description": "Optional list of plugin NSIDs this plugin depends on at runtime.",
|
|
73
|
+
"items": { "type": "string" }
|
|
74
|
+
},
|
|
75
|
+
"spec": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"description": "Optional relative path inside the package to a bundled MDL spec."
|
|
78
|
+
},
|
|
79
|
+
"createdAt": {
|
|
80
|
+
"type": "string",
|
|
81
|
+
"format": "datetime"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|