@vibe-validate/cli 0.9.11 → 0.10.1
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/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +151 -38
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +254 -332
- package/dist/commands/init.js.map +1 -1
- package/dist/utils/config-loader.d.ts +3 -7
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js +7 -19
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/git-detection.d.ts +41 -0
- package/dist/utils/git-detection.d.ts.map +1 -0
- package/dist/utils/git-detection.js +109 -0
- package/dist/utils/git-detection.js.map +1 -0
- package/dist/utils/runner-adapter.js +3 -3
- package/dist/utils/runner-adapter.js.map +1 -1
- package/dist/utils/setup-checks/gitignore-check.d.ts +23 -0
- package/dist/utils/setup-checks/gitignore-check.d.ts.map +1 -0
- package/dist/utils/setup-checks/gitignore-check.js +156 -0
- package/dist/utils/setup-checks/gitignore-check.js.map +1 -0
- package/dist/utils/setup-checks/hooks-check.d.ts +27 -0
- package/dist/utils/setup-checks/hooks-check.d.ts.map +1 -0
- package/dist/utils/setup-checks/hooks-check.js +175 -0
- package/dist/utils/setup-checks/hooks-check.js.map +1 -0
- package/dist/utils/setup-checks/workflow-check.d.ts +22 -0
- package/dist/utils/setup-checks/workflow-check.d.ts.map +1 -0
- package/dist/utils/setup-checks/workflow-check.js +147 -0
- package/dist/utils/setup-checks/workflow-check.js.map +1 -0
- package/dist/utils/setup-engine.d.ts +155 -0
- package/dist/utils/setup-engine.d.ts.map +1 -0
- package/dist/utils/setup-engine.js +31 -0
- package/dist/utils/setup-engine.js.map +1 -0
- package/package.json +4 -4
package/dist/commands/init.js
CHANGED
|
@@ -3,61 +3,45 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Interactive setup wizard for vibe-validate configuration.
|
|
5
5
|
*/
|
|
6
|
-
import { writeFileSync } from 'fs';
|
|
6
|
+
import { writeFileSync, existsSync } from 'fs';
|
|
7
7
|
import { join } from 'path';
|
|
8
|
-
import {
|
|
8
|
+
import { pathToFileURL } from 'url';
|
|
9
|
+
import { dump as stringifyYaml } from 'js-yaml';
|
|
9
10
|
import chalk from 'chalk';
|
|
10
11
|
import { configExists } from '../utils/config-loader.js';
|
|
11
|
-
import {
|
|
12
|
+
import { detectGitConfig } from '../utils/git-detection.js';
|
|
13
|
+
import { GitignoreSetupCheck } from '../utils/setup-checks/gitignore-check.js';
|
|
14
|
+
import { HooksSetupCheck } from '../utils/setup-checks/hooks-check.js';
|
|
15
|
+
import { WorkflowSetupCheck } from '../utils/setup-checks/workflow-check.js';
|
|
12
16
|
export function initCommand(program) {
|
|
13
17
|
program
|
|
14
18
|
.command('init')
|
|
15
19
|
.description('Initialize vibe-validate configuration')
|
|
16
20
|
.option('-p, --preset <preset>', 'Use preset (typescript-library|typescript-nodejs|typescript-react)')
|
|
17
21
|
.option('-f, --force', 'Overwrite existing configuration')
|
|
22
|
+
.option('--dry-run', 'Preview changes without writing files')
|
|
23
|
+
.option('--setup-hooks', 'Install pre-commit hook')
|
|
24
|
+
.option('--setup-workflow', 'Create GitHub Actions workflow')
|
|
25
|
+
.option('--fix-gitignore', 'Add state file to .gitignore')
|
|
26
|
+
.option('--migrate', 'Migrate .mjs config to .yaml format')
|
|
18
27
|
.action(async (options) => {
|
|
19
28
|
try {
|
|
20
29
|
const cwd = process.cwd();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
const isDryRun = options.dryRun || false;
|
|
31
|
+
// Handle migration
|
|
32
|
+
if (options.migrate) {
|
|
33
|
+
await handleMigration(cwd, options, isDryRun);
|
|
34
|
+
return;
|
|
26
35
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
process.exit(1);
|
|
36
|
+
// Check if this is a focused operation
|
|
37
|
+
const isFocusedOperation = options.setupHooks || options.setupWorkflow || options.fixGitignore;
|
|
38
|
+
// Handle focused operations
|
|
39
|
+
if (isFocusedOperation) {
|
|
40
|
+
await handleFocusedOperations(cwd, options, isDryRun);
|
|
41
|
+
return;
|
|
34
42
|
}
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
if (gitConfig.detected) {
|
|
38
|
-
console.log(chalk.blue('🔍 Auto-detected git configuration:'));
|
|
39
|
-
console.log(chalk.gray(` Main branch: ${gitConfig.mainBranch}`));
|
|
40
|
-
console.log(chalk.gray(` Remote: ${gitConfig.remoteOrigin}`));
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
console.log(chalk.gray('ℹ️ Using default git configuration (main, origin)'));
|
|
44
|
-
}
|
|
45
|
-
// Generate config file content
|
|
46
|
-
const configContent = generateConfig(preset, gitConfig);
|
|
47
|
-
const configPath = join(cwd, 'vibe-validate.config.ts');
|
|
48
|
-
// Write config file
|
|
49
|
-
writeFileSync(configPath, configContent, 'utf-8');
|
|
50
|
-
console.log(chalk.green('✅ Configuration file created successfully'));
|
|
51
|
-
console.log(chalk.blue(`📋 Created: ${configPath}`));
|
|
52
|
-
console.log(chalk.gray(` Preset: ${preset}`));
|
|
53
|
-
console.log();
|
|
54
|
-
console.log(chalk.yellow('Next steps:'));
|
|
55
|
-
console.log(chalk.gray(' 1. Review and customize vibe-validate.config.ts'));
|
|
56
|
-
console.log(chalk.gray(' 2. Run: vibe-validate validate'));
|
|
57
|
-
console.log(chalk.gray(' 3. Add to package.json scripts:'));
|
|
58
|
-
console.log(chalk.gray(' "validate": "vibe-validate validate"'));
|
|
59
|
-
console.log(chalk.gray(' "pre-commit": "vibe-validate pre-commit"'));
|
|
60
|
-
process.exit(0);
|
|
43
|
+
// Handle config initialization
|
|
44
|
+
await handleConfigInitialization(cwd, options, isDryRun);
|
|
61
45
|
}
|
|
62
46
|
catch (error) {
|
|
63
47
|
console.error(chalk.red('❌ Failed to initialize configuration:'), error);
|
|
@@ -65,309 +49,247 @@ export function initCommand(program) {
|
|
|
65
49
|
}
|
|
66
50
|
});
|
|
67
51
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Handle focused operations (--setup-hooks, --setup-workflow, --fix-gitignore)
|
|
54
|
+
*
|
|
55
|
+
* Executes specific setup tasks independently without creating config files.
|
|
56
|
+
* All operations are idempotent and can be safely run multiple times.
|
|
57
|
+
*
|
|
58
|
+
* @param cwd - Current working directory
|
|
59
|
+
* @param options - Init command options
|
|
60
|
+
* @param isDryRun - Preview mode (no file modifications)
|
|
61
|
+
* @throws Error if setup check fails
|
|
62
|
+
*/
|
|
63
|
+
async function handleFocusedOperations(cwd, options, isDryRun) {
|
|
64
|
+
const fixOptions = { cwd, dryRun: isDryRun, force: options.force };
|
|
65
|
+
const operations = [];
|
|
66
|
+
// Setup gitignore check
|
|
67
|
+
if (options.fixGitignore) {
|
|
68
|
+
operations.push({
|
|
69
|
+
name: 'Gitignore',
|
|
70
|
+
check: new GitignoreSetupCheck(),
|
|
71
|
+
enabled: true,
|
|
72
|
+
});
|
|
77
73
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
// Setup hooks check
|
|
75
|
+
if (options.setupHooks) {
|
|
76
|
+
operations.push({
|
|
77
|
+
name: 'Pre-commit hook',
|
|
78
|
+
check: new HooksSetupCheck(),
|
|
79
|
+
enabled: true,
|
|
80
|
+
});
|
|
81
81
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
stdio: 'pipe',
|
|
106
|
-
}).trim();
|
|
107
|
-
mainBranch = headRef.replace(`refs/remotes/${remoteOrigin}/`, '');
|
|
108
|
-
detected = true;
|
|
109
|
-
}
|
|
110
|
-
catch {
|
|
111
|
-
// Remote HEAD not set, try to detect from common branch names
|
|
112
|
-
try {
|
|
113
|
-
const branches = execSync(`git ls-remote --heads ${remoteOrigin}`, {
|
|
114
|
-
encoding: 'utf8',
|
|
115
|
-
stdio: 'pipe',
|
|
116
|
-
}).trim();
|
|
117
|
-
// Check for common main branch names in order of preference
|
|
118
|
-
if (branches.includes('refs/heads/main')) {
|
|
119
|
-
mainBranch = 'main';
|
|
120
|
-
detected = true;
|
|
121
|
-
}
|
|
122
|
-
else if (branches.includes('refs/heads/master')) {
|
|
123
|
-
mainBranch = 'master';
|
|
124
|
-
detected = true;
|
|
125
|
-
}
|
|
126
|
-
else if (branches.includes('refs/heads/develop')) {
|
|
127
|
-
mainBranch = 'develop';
|
|
128
|
-
detected = true;
|
|
82
|
+
// Setup workflow check
|
|
83
|
+
if (options.setupWorkflow) {
|
|
84
|
+
operations.push({
|
|
85
|
+
name: 'GitHub Actions workflow',
|
|
86
|
+
check: new WorkflowSetupCheck(),
|
|
87
|
+
enabled: true,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
// Execute operations
|
|
91
|
+
for (const operation of operations) {
|
|
92
|
+
if (!operation.enabled)
|
|
93
|
+
continue;
|
|
94
|
+
if (isDryRun) {
|
|
95
|
+
// Preview mode
|
|
96
|
+
const preview = await operation.check.preview(fixOptions);
|
|
97
|
+
console.log(chalk.blue(`\n🔍 ${operation.name} (dry-run):`));
|
|
98
|
+
console.log(chalk.gray(` ${preview.description}`));
|
|
99
|
+
if (preview.changes && preview.changes.length > 0) {
|
|
100
|
+
console.log(chalk.yellow(' Would create:'));
|
|
101
|
+
for (const change of preview.changes) {
|
|
102
|
+
console.log(chalk.gray(` - ${change.file} (${change.action})`));
|
|
103
|
+
if (change.content && change.content.length < 500) {
|
|
104
|
+
console.log(chalk.gray('\n' + change.content));
|
|
129
105
|
}
|
|
130
106
|
}
|
|
131
|
-
|
|
132
|
-
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// Fix mode
|
|
111
|
+
const result = await operation.check.fix(fixOptions);
|
|
112
|
+
if (result.success) {
|
|
113
|
+
if (result.filesChanged.length > 0) {
|
|
114
|
+
console.log(chalk.green(`✅ ${operation.name}: ${result.message}`));
|
|
133
115
|
}
|
|
116
|
+
else {
|
|
117
|
+
console.log(chalk.gray(`ℹ️ ${operation.name}: ${result.message}`));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
console.error(chalk.red(`❌ ${operation.name}: ${result.message}`));
|
|
134
122
|
}
|
|
135
123
|
}
|
|
136
124
|
}
|
|
137
|
-
|
|
138
|
-
|
|
125
|
+
if (isDryRun) {
|
|
126
|
+
console.log(chalk.yellow('\n💡 Run without --dry-run to apply changes'));
|
|
139
127
|
}
|
|
140
|
-
|
|
141
|
-
mainBranch,
|
|
142
|
-
remoteOrigin,
|
|
143
|
-
detected,
|
|
144
|
-
};
|
|
128
|
+
process.exit(0);
|
|
145
129
|
}
|
|
146
130
|
/**
|
|
147
|
-
*
|
|
131
|
+
* Handle config file initialization
|
|
132
|
+
*
|
|
133
|
+
* Creates a new vibe-validate configuration file using the specified preset.
|
|
134
|
+
* Auto-detects git configuration and generates appropriate defaults.
|
|
135
|
+
*
|
|
136
|
+
* @param cwd - Current working directory
|
|
137
|
+
* @param options - Init command options
|
|
138
|
+
* @param isDryRun - Preview mode (no file modifications)
|
|
139
|
+
* @throws Error if config already exists (unless force is true)
|
|
140
|
+
*/
|
|
141
|
+
async function handleConfigInitialization(cwd, options, isDryRun) {
|
|
142
|
+
// Check if config already exists
|
|
143
|
+
if (configExists(cwd) && !options.force && !isDryRun) {
|
|
144
|
+
console.error(chalk.red('❌ Configuration file already exists'));
|
|
145
|
+
console.error(chalk.gray(' Use --force to overwrite'));
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
const preset = options.preset || 'typescript-library';
|
|
149
|
+
// Validate preset
|
|
150
|
+
const validPresets = ['typescript-library', 'typescript-nodejs', 'typescript-react'];
|
|
151
|
+
if (!validPresets.includes(preset)) {
|
|
152
|
+
console.error(chalk.red(`❌ Invalid preset: ${preset}`));
|
|
153
|
+
console.error(chalk.gray(` Valid presets: ${validPresets.join(', ')}`));
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
// Detect git configuration
|
|
157
|
+
const gitConfig = detectGitConfig();
|
|
158
|
+
if (!isDryRun) {
|
|
159
|
+
if (gitConfig.detected) {
|
|
160
|
+
console.log(chalk.blue('🔍 Auto-detected git configuration:'));
|
|
161
|
+
console.log(chalk.gray(` Main branch: ${gitConfig.mainBranch}`));
|
|
162
|
+
console.log(chalk.gray(` Remote: ${gitConfig.remoteOrigin}`));
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
console.log(chalk.gray('ℹ️ Using default git configuration (main, origin)'));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Generate YAML config file content
|
|
169
|
+
const configContent = generateYamlConfig(preset, gitConfig);
|
|
170
|
+
const configPath = join(cwd, 'vibe-validate.config.yaml');
|
|
171
|
+
if (isDryRun) {
|
|
172
|
+
// Preview mode - show what would be created
|
|
173
|
+
console.log(chalk.blue('🔍 Configuration preview (dry-run):'));
|
|
174
|
+
console.log(chalk.yellow(' Would create:'));
|
|
175
|
+
console.log(chalk.gray(` - ${configPath}`));
|
|
176
|
+
console.log(chalk.gray(` - Preset: ${preset}`));
|
|
177
|
+
console.log();
|
|
178
|
+
console.log(chalk.yellow('💡 Run without --dry-run to create configuration'));
|
|
179
|
+
process.exit(0);
|
|
180
|
+
}
|
|
181
|
+
// Write config file
|
|
182
|
+
writeFileSync(configPath, configContent, 'utf-8');
|
|
183
|
+
console.log(chalk.green('✅ Configuration file created successfully'));
|
|
184
|
+
console.log(chalk.blue(`📋 Created: ${configPath}`));
|
|
185
|
+
console.log(chalk.gray(` Preset: ${preset}`));
|
|
186
|
+
console.log();
|
|
187
|
+
console.log(chalk.yellow('Next steps:'));
|
|
188
|
+
console.log(chalk.gray(' 1. Review and customize vibe-validate.config.yaml'));
|
|
189
|
+
console.log(chalk.gray(' 2. Run: vibe-validate validate'));
|
|
190
|
+
console.log(chalk.gray(' 3. Add to package.json scripts:'));
|
|
191
|
+
console.log(chalk.gray(' "validate": "vibe-validate validate"'));
|
|
192
|
+
console.log(chalk.gray(' "pre-commit": "vibe-validate pre-commit"'));
|
|
193
|
+
process.exit(0);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Generate YAML configuration content based on preset
|
|
197
|
+
*
|
|
198
|
+
* Creates YAML configuration file content with the specified preset
|
|
199
|
+
* and git configuration values.
|
|
200
|
+
*
|
|
201
|
+
* @param preset - Preset name (typescript-library, typescript-nodejs, typescript-react)
|
|
202
|
+
* @param gitConfig - Detected git configuration
|
|
203
|
+
* @returns YAML configuration file content
|
|
148
204
|
*/
|
|
149
|
-
function
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
{
|
|
170
|
-
name: 'ESLint',
|
|
171
|
-
command: 'eslint src/',
|
|
172
|
-
description: 'Lint source code',
|
|
173
|
-
},
|
|
174
|
-
],
|
|
175
|
-
},
|
|
176
|
-
|
|
177
|
-
// Phase 2: Unit Tests
|
|
178
|
-
{
|
|
179
|
-
name: 'Testing',
|
|
180
|
-
parallel: false,
|
|
181
|
-
steps: [
|
|
182
|
-
{
|
|
183
|
-
name: 'Unit Tests',
|
|
184
|
-
command: 'npm test',
|
|
185
|
-
description: 'Run unit tests with coverage',
|
|
186
|
-
},
|
|
187
|
-
],
|
|
188
|
-
},
|
|
189
|
-
|
|
190
|
-
// Phase 3: Build Verification
|
|
191
|
-
{
|
|
192
|
-
name: 'Build',
|
|
193
|
-
parallel: false,
|
|
194
|
-
steps: [
|
|
195
|
-
{
|
|
196
|
-
name: 'Build Package',
|
|
197
|
-
command: 'npm run build',
|
|
198
|
-
description: 'Build TypeScript to JavaScript',
|
|
199
|
-
},
|
|
200
|
-
],
|
|
201
|
-
},
|
|
202
|
-
],
|
|
203
|
-
|
|
204
|
-
// Use git tree hash caching for maximum performance
|
|
205
|
-
caching: {
|
|
206
|
-
strategy: 'git-tree-hash',
|
|
207
|
-
enabled: true,
|
|
208
|
-
},
|
|
209
|
-
|
|
210
|
-
// Fail fast on first error
|
|
211
|
-
failFast: true,
|
|
212
|
-
},
|
|
213
|
-
|
|
214
|
-
// Git integration settings
|
|
215
|
-
git: {
|
|
216
|
-
mainBranch: '${gitConfig.mainBranch}',
|
|
217
|
-
remoteOrigin: '${gitConfig.remoteOrigin}',
|
|
218
|
-
autoSync: false, // Never auto-merge - safety first
|
|
219
|
-
},
|
|
220
|
-
|
|
221
|
-
// Output configuration - state files are always written as YAML
|
|
222
|
-
});
|
|
223
|
-
`,
|
|
224
|
-
'typescript-nodejs': `import { defineConfig } from '@vibe-validate/config';
|
|
225
|
-
|
|
226
|
-
export default defineConfig({
|
|
227
|
-
// Use TypeScript Node.js preset as base
|
|
228
|
-
extends: 'typescript-nodejs',
|
|
229
|
-
|
|
230
|
-
validation: {
|
|
231
|
-
phases: [
|
|
232
|
-
// Phase 1: Fast Pre-Qualification (parallel)
|
|
233
|
-
{
|
|
234
|
-
name: 'Pre-Qualification',
|
|
235
|
-
parallel: true,
|
|
236
|
-
steps: [
|
|
237
|
-
{
|
|
238
|
-
name: 'TypeScript Type Check',
|
|
239
|
-
command: 'tsc --noEmit',
|
|
240
|
-
description: 'Type-check TypeScript files',
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
name: 'ESLint',
|
|
244
|
-
command: 'eslint src/',
|
|
245
|
-
description: 'Lint source code',
|
|
246
|
-
},
|
|
247
|
-
],
|
|
248
|
-
},
|
|
249
|
-
|
|
250
|
-
// Phase 2: Unit Tests
|
|
251
|
-
{
|
|
252
|
-
name: 'Testing',
|
|
253
|
-
parallel: false,
|
|
254
|
-
steps: [
|
|
255
|
-
{
|
|
256
|
-
name: 'Unit Tests',
|
|
257
|
-
command: 'npm test',
|
|
258
|
-
description: 'Run unit tests with coverage',
|
|
259
|
-
},
|
|
260
|
-
],
|
|
261
|
-
},
|
|
262
|
-
|
|
263
|
-
// Phase 3: Build Verification
|
|
264
|
-
{
|
|
265
|
-
name: 'Build',
|
|
266
|
-
parallel: false,
|
|
267
|
-
steps: [
|
|
268
|
-
{
|
|
269
|
-
name: 'Build Application',
|
|
270
|
-
command: 'npm run build',
|
|
271
|
-
description: 'Build TypeScript to JavaScript',
|
|
272
|
-
},
|
|
273
|
-
],
|
|
274
|
-
},
|
|
275
|
-
],
|
|
276
|
-
|
|
277
|
-
// Use git tree hash caching for maximum performance
|
|
278
|
-
caching: {
|
|
279
|
-
strategy: 'git-tree-hash',
|
|
280
|
-
enabled: true,
|
|
281
|
-
},
|
|
282
|
-
|
|
283
|
-
// Fail fast on first error
|
|
284
|
-
failFast: true,
|
|
285
|
-
},
|
|
286
|
-
|
|
287
|
-
// Git integration settings
|
|
288
|
-
git: {
|
|
289
|
-
mainBranch: '${gitConfig.mainBranch}',
|
|
290
|
-
remoteOrigin: '${gitConfig.remoteOrigin}',
|
|
291
|
-
autoSync: false, // Never auto-merge - safety first
|
|
292
|
-
},
|
|
293
|
-
|
|
294
|
-
// Output configuration - state files are always written as YAML
|
|
295
|
-
});
|
|
296
|
-
`,
|
|
297
|
-
'typescript-react': `import { defineConfig } from '@vibe-validate/config';
|
|
298
|
-
|
|
299
|
-
export default defineConfig({
|
|
300
|
-
// Use TypeScript React preset as base
|
|
301
|
-
extends: 'typescript-react',
|
|
302
|
-
|
|
303
|
-
validation: {
|
|
304
|
-
phases: [
|
|
305
|
-
// Phase 1: Fast Pre-Qualification (parallel)
|
|
306
|
-
{
|
|
307
|
-
name: 'Pre-Qualification',
|
|
308
|
-
parallel: true,
|
|
309
|
-
steps: [
|
|
310
|
-
{
|
|
311
|
-
name: 'TypeScript Type Check',
|
|
312
|
-
command: 'tsc --noEmit',
|
|
313
|
-
description: 'Type-check TypeScript and React files',
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
name: 'ESLint',
|
|
317
|
-
command: 'eslint src/',
|
|
318
|
-
description: 'Lint source code with React rules',
|
|
319
|
-
},
|
|
320
|
-
],
|
|
321
|
-
},
|
|
322
|
-
|
|
323
|
-
// Phase 2: Unit Tests
|
|
324
|
-
{
|
|
325
|
-
name: 'Testing',
|
|
326
|
-
parallel: false,
|
|
327
|
-
steps: [
|
|
328
|
-
{
|
|
329
|
-
name: 'Unit Tests',
|
|
330
|
-
command: 'npm test',
|
|
331
|
-
description: 'Run unit tests with coverage',
|
|
332
|
-
},
|
|
333
|
-
],
|
|
334
|
-
},
|
|
335
|
-
|
|
336
|
-
// Phase 3: Build Verification
|
|
337
|
-
{
|
|
338
|
-
name: 'Build',
|
|
339
|
-
parallel: false,
|
|
340
|
-
steps: [
|
|
341
|
-
{
|
|
342
|
-
name: 'Build Application',
|
|
343
|
-
command: 'npm run build',
|
|
344
|
-
description: 'Build React application for production',
|
|
345
|
-
},
|
|
346
|
-
],
|
|
347
|
-
},
|
|
348
|
-
],
|
|
349
|
-
|
|
350
|
-
// Use git tree hash caching for maximum performance
|
|
351
|
-
caching: {
|
|
352
|
-
strategy: 'git-tree-hash',
|
|
353
|
-
enabled: true,
|
|
354
|
-
},
|
|
355
|
-
|
|
356
|
-
// Fail fast on first error
|
|
357
|
-
failFast: true,
|
|
358
|
-
},
|
|
359
|
-
|
|
360
|
-
// Git integration settings
|
|
361
|
-
git: {
|
|
362
|
-
mainBranch: '${gitConfig.mainBranch}',
|
|
363
|
-
remoteOrigin: '${gitConfig.remoteOrigin}',
|
|
364
|
-
autoSync: false, // Never auto-merge - safety first
|
|
365
|
-
},
|
|
366
|
-
|
|
367
|
-
// Output configuration - state files are always written as YAML
|
|
368
|
-
});
|
|
369
|
-
`,
|
|
205
|
+
function generateYamlConfig(preset, gitConfig) {
|
|
206
|
+
const baseConfig = {
|
|
207
|
+
// JSON Schema for IDE validation
|
|
208
|
+
$schema: 'https://raw.githubusercontent.com/jdutton/vibe-validate/main/packages/config/vibe-validate.schema.json',
|
|
209
|
+
// Use preset as base configuration
|
|
210
|
+
extends: preset,
|
|
211
|
+
// Git integration settings
|
|
212
|
+
git: {
|
|
213
|
+
mainBranch: gitConfig.mainBranch,
|
|
214
|
+
remoteOrigin: gitConfig.remoteOrigin,
|
|
215
|
+
autoSync: false, // Never auto-merge - safety first
|
|
216
|
+
},
|
|
217
|
+
// Validation configuration (from preset)
|
|
218
|
+
validation: {
|
|
219
|
+
caching: {
|
|
220
|
+
strategy: 'git-tree-hash',
|
|
221
|
+
enabled: true,
|
|
222
|
+
},
|
|
223
|
+
failFast: true,
|
|
224
|
+
},
|
|
370
225
|
};
|
|
371
|
-
return
|
|
226
|
+
return stringifyYaml(baseConfig, {
|
|
227
|
+
indent: 2,
|
|
228
|
+
lineWidth: 100,
|
|
229
|
+
noRefs: true,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Handle migration from .mjs to .yaml config format
|
|
234
|
+
*
|
|
235
|
+
* Loads the existing .mjs configuration, converts it to YAML format,
|
|
236
|
+
* and writes it to vibe-validate.config.yaml.
|
|
237
|
+
*
|
|
238
|
+
* @param cwd - Current working directory
|
|
239
|
+
* @param options - Init command options
|
|
240
|
+
* @param isDryRun - Preview mode (no file modifications)
|
|
241
|
+
* @throws Error if .mjs config doesn't exist or .yaml already exists (without --force)
|
|
242
|
+
*/
|
|
243
|
+
async function handleMigration(cwd, options, isDryRun) {
|
|
244
|
+
const mjsPath = join(cwd, 'vibe-validate.config.mjs');
|
|
245
|
+
const yamlPath = join(cwd, 'vibe-validate.config.yaml');
|
|
246
|
+
// Check if .mjs config exists
|
|
247
|
+
if (!existsSync(mjsPath)) {
|
|
248
|
+
console.error(chalk.red('❌ No .mjs config found to migrate'));
|
|
249
|
+
console.error(chalk.gray(' Expected: vibe-validate.config.mjs'));
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
// Check if .yaml config already exists (unless --force)
|
|
253
|
+
if (existsSync(yamlPath) && !options.force && !isDryRun) {
|
|
254
|
+
console.error(chalk.red('❌ YAML config already exists'));
|
|
255
|
+
console.error(chalk.gray(' Use --force to overwrite'));
|
|
256
|
+
process.exit(1);
|
|
257
|
+
}
|
|
258
|
+
// Load the .mjs config
|
|
259
|
+
const fileUrl = pathToFileURL(mjsPath).href;
|
|
260
|
+
const module = await import(fileUrl);
|
|
261
|
+
const config = module.default || module;
|
|
262
|
+
// Convert to YAML
|
|
263
|
+
const yamlContent = stringifyYaml(config, {
|
|
264
|
+
indent: 2,
|
|
265
|
+
lineWidth: 100,
|
|
266
|
+
noRefs: true,
|
|
267
|
+
});
|
|
268
|
+
if (isDryRun) {
|
|
269
|
+
// Preview mode
|
|
270
|
+
console.log(chalk.blue('🔍 Migration preview (dry-run):'));
|
|
271
|
+
console.log(chalk.yellow(' Would create:'));
|
|
272
|
+
console.log(chalk.gray(` - ${yamlPath}`));
|
|
273
|
+
console.log();
|
|
274
|
+
console.log(chalk.gray('Preview of YAML content:'));
|
|
275
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
276
|
+
console.log(yamlContent);
|
|
277
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
278
|
+
console.log();
|
|
279
|
+
console.log(chalk.yellow('💡 Run without --dry-run to apply migration'));
|
|
280
|
+
console.log(chalk.gray(' Original .mjs file will be preserved (you can delete it manually)'));
|
|
281
|
+
process.exit(0);
|
|
282
|
+
}
|
|
283
|
+
// Write YAML config
|
|
284
|
+
writeFileSync(yamlPath, yamlContent, 'utf-8');
|
|
285
|
+
console.log(chalk.green('✅ Migration completed successfully'));
|
|
286
|
+
console.log(chalk.blue(`📋 Created: ${yamlPath}`));
|
|
287
|
+
console.log();
|
|
288
|
+
console.log(chalk.yellow('Next steps:'));
|
|
289
|
+
console.log(chalk.gray(' 1. Review vibe-validate.config.yaml'));
|
|
290
|
+
console.log(chalk.gray(' 2. Test with: vibe-validate validate'));
|
|
291
|
+
console.log(chalk.gray(` 3. Delete old config: rm ${mjsPath}`));
|
|
292
|
+
console.log(chalk.gray(' 4. Commit the new YAML config'));
|
|
293
|
+
process.exit(0);
|
|
372
294
|
}
|
|
373
295
|
//# sourceMappingURL=init.js.map
|