@vibe-validate/extractors 0.17.0-rc3 → 0.17.0

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 (159) hide show
  1. package/dist/extractor-registry.d.ts +103 -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 +254 -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 +345 -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 +278 -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 +353 -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 +169 -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 -13
  118. package/dist/index.d.ts.map +1 -1
  119. package/dist/index.js +27 -13
  120. package/dist/index.js.map +1 -1
  121. package/dist/maven-compiler-extractor.d.ts +20 -0
  122. package/dist/maven-compiler-extractor.d.ts.map +1 -0
  123. package/dist/maven-compiler-extractor.js +218 -0
  124. package/dist/maven-compiler-extractor.js.map +1 -0
  125. package/dist/maven-utils.d.ts +24 -0
  126. package/dist/maven-utils.d.ts.map +1 -0
  127. package/dist/maven-utils.js +36 -0
  128. package/dist/maven-utils.js.map +1 -0
  129. package/dist/plugin-loader.d.ts +82 -0
  130. package/dist/plugin-loader.d.ts.map +1 -0
  131. package/dist/plugin-loader.js +201 -0
  132. package/dist/plugin-loader.js.map +1 -0
  133. package/dist/result-schema.d.ts +59 -9
  134. package/dist/result-schema.d.ts.map +1 -1
  135. package/dist/result-schema.js +3 -19
  136. package/dist/result-schema.js.map +1 -1
  137. package/dist/sandbox.d.ts +161 -0
  138. package/dist/sandbox.d.ts.map +1 -0
  139. package/dist/sandbox.js +254 -0
  140. package/dist/sandbox.js.map +1 -0
  141. package/dist/sandbox.test.d.ts +8 -0
  142. package/dist/sandbox.test.d.ts.map +1 -0
  143. package/dist/sandbox.test.js +395 -0
  144. package/dist/sandbox.test.js.map +1 -0
  145. package/dist/sandboxed-extractor.d.ts +46 -0
  146. package/dist/sandboxed-extractor.d.ts.map +1 -0
  147. package/dist/sandboxed-extractor.js +172 -0
  148. package/dist/sandboxed-extractor.js.map +1 -0
  149. package/dist/sandboxed-extractor.test.d.ts +5 -0
  150. package/dist/sandboxed-extractor.test.d.ts.map +1 -0
  151. package/dist/sandboxed-extractor.test.js +346 -0
  152. package/dist/sandboxed-extractor.test.js.map +1 -0
  153. package/dist/smart-extractor.d.ts +22 -10
  154. package/dist/smart-extractor.d.ts.map +1 -1
  155. package/dist/smart-extractor.js +116 -186
  156. package/dist/smart-extractor.js.map +1 -1
  157. package/dist/types.d.ts +94 -0
  158. package/dist/types.d.ts.map +1 -1
  159. package/package.json +3 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/extractors/playwright/index.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Playwright Error Extractor Plugin Tests
3
+ *
4
+ * @package @vibe-validate/extractors
5
+ */
6
+ import { describe, it, expect } from 'vitest';
7
+ import playwrightPlugin from './index.js';
8
+ describe('playwright extractor plugin', () => {
9
+ describe('detect', () => {
10
+ it('should detect Playwright output with ✘ marker', () => {
11
+ const output = `
12
+ ✘ 1 tests/example.spec.ts:10:5 › should fail (100ms)
13
+ `;
14
+ const result = playwrightPlugin.detect(output);
15
+ expect(result.confidence).toBe(90);
16
+ expect(result.reason).toContain('Playwright');
17
+ });
18
+ it('should detect Playwright output with numbered failures', () => {
19
+ const output = `
20
+ 1) tests/example.spec.ts:10:5 › test name
21
+ `;
22
+ const result = playwrightPlugin.detect(output);
23
+ expect(result.confidence).toBe(90);
24
+ });
25
+ it('should not detect non-Playwright output', () => {
26
+ const output = 'Some random text without Playwright patterns';
27
+ const result = playwrightPlugin.detect(output);
28
+ expect(result.confidence).toBe(0);
29
+ });
30
+ });
31
+ describe('extract', () => {
32
+ describe('Basic Extraction', () => {
33
+ it('should extract single failure', () => {
34
+ const output = `
35
+ Running 1 test using 1 worker
36
+
37
+ ✘ 1 tests/example.spec.ts:10:5 › should fail (100ms)
38
+
39
+
40
+ 1) tests/example.spec.ts:10:5 › should fail
41
+
42
+ Error: expect(received).toBe(expected)
43
+
44
+ Expected: "foo"
45
+ Received: "bar"
46
+
47
+ 10 | test('should fail', async () => {
48
+ 11 | const value = 'bar';
49
+ > 12 | expect(value).toBe('foo');
50
+ | ^
51
+ 13 | });
52
+
53
+ at tests/example.spec.ts:12:21
54
+
55
+ 1 failed
56
+ `;
57
+ const result = playwrightPlugin.extract(output);
58
+ expect(result.errors).toHaveLength(1);
59
+ expect(result.errors[0]).toMatchObject({
60
+ file: 'tests/example.spec.ts',
61
+ line: 12,
62
+ column: 21,
63
+ message: expect.stringContaining('expect(received).toBe(expected)'),
64
+ });
65
+ expect(result.errors[0].guidance).toContain('assertion');
66
+ });
67
+ it('should extract multiple failures', () => {
68
+ const output = `
69
+ Running 3 tests using 1 worker
70
+
71
+ ✘ 1 tests/example.spec.ts:10:5 › first failure (100ms)
72
+ ✘ 2 tests/example.spec.ts:20:5 › second failure (150ms)
73
+ ✘ 3 tests/example.spec.ts:30:5 › third failure (200ms)
74
+
75
+
76
+ 1) tests/example.spec.ts:10:5 › first failure
77
+
78
+ Error: First error
79
+
80
+ at tests/example.spec.ts:12:21
81
+
82
+ 2) tests/example.spec.ts:20:5 › second failure
83
+
84
+ Error: Second error
85
+
86
+ at tests/example.spec.ts:22:21
87
+
88
+ 3) tests/example.spec.ts:30:5 › third failure
89
+
90
+ Error: Third error
91
+
92
+ at tests/example.spec.ts:32:21
93
+
94
+ 3 failed
95
+ `;
96
+ const result = playwrightPlugin.extract(output);
97
+ expect(result.errors).toHaveLength(3);
98
+ expect(result.errors[0].message).toContain('First error');
99
+ expect(result.errors[1].message).toContain('Second error');
100
+ expect(result.errors[2].message).toContain('Third error');
101
+ });
102
+ it('should return empty array when no failures', () => {
103
+ const output = `
104
+ Running 5 tests using 2 workers
105
+
106
+ ✓ tests/example.spec.ts:10:5 › test passes (100ms)
107
+
108
+ 5 passed (1.2s)
109
+ `;
110
+ const result = playwrightPlugin.extract(output);
111
+ expect(result.errors).toHaveLength(0);
112
+ expect(result.metadata.completeness).toBe(100);
113
+ });
114
+ });
115
+ describe('Error Type Detection', () => {
116
+ it('should detect assertion errors', () => {
117
+ const output = `
118
+ 1) tests/test.spec.ts:10:5 › assertion test
119
+
120
+ Error: expect(received).toBe(expected)
121
+
122
+ at tests/test.spec.ts:12:21
123
+ `;
124
+ const result = playwrightPlugin.extract(output);
125
+ expect(result.errors[0].guidance).toContain('assertion');
126
+ });
127
+ it('should detect timeout errors', () => {
128
+ const output = `
129
+ 1) tests/test.spec.ts:10:5 › timeout test
130
+
131
+ Test timeout of 30000ms exceeded.
132
+
133
+ Error: page.click: Test timeout of 30000ms exceeded.
134
+
135
+ at tests/test.spec.ts:12:18
136
+ `;
137
+ const result = playwrightPlugin.extract(output);
138
+ expect(result.errors[0].guidance).toContain('timeout');
139
+ });
140
+ it('should detect element not found errors', () => {
141
+ const output = `
142
+ 1) tests/test.spec.ts:10:5 › element not found
143
+
144
+ Error: page.click: Test timeout of 30000ms exceeded.
145
+ Call log:
146
+ - waiting for locator('#nonexistent')
147
+
148
+ at tests/test.spec.ts:12:18
149
+ `;
150
+ const result = playwrightPlugin.extract(output);
151
+ expect(result.errors[0].guidance).toContain('element');
152
+ });
153
+ it('should detect navigation errors', () => {
154
+ const output = `
155
+ 1) tests/test.spec.ts:10:5 › navigation error
156
+
157
+ Error: page.goto: net::ERR_FILE_NOT_FOUND at file:///nonexistent.html
158
+
159
+ at tests/test.spec.ts:12:18
160
+ `;
161
+ const result = playwrightPlugin.extract(output);
162
+ expect(result.errors[0].guidance).toContain('navigate');
163
+ });
164
+ });
165
+ describe('Location Extraction', () => {
166
+ it('should extract file, line, and column from stack trace', () => {
167
+ const output = `
168
+ 1) tests/deep/nested/test.spec.ts:42:7 › failure
169
+
170
+ Error: Test error
171
+
172
+ at tests/deep/nested/test.spec.ts:45:23
173
+ `;
174
+ const result = playwrightPlugin.extract(output);
175
+ expect(result.errors[0]).toMatchObject({
176
+ file: 'tests/deep/nested/test.spec.ts',
177
+ line: 45,
178
+ column: 23,
179
+ });
180
+ });
181
+ it('should handle absolute paths in error location', () => {
182
+ const output = `
183
+ 1) tests/test.spec.ts:10:5 › failure
184
+
185
+ Error: Test error
186
+
187
+ at /Users/jeff/project/tests/test.spec.ts:12:21
188
+ `;
189
+ const result = playwrightPlugin.extract(output);
190
+ expect(result.errors[0].file).toMatch(/test\.spec\.ts$/);
191
+ expect(result.errors[0].line).toBe(12);
192
+ expect(result.errors[0].column).toBe(21);
193
+ });
194
+ });
195
+ describe('Test Hierarchy', () => {
196
+ it('should preserve test hierarchy from summary line', () => {
197
+ const output = `
198
+ ✘ 1 tests/test.spec.ts:10:5 › Outer Describe › Inner Describe › test name (100ms)
199
+
200
+ 1) tests/test.spec.ts:10:5 › Outer Describe › Inner Describe › test name
201
+
202
+ Error: Test failed
203
+
204
+ at tests/test.spec.ts:12:21
205
+ `;
206
+ const result = playwrightPlugin.extract(output);
207
+ expect(result.errors[0].message).toContain('Outer Describe › Inner Describe › test name');
208
+ });
209
+ });
210
+ describe('Quality Metadata', () => {
211
+ it('should report confidence level', () => {
212
+ const output = `
213
+ 1) tests/test.spec.ts:10:5 › test
214
+
215
+ Error: Test error
216
+
217
+ at tests/test.spec.ts:12:21
218
+ `;
219
+ const result = playwrightPlugin.extract(output);
220
+ expect(result.metadata.confidence).toBeGreaterThan(0);
221
+ expect(result.metadata.confidence).toBeLessThanOrEqual(100);
222
+ });
223
+ it('should report issues when extraction has problems', () => {
224
+ const output = `
225
+ 1) tests/test.spec.ts:10:5 › failure without stack trace
226
+
227
+ Error: Some error message
228
+ Expected: foo
229
+ Received: bar
230
+
231
+ 2) tests/test.spec.ts:20:5 › another failure without stack
232
+
233
+ Error: Another error
234
+ `;
235
+ const result = playwrightPlugin.extract(output);
236
+ // Should extract both failures
237
+ expect(result.errors.length).toBe(2);
238
+ // Should report issues for missing stack traces
239
+ expect(result.metadata.issues).toBeDefined();
240
+ expect(result.metadata.issues.length).toBe(2);
241
+ expect(result.metadata.issues[0]).toContain('No stack trace');
242
+ });
243
+ });
244
+ });
245
+ describe('samples', () => {
246
+ it('should have at least 2 sample test cases', () => {
247
+ expect(playwrightPlugin.samples).toBeDefined();
248
+ expect(playwrightPlugin.samples.length).toBeGreaterThanOrEqual(2);
249
+ });
250
+ it('should successfully parse all sample inputs', () => {
251
+ for (const sample of playwrightPlugin.samples) {
252
+ const result = playwrightPlugin.extract(sample.input);
253
+ expect(result.errors.length).toBeGreaterThan(0);
254
+ expect(result.errors.length).toBe(sample.expectedErrors);
255
+ }
256
+ });
257
+ });
258
+ describe('metadata', () => {
259
+ it('should have complete plugin metadata', () => {
260
+ expect(playwrightPlugin.metadata.name).toBe('playwright');
261
+ expect(playwrightPlugin.metadata.version).toBe('1.0.0');
262
+ expect(playwrightPlugin.metadata.description).toBeTruthy();
263
+ expect(playwrightPlugin.metadata.tags).toContain('playwright');
264
+ });
265
+ it('should have appropriate priority', () => {
266
+ expect(playwrightPlugin.priority).toBe(90);
267
+ });
268
+ it('should have detection hints', () => {
269
+ expect(playwrightPlugin.hints.required).toContain('.spec.ts');
270
+ expect(playwrightPlugin.hints.anyOf).toContain('✘');
271
+ });
272
+ });
273
+ });
274
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/extractors/playwright/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * TAP Error Extractor Plugin
3
+ *
4
+ * Parses TAP (Test Anything Protocol) test output and formats failures for LLM consumption.
5
+ * Supports TAP version 13 and compatible test frameworks (tape, node-tap, etc.)
6
+ *
7
+ * @package @vibe-validate/extractors
8
+ */
9
+ import type { ExtractorPlugin, DetectionResult, ErrorExtractorResult } from '../../types.js';
10
+ /**
11
+ * Detects if output is from TAP protocol
12
+ */
13
+ export declare function detectTAP(output: string): DetectionResult;
14
+ /**
15
+ * Extract errors from TAP test output
16
+ */
17
+ export declare function extractTAP(output: string, _command?: string): ErrorExtractorResult;
18
+ /**
19
+ * TAP Extractor Plugin
20
+ */
21
+ declare const tapExtractor: ExtractorPlugin;
22
+ export default tapExtractor;
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extractors/tap/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,oBAAoB,EAGrB,MAAM,gBAAgB,CAAC;AA2CxB;;GAEG;AAEH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAwDzD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAkGlF;AAmID;;GAEG;AACH,QAAA,MAAM,YAAY,EAAE,eA2DnB,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -0,0 +1,352 @@
1
+ /**
2
+ * TAP Error Extractor Plugin
3
+ *
4
+ * Parses TAP (Test Anything Protocol) test output and formats failures for LLM consumption.
5
+ * Supports TAP version 13 and compatible test frameworks (tape, node-tap, etc.)
6
+ *
7
+ * @package @vibe-validate/extractors
8
+ */
9
+ import { formatCleanOutput } from '../../utils/formatter-utils.js';
10
+ import { generateGuidanceFromPatterns } from '../../utils/guidance-generator.js';
11
+ /**
12
+ * TAP-specific guidance patterns
13
+ * TAP uses detectErrorType() which returns specific keys, so we map those to guidance
14
+ */
15
+ const TAP_GUIDANCE_PATTERNS = [
16
+ {
17
+ key: 'assertion',
18
+ messageMatchers: ['expected', 'should'],
19
+ guidance: 'Review the assertion logic and expected vs actual values',
20
+ },
21
+ {
22
+ key: 'timeout',
23
+ messageMatchers: ['timeout', 'timed out'],
24
+ guidance: 'Increase timeout limit or optimize async operations',
25
+ },
26
+ {
27
+ key: 'file-not-found',
28
+ messageMatchers: ['enoent', 'no such file'],
29
+ guidance: 'Verify file path exists and permissions are correct',
30
+ },
31
+ {
32
+ key: 'type-error',
33
+ messageMatchers: ['cannot read properties', 'typeerror'],
34
+ guidance: 'Check for null/undefined values before accessing properties',
35
+ },
36
+ ];
37
+ /**
38
+ * Detects if output is from TAP protocol
39
+ */
40
+ // eslint-disable-next-line sonarjs/cognitive-complexity -- Complexity 16 acceptable for TAP detection (pattern scoring with multiple marker types)
41
+ export function detectTAP(output) {
42
+ const lines = output.split('\n');
43
+ let score = 0;
44
+ const foundPatterns = [];
45
+ let hasTAPVersion = false;
46
+ let hasNotOk = false;
47
+ let hasYAMLBlock = false;
48
+ let hasTestComment = false;
49
+ for (const line of lines) {
50
+ const trimmed = line.trim();
51
+ // High-value markers (30 points each)
52
+ if (!hasTAPVersion && /^TAP version \d+/.test(trimmed)) {
53
+ score += 30;
54
+ foundPatterns.push('TAP version header');
55
+ hasTAPVersion = true;
56
+ }
57
+ // Medium-value markers (20 points)
58
+ if (!hasNotOk && /^not ok \d+/.test(trimmed)) {
59
+ score += 20;
60
+ foundPatterns.push('not ok N failure marker');
61
+ hasNotOk = true;
62
+ }
63
+ if (!hasYAMLBlock && trimmed === '---') {
64
+ score += 15;
65
+ foundPatterns.push('YAML diagnostic block (---)');
66
+ hasYAMLBlock = true;
67
+ }
68
+ // Low-value markers (10 points)
69
+ if (!hasTestComment && trimmed.startsWith('# ')) {
70
+ score += 10;
71
+ foundPatterns.push('Test comment marker (#)');
72
+ hasTestComment = true;
73
+ }
74
+ }
75
+ // Determine reason based on score
76
+ let reason;
77
+ if (score >= 60) {
78
+ reason = 'TAP protocol output detected';
79
+ }
80
+ else if (score >= 30) {
81
+ reason = 'Possible TAP output';
82
+ }
83
+ else {
84
+ reason = 'Not TAP output';
85
+ }
86
+ return {
87
+ confidence: Math.min(score, 100),
88
+ patterns: foundPatterns,
89
+ reason,
90
+ };
91
+ }
92
+ /**
93
+ * Extract errors from TAP test output
94
+ */
95
+ export function extractTAP(output, _command) {
96
+ const detection = detectTAP(output);
97
+ if (detection.confidence < 30) {
98
+ return {
99
+ summary: 'Not TAP output',
100
+ totalErrors: 0,
101
+ errors: [],
102
+ metadata: {
103
+ detection: {
104
+ extractor: 'tap',
105
+ confidence: detection.confidence,
106
+ patterns: detection.patterns,
107
+ reason: detection.reason,
108
+ },
109
+ confidence: detection.confidence,
110
+ completeness: 100,
111
+ issues: [],
112
+ },
113
+ };
114
+ }
115
+ // Extract all failures
116
+ const failures = extractFailures(output);
117
+ if (failures.length === 0) {
118
+ return {
119
+ summary: '0 test(s) failed',
120
+ errors: [],
121
+ totalErrors: 0,
122
+ errorSummary: '',
123
+ guidance: '',
124
+ metadata: {
125
+ detection: {
126
+ extractor: 'tap',
127
+ confidence: detection.confidence,
128
+ patterns: detection.patterns,
129
+ reason: detection.reason,
130
+ },
131
+ confidence: 100,
132
+ completeness: 100,
133
+ issues: [],
134
+ },
135
+ };
136
+ }
137
+ const errors = [];
138
+ let completeCount = 0;
139
+ for (const failure of failures) {
140
+ const file = failure.file ?? undefined;
141
+ const message = failure.message ?? 'Test failed';
142
+ const context = failure.testName ?? '';
143
+ const isComplete = file && failure.line && message;
144
+ if (isComplete) {
145
+ completeCount++;
146
+ }
147
+ errors.push({
148
+ file,
149
+ line: failure.line,
150
+ message,
151
+ context,
152
+ guidance: failure.guidance,
153
+ });
154
+ }
155
+ // Generate summary
156
+ const summary = `${failures.length} test(s) failed`;
157
+ // Generate guidance using TAP-specific patterns
158
+ const guidance = generateGuidanceFromPatterns(failures, TAP_GUIDANCE_PATTERNS);
159
+ // Calculate quality metadata
160
+ const completeness = failures.length > 0 ? (completeCount / failures.length) * 100 : 100;
161
+ const confidence = failures.length > 0 ? 95 : 100; // High confidence for TAP
162
+ const metadata = {
163
+ detection: {
164
+ extractor: 'tap',
165
+ confidence: detection.confidence,
166
+ patterns: detection.patterns,
167
+ reason: detection.reason,
168
+ },
169
+ confidence,
170
+ completeness,
171
+ issues: [],
172
+ };
173
+ return {
174
+ summary,
175
+ errors,
176
+ totalErrors: failures.length,
177
+ errorSummary: formatCleanOutput(errors),
178
+ guidance,
179
+ metadata,
180
+ };
181
+ }
182
+ /**
183
+ * Extract all failures from TAP output
184
+ */
185
+ // eslint-disable-next-line sonarjs/cognitive-complexity -- Complexity 17 acceptable for TAP output parsing (handles test comments, failure markers, and YAML diagnostic blocks)
186
+ function extractFailures(output) {
187
+ const failures = [];
188
+ const lines = output.split('\n');
189
+ let currentTestName = '';
190
+ let i = 0;
191
+ while (i < lines.length) {
192
+ const line = lines[i];
193
+ // Track test names from comments
194
+ if (line.trim().startsWith('#')) {
195
+ currentTestName = line.trim().substring(1).trim();
196
+ i++;
197
+ continue;
198
+ }
199
+ // Look for failures: "not ok N message"
200
+ // eslint-disable-next-line sonarjs/slow-regex -- Safe: only parses TAP test framework output (controlled output), not user input
201
+ const failureMatch = /^not ok\s+\d+\s+(.+)$/.exec(line);
202
+ if (failureMatch) {
203
+ const message = failureMatch[1].trim();
204
+ const failure = {
205
+ message,
206
+ testName: currentTestName,
207
+ };
208
+ // Look for YAML diagnostic block (starts with " ---")
209
+ if (i + 1 < lines.length && lines[i + 1].trim() === '---') {
210
+ i += 2; // Skip "not ok" line and "---" line
211
+ // Parse YAML block until we hit "..."
212
+ while (i < lines.length && !lines[i].trim().startsWith('...')) {
213
+ const yamlLine = lines[i];
214
+ // Extract location from "at:" field
215
+ // Format: "at: Test.<anonymous> (file:///path/to/file.js:line:col)"
216
+ // or: "at: file.js:line:col"
217
+ // eslint-disable-next-line sonarjs/slow-regex -- Safe: only parses TAP test framework YAML diagnostics (controlled output), not user input
218
+ const atMatch = /^\s+at:\s+(.+)$/.exec(yamlLine);
219
+ if (atMatch) {
220
+ const location = atMatch[1];
221
+ const { file, line } = parseLocation(location);
222
+ if (file)
223
+ failure.file = file;
224
+ if (line)
225
+ failure.line = line;
226
+ }
227
+ i++;
228
+ }
229
+ }
230
+ // Detect error type and add guidance
231
+ const errorType = detectErrorType(message);
232
+ failure.errorType = errorType;
233
+ failure.guidance = getErrorGuidance(errorType);
234
+ failures.push(failure);
235
+ }
236
+ i++;
237
+ }
238
+ return failures;
239
+ }
240
+ /**
241
+ * Parse location string to extract file and line number
242
+ *
243
+ * Handles formats:
244
+ * - Test.<anonymous> (file:///path/to/file.js:28:5)
245
+ * - Test.<anonymous> (./path/to/file.js:28:5)
246
+ * - file.js:28:5
247
+ */
248
+ function parseLocation(location) {
249
+ // Try to extract from parentheses first: (file:///path:line:col) or (path:line:col)
250
+ // eslint-disable-next-line sonarjs/slow-regex -- Safe: only parses TAP test framework location strings (controlled output), not user input
251
+ const parenMatch = /\(([^)]+)\)/.exec(location);
252
+ const pathString = parenMatch ? parenMatch[1] : location;
253
+ // Remove file:// protocol if present
254
+ const cleanPath = pathString.replace(/^file:\/\//, '');
255
+ // Extract file path and line number
256
+ // Format: /path/to/file.js:line:col or path/to/file.js:line:col
257
+ const match = /^(.+):(\d+):\d+$/.exec(cleanPath);
258
+ if (match) {
259
+ return {
260
+ file: match[1],
261
+ line: Number.parseInt(match[2], 10),
262
+ };
263
+ }
264
+ return {};
265
+ }
266
+ /**
267
+ * Detect error type from message
268
+ */
269
+ function detectErrorType(message) {
270
+ const lowerMessage = message.toLowerCase();
271
+ if (lowerMessage.includes('timeout') || lowerMessage.includes('timed out')) {
272
+ return 'timeout';
273
+ }
274
+ if (lowerMessage.includes('enoent') || lowerMessage.includes('no such file')) {
275
+ return 'file-not-found';
276
+ }
277
+ if (lowerMessage.includes('cannot read properties') || lowerMessage.includes('typeerror')) {
278
+ return 'type-error';
279
+ }
280
+ if (lowerMessage.includes('expected') || lowerMessage.includes('should')) {
281
+ return 'assertion';
282
+ }
283
+ return 'unknown';
284
+ }
285
+ /**
286
+ * Get guidance for a specific error type
287
+ */
288
+ function getErrorGuidance(errorType) {
289
+ const pattern = TAP_GUIDANCE_PATTERNS.find((p) => p.key === errorType);
290
+ return pattern?.guidance;
291
+ }
292
+ /**
293
+ * TAP Extractor Plugin
294
+ */
295
+ const tapExtractor = {
296
+ metadata: {
297
+ name: 'tap',
298
+ version: '1.0.0',
299
+ author: 'Jeff Dutton <jeff@duckcreek.com>',
300
+ description: 'Extracts test failures from TAP (Test Anything Protocol) output',
301
+ repository: 'https://github.com/jdutton/vibe-validate',
302
+ tags: ['tap', 'test', 'tape', 'node-tap'],
303
+ },
304
+ hints: {
305
+ anyOf: ['not ok', 'TAP version', '---'],
306
+ },
307
+ priority: 78,
308
+ detect: detectTAP,
309
+ extract: extractTAP,
310
+ samples: [
311
+ {
312
+ name: 'basic-failure',
313
+ description: 'Simple TAP failure with YAML diagnostics',
314
+ // NOSONAR -- /tmp path is part of test fixture sample data, not actual temporary file creation or manipulation
315
+ input: `TAP version 13
316
+ # Test › should pass assertion
317
+ not ok 1 should have 5 errors
318
+ ---
319
+ operator: equal
320
+ expected: 5
321
+ actual: 1
322
+ at: Test.<anonymous> (file:///tmp/test.js:28:5)
323
+ stack: |-
324
+ Error: should have 5 errors
325
+ at Test.assert [as _assert] (/path/to/tape/lib/test.js:492:48)
326
+ at Test.<anonymous> (file:///tmp/test.js:28:5)
327
+ ...
328
+ `,
329
+ expected: {
330
+ totalErrors: 1,
331
+ errors: [
332
+ {
333
+ // eslint-disable-next-line sonarjs/publicly-writable-directories -- /tmp path is part of test fixture sample data, not actual temporary file creation
334
+ file: '/tmp/test.js',
335
+ line: 28,
336
+ message: 'should have 5 errors',
337
+ },
338
+ ],
339
+ },
340
+ },
341
+ {
342
+ name: 'comprehensive-failures',
343
+ description: 'Real TAP comprehensive failure output',
344
+ inputFile: './samples/comprehensive-failures-001.txt',
345
+ expected: {
346
+ totalErrors: 15,
347
+ },
348
+ },
349
+ ],
350
+ };
351
+ export default tapExtractor;
352
+ //# sourceMappingURL=index.js.map