/** * Build Cache Utility * * Content-hash–based short-circuit for `pio run`. EmbedBench traces showed * agents repeatedly rebuilding identical firmware across hill-climbing * iterations (same `src/*` contents, same `platformio.ini`, k=1..k=5) and * paying 30–120 s of wall + agent overhead for no toolchain work. * * Strategy: * 1. Hash a deterministic projection of inputs that *should* invalidate a * cached build: every regular file under `src/`, `include/`, `lib/`, plus * `platformio.ini`. Each file contributes `path|size|sha256(content)`. * 2. Combine with the requested `environment` (or "default") and a schema * version tag so changes to this module bust prior caches. * 3. Persist the cache as `/.pio/.mcp-build-cache.json` — the * `.pio/` directory is already gitignored by PlatformIO convention. * 4. On a hit, verify the recorded firmware artifact (if any) still exists * on disk; otherwise treat as miss so we don't lie to upload tools. * * Intentionally simple: no LRU, no multi-entry cache, no mtime fast path * before hash. Content-only hashing is robust against editor "touch" without * change and against partial rebuilds. The miss cost (one full `pio run`) is * the same as today, so the worst case is unchanged. */ /** Persisted shape on disk. Keep additive — old fields must remain readable. */ export interface BuildCacheEntry { schema: string; /** Hash of all project inputs (see {@link computeProjectHash}). */ inputsHash: string; /** Specific environment built (or `"default"`). */ environment: string; /** UNIX epoch milliseconds of when this entry was recorded. */ builtAtMs: number; /** Optional absolute path to the firmware artifact verified on cache hits. */ firmwarePath?: string; /** RAM bytes parsed from the original build log (for replay). */ ramUsageBytes?: number; /** Flash bytes parsed from the original build log (for replay). */ flashUsageBytes?: number; /** Tail of build log we replay on cache hits. */ finalOutputTail?: string; } /** * Computes the content fingerprint for a project directory. Pure function over * disk state — same project → same hash, regardless of mtime drift. * * @param projectDir - Absolute path to the PlatformIO project root. * @param environment - Environment name (or "default"); included in the hash. * @returns Lowercase hex SHA-256 digest. Empty projects still produce a * stable digest so first-build wiring is deterministic. */ export declare function computeProjectHash(projectDir: string, environment: string): string; /** * Returns the cache file path for a project. Created lazily on writes; reads * tolerate missing/corrupt files by returning `null` (always a miss). */ export declare function cacheFilePath(projectDir: string): string; /** * Reads the persisted cache entry for a project, validating the schema tag. * Returns `null` on any of: missing file, JSON parse error, schema mismatch. */ export declare function readCache(projectDir: string): BuildCacheEntry | null; /** * Writes a cache entry to disk, ensuring the `.pio/` parent exists. Failures * are swallowed because cache writes are best-effort — a missed cache write * just means the next call is a (correct) cache miss. */ export declare function writeCache(projectDir: string, entry: Omit): void; /** * Looks up a cache entry for the project + environment and reports whether * it's a usable hit. A hit requires the inputs hash, environment match, *and* * (when recorded) the firmware artifact still existing on disk. * * @returns `{ hit: true, entry }` if usable, otherwise `{ hit: false }`. */ export declare function lookupBuildCache(projectDir: string, environment: string): { hit: true; entry: BuildCacheEntry; inputsHash: string; } | { hit: false; inputsHash: string; }; /** * Heuristically locates the most recently modified firmware artifact under * `.pio/build//`. PIO writes `firmware.bin`, `firmware.elf`, * `firmware.hex`, or `program` depending on the platform. Returns `undefined` * when nothing exists — that's fine, callers downgrade to a no-artifact * cache entry which still saves the toolchain reinvocation. */ export declare function findFirmwareArtifact(projectDir: string, environment: string): string | undefined; /** * Invalidates the cache by removing the persisted entry. Safe to call when * no cache exists. Intended for `clean_project` and for explicit overrides. */ export declare function invalidateBuildCache(projectDir: string): void; //# sourceMappingURL=build-cache.d.ts.map