Skip to content

Commit 6df0633

Browse files
lestrratCopilot
andauthored
Add AGENTS.md (#1546)
* Add AGENTS.md * Update AGENTS.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 1f71571 commit 6df0633

File tree

1 file changed

+232
-0
lines changed

1 file changed

+232
-0
lines changed

AGENTS.md

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# AGENTS.md
2+
3+
## For Module Consumers
4+
5+
If you are writing code that *uses* jwx (not developing jwx itself):
6+
7+
- **Examples**: See `examples/` directory for runnable usage patterns
8+
- **Documentation**: See `docs/` directory and package READMEs
9+
- **API Reference**: Use `go doc` or https://pkg.go.dev/github.com/lestrrat-go/jwx/v3
10+
11+
The rest of this document focuses on developing the jwx library itself.
12+
13+
---
14+
15+
## Go Version
16+
17+
This project requires **Go 1.24.0** or later. Check `go.mod` for the exact version.
18+
19+
## Module Path vs Physical Layout
20+
21+
This repository uses a **flat layout** with vanity import paths. There is no physical `v3/` directory.
22+
23+
| Branch | Module Path | Physical Root |
24+
|--------|-------------|---------------|
25+
| `develop/v3` | `github.com/lestrrat-go/jwx/v3` | `/` (repo root) |
26+
27+
`import "github.com/lestrrat-go/jwx/v3/jwt"` → files are at `./jwt/`, not `./v3/jwt/`.
28+
29+
## Code Generation
30+
31+
### Immutable Rule
32+
33+
**NEVER edit files ending in `_gen.go` directly.** These are generated files. Edit the generator sources instead.
34+
35+
### Generated Files Pattern
36+
37+
Files matching `*_gen.go` are generated. Examples:
38+
- `jwt/options_gen.go`
39+
- `jwt/token_gen.go`
40+
- `jws/headers_gen.go`
41+
- `jwk/rsa_gen.go`
42+
- `jwa/signature_gen.go`
43+
44+
### Generator Locations
45+
46+
| Generator | Location | Input Files | Output |
47+
|-----------|----------|-------------|--------|
48+
| `genoptions` | `tools/cmd/genoptions/` | `{jwa,jwe,jwk,jws,jwt}/options.yaml` | `*/options_gen.go` |
49+
| `genjwt` | `tools/cmd/genjwt/` | `tools/cmd/genjwt/objects.yml` | `jwt/*_gen.go` |
50+
| `genjws` | `tools/cmd/genjws/` | `tools/cmd/genjws/objects.yml` | `jws/*_gen.go` |
51+
| `genjwe` | `tools/cmd/genjwe/` | `tools/cmd/genjwe/objects.yml` | `jwe/*_gen.go` |
52+
| `genjwk` | `tools/cmd/genjwk/` | `tools/cmd/genjwk/objects.yml` | `jwk/*_gen.go` |
53+
| `genjwa` | `tools/cmd/genjwa/` | `tools/cmd/genjwa/objects.yml` | `jwa/*_gen.go` |
54+
| `genreadfile` | `tools/cmd/genreadfile/` | - | ReadFile helpers |
55+
56+
### Regeneration Commands
57+
58+
```bash
59+
# Regenerate all code
60+
make generate
61+
62+
# Regenerate specific package
63+
make generate-jwt
64+
make generate-jws
65+
make generate-jwe
66+
make generate-jwk
67+
make generate-jwa
68+
```
69+
70+
## Functional Options Pattern
71+
72+
Options are defined in `{package}/options.yaml` and generated into `{package}/options_gen.go`.
73+
74+
Example `options.yaml` entry:
75+
76+
```yaml
77+
options:
78+
- ident: Token
79+
interface: ParseOption
80+
argument_type: Token
81+
comment: |
82+
WithToken specifies the token instance...
83+
```
84+
85+
Generates `WithToken(v Token) ParseOption` function.
86+
87+
## Multi-Module Structure
88+
89+
This repository contains multiple Go modules. The nested modules use `replace` directives for local development.
90+
91+
| Module | Path | Purpose |
92+
|--------|------|---------|
93+
| Main | `./go.mod` | Core library |
94+
| Examples | `./examples/go.mod` | Usage examples |
95+
| CLI | `./cmd/jwx/go.mod` | Command-line tool |
96+
| Perf Bench | `./bench/performance/go.mod` | Performance benchmarks |
97+
| Comparison | `./bench/comparison/go.mod` | Library comparison |
98+
| Generators | `./tools/cmd/*/go.mod` | Code generators |
99+
100+
### Local Development
101+
102+
The `examples/go.mod` contains:
103+
```go
104+
replace github.com/lestrrat-go/jwx/v3 v3.0.0 => ../
105+
```
106+
107+
No `go.work` file is present. When working across modules, either:
108+
1. Create a temporary `go.work` file
109+
2. Rely on the `replace` directives already in place
110+
111+
## Development Commands
112+
113+
```bash
114+
# Run all tests
115+
make test
116+
117+
# Run tests with specific build tags
118+
make test-goccy # Use goccy/go-json
119+
make test-es256k # Enable ES256K support
120+
make test-alltags # All optional features
121+
122+
# Run short/smoke tests
123+
make smoke
124+
125+
# Generate coverage report
126+
make cover
127+
make viewcover
128+
129+
# Lint
130+
make lint
131+
132+
# Format and tidy
133+
make imports
134+
make tidy
135+
```
136+
137+
### Test Script Details
138+
139+
Tests are run via `./tools/test.sh` which iterates over:
140+
- `.` (main module)
141+
- `./examples`
142+
- `./bench/performance`
143+
- `./cmd/jwx`
144+
145+
## Package Directory Map
146+
147+
| Package | Responsibility |
148+
|---------|----------------|
149+
| `jwa/` | Algorithm identifiers (e.g., `RS256`, `ES384`, `A128GCM`) |
150+
| `jwk/` | JSON Web Keys - key representation and management |
151+
| `jws/` | JSON Web Signatures - `Sign()` and `Verify()` |
152+
| `jwe/` | JSON Web Encryption - `Encrypt()` and `Decrypt()` |
153+
| `jwt/` | JSON Web Tokens - claims and validation |
154+
| `jwt/openid/` | OpenID Connect ID tokens |
155+
| `transform/` | Token transformation utilities |
156+
157+
## Relevant RFCs
158+
159+
- RFC 7515 - JWS (JSON Web Signature)
160+
- RFC 7516 - JWE (JSON Web Encryption)
161+
- RFC 7517 - JWK (JSON Web Key)
162+
- RFC 7518 - JWA (JSON Web Algorithms)
163+
- RFC 7519 - JWT (JSON Web Token)
164+
- OpenID Connect Core 1.0
165+
166+
## Error Handling
167+
168+
Sentinel errors are exposed via functions. Use `errors.Is()`:
169+
170+
```go
171+
if errors.Is(err, jwt.TokenExpiredError()) { ... }
172+
```
173+
174+
| Package | Function | Meaning |
175+
|---------|----------|---------|
176+
| `jwt` | `TokenExpiredError()` | `exp` claim not satisfied |
177+
| `jwt` | `TokenNotYetValidError()` | `nbf` claim not satisfied |
178+
| `jwt` | `InvalidIssuerError()` | `iss` claim not satisfied |
179+
| `jwt` | `InvalidAudienceError()` | `aud` claim not satisfied |
180+
| `jwt` | `ValidateError()` | Generic validation failure |
181+
| `jwt` | `ParseError()` | Parse failed |
182+
| `jws` | `VerificationError()` | Signature verification failed |
183+
| `jwe` | `DecryptError()` | Decryption failed |
184+
185+
## Testing
186+
187+
Use `github.com/stretchr/testify/require` for assertions (not `assert`).
188+
189+
## Build Tags
190+
191+
| Tag | Effect |
192+
|-----|--------|
193+
| `jwx_goccy` | Use `goccy/go-json` instead of `encoding/json` |
194+
| `jwx_es256k` | Enable secp256k1/ES256K algorithm support |
195+
| `jwx_secp256k1_pem` | Enable PEM encoding for secp256k1 keys |
196+
| `jwx_asmbase64` | Use assembly-optimized base64 |
197+
198+
## Quick Reference: Common Modifications
199+
200+
| Task | Edit This | Then Run |
201+
|------|-----------|----------|
202+
| Add new JWT option | `jwt/options.yaml` | `make generate-jwt` |
203+
| Add new JWS header field | `tools/cmd/genjws/objects.yml` | `make generate-jws` |
204+
| Add new JWK key field | `tools/cmd/genjwk/objects.yml` | `make generate-jwk` |
205+
| Add new algorithm | `tools/cmd/genjwa/objects.yml` | `make generate-jwa` |
206+
| Modify token fields | `tools/cmd/genjwt/objects.yml` | `make generate-jwt` |
207+
208+
## File Naming Conventions
209+
210+
| Pattern | Meaning |
211+
|---------|---------|
212+
| `*_gen.go` | Generated code - DO NOT EDIT |
213+
| `*_test.go` | Test files |
214+
| `*_gen_test.go` | Generated tests - DO NOT EDIT |
215+
| `options.yaml` | Option definitions (input to genoptions) |
216+
| `objects.yml` | Object definitions (input to package-specific generators) |
217+
218+
## Examples Directory
219+
220+
Naming convention: `{package}_xxx_example_test.go`
221+
- `jwt_parse_example_test.go`
222+
- `jws_sign_example_test.go`
223+
- `jwx_example_test.go` (cross-package)
224+
- `jwx_readme_example_test.go` (cross-package, used in README)
225+
- `jwx_register_ec_and_key_example_test.go` (cross-package, key registration)
226+
227+
Examples are included in `docs/` via autodoc markers:
228+
```markdown
229+
<!-- INCLUDE(examples/jwt_parse_example_test.go) -->
230+
<!-- END INCLUDE -->
231+
```
232+

0 commit comments

Comments
 (0)