بنقرة واحدة
writing-go
// Apply modern Go syntax guidelines based on project's Go version. Use when user ask for modern Go code guidelines.
// Apply modern Go syntax guidelines based on project's Go version. Use when user ask for modern Go code guidelines.
Post-edit toolchain to run after writing or modifying any `.go` file. Load whenever a task changes Go source.
Using the Kronk MCP service in the default agent configuration, where Kronk is wired directly into the host (OpenCode, Kilo, Pi) as an MCP server. Exposes `fuzzy_edit` (fallback for the host's exact-match edit when whitespace / line-endings cause it to miss) and `web_search` (Brave-powered). Load whenever you need web research, or when a host edit fails on exact matching.
The ONLY sanctioned path to the Kronk MCP service (`web_search`, `fuzzy_edit`) in the rote-routed config. Every command is a `rote ...` invocation in Bash. Load whenever you need web research, or when a host edit fails on exact-string matching and you need the rote-routed `fuzzy_edit` fallback.
| name | writing-go |
| description | Apply modern Go syntax guidelines based on project's Go version. Use when user ask for modern Go code guidelines. |
!grep -rh "^go " --include="go.mod" . 2>/dev/null | cut -d' ' -f2 | sort | uniq -c | sort -nr | head -1 | xargs | cut -d' ' -f2 | grep . || echo unknown
DO NOT search for go.mod files or try to detect the version yourself. Use ONLY the version shown above.
If version detected (not "unknown"):
If version is "unknown":
When writing Go code, use ALL features from this document up to the target version:
slices, maps, cmp) over legacy patternsAfter writing or editing any .go file, run these against the changed
package(s). All must pass; fix the code, do not suppress diagnostics.
gofmt -s -w <changed-files>
go vet ./<changed-pkg>/...
staticcheck ./<changed-pkg>/... # if installed
go build ./...
go test ./<changed-pkg>/...
go fix ./...
If the repo's AGENTS.md specifies required env vars, directories to
skip, or extra checks, follow those instead.
t.Context() not context.WithCancel(context.Background()) in tests.
ALWAYS use t.Context() when a test function needs a context.Before:
func TestFoo(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
result := doSomething(ctx)
}
After:
func TestFoo(t *testing.T) {
ctx := t.Context()
result := doSomething(ctx)
}
omitzero not omitempty in JSON struct tags.
ALWAYS use omitzero for time.Duration, time.Time, structs, slices, maps.Before:
type Config struct {
Timeout time.Duration `json:"timeout,omitempty"` // doesn't work for Duration!
}
After:
type Config struct {
Timeout time.Duration `json:"timeout,omitzero"`
}
b.Loop() not for i := 0; i < b.N; i++ in benchmarks.
ALWAYS use b.Loop() for the main loop in benchmark functions.Before:
func BenchmarkFoo(b *testing.B) {
for i := 0; i < b.N; i++ {
doWork()
}
}
After:
func BenchmarkFoo(b *testing.B) {
for b.Loop() {
doWork()
}
}
strings.SplitSeq not strings.Split when iterating.
ALWAYS use SplitSeq/FieldsSeq when iterating over split results in a for-range loop.Before:
for _, part := range strings.Split(s, ",") {
process(part)
}
After:
for part := range strings.SplitSeq(s, ",") {
process(part)
}
Also: strings.FieldsSeq, bytes.SplitSeq, bytes.FieldsSeq.
wg.Go(fn) not wg.Add(1) + go func() { defer wg.Done(); ... }().
ALWAYS use wg.Go() when spawning goroutines with sync.WaitGroup.Before:
var wg sync.WaitGroup
for _, item := range items {
wg.Add(1)
go func() {
defer wg.Done()
process(item)
}()
}
wg.Wait()
After:
var wg sync.WaitGroup
for _, item := range items {
wg.Go(func() {
process(item)
})
}
wg.Wait()
new(val) not x := val; &x — returns pointer to any value.
Go 1.26 extends new() to accept expressions, not just types.
Type is inferred: new(0) → *int, new("s") → *string, new(T{}) → *T.
DO NOT use x := val; &x pattern — always use new(val) directly.
DO NOT use redundant casts like new(int(0)) — just write new(0).
Common use case: struct fields with pointer types.Before:
timeout := 30
debug := true
cfg := Config{
Timeout: &timeout,
Debug: &debug,
}
After:
cfg := Config{
Timeout: new(30), // *int
Debug: new(true), // *bool
}
errors.AsType[T](err) not errors.As(err, &target).
ALWAYS use errors.AsType when checking if error matches a specific type.Before:
var pathErr *os.PathError
if errors.As(err, &pathErr) {
handle(pathErr)
}
After:
if pathErr, ok := errors.AsType[*os.PathError](err); ok {
handle(pathErr)
}