fix(sf): isolate sift warmup cache per project
This commit is contained in:
parent
f21890addb
commit
c4ac851187
2 changed files with 65 additions and 6 deletions
|
|
@ -144,6 +144,29 @@ const DEFAULT_SIFT_WARMUP_RETRIEVER_TIMEOUT_MS = 30_000;
|
|||
const DEFAULT_SIFT_WARMUP_HARD_TIMEOUT_SEC = 30;
|
||||
const SIFT_WARMUP_KILL_GRACE_SEC = 10;
|
||||
|
||||
function resolveSiftWarmupRuntimeDirs(projectRoot: string): {
|
||||
cacheHome: string;
|
||||
tmpDir: string;
|
||||
} {
|
||||
const runtimeRoot = join(projectRoot, ".sf", "runtime", "sift");
|
||||
return {
|
||||
cacheHome: join(runtimeRoot, "xdg-cache"),
|
||||
tmpDir: join(runtimeRoot, "tmp"),
|
||||
};
|
||||
}
|
||||
|
||||
function buildSiftWarmupEnv(
|
||||
projectRoot: string,
|
||||
env: NodeJS.ProcessEnv,
|
||||
): NodeJS.ProcessEnv {
|
||||
const dirs = resolveSiftWarmupRuntimeDirs(projectRoot);
|
||||
return {
|
||||
...env,
|
||||
XDG_CACHE_HOME: dirs.cacheHome,
|
||||
TMPDIR: dirs.tmpDir,
|
||||
};
|
||||
}
|
||||
|
||||
function readJsonConfig(configPath: string): McpConfigFile {
|
||||
if (!existsSync(configPath)) return {};
|
||||
const raw = readFileSync(configPath, "utf-8");
|
||||
|
|
@ -488,7 +511,11 @@ export function ensureSiftIndexWarmup(
|
|||
: "sift page-index-hybrid warmup started (no timeout(1)/gtimeout on PATH; running unbounded)";
|
||||
|
||||
try {
|
||||
const runtimeDirs = resolveSiftWarmupRuntimeDirs(projectRoot);
|
||||
mkdirSync(join(projectRoot, ".sf", "runtime"), { recursive: true });
|
||||
mkdirSync(runtimeDirs.cacheHome, { recursive: true });
|
||||
mkdirSync(runtimeDirs.tmpDir, { recursive: true });
|
||||
const childEnv = buildSiftWarmupEnv(projectRoot, env);
|
||||
writeFileSync(
|
||||
markerPath,
|
||||
`${JSON.stringify(
|
||||
|
|
@ -500,6 +527,8 @@ export function ensureSiftIndexWarmup(
|
|||
args,
|
||||
siftBinary: detection.binaryPath,
|
||||
hardTimeoutSec: wrapper?.timeoutSec ?? null,
|
||||
cacheHome: runtimeDirs.cacheHome,
|
||||
tmpDir: runtimeDirs.tmpDir,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
|
|
@ -509,7 +538,7 @@ export function ensureSiftIndexWarmup(
|
|||
|
||||
const child = (options.spawnFn ?? spawn)(command, args, {
|
||||
cwd: projectRoot,
|
||||
env,
|
||||
env: childEnv,
|
||||
stdio: "ignore",
|
||||
detached: true,
|
||||
});
|
||||
|
|
@ -791,7 +820,7 @@ function buildSiftContextLines(
|
|||
'`--strategy path-hybrid` for path-heavy queries, and `sift search <path> --agent "<task>"` for bounded planner-driven exploration.',
|
||||
);
|
||||
lines.push(
|
||||
"- Sift uses a sector-aware cache in the platform cache directory, typically `~/.cache/sift`; " +
|
||||
"- SF runs Sift warmup with project-scoped cache/temp directories under `.sf/runtime/sift/`; " +
|
||||
"if the CLI is missing or fails, continue with `.sf/CODEBASE.md`, native `grep`/`find`/`ls`, `lsp`, and scout.",
|
||||
);
|
||||
} else {
|
||||
|
|
@ -960,7 +989,7 @@ export function formatSiftStatus(
|
|||
'When configured, agents should use `sift search --json <path> "<query>"`; `page-index-hybrid` is the strongest direct-search preset and `path-hybrid` is best for path-heavy queries.',
|
||||
);
|
||||
lines.push(
|
||||
"Sift reuses a sector-aware cache in the platform cache directory, typically ~/.cache/sift.",
|
||||
"SF runs Sift warmup with project-scoped cache/temp directories under .sf/runtime/sift/.",
|
||||
);
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -499,9 +499,17 @@ test("ensureSiftIndexWarmup defaults optional warmup hard cap to 30 seconds", ()
|
|||
const fakeTimeout = join(projectRoot, "bin", "timeout");
|
||||
writeFileSync(fakeTimeout, "", "utf-8");
|
||||
|
||||
const calls: Array<{ command: string; args: string[] }> = [];
|
||||
const fakeSpawn = ((command: string, args: string[]) => {
|
||||
calls.push({ command, args });
|
||||
const calls: Array<{
|
||||
command: string;
|
||||
args: string[];
|
||||
options?: { env?: NodeJS.ProcessEnv };
|
||||
}> = [];
|
||||
const fakeSpawn = ((command: string, args: string[], options?: unknown) => {
|
||||
calls.push({
|
||||
command,
|
||||
args,
|
||||
options: options as { env?: NodeJS.ProcessEnv },
|
||||
});
|
||||
return { unref() {} };
|
||||
}) as unknown as typeof import("node:child_process").spawn;
|
||||
|
||||
|
|
@ -520,6 +528,28 @@ test("ensureSiftIndexWarmup defaults optional warmup hard cap to 30 seconds", ()
|
|||
fakeSift,
|
||||
]);
|
||||
assert.match(result.reason, /hard cap 30s/);
|
||||
assert.equal(
|
||||
calls[0].options?.env?.XDG_CACHE_HOME,
|
||||
join(projectRoot, ".sf", "runtime", "sift", "xdg-cache"),
|
||||
);
|
||||
assert.equal(
|
||||
calls[0].options?.env?.TMPDIR,
|
||||
join(projectRoot, ".sf", "runtime", "sift", "tmp"),
|
||||
);
|
||||
const marker = JSON.parse(
|
||||
readFileSync(
|
||||
join(projectRoot, ".sf", "runtime", "sift-index-warmup.json"),
|
||||
"utf-8",
|
||||
),
|
||||
);
|
||||
assert.equal(
|
||||
marker.cacheHome,
|
||||
join(projectRoot, ".sf", "runtime", "sift", "xdg-cache"),
|
||||
);
|
||||
assert.equal(
|
||||
marker.tmpDir,
|
||||
join(projectRoot, ".sf", "runtime", "sift", "tmp"),
|
||||
);
|
||||
} finally {
|
||||
cleanup(projectRoot);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue