Merge pull request #3111 from code-yeongyu/fix/prepublish-config-regression

fix(config): use canonical path after legacy migration and make writes atomic
This commit is contained in:
YeonGyu-Kim
2026-04-04 14:56:52 +09:00
committed by GitHub
6 changed files with 80 additions and 39 deletions
+1
View File
@@ -28,6 +28,7 @@ export * from "./permission-compat"
export * from "./external-plugin-detector"
export * from "./zip-extractor"
export * from "./binary-downloader"
export * from "./write-file-atomically"
export * from "./agent-variant"
export * from "./session-cursor"
export * from "./shell-env"
+2 -13
View File
@@ -1,8 +1,9 @@
import { closeSync, existsSync, fsyncSync, openSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs"
import { existsSync, readFileSync, renameSync, rmSync } from "node:fs"
import { join, dirname, basename } from "node:path"
import { log } from "./logger"
import { CONFIG_BASENAME, LEGACY_CONFIG_BASENAME } from "./plugin-identity"
import { writeFileAtomically } from "./write-file-atomically"
function buildCanonicalPath(legacyPath: string): string {
const dir = dirname(legacyPath)
@@ -10,18 +11,6 @@ function buildCanonicalPath(legacyPath: string): string {
return join(dir, `${CONFIG_BASENAME}${ext}`)
}
function writeFileAtomically(filePath: string, content: string): void {
const tempPath = `${filePath}.tmp`
writeFileSync(tempPath, content, "utf-8")
const tempFileDescriptor = openSync(tempPath, "r")
try {
fsyncSync(tempFileDescriptor)
} finally {
closeSync(tempFileDescriptor)
}
renameSync(tempPath, filePath)
}
function archiveLegacyConfigFile(legacyPath: string): boolean {
const backupPath = `${legacyPath}.bak`
+2 -1
View File
@@ -1,5 +1,6 @@
import * as fs from "fs"
import { log } from "../logger"
import { writeFileAtomically } from "../write-file-atomically"
import { AGENT_NAME_MAP, migrateAgentNames } from "./agent-names"
import { migrateHookNames } from "./hook-names"
import { migrateModelVersions } from "./model-versions"
@@ -123,7 +124,7 @@ export function migrateConfigFile(
let writeSucceeded = false
try {
fs.writeFileSync(configPath, JSON.stringify(copy, null, 2) + "\n", "utf-8")
writeFileAtomically(configPath, JSON.stringify(copy, null, 2) + "\n")
writeSucceeded = true
} catch (err) {
log(`Failed to write migrated config to ${configPath}:`, err)
+13
View File
@@ -0,0 +1,13 @@
import { closeSync, fsyncSync, openSync, renameSync, writeFileSync } from "node:fs"
export function writeFileAtomically(filePath: string, content: string): void {
const tempPath = `${filePath}.tmp`
writeFileSync(tempPath, content, "utf-8")
const tempFileDescriptor = openSync(tempPath, "r")
try {
fsyncSync(tempFileDescriptor)
} finally {
closeSync(tempFileDescriptor)
}
renameSync(tempPath, filePath)
}