From swe-workbench
Go idioms — error handling, concurrency, and standard library usage. Auto-load when working with .go files, go.mod, go.sum, or when the user mentions Go, Golang, goroutines, channels, interfaces, context, or error wrapping.
How this skill is triggered — by the user, by Claude, or both
Slash command
/swe-workbench:language-goThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- Return `error`; do not `panic` across package boundaries.
error; do not panic across package boundaries.fmt.Errorf("doing X: %w", err) to preserve the chain.errors.Is and errors.As. Never string-match messages.var ErrNotFound = errors.New(...)) for expected cases; typed errors when callers need structured data.if err != nil {
return fmt.Errorf("load user %s: %w", id, err)
}
io.Reader, io.Closer).context.Context plumbs cancellation and deadlines — first parameter, named ctx.sync.Mutex is often simpler than a goroutine.errgroup.Group for structured concurrency with error propagation.g, ctx := errgroup.WithContext(ctx)
for _, job := range jobs {
job := job
g.Go(func() error { return process(ctx, job) })
}
if err := g.Wait(); err != nil { return err }
ctx is the first parameter of any blocking or IO function.context.Context in a struct field.context.Value for required parameters — only cross-cutting concerns like request IDs.// Code generated ... DO NOT EDIT. header means the file is output, not source. Never hand-edit it — edits are clobbered on the next run and drift from their input.go generate ./... (or the tool directly). Commit the regenerated file with the source change.stringer, mockgen, sqlc, protoc-gen-go, and google/wire.google/wire — detected by a wire.go tagged //go:build wireinject plus a wire_gen.go carrying the Wire DO NOT EDIT. header. To change dependency injection:
wire.go only — never wire_gen.go.go generate ./... (or wire ./...), then stage the updated wire_gen.go. If go generate ./... produces no diff, wire.go likely lacks a //go:generate wire directive — run wire ./... directly.//go:build wireinject
// wire.go — edit here: provider sets and injector signatures.
func InitApp(ctx context.Context) (*App, error) {
wire.Build(configSet, storeSet, NewApp)
return nil, nil // wire fills the body in wire_gen.go
}
goimports -w .gofmt -w . (redundant if running goimports; keep for explicit CI parity)go vet ./... + golangci-lint rungo test ./... (see Testing below)t.Run(name, ...) for subtests.t.Cleanup beats defer for shared fixtures.httptest.Server for HTTP; testing/iotest for edge IO.for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if got := Add(c.a, c.b); got != c.want {
t.Errorf("Add(%d,%d) = %d, want %d", c.a, c.b, got, c.want)
}
})
}
util, common, helpers. Name by the domain thing it owns.if err := do(); err != nil { ... } — keep errors close to their cause.defer for cleanup; defer in a loop accumulates.any over interface{} in new code.slices, maps, cmp from stdlib over hand-rolled helpers.panic as flow control.npx claudepluginhub lugassawan/swe-workbench --plugin swe-workbenchCreates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.