+66
.github/workflows/appview.yml
+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
+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
+2
-2
.gitignore
+111
.pre-commit-config.yaml
+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
+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
+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
+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
+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
+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
+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
packages/lexicons/lex-gen.sh
···
1
+
lex gen-server ./src ./../../lexicons/**/*.* --yes
+14
packages/lexicons/package.json
+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
+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
+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
+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
+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.md
···
1
+
# Test git hooks with lexicons
+13
-1
turbo.json
+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
}