omnirush 0.8.3 → 0.8.4
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.
|
@@ -36,10 +36,11 @@
|
|
|
36
36
|
// signed-in omnirush identities.
|
|
37
37
|
|
|
38
38
|
import { createHash } from "node:crypto";
|
|
39
|
-
import { readdirSync, readFileSync, rmSync } from "node:fs";
|
|
40
|
-
import { readdir,
|
|
39
|
+
import { createReadStream, readdirSync, readFileSync, rmSync } from "node:fs";
|
|
40
|
+
import { readdir, stat } from "node:fs/promises";
|
|
41
41
|
import os from "node:os";
|
|
42
42
|
import path from "node:path";
|
|
43
|
+
import { createInterface } from "node:readline";
|
|
43
44
|
|
|
44
45
|
import { gatewayUrlForOrigin, omniDir, resolveOrigin } from "./auth";
|
|
45
46
|
import { WorkspaceCollector } from "./capture/workspace-collector";
|
|
@@ -50,7 +51,6 @@ import {
|
|
|
50
51
|
engineMessagesFromEntries,
|
|
51
52
|
MAX_TURN_MESSAGE_BYTES,
|
|
52
53
|
messageParts,
|
|
53
|
-
parseSessionFile,
|
|
54
54
|
turnHistory,
|
|
55
55
|
turnModelFromMessages,
|
|
56
56
|
type EngineMessage,
|
|
@@ -158,6 +158,32 @@ async function findSessionFile(sessionId: string, dirs: readonly string[]): Prom
|
|
|
158
158
|
return null;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
/** Parse a session JSONL file without buffering the raw transcript or its line array. */
|
|
162
|
+
export async function parseSessionFileStream(file: string): Promise<{ header: PiEntry | null; entries: PiEntry[] }> {
|
|
163
|
+
let header: PiEntry | null = null;
|
|
164
|
+
const entries: PiEntry[] = [];
|
|
165
|
+
const input = createReadStream(file, { encoding: "utf8" });
|
|
166
|
+
const lines = createInterface({ input, crlfDelay: Infinity });
|
|
167
|
+
try {
|
|
168
|
+
for await (const line of lines) {
|
|
169
|
+
if (!line.trim()) continue;
|
|
170
|
+
let value: unknown;
|
|
171
|
+
try {
|
|
172
|
+
value = JSON.parse(line);
|
|
173
|
+
} catch {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
177
|
+
if ((value as { type?: unknown }).type === "session") header ??= value as PiEntry;
|
|
178
|
+
else entries.push(value as PiEntry);
|
|
179
|
+
}
|
|
180
|
+
} finally {
|
|
181
|
+
lines.close();
|
|
182
|
+
input.destroy();
|
|
183
|
+
}
|
|
184
|
+
return { header, entries };
|
|
185
|
+
}
|
|
186
|
+
|
|
161
187
|
type Collector = Pick<
|
|
162
188
|
WorkspaceCollector,
|
|
163
189
|
"recordTrace" | "recordChildSession" | "childCheckpoints" | "childSessionIds"
|
|
@@ -195,7 +221,7 @@ export async function captureChildSessions(input: {
|
|
|
195
221
|
const stats = await stat(file).catch(() => null);
|
|
196
222
|
const signature = stats ? `${stats.size}:${stats.mtimeMs}` : "";
|
|
197
223
|
if (signature && input.seenFiles.get(child.id) === signature && input.known.has(child.id)) continue;
|
|
198
|
-
const parsed =
|
|
224
|
+
const parsed = await parseSessionFileStream(file).catch(() => ({ header: null, entries: [] }));
|
|
199
225
|
entries = branchOfEntries(parsed.entries);
|
|
200
226
|
cwd = typeof parsed.header?.cwd === "string" ? parsed.header.cwd : "";
|
|
201
227
|
if (signature) input.seenFiles.set(child.id, signature);
|