/modern-go
Modernize Go code by applying version-appropriate idioms and APIs (gofix-style transformations). Scans go.mod for the Go version, then transforms Go source files to use modern patterns—from Go 1.0 through 1.26+. Use when the user says "现代化","现代Go语言", "地道的", "idiomatic",
$ npx -y skills add smallnest/goal-workflow --skill modern-go --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/modern-go
Context preview
The summary Claude sees to decide when to auto-load this skill.
Modernize Go code by applying version-appropriate idioms and APIs (gofix-style transformations). Scans go.mod for the Go version, then transforms Go source files to use modern patterns—from Go 1.0 through 1.26+. Use when the user says "现代化","现代Go语言", "地道的", "idiomatic",
SKILL.md
modern-go.SKILL.mdname: modern-go
description: Modernize Go code by applying version-appropriate idioms and APIs (gofix-style transformations). Scans go.mod for the Go version, then transforms Go source files to use modern patterns—from Go 1.0 through 1.26+. Use when the user says "现代化","现代Go语言", "地道的", "idiomatic", "modernize", "modern-go", "update Go code", "gofix", or wants to upgrade Go idioms.
modern-go
Modernize Go source code by applying version-appropriate idioms, APIs, and language features. Works like `go fix` plus additional transformations curated from the Go team's modernize analysis passes and community best practices.
Usage
Invoke this skill when the user asks to modernize Go code. By default, modernize the entire project; the user may specify a file or directory instead.
When invoked: 1. Detect the project's Go version from `go.mod` (the `go` directive). 2. Find all `.go` files in the target scope (excluding `vendor/`, `.git/`, `testdata/`). 3. For each file, apply **all transformations for versions ≤ the project's Go version**, starting from the oldest to the newest. 4. After all transformations, print a summary of what was changed and what was skipped.
If the user specifies a file or directory, limit the scope to that path.
Transformation Catalog
Each transformation includes a **Go version** gate—only apply when the project's `go.mod` version ≥ that version. Never apply a transformation that requires a version higher than the project declares.
Go 1.0+ — `time.Since`
| Before | After | |---|---| | `time.Now().Sub(start)` | `time.Since(start)` |
// before
elapsed := time.Now().Sub(start)
// after
elapsed := time.Since(start)
Go 1.8+ — `time.Until`
| Before | After | |---|---| | `deadline.Sub(time.Now())` | `time.Until(deadline)` |
// before
remaining := deadline.Sub(time.Now())
// after
remaining := time.Until(deadline)
Go 1.10+ — `strings.Builder` (loop concatenation)
| Before | After | |---|---| | `s += item` in a loop | `var b strings.Builder; b.WriteString(item)` |
// before
s := ""
for _, item := range items {
s += item
}
// after
var b strings.Builder
for _, item := range items {
b.WriteString(item)
}
s := b.String()Only when `+=` concatenation happens inside a loop.
Go 1.13+ — `errors.Is`
| Before | After | |---|---| | `err == io.EOF` | `errors.Is(err, io.EOF)` |
// before
if err == io.EOF {
return
}
// after
if errors.Is(err, io.EOF) {
return
}Go 1.17+ — `//go:build` constraints (plusbuild)
| Before | After | |---|---| | `// +build linux` + `//go:build linux` (both present) | keep only `//go:build linux` |
// before
//go:build linux && amd64
// +build linux,amd64
package foo
// after
//go:build linux && amd64
package foo
The `plusbuild` modernizer removes obsolete `// +build` constraint lines once the equivalent `//go:build` line is present (the `//go:build` syntax landed in Go 1.17). Only strip the old line when a matching `//go:build` already exists — never drop the sole constraint.
Go 1.17+ — `unsafe.Add` / `unsafe.Slice` (unsafefuncs)
| Before | After | |---|---| | `unsafe.Pointer(uintptr(ptr) + uintptr(n))` | `unsafe.Add(ptr, n)` | | `(*[n]T)(unsafe.Pointer(p))[:]` slice construction | `unsafe.Slice(p, n)` |
// before — pointer arithmetic via uintptr
p2 := unsafe.Pointer(uintptr(ptr) + uintptr(offset))
// after
p2 := unsafe.Add(ptr, offset)
// before — building a slice from a base pointer
s := (*[1 << 30]byte)(unsafe.Pointer(p))[:n:n]
// after
s := unsafe.Slice(p, n)
The `unsafefuncs` modernizer (gopls v0.22.0) rewrites error-prone `uintptr` pointer math into `unsafe.Add` / `unsafe.Slice`, which the compiler and `go vet` understand as GC-safe.
Go 1.18+ — `any`
| Before | After | |---|---| | `interface{}` | `any` |
// before
func decode(v interface{}) error { ... }
// after
func decode(v any) error { ... }Go 1.18+ — `strings.Cut`
| Before | After | |---|---| | `i := strings.Index(s, sep); ... s[:i], s[i+len(sep):]` | `key, val, found := strings.Cut(s, sep)` |
// before
if i := strings.Index(s, "="); i >= 0 {
key, val := s[:i], s[i+1:]
}
// after
if key, val, found := strings.Cut(s, "="); found {
...
}Go 1.18+ — `bytes.Cut`
| Before | After | |---|---| | `i := bytes.Index(b, sep); ... b[:i], b[i+len(sep):]` | `before, after, found := bytes.Cut(b, sep)` |
// before
if i := bytes.Index(b, sep); i >= 0 {
before, after := b[:i], b[i+len(sep):]
}
// after
before, after, found := bytes.Cut(b, sep)Go 1.19+ — `fmt.Appendf`
| Before | After | |---|---| | `buf = append(buf, fmt.Sprintf(...)...)` | `buf = fmt.Appendf(buf, ...)` |
// before
buf = append(buf, fmt.Sprintf("x=%d", x)...)
// after
buf = fmt.Appendf(buf, "x=%d", x)Go 1.19+ — Type-safe atomics (atomictypes)
| Before | After | |---|---| | `atomic.StoreInt32(&v, 1)` / `atomic.LoadInt32(&v)` | `var v atomic.Int32; v.Store(1); v.Load()` | | `atomic.AddInt64(&v, 1)` | `var v atomic.Int64; v.Add(1)` | | `atomic.Value` + type assertion | `atomic.Pointer[T]` |
// before
var ready int32
atomic.StoreInt32(&ready, 1)
if atomic.LoadInt32(&ready) == 1 { ... }
// after
var ready atomic.Int32
ready.Store(1)
if ready.Load() == 1 { ... }// before
var cache atomic.Value
cache.Store(&Config{})
cfg := cache.Load().(*Config)
// after
var cache atomic.Pointer[Config]
cache.Store(&Config{})
cfg := cache.Load()The `atomictypes` modernizer (gopls v0.22.0, `AtomicTypesAnalyzer`) rewrites both the variable declaration and every call site. Typed wrappers (`atomic.Int32/Int64/Uint32/Uint64/Bool/Pointer[T]`) have identical performance but prevent accidental non-atomic access and fix 64-bit alignment crashes on 32-bit architectures.
Go 1.20+ — `strings.Clone`
| Before | After | |---|---| | `string([]byte(s))` | `strings.Clone(s)` |
// before
s2 := string([]byte(s)) // force
Read more
name: modern-go description: Modernize Go code by applying version-appropriate idioms and APIs (gofix-style transformations). Scans go.mod for the Go version, then transforms Go source files to use modern patterns—from Go 1.0 through 1.26+. Use when the user says "现代化","现代Go语言", "地道的", "idiomatic", "modernize", "modern-go", "update Go code", "gofix", or wants to upgrade Go idioms.
modern-go
Modernize Go source code by applying version-appropriate idioms, APIs, and language features. Works like `go fix` plus additional transformations curated from the Go team's modernize analysis passes and community best practices.
Usage
Invoke this skill when the user asks to modernize Go code. By default, modernize the entire project; the user may specify a file or directory instead.
When invoked: 1. Detect the project's Go version from `go.mod` (the `go` directive). 2. Find all `.go` files in the target scope (excluding `vendor/`, `.git/`, `testdata/`). 3. For each file, apply **all transformations for versions ≤ the project's Go version**, starting from the oldest to the newest. 4. After all transformations, print a summary of what was changed and what was skipped.
If the user specifies a file or directory, limit the scope to that path.
Transformation Catalog
Each transformation includes a **Go version** gate—only apply when the project's `go.mod` version ≥ that version. Never apply a transformation that requires a version higher than the project declares.
Go 1.0+ — `time.Since`
| Before | After | |---|---| | `time.Now().Sub(start)` | `time.Since(start)` |
// before elapsed := time.Now().Sub(start) // after elapsed := time.Since(start)
Go 1.8+ — `time.Until`
| Before | After | |---|---| | `deadline.Sub(time.Now())` | `time.Until(deadline)` |
// before remaining := deadline.Sub(time.Now()) // after remaining := time.Until(deadline)
Go 1.10+ — `strings.Builder` (loop concatenation)
| Before | After | |---|---| | `s += item` in a loop | `var b strings.Builder; b.WriteString(item)` |
// before
s := ""
for _, item := range items {
s += item
}
// after
var b strings.Builder
for _, item := range items {
b.WriteString(item)
}
s := b.String()Only when `+=` concatenation happens inside a loop.
Go 1.13+ — `errors.Is`
| Before | After | |---|---| | `err == io.EOF` | `errors.Is(err, io.EOF)` |
// before
if err == io.EOF {
return
}
// after
if errors.Is(err, io.EOF) {
return
}Go 1.17+ — `//go:build` constraints (plusbuild)
| Before | After | |---|---| | `// +build linux` + `//go:build linux` (both present) | keep only `//go:build linux` |
// before //go:build linux && amd64 // +build linux,amd64 package foo // after //go:build linux && amd64 package foo
The `plusbuild` modernizer removes obsolete `// +build` constraint lines once the equivalent `//go:build` line is present (the `//go:build` syntax landed in Go 1.17). Only strip the old line when a matching `//go:build` already exists — never drop the sole constraint.
Go 1.17+ — `unsafe.Add` / `unsafe.Slice` (unsafefuncs)
| Before | After | |---|---| | `unsafe.Pointer(uintptr(ptr) + uintptr(n))` | `unsafe.Add(ptr, n)` | | `(*[n]T)(unsafe.Pointer(p))[:]` slice construction | `unsafe.Slice(p, n)` |
// before — pointer arithmetic via uintptr p2 := unsafe.Pointer(uintptr(ptr) + uintptr(offset)) // after p2 := unsafe.Add(ptr, offset)
// before — building a slice from a base pointer s := (*[1 << 30]byte)(unsafe.Pointer(p))[:n:n] // after s := unsafe.Slice(p, n)
The `unsafefuncs` modernizer (gopls v0.22.0) rewrites error-prone `uintptr` pointer math into `unsafe.Add` / `unsafe.Slice`, which the compiler and `go vet` understand as GC-safe.
Go 1.18+ — `any`
| Before | After | |---|---| | `interface{}` | `any` |
// before
func decode(v interface{}) error { ... }
// after
func decode(v any) error { ... }Go 1.18+ — `strings.Cut`
| Before | After | |---|---| | `i := strings.Index(s, sep); ... s[:i], s[i+len(sep):]` | `key, val, found := strings.Cut(s, sep)` |
// before
if i := strings.Index(s, "="); i >= 0 {
key, val := s[:i], s[i+1:]
}
// after
if key, val, found := strings.Cut(s, "="); found {
...
}Go 1.18+ — `bytes.Cut`
| Before | After | |---|---| | `i := bytes.Index(b, sep); ... b[:i], b[i+len(sep):]` | `before, after, found := bytes.Cut(b, sep)` |
// before
if i := bytes.Index(b, sep); i >= 0 {
before, after := b[:i], b[i+len(sep):]
}
// after
before, after, found := bytes.Cut(b, sep)Go 1.19+ — `fmt.Appendf`
| Before | After | |---|---| | `buf = append(buf, fmt.Sprintf(...)...)` | `buf = fmt.Appendf(buf, ...)` |
// before
buf = append(buf, fmt.Sprintf("x=%d", x)...)
// after
buf = fmt.Appendf(buf, "x=%d", x)Go 1.19+ — Type-safe atomics (atomictypes)
| Before | After | |---|---| | `atomic.StoreInt32(&v, 1)` / `atomic.LoadInt32(&v)` | `var v atomic.Int32; v.Store(1); v.Load()` | | `atomic.AddInt64(&v, 1)` | `var v atomic.Int64; v.Add(1)` | | `atomic.Value` + type assertion | `atomic.Pointer[T]` |
// before
var ready int32
atomic.StoreInt32(&ready, 1)
if atomic.LoadInt32(&ready) == 1 { ... }
// after
var ready atomic.Int32
ready.Store(1)
if ready.Load() == 1 { ... }// before
var cache atomic.Value
cache.Store(&Config{})
cfg := cache.Load().(*Config)
// after
var cache atomic.Pointer[Config]
cache.Store(&Config{})
cfg := cache.Load()The `atomictypes` modernizer (gopls v0.22.0, `AtomicTypesAnalyzer`) rewrites both the variable declaration and every call site. Typed wrappers (`atomic.Int32/Int64/Uint32/Uint64/Bool/Pointer[T]`) have identical performance but prevent accidental non-atomic access and fix 64-bit alignment crashes on 32-bit architectures.
Go 1.20+ — `strings.Clone`
| Before | After | |---|---| | `string([]byte(s))` | `strings.Clone(s)` |
// before s2 := string([]byte(s)) // force
An AI-driven development workflow — from PRD to shipped code, all within Claude Code.
Other skills on goal-workflow-skills.
- /article-icons
Illustrate an article (Markdown, HTML, etc.) with animated-style icons from itshover.com/icons. Fetches icons as clean inline SVG and places them at section headings, key concepts, lists, and callouts. Triggers on: /article-icons, 配图, 给文章配图标, add icons to article, illustrate
Open skill - /code-to-spec
Reverse-engineer a SPEC document from an existing project. Analyzes code, config, tests, and structure to produce a comprehensive specification. Triggers on: code-to-spec, reverse spec, generate spec, 逆向规格, 生成规格文档, 生成设计文档, 生成设计方案, extract spec, document this project, what does
Open skill - /graph
Graph engineering for parallel task execution: convert a task, PRD, SPEC, or issue set into a dependency graph (DAG), layer it into supersteps, then implement each independent node concurrently with subagents — each node runs /goal → /review-it → /ship-it in an isolated git
Open skill - /humanize-it
对指定文档进行去 AI 味的改写。自动选择最合适的人性化策略(humanizer-zh / humanize-chinese / technical-writing), 迭代改写直到效果达标或迭代 42 次为止。适用于中文文本的去 AI 化处理,包括通用文章、技术文档、学术论文等。 Use when user says: "humanize this", "去AI味", "降AIGC", "人性化改写", "改成人话", "去除AI痕迹", "humanize document", "make text human-like", "去机器味",
Open skill - /insight-diagram
为任意项目生成 UML 图、架构图和流程图。分析代码库后让用户选择要生成的图表类型,使用 architecture-diagram skill 渲染为 HTML+SVG,保存到 docs/ 目录。适用于任何软件项目的文档可视化。
Open skill - /listenhub-tts
使用 ListenHub API 将文本转换为语音(TTS)。支持三种模式:快速合成(/v1/tts)、 多角色脚本(/v1/speech)、长文本流式合成(/v1/flow-speech/episodes)。 音色未指定时自动获取音色列表供用户选择,默认使用 chat-girl-105-cn(晓曼)。 Use when user says: "tts", "text to speech", "语音合成", "文字转语音", "朗读", "生成语音", "生成音频", "转音频", "text to audio"
Open skill

