@baselane/packs 0.1.3 → 0.1.5

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 (91) hide show
  1. package/dist/aliases.js +1 -0
  2. package/package.json +2 -2
  3. package/packs/database-review/pack.json +75 -9
  4. package/packs/database-review/rendered/.claude/agents/database-reviewer.md +75 -2
  5. package/packs/database-review/rendered/.claude/commands/migration-review.md +6 -0
  6. package/packs/database-review/rendered/.claude/settings.json +11 -0
  7. package/packs/database-review/rendered/.claude/skills/database-migrations/SKILL.md +431 -0
  8. package/packs/database-review/rendered/.claude/skills/mysql-patterns/SKILL.md +414 -0
  9. package/packs/database-review/rendered/.claude/skills/postgres-patterns/SKILL.md +149 -0
  10. package/packs/database-review/rendered/.github/copilot-instructions.md +1096 -14
  11. package/packs/database-review/rendered/AGENTS.md +45 -16
  12. package/packs/database-review/rendered/CLAUDE.md +4 -0
  13. package/packs/database-review/rendered/GEMINI.md +987 -0
  14. package/packs/go-rules/pack.json +65 -9
  15. package/packs/go-rules/rendered/.claude/agents/go-build-resolver.md +90 -0
  16. package/packs/go-rules/rendered/.claude/agents/go-reviewer.md +72 -2
  17. package/packs/go-rules/rendered/.claude/commands/go-build.md +6 -0
  18. package/packs/go-rules/rendered/.claude/commands/go-review.md +1 -1
  19. package/packs/go-rules/rendered/.claude/commands/go-test.md +6 -0
  20. package/packs/go-rules/rendered/.claude/settings.json +9 -0
  21. package/packs/go-rules/rendered/.claude/skills/golang-patterns/SKILL.md +673 -0
  22. package/packs/go-rules/rendered/.claude/skills/golang-testing/SKILL.md +719 -0
  23. package/packs/go-rules/rendered/.github/copilot-instructions.md +1783 -7
  24. package/packs/go-rules/rendered/AGENTS.md +244 -8
  25. package/packs/go-rules/rendered/CLAUDE.md +5 -0
  26. package/packs/go-rules/rendered/GEMINI.md +1394 -0
  27. package/packs/python-rules/pack.json +87 -10
  28. package/packs/python-rules/rendered/.claude/agents/django-reviewer.md +159 -0
  29. package/packs/python-rules/rendered/.claude/agents/fastapi-reviewer.md +70 -0
  30. package/packs/python-rules/rendered/.claude/agents/python-reviewer.md +92 -2
  31. package/packs/python-rules/rendered/.claude/commands/django-review.md +6 -0
  32. package/packs/python-rules/rendered/.claude/commands/fastapi-review.md +6 -0
  33. package/packs/python-rules/rendered/.claude/commands/python-review.md +1 -1
  34. package/packs/python-rules/rendered/.claude/settings.json +1 -1
  35. package/packs/python-rules/rendered/.claude/skills/django-security/SKILL.md +642 -0
  36. package/packs/python-rules/rendered/.claude/skills/django-tdd/SKILL.md +728 -0
  37. package/packs/python-rules/rendered/.claude/skills/fastapi-patterns/SKILL.md +512 -0
  38. package/packs/python-rules/rendered/.claude/skills/python-patterns/SKILL.md +749 -0
  39. package/packs/python-rules/rendered/.claude/skills/python-testing/SKILL.md +815 -0
  40. package/packs/python-rules/rendered/.github/copilot-instructions.md +3815 -12
  41. package/packs/python-rules/rendered/AGENTS.md +73 -13
  42. package/packs/python-rules/rendered/CLAUDE.md +9 -0
  43. package/packs/python-rules/rendered/GEMINI.md +3448 -0
  44. package/packs/security-review/pack.json +51 -7
  45. package/packs/security-review/rendered/.claude/agents/security-reviewer.md +29 -2
  46. package/packs/security-review/rendered/.claude/settings.json +11 -0
  47. package/packs/security-review/rendered/.claude/skills/security-review/SKILL.md +302 -0
  48. package/packs/security-review/rendered/.claude/skills/security-review/cloud-infrastructure-security.md +171 -0
  49. package/packs/security-review/rendered/.claude/skills/security-scan-config/SKILL.md +56 -0
  50. package/packs/security-review/rendered/.github/copilot-instructions.md +658 -15
  51. package/packs/security-review/rendered/AGENTS.md +283 -17
  52. package/packs/security-review/rendered/CLAUDE.md +2 -0
  53. package/packs/security-review/rendered/GEMINI.md +352 -0
  54. package/packs/software-engineer-harness/pack.json +249 -13
  55. package/packs/software-engineer-harness/rendered/.claude/agents/build-error-resolver.md +15 -0
  56. package/packs/software-engineer-harness/rendered/.claude/agents/code-explorer.md +67 -0
  57. package/packs/software-engineer-harness/rendered/.claude/agents/performance-optimizer.md +444 -0
  58. package/packs/software-engineer-harness/rendered/.claude/agents/pr-test-analyzer.md +43 -0
  59. package/packs/software-engineer-harness/rendered/.claude/agents/refactor-cleaner.md +12 -0
  60. package/packs/software-engineer-harness/rendered/.claude/agents/silent-failure-hunter.md +16 -0
  61. package/packs/software-engineer-harness/rendered/.claude/agents/tdd-guide.md +16 -0
  62. package/packs/software-engineer-harness/rendered/.claude/commands/feature-dev.md +6 -0
  63. package/packs/software-engineer-harness/rendered/.claude/commands/fix-build.md +6 -0
  64. package/packs/software-engineer-harness/rendered/.claude/commands/hunt-silent-failures.md +6 -0
  65. package/packs/software-engineer-harness/rendered/.claude/commands/tdd.md +6 -0
  66. package/packs/software-engineer-harness/rendered/.claude/settings.json +29 -0
  67. package/packs/software-engineer-harness/rendered/.claude/skills/api-design/SKILL.md +522 -0
  68. package/packs/software-engineer-harness/rendered/.claude/skills/architecture-decision-records/SKILL.md +178 -0
  69. package/packs/software-engineer-harness/rendered/.claude/skills/backend-patterns/SKILL.md +560 -0
  70. package/packs/software-engineer-harness/rendered/.claude/skills/codebase-onboarding/SKILL.md +232 -0
  71. package/packs/software-engineer-harness/rendered/.claude/skills/deployment-patterns/SKILL.md +426 -0
  72. package/packs/software-engineer-harness/rendered/.claude/skills/docker-patterns/SKILL.md +363 -0
  73. package/packs/software-engineer-harness/rendered/.claude/skills/e2e-testing/SKILL.md +325 -0
  74. package/packs/software-engineer-harness/rendered/.claude/skills/tdd-red-green-refactor/SKILL.md +20 -0
  75. package/packs/software-engineer-harness/rendered/.claude/skills/tdd-workflow/SKILL.md +580 -0
  76. package/packs/software-engineer-harness/rendered/.github/copilot-instructions.md +3948 -2
  77. package/packs/software-engineer-harness/rendered/AGENTS.md +194 -4
  78. package/packs/software-engineer-harness/rendered/CLAUDE.md +20 -0
  79. package/packs/software-engineer-harness/rendered/GEMINI.md +3208 -0
  80. package/packs/typescript-rules/pack.json +68 -5
  81. package/packs/typescript-rules/rendered/.claude/agents/react-reviewer.md +165 -0
  82. package/packs/typescript-rules/rendered/.claude/agents/type-design-analyzer.md +48 -0
  83. package/packs/typescript-rules/rendered/.claude/commands/react-review.md +6 -0
  84. package/packs/typescript-rules/rendered/.claude/settings.json +9 -0
  85. package/packs/typescript-rules/rendered/.claude/skills/react-patterns/SKILL.md +340 -0
  86. package/packs/typescript-rules/rendered/.claude/skills/react-performance/SKILL.md +573 -0
  87. package/packs/typescript-rules/rendered/.claude/skills/react-testing/SKILL.md +422 -0
  88. package/packs/typescript-rules/rendered/.github/copilot-instructions.md +2459 -53
  89. package/packs/typescript-rules/rendered/AGENTS.md +893 -17
  90. package/packs/typescript-rules/rendered/CLAUDE.md +6 -0
  91. package/packs/typescript-rules/rendered/GEMINI.md +1335 -0
@@ -0,0 +1,673 @@
1
+ ---
2
+ name: golang-patterns
3
+ description: Idiomatic Go patterns, best practices, and conventions for building robust, efficient, and maintainable Go applications — API shape, error handling, concurrency, interface design, package organization, and performance. Use when writing, reviewing, or refactoring Go code, or designing Go packages/modules.
4
+ ---
5
+
6
+ # Go Development Patterns
7
+
8
+ Idiomatic Go patterns and best practices for building robust, efficient, and maintainable applications.
9
+
10
+ ## When to use
11
+
12
+ - Writing new Go code.
13
+ - Reviewing Go code.
14
+ - Refactoring existing Go code.
15
+ - Designing Go packages/modules.
16
+
17
+ ## Core principles
18
+
19
+ ### 1. Simplicity and clarity
20
+
21
+ Go favors simplicity over cleverness. Code should be obvious and easy to read.
22
+
23
+ \`\`\`go
24
+ // Good: clear and direct
25
+ func GetUser(id string) (*User, error) {
26
+ user, err := db.FindUser(id)
27
+ if err != nil {
28
+ return nil, fmt.Errorf("get user %s: %w", id, err)
29
+ }
30
+ return user, nil
31
+ }
32
+
33
+ // Bad: overly clever
34
+ func GetUser(id string) (*User, error) {
35
+ return func() (*User, error) {
36
+ if u, e := db.FindUser(id); e == nil {
37
+ return u, nil
38
+ } else {
39
+ return nil, e
40
+ }
41
+ }()
42
+ }
43
+ \`\`\`
44
+
45
+ ### 2. Make the zero value useful
46
+
47
+ Design types so their zero value is immediately usable without initialization.
48
+
49
+ \`\`\`go
50
+ // Good: zero value is useful
51
+ type Counter struct {
52
+ mu sync.Mutex
53
+ count int // zero value is 0, ready to use
54
+ }
55
+
56
+ func (c *Counter) Inc() {
57
+ c.mu.Lock()
58
+ c.count++
59
+ c.mu.Unlock()
60
+ }
61
+
62
+ // Good: bytes.Buffer works with zero value
63
+ var buf bytes.Buffer
64
+ buf.WriteString("hello")
65
+
66
+ // Bad: requires initialization
67
+ type BadCounter struct {
68
+ counts map[string]int // nil map will panic
69
+ }
70
+ \`\`\`
71
+
72
+ ### 3. Accept interfaces, return structs
73
+
74
+ Functions should accept interface parameters and return concrete types.
75
+
76
+ \`\`\`go
77
+ // Good: accepts interface, returns concrete type
78
+ func ProcessData(r io.Reader) (*Result, error) {
79
+ data, err := io.ReadAll(r)
80
+ if err != nil {
81
+ return nil, err
82
+ }
83
+ return &Result{Data: data}, nil
84
+ }
85
+
86
+ // Bad: returns interface (hides implementation details unnecessarily)
87
+ func ProcessData(r io.Reader) (io.Reader, error) {
88
+ // ...
89
+ }
90
+ \`\`\`
91
+
92
+ ## Error handling patterns
93
+
94
+ ### Error wrapping with context
95
+
96
+ \`\`\`go
97
+ func LoadConfig(path string) (*Config, error) {
98
+ data, err := os.ReadFile(path)
99
+ if err != nil {
100
+ return nil, fmt.Errorf("load config %s: %w", path, err)
101
+ }
102
+
103
+ var cfg Config
104
+ if err := json.Unmarshal(data, &cfg); err != nil {
105
+ return nil, fmt.Errorf("parse config %s: %w", path, err)
106
+ }
107
+
108
+ return &cfg, nil
109
+ }
110
+ \`\`\`
111
+
112
+ ### Custom error types
113
+
114
+ \`\`\`go
115
+ // Define domain-specific errors
116
+ type ValidationError struct {
117
+ Field string
118
+ Message string
119
+ }
120
+
121
+ func (e *ValidationError) Error() string {
122
+ return fmt.Sprintf("validation failed on %s: %s", e.Field, e.Message)
123
+ }
124
+
125
+ // Sentinel errors for common cases
126
+ var (
127
+ ErrNotFound = errors.New("resource not found")
128
+ ErrUnauthorized = errors.New("unauthorized")
129
+ ErrInvalidInput = errors.New("invalid input")
130
+ )
131
+ \`\`\`
132
+
133
+ ### Error checking with errors.Is and errors.As
134
+
135
+ \`\`\`go
136
+ func HandleError(err error) {
137
+ // Check for specific error
138
+ if errors.Is(err, sql.ErrNoRows) {
139
+ log.Println("No records found")
140
+ return
141
+ }
142
+
143
+ // Check for error type
144
+ var validationErr *ValidationError
145
+ if errors.As(err, &validationErr) {
146
+ log.Printf("Validation error on field %s: %s",
147
+ validationErr.Field, validationErr.Message)
148
+ return
149
+ }
150
+
151
+ // Unknown error
152
+ log.Printf("Unexpected error: %v", err)
153
+ }
154
+ \`\`\`
155
+
156
+ ### Never ignore errors
157
+
158
+ \`\`\`go
159
+ // Bad: ignoring error with blank identifier
160
+ result, _ := doSomething()
161
+
162
+ // Good: handle or explicitly document why it's safe to ignore
163
+ result, err := doSomething()
164
+ if err != nil {
165
+ return err
166
+ }
167
+
168
+ // Acceptable: when error truly doesn't matter (rare)
169
+ _ = writer.Close() // Best-effort cleanup, error logged elsewhere
170
+ \`\`\`
171
+
172
+ ## Concurrency patterns
173
+
174
+ ### Worker pool
175
+
176
+ \`\`\`go
177
+ func WorkerPool(jobs <-chan Job, results chan<- Result, numWorkers int) {
178
+ var wg sync.WaitGroup
179
+
180
+ for i := 0; i < numWorkers; i++ {
181
+ wg.Add(1)
182
+ go func() {
183
+ defer wg.Done()
184
+ for job := range jobs {
185
+ results <- process(job)
186
+ }
187
+ }()
188
+ }
189
+
190
+ wg.Wait()
191
+ close(results)
192
+ }
193
+ \`\`\`
194
+
195
+ ### Context for cancellation and timeouts
196
+
197
+ \`\`\`go
198
+ func FetchWithTimeout(ctx context.Context, url string) ([]byte, error) {
199
+ ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
200
+ defer cancel()
201
+
202
+ req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
203
+ if err != nil {
204
+ return nil, fmt.Errorf("create request: %w", err)
205
+ }
206
+
207
+ resp, err := http.DefaultClient.Do(req)
208
+ if err != nil {
209
+ return nil, fmt.Errorf("fetch %s: %w", url, err)
210
+ }
211
+ defer resp.Body.Close()
212
+
213
+ return io.ReadAll(resp.Body)
214
+ }
215
+ \`\`\`
216
+
217
+ ### Graceful shutdown
218
+
219
+ \`\`\`go
220
+ func GracefulShutdown(server *http.Server) {
221
+ quit := make(chan os.Signal, 1)
222
+ signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
223
+
224
+ <-quit
225
+ log.Println("Shutting down server...")
226
+
227
+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
228
+ defer cancel()
229
+
230
+ if err := server.Shutdown(ctx); err != nil {
231
+ log.Fatalf("Server forced to shutdown: %v", err)
232
+ }
233
+
234
+ log.Println("Server exited")
235
+ }
236
+ \`\`\`
237
+
238
+ ### errgroup for coordinated goroutines
239
+
240
+ \`\`\`go
241
+ import "golang.org/x/sync/errgroup"
242
+
243
+ func FetchAll(ctx context.Context, urls []string) ([][]byte, error) {
244
+ g, ctx := errgroup.WithContext(ctx)
245
+ results := make([][]byte, len(urls))
246
+
247
+ for i, url := range urls {
248
+ i, url := i, url // Capture loop variables
249
+ g.Go(func() error {
250
+ data, err := FetchWithTimeout(ctx, url)
251
+ if err != nil {
252
+ return err
253
+ }
254
+ results[i] = data
255
+ return nil
256
+ })
257
+ }
258
+
259
+ if err := g.Wait(); err != nil {
260
+ return nil, err
261
+ }
262
+ return results, nil
263
+ }
264
+ \`\`\`
265
+
266
+ ### Avoiding goroutine leaks
267
+
268
+ \`\`\`go
269
+ // Bad: goroutine leak if context is cancelled
270
+ func leakyFetch(ctx context.Context, url string) <-chan []byte {
271
+ ch := make(chan []byte)
272
+ go func() {
273
+ data, _ := fetch(url)
274
+ ch <- data // Blocks forever if no receiver
275
+ }()
276
+ return ch
277
+ }
278
+
279
+ // Good: properly handles cancellation
280
+ func safeFetch(ctx context.Context, url string) <-chan []byte {
281
+ ch := make(chan []byte, 1) // Buffered channel
282
+ go func() {
283
+ data, err := fetch(url)
284
+ if err != nil {
285
+ return
286
+ }
287
+ select {
288
+ case ch <- data:
289
+ case <-ctx.Done():
290
+ }
291
+ }()
292
+ return ch
293
+ }
294
+ \`\`\`
295
+
296
+ ## Interface design
297
+
298
+ ### Small, focused interfaces
299
+
300
+ \`\`\`go
301
+ // Good: single-method interfaces
302
+ type Reader interface {
303
+ Read(p []byte) (n int, err error)
304
+ }
305
+
306
+ type Writer interface {
307
+ Write(p []byte) (n int, err error)
308
+ }
309
+
310
+ type Closer interface {
311
+ Close() error
312
+ }
313
+
314
+ // Compose interfaces as needed
315
+ type ReadWriteCloser interface {
316
+ Reader
317
+ Writer
318
+ Closer
319
+ }
320
+ \`\`\`
321
+
322
+ ### Define interfaces where they're used
323
+
324
+ \`\`\`go
325
+ // In the consumer package, not the provider
326
+ package service
327
+
328
+ // UserStore defines what this service needs
329
+ type UserStore interface {
330
+ GetUser(id string) (*User, error)
331
+ SaveUser(user *User) error
332
+ }
333
+
334
+ type Service struct {
335
+ store UserStore
336
+ }
337
+
338
+ // Concrete implementation can be in another package
339
+ // It doesn't need to know about this interface
340
+ \`\`\`
341
+
342
+ ### Optional behavior with type assertions
343
+
344
+ \`\`\`go
345
+ type Flusher interface {
346
+ Flush() error
347
+ }
348
+
349
+ func WriteAndFlush(w io.Writer, data []byte) error {
350
+ if _, err := w.Write(data); err != nil {
351
+ return err
352
+ }
353
+
354
+ // Flush if supported
355
+ if f, ok := w.(Flusher); ok {
356
+ return f.Flush()
357
+ }
358
+ return nil
359
+ }
360
+ \`\`\`
361
+
362
+ ## Package organization
363
+
364
+ ### Standard project layout
365
+
366
+ \`\`\`text
367
+ myproject/
368
+ ├── cmd/
369
+ │ └── myapp/
370
+ │ └── main.go # Entry point
371
+ ├── internal/
372
+ │ ├── handler/ # HTTP handlers
373
+ │ ├── service/ # Business logic
374
+ │ ├── repository/ # Data access
375
+ │ └── config/ # Configuration
376
+ ├── pkg/
377
+ │ └── client/ # Public API client
378
+ ├── api/
379
+ │ └── v1/ # API definitions (proto, OpenAPI)
380
+ ├── testdata/ # Test fixtures
381
+ ├── go.mod
382
+ ├── go.sum
383
+ └── Makefile
384
+ \`\`\`
385
+
386
+ ### Package naming
387
+
388
+ \`\`\`go
389
+ // Good: short, lowercase, no underscores
390
+ package http
391
+ package json
392
+ package user
393
+
394
+ // Bad: verbose, mixed case, or redundant
395
+ package httpHandler
396
+ package json_parser
397
+ package userService // Redundant 'Service' suffix
398
+ \`\`\`
399
+
400
+ ### Avoid package-level state
401
+
402
+ \`\`\`go
403
+ // Bad: global mutable state
404
+ var db *sql.DB
405
+
406
+ func init() {
407
+ db, _ = sql.Open("postgres", os.Getenv("DATABASE_URL"))
408
+ }
409
+
410
+ // Good: dependency injection
411
+ type Server struct {
412
+ db *sql.DB
413
+ }
414
+
415
+ func NewServer(db *sql.DB) *Server {
416
+ return &Server{db: db}
417
+ }
418
+ \`\`\`
419
+
420
+ ## Struct design
421
+
422
+ ### Functional options pattern
423
+
424
+ \`\`\`go
425
+ type Server struct {
426
+ addr string
427
+ timeout time.Duration
428
+ logger *log.Logger
429
+ }
430
+
431
+ type Option func(*Server)
432
+
433
+ func WithTimeout(d time.Duration) Option {
434
+ return func(s *Server) {
435
+ s.timeout = d
436
+ }
437
+ }
438
+
439
+ func WithLogger(l *log.Logger) Option {
440
+ return func(s *Server) {
441
+ s.logger = l
442
+ }
443
+ }
444
+
445
+ func NewServer(addr string, opts ...Option) *Server {
446
+ s := &Server{
447
+ addr: addr,
448
+ timeout: 30 * time.Second, // default
449
+ logger: log.Default(), // default
450
+ }
451
+ for _, opt := range opts {
452
+ opt(s)
453
+ }
454
+ return s
455
+ }
456
+
457
+ // Usage
458
+ server := NewServer(":8080",
459
+ WithTimeout(60*time.Second),
460
+ WithLogger(customLogger),
461
+ )
462
+ \`\`\`
463
+
464
+ ### Embedding for composition
465
+
466
+ \`\`\`go
467
+ type Logger struct {
468
+ prefix string
469
+ }
470
+
471
+ func (l *Logger) Log(msg string) {
472
+ fmt.Printf("[%s] %s\n", l.prefix, msg)
473
+ }
474
+
475
+ type Server struct {
476
+ *Logger // Embedding - Server gets Log method
477
+ addr string
478
+ }
479
+
480
+ func NewServer(addr string) *Server {
481
+ return &Server{
482
+ Logger: &Logger{prefix: "SERVER"},
483
+ addr: addr,
484
+ }
485
+ }
486
+
487
+ // Usage
488
+ s := NewServer(":8080")
489
+ s.Log("Starting...") // Calls embedded Logger.Log
490
+ \`\`\`
491
+
492
+ ## Memory and performance
493
+
494
+ ### Preallocate slices when size is known
495
+
496
+ \`\`\`go
497
+ // Bad: grows slice multiple times
498
+ func processItems(items []Item) []Result {
499
+ var results []Result
500
+ for _, item := range items {
501
+ results = append(results, process(item))
502
+ }
503
+ return results
504
+ }
505
+
506
+ // Good: single allocation
507
+ func processItems(items []Item) []Result {
508
+ results := make([]Result, 0, len(items))
509
+ for _, item := range items {
510
+ results = append(results, process(item))
511
+ }
512
+ return results
513
+ }
514
+ \`\`\`
515
+
516
+ ### Use sync.Pool for frequent allocations
517
+
518
+ \`\`\`go
519
+ var bufferPool = sync.Pool{
520
+ New: func() interface{} {
521
+ return new(bytes.Buffer)
522
+ },
523
+ }
524
+
525
+ func ProcessRequest(data []byte) []byte {
526
+ buf := bufferPool.Get().(*bytes.Buffer)
527
+ defer func() {
528
+ buf.Reset()
529
+ bufferPool.Put(buf)
530
+ }()
531
+
532
+ buf.Write(data)
533
+ // Process...
534
+ return buf.Bytes()
535
+ }
536
+ \`\`\`
537
+
538
+ ### Avoid string concatenation in loops
539
+
540
+ \`\`\`go
541
+ // Bad: creates many string allocations
542
+ func join(parts []string) string {
543
+ var result string
544
+ for _, p := range parts {
545
+ result += p + ","
546
+ }
547
+ return result
548
+ }
549
+
550
+ // Good: single allocation with strings.Builder
551
+ func join(parts []string) string {
552
+ var sb strings.Builder
553
+ for i, p := range parts {
554
+ if i > 0 {
555
+ sb.WriteString(",")
556
+ }
557
+ sb.WriteString(p)
558
+ }
559
+ return sb.String()
560
+ }
561
+
562
+ // Best: use standard library
563
+ func join(parts []string) string {
564
+ return strings.Join(parts, ",")
565
+ }
566
+ \`\`\`
567
+
568
+ ## Go tooling integration
569
+
570
+ ### Essential commands
571
+
572
+ \`\`\`bash
573
+ # Build and run
574
+ go build ./...
575
+ go run ./cmd/myapp
576
+
577
+ # Testing
578
+ go test ./...
579
+ go test -race ./...
580
+ go test -cover ./...
581
+
582
+ # Static analysis
583
+ go vet ./...
584
+ staticcheck ./...
585
+ golangci-lint run
586
+
587
+ # Module management
588
+ go mod tidy
589
+ go mod verify
590
+
591
+ # Formatting
592
+ gofmt -w .
593
+ goimports -w .
594
+ \`\`\`
595
+
596
+ ### Recommended linter configuration (.golangci.yml)
597
+
598
+ \`\`\`yaml
599
+ linters:
600
+ enable:
601
+ - errcheck
602
+ - gosimple
603
+ - govet
604
+ - ineffassign
605
+ - staticcheck
606
+ - unused
607
+ - gofmt
608
+ - goimports
609
+ - misspell
610
+ - unconvert
611
+ - unparam
612
+
613
+ linters-settings:
614
+ errcheck:
615
+ check-type-assertions: true
616
+ govet:
617
+ enable:
618
+ - shadow
619
+
620
+ issues:
621
+ exclude-use-default: false
622
+ \`\`\`
623
+
624
+ ## Quick reference: Go idioms
625
+
626
+ | Idiom | Description |
627
+ |-------|-------------|
628
+ | Accept interfaces, return structs | Functions accept interface params, return concrete types |
629
+ | Errors are values | Treat errors as first-class values, not exceptions |
630
+ | Don't communicate by sharing memory | Use channels for coordination between goroutines |
631
+ | Make the zero value useful | Types should work without explicit initialization |
632
+ | A little copying is better than a little dependency | Avoid unnecessary external dependencies |
633
+ | Clear is better than clever | Prioritize readability over cleverness |
634
+ | gofmt is no one's favorite but everyone's friend | Always format with gofmt/goimports |
635
+ | Return early | Handle errors first, keep happy path unindented |
636
+
637
+ ## Anti-patterns to avoid
638
+
639
+ \`\`\`go
640
+ // Bad: naked returns in long functions
641
+ func process() (result int, err error) {
642
+ // ... 50 lines ...
643
+ return // What is being returned?
644
+ }
645
+
646
+ // Bad: using panic for control flow
647
+ func GetUser(id string) *User {
648
+ user, err := db.Find(id)
649
+ if err != nil {
650
+ panic(err) // Don't do this
651
+ }
652
+ return user
653
+ }
654
+
655
+ // Bad: passing context in struct
656
+ type Request struct {
657
+ ctx context.Context // Context should be first param
658
+ ID string
659
+ }
660
+
661
+ // Good: context as first parameter
662
+ func ProcessRequest(ctx context.Context, id string) error {
663
+ // ...
664
+ }
665
+
666
+ // Bad: mixing value and pointer receivers
667
+ type Counter struct{ n int }
668
+ func (c Counter) Value() int { return c.n } // Value receiver
669
+ func (c *Counter) Increment() { c.n++ } // Pointer receiver
670
+ // Pick one style and be consistent
671
+ \`\`\`
672
+
673
+ **Remember**: Go code should be boring in the best way — predictable, consistent, and easy to understand. When in doubt, keep it simple.