Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 37 additions & 8 deletions scripts/common.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,42 @@ function Get-LiveConfigValueMap {
return $values
}

function Get-PortableConfigDrift {
param(
[string]$Source,
[string]$Destination
)

$live = [System.Collections.Generic.Dictionary[string, string]]::new(
[System.StringComparer]::Ordinal
)
if (Test-Path -LiteralPath $Destination -PathType Leaf) {
$live = Get-LiveConfigValueMap -Path $Destination
}
foreach ($entry in Get-PortableConfigEntries -Path $Source) {
$identity = "$($entry.Section)`n$($entry.Key)"
if (-not $live.ContainsKey($identity)) {
$state = "missing"
}
elseif ($live[$identity] -ne $entry.Value) {
$state = "differs"
}
else {
continue
}
$key = if ($entry.Section) {
"$($entry.Section).$($entry.Key)"
}
else {
$entry.Key
}
[pscustomobject]@{
Key = $key
State = $state
}
}
}

function Merge-PortableConfig {
param(
[string]$Source,
Expand Down Expand Up @@ -671,14 +707,7 @@ function Test-PortableConfigInSync {
if (-not (Test-Path -LiteralPath $Destination -PathType Leaf)) {
return $false
}
$live = Get-LiveConfigValueMap -Path $Destination
foreach ($entry in Get-PortableConfigEntries -Path $Source) {
$identity = "$($entry.Section)`n$($entry.Key)"
if (-not $live.ContainsKey($identity) -or $live[$identity] -ne $entry.Value) {
return $false
}
}
return $true
return @(Get-PortableConfigDrift -Source $Source -Destination $Destination).Count -eq 0
}

function Copy-PortableItem {
Expand Down
8 changes: 8 additions & 0 deletions scripts/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ if (-not $Apply) {
else {
foreach ($state in $changes) {
Write-Host " $($state.Item.RepoPath) -> $($state.Item.LivePath)"
if ($state.Item.Type -eq "config" -and $state.Exists) {
foreach ($entry in @(Get-PortableConfigDrift `
-Source $state.Item.RepoPath `
-Destination $state.Item.LivePath
)) {
Write-Host " reviewed config key $($entry.State): $($entry.Key)"
}
}
}
}
Write-Host ""
Expand Down
56 changes: 56 additions & 0 deletions scripts/test-all.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,49 @@ function Assert-TestFileContains {
}
}

function Assert-TestDriftOutput {
param([string]$Text)

foreach ($expected in @(
"reviewed config key differs: model_reasoning_effort"
"reviewed config key missing: features.goals"
)) {
if (-not $Text.Contains($expected)) {
throw "expected output to contain: $expected"
}
}
foreach ($unexpected in @(
"machine_setting"
"machine-sensitive-preview-value"
)) {
if ($Text.Contains($unexpected)) {
throw "expected output not to contain: $unexpected"
}
}
}

$testRoot = Join-Path ([System.IO.Path]::GetTempPath()) "compass-test-$([guid]::NewGuid().ToString('N'))"
$codexHome = Join-Path $testRoot "codex"
$agentsHome = Join-Path $testRoot "agents"
$claudeHome = Join-Path $testRoot "claude"

try {
. "$PSScriptRoot\common.ps1"

$emptyConfigPath = Join-Path $testRoot "empty-config.toml"
$directoryTarget = Join-Path $testRoot "config-directory"
Write-TestFile -Path $emptyConfigPath -Content ""
New-Item -ItemType Directory -Path $directoryTarget | Out-Null
if (Test-PortableConfigInSync -Source $emptyConfigPath -Destination $directoryTarget) {
throw "config directory target reported in sync"
}

$machineLabel = "preserve caf$([char]0x00E9)"
Write-TestFile -Path (Join-Path $codexHome "AGENTS.md\local.txt") -Content "preserve this backup`n"
Write-TestFile -Path (Join-Path $codexHome "auth.json") -Content "leave unlisted state alone`n"
Write-TestFile -Path (Join-Path $codexHome "config.toml") -Content @"
MODEL = "machine-specific"
model_reasoning_effort = "machine-sensitive-preview-value"
machine_setting = "$machineLabel"

["features"]
Expand All @@ -56,6 +88,30 @@ memories = false
trust_level = "trusted"
"@

$configPath = Join-Path $codexHome "config.toml"
$configBeforePreview = Get-Content -Raw -LiteralPath $configPath
$powerShellPath = (Get-Process -Id $PID).Path
$previewOutput = & $powerShellPath `
-NoProfile `
-ExecutionPolicy Bypass `
-File (Join-Path $PSScriptRoot "install.ps1") `
-CodexHome $codexHome `
-AgentsHome $agentsHome `
-ClaudeHome $claudeHome 2>&1 | Out-String
if ($LASTEXITCODE -ne 0) {
throw "install preview failed: $previewOutput"
}
if ((Get-Content -Raw -LiteralPath $configPath) -cne $configBeforePreview) {
throw "install preview changed live config"
}
Assert-TestDriftOutput -Text $previewOutput

$verifyOutput = & (Join-Path $PSScriptRoot "verify-live.ps1") `
-CodexHome $codexHome `
-AgentsHome $agentsHome `
-ClaudeHome $claudeHome 6>&1 | Out-String
Assert-TestDriftOutput -Text $verifyOutput

& (Join-Path $PSScriptRoot "install.ps1") `
-Apply `
-CodexHome $codexHome `
Expand Down
16 changes: 12 additions & 4 deletions scripts/verify-live.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ $items = @(
-ClaudeHome $claudeHome
)
$missing = New-Object System.Collections.Generic.List[string]
$drift = New-Object System.Collections.Generic.List[string]
$drift = New-Object System.Collections.Generic.List[object]

foreach ($item in $items) {
if (-not (Test-Path -LiteralPath $item.LivePath)) {
$missing.Add($item.LivePath)
continue
}
if (-not (Test-PortableItemInSync -Item $item)) {
$drift.Add($item.LivePath)
$drift.Add($item)
}
}

Expand All @@ -48,8 +48,16 @@ if ($missing.Count -gt 0) {
if ($drift.Count -gt 0) {
Write-Host ""
Write-Host "drift:"
foreach ($path in $drift) {
Write-Host " $path"
foreach ($item in $drift) {
Write-Host " $($item.LivePath)"
if ($item.Type -eq "config") {
foreach ($entry in @(Get-PortableConfigDrift `
-Source $item.RepoPath `
-Destination $item.LivePath
)) {
Write-Host " reviewed config key $($entry.State): $($entry.Key)"
}
}
}
}

Expand Down