oh-my-customcode 0.1.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 (237) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +287 -0
  3. package/dist/cli/index.js +13299 -0
  4. package/dist/index.js +927 -0
  5. package/package.json +74 -0
  6. package/templates/.claude/contexts/dev.md +20 -0
  7. package/templates/.claude/contexts/ecomode.md +63 -0
  8. package/templates/.claude/contexts/index.yaml +41 -0
  9. package/templates/.claude/contexts/research.md +28 -0
  10. package/templates/.claude/contexts/review.md +23 -0
  11. package/templates/.claude/hooks/hooks.json +185 -0
  12. package/templates/.claude/hooks/hud/index.yaml +27 -0
  13. package/templates/.claude/hooks/hud/update-status.sh +32 -0
  14. package/templates/.claude/hooks/index.yaml +46 -0
  15. package/templates/.claude/hooks/memory-persistence/pre-compact.sh +37 -0
  16. package/templates/.claude/hooks/memory-persistence/session-end.sh +64 -0
  17. package/templates/.claude/hooks/memory-persistence/session-start.sh +41 -0
  18. package/templates/.claude/hooks/strategic-compact/suggest-compact.sh +50 -0
  19. package/templates/.claude/install-hooks.sh +100 -0
  20. package/templates/.claude/rules/MAY-optimization.md +93 -0
  21. package/templates/.claude/rules/MUST-agent-design.md +107 -0
  22. package/templates/.claude/rules/MUST-agent-identification.md +108 -0
  23. package/templates/.claude/rules/MUST-continuous-improvement.md +132 -0
  24. package/templates/.claude/rules/MUST-intent-transparency.md +199 -0
  25. package/templates/.claude/rules/MUST-language-policy.md +62 -0
  26. package/templates/.claude/rules/MUST-orchestrator-coordination.md +266 -0
  27. package/templates/.claude/rules/MUST-parallel-execution.md +341 -0
  28. package/templates/.claude/rules/MUST-permissions.md +84 -0
  29. package/templates/.claude/rules/MUST-safety.md +69 -0
  30. package/templates/.claude/rules/MUST-sync-verification.md +219 -0
  31. package/templates/.claude/rules/MUST-tool-identification.md +112 -0
  32. package/templates/.claude/rules/SHOULD-ecomode.md +145 -0
  33. package/templates/.claude/rules/SHOULD-error-handling.md +102 -0
  34. package/templates/.claude/rules/SHOULD-hud-statusline.md +89 -0
  35. package/templates/.claude/rules/SHOULD-interaction.md +103 -0
  36. package/templates/.claude/rules/SHOULD-memory-integration.md +114 -0
  37. package/templates/.claude/rules/SHOULD-pipeline-mode.md +165 -0
  38. package/templates/.claude/rules/index.yaml +125 -0
  39. package/templates/.claude/uninstall-hooks.sh +52 -0
  40. package/templates/CLAUDE.md.en +259 -0
  41. package/templates/CLAUDE.md.ko +259 -0
  42. package/templates/agents/index.yaml +237 -0
  43. package/templates/agents/infra-engineer/aws-expert/AGENT.md +47 -0
  44. package/templates/agents/infra-engineer/aws-expert/index.yaml +27 -0
  45. package/templates/agents/infra-engineer/docker-expert/AGENT.md +47 -0
  46. package/templates/agents/infra-engineer/docker-expert/index.yaml +27 -0
  47. package/templates/agents/manager/creator/AGENT.md +274 -0
  48. package/templates/agents/manager/creator/index.yaml +66 -0
  49. package/templates/agents/manager/gitnerd/AGENT.md +91 -0
  50. package/templates/agents/manager/gitnerd/index.yaml +55 -0
  51. package/templates/agents/manager/sauron/AGENT.md +153 -0
  52. package/templates/agents/manager/sauron/index.yaml +52 -0
  53. package/templates/agents/manager/supplier/AGENT.md +142 -0
  54. package/templates/agents/manager/supplier/index.yaml +31 -0
  55. package/templates/agents/manager/sync-checker/AGENT.md +34 -0
  56. package/templates/agents/manager/sync-checker/index.yaml +32 -0
  57. package/templates/agents/manager/updater/AGENT.md +125 -0
  58. package/templates/agents/manager/updater/index.yaml +31 -0
  59. package/templates/agents/orchestrator/dev-lead/AGENT.md +116 -0
  60. package/templates/agents/orchestrator/dev-lead/index.yaml +73 -0
  61. package/templates/agents/orchestrator/planner/AGENT.md +102 -0
  62. package/templates/agents/orchestrator/planner/index.yaml +38 -0
  63. package/templates/agents/orchestrator/qa-lead/AGENT.md +92 -0
  64. package/templates/agents/orchestrator/qa-lead/index.yaml +40 -0
  65. package/templates/agents/orchestrator/secretary/AGENT.md +132 -0
  66. package/templates/agents/orchestrator/secretary/index.yaml +55 -0
  67. package/templates/agents/qa-team/qa-engineer/AGENT.md +98 -0
  68. package/templates/agents/qa-team/qa-engineer/index.yaml +59 -0
  69. package/templates/agents/qa-team/qa-planner/AGENT.md +75 -0
  70. package/templates/agents/qa-team/qa-planner/index.yaml +47 -0
  71. package/templates/agents/qa-team/qa-writer/AGENT.md +98 -0
  72. package/templates/agents/qa-team/qa-writer/index.yaml +44 -0
  73. package/templates/agents/sw-architect/documenter/AGENT.md +120 -0
  74. package/templates/agents/sw-architect/documenter/index.yaml +39 -0
  75. package/templates/agents/sw-architect/speckit-agent/AGENT.md +127 -0
  76. package/templates/agents/sw-architect/speckit-agent/index.yaml +78 -0
  77. package/templates/agents/sw-engineer/backend/express-expert/AGENT.md +132 -0
  78. package/templates/agents/sw-engineer/backend/express-expert/index.yaml +36 -0
  79. package/templates/agents/sw-engineer/backend/fastapi-expert/AGENT.md +47 -0
  80. package/templates/agents/sw-engineer/backend/fastapi-expert/index.yaml +27 -0
  81. package/templates/agents/sw-engineer/backend/go-backend-expert/AGENT.md +47 -0
  82. package/templates/agents/sw-engineer/backend/go-backend-expert/index.yaml +27 -0
  83. package/templates/agents/sw-engineer/backend/nestjs-expert/AGENT.md +107 -0
  84. package/templates/agents/sw-engineer/backend/nestjs-expert/index.yaml +43 -0
  85. package/templates/agents/sw-engineer/backend/springboot-expert/AGENT.md +103 -0
  86. package/templates/agents/sw-engineer/backend/springboot-expert/index.yaml +69 -0
  87. package/templates/agents/sw-engineer/frontend/svelte-agent/AGENT.md +71 -0
  88. package/templates/agents/sw-engineer/frontend/svelte-agent/index.yaml +41 -0
  89. package/templates/agents/sw-engineer/frontend/vercel-agent/AGENT.md +67 -0
  90. package/templates/agents/sw-engineer/frontend/vercel-agent/index.yaml +43 -0
  91. package/templates/agents/sw-engineer/frontend/vuejs-agent/AGENT.md +71 -0
  92. package/templates/agents/sw-engineer/frontend/vuejs-agent/index.yaml +48 -0
  93. package/templates/agents/sw-engineer/language/golang-expert/AGENT.md +47 -0
  94. package/templates/agents/sw-engineer/language/golang-expert/index.yaml +27 -0
  95. package/templates/agents/sw-engineer/language/java21-expert/AGENT.md +122 -0
  96. package/templates/agents/sw-engineer/language/java21-expert/index.yaml +51 -0
  97. package/templates/agents/sw-engineer/language/kotlin-expert/AGENT.md +47 -0
  98. package/templates/agents/sw-engineer/language/kotlin-expert/index.yaml +27 -0
  99. package/templates/agents/sw-engineer/language/python-expert/AGENT.md +47 -0
  100. package/templates/agents/sw-engineer/language/python-expert/index.yaml +27 -0
  101. package/templates/agents/sw-engineer/language/rust-expert/AGENT.md +47 -0
  102. package/templates/agents/sw-engineer/language/rust-expert/index.yaml +27 -0
  103. package/templates/agents/sw-engineer/language/typescript-expert/AGENT.md +47 -0
  104. package/templates/agents/sw-engineer/language/typescript-expert/index.yaml +27 -0
  105. package/templates/agents/sw-engineer/tooling/bun-expert/AGENT.md +73 -0
  106. package/templates/agents/sw-engineer/tooling/bun-expert/index.yaml +46 -0
  107. package/templates/agents/sw-engineer/tooling/npm-expert/AGENT.md +160 -0
  108. package/templates/agents/sw-engineer/tooling/npm-expert/index.yaml +45 -0
  109. package/templates/agents/sw-engineer/tooling/optimizer/AGENT.md +170 -0
  110. package/templates/agents/sw-engineer/tooling/optimizer/index.yaml +45 -0
  111. package/templates/agents/system/memory-keeper/AGENT.md +126 -0
  112. package/templates/agents/system/memory-keeper/index.yaml +45 -0
  113. package/templates/agents/system/naggy/AGENT.md +72 -0
  114. package/templates/agents/system/naggy/index.yaml +35 -0
  115. package/templates/commands/COMMANDS.md +136 -0
  116. package/templates/commands/creator/agent.md +121 -0
  117. package/templates/commands/dev/refactor.md +126 -0
  118. package/templates/commands/dev/review.md +82 -0
  119. package/templates/commands/git/branch.yaml +8 -0
  120. package/templates/commands/git/commit.yaml +4 -0
  121. package/templates/commands/git/pr.yaml +4 -0
  122. package/templates/commands/git/status.yaml +4 -0
  123. package/templates/commands/git/sync.yaml +4 -0
  124. package/templates/commands/index.yaml +225 -0
  125. package/templates/commands/intent/explain.md +144 -0
  126. package/templates/commands/memory/recall.md +164 -0
  127. package/templates/commands/memory/save.md +128 -0
  128. package/templates/commands/naggy/add.yaml +8 -0
  129. package/templates/commands/naggy/done.yaml +8 -0
  130. package/templates/commands/naggy/list.yaml +4 -0
  131. package/templates/commands/naggy/priority.yaml +11 -0
  132. package/templates/commands/naggy/remind.yaml +4 -0
  133. package/templates/commands/npm/audit.yaml +62 -0
  134. package/templates/commands/npm/publish.yaml +52 -0
  135. package/templates/commands/npm/version.yaml +62 -0
  136. package/templates/commands/optimize/analyze.yaml +34 -0
  137. package/templates/commands/optimize/bundle.yaml +50 -0
  138. package/templates/commands/optimize/report.yaml +56 -0
  139. package/templates/commands/pipeline/list.md +81 -0
  140. package/templates/commands/pipeline/run.md +127 -0
  141. package/templates/commands/sauron/quick.yaml +4 -0
  142. package/templates/commands/sauron/report.yaml +4 -0
  143. package/templates/commands/sauron/watch.yaml +4 -0
  144. package/templates/commands/supplier/audit.md +133 -0
  145. package/templates/commands/supplier/fix.md +121 -0
  146. package/templates/commands/sync/agents.yaml +4 -0
  147. package/templates/commands/sync/check.yaml +4 -0
  148. package/templates/commands/sync/commands.yaml +4 -0
  149. package/templates/commands/sync/docs.yaml +4 -0
  150. package/templates/commands/sync/fix.yaml +4 -0
  151. package/templates/commands/system/help.md +137 -0
  152. package/templates/commands/system/lists.md +86 -0
  153. package/templates/commands/system/status.md +163 -0
  154. package/templates/commands/updater/docs.md +165 -0
  155. package/templates/commands/updater/external.md +214 -0
  156. package/templates/guides/aws/common-patterns.md +169 -0
  157. package/templates/guides/aws/index.yaml +26 -0
  158. package/templates/guides/aws/well-architected.md +143 -0
  159. package/templates/guides/claude-code/01-overview.md +42 -0
  160. package/templates/guides/claude-code/03-tools.md +107 -0
  161. package/templates/guides/claude-code/04-agent-skills.md +90 -0
  162. package/templates/guides/claude-code/05-agent-sdk.md +129 -0
  163. package/templates/guides/claude-code/06-mcp.md +165 -0
  164. package/templates/guides/claude-code/07-prompt-engineering.md +100 -0
  165. package/templates/guides/claude-code/08-testing.md +58 -0
  166. package/templates/guides/claude-code/09-guardrails.md +80 -0
  167. package/templates/guides/claude-code/10-monitoring.md +89 -0
  168. package/templates/guides/claude-code/index.yaml +51 -0
  169. package/templates/guides/docker/compose-best-practices.md +284 -0
  170. package/templates/guides/docker/dockerfile-best-practices.md +262 -0
  171. package/templates/guides/docker/index.yaml +26 -0
  172. package/templates/guides/fastapi/best-practices.md +232 -0
  173. package/templates/guides/fastapi/index.yaml +21 -0
  174. package/templates/guides/go-backend/index.yaml +26 -0
  175. package/templates/guides/go-backend/project-layout.md +243 -0
  176. package/templates/guides/go-backend/uber-style.md +212 -0
  177. package/templates/guides/golang/concurrency.md +282 -0
  178. package/templates/guides/golang/effective-go.md +309 -0
  179. package/templates/guides/golang/error-handling.md +250 -0
  180. package/templates/guides/golang/index.yaml +27 -0
  181. package/templates/guides/index.yaml +101 -0
  182. package/templates/guides/kotlin/coding-conventions.md +247 -0
  183. package/templates/guides/kotlin/idioms.md +234 -0
  184. package/templates/guides/kotlin/index.yaml +26 -0
  185. package/templates/guides/python/index.yaml +26 -0
  186. package/templates/guides/python/pep8-style-guide.md +202 -0
  187. package/templates/guides/python/zen-of-python.md +79 -0
  188. package/templates/guides/rust/error-handling.md +262 -0
  189. package/templates/guides/rust/index.yaml +26 -0
  190. package/templates/guides/rust/ownership.md +180 -0
  191. package/templates/guides/springboot/best-practices.md +361 -0
  192. package/templates/guides/springboot/index.yaml +22 -0
  193. package/templates/guides/typescript/advanced-types.md +225 -0
  194. package/templates/guides/typescript/index.yaml +26 -0
  195. package/templates/guides/typescript/type-system.md +219 -0
  196. package/templates/guides/web-design/accessibility.md +66 -0
  197. package/templates/guides/web-design/index.yaml +20 -0
  198. package/templates/guides/web-design/performance.md +102 -0
  199. package/templates/pipelines/examples/code-review.yaml +66 -0
  200. package/templates/pipelines/index.yaml +18 -0
  201. package/templates/pipelines/templates/pipeline-template.yaml +50 -0
  202. package/templates/skills/backend/fastapi-best-practices/SKILL.md +269 -0
  203. package/templates/skills/backend/fastapi-best-practices/index.yaml +25 -0
  204. package/templates/skills/backend/go-backend-best-practices/SKILL.md +337 -0
  205. package/templates/skills/backend/go-backend-best-practices/index.yaml +26 -0
  206. package/templates/skills/backend/springboot-best-practices/SKILL.md +356 -0
  207. package/templates/skills/backend/springboot-best-practices/index.yaml +27 -0
  208. package/templates/skills/development/go-best-practices/SKILL.md +202 -0
  209. package/templates/skills/development/go-best-practices/index.yaml +25 -0
  210. package/templates/skills/development/kotlin-best-practices/SKILL.md +255 -0
  211. package/templates/skills/development/kotlin-best-practices/index.yaml +27 -0
  212. package/templates/skills/development/python-best-practices/SKILL.md +221 -0
  213. package/templates/skills/development/python-best-practices/index.yaml +25 -0
  214. package/templates/skills/development/react-best-practices/SKILL.md +100 -0
  215. package/templates/skills/development/react-best-practices/index.yaml +39 -0
  216. package/templates/skills/development/rust-best-practices/SKILL.md +266 -0
  217. package/templates/skills/development/rust-best-practices/index.yaml +26 -0
  218. package/templates/skills/development/typescript-best-practices/SKILL.md +320 -0
  219. package/templates/skills/development/typescript-best-practices/index.yaml +28 -0
  220. package/templates/skills/development/vercel-deploy/SKILL.md +73 -0
  221. package/templates/skills/development/vercel-deploy/index.yaml +30 -0
  222. package/templates/skills/development/web-design-guidelines/SKILL.md +117 -0
  223. package/templates/skills/development/web-design-guidelines/index.yaml +34 -0
  224. package/templates/skills/index.yaml +129 -0
  225. package/templates/skills/infrastructure/aws-best-practices/SKILL.md +279 -0
  226. package/templates/skills/infrastructure/aws-best-practices/index.yaml +27 -0
  227. package/templates/skills/infrastructure/docker-best-practices/SKILL.md +274 -0
  228. package/templates/skills/infrastructure/docker-best-practices/index.yaml +26 -0
  229. package/templates/skills/orchestration/intent-detection/SKILL.md +214 -0
  230. package/templates/skills/orchestration/intent-detection/index.yaml +30 -0
  231. package/templates/skills/orchestration/intent-detection/patterns/agent-triggers.yaml +333 -0
  232. package/templates/skills/orchestration/pipeline-execution/SKILL.md +188 -0
  233. package/templates/skills/orchestration/pipeline-execution/index.yaml +27 -0
  234. package/templates/skills/system/memory-management/SKILL.md +194 -0
  235. package/templates/skills/system/memory-management/index.yaml +30 -0
  236. package/templates/skills/system/result-aggregation/SKILL.md +163 -0
  237. package/templates/skills/system/result-aggregation/index.yaml +36 -0
@@ -0,0 +1,243 @@
1
+ # Standard Go Project Layout
2
+
3
+ > Source: https://github.com/golang-standards/project-layout
4
+
5
+ ## Directory Structure
6
+
7
+ ```
8
+ project/
9
+ ├── cmd/ # Main applications
10
+ │ ├── server/
11
+ │ │ └── main.go
12
+ │ └── worker/
13
+ │ └── main.go
14
+ ├── internal/ # Private code
15
+ │ ├── handler/
16
+ │ ├── service/
17
+ │ ├── repository/
18
+ │ ├── model/
19
+ │ └── config/
20
+ ├── pkg/ # Public library code
21
+ │ └── validator/
22
+ ├── api/ # API definitions
23
+ │ ├── openapi.yaml
24
+ │ └── proto/
25
+ ├── configs/ # Configuration files
26
+ │ └── config.yaml
27
+ ├── scripts/ # Build scripts
28
+ │ └── build.sh
29
+ ├── test/ # Additional test data
30
+ │ └── testdata/
31
+ ├── docs/ # Documentation
32
+ ├── Dockerfile
33
+ ├── Makefile
34
+ ├── go.mod
35
+ └── go.sum
36
+ ```
37
+
38
+ ## Directory Descriptions
39
+
40
+ ### `/cmd`
41
+
42
+ Main applications for this project. Each application has its own subdirectory.
43
+
44
+ ```go
45
+ // cmd/server/main.go
46
+ package main
47
+
48
+ import (
49
+ "log"
50
+ "myapp/internal/config"
51
+ "myapp/internal/handler"
52
+ "myapp/internal/service"
53
+ )
54
+
55
+ func main() {
56
+ cfg, err := config.Load()
57
+ if err != nil {
58
+ log.Fatal(err)
59
+ }
60
+
61
+ svc := service.New(cfg)
62
+ h := handler.New(svc)
63
+
64
+ log.Fatal(h.ListenAndServe(cfg.Addr))
65
+ }
66
+ ```
67
+
68
+ ### `/internal`
69
+
70
+ Private application and library code. Not importable by other projects.
71
+
72
+ ```
73
+ internal/
74
+ ├── handler/ # HTTP/gRPC handlers
75
+ │ └── user.go
76
+ ├── service/ # Business logic
77
+ │ └── user.go
78
+ ├── repository/ # Data access
79
+ │ └── user.go
80
+ ├── model/ # Domain models
81
+ │ └── user.go
82
+ └── config/ # Configuration
83
+ └── config.go
84
+ ```
85
+
86
+ ### `/pkg`
87
+
88
+ Library code safe for external use.
89
+
90
+ ```go
91
+ // pkg/validator/validator.go
92
+ package validator
93
+
94
+ func ValidateEmail(email string) bool {
95
+ // validation logic
96
+ }
97
+ ```
98
+
99
+ ### `/api`
100
+
101
+ API definitions (OpenAPI/Swagger, Protocol Buffers).
102
+
103
+ ```yaml
104
+ # api/openapi.yaml
105
+ openapi: "3.0.0"
106
+ info:
107
+ title: "My API"
108
+ version: "1.0.0"
109
+ paths:
110
+ /users:
111
+ get:
112
+ summary: "List users"
113
+ ```
114
+
115
+ ## Common Patterns
116
+
117
+ ### Application Structure
118
+
119
+ ```go
120
+ // internal/app/app.go
121
+ type App struct {
122
+ config *config.Config
123
+ db *sql.DB
124
+ cache *redis.Client
125
+ handler *handler.Handler
126
+ }
127
+
128
+ func New(cfg *config.Config) (*App, error) {
129
+ db, err := sql.Open("postgres", cfg.DatabaseURL)
130
+ if err != nil {
131
+ return nil, fmt.Errorf("open db: %w", err)
132
+ }
133
+
134
+ cache := redis.NewClient(&redis.Options{
135
+ Addr: cfg.RedisURL,
136
+ })
137
+
138
+ repo := repository.New(db)
139
+ svc := service.New(repo, cache)
140
+ h := handler.New(svc)
141
+
142
+ return &App{
143
+ config: cfg,
144
+ db: db,
145
+ cache: cache,
146
+ handler: h,
147
+ }, nil
148
+ }
149
+
150
+ func (a *App) Run() error {
151
+ return http.ListenAndServe(a.config.Addr, a.handler.Router())
152
+ }
153
+
154
+ func (a *App) Shutdown(ctx context.Context) error {
155
+ if err := a.db.Close(); err != nil {
156
+ return err
157
+ }
158
+ return a.cache.Close()
159
+ }
160
+ ```
161
+
162
+ ### Main Entry Point
163
+
164
+ ```go
165
+ // cmd/server/main.go
166
+ package main
167
+
168
+ import (
169
+ "context"
170
+ "log/slog"
171
+ "os"
172
+ "os/signal"
173
+ "syscall"
174
+
175
+ "myapp/internal/app"
176
+ "myapp/internal/config"
177
+ )
178
+
179
+ func main() {
180
+ logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
181
+ slog.SetDefault(logger)
182
+
183
+ cfg, err := config.Load()
184
+ if err != nil {
185
+ slog.Error("load config", "error", err)
186
+ os.Exit(1)
187
+ }
188
+
189
+ application, err := app.New(cfg)
190
+ if err != nil {
191
+ slog.Error("create app", "error", err)
192
+ os.Exit(1)
193
+ }
194
+
195
+ // Graceful shutdown
196
+ ctx, stop := signal.NotifyContext(
197
+ context.Background(),
198
+ syscall.SIGINT, syscall.SIGTERM,
199
+ )
200
+ defer stop()
201
+
202
+ go func() {
203
+ slog.Info("starting server", "addr", cfg.Addr)
204
+ if err := application.Run(); err != nil {
205
+ slog.Error("server error", "error", err)
206
+ }
207
+ }()
208
+
209
+ <-ctx.Done()
210
+ slog.Info("shutting down")
211
+
212
+ shutdownCtx, cancel := context.WithTimeout(
213
+ context.Background(),
214
+ 30*time.Second,
215
+ )
216
+ defer cancel()
217
+
218
+ if err := application.Shutdown(shutdownCtx); err != nil {
219
+ slog.Error("shutdown error", "error", err)
220
+ }
221
+ }
222
+ ```
223
+
224
+ ### Makefile
225
+
226
+ ```makefile
227
+ .PHONY: build run test lint
228
+
229
+ build:
230
+ go build -o bin/server ./cmd/server
231
+
232
+ run:
233
+ go run ./cmd/server
234
+
235
+ test:
236
+ go test -v -race ./...
237
+
238
+ lint:
239
+ golangci-lint run
240
+
241
+ docker:
242
+ docker build -t myapp .
243
+ ```
@@ -0,0 +1,212 @@
1
+ # Uber Go Style Guide
2
+
3
+ > Source: https://github.com/uber-go/guide/blob/master/style.md
4
+
5
+ ## Guidelines
6
+
7
+ ### Verify Interface Compliance
8
+
9
+ ```go
10
+ // Compile-time check
11
+ var _ http.Handler = (*Handler)(nil)
12
+ var _ io.Reader = (*MyReader)(nil)
13
+ ```
14
+
15
+ ### Receiver Type
16
+
17
+ ```go
18
+ // Value receiver: doesn't modify state
19
+ func (s Stack) Length() int {
20
+ return len(s.items)
21
+ }
22
+
23
+ // Pointer receiver: modifies state or is large
24
+ func (s *Stack) Push(item int) {
25
+ s.items = append(s.items, item)
26
+ }
27
+ ```
28
+
29
+ ### Zero-value Mutexes
30
+
31
+ ```go
32
+ // Good: zero-value is valid
33
+ var mu sync.Mutex
34
+
35
+ // Good: embedded in struct
36
+ type Store struct {
37
+ mu sync.Mutex
38
+ items map[string]Item
39
+ }
40
+ ```
41
+
42
+ ### Copy Slices and Maps
43
+
44
+ ```go
45
+ // Returning: copy to prevent external modification
46
+ func (s *Store) GetItems() []Item {
47
+ s.mu.RLock()
48
+ defer s.mu.RUnlock()
49
+ items := make([]Item, len(s.items))
50
+ copy(items, s.items)
51
+ return items
52
+ }
53
+
54
+ // Receiving: copy to prevent caller modification
55
+ func (s *Store) SetItems(items []Item) {
56
+ s.mu.Lock()
57
+ defer s.mu.Unlock()
58
+ s.items = make([]Item, len(items))
59
+ copy(s.items, items)
60
+ }
61
+ ```
62
+
63
+ ### Defer for Cleanup
64
+
65
+ ```go
66
+ func readFile(path string) ([]byte, error) {
67
+ f, err := os.Open(path)
68
+ if err != nil {
69
+ return nil, err
70
+ }
71
+ defer f.Close()
72
+ return io.ReadAll(f)
73
+ }
74
+
75
+ func process() {
76
+ mu.Lock()
77
+ defer mu.Unlock()
78
+ // ...
79
+ }
80
+ ```
81
+
82
+ ### Channel Size
83
+
84
+ ```go
85
+ // Good: unbuffered or 1
86
+ ch := make(chan int)
87
+ ch := make(chan int, 1)
88
+
89
+ // Requires justification
90
+ ch := make(chan int, 100) // Why 100?
91
+ ```
92
+
93
+ ### Start Enums at One
94
+
95
+ ```go
96
+ type Operation int
97
+
98
+ const (
99
+ Add Operation = iota + 1
100
+ Subtract
101
+ Multiply
102
+ )
103
+ ```
104
+
105
+ ### Error Types
106
+
107
+ ```go
108
+ // Sentinel errors
109
+ var ErrNotFound = errors.New("not found")
110
+
111
+ // Error wrapping
112
+ if err != nil {
113
+ return fmt.Errorf("failed to get user: %w", err)
114
+ }
115
+
116
+ // Checking errors
117
+ if errors.Is(err, ErrNotFound) {
118
+ // handle not found
119
+ }
120
+ ```
121
+
122
+ ### Handle Errors Once
123
+
124
+ ```go
125
+ // Bad: logs AND returns
126
+ if err != nil {
127
+ log.Printf("error: %v", err)
128
+ return err
129
+ }
130
+
131
+ // Good: return with context
132
+ if err != nil {
133
+ return fmt.Errorf("process: %w", err)
134
+ }
135
+ ```
136
+
137
+ ### Use strconv Over fmt
138
+
139
+ ```go
140
+ // Good
141
+ s := strconv.Itoa(n)
142
+ n, err := strconv.Atoi(s)
143
+
144
+ // Slower
145
+ s := fmt.Sprintf("%d", n)
146
+ ```
147
+
148
+ ### Table-Driven Tests
149
+
150
+ ```go
151
+ func TestSplit(t *testing.T) {
152
+ tests := []struct {
153
+ name string
154
+ input string
155
+ sep string
156
+ want []string
157
+ }{
158
+ {
159
+ name: "simple",
160
+ input: "a/b/c",
161
+ sep: "/",
162
+ want: []string{"a", "b", "c"},
163
+ },
164
+ {
165
+ name: "empty",
166
+ input: "",
167
+ sep: "/",
168
+ want: []string{""},
169
+ },
170
+ }
171
+
172
+ for _, tt := range tests {
173
+ t.Run(tt.name, func(t *testing.T) {
174
+ got := strings.Split(tt.input, tt.sep)
175
+ if diff := cmp.Diff(tt.want, got); diff != "" {
176
+ t.Errorf("mismatch (-want +got):\n%s", diff)
177
+ }
178
+ })
179
+ }
180
+ }
181
+ ```
182
+
183
+ ### Functional Options
184
+
185
+ ```go
186
+ type Server struct {
187
+ addr string
188
+ timeout time.Duration
189
+ }
190
+
191
+ type Option func(*Server)
192
+
193
+ func WithTimeout(d time.Duration) Option {
194
+ return func(s *Server) {
195
+ s.timeout = d
196
+ }
197
+ }
198
+
199
+ func NewServer(addr string, opts ...Option) *Server {
200
+ s := &Server{
201
+ addr: addr,
202
+ timeout: time.Second * 30,
203
+ }
204
+ for _, opt := range opts {
205
+ opt(s)
206
+ }
207
+ return s
208
+ }
209
+
210
+ // Usage
211
+ server := NewServer(":8080", WithTimeout(time.Minute))
212
+ ```
@@ -0,0 +1,282 @@
1
+ # Go Concurrency Patterns
2
+
3
+ > Reference for concurrent programming in Go
4
+
5
+ ## Core Philosophy
6
+
7
+ > Do not communicate by sharing memory; instead, share memory by communicating.
8
+
9
+ Go's approach to concurrency differs from traditional threading models. Channels provide a way to safely communicate between goroutines without explicit locks.
10
+
11
+ ## Goroutines
12
+
13
+ A goroutine is a lightweight thread managed by the Go runtime.
14
+
15
+ ```go
16
+ // Start a goroutine
17
+ go doSomething()
18
+
19
+ // With anonymous function
20
+ go func() {
21
+ // concurrent work
22
+ }()
23
+ ```
24
+
25
+ ### Goroutine Lifecycle
26
+
27
+ - Created with `go` keyword
28
+ - Runs concurrently with calling goroutine
29
+ - Exits when function returns
30
+ - Main goroutine exit = program exit
31
+
32
+ ## Channels
33
+
34
+ ### Basic Operations
35
+
36
+ ```go
37
+ // Create
38
+ ch := make(chan int) // unbuffered
39
+ ch := make(chan int, 10) // buffered, capacity 10
40
+
41
+ // Send
42
+ ch <- value
43
+
44
+ // Receive
45
+ value := <-ch
46
+ value, ok := <-ch // ok is false if channel closed
47
+
48
+ // Close
49
+ close(ch)
50
+ ```
51
+
52
+ ### Unbuffered vs Buffered
53
+
54
+ | Type | Behavior |
55
+ |------|----------|
56
+ | Unbuffered | Sender blocks until receiver ready |
57
+ | Buffered | Sender blocks only when buffer full |
58
+
59
+ ### Directional Channels
60
+
61
+ ```go
62
+ func sender(ch chan<- int) {
63
+ ch <- 42 // send-only
64
+ }
65
+
66
+ func receiver(ch <-chan int) {
67
+ v := <-ch // receive-only
68
+ }
69
+ ```
70
+
71
+ ## Common Patterns
72
+
73
+ ### Worker Pool
74
+
75
+ ```go
76
+ func worker(id int, jobs <-chan int, results chan<- int) {
77
+ for j := range jobs {
78
+ results <- j * 2
79
+ }
80
+ }
81
+
82
+ func main() {
83
+ jobs := make(chan int, 100)
84
+ results := make(chan int, 100)
85
+
86
+ // Start 3 workers
87
+ for w := 1; w <= 3; w++ {
88
+ go worker(w, jobs, results)
89
+ }
90
+
91
+ // Send jobs
92
+ for j := 1; j <= 9; j++ {
93
+ jobs <- j
94
+ }
95
+ close(jobs)
96
+
97
+ // Collect results
98
+ for a := 1; a <= 9; a++ {
99
+ <-results
100
+ }
101
+ }
102
+ ```
103
+
104
+ ### Fan-Out, Fan-In
105
+
106
+ ```go
107
+ // Fan-out: multiple goroutines read from same channel
108
+ // Fan-in: single goroutine reads from multiple channels
109
+
110
+ func fanIn(ch1, ch2 <-chan int) <-chan int {
111
+ out := make(chan int)
112
+ go func() {
113
+ for {
114
+ select {
115
+ case v := <-ch1:
116
+ out <- v
117
+ case v := <-ch2:
118
+ out <- v
119
+ }
120
+ }
121
+ }()
122
+ return out
123
+ }
124
+ ```
125
+
126
+ ### Pipeline
127
+
128
+ ```go
129
+ func gen(nums ...int) <-chan int {
130
+ out := make(chan int)
131
+ go func() {
132
+ for _, n := range nums {
133
+ out <- n
134
+ }
135
+ close(out)
136
+ }()
137
+ return out
138
+ }
139
+
140
+ func sq(in <-chan int) <-chan int {
141
+ out := make(chan int)
142
+ go func() {
143
+ for n := range in {
144
+ out <- n * n
145
+ }
146
+ close(out)
147
+ }()
148
+ return out
149
+ }
150
+
151
+ // Usage: for v := range sq(sq(gen(2, 3))) { ... }
152
+ ```
153
+
154
+ ### Context for Cancellation
155
+
156
+ ```go
157
+ func operation(ctx context.Context) error {
158
+ select {
159
+ case <-time.After(time.Second):
160
+ return nil // completed
161
+ case <-ctx.Done():
162
+ return ctx.Err() // cancelled
163
+ }
164
+ }
165
+
166
+ func main() {
167
+ ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
168
+ defer cancel()
169
+
170
+ if err := operation(ctx); err != nil {
171
+ log.Fatal(err)
172
+ }
173
+ }
174
+ ```
175
+
176
+ ## Select Statement
177
+
178
+ ```go
179
+ select {
180
+ case v := <-ch1:
181
+ // received from ch1
182
+ case ch2 <- x:
183
+ // sent to ch2
184
+ case <-time.After(time.Second):
185
+ // timeout
186
+ default:
187
+ // non-blocking
188
+ }
189
+ ```
190
+
191
+ ## Synchronization
192
+
193
+ ### sync.WaitGroup
194
+
195
+ ```go
196
+ var wg sync.WaitGroup
197
+
198
+ for i := 0; i < 5; i++ {
199
+ wg.Add(1)
200
+ go func(id int) {
201
+ defer wg.Done()
202
+ // work
203
+ }(i)
204
+ }
205
+
206
+ wg.Wait() // blocks until all done
207
+ ```
208
+
209
+ ### sync.Mutex
210
+
211
+ ```go
212
+ var (
213
+ mu sync.Mutex
214
+ counter int
215
+ )
216
+
217
+ func increment() {
218
+ mu.Lock()
219
+ defer mu.Unlock()
220
+ counter++
221
+ }
222
+ ```
223
+
224
+ ### sync.Once
225
+
226
+ ```go
227
+ var once sync.Once
228
+
229
+ func initialize() {
230
+ once.Do(func() {
231
+ // runs exactly once
232
+ })
233
+ }
234
+ ```
235
+
236
+ ## Avoiding Common Pitfalls
237
+
238
+ ### Goroutine Leaks
239
+
240
+ ```go
241
+ // BAD: goroutine never exits
242
+ go func() {
243
+ for {
244
+ // infinite loop with no exit
245
+ }
246
+ }()
247
+
248
+ // GOOD: use context or done channel
249
+ go func(ctx context.Context) {
250
+ for {
251
+ select {
252
+ case <-ctx.Done():
253
+ return
254
+ default:
255
+ // work
256
+ }
257
+ }
258
+ }(ctx)
259
+ ```
260
+
261
+ ### Race Conditions
262
+
263
+ ```go
264
+ // BAD: race condition
265
+ go func() { x++ }()
266
+ go func() { x++ }()
267
+
268
+ // GOOD: use channels or mutex
269
+ go func() { ch <- 1 }()
270
+ go func() { ch <- 1 }()
271
+ x += <-ch + <-ch
272
+ ```
273
+
274
+ ### Closing Channels
275
+
276
+ ```go
277
+ // Only sender should close
278
+ // Closing already-closed channel panics
279
+ // Sending to closed channel panics
280
+
281
+ // Pattern: use sync.Once or single sender
282
+ ```