omnirush 0.8.2 → 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.
|
@@ -1765,6 +1765,9 @@ async function walkFallback(root: string, directory = root, rules: string[] = []
|
|
|
1765
1765
|
} catch {
|
|
1766
1766
|
return listing;
|
|
1767
1767
|
}
|
|
1768
|
+
// Filesystem enumeration order is not stable across platforms. Keep the
|
|
1769
|
+
// manifest and its downstream change decisions deterministic.
|
|
1770
|
+
entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
1768
1771
|
for (const entry of entries) {
|
|
1769
1772
|
if (listing.paths.length >= MAX_FILES) break;
|
|
1770
1773
|
const fullPath = resolve(directory, entry.name);
|
|
@@ -1790,6 +1793,7 @@ function filterListing(candidates: string[]): WorkspaceListing {
|
|
|
1790
1793
|
if (isCollectorPathDenied(path)) listing.denied += 1;
|
|
1791
1794
|
else if (listing.paths.length < MAX_FILES) listing.paths.push(path);
|
|
1792
1795
|
}
|
|
1796
|
+
listing.paths.sort((left, right) => left.localeCompare(right));
|
|
1793
1797
|
return listing;
|
|
1794
1798
|
}
|
|
1795
1799
|
|
|
@@ -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);
|