/** * `peaks test` per-test fingerprint cache (slice 2.5.0 sub-fix B). * * Persists per-test results keyed by (file, testName) so a re-run can * skip tests where the file's mtime + sha256 are unchanged AND the * previous run status was "passed". The cache lives at * `/.peaks/_runtime/test-cache/.json` and is * session-bound runtime state (gitignored via the existing * `.peaks/_runtime/` rule). * * Schema (per file): * { * filePath: string; // absolute path to the test file * fileMtime: number; // mtime in ms * fileSha256: string; // hex sha256 * framework: 'jest' | 'vitest' | 'mocha'; * tests: Array<{ * testName: string; * status: 'passed' | 'failed' | 'skipped'; * durationMs: number; * lastRun: string; // ISO timestamp * }>; * lastRunAt: string; * } */ export type TestFramework = 'jest' | 'vitest' | 'mocha'; export type TestStatus = 'passed' | 'failed' | 'skipped'; export interface TestRecord { testName: string; status: TestStatus; durationMs: number; lastRun: string; } export interface TestCacheFile { filePath: string; fileMtime: number; fileSha256: string; framework: TestFramework; tests: TestRecord[]; lastRunAt: string; } export declare const TEST_CACHE_DIR = "test-cache"; export declare function testCacheDir(projectRoot: string): string; export declare function testCachePath(projectRoot: string, filePath: string): string; export declare function sha256OfFile(filePath: string): string; export declare function mtimeOfFile(filePath: string): number; export declare function readTestCache(projectRoot: string, filePath: string): TestCacheFile | null; export declare function writeTestCache(projectRoot: string, cache: TestCacheFile): void; export declare function clearTestCache(projectRoot: string): { removed: number; }; export interface CacheLookup { hit: boolean; reason?: 'no-cache' | 'mtime-changed' | 'sha-changed' | 'previous-failed' | 'previous-skipped'; cached?: TestRecord; } /** * Decide whether a test is cacheable (i.e. can be skipped on a re-run). * Returns hit=true if the cache record shows passed AND both * (fileMtime, fileSha256) match the current file state. */ export declare function isCacheable(projectRoot: string, filePath: string, testName: string): CacheLookup; export declare function recordTestResult(projectRoot: string, filePath: string, framework: TestFramework, record: TestRecord): void; /** * Detect the consumer project's test framework by reading * package.json devDependencies / dependencies. Picks the dominant * one (most-installed). Returns null if no supported framework * is found. */ export declare function detectTestFramework(projectRoot: string): TestFramework | null;