Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions community/lexicon/app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# community.lexicon.app

This set of Lexicon schemas describes apps built on or for the AT Protocol.

## Records

* `profile`: A canonical app profile published by the app's DID at rkey
`self`.

* `profileLocalization`: Locale-specific metadata for a canonical app profile.
These records should be published by the same DID as the profile. Publishers
should use normalized BCP 47 language tags as rkeys when possible, such as
`fr` or `pt-BR`; consumers should trust the record's `locale` field over the
rkey.

* `entry`: A community or third-party app listing. Any account can publish an
entry, including entries for apps they do not own.

## Canonical profiles

Entries can name a `profileDid`. Consumers can derive the canonical profile URI
from that DID:

```text
at://<profileDid>/community.lexicon.app.profile/self
```

An entry without `profileDid` should be treated as a standalone third-party
listing. A `profileDid` is a pointer to where a canonical profile may exist, not
proof of ownership or verification by itself.

## Internationalization

Entries can include a `locale` field when the listing is intended for a
particular language or regional audience. App publishers can add
`profileLocalization` records for authoritative localized names, descriptions,
links, images, and Web App Manifest URIs.

## Rich app metadata

Records can include an `images` array for icons, logos, hero images,
screenshots, banners, social cards, app store visuals, ads, or other directory
media. Each image includes alt text and either an ATProto blob or a hosted image
URI; purpose and aspect ratio are optional.

Records may also include `webManifestUri` to point at a Web App Manifest.
Manifests can prefill or augment install behavior, icons, screenshots,
language, and platform or form-factor metadata without making manifests the only
way to describe visual assets.

## Verification

Verification is intentionally out of scope for these records. Directories and
clients can verify ownership out of band using methods such as `rel=me`,
`.well-known` resources, or other trust policies.
103 changes: 103 additions & 0 deletions community/lexicon/app/defs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{
"lexicon": 1,
"id": "community.lexicon.app.defs",
"defs": {
"link": {
"type": "object",
"description": "A labeled URI associated with an app.",
"required": ["uri"],
"properties": {
"uri": {
"type": "string",
"format": "uri",
"description": "Destination URI."
},
"label": {
"type": "string",
"maxLength": 100,
"maxGraphemes": 50,
"description": "Human-readable label for the URI."
}
}
},
"image": {
"type": "object",
"description": "An image associated with an app, including accessibility and display metadata. Use either image for an ATProto blob or uri for a remotely hosted image.",
"required": ["alt"],
"properties": {
"purpose": {
"type": "string",
"knownValues": ["icon", "logo", "hero", "screenshot", "banner", "social-card", "app-store", "ad", "other"],
"description": "How directories and stores should use the image."
},
"image": {
"type": "blob",
"description": "The raw image file.",
"accept": ["image/*"],
"maxSize": 2000000
},
"uri": {
"type": "string",
"format": "uri",
"description": "Remote image URI."
},
"alt": {
"type": "string",
"maxLength": 1000,
"maxGraphemes": 300,
"description": "Alt text description of the image, for accessibility."
},
"aspectRatio": {
"type": "ref",
"ref": "#aspectRatio"
}
}
},
"aspectRatio": {
"type": "object",
"description": "width:height represents an aspect ratio. It may be approximate.",
"required": ["width", "height"],
"properties": {
"width": {
"type": "integer",
"minimum": 1
},
"height": {
"type": "integer",
"minimum": 1
}
}
},
"status": {
"type": "string",
"description": "Current release or maintenance status of an app.",
"knownValues": [
"community.lexicon.app.defs#unreleased",
"community.lexicon.app.defs#preview",
"community.lexicon.app.defs#released",
"community.lexicon.app.defs#unmaintained",
"community.lexicon.app.defs#discontinued"
]
},
"unreleased": {
"type": "token",
"description": "The app has been announced but is not yet available."
},
"preview": {
"type": "token",
"description": "The app is available as an alpha, beta, early access, or preview release."
},
"released": {
"type": "token",
"description": "The app is generally available."
},
"unmaintained": {
"type": "token",
"description": "The app may still be available, but is no longer actively maintained."
},
"discontinued": {
"type": "token",
"description": "The app is no longer available or supported."
}
}
}
87 changes: 87 additions & 0 deletions community/lexicon/app/entry.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"lexicon": 1,
"id": "community.lexicon.app.entry",
"defs": {
"main": {
"type": "record",
"description": "A third-party or community listing for an app built on or for the AT Protocol.",
"key": "tid",
"record": {
"type": "object",
"required": ["name", "links", "createdAt"],
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"maxGraphemes": 100,
"description": "The display name of the app."
},
"description": {
"type": "string",
"maxLength": 3000,
"maxGraphemes": 300,
"description": "A short description of what the app does."
},
"images": {
"type": "array",
"maxLength": 12,
"description": "Visual assets for directories and stores, such as icons, hero images, screenshots, banners, and social cards.",
"items": {
"type": "ref",
"ref": "community.lexicon.app.defs#image"
}
},
"tags": {
"type": "array",
"maxLength": 10,
Comment thread
pixeline marked this conversation as resolved.
"items": {
"type": "string",
"maxLength": 64,
"maxGraphemes": 32
},
"description": "Open discovery tags for filtering and search, preferably lowercase."
},
"status": {
"type": "ref",
"ref": "community.lexicon.app.defs#status",
"description": "Current release or maintenance status of the app."
},
"profileDid": {
"type": "string",
"format": "did",
"description": "DID expected to publish the canonical app profile at community.lexicon.app.profile/self."
},
"locale": {
"type": "string",
"format": "language",
"description": "BCP 47 language tag indicating the language or regional audience this entry is intended for."
},
"links": {
"type": "array",
"maxLength": 12,
"description": "Relevant destinations for the app. The first link should be the primary destination.",
"items": {
"type": "ref",
"ref": "community.lexicon.app.defs#link"
}
},
"webManifestUri": {
"type": "string",
"format": "uri",
"description": "URI of a Web App Manifest for richer install and directory metadata, such as icons and screenshots."
},
"createdAt": {
"type": "string",
"format": "datetime",
"description": "Client-declared timestamp when this entry was created."
},
"updatedAt": {
"type": "string",
"format": "datetime",
"description": "Client-declared timestamp when this entry was last updated."
}
}
}
}
}
}
77 changes: 77 additions & 0 deletions community/lexicon/app/profile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
"lexicon": 1,
"id": "community.lexicon.app.profile",
"defs": {
"main": {
"type": "record",
"description": "The canonical self-published profile for an app built on or for the AT Protocol.",
"key": "literal:self",
"record": {
"type": "object",
"required": ["name", "links", "createdAt"],
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"maxGraphemes": 100,
"description": "The display name of the app."
},
"description": {
"type": "string",
"maxLength": 3000,
"maxGraphemes": 300,
"description": "A short description of what the app does."
},
"images": {
"type": "array",
"maxLength": 12,
"description": "Visual assets for directories and stores, such as icons, hero images, screenshots, banners, and social cards.",
"items": {
"type": "ref",
"ref": "community.lexicon.app.defs#image"
}
},
"tags": {
"type": "array",
"maxLength": 10,
"items": {
"type": "string",
"maxLength": 64,
"maxGraphemes": 32
},
"description": "Open discovery tags for filtering and search, preferably lowercase."
},
"status": {
"type": "ref",
"ref": "community.lexicon.app.defs#status",
"description": "Current release or maintenance status of the app."
},
"links": {
"type": "array",
"maxLength": 12,
"description": "Relevant destinations for the app. The first link should be the primary destination.",
"items": {
"type": "ref",
"ref": "community.lexicon.app.defs#link"
}
},
Comment thread
pixeline marked this conversation as resolved.
"webManifestUri": {
"type": "string",
"format": "uri",
"description": "URI of a Web App Manifest for richer install and directory metadata, such as icons and screenshots."
},
"createdAt": {
"type": "string",
"format": "datetime",
"description": "Client-declared timestamp when this profile was created."
},
"updatedAt": {
"type": "string",
"format": "datetime",
"description": "Client-declared timestamp when this profile was last updated."
}
}
}
}
}
}
Loading