Skip to content

Commit 98810a3

Browse files
docs: add CLAUDE.md agent guidelines with references
Generate CLAUDE.md as the single source of truth for AI coding agents, plus an AGENTS.md pointer and offloaded references/ files (commands, testing, code-style, git-workflow, pitfalls, docs-update).
1 parent 8de0ea2 commit 98810a3

8 files changed

Lines changed: 399 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# AGENTS.md
2+
3+
This repository's guidelines for AI coding agents live in [CLAUDE.md](CLAUDE.md), the single source of truth.
4+
5+
Read **@CLAUDE.md** for the project overview, structure, boundaries, security considerations, commands, testing, code style, git workflow, common pitfalls, and docs-update rules. The detailed reference material is offloaded under [`references/`](references/) and linked from CLAUDE.md.

CLAUDE.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# AI Agent Guidelines for auth0-cli
2+
3+
This document provides context and guidelines for AI coding assistants working with the auth0-cli codebase.
4+
5+
## Your Role
6+
7+
You are a Go CLI engineer maintaining the Auth0 CLI — a Cobra-based command-line tool for building, managing, and testing Auth0 integrations. Your work centers on the command surface in `internal/cli`, wrapping the `go-auth0` Management API, and handling authentication credentials securely. Because this tool stores tenant secrets and access tokens on users' machines and its command docs are generated, treat secure credential handling and doc regeneration as first-class concerns on every change.
8+
9+
---
10+
11+
## Working Principles
12+
13+
Apply these on every task in this repo — they keep changes correct, small, and reviewable.
14+
15+
- **Think before coding.** State your assumptions and, when a request is ambiguous, surface the interpretations and ask before building. Recommend a simpler approach when you see one. A clarifying question up front beats a wrong implementation.
16+
- **Simplicity first.** Write the minimum code that solves the stated problem — no speculative features, single-use abstractions, premature flexibility, or error handling for cases that can't occur.
17+
- **Surgical changes.** Touch only what the request requires. Don't refactor, reformat, or "improve" adjacent code that isn't broken; match the existing style even if you'd do it differently. Every changed line should trace directly to the request. Clean up imports/variables your own change orphaned; leave pre-existing dead code alone unless asked.
18+
- **Goal-driven execution.** Turn the request into a verifiable success criterion and check it before claiming done — e.g. "add a flag" becomes "add the flag, wire it through, add a table-driven test, and regenerate docs." Don't report success you haven't verified.
19+
20+
---
21+
22+
## Project Overview
23+
24+
**auth0-cli** is the official command-line interface for Auth0 — build, manage, and test Auth0 integrations from the terminal.
25+
26+
- **Language:** Go 1.25.8
27+
- **Tech Stack:** Cobra (commands) + pflag, go-auth0 Management SDK (v1 `management` and v2), Sentry crash reporting, zalando/go-keyring for secret storage, terraform-exec (Terraform export), charmbracelet/glamour (markdown rendering)
28+
- **Package Manager:** Go modules — **vendored** (`vendor/` is committed; run `go mod tidy && go mod vendor` after dependency changes)
29+
- **Minimum Platform Version:** Go 1.25.8 (from `go.mod`)
30+
- **Dependencies:** go-auth0 v1.44.0 + v2.14.0, spf13/cobra 1.10.2, getsentry/sentry-go 0.47.0, zalando/go-keyring 0.2.8 · test: stretchr/testify 1.11.1, golang/mock (gomock) 1.6.0
31+
32+
---
33+
34+
## Project Structure
35+
36+
```
37+
auth0-cli/
38+
├── cmd/
39+
│ ├── auth0/ # Main entrypoint — calls cli.Execute()
40+
│ └── doc-gen/ # Generates docs/*.md from Cobra commands
41+
├── internal/
42+
│ ├── cli/ # All CLI commands (Cobra) — the bulk of the code
43+
│ ├── auth/ # Device-code authentication flow against Auth0
44+
│ ├── auth0/ # go-auth0 Management API wrappers + generated mocks
45+
│ ├── keyring/ # System keyring storage for tokens & client secrets
46+
│ ├── analytics/ # Segment usage tracking (opt-out via env var)
47+
│ ├── instrumentation/ # Sentry crash reporting
48+
│ ├── config/ # On-disk CLI config (tenants, default tenant)
49+
│ ├── display/ # Output rendering (tables, JSON, colors)
50+
│ ├── prompt/ # Interactive prompts (survey/promptui)
51+
│ └── iostream/ # TTY / pipe detection
52+
├── docs/ # GENERATED command reference (make docs) — do not hand-edit
53+
├── test/integration/ # YAML-driven integration tests (commander)
54+
└── Makefile # Canonical build/test/lint/docs targets
55+
```
56+
57+
### Key Files
58+
59+
| File | Purpose |
60+
|------|---------|
61+
| `cmd/auth0/main.go` | Entry point — thin wrapper over `cli.Execute()` |
62+
| `internal/cli/root.go` | Root command, DI wiring (`cli` struct, renderer, tracker) |
63+
| `internal/cli/cli.go` | `cli` struct, tenant/config setup, API client init |
64+
| `internal/auth/auth.go` | Device-code OAuth flow, token exchange |
65+
| `internal/keyring/keyring.go` | Secret storage abstraction over go-keyring |
66+
| `Makefile` | All build/test/lint/docs commands |
67+
68+
---
69+
70+
## Boundaries
71+
72+
### ✅ Always Do
73+
74+
- Run `make lint` and `make test-unit` before committing.
75+
- Follow the existing Cobra command patterns and naming (see [references/code-style.md](references/code-style.md)).
76+
- Add table-driven unit tests for new functionality; regenerate mocks with `make test-mocks` when an interface changes.
77+
- **Regenerate command docs with `make docs` whenever you add/change a command, flag, or help text.** CI runs `make check-docs` and fails if `docs/` is out of sync.
78+
- Update `CHANGELOG.md` for user-facing changes.
79+
- Update `README.md` and any affected guides (`CUSTOMIZATION_GUIDE.md`, `MIGRATION_GUIDE.md`) in the same PR when changing the public command surface, flags, or supported workflows.
80+
- After changing dependencies, run `go mod tidy && go mod vendor` — the `vendor/` directory is committed and must stay in sync.
81+
- Route new usage tracking through the existing `analytics.Tracker` (`internal/analytics`) and preserve the `AUTH0_CLI_ANALYTICS=false` opt-out; do not hand-roll a new tracking client.
82+
83+
### ⚠️ Ask First
84+
85+
- **Any breaking change to a command, flag, or output format — always ask first.** Never break backward compatibility on your own initiative.
86+
- Adding new dependencies (also requires `go mod vendor`).
87+
- Modifying authentication, token exchange, or keyring storage code (`internal/auth`, `internal/keyring`).
88+
- Changes to CI/CD configuration (`.github/workflows/`, `.goreleaser.yml`).
89+
- Running integration tests (`make test-integration`) — they hit a **live Auth0 tenant**, are slow, and can mutate real resources (see [references/testing.md](references/testing.md)).
90+
91+
### 🚫 Never Do
92+
93+
- Commit secrets, API keys, tokens, or a populated `.env`.
94+
- Log or print access tokens, refresh tokens, or client secrets.
95+
- Hand-edit generated files: `docs/*.md` (regenerate via `make docs`) or `internal/auth0/mock/*` (regenerate via `make test-mocks`).
96+
- Hand-edit the `vendor/` directory.
97+
- Remove or skip failing tests without fixing them.
98+
- Break backward compatibility without asking first and getting explicit approval.
99+
100+
---
101+
102+
## Security Considerations
103+
104+
- **Credential storage:** Client secrets, access tokens, and legacy refresh tokens are stored in the OS keyring via `zalando/go-keyring` (`internal/keyring`). Access tokens are chunked (2048-byte segments) because some keyrings cap value size. Never move secrets to plaintext config or logs.
105+
- **Authentication:** Uses the OAuth device-authorization flow (`internal/auth`) for interactive login, and client-credentials (secret or private-key JWT) for machine auth. Do not weaken or bypass these flows.
106+
- **Crash reporting:** `internal/instrumentation` ships a **public, write-only** Sentry DSN (safe to embed). Crash reporting is disabled for `dev`/empty-version builds — do not enable it for local builds.
107+
- **Analytics:** `internal/analytics` sends usage events; honor the `AUTH0_CLI_ANALYTICS=false` opt-out and the debug-build skip.
108+
- **Never commit secrets, API keys, or tokens.**
109+
110+
---
111+
112+
> The sections below are **reference** — each keeps a one-line anchor inline and offloads its body to `references/*.md`. Read a file only when the task needs it.
113+
114+
## Commands
115+
116+
Core loop: `make build` (binary to `./out/auth0`), `make test-unit` (safe, no creds), `make lint`, `make docs` (regenerate command reference).
117+
118+
See [references/commands.md](references/commands.md) for the full command list. Read it when you need to build, test, lint, generate docs/mocks, or check vulnerabilities.
119+
120+
## Testing
121+
122+
Framework is Go's `testing` + `testify` assertions + `gomock`; tests are table-driven and colocated as `*_test.go`. The default `make test-unit` suite is unit-only and needs no credentials; `make test-integration` hits a live tenant and requires `AUTH0_DOMAIN`/`AUTH0_CLIENT_ID`/`AUTH0_CLIENT_SECRET` (Ask First).
123+
124+
See [references/testing.md](references/testing.md) for conventions, mocking, running a single test, and the integration tier. Read it when writing or running tests.
125+
126+
## Code Style
127+
128+
Go standard style enforced by `golangci-lint` (v2): `gofmt -s` + `goimports` with local prefix `github.com/auth0/auth0-cli`, plus `errcheck`, `revive`, `staticcheck`, `gocritic`, `godot` (comments end with a capitalized sentence + period). Commands follow a consistent Cobra constructor pattern with declarative `Flag` structs.
129+
130+
See [references/code-style.md](references/code-style.md) for naming, the command pattern, and good/bad examples. Read it when adding or editing a command.
131+
132+
## Git Workflow
133+
134+
Branch names are ticket-scoped (e.g. `DXCDT-1234/short-description`) or `docs/…`, `fix-…`. PRs use `.github/PULL_REQUEST_TEMPLATE.md` (Changes / References / Testing sections).
135+
136+
See [references/git-workflow.md](references/git-workflow.md) for branch, commit, and PR conventions. Read it before committing or opening a PR.
137+
138+
## Common Pitfalls
139+
140+
The top one: forgetting `make docs` after a command/flag change fails CI (`make check-docs`). Others involve vendoring, mock regeneration, and the v1/v2 go-auth0 split.
141+
142+
See [references/pitfalls.md](references/pitfalls.md) for the full list. Read it when a build/CI step fails unexpectedly.
143+
144+
## Docs Update Rules
145+
146+
> Treat documentation as a first-class deliverable. A PR that changes the command surface, flags, or supported workflows is **not complete** until the relevant docs are updated in the same PR.
147+
148+
The `docs/` command reference is **generated** — never hand-edit it; run `make docs`. Prose docs (`README.md`, guides) are hand-maintained.
149+
150+
See [references/docs-update.md](references/docs-update.md) for the tracked-docs inventory and the code-to-docs mapping. Read it when your change touches user-facing behavior.

references/code-style.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Code Style
2+
3+
## Enforced tooling
4+
5+
`golangci-lint` v2 (`.golangci.yml`) is the gate. Enabled linters: `errcheck`, `gocritic`, `godot`, `revive`, `staticcheck` (all checks), `unconvert`, `unused`, `whitespace`. Formatters: `gofmt` with `simplify`, and `goimports` with local prefix `github.com/auth0/auth0-cli` (local imports grouped last).
6+
7+
- `godot`: comments must be full sentences — capitalized, ending in a period.
8+
- `errcheck`: check returned errors (the config exempts some via exclusion rules, but prefer handling them).
9+
10+
## Naming conventions
11+
12+
- Standard Go: `PascalCase` for exported identifiers, `camelCase` for unexported, short receiver names.
13+
- Command files are named after the resource: `apps.go`, `apis.go`, `custom_domains.go`; their tests are `<name>_test.go`.
14+
- Flags are declared as package-level `Flag` structs (see below), named `<command><Field>` (e.g. `loginClientID`).
15+
16+
## The command pattern
17+
18+
Commands are Cobra constructors that take the shared `*cli` struct and return a `*cobra.Command`. Flags are declared declaratively:
19+
20+
**✅ Good** — declarative flag, wired into a Cobra command:
21+
22+
```go
23+
var loginClientID = Flag{
24+
Name: "Client ID",
25+
LongForm: "client-id",
26+
Help: "Client ID of the application when authenticating via client credentials.",
27+
IsRequired: false,
28+
}
29+
30+
func loginCmd(cli *cli) *cobra.Command {
31+
var inputs LoginInputs
32+
cmd := &cobra.Command{
33+
Use: "login",
34+
Short: "Authenticate to your tenant",
35+
RunE: func(cmd *cobra.Command, args []string) error {
36+
return runLogin(cmd.Context(), cli, &inputs)
37+
},
38+
}
39+
loginClientID.RegisterString(cmd, &inputs.ClientID, "")
40+
return cmd
41+
}
42+
```
43+
44+
**❌ Bad** — hardcoded flag strings, ignored error, no help text:
45+
46+
```go
47+
func loginCmd(cli *cli) *cobra.Command {
48+
cmd := &cobra.Command{Use: "login", Run: func(cmd *cobra.Command, args []string) {
49+
id, _ := cmd.Flags().GetString("client-id") // errcheck: unchecked error
50+
doLogin(id) // no context, no error return
51+
}}
52+
cmd.Flags().String("client-id", "", "") // no help; not a Flag struct
53+
return cmd
54+
}
55+
```
56+
57+
## Dominant patterns
58+
59+
- **Dependency injection via the `cli` struct** (`internal/cli/cli.go`) — carries the renderer, analytics tracker, config, and API client; passed to every command constructor.
60+
- **`RunE` returning errors** rather than `Run` + `os.Exit`; errors bubble to the root command.
61+
- **Rendering through `internal/display`** — never `fmt.Println` results directly; use the renderer so JSON/table/format flags work.

references/commands.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Commands
2+
3+
All commands are Makefile targets (run `make help` to list them). These mirror what CI runs in `.github/workflows/main.yml`.
4+
5+
```bash
6+
# Build the CLI binary for the native platform -> ./out/auth0
7+
make build
8+
9+
# Install the binary into $GOPATH/bin
10+
make install
11+
12+
# Build for all supported platforms (CI "Build" job)
13+
make build-all-platforms
14+
15+
# Run unit tests (safe — no credentials required)
16+
make test-unit
17+
18+
# Run all tests (unit + integration; integration needs a live tenant)
19+
make test
20+
21+
# Run integration tests only (requires AUTH0_DOMAIN/CLIENT_ID/CLIENT_SECRET)
22+
make test-integration
23+
# Filter to a subset:
24+
make test-integration FILTER="attack protection"
25+
26+
# Regenerate gomock mocks (after changing a mocked interface)
27+
make test-mocks
28+
29+
# Lint (golangci-lint v2, config .golangci.yml)
30+
make lint
31+
32+
# Check for known vulnerabilities (govulncheck)
33+
make check-vuln
34+
35+
# Regenerate the docs/ command reference from Cobra commands
36+
make docs
37+
38+
# Verify docs are in sync (CI gate — fails if `make docs` produces a diff)
39+
make check-docs
40+
41+
# Download dependencies
42+
make deps
43+
44+
# Clean the docs output
45+
make docs-clean
46+
```
47+
48+
## CI jobs (`.github/workflows/main.yml`)
49+
50+
1. **Checks**`make check-docs` + `golangci-lint` with `-c .golangci.yml`.
51+
2. **Unit Tests**`make test-unit`, uploads coverage.
52+
3. **Integration Tests**`make test-integration` (skipped for forks/dependabot; only on `main`-targeted PRs). Uses `AUTH0_DOMAIN`, `AUTH0_CLIENT_ID`, `AUTH0_CLIENT_SECRET` secrets.
53+
4. **Build**`make build-all-platforms`.
54+
55+
## Running without building
56+
57+
```bash
58+
go run ./cmd/auth0 <command>
59+
```

references/docs-update.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Docs Update Rules
2+
3+
This is a **CLI** repo, so the code-to-docs mapping is command/flag-oriented.
4+
5+
## Tracked docs
6+
7+
| Doc | Covers | Present |
8+
|-----|--------|---------|
9+
| `README.md` | Install, quickstart, top-level command overview | present |
10+
| `docs/*.md` | **Generated** per-command reference (`make docs`) — one file per command | present |
11+
| `CHANGELOG.md` | User-facing change history | present |
12+
| `CUSTOMIZATION_GUIDE.md` | Universal Login / branding customization workflow | present |
13+
| `MIGRATION_GUIDE.md` | Migration notes for breaking changes | present |
14+
| `CONTRIBUTING.md` | Dev setup, adding a command, adding a dependency, releasing | present |
15+
16+
> `EXAMPLES.md` is not tracked in this repo — usage examples live in `README.md` and the generated `docs/`.
17+
18+
## When you change code, update these docs
19+
20+
| Change | Update |
21+
|--------|--------|
22+
| Add/rename/remove a command | `make docs` (regenerates `docs/`), plus `README.md` if it's a top-level command; `CHANGELOG.md` |
23+
| Add/change a flag or its help text | `make docs`; `CHANGELOG.md` |
24+
| Change command output/behavior | `make docs` if help text changed; `CHANGELOG.md` |
25+
| Breaking change (flag/output/command removed or renamed) | Ask first; then `MIGRATION_GUIDE.md` + `CHANGELOG.md` + `make docs` |
26+
| Change to Universal Login / branding flow | `CUSTOMIZATION_GUIDE.md` |
27+
| Change dev setup, build, or release steps | `CONTRIBUTING.md` |
28+
29+
> The generated `docs/` reference must never be hand-edited — always regenerate via `make docs`. CI's `make check-docs` enforces this. Update the mapped hand-written doc **in the same PR** as the code change.

references/git-workflow.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Git Workflow
2+
3+
## Branch naming
4+
5+
Observed conventions in this repo:
6+
7+
- Ticket-scoped: `DXCDT-1234/short-description` (Jira key + slug).
8+
- Type-scoped: `docs/…`, `fix-…`, `issue-<number>-…`.
9+
- Automated: `dependabot/…`.
10+
11+
Match the pattern that fits your change; prefer the ticket-scoped form when a Jira ticket exists.
12+
13+
## Commit messages
14+
15+
Conventional-commit style prefixes are used across history: `docs:`, `chore(deps):`, `fix:`, `feat:`. Keep the subject imperative and concise; scope in parentheses where useful (e.g. `chore(deps): bump ...`).
16+
17+
## Pull requests
18+
19+
Use `.github/PULL_REQUEST_TEMPLATE.md`, which has three sections:
20+
21+
- **🔧 Changes** — what changed and why; types/methods added, deleted, deprecated, or changed; usage summary for new/changed public surface.
22+
- **📚 References** — GitHub issue/PR links, Community posts, related PRs.
23+
- **🔬 Testing** — how the change was tested.
24+
25+
## Before opening a PR
26+
27+
1. `make lint`
28+
2. `make test-unit`
29+
3. `make docs` (if you touched commands/flags/help) — CI's `make check-docs` will fail otherwise.
30+
4. `go mod tidy && go mod vendor` (if you touched dependencies).
31+
5. Update `CHANGELOG.md` for user-facing changes.
32+
33+
## Releases
34+
35+
Releases are cut by maintainers via a tag-triggered GitHub workflow + Goreleaser — not by agents editing files. Do not bump versions by hand; keep `CHANGELOG.md` current instead.

references/pitfalls.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Common Pitfalls
2+
3+
1. **Forgetting to regenerate docs.** Any change to a command, flag, or help string must be followed by `make docs`. CI runs `make check-docs`, which regenerates and fails if `git status` is dirty. This is the most common CI failure.
4+
5+
2. **Vendoring drift.** Dependencies are vendored (`vendor/` is committed). After `go get`/`go mod` changes you must run `go mod tidy && go mod vendor`, or the build/CI breaks. Do not hand-edit `vendor/`.
6+
7+
3. **Stale mocks.** Mocks in `internal/auth0/mock` are generated by `mockgen`. After changing a mocked interface, run `make test-mocks` — do not hand-edit the generated files.
8+
9+
4. **Two go-auth0 major versions coexist.** The repo imports both `github.com/auth0/go-auth0` (v1, `management`) and `github.com/auth0/go-auth0/v2`. Check which version a given command already uses before adding calls; don't mix types across the two.
10+
11+
5. **Printing results directly.** Use the `internal/display` renderer instead of `fmt.Println` so `--json` and format flags keep working, and so nothing accidentally prints a secret.
12+
13+
6. **Leaking secrets in output/logs.** Client secrets and tokens live in the OS keyring (`internal/keyring`). Never log them; secret-revealing output (e.g. `--reveal-secrets`) must be explicit and opt-in.
14+
15+
7. **Enabling telemetry/crash reporting for dev builds.** Both analytics and Sentry intentionally no-op when `buildinfo.Version` is empty or `dev`. Don't remove those guards.
16+
17+
8. **`godot` lint failures.** Comments must be complete sentences ending in a period — an easy lint miss on new code.

0 commit comments

Comments
 (0)