fix(install): replace all managed files atomically

Write config.toml, settings.json, the manifest, and every other managed file to
a temporary sibling and rename it over the target, so an interrupted run
cannot leave a partly written file. Previously only SKILL.md was replaced
this way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Julian lechnerandClaude Opus 5.5 committed 2026-10-01 12:45:38 +02:00
1 parent 3285055d80
commit d4143ae2ac
4 files changed
+30 -26

No files matched your search

+5 -9
View File
@@ -43,9 +43,9 @@ function Get-Sha256HashOfBytes {
finally { $sha256.Dispose() }
}
function Write-ManagedSkillFile {
param([Parameter(Mandatory=$true)][string]$Path,[Parameter(Mandatory=$true)][byte[]]$Bytes)
$temporary = Join-Path (Split-Path $Path -Parent) ('.ai-config-skill-' + [Guid]::NewGuid().ToString('N') + '.tmp')
function Write-ManagedFileAtomically {
param([Parameter(Mandatory=$true)][string]$Path,[Parameter(Mandatory=$true)][AllowEmptyCollection()][byte[]]$Bytes)
$temporary = Join-Path (Split-Path $Path -Parent) ('.ai-config-write-' + [Guid]::NewGuid().ToString('N') + '.tmp')
$backup = "$temporary.bak"
try {
[System.IO.File]::WriteAllBytes($temporary, $Bytes)
@@ -83,7 +83,7 @@ function Write-ManagedManifest {
# without BOM and with LF line endings so either implementation can read the file
# regardless of which one wrote it.
$content = ($lines -join "`n") + "`n"
[System.IO.File]::WriteAllText($ManifestPath, $content, (New-Object System.Text.UTF8Encoding($false)))
Write-ManagedFileAtomically -Path $ManifestPath -Bytes ((New-Object System.Text.UTF8Encoding($false)).GetBytes($content))
}
function Invoke-InstallOptions {
@@ -190,11 +190,7 @@ function Sync-ManagedDestination {
if (-not $wasManaged) { Write-Output "WARN $target existed before this installation but was not tracked by a previous run; it was backed up before being overwritten."; $tally.Warned++ }
}
New-Item (Split-Path $target -Parent) -ItemType Directory -Force | Out-Null
if ($relative -eq 'SKILL.md' -or $relative.EndsWith('/SKILL.md', [StringComparison]::Ordinal)) {
Write-ManagedSkillFile -Path $target -Bytes $newBytes
} else {
[System.IO.File]::WriteAllBytes($target, $newBytes)
}
Write-ManagedFileAtomically -Path $target -Bytes $newBytes
if (-not $Summary) { Write-Output "$action $target" }
if ($action -eq 'CREATE') { $tally.Created++ } else { $tally.Updated++ }
}