fix(config): warn on unrecognized keys in config.json instead of silent drop (#1542)
* fix(config): warn on unrecognized keys in config.json instead of silent drop (#1535) loadConfig() silently ignores any config.json keys not in its known set, leaving users confused when their settings have no effect. Add a stderr warning listing unrecognized top-level keys so the problem surfaces immediately. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(config): derive known keys from VALID_CONFIG_KEYS instead of hardcoded set Address review feedback: replace hardcoded KNOWN_CONFIG_KEYS with programmatic derivation from config-set's VALID_CONFIG_KEYS (single source of truth). New config keys added to config-set are automatically recognized by loadConfig without a separate update. Add sync test verifying all VALID_CONFIG_KEYS entries pass without warning. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -126,6 +126,61 @@ describe('loadConfig', () => {
|
||||
const config = loadConfig(tmpDir);
|
||||
assert.strictEqual(config.commit_docs, false);
|
||||
});
|
||||
|
||||
test('warns on unknown config keys to stderr (#1535)', () => {
|
||||
writeConfig({ model_profile: 'quality', active_project: 'my-project', custom_flag: true });
|
||||
const origWrite = process.stderr.write;
|
||||
let stderrOutput = '';
|
||||
process.stderr.write = (chunk) => { stderrOutput += chunk; };
|
||||
try {
|
||||
const config = loadConfig(tmpDir);
|
||||
// Known key still loads correctly
|
||||
assert.strictEqual(config.model_profile, 'quality');
|
||||
// Warning emitted for unknown keys
|
||||
assert.ok(stderrOutput.includes('active_project'), 'should warn about active_project');
|
||||
assert.ok(stderrOutput.includes('custom_flag'), 'should warn about custom_flag');
|
||||
assert.ok(stderrOutput.includes('ignored'), 'should mention keys will be ignored');
|
||||
} finally {
|
||||
process.stderr.write = origWrite;
|
||||
}
|
||||
});
|
||||
|
||||
test('known config keys are derived from VALID_CONFIG_KEYS (not hardcoded)', () => {
|
||||
// Verify that loadConfig's unknown-key check uses config-set's VALID_CONFIG_KEYS
|
||||
// as its source of truth. If a new key is added to config-set, it should
|
||||
// automatically be recognized by loadConfig without a separate update.
|
||||
const { VALID_CONFIG_KEYS } = require('../get-shit-done/bin/lib/config.cjs');
|
||||
// Every top-level key from VALID_CONFIG_KEYS should be recognized
|
||||
const topLevelKeys = [...VALID_CONFIG_KEYS].map(k => k.split('.')[0]);
|
||||
for (const key of topLevelKeys) {
|
||||
writeConfig({ [key]: 'test-value' });
|
||||
const origWrite = process.stderr.write;
|
||||
let stderrOutput = '';
|
||||
process.stderr.write = (chunk) => { stderrOutput += chunk; };
|
||||
try {
|
||||
loadConfig(tmpDir);
|
||||
assert.ok(
|
||||
!stderrOutput.includes(key),
|
||||
`VALID_CONFIG_KEYS key "${key}" should not trigger unknown-key warning`
|
||||
);
|
||||
} finally {
|
||||
process.stderr.write = origWrite;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('does not warn when all config keys are known', () => {
|
||||
writeConfig({ model_profile: 'balanced', workflow: { research: false }, git: { branching_strategy: 'per-phase' } });
|
||||
const origWrite = process.stderr.write;
|
||||
let stderrOutput = '';
|
||||
process.stderr.write = (chunk) => { stderrOutput += chunk; };
|
||||
try {
|
||||
loadConfig(tmpDir);
|
||||
assert.strictEqual(stderrOutput, '', 'should not emit any warnings for valid config');
|
||||
} finally {
|
||||
process.stderr.write = origWrite;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ─── loadConfig commit_docs gitignore auto-detection (#1250) ──────────────────
|
||||
|
||||
Reference in New Issue
Block a user