diff --git a/src/resources/extensions/sf/guided-flow-queue.ts b/src/resources/extensions/sf/guided-flow-queue.ts index 0fb11531d..21d667e3a 100644 --- a/src/resources/extensions/sf/guided-flow-queue.ts +++ b/src/resources/extensions/sf/guided-flow-queue.ts @@ -17,7 +17,8 @@ import { sfRoot, resolveMilestoneFile, resolveSliceFile, resolveSfRootFile, relSfRootFile, relSliceFile, } from "./paths.js"; -import { readFileSync, writeFileSync, existsSync } from "node:fs"; +import { readFileSync, existsSync } from "node:fs"; +import { atomicWriteSync } from "./atomic-write.js"; import { nativeAddPaths, nativeCommit } from "./native-git-bridge.js"; import { loadEffectiveSFPreferences } from "./preferences.js"; import { loadQueueOrder, sortByQueueOrder, saveQueueOrder } from "./queue-order.js"; @@ -387,7 +388,7 @@ function removeDependsOnFromContextFiles( const newContent = newFm.trim() ? `---\n${newFm}\n---${body}` : body.replace(/^\n+/, ""); - writeFileSync(contextFile, newContent, "utf-8"); + atomicWriteSync(contextFile, newContent, "utf-8"); } } @@ -435,5 +436,5 @@ function syncProjectMdSequence( const separatorLine = lines[tableStart + 1]; const newTable = [headerLine, separatorLine, ...newRows]; lines.splice(tableStart, tableEnd - tableStart, ...newTable); - writeFileSync(projectPath, lines.join("\n"), "utf-8"); + atomicWriteSync(projectPath, lines.join("\n"), "utf-8"); } diff --git a/src/resources/extensions/sf/reports.ts b/src/resources/extensions/sf/reports.ts index 3b97b8d47..f89032274 100644 --- a/src/resources/extensions/sf/reports.ts +++ b/src/resources/extensions/sf/reports.ts @@ -14,11 +14,12 @@ * Manual: /sf export --html */ -import { writeFileSync, readFileSync, mkdirSync, existsSync } from 'node:fs'; +import { readFileSync, mkdirSync, existsSync } from 'node:fs'; import { join, basename } from 'node:path'; import { sfRoot } from './paths.js'; import { formatCost, formatTokenCount } from './metrics.js'; import { formatDateShort, formatDuration } from '../shared/format-utils.js'; +import { atomicWriteSync } from './atomic-write.js'; // ─── Types ──────────────────────────────────────────────────────────────────── @@ -83,7 +84,7 @@ export function loadReportsIndex(basePath: string): ReportsIndex | null { function saveReportsIndex(basePath: string, index: ReportsIndex): void { const dir = reportsDir(basePath); mkdirSync(dir, { recursive: true }); - writeFileSync(reportsIndexPath(basePath), JSON.stringify(index, null, 2) + '\n', 'utf-8'); + atomicWriteSync(reportsIndexPath(basePath), JSON.stringify(index, null, 2) + '\n', 'utf-8'); } // ─── Write a report snapshot ────────────────────────────────────────────────── @@ -121,7 +122,7 @@ export function writeReportSnapshot(args: WriteReportSnapshotArgs): string { const filename = `${prefix}-${timestamp}.html`; const filePath = join(dir, filename); - writeFileSync(filePath, args.html, 'utf-8'); + atomicWriteSync(filePath, args.html, 'utf-8'); // Load or init registry const existing = loadReportsIndex(args.basePath); @@ -170,7 +171,7 @@ export function writeReportSnapshot(args: WriteReportSnapshotArgs): string { export function regenerateHtmlIndex(basePath: string, index: ReportsIndex): void { const html = buildIndexHtml(index); - writeFileSync(reportsHtmlIndexPath(basePath), html, 'utf-8'); + atomicWriteSync(reportsHtmlIndexPath(basePath), html, 'utf-8'); } function buildIndexHtml(index: ReportsIndex): string {