go-dev
Expert knowledge for Go development. Includes idiomatic patterns, error handling, testing, package naming, and build system detection (go toolchain, Bazel, Makefile). Use when writing, testing, or building Go code.
What this skill does
# Go Development Skill
Use this skill when the user **writes, modifies, tests, or builds Go code**.
## 1. Build System Detection
Detect the project's build system and use the appropriate commands. **Do not assume one build system over another.**
### Standard Go Toolchain (default)
Use when no `BUILD`, `BUILD.bazel`, or `WORKSPACE` files are present:
```bash
go build ./...
go test ./...
go test -race ./...
go vet ./...
```
### Bazel Projects
Use when `BUILD`, `BUILD.bazel`, or `WORKSPACE` files are present. **Do not use `go build` or `go test` directly** in Bazel projects — generated code (protobufs, etc.) may not resolve with the standard toolchain.
```bash
# Build and test
bazel build //path/to:target
bazel test //path/to:target_test
# Query targets
bazel query 'kind("go_library", //path/to/package/...)'
bazel query 'kind("go_test", //path/to/package/...)'
```
### Makefile Projects
Use when a `Makefile` is present with Go-related targets:
```bash
make build
make test
make lint
```
## 2. Linting
### Standard Go Toolchain
Use `go vet` and `golangci-lint` if available:
```bash
go vet ./...
golangci-lint run ./...
```
### Bazel Nogo
In Bazel projects, nogo analyzers run during `bazel build`. These are **compilation errors, not warnings**.
**Do not add `//nolint` directives carelessly:**
- **First**: Understand why the linter is complaining.
- **Second**: Fix the code to comply.
- **Only as last resort**: Add `//nolint:<analyzer>` with a comment explaining why.
```go
// BAD - suppressing without understanding
//nolint:ineffassign
x = computeValue()
// ACCEPTABLE - fix requires out-of-scope changes
//nolint:lintername // TODO: Requires updating callers across multiple packages
```
**When `//nolint` might be appropriate:**
- Fix requires significant unrelated changes out of scope
- Linter false positive (e.g., function used via reflection)
- Implementing an external interface that requires a specific pattern
**When `//nolint` is NOT appropriate:**
- "I don't understand why it's complaining"
- "It's easier than fixing"
- "It is needed in the future"
- The fix is within scope of the current change
### Common Analyzers
| Analyzer | Purpose |
|---------------|----------------------------------------|
| `godot` | Comments should end with a period. |
| `ineffassign` | Detects ineffectual assignments. |
| `staticcheck` | Various Go best practices. |
| `govet` | Unreachable code, format mismatches. |
| `errcheck` | Unchecked error return values. |
| `gosimple` | Suggests code simplifications. |
### Unused Interfaces? Delete Them
If a linter reports an unused interface, **delete the interface** rather than adding artificial usage:
```go
// BAD - artificial usage to silence the linter
var _ MyInterface = (*MyImpl)(nil)
// GOOD - just delete the unused interface entirely
```
Interfaces should be defined where they are used. If nothing uses it, it shouldn't exist.
## 3. Gazelle (Bazel Projects Only)
Use Gazelle to manage BUILD files when the project has Gazelle configured:
```bash
# Generate/update BUILD files for a directory
bazel run //:gazelle -- update path/to/package
# Fix BUILD files
bazel run //:gazelle -- fix path/to/package
# Update deps from go.mod
bazel run //:gazelle -- update-repos -from_file=go.mod
# Format BUILD files (if buildifier is configured)
bazel run //:buildifier
```
### Adding External Dependencies (Bazel)
1. Add to `go.mod`: `go get github.com/external/package`
2. Tidy: `go mod tidy`
3. Sync to Bazel: `bazel run //:gazelle -- update-repos -from_file=go.mod`
4. Regenerate BUILD files: `bazel run //:gazelle -- update path/to/package`
### Adding External Dependencies (Standard)
1. Add: `go get github.com/external/package`
2. Tidy: `go mod tidy`
## 4. Directory and Package Naming
**Directory names are hard to change later.** Get them right from the start.
### Go Package Naming Convention
| Rule | Good | Bad |
|--------------------|---------------|--------------------------|
| Lowercase only | `datastore` | `dataStore`, `DataStore` |
| No underscores | `loguploader` | `log_uploader` |
| No hyphens | `apiserver` | `api-server` |
| Short, clear names | `health` | `healthcheckservice` |
### Directory Structure
```
myproject/
├── cmd/ # Entry points
│ └── myapp/
│ └── main.go
├── internal/ # Private packages
│ └── auth/
│ ├── auth.go
│ └── auth_test.go
├── pkg/ # Public packages (optional)
│ └── client/
│ └── client.go
├── go.mod
└── go.sum
```
### Package Documentation
Put package-level documentation in a file named after the package or in `doc.go`:
```go
// Package health provides health checking functionality for services.
//
// It supports multiple health check types including liveness and readiness
// probes compatible with Kubernetes.
package health
```
## 5. Code Style
### Keep CLI Flag and Command Definitions in `main` or `cmd/` Packages
Library and business-logic packages must not import `flag`, `cobra`, `pflag`, `urfave/cli`, or similar CLI frameworks. CLI concerns belong in `main` or `cmd/` subpackages — library code receives configuration via function parameters or config structs.
```go
// BAD - library package imports flag
package auth
import "flag"
var verbose = flag.Bool("verbose", false, "enable verbose logging")
// GOOD - library package accepts config as a parameter
package auth
type Config struct {
Verbose bool
}
func NewService(cfg Config) *Service { ... }
```
**Why:**
- Keeps library packages reusable and testable without implicit global state.
- Makes dependency injection explicit — config flows down as parameters or structs.
- Avoids `init()`-time side effects from `flag.Parse()` scattered across packages.
**Cobra and subcommands:** Cobra-style projects typically define subcommands in `cmd/` subpackages (e.g., `cmd/serve/`, `cmd/migrate/`). This is fine — those packages are CLI entry points, not reusable libraries.
### Error Handling: Handle OR Return, Not Both
Either handle the error or return it, but not both. Logging at error level and returning duplicates logs.
```go
// BAD - logs error AND returns it (duplicates logs)
if err != nil {
slog.Error("operation failed", "reason", err)
return err
}
// GOOD - just return (let caller decide how to handle)
if err != nil {
return fmt.Errorf("operation failed: %w", err)
}
// GOOD - handle it here (don't return the error)
if err != nil {
slog.Error("operation failed, using fallback", "reason", err)
return fallbackValue, nil
}
```
**Exception:** Log at service/process boundaries where you don't control the caller.
### Error Wrapping
Use standard library patterns:
```go
// Wrap with context
return fmt.Errorf("failed to fetch user: %w", err)
// Join multiple independent errors
return errors.Join(err1, err2)
```
### Logging
Use `log/slog` for structured logging:
```go
slog.Info("starting operation", "param", val)
slog.Debug("detailed info for debugging", "state", s)
slog.Error("operation failed", "err", err, "userID", id)
```
### Interfaces
Define interfaces where they are **used**, not where implemented:
```go
// In the consumer package, not the provider
type Storage interface {
Save(ctx context.Context, data []byte) error
}
```
### Context
- First parameter of functions that do I/O or may be cancelled.
- Never store in structs.
- Use `context.WithTimeout` or `context.WithCancel` to manage lifetimes.
```go
func (s *Service) Process(ctx context.Context, req *Request) error {
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
return s.db.Query(ctx, req.ID)
}
```
## 6. Testing
### Run Tests with Race Detector
```bash
# Standard Go
go test -race ./...
# Bazel
bazel test //path/to:targRelated in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.