Skip to content

Commit 60c1915

Browse files
Aitomatesclaude
andcommitted
chore: update register-global scripts and tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 27e8c11 commit 60c1915

3 files changed

Lines changed: 54 additions & 11 deletions

File tree

universal-refiner/scripts/operations/REGISTER-GLOBAL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Optional overrides:
2525
-ObsidianVaultPath 'C:\repo\global.obsidian'
2626
```
2727

28-
The script preserves unrelated JSON and TOML configuration. In `-Apply` mode it creates timestamped backups before changed files are replaced through same-directory atomic UTF-8 writes. The doctor reports mojibake and suspicious plaintext credential field paths without printing credential values.
28+
The script preserves unrelated JSON and TOML configuration. In `-Apply` mode it first preflights every target, then creates timestamped backups before changed files are replaced through same-directory atomic UTF-8 writes. Apply is refused when invalid JSON, mojibake, or suspicious plaintext credential fields are detected. Diagnostics print field paths, never credential values.
2929

3030
Exit codes:
3131

universal-refiner/scripts/operations/register-global.ps1

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -267,19 +267,26 @@ function Set-TomlSection {
267267
return $Content + $section
268268
}
269269

270-
function Update-CodexConfig {
271-
param(
272-
[Parameter(Mandatory = $true)][string]$Path,
273-
[Parameter(Mandatory = $true)][System.Collections.IDictionary]$Servers
274-
)
270+
function Inspect-TomlConfig {
271+
param([Parameter(Mandatory = $true)][string]$Path)
275272

276-
$content = if (Test-Path -LiteralPath $Path) { [System.IO.File]::ReadAllText($Path) } else { "" }
273+
if (-not (Test-Path -LiteralPath $Path)) { return }
274+
$content = [System.IO.File]::ReadAllText($Path)
277275
if (Test-Mojibake $content) {
278276
$script:Issues.Add("mojibake detected: $Path")
279277
}
280278
foreach ($match in [regex]::Matches($content, '(?im)^\s*([A-Za-z0-9_.-]*(?:key|token|secret|password|credential|authorization|bearer)[A-Za-z0-9_.-]*)\s*=\s*(?!"\$\{)[^#\r\n]+')) {
281279
$script:Issues.Add("plaintext credential field: `$.$($match.Groups[1].Value)")
282280
}
281+
}
282+
283+
function Update-CodexConfig {
284+
param(
285+
[Parameter(Mandatory = $true)][string]$Path,
286+
[Parameter(Mandatory = $true)][System.Collections.IDictionary]$Servers
287+
)
288+
289+
$content = if (Test-Path -LiteralPath $Path) { [System.IO.File]::ReadAllText($Path) } else { "" }
283290

284291
$desiredContent = $content
285292
foreach ($serverName in $Servers.Keys) {
@@ -339,11 +346,34 @@ Write-Host "Mode: $(if ($Apply) { 'Apply' } else { 'Check' })"
339346
Write-Host "Profile: $profile"
340347
Write-Host "Checkout: $repoRoot"
341348

349+
$codexConfigPath = Join-Path $codexRoot "config.toml"
350+
$claudeMcpPath = Join-Path $profile ".claude.json"
351+
$claudeSettingsPath = Join-Path $profile ".claude\settings.json"
352+
$geminiSettingsPath = Join-Path $profile ".gemini\settings.json"
353+
354+
try {
355+
Inspect-TomlConfig $codexConfigPath
356+
[void](Read-JsonConfig $claudeMcpPath)
357+
[void](Read-JsonConfig $claudeSettingsPath)
358+
[void](Read-JsonConfig $geminiSettingsPath)
359+
} catch {
360+
Write-Warning $_.Exception.Message
361+
exit 2
362+
}
363+
364+
if ($Apply -and $script:Issues.Count -gt 0) {
365+
foreach ($issue in $script:Issues | Select-Object -Unique) {
366+
Write-Warning $issue
367+
}
368+
Write-Warning "Apply refused because preflight diagnostics must be resolved first."
369+
exit 2
370+
}
371+
342372
try {
343-
Update-CodexConfig (Join-Path $codexRoot "config.toml") $servers
344-
Update-JsonConfig "Claude Code MCP" (Join-Path $profile ".claude.json") $servers
345-
Update-JsonConfig "Claude Code hooks" (Join-Path $profile ".claude\settings.json") ([ordered]@{}) $claudeHooks["hooks"]
346-
Update-JsonConfig "Gemini" (Join-Path $profile ".gemini\settings.json") $servers $geminiHooks["hooks"]
373+
Update-CodexConfig $codexConfigPath $servers
374+
Update-JsonConfig "Claude Code MCP" $claudeMcpPath $servers
375+
Update-JsonConfig "Claude Code hooks" $claudeSettingsPath ([ordered]@{}) $claudeHooks["hooks"]
376+
Update-JsonConfig "Gemini" $geminiSettingsPath $servers $geminiHooks["hooks"]
347377
} catch {
348378
Write-Warning $_.Exception.Message
349379
exit 2

universal-refiner/tests/register-global.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,17 @@ describe("global registration doctor", () => {
9393
expect(result.stdout + result.stderr).not.toContain("do-not-print-this");
9494
expect(existsSync(join(root, ".claude.json"))).toBe(false);
9595
});
96+
97+
it("refuses to merge invalid JSON without overwriting it", () => {
98+
const root = makeRoot();
99+
mkdirSync(join(root, ".claude"), { recursive: true });
100+
const configPath = join(root, ".claude", "settings.json");
101+
writeFileSync(configPath, "{", "utf8");
102+
103+
const result = run(root, "-Apply");
104+
expect(result.status, result.stdout + result.stderr).toBe(2);
105+
expect(result.stdout + result.stderr).toContain("Cannot safely merge invalid JSON config");
106+
expect(readFileSync(configPath, "utf8")).toBe("{");
107+
expect(existsSync(join(root, ".codex", "config.toml"))).toBe(false);
108+
});
96109
});

0 commit comments

Comments
 (0)