@defai.digital/automatosx 12.8.7 → 13.1.2

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 (130) hide show
  1. package/LICENSE +1 -1
  2. package/dist/bin.d.ts +8 -0
  3. package/dist/bin.d.ts.map +1 -0
  4. package/dist/bin.js +16 -0
  5. package/dist/bin.js.map +1 -0
  6. package/dist/index.d.ts +8 -2
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +7 -74239
  9. package/dist/index.js.map +1 -0
  10. package/package.json +35 -160
  11. package/.github/assets/ax-cli.png +0 -0
  12. package/.github/assets/axlogo.png +0 -0
  13. package/CHANGELOG.md +0 -81
  14. package/README.md +0 -790
  15. package/SECURITY.md +0 -173
  16. package/dist/mcp/index.d.ts +0 -2
  17. package/dist/mcp/index.js +0 -43627
  18. package/examples/AGENTS_INFO.md +0 -187
  19. package/examples/README.md +0 -434
  20. package/examples/abilities/accessibility.md +0 -115
  21. package/examples/abilities/api-design.md +0 -168
  22. package/examples/abilities/best-practices.md +0 -102
  23. package/examples/abilities/caching-strategy.md +0 -165
  24. package/examples/abilities/ci-cd.md +0 -61
  25. package/examples/abilities/clean-code.md +0 -398
  26. package/examples/abilities/code-generation.md +0 -333
  27. package/examples/abilities/code-review.md +0 -51
  28. package/examples/abilities/component-architecture.md +0 -112
  29. package/examples/abilities/content-creation.md +0 -97
  30. package/examples/abilities/data-modeling.md +0 -171
  31. package/examples/abilities/data-validation.md +0 -50
  32. package/examples/abilities/db-modeling.md +0 -167
  33. package/examples/abilities/debugging.md +0 -52
  34. package/examples/abilities/design-patterns.md +0 -437
  35. package/examples/abilities/design-system-implementation.md +0 -126
  36. package/examples/abilities/documentation.md +0 -54
  37. package/examples/abilities/etl-pipelines.md +0 -44
  38. package/examples/abilities/feasibility-study.md +0 -20
  39. package/examples/abilities/general-assistance.md +0 -26
  40. package/examples/abilities/idea-evaluation.md +0 -21
  41. package/examples/abilities/infra-as-code.md +0 -57
  42. package/examples/abilities/job-orchestration.md +0 -44
  43. package/examples/abilities/literature-review.md +0 -19
  44. package/examples/abilities/longform-report.md +0 -25
  45. package/examples/abilities/mathematical-reasoning.md +0 -170
  46. package/examples/abilities/observability.md +0 -61
  47. package/examples/abilities/orbital-mechanics.md +0 -50
  48. package/examples/abilities/our-architecture-decisions.md +0 -180
  49. package/examples/abilities/our-code-review-checklist.md +0 -149
  50. package/examples/abilities/our-coding-standards.md +0 -369
  51. package/examples/abilities/our-project-structure.md +0 -183
  52. package/examples/abilities/performance.md +0 -89
  53. package/examples/abilities/problem-solving.md +0 -50
  54. package/examples/abilities/propulsion-systems.md +0 -50
  55. package/examples/abilities/quantum-algorithm-design.md +0 -54
  56. package/examples/abilities/quantum-error-correction.md +0 -56
  57. package/examples/abilities/quantum-frameworks-transpilation.md +0 -53
  58. package/examples/abilities/quantum-noise-modeling.md +0 -58
  59. package/examples/abilities/refactoring.md +0 -223
  60. package/examples/abilities/release-strategy.md +0 -58
  61. package/examples/abilities/secrets-policy.md +0 -61
  62. package/examples/abilities/secure-coding-review.md +0 -60
  63. package/examples/abilities/software-architecture.md +0 -394
  64. package/examples/abilities/solid-principles.md +0 -341
  65. package/examples/abilities/sql-optimization.md +0 -84
  66. package/examples/abilities/state-management.md +0 -96
  67. package/examples/abilities/task-planning.md +0 -65
  68. package/examples/abilities/technical-writing.md +0 -77
  69. package/examples/abilities/telemetry-diagnostics.md +0 -51
  70. package/examples/abilities/testing.md +0 -56
  71. package/examples/abilities/threat-modeling.md +0 -58
  72. package/examples/abilities/troubleshooting.md +0 -80
  73. package/examples/abilities/typescript-zod-validation.md +0 -830
  74. package/examples/agents/AGENTS_INTEGRATION.md +0 -99
  75. package/examples/agents/aerospace-scientist.yaml +0 -159
  76. package/examples/agents/architecture.yaml +0 -244
  77. package/examples/agents/automatosx.config.json +0 -286
  78. package/examples/agents/backend.yaml +0 -141
  79. package/examples/agents/ceo.yaml +0 -105
  80. package/examples/agents/creative-marketer.yaml +0 -173
  81. package/examples/agents/cto.yaml +0 -118
  82. package/examples/agents/data-scientist.yaml +0 -200
  83. package/examples/agents/data.yaml +0 -106
  84. package/examples/agents/design.yaml +0 -115
  85. package/examples/agents/devops.yaml +0 -124
  86. package/examples/agents/frontend.yaml +0 -171
  87. package/examples/agents/fullstack.yaml +0 -172
  88. package/examples/agents/mobile.yaml +0 -185
  89. package/examples/agents/product.yaml +0 -103
  90. package/examples/agents/quality.yaml +0 -117
  91. package/examples/agents/quantum-engineer.yaml +0 -166
  92. package/examples/agents/researcher.yaml +0 -122
  93. package/examples/agents/security.yaml +0 -115
  94. package/examples/agents/standard.yaml +0 -214
  95. package/examples/agents/writer.yaml +0 -122
  96. package/examples/providers/README.md +0 -117
  97. package/examples/providers/claude/CLAUDE_INTEGRATION.md +0 -302
  98. package/examples/providers/claude/mcp/automatosx.json +0 -244
  99. package/examples/providers/codex/CODEX_INTEGRATION.md +0 -593
  100. package/examples/providers/codex/README.md +0 -349
  101. package/examples/providers/codex/usage-examples.ts +0 -421
  102. package/examples/providers/gemini/GEMINI_INTEGRATION.md +0 -236
  103. package/examples/providers/gemini/README.md +0 -76
  104. package/examples/providers/openai-codex-example.ts +0 -421
  105. package/examples/pytorch_resnet50_training.py +0 -289
  106. package/examples/specs/automatosx-release.ax.yaml +0 -380
  107. package/examples/specs/enterprise.ax.yaml +0 -121
  108. package/examples/specs/enterprise.yaml.mustache +0 -121
  109. package/examples/specs/government.ax.yaml +0 -148
  110. package/examples/specs/government.yaml.mustache +0 -148
  111. package/examples/specs/minimal.ax.yaml +0 -21
  112. package/examples/specs/minimal.yaml.mustache +0 -21
  113. package/examples/teams/business.yaml +0 -56
  114. package/examples/teams/core.yaml +0 -60
  115. package/examples/teams/design.yaml +0 -58
  116. package/examples/teams/engineering.yaml +0 -69
  117. package/examples/teams/research.yaml +0 -56
  118. package/examples/use-cases/01-web-app-development.md +0 -374
  119. package/examples/workflows/analyst.yaml +0 -60
  120. package/examples/workflows/assistant.yaml +0 -48
  121. package/examples/workflows/basic-agent.yaml +0 -28
  122. package/examples/workflows/code-reviewer.yaml +0 -52
  123. package/examples/workflows/debugger.yaml +0 -63
  124. package/examples/workflows/designer.yaml +0 -69
  125. package/examples/workflows/developer.yaml +0 -60
  126. package/examples/workflows/fullstack-developer.yaml +0 -395
  127. package/examples/workflows/qa-specialist.yaml +0 -71
  128. package/schema/ability-metadata.json +0 -21
  129. package/schema/config.json +0 -703
  130. package/schema/spec-schema.json +0 -608
@@ -1,830 +0,0 @@
1
- # TypeScript + Zod Validation
2
-
3
- **CRITICAL**: When writing JavaScript or TypeScript scripts, ALWAYS use TypeScript with Zod for runtime type safety and validation. This is a REQUIRED standard for AutomatosX agents.
4
-
5
- ## Why TypeScript + Zod?
6
-
7
- ### The Problem with TypeScript Alone
8
-
9
- TypeScript provides **compile-time** type safety, but types disappear at runtime:
10
-
11
- ```typescript
12
- // ❌ TypeScript types don't catch runtime errors
13
- interface User {
14
- email: string;
15
- age: number;
16
- }
17
-
18
- function createUser(data: unknown): User {
19
- return data as User; // UNSAFE! No validation!
20
- }
21
-
22
- // This will compile fine but crash at runtime
23
- const user = createUser({ email: 123, age: "invalid" });
24
- console.log(user.email.toLowerCase()); // Runtime error!
25
- ```
26
-
27
- ### The Solution: Zod
28
-
29
- Zod provides **runtime** validation + automatic TypeScript type inference:
30
-
31
- ```typescript
32
- // ✅ Zod catches errors at runtime
33
- import { z } from 'zod';
34
-
35
- const UserSchema = z.object({
36
- email: z.string().email(),
37
- age: z.number().int().positive(),
38
- });
39
-
40
- type User = z.infer<typeof UserSchema>;
41
-
42
- function createUser(data: unknown): User {
43
- return UserSchema.parse(data); // Throws if invalid!
44
- }
45
-
46
- // This will throw a clear error before anything bad happens
47
- try {
48
- const user = createUser({ email: 123, age: "invalid" });
49
- } catch (error) {
50
- console.error('Validation failed:', error.message);
51
- // Output: "email: Expected string, received number"
52
- }
53
- ```
54
-
55
- ## Installation
56
-
57
- ```bash
58
- npm install zod
59
- # or
60
- pnpm add zod
61
- # or
62
- yarn add zod
63
- ```
64
-
65
- ## Core Concepts
66
-
67
- ### 1. Schema Definition
68
-
69
- ```typescript
70
- import { z } from 'zod';
71
-
72
- // Primitive types
73
- const StringSchema = z.string();
74
- const NumberSchema = z.number();
75
- const BooleanSchema = z.boolean();
76
- const DateSchema = z.date();
77
-
78
- // Objects
79
- const UserSchema = z.object({
80
- id: z.string().uuid(),
81
- name: z.string().min(1).max(100),
82
- email: z.string().email(),
83
- age: z.number().int().min(0).max(150).optional(),
84
- });
85
-
86
- // Arrays
87
- const StringArraySchema = z.array(z.string());
88
- const UserArraySchema = z.array(UserSchema);
89
-
90
- // Enums
91
- const RoleSchema = z.enum(['admin', 'user', 'guest']);
92
-
93
- // Unions (OR)
94
- const StringOrNumberSchema = z.union([z.string(), z.number()]);
95
- const StringOrNumberSchema2 = z.string().or(z.number()); // Alternative syntax
96
-
97
- // Intersections (AND)
98
- const BaseUserSchema = z.object({ id: z.string() });
99
- const ExtendedUserSchema = BaseUserSchema.and(
100
- z.object({ email: z.string() })
101
- );
102
- ```
103
-
104
- ### 2. Type Inference
105
-
106
- ```typescript
107
- import { z } from 'zod';
108
-
109
- // ✅ Define schema once, get TypeScript types for free
110
- const UserSchema = z.object({
111
- id: z.string().uuid(),
112
- email: z.string().email(),
113
- role: z.enum(['admin', 'user']),
114
- });
115
-
116
- // Type is automatically inferred
117
- type User = z.infer<typeof UserSchema>;
118
- // Equivalent to:
119
- // type User = {
120
- // id: string;
121
- // email: string;
122
- // role: 'admin' | 'user';
123
- // }
124
- ```
125
-
126
- ### 3. Parsing and Validation
127
-
128
- ```typescript
129
- import { z } from 'zod';
130
-
131
- const UserSchema = z.object({
132
- email: z.string().email(),
133
- age: z.number().int().positive(),
134
- });
135
-
136
- // parse() - Throws on validation failure
137
- try {
138
- const user = UserSchema.parse({ email: 'test@example.com', age: 25 });
139
- console.log(user); // { email: 'test@example.com', age: 25 }
140
- } catch (error) {
141
- if (error instanceof z.ZodError) {
142
- console.error('Validation failed:', error.issues);
143
- }
144
- }
145
-
146
- // safeParse() - Returns success/error object (recommended)
147
- const result = UserSchema.safeParse({ email: 'invalid', age: -5 });
148
-
149
- if (result.success) {
150
- console.log('Valid user:', result.data);
151
- } else {
152
- console.error('Validation errors:', result.error.issues);
153
- // [
154
- // { path: ['email'], message: 'Invalid email' },
155
- // { path: ['age'], message: 'Number must be greater than 0' }
156
- // ]
157
- }
158
- ```
159
-
160
- ## Common Use Cases
161
-
162
- ### Use Case 1: CLI Argument Validation
163
-
164
- ```typescript
165
- import { z } from 'zod';
166
-
167
- const CliArgsSchema = z.object({
168
- input: z.string().min(1, 'Input file required'),
169
- output: z.string().min(1, 'Output file required'),
170
- verbose: z.boolean().default(false),
171
- format: z.enum(['json', 'yaml', 'csv']).default('json'),
172
- limit: z.number().int().positive().optional(),
173
- filters: z.array(z.string()).default([]),
174
- });
175
-
176
- type CliArgs = z.infer<typeof CliArgsSchema>;
177
-
178
- function parseCliArgs(argv: string[]): CliArgs {
179
- // Build args object from process.argv
180
- const rawArgs = {
181
- input: argv[2],
182
- output: argv[3],
183
- verbose: argv.includes('--verbose'),
184
- format: argv.includes('--format')
185
- ? argv[argv.indexOf('--format') + 1]
186
- : undefined,
187
- limit: argv.includes('--limit')
188
- ? parseInt(argv[argv.indexOf('--limit') + 1], 10)
189
- : undefined,
190
- filters: argv.filter(arg => arg.startsWith('--filter=')).map(f => f.slice(9)),
191
- };
192
-
193
- // Validate and apply defaults
194
- const result = CliArgsSchema.safeParse(rawArgs);
195
-
196
- if (!result.success) {
197
- const errors = result.error.issues.map(
198
- (issue) => ` ${issue.path.join('.')}: ${issue.message}`
199
- );
200
- throw new Error(`Invalid CLI arguments:\n${errors.join('\n')}`);
201
- }
202
-
203
- return result.data;
204
- }
205
-
206
- // Usage
207
- try {
208
- const args = parseCliArgs(process.argv);
209
- console.log('Parsed args:', args);
210
- } catch (error) {
211
- console.error(error.message);
212
- process.exit(1);
213
- }
214
- ```
215
-
216
- ### Use Case 2: Configuration File Validation
217
-
218
- ```typescript
219
- import { z } from 'zod';
220
- import { readFile } from 'fs/promises';
221
-
222
- const ServerConfigSchema = z.object({
223
- port: z.number().int().min(1024).max(65535).default(3000),
224
- host: z.string().default('localhost'),
225
- cors: z.object({
226
- enabled: z.boolean().default(true),
227
- origins: z.array(z.string().url()).default(['http://localhost:3000']),
228
- }).optional(),
229
- });
230
-
231
- const DatabaseConfigSchema = z.object({
232
- url: z.string().url(),
233
- poolSize: z.number().int().positive().default(10),
234
- ssl: z.boolean().default(false),
235
- migrations: z.object({
236
- auto: z.boolean().default(false),
237
- directory: z.string().default('./migrations'),
238
- }).optional(),
239
- });
240
-
241
- const LoggingConfigSchema = z.object({
242
- level: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
243
- format: z.enum(['json', 'text']).default('text'),
244
- destination: z.string().default('stdout'),
245
- });
246
-
247
- const AppConfigSchema = z.object({
248
- server: ServerConfigSchema,
249
- database: DatabaseConfigSchema,
250
- logging: LoggingConfigSchema.optional(),
251
- });
252
-
253
- type AppConfig = z.infer<typeof AppConfigSchema>;
254
-
255
- async function loadConfig(path: string): Promise<AppConfig> {
256
- try {
257
- const raw = await readFile(path, 'utf-8');
258
- const json = JSON.parse(raw);
259
-
260
- // Validate and apply defaults
261
- const result = AppConfigSchema.safeParse(json);
262
-
263
- if (!result.success) {
264
- const errors = result.error.issues.map((issue) => {
265
- const path = issue.path.join('.');
266
- return ` config.${path}: ${issue.message}`;
267
- });
268
- throw new Error(
269
- `Invalid configuration file:\n${errors.join('\n')}\n\nPlease check ${path}`
270
- );
271
- }
272
-
273
- return result.data;
274
- } catch (error) {
275
- if (error instanceof SyntaxError) {
276
- throw new Error(`Invalid JSON in config file: ${error.message}`);
277
- }
278
- throw error;
279
- }
280
- }
281
-
282
- // Usage
283
- const config = await loadConfig('./config.json');
284
- console.log('Server running on:', `${config.server.host}:${config.server.port}`);
285
- ```
286
-
287
- ### Use Case 3: API Request/Response Validation
288
-
289
- ```typescript
290
- import { z } from 'zod';
291
-
292
- // Input schema for creating a blog post
293
- const CreatePostInputSchema = z.object({
294
- title: z.string().min(1).max(200),
295
- content: z.string().min(1).max(50000),
296
- tags: z.array(z.string().min(1).max(50)).max(10).default([]),
297
- publishAt: z.string().datetime().optional(),
298
- draft: z.boolean().default(true),
299
- });
300
-
301
- // Response schema for a blog post
302
- const PostResponseSchema = z.object({
303
- id: z.string().uuid(),
304
- title: z.string(),
305
- content: z.string(),
306
- tags: z.array(z.string()),
307
- publishAt: z.string().datetime().nullable(),
308
- draft: z.boolean(),
309
- createdAt: z.string().datetime(),
310
- updatedAt: z.string().datetime(),
311
- author: z.object({
312
- id: z.string().uuid(),
313
- name: z.string(),
314
- email: z.string().email(),
315
- }),
316
- });
317
-
318
- type CreatePostInput = z.infer<typeof CreatePostInputSchema>;
319
- type PostResponse = z.infer<typeof PostResponseSchema>;
320
-
321
- // API handler with validation
322
- async function createPostHandler(req: Request): Promise<Response> {
323
- try {
324
- // Validate request body
325
- const body = await req.json();
326
- const input = CreatePostInputSchema.parse(body);
327
-
328
- // Business logic
329
- const post = await database.posts.create({
330
- title: input.title,
331
- content: input.content,
332
- tags: input.tags,
333
- publishAt: input.publishAt ? new Date(input.publishAt) : null,
334
- draft: input.draft,
335
- authorId: req.user.id,
336
- });
337
-
338
- // Build response
339
- const responseData = {
340
- id: post.id,
341
- title: post.title,
342
- content: post.content,
343
- tags: post.tags,
344
- publishAt: post.publishAt?.toISOString() ?? null,
345
- draft: post.draft,
346
- createdAt: post.createdAt.toISOString(),
347
- updatedAt: post.updatedAt.toISOString(),
348
- author: {
349
- id: req.user.id,
350
- name: req.user.name,
351
- email: req.user.email,
352
- },
353
- };
354
-
355
- // Validate response before sending
356
- const validatedResponse = PostResponseSchema.parse(responseData);
357
-
358
- return new Response(JSON.stringify(validatedResponse), {
359
- status: 201,
360
- headers: { 'Content-Type': 'application/json' },
361
- });
362
-
363
- } catch (error) {
364
- if (error instanceof z.ZodError) {
365
- return new Response(
366
- JSON.stringify({
367
- error: 'Validation failed',
368
- issues: error.issues.map((issue) => ({
369
- field: issue.path.join('.'),
370
- message: issue.message,
371
- })),
372
- }),
373
- { status: 400, headers: { 'Content-Type': 'application/json' } }
374
- );
375
- }
376
- throw error;
377
- }
378
- }
379
- ```
380
-
381
- ### Use Case 4: Environment Variable Validation
382
-
383
- ```typescript
384
- import { z } from 'zod';
385
-
386
- const EnvSchema = z.object({
387
- NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
388
- PORT: z.string().transform((val) => parseInt(val, 10)).pipe(
389
- z.number().int().min(1024).max(65535)
390
- ).default('3000'),
391
- DATABASE_URL: z.string().url(),
392
- REDIS_URL: z.string().url().optional(),
393
- LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
394
- API_KEY: z.string().min(32),
395
- ENABLE_FEATURE_X: z.string()
396
- .transform((val) => val === 'true')
397
- .default('false'),
398
- });
399
-
400
- type Env = z.infer<typeof EnvSchema>;
401
-
402
- function loadEnv(): Env {
403
- const result = EnvSchema.safeParse(process.env);
404
-
405
- if (!result.success) {
406
- const errors = result.error.issues.map((issue) => {
407
- const envVar = issue.path.join('.');
408
- return ` ${envVar}: ${issue.message}`;
409
- });
410
-
411
- console.error('❌ Invalid environment variables:');
412
- console.error(errors.join('\n'));
413
- console.error('\nPlease check your .env file or environment configuration.');
414
- process.exit(1);
415
- }
416
-
417
- return result.data;
418
- }
419
-
420
- // Usage at application startup
421
- const env = loadEnv();
422
- console.log(`Starting server on port ${env.PORT} in ${env.NODE_ENV} mode`);
423
- ```
424
-
425
- ### Use Case 5: File Content Validation
426
-
427
- ```typescript
428
- import { z } from 'zod';
429
- import { readFile, writeFile } from 'fs/promises';
430
-
431
- const PackageJsonSchema = z.object({
432
- name: z.string().min(1),
433
- version: z.string().regex(/^\d+\.\d+\.\d+$/),
434
- description: z.string().optional(),
435
- main: z.string().default('index.js'),
436
- scripts: z.record(z.string(), z.string()).optional(),
437
- dependencies: z.record(z.string(), z.string()).optional(),
438
- devDependencies: z.record(z.string(), z.string()).optional(),
439
- engines: z.object({
440
- node: z.string().optional(),
441
- npm: z.string().optional(),
442
- }).optional(),
443
- });
444
-
445
- type PackageJson = z.infer<typeof PackageJsonSchema>;
446
-
447
- async function readPackageJson(path: string): Promise<PackageJson> {
448
- try {
449
- const raw = await readFile(path, 'utf-8');
450
- const json = JSON.parse(raw);
451
-
452
- const result = PackageJsonSchema.safeParse(json);
453
-
454
- if (!result.success) {
455
- const errors = result.error.issues.map((issue) => {
456
- const field = issue.path.join('.');
457
- return ` ${field}: ${issue.message}`;
458
- });
459
- throw new Error(
460
- `Invalid package.json at ${path}:\n${errors.join('\n')}`
461
- );
462
- }
463
-
464
- return result.data;
465
- } catch (error) {
466
- if (error instanceof SyntaxError) {
467
- throw new Error(`Invalid JSON in package.json: ${error.message}`);
468
- }
469
- throw error;
470
- }
471
- }
472
-
473
- async function updatePackageVersion(
474
- path: string,
475
- newVersion: string
476
- ): Promise<void> {
477
- const pkg = await readPackageJson(path);
478
-
479
- // Validate new version format
480
- const versionSchema = z.string().regex(/^\d+\.\d+\.\d+$/);
481
- const validatedVersion = versionSchema.parse(newVersion);
482
-
483
- pkg.version = validatedVersion;
484
-
485
- // Re-validate entire package.json before writing
486
- const validated = PackageJsonSchema.parse(pkg);
487
-
488
- await writeFile(path, JSON.stringify(validated, null, 2), 'utf-8');
489
- console.log(`✅ Updated package.json version to ${validatedVersion}`);
490
- }
491
- ```
492
-
493
- ## Advanced Patterns
494
-
495
- ### Pattern 1: Refinements (Custom Validation)
496
-
497
- ```typescript
498
- import { z } from 'zod';
499
-
500
- const PasswordSchema = z.string()
501
- .min(8, 'Password must be at least 8 characters')
502
- .refine((password) => /[A-Z]/.test(password), {
503
- message: 'Password must contain at least one uppercase letter',
504
- })
505
- .refine((password) => /[a-z]/.test(password), {
506
- message: 'Password must contain at least one lowercase letter',
507
- })
508
- .refine((password) => /[0-9]/.test(password), {
509
- message: 'Password must contain at least one number',
510
- });
511
-
512
- const UserRegistrationSchema = z.object({
513
- email: z.string().email(),
514
- password: PasswordSchema,
515
- confirmPassword: z.string(),
516
- }).refine((data) => data.password === data.confirmPassword, {
517
- message: 'Passwords do not match',
518
- path: ['confirmPassword'], // Error will be attached to confirmPassword field
519
- });
520
- ```
521
-
522
- ### Pattern 2: Transformations
523
-
524
- ```typescript
525
- import { z } from 'zod';
526
-
527
- // Transform string to Date
528
- const DateFromStringSchema = z.string()
529
- .datetime()
530
- .transform((str) => new Date(str));
531
-
532
- // Transform and validate
533
- const UserInputSchema = z.object({
534
- email: z.string().email().transform((e) => e.toLowerCase()),
535
- age: z.string().transform((s) => parseInt(s, 10)).pipe(
536
- z.number().int().min(0).max(150)
537
- ),
538
- createdAt: DateFromStringSchema,
539
- });
540
-
541
- // Input: { email: 'USER@EXAMPLE.COM', age: '25', createdAt: '2024-01-01T00:00:00Z' }
542
- // Output: { email: 'user@example.com', age: 25, createdAt: Date object }
543
- ```
544
-
545
- ### Pattern 3: Discriminated Unions
546
-
547
- ```typescript
548
- import { z } from 'zod';
549
-
550
- const SuccessResponseSchema = z.object({
551
- status: z.literal('success'),
552
- data: z.object({
553
- id: z.string(),
554
- name: z.string(),
555
- }),
556
- });
557
-
558
- const ErrorResponseSchema = z.object({
559
- status: z.literal('error'),
560
- error: z.object({
561
- code: z.string(),
562
- message: z.string(),
563
- }),
564
- });
565
-
566
- const ApiResponseSchema = z.discriminatedUnion('status', [
567
- SuccessResponseSchema,
568
- ErrorResponseSchema,
569
- ]);
570
-
571
- type ApiResponse = z.infer<typeof ApiResponseSchema>;
572
-
573
- function handleResponse(response: ApiResponse) {
574
- if (response.status === 'success') {
575
- // TypeScript knows response.data exists here
576
- console.log('Success:', response.data.name);
577
- } else {
578
- // TypeScript knows response.error exists here
579
- console.error('Error:', response.error.message);
580
- }
581
- }
582
- ```
583
-
584
- ### Pattern 4: Recursive Schemas
585
-
586
- ```typescript
587
- import { z } from 'zod';
588
-
589
- type Category = {
590
- id: string;
591
- name: string;
592
- subcategories: Category[];
593
- };
594
-
595
- const CategorySchema: z.ZodType<Category> = z.lazy(() =>
596
- z.object({
597
- id: z.string().uuid(),
598
- name: z.string().min(1),
599
- subcategories: z.array(CategorySchema),
600
- })
601
- );
602
-
603
- // Can validate deeply nested category trees
604
- const category = CategorySchema.parse({
605
- id: '123',
606
- name: 'Electronics',
607
- subcategories: [
608
- {
609
- id: '456',
610
- name: 'Computers',
611
- subcategories: [
612
- {
613
- id: '789',
614
- name: 'Laptops',
615
- subcategories: [],
616
- },
617
- ],
618
- },
619
- ],
620
- });
621
- ```
622
-
623
- ## Error Handling Best Practices
624
-
625
- ### Detailed Error Messages
626
-
627
- ```typescript
628
- import { z } from 'zod';
629
-
630
- function validateData(data: unknown) {
631
- const result = UserSchema.safeParse(data);
632
-
633
- if (!result.success) {
634
- // ✅ Extract detailed error information
635
- const errors = result.error.issues.map((issue) => ({
636
- field: issue.path.join('.'),
637
- message: issue.message,
638
- code: issue.code,
639
- received: issue.received,
640
- }));
641
-
642
- console.error('Validation failed:');
643
- errors.forEach((err) => {
644
- console.error(` - ${err.field}: ${err.message} (got: ${err.received})`);
645
- });
646
-
647
- throw new ValidationError('Data validation failed', errors);
648
- }
649
-
650
- return result.data;
651
- }
652
- ```
653
-
654
- ### Custom Error Messages
655
-
656
- ```typescript
657
- import { z } from 'zod';
658
-
659
- const UserSchema = z.object({
660
- email: z.string({
661
- required_error: 'Email is required',
662
- invalid_type_error: 'Email must be a string',
663
- }).email('Please provide a valid email address'),
664
-
665
- age: z.number({
666
- required_error: 'Age is required',
667
- invalid_type_error: 'Age must be a number',
668
- }).int('Age must be a whole number')
669
- .min(0, 'Age cannot be negative')
670
- .max(150, 'Age must be less than 150'),
671
-
672
- role: z.enum(['admin', 'user', 'guest'], {
673
- errorMap: () => ({ message: 'Role must be either admin, user, or guest' }),
674
- }),
675
- });
676
- ```
677
-
678
- ## Testing with Zod
679
-
680
- ```typescript
681
- import { describe, it, expect } from 'vitest';
682
- import { z } from 'zod';
683
-
684
- const UserSchema = z.object({
685
- email: z.string().email(),
686
- age: z.number().int().positive(),
687
- });
688
-
689
- describe('UserSchema', () => {
690
- it('should validate valid user data', () => {
691
- const result = UserSchema.safeParse({
692
- email: 'test@example.com',
693
- age: 25,
694
- });
695
-
696
- expect(result.success).toBe(true);
697
- if (result.success) {
698
- expect(result.data.email).toBe('test@example.com');
699
- expect(result.data.age).toBe(25);
700
- }
701
- });
702
-
703
- it('should reject invalid email', () => {
704
- const result = UserSchema.safeParse({
705
- email: 'not-an-email',
706
- age: 25,
707
- });
708
-
709
- expect(result.success).toBe(false);
710
- if (!result.success) {
711
- expect(result.error.issues[0].path).toEqual(['email']);
712
- expect(result.error.issues[0].message).toContain('email');
713
- }
714
- });
715
-
716
- it('should reject negative age', () => {
717
- const result = UserSchema.safeParse({
718
- email: 'test@example.com',
719
- age: -5,
720
- });
721
-
722
- expect(result.success).toBe(false);
723
- if (!result.success) {
724
- expect(result.error.issues[0].path).toEqual(['age']);
725
- }
726
- });
727
- });
728
- ```
729
-
730
- ## Quick Reference Checklist
731
-
732
- ### Before Writing Any Script
733
-
734
- - [ ] Installed Zod (`npm install zod`)
735
- - [ ] Imported Zod (`import { z } from 'zod'`)
736
- - [ ] Defined schemas for all external data sources
737
- - [ ] Used `z.infer<typeof Schema>` for type inference
738
- - [ ] Validated at system boundaries (CLI, files, APIs, env vars)
739
- - [ ] Used `safeParse()` for better error handling
740
- - [ ] Provided meaningful custom error messages
741
- - [ ] No `any` types (use `z.unknown()` if type is truly unknown)
742
- - [ ] Tested validation logic with unit tests
743
-
744
- ### When to Use Zod (Required)
745
-
746
- ✅ **ALWAYS use Zod for:**
747
- - CLI argument parsing
748
- - Configuration file validation (JSON, YAML, etc.)
749
- - API request/response validation
750
- - File content validation
751
- - Environment variable validation
752
- - Database query results
753
- - External API responses
754
- - User input from any source
755
-
756
- ❌ **TypeScript types alone are sufficient for:**
757
- - Internal function parameters (same file)
758
- - Return types of pure functions
759
- - Class properties with known types
760
- - Type aliases and interfaces for documentation
761
- - Generic type parameters
762
-
763
- ## Common Zod Methods Reference
764
-
765
- ```typescript
766
- // String validations
767
- z.string()
768
- z.string().min(5)
769
- z.string().max(100)
770
- z.string().email()
771
- z.string().url()
772
- z.string().uuid()
773
- z.string().regex(/pattern/)
774
- z.string().datetime()
775
-
776
- // Number validations
777
- z.number()
778
- z.number().int()
779
- z.number().positive()
780
- z.number().negative()
781
- z.number().min(0)
782
- z.number().max(100)
783
-
784
- // Array validations
785
- z.array(z.string())
786
- z.array(z.number()).min(1)
787
- z.array(z.string()).max(10)
788
-
789
- // Object validations
790
- z.object({ key: z.string() })
791
- z.object({ key: z.string() }).strict() // No extra keys
792
- z.object({ key: z.string() }).partial() // All keys optional
793
- z.object({ key: z.string() }).required() // All keys required
794
-
795
- // Optional and nullable
796
- z.string().optional()
797
- z.string().nullable()
798
- z.string().nullish() // null | undefined
799
-
800
- // Default values
801
- z.string().default('default value')
802
- z.number().default(0)
803
-
804
- // Enums
805
- z.enum(['option1', 'option2'])
806
- z.nativeEnum(MyEnum)
807
-
808
- // Unions and intersections
809
- z.union([z.string(), z.number()])
810
- z.string().or(z.number())
811
- z.intersection(Schema1, Schema2)
812
- Schema1.and(Schema2)
813
-
814
- // Transformations
815
- z.string().transform((val) => val.toLowerCase())
816
- z.string().transform((val) => parseInt(val, 10))
817
-
818
- // Refinements
819
- z.string().refine((val) => val.length > 5, 'Must be longer than 5')
820
- ```
821
-
822
- ## Resources
823
-
824
- - Official Docs: https://zod.dev
825
- - GitHub: https://github.com/colinhacks/zod
826
- - NPM: https://www.npmjs.com/package/zod
827
-
828
- ---
829
-
830
- **Remember**: When an AutomatosX agent writes a TypeScript script, Zod validation is **MANDATORY** for all external data. No exceptions!