autoworkflow 3.1.4 → 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 +174 -11
  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,489 @@
1
+ # OpenAPI Skill
2
+
3
+ ## Complete Specification
4
+ \`\`\`yaml
5
+ openapi: 3.1.0
6
+ info:
7
+ title: My API
8
+ description: RESTful API for user management
9
+ version: 1.0.0
10
+ contact:
11
+ name: API Support
12
+ email: support@example.com
13
+ license:
14
+ name: MIT
15
+ url: https://opensource.org/licenses/MIT
16
+
17
+ servers:
18
+ - url: https://api.example.com/v1
19
+ description: Production
20
+ - url: https://staging-api.example.com/v1
21
+ description: Staging
22
+ - url: http://localhost:3000/v1
23
+ description: Development
24
+
25
+ tags:
26
+ - name: Users
27
+ description: User management operations
28
+ - name: Posts
29
+ description: Blog post operations
30
+ - name: Auth
31
+ description: Authentication endpoints
32
+
33
+ paths:
34
+ /users:
35
+ get:
36
+ tags: [Users]
37
+ summary: List users
38
+ description: Returns a paginated list of users
39
+ operationId: listUsers
40
+ parameters:
41
+ - $ref: '#/components/parameters/PageParam'
42
+ - $ref: '#/components/parameters/LimitParam'
43
+ - name: status
44
+ in: query
45
+ schema:
46
+ type: string
47
+ enum: [active, inactive, pending]
48
+ - name: search
49
+ in: query
50
+ schema:
51
+ type: string
52
+ description: Search by name or email
53
+ responses:
54
+ '200':
55
+ description: Successful response
56
+ content:
57
+ application/json:
58
+ schema:
59
+ $ref: '#/components/schemas/UserListResponse'
60
+ '401':
61
+ $ref: '#/components/responses/Unauthorized'
62
+ security:
63
+ - BearerAuth: []
64
+
65
+ post:
66
+ tags: [Users]
67
+ summary: Create user
68
+ operationId: createUser
69
+ requestBody:
70
+ required: true
71
+ content:
72
+ application/json:
73
+ schema:
74
+ $ref: '#/components/schemas/CreateUserInput'
75
+ examples:
76
+ basic:
77
+ summary: Basic user
78
+ value:
79
+ email: user@example.com
80
+ name: John Doe
81
+ password: securepassword123
82
+ responses:
83
+ '201':
84
+ description: User created
85
+ content:
86
+ application/json:
87
+ schema:
88
+ $ref: '#/components/schemas/UserResponse'
89
+ headers:
90
+ Location:
91
+ schema:
92
+ type: string
93
+ description: URL of created resource
94
+ '400':
95
+ $ref: '#/components/responses/ValidationError'
96
+ '409':
97
+ description: Email already exists
98
+ content:
99
+ application/json:
100
+ schema:
101
+ $ref: '#/components/schemas/Error'
102
+
103
+ /users/{id}:
104
+ get:
105
+ tags: [Users]
106
+ summary: Get user by ID
107
+ operationId: getUserById
108
+ parameters:
109
+ - $ref: '#/components/parameters/UserIdParam'
110
+ responses:
111
+ '200':
112
+ description: User found
113
+ content:
114
+ application/json:
115
+ schema:
116
+ $ref: '#/components/schemas/UserResponse'
117
+ '404':
118
+ $ref: '#/components/responses/NotFound'
119
+
120
+ patch:
121
+ tags: [Users]
122
+ summary: Update user
123
+ operationId: updateUser
124
+ parameters:
125
+ - $ref: '#/components/parameters/UserIdParam'
126
+ requestBody:
127
+ required: true
128
+ content:
129
+ application/json:
130
+ schema:
131
+ $ref: '#/components/schemas/UpdateUserInput'
132
+ responses:
133
+ '200':
134
+ description: User updated
135
+ content:
136
+ application/json:
137
+ schema:
138
+ $ref: '#/components/schemas/UserResponse'
139
+ '404':
140
+ $ref: '#/components/responses/NotFound'
141
+ security:
142
+ - BearerAuth: []
143
+
144
+ delete:
145
+ tags: [Users]
146
+ summary: Delete user
147
+ operationId: deleteUser
148
+ parameters:
149
+ - $ref: '#/components/parameters/UserIdParam'
150
+ responses:
151
+ '204':
152
+ description: User deleted
153
+ '404':
154
+ $ref: '#/components/responses/NotFound'
155
+ security:
156
+ - BearerAuth: []
157
+
158
+ /auth/login:
159
+ post:
160
+ tags: [Auth]
161
+ summary: Login
162
+ operationId: login
163
+ requestBody:
164
+ required: true
165
+ content:
166
+ application/json:
167
+ schema:
168
+ type: object
169
+ required: [email, password]
170
+ properties:
171
+ email:
172
+ type: string
173
+ format: email
174
+ password:
175
+ type: string
176
+ format: password
177
+ responses:
178
+ '200':
179
+ description: Login successful
180
+ content:
181
+ application/json:
182
+ schema:
183
+ type: object
184
+ properties:
185
+ accessToken:
186
+ type: string
187
+ refreshToken:
188
+ type: string
189
+ expiresIn:
190
+ type: integer
191
+ '401':
192
+ description: Invalid credentials
193
+
194
+ components:
195
+ schemas:
196
+ User:
197
+ type: object
198
+ required: [id, email, name, createdAt]
199
+ properties:
200
+ id:
201
+ type: string
202
+ format: uuid
203
+ readOnly: true
204
+ email:
205
+ type: string
206
+ format: email
207
+ name:
208
+ type: string
209
+ minLength: 2
210
+ maxLength: 100
211
+ bio:
212
+ type: string
213
+ maxLength: 500
214
+ nullable: true
215
+ role:
216
+ type: string
217
+ enum: [user, admin, moderator]
218
+ default: user
219
+ status:
220
+ type: string
221
+ enum: [active, inactive, pending]
222
+ createdAt:
223
+ type: string
224
+ format: date-time
225
+ readOnly: true
226
+ updatedAt:
227
+ type: string
228
+ format: date-time
229
+ readOnly: true
230
+
231
+ CreateUserInput:
232
+ type: object
233
+ required: [email, name, password]
234
+ properties:
235
+ email:
236
+ type: string
237
+ format: email
238
+ name:
239
+ type: string
240
+ minLength: 2
241
+ password:
242
+ type: string
243
+ format: password
244
+ minLength: 8
245
+
246
+ UpdateUserInput:
247
+ type: object
248
+ properties:
249
+ name:
250
+ type: string
251
+ minLength: 2
252
+ bio:
253
+ type: string
254
+ maxLength: 500
255
+
256
+ UserResponse:
257
+ type: object
258
+ properties:
259
+ data:
260
+ $ref: '#/components/schemas/User'
261
+
262
+ UserListResponse:
263
+ type: object
264
+ properties:
265
+ data:
266
+ type: array
267
+ items:
268
+ $ref: '#/components/schemas/User'
269
+ meta:
270
+ $ref: '#/components/schemas/PaginationMeta'
271
+
272
+ PaginationMeta:
273
+ type: object
274
+ properties:
275
+ page:
276
+ type: integer
277
+ limit:
278
+ type: integer
279
+ total:
280
+ type: integer
281
+ totalPages:
282
+ type: integer
283
+
284
+ Error:
285
+ type: object
286
+ required: [code, message]
287
+ properties:
288
+ code:
289
+ type: string
290
+ message:
291
+ type: string
292
+ details:
293
+ type: array
294
+ items:
295
+ type: object
296
+ properties:
297
+ field:
298
+ type: string
299
+ message:
300
+ type: string
301
+
302
+ parameters:
303
+ UserIdParam:
304
+ name: id
305
+ in: path
306
+ required: true
307
+ schema:
308
+ type: string
309
+ format: uuid
310
+ description: User ID
311
+
312
+ PageParam:
313
+ name: page
314
+ in: query
315
+ schema:
316
+ type: integer
317
+ minimum: 1
318
+ default: 1
319
+
320
+ LimitParam:
321
+ name: limit
322
+ in: query
323
+ schema:
324
+ type: integer
325
+ minimum: 1
326
+ maximum: 100
327
+ default: 20
328
+
329
+ responses:
330
+ NotFound:
331
+ description: Resource not found
332
+ content:
333
+ application/json:
334
+ schema:
335
+ $ref: '#/components/schemas/Error'
336
+ example:
337
+ code: NOT_FOUND
338
+ message: Resource not found
339
+
340
+ Unauthorized:
341
+ description: Authentication required
342
+ content:
343
+ application/json:
344
+ schema:
345
+ $ref: '#/components/schemas/Error'
346
+
347
+ ValidationError:
348
+ description: Validation failed
349
+ content:
350
+ application/json:
351
+ schema:
352
+ $ref: '#/components/schemas/Error'
353
+
354
+ securitySchemes:
355
+ BearerAuth:
356
+ type: http
357
+ scheme: bearer
358
+ bearerFormat: JWT
359
+
360
+ ApiKeyAuth:
361
+ type: apiKey
362
+ in: header
363
+ name: X-API-Key
364
+
365
+ OAuth2:
366
+ type: oauth2
367
+ flows:
368
+ authorizationCode:
369
+ authorizationUrl: https://auth.example.com/authorize
370
+ tokenUrl: https://auth.example.com/token
371
+ scopes:
372
+ read:users: Read user data
373
+ write:users: Modify user data
374
+ \`\`\`
375
+
376
+ ## Code Generation
377
+ \`\`\`bash
378
+ # Generate TypeScript types
379
+ npx openapi-typescript openapi.yaml -o types/api.d.ts
380
+
381
+ # Generate client SDK
382
+ npx @openapitools/openapi-generator-cli generate \\
383
+ -i openapi.yaml \\
384
+ -g typescript-fetch \\
385
+ -o src/api-client
386
+
387
+ # Generate server stubs
388
+ npx @openapitools/openapi-generator-cli generate \\
389
+ -i openapi.yaml \\
390
+ -g typescript-express-server \\
391
+ -o src/server
392
+
393
+ # Validate spec
394
+ npx @redocly/cli lint openapi.yaml
395
+ \`\`\`
396
+
397
+ ## TypeScript Integration
398
+ \`\`\`typescript
399
+ // Using generated types
400
+ import type { paths, components } from './types/api';
401
+
402
+ type User = components['schemas']['User'];
403
+ type CreateUserInput = components['schemas']['CreateUserInput'];
404
+
405
+ // Type-safe fetch with openapi-fetch
406
+ import createClient from 'openapi-fetch';
407
+ import type { paths } from './types/api';
408
+
409
+ const client = createClient<paths>({ baseUrl: '/api' });
410
+
411
+ // Fully typed request/response
412
+ const { data, error } = await client.GET('/users/{id}', {
413
+ params: { path: { id: '123' } },
414
+ });
415
+
416
+ // data is typed as User | undefined
417
+ // error is typed as Error | undefined
418
+ \`\`\`
419
+
420
+ ## Schema Patterns
421
+ \`\`\`yaml
422
+ # Inheritance with allOf
423
+ components:
424
+ schemas:
425
+ BaseEntity:
426
+ type: object
427
+ properties:
428
+ id:
429
+ type: string
430
+ format: uuid
431
+ createdAt:
432
+ type: string
433
+ format: date-time
434
+
435
+ User:
436
+ allOf:
437
+ - $ref: '#/components/schemas/BaseEntity'
438
+ - type: object
439
+ properties:
440
+ email:
441
+ type: string
442
+
443
+ # Polymorphism with oneOf
444
+ Pet:
445
+ oneOf:
446
+ - $ref: '#/components/schemas/Cat'
447
+ - $ref: '#/components/schemas/Dog'
448
+ discriminator:
449
+ propertyName: type
450
+ mapping:
451
+ cat: '#/components/schemas/Cat'
452
+ dog: '#/components/schemas/Dog'
453
+
454
+ # Nullable fields
455
+ Profile:
456
+ type: object
457
+ properties:
458
+ bio:
459
+ type: string
460
+ nullable: true
461
+ \`\`\`
462
+
463
+ ## Documentation Tools
464
+ \`\`\`bash
465
+ # Swagger UI
466
+ npx swagger-ui-express # Express middleware
467
+
468
+ # Redoc (static docs)
469
+ npx @redocly/cli build-docs openapi.yaml -o docs/index.html
470
+
471
+ # Stoplight Elements (React component)
472
+ npm install @stoplight/elements
473
+ \`\`\`
474
+
475
+ ## ❌ DON'T
476
+ - Skip required fields in schemas
477
+ - Use generic names (data, item, object)
478
+ - Forget error responses
479
+ - Leave descriptions empty
480
+ - Use inconsistent naming conventions
481
+
482
+ ## ✅ DO
483
+ - Use \$ref for reusable components
484
+ - Include examples for all schemas
485
+ - Document all error responses
486
+ - Add operationId for code generation
487
+ - Use semantic versioning
488
+ - Validate spec before deployment
489
+ - Generate types from spec
@@ -0,0 +1,199 @@
1
+ # Performance Skill
2
+
3
+ ## Core Web Vitals
4
+ \`\`\`
5
+ LCP (Largest Contentful Paint): < 2.5s
6
+ - Optimize images, fonts, critical CSS
7
+ - Preload key resources
8
+
9
+ FID (First Input Delay): < 100ms
10
+ - Minimize JavaScript execution
11
+ - Break up long tasks
12
+
13
+ CLS (Cumulative Layout Shift): < 0.1
14
+ - Set dimensions on images/videos
15
+ - Avoid inserting content above existing content
16
+ \`\`\`
17
+
18
+ ## Code Splitting & Lazy Loading
19
+ \`\`\`tsx
20
+ // ✅ React lazy loading
21
+ import { lazy, Suspense } from 'react';
22
+
23
+ const Dashboard = lazy(() => import('./Dashboard'));
24
+ const Settings = lazy(() => import('./Settings'));
25
+
26
+ function App() {
27
+ return (
28
+ <Suspense fallback={<Loading />}>
29
+ <Routes>
30
+ <Route path="/dashboard" element={<Dashboard />} />
31
+ <Route path="/settings" element={<Settings />} />
32
+ </Routes>
33
+ </Suspense>
34
+ );
35
+ }
36
+
37
+ // ✅ Next.js dynamic import
38
+ import dynamic from 'next/dynamic';
39
+
40
+ const HeavyChart = dynamic(() => import('./HeavyChart'), {
41
+ loading: () => <Skeleton />,
42
+ ssr: false // Skip server-side rendering
43
+ });
44
+ \`\`\`
45
+
46
+ ## Image Optimization
47
+ \`\`\`tsx
48
+ // ✅ Next.js Image (automatic optimization)
49
+ import Image from 'next/image';
50
+
51
+ <Image
52
+ src="/hero.jpg"
53
+ width={1200}
54
+ height={600}
55
+ alt="Hero"
56
+ priority // Preload above-the-fold images
57
+ placeholder="blur"
58
+ blurDataURL={blurHash}
59
+ />
60
+
61
+ // ✅ Responsive images
62
+ <Image
63
+ src="/photo.jpg"
64
+ sizes="(max-width: 768px) 100vw, 50vw"
65
+ fill
66
+ style={{ objectFit: 'cover' }}
67
+ />
68
+ \`\`\`
69
+
70
+ ## React Memoization
71
+ \`\`\`tsx
72
+ // ✅ Memoize expensive computations
73
+ const sortedItems = useMemo(
74
+ () => items.sort((a, b) => b.score - a.score),
75
+ [items]
76
+ );
77
+
78
+ // ✅ Memoize callbacks passed to children
79
+ const handleClick = useCallback(
80
+ (id: string) => dispatch({ type: 'SELECT', id }),
81
+ [dispatch]
82
+ );
83
+
84
+ // ✅ Memoize components that receive objects/arrays
85
+ const MemoizedList = memo(function List({ items }: Props) {
86
+ return items.map(item => <Item key={item.id} {...item} />);
87
+ });
88
+ \`\`\`
89
+
90
+ ## Database Performance
91
+ \`\`\`typescript
92
+ // ❌ N+1 Problem
93
+ const users = await prisma.user.findMany();
94
+ for (const user of users) {
95
+ const posts = await prisma.post.findMany({ where: { authorId: user.id } });
96
+ }
97
+
98
+ // ✅ Single query with include
99
+ const users = await prisma.user.findMany({
100
+ include: { posts: true }
101
+ });
102
+
103
+ // ✅ Select only needed fields
104
+ const users = await prisma.user.findMany({
105
+ select: { id: true, name: true, email: true }
106
+ });
107
+
108
+ // ✅ Add database indexes
109
+ // schema.prisma
110
+ model User {
111
+ id String @id
112
+ email String @unique
113
+ name String
114
+
115
+ @@index([name]) // Add index for frequent lookups
116
+ }
117
+ \`\`\`
118
+
119
+ ## Redis Caching
120
+ \`\`\`typescript
121
+ import Redis from 'ioredis';
122
+
123
+ const redis = new Redis(process.env.REDIS_URL);
124
+
125
+ async function getUser(id: string) {
126
+ // Check cache first
127
+ const cached = await redis.get(\`user:\${id}\`);
128
+ if (cached) return JSON.parse(cached);
129
+
130
+ // Fetch from DB
131
+ const user = await prisma.user.findUnique({ where: { id } });
132
+
133
+ // Cache for 1 hour
134
+ await redis.set(\`user:\${id}\`, JSON.stringify(user), 'EX', 3600);
135
+
136
+ return user;
137
+ }
138
+
139
+ // Invalidate on update
140
+ async function updateUser(id: string, data: UpdateData) {
141
+ await prisma.user.update({ where: { id }, data });
142
+ await redis.del(\`user:\${id}\`); // Clear cache
143
+ }
144
+ \`\`\`
145
+
146
+ ## Bundle Analysis
147
+ \`\`\`bash
148
+ # Next.js
149
+ ANALYZE=true npm run build
150
+
151
+ # Webpack (add to package.json)
152
+ npx webpack-bundle-analyzer stats.json
153
+
154
+ # Vite
155
+ npx vite-bundle-visualizer
156
+ \`\`\`
157
+
158
+ ## Performance Budgets
159
+ \`\`\`json
160
+ // package.json or bundlesize config
161
+ {
162
+ "bundlesize": [
163
+ { "path": "./dist/main.js", "maxSize": "150 kB" },
164
+ { "path": "./dist/vendor.js", "maxSize": "300 kB" }
165
+ ]
166
+ }
167
+ \`\`\`
168
+
169
+ ## Monitoring
170
+ \`\`\`typescript
171
+ // Send Web Vitals to analytics
172
+ import { onCLS, onFID, onLCP } from 'web-vitals';
173
+
174
+ function sendToAnalytics({ name, delta, id }) {
175
+ fetch('/api/vitals', {
176
+ method: 'POST',
177
+ body: JSON.stringify({ name, delta, id })
178
+ });
179
+ }
180
+
181
+ onCLS(sendToAnalytics);
182
+ onFID(sendToAnalytics);
183
+ onLCP(sendToAnalytics);
184
+ \`\`\`
185
+
186
+ ## ❌ DON'T
187
+ - Optimize without measuring
188
+ - Load unused JavaScript
189
+ - Use large unoptimized images
190
+ - Forget to cache database queries
191
+ - Skip lazy loading for heavy components
192
+
193
+ ## ✅ DO
194
+ - Measure before optimizing
195
+ - Set performance budgets
196
+ - Use caching strategically
197
+ - Optimize critical path first
198
+ - Monitor Core Web Vitals
199
+ - Use CDN for static assets