/** * cli:aggregate-component-registry — atomic disk writer. * * ② The aggregator is an app-wide reducer: N parallel `/ba-develop` module * subagents each run it over the FULL app and overwrite the SAME two shared files * (`componentRegistry.generated.ts` + `moduleResources.generated.ts`). A plain * `writeFileSync` can be observed half-written by a reader or a racing aggregator. * Writing to a per-process temp file then `rename()` (atomic on the same volume) * makes every observed state a complete file, and concurrent runs never collide on * the temp name (it carries `process.pid`). */ import { mkdirSync, writeFileSync, renameSync } from 'node:fs' import { dirname, resolve } from 'node:path' import type { GeneratedFile } from './types.js' /** Write each generated file atomically (tmp + rename). Returns the absolute * paths written, in input order. */ export function writeGeneratedFilesAtomic( projectPath: string, files: GeneratedFile[], ): string[] { const written: string[] = [] for (const file of files) { const abs = resolve(projectPath, file.path) mkdirSync(dirname(abs), { recursive: true }) const tmp = `${abs}.tmp-${process.pid}` writeFileSync(tmp, file.content, 'utf-8') renameSync(tmp, abs) written.push(abs) } return written }