@siuver/omp-debug-mode 0.1.2 → 0.1.3
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/CHANGELOG.md +9 -0
- package/README.md +30 -14
- package/package.json +1 -1
- package/src/debug-mode.ts +638 -0
- package/src/gate.ts +36 -0
- package/src/log-files.ts +69 -0
- package/src/main.ts +12 -672
- package/src/methodology.ts +140 -0
- package/src/probes.ts +97 -0
- package/src/review-actions.ts +12 -1
- package/src/state.ts +147 -0
- package/src/tools.ts +78 -0
- package/src/ui.ts +78 -0
- package/src/workspace.ts +79 -0
package/src/log-files.ts
CHANGED
|
@@ -24,6 +24,75 @@ export function readJsonlLines(file: string | null): string[] {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
interface CountEntry {
|
|
28
|
+
size: number;
|
|
29
|
+
mtimeMs: number;
|
|
30
|
+
count: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Line counts keyed by file identity. The reproduction gate polls the active
|
|
35
|
+
* log once a second, so re-reading every archived run each time would scale
|
|
36
|
+
* with the length of the debugging session for no new information.
|
|
37
|
+
*/
|
|
38
|
+
export class JsonlLineCounter {
|
|
39
|
+
#cache = new Map<string, CountEntry>();
|
|
40
|
+
|
|
41
|
+
count(file: string | null): number {
|
|
42
|
+
if (!file) return 0;
|
|
43
|
+
const stat = fs.statSync(file, { throwIfNoEntry: false });
|
|
44
|
+
if (!stat) {
|
|
45
|
+
this.#cache.delete(file);
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
const hit = this.#cache.get(file);
|
|
49
|
+
if (hit && hit.size === stat.size && hit.mtimeMs === stat.mtimeMs) return hit.count;
|
|
50
|
+
const count = readJsonlLines(file).length;
|
|
51
|
+
this.#cache.set(file, { size: stat.size, mtimeMs: stat.mtimeMs, count });
|
|
52
|
+
return count;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
clear(): void {
|
|
56
|
+
this.#cache.clear();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface HypothesisTally {
|
|
61
|
+
id: string;
|
|
62
|
+
count: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const UNATTRIBUTED = "(unattributed)";
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Group observations by the hypothesis each probe was meant to settle, so the
|
|
69
|
+
* user and the agent can see which hypotheses actually produced evidence
|
|
70
|
+
* before anyone reads the raw log.
|
|
71
|
+
*/
|
|
72
|
+
export function summarizeHypotheses(lines: readonly string[]): HypothesisTally[] {
|
|
73
|
+
const counts = new Map<string, number>();
|
|
74
|
+
for (const line of lines) {
|
|
75
|
+
let id = UNATTRIBUTED;
|
|
76
|
+
try {
|
|
77
|
+
const entry = JSON.parse(line) as { hypothesisId?: unknown };
|
|
78
|
+
if (typeof entry.hypothesisId === "string" && entry.hypothesisId.trim().length > 0) {
|
|
79
|
+
id = entry.hypothesisId.trim();
|
|
80
|
+
}
|
|
81
|
+
} catch {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
counts.set(id, (counts.get(id) ?? 0) + 1);
|
|
85
|
+
}
|
|
86
|
+
return [...counts]
|
|
87
|
+
.map(([id, count]) => ({ id, count }))
|
|
88
|
+
.sort((a, b) => (b.count !== a.count ? b.count - a.count : a.id < b.id ? -1 : 1));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function describeHypotheses(tallies: readonly HypothesisTally[]): string {
|
|
92
|
+
if (tallies.length === 0) return "no hypothesis-attributed observations";
|
|
93
|
+
return tallies.map(t => `${t.id}=${t.count}`).join(", ");
|
|
94
|
+
}
|
|
95
|
+
|
|
27
96
|
export function prepareRunLog(debugDir: string, previousRun: string | null): string {
|
|
28
97
|
const activeFile = path.join(debugDir, ACTIVE_LOG_FILE);
|
|
29
98
|
const archivedFile = previousRun ? path.join(debugDir, `${previousRun}.jsonl`) : null;
|