···11+#!/usr/bin/env bash
22+33+export DIRENV_WARN_TIMEOUT=20s
44+55+eval "$(devenv direnvrc)"
66+77+# `use devenv` supports the same options as the `devenv shell` command.
88+#
99+# To silence all output, use `--quiet`.
1010+#
1111+# Example usage: use devenv --quiet --impure --option services.postgres.enable:bool true
1212+use devenv
···11+MIT License
22+33+Copyright (c) 2025 Vince Hodges
44+55+Permission is hereby granted, free of charge, to any person obtaining a copy
66+of this software and associated documentation files (the "Software"), to deal
77+in the Software without restriction, including without limitation the rights
88+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99+copies of the Software, and to permit persons to whom the Software is
1010+furnished to do so, subject to the following conditions:
1111+1212+The above copyright notice and this permission notice shall be included in all
1313+copies or substantial portions of the Software.
1414+1515+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1616+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1717+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121+SOFTWARE.
+47
README.md
···11+# Bragsheet.social
22+Shared lexicon schemas for Bragsheet.social
33+44+## Overview
55+66+This repository contains the official lexicon definitions for [bragsheet.social](https://bragsheet.social/). These schemas enable content discovery, indexing, and portability across the decentralized AT Protocol network.
77+88+One schema. Every platform.
99+1010+## Installation
1111+1212+```bash
1313+bun install
1414+```
1515+1616+## Usage
1717+1818+```bash
1919+bun run lexicon:emit # Generate JSON schemas from TypeScript
2020+bun run lexicon:import # Generate TypeScript from JSON schemas
2121+```
2222+2323+## Project Structure
2424+2525+```
2626+/
2727+├── src/
2828+│ └── lexicons/ # TypeScript lexicon definitions (source)
2929+│ ├── social.bragsheet.entry.ts
3030+└── out/ # Generated JSON schemas
3131+ ├── social.bragsheet.entry.json
3232+```
3333+3434+## Resources
3535+3636+- [Bragsheet.social](https://bragsheet.social/) - The app
3737+- [AT Protocol](https://atproto.com/) - The underlying protocol
3838+- [Lexicon Documentation](https://atproto.com/specs/lexicon) - AT Protocol lexicon spec
3939+- [Prototypey](https://github.com/tylersayshi/prototypey) - AT Protocol lexicon typescript toolkit
4040+4141+## License
4242+4343+This project is open-source software licensed under the [MIT license](LICENSE).
4444+4545+---
4646+4747+**Designed for the ATmosphere**
···11+# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json
22+inputs:
33+ nixpkgs:
44+ url: github:cachix/devenv-nixpkgs/rolling
55+66+# If you're using non-OSS software, you can set allowUnfree to true.
77+allowUnfree: true
88+# If you're willing to use a package that's vulnerable
99+# permittedInsecurePackages:
1010+# - "openssl-1.1.1w"
1111+1212+# If you have more than one devenv you can merge them
1313+#imports:
1414+# - ./backend
···11+import { lx } from "prototypey";
22+import { MB } from "../constants.ts";
33+44+export const socialBragsheetEntry = lx.lexicon("social.bragsheet.entry", {
55+ main: lx.record({
66+ key: "tid",
77+ type: "record",
88+ record: lx.object({
99+ title: lx.string({
1010+ required: true,
1111+ maxLength: 5000,
1212+ maxGraphemes: 500,
1313+ description: "Title of the entry.",
1414+ }),
1515+ content: lx.string({
1616+ required: true,
1717+ maxLength: 50000,
1818+ maxGraphemes: 5000,
1919+ description: "The body of the entry.",
2020+ }),
2121+ rangeStart: lx.string({
2222+ format: "datetime",
2323+ description:
2424+ "Timestamp representing the beginning of the timeframe for this entry.",
2525+ }),
2626+ rangeEnd: lx.string({
2727+ format: "datetime",
2828+ description:
2929+ "Timestamp representing the end of the timeframe for this entry.",
3030+ }),
3131+ publishedAt: lx.string({
3232+ required: true,
3333+ format: "datetime",
3434+ description: "Timestamp of the entry's publish time.",
3535+ }),
3636+ updatedAt: lx.string({
3737+ format: "datetime",
3838+ description: "Timestamp of the entry's last edit.",
3939+ }),
4040+ }),
4141+ description:
4242+ "A document record representing a published article, blog post, or other content. Documents can belong to a publication or exist independently.",
4343+ }),
4444+});