fix(scripts): avoid false-positive legacy Codex sync detection

Tighten uninstall auto-detection so it only falls back to the legacy
sync-ecc-to-codex.sh path when there is an ownership manifest
(~/.codex/ecc/legacy-sync-state.json) or an ECC marker block in
~/.codex/AGENTS.md. Previously a clean Codex home with unrelated prompt
files could be misclassified as a legacy install, causing uninstall to
skip normal install-state reconciliation and exit with a partial warning.

Also make the no-state fallback return 'not-found' when there is no
marker to remove and no candidate files to clean, and make explicit
--legacy-codex-sync report the same on a clean home.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Santhi Prakash
2026-08-24 20:09:12 -04:00
committed by haelyra
co-authored by Paperclip
parent 09d6d22c09
commit f4f5cf9027
3 changed files with 84 additions and 10 deletions
+50
View File
@@ -418,6 +418,56 @@ function runTests() {
}
})) passed++; else failed++;
if (test('does not misclassify a clean Codex home as a legacy install', () => {
const homeDir = createTempDir('uninstall-clean-codex-home-');
const projectRoot = createTempDir('uninstall-clean-codex-project-');
try {
const codexHome = path.join(homeDir, '.codex');
const configPath = path.join(codexHome, 'config.toml');
const conversationPath = path.join(codexHome, 'conversations', 'keep-me.md');
fs.mkdirSync(codexHome, { recursive: true });
fs.writeFileSync(configPath, 'model = "user"\n');
fs.mkdirSync(path.dirname(conversationPath), { recursive: true });
fs.writeFileSync(conversationPath, 'conversation history');
const uninstallResult = run([], { cwd: projectRoot, homeDir });
assert.strictEqual(uninstallResult.code, 0, uninstallResult.stderr);
assert.ok(uninstallResult.stdout.includes('No ECC install-state files found'), uninstallResult.stdout);
assert.ok(!uninstallResult.stdout.includes('Legacy Codex sync cleanup summary'), uninstallResult.stdout);
assert.strictEqual(fs.readFileSync(configPath, 'utf8'), 'model = "user"\n');
assert.strictEqual(fs.readFileSync(conversationPath, 'utf8'), 'conversation history');
} finally {
cleanup(homeDir);
cleanup(projectRoot);
}
})) passed++; else failed++;
if (test('explicit --legacy-codex-sync on a clean home reports not-found without removing files', () => {
const homeDir = createTempDir('uninstall-legacy-clean-home-');
const projectRoot = createTempDir('uninstall-legacy-clean-project-');
try {
const codexHome = path.join(homeDir, '.codex');
const configPath = path.join(codexHome, 'config.toml');
fs.mkdirSync(codexHome, { recursive: true });
fs.writeFileSync(configPath, 'model = "user"\n');
const uninstallResult = run(['--legacy-codex-sync', '--json'], { cwd: projectRoot, homeDir });
assert.strictEqual(uninstallResult.code, 0, uninstallResult.stderr);
const parsed = JSON.parse(uninstallResult.stdout);
assert.strictEqual(parsed.status, 'not-found');
assert.deepStrictEqual(parsed.plannedRemovals, []);
assert.deepStrictEqual(parsed.retainedPaths, []);
assert.strictEqual(fs.readFileSync(configPath, 'utf8'), 'model = "user"\n');
} finally {
cleanup(homeDir);
cleanup(projectRoot);
}
})) passed++; else failed++;
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
process.exit(failed > 0 ? 1 : 0);
}