# atBB Monorepo **atBB** is a decentralized BB-style forum built on the AT Protocol. Users own their posts on their own PDS; the forum's AppView indexes and serves them. Lexicon namespace: `space.atbb.*` (domain `atbb.space` is owned). License: AGPL-3.0. The master project plan with MVP phases and progress tracking lives at `docs/atproto-forum-plan.md`. ## Packages | Package | Description | Port | |---------|-------------|------| | `@atbb/lexicon` | AT Proto lexicon definitions (YAML) + generated TypeScript types | — | | `@atbb/appview` | Hono JSON API server — indexes forum data, serves API | 3000 | | `@atbb/web` | Hono JSX + HTMX server-rendered web UI — calls appview API | 3001 | | `@atbb/spike` | PDS read/write test script for validating AT Proto operations | — | **Dependency chain:** `@atbb/lexicon` builds first (generates types), then `@atbb/appview` and `@atbb/web` build in parallel. Turbo handles this via `^build`. ## Development ### Setup ```sh devenv shell # enter Nix dev shell (Node.js, pnpm, turbo) pnpm install # install all workspace dependencies cp .env.example .env # configure environment variables ``` ### Commands ```sh pnpm build # build all packages (lexicon → appview + web) pnpm dev # start all dev servers with hot reload pnpm clean # remove all dist/ directories devenv up # start appview + web servers via process manager pnpm --filter @atbb/appview dev # run a single package pnpm --filter @atbb/spike spike # run the PDS spike script ``` ### Environment Variables See `.env.example`. Key variables: - `PORT` — server port (appview: 3000, web: 3001) - `FORUM_DID` — the forum's AT Proto DID - `PDS_URL` — URL of the forum's PDS - `APPVIEW_URL` — URL the web package uses to reach the appview API - `FORUM_HANDLE`, `FORUM_PASSWORD` — forum service account credentials (for spike/writes) ## Lexicon Conventions - **Source of truth is YAML** in `packages/lexicon/lexicons/`. Never edit generated JSON or TypeScript. - **Build pipeline:** YAML → JSON (`scripts/build.ts`) → TypeScript (`@atproto/lex-cli gen-api`). - **Adding a new lexicon:** Create a `.yaml` file under `lexicons/space/atbb/`, run `pnpm --filter @atbb/lexicon build`. - **Record keys:** Use `key: tid` for collections (multiple records per repo). Use `key: literal:self` for singletons. - **References:** Use `com.atproto.repo.strongRef` wrapped in named defs (e.g., `forumRef`, `subjectRef`). - **Extensible fields:** Use `knownValues` (not `enum`) for strings that may grow (permissions, reaction types, mod actions). - **Record ownership:** - Forum DID owns: `forum.forum`, `forum.category`, `forum.role`, `modAction` - User DID owns: `post`, `membership`, `reaction` ## AT Protocol Conventions - **Unified post model:** There is no separate "topic" type. A `space.atbb.post` without a `reply` ref is a topic starter; one with a `reply` ref is a reply. - **Reply chains:** `replyRef` has both `root` (thread starter) and `parent` (direct parent) — same pattern as `app.bsky.feed.post`. - **MVP trust model:** The AppView holds the Forum DID's signing keys directly and writes forum-level records on behalf of admins/mods after verifying their role. This will be replaced by AT Protocol privilege delegation post-MVP. ## TypeScript / Hono Gotchas - **`@types/node` is required** as a devDependency in every package that uses `process.env` or other Node APIs. `tsx` doesn't need it at runtime, but `tsc` builds will fail without it. - **Hono JSX `children`:** Use `PropsWithChildren` from `hono/jsx` for components that accept children. Unlike React, Hono's `FC` does not include `children` implicitly. - **HTMX attributes in JSX:** The `typed-htmx` package provides types for `hx-*` attributes. See `packages/web/src/global.d.ts` for the augmentation. - **Glob expansion in npm scripts:** `@atproto/lex-cli` needs file paths, not globs. Use `bash -c 'shopt -s globstar && ...'` to expand `**/*.json` in npm scripts. - **`.env` loading:** Dev and spike scripts use Node's `--env-file=../../.env` flag to load the root `.env` file. No `dotenv` dependency needed. ## Git Conventions - Do not include `Co-Authored-By` lines in commit messages. - `prior-art/` contains git submodules (Rust AppView, original lexicons, delegation spec) — reference material only, not used at build time. - Worktrees with submodules need `submodule deinit --all -f` then `worktree remove --force` to clean up.