ai-factory 2.0.0 → 2.2.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 (91) hide show
  1. package/README.md +17 -4
  2. package/dist/cli/commands/extension.d.ts +4 -0
  3. package/dist/cli/commands/extension.d.ts.map +1 -0
  4. package/dist/cli/commands/extension.js +288 -0
  5. package/dist/cli/commands/extension.js.map +1 -0
  6. package/dist/cli/commands/init.d.ts.map +1 -1
  7. package/dist/cli/commands/init.js +31 -35
  8. package/dist/cli/commands/init.js.map +1 -1
  9. package/dist/cli/commands/update.d.ts.map +1 -1
  10. package/dist/cli/commands/update.js +86 -7
  11. package/dist/cli/commands/update.js.map +1 -1
  12. package/dist/cli/commands/upgrade.d.ts.map +1 -1
  13. package/dist/cli/commands/upgrade.js +44 -41
  14. package/dist/cli/commands/upgrade.js.map +1 -1
  15. package/dist/cli/index.js +48 -1
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cli/wizard/prompts.d.ts +2 -1
  18. package/dist/cli/wizard/prompts.d.ts.map +1 -1
  19. package/dist/cli/wizard/prompts.js +13 -20
  20. package/dist/cli/wizard/prompts.js.map +1 -1
  21. package/dist/core/agents.d.ts.map +1 -1
  22. package/dist/core/agents.js +9 -0
  23. package/dist/core/agents.js.map +1 -1
  24. package/dist/core/config.d.ts +8 -2
  25. package/dist/core/config.d.ts.map +1 -1
  26. package/dist/core/config.js +5 -8
  27. package/dist/core/config.js.map +1 -1
  28. package/dist/core/extension-ops.d.ts +32 -0
  29. package/dist/core/extension-ops.d.ts.map +1 -0
  30. package/dist/core/extension-ops.js +83 -0
  31. package/dist/core/extension-ops.js.map +1 -0
  32. package/dist/core/extensions.d.ts +53 -0
  33. package/dist/core/extensions.d.ts.map +1 -0
  34. package/dist/core/extensions.js +141 -0
  35. package/dist/core/extensions.js.map +1 -0
  36. package/dist/core/injections.d.ts +10 -0
  37. package/dist/core/injections.d.ts.map +1 -0
  38. package/dist/core/injections.js +154 -0
  39. package/dist/core/injections.js.map +1 -0
  40. package/dist/core/installer.d.ts +7 -3
  41. package/dist/core/installer.d.ts.map +1 -1
  42. package/dist/core/installer.js +68 -26
  43. package/dist/core/installer.js.map +1 -1
  44. package/dist/core/mcp.d.ts +12 -0
  45. package/dist/core/mcp.d.ts.map +1 -1
  46. package/dist/core/mcp.js +112 -67
  47. package/dist/core/mcp.js.map +1 -1
  48. package/dist/core/transformer.d.ts +10 -1
  49. package/dist/core/transformer.d.ts.map +1 -1
  50. package/dist/core/transformer.js +19 -1
  51. package/dist/core/transformer.js.map +1 -1
  52. package/dist/core/transformers/antigravity.d.ts +1 -0
  53. package/dist/core/transformers/antigravity.d.ts.map +1 -1
  54. package/dist/core/transformers/antigravity.js +19 -4
  55. package/dist/core/transformers/antigravity.js.map +1 -1
  56. package/dist/core/transformers/codex.d.ts +7 -0
  57. package/dist/core/transformers/codex.d.ts.map +1 -0
  58. package/dist/core/transformers/codex.js +24 -0
  59. package/dist/core/transformers/codex.js.map +1 -0
  60. package/dist/core/transformers/default.d.ts +1 -0
  61. package/dist/core/transformers/default.d.ts.map +1 -1
  62. package/dist/core/transformers/default.js +6 -0
  63. package/dist/core/transformers/default.js.map +1 -1
  64. package/dist/core/transformers/kilocode.js +1 -1
  65. package/dist/core/transformers/kilocode.js.map +1 -1
  66. package/dist/core/transformers/qwen.d.ts +7 -0
  67. package/dist/core/transformers/qwen.d.ts.map +1 -0
  68. package/dist/core/transformers/qwen.js +25 -0
  69. package/dist/core/transformers/qwen.js.map +1 -0
  70. package/dist/utils/fs.d.ts +0 -2
  71. package/dist/utils/fs.d.ts.map +1 -1
  72. package/dist/utils/fs.js +1 -5
  73. package/dist/utils/fs.js.map +1 -1
  74. package/mcp/templates/playwright.json +4 -0
  75. package/package.json +16 -1
  76. package/skills/aif/SKILL.md +27 -52
  77. package/skills/aif-commit/SKILL.md +13 -1
  78. package/skills/aif-grounded/SKILL.md +90 -0
  79. package/skills/aif-implement/SKILL.md +39 -2
  80. package/skills/aif-implement/references/IMPLEMENTATION-GUIDE.md +16 -0
  81. package/skills/aif-loop/SKILL.md +2 -2
  82. package/dist/cli/wizard/detector.d.ts +0 -10
  83. package/dist/cli/wizard/detector.d.ts.map +0 -1
  84. package/dist/cli/wizard/detector.js +0 -231
  85. package/dist/cli/wizard/detector.js.map +0 -1
  86. package/skills/_templates/nextjs/nextjs-patterns/SKILL.md +0 -146
  87. package/skills/_templates/node-api/api-patterns/SKILL.md +0 -245
  88. package/skills/_templates/php/php-patterns/SKILL.md +0 -491
  89. package/skills/_templates/python/python-patterns/SKILL.md +0 -236
  90. package/skills/_templates/react/react-patterns/SKILL.md +0 -181
  91. package/skills/aif-deploy/SKILL.md +0 -138
@@ -1,231 +0,0 @@
1
- import path from 'path';
2
- import { readJsonFile, readTextFile, fileExists } from '../../utils/fs.js';
3
- export async function detectStack(projectDir) {
4
- const packageJsonPath = path.join(projectDir, 'package.json');
5
- const composerJsonPath = path.join(projectDir, 'composer.json');
6
- const requirementsPath = path.join(projectDir, 'requirements.txt');
7
- const pyprojectPath = path.join(projectDir, 'pyproject.toml');
8
- const goModPath = path.join(projectDir, 'go.mod');
9
- const cargoTomlPath = path.join(projectDir, 'Cargo.toml');
10
- if (await fileExists(packageJsonPath)) {
11
- const packageJson = await readJsonFile(packageJsonPath);
12
- if (packageJson) {
13
- return detectJavaScriptStack(packageJson, projectDir);
14
- }
15
- }
16
- if (await fileExists(composerJsonPath)) {
17
- const composerJson = await readJsonFile(composerJsonPath);
18
- if (composerJson) {
19
- return detectPhpStack(composerJson);
20
- }
21
- }
22
- if (await fileExists(requirementsPath) || await fileExists(pyprojectPath)) {
23
- return detectPythonStack(projectDir);
24
- }
25
- if (await fileExists(goModPath)) {
26
- return {
27
- name: 'go',
28
- confidence: 'high',
29
- frameworks: [],
30
- languages: ['go'],
31
- };
32
- }
33
- if (await fileExists(cargoTomlPath)) {
34
- return {
35
- name: 'rust',
36
- confidence: 'high',
37
- frameworks: [],
38
- languages: ['rust'],
39
- };
40
- }
41
- return null;
42
- }
43
- async function detectJavaScriptStack(packageJson, projectDir) {
44
- const allDeps = {
45
- ...packageJson.dependencies,
46
- ...packageJson.devDependencies,
47
- };
48
- const frameworks = [];
49
- const languages = ['javascript'];
50
- if (allDeps['typescript']) {
51
- languages.push('typescript');
52
- }
53
- if (allDeps['next']) {
54
- frameworks.push('next.js');
55
- const hasAppDir = await fileExists(path.join(projectDir, 'app'));
56
- const hasPagesDir = await fileExists(path.join(projectDir, 'pages'));
57
- return {
58
- name: 'nextjs',
59
- confidence: 'high',
60
- frameworks,
61
- languages,
62
- };
63
- }
64
- if (allDeps['react']) {
65
- frameworks.push('react');
66
- if (allDeps['vite']) {
67
- frameworks.push('vite');
68
- }
69
- return {
70
- name: 'react',
71
- confidence: 'high',
72
- frameworks,
73
- languages,
74
- };
75
- }
76
- if (allDeps['vue']) {
77
- frameworks.push('vue');
78
- return {
79
- name: 'vue',
80
- confidence: 'high',
81
- frameworks,
82
- languages,
83
- };
84
- }
85
- if (allDeps['express'] || allDeps['fastify'] || allDeps['koa'] || allDeps['hono']) {
86
- if (allDeps['express'])
87
- frameworks.push('express');
88
- if (allDeps['fastify'])
89
- frameworks.push('fastify');
90
- if (allDeps['koa'])
91
- frameworks.push('koa');
92
- if (allDeps['hono'])
93
- frameworks.push('hono');
94
- return {
95
- name: 'node-api',
96
- confidence: 'high',
97
- frameworks,
98
- languages,
99
- };
100
- }
101
- return {
102
- name: 'node',
103
- confidence: 'medium',
104
- frameworks,
105
- languages,
106
- };
107
- }
108
- function detectPhpStack(composerJson) {
109
- const allDeps = {
110
- ...composerJson.require,
111
- ...composerJson['require-dev'],
112
- };
113
- const frameworks = [];
114
- const languages = ['php'];
115
- if (allDeps['laravel/framework']) {
116
- frameworks.push('laravel');
117
- return {
118
- name: 'laravel',
119
- confidence: 'high',
120
- frameworks,
121
- languages,
122
- };
123
- }
124
- if (allDeps['symfony/framework-bundle'] || allDeps['symfony/symfony']) {
125
- frameworks.push('symfony');
126
- return {
127
- name: 'symfony',
128
- confidence: 'high',
129
- frameworks,
130
- languages,
131
- };
132
- }
133
- if (allDeps['slim/slim']) {
134
- frameworks.push('slim');
135
- return {
136
- name: 'slim',
137
- confidence: 'high',
138
- frameworks,
139
- languages,
140
- };
141
- }
142
- return {
143
- name: 'php',
144
- confidence: 'medium',
145
- frameworks,
146
- languages,
147
- };
148
- }
149
- async function detectPythonStack(projectDir) {
150
- const frameworks = [];
151
- const languages = ['python'];
152
- const requirementsPath = path.join(projectDir, 'requirements.txt');
153
- const requirements = await readTextFile(requirementsPath);
154
- if (requirements) {
155
- const lowerReqs = requirements.toLowerCase();
156
- if (lowerReqs.includes('django')) {
157
- frameworks.push('django');
158
- return {
159
- name: 'django',
160
- confidence: 'high',
161
- frameworks,
162
- languages,
163
- };
164
- }
165
- if (lowerReqs.includes('fastapi')) {
166
- frameworks.push('fastapi');
167
- return {
168
- name: 'fastapi',
169
- confidence: 'high',
170
- frameworks,
171
- languages,
172
- };
173
- }
174
- if (lowerReqs.includes('flask')) {
175
- frameworks.push('flask');
176
- return {
177
- name: 'flask',
178
- confidence: 'high',
179
- frameworks,
180
- languages,
181
- };
182
- }
183
- }
184
- return {
185
- name: 'python',
186
- confidence: 'medium',
187
- frameworks,
188
- languages,
189
- };
190
- }
191
- export function getRecommendedSkills(stack) {
192
- const baseSkills = [
193
- 'aif',
194
- 'aif-skill-generator',
195
- 'aif-plan',
196
- 'aif-implement',
197
- 'aif-commit',
198
- 'aif-review',
199
- 'aif-best-practices',
200
- 'aif-architecture',
201
- 'aif-security-checklist',
202
- ];
203
- if (!stack) {
204
- return baseSkills;
205
- }
206
- const skills = [...baseSkills];
207
- if (['nextjs', 'react', 'vue', 'node-api', 'fastapi', 'django', 'flask', 'laravel', 'symfony'].includes(stack.name)) {
208
- skills.push('aif-deploy');
209
- }
210
- return skills;
211
- }
212
- export function getRecommendedTemplate(stack) {
213
- if (!stack)
214
- return null;
215
- const templateMap = {
216
- 'nextjs': 'nextjs',
217
- 'react': 'react',
218
- 'node-api': 'node-api',
219
- 'node': 'node-api',
220
- 'python': 'python',
221
- 'django': 'python',
222
- 'fastapi': 'python',
223
- 'flask': 'python',
224
- 'php': 'php',
225
- 'laravel': 'php',
226
- 'symfony': 'php',
227
- 'slim': 'php',
228
- };
229
- return templateMap[stack.name] || null;
230
- }
231
- //# sourceMappingURL=detector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"detector.js","sourceRoot":"","sources":["../../../src/cli/wizard/detector.ts"],"names":[],"mappings":"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"}
@@ -1,146 +0,0 @@
1
- ---
2
- name: nextjs-patterns
3
- description: Next.js development patterns and best practices. Helps with App Router, Server Components, API routes, and data fetching.
4
- argument-hint: "[topic: routing|data|api|auth|forms]"
5
- ---
6
-
7
- # Next.js Patterns Guide
8
-
9
- Expert guidance on Next.js patterns using the App Router and React Server Components.
10
-
11
- ## Topics
12
-
13
- ### Routing (`/nextjs-patterns routing`)
14
-
15
- **App Router Structure:**
16
- ```
17
- app/
18
- ├── layout.tsx # Root layout
19
- ├── page.tsx # Home page
20
- ├── loading.tsx # Loading UI
21
- ├── error.tsx # Error boundary
22
- ├── not-found.tsx # 404 page
23
- ├── dashboard/
24
- │ ├── layout.tsx # Nested layout
25
- │ ├── page.tsx # /dashboard
26
- │ └── [id]/
27
- │ └── page.tsx # /dashboard/[id]
28
- └── api/
29
- └── route.ts # API route
30
- ```
31
-
32
- **Key Patterns:**
33
- - Use `layout.tsx` for shared UI and data fetching
34
- - Use `loading.tsx` with Suspense for streaming
35
- - Dynamic routes with `[param]` folders
36
- - Route groups with `(group)` folders
37
- - Parallel routes with `@slot` folders
38
-
39
- ### Data Fetching (`/nextjs-patterns data`)
40
-
41
- **Server Components (default):**
42
- ```typescript
43
- // Fetch directly in component - no useEffect needed
44
- async function Page() {
45
- const data = await fetch('https://api.example.com/data');
46
- return <div>{data}</div>;
47
- }
48
- ```
49
-
50
- **Caching:**
51
- ```typescript
52
- // Cache options
53
- fetch(url, { cache: 'force-cache' }); // Default - cached
54
- fetch(url, { cache: 'no-store' }); // Never cache
55
- fetch(url, { next: { revalidate: 60 } }); // Revalidate every 60s
56
- ```
57
-
58
- **Server Actions:**
59
- ```typescript
60
- 'use server';
61
-
62
- export async function createItem(formData: FormData) {
63
- const name = formData.get('name');
64
- await db.items.create({ name });
65
- revalidatePath('/items');
66
- }
67
- ```
68
-
69
- ### API Routes (`/nextjs-patterns api`)
70
-
71
- **Route Handlers:**
72
- ```typescript
73
- // app/api/users/route.ts
74
- import { NextRequest, NextResponse } from 'next/server';
75
-
76
- export async function GET(request: NextRequest) {
77
- const users = await db.users.findMany();
78
- return NextResponse.json(users);
79
- }
80
-
81
- export async function POST(request: NextRequest) {
82
- const body = await request.json();
83
- const user = await db.users.create(body);
84
- return NextResponse.json(user, { status: 201 });
85
- }
86
- ```
87
-
88
- ### Authentication (`/nextjs-patterns auth`)
89
-
90
- **Middleware Protection:**
91
- ```typescript
92
- // middleware.ts
93
- import { NextResponse } from 'next/server';
94
- import type { NextRequest } from 'next/server';
95
-
96
- export function middleware(request: NextRequest) {
97
- const token = request.cookies.get('token');
98
- if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
99
- return NextResponse.redirect(new URL('/login', request.url));
100
- }
101
- return NextResponse.next();
102
- }
103
-
104
- export const config = {
105
- matcher: '/dashboard/:path*',
106
- };
107
- ```
108
-
109
- ### Forms (`/nextjs-patterns forms`)
110
-
111
- **Server Action Forms:**
112
- ```typescript
113
- // Using server actions
114
- export default function Form() {
115
- async function handleSubmit(formData: FormData) {
116
- 'use server';
117
- await saveData(formData);
118
- redirect('/success');
119
- }
120
-
121
- return (
122
- <form action={handleSubmit}>
123
- <input name="email" type="email" required />
124
- <button type="submit">Submit</button>
125
- </form>
126
- );
127
- }
128
- ```
129
-
130
- ## Best Practices
131
-
132
- 1. **Default to Server Components** - Only use `'use client'` when needed
133
- 2. **Colocate data fetching** - Fetch data where it's used
134
- 3. **Use streaming** - Add `loading.tsx` for better UX
135
- 4. **Validate on server** - Never trust client input
136
- 5. **Use TypeScript** - Full type safety with Next.js
137
- 6. **Image optimization** - Always use `next/image`
138
- 7. **Font optimization** - Use `next/font`
139
-
140
- ## Common Mistakes
141
-
142
- - Adding `'use client'` unnecessarily
143
- - Fetching data in client components when server would work
144
- - Not using proper error boundaries
145
- - Missing loading states
146
- - Over-fetching with multiple small requests
@@ -1,245 +0,0 @@
1
- ---
2
- name: api-patterns
3
- description: Node.js API development patterns. Covers REST design, validation, error handling, authentication, and database access.
4
- argument-hint: "[topic: rest|validation|errors|auth|database]"
5
- ---
6
-
7
- # Node.js API Patterns Guide
8
-
9
- Best practices for building robust Node.js APIs.
10
-
11
- ## Topics
12
-
13
- ### REST Design (`/api-patterns rest`)
14
-
15
- **Resource Naming:**
16
- ```
17
- GET /users # List users
18
- GET /users/:id # Get single user
19
- POST /users # Create user
20
- PUT /users/:id # Replace user
21
- PATCH /users/:id # Update user partially
22
- DELETE /users/:id # Delete user
23
-
24
- # Nested resources
25
- GET /users/:id/posts # User's posts
26
- POST /users/:id/posts # Create post for user
27
-
28
- # Filtering, sorting, pagination
29
- GET /users?role=admin&sort=-createdAt&page=2&limit=20
30
- ```
31
-
32
- **Response Format:**
33
- ```typescript
34
- // Success response
35
- {
36
- "data": { ... },
37
- "meta": {
38
- "page": 1,
39
- "limit": 20,
40
- "total": 100
41
- }
42
- }
43
-
44
- // Error response
45
- {
46
- "error": {
47
- "code": "VALIDATION_ERROR",
48
- "message": "Invalid input",
49
- "details": [
50
- { "field": "email", "message": "Invalid email format" }
51
- ]
52
- }
53
- }
54
- ```
55
-
56
- ### Validation (`/api-patterns validation`)
57
-
58
- **Zod Schema Validation:**
59
- ```typescript
60
- import { z } from 'zod';
61
-
62
- const createUserSchema = z.object({
63
- email: z.string().email(),
64
- password: z.string().min(8),
65
- name: z.string().min(1).max(100),
66
- role: z.enum(['user', 'admin']).default('user'),
67
- });
68
-
69
- // Middleware
70
- function validate(schema: z.ZodSchema) {
71
- return (req, res, next) => {
72
- const result = schema.safeParse(req.body);
73
- if (!result.success) {
74
- return res.status(400).json({
75
- error: {
76
- code: 'VALIDATION_ERROR',
77
- details: result.error.flatten(),
78
- },
79
- });
80
- }
81
- req.body = result.data;
82
- next();
83
- };
84
- }
85
-
86
- // Usage
87
- app.post('/users', validate(createUserSchema), createUser);
88
- ```
89
-
90
- ### Error Handling (`/api-patterns errors`)
91
-
92
- **Custom Error Classes:**
93
- ```typescript
94
- class AppError extends Error {
95
- constructor(
96
- public statusCode: number,
97
- public code: string,
98
- message: string,
99
- public details?: unknown
100
- ) {
101
- super(message);
102
- }
103
- }
104
-
105
- class NotFoundError extends AppError {
106
- constructor(resource: string) {
107
- super(404, 'NOT_FOUND', `${resource} not found`);
108
- }
109
- }
110
-
111
- class ValidationError extends AppError {
112
- constructor(details: unknown) {
113
- super(400, 'VALIDATION_ERROR', 'Invalid input', details);
114
- }
115
- }
116
- ```
117
-
118
- **Global Error Handler:**
119
- ```typescript
120
- function errorHandler(err: Error, req: Request, res: Response, next: NextFunction) {
121
- console.error(err);
122
-
123
- if (err instanceof AppError) {
124
- return res.status(err.statusCode).json({
125
- error: {
126
- code: err.code,
127
- message: err.message,
128
- details: err.details,
129
- },
130
- });
131
- }
132
-
133
- // Unexpected error
134
- res.status(500).json({
135
- error: {
136
- code: 'INTERNAL_ERROR',
137
- message: 'Something went wrong',
138
- },
139
- });
140
- }
141
-
142
- app.use(errorHandler);
143
- ```
144
-
145
- ### Authentication (`/api-patterns auth`)
146
-
147
- **JWT Authentication:**
148
- ```typescript
149
- import jwt from 'jsonwebtoken';
150
-
151
- // Generate token
152
- function generateToken(user: User) {
153
- return jwt.sign(
154
- { id: user.id, role: user.role },
155
- process.env.JWT_SECRET!,
156
- { expiresIn: '7d' }
157
- );
158
- }
159
-
160
- // Auth middleware
161
- function authenticate(req: Request, res: Response, next: NextFunction) {
162
- const token = req.headers.authorization?.replace('Bearer ', '');
163
-
164
- if (!token) {
165
- throw new AppError(401, 'UNAUTHORIZED', 'No token provided');
166
- }
167
-
168
- try {
169
- const payload = jwt.verify(token, process.env.JWT_SECRET!);
170
- req.user = payload;
171
- next();
172
- } catch {
173
- throw new AppError(401, 'UNAUTHORIZED', 'Invalid token');
174
- }
175
- }
176
-
177
- // Role-based access
178
- function authorize(...roles: string[]) {
179
- return (req: Request, res: Response, next: NextFunction) => {
180
- if (!roles.includes(req.user.role)) {
181
- throw new AppError(403, 'FORBIDDEN', 'Insufficient permissions');
182
- }
183
- next();
184
- };
185
- }
186
- ```
187
-
188
- ### Database (`/api-patterns database`)
189
-
190
- **Repository Pattern:**
191
- ```typescript
192
- // Abstract database operations
193
- class UserRepository {
194
- async findById(id: string): Promise<User | null> {
195
- return db.user.findUnique({ where: { id } });
196
- }
197
-
198
- async findByEmail(email: string): Promise<User | null> {
199
- return db.user.findUnique({ where: { email } });
200
- }
201
-
202
- async create(data: CreateUserInput): Promise<User> {
203
- return db.user.create({ data });
204
- }
205
-
206
- async update(id: string, data: UpdateUserInput): Promise<User> {
207
- return db.user.update({ where: { id }, data });
208
- }
209
-
210
- async delete(id: string): Promise<void> {
211
- await db.user.delete({ where: { id } });
212
- }
213
- }
214
- ```
215
-
216
- **Transaction Pattern:**
217
- ```typescript
218
- async function transferFunds(fromId: string, toId: string, amount: number) {
219
- return db.$transaction(async (tx) => {
220
- const from = await tx.account.update({
221
- where: { id: fromId },
222
- data: { balance: { decrement: amount } },
223
- });
224
-
225
- if (from.balance < 0) {
226
- throw new AppError(400, 'INSUFFICIENT_FUNDS', 'Not enough balance');
227
- }
228
-
229
- await tx.account.update({
230
- where: { id: toId },
231
- data: { balance: { increment: amount } },
232
- });
233
- });
234
- }
235
- ```
236
-
237
- ## Best Practices
238
-
239
- 1. **Validate all input** - Never trust client data
240
- 2. **Use async/await** - Avoid callback hell
241
- 3. **Handle errors centrally** - Single error handler
242
- 4. **Log appropriately** - Structured logging
243
- 5. **Rate limit** - Protect against abuse
244
- 6. **Use CORS properly** - Restrict origins
245
- 7. **Keep secrets safe** - Use environment variables