clavix 5.6.2 → 5.6.3

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.
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Zod schemas for configuration file validation
3
+ * Provides runtime validation for integrations.json and user config.json
4
+ */
5
+ import { z } from 'zod';
6
+ /**
7
+ * Integration type discriminator
8
+ * - "standard": Normal adapter with slash command generation
9
+ * - "universal": Documentation-only adapter (Copilot, OCTO, WARP)
10
+ */
11
+ const IntegrationTypeSchema = z.enum(['standard', 'universal']).optional().default('standard');
12
+ /**
13
+ * Schema for a single integration entry in integrations.json
14
+ */
15
+ export const IntegrationEntrySchema = z.object({
16
+ name: z.string().min(1, 'Integration name is required'),
17
+ displayName: z.string().min(1, 'Display name is required'),
18
+ directory: z.string().min(1, 'Directory path is required'),
19
+ filenamePattern: z.string().min(1, 'Filename pattern is required'),
20
+ extension: z.enum(['.md', '.toml']),
21
+ separator: z.enum([':', '-']),
22
+ detection: z.string().min(1, 'Detection path is required'),
23
+ type: IntegrationTypeSchema,
24
+ // Optional fields
25
+ specialAdapter: z.enum(['toml', 'doc-injection']).optional(),
26
+ rootDir: z.string().optional(),
27
+ global: z.boolean().optional(),
28
+ placeholder: z.string().optional(),
29
+ });
30
+ /**
31
+ * Schema for the full integrations.json file
32
+ */
33
+ export const IntegrationsConfigSchema = z.object({
34
+ $schema: z.string().optional(),
35
+ version: z.string().regex(/^\d+\.\d+\.\d+$/, 'Version must be semver format (e.g., "1.0.0")'),
36
+ integrations: z
37
+ .array(IntegrationEntrySchema)
38
+ .min(1, 'At least one integration is required')
39
+ .refine((integrations) => {
40
+ const names = integrations.map((i) => i.name);
41
+ return new Set(names).size === names.length;
42
+ }, { message: 'Integration names must be unique' }),
43
+ });
44
+ /**
45
+ * Schema for user's .clavix/config.json
46
+ */
47
+ export const UserConfigSchema = z.object({
48
+ integrations: z.array(z.string().min(1)).optional().describe('List of enabled integration names'),
49
+ // Legacy field name (backwards compatibility)
50
+ providers: z
51
+ .array(z.string().min(1))
52
+ .optional()
53
+ .describe('Legacy field: use "integrations" instead'),
54
+ });
55
+ /**
56
+ * Validate integrations.json content (build-time, strict)
57
+ * @param content - Parsed JSON content from integrations.json
58
+ * @returns Validation result with parsed data or errors
59
+ */
60
+ export function validateIntegrationsConfig(content) {
61
+ const result = IntegrationsConfigSchema.safeParse(content);
62
+ if (!result.success) {
63
+ return {
64
+ success: false,
65
+ errors: result.error,
66
+ };
67
+ }
68
+ const warnings = [];
69
+ // Check for unknown fields (warn only)
70
+ if (typeof content === 'object' && content !== null) {
71
+ const knownFields = new Set(['$schema', 'version', 'integrations']);
72
+ const contentKeys = Object.keys(content);
73
+ const unknownKeys = contentKeys.filter((key) => !knownFields.has(key));
74
+ if (unknownKeys.length > 0) {
75
+ warnings.push(`Unknown fields in integrations.json: ${unknownKeys.join(', ')}`);
76
+ }
77
+ }
78
+ return {
79
+ success: true,
80
+ data: result.data,
81
+ warnings: warnings.length > 0 ? warnings : undefined,
82
+ };
83
+ }
84
+ /**
85
+ * Validate user config.json content (runtime, lenient)
86
+ * @param content - Parsed JSON content from .clavix/config.json
87
+ * @returns Validation result with parsed data or errors
88
+ */
89
+ export function validateUserConfig(content) {
90
+ const result = UserConfigSchema.safeParse(content);
91
+ if (!result.success) {
92
+ return {
93
+ success: false,
94
+ errors: result.error,
95
+ };
96
+ }
97
+ const warnings = [];
98
+ // Warn about legacy field usage
99
+ if (result.data.providers && !result.data.integrations) {
100
+ warnings.push('Using deprecated "providers" field. Please rename to "integrations" in .clavix/config.json');
101
+ }
102
+ // Check for unknown fields (warn only)
103
+ if (typeof content === 'object' && content !== null) {
104
+ const knownFields = new Set(['integrations', 'providers']);
105
+ const contentKeys = Object.keys(content);
106
+ const unknownKeys = contentKeys.filter((key) => !knownFields.has(key));
107
+ if (unknownKeys.length > 0) {
108
+ warnings.push(`Unknown fields in config.json: ${unknownKeys.join(', ')}`);
109
+ }
110
+ }
111
+ return {
112
+ success: true,
113
+ data: result.data,
114
+ warnings: warnings.length > 0 ? warnings : undefined,
115
+ };
116
+ }
117
+ /**
118
+ * Format Zod errors into human-readable messages
119
+ * @param errors - Zod validation errors
120
+ * @returns Array of formatted error messages
121
+ */
122
+ export function formatZodErrors(errors) {
123
+ return errors.errors.map((err) => {
124
+ const path = err.path.join('.');
125
+ return path ? `${path}: ${err.message}` : err.message;
126
+ });
127
+ }
128
+ //# sourceMappingURL=schemas.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clavix",
3
- "version": "5.6.2",
3
+ "version": "5.6.3",
4
4
  "description": "Agentic-first prompt workflows. Markdown templates that teach AI agents how to optimize prompts, create PRDs, and manage implementation.\n\nSLASH COMMANDS (in your AI assistant):\n /clavix:improve Optimize prompts with auto-depth\n /clavix:prd Generate PRD through questions\n /clavix:plan Create task breakdown from PRD\n /clavix:implement Execute tasks with progress tracking\n /clavix:start Begin conversational session\n /clavix:summarize Extract requirements from conversation\n\nWorks with Claude Code, Cursor, Windsurf, and 19+ other AI coding tools.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -70,7 +70,8 @@
70
70
  "@oclif/plugin-help": "^6.2.35",
71
71
  "chalk": "^5.6.2",
72
72
  "fs-extra": "^11.3.2",
73
- "inquirer": "^12.11.1"
73
+ "inquirer": "^12.11.1",
74
+ "zod": "^3.24.4"
74
75
  },
75
76
  "devDependencies": {
76
77
  "@eslint/js": "^9.17.0",