@devmunna/agent-skillkit 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.
- package/LICENSE +21 -0
- package/README.md +147 -0
- package/bin/ai-skills.js +5 -0
- package/dist/cli/commands/add.d.ts +2 -0
- package/dist/cli/commands/add.d.ts.map +1 -0
- package/dist/cli/commands/add.js +66 -0
- package/dist/cli/commands/add.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +33 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init.d.ts +10 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +145 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/list.d.ts +5 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +55 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/update.d.ts +2 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +49 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +2 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +22 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +49 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompts/agent-selector.d.ts +3 -0
- package/dist/cli/prompts/agent-selector.d.ts.map +1 -0
- package/dist/cli/prompts/agent-selector.js +23 -0
- package/dist/cli/prompts/agent-selector.js.map +1 -0
- package/dist/cli/prompts/stack-selector.d.ts +3 -0
- package/dist/cli/prompts/stack-selector.d.ts.map +1 -0
- package/dist/cli/prompts/stack-selector.js +60 -0
- package/dist/cli/prompts/stack-selector.js.map +1 -0
- package/dist/core/config-manager.d.ts +20 -0
- package/dist/core/config-manager.d.ts.map +1 -0
- package/dist/core/config-manager.js +107 -0
- package/dist/core/config-manager.js.map +1 -0
- package/dist/core/detector.d.ts +3 -0
- package/dist/core/detector.d.ts.map +1 -0
- package/dist/core/detector.js +50 -0
- package/dist/core/detector.js.map +1 -0
- package/dist/core/doctor.d.ts +12 -0
- package/dist/core/doctor.d.ts.map +1 -0
- package/dist/core/doctor.js +102 -0
- package/dist/core/doctor.js.map +1 -0
- package/dist/core/skill-registry.d.ts +11 -0
- package/dist/core/skill-registry.d.ts.map +1 -0
- package/dist/core/skill-registry.js +174 -0
- package/dist/core/skill-registry.js.map +1 -0
- package/dist/core/skill-resolver.d.ts +3 -0
- package/dist/core/skill-resolver.d.ts.map +1 -0
- package/dist/core/skill-resolver.js +36 -0
- package/dist/core/skill-resolver.js.map +1 -0
- package/dist/core/validator.d.ts +13 -0
- package/dist/core/validator.d.ts.map +1 -0
- package/dist/core/validator.js +99 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/generators/agent-installer.d.ts +5 -0
- package/dist/generators/agent-installer.d.ts.map +1 -0
- package/dist/generators/agent-installer.js +20 -0
- package/dist/generators/agent-installer.js.map +1 -0
- package/dist/generators/agents-md.d.ts +3 -0
- package/dist/generators/agents-md.d.ts.map +1 -0
- package/dist/generators/agents-md.js +70 -0
- package/dist/generators/agents-md.js.map +1 -0
- package/dist/generators/claude-md.d.ts +3 -0
- package/dist/generators/claude-md.d.ts.map +1 -0
- package/dist/generators/claude-md.js +47 -0
- package/dist/generators/claude-md.js.map +1 -0
- package/dist/generators/skill-generator.d.ts +5 -0
- package/dist/generators/skill-generator.d.ts.map +1 -0
- package/dist/generators/skill-generator.js +34 -0
- package/dist/generators/skill-generator.js.map +1 -0
- package/dist/generators/workflows.d.ts +3 -0
- package/dist/generators/workflows.d.ts.map +1 -0
- package/dist/generators/workflows.js +57 -0
- package/dist/generators/workflows.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +55 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/file-utils.d.ts +12 -0
- package/dist/utils/file-utils.d.ts.map +1 -0
- package/dist/utils/file-utils.js +39 -0
- package/dist/utils/file-utils.js.map +1 -0
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +11 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +73 -0
- package/skills/clean-architecture/SKILL.md +324 -0
- package/skills/express-mvc-prisma/SKILL.md +168 -0
- package/skills/express-mvc-prisma/references/auth.md +190 -0
- package/skills/express-mvc-prisma/references/boilerplate.md +196 -0
- package/skills/express-mvc-prisma/references/error-handling.md +121 -0
- package/skills/express-mvc-prisma/references/module-scaffold.md +253 -0
- package/skills/express-mvc-prisma/references/prisma-setup.md +97 -0
- package/skills/express-mvc-prisma/references/response-helpers.md +157 -0
- package/skills/express-mvc-prisma/references/zod-validation.md +157 -0
- package/skills/fastify-rest/SKILL.md +287 -0
- package/skills/mongoose-odm/SKILL.md +281 -0
- package/skills/nextjs-fullstack/SKILL.md +328 -0
- package/skills/nextjs-fullstack/references/auth.md +270 -0
- package/skills/nextjs-fullstack/references/caching.md +157 -0
- package/skills/nextjs-fullstack/references/route-handlers.md +194 -0
- package/skills/nextjs-fullstack/references/server-actions.md +214 -0
- package/skills/nextjs-fullstack/references/server-components.md +190 -0
- package/skills/node-base/SKILL.md +139 -0
- package/skills/prisma-orm/SKILL.md +334 -0
- package/skills/react-feature-arch/SKILL.md +208 -0
- package/skills/react-feature-arch/references/api-layer.md +110 -0
- package/skills/react-feature-arch/references/components.md +192 -0
- package/skills/react-feature-arch/references/data-fetching.md +198 -0
- package/skills/react-feature-arch/references/forms.md +194 -0
- package/skills/react-feature-arch/references/routing.md +148 -0
- package/skills/react-feature-arch/references/state-management.md +107 -0
- package/skills/tailwind-css/SKILL.md +236 -0
- package/skills/tailwind-css/references/components.md +340 -0
- package/skills/tailwind-css/references/design-tokens.md +230 -0
- package/skills/tailwind-css/references/patterns.md +375 -0
- package/skills/tailwind-css/references/setup.md +165 -0
- package/skills/zod-validation/SKILL.md +267 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zod-validation
|
|
3
|
+
version: 2.0.0
|
|
4
|
+
description: >
|
|
5
|
+
Apply this skill for any task involving Zod: writing validation schemas, validating request bodies/params/query, inferring TypeScript types, validating environment variables, composing schemas, or handling validation errors. Triggers: "validate with Zod", "Zod schema", "request validation", "env validation", "parse input", "schema inference". Updated for Zod v4.
|
|
6
|
+
stack: [zod]
|
|
7
|
+
depends: []
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Zod Validation Skill — v4
|
|
11
|
+
|
|
12
|
+
TypeScript-first schema validation. This skill covers **Zod v4** (current in IPSUM PLMS and recommended for all new projects).
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Zod v4 — Key Differences from v3
|
|
17
|
+
|
|
18
|
+
| Feature | v3 | v4 |
|
|
19
|
+
|---------|----|----|
|
|
20
|
+
| Error accessor | `error.errors` or `error.flatten()` | **`error.issues`** (primary) |
|
|
21
|
+
| Field errors | `error.flatten().fieldErrors` | `error.issues.map(i => ({ field: i.path.join('.'), message: i.message }))` |
|
|
22
|
+
| Performance | Baseline | 10–100x faster parsing |
|
|
23
|
+
| Bundle size | ~50kb | ~30kb |
|
|
24
|
+
| JSON Schema | External lib | `z.toJSONSchema()` built-in |
|
|
25
|
+
| API compatibility | — | Mostly backwards-compatible |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Core Principle
|
|
30
|
+
|
|
31
|
+
Zod validates AND transforms. After `safeParse`, the output is the coerced/defaulted value — always use `result.data`, never the raw input.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Request Validation Middleware
|
|
36
|
+
|
|
37
|
+
### Zod v4 — IPSUM PLMS pattern (body-only)
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
// src/middlewares/validate.middleware.js — IPSUM pattern
|
|
41
|
+
export const validate = (schema) => (req, res, next) => {
|
|
42
|
+
const result = schema.safeParse(req.body);
|
|
43
|
+
|
|
44
|
+
if (!result.success) {
|
|
45
|
+
// Zod v4: use .issues (array of { path, message, code })
|
|
46
|
+
const errors = result.error.issues.map((e) => ({
|
|
47
|
+
field: e.path.join('.'),
|
|
48
|
+
message: e.message,
|
|
49
|
+
}));
|
|
50
|
+
|
|
51
|
+
return res.status(400).json({
|
|
52
|
+
success: false,
|
|
53
|
+
message: 'Validation failed',
|
|
54
|
+
errors,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
req.body = result.data; // replace with parsed/coerced data
|
|
59
|
+
next();
|
|
60
|
+
};
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Zod v4 — Full pattern (body + params + query)
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
export const validate = (schema) => (req, res, next) => {
|
|
67
|
+
const result = schema.safeParse({
|
|
68
|
+
body: req.body,
|
|
69
|
+
params: req.params,
|
|
70
|
+
query: req.query,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (!result.success) {
|
|
74
|
+
const errors = result.error.issues.map((e) => ({
|
|
75
|
+
field: e.path.join('.'),
|
|
76
|
+
message: e.message,
|
|
77
|
+
}));
|
|
78
|
+
return res.status(422).json({ success: false, message: 'Validation failed', errors });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (result.data.body) req.body = result.data.body;
|
|
82
|
+
if (result.data.params) req.params = result.data.params;
|
|
83
|
+
if (result.data.query) req.query = result.data.query;
|
|
84
|
+
next();
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Schema Structure
|
|
92
|
+
|
|
93
|
+
Always wrap in `z.object({ body?, params?, query? })` for the validate middleware:
|
|
94
|
+
|
|
95
|
+
```js
|
|
96
|
+
import { z } from 'zod';
|
|
97
|
+
|
|
98
|
+
export const createUserSchema = z.object({
|
|
99
|
+
body: z.object({
|
|
100
|
+
name: z.string().min(2).max(100),
|
|
101
|
+
email: z.string().email(),
|
|
102
|
+
password: z.string().min(8),
|
|
103
|
+
role: z.enum(['USER', 'ADMIN']).default('USER'),
|
|
104
|
+
}).strict(),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export const getUserSchema = z.object({
|
|
108
|
+
params: z.object({ id: z.string().uuid() }),
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
export const listUsersSchema = z.object({
|
|
112
|
+
query: z.object({
|
|
113
|
+
page: z.coerce.number().int().positive().default(1),
|
|
114
|
+
limit: z.coerce.number().int().positive().max(100).default(10),
|
|
115
|
+
search: z.string().optional(),
|
|
116
|
+
role: z.enum(['USER', 'ADMIN']).optional(),
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Type Inference (TypeScript)
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { z } from 'zod';
|
|
127
|
+
|
|
128
|
+
const createUserSchema = z.object({
|
|
129
|
+
name: z.string(),
|
|
130
|
+
email: z.string().email(),
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Infer type from schema
|
|
134
|
+
type CreateUserDto = z.infer<typeof createUserSchema>;
|
|
135
|
+
// { name: string; email: string }
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
For JavaScript (JSDoc):
|
|
139
|
+
```js
|
|
140
|
+
/** @typedef {import('zod').infer<typeof createUserSchema>} CreateUserDto */
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Validation Pattern Reference
|
|
146
|
+
|
|
147
|
+
### Strings
|
|
148
|
+
```js
|
|
149
|
+
z.string().min(1, 'Required').max(255)
|
|
150
|
+
z.string().email()
|
|
151
|
+
z.string().uuid()
|
|
152
|
+
z.string().url()
|
|
153
|
+
z.string().regex(/^\d{11}$/, '11 digits required')
|
|
154
|
+
z.string().trim().toLowerCase() // transform on parse
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Numbers
|
|
158
|
+
```js
|
|
159
|
+
z.number().int().positive()
|
|
160
|
+
z.number().min(0).max(100)
|
|
161
|
+
z.coerce.number() // coerce string → number (use for query params)
|
|
162
|
+
z.coerce.number().int().positive()
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Optional / Nullable
|
|
166
|
+
```js
|
|
167
|
+
z.string().optional() // value | undefined
|
|
168
|
+
z.string().nullable() // value | null
|
|
169
|
+
z.string().nullish() // value | null | undefined
|
|
170
|
+
z.string().default('fallback') // use fallback if undefined
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Enums
|
|
174
|
+
```js
|
|
175
|
+
z.enum(['active', 'inactive', 'pending'])
|
|
176
|
+
z.nativeEnum(MyTypeScriptEnum) // for TS enums
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Objects
|
|
180
|
+
```js
|
|
181
|
+
z.object({ name: z.string() })
|
|
182
|
+
z.object({ name: z.string() }).strict() // reject extra keys
|
|
183
|
+
z.object({ name: z.string() }).passthrough() // keep extra keys
|
|
184
|
+
z.object({ name: z.string() }).pick({ name: true })
|
|
185
|
+
z.object({ name: z.string() }).omit({ name: true })
|
|
186
|
+
z.object({ name: z.string() }).partial() // all fields optional
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Arrays
|
|
190
|
+
```js
|
|
191
|
+
z.array(z.string())
|
|
192
|
+
z.array(z.string()).min(1).max(10)
|
|
193
|
+
z.array(z.string()).nonempty()
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Dates
|
|
197
|
+
```js
|
|
198
|
+
z.coerce.date() // string/number → Date
|
|
199
|
+
z.date().min(new Date('2020-01-01'))
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Conditional / Refine
|
|
203
|
+
```js
|
|
204
|
+
z.object({
|
|
205
|
+
type: z.enum(['individual', 'company']),
|
|
206
|
+
companyName: z.string().optional(),
|
|
207
|
+
}).refine(
|
|
208
|
+
(d) => d.type !== 'company' || !!d.companyName,
|
|
209
|
+
{ message: 'companyName required for company type', path: ['companyName'] }
|
|
210
|
+
)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Transform
|
|
214
|
+
```js
|
|
215
|
+
z.string().transform((val) => val.trim().toLowerCase())
|
|
216
|
+
z.string().transform((val) => parseInt(val, 10))
|
|
217
|
+
z.preprocess((val) => String(val).trim(), z.string())
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Environment Variables
|
|
223
|
+
|
|
224
|
+
```js
|
|
225
|
+
// src/config/env.js
|
|
226
|
+
import { z } from 'zod';
|
|
227
|
+
import 'dotenv/config';
|
|
228
|
+
|
|
229
|
+
const schema = z.object({
|
|
230
|
+
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
|
|
231
|
+
PORT: z.coerce.number().default(3000),
|
|
232
|
+
DATABASE_URL: z.string().url(),
|
|
233
|
+
JWT_SECRET: z.string().min(32, 'JWT_SECRET must be at least 32 chars'),
|
|
234
|
+
JWT_EXPIRES_IN: z.string().default('7d'),
|
|
235
|
+
REDIS_URL: z.string().url().optional(),
|
|
236
|
+
}).strict();
|
|
237
|
+
|
|
238
|
+
const result = schema.safeParse(process.env);
|
|
239
|
+
|
|
240
|
+
if (!result.success) {
|
|
241
|
+
console.error('❌ Invalid environment variables:');
|
|
242
|
+
// v4: use .issues
|
|
243
|
+
console.error(result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`));
|
|
244
|
+
process.exit(1);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export const env = result.data;
|
|
248
|
+
// env.PORT is number, not string — coercion worked
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Schema Composition
|
|
254
|
+
|
|
255
|
+
```js
|
|
256
|
+
// Reuse base schema across create/update
|
|
257
|
+
const baseProductSchema = z.object({
|
|
258
|
+
name: z.string().min(1).max(255),
|
|
259
|
+
price: z.number().positive(),
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const createProductSchema = z.object({ body: baseProductSchema.strict() });
|
|
263
|
+
const updateProductSchema = z.object({
|
|
264
|
+
body: baseProductSchema.partial().strict(), // all fields optional
|
|
265
|
+
params: z.object({ id: z.string().uuid() }),
|
|
266
|
+
});
|
|
267
|
+
```
|