@deathbeam/pi-archive 0.0.1 → 0.0.2
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/README.md +1 -1
- package/index.ts +13 -9
- package/package.json +1 -1
package/README.md
CHANGED
package/index.ts
CHANGED
|
@@ -9,7 +9,6 @@ const MAX_PER_FILE = 3; // max matches per session file
|
|
|
9
9
|
const MAX_SEARCH_LIMIT = 100;
|
|
10
10
|
const READ_CHUNK_BYTES = 64 * 1024;
|
|
11
11
|
const MAX_LINE_BYTES = 16 * 1024 * 1024;
|
|
12
|
-
// ponytail: 16 MiB record ceiling; raise only if real sessions exceed it, or add incremental JSON parsing.
|
|
13
12
|
|
|
14
13
|
export interface ArchiveMatch {
|
|
15
14
|
file: string;
|
|
@@ -194,14 +193,16 @@ export async function searchSessions(
|
|
|
194
193
|
if (terms.length === 0) return { matches: [], bytesScanned: 0, filesScanned: 0, truncated: false };
|
|
195
194
|
const limit = opts.limit ?? 20;
|
|
196
195
|
const filter = opts.sessionFilter?.toLowerCase();
|
|
197
|
-
|
|
198
196
|
const files: { file: string; dir: string; name: string; mtime: number }[] = [];
|
|
199
197
|
let rootEntries: fs.Dirent[];
|
|
200
198
|
try {
|
|
201
199
|
rootEntries = await fs.promises.readdir(root, { withFileTypes: true });
|
|
202
|
-
} catch {
|
|
200
|
+
} catch (err) {
|
|
201
|
+
// A missing archive is normal; other errors must not look like clean misses.
|
|
202
|
+
if ((err as NodeJS.ErrnoException)?.code !== "ENOENT") throw err;
|
|
203
203
|
return { matches: [], bytesScanned: 0, filesScanned: 0, truncated: false };
|
|
204
204
|
}
|
|
205
|
+
let incompleteDiscovery = false;
|
|
205
206
|
for (const entry of rootEntries) {
|
|
206
207
|
if (signal?.aborted) break;
|
|
207
208
|
if (!entry.isDirectory()) continue;
|
|
@@ -211,8 +212,9 @@ export async function searchSessions(
|
|
|
211
212
|
let entries: fs.Dirent[];
|
|
212
213
|
try {
|
|
213
214
|
entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
214
|
-
} catch {
|
|
215
|
-
|
|
215
|
+
} catch (err) {
|
|
216
|
+
if ((err as NodeJS.ErrnoException)?.code !== "ENOENT") incompleteDiscovery = true;
|
|
217
|
+
continue;
|
|
216
218
|
}
|
|
217
219
|
for (const fileEntry of entries) {
|
|
218
220
|
if (signal?.aborted) break;
|
|
@@ -220,7 +222,9 @@ export async function searchSessions(
|
|
|
220
222
|
const file = path.join(dir, fileEntry.name);
|
|
221
223
|
try {
|
|
222
224
|
files.push({ file, dir: dirName, name: fileEntry.name, mtime: (await fs.promises.stat(file)).mtimeMs });
|
|
223
|
-
} catch {
|
|
225
|
+
} catch (err) {
|
|
226
|
+
if ((err as NodeJS.ErrnoException)?.code !== "ENOENT") incompleteDiscovery = true;
|
|
227
|
+
}
|
|
224
228
|
}
|
|
225
229
|
}
|
|
226
230
|
if (signal?.aborted) return { matches: [], bytesScanned: 0, filesScanned: 0, truncated: true };
|
|
@@ -233,7 +237,7 @@ export async function searchSessions(
|
|
|
233
237
|
const matches: ArchiveMatch[] = [];
|
|
234
238
|
let bytes = 0;
|
|
235
239
|
let filesScanned = 0;
|
|
236
|
-
let truncated =
|
|
240
|
+
let truncated = incompleteDiscovery;
|
|
237
241
|
for (const { file, dir, name } of files) {
|
|
238
242
|
if (signal?.aborted || bytes >= MAX_TOTAL_BYTES) {
|
|
239
243
|
truncated = true;
|
|
@@ -309,7 +313,7 @@ export function recentSessions(
|
|
|
309
313
|
}
|
|
310
314
|
|
|
311
315
|
export function formatResults(query: string, result: Awaited<ReturnType<typeof searchSessions>>): string {
|
|
312
|
-
const note = result.truncated ? "\n(Search incomplete; narrow
|
|
316
|
+
const note = result.truncated ? "\n(Search incomplete; narrow the search or check archive access.)" : "";
|
|
313
317
|
if (result.matches.length === 0) {
|
|
314
318
|
return `No matches for "${query}" in ${result.filesScanned} scanned session files.${note}`;
|
|
315
319
|
}
|
|
@@ -317,7 +321,7 @@ export function formatResults(query: string, result: Awaited<ReturnType<typeof s
|
|
|
317
321
|
(m) =>
|
|
318
322
|
`${m.file}\n[${m.currentSession ? "this session" : m.sameProject ? "this project" : m.project} | ${m.date} | ${m.role}] ${m.excerpt.replace(/\s+/g, " ")}`,
|
|
319
323
|
);
|
|
320
|
-
return `Found ${result.matches.length} match(es) for "${query}" —
|
|
324
|
+
return `Found ${result.matches.length} match(es) for "${query}" — at most ${MAX_PER_FILE} per session file (read or grep the file for more):\n\n${lines.join("\n\n")}${note}`;
|
|
321
325
|
}
|
|
322
326
|
|
|
323
327
|
export default async function piArchive(pi: ExtensionAPI) {
|