merge: preserve project and user Codex configuration source 3253

This commit is contained in:
haelyra
2026-10-09 17:02:47 -04:00
6 changed files with 463 additions and 102 deletions
+2 -2
View File
@@ -2,7 +2,7 @@
'use strict';
/**
* Merge the non-MCP Codex baseline from `.codex/config.toml` into a target
* Merge the non-MCP Codex baseline from `.codex/user-config.example.toml` into a target
* `config.toml` without overwriting existing user choices.
*
* Strategy: add-only.
@@ -219,7 +219,7 @@ function main() {
process.exit(1);
}
const referencePath = path.join(__dirname, '..', '..', '.codex', 'config.toml');
const referencePath = path.join(__dirname, '..', '..', '.codex', 'user-config.example.toml');
if (!fs.existsSync(referencePath)) {
console.error(`[ecc-codex] Reference config not found: ${referencePath}`);
process.exit(1);
+38 -2
View File
@@ -1,6 +1,10 @@
const { HOME_INSTALL_EXCLUDED_SOURCE_PATHS, createInstallTargetAdapter } = require('./helpers');
const fs = require('fs');
const path = require('path');
const {
HOME_INSTALL_EXCLUDED_SOURCE_PATHS, createInstallTargetAdapter, createManagedOperation,
} = require('./helpers');
module.exports = createInstallTargetAdapter({
const adapter = createInstallTargetAdapter({
id: 'codex-home',
target: 'codex',
kind: 'home',
@@ -9,3 +13,35 @@ module.exports = createInstallTargetAdapter({
nativeRootRelativePath: '.codex',
excludedSourcePaths: HOME_INSTALL_EXCLUDED_SOURCE_PATHS,
});
const USER_REFERENCE = '.codex/user-config.example.toml';
module.exports = Object.freeze({
...adapter,
planOperations(input = {}) {
// Delegate the existing platform filters, exclusions and scaffold metadata.
return adapter.planOperations(input).flatMap(operation => {
if (operation.sourceRelativePath !== '.codex') return [operation];
// Abstract metadata-only plans need no filesystem. A selected real source
// must not silently fall back to the narrower project config.
if (input.repoRoot && fs.existsSync(input.repoRoot)) {
let stat;
try {
stat = fs.lstatSync(path.join(input.repoRoot, USER_REFERENCE));
} catch (error) {
if (error.code !== 'ENOENT') throw error;
}
if (!stat || !stat.isFile() || stat.isSymbolicLink()) {
throw new Error('Codex user reference must exist as a regular file');
}
}
// The planner materializes these operations, then keeps the last copy per
// destination before preview/state/apply. Only the user reference survives.
return [operation, createManagedOperation({
moduleId: operation.moduleId,
sourceRelativePath: USER_REFERENCE,
destinationPath: path.join(operation.destinationPath, 'config.toml'),
})];
});
},
});