tewip-ai 0.62.0 → 0.63.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.
- package/dist/reporters/store.js +57 -12
- package/package.json +1 -1
package/dist/reporters/store.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// JSONL persistence shared by the reporter, the history script and future layers.
|
|
2
|
-
import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { openSync, readSync, closeSync, fstatSync, appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
3
3
|
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
4
4
|
export const PROJECT_ROOT = join(import.meta.dirname, '..');
|
|
5
5
|
export const DATA_DIR = join(PROJECT_ROOT, 'data');
|
|
@@ -13,23 +13,68 @@ export function appendJsonl(file, rows) {
|
|
|
13
13
|
mkdirSync(dirname(file), { recursive: true });
|
|
14
14
|
appendFileSync(file, rows.map((row) => JSON.stringify(row)).join('\n') + '\n', 'utf8');
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Reads a JSONL file; missing file yields []. Malformed lines are skipped with a warning.
|
|
18
|
+
*
|
|
19
|
+
* Read in chunks rather than whole. `readFileSync(file, 'utf8')` builds one string, and a string in
|
|
20
|
+
* Node cannot exceed 0x1fffffe8 characters - about 512MB. These files only ever grow: the weekly
|
|
21
|
+
* shadow run appends every CI failure it harvests from a public project and keeps the lot, so that
|
|
22
|
+
* accuracy is measured against everything ever collected rather than one week of it. gutenberg's
|
|
23
|
+
* dataset crossed the limit and **every run since has died on this line**, for weeks, while the
|
|
24
|
+
* workflow's only symptom was a red tick nobody was looking at.
|
|
25
|
+
*
|
|
26
|
+
* A UTF-8 character can straddle a chunk boundary, so the last partial line is carried into the next
|
|
27
|
+
* read rather than decoded on its own - decoding a split character gives U+FFFD and a line that no
|
|
28
|
+
* longer parses.
|
|
29
|
+
*/
|
|
17
30
|
export function readJsonl(file) {
|
|
18
31
|
if (!existsSync(file))
|
|
19
32
|
return [];
|
|
20
33
|
const rows = [];
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
const handle = openSync(file, 'r');
|
|
35
|
+
try {
|
|
36
|
+
const size = fstatSync(handle).size;
|
|
37
|
+
const buffer = Buffer.allocUnsafe(8 * 1024 * 1024);
|
|
38
|
+
let carry = Buffer.alloc(0);
|
|
39
|
+
let line = 0;
|
|
40
|
+
let offset = 0;
|
|
41
|
+
while (offset < size) {
|
|
42
|
+
const read = readSync(handle, buffer, 0, buffer.length, offset);
|
|
43
|
+
if (read <= 0)
|
|
44
|
+
break;
|
|
45
|
+
offset += read;
|
|
46
|
+
const chunk = Buffer.concat([carry, buffer.subarray(0, read)]);
|
|
47
|
+
let from = 0;
|
|
48
|
+
for (let i = 0; i < chunk.length; i += 1) {
|
|
49
|
+
if (chunk[i] !== 0x0a)
|
|
50
|
+
continue;
|
|
51
|
+
const text = chunk.subarray(from, i).toString('utf8').replace(/\r$/, '');
|
|
52
|
+
from = i + 1;
|
|
53
|
+
line += 1;
|
|
54
|
+
if (!text.trim())
|
|
55
|
+
continue;
|
|
56
|
+
try {
|
|
57
|
+
rows.push(JSON.parse(text));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
console.warn(`[triage] skipping malformed line ${line} in ${file}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
carry = chunk.subarray(from);
|
|
28
64
|
}
|
|
29
|
-
|
|
30
|
-
|
|
65
|
+
const last = carry.toString('utf8').replace(/\r$/, '');
|
|
66
|
+
if (last.trim()) {
|
|
67
|
+
try {
|
|
68
|
+
rows.push(JSON.parse(last));
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
console.warn(`[triage] skipping malformed line ${line + 1} in ${file}`);
|
|
72
|
+
}
|
|
31
73
|
}
|
|
32
|
-
}
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
closeSync(handle);
|
|
77
|
+
}
|
|
33
78
|
return rows;
|
|
34
79
|
}
|
|
35
80
|
export const readTriageRecords = (file = TRIAGE_FILE) => readJsonl(file);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tewip-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.0",
|
|
4
4
|
"mcpName": "io.github.hmamut39/tewip",
|
|
5
5
|
"description": "Tewip finds why each failing test failed - real bug, flaky test, environment, test data or changed selector - for any stack, from the command line, CI, or your editor.",
|
|
6
6
|
"keywords": [
|