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,237 @@
1
+ # Angular Skill
2
+
3
+ ## Component Structure
4
+ \`\`\`typescript
5
+ @Component({
6
+ selector: 'app-user-card',
7
+ standalone: true,
8
+ imports: [CommonModule],
9
+ template: \`
10
+ <div class="card">
11
+ <h2>{{ user()?.name }}</h2>
12
+ <button (click)="increment()">Count: {{ count() }}</button>
13
+ <p>Double: {{ doubleCount() }}</p>
14
+ </div>
15
+ \`
16
+ })
17
+ export class UserCardComponent {
18
+ private userService = inject(UserService);
19
+
20
+ // Signals (Angular 16+)
21
+ count = signal(0);
22
+ user = signal<User | null>(null);
23
+ doubleCount = computed(() => this.count() * 2);
24
+
25
+ // Input signals (Angular 17+)
26
+ userId = input.required<string>();
27
+ initialCount = input(0);
28
+
29
+ // Output
30
+ countChange = output<number>();
31
+
32
+ increment() {
33
+ this.count.update(c => c + 1);
34
+ this.countChange.emit(this.count());
35
+ }
36
+
37
+ constructor() {
38
+ // Effect for side effects
39
+ effect(() => {
40
+ console.log('Count changed:', this.count());
41
+ });
42
+ }
43
+ }
44
+ \`\`\`
45
+
46
+ ## Services & Dependency Injection
47
+ \`\`\`typescript
48
+ // user.service.ts
49
+ @Injectable({ providedIn: 'root' })
50
+ export class UserService {
51
+ private http = inject(HttpClient);
52
+ private apiUrl = '/api/users';
53
+
54
+ getUsers(): Observable<User[]> {
55
+ return this.http.get<User[]>(this.apiUrl);
56
+ }
57
+
58
+ getUser(id: string): Observable<User> {
59
+ return this.http.get<User>(\`\${this.apiUrl}/\${id}\`);
60
+ }
61
+
62
+ createUser(user: CreateUserDto): Observable<User> {
63
+ return this.http.post<User>(this.apiUrl, user);
64
+ }
65
+ }
66
+
67
+ // Usage in component
68
+ export class UsersComponent {
69
+ private userService = inject(UserService);
70
+
71
+ users = signal<User[]>([]);
72
+ loading = signal(true);
73
+
74
+ constructor() {
75
+ this.userService.getUsers().subscribe({
76
+ next: (users) => this.users.set(users),
77
+ complete: () => this.loading.set(false)
78
+ });
79
+ }
80
+ }
81
+ \`\`\`
82
+
83
+ ## Routing
84
+ \`\`\`typescript
85
+ // app.routes.ts
86
+ export const routes: Routes = [
87
+ { path: '', component: HomeComponent },
88
+ { path: 'users', component: UsersComponent },
89
+ { path: 'users/:id', component: UserDetailComponent },
90
+ {
91
+ path: 'admin',
92
+ loadComponent: () => import('./admin/admin.component'),
93
+ canActivate: [authGuard],
94
+ children: [
95
+ { path: 'dashboard', component: DashboardComponent }
96
+ ]
97
+ },
98
+ { path: '**', component: NotFoundComponent }
99
+ ];
100
+
101
+ // Route guard
102
+ export const authGuard: CanActivateFn = (route, state) => {
103
+ const authService = inject(AuthService);
104
+ const router = inject(Router);
105
+
106
+ if (authService.isLoggedIn()) {
107
+ return true;
108
+ }
109
+
110
+ return router.createUrlTree(['/login'], {
111
+ queryParams: { returnUrl: state.url }
112
+ });
113
+ };
114
+
115
+ // Accessing route params
116
+ export class UserDetailComponent {
117
+ private route = inject(ActivatedRoute);
118
+
119
+ userId = input.required<string>(); // With input binding
120
+ // Or from route snapshot:
121
+ // userId = this.route.snapshot.paramMap.get('id');
122
+ }
123
+ \`\`\`
124
+
125
+ ## Reactive Forms
126
+ \`\`\`typescript
127
+ @Component({
128
+ standalone: true,
129
+ imports: [ReactiveFormsModule],
130
+ template: \`
131
+ <form [formGroup]="form" (ngSubmit)="onSubmit()">
132
+ <input formControlName="email" />
133
+ @if (form.get('email')?.errors?.['required']) {
134
+ <span class="error">Email is required</span>
135
+ }
136
+ @if (form.get('email')?.errors?.['email']) {
137
+ <span class="error">Invalid email</span>
138
+ }
139
+
140
+ <input type="password" formControlName="password" />
141
+
142
+ <button type="submit" [disabled]="form.invalid">Submit</button>
143
+ </form>
144
+ \`
145
+ })
146
+ export class LoginComponent {
147
+ private fb = inject(FormBuilder);
148
+
149
+ form = this.fb.group({
150
+ email: ['', [Validators.required, Validators.email]],
151
+ password: ['', [Validators.required, Validators.minLength(8)]]
152
+ });
153
+
154
+ onSubmit() {
155
+ if (this.form.valid) {
156
+ console.log(this.form.value);
157
+ }
158
+ }
159
+ }
160
+ \`\`\`
161
+
162
+ ## HTTP Interceptors
163
+ \`\`\`typescript
164
+ // auth.interceptor.ts
165
+ export const authInterceptor: HttpInterceptorFn = (req, next) => {
166
+ const authService = inject(AuthService);
167
+ const token = authService.getToken();
168
+
169
+ if (token) {
170
+ req = req.clone({
171
+ setHeaders: { Authorization: \`Bearer \${token}\` }
172
+ });
173
+ }
174
+
175
+ return next(req).pipe(
176
+ catchError((error: HttpErrorResponse) => {
177
+ if (error.status === 401) {
178
+ authService.logout();
179
+ }
180
+ return throwError(() => error);
181
+ })
182
+ );
183
+ };
184
+
185
+ // Register in app.config.ts
186
+ export const appConfig: ApplicationConfig = {
187
+ providers: [
188
+ provideHttpClient(withInterceptors([authInterceptor])),
189
+ provideRouter(routes)
190
+ ]
191
+ };
192
+ \`\`\`
193
+
194
+ ## RxJS Patterns
195
+ \`\`\`typescript
196
+ // Search with debounce
197
+ searchTerm = new Subject<string>();
198
+
199
+ results$ = this.searchTerm.pipe(
200
+ debounceTime(300),
201
+ distinctUntilChanged(),
202
+ switchMap(term => this.searchService.search(term))
203
+ );
204
+
205
+ // Combine observables
206
+ user$ = combineLatest([
207
+ this.userService.getUser(this.userId),
208
+ this.userService.getUserPosts(this.userId)
209
+ ]).pipe(
210
+ map(([user, posts]) => ({ ...user, posts }))
211
+ );
212
+
213
+ // Auto-unsubscribe with takeUntilDestroyed
214
+ export class MyComponent {
215
+ private destroyRef = inject(DestroyRef);
216
+
217
+ ngOnInit() {
218
+ interval(1000).pipe(
219
+ takeUntilDestroyed(this.destroyRef)
220
+ ).subscribe(console.log);
221
+ }
222
+ }
223
+ \`\`\`
224
+
225
+ ## ❌ DON'T
226
+ - Use constructor for complex logic (use inject())
227
+ - Forget to unsubscribe from observables
228
+ - Use NgModules for new projects (use standalone)
229
+ - Mutate signal values directly
230
+
231
+ ## ✅ DO
232
+ - Use standalone components
233
+ - Use signals for reactive state
234
+ - Use inject() for DI
235
+ - Use functional guards and interceptors
236
+ - Use takeUntilDestroyed for cleanup
237
+ - Use control flow (@if, @for) instead of *ngIf, *ngFor
@@ -0,0 +1,187 @@
1
+ # API Design Skill
2
+
3
+ ## REST Best Practices
4
+ \`\`\`
5
+ GET /users → List users
6
+ GET /users/:id → Get single user
7
+ POST /users → Create user
8
+ PUT /users/:id → Update user (full)
9
+ PATCH /users/:id → Update user (partial)
10
+ DELETE /users/:id → Delete user
11
+
12
+ Nested Resources:
13
+ GET /users/:id/posts → List user's posts
14
+ POST /users/:id/posts → Create post for user
15
+ \`\`\`
16
+
17
+ ## Status Codes
18
+ \`\`\`
19
+ 2xx Success:
20
+ 200 OK - Success with body
21
+ 201 Created - Resource created (include Location header)
22
+ 204 No Content - Success, no body (DELETE, PUT)
23
+
24
+ 4xx Client Errors:
25
+ 400 Bad Request - Invalid input/validation failed
26
+ 401 Unauthorized - Not authenticated
27
+ 403 Forbidden - Not authorized for this resource
28
+ 404 Not Found - Resource doesn't exist
29
+ 409 Conflict - Duplicate resource (e.g., email exists)
30
+ 422 Unprocessable - Validation error (alternative to 400)
31
+ 429 Too Many Reqs - Rate limit exceeded
32
+
33
+ 5xx Server Errors:
34
+ 500 Internal Error - Server error (hide details from client)
35
+ 503 Unavailable - Maintenance/overload
36
+ \`\`\`
37
+
38
+ ## Pagination Patterns
39
+
40
+ ### Offset-based (simple, but slow for large datasets)
41
+ \`\`\`typescript
42
+ // Request: GET /users?page=2&limit=20
43
+ // Response:
44
+ {
45
+ "data": [...],
46
+ "pagination": {
47
+ "page": 2,
48
+ "limit": 20,
49
+ "total": 150,
50
+ "totalPages": 8
51
+ }
52
+ }
53
+ \`\`\`
54
+
55
+ ### Cursor-based (better for large/real-time data)
56
+ \`\`\`typescript
57
+ // Request: GET /users?cursor=abc123&limit=20
58
+ // Response:
59
+ {
60
+ "data": [...],
61
+ "pagination": {
62
+ "nextCursor": "def456",
63
+ "prevCursor": "xyz789",
64
+ "hasMore": true
65
+ }
66
+ }
67
+
68
+ // Implementation
69
+ const users = await prisma.user.findMany({
70
+ take: limit + 1, // Fetch one extra to check hasMore
71
+ cursor: cursor ? { id: cursor } : undefined,
72
+ orderBy: { createdAt: 'desc' }
73
+ });
74
+
75
+ const hasMore = users.length > limit;
76
+ const data = hasMore ? users.slice(0, -1) : users;
77
+ const nextCursor = hasMore ? data[data.length - 1].id : null;
78
+ \`\`\`
79
+
80
+ ## Filtering & Sorting
81
+ \`\`\`typescript
82
+ // Request: GET /users?status=active&role=admin&sort=-createdAt,name
83
+
84
+ // Parse and validate query params
85
+ const filters = {
86
+ status: z.enum(['active', 'inactive']).optional(),
87
+ role: z.enum(['user', 'admin']).optional(),
88
+ search: z.string().max(100).optional(),
89
+ };
90
+
91
+ const sortFields = ['createdAt', 'name', 'email'];
92
+ // - prefix means descending: -createdAt
93
+
94
+ // Response includes applied filters
95
+ {
96
+ "data": [...],
97
+ "filters": { "status": "active", "role": "admin" },
98
+ "sort": ["-createdAt", "name"]
99
+ }
100
+ \`\`\`
101
+
102
+ ## Error Response Format
103
+ \`\`\`json
104
+ {
105
+ "error": {
106
+ "code": "VALIDATION_ERROR",
107
+ "message": "Invalid input data",
108
+ "details": [
109
+ { "field": "email", "message": "Invalid email format" },
110
+ { "field": "age", "message": "Must be a positive number" }
111
+ ],
112
+ "requestId": "req_abc123"
113
+ }
114
+ }
115
+ \`\`\`
116
+
117
+ ## Rate Limiting Headers
118
+ \`\`\`
119
+ X-RateLimit-Limit: 100 # Max requests per window
120
+ X-RateLimit-Remaining: 45 # Remaining requests
121
+ X-RateLimit-Reset: 1640000000 # Unix timestamp when window resets
122
+ Retry-After: 60 # Seconds until retry (on 429)
123
+ \`\`\`
124
+
125
+ ## API Versioning Strategies
126
+ \`\`\`
127
+ 1. URL Path (recommended):
128
+ /api/v1/users
129
+ /api/v2/users
130
+
131
+ 2. Header:
132
+ Accept: application/vnd.myapi.v1+json
133
+
134
+ 3. Query Parameter:
135
+ /api/users?version=1
136
+ \`\`\`
137
+
138
+ ## Request/Response Examples
139
+ \`\`\`typescript
140
+ // POST /api/v1/users
141
+ // Request:
142
+ {
143
+ "email": "user@example.com",
144
+ "name": "John Doe",
145
+ "role": "user"
146
+ }
147
+
148
+ // Response: 201 Created
149
+ // Headers: Location: /api/v1/users/123
150
+ {
151
+ "id": "123",
152
+ "email": "user@example.com",
153
+ "name": "John Doe",
154
+ "role": "user",
155
+ "createdAt": "2024-01-15T10:30:00Z"
156
+ }
157
+
158
+ // GET /api/v1/users/123
159
+ // Response: 200 OK
160
+ {
161
+ "id": "123",
162
+ "email": "user@example.com",
163
+ "name": "John Doe",
164
+ "role": "user",
165
+ "createdAt": "2024-01-15T10:30:00Z",
166
+ "_links": {
167
+ "self": "/api/v1/users/123",
168
+ "posts": "/api/v1/users/123/posts"
169
+ }
170
+ }
171
+ \`\`\`
172
+
173
+ ## ❌ DON'T
174
+ - Use verbs in URLs (POST /createUser)
175
+ - Return 200 for errors
176
+ - Ignore pagination for list endpoints
177
+ - Expose internal IDs or stack traces
178
+ - Change API without versioning
179
+
180
+ ## ✅ DO
181
+ - Version your APIs (/api/v1/)
182
+ - Document with OpenAPI
183
+ - Use consistent naming (plural nouns)
184
+ - Implement pagination for all lists
185
+ - Add rate limiting with headers
186
+ - Include request IDs for debugging
187
+ - Use ISO 8601 for dates