@vibe-validate/core 0.9.3 → 0.9.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/dist/cli.d.ts ADDED
@@ -0,0 +1,8 @@
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
+ export {};
8
+ //# sourceMappingURL=cli.d.ts.map
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -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"}
@@ -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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"}
@@ -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,7 @@
1
+ /**
2
+ * Core validation types for vibe-validate
3
+ *
4
+ * These types define the validation configuration structure and result types.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-validate/core",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "description": "Core validation orchestration engine for vibe-validate",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",