@vibe-validate/core 0.9.3 ā 0.9.5
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/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +104 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/process-utils.d.ts +29 -0
- package/dist/process-utils.d.ts.map +1 -0
- package/dist/process-utils.js +62 -0
- package/dist/process-utils.js.map +1 -0
- package/dist/runner.d.ts +190 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +402 -0
- package/dist/runner.js.map +1 -0
- package/dist/types.d.ts +126 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +1 -1
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;GAIG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Vibe-Validate CLI Entry Point
|
|
4
|
+
*
|
|
5
|
+
* This script loads the configuration and runs the validation runner.
|
|
6
|
+
*/
|
|
7
|
+
import { join, resolve } from 'path';
|
|
8
|
+
import { existsSync } from 'fs';
|
|
9
|
+
import { runValidation } from './runner.js';
|
|
10
|
+
/**
|
|
11
|
+
* Find and load vibe-validate.config.ts
|
|
12
|
+
*
|
|
13
|
+
* @returns A config object with validation, git, and output settings
|
|
14
|
+
*/
|
|
15
|
+
async function loadConfig() {
|
|
16
|
+
const cwd = process.cwd();
|
|
17
|
+
const configPaths = [
|
|
18
|
+
'vibe-validate.config.ts',
|
|
19
|
+
'vibe-validate.config.js',
|
|
20
|
+
'vibe-validate.config.mjs',
|
|
21
|
+
'.vibe-validate.ts',
|
|
22
|
+
'.vibe-validate.js',
|
|
23
|
+
'.vibe-validate.mjs',
|
|
24
|
+
];
|
|
25
|
+
for (const configPath of configPaths) {
|
|
26
|
+
const fullPath = join(cwd, configPath);
|
|
27
|
+
if (existsSync(fullPath)) {
|
|
28
|
+
console.log(`š Loading config from ${configPath}`);
|
|
29
|
+
try {
|
|
30
|
+
// Use dynamic import to support both .ts and .js configs
|
|
31
|
+
const configModule = await import(`file://${resolve(fullPath)}`);
|
|
32
|
+
const config = configModule.default || configModule;
|
|
33
|
+
return config;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.error(`ā Failed to load config from ${configPath}:`, error);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
console.error('ā No vibe-validate.config.ts found in current directory');
|
|
42
|
+
console.error(' Searched for:');
|
|
43
|
+
configPaths.forEach((path) => console.error(` - ${path}`));
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Main CLI entry point
|
|
48
|
+
*/
|
|
49
|
+
async function main() {
|
|
50
|
+
try {
|
|
51
|
+
// Load configuration
|
|
52
|
+
const rawConfig = await loadConfig();
|
|
53
|
+
// Adapt config structure for runner
|
|
54
|
+
// The config loader returns a structured config with {validation, git, output}
|
|
55
|
+
// The runner expects a flat config with {phases, ...}
|
|
56
|
+
// Convert process.env to Record<string, string> by filtering out undefined values
|
|
57
|
+
const envVars = {};
|
|
58
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
59
|
+
if (value !== undefined) {
|
|
60
|
+
envVars[key] = value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const runnerConfig = {
|
|
64
|
+
phases: rawConfig.validation?.phases || [],
|
|
65
|
+
enableFailFast: rawConfig.validation?.failFast ?? true,
|
|
66
|
+
env: envVars,
|
|
67
|
+
stateFilePath: '.vibe-validate-state.yaml',
|
|
68
|
+
onPhaseStart: (phase) => console.log(`\nš Running phase: ${phase.name}`),
|
|
69
|
+
onPhaseComplete: (phase, result) => {
|
|
70
|
+
if (result.passed) {
|
|
71
|
+
console.log(`ā
Phase ${phase.name} completed successfully`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.log(`ā Phase ${phase.name} failed`);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
onStepStart: (step) => console.log(` ā³ ${step.name}...`),
|
|
78
|
+
onStepComplete: (step, result) => {
|
|
79
|
+
if (result.passed) {
|
|
80
|
+
console.log(` ā
${step.name} (${result.duration}ms)`);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
console.log(` ā ${step.name} failed (${result.duration}ms)`);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
// Run validation
|
|
88
|
+
const result = await runValidation(runnerConfig);
|
|
89
|
+
// Exit with appropriate code
|
|
90
|
+
process.exit(result.passed ? 0 : 1);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error('ā Validation failed with error:', error);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Run if executed directly
|
|
98
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
99
|
+
main().catch((error) => {
|
|
100
|
+
console.error('Fatal error:', error);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C;;;;GAIG;AACH,KAAK,UAAU,UAAU;IACvB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,WAAW,GAAG;QAClB,yBAAyB;QACzB,yBAAyB;QACzB,0BAA0B;QAC1B,mBAAmB;QACnB,mBAAmB;QACnB,oBAAoB;KACrB,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACvC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;YACpD,IAAI,CAAC;gBACH,yDAAyD;gBACzD,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,UAAU,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACjE,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC;gBACpD,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,gCAAgC,UAAU,GAAG,EAAE,KAAK,CAAC,CAAC;gBACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IACzE,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAClC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,qBAAqB;QACrB,MAAM,SAAS,GAAG,MAAM,UAAU,EAAE,CAAC;QAErC,oCAAoC;QACpC,+EAA+E;QAC/E,sDAAsD;QAEtD,kFAAkF;QAClF,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACvB,CAAC;QACH,CAAC;QAED,MAAM,YAAY,GAAqB;YACrC,MAAM,EAAE,SAAS,CAAC,UAAU,EAAE,MAAM,IAAI,EAAE;YAC1C,cAAc,EAAE,SAAS,CAAC,UAAU,EAAE,QAAQ,IAAI,IAAI;YACtD,GAAG,EAAE,OAAO;YACZ,aAAa,EAAE,2BAA2B;YAC1C,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,IAAI,EAAE,CAAC;YACzE,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;gBACjC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,yBAAyB,CAAC,CAAC;gBAC9D,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC;YACD,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,KAAK,CAAC;YACzD,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;gBAC/B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;gBACzD,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,YAAY,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;gBAChE,CAAC;YACH,CAAC;SACF,CAAC;QAEF,iBAAiB;QACjB,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC,CAAC;QAEjD,6BAA6B;QAC7B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,2BAA2B;AAC3B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpD,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vibe-validate/core
|
|
3
|
+
*
|
|
4
|
+
* Core validation engine with git tree hash caching, parallel execution, and fail-fast support.
|
|
5
|
+
*
|
|
6
|
+
* ## Features
|
|
7
|
+
*
|
|
8
|
+
* - **Git Tree Hash Caching**: Skip validation if code unchanged
|
|
9
|
+
* - **Parallel Execution**: Run validation steps concurrently for speed
|
|
10
|
+
* - **Fail-Fast**: Stop on first failure with proper process cleanup
|
|
11
|
+
* - **Signal Handling**: Graceful cleanup on SIGTERM/SIGINT
|
|
12
|
+
* - **Language Agnostic**: Works with any command-line tool
|
|
13
|
+
*
|
|
14
|
+
* ## Example Usage
|
|
15
|
+
*
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { runValidation } from '@vibe-validate/core';
|
|
18
|
+
*
|
|
19
|
+
* const result = await runValidation({
|
|
20
|
+
* phases: [
|
|
21
|
+
* {
|
|
22
|
+
* name: 'Type Checking',
|
|
23
|
+
* steps: [
|
|
24
|
+
* { name: 'TypeScript', command: 'tsc --noEmit' },
|
|
25
|
+
* { name: 'ESLint', command: 'eslint src/' },
|
|
26
|
+
* ],
|
|
27
|
+
* },
|
|
28
|
+
* {
|
|
29
|
+
* name: 'Testing',
|
|
30
|
+
* steps: [
|
|
31
|
+
* { name: 'Unit Tests', command: 'npm test' },
|
|
32
|
+
* ],
|
|
33
|
+
* },
|
|
34
|
+
* ],
|
|
35
|
+
* enableFailFast: true,
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* if (result.passed) {
|
|
39
|
+
* console.log('ā
Validation passed!');
|
|
40
|
+
* } else {
|
|
41
|
+
* console.error('ā Validation failed:', result.failedStep);
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @packageDocumentation
|
|
46
|
+
*/
|
|
47
|
+
export type { ValidationStep, ValidationPhase, ValidationConfig, ValidationResult, StepResult, PhaseResult, } from './types.js';
|
|
48
|
+
export { runValidation, runStepsInParallel, getWorkingTreeHash, checkExistingValidation, parseFailures, setupSignalHandlers, } from './runner.js';
|
|
49
|
+
export { stopProcessGroup, } from './process-utils.js';
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAGH,YAAY,EACV,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,gBAAgB,GACjB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vibe-validate/core
|
|
3
|
+
*
|
|
4
|
+
* Core validation engine with git tree hash caching, parallel execution, and fail-fast support.
|
|
5
|
+
*
|
|
6
|
+
* ## Features
|
|
7
|
+
*
|
|
8
|
+
* - **Git Tree Hash Caching**: Skip validation if code unchanged
|
|
9
|
+
* - **Parallel Execution**: Run validation steps concurrently for speed
|
|
10
|
+
* - **Fail-Fast**: Stop on first failure with proper process cleanup
|
|
11
|
+
* - **Signal Handling**: Graceful cleanup on SIGTERM/SIGINT
|
|
12
|
+
* - **Language Agnostic**: Works with any command-line tool
|
|
13
|
+
*
|
|
14
|
+
* ## Example Usage
|
|
15
|
+
*
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { runValidation } from '@vibe-validate/core';
|
|
18
|
+
*
|
|
19
|
+
* const result = await runValidation({
|
|
20
|
+
* phases: [
|
|
21
|
+
* {
|
|
22
|
+
* name: 'Type Checking',
|
|
23
|
+
* steps: [
|
|
24
|
+
* { name: 'TypeScript', command: 'tsc --noEmit' },
|
|
25
|
+
* { name: 'ESLint', command: 'eslint src/' },
|
|
26
|
+
* ],
|
|
27
|
+
* },
|
|
28
|
+
* {
|
|
29
|
+
* name: 'Testing',
|
|
30
|
+
* steps: [
|
|
31
|
+
* { name: 'Unit Tests', command: 'npm test' },
|
|
32
|
+
* ],
|
|
33
|
+
* },
|
|
34
|
+
* ],
|
|
35
|
+
* enableFailFast: true,
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* if (result.passed) {
|
|
39
|
+
* console.log('ā
Validation passed!');
|
|
40
|
+
* } else {
|
|
41
|
+
* console.error('ā Validation failed:', result.failedStep);
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @packageDocumentation
|
|
46
|
+
*/
|
|
47
|
+
// Export core runner functions
|
|
48
|
+
export { runValidation, runStepsInParallel, getWorkingTreeHash, checkExistingValidation, parseFailures, setupSignalHandlers, } from './runner.js';
|
|
49
|
+
// Export process utilities
|
|
50
|
+
export { stopProcessGroup, } from './process-utils.js';
|
|
51
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAYH,+BAA+B;AAC/B,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,2BAA2B;AAC3B,OAAO,EACL,gBAAgB,GACjB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process management utilities for validation runner
|
|
3
|
+
*
|
|
4
|
+
* Provides reliable process group cleanup for spawned child processes.
|
|
5
|
+
* Used by validation runner for signal handling and fail-fast behavior.
|
|
6
|
+
*/
|
|
7
|
+
import { ChildProcess } from 'child_process';
|
|
8
|
+
/**
|
|
9
|
+
* Stop a child process and its entire process group
|
|
10
|
+
*
|
|
11
|
+
* Uses negative PID to kill process group, ensuring all children are terminated.
|
|
12
|
+
*
|
|
13
|
+
* **Implementation:**
|
|
14
|
+
* - Graceful shutdown: SIGTERM to process group (-PID)
|
|
15
|
+
* - Force kill after 1s: SIGKILL to process group
|
|
16
|
+
* - Ultimate timeout: Resolves after 2s regardless
|
|
17
|
+
*
|
|
18
|
+
* @param childProcess - The child process to stop
|
|
19
|
+
* @param processName - Optional name for logging (e.g., "TypeScript", "ESLint")
|
|
20
|
+
* @returns Promise that resolves when process is stopped
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const proc = spawn('tsc', ['--noEmit']);
|
|
25
|
+
* await stopProcessGroup(proc, 'TypeScript');
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function stopProcessGroup(childProcess: ChildProcess, processName?: string): Promise<void>;
|
|
29
|
+
//# sourceMappingURL=process-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-utils.d.ts","sourceRoot":"","sources":["../src/process-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,gBAAgB,CACpC,YAAY,EAAE,YAAY,EAC1B,WAAW,GAAE,MAAkB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAmCf"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process management utilities for validation runner
|
|
3
|
+
*
|
|
4
|
+
* Provides reliable process group cleanup for spawned child processes.
|
|
5
|
+
* Used by validation runner for signal handling and fail-fast behavior.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Stop a child process and its entire process group
|
|
9
|
+
*
|
|
10
|
+
* Uses negative PID to kill process group, ensuring all children are terminated.
|
|
11
|
+
*
|
|
12
|
+
* **Implementation:**
|
|
13
|
+
* - Graceful shutdown: SIGTERM to process group (-PID)
|
|
14
|
+
* - Force kill after 1s: SIGKILL to process group
|
|
15
|
+
* - Ultimate timeout: Resolves after 2s regardless
|
|
16
|
+
*
|
|
17
|
+
* @param childProcess - The child process to stop
|
|
18
|
+
* @param processName - Optional name for logging (e.g., "TypeScript", "ESLint")
|
|
19
|
+
* @returns Promise that resolves when process is stopped
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const proc = spawn('tsc', ['--noEmit']);
|
|
24
|
+
* await stopProcessGroup(proc, 'TypeScript');
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export async function stopProcessGroup(childProcess, processName = 'Process') {
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
if (!childProcess.killed && childProcess.pid) {
|
|
30
|
+
const pid = childProcess.pid;
|
|
31
|
+
childProcess.on('exit', () => {
|
|
32
|
+
console.log(`š ${processName} stopped`);
|
|
33
|
+
resolve();
|
|
34
|
+
});
|
|
35
|
+
// Kill the entire process group by negating the PID
|
|
36
|
+
// This kills the process and all its children
|
|
37
|
+
try {
|
|
38
|
+
process.kill(-pid, 'SIGTERM');
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Process may already be dead, ignore error
|
|
42
|
+
}
|
|
43
|
+
// Force kill entire process group after 1 second if not stopped
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
try {
|
|
46
|
+
process.kill(-pid, 'SIGKILL');
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Process may already be dead, ignore error
|
|
50
|
+
}
|
|
51
|
+
}, 1000);
|
|
52
|
+
// Ultimate timeout - resolve after 2 seconds regardless
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
resolve();
|
|
55
|
+
}, 2000);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
resolve();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=process-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-utils.js","sourceRoot":"","sources":["../src/process-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,YAA0B,EAC1B,cAAsB,SAAS;IAE/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,CAAC;YAC7C,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC;YAE7B,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;gBAC3B,OAAO,CAAC,GAAG,CAAC,MAAM,WAAW,UAAU,CAAC,CAAC;gBACzC,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;YAEH,oDAAoD;YACpD,8CAA8C;YAC9C,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAChC,CAAC;YAAC,MAAM,CAAC;gBACP,4CAA4C;YAC9C,CAAC;YAED,gEAAgE;YAChE,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC;oBACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAChC,CAAC;gBAAC,MAAM,CAAC;oBACP,4CAA4C;gBAC9C,CAAC;YACH,CAAC,EAAE,IAAI,CAAC,CAAC;YAET,wDAAwD;YACxD,UAAU,CAAC,GAAG,EAAE;gBACd,OAAO,EAAE,CAAC;YACZ,CAAC,EAAE,IAAI,CAAC,CAAC;QACX,CAAC;aAAM,CAAC;YACN,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/runner.d.ts
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation Runner - Core validation orchestration with state caching
|
|
3
|
+
*
|
|
4
|
+
* This module provides the core validation engine that:
|
|
5
|
+
* 1. Executes validation steps in parallel for speed
|
|
6
|
+
* 2. Tracks state using git tree hashes for caching
|
|
7
|
+
* 3. Provides fail-fast execution with proper cleanup
|
|
8
|
+
* 4. Handles signals (SIGTERM/SIGINT) gracefully
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import { type ChildProcess } from 'child_process';
|
|
13
|
+
import type { ValidationStep, ValidationResult, ValidationConfig, StepResult } from './types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Git tree hash calculator
|
|
16
|
+
*
|
|
17
|
+
* NOTE: This is a simplified fallback implementation.
|
|
18
|
+
* For production use, prefer @vibe-validate/git package which provides
|
|
19
|
+
* deterministic git tree hashing using git write-tree instead of git stash create.
|
|
20
|
+
*
|
|
21
|
+
* This implementation uses git stash create, which includes timestamps and is
|
|
22
|
+
* non-deterministic (same code content may produce different hashes).
|
|
23
|
+
*
|
|
24
|
+
* @returns SHA-1 hash representing working tree state (non-deterministic)
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export declare function getWorkingTreeHash(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Check if validation has already passed for current working tree state
|
|
30
|
+
*
|
|
31
|
+
* Reads the validation state file and compares the git tree hash to determine
|
|
32
|
+
* if validation can be skipped (cache hit).
|
|
33
|
+
*
|
|
34
|
+
* @param currentTreeHash - Current git tree hash of working directory
|
|
35
|
+
* @param stateFilePath - Path to validation state file
|
|
36
|
+
* @returns Object with alreadyPassed flag and optional previousState
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const { alreadyPassed, previousState } = checkExistingValidation(
|
|
41
|
+
* 'abc123...',
|
|
42
|
+
* '.validate-state.json'
|
|
43
|
+
* );
|
|
44
|
+
*
|
|
45
|
+
* if (alreadyPassed) {
|
|
46
|
+
* console.log('Validation already passed!');
|
|
47
|
+
* return previousState;
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @public
|
|
52
|
+
*/
|
|
53
|
+
export declare function checkExistingValidation(currentTreeHash: string, stateFilePath: string): {
|
|
54
|
+
alreadyPassed: boolean;
|
|
55
|
+
previousState?: ValidationResult;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Parse test output to extract specific failures
|
|
59
|
+
*
|
|
60
|
+
* Extracts failure details from validation step output using pattern matching.
|
|
61
|
+
* Supports Vitest, TypeScript, and ESLint error formats.
|
|
62
|
+
*
|
|
63
|
+
* Note: This is a basic implementation - the formatters package provides
|
|
64
|
+
* more sophisticated parsing with tool-specific formatters.
|
|
65
|
+
*
|
|
66
|
+
* @param output - Raw stdout/stderr output from validation step
|
|
67
|
+
* @returns Array of extracted failure messages (max 10 per failure type)
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const output = `
|
|
72
|
+
* ā should validate user input
|
|
73
|
+
* src/user.ts(42,10): error TS2345: Argument type mismatch
|
|
74
|
+
* `;
|
|
75
|
+
*
|
|
76
|
+
* const failures = parseFailures(output);
|
|
77
|
+
* // ['ā should validate user input', 'src/user.ts(42,10): error TS2345: ...']
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @public
|
|
81
|
+
*/
|
|
82
|
+
export declare function parseFailures(output: string): string[];
|
|
83
|
+
/**
|
|
84
|
+
* Run validation steps in parallel with smart fail-fast
|
|
85
|
+
*
|
|
86
|
+
* Executes multiple validation steps concurrently, capturing output and
|
|
87
|
+
* providing fail-fast termination if enabled. Each step runs in its own
|
|
88
|
+
* detached process group for clean termination.
|
|
89
|
+
*
|
|
90
|
+
* @param steps - Array of validation steps to execute in parallel
|
|
91
|
+
* @param phaseName - Human-readable phase name for logging
|
|
92
|
+
* @param enableFailFast - If true, kills remaining processes on first failure
|
|
93
|
+
* @param env - Additional environment variables for child processes
|
|
94
|
+
* @returns Promise resolving to execution results with outputs and step results
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const result = await runStepsInParallel(
|
|
99
|
+
* [
|
|
100
|
+
* { name: 'TypeScript', command: 'pnpm typecheck' },
|
|
101
|
+
* { name: 'ESLint', command: 'pnpm lint' },
|
|
102
|
+
* ],
|
|
103
|
+
* 'Pre-Qualification',
|
|
104
|
+
* true, // Enable fail-fast
|
|
105
|
+
* { NODE_ENV: 'test' }
|
|
106
|
+
* );
|
|
107
|
+
*
|
|
108
|
+
* if (!result.success) {
|
|
109
|
+
* console.error(`Step ${result.failedStep?.name} failed`);
|
|
110
|
+
* }
|
|
111
|
+
* ```
|
|
112
|
+
*
|
|
113
|
+
* @public
|
|
114
|
+
*/
|
|
115
|
+
export declare function runStepsInParallel(steps: ValidationStep[], phaseName: string, enableFailFast?: boolean, env?: Record<string, string>): Promise<{
|
|
116
|
+
success: boolean;
|
|
117
|
+
failedStep?: ValidationStep;
|
|
118
|
+
outputs: Map<string, string>;
|
|
119
|
+
stepResults: StepResult[];
|
|
120
|
+
}>;
|
|
121
|
+
/**
|
|
122
|
+
* Validation runner with state tracking and caching
|
|
123
|
+
*
|
|
124
|
+
* Main entry point for running validation with git tree hash-based caching.
|
|
125
|
+
* Executes validation phases sequentially, with parallel step execution within
|
|
126
|
+
* each phase. Supports fail-fast termination and comprehensive state tracking.
|
|
127
|
+
*
|
|
128
|
+
* Features:
|
|
129
|
+
* - Git tree hash-based caching (skip if code unchanged)
|
|
130
|
+
* - Parallel step execution within phases
|
|
131
|
+
* - Fail-fast mode (stop on first failure)
|
|
132
|
+
* - Comprehensive output logging
|
|
133
|
+
* - State file persistence for cache validation
|
|
134
|
+
*
|
|
135
|
+
* @param config - Validation configuration with phases, steps, and options
|
|
136
|
+
* @returns Promise resolving to validation result with pass/fail status
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* const result = await runValidation({
|
|
141
|
+
* phases: [
|
|
142
|
+
* {
|
|
143
|
+
* name: 'Pre-Qualification',
|
|
144
|
+
* parallel: true,
|
|
145
|
+
* steps: [
|
|
146
|
+
* { name: 'TypeScript', command: 'pnpm typecheck' },
|
|
147
|
+
* { name: 'ESLint', command: 'pnpm lint' },
|
|
148
|
+
* ],
|
|
149
|
+
* },
|
|
150
|
+
* ],
|
|
151
|
+
* stateFilePath: '.vibe-validate-state.yaml',
|
|
152
|
+
* enableFailFast: false,
|
|
153
|
+
* forceRun: false,
|
|
154
|
+
* });
|
|
155
|
+
*
|
|
156
|
+
* if (result.passed) {
|
|
157
|
+
* console.log('ā
Validation passed');
|
|
158
|
+
* } else {
|
|
159
|
+
* console.error(`ā Failed at step: ${result.failedStep}`);
|
|
160
|
+
* console.error(result.failedStepOutput);
|
|
161
|
+
* }
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* @public
|
|
165
|
+
*/
|
|
166
|
+
export declare function runValidation(config: ValidationConfig): Promise<ValidationResult>;
|
|
167
|
+
/**
|
|
168
|
+
* Setup signal handlers for graceful cleanup
|
|
169
|
+
*
|
|
170
|
+
* Registers SIGTERM and SIGINT handlers to ensure all active child processes
|
|
171
|
+
* are properly terminated when the validation runner is interrupted.
|
|
172
|
+
*
|
|
173
|
+
* @param activeProcesses - Set of active child processes to track for cleanup
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* const activeProcesses = new Set<ChildProcess>();
|
|
178
|
+
* setupSignalHandlers(activeProcesses);
|
|
179
|
+
*
|
|
180
|
+
* // When spawning new processes:
|
|
181
|
+
* const proc = spawn('npm', ['test']);
|
|
182
|
+
* activeProcesses.add(proc);
|
|
183
|
+
*
|
|
184
|
+
* // Cleanup is automatic on SIGTERM/SIGINT
|
|
185
|
+
* ```
|
|
186
|
+
*
|
|
187
|
+
* @public
|
|
188
|
+
*/
|
|
189
|
+
export declare function setupSignalHandlers(activeProcesses: Set<ChildProcess>): void;
|
|
190
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAKnE,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EAEX,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CA0B3C;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,GACpB;IAAE,aAAa,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,gBAAgB,CAAA;CAAE,CAmB9D;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAsBtD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,cAAc,EAAE,EACvB,SAAS,EAAE,MAAM,EACjB,cAAc,GAAE,OAAe,EAC/B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC/B,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,CAAC,CAoFD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkHvF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,IAAI,CAe5E"}
|
package/dist/runner.js
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation Runner - Core validation orchestration with state caching
|
|
3
|
+
*
|
|
4
|
+
* This module provides the core validation engine that:
|
|
5
|
+
* 1. Executes validation steps in parallel for speed
|
|
6
|
+
* 2. Tracks state using git tree hashes for caching
|
|
7
|
+
* 3. Provides fail-fast execution with proper cleanup
|
|
8
|
+
* 4. Handles signals (SIGTERM/SIGINT) gracefully
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import { spawn, execSync } from 'child_process';
|
|
13
|
+
import { writeFileSync, appendFileSync, existsSync, readFileSync } from 'fs';
|
|
14
|
+
import { tmpdir } from 'os';
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
import { stopProcessGroup } from './process-utils.js';
|
|
17
|
+
/**
|
|
18
|
+
* Git tree hash calculator
|
|
19
|
+
*
|
|
20
|
+
* NOTE: This is a simplified fallback implementation.
|
|
21
|
+
* For production use, prefer @vibe-validate/git package which provides
|
|
22
|
+
* deterministic git tree hashing using git write-tree instead of git stash create.
|
|
23
|
+
*
|
|
24
|
+
* This implementation uses git stash create, which includes timestamps and is
|
|
25
|
+
* non-deterministic (same code content may produce different hashes).
|
|
26
|
+
*
|
|
27
|
+
* @returns SHA-1 hash representing working tree state (non-deterministic)
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export function getWorkingTreeHash() {
|
|
31
|
+
try {
|
|
32
|
+
// Use git stash create to include ALL working tree changes
|
|
33
|
+
// WARNING: This creates commit objects with timestamps (non-deterministic)
|
|
34
|
+
const stashHash = execSync('git stash create', {
|
|
35
|
+
encoding: 'utf8',
|
|
36
|
+
stdio: ['pipe', 'pipe', 'ignore']
|
|
37
|
+
}).trim();
|
|
38
|
+
// If no changes, fall back to HEAD tree
|
|
39
|
+
if (!stashHash) {
|
|
40
|
+
return execSync('git rev-parse HEAD^{tree}', {
|
|
41
|
+
encoding: 'utf8',
|
|
42
|
+
stdio: ['pipe', 'pipe', 'ignore']
|
|
43
|
+
}).trim();
|
|
44
|
+
}
|
|
45
|
+
// Extract tree hash from stash commit
|
|
46
|
+
return execSync(`git rev-parse ${stashHash}^{tree}`, {
|
|
47
|
+
encoding: 'utf8',
|
|
48
|
+
stdio: ['pipe', 'pipe', 'ignore']
|
|
49
|
+
}).trim();
|
|
50
|
+
}
|
|
51
|
+
catch (_error) {
|
|
52
|
+
// Fallback for non-git repos or git command failures
|
|
53
|
+
return `nogit-${Date.now()}`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check if validation has already passed for current working tree state
|
|
58
|
+
*
|
|
59
|
+
* Reads the validation state file and compares the git tree hash to determine
|
|
60
|
+
* if validation can be skipped (cache hit).
|
|
61
|
+
*
|
|
62
|
+
* @param currentTreeHash - Current git tree hash of working directory
|
|
63
|
+
* @param stateFilePath - Path to validation state file
|
|
64
|
+
* @returns Object with alreadyPassed flag and optional previousState
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const { alreadyPassed, previousState } = checkExistingValidation(
|
|
69
|
+
* 'abc123...',
|
|
70
|
+
* '.validate-state.json'
|
|
71
|
+
* );
|
|
72
|
+
*
|
|
73
|
+
* if (alreadyPassed) {
|
|
74
|
+
* console.log('Validation already passed!');
|
|
75
|
+
* return previousState;
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
export function checkExistingValidation(currentTreeHash, stateFilePath) {
|
|
82
|
+
if (!existsSync(stateFilePath)) {
|
|
83
|
+
return { alreadyPassed: false };
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const content = readFileSync(stateFilePath, 'utf8');
|
|
87
|
+
// Parse as JSON (will support YAML in CLI package)
|
|
88
|
+
const state = JSON.parse(content);
|
|
89
|
+
// Check if validation passed and tree hash matches
|
|
90
|
+
if (state.passed && state.treeHash === currentTreeHash) {
|
|
91
|
+
return { alreadyPassed: true, previousState: state };
|
|
92
|
+
}
|
|
93
|
+
return { alreadyPassed: false, previousState: state };
|
|
94
|
+
}
|
|
95
|
+
catch (_error) {
|
|
96
|
+
return { alreadyPassed: false };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Parse test output to extract specific failures
|
|
101
|
+
*
|
|
102
|
+
* Extracts failure details from validation step output using pattern matching.
|
|
103
|
+
* Supports Vitest, TypeScript, and ESLint error formats.
|
|
104
|
+
*
|
|
105
|
+
* Note: This is a basic implementation - the formatters package provides
|
|
106
|
+
* more sophisticated parsing with tool-specific formatters.
|
|
107
|
+
*
|
|
108
|
+
* @param output - Raw stdout/stderr output from validation step
|
|
109
|
+
* @returns Array of extracted failure messages (max 10 per failure type)
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const output = `
|
|
114
|
+
* ā should validate user input
|
|
115
|
+
* src/user.ts(42,10): error TS2345: Argument type mismatch
|
|
116
|
+
* `;
|
|
117
|
+
*
|
|
118
|
+
* const failures = parseFailures(output);
|
|
119
|
+
* // ['ā should validate user input', 'src/user.ts(42,10): error TS2345: ...']
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* @public
|
|
123
|
+
*/
|
|
124
|
+
export function parseFailures(output) {
|
|
125
|
+
const failures = [];
|
|
126
|
+
// Vitest test failures - extract test names
|
|
127
|
+
const vitestFailures = output.match(/ā .+/g);
|
|
128
|
+
if (vitestFailures) {
|
|
129
|
+
failures.push(...vitestFailures.slice(0, 10)); // Limit to first 10
|
|
130
|
+
}
|
|
131
|
+
// TypeScript errors - extract file:line
|
|
132
|
+
const tsErrors = output.match(/[^(]+\(\d+,\d+\): error TS\d+:.+/g);
|
|
133
|
+
if (tsErrors) {
|
|
134
|
+
failures.push(...tsErrors.slice(0, 10).map(e => e.trim()));
|
|
135
|
+
}
|
|
136
|
+
// ESLint errors - extract file:line
|
|
137
|
+
const eslintErrors = output.match(/\S+\.ts\(\d+,\d+\): .+/g);
|
|
138
|
+
if (eslintErrors) {
|
|
139
|
+
failures.push(...eslintErrors.slice(0, 10).map(e => e.trim()));
|
|
140
|
+
}
|
|
141
|
+
return failures;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Run validation steps in parallel with smart fail-fast
|
|
145
|
+
*
|
|
146
|
+
* Executes multiple validation steps concurrently, capturing output and
|
|
147
|
+
* providing fail-fast termination if enabled. Each step runs in its own
|
|
148
|
+
* detached process group for clean termination.
|
|
149
|
+
*
|
|
150
|
+
* @param steps - Array of validation steps to execute in parallel
|
|
151
|
+
* @param phaseName - Human-readable phase name for logging
|
|
152
|
+
* @param enableFailFast - If true, kills remaining processes on first failure
|
|
153
|
+
* @param env - Additional environment variables for child processes
|
|
154
|
+
* @returns Promise resolving to execution results with outputs and step results
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* const result = await runStepsInParallel(
|
|
159
|
+
* [
|
|
160
|
+
* { name: 'TypeScript', command: 'pnpm typecheck' },
|
|
161
|
+
* { name: 'ESLint', command: 'pnpm lint' },
|
|
162
|
+
* ],
|
|
163
|
+
* 'Pre-Qualification',
|
|
164
|
+
* true, // Enable fail-fast
|
|
165
|
+
* { NODE_ENV: 'test' }
|
|
166
|
+
* );
|
|
167
|
+
*
|
|
168
|
+
* if (!result.success) {
|
|
169
|
+
* console.error(`Step ${result.failedStep?.name} failed`);
|
|
170
|
+
* }
|
|
171
|
+
* ```
|
|
172
|
+
*
|
|
173
|
+
* @public
|
|
174
|
+
*/
|
|
175
|
+
export async function runStepsInParallel(steps, phaseName, enableFailFast = false, env = {}) {
|
|
176
|
+
console.log(`\nš Running ${phaseName} (${steps.length} steps in parallel)...`);
|
|
177
|
+
// Find longest step name for alignment
|
|
178
|
+
const maxNameLength = Math.max(...steps.map(s => s.name.length));
|
|
179
|
+
const outputs = new Map();
|
|
180
|
+
const stepResults = [];
|
|
181
|
+
const processes = [];
|
|
182
|
+
let firstFailure = null;
|
|
183
|
+
const results = await Promise.allSettled(steps.map(step => new Promise((resolve, reject) => {
|
|
184
|
+
const paddedName = step.name.padEnd(maxNameLength);
|
|
185
|
+
console.log(` ā³ ${paddedName} ā ${step.command}`);
|
|
186
|
+
const startTime = Date.now();
|
|
187
|
+
const proc = spawn('sh', ['-c', step.command], {
|
|
188
|
+
stdio: 'pipe',
|
|
189
|
+
detached: true, // Create new process group for easier cleanup
|
|
190
|
+
env: {
|
|
191
|
+
...process.env,
|
|
192
|
+
...env,
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
// Track process for potential kill
|
|
196
|
+
processes.push({ proc, step });
|
|
197
|
+
let stdout = '';
|
|
198
|
+
let stderr = '';
|
|
199
|
+
proc.stdout.on('data', data => { stdout += data.toString(); });
|
|
200
|
+
proc.stderr.on('data', data => { stderr += data.toString(); });
|
|
201
|
+
proc.on('close', code => {
|
|
202
|
+
const duration = Date.now() - startTime;
|
|
203
|
+
const output = stdout + stderr;
|
|
204
|
+
outputs.set(step.name, output);
|
|
205
|
+
const durationSec = (duration / 1000).toFixed(1);
|
|
206
|
+
const status = code === 0 ? 'ā
' : 'ā';
|
|
207
|
+
const result = code === 0 ? 'PASSED' : 'FAILED';
|
|
208
|
+
console.log(` ${status} ${step.name.padEnd(maxNameLength)} - ${result} (${durationSec}s)`);
|
|
209
|
+
stepResults.push({ name: step.name, passed: code === 0, duration });
|
|
210
|
+
if (code === 0) {
|
|
211
|
+
resolve({ step, output, duration });
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
// On first failure, kill other processes if fail-fast enabled
|
|
215
|
+
// RACE CONDITION SAFE: While multiple processes could fail simultaneously,
|
|
216
|
+
// JavaScript's single-threaded event loop ensures atomic assignment.
|
|
217
|
+
// Even if multiple failures occur, only one will be firstFailure, which is acceptable.
|
|
218
|
+
if (enableFailFast && !firstFailure) {
|
|
219
|
+
firstFailure = { step, output };
|
|
220
|
+
console.log(`\nā ļø Fail-fast enabled: Killing remaining processes...`);
|
|
221
|
+
// Kill all other running processes
|
|
222
|
+
for (const { proc: otherProc, step: otherStep } of processes) {
|
|
223
|
+
if (otherStep !== step && otherProc.exitCode === null) {
|
|
224
|
+
stopProcessGroup(otherProc, otherStep.name).catch(() => {
|
|
225
|
+
// Process may have already exited, ignore errors
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
reject({ step, output, duration });
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
})));
|
|
234
|
+
// Check for failures
|
|
235
|
+
for (const result of results) {
|
|
236
|
+
if (result.status === 'rejected') {
|
|
237
|
+
const { step } = result.reason;
|
|
238
|
+
return { success: false, failedStep: step, outputs, stepResults };
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return { success: true, outputs, stepResults };
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Validation runner with state tracking and caching
|
|
245
|
+
*
|
|
246
|
+
* Main entry point for running validation with git tree hash-based caching.
|
|
247
|
+
* Executes validation phases sequentially, with parallel step execution within
|
|
248
|
+
* each phase. Supports fail-fast termination and comprehensive state tracking.
|
|
249
|
+
*
|
|
250
|
+
* Features:
|
|
251
|
+
* - Git tree hash-based caching (skip if code unchanged)
|
|
252
|
+
* - Parallel step execution within phases
|
|
253
|
+
* - Fail-fast mode (stop on first failure)
|
|
254
|
+
* - Comprehensive output logging
|
|
255
|
+
* - State file persistence for cache validation
|
|
256
|
+
*
|
|
257
|
+
* @param config - Validation configuration with phases, steps, and options
|
|
258
|
+
* @returns Promise resolving to validation result with pass/fail status
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* const result = await runValidation({
|
|
263
|
+
* phases: [
|
|
264
|
+
* {
|
|
265
|
+
* name: 'Pre-Qualification',
|
|
266
|
+
* parallel: true,
|
|
267
|
+
* steps: [
|
|
268
|
+
* { name: 'TypeScript', command: 'pnpm typecheck' },
|
|
269
|
+
* { name: 'ESLint', command: 'pnpm lint' },
|
|
270
|
+
* ],
|
|
271
|
+
* },
|
|
272
|
+
* ],
|
|
273
|
+
* stateFilePath: '.vibe-validate-state.yaml',
|
|
274
|
+
* enableFailFast: false,
|
|
275
|
+
* forceRun: false,
|
|
276
|
+
* });
|
|
277
|
+
*
|
|
278
|
+
* if (result.passed) {
|
|
279
|
+
* console.log('ā
Validation passed');
|
|
280
|
+
* } else {
|
|
281
|
+
* console.error(`ā Failed at step: ${result.failedStep}`);
|
|
282
|
+
* console.error(result.failedStepOutput);
|
|
283
|
+
* }
|
|
284
|
+
* ```
|
|
285
|
+
*
|
|
286
|
+
* @public
|
|
287
|
+
*/
|
|
288
|
+
export async function runValidation(config) {
|
|
289
|
+
const { phases, stateFilePath = '.validate-state.json', logPath = join(tmpdir(), `validation-${new Date().toISOString().replace(/[:.]/g, '-')}.log`), enableFailFast = false, forceRun = false, env = {}, onPhaseStart, onPhaseComplete, } = config;
|
|
290
|
+
// Get current working tree hash
|
|
291
|
+
const currentTreeHash = getWorkingTreeHash();
|
|
292
|
+
// Check if validation already passed for this exact code state
|
|
293
|
+
if (!forceRun) {
|
|
294
|
+
const { alreadyPassed, previousState } = checkExistingValidation(currentTreeHash, stateFilePath);
|
|
295
|
+
if (alreadyPassed && previousState) {
|
|
296
|
+
console.log('ā
Validation already passed for current working tree state');
|
|
297
|
+
console.log(` Tree hash: ${currentTreeHash.substring(0, 12)}...`);
|
|
298
|
+
console.log(` Last validated: ${previousState.timestamp}`);
|
|
299
|
+
return previousState;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// Initialize log file
|
|
303
|
+
writeFileSync(logPath, `Validation started at ${new Date().toISOString()}\n\n`);
|
|
304
|
+
let failedStep = null;
|
|
305
|
+
const phaseResults = [];
|
|
306
|
+
// Run each phase
|
|
307
|
+
for (const phase of phases) {
|
|
308
|
+
if (onPhaseStart) {
|
|
309
|
+
onPhaseStart(phase);
|
|
310
|
+
}
|
|
311
|
+
const phaseStartTime = Date.now();
|
|
312
|
+
const result = await runStepsInParallel(phase.steps, phase.name, enableFailFast, env);
|
|
313
|
+
const phaseDuration = Date.now() - phaseStartTime;
|
|
314
|
+
// Append all outputs to log file
|
|
315
|
+
for (const [stepName, output] of result.outputs) {
|
|
316
|
+
appendFileSync(logPath, `\n${'='.repeat(60)}\n`);
|
|
317
|
+
appendFileSync(logPath, `${stepName}${result.failedStep?.name === stepName ? ' - FAILED' : ''}\n`);
|
|
318
|
+
appendFileSync(logPath, `${'='.repeat(60)}\n`);
|
|
319
|
+
appendFileSync(logPath, output);
|
|
320
|
+
}
|
|
321
|
+
// Record phase result
|
|
322
|
+
const phaseResult = {
|
|
323
|
+
name: phase.name,
|
|
324
|
+
duration: phaseDuration,
|
|
325
|
+
passed: result.success,
|
|
326
|
+
steps: result.stepResults,
|
|
327
|
+
};
|
|
328
|
+
// If phase failed, include output
|
|
329
|
+
if (!result.success && result.failedStep) {
|
|
330
|
+
phaseResult.output = result.outputs.get(result.failedStep.name);
|
|
331
|
+
}
|
|
332
|
+
phaseResults.push(phaseResult);
|
|
333
|
+
if (onPhaseComplete) {
|
|
334
|
+
onPhaseComplete(phase, phaseResult);
|
|
335
|
+
}
|
|
336
|
+
// If phase failed, stop here
|
|
337
|
+
if (!result.success && result.failedStep) {
|
|
338
|
+
failedStep = result.failedStep;
|
|
339
|
+
const failedOutput = result.outputs.get(failedStep.name) || '';
|
|
340
|
+
const failures = parseFailures(failedOutput);
|
|
341
|
+
const validationResult = {
|
|
342
|
+
passed: false,
|
|
343
|
+
timestamp: new Date().toISOString(),
|
|
344
|
+
treeHash: currentTreeHash,
|
|
345
|
+
phases: phaseResults,
|
|
346
|
+
failedStep: failedStep.name,
|
|
347
|
+
rerunCommand: failedStep.command,
|
|
348
|
+
failedStepOutput: failedOutput,
|
|
349
|
+
failedTests: failures.length > 0 ? failures : undefined,
|
|
350
|
+
fullLogFile: logPath,
|
|
351
|
+
};
|
|
352
|
+
// Write state file
|
|
353
|
+
writeFileSync(stateFilePath, JSON.stringify(validationResult, null, 2));
|
|
354
|
+
return validationResult;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// All steps passed!
|
|
358
|
+
const validationResult = {
|
|
359
|
+
passed: true,
|
|
360
|
+
timestamp: new Date().toISOString(),
|
|
361
|
+
treeHash: currentTreeHash,
|
|
362
|
+
phases: phaseResults,
|
|
363
|
+
fullLogFile: logPath,
|
|
364
|
+
};
|
|
365
|
+
// Write state file
|
|
366
|
+
writeFileSync(stateFilePath, JSON.stringify(validationResult, null, 2));
|
|
367
|
+
return validationResult;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Setup signal handlers for graceful cleanup
|
|
371
|
+
*
|
|
372
|
+
* Registers SIGTERM and SIGINT handlers to ensure all active child processes
|
|
373
|
+
* are properly terminated when the validation runner is interrupted.
|
|
374
|
+
*
|
|
375
|
+
* @param activeProcesses - Set of active child processes to track for cleanup
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```typescript
|
|
379
|
+
* const activeProcesses = new Set<ChildProcess>();
|
|
380
|
+
* setupSignalHandlers(activeProcesses);
|
|
381
|
+
*
|
|
382
|
+
* // When spawning new processes:
|
|
383
|
+
* const proc = spawn('npm', ['test']);
|
|
384
|
+
* activeProcesses.add(proc);
|
|
385
|
+
*
|
|
386
|
+
* // Cleanup is automatic on SIGTERM/SIGINT
|
|
387
|
+
* ```
|
|
388
|
+
*
|
|
389
|
+
* @public
|
|
390
|
+
*/
|
|
391
|
+
export function setupSignalHandlers(activeProcesses) {
|
|
392
|
+
const cleanup = async (signal) => {
|
|
393
|
+
console.log(`\nā ļø Received ${signal}, cleaning up ${activeProcesses.size} active processes...`);
|
|
394
|
+
// Kill all active processes
|
|
395
|
+
const cleanupPromises = Array.from(activeProcesses).map(proc => stopProcessGroup(proc, 'Validation step'));
|
|
396
|
+
await Promise.all(cleanupPromises);
|
|
397
|
+
process.exit(1);
|
|
398
|
+
};
|
|
399
|
+
process.on('SIGTERM', () => cleanup('SIGTERM'));
|
|
400
|
+
process.on('SIGINT', () => cleanup('SIGINT'));
|
|
401
|
+
}
|
|
402
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core validation types for vibe-validate
|
|
3
|
+
*
|
|
4
|
+
* These types define the validation configuration structure and result types.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A single validation step (language-agnostic)
|
|
8
|
+
*/
|
|
9
|
+
export interface ValidationStep {
|
|
10
|
+
/** Human-readable step name */
|
|
11
|
+
name: string;
|
|
12
|
+
/** Command to execute (can be any shell command, not just npm scripts) */
|
|
13
|
+
command: string;
|
|
14
|
+
/** Optional timeout in milliseconds */
|
|
15
|
+
timeout?: number;
|
|
16
|
+
/** Optional environment variables for this step */
|
|
17
|
+
env?: Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A validation phase containing multiple steps
|
|
21
|
+
*/
|
|
22
|
+
export interface ValidationPhase {
|
|
23
|
+
/** Human-readable phase name */
|
|
24
|
+
name: string;
|
|
25
|
+
/** Run steps in parallel? */
|
|
26
|
+
parallel: boolean;
|
|
27
|
+
/** Phase names this phase depends on */
|
|
28
|
+
dependsOn?: string[];
|
|
29
|
+
/** Steps to execute in this phase */
|
|
30
|
+
steps: ValidationStep[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Result from executing a validation step
|
|
34
|
+
*/
|
|
35
|
+
export interface StepResult {
|
|
36
|
+
/** Step name */
|
|
37
|
+
name: string;
|
|
38
|
+
/** Did the step pass? */
|
|
39
|
+
passed: boolean;
|
|
40
|
+
/** Execution duration in milliseconds */
|
|
41
|
+
duration: number;
|
|
42
|
+
/** Output from the step (stdout + stderr) */
|
|
43
|
+
output?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Result from executing a validation phase
|
|
47
|
+
*/
|
|
48
|
+
export interface PhaseResult {
|
|
49
|
+
/** Phase name */
|
|
50
|
+
name: string;
|
|
51
|
+
/** Phase execution duration in milliseconds */
|
|
52
|
+
duration: number;
|
|
53
|
+
/** Did the phase pass? */
|
|
54
|
+
passed: boolean;
|
|
55
|
+
/** Results from individual steps */
|
|
56
|
+
steps: StepResult[];
|
|
57
|
+
/** Output from failed step (if any) */
|
|
58
|
+
output?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Overall validation result
|
|
62
|
+
*/
|
|
63
|
+
export interface ValidationResult {
|
|
64
|
+
/** Did validation pass? */
|
|
65
|
+
passed: boolean;
|
|
66
|
+
/** ISO 8601 timestamp */
|
|
67
|
+
timestamp: string;
|
|
68
|
+
/** Git tree hash (if in git repo) */
|
|
69
|
+
treeHash: string;
|
|
70
|
+
/** Results from each phase */
|
|
71
|
+
phases?: PhaseResult[];
|
|
72
|
+
/** Name of failed step (if any) */
|
|
73
|
+
failedStep?: string;
|
|
74
|
+
/** Command to re-run failed step */
|
|
75
|
+
rerunCommand?: string;
|
|
76
|
+
/** Output from the failed step */
|
|
77
|
+
failedStepOutput?: string;
|
|
78
|
+
/** Failed test names (if applicable) */
|
|
79
|
+
failedTests?: string[];
|
|
80
|
+
/** Path to full log file */
|
|
81
|
+
fullLogFile?: string;
|
|
82
|
+
/** Summary message */
|
|
83
|
+
summary?: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Validation configuration
|
|
87
|
+
*/
|
|
88
|
+
export interface ValidationConfig {
|
|
89
|
+
/** Validation phases to execute */
|
|
90
|
+
phases: ValidationPhase[];
|
|
91
|
+
/** Path to state file (default: .validate-state.json) */
|
|
92
|
+
stateFilePath?: string;
|
|
93
|
+
/** Path to log file (default: os.tmpdir()/validation-{timestamp}.log) */
|
|
94
|
+
logPath?: string;
|
|
95
|
+
/** Enable fail-fast (stop on first failure) */
|
|
96
|
+
enableFailFast?: boolean;
|
|
97
|
+
/** Force re-run even if state says validation already passed */
|
|
98
|
+
forceRun?: boolean;
|
|
99
|
+
/** Environment variables to pass to all child processes */
|
|
100
|
+
env?: Record<string, string>;
|
|
101
|
+
/** Callback when phase starts */
|
|
102
|
+
onPhaseStart?: (_phase: ValidationPhase) => void;
|
|
103
|
+
/** Callback when phase completes */
|
|
104
|
+
onPhaseComplete?: (_phase: ValidationPhase, _result: PhaseResult) => void;
|
|
105
|
+
/** Callback when step starts */
|
|
106
|
+
onStepStart?: (_step: ValidationStep) => void;
|
|
107
|
+
/** Callback when step completes */
|
|
108
|
+
onStepComplete?: (_step: ValidationStep, _result: StepResult) => void;
|
|
109
|
+
/** Caching configuration */
|
|
110
|
+
caching?: {
|
|
111
|
+
/** Enable git tree hash caching */
|
|
112
|
+
enabled: boolean;
|
|
113
|
+
/** Cache strategy */
|
|
114
|
+
strategy: 'git-tree-hash' | 'file-hash' | 'timestamp';
|
|
115
|
+
/** Maximum age of cached results (ms) */
|
|
116
|
+
maxAge?: number;
|
|
117
|
+
};
|
|
118
|
+
/** Output configuration */
|
|
119
|
+
output?: {
|
|
120
|
+
/** Output format */
|
|
121
|
+
format: 'auto' | 'human' | 'yaml' | 'json';
|
|
122
|
+
/** Show verbose output */
|
|
123
|
+
verbose?: boolean;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|