Skip to content

Commit 0b15245

Browse files
committed
refactor(pi-add-dir): use fs glob for file search
1 parent 70e7c2d commit 0b15245

4 files changed

Lines changed: 29 additions & 26 deletions

File tree

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/pi-add-dir/extensions/add-dir-helpers.ts

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
2-
import { readdir } from "node:fs/promises";
2+
import { glob } from "node:fs/promises";
33
import { homedir } from "node:os";
44
import * as path from "node:path";
55

@@ -146,33 +146,21 @@ export async function findFiles(
146146

147147
const matchPath = normalizedPattern.includes(path.sep);
148148
const results: string[] = [];
149-
const pending = [root];
150149

151150
signal?.throwIfAborted();
152-
while (pending.length > 0) {
151+
for await (const entry of glob("**/@(*|.*)", {
152+
cwd: root,
153+
withFileTypes: true,
154+
exclude: (entry) => entry.isDirectory() && SKIPPED_SEARCH_DIRS.has(entry.name),
155+
})) {
153156
signal?.throwIfAborted();
154-
const current = pending.pop()!;
155-
let entries;
156-
try {
157-
entries = await readdir(current, { withFileTypes: true });
158-
} catch {
159-
continue;
160-
}
157+
if (!entry.isFile()) continue;
161158

162-
for (const entry of entries) {
163-
signal?.throwIfAborted();
164-
const fullPath = path.join(current, entry.name);
165-
if (entry.isDirectory()) {
166-
if (!SKIPPED_SEARCH_DIRS.has(entry.name)) pending.push(fullPath);
167-
continue;
168-
}
169-
if (!entry.isFile()) continue;
170-
171-
const candidate = matchPath ? path.relative(root, fullPath) : entry.name;
172-
if (!path.matchesGlob(candidate, normalizedPattern)) continue;
173-
results.push(fullPath);
174-
if (results.length >= maxResults) return results;
175-
}
159+
const fullPath = path.join(entry.parentPath, entry.name);
160+
const candidate = matchPath ? path.relative(root, fullPath) : entry.name;
161+
if (!path.matchesGlob(candidate, normalizedPattern)) continue;
162+
results.push(fullPath);
163+
if (results.length >= maxResults) return results;
176164
}
177165

178166
return results;

packages/pi-add-dir/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@henryqw/pi-add-dir",
3-
"version": "0.1.10",
3+
"version": "0.1.11",
44
"description": "Add external directories to a Pi session with context, skills, and file search.",
55
"keywords": [
66
"pi-package",

packages/pi-add-dir/test/add-dir.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,21 @@ test("registers external skills without duplicating Pi's skill prompt", async ()
2424
}
2525
});
2626

27+
test("finds files recursively while skipping dependency and Git trees", async () => {
28+
const dir = await mkdtemp(join(tmpdir(), "pi-add-dir-"));
29+
try {
30+
const matches = [join(dir, "src", "main.ts"), join(dir, ".hidden", "config.ts")];
31+
for (const file of [...matches, join(dir, "node_modules", "ignored.ts"), join(dir, ".git", "ignored.ts")]) {
32+
await mkdir(join(file, ".."), { recursive: true });
33+
await writeFile(file, "");
34+
}
35+
36+
assert.deepEqual((await findFiles(dir, "*.ts", 10)).sort(), matches.sort());
37+
} finally {
38+
await rm(dir, { recursive: true, force: true });
39+
}
40+
});
41+
2742
test("returns no results when an external directory disappears", async () => {
2843
const dir = await mkdtemp(join(tmpdir(), "pi-add-dir-"));
2944
await rm(dir, { recursive: true, force: true });

0 commit comments

Comments
 (0)