Your music, beautifully tracked. All yours. (coming soon) teal.fm
teal-fm atproto
README.md

Lexicon CLI Tool #

A unified command-line tool for managing AT Protocol lexicons across TypeScript and Rust codegen in the Teal monorepo.

Features #

  • Unified Generation: Generate both TypeScript and Rust types from lexicons with a single command
  • Auto-installation: Automatically installs required dependencies (jacquard-lexicon) when needed
  • File Watching: Watch lexicon files for changes and auto-regenerate types
  • Cross-language Validation: Validate consistency between TypeScript and Rust generated types
  • Diff Analysis: Show impact of lexicon changes on generated code

Installation #

The tool is automatically available in the workspace. Install dependencies:

pnpm install

Commands #

Generate Types #

Generate both TypeScript and Rust types from lexicons:

# Generate all types
pnpm lex:gen

# Generate only TypeScript types
lex gen --ts-only

# Generate only Rust types  
lex gen --rust-only

# Force regeneration even if no changes detected
lex gen --force

Watch for Changes #

Automatically regenerate types when lexicon files change:

# Watch all lexicon files
pnpm lex:watch

# Watch only for TypeScript generation
lex watch --ts-only

# Watch only for Rust generation
lex watch --rust-only

Validate Types #

Validate that generated types are consistent and up-to-date:

pnpm lex:validate

Show Changes #

Display lexicon and generated type changes:

# Show changes since last commit
pnpm lex:diff

# Show changes since specific commit
lex diff HEAD~3

How It Works #

TypeScript Generation #

  • Uses the workspace lexicon script, whose schema validation is powered by @atproto/lex
  • Keeps the legacy server binding step isolated in packages/lexicons until Aqua migrates its XRPC bindings
  • Sources lexicons from packages/lexicons/real/
  • Outputs to packages/lexicons/src/types/

Rust Generation #

  • Uses jacquard-codegen for Rust code generation
  • Sources lexicons from services/types/lexicons/
  • Outputs to services/types/src/
  • Auto-installs jacquard-lexicon if not present (tries cargo-binstall first for speed)

File Watching #

  • Monitors both lexicon source directories
  • Debounces changes to avoid multiple regenerations
  • Shows clear feedback about what changed

Integration with Build System #

The tool integrates with the existing Turbo build pipeline:

  • lex:gen-server - Legacy TypeScript-only generation (kept for compatibility)
  • lex:gen - New unified generation command
  • lex:watch - File watching for development
  • lex:validate - Type validation

Lexicon Sources #

Teal Lexicons (fm.teal.*) #

  • Actor: Profile management, status tracking, search
  • Feed: Music play tracking, artist/track data
  • Stats: Top artists, releases, user statistics

External Protocol Support #

  • Bluesky (app.bsky.*): Full AT Protocol compatibility
  • Statusphere (xyz.statusphere.*): Status sharing
  • AT Protocol Core (com.atproto.*): Authentication, repositories, admin

Developer Workflow #

  1. Making Lexicon Changes: Edit files in packages/lexicons/real/ or services/types/lexicons/
  2. Regenerate Types: Run pnpm lex:gen or use pnpm lex:watch during development
  3. Validate Changes: Run pnpm lex:validate to check consistency
  4. Review Impact: Use pnpm lex:diff to see what changed

Troubleshooting #

jacquard-lexicon Installation Issues #

If automatic installation fails:

cargo install jacquard-lexicon

For faster installation, consider using cargo-binstall:

cargo install cargo-binstall
cargo binstall jacquard-lexicon

Type Generation Failures #

  • Ensure lexicon JSON files are valid
  • Check that both TypeScript and Rust lexicon directories exist
  • Verify file permissions for output directories

Watch Mode Issues #

  • File watching uses chokidar for cross-platform compatibility
  • If changes aren't detected, try restarting the watcher
  • Large numbers of files may cause performance issues

Configuration #

The tool automatically detects the workspace structure using:

  • pnpm-workspace.yaml for workspace root detection
  • Package structure for TypeScript and Rust paths
  • Git for diff operations

No additional configuration is required.