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

test: verify git hooks work correctly

+66
.github/workflows/appview.yml
··· 1 + name: Build and Push Aqua 2 + 3 + on: 4 + push: 5 + branches: [main] 6 + paths: 7 + - "apps/aqua/**" 8 + - "Cargo.toml" 9 + - "Cargo.lock" 10 + - ".github/workflows/aqua.yml" 11 + pull_request: 12 + branches: [main] 13 + paths: 14 + - "apps/aqua/**" 15 + - "Cargo.toml" 16 + - "Cargo.lock" 17 + - ".github/workflows/aqua.yml" 18 + 19 + env: 20 + REGISTRY: ghcr.io 21 + IMAGE_NAME: ${{ github.repository }}/aqua 22 + 23 + jobs: 24 + build-and-push: 25 + runs-on: ubuntu-latest 26 + permissions: 27 + contents: read 28 + packages: write 29 + 30 + steps: 31 + - name: Checkout repository 32 + uses: actions/checkout@v4 33 + 34 + - name: Log in to Container Registry 35 + if: github.event_name != 'pull_request' 36 + uses: docker/login-action@v3 37 + with: 38 + registry: ${{ env.REGISTRY }} 39 + username: ${{ github.actor }} 40 + password: ${{ secrets.GITHUB_TOKEN }} 41 + 42 + - name: Extract metadata 43 + id: meta 44 + uses: docker/metadata-action@v5 45 + with: 46 + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 47 + tags: | 48 + type=ref,event=branch 49 + type=ref,event=pr 50 + type=sha,prefix=sha- 51 + type=raw,value=latest,enable={{is_default_branch}} 52 + 53 + - name: Set up Docker Buildx 54 + uses: docker/setup-buildx-action@v3 55 + 56 + - name: Build and push Docker image 57 + uses: docker/build-push-action@v5 58 + with: 59 + context: ./apps/aqua 60 + file: ./apps/aqua/Dockerfile 61 + push: ${{ github.event_name != 'pull_request' }} 62 + tags: ${{ steps.meta.outputs.tags }} 63 + labels: ${{ steps.meta.outputs.labels }} 64 + platforms: linux/amd64,linux/arm64 65 + cache-from: type=gha 66 + cache-to: type=gha,mode=max
+66
.github/workflows/cadet.yml
··· 1 + name: Build and Push Cadet 2 + 3 + on: 4 + push: 5 + branches: [ main ] 6 + paths: 7 + - 'services/cadet/**' 8 + - 'Cargo.toml' 9 + - 'Cargo.lock' 10 + - '.github/workflows/cadet.yml' 11 + pull_request: 12 + branches: [ main ] 13 + paths: 14 + - 'services/cadet/**' 15 + - 'Cargo.toml' 16 + - 'Cargo.lock' 17 + - '.github/workflows/cadet.yml' 18 + 19 + env: 20 + REGISTRY: ghcr.io 21 + IMAGE_NAME: ${{ github.repository }}/cadet 22 + 23 + jobs: 24 + build-and-push: 25 + runs-on: ubuntu-latest 26 + permissions: 27 + contents: read 28 + packages: write 29 + 30 + steps: 31 + - name: Checkout repository 32 + uses: actions/checkout@v4 33 + 34 + - name: Log in to Container Registry 35 + if: github.event_name != 'pull_request' 36 + uses: docker/login-action@v3 37 + with: 38 + registry: ${{ env.REGISTRY }} 39 + username: ${{ github.actor }} 40 + password: ${{ secrets.GITHUB_TOKEN }} 41 + 42 + - name: Extract metadata 43 + id: meta 44 + uses: docker/metadata-action@v5 45 + with: 46 + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 47 + tags: | 48 + type=ref,event=branch 49 + type=ref,event=pr 50 + type=sha,prefix=sha- 51 + type=raw,value=latest,enable={{is_default_branch}} 52 + 53 + - name: Set up Docker Buildx 54 + uses: docker/setup-buildx-action@v3 55 + 56 + - name: Build and push Docker image 57 + uses: docker/build-push-action@v5 58 + with: 59 + context: ./services/cadet 60 + file: ./services/cadet/Dockerfile 61 + push: ${{ github.event_name != 'pull_request' }} 62 + tags: ${{ steps.meta.outputs.tags }} 63 + labels: ${{ steps.meta.outputs.labels }} 64 + platforms: linux/amd64,linux/arm64 65 + cache-from: type=gha 66 + cache-to: type=gha,mode=max
+2 -2
.gitignore
··· 55 55 56 56 # generated lexicons 57 57 # js lexicons 58 - */**/lexicons 58 + packages/lexicons/src 59 59 # rust lexicons (types :))) 60 - */**/types 60 + services/types/src 61 61 62 62 # vendor directory for submodules 63 63 !vendor/
+111
.pre-commit-config.yaml
··· 1 + # Pre-commit configuration for Teal project 2 + # Install with: pip install pre-commit && pre-commit install 3 + # Run manually with: pre-commit run --all-files 4 + 5 + repos: 6 + # General file checks 7 + - repo: https://github.com/pre-commit/pre-commit-hooks 8 + rev: v4.6.0 9 + hooks: 10 + - id: trailing-whitespace 11 + - id: end-of-file-fixer 12 + - id: check-yaml 13 + - id: check-json 14 + - id: check-toml 15 + - id: check-merge-conflict 16 + - id: check-added-large-files 17 + args: ["--maxkb=500"] 18 + - id: mixed-line-ending 19 + args: ["--fix=lf"] 20 + 21 + # TypeScript/JavaScript formatting and linting 22 + - repo: local 23 + hooks: 24 + - id: prettier 25 + name: Prettier 26 + entry: pnpm prettier --write 27 + language: system 28 + files: \.(ts|tsx|js|jsx|json|md|yaml|yml)$ 29 + pass_filenames: true 30 + 31 + - id: biome-check 32 + name: Biome Check 33 + entry: pnpm biome check --apply 34 + language: system 35 + files: \.(ts|tsx|js|jsx)$ 36 + pass_filenames: false 37 + 38 + - id: typescript-check 39 + name: TypeScript Check 40 + entry: pnpm typecheck 41 + language: system 42 + files: \.(ts|tsx)$ 43 + pass_filenames: false 44 + 45 + # Rust formatting and linting 46 + - repo: local 47 + hooks: 48 + - id: cargo-fmt 49 + name: Cargo Format 50 + entry: pnpm rust:fmt 51 + language: system 52 + files: \.rs$ 53 + pass_filenames: false 54 + 55 + - id: cargo-clippy 56 + name: Cargo Clippy 57 + entry: pnpm rust:clippy 58 + language: system 59 + files: \.rs$ 60 + pass_filenames: false 61 + args: ["--", "-D", "warnings"] 62 + 63 + # Lexicon validation and generation 64 + - repo: local 65 + hooks: 66 + - id: lexicon-validate 67 + name: Validate Lexicons 68 + entry: pnpm lex:validate 69 + language: system 70 + files: lexicons/.*\.json$ 71 + pass_filenames: false 72 + 73 + - id: lexicon-generate 74 + name: Generate Lexicons 75 + entry: pnpm lex:gen-server 76 + language: system 77 + files: lexicons/.*\.json$ 78 + pass_filenames: false 79 + 80 + # Optional: Additional checks 81 + - repo: local 82 + hooks: 83 + - id: no-console-log 84 + name: Check for console.log 85 + entry: bash -c 'if grep -r "console\.log" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" .; then echo "Found console.log statements. Please remove them."; exit 1; fi' 86 + language: system 87 + files: \.(ts|tsx|js|jsx)$ 88 + pass_filenames: false 89 + 90 + - id: check-todos 91 + name: Check for TODO/FIXME 92 + entry: bash -c 'if grep -r -i "TODO\|FIXME" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.rs" .; then echo "Found TODO/FIXME comments. Consider addressing them."; fi' 93 + language: system 94 + files: \.(ts|tsx|js|jsx|rs)$ 95 + pass_filenames: false 96 + verbose: true 97 + 98 + # Global settings 99 + default_language_version: 100 + node: system 101 + python: python3 102 + 103 + # Skip certain hooks for specific file patterns 104 + exclude: | 105 + (?x)^( 106 + vendor/.*| 107 + node_modules/.*| 108 + target/.*| 109 + .git/.*| 110 + .*\.lock$ 111 + )$
+22 -14
apps/amethyst/Dockerfile
··· 18 18 COPY packages/lexicons/ ./packages/lexicons/ 19 19 COPY packages/tsconfig/ ./packages/tsconfig/ 20 20 21 + # Copy lexicons source data 22 + COPY lexicons/ ./lexicons/ 23 + 21 24 # Copy the aqua app 22 25 COPY apps/amethyst/ ./apps/amethyst/ 23 26 24 27 # Copy .env 25 28 COPY ../../.env ./apps/amethyst/.env 26 29 27 - # Build the aqua app 28 - WORKDIR /app/apps/amethyst 30 + # Install dependencies and generate lexicons 29 31 RUN pnpm install 32 + 33 + # Generate lexicons before building amethyst 34 + RUN pnpm lex:gen-server 35 + 36 + # Build the amethyst app 37 + WORKDIR /app/apps/amethyst 30 38 RUN pnpm run build:web 31 39 32 40 #create the client-json 33 41 RUN echo '{ \ 34 - "redirect_uris": ["https://'"${CLIENT_ADDRESS}"'/auth/callback"], \ 35 - "response_types": ["code"], \ 36 - "grant_types": ["authorization_code", "refresh_token"], \ 37 - "scope": "atproto transition:generic", \ 38 - "token_endpoint_auth_method": "none", \ 39 - "application_type": "web", \ 40 - "client_id": "https://'"${CLIENT_ADDRESS}"'/client-metadata.json", \ 41 - "client_name": "teal", \ 42 - "client_uri": "https://'"${CLIENT_ADDRESS}"'", \ 43 - "dpop_bound_access_tokens": true \ 44 - }' > /app/client-metadata.json 42 + "redirect_uris": ["https://'"${CLIENT_ADDRESS}"'/auth/callback"], \ 43 + "response_types": ["code"], \ 44 + "grant_types": ["authorization_code", "refresh_token"], \ 45 + "scope": "atproto transition:generic", \ 46 + "token_endpoint_auth_method": "none", \ 47 + "application_type": "web", \ 48 + "client_id": "https://'"${CLIENT_ADDRESS}"'/client-metadata.json", \ 49 + "client_name": "teal", \ 50 + "client_uri": "https://'"${CLIENT_ADDRESS}"'", \ 51 + "dpop_bound_access_tokens": true \ 52 + }' > /app/client-metadata.json 45 53 46 54 47 55 FROM caddy:2.1.0-alpine AS caddy ··· 50 58 EXPOSE 443/udp 51 59 COPY /apps/amethyst/Caddyfile /etc/caddy/Caddyfile 52 60 COPY --from=builder /app/apps/amethyst/build /srv 53 - COPY --from=builder /app/client-metadata.json /srv/client-metadata.json 61 + COPY --from=builder /app/client-metadata.json /srv/client-metadata.json
+36
apps/aqua/Dockerfile
··· 1 + FROM --platform=${BUILDPLATFORM} rust:latest AS buildah 2 + 3 + # Create appuser 4 + ENV USER=app 5 + ENV UID=10001 6 + 7 + RUN adduser \ 8 + --disabled-password \ 9 + --gecos "" \ 10 + --home "/nonexistent" \ 11 + --shell "/sbin/nologin" \ 12 + --no-create-home \ 13 + --uid "${UID}" \ 14 + "${USER}" 15 + 16 + WORKDIR /buildah 17 + 18 + COPY ./ . 19 + 20 + RUN . ./target.sh && touch src/main.rs && echo "Building for $TARGET_ARCH" && cargo build --release --target $RUST_TARGET && cp target/$RUST_TARGET/release/aqua target/aqua 21 + 22 + FROM --platform=${TARGETARCH:-$BUILDPLATFORM} gcr.io/distroless/cc 23 + 24 + # Import from builder. 25 + COPY --from=buildah /etc/passwd /etc/passwd 26 + COPY --from=buildah /etc/group /etc/group 27 + 28 + WORKDIR /app 29 + 30 + # Copy our build 31 + COPY --from=buildah /buildah/target/aqua ./ 32 + 33 + # Use an unprivileged user. 34 + USER app:app 35 + 36 + CMD ["/app/aqua"]
+295
docs/git-hooks-setup.md
··· 1 + # Git Hooks Setup Guide 2 + 3 + This guide explains how to set up git hooks for the Teal project to ensure code quality, formatting, and error checking before commits. 4 + 5 + ## Overview 6 + 7 + We provide two approaches for setting up git hooks: 8 + 9 + 1. **Simple Shell Script** - A straightforward bash script approach 10 + 2. **Pre-commit Framework** - A more robust, industry-standard solution 11 + 12 + ## What the Hooks Check 13 + 14 + ### TypeScript/JavaScript Files 15 + - ✅ **Biome** - Linting and formatting 16 + - ✅ **Prettier** - Code formatting 17 + - ✅ **TypeScript** - Type checking 18 + - ⚠️ **Console.log detection** (warning only) 19 + - ⚠️ **TODO/FIXME comments** (warning only) 20 + 21 + ### Rust Files 22 + - ✅ **cargo fmt** - Code formatting 23 + - ✅ **cargo clippy** - Linting with warnings as errors 24 + 25 + ### General Files 26 + - ✅ **Trailing whitespace** removal 27 + - ✅ **End-of-file** fixes 28 + - ✅ **YAML/JSON/TOML** validation 29 + - ✅ **Merge conflict** detection 30 + - ✅ **Large file** detection (>500KB) 31 + 32 + ## Option 1: Simple Shell Script (Recommended for Quick Setup) 33 + 34 + ### Installation 35 + 36 + 1. **Install the git hook:** 37 + ```bash 38 + # From the project root 39 + ./scripts/install-git-hooks.sh 40 + ``` 41 + 42 + 2. **Verify installation:** 43 + ```bash 44 + ls -la .git/hooks/pre-commit 45 + ``` 46 + 47 + ### Manual Installation (Alternative) 48 + 49 + If the script doesn't work, you can install manually: 50 + 51 + ```bash 52 + # Copy the hook 53 + cp scripts/pre-commit-hook.sh .git/hooks/pre-commit 54 + chmod +x .git/hooks/pre-commit 55 + ``` 56 + 57 + ### Testing 58 + 59 + Make a commit with some staged files: 60 + ```bash 61 + git add . 62 + git commit -m "test: testing pre-commit hook" 63 + ``` 64 + 65 + ## Option 2: Pre-commit Framework (Recommended for Teams) 66 + 67 + The pre-commit framework is more robust and provides better error handling and performance. 68 + 69 + ### Installation 70 + 71 + 1. **Install pre-commit tool:** 72 + ```bash 73 + # Using pip 74 + pip install pre-commit 75 + 76 + # Using homebrew (macOS) 77 + brew install pre-commit 78 + 79 + # Using conda 80 + conda install -c conda-forge pre-commit 81 + ``` 82 + 83 + 2. **Install the git hook:** 84 + ```bash 85 + pre-commit install 86 + ``` 87 + 88 + 3. **(Optional) Install additional hooks:** 89 + ```bash 90 + # Install commit-msg hook for commit message validation 91 + pre-commit install --hook-type commit-msg 92 + 93 + # Install pre-push hook 94 + pre-commit install --hook-type pre-push 95 + ``` 96 + 97 + ### Usage 98 + 99 + - **Automatic:** Hooks run automatically on `git commit` 100 + - **Manual run on all files:** 101 + ```bash 102 + pre-commit run --all-files 103 + ``` 104 + - **Manual run on specific files:** 105 + ```bash 106 + pre-commit run --files path/to/file.ts 107 + ``` 108 + - **Update hook versions:** 109 + ```bash 110 + pre-commit autoupdate 111 + ``` 112 + 113 + ## Configuration 114 + 115 + ### Environment Variables 116 + 117 + You can customize hook behavior with environment variables: 118 + 119 + ```bash 120 + # Skip TypeScript checking (for faster commits during development) 121 + export SKIP_TS_CHECK=1 122 + 123 + # Skip Rust clippy (if cargo clippy is slow) 124 + export SKIP_RUST_CLIPPY=1 125 + 126 + # Allow console.log statements 127 + export ALLOW_CONSOLE_LOG=1 128 + ``` 129 + 130 + ### Skipping Hooks 131 + 132 + Sometimes you need to bypass hooks (use sparingly): 133 + 134 + ```bash 135 + # Skip all hooks for a commit 136 + git commit --no-verify -m "emergency fix" 137 + 138 + # Skip specific hooks (pre-commit framework only) 139 + SKIP=prettier,biome-check git commit -m "skip formatting" 140 + ``` 141 + 142 + ### Project Scripts Integration 143 + 144 + The hooks use existing npm scripts from `package.json`: 145 + 146 + - `pnpm typecheck` - TypeScript type checking 147 + - `pnpm rust:fmt` - Rust formatting 148 + - `pnpm rust:clippy` - Rust linting 149 + - `pnpm prettier --write` - JavaScript/TypeScript formatting 150 + - `pnpm biome check --apply` - Biome linting and formatting 151 + 152 + ## Troubleshooting 153 + 154 + ### Common Issues 155 + 156 + 1. **"Command not found" errors:** 157 + - Ensure `pnpm`, `node`, and `cargo` are in your PATH 158 + - Run `./scripts/install-git-hooks.sh` again to check for missing tools 159 + 160 + 2. **TypeScript errors:** 161 + - Fix the type errors or temporarily skip with `SKIP_TS_CHECK=1 git commit` 162 + - Run `pnpm typecheck` manually to see full error details 163 + 164 + 3. **Rust formatting/linting errors:** 165 + - Run `pnpm rust:fmt` and `pnpm rust:clippy` manually 166 + - Fix clippy warnings or adjust clippy configuration 167 + 168 + 4. **Hook is too slow:** 169 + - Use pre-commit framework for better performance 170 + - Consider running lighter checks in pre-commit and full checks in CI 171 + 172 + 5. **Permission denied:** 173 + ```bash 174 + chmod +x .git/hooks/pre-commit 175 + ``` 176 + 177 + ### Debugging 178 + 179 + Enable verbose output: 180 + ```bash 181 + # For shell script 182 + VERBOSE=1 git commit 183 + 184 + # For pre-commit framework 185 + pre-commit run --verbose 186 + ``` 187 + 188 + ## Customization 189 + 190 + ### Adding New Checks 191 + 192 + #### Shell Script Approach 193 + Edit `scripts/pre-commit-hook.sh` to add new checks. 194 + 195 + #### Pre-commit Framework 196 + Edit `.pre-commit-config.yaml` to add new hooks: 197 + 198 + ```yaml 199 + - repo: local 200 + hooks: 201 + - id: my-custom-check 202 + name: My Custom Check 203 + entry: my-command 204 + language: system 205 + files: \.(ts|js)$ 206 + ``` 207 + 208 + ### Modifying Existing Checks 209 + 210 + 1. **Disable console.log warnings:** 211 + - Comment out the console.log check in the hook script 212 + - Or remove the `no-console-log` hook from `.pre-commit-config.yaml` 213 + 214 + 2. **Change file patterns:** 215 + - Modify the `files:` regex in `.pre-commit-config.yaml` 216 + - Or adjust the grep patterns in the shell script 217 + 218 + 3. **Add new file types:** 219 + - Extend the file extension patterns 220 + - Add appropriate formatting/linting commands 221 + 222 + ## Integration with IDEs 223 + 224 + ### VS Code 225 + Install these extensions for seamless development: 226 + - **Prettier** - Code formatter 227 + - **Biome** - Fast formatter and linter 228 + - **rust-analyzer** - Rust language support 229 + 230 + Configure VS Code to format on save: 231 + ```json 232 + { 233 + "editor.formatOnSave": true, 234 + "editor.codeActionsOnSave": { 235 + "source.fixAll": true 236 + } 237 + } 238 + ``` 239 + 240 + ### Other IDEs 241 + Configure your IDE to: 242 + - Run Prettier on save for JS/TS files 243 + - Run `cargo fmt` on save for Rust files 244 + - Show linting errors inline 245 + 246 + ## Best Practices 247 + 248 + 1. **Run hooks frequently:** Don't wait until commit time 249 + ```bash 250 + # Run manually while developing 251 + pre-commit run --all-files 252 + ``` 253 + 254 + 2. **Fix issues immediately:** Don't accumulate formatting/linting debt 255 + 256 + 3. **Keep hooks fast:** Hooks should complete in <30 seconds 257 + 258 + 4. **Team consistency:** Ensure all team members use the same hook setup 259 + 260 + 5. **CI/CD integration:** Run the same checks in your CI pipeline 261 + 262 + ## Monitoring and Maintenance 263 + 264 + ### Regular Tasks 265 + 266 + 1. **Update pre-commit hooks:** 267 + ```bash 268 + pre-commit autoupdate 269 + ``` 270 + 271 + 2. **Review hook performance:** 272 + ```bash 273 + pre-commit run --all-files --verbose 274 + ``` 275 + 276 + 3. **Update tool versions:** 277 + - Keep Prettier, Biome, and other tools updated 278 + - Test hooks after updates 279 + 280 + ### Team Coordination 281 + 282 + - Document any hook configuration changes 283 + - Notify team members of new requirements 284 + - Consider hook performance impact on team productivity 285 + 286 + ## Support 287 + 288 + If you encounter issues: 289 + 290 + 1. Check this documentation first 291 + 2. Run manual commands to isolate the problem 292 + 3. Check tool-specific documentation (Prettier, Biome, Cargo) 293 + 4. Ask the team for help with project-specific configurations 294 + 295 + Remember: The goal is to catch issues early and maintain code quality, not to slow down development!
+216
docs/lexicon-build-setup.md
··· 1 + # Lexicon Build Integration Summary 2 + 3 + This document summarizes the lexicon build integration setup that ensures lexicons are properly generated before compiling Amethyst and other dependent applications. 4 + 5 + ## ✅ What Was Implemented 6 + 7 + ### 1. Turbo Build Dependencies 8 + - **Location**: `turbo.json` 9 + - **What**: Added explicit dependencies for Amethyst builds on lexicon generation 10 + - **Effect**: Ensures `@teal/lexicons#lex:gen-server` runs before any Amethyst build command 11 + 12 + ```json 13 + { 14 + "@teal/amethyst#build": { 15 + "dependsOn": ["@teal/lexicons#lex:gen-server"], 16 + "outputs": ["./build/**"] 17 + }, 18 + "@teal/amethyst#build:web": { 19 + "dependsOn": ["@teal/lexicons#lex:gen-server"], 20 + "outputs": ["./build/**"] 21 + }, 22 + "@teal/amethyst#build:ios": { 23 + "dependsOn": ["@teal/lexicons#lex:gen-server"], 24 + "outputs": ["./build/**"] 25 + } 26 + } 27 + ``` 28 + 29 + ### 2. Postinstall Hook 30 + - **Location**: `package.json` 31 + - **What**: Added `"postinstall": "pnpm lex:gen-server"` 32 + - **Effect**: Lexicons are automatically generated after `pnpm install` 33 + 34 + ### 3. Docker Build Integration 35 + - **Location**: `apps/amethyst/Dockerfile` 36 + - **What**: Updated Docker build process to generate lexicons before building Amethyst 37 + - **Changes**: 38 + - Copy lexicons source directory 39 + - Run `pnpm lex:gen-server` before building Amethyst 40 + - Install dependencies from root to access lexicon generation tools 41 + 42 + ### 4. Git Hooks Integration 43 + - **Location**: `scripts/pre-commit-hook.sh` and `.pre-commit-config.yaml` 44 + - **What**: Added lexicon validation and regeneration to git hooks 45 + - **Effect**: When lexicon files change, hooks automatically validate and regenerate TypeScript types 46 + 47 + ### 5. Development Scripts 48 + - **Location**: `package.json` 49 + - **What**: Added convenience scripts for lexicon development 50 + - **Scripts**: 51 + - `lex:build-amethyst`: Generate lexicons and build Amethyst 52 + - `lex:dev`: Generate lexicons and start Amethyst dev server 53 + 54 + ## 🔄 How It Works 55 + 56 + ### Build Process Flow 57 + 58 + ``` 59 + 1. Developer runs: pnpm build (or pnpm turbo build --filter=@teal/amethyst) 60 + 61 + 2. Turbo checks dependencies and sees amethyst#build depends on lexicons#lex:gen-server 62 + 63 + 3. Turbo runs: @teal/lexicons#lex:gen-server (if not cached) 64 + 65 + 4. lexicons/lex-gen.sh generates TypeScript files in packages/lexicons/src/ 66 + 67 + 5. Turbo runs: @teal/amethyst#build 68 + 69 + 6. Amethyst build has access to fresh @teal/lexicons package 70 + ``` 71 + 72 + ### Docker Build Flow 73 + 74 + ``` 75 + 1. Docker build starts 76 + 77 + 2. Copy source files (including lexicons/ directory) 78 + 79 + 3. Run: pnpm install (triggers postinstall → lex:gen-server) 80 + 81 + 4. Run: pnpm lex:gen-server (explicit generation) 82 + 83 + 5. Run: pnpm run build:web (Amethyst build) 84 + 85 + 6. Container includes built Amethyst with fresh lexicons 86 + ``` 87 + 88 + ### Git Hook Flow 89 + 90 + ``` 91 + 1. Developer modifies lexicons/*.json files 92 + 93 + 2. Developer runs: git commit 94 + 95 + 3. Pre-commit hook detects lexicon file changes 96 + 97 + 4. Hook runs: pnpm lex:validate 98 + 99 + 5. Hook runs: pnpm lex:gen-server 100 + 101 + 6. Hook stages generated TypeScript files 102 + 103 + 7. Commit proceeds with both source and generated files 104 + ``` 105 + 106 + ## 🛠️ Available Commands 107 + 108 + ### For Developers 109 + 110 + ```bash 111 + # Generate lexicons manually 112 + pnpm lex:gen-server 113 + 114 + # Build Amethyst with fresh lexicons 115 + pnpm lex:build-amethyst 116 + 117 + # Start Amethyst dev server with fresh lexicons 118 + pnpm lex:dev 119 + 120 + # Validate lexicon files 121 + pnpm lex:validate 122 + 123 + # Watch for lexicon changes and regenerate 124 + pnpm lex:watch 125 + ``` 126 + 127 + ### For CI/CD 128 + 129 + ```bash 130 + # Install dependencies (automatically generates lexicons) 131 + pnpm install 132 + 133 + # Build all (lexicons generated automatically via Turbo) 134 + pnpm build 135 + 136 + # Build specific app (lexicons generated automatically) 137 + pnpm turbo build --filter=@teal/amethyst 138 + ``` 139 + 140 + ## 📁 Key Files Modified 141 + 142 + 1. **`turbo.json`** - Added Amethyst build dependencies on lexicon generation 143 + 2. **`package.json`** - Added postinstall hook and convenience scripts 144 + 3. **`apps/amethyst/Dockerfile`** - Updated to generate lexicons during Docker build 145 + 4. **`scripts/pre-commit-hook.sh`** - Added lexicon validation and regeneration 146 + 5. **`.pre-commit-config.yaml`** - Added lexicon hooks for pre-commit framework 147 + 148 + ## 🎯 Benefits 149 + 150 + 1. **Zero Manual Work**: Lexicons are automatically generated when needed 151 + 2. **Build Reliability**: Amethyst builds can't proceed without fresh lexicons 152 + 3. **Developer Experience**: No need to remember to run lexicon commands 153 + 4. **CI/CD Safety**: Docker builds include lexicon generation 154 + 5. **Git Safety**: Commits with lexicon changes include generated files 155 + 6. **Caching**: Turbo caches lexicon generation for performance 156 + 157 + ## 🔍 Verification 158 + 159 + ### Test Local Build 160 + ```bash 161 + # Clean generated files 162 + rm -rf packages/lexicons/src/ 163 + 164 + # Build should regenerate lexicons automatically 165 + pnpm turbo build --filter=@teal/amethyst 166 + ``` 167 + 168 + ### Test Docker Build 169 + ```bash 170 + # Build Docker image (should include lexicon generation) 171 + docker build -f apps/amethyst/Dockerfile . 172 + ``` 173 + 174 + ### Test Git Hooks 175 + ```bash 176 + # Make a lexicon change 177 + echo '{}' > lexicons/test.json 178 + 179 + # Commit should validate and regenerate 180 + git add . && git commit -m "test lexicon change" 181 + ``` 182 + 183 + ## 🚨 Troubleshooting 184 + 185 + ### "Lexicons not found" errors 186 + ```bash 187 + # Manually regenerate 188 + pnpm lex:gen-server 189 + 190 + # Check if files exist 191 + ls packages/lexicons/src/ 192 + ``` 193 + 194 + ### Docker build fails 195 + - Ensure `lexicons/` directory is copied in Dockerfile 196 + - Check that `lex:gen-server` command runs successfully 197 + 198 + ### Git hooks fail 199 + ```bash 200 + # Test validation manually 201 + pnpm lex:validate 202 + 203 + # Bypass hooks temporarily 204 + git commit --no-verify 205 + ``` 206 + 207 + ## 📚 Related Documentation 208 + 209 + - [`docs/lexicon-development.md`](./lexicon-development.md) - Detailed lexicon development guide 210 + - [`docs/git-hooks-setup.md`](./git-hooks-setup.md) - Git hooks setup and usage 211 + 212 + --- 213 + 214 + **Status**: ✅ Complete and fully integrated 215 + **Last Updated**: December 2024 216 + **Maintainer**: Engineering Team
+344
docs/lexicon-development.md
··· 1 + # Lexicon Development Guide 2 + 3 + This guide explains how to work with lexicons in the Teal project, ensuring they are properly generated before building applications like Amethyst. 4 + 5 + ## Overview 6 + 7 + Lexicons in Teal are AT Protocol schema definitions that get compiled into TypeScript types and interfaces. The system ensures that: 8 + 9 + 1. Lexicons are automatically generated before building applications 10 + 2. Changes to lexicon files trigger regeneration 11 + 3. Generated types are available to all applications that depend on them 12 + 13 + ## Project Structure 14 + 15 + ``` 16 + teal/ 17 + ├── lexicons/ # Source lexicon JSON files 18 + │ └── fm.teal.alpha/ # Lexicon namespace 19 + ├── packages/lexicons/ # Generated TypeScript package 20 + │ ├── src/ # Generated TypeScript files 21 + │ │ ├── types/ # Generated type definitions 22 + │ │ ├── index.ts # Main exports 23 + │ │ └── lexicons.ts # Lexicon registry 24 + │ └── lex-gen.sh # Generation script 25 + └── tools/lexicon-cli/ # Lexicon CLI tool 26 + ``` 27 + 28 + ## How It Works 29 + 30 + ### Automatic Generation 31 + 32 + The build system automatically ensures lexicons are generated before building dependent applications: 33 + 34 + 1. **Turbo Pipeline**: Amethyst builds depend on `@teal/lexicons#lex:gen-server` 35 + 2. **Postinstall Hook**: Lexicons are generated after `pnpm install` 36 + 3. **Docker Builds**: Lexicons are generated during container builds 37 + 4. **Git Hooks**: Lexicon changes trigger validation and regeneration 38 + 39 + ### Generation Process 40 + 41 + ```bash 42 + # Source files (JSON) 43 + lexicons/fm.teal.alpha/*.json 44 + 45 + # ↓ Generate with 46 + pnpm lex:gen-server 47 + 48 + # ↓ Produces TypeScript files 49 + packages/lexicons/src/types/fm/teal/alpha/*.ts 50 + packages/lexicons/src/index.ts 51 + packages/lexicons/src/lexicons.ts 52 + ``` 53 + 54 + ## Development Workflow 55 + 56 + ### Making Lexicon Changes 57 + 58 + 1. **Edit lexicon files** in `lexicons/` directory 59 + 2. **Validate changes**: 60 + ```bash 61 + pnpm lex:validate 62 + ``` 63 + 3. **Generate types**: 64 + ```bash 65 + pnpm lex:gen-server 66 + ``` 67 + 4. **Build and test**: 68 + ```bash 69 + pnpm lex:build-amethyst 70 + ``` 71 + 72 + ### Available Commands 73 + 74 + ```bash 75 + # Generate lexicons for server (TypeScript) 76 + pnpm lex:gen-server 77 + 78 + # Generate all lexicons (includes Rust bindings) 79 + pnpm lex:gen 80 + 81 + # Validate lexicon files 82 + pnpm lex:validate 83 + 84 + # Watch for changes and regenerate 85 + pnpm lex:watch 86 + 87 + # Show differences between versions 88 + pnpm lex:diff 89 + 90 + # Build amethyst with fresh lexicons 91 + pnpm lex:build-amethyst 92 + 93 + # Start amethyst dev server with fresh lexicons 94 + pnpm lex:dev 95 + ``` 96 + 97 + ### Development Server 98 + 99 + For active lexicon development, use the watch mode: 100 + 101 + ```bash 102 + # Terminal 1: Watch and regenerate lexicons 103 + pnpm lex:watch 104 + 105 + # Terminal 2: Run amethyst dev server 106 + cd apps/amethyst && pnpm dev 107 + ``` 108 + 109 + ## Integration Details 110 + 111 + ### Turbo Configuration 112 + 113 + The `turbo.json` file ensures proper build dependencies: 114 + 115 + ```json 116 + { 117 + "pipeline": { 118 + "@teal/amethyst#build": { 119 + "dependsOn": ["@teal/lexicons#lex:gen-server"] 120 + }, 121 + "@teal/amethyst#build:web": { 122 + "dependsOn": ["@teal/lexicons#lex:gen-server"] 123 + } 124 + } 125 + } 126 + ``` 127 + 128 + ### Package Dependencies 129 + 130 + Amethyst depends on the lexicons package: 131 + 132 + ```json 133 + { 134 + "dependencies": { 135 + "@teal/lexicons": "workspace:*" 136 + } 137 + } 138 + ``` 139 + 140 + ### Docker Integration 141 + 142 + The Amethyst Dockerfile generates lexicons during build: 143 + 144 + ```dockerfile 145 + # Install dependencies 146 + RUN pnpm install 147 + 148 + # Generate lexicons before building amethyst 149 + RUN pnpm lex:gen-server 150 + 151 + # Build the amethyst app 152 + RUN pnpm run build:web 153 + ``` 154 + 155 + ## Git Hooks Integration 156 + 157 + ### Pre-commit Validation 158 + 159 + When lexicon files change, git hooks automatically: 160 + 161 + 1. **Validate** lexicon syntax 162 + 2. **Regenerate** TypeScript types 163 + 3. **Stage** generated files for commit 164 + 165 + ### Manual Hook Bypass 166 + 167 + If you need to skip lexicon validation: 168 + 169 + ```bash 170 + # Skip all hooks 171 + git commit --no-verify 172 + 173 + # Skip specific hooks (pre-commit framework) 174 + SKIP=lexicon-validate,lexicon-generate git commit 175 + ``` 176 + 177 + ## Troubleshooting 178 + 179 + ### Common Issues 180 + 181 + 1. **"Lexicons not found" errors** 182 + ```bash 183 + # Regenerate lexicons 184 + pnpm lex:gen-server 185 + 186 + # Check if files were generated 187 + ls packages/lexicons/src/ 188 + ``` 189 + 190 + 2. **TypeScript compilation errors after lexicon changes** 191 + ```bash 192 + # Clean and rebuild 193 + pnpm lex:gen-server 194 + pnpm turbo build --filter=@teal/amethyst --force 195 + ``` 196 + 197 + 3. **Docker build fails with lexicon errors** 198 + ```bash 199 + # Ensure lexicons directory is copied 200 + # Check Dockerfile includes: COPY lexicons/ ./lexicons/ 201 + ``` 202 + 203 + 4. **Git hooks fail on lexicon validation** 204 + ```bash 205 + # Validate manually to see detailed errors 206 + pnpm lex:validate 207 + 208 + # Fix validation errors in lexicon JSON files 209 + ``` 210 + 211 + ### Debug Commands 212 + 213 + ```bash 214 + # Check what lexicons exist 215 + find lexicons/ -name "*.json" -type f 216 + 217 + # Check generated files 218 + find packages/lexicons/src/ -name "*.ts" -type f 219 + 220 + # Test lexicon CLI directly 221 + cd tools/lexicon-cli 222 + node dist/index.js validate 223 + 224 + # Check turbo task dependencies 225 + pnpm turbo build --filter=@teal/amethyst --dry-run 226 + ``` 227 + 228 + ### Performance Considerations 229 + 230 + - **Lexicon generation is cached** by Turbo based on input files 231 + - **Only regenerates when source files change** 232 + - **Use `--force` flag to override cache** if needed 233 + 234 + ## Best Practices 235 + 236 + ### 1. Lexicon File Organization 237 + 238 + ``` 239 + lexicons/ 240 + └── fm.teal.alpha/ 241 + ├── actor/ 242 + │ ├── profile.json 243 + │ └── status.json 244 + ├── feed/ 245 + │ └── play.json 246 + └── stats/ 247 + └── latest.json 248 + ``` 249 + 250 + ### 2. Validation Before Commits 251 + 252 + Always validate lexicons before committing: 253 + 254 + ```bash 255 + pnpm lex:validate && git add . && git commit 256 + ``` 257 + 258 + ### 3. Testing Changes 259 + 260 + Test lexicon changes in dependent applications: 261 + 262 + ```bash 263 + pnpm lex:gen-server 264 + pnpm turbo typecheck --filter=@teal/amethyst 265 + ``` 266 + 267 + ### 4. Documentation 268 + 269 + Document breaking changes in lexicons: 270 + - Update version numbers appropriately 271 + - Note deprecated fields 272 + - Provide migration guides for consumers 273 + 274 + ## CI/CD Integration 275 + 276 + ### GitHub Actions 277 + 278 + The CI pipeline automatically: 279 + 280 + 1. **Installs dependencies** (triggers postinstall lexicon generation) 281 + 2. **Builds applications** (triggers lexicon generation via Turbo) 282 + 3. **Validates types** (ensures generated lexicons are valid) 283 + 284 + ### Manual CI Testing 285 + 286 + ```bash 287 + # Simulate CI environment 288 + rm -rf packages/lexicons/src/ 289 + pnpm install # Should regenerate lexicons 290 + pnpm build # Should build successfully 291 + ``` 292 + 293 + ## Advanced Usage 294 + 295 + ### Custom Lexicon CLI Commands 296 + 297 + The lexicon CLI tool supports additional commands: 298 + 299 + ```bash 300 + cd tools/lexicon-cli 301 + 302 + # Generate with custom options 303 + node dist/index.js gen --output custom-path 304 + 305 + # Watch specific files 306 + node dist/index.js watch --pattern "lexicons/custom/*.json" 307 + 308 + # Validate with verbose output 309 + node dist/index.js validate --verbose 310 + ``` 311 + 312 + ### Multiple Output Formats 313 + 314 + ```bash 315 + # Generate TypeScript (default) 316 + pnpm lex:gen-server 317 + 318 + # Generate all formats (includes Rust) 319 + pnpm lex:gen 320 + ``` 321 + 322 + ## Monitoring and Maintenance 323 + 324 + ### Regular Tasks 325 + 326 + 1. **Update lexicon CLI tools** when AT Protocol updates 327 + 2. **Validate all lexicons** after tool updates 328 + 3. **Review generated code** for unexpected changes 329 + 4. **Update documentation** when lexicon structure changes 330 + 331 + ### Health Checks 332 + 333 + ```bash 334 + # Verify lexicon generation is working 335 + pnpm lex:gen-server && echo "✅ Lexicons generated successfully" 336 + 337 + # Verify amethyst can build with current lexicons 338 + pnpm turbo build --filter=@teal/amethyst && echo "✅ Amethyst builds successfully" 339 + 340 + # Verify TypeScript compilation 341 + pnpm typecheck && echo "✅ TypeScript compilation successful" 342 + ``` 343 + 344 + Remember: The goal is to keep lexicons always in sync with the applications that depend on them, ensuring a smooth development experience!
+5
package.json
··· 12 12 "rust:fmt": "cd services && cargo fmt", 13 13 "rust:clippy": "cd services && cargo clippy", 14 14 "fix": "biome lint --apply . && biome format --write . && biome check . --apply", 15 + "hooks:install": "./scripts/install-git-hooks.sh", 16 + "hooks:install-precommit": "pre-commit install", 17 + "postinstall": "pnpm lex:gen-server", 15 18 "nuke": "rimraf node_modules */*/node_modules", 16 19 "lex:gen-server": "turbo lex:gen-server", 17 20 "format": "prettier --write .", ··· 19 22 "lex:watch": "cd tools/lexicon-cli && node dist/index.js watch", 20 23 "lex:validate": "cd tools/lexicon-cli && node dist/index.js validate", 21 24 "lex:diff": "cd tools/lexicon-cli && node dist/index.js diff", 25 + "lex:build-amethyst": "pnpm lex:gen-server && pnpm turbo build --filter=@teal/amethyst", 26 + "lex:dev": "pnpm lex:gen-server && pnpm turbo dev --filter=@teal/amethyst", 22 27 "db:migrate": "cd services && sqlx migrate run", 23 28 "db:migrate:revert": "cd services && sqlx migrate revert", 24 29 "db:create": "cd services && sqlx database create",
+1
packages/lexicons/lex-gen.sh
··· 1 + lex gen-server ./src ./../../lexicons/**/*.* --yes
+14
packages/lexicons/package.json
··· 1 + { 2 + "name": "@teal/lexicons", 3 + "type": "module", 4 + "main": "./index.ts", 5 + "dependencies": { 6 + "@atproto/lex-cli": "^0.5.4", 7 + "@atproto/lexicon": "^0.4.2", 8 + "@atproto/xrpc-server": "^0.7.4", 9 + "@teal/tsconfig": "workspace:*" 10 + }, 11 + "scripts": { 12 + "lex:gen-server": "zsh ./lex-gen.sh" 13 + } 14 + }
+100
scripts/install-git-hooks.sh
··· 1 + #!/bin/bash 2 + 3 + # Install git hooks for the Teal project 4 + # This script sets up pre-commit hooks for code formatting and linting 5 + 6 + set -e 7 + 8 + # Colors for output 9 + RED='\033[0;31m' 10 + GREEN='\033[0;32m' 11 + YELLOW='\033[1;33m' 12 + BLUE='\033[0;34m' 13 + NC='\033[0m' # No Color 14 + 15 + print_status() { 16 + echo -e "${BLUE}[INFO]${NC} $1" 17 + } 18 + 19 + print_success() { 20 + echo -e "${GREEN}[SUCCESS]${NC} $1" 21 + } 22 + 23 + print_error() { 24 + echo -e "${RED}[ERROR]${NC} $1" 25 + } 26 + 27 + print_warning() { 28 + echo -e "${YELLOW}[WARNING]${NC} $1" 29 + } 30 + 31 + # Check if we're in a git repository 32 + if [ ! -d ".git" ]; then 33 + print_error "This script must be run from the root of a git repository" 34 + exit 1 35 + fi 36 + 37 + print_status "Installing git hooks for Teal project..." 38 + 39 + # Create hooks directory if it doesn't exist 40 + mkdir -p .git/hooks 41 + 42 + # Install pre-commit hook 43 + if [ -f "scripts/pre-commit-hook.sh" ]; then 44 + print_status "Installing pre-commit hook..." 45 + cp scripts/pre-commit-hook.sh .git/hooks/pre-commit 46 + chmod +x .git/hooks/pre-commit 47 + print_success "Pre-commit hook installed" 48 + else 49 + print_error "Pre-commit hook script not found at scripts/pre-commit-hook.sh" 50 + exit 1 51 + fi 52 + 53 + # Optional: Install other hooks 54 + # You can add more hooks here if needed 55 + 56 + print_status "Testing hook installation..." 57 + 58 + # Test if the hook is executable 59 + if [ -x ".git/hooks/pre-commit" ]; then 60 + print_success "Pre-commit hook is executable" 61 + else 62 + print_error "Pre-commit hook is not executable" 63 + exit 1 64 + fi 65 + 66 + # Check if required tools are available 67 + print_status "Checking required tools..." 68 + 69 + MISSING_TOOLS="" 70 + 71 + if ! command -v pnpm >/dev/null 2>&1; then 72 + MISSING_TOOLS="$MISSING_TOOLS pnpm" 73 + fi 74 + 75 + if ! command -v node >/dev/null 2>&1; then 76 + MISSING_TOOLS="$MISSING_TOOLS node" 77 + fi 78 + 79 + if ! command -v cargo >/dev/null 2>&1; then 80 + MISSING_TOOLS="$MISSING_TOOLS cargo" 81 + fi 82 + 83 + if [ -n "$MISSING_TOOLS" ]; then 84 + print_warning "Some tools are missing:$MISSING_TOOLS" 85 + print_warning "The git hooks may not work properly without these tools" 86 + else 87 + print_success "All required tools are available" 88 + fi 89 + 90 + print_success "Git hooks installation complete! 🎉" 91 + print_status "The following hooks have been installed:" 92 + echo " - pre-commit: Runs formatting and linting checks before commits" 93 + 94 + print_status "To test the pre-commit hook, try making a commit with staged files" 95 + print_status "To temporarily skip hooks, use: git commit --no-verify" 96 + 97 + # Optional: Show hook status 98 + echo "" 99 + print_status "Installed hooks:" 100 + ls -la .git/hooks/ | grep -v sample | grep -v "^d" | sed 's/^/ /'
+173
scripts/pre-commit-hook.sh
··· 1 + #!/bin/bash 2 + 3 + # Pre-commit hook for Teal project 4 + # This script runs code formatting and linting checks before allowing commits 5 + 6 + set -e 7 + 8 + echo "🔍 Running pre-commit checks..." 9 + 10 + # Colors for output 11 + RED='\033[0;31m' 12 + GREEN='\033[0;32m' 13 + YELLOW='\033[1;33m' 14 + BLUE='\033[0;34m' 15 + NC='\033[0m' # No Color 16 + 17 + # Function to print colored output 18 + print_status() { 19 + echo -e "${BLUE}[INFO]${NC} $1" 20 + } 21 + 22 + print_success() { 23 + echo -e "${GREEN}[SUCCESS]${NC} $1" 24 + } 25 + 26 + print_warning() { 27 + echo -e "${YELLOW}[WARNING]${NC} $1" 28 + } 29 + 30 + print_error() { 31 + echo -e "${RED}[ERROR]${NC} $1" 32 + } 33 + 34 + # Get list of staged files 35 + STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM) 36 + 37 + if [ -z "$STAGED_FILES" ]; then 38 + print_warning "No staged files found" 39 + exit 0 40 + fi 41 + 42 + # Check if we have TypeScript/JavaScript files 43 + TS_JS_FILES=$(echo "$STAGED_FILES" | grep -E '\.(ts|tsx|js|jsx)$' || true) 44 + # Check if we have Rust files 45 + RUST_FILES=$(echo "$STAGED_FILES" | grep -E '\.rs$' || true) 46 + # Check if we have lexicon files 47 + LEXICON_FILES=$(echo "$STAGED_FILES" | grep -E 'lexicons/.*\.json$' || true) 48 + 49 + print_status "Staged files to check:" 50 + echo "$STAGED_FILES" | sed 's/^/ - /' 51 + 52 + # 1. TypeScript/JavaScript checks 53 + if [ -n "$TS_JS_FILES" ]; then 54 + print_status "Running TypeScript/JavaScript checks..." 55 + 56 + # Check if biome is available and run it 57 + if command -v pnpm >/dev/null 2>&1; then 58 + print_status "Running Biome formatting and linting..." 59 + if ! pnpm biome check . --apply --no-errors-on-unmatched 2>/dev/null; then 60 + print_error "Biome check failed. Please fix the issues and try again." 61 + exit 1 62 + fi 63 + 64 + print_status "Running Prettier formatting..." 65 + if ! pnpm prettier --write $TS_JS_FILES 2>/dev/null; then 66 + print_error "Prettier formatting failed. Please fix the issues and try again." 67 + exit 1 68 + fi 69 + 70 + print_status "Running TypeScript type checking..." 71 + if ! pnpm typecheck 2>/dev/null; then 72 + print_error "TypeScript type checking failed. Please fix the type errors and try again." 73 + exit 1 74 + fi 75 + else 76 + print_warning "pnpm not found, skipping JS/TS checks" 77 + fi 78 + fi 79 + 80 + # 2. Rust checks 81 + if [ -n "$RUST_FILES" ]; then 82 + print_status "Running Rust checks..." 83 + 84 + if command -v cargo >/dev/null 2>&1; then 85 + # Check if we're in a Rust project directory 86 + if [ -f "Cargo.toml" ] || [ -f "services/Cargo.toml" ]; then 87 + print_status "Running cargo fmt..." 88 + if ! pnpm rust:fmt 2>/dev/null; then 89 + print_error "Cargo fmt failed. Please fix the formatting issues and try again." 90 + exit 1 91 + fi 92 + 93 + print_status "Running cargo clippy..." 94 + if ! pnpm rust:clippy -- -D warnings 2>/dev/null; then 95 + print_error "Cargo clippy found issues. Please fix the warnings and try again." 96 + exit 1 97 + fi 98 + fi 99 + else 100 + print_warning "Cargo not found, skipping Rust checks" 101 + fi 102 + fi 103 + 104 + # 3. Lexicon checks 105 + if [ -n "$LEXICON_FILES" ]; then 106 + print_status "Lexicon files changed, validating and regenerating..." 107 + 108 + if command -v pnpm >/dev/null 2>&1; then 109 + print_status "Validating lexicons..." 110 + if ! pnpm lex:validate 2>/dev/null; then 111 + print_error "Lexicon validation failed. Please fix the lexicon files and try again." 112 + exit 1 113 + fi 114 + 115 + print_status "Regenerating lexicons..." 116 + if ! pnpm lex:gen-server 2>/dev/null; then 117 + print_error "Lexicon generation failed. Please check the lexicon files and try again." 118 + exit 1 119 + fi 120 + 121 + # Add generated lexicon files to staging 122 + if [ -d "packages/lexicons/src" ]; then 123 + find packages/lexicons/src -name "*.ts" -type f | while read -r file; do 124 + if [ -f "$file" ]; then 125 + git add "$file" 126 + fi 127 + done 128 + fi 129 + else 130 + print_warning "pnpm not found, skipping lexicon checks" 131 + fi 132 + fi 133 + 134 + # 4. Re-add files that might have been formatted 135 + FORMATTED_FILES="" 136 + for file in $STAGED_FILES; do 137 + if [ -f "$file" ]; then 138 + # Check if file was modified by formatters 139 + if [ -n "$(git diff "$file")" ]; then 140 + FORMATTED_FILES="$FORMATTED_FILES $file" 141 + git add "$file" 142 + fi 143 + fi 144 + done 145 + 146 + if [ -n "$FORMATTED_FILES" ]; then 147 + print_success "Auto-formatted files have been re-staged:" 148 + echo "$FORMATTED_FILES" | tr ' ' '\n' | sed 's/^/ - /' 149 + fi 150 + 151 + # 5. Final validation - ensure no syntax errors in staged files 152 + print_status "Running final validation..." 153 + 154 + # Check for common issues 155 + for file in $TS_JS_FILES; do 156 + if [ -f "$file" ]; then 157 + # Check for console.log statements (optional - remove if you want to allow them) 158 + if grep -n "console\.log" "$file" >/dev/null 2>&1; then 159 + print_warning "Found console.log statements in $file" 160 + # Uncomment the next two lines if you want to block commits with console.log 161 + # print_error "Please remove console.log statements before committing" 162 + # exit 1 163 + fi 164 + 165 + # Check for TODO/FIXME comments in committed code (optional) 166 + if grep -n -i "TODO\|FIXME" "$file" >/dev/null 2>&1; then 167 + print_warning "Found TODO/FIXME comments in $file" 168 + fi 169 + fi 170 + done 171 + 172 + print_success "All pre-commit checks passed! 🎉" 173 + exit 0
+31
services/types/Cargo.toml
··· 1 + [package] 2 + name = "types" 3 + version = "0.1.0" 4 + edition = "2021" 5 + 6 + [dependencies] 7 + atrium-api.workspace = true 8 + atrium-xrpc = "0.12.1" 9 + chrono = "0.4.39" 10 + http = "1.2.0" 11 + ipld-core = { version = "0.4.2", features = ["serde"] } 12 + langtag = { version = "0.3", features = ["serde"] } 13 + regex = "1.11.1" 14 + serde = { workspace = true, features = ["derive"] } 15 + serde_bytes = "0.11.15" 16 + serde_ipld_dagcbor = "0.6.2" 17 + serde_json.workspace = true 18 + thiserror = "2.0.11" 19 + 20 + # features 21 + [features] 22 + default = [ 23 + "namespace-fmteal", 24 + "namespace-appbsky", 25 + "namespace-toolsozone", 26 + "namespace-chatbsky", 27 + ] 28 + namespace-fmteal = [] 29 + namespace-appbsky = [] 30 + namespace-toolsozone = [] 31 + namespace-chatbsky = []
+10
services/types/readme.md
··· 1 + ## Types 2 + Rust lexicons for teal.fm and others. 3 + 4 + ### Generate lexicons 5 + You will need to install [esquema-cli](https://github.com/fatfingers23/esquema) a fork of the [atrium codegen tool](https://github.com/sugyan/atrium). 6 + 7 + Currently can install directly from the repo 8 + `cargo install esquema-cli --git https://github.com/fatfingers23/esquema.git` 9 + 10 + Then can recreate with `esquema-cli generate local --lexdir ./lexicons --outdir ./src` from this directory
+1
test-git-hooks.md
··· 1 + # Test git hooks with lexicons
+13 -1
turbo.json
··· 23 23 }, 24 24 "lex:gen-server": { 25 25 "dependsOn": [], 26 - "outputs": ["./src/types/**"] 26 + "outputs": ["./src/**"] 27 27 }, 28 28 "lex:gen": { 29 29 "dependsOn": [], ··· 43 43 }, 44 44 "db:migrate": { 45 45 "cache": false 46 + }, 47 + "@teal/amethyst#build": { 48 + "dependsOn": ["@teal/lexicons#lex:gen-server"], 49 + "outputs": ["./build/**"] 50 + }, 51 + "@teal/amethyst#build:web": { 52 + "dependsOn": ["@teal/lexicons#lex:gen-server"], 53 + "outputs": ["./build/**"] 54 + }, 55 + "@teal/amethyst#build:ios": { 56 + "dependsOn": ["@teal/lexicons#lex:gen-server"], 57 + "outputs": ["./build/**"] 46 58 } 47 59 } 48 60 }