clavix 5.6.2 → 5.6.4
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/README.md +50 -6
- package/dist/cli/commands/init.js +97 -74
- package/dist/cli/commands/update.js +34 -1
- package/dist/cli/commands/version.js +9 -3
- package/dist/config/integrations.json +73 -17
- package/dist/core/adapter-registry.js +13 -1
- package/dist/templates/slash-commands/_canonical/implement.md +25 -1
- package/dist/templates/slash-commands/_canonical/improve.md +1 -1
- package/dist/templates/slash-commands/_canonical/plan.md +6 -3
- package/dist/templates/slash-commands/_canonical/prd.md +1 -1
- package/dist/templates/slash-commands/_canonical/refine.md +1 -1
- package/dist/templates/slash-commands/_canonical/start.md +1 -1
- package/dist/templates/slash-commands/_canonical/summarize.md +34 -7
- package/dist/utils/schemas.d.ts +268 -0
- package/dist/utils/schemas.js +164 -0
- package/package.json +3 -2
|
@@ -0,0 +1,164 @@
|
|
|
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 template configuration
|
|
46
|
+
*/
|
|
47
|
+
const TemplateConfigSchema = z.object({
|
|
48
|
+
prdQuestions: z.string(),
|
|
49
|
+
fullPrd: z.string(),
|
|
50
|
+
quickPrd: z.string(),
|
|
51
|
+
});
|
|
52
|
+
/**
|
|
53
|
+
* Schema for output configuration
|
|
54
|
+
*/
|
|
55
|
+
const OutputConfigSchema = z.object({
|
|
56
|
+
path: z.string(),
|
|
57
|
+
format: z.enum(['markdown', 'pdf']),
|
|
58
|
+
});
|
|
59
|
+
/**
|
|
60
|
+
* Schema for user preferences
|
|
61
|
+
*/
|
|
62
|
+
const PreferencesConfigSchema = z.object({
|
|
63
|
+
autoOpenOutputs: z.boolean(),
|
|
64
|
+
verboseLogging: z.boolean(),
|
|
65
|
+
});
|
|
66
|
+
/**
|
|
67
|
+
* Schema for user's .clavix/config.json
|
|
68
|
+
* Matches ClavixConfig interface in src/types/config.ts
|
|
69
|
+
*/
|
|
70
|
+
export const UserConfigSchema = z.object({
|
|
71
|
+
version: z.string().optional(),
|
|
72
|
+
integrations: z.array(z.string().min(1)).optional().describe('List of enabled integration names'),
|
|
73
|
+
// Legacy field name (backwards compatibility)
|
|
74
|
+
providers: z
|
|
75
|
+
.array(z.string().min(1))
|
|
76
|
+
.optional()
|
|
77
|
+
.describe('Legacy field: use "integrations" instead'),
|
|
78
|
+
templates: TemplateConfigSchema.optional(),
|
|
79
|
+
outputs: OutputConfigSchema.optional(),
|
|
80
|
+
preferences: PreferencesConfigSchema.optional(),
|
|
81
|
+
experimental: z.record(z.unknown()).optional(),
|
|
82
|
+
});
|
|
83
|
+
/**
|
|
84
|
+
* Validate integrations.json content (build-time, strict)
|
|
85
|
+
* @param content - Parsed JSON content from integrations.json
|
|
86
|
+
* @returns Validation result with parsed data or errors
|
|
87
|
+
*/
|
|
88
|
+
export function validateIntegrationsConfig(content) {
|
|
89
|
+
const result = IntegrationsConfigSchema.safeParse(content);
|
|
90
|
+
if (!result.success) {
|
|
91
|
+
return {
|
|
92
|
+
success: false,
|
|
93
|
+
errors: result.error,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const warnings = [];
|
|
97
|
+
// Check for unknown fields (warn only)
|
|
98
|
+
if (typeof content === 'object' && content !== null) {
|
|
99
|
+
const knownFields = new Set(['$schema', 'version', 'integrations']);
|
|
100
|
+
const contentKeys = Object.keys(content);
|
|
101
|
+
const unknownKeys = contentKeys.filter((key) => !knownFields.has(key));
|
|
102
|
+
if (unknownKeys.length > 0) {
|
|
103
|
+
warnings.push(`Unknown fields in integrations.json: ${unknownKeys.join(', ')}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
success: true,
|
|
108
|
+
data: result.data,
|
|
109
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Validate user config.json content (runtime, lenient)
|
|
114
|
+
* @param content - Parsed JSON content from .clavix/config.json
|
|
115
|
+
* @returns Validation result with parsed data or errors
|
|
116
|
+
*/
|
|
117
|
+
export function validateUserConfig(content) {
|
|
118
|
+
const result = UserConfigSchema.safeParse(content);
|
|
119
|
+
if (!result.success) {
|
|
120
|
+
return {
|
|
121
|
+
success: false,
|
|
122
|
+
errors: result.error,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const warnings = [];
|
|
126
|
+
// Warn about legacy field usage
|
|
127
|
+
if (result.data.providers && !result.data.integrations) {
|
|
128
|
+
warnings.push('Using deprecated "providers" field. Please rename to "integrations" in .clavix/config.json');
|
|
129
|
+
}
|
|
130
|
+
// Check for unknown fields (warn only)
|
|
131
|
+
if (typeof content === 'object' && content !== null) {
|
|
132
|
+
const knownFields = new Set([
|
|
133
|
+
'version',
|
|
134
|
+
'integrations',
|
|
135
|
+
'providers',
|
|
136
|
+
'templates',
|
|
137
|
+
'outputs',
|
|
138
|
+
'preferences',
|
|
139
|
+
'experimental',
|
|
140
|
+
]);
|
|
141
|
+
const contentKeys = Object.keys(content);
|
|
142
|
+
const unknownKeys = contentKeys.filter((key) => !knownFields.has(key));
|
|
143
|
+
if (unknownKeys.length > 0) {
|
|
144
|
+
warnings.push(`Unknown fields in config.json: ${unknownKeys.join(', ')}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
success: true,
|
|
149
|
+
data: result.data,
|
|
150
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Format Zod errors into human-readable messages
|
|
155
|
+
* @param errors - Zod validation errors
|
|
156
|
+
* @returns Array of formatted error messages
|
|
157
|
+
*/
|
|
158
|
+
export function formatZodErrors(errors) {
|
|
159
|
+
return errors.errors.map((err) => {
|
|
160
|
+
const path = err.path.join('.');
|
|
161
|
+
return path ? `${path}: ${err.message}` : err.message;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=schemas.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clavix",
|
|
3
|
-
"version": "5.6.
|
|
3
|
+
"version": "5.6.4",
|
|
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",
|