autoworkflow 3.1.5 → 3.5.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 (123) hide show
  1. package/.claude/commands/analyze.md +19 -0
  2. package/.claude/commands/audit.md +26 -0
  3. package/.claude/commands/build.md +39 -0
  4. package/.claude/commands/commit.md +25 -0
  5. package/.claude/commands/fix.md +23 -0
  6. package/.claude/commands/plan.md +18 -0
  7. package/.claude/commands/suggest.md +23 -0
  8. package/.claude/commands/verify.md +18 -0
  9. package/.claude/hooks/post-bash-router.sh +20 -0
  10. package/.claude/hooks/post-commit.sh +140 -0
  11. package/.claude/hooks/pre-edit.sh +129 -0
  12. package/.claude/hooks/session-check.sh +79 -0
  13. package/.claude/settings.json +40 -6
  14. package/.claude/settings.local.json +3 -1
  15. package/.claude/skills/actix.md +337 -0
  16. package/.claude/skills/alembic.md +504 -0
  17. package/.claude/skills/angular.md +237 -0
  18. package/.claude/skills/api-design.md +187 -0
  19. package/.claude/skills/aspnet-core.md +377 -0
  20. package/.claude/skills/astro.md +245 -0
  21. package/.claude/skills/auth-clerk.md +327 -0
  22. package/.claude/skills/auth-firebase.md +367 -0
  23. package/.claude/skills/auth-nextauth.md +359 -0
  24. package/.claude/skills/auth-supabase.md +368 -0
  25. package/.claude/skills/axum.md +386 -0
  26. package/.claude/skills/blazor.md +456 -0
  27. package/.claude/skills/chi.md +348 -0
  28. package/.claude/skills/code-review.md +133 -0
  29. package/.claude/skills/csharp.md +296 -0
  30. package/.claude/skills/css-modules.md +325 -0
  31. package/.claude/skills/cypress.md +343 -0
  32. package/.claude/skills/debugging.md +133 -0
  33. package/.claude/skills/diesel.md +392 -0
  34. package/.claude/skills/django.md +301 -0
  35. package/.claude/skills/docker.md +319 -0
  36. package/.claude/skills/doctrine.md +473 -0
  37. package/.claude/skills/documentation.md +182 -0
  38. package/.claude/skills/dotnet.md +409 -0
  39. package/.claude/skills/drizzle.md +293 -0
  40. package/.claude/skills/echo.md +321 -0
  41. package/.claude/skills/eloquent.md +256 -0
  42. package/.claude/skills/emotion.md +426 -0
  43. package/.claude/skills/entity-framework.md +370 -0
  44. package/.claude/skills/express.md +316 -0
  45. package/.claude/skills/fastapi.md +329 -0
  46. package/.claude/skills/fastify.md +299 -0
  47. package/.claude/skills/fiber.md +315 -0
  48. package/.claude/skills/flask.md +322 -0
  49. package/.claude/skills/gin.md +342 -0
  50. package/.claude/skills/git.md +116 -0
  51. package/.claude/skills/github-actions.md +353 -0
  52. package/.claude/skills/go.md +377 -0
  53. package/.claude/skills/gorm.md +409 -0
  54. package/.claude/skills/graphql.md +478 -0
  55. package/.claude/skills/hibernate.md +379 -0
  56. package/.claude/skills/hono.md +306 -0
  57. package/.claude/skills/java.md +400 -0
  58. package/.claude/skills/jest.md +313 -0
  59. package/.claude/skills/jpa.md +282 -0
  60. package/.claude/skills/kotlin.md +347 -0
  61. package/.claude/skills/kubernetes.md +363 -0
  62. package/.claude/skills/laravel.md +414 -0
  63. package/.claude/skills/mcp-browser.md +320 -0
  64. package/.claude/skills/mcp-database.md +219 -0
  65. package/.claude/skills/mcp-fetch.md +241 -0
  66. package/.claude/skills/mcp-filesystem.md +204 -0
  67. package/.claude/skills/mcp-github.md +217 -0
  68. package/.claude/skills/mcp-memory.md +240 -0
  69. package/.claude/skills/mcp-search.md +218 -0
  70. package/.claude/skills/mcp-slack.md +262 -0
  71. package/.claude/skills/micronaut.md +388 -0
  72. package/.claude/skills/mongodb.md +319 -0
  73. package/.claude/skills/mongoose.md +355 -0
  74. package/.claude/skills/mysql.md +281 -0
  75. package/.claude/skills/nestjs.md +335 -0
  76. package/.claude/skills/nextjs-app-router.md +260 -0
  77. package/.claude/skills/nextjs-pages.md +172 -0
  78. package/.claude/skills/nuxt.md +202 -0
  79. package/.claude/skills/openapi.md +489 -0
  80. package/.claude/skills/performance.md +199 -0
  81. package/.claude/skills/php.md +398 -0
  82. package/.claude/skills/playwright.md +371 -0
  83. package/.claude/skills/postgresql.md +257 -0
  84. package/.claude/skills/prisma.md +293 -0
  85. package/.claude/skills/pydantic.md +304 -0
  86. package/.claude/skills/pytest.md +313 -0
  87. package/.claude/skills/python.md +272 -0
  88. package/.claude/skills/quarkus.md +377 -0
  89. package/.claude/skills/react.md +230 -0
  90. package/.claude/skills/redis.md +391 -0
  91. package/.claude/skills/refactoring.md +143 -0
  92. package/.claude/skills/remix.md +246 -0
  93. package/.claude/skills/rest-api.md +490 -0
  94. package/.claude/skills/rocket.md +366 -0
  95. package/.claude/skills/rust.md +341 -0
  96. package/.claude/skills/sass.md +380 -0
  97. package/.claude/skills/sea-orm.md +382 -0
  98. package/.claude/skills/security.md +167 -0
  99. package/.claude/skills/sequelize.md +395 -0
  100. package/.claude/skills/spring-boot.md +416 -0
  101. package/.claude/skills/sqlalchemy.md +269 -0
  102. package/.claude/skills/sqlx-rust.md +408 -0
  103. package/.claude/skills/state-jotai.md +346 -0
  104. package/.claude/skills/state-mobx.md +353 -0
  105. package/.claude/skills/state-pinia.md +431 -0
  106. package/.claude/skills/state-redux.md +337 -0
  107. package/.claude/skills/state-tanstack-query.md +434 -0
  108. package/.claude/skills/state-zustand.md +340 -0
  109. package/.claude/skills/styled-components.md +403 -0
  110. package/.claude/skills/svelte.md +238 -0
  111. package/.claude/skills/sveltekit.md +207 -0
  112. package/.claude/skills/symfony.md +437 -0
  113. package/.claude/skills/tailwind.md +279 -0
  114. package/.claude/skills/terraform.md +394 -0
  115. package/.claude/skills/testing-library.md +371 -0
  116. package/.claude/skills/trpc.md +426 -0
  117. package/.claude/skills/typeorm.md +368 -0
  118. package/.claude/skills/vitest.md +330 -0
  119. package/.claude/skills/vue.md +202 -0
  120. package/.claude/skills/warp.md +365 -0
  121. package/README.md +135 -52
  122. package/package.json +1 -1
  123. package/system/triggers.md +152 -11
@@ -0,0 +1,348 @@
1
+ # Chi Router Skill
2
+
3
+ ## Application Setup
4
+ \`\`\`go
5
+ package main
6
+
7
+ import (
8
+ "context"
9
+ "encoding/json"
10
+ "log"
11
+ "net/http"
12
+ "time"
13
+
14
+ "github.com/go-chi/chi/v5"
15
+ "github.com/go-chi/chi/v5/middleware"
16
+ "github.com/go-chi/cors"
17
+ "github.com/go-chi/httprate"
18
+ )
19
+
20
+ func main() {
21
+ r := chi.NewRouter()
22
+
23
+ // Global middleware stack
24
+ r.Use(middleware.RequestID)
25
+ r.Use(middleware.RealIP)
26
+ r.Use(middleware.Logger)
27
+ r.Use(middleware.Recoverer)
28
+ r.Use(middleware.Timeout(30 * time.Second))
29
+ r.Use(cors.Handler(cors.Options{
30
+ AllowedOrigins: []string{"*"},
31
+ AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
32
+ AllowedHeaders: []string{"Authorization", "Content-Type"},
33
+ AllowCredentials: true,
34
+ MaxAge: 300,
35
+ }))
36
+
37
+ // Health check
38
+ r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
39
+ respondJSON(w, http.StatusOK, map[string]string{"status": "ok"})
40
+ })
41
+
42
+ // Mount routes
43
+ r.Mount("/api/v1", apiRouter())
44
+
45
+ log.Println("Server starting on :8080")
46
+ log.Fatal(http.ListenAndServe(":8080", r))
47
+ }
48
+ \`\`\`
49
+
50
+ ## Route Groups and Subrouters
51
+ \`\`\`go
52
+ func apiRouter() http.Handler {
53
+ r := chi.NewRouter()
54
+
55
+ // Public routes
56
+ r.Group(func(r chi.Router) {
57
+ r.Post("/auth/login", loginHandler)
58
+ r.Post("/auth/register", registerHandler)
59
+ })
60
+
61
+ // Protected routes
62
+ r.Group(func(r chi.Router) {
63
+ r.Use(AuthMiddleware)
64
+
65
+ // Users routes
66
+ r.Route("/users", func(r chi.Router) {
67
+ r.Get("/", listUsersHandler)
68
+ r.Post("/", createUserHandler)
69
+
70
+ r.Route("/{userID}", func(r chi.Router) {
71
+ r.Use(UserCtx) // Load user into context
72
+ r.Get("/", getUserHandler)
73
+ r.Put("/", updateUserHandler)
74
+ r.Delete("/", deleteUserHandler)
75
+ })
76
+ })
77
+
78
+ // Posts routes with rate limiting
79
+ r.Route("/posts", func(r chi.Router) {
80
+ r.Use(httprate.LimitByIP(10, time.Minute))
81
+ r.Get("/", listPostsHandler)
82
+ r.Post("/", createPostHandler)
83
+
84
+ r.Route("/{postID}", func(r chi.Router) {
85
+ r.Use(PostCtx)
86
+ r.Get("/", getPostHandler)
87
+ r.Put("/", updatePostHandler)
88
+ r.Delete("/", deletePostHandler)
89
+ })
90
+ })
91
+ })
92
+
93
+ return r
94
+ }
95
+ \`\`\`
96
+
97
+ ## Context Middleware Pattern
98
+ \`\`\`go
99
+ // Context keys
100
+ type contextKey string
101
+
102
+ const (
103
+ userCtxKey contextKey = "user"
104
+ postCtxKey contextKey = "post"
105
+ )
106
+
107
+ // UserCtx loads user from URL param into context
108
+ func UserCtx(next http.Handler) http.Handler {
109
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
110
+ userID := chi.URLParam(r, "userID")
111
+
112
+ user, err := userService.GetByID(r.Context(), userID)
113
+ if err != nil {
114
+ if errors.Is(err, ErrNotFound) {
115
+ respondError(w, http.StatusNotFound, "user not found")
116
+ return
117
+ }
118
+ respondError(w, http.StatusInternalServerError, "internal error")
119
+ return
120
+ }
121
+
122
+ ctx := context.WithValue(r.Context(), userCtxKey, user)
123
+ next.ServeHTTP(w, r.WithContext(ctx))
124
+ })
125
+ }
126
+
127
+ // Helper to get user from context
128
+ func UserFromContext(ctx context.Context) *model.User {
129
+ user, _ := ctx.Value(userCtxKey).(*model.User)
130
+ return user
131
+ }
132
+
133
+ // Handler using context
134
+ func getUserHandler(w http.ResponseWriter, r *http.Request) {
135
+ user := UserFromContext(r.Context())
136
+ respondJSON(w, http.StatusOK, user)
137
+ }
138
+ \`\`\`
139
+
140
+ ## Request Handling
141
+ \`\`\`go
142
+ type CreateUserRequest struct {
143
+ Email string \`json:"email" validate:"required,email"\`
144
+ Name string \`json:"name" validate:"required,min=2,max=100"\`
145
+ Password string \`json:"password" validate:"required,min=8"\`
146
+ }
147
+
148
+ type QueryParams struct {
149
+ Page int \`json:"page"\`
150
+ PerPage int \`json:"per_page"\`
151
+ Sort string \`json:"sort"\`
152
+ }
153
+
154
+ func createUserHandler(w http.ResponseWriter, r *http.Request) {
155
+ var req CreateUserRequest
156
+ if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
157
+ respondError(w, http.StatusBadRequest, "invalid request body")
158
+ return
159
+ }
160
+
161
+ if err := validate.Struct(&req); err != nil {
162
+ respondError(w, http.StatusBadRequest, formatValidationErrors(err))
163
+ return
164
+ }
165
+
166
+ user, err := userService.Create(r.Context(), req)
167
+ if err != nil {
168
+ handleError(w, err)
169
+ return
170
+ }
171
+
172
+ respondJSON(w, http.StatusCreated, user)
173
+ }
174
+
175
+ func listUsersHandler(w http.ResponseWriter, r *http.Request) {
176
+ // Parse query params
177
+ page, _ := strconv.Atoi(r.URL.Query().Get("page"))
178
+ perPage, _ := strconv.Atoi(r.URL.Query().Get("per_page"))
179
+
180
+ if page == 0 {
181
+ page = 1
182
+ }
183
+ if perPage == 0 {
184
+ perPage = 20
185
+ }
186
+
187
+ users, total, err := userService.List(r.Context(), page, perPage)
188
+ if err != nil {
189
+ handleError(w, err)
190
+ return
191
+ }
192
+
193
+ respondJSON(w, http.StatusOK, map[string]interface{}{
194
+ "data": users,
195
+ "total": total,
196
+ "page": page,
197
+ "per_page": perPage,
198
+ })
199
+ }
200
+ \`\`\`
201
+
202
+ ## Auth Middleware
203
+ \`\`\`go
204
+ type authContextKey struct{}
205
+
206
+ type AuthInfo struct {
207
+ UserID string
208
+ Role string
209
+ }
210
+
211
+ func AuthMiddleware(next http.Handler) http.Handler {
212
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
213
+ authHeader := r.Header.Get("Authorization")
214
+ if authHeader == "" {
215
+ respondError(w, http.StatusUnauthorized, "missing authorization header")
216
+ return
217
+ }
218
+
219
+ tokenString := strings.TrimPrefix(authHeader, "Bearer ")
220
+ claims, err := validateToken(tokenString)
221
+ if err != nil {
222
+ respondError(w, http.StatusUnauthorized, "invalid token")
223
+ return
224
+ }
225
+
226
+ // Store auth info in context
227
+ authInfo := &AuthInfo{
228
+ UserID: claims.UserID,
229
+ Role: claims.Role,
230
+ }
231
+ ctx := context.WithValue(r.Context(), authContextKey{}, authInfo)
232
+ next.ServeHTTP(w, r.WithContext(ctx))
233
+ })
234
+ }
235
+
236
+ func AuthFromContext(ctx context.Context) *AuthInfo {
237
+ auth, _ := ctx.Value(authContextKey{}).(*AuthInfo)
238
+ return auth
239
+ }
240
+ \`\`\`
241
+
242
+ ## Response Helpers
243
+ \`\`\`go
244
+ func respondJSON(w http.ResponseWriter, status int, data interface{}) {
245
+ w.Header().Set("Content-Type", "application/json")
246
+ w.WriteHeader(status)
247
+ if data != nil {
248
+ json.NewEncoder(w).Encode(data)
249
+ }
250
+ }
251
+
252
+ func respondError(w http.ResponseWriter, status int, message interface{}) {
253
+ respondJSON(w, status, map[string]interface{}{"error": message})
254
+ }
255
+
256
+ func handleError(w http.ResponseWriter, err error) {
257
+ switch {
258
+ case errors.Is(err, ErrNotFound):
259
+ respondError(w, http.StatusNotFound, "resource not found")
260
+ case errors.Is(err, ErrUnauthorized):
261
+ respondError(w, http.StatusUnauthorized, "unauthorized")
262
+ case errors.Is(err, ErrForbidden):
263
+ respondError(w, http.StatusForbidden, "forbidden")
264
+ case errors.Is(err, ErrConflict):
265
+ respondError(w, http.StatusConflict, "resource already exists")
266
+ default:
267
+ log.Printf("internal error: %v", err)
268
+ respondError(w, http.StatusInternalServerError, "internal server error")
269
+ }
270
+ }
271
+ \`\`\`
272
+
273
+ ## Testing
274
+ \`\`\`go
275
+ package handler_test
276
+
277
+ import (
278
+ "bytes"
279
+ "encoding/json"
280
+ "net/http"
281
+ "net/http/httptest"
282
+ "testing"
283
+
284
+ "github.com/go-chi/chi/v5"
285
+ "github.com/stretchr/testify/assert"
286
+ )
287
+
288
+ func setupTestRouter() *chi.Mux {
289
+ r := chi.NewRouter()
290
+ r.Mount("/api/v1", apiRouter())
291
+ return r
292
+ }
293
+
294
+ func TestCreateUser(t *testing.T) {
295
+ router := setupTestRouter()
296
+
297
+ tests := []struct {
298
+ name string
299
+ body map[string]interface{}
300
+ wantStatus int
301
+ }{
302
+ {
303
+ name: "valid user",
304
+ body: map[string]interface{}{
305
+ "email": "test@example.com",
306
+ "name": "Test User",
307
+ "password": "password123",
308
+ },
309
+ wantStatus: http.StatusCreated,
310
+ },
311
+ {
312
+ name: "missing email",
313
+ body: map[string]interface{}{
314
+ "name": "Test User",
315
+ "password": "password123",
316
+ },
317
+ wantStatus: http.StatusBadRequest,
318
+ },
319
+ }
320
+
321
+ for _, tt := range tests {
322
+ t.Run(tt.name, func(t *testing.T) {
323
+ body, _ := json.Marshal(tt.body)
324
+ req := httptest.NewRequest("POST", "/api/v1/users", bytes.NewBuffer(body))
325
+ req.Header.Set("Content-Type", "application/json")
326
+
327
+ rec := httptest.NewRecorder()
328
+ router.ServeHTTP(rec, req)
329
+
330
+ assert.Equal(t, tt.wantStatus, rec.Code)
331
+ })
332
+ }
333
+ }
334
+ \`\`\`
335
+
336
+ ## ✅ DO
337
+ - Use \`chi.URLParam()\` to get URL parameters
338
+ - Use context middleware pattern for loading resources
339
+ - Use \`r.Group()\` for applying middleware to route groups
340
+ - Use \`r.Mount()\` for modular subrouters
341
+ - Use \`middleware.Timeout\` to prevent hanging requests
342
+ - Pass \`r.Context()\` to service layer
343
+
344
+ ## ❌ DON'T
345
+ - Don't forget to call \`next.ServeHTTP()\` in middleware
346
+ - Don't use global state - pass dependencies through context or closures
347
+ - Don't ignore errors from \`json.NewDecoder().Decode()\`
348
+ - Don't write to response after calling \`next.ServeHTTP()\`
@@ -0,0 +1,133 @@
1
+ # Code Review Skill
2
+
3
+ ## PR Size Guidelines
4
+ - **Ideal**: < 400 lines changed
5
+ - **Acceptable**: 400-800 lines
6
+ - **Too Large**: > 800 lines (request split)
7
+ - **Exception**: Generated files, migrations, dependencies
8
+
9
+ ## Review Checklist
10
+
11
+ ### Correctness
12
+ - [ ] Does the code do what it's supposed to?
13
+ - [ ] Are edge cases handled?
14
+ - [ ] Are error cases handled?
15
+ - [ ] Does it match the requirements/ticket?
16
+
17
+ ### Security (OWASP Top 10)
18
+ - [ ] Input validation present? (Injection prevention)
19
+ - [ ] Authentication/authorization correct?
20
+ - [ ] No sensitive data exposure? (logs, errors, responses)
21
+ - [ ] No SQL injection risks? (parameterized queries)
22
+ - [ ] No XSS vulnerabilities? (output encoding)
23
+ - [ ] Secrets not hardcoded? (use env vars)
24
+ - [ ] CSRF protection for state-changing operations?
25
+ - [ ] Dependencies up to date? (known vulnerabilities)
26
+
27
+ ### Performance
28
+ - [ ] No N+1 queries?
29
+ - [ ] Large lists paginated?
30
+ - [ ] Expensive operations cached?
31
+ - [ ] No blocking operations in hot paths?
32
+ - [ ] Indexes added for new queries?
33
+
34
+ ### Maintainability
35
+ - [ ] Code is readable?
36
+ - [ ] Functions are focused (single responsibility)?
37
+ - [ ] Names are meaningful?
38
+ - [ ] No magic numbers?
39
+ - [ ] Complex logic has comments explaining "why"?
40
+
41
+ ### Testing
42
+ - [ ] Tests cover happy path?
43
+ - [ ] Tests cover error cases?
44
+ - [ ] Tests are maintainable?
45
+ - [ ] No flaky tests introduced?
46
+
47
+ ## Automation (Let Tools Handle These)
48
+ \`\`\`yaml
49
+ # .github/workflows/pr-checks.yml
50
+ name: PR Checks
51
+ on: [pull_request]
52
+ jobs:
53
+ checks:
54
+ runs-on: ubuntu-latest
55
+ steps:
56
+ - uses: actions/checkout@v4
57
+ - run: npm ci
58
+ - run: npm run lint # Code style
59
+ - run: npm run typecheck # Type errors
60
+ - run: npm run test # Unit tests
61
+ - run: npm audit # Security vulnerabilities
62
+ \`\`\`
63
+
64
+ ## Giving Feedback
65
+
66
+ ### Feedback Prefixes
67
+ \`\`\`markdown
68
+ [MUST] → Required change, blocking
69
+ [SHOULD] → Strong recommendation
70
+ [NIT] → Minor suggestion, non-blocking
71
+ [Q] → Question for clarification
72
+ [PRAISE] → Highlight good code
73
+ \`\`\`
74
+
75
+ ### Good Feedback Examples
76
+ \`\`\`markdown
77
+ # ✅ GOOD FEEDBACK
78
+ "[SHOULD] Consider using early return here to reduce nesting - it makes the happy path clearer"
79
+
80
+ "[NIT] This could be extracted to a constant, but not blocking"
81
+
82
+ "[Q] What happens if the user array is empty here?"
83
+
84
+ "[PRAISE] Nice use of the builder pattern here!"
85
+
86
+ # ❌ BAD FEEDBACK
87
+ "This code is bad"
88
+ "You should know better"
89
+ "Why didn't you...?"
90
+ \`\`\`
91
+
92
+ ## Response Templates
93
+
94
+ ### Requesting Changes
95
+ \`\`\`markdown
96
+ Thanks for the PR! I have a few suggestions:
97
+
98
+ 1. **Security**: [specific issue]
99
+ 2. **Performance**: [specific issue]
100
+
101
+ Happy to discuss any of these!
102
+ \`\`\`
103
+
104
+ ### Approving with Comments
105
+ \`\`\`markdown
106
+ LGTM! 🚀
107
+
108
+ A few optional suggestions for future consideration:
109
+ - [non-blocking suggestion]
110
+
111
+ Nice work on [specific positive aspect].
112
+ \`\`\`
113
+
114
+ ## Review Time Guidelines
115
+ - Respond within 24 hours (business days)
116
+ - Small PRs: Review immediately if possible
117
+ - Large PRs: Schedule dedicated time
118
+ - Time-box reviews: 30-60 min max per session
119
+
120
+ ## ❌ DON'T
121
+ - Be harsh or personal
122
+ - Nitpick style (use linters)
123
+ - Approve without reading
124
+ - Let PRs sit for days
125
+ - Request changes without explanation
126
+
127
+ ## ✅ DO
128
+ - Be specific and constructive
129
+ - Explain the "why"
130
+ - Suggest alternatives with code examples
131
+ - Acknowledge good code
132
+ - Use automation for style/formatting
133
+ - Prioritize blocking issues first