Add Claude agents and review-and-commit skill
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
8
.claude/agents/auto-review-commit.md
Normal file
8
.claude/agents/auto-review-commit.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
description: Auto-trigger review and commit when feature implementation is complete
|
||||||
|
alwaysApply: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Auto-Trigger Review & Commit
|
||||||
|
|
||||||
|
When a feature implementation is complete, automatically execute the `/review-and-commit` workflow without waiting for the user to manually request it. Do not automatically push and watch.
|
||||||
40
.claude/agents/go-conventions.md
Normal file
40
.claude/agents/go-conventions.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
description: Go conventions and patterns for this project
|
||||||
|
globs: "**/*.go"
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
|
||||||
|
# Go Conventions
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Every exported function that does I/O takes `context.Context` as its first argument.
|
||||||
|
|
||||||
|
## Errors
|
||||||
|
|
||||||
|
- Define package-level sentinel errors for expected conditions:
|
||||||
|
|
||||||
|
```go
|
||||||
|
var ErrNotFound = fmt.Errorf("not found")
|
||||||
|
```
|
||||||
|
|
||||||
|
- Wrap unexpected errors with `fmt.Errorf("doing X: %w", err)` to preserve the chain.
|
||||||
|
- Callers check expected errors with `errors.Is(err, store.ErrNotFound)`.
|
||||||
|
|
||||||
|
## UUIDs
|
||||||
|
|
||||||
|
- Use `github.com/google/uuid` for all UUID types.
|
||||||
|
- Model structs use `uuid.UUID`, not `string`, for ID fields.
|
||||||
|
|
||||||
|
## Database
|
||||||
|
|
||||||
|
- Use `?` parameter placeholders (MySQL style), never string interpolation.
|
||||||
|
- Use `gen_random_uuid()` for server-generated UUIDs (Postgres built-in).
|
||||||
|
- **Queries**: use [sqlc](https://sqlc.dev/) to generate type-safe Go from SQL.
|
||||||
|
Write annotated SQL in `internal/store/queries/*.sql`; run `task sqlc` to
|
||||||
|
regenerate. Never hand-write query code in Go — edit the `.sql` source instead.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
- Use the standard `testing` package. No external assertion libraries.
|
||||||
|
- Test functions follow `TestTypeName_MethodName` naming
|
||||||
66
.claude/agents/go-dev.md
Normal file
66
.claude/agents/go-dev.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
description: Standard Go development commands for this project
|
||||||
|
globs: "**/*.go"
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
|
||||||
|
# Go Development Commands
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run all tests
|
||||||
|
go test ./...
|
||||||
|
|
||||||
|
# Run tests in a specific package
|
||||||
|
go test ./internal/checkin/...
|
||||||
|
|
||||||
|
# Run a single test by name
|
||||||
|
go test ./internal/checkin/... -run TestCheckOut
|
||||||
|
|
||||||
|
# Run tests with verbose output
|
||||||
|
go test -v ./...
|
||||||
|
|
||||||
|
# Run tests with race detector
|
||||||
|
go test -race ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Formatting and Linting
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Format all Go files
|
||||||
|
gofmt -w .
|
||||||
|
|
||||||
|
# Organize imports (group stdlib, external, internal)
|
||||||
|
goimports -w .
|
||||||
|
|
||||||
|
# Vet for common mistakes
|
||||||
|
go vet ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Generation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Regenerate sqlc query code after editing internal/store/queries/*.sql
|
||||||
|
task sqlc
|
||||||
|
|
||||||
|
# Regenerate proto/gRPC code after editing .proto files
|
||||||
|
task generate
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Compile all packages (catches errors without producing binaries)
|
||||||
|
go build ./...
|
||||||
|
|
||||||
|
# Tidy module dependencies after adding/removing imports
|
||||||
|
go mod tidy
|
||||||
|
```
|
||||||
|
|
||||||
|
## After any code change
|
||||||
|
|
||||||
|
1. `gofmt -w .`
|
||||||
|
2. `goimports -w .` (if imports changed)
|
||||||
|
3. `go vet ./...`
|
||||||
|
4. `go test ./...`
|
||||||
12
.claude/agents/minimal-changes.md
Normal file
12
.claude/agents/minimal-changes.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
description: Make only the changes the user asked for
|
||||||
|
alwaysApply: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Minimal Changes
|
||||||
|
|
||||||
|
When implementing a requested change, make **only** the changes the user asked for.
|
||||||
|
|
||||||
|
- Do not make additional "cleanup" or "consistency" changes alongside the requested work (e.g. removing annotations you consider redundant, restructuring related code, adding backward-compatibility guards).
|
||||||
|
- If you notice something that *should* be changed but wasn't requested, mention it after completing the requested work — don't silently include it.
|
||||||
|
- When presenting multiple implementation paths, wait for the user to choose before writing any code.
|
||||||
13
.claude/agents/taskfile-not-make.md
Normal file
13
.claude/agents/taskfile-not-make.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
description: Use go-task (Taskfile) instead of Make for task automation
|
||||||
|
alwaysApply: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Use Taskfile, not Make
|
||||||
|
|
||||||
|
This project uses [go-task](https://taskfile.dev/) (`Taskfile.yaml`) for task automation. **Do not** use Makefiles.
|
||||||
|
|
||||||
|
- Task definitions go in `Taskfile.yaml` at the repo root.
|
||||||
|
- Use `task <name>` to run tasks (e.g. `task test`, `task db`).
|
||||||
|
- Use colon-separated namespacing for related tasks (e.g. `task db:stop`).
|
||||||
|
- When adding new automation, add a task to `Taskfile.yaml` rather than creating a Makefile or shell script.
|
||||||
14
.claude/agents/test-isolation.md
Normal file
14
.claude/agents/test-isolation.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
description: Tests must be self-contained; mock external service dependencies
|
||||||
|
globs: "**/*_test.go"
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
|
||||||
|
# Test Isolation
|
||||||
|
|
||||||
|
Tests must be self-contained. The only shared infrastructure allowed is the database.
|
||||||
|
|
||||||
|
- **Database**: tests may depend on a real database connection — this is expected and acceptable.
|
||||||
|
- **External services** (gRPC clients, HTTP APIs, third-party SDKs, etc.): must be mocked or stubbed. Tests must never make real calls to external services.
|
||||||
|
- Use interfaces for service dependencies so they are straightforward to mock in tests.
|
||||||
|
- Keep mocks minimal — only stub the methods the test actually exercises.
|
||||||
11
.claude/agents/testing-mocks.md
Normal file
11
.claude/agents/testing-mocks.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
description: Preferences for testing and mocks
|
||||||
|
globs: ["**/*_test.go", "e2e/**/*.go"]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Testing Mocks
|
||||||
|
|
||||||
|
When writing or updating tests:
|
||||||
|
- Always prefer real code, a local version of a server (like `httptest`), etc., to static mocks.
|
||||||
|
- Prefer dependency injection if useful for testing.
|
||||||
|
- A mock implementation should be the absolute last resort.
|
||||||
93
.claude/skills/review-and-commit/SKILL.md
Normal file
93
.claude/skills/review-and-commit/SKILL.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
---
|
||||||
|
name: review-and-commit
|
||||||
|
description: Review and Commit
|
||||||
|
disable-model-invocation: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Review and Commit
|
||||||
|
|
||||||
|
Perform the following steps in order. Stop and report if any step fails.
|
||||||
|
|
||||||
|
## 1. Run Code Checks
|
||||||
|
|
||||||
|
Run these in parallel where possible:
|
||||||
|
|
||||||
|
- `task lint` (buf format + buf lint + gofmt + goimports + go vet)
|
||||||
|
- `task generate` then verify no diff in generated files (`git diff --exit-code gen/ api/openapi.yaml`)
|
||||||
|
|
||||||
|
Fix any issues found. Re-run checks after fixes.
|
||||||
|
|
||||||
|
## 2. Run Tests with Coverage
|
||||||
|
|
||||||
|
Run tests uncached with verbose output and coverage:
|
||||||
|
|
||||||
|
```
|
||||||
|
go test -count=1 -v -coverprofile=coverage.out ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
Then analyze coverage:
|
||||||
|
|
||||||
|
```
|
||||||
|
go tool cover -func=coverage.out
|
||||||
|
```
|
||||||
|
|
||||||
|
### Coverage analysis
|
||||||
|
|
||||||
|
1. **Baseline**: before the review, capture coverage on the base branch (or use the most recent known coverage if available). If no baseline exists, use the current run as the initial baseline.
|
||||||
|
2. **Compare**: check total coverage and per-package coverage for packages that contain changed files.
|
||||||
|
3. **Thresholds**:
|
||||||
|
- If total coverage drops by **2 or more percentage points**, suggest adding tests and ask for confirmation before committing. Do not block the commit.
|
||||||
|
- If a changed package has **0% coverage**, mention it in the report unless the package is purely generated code or contains only types/constants.
|
||||||
|
4. **Report**: include a short coverage summary in the findings (total %, per-changed-package %, and delta if baseline is available).
|
||||||
|
|
||||||
|
Clean up `coverage.out` after analysis.
|
||||||
|
|
||||||
|
## 3. Review Changed Go Files
|
||||||
|
|
||||||
|
For each `.go` file in the diff (excluding `gen/`), review against:
|
||||||
|
|
||||||
|
### Go Code Review Comments (go.dev/wiki/CodeReviewComments)
|
||||||
|
|
||||||
|
- Comment sentences: doc comments are full sentences starting with the name, ending with a period.
|
||||||
|
- Contexts: `context.Context` as first param, never stored in structs.
|
||||||
|
- Error strings: lowercase, no trailing punctuation.
|
||||||
|
- Handle errors: no discarded errors with `_`.
|
||||||
|
- Imports: grouped (stdlib, external, internal), no unnecessary renames.
|
||||||
|
- Indent error flow: normal path at minimal indentation, error handling first.
|
||||||
|
- Initialisms: `ID`, `URL`, `HTTP` — consistent casing.
|
||||||
|
- Interfaces: defined where used, not where implemented.
|
||||||
|
- Named result parameters: only when they clarify meaning.
|
||||||
|
- Receiver names: short, consistent, never `this`/`self`.
|
||||||
|
- Variable names: short for narrow scope, descriptive for wide scope.
|
||||||
|
|
||||||
|
### Effective Go (go.dev/doc/effective_go)
|
||||||
|
|
||||||
|
- Zero value useful: structs should be usable without explicit init.
|
||||||
|
- Don't panic: use error returns, not panic, for normal error handling.
|
||||||
|
- Goroutine lifetimes: clear when/whether goroutines exit.
|
||||||
|
- Embedding: prefer embedding over forwarding methods when appropriate.
|
||||||
|
- Concurrency: share memory by communicating, not vice versa.
|
||||||
|
|
||||||
|
### Go Proverbs (go-proverbs.github.io)
|
||||||
|
|
||||||
|
- The bigger the interface, the weaker the abstraction.
|
||||||
|
- A little copying is better than a little dependency.
|
||||||
|
- Clear is better than clever.
|
||||||
|
- Errors are values — handle them, don't just check them.
|
||||||
|
- Don't panic.
|
||||||
|
- Make the zero value useful.
|
||||||
|
- Design the architecture, name the components, document the details.
|
||||||
|
|
||||||
|
## 4. Report Findings
|
||||||
|
|
||||||
|
Present findings grouped by severity:
|
||||||
|
|
||||||
|
- **Must fix**: violations that would break conventions, correctness, or backwards compatibility.
|
||||||
|
- **Should fix**: style, clarity, or maintainability issues.
|
||||||
|
- **Nit**: minor suggestions, optional.
|
||||||
|
|
||||||
|
Apply must-fix and should-fix changes (ask if unsure about any). Re-run checks.
|
||||||
|
|
||||||
|
## 5. Commit
|
||||||
|
|
||||||
|
After all checks pass and review issues are resolved, create a commit following the repository's commit conventions. Do not push unless asked.
|
||||||
Reference in New Issue
Block a user