@vibe-validate/extractors 0.16.1 → 0.17.0-rc.6

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 (163) hide show
  1. package/dist/extractor-registry.d.ts +104 -0
  2. package/dist/extractor-registry.d.ts.map +1 -0
  3. package/dist/extractor-registry.js +278 -0
  4. package/dist/extractor-registry.js.map +1 -0
  5. package/dist/extractors/ava/index.d.ts +23 -0
  6. package/dist/extractors/ava/index.d.ts.map +1 -0
  7. package/dist/extractors/ava/index.js +507 -0
  8. package/dist/extractors/ava/index.js.map +1 -0
  9. package/dist/extractors/ava/index.test.d.ts +7 -0
  10. package/dist/extractors/ava/index.test.d.ts.map +1 -0
  11. package/dist/extractors/ava/index.test.js +408 -0
  12. package/dist/extractors/ava/index.test.js.map +1 -0
  13. package/dist/extractors/eslint/index.d.ts +18 -0
  14. package/dist/extractors/eslint/index.d.ts.map +1 -0
  15. package/dist/extractors/eslint/index.js +206 -0
  16. package/dist/extractors/eslint/index.js.map +1 -0
  17. package/dist/extractors/eslint/index.test.d.ts +9 -0
  18. package/dist/extractors/eslint/index.test.d.ts.map +1 -0
  19. package/dist/extractors/eslint/index.test.js +191 -0
  20. package/dist/extractors/eslint/index.test.js.map +1 -0
  21. package/dist/extractors/generic/index.d.ts +30 -0
  22. package/dist/extractors/generic/index.d.ts.map +1 -0
  23. package/dist/extractors/generic/index.js +140 -0
  24. package/dist/extractors/generic/index.js.map +1 -0
  25. package/dist/extractors/generic/index.test.d.ts +7 -0
  26. package/dist/extractors/generic/index.test.d.ts.map +1 -0
  27. package/dist/extractors/generic/index.test.js +61 -0
  28. package/dist/extractors/generic/index.test.js.map +1 -0
  29. package/dist/extractors/jasmine/index.d.ts +17 -0
  30. package/dist/extractors/jasmine/index.d.ts.map +1 -0
  31. package/dist/extractors/jasmine/index.js +242 -0
  32. package/dist/extractors/jasmine/index.js.map +1 -0
  33. package/dist/extractors/jasmine/index.test.d.ts +7 -0
  34. package/dist/extractors/jasmine/index.test.d.ts.map +1 -0
  35. package/dist/extractors/jasmine/index.test.js +318 -0
  36. package/dist/extractors/jasmine/index.test.js.map +1 -0
  37. package/dist/extractors/jest/index.d.ts +17 -0
  38. package/dist/extractors/jest/index.d.ts.map +1 -0
  39. package/dist/extractors/jest/index.js +273 -0
  40. package/dist/extractors/jest/index.js.map +1 -0
  41. package/dist/extractors/jest/index.test.d.ts +9 -0
  42. package/dist/extractors/jest/index.test.d.ts.map +1 -0
  43. package/dist/extractors/jest/index.test.js +338 -0
  44. package/dist/extractors/jest/index.test.js.map +1 -0
  45. package/dist/extractors/junit/index.d.ts +18 -0
  46. package/dist/extractors/junit/index.d.ts.map +1 -0
  47. package/dist/extractors/junit/index.js +259 -0
  48. package/dist/extractors/junit/index.js.map +1 -0
  49. package/dist/extractors/junit/index.test.d.ts +7 -0
  50. package/dist/extractors/junit/index.test.d.ts.map +1 -0
  51. package/dist/extractors/junit/index.test.js +341 -0
  52. package/dist/extractors/junit/index.test.js.map +1 -0
  53. package/dist/extractors/maven-checkstyle/index.d.ts +23 -0
  54. package/dist/extractors/maven-checkstyle/index.d.ts.map +1 -0
  55. package/dist/extractors/maven-checkstyle/index.js +263 -0
  56. package/dist/extractors/maven-checkstyle/index.js.map +1 -0
  57. package/dist/extractors/maven-checkstyle/index.test.d.ts +2 -0
  58. package/dist/extractors/maven-checkstyle/index.test.d.ts.map +1 -0
  59. package/dist/extractors/maven-checkstyle/index.test.js +197 -0
  60. package/dist/extractors/maven-checkstyle/index.test.js.map +1 -0
  61. package/dist/extractors/maven-compiler/index.d.ts +23 -0
  62. package/dist/extractors/maven-compiler/index.d.ts.map +1 -0
  63. package/dist/extractors/maven-compiler/index.js +271 -0
  64. package/dist/extractors/maven-compiler/index.js.map +1 -0
  65. package/dist/extractors/maven-compiler/index.test.d.ts +2 -0
  66. package/dist/extractors/maven-compiler/index.test.d.ts.map +1 -0
  67. package/dist/extractors/maven-compiler/index.test.js +189 -0
  68. package/dist/extractors/maven-compiler/index.test.js.map +1 -0
  69. package/dist/extractors/maven-surefire/index.d.ts +23 -0
  70. package/dist/extractors/maven-surefire/index.d.ts.map +1 -0
  71. package/dist/extractors/maven-surefire/index.js +292 -0
  72. package/dist/extractors/maven-surefire/index.js.map +1 -0
  73. package/dist/extractors/maven-surefire/index.test.d.ts +2 -0
  74. package/dist/extractors/maven-surefire/index.test.d.ts.map +1 -0
  75. package/dist/extractors/maven-surefire/index.test.js +163 -0
  76. package/dist/extractors/maven-surefire/index.test.js.map +1 -0
  77. package/dist/extractors/mocha/index.d.ts +17 -0
  78. package/dist/extractors/mocha/index.d.ts.map +1 -0
  79. package/dist/extractors/mocha/index.js +241 -0
  80. package/dist/extractors/mocha/index.js.map +1 -0
  81. package/dist/extractors/mocha/index.test.d.ts +7 -0
  82. package/dist/extractors/mocha/index.test.d.ts.map +1 -0
  83. package/dist/extractors/mocha/index.test.js +300 -0
  84. package/dist/extractors/mocha/index.test.js.map +1 -0
  85. package/dist/extractors/playwright/index.d.ts +17 -0
  86. package/dist/extractors/playwright/index.d.ts.map +1 -0
  87. package/dist/extractors/playwright/index.js +320 -0
  88. package/dist/extractors/playwright/index.js.map +1 -0
  89. package/dist/extractors/playwright/index.test.d.ts +7 -0
  90. package/dist/extractors/playwright/index.test.d.ts.map +1 -0
  91. package/dist/extractors/playwright/index.test.js +274 -0
  92. package/dist/extractors/playwright/index.test.js.map +1 -0
  93. package/dist/extractors/tap/index.d.ts +23 -0
  94. package/dist/extractors/tap/index.d.ts.map +1 -0
  95. package/dist/extractors/tap/index.js +352 -0
  96. package/dist/extractors/tap/index.js.map +1 -0
  97. package/dist/extractors/tap/index.test.d.ts +7 -0
  98. package/dist/extractors/tap/index.test.d.ts.map +1 -0
  99. package/dist/extractors/tap/index.test.js +100 -0
  100. package/dist/extractors/tap/index.test.js.map +1 -0
  101. package/dist/extractors/typescript/index.d.ts +17 -0
  102. package/dist/extractors/typescript/index.d.ts.map +1 -0
  103. package/dist/extractors/typescript/index.js +150 -0
  104. package/dist/extractors/typescript/index.js.map +1 -0
  105. package/dist/extractors/typescript/index.test.d.ts +9 -0
  106. package/dist/extractors/typescript/index.test.d.ts.map +1 -0
  107. package/dist/extractors/typescript/index.test.js +177 -0
  108. package/dist/extractors/typescript/index.test.js.map +1 -0
  109. package/dist/extractors/vitest/index.d.ts +17 -0
  110. package/dist/extractors/vitest/index.d.ts.map +1 -0
  111. package/dist/extractors/vitest/index.js +564 -0
  112. package/dist/extractors/vitest/index.js.map +1 -0
  113. package/dist/extractors/vitest/index.test.d.ts +9 -0
  114. package/dist/extractors/vitest/index.test.d.ts.map +1 -0
  115. package/dist/extractors/vitest/index.test.js +373 -0
  116. package/dist/extractors/vitest/index.test.js.map +1 -0
  117. package/dist/index.d.ts +27 -11
  118. package/dist/index.d.ts.map +1 -1
  119. package/dist/index.js +27 -11
  120. package/dist/index.js.map +1 -1
  121. package/dist/maven-checkstyle-extractor.d.ts +20 -0
  122. package/dist/maven-checkstyle-extractor.d.ts.map +1 -0
  123. package/dist/maven-checkstyle-extractor.js +208 -0
  124. package/dist/maven-checkstyle-extractor.js.map +1 -0
  125. package/dist/maven-compiler-extractor.d.ts +20 -0
  126. package/dist/maven-compiler-extractor.d.ts.map +1 -0
  127. package/dist/maven-compiler-extractor.js +218 -0
  128. package/dist/maven-compiler-extractor.js.map +1 -0
  129. package/dist/maven-surefire-extractor.d.ts +20 -0
  130. package/dist/maven-surefire-extractor.d.ts.map +1 -0
  131. package/dist/maven-surefire-extractor.js +228 -0
  132. package/dist/maven-surefire-extractor.js.map +1 -0
  133. package/dist/maven-utils.d.ts +24 -0
  134. package/dist/maven-utils.d.ts.map +1 -0
  135. package/dist/maven-utils.js +36 -0
  136. package/dist/maven-utils.js.map +1 -0
  137. package/dist/plugin-loader.d.ts +82 -0
  138. package/dist/plugin-loader.d.ts.map +1 -0
  139. package/dist/plugin-loader.js +200 -0
  140. package/dist/plugin-loader.js.map +1 -0
  141. package/dist/sandbox.d.ts +161 -0
  142. package/dist/sandbox.d.ts.map +1 -0
  143. package/dist/sandbox.js +254 -0
  144. package/dist/sandbox.js.map +1 -0
  145. package/dist/sandbox.test.d.ts +8 -0
  146. package/dist/sandbox.test.d.ts.map +1 -0
  147. package/dist/sandbox.test.js +395 -0
  148. package/dist/sandbox.test.js.map +1 -0
  149. package/dist/sandboxed-extractor.d.ts +46 -0
  150. package/dist/sandboxed-extractor.d.ts.map +1 -0
  151. package/dist/sandboxed-extractor.js +172 -0
  152. package/dist/sandboxed-extractor.js.map +1 -0
  153. package/dist/sandboxed-extractor.test.d.ts +5 -0
  154. package/dist/sandboxed-extractor.test.d.ts.map +1 -0
  155. package/dist/sandboxed-extractor.test.js +346 -0
  156. package/dist/sandboxed-extractor.test.js.map +1 -0
  157. package/dist/smart-extractor.d.ts +22 -10
  158. package/dist/smart-extractor.d.ts.map +1 -1
  159. package/dist/smart-extractor.js +116 -163
  160. package/dist/smart-extractor.js.map +1 -1
  161. package/dist/types.d.ts +94 -0
  162. package/dist/types.d.ts.map +1 -1
  163. package/package.json +1 -1
@@ -5,15 +5,8 @@
5
5
  *
6
6
  * @package @vibe-validate/extractors
7
7
  */
8
- import { extractTypeScriptErrors } from './typescript-extractor.js';
9
- import { extractESLintErrors } from './eslint-extractor.js';
10
- import { extractVitestErrors } from './vitest-extractor.js';
11
- import { extractJestErrors } from './jest-extractor.js';
12
- import { extractJUnitErrors } from './junit-extractor.js';
13
- import { extractMochaErrors } from './mocha-extractor.js';
14
- import { extractJasmineErrors } from './jasmine-extractor.js';
15
- import { extractPlaywrightErrors } from './playwright-extractor.js';
16
- import { extractGenericErrors } from './generic-extractor.js';
8
+ import { EXTRACTOR_REGISTRY } from './extractor-registry.js';
9
+ import genericPlugin from './extractors/generic/index.js';
17
10
  import { stripAnsiCodes } from './utils.js';
18
11
  /**
19
12
  * Auto-detect tool type from output patterns and extract errors
@@ -21,18 +14,27 @@ import { stripAnsiCodes } from './utils.js';
21
14
  * Detection is 100% pattern-based from output analysis only.
22
15
  * This ensures robust detection regardless of how users name their validation steps.
23
16
  *
17
+ * **Multi-Extractor Fallback Strategy** (new in v0.17.0-rc4):
18
+ * When exitCode != 0 but primary extractor finds 0 errors, tries other extractors
19
+ * until one produces results. This prevents false positives (e.g., Checkstyle
20
+ * detecting compiler errors with 70% confidence but extracting nothing).
21
+ *
24
22
  * Auto-detection rules (checked in order):
25
23
  * 1. **TypeScript**: `error TS####:` pattern (e.g., `error TS2322:`)
26
24
  * 2. **ESLint**: `✖ X problems` summary or `line:col error/warning` format
27
- * 3. **JUnit XML**: `<?xml` + `<testsuite>` tags
28
- * 4. **Jasmine**: `Failures:` header + numbered list (`1) test name`)
29
- * 5. **Jest**: `●` bullets or `Test Suites:` summary (checked before Mocha)
30
- * 6. **Mocha**: `X passing`/`X failing` summary + numbered list
31
- * 7. **Playwright**: `.spec.ts` files + numbered failures with `›` separator
32
- * 8. **Vitest**: `×`/`❯`/`❌` symbols + `Test Files` summary
33
- * 9. **Generic**: Fallback for all other formats
25
+ * 3. **Maven Checkstyle**: Checkstyle plugin markers
26
+ * 4. **Maven Surefire**: Test plugin markers
27
+ * 5. **Maven Compiler**: Compilation error markers
28
+ * 6. **JUnit XML**: `<?xml` + `<testsuite>` tags
29
+ * 7. **Jasmine**: `Failures:` header + numbered list (`1) test name`)
30
+ * 8. **Jest**: `●` bullets or `Test Suites:` summary (checked before Mocha)
31
+ * 9. **Mocha**: `X passing`/`X failing` summary + numbered list
32
+ * 10. **Playwright**: `.spec.ts` files + numbered failures with `›` separator
33
+ * 11. **Vitest**: `×`/`❯`/`❌` symbols + `Test Files` summary
34
+ * 12. **Generic**: Fallback for all other formats
34
35
  *
35
36
  * @param input - Raw command output (string) or separated streams (ExtractorInput)
37
+ * @param exitCode - Optional exit code from command (enables fallback logic)
36
38
  * @returns Structured error information from appropriate extractor
37
39
  *
38
40
  * @example
@@ -40,16 +42,18 @@ import { stripAnsiCodes } from './utils.js';
40
42
  * // Legacy usage (string)
41
43
  * const result1 = autoDetectAndExtract(tscOutput);
42
44
  *
45
+ * // New usage with exit code (enables fallback)
46
+ * const result2 = autoDetectAndExtract(output, 1);
47
+ *
43
48
  * // New usage (separated streams)
44
- * const result2 = autoDetectAndExtract({
49
+ * const result3 = autoDetectAndExtract({
45
50
  * stdout: stdoutString,
46
51
  * stderr: stderrString,
47
52
  * combined: combinedString
48
- * });
53
+ * }, 0);
49
54
  * ```
50
55
  */
51
- // eslint-disable-next-line sonarjs/cognitive-complexity -- Complexity 26 acceptable for smart extractor (sequentially detects 9 different test framework output formats with pattern matching)
52
- export function autoDetectAndExtract(input) {
56
+ export function autoDetectAndExtract(input, exitCode) {
53
57
  // Normalize input to string for backwards compatibility
54
58
  // Most extractors currently use combined output, but this structure
55
59
  // allows future extractors to be stream-specific
@@ -68,155 +72,104 @@ export function autoDetectAndExtract(input) {
68
72
  // - Consistent behavior across all extraction paths
69
73
  // - Easier to maintain and test
70
74
  const errorSummary = stripAnsiCodes(output);
71
- // TypeScript detection: Check for TypeScript compiler error patterns
72
- // - "error TS####:" (error code like TS2322, TS2345)
73
- // - Format: file.ts(line,col): error TS####:
74
- const hasTypeScriptMarkers = /error TS\d+:/.exec(errorSummary);
75
- if (hasTypeScriptMarkers) {
76
- const result = extractTypeScriptErrors(errorSummary);
77
- return addDetectionMetadata(result, 'typescript', 95, ['error TS#### pattern'], 'TypeScript compiler error format detected');
78
- }
79
- // ESLint detection: Check for ESLint-specific patterns
80
- // - "✖ X problem(s)" summary line
81
- // - File paths with line:col followed by error/warning (with optional colon)
82
- const hasESLintMarkers =
83
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Boolean OR for pattern matching, not nullish check
84
- /✖ \d+ problems?/.exec(errorSummary) ||
85
- // eslint-disable-next-line sonarjs/slow-regex -- Safe: only detects ESLint output format (controlled linter output), limited input size
86
- /\d+:\d+:?\s+(error|warning)\s+/.exec(errorSummary);
87
- if (hasESLintMarkers) {
88
- const result = extractESLintErrors(errorSummary);
89
- const patterns = [];
90
- if (/✖ \d+ problems?/.exec(errorSummary))
91
- patterns.push('✖ X problems summary');
92
- // eslint-disable-next-line sonarjs/slow-regex -- Safe: only detects ESLint output format (controlled linter output), limited input size
93
- if (/\d+:\d+:?\s+(error|warning)\s+/.exec(errorSummary))
94
- patterns.push('line:col error/warning format');
95
- return addDetectionMetadata(result, 'eslint', 90, patterns, 'ESLint error format detected');
96
- }
97
- // Vitest priority detection: Check for "RUN v" pattern (100% unique to vitest)
98
- // CRITICAL: Must check BEFORE Jest to prevent false positives
99
- // Jest's loose ● detection can match test names that mention Jest patterns
100
- // (e.g., "should detect Jest from ● bullet marker")
101
- // The "RUN v" pattern at the start of vitest output is unmistakable
102
- // Note: Allow optional leading whitespace (ANSI stripping can leave spaces)
103
- // eslint-disable-next-line sonarjs/slow-regex -- False positive: regex is anchored and has limited repetition
104
- if (/^\s*RUN\s+v\d+\.\d+\.\d+/m.test(errorSummary)) {
105
- const result = extractVitestErrors(errorSummary);
106
- const patterns = ['RUN v#### version header'];
107
- if (errorSummary.includes('×'))
108
- patterns.push('× symbol (U+00D7)');
109
- if (errorSummary.includes('❌'))
110
- patterns.push('❌ cross mark');
111
- if (errorSummary.includes(' ❯ '))
112
- patterns.push('❯ arrow marker');
113
- if (errorSummary.includes('Test Files'))
114
- patterns.push('Test Files summary');
115
- if (errorSummary.includes('.test.ts'))
116
- patterns.push('.test.ts files');
117
- if (/FAIL\s+\d+\s+test\s+(file|case)/i.exec(errorSummary))
118
- patterns.push('FAIL N test files/cases pattern');
119
- return addDetectionMetadata(result, 'vitest', 100, patterns, 'Vitest test output format detected (RUN v#### header)');
120
- }
121
- // Auto-detect JUnit XML format
122
- // Must have both <?xml at start of line AND <testsuite tag (not just mentioned in text)
123
- if (/^<\?xml\s+/m.exec(errorSummary) && errorSummary.includes('<testsuite')) {
124
- const result = extractJUnitErrors(errorSummary);
125
- return addDetectionMetadata(result, 'junit', 100, ['<?xml header', '<testsuite> tag'], 'JUnit XML format detected');
75
+ // NEW: Multi-extractor fallback when exitCode provided
76
+ // This prevents false positives where detector matches but extractor finds nothing
77
+ if (exitCode !== undefined) {
78
+ return autoDetectWithFallback(errorSummary, exitCode);
126
79
  }
127
- // Auto-detect Jasmine format (distinctive "Failures:" header)
128
- if (errorSummary.includes('Failures:') && /^\d+\)\s+/m.exec(errorSummary)) {
129
- const result = extractJasmineErrors(errorSummary);
130
- return addDetectionMetadata(result, 'jasmine', 85, ['Failures: header', 'numbered test list'], 'Jasmine test output format detected');
80
+ // LEGACY: Sequential detection (for backward compatibility when exitCode not provided)
81
+ return sequentialDetection(errorSummary);
82
+ }
83
+ /**
84
+ * Sequential detection (legacy behavior)
85
+ * Returns first extractor that matches with confidence >= 70
86
+ */
87
+ function sequentialDetection(errorSummary) {
88
+ // Try each extractor in the registry in order
89
+ for (const descriptor of EXTRACTOR_REGISTRY) {
90
+ const detection = descriptor.detect(errorSummary);
91
+ // Return first match with confidence >= 70 (legacy threshold)
92
+ if (detection.confidence >= 70) {
93
+ const result = descriptor.extract(errorSummary);
94
+ return addDetectionMetadata(result, descriptor.name, detection.confidence, detection.patterns, detection.reason);
95
+ }
131
96
  }
132
- // Jest detection: Check output for Jest-specific patterns
133
- // CRITICAL: Must check BEFORE Mocha to avoid false positives
134
- // - "●" bullet marker for detailed errors (Jest-specific, Vitest uses ×)
135
- // - "Test Suites:" summary line (Jest-specific, Vitest uses "Test Files")
136
- // Jest patterns are highly distinctive (confidence 90) vs Mocha's generic patterns (confidence 80)
137
- // Mocha's "passing"/"failing" patterns can appear in Jest test names, causing misdetection
138
- const hasJestMarkers = errorSummary.includes('●') ||
139
- errorSummary.includes('Test Suites:');
140
- if (hasJestMarkers) {
141
- const result = extractJestErrors(errorSummary);
142
- const patterns = [];
143
- if (errorSummary.includes('●'))
144
- patterns.push('● bullet marker');
145
- if (errorSummary.includes('Test Suites:'))
146
- patterns.push('Test Suites: summary');
147
- // eslint-disable-next-line sonarjs/slow-regex -- Safe: only detects Jest test framework output format (controlled test framework output), not user input
148
- if (/^\s*FAIL\s+/m.exec(errorSummary))
149
- patterns.push('FAIL marker');
150
- // eslint-disable-next-line sonarjs/slow-regex -- Safe: only detects Jest test framework output format (controlled test framework output), not user input
151
- if (/^\s*PASS\s+/m.exec(errorSummary))
152
- patterns.push('PASS marker');
153
- return addDetectionMetadata(result, 'jest', 90, patterns, 'Jest test output format detected');
97
+ // No specific pattern detected - use generic extractor
98
+ const result = genericPlugin.extract(errorSummary);
99
+ return addDetectionMetadata(result, 'generic', 50, ['no specific patterns'], 'No specific tool detected, using generic extractor');
100
+ }
101
+ /**
102
+ * Multi-extractor fallback strategy (new in v0.17.0-rc4)
103
+ *
104
+ * **RED FLAG HEURISTIC**: When exitCode != 0 but extractor finds 0 errors,
105
+ * this is a strong signal of false positive detection. We try other extractors
106
+ * until we find one that actually extracts errors, or fall back to generic.
107
+ *
108
+ * This solves real-world issues like:
109
+ * - Checkstyle detector matches (70% confidence) on compiler output
110
+ * - But extracts 0 errors (wrong format)
111
+ * - User gets no actionable feedback despite command failure
112
+ *
113
+ * @param errorSummary - ANSI-stripped command output
114
+ * @param exitCode - Command exit code (0 = success, non-zero = failure)
115
+ * @returns Best extraction result based on confidence AND actual error count
116
+ */
117
+ function autoDetectWithFallback(errorSummary, exitCode) {
118
+ const allCandidates = [];
119
+ // Try each extractor in the registry
120
+ // Track which extractors we've already tried (by name) to avoid duplicates
121
+ const triedExtractors = new Set();
122
+ for (const descriptor of EXTRACTOR_REGISTRY) {
123
+ // Skip if we've already tried this extractor name
124
+ if (triedExtractors.has(descriptor.name)) {
125
+ continue;
126
+ }
127
+ const detection = descriptor.detect(errorSummary);
128
+ // Only consider extractors with confidence >= 40
129
+ if (detection.confidence >= 40) {
130
+ triedExtractors.add(descriptor.name);
131
+ const result = descriptor.extract(errorSummary);
132
+ const enrichedResult = addDetectionMetadata(result, descriptor.name, detection.confidence, detection.patterns, detection.reason);
133
+ allCandidates.push({
134
+ name: descriptor.name,
135
+ result: enrichedResult,
136
+ confidence: detection.confidence,
137
+ errorCount: result.totalErrors,
138
+ });
139
+ }
154
140
  }
155
- // Auto-detect Mocha format (distinctive "X passing"/"X failing" pattern)
156
- // NOTE: Checked AFTER Jest because "passing"/"failing" can appear in Jest test names
157
- if ((errorSummary.includes(' passing') || errorSummary.includes(' failing')) &&
158
- // eslint-disable-next-line sonarjs/slow-regex -- Safe: only detects Mocha test framework output format (controlled test framework output), not user input
159
- /\s+\d+\)\s+/.exec(errorSummary)) {
160
- const result = extractMochaErrors(errorSummary);
161
- return addDetectionMetadata(result, 'mocha', 80, ['passing/failing summary', 'numbered failures'], 'Mocha test output format detected');
141
+ // Step 2: Apply RED FLAG HEURISTIC for failed commands
142
+ if (exitCode !== 0 && allCandidates.length > 0) {
143
+ // Prefer extractors that actually found errors
144
+ const withErrors = allCandidates.filter(c => c.errorCount > 0);
145
+ if (withErrors.length > 0) {
146
+ // Pick highest confidence among extractors that found errors
147
+ withErrors.sort((a, b) => b.confidence - a.confidence);
148
+ return withErrors[0].result;
149
+ }
150
+ // RED FLAG: Exit code != 0 but NO extractor found errors
151
+ // Fall back to generic extractor (shows raw output context)
152
+ const result = genericPlugin.extract(errorSummary);
153
+ return addDetectionMetadata(result, 'generic', 50, ['exit code != 0 but no extractor found errors (fallback)'], `Command failed (exit code ${exitCode}) but no extractor found errors. Using generic extractor.`);
162
154
  }
163
- // Playwright detection: Check for Playwright-specific patterns
164
- // - .spec.ts files (Playwright convention, Jest/Vitest use .test.ts)
165
- // - Numbered failures with › separator: "1) file.spec.ts:26:5 › test name"
166
- // - ✘ symbol followed by .spec.ts file path
167
- // IMPORTANT: Require .spec.ts with › separator OR ✘ + .spec.ts (not just mentioned in text)
168
- // Must check BEFORE Vitest to avoid misdetection (.spec.ts vs .test.ts)
169
- const hasPlaywrightMarkers = (errorSummary.includes('.spec.ts') &&
170
- // eslint-disable-next-line sonarjs/slow-regex, @typescript-eslint/prefer-nullish-coalescing -- Safe: only detects Playwright test framework output format (controlled test framework output), not user input. Boolean OR for pattern matching.
171
- (/\d+\)\s+.*\.spec\.ts:\d+:\d+\s+›/.exec(errorSummary) ||
172
- // eslint-disable-next-line sonarjs/slow-regex -- Safe: only detects Playwright test framework output format (controlled test framework output), not user input
173
- /✘.*\.spec\.ts/.exec(errorSummary)));
174
- if (hasPlaywrightMarkers) {
175
- const result = extractPlaywrightErrors(errorSummary);
176
- const patterns = [];
177
- if (errorSummary.includes('.spec.ts'))
178
- patterns.push('.spec.ts files');
179
- // eslint-disable-next-line sonarjs/slow-regex -- Safe: only detects Playwright test framework output format (controlled test framework output), not user input
180
- if (/\d+\)\s+.*\.spec\.ts:\d+:\d+\s+›/.exec(errorSummary))
181
- patterns.push('numbered failures with › separator');
182
- // eslint-disable-next-line sonarjs/slow-regex -- Safe: only detects Playwright test framework output format (controlled test framework output), not user input
183
- if (/✘.*\.spec\.ts/.exec(errorSummary))
184
- patterns.push('✘ failure with .spec.ts file');
185
- return addDetectionMetadata(result, 'playwright', 95, patterns, 'Playwright test output format detected');
155
+ // Step 3: Command succeeded with candidates - use highest confidence
156
+ if (exitCode === 0 && allCandidates.length > 0) {
157
+ allCandidates.sort((a, b) => b.confidence - a.confidence);
158
+ return allCandidates[0].result;
186
159
  }
187
- // Vitest detection: Check output for Vitest-specific patterns
188
- // - "×" symbol (U+00D7 multiplication, Vitest-specific - Jest uses ✕ U+2715)
189
- // - "❌" cross mark symbol (Vitest failure marker in some formats)
190
- // - " ❯ " arrow symbol (Vitest-specific file marker)
191
- // - "Test Files" summary line (Vitest-specific, Jest uses "Test Suites:")
192
- // - "FAIL N test files" pattern (Vitest-specific)
193
- // - ".test.ts" file extension (Vitest convention, Playwright uses .spec.ts)
194
- // NOTE: Both Vitest and Jest use ✓ (check mark), so we don't check for it alone
195
- // IMPORTANT: Require MULTIPLE patterns together to avoid false positives
196
- // (e.g., ❯ can appear in Jest stack traces from source code comments)
197
- const hasVitestMarkers = (errorSummary.includes('×') || errorSummary.includes(' ❯ ') || errorSummary.includes('❌')) &&
198
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Boolean OR for pattern matching, not nullish check
199
- (errorSummary.includes('Test Files') || /FAIL\s+\d+\s+test\s+(file|case)/i.exec(errorSummary) || errorSummary.includes('.test.ts'));
200
- if (hasVitestMarkers) {
201
- const result = extractVitestErrors(errorSummary);
202
- const patterns = [];
203
- if (errorSummary.includes('×'))
204
- patterns.push('× symbol (U+00D7)');
205
- if (errorSummary.includes('❌'))
206
- patterns.push('❌ cross mark');
207
- if (errorSummary.includes(' ❯ '))
208
- patterns.push('❯ arrow marker');
209
- if (errorSummary.includes('Test Files'))
210
- patterns.push('Test Files summary');
211
- if (errorSummary.includes('.test.ts'))
212
- patterns.push('.test.ts files');
213
- if (/FAIL\s+\d+\s+test\s+(file|case)/i.exec(errorSummary))
214
- patterns.push('FAIL N test files/cases pattern');
215
- return addDetectionMetadata(result, 'vitest', 90, patterns, 'Vitest test output format detected');
160
+ // Step 4: No extractors matched at all
161
+ if (allCandidates.length === 0) {
162
+ const result = genericPlugin.extract(errorSummary);
163
+ if (exitCode !== 0) {
164
+ // Command failed but no extractor could parse the output
165
+ return addDetectionMetadata(result, 'generic', 50, ['exit code != 0 but no extractor matched output'], `Command failed (exit code ${exitCode}) but no extractor found errors. Using generic extractor.`);
166
+ }
167
+ // Command succeeded and no extractor needed
168
+ return addDetectionMetadata(result, 'generic', 50, ['no specific patterns'], 'No specific tool detected, using generic extractor');
216
169
  }
217
- // No specific pattern detected - use generic extractor
218
- const result = extractGenericErrors(errorSummary);
219
- return addDetectionMetadata(result, 'generic', 50, ['no specific patterns'], 'No specific tool detected, using generic extractor');
170
+ // Step 5: Have candidates but not handled above - use highest confidence
171
+ allCandidates.sort((a, b) => b.confidence - a.confidence);
172
+ return allCandidates[0].result;
220
173
  }
221
174
  /**
222
175
  * Add detection metadata to extraction result
@@ -1 +1 @@
1
- {"version":3,"file":"smart-extractor.js","sourceRoot":"","sources":["../src/smart-extractor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"smart-extractor.js","sourceRoot":"","sources":["../src/smart-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,aAAa,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAA8B,EAAE,QAAiB;IACpF,wDAAwD;IACxD,oEAAoE;IACpE,iDAAiD;IACjD,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;IAElE,oEAAoE;IACpE,EAAE;IACF,uDAAuD;IACvD,iDAAiD;IACjD,oEAAoE;IACpE,8CAA8C;IAC9C,wEAAwE;IACxE,oEAAoE;IACpE,EAAE;IACF,YAAY;IACZ,uDAAuD;IACvD,oDAAoD;IACpD,gCAAgC;IAChC,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAE5C,uDAAuD;IACvD,mFAAmF;IACnF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,sBAAsB,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACxD,CAAC;IAED,uFAAuF;IACvF,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,YAAoB;IAC/C,8CAA8C;IAC9C,KAAK,MAAM,UAAU,IAAI,kBAAkB,EAAE,CAAC;QAC5C,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAElD,8DAA8D;QAC9D,IAAI,SAAS,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAChD,OAAO,oBAAoB,CACzB,MAAM,EACN,UAAU,CAAC,IAAI,EACf,SAAS,CAAC,UAAU,EACpB,SAAS,CAAC,QAAQ,EAClB,SAAS,CAAC,MAAM,CACjB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACnD,OAAO,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,sBAAsB,CAAC,EAAE,oDAAoD,CAAC,CAAC;AACrI,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAS,sBAAsB,CAAC,YAAoB,EAAE,QAAgB;IASpE,MAAM,aAAa,GAAyB,EAAE,CAAC;IAE/C,qCAAqC;IACrC,2EAA2E;IAC3E,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAE1C,KAAK,MAAM,UAAU,IAAI,kBAAkB,EAAE,CAAC;QAC5C,kDAAkD;QAClD,IAAI,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAElD,iDAAiD;QACjD,IAAI,SAAS,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;YAC/B,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAErC,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAChD,MAAM,cAAc,GAAG,oBAAoB,CACzC,MAAM,EACN,UAAU,CAAC,IAAI,EACf,SAAS,CAAC,UAAU,EACpB,SAAS,CAAC,QAAQ,EAClB,SAAS,CAAC,MAAM,CACjB,CAAC;YAEF,aAAa,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,UAAU,CAAC,IAAI;gBACrB,MAAM,EAAE,cAAc;gBACtB,UAAU,EAAE,SAAS,CAAC,UAAU;gBAChC,UAAU,EAAE,MAAM,CAAC,WAAW;aAC/B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,IAAI,QAAQ,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/C,+CAA+C;QAC/C,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QAE/D,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,6DAA6D;YAC7D,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;YACvD,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9B,CAAC;QAED,yDAAyD;QACzD,4DAA4D;QAC5D,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACnD,OAAO,oBAAoB,CACzB,MAAM,EACN,SAAS,EACT,EAAE,EACF,CAAC,yDAAyD,CAAC,EAC3D,6BAA6B,QAAQ,2DAA2D,CACjG,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,IAAI,QAAQ,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/C,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;QAC1D,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACjC,CAAC;IAED,uCAAuC;IACvC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACnD,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YACnB,yDAAyD;YACzD,OAAO,oBAAoB,CACzB,MAAM,EACN,SAAS,EACT,EAAE,EACF,CAAC,gDAAgD,CAAC,EAClD,6BAA6B,QAAQ,2DAA2D,CACjG,CAAC;QACJ,CAAC;QACD,4CAA4C;QAC5C,OAAO,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,sBAAsB,CAAC,EAAE,oDAAoD,CAAC,CAAC;IACrI,CAAC;IAED,yEAAyE;IACzE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;IAC1D,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACjC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,SAAS,oBAAoB,CAC3B,MAA4B,EAC5B,SAAiB,EACjB,UAAkB,EAClB,QAAkB,EAClB,MAAc;IAEd,0DAA0D;IAC1D,wDAAwD;IACxD,MAAM,CAAC,QAAQ,KAAK;QAChB,UAAU,EAAE,GAAG;QACf,YAAY,EAAE,GAAG;QACjB,MAAM,EAAE,EAAE;KACX,CAAC;IAEJ,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAG;QAC1B,SAAS;QACT,UAAU;QACV,QAAQ;QACR,MAAM;KACP,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/dist/types.d.ts CHANGED
@@ -38,4 +38,98 @@ export interface ErrorExtractor {
38
38
  */
39
39
  format(_output: string): ExtractorResult;
40
40
  }
41
+ /**
42
+ * Detection result from pattern matching
43
+ */
44
+ export interface DetectionResult {
45
+ /** Confidence level (0-100) - higher means more certain */
46
+ confidence: number;
47
+ /** Patterns that matched in the output */
48
+ patterns: string[];
49
+ /** Human-readable explanation of detection */
50
+ reason: string;
51
+ }
52
+ /**
53
+ * Fast filtering hints for efficient multi-extractor detection
54
+ * Uses simple string.includes() checks (no regex) for O(M) single-pass filtering
55
+ */
56
+ export interface ExtractorHints {
57
+ /** Required keywords - all must be present */
58
+ required?: string[];
59
+ /** Any-of keywords - at least one must be present */
60
+ anyOf?: string[];
61
+ /** Forbidden keywords - if present, skip this extractor */
62
+ forbidden?: string[];
63
+ }
64
+ /**
65
+ * Sample test data for extractor validation
66
+ */
67
+ export interface ExtractorSample {
68
+ /** Unique name for this sample */
69
+ name: string;
70
+ /** Human-readable description */
71
+ description: string;
72
+ /** Inline sample data OR */
73
+ input?: string;
74
+ /** Path to sample file (relative to extractor directory) */
75
+ inputFile?: string;
76
+ /** Expected extraction result (partial match) */
77
+ expected?: Partial<ExtractorResult>;
78
+ /** Expected number of errors (simplified validation) */
79
+ expectedErrors?: number;
80
+ /** Expected patterns in output (simplified validation) */
81
+ expectedPatterns?: string[];
82
+ }
83
+ /**
84
+ * Extractor plugin metadata
85
+ */
86
+ export interface ExtractorMetadata {
87
+ /** Unique name identifying this extractor (source of truth for registration) */
88
+ name: string;
89
+ /** Semantic version */
90
+ version: string;
91
+ /** Author name and email */
92
+ author?: string;
93
+ /** Human-readable description */
94
+ description: string;
95
+ /** Repository URL */
96
+ repository?: string;
97
+ /** Tags for discovery and categorization */
98
+ tags?: string[];
99
+ }
100
+ /**
101
+ * Complete extractor plugin interface
102
+ *
103
+ * This is the unified interface for all extractors (built-in and external plugins).
104
+ */
105
+ export interface ExtractorPlugin {
106
+ /** Plugin metadata (source of truth for name/version) */
107
+ metadata: ExtractorMetadata;
108
+ /** Fast filtering hints for efficient detection */
109
+ hints?: ExtractorHints;
110
+ /** Priority for detection order (higher = check first) */
111
+ priority: number;
112
+ /**
113
+ * Detection function - determines if this extractor can handle the output
114
+ * Only called if hints match (or no hints provided)
115
+ *
116
+ * @param _output - Raw command output
117
+ * @returns Detection result with confidence score
118
+ */
119
+ detect(_output: string): DetectionResult;
120
+ /**
121
+ * Extraction function - parses errors from output
122
+ * Only called if detect() returns confidence >= threshold
123
+ *
124
+ * @param _output - Raw command output
125
+ * @param _command - Optional command that produced output (for guidance)
126
+ * @returns Structured error information
127
+ */
128
+ extract(_output: string, _command?: string): ExtractorResult;
129
+ /**
130
+ * Sample test data (REQUIRED for contributions)
131
+ * Used to auto-generate tests and validate extractor functionality
132
+ */
133
+ samples: ExtractorSample[];
134
+ }
41
135
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,oBAAoB,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGlF,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAAC;CAC1C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,oBAAoB,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGlF,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACpC,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,QAAQ,EAAE,iBAAiB,CAAC;IAE5B,mDAAmD;IACnD,KAAK,CAAC,EAAE,cAAc,CAAC;IAEvB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAAC;IAEzC;;;;;;;OAOG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC;IAE7D;;;OAGG;IACH,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-validate/extractors",
3
- "version": "0.16.1",
3
+ "version": "0.17.0-rc.6",
4
4
  "description": "LLM-optimized error extractors for validation output",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",