devflow-kit 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +35 -11
  3. package/dist/cli.js +5 -1
  4. package/dist/commands/ambient.d.ts +18 -0
  5. package/dist/commands/ambient.js +136 -0
  6. package/dist/commands/init.d.ts +2 -0
  7. package/dist/commands/init.js +97 -10
  8. package/dist/commands/memory.d.ts +22 -0
  9. package/dist/commands/memory.js +175 -0
  10. package/dist/commands/uninstall.js +72 -5
  11. package/dist/plugins.js +74 -3
  12. package/dist/utils/post-install.d.ts +12 -0
  13. package/dist/utils/post-install.js +82 -1
  14. package/dist/utils/safe-delete-install.d.ts +7 -0
  15. package/dist/utils/safe-delete-install.js +40 -5
  16. package/package.json +2 -1
  17. package/plugins/devflow-accessibility/.claude-plugin/plugin.json +15 -0
  18. package/plugins/devflow-ambient/.claude-plugin/plugin.json +7 -0
  19. package/plugins/devflow-ambient/README.md +49 -0
  20. package/plugins/devflow-ambient/commands/ambient.md +110 -0
  21. package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +89 -0
  22. package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +68 -0
  23. package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +1 -1
  24. package/plugins/devflow-code-review/.claude-plugin/plugin.json +1 -4
  25. package/plugins/devflow-code-review/agents/reviewer.md +8 -0
  26. package/plugins/devflow-code-review/commands/code-review-teams.md +11 -1
  27. package/plugins/devflow-code-review/commands/code-review.md +12 -2
  28. package/plugins/devflow-core-skills/.claude-plugin/plugin.json +3 -6
  29. package/plugins/devflow-core-skills/skills/docs-framework/SKILL.md +10 -6
  30. package/plugins/devflow-core-skills/skills/test-driven-development/SKILL.md +139 -0
  31. package/plugins/devflow-core-skills/skills/test-driven-development/references/rationalization-prevention.md +111 -0
  32. package/plugins/devflow-debug/.claude-plugin/plugin.json +1 -1
  33. package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +15 -0
  34. package/plugins/devflow-go/.claude-plugin/plugin.json +15 -0
  35. package/plugins/devflow-go/skills/go/SKILL.md +187 -0
  36. package/plugins/devflow-go/skills/go/references/concurrency.md +312 -0
  37. package/plugins/devflow-go/skills/go/references/detection.md +129 -0
  38. package/plugins/devflow-go/skills/go/references/patterns.md +232 -0
  39. package/plugins/devflow-go/skills/go/references/violations.md +205 -0
  40. package/plugins/devflow-implement/.claude-plugin/plugin.json +1 -3
  41. package/plugins/devflow-implement/agents/coder.md +11 -6
  42. package/plugins/devflow-java/.claude-plugin/plugin.json +15 -0
  43. package/plugins/devflow-java/skills/java/SKILL.md +183 -0
  44. package/plugins/devflow-java/skills/java/references/detection.md +120 -0
  45. package/plugins/devflow-java/skills/java/references/modern-java.md +270 -0
  46. package/plugins/devflow-java/skills/java/references/patterns.md +235 -0
  47. package/plugins/devflow-java/skills/java/references/violations.md +213 -0
  48. package/plugins/devflow-python/.claude-plugin/plugin.json +15 -0
  49. package/plugins/devflow-python/skills/python/SKILL.md +188 -0
  50. package/plugins/devflow-python/skills/python/references/async.md +220 -0
  51. package/plugins/devflow-python/skills/python/references/detection.md +128 -0
  52. package/plugins/devflow-python/skills/python/references/patterns.md +226 -0
  53. package/plugins/devflow-python/skills/python/references/violations.md +204 -0
  54. package/plugins/devflow-react/.claude-plugin/plugin.json +15 -0
  55. package/plugins/{devflow-core-skills → devflow-react}/skills/react/SKILL.md +1 -1
  56. package/plugins/{devflow-core-skills → devflow-react}/skills/react/references/patterns.md +3 -3
  57. package/plugins/devflow-resolve/.claude-plugin/plugin.json +1 -1
  58. package/plugins/devflow-rust/.claude-plugin/plugin.json +15 -0
  59. package/plugins/devflow-rust/skills/rust/SKILL.md +193 -0
  60. package/plugins/devflow-rust/skills/rust/references/detection.md +131 -0
  61. package/plugins/devflow-rust/skills/rust/references/ownership.md +242 -0
  62. package/plugins/devflow-rust/skills/rust/references/patterns.md +210 -0
  63. package/plugins/devflow-rust/skills/rust/references/violations.md +191 -0
  64. package/plugins/devflow-self-review/.claude-plugin/plugin.json +1 -1
  65. package/plugins/devflow-specify/.claude-plugin/plugin.json +1 -1
  66. package/plugins/devflow-typescript/.claude-plugin/plugin.json +15 -0
  67. package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/patterns.md +3 -3
  68. package/scripts/hooks/ambient-prompt.sh +48 -0
  69. package/scripts/hooks/background-memory-update.sh +49 -8
  70. package/scripts/hooks/ensure-memory-gitignore.sh +17 -0
  71. package/scripts/hooks/pre-compact-memory.sh +12 -6
  72. package/scripts/hooks/session-start-memory.sh +50 -8
  73. package/scripts/hooks/stop-update-memory.sh +10 -6
  74. package/shared/agents/coder.md +11 -6
  75. package/shared/agents/reviewer.md +8 -0
  76. package/shared/skills/ambient-router/SKILL.md +89 -0
  77. package/shared/skills/ambient-router/references/skill-catalog.md +68 -0
  78. package/shared/skills/docs-framework/SKILL.md +10 -6
  79. package/shared/skills/go/SKILL.md +187 -0
  80. package/shared/skills/go/references/concurrency.md +312 -0
  81. package/shared/skills/go/references/detection.md +129 -0
  82. package/shared/skills/go/references/patterns.md +232 -0
  83. package/shared/skills/go/references/violations.md +205 -0
  84. package/shared/skills/java/SKILL.md +183 -0
  85. package/shared/skills/java/references/detection.md +120 -0
  86. package/shared/skills/java/references/modern-java.md +270 -0
  87. package/shared/skills/java/references/patterns.md +235 -0
  88. package/shared/skills/java/references/violations.md +213 -0
  89. package/shared/skills/python/SKILL.md +188 -0
  90. package/shared/skills/python/references/async.md +220 -0
  91. package/shared/skills/python/references/detection.md +128 -0
  92. package/shared/skills/python/references/patterns.md +226 -0
  93. package/shared/skills/python/references/violations.md +204 -0
  94. package/shared/skills/react/SKILL.md +1 -1
  95. package/shared/skills/react/references/patterns.md +3 -3
  96. package/shared/skills/rust/SKILL.md +193 -0
  97. package/shared/skills/rust/references/detection.md +131 -0
  98. package/shared/skills/rust/references/ownership.md +242 -0
  99. package/shared/skills/rust/references/patterns.md +210 -0
  100. package/shared/skills/rust/references/violations.md +191 -0
  101. package/shared/skills/test-driven-development/SKILL.md +139 -0
  102. package/shared/skills/test-driven-development/references/rationalization-prevention.md +111 -0
  103. package/shared/skills/typescript/references/patterns.md +3 -3
  104. package/src/templates/managed-settings.json +14 -0
  105. package/plugins/devflow-code-review/skills/react/SKILL.md +0 -276
  106. package/plugins/devflow-code-review/skills/react/references/patterns.md +0 -1331
  107. package/plugins/devflow-core-skills/skills/accessibility/SKILL.md +0 -229
  108. package/plugins/devflow-core-skills/skills/accessibility/references/detection.md +0 -171
  109. package/plugins/devflow-core-skills/skills/accessibility/references/patterns.md +0 -670
  110. package/plugins/devflow-core-skills/skills/accessibility/references/violations.md +0 -419
  111. package/plugins/devflow-core-skills/skills/frontend-design/SKILL.md +0 -254
  112. package/plugins/devflow-core-skills/skills/frontend-design/references/detection.md +0 -184
  113. package/plugins/devflow-core-skills/skills/frontend-design/references/patterns.md +0 -511
  114. package/plugins/devflow-core-skills/skills/frontend-design/references/violations.md +0 -453
  115. package/plugins/devflow-core-skills/skills/react/references/violations.md +0 -565
  116. package/plugins/devflow-implement/skills/accessibility/SKILL.md +0 -229
  117. package/plugins/devflow-implement/skills/accessibility/references/detection.md +0 -171
  118. package/plugins/devflow-implement/skills/accessibility/references/patterns.md +0 -670
  119. package/plugins/devflow-implement/skills/accessibility/references/violations.md +0 -419
  120. package/plugins/devflow-implement/skills/frontend-design/SKILL.md +0 -254
  121. package/plugins/devflow-implement/skills/frontend-design/references/detection.md +0 -184
  122. package/plugins/devflow-implement/skills/frontend-design/references/patterns.md +0 -511
  123. package/plugins/devflow-implement/skills/frontend-design/references/violations.md +0 -453
  124. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/SKILL.md +0 -0
  125. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/detection.md +0 -0
  126. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/patterns.md +0 -0
  127. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/violations.md +0 -0
  128. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/SKILL.md +0 -0
  129. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/detection.md +0 -0
  130. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/patterns.md +0 -0
  131. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/violations.md +0 -0
  132. /package/plugins/{devflow-code-review → devflow-react}/skills/react/references/violations.md +0 -0
  133. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/SKILL.md +0 -0
  134. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/violations.md +0 -0
@@ -0,0 +1,187 @@
1
+ ---
2
+ name: go
3
+ description: This skill should be used when the user works with Go files (.go), asks about "error handling", "interfaces", "goroutines", "channels", "packages", or discusses Go idioms and concurrency. Provides patterns for error handling, interface design, concurrency, and package organization.
4
+ user-invocable: false
5
+ allowed-tools: Read, Grep, Glob
6
+ activation:
7
+ file-patterns:
8
+ - "**/*.go"
9
+ exclude:
10
+ - "vendor/**"
11
+ ---
12
+
13
+ # Go Patterns
14
+
15
+ Reference for Go-specific patterns, idioms, and best practices.
16
+
17
+ ## Iron Law
18
+
19
+ > **ERRORS ARE VALUES**
20
+ >
21
+ > Never ignore errors. `if err != nil` is correctness, not boilerplate. Every error
22
+ > return must be checked, wrapped with context, or explicitly documented as intentionally
23
+ > ignored with `_ = fn()`. Silent error swallowing causes cascading failures.
24
+
25
+ ## When This Skill Activates
26
+
27
+ - Working with Go codebases
28
+ - Designing interfaces and packages
29
+ - Implementing concurrent code
30
+ - Handling errors
31
+ - Structuring Go projects
32
+
33
+ ---
34
+
35
+ ## Error Handling
36
+
37
+ ### Wrap Errors with Context
38
+
39
+ ```go
40
+ // BAD: return err
41
+ // GOOD: return fmt.Errorf("reading config %s: %w", path, err)
42
+ ```
43
+
44
+ ### Sentinel Errors for Expected Conditions
45
+
46
+ ```go
47
+ var ErrNotFound = errors.New("not found")
48
+
49
+ func FindUser(id string) (*User, error) {
50
+ u, err := db.Get(id)
51
+ if err != nil {
52
+ return nil, fmt.Errorf("finding user %s: %w", id, err)
53
+ }
54
+ if u == nil {
55
+ return nil, ErrNotFound
56
+ }
57
+ return u, nil
58
+ }
59
+ // Caller: if errors.Is(err, ErrNotFound) { ... }
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Interface Design
65
+
66
+ ### Accept Interfaces, Return Structs
67
+
68
+ ```go
69
+ // BAD: func NewService(repo *PostgresRepo) *Service
70
+ // GOOD: func NewService(repo Repository) *Service
71
+
72
+ type Repository interface {
73
+ FindByID(ctx context.Context, id string) (*Entity, error)
74
+ Save(ctx context.Context, entity *Entity) error
75
+ }
76
+ ```
77
+
78
+ ### Keep Interfaces Small
79
+
80
+ ```go
81
+ // BAD: 10-method interface
82
+ // GOOD: single-method interfaces composed as needed
83
+ type Reader interface { Read(p []byte) (n int, err error) }
84
+ type Writer interface { Write(p []byte) (n int, err error) }
85
+ type ReadWriter interface { Reader; Writer }
86
+ ```
87
+
88
+ ---
89
+
90
+ ## Concurrency
91
+
92
+ ### Use Context for Cancellation
93
+
94
+ ```go
95
+ func Process(ctx context.Context, items []Item) error {
96
+ g, ctx := errgroup.WithContext(ctx)
97
+ for _, item := range items {
98
+ g.Go(func() error {
99
+ return processItem(ctx, item)
100
+ })
101
+ }
102
+ return g.Wait()
103
+ }
104
+ ```
105
+
106
+ ### Channel Direction
107
+
108
+ ```go
109
+ // Declare direction in function signatures
110
+ func producer(ch chan<- int) { ch <- 42 }
111
+ func consumer(ch <-chan int) { v := <-ch; _ = v }
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Package Design
117
+
118
+ ### Organize by Domain, Not by Type
119
+
120
+ ```go
121
+ // BAD: models/, controllers/, services/
122
+ // GOOD: user/, order/, payment/
123
+ ```
124
+
125
+ ### Export Only What's Needed
126
+
127
+ ```go
128
+ // Internal helpers stay unexported (lowercase)
129
+ func (s *Service) validate(u *User) error { ... }
130
+
131
+ // Public API is exported (uppercase)
132
+ func (s *Service) CreateUser(ctx context.Context, req CreateUserReq) (*User, error) { ... }
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Zero Values
138
+
139
+ ```go
140
+ // Use zero values as valid defaults
141
+ var mu sync.Mutex // Ready to use
142
+ var buf bytes.Buffer // Ready to use
143
+ var wg sync.WaitGroup // Ready to use
144
+
145
+ // Design types with useful zero values
146
+ type Config struct {
147
+ Timeout time.Duration // zero = no timeout
148
+ Retries int // zero = no retries
149
+ }
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Anti-Patterns
155
+
156
+ | Pattern | Bad | Good |
157
+ |---------|-----|------|
158
+ | Ignoring error | `val, _ := fn()` | `val, err := fn(); if err != nil { ... }` |
159
+ | Naked return | `return` in named returns | Explicit `return val, err` |
160
+ | init() abuse | Complex `init()` functions | Explicit initialization in `main()` or constructors |
161
+ | Interface pollution | Defining interfaces before use | Define interfaces at the consumer site |
162
+ | Goroutine leak | `go fn()` without lifecycle | Use context, errgroup, or done channels |
163
+
164
+ ---
165
+
166
+ ## Extended References
167
+
168
+ For additional patterns and examples:
169
+ - `references/violations.md` - Common Go violations
170
+ - `references/patterns.md` - Extended Go patterns
171
+ - `references/detection.md` - Detection patterns for Go issues
172
+ - `references/concurrency.md` - Advanced concurrency patterns
173
+
174
+ ---
175
+
176
+ ## Checklist
177
+
178
+ - [ ] All errors checked or explicitly ignored with `_ =`
179
+ - [ ] Errors wrapped with `fmt.Errorf("context: %w", err)`
180
+ - [ ] Interfaces defined at consumer, not producer
181
+ - [ ] Interfaces kept small (1-3 methods)
182
+ - [ ] Context passed as first parameter
183
+ - [ ] Goroutines have clear lifecycle/cancellation
184
+ - [ ] Channel direction specified in signatures
185
+ - [ ] Zero values are useful defaults
186
+ - [ ] Packages organized by domain
187
+ - [ ] No `init()` with side effects
@@ -0,0 +1,312 @@
1
+ # Go Concurrency Patterns
2
+
3
+ Advanced concurrency patterns for Go. Reference from main SKILL.md.
4
+
5
+ ## errgroup for Structured Concurrency
6
+
7
+ ```go
8
+ import "golang.org/x/sync/errgroup"
9
+
10
+ func FetchAll(ctx context.Context, urls []string) ([]Response, error) {
11
+ g, ctx := errgroup.WithContext(ctx)
12
+ responses := make([]Response, len(urls))
13
+
14
+ for i, url := range urls {
15
+ g.Go(func() error {
16
+ resp, err := fetch(ctx, url)
17
+ if err != nil {
18
+ return fmt.Errorf("fetching %s: %w", url, err)
19
+ }
20
+ responses[i] = resp // Safe: each goroutine writes to unique index
21
+ return nil
22
+ })
23
+ }
24
+
25
+ if err := g.Wait(); err != nil {
26
+ return nil, err
27
+ }
28
+ return responses, nil
29
+ }
30
+ ```
31
+
32
+ ### errgroup with Concurrency Limit
33
+
34
+ ```go
35
+ func ProcessItems(ctx context.Context, items []Item) error {
36
+ g, ctx := errgroup.WithContext(ctx)
37
+ g.SetLimit(10) // Maximum 10 concurrent goroutines
38
+
39
+ for _, item := range items {
40
+ g.Go(func() error {
41
+ return processItem(ctx, item)
42
+ })
43
+ }
44
+
45
+ return g.Wait()
46
+ }
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Worker Pool
52
+
53
+ ```go
54
+ func WorkerPool(ctx context.Context, jobs <-chan Job, workers int) <-chan Result {
55
+ results := make(chan Result, workers)
56
+
57
+ var wg sync.WaitGroup
58
+ for range workers {
59
+ wg.Add(1)
60
+ go func() {
61
+ defer wg.Done()
62
+ for {
63
+ select {
64
+ case job, ok := <-jobs:
65
+ if !ok {
66
+ return
67
+ }
68
+ results <- process(ctx, job)
69
+ case <-ctx.Done():
70
+ return
71
+ }
72
+ }
73
+ }()
74
+ }
75
+
76
+ go func() {
77
+ wg.Wait()
78
+ close(results)
79
+ }()
80
+
81
+ return results
82
+ }
83
+
84
+ // Usage
85
+ jobs := make(chan Job, 100)
86
+ results := WorkerPool(ctx, jobs, 5)
87
+
88
+ // Send jobs
89
+ go func() {
90
+ defer close(jobs)
91
+ for _, j := range allJobs {
92
+ jobs <- j
93
+ }
94
+ }()
95
+
96
+ // Collect results
97
+ for r := range results {
98
+ fmt.Println(r)
99
+ }
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Fan-Out / Fan-In
105
+
106
+ ```go
107
+ // Fan-out: one source, multiple workers
108
+ func fanOut(ctx context.Context, input <-chan int, workers int) []<-chan int {
109
+ channels := make([]<-chan int, workers)
110
+ for i := range workers {
111
+ channels[i] = worker(ctx, input)
112
+ }
113
+ return channels
114
+ }
115
+
116
+ func worker(ctx context.Context, input <-chan int) <-chan int {
117
+ out := make(chan int)
118
+ go func() {
119
+ defer close(out)
120
+ for n := range input {
121
+ select {
122
+ case out <- n * n:
123
+ case <-ctx.Done():
124
+ return
125
+ }
126
+ }
127
+ }()
128
+ return out
129
+ }
130
+
131
+ // Fan-in: multiple sources, one destination
132
+ func fanIn(ctx context.Context, channels ...<-chan int) <-chan int {
133
+ merged := make(chan int)
134
+ var wg sync.WaitGroup
135
+
136
+ for _, ch := range channels {
137
+ wg.Add(1)
138
+ go func() {
139
+ defer wg.Done()
140
+ for val := range ch {
141
+ select {
142
+ case merged <- val:
143
+ case <-ctx.Done():
144
+ return
145
+ }
146
+ }
147
+ }()
148
+ }
149
+
150
+ go func() {
151
+ wg.Wait()
152
+ close(merged)
153
+ }()
154
+
155
+ return merged
156
+ }
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Select with Timeout
162
+
163
+ ```go
164
+ func fetchWithTimeout(ctx context.Context, url string) ([]byte, error) {
165
+ ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
166
+ defer cancel()
167
+
168
+ ch := make(chan result, 1)
169
+ go func() {
170
+ data, err := doFetch(ctx, url)
171
+ ch <- result{data, err}
172
+ }()
173
+
174
+ select {
175
+ case r := <-ch:
176
+ return r.data, r.err
177
+ case <-ctx.Done():
178
+ return nil, fmt.Errorf("fetch %s: %w", url, ctx.Err())
179
+ }
180
+ }
181
+
182
+ type result struct {
183
+ data []byte
184
+ err error
185
+ }
186
+ ```
187
+
188
+ ### Select for Multiple Sources
189
+
190
+ ```go
191
+ func merge(ctx context.Context, primary, fallback <-chan Event) <-chan Event {
192
+ out := make(chan Event)
193
+ go func() {
194
+ defer close(out)
195
+ for {
196
+ select {
197
+ case e, ok := <-primary:
198
+ if !ok {
199
+ return
200
+ }
201
+ out <- e
202
+ case e, ok := <-fallback:
203
+ if !ok {
204
+ return
205
+ }
206
+ out <- e
207
+ case <-ctx.Done():
208
+ return
209
+ }
210
+ }
211
+ }()
212
+ return out
213
+ }
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Mutex vs Channels
219
+
220
+ ### Use Mutex When
221
+
222
+ ```go
223
+ // Protecting shared state with simple read/write
224
+ type SafeCounter struct {
225
+ mu sync.RWMutex
226
+ v map[string]int
227
+ }
228
+
229
+ func (c *SafeCounter) Inc(key string) {
230
+ c.mu.Lock()
231
+ defer c.mu.Unlock()
232
+ c.v[key]++
233
+ }
234
+
235
+ func (c *SafeCounter) Get(key string) int {
236
+ c.mu.RLock()
237
+ defer c.mu.RUnlock()
238
+ return c.v[key]
239
+ }
240
+ ```
241
+
242
+ ### Use Channels When
243
+
244
+ ```go
245
+ // Communicating between goroutines / coordinating work
246
+ func pipeline(ctx context.Context, input []int) <-chan int {
247
+ out := make(chan int)
248
+ go func() {
249
+ defer close(out)
250
+ for _, n := range input {
251
+ select {
252
+ case out <- transform(n):
253
+ case <-ctx.Done():
254
+ return
255
+ }
256
+ }
257
+ }()
258
+ return out
259
+ }
260
+ ```
261
+
262
+ ### Decision Guide
263
+
264
+ | Scenario | Use |
265
+ |----------|-----|
266
+ | Guarding shared state | `sync.Mutex` or `sync.RWMutex` |
267
+ | Passing ownership of data | Channels |
268
+ | Coordinating goroutine lifecycle | `context.Context` + channels |
269
+ | Waiting for N goroutines | `sync.WaitGroup` or `errgroup` |
270
+ | One-time initialization | `sync.Once` |
271
+ | Concurrent map access | `sync.Map` (high read, low write) |
272
+
273
+ ---
274
+
275
+ ## sync.Once for Initialization
276
+
277
+ ```go
278
+ type Client struct {
279
+ once sync.Once
280
+ conn *grpc.ClientConn
281
+ err error
282
+ }
283
+
284
+ func (c *Client) connection() (*grpc.ClientConn, error) {
285
+ c.once.Do(func() {
286
+ // requires: "google.golang.org/grpc/credentials/insecure"
287
+ c.conn, c.err = grpc.Dial("localhost:50051",
288
+ grpc.WithTransportCredentials(insecure.NewCredentials()))
289
+ })
290
+ return c.conn, c.err
291
+ }
292
+ ```
293
+
294
+ ---
295
+
296
+ ## Rate Limiting
297
+
298
+ ```go
299
+ func rateLimited(ctx context.Context, items []Item, rps int) error {
300
+ limiter := rate.NewLimiter(rate.Limit(rps), 1)
301
+
302
+ for _, item := range items {
303
+ if err := limiter.Wait(ctx); err != nil {
304
+ return fmt.Errorf("rate limiter: %w", err)
305
+ }
306
+ if err := process(ctx, item); err != nil {
307
+ return fmt.Errorf("processing item %s: %w", item.ID, err)
308
+ }
309
+ }
310
+ return nil
311
+ }
312
+ ```
@@ -0,0 +1,129 @@
1
+ # Go Issue Detection
2
+
3
+ Grep and regex patterns for finding common Go issues. Reference from main SKILL.md.
4
+
5
+ ## Error Handling Detection
6
+
7
+ ### Unchecked Errors
8
+
9
+ ```bash
10
+ # Find ignored error returns (blank identifier)
11
+ grep -rn ', _ := ' --include='*.go' .
12
+ grep -rn ', _ = ' --include='*.go' .
13
+
14
+ # Find bare error returns without wrapping
15
+ grep -rn 'return.*err$' --include='*.go' . | grep -v 'fmt.Errorf' | grep -v ':= err'
16
+
17
+ # Find deferred calls that return errors (Close, Flush, Sync)
18
+ grep -rn 'defer.*\.Close()' --include='*.go' .
19
+ grep -rn 'defer.*\.Flush()' --include='*.go' .
20
+ ```
21
+
22
+ ### Missing Error Context
23
+
24
+ ```bash
25
+ # Find raw error returns (no wrapping)
26
+ grep -rn 'return nil, err$' --include='*.go' .
27
+ grep -rn 'return err$' --include='*.go' .
28
+ ```
29
+
30
+ ---
31
+
32
+ ## Concurrency Detection
33
+
34
+ ### Goroutine Without Context
35
+
36
+ ```bash
37
+ # Find goroutines that don't reference ctx
38
+ grep -rn 'go func()' --include='*.go' .
39
+
40
+ # Find goroutines without done/cancel/ctx
41
+ grep -B5 -A10 'go func' --include='*.go' . | grep -L 'ctx\|done\|cancel\|errgroup'
42
+ ```
43
+
44
+ ### Potential Goroutine Leaks
45
+
46
+ ```bash
47
+ # Find unbuffered channel creation followed by goroutine
48
+ grep -rn 'make(chan ' --include='*.go' . | grep -v ', [0-9]'
49
+
50
+ # Find goroutines with infinite loops
51
+ grep -A5 'go func' --include='*.go' . | grep 'for {'
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Interface Detection
57
+
58
+ ### Empty Interface Usage
59
+
60
+ ```bash
61
+ # Find empty interface (pre-1.18 style)
62
+ grep -rn 'interface{}' --include='*.go' .
63
+
64
+ # Find any type (1.18+ style) - may be intentional, review context
65
+ grep -rn '\bany\b' --include='*.go' . | grep -v '_test.go' | grep -v 'vendor/'
66
+ ```
67
+
68
+ ### Large Interfaces
69
+
70
+ ```bash
71
+ # Find interface declarations and count methods (interfaces > 5 methods)
72
+ grep -B1 -A20 'type.*interface {' --include='*.go' .
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Panic Detection
78
+
79
+ ### Panic in Library Code
80
+
81
+ ```bash
82
+ # Find panic calls outside main/test
83
+ grep -rn 'panic(' --include='*.go' . | grep -v '_test.go' | grep -v 'main.go'
84
+
85
+ # Find log.Fatal (calls os.Exit) in library code
86
+ grep -rn 'log.Fatal' --include='*.go' . | grep -v 'main.go' | grep -v '_test.go'
87
+
88
+ # Find os.Exit in library code
89
+ grep -rn 'os.Exit' --include='*.go' . | grep -v 'main.go' | grep -v '_test.go'
90
+ ```
91
+
92
+ ---
93
+
94
+ ## init() Detection
95
+
96
+ ```bash
97
+ # Find all init functions
98
+ grep -rn '^func init()' --include='*.go' .
99
+
100
+ # Find init functions with side effects (network, file, global state)
101
+ grep -A10 '^func init()' --include='*.go' . | grep -E 'http\.|sql\.|os\.|Open|Dial|Connect'
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Mutex and Race Detection
107
+
108
+ ```bash
109
+ # Find mutex passed by value (function params with Mutex, not pointer)
110
+ grep -rn 'func.*sync\.Mutex[^*]' --include='*.go' .
111
+
112
+ # Find Lock without corresponding Unlock
113
+ grep -rn '\.Lock()' --include='*.go' . | grep -v 'defer.*Unlock'
114
+
115
+ # Find RLock without RUnlock
116
+ grep -rn '\.RLock()' --include='*.go' . | grep -v 'defer.*RUnlock'
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Map and Slice Safety
122
+
123
+ ```bash
124
+ # Find uninitialized map declarations (potential nil map panic)
125
+ grep -rn 'var.*map\[' --include='*.go' . | grep -v 'make\|:='
126
+
127
+ # Find slice append without pre-allocation hint
128
+ grep -rn 'append(' --include='*.go' . | head -20
129
+ ```