@vibe-validate/core 0.14.2 → 0.15.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +24 -0
  2. package/dist/index.d.ts +9 -3
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +7 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/output-capture-schema.d.ts +144 -0
  7. package/dist/output-capture-schema.d.ts.map +1 -0
  8. package/dist/output-capture-schema.js +52 -0
  9. package/dist/output-capture-schema.js.map +1 -0
  10. package/dist/process-utils.d.ts +85 -1
  11. package/dist/process-utils.d.ts.map +1 -1
  12. package/dist/process-utils.js +176 -1
  13. package/dist/process-utils.js.map +1 -1
  14. package/dist/result-schema.d.ts +1352 -88
  15. package/dist/result-schema.d.ts.map +1 -1
  16. package/dist/result-schema.js +114 -57
  17. package/dist/result-schema.js.map +1 -1
  18. package/dist/run-output-parser.d.ts +47 -0
  19. package/dist/run-output-parser.d.ts.map +1 -0
  20. package/dist/run-output-parser.js +109 -0
  21. package/dist/run-output-parser.js.map +1 -0
  22. package/dist/runner.d.ts +36 -3
  23. package/dist/runner.d.ts.map +1 -1
  24. package/dist/runner.js +199 -172
  25. package/dist/runner.js.map +1 -1
  26. package/dist/schema-utils.d.ts +57 -0
  27. package/dist/schema-utils.d.ts.map +1 -0
  28. package/dist/schema-utils.js +67 -0
  29. package/dist/schema-utils.js.map +1 -0
  30. package/dist/scripts/generate-result-schema.d.ts +1 -1
  31. package/dist/scripts/generate-result-schema.js +3 -3
  32. package/dist/scripts/generate-result-schema.js.map +1 -1
  33. package/dist/types.js +5 -1
  34. package/dist/types.js.map +1 -1
  35. package/package.json +6 -5
  36. package/validate-result.schema.json +245 -0
  37. package/dist/types.d.ts +0 -138
  38. package/dist/types.d.ts.map +0 -1
  39. package/validation-result.schema.json +0 -100
package/README.md CHANGED
@@ -41,6 +41,30 @@ const result = await runner.run();
41
41
 
42
42
  See [TypeScript types](./src/index.ts) for complete API documentation.
43
43
 
44
+ ## JSON Schema
45
+
46
+ This package publishes `validate-result.schema.json` for IDE autocomplete and validation of validation result files:
47
+
48
+ ```yaml
49
+ # Version-pinned (recommended)
50
+ $schema: https://unpkg.com/@vibe-validate/core@0.15.0/validate-result.schema.json
51
+
52
+ # Latest version
53
+ $schema: https://unpkg.com/@vibe-validate/core/validate-result.schema.json
54
+ ```
55
+
56
+ **Use for:**
57
+ - Validation state files stored in git notes
58
+ - History records (`vibe-validate history show`)
59
+ - Custom validation result processing
60
+
61
+ **Features:**
62
+ - ✅ IDE autocomplete for all ValidationResult properties
63
+ - ✅ Inline validation errors
64
+ - ✅ Type checking for YAML validation results
65
+
66
+ See [Schema Documentation](../../docs/schemas.md) for complete details.
67
+
44
68
  ## License
45
69
 
46
70
  MIT © Jeff Dutton
package/dist/index.d.ts CHANGED
@@ -44,9 +44,15 @@
44
44
  *
45
45
  * @packageDocumentation
46
46
  */
47
- export type { ValidationStep, ValidationPhase, ValidationConfig, ValidationResult, StepResult, PhaseResult, ExtractionQuality, } from './types.js';
47
+ export type { ValidationStep, ValidationPhase, } from '@vibe-validate/config';
48
+ export type { ValidationResult, StepResult, PhaseResult, OutputFiles, } from './result-schema.js';
49
+ export type { ValidationConfig, } from './runner.js';
48
50
  export { runValidation, runStepsInParallel, parseFailures, setupSignalHandlers, } from './runner.js';
49
- export { stopProcessGroup, } from './process-utils.js';
50
- export { ValidationResultSchema, StepResultSchema, PhaseResultSchema, safeValidateResult, validateResult, } from './result-schema.js';
51
+ export { stopProcessGroup, spawnCommand, captureCommandOutput, type CaptureCommandOptions, } from './process-utils.js';
52
+ export { ValidationResultSchema, StepResultSchema, PhaseResultSchema, CommandExecutionSchema, OperationMetadataSchema, OutputFilesSchema, safeValidateResult, validateResult, } from './result-schema.js';
53
+ export { createSafeValidator, createStrictValidator, } from './schema-utils.js';
51
54
  export { validationResultJsonSchema, generateValidationResultJsonSchema, } from './result-schema-export.js';
55
+ export { parseVibeValidateOutput, type ParsedVibeValidateOutput, } from './run-output-parser.js';
56
+ export type { OutputLine, CapturedOutput, } from './output-capture-schema.js';
57
+ export { OutputLineSchema, CapturedOutputSchema, } from './output-capture-schema.js';
52
58
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,0BAA0B,EAC1B,kCAAkC,GACnC,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAGH,YAAY,EACV,cAAc,EACd,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAG/B,YAAY,EACV,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EACV,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,EACpB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,0BAA0B,EAC1B,kCAAkC,GACnC,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,uBAAuB,EACvB,KAAK,wBAAwB,GAC9B,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EACV,UAAU,EACV,cAAc,GACf,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -47,9 +47,14 @@
47
47
  // Export core runner functions
48
48
  export { runValidation, runStepsInParallel, parseFailures, setupSignalHandlers, } from './runner.js';
49
49
  // Export process utilities
50
- export { stopProcessGroup, } from './process-utils.js';
50
+ export { stopProcessGroup, spawnCommand, captureCommandOutput, } from './process-utils.js';
51
51
  // Export validation result schema and validators
52
- export { ValidationResultSchema, StepResultSchema, PhaseResultSchema, safeValidateResult, validateResult, } from './result-schema.js';
52
+ export { ValidationResultSchema, StepResultSchema, PhaseResultSchema, CommandExecutionSchema, OperationMetadataSchema, OutputFilesSchema, safeValidateResult, validateResult, } from './result-schema.js';
53
+ // Export shared schema utilities
54
+ export { createSafeValidator, createStrictValidator, } from './schema-utils.js';
53
55
  // Export JSON Schema generation
54
56
  export { validationResultJsonSchema, generateValidationResultJsonSchema, } from './result-schema-export.js';
57
+ // Export run output parser (shared by run command and phase runner)
58
+ export { parseVibeValidateOutput, } from './run-output-parser.js';
59
+ export { OutputLineSchema, CapturedOutputSchema, } from './output-capture-schema.js';
55
60
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAaH,+BAA+B;AAC/B,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,2BAA2B;AAC3B,OAAO,EACL,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,iDAAiD;AACjD,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAE5B,gCAAgC;AAChC,OAAO,EACL,0BAA0B,EAC1B,kCAAkC,GACnC,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAqBH,+BAA+B;AAC/B,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,2BAA2B;AAC3B,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,GAErB,MAAM,oBAAoB,CAAC;AAE5B,iDAAiD;AACjD,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAE5B,iCAAiC;AACjC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAE3B,gCAAgC;AAChC,OAAO,EACL,0BAA0B,EAC1B,kCAAkC,GACnC,MAAM,2BAA2B,CAAC;AAEnC,oEAAoE;AACpE,OAAO,EACL,uBAAuB,GAExB,MAAM,wBAAwB,CAAC;AAQhC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Output capture schemas for command execution
3
+ *
4
+ * These schemas define the structure for capturing and organizing
5
+ * command output (stdout/stderr) with timestamps and proper separation.
6
+ *
7
+ * All types are derived from Zod schemas (not manual interfaces) to ensure
8
+ * consistency between runtime validation and TypeScript types.
9
+ */
10
+ import { z } from 'zod';
11
+ /**
12
+ * A single line of output with timestamp and stream identification
13
+ */
14
+ export declare const OutputLineSchema: z.ZodObject<{
15
+ /** ISO8601 timestamp: "2025-11-05T17:30:45.123Z" */
16
+ ts: z.ZodString;
17
+ /** Output stream (stdout or stderr) */
18
+ stream: z.ZodEnum<["stdout", "stderr"]>;
19
+ /** Line content (ANSI codes stripped) */
20
+ line: z.ZodString;
21
+ }, "strip", z.ZodTypeAny, {
22
+ ts: string;
23
+ stream: "stdout" | "stderr";
24
+ line: string;
25
+ }, {
26
+ ts: string;
27
+ stream: "stdout" | "stderr";
28
+ line: string;
29
+ }>;
30
+ /**
31
+ * Complete captured output from command execution
32
+ */
33
+ export declare const CapturedOutputSchema: z.ZodObject<{
34
+ /** Standard output */
35
+ stdout: z.ZodObject<{
36
+ /** Raw stdout with ANSI codes */
37
+ raw: z.ZodString;
38
+ /** Path to stdout.log file (omitted if empty) */
39
+ file: z.ZodOptional<z.ZodString>;
40
+ }, "strip", z.ZodTypeAny, {
41
+ raw: string;
42
+ file?: string | undefined;
43
+ }, {
44
+ raw: string;
45
+ file?: string | undefined;
46
+ }>;
47
+ /** Standard error */
48
+ stderr: z.ZodObject<{
49
+ /** Raw stderr with ANSI codes */
50
+ raw: z.ZodString;
51
+ /** Path to stderr.log file (omitted if empty) */
52
+ file: z.ZodOptional<z.ZodString>;
53
+ }, "strip", z.ZodTypeAny, {
54
+ raw: string;
55
+ file?: string | undefined;
56
+ }, {
57
+ raw: string;
58
+ file?: string | undefined;
59
+ }>;
60
+ /** Combined chronological output */
61
+ combined: z.ZodObject<{
62
+ /** Chronologically ordered lines (ANSI-stripped) */
63
+ lines: z.ZodArray<z.ZodObject<{
64
+ /** ISO8601 timestamp: "2025-11-05T17:30:45.123Z" */
65
+ ts: z.ZodString;
66
+ /** Output stream (stdout or stderr) */
67
+ stream: z.ZodEnum<["stdout", "stderr"]>;
68
+ /** Line content (ANSI codes stripped) */
69
+ line: z.ZodString;
70
+ }, "strip", z.ZodTypeAny, {
71
+ ts: string;
72
+ stream: "stdout" | "stderr";
73
+ line: string;
74
+ }, {
75
+ ts: string;
76
+ stream: "stdout" | "stderr";
77
+ line: string;
78
+ }>, "many">;
79
+ /** Path to combined.jsonl file */
80
+ file: z.ZodString;
81
+ }, "strip", z.ZodTypeAny, {
82
+ file: string;
83
+ lines: {
84
+ ts: string;
85
+ stream: "stdout" | "stderr";
86
+ line: string;
87
+ }[];
88
+ }, {
89
+ file: string;
90
+ lines: {
91
+ ts: string;
92
+ stream: "stdout" | "stderr";
93
+ line: string;
94
+ }[];
95
+ }>;
96
+ /** Command exit code */
97
+ exitCode: z.ZodNumber;
98
+ /** Execution duration in seconds */
99
+ durationSecs: z.ZodNumber;
100
+ }, "strip", z.ZodTypeAny, {
101
+ exitCode: number;
102
+ durationSecs: number;
103
+ stdout: {
104
+ raw: string;
105
+ file?: string | undefined;
106
+ };
107
+ stderr: {
108
+ raw: string;
109
+ file?: string | undefined;
110
+ };
111
+ combined: {
112
+ file: string;
113
+ lines: {
114
+ ts: string;
115
+ stream: "stdout" | "stderr";
116
+ line: string;
117
+ }[];
118
+ };
119
+ }, {
120
+ exitCode: number;
121
+ durationSecs: number;
122
+ stdout: {
123
+ raw: string;
124
+ file?: string | undefined;
125
+ };
126
+ stderr: {
127
+ raw: string;
128
+ file?: string | undefined;
129
+ };
130
+ combined: {
131
+ file: string;
132
+ lines: {
133
+ ts: string;
134
+ stream: "stdout" | "stderr";
135
+ line: string;
136
+ }[];
137
+ };
138
+ }>;
139
+ /**
140
+ * TypeScript types derived from Zod schemas
141
+ */
142
+ export type OutputLine = z.infer<typeof OutputLineSchema>;
143
+ export type CapturedOutput = z.infer<typeof CapturedOutputSchema>;
144
+ //# sourceMappingURL=output-capture-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-capture-schema.d.ts","sourceRoot":"","sources":["../src/output-capture-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B,oDAAoD;;IAEpD,uCAAuC;;IAEvC,yCAAyC;;;;;;;;;;EAEzC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,oBAAoB;IAC/B,sBAAsB;;QAEpB,iCAAiC;;QAEjC,iDAAiD;;;;;;;;;IAGnD,qBAAqB;;QAEnB,iCAAiC;;QAEjC,iDAAiD;;;;;;;;;IAGnD,oCAAoC;;QAElC,oDAAoD;;YA5BtD,oDAAoD;;YAEpD,uCAAuC;;YAEvC,yCAAyC;;;;;;;;;;;QA0BvC,kCAAkC;;;;;;;;;;;;;;;;;IAGpC,wBAAwB;;IAExB,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEpC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Output capture schemas for command execution
3
+ *
4
+ * These schemas define the structure for capturing and organizing
5
+ * command output (stdout/stderr) with timestamps and proper separation.
6
+ *
7
+ * All types are derived from Zod schemas (not manual interfaces) to ensure
8
+ * consistency between runtime validation and TypeScript types.
9
+ */
10
+ import { z } from 'zod';
11
+ /**
12
+ * A single line of output with timestamp and stream identification
13
+ */
14
+ export const OutputLineSchema = z.object({
15
+ /** ISO8601 timestamp: "2025-11-05T17:30:45.123Z" */
16
+ ts: z.string(),
17
+ /** Output stream (stdout or stderr) */
18
+ stream: z.enum(['stdout', 'stderr']),
19
+ /** Line content (ANSI codes stripped) */
20
+ line: z.string(),
21
+ });
22
+ /**
23
+ * Complete captured output from command execution
24
+ */
25
+ export const CapturedOutputSchema = z.object({
26
+ /** Standard output */
27
+ stdout: z.object({
28
+ /** Raw stdout with ANSI codes */
29
+ raw: z.string(),
30
+ /** Path to stdout.log file (omitted if empty) */
31
+ file: z.string().optional(),
32
+ }),
33
+ /** Standard error */
34
+ stderr: z.object({
35
+ /** Raw stderr with ANSI codes */
36
+ raw: z.string(),
37
+ /** Path to stderr.log file (omitted if empty) */
38
+ file: z.string().optional(),
39
+ }),
40
+ /** Combined chronological output */
41
+ combined: z.object({
42
+ /** Chronologically ordered lines (ANSI-stripped) */
43
+ lines: z.array(OutputLineSchema),
44
+ /** Path to combined.jsonl file */
45
+ file: z.string(),
46
+ }),
47
+ /** Command exit code */
48
+ exitCode: z.number(),
49
+ /** Execution duration in seconds */
50
+ durationSecs: z.number(),
51
+ });
52
+ //# sourceMappingURL=output-capture-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-capture-schema.js","sourceRoot":"","sources":["../src/output-capture-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,oDAAoD;IACpD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,uCAAuC;IACvC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACpC,yCAAyC;IACzC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,sBAAsB;IACtB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,iCAAiC;QACjC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;QACf,iDAAiD;QACjD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC5B,CAAC;IACF,qBAAqB;IACrB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,iCAAiC;QACjC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;QACf,iDAAiD;QACjD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC5B,CAAC;IACF,oCAAoC;IACpC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;QACjB,oDAAoD;QACpD,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC;QAChC,kCAAkC;QAClC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;KACjB,CAAC;IACF,wBAAwB;IACxB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,oCAAoC;IACpC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;CACzB,CAAC,CAAC"}
@@ -4,7 +4,8 @@
4
4
  * Provides reliable process group cleanup for spawned child processes.
5
5
  * Used by validation runner for signal handling and fail-fast behavior.
6
6
  */
7
- import { ChildProcess } from 'child_process';
7
+ import { ChildProcess } from 'node:child_process';
8
+ import type { CapturedOutput } from './output-capture-schema.js';
8
9
  /**
9
10
  * Stop a child process and its entire process group (cross-platform)
10
11
  *
@@ -29,4 +30,87 @@ import { ChildProcess } from 'child_process';
29
30
  * ```
30
31
  */
31
32
  export declare function stopProcessGroup(childProcess: ChildProcess, processName?: string): Promise<void>;
33
+ /**
34
+ * Spawn a command with consistent, secure defaults for validation
35
+ *
36
+ * **Key Features:**
37
+ * - **No stdin**: Commands cannot block waiting for user input
38
+ * - **Shell mode**: Supports operators (&&, ||, |) and cross-platform compatibility
39
+ * - **Process groups**: Proper cleanup on Unix (detached mode)
40
+ * - **Captured output**: stdout/stderr piped for extraction
41
+ *
42
+ * **Security:**
43
+ * - Commands from user config files only (same trust as npm scripts)
44
+ * - See SECURITY.md for full threat model
45
+ *
46
+ * @param command - Command string to execute (e.g., "npm test", "tsc --noEmit")
47
+ * @param options - Optional spawn configuration
48
+ * @returns ChildProcess instance for monitoring/cleanup
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * // Simple command
53
+ * const proc = spawnCommand('npm test');
54
+ *
55
+ * // With custom environment
56
+ * const proc = spawnCommand('npm run build', {
57
+ * env: { NODE_ENV: 'production' }
58
+ * });
59
+ *
60
+ * // Git command with timeout
61
+ * const proc = spawnCommand('git', {
62
+ * args: ['fetch', 'origin'],
63
+ * timeout: 30000
64
+ * });
65
+ * ```
66
+ */
67
+ export declare function spawnCommand(command: string, options?: {
68
+ /** Command arguments (when command is executable name, not shell string) */
69
+ args?: string[];
70
+ /** Timeout in milliseconds */
71
+ timeout?: number;
72
+ /** Run detached (defaults to true on Unix, false on Windows) */
73
+ detached?: boolean;
74
+ /** Environment variables (merged with process.env) */
75
+ env?: Record<string, string>;
76
+ }): ChildProcess;
77
+ /**
78
+ * Options for capturing command output
79
+ */
80
+ export interface CaptureCommandOptions {
81
+ /** Command to execute */
82
+ command: string;
83
+ /** Output directory for log files */
84
+ outputDir: string;
85
+ /** Command arguments (optional) */
86
+ args?: string[];
87
+ /** Timeout in milliseconds (optional) */
88
+ timeout?: number;
89
+ /** Environment variables (optional) */
90
+ env?: Record<string, string>;
91
+ }
92
+ /**
93
+ * Capture command output with organized file structure
94
+ *
95
+ * Executes a command and captures stdout/stderr with proper separation:
96
+ * - stdout.log: Raw stdout with ANSI codes (omitted if empty)
97
+ * - stderr.log: Raw stderr with ANSI codes (omitted if empty)
98
+ * - combined.jsonl: Chronological output with ANSI codes stripped
99
+ *
100
+ * @param options - Capture options
101
+ * @returns Captured output with file paths
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const output = await captureCommandOutput({
106
+ * command: 'npm test',
107
+ * outputDir: '/tmp/vibe-validate/runs/2025-11-05/abc123-17-30-45'
108
+ * });
109
+ *
110
+ * console.log(output.exitCode); // 0 or 1
111
+ * console.log(output.stdout.file); // Path to stdout.log (if non-empty)
112
+ * console.log(output.combined.file); // Path to combined.jsonl
113
+ * ```
114
+ */
115
+ export declare function captureCommandOutput(options: CaptureCommandOptions): Promise<CapturedOutput>;
32
116
  //# sourceMappingURL=process-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"process-utils.d.ts","sourceRoot":"","sources":["../src/process-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAY,MAAM,eAAe,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,gBAAgB,CACpC,YAAY,EAAE,YAAY,EAC1B,WAAW,GAAE,MAAkB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA+Cf"}
1
+ {"version":3,"file":"process-utils.d.ts","sourceRoot":"","sources":["../src/process-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAmB,MAAM,oBAAoB,CAAC;AAGnE,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,4BAA4B,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,gBAAgB,CACpC,YAAY,EAAE,YAAY,EAC1B,WAAW,GAAE,MAAkB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IACR,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,GACA,YAAY,CAYd;AAcD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,cAAc,CAAC,CA2GzB"}
@@ -4,7 +4,9 @@
4
4
  * Provides reliable process group cleanup for spawned child processes.
5
5
  * Used by validation runner for signal handling and fail-fast behavior.
6
6
  */
7
- import { execSync } from 'child_process';
7
+ import { execSync, spawn } from 'node:child_process';
8
+ import { mkdir, writeFile } from 'node:fs/promises';
9
+ import { join } from 'node:path';
8
10
  /**
9
11
  * Stop a child process and its entire process group (cross-platform)
10
12
  *
@@ -77,4 +79,177 @@ export async function stopProcessGroup(childProcess, processName = 'Process') {
77
79
  }
78
80
  });
79
81
  }
82
+ /**
83
+ * Spawn a command with consistent, secure defaults for validation
84
+ *
85
+ * **Key Features:**
86
+ * - **No stdin**: Commands cannot block waiting for user input
87
+ * - **Shell mode**: Supports operators (&&, ||, |) and cross-platform compatibility
88
+ * - **Process groups**: Proper cleanup on Unix (detached mode)
89
+ * - **Captured output**: stdout/stderr piped for extraction
90
+ *
91
+ * **Security:**
92
+ * - Commands from user config files only (same trust as npm scripts)
93
+ * - See SECURITY.md for full threat model
94
+ *
95
+ * @param command - Command string to execute (e.g., "npm test", "tsc --noEmit")
96
+ * @param options - Optional spawn configuration
97
+ * @returns ChildProcess instance for monitoring/cleanup
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * // Simple command
102
+ * const proc = spawnCommand('npm test');
103
+ *
104
+ * // With custom environment
105
+ * const proc = spawnCommand('npm run build', {
106
+ * env: { NODE_ENV: 'production' }
107
+ * });
108
+ *
109
+ * // Git command with timeout
110
+ * const proc = spawnCommand('git', {
111
+ * args: ['fetch', 'origin'],
112
+ * timeout: 30000
113
+ * });
114
+ * ```
115
+ */
116
+ export function spawnCommand(command, options) {
117
+ // SECURITY: shell: true required for shell operators (&&, ||, |) and cross-platform compatibility.
118
+ // Commands from user config files only (same trust as npm scripts). See SECURITY.md for full threat model.
119
+ // NOSONAR - Intentional shell execution of user-defined commands
120
+ return spawn(command, options?.args ?? [], {
121
+ shell: true,
122
+ stdio: ['ignore', 'pipe', 'pipe'], // No stdin (prevent hangs), capture stdout/stderr
123
+ timeout: options?.timeout,
124
+ // detached: true only on Unix - Windows doesn't pipe stdio correctly when detached
125
+ detached: options?.detached ?? (process.platform !== 'win32'),
126
+ env: options?.env ? { ...process.env, ...options.env } : process.env,
127
+ });
128
+ }
129
+ /**
130
+ * Strip ANSI escape codes from text
131
+ *
132
+ * @param text - Text with ANSI codes
133
+ * @returns Clean text without ANSI codes
134
+ */
135
+ function stripAnsiCodes(text) {
136
+ // Control character \x1b is intentionally used to match ANSI escape codes
137
+ // eslint-disable-next-line no-control-regex, sonarjs/no-control-regex
138
+ return text.replace(/\x1b\[[0-9;]*m/g, '');
139
+ }
140
+ /**
141
+ * Capture command output with organized file structure
142
+ *
143
+ * Executes a command and captures stdout/stderr with proper separation:
144
+ * - stdout.log: Raw stdout with ANSI codes (omitted if empty)
145
+ * - stderr.log: Raw stderr with ANSI codes (omitted if empty)
146
+ * - combined.jsonl: Chronological output with ANSI codes stripped
147
+ *
148
+ * @param options - Capture options
149
+ * @returns Captured output with file paths
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * const output = await captureCommandOutput({
154
+ * command: 'npm test',
155
+ * outputDir: '/tmp/vibe-validate/runs/2025-11-05/abc123-17-30-45'
156
+ * });
157
+ *
158
+ * console.log(output.exitCode); // 0 or 1
159
+ * console.log(output.stdout.file); // Path to stdout.log (if non-empty)
160
+ * console.log(output.combined.file); // Path to combined.jsonl
161
+ * ```
162
+ */
163
+ export async function captureCommandOutput(options) {
164
+ const { command, outputDir, args, timeout, env } = options;
165
+ const startTime = Date.now();
166
+ const combinedLines = [];
167
+ let stdoutRaw = '';
168
+ let stderrRaw = '';
169
+ // Spawn the command
170
+ const proc = spawnCommand(command, { args, timeout, env });
171
+ // Capture stdout
172
+ proc.stdout?.on('data', (data) => {
173
+ const chunk = data.toString();
174
+ stdoutRaw += chunk;
175
+ // Add to combined output (ANSI-stripped)
176
+ const lines = chunk.split('\n');
177
+ for (const line of lines) {
178
+ if (line) {
179
+ combinedLines.push({
180
+ ts: new Date().toISOString(),
181
+ stream: 'stdout',
182
+ line: stripAnsiCodes(line),
183
+ });
184
+ }
185
+ }
186
+ });
187
+ // Capture stderr
188
+ proc.stderr?.on('data', (data) => {
189
+ const chunk = data.toString();
190
+ stderrRaw += chunk;
191
+ // Add to combined output (ANSI-stripped)
192
+ const lines = chunk.split('\n');
193
+ for (const line of lines) {
194
+ if (line) {
195
+ combinedLines.push({
196
+ ts: new Date().toISOString(),
197
+ stream: 'stderr',
198
+ line: stripAnsiCodes(line),
199
+ });
200
+ }
201
+ }
202
+ });
203
+ // Wait for process to complete
204
+ const exitCode = await new Promise((resolve) => {
205
+ proc.on('close', (code) => {
206
+ resolve(code ?? 1);
207
+ });
208
+ proc.on('error', () => {
209
+ resolve(1);
210
+ });
211
+ });
212
+ const endTime = Date.now();
213
+ const durationSecs = (endTime - startTime) / 1000;
214
+ // Ensure output directory exists
215
+ await mkdir(outputDir, { recursive: true });
216
+ // Write output files
217
+ const writePromises = [];
218
+ // Write stdout.log (only if non-empty)
219
+ let stdoutFile;
220
+ if (stdoutRaw.trim()) {
221
+ stdoutFile = join(outputDir, 'stdout.log');
222
+ writePromises.push(writeFile(stdoutFile, stdoutRaw, 'utf-8'));
223
+ }
224
+ // Write stderr.log (only if non-empty)
225
+ let stderrFile;
226
+ if (stderrRaw.trim()) {
227
+ stderrFile = join(outputDir, 'stderr.log');
228
+ writePromises.push(writeFile(stderrFile, stderrRaw, 'utf-8'));
229
+ }
230
+ // Write combined.jsonl (always)
231
+ const combinedFile = join(outputDir, 'combined.jsonl');
232
+ const combinedContent = combinedLines
233
+ .map(line => JSON.stringify(line))
234
+ .join('\n');
235
+ writePromises.push(writeFile(combinedFile, combinedContent, 'utf-8'));
236
+ // Wait for all writes to complete
237
+ await Promise.all(writePromises);
238
+ return {
239
+ stdout: {
240
+ raw: stdoutRaw,
241
+ file: stdoutFile,
242
+ },
243
+ stderr: {
244
+ raw: stderrRaw,
245
+ file: stderrFile,
246
+ },
247
+ combined: {
248
+ lines: combinedLines,
249
+ file: combinedFile,
250
+ },
251
+ exitCode,
252
+ durationSecs,
253
+ };
254
+ }
80
255
  //# sourceMappingURL=process-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"process-utils.js","sourceRoot":"","sources":["../src/process-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAgB,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;GAsBG;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,wCAAwC;YACxC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACjC,kDAAkD;gBAClD,sCAAsC;gBACtC,yCAAyC;gBACzC,IAAI,CAAC;oBACH,QAAQ,CAAC,iBAAiB,GAAG,QAAQ,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC9D,CAAC;gBAAC,MAAM,CAAC;oBACP,4CAA4C;gBAC9C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,6CAA6C;gBAC7C,8CAA8C;gBAC9C,IAAI,CAAC;oBACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAChC,CAAC;gBAAC,MAAM,CAAC;oBACP,4CAA4C;gBAC9C,CAAC;gBAED,gEAAgE;gBAChE,UAAU,CAAC,GAAG,EAAE;oBACd,IAAI,CAAC;wBACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;oBAChC,CAAC;oBAAC,MAAM,CAAC;wBACP,4CAA4C;oBAC9C,CAAC;gBACH,CAAC,EAAE,IAAI,CAAC,CAAC;YACX,CAAC;YAED,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"}
1
+ {"version":3,"file":"process-utils.js","sourceRoot":"","sources":["../src/process-utils.ts"],"names":[],"mappings":"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"}