perf(rules-injector): cache project root for visited ancestors
findProjectRoot was keyed by exact startPath, so sibling files in the same project repeated the entire upward marker walk. The walk does one existsSync per marker per ancestor directory, which adds up on every read/write/edit/multiedit tool call. Track every directory visited during the walk and seed the cache with the resolved root for each of them. Subsequent lookups for any descendant short-circuit to the cached ancestor without re-running marker probes. Cache invalidation still happens on session.deleted / session.compacted, so production semantics are unchanged. Pin the new contract via a sibling-startpath test, and make the existing finder.test.ts beforeEach explicit about cache state so the more aggressive cache does not leak between tests.
This commit is contained in:
@@ -3,12 +3,14 @@ import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { findProjectRoot, findRuleFiles } from "./finder";
|
||||
import { clearProjectRootCache } from "./project-root-finder";
|
||||
|
||||
describe("findRuleFiles", () => {
|
||||
const TEST_DIR = join(tmpdir(), `rules-injector-test-${Date.now()}`);
|
||||
const homeDir = join(TEST_DIR, "home");
|
||||
|
||||
beforeEach(() => {
|
||||
clearProjectRootCache();
|
||||
mkdirSync(TEST_DIR, { recursive: true });
|
||||
mkdirSync(homeDir, { recursive: true });
|
||||
mkdirSync(join(TEST_DIR, ".git"), { recursive: true });
|
||||
@@ -328,6 +330,7 @@ describe("findProjectRoot", () => {
|
||||
const TEST_DIR = join(tmpdir(), `project-root-test-${Date.now()}`);
|
||||
|
||||
beforeEach(() => {
|
||||
clearProjectRootCache();
|
||||
mkdirSync(TEST_DIR, { recursive: true });
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user