fix: preserve user settings when enabling/disabling hooks#24
Merged
mylee04 merged 4 commits intomylee04:mainfrom Feb 14, 2026
Merged
fix: preserve user settings when enabling/disabling hooks#24mylee04 merged 4 commits intomylee04:mainfrom
mylee04 merged 4 commits intomylee04:mainfrom
Conversation
Critical bug fix: Previously, `cn off` would overwrite the entire settings.json file, destroying user's custom configuration including: - Preferred model setting (was hardcoded to "opus") - Permission rules - Environment variables - Any other custom settings Changes: - enable_hooks_in_settings(): Preserve existing settings, add hooks only - disable_hooks_in_settings(): Only remove hooks key, keep other settings - disable_gemini_hooks(): Only remove code-notify hooks, preserve rest Implementation: - Uses jq (preferred) or python3 (fallback) for proper JSON handling - Warns user if neither tool is available (safer than corrupting config) Testing: - Added tests/test-config-preservation.sh with 4 test cases - All tests verify settings are preserved correctly Documentation: - Added docs/BUG_FIX_CONFIG_PRESERVATION.md with before/after examples Fixes: Config overwrite bug that destroyed user settings
Fixed critical bugs in Python fallback path: 1. enable_hooks_in_settings: - Wrong: `python3 - ... << 'PYTHON' "$settings"` passed JSON as argument - Fixed: `echo "$settings" | python3 -c "..."` pipes JSON via stdin 2. disable_hooks_in_settings: - Wrong: `python3 << 'PYTHON' "$file"` executed file as Python script - Fixed: `python3 - "$file" << 'PYTHON'` passes file path as argument 3. disable_gemini_hooks: Same fix as mylee04#2 4. No-tools case: Now aborts with error instead of modifying file Tests updated: - Now tests both jq and Python fallback paths - Uses subshells to properly mock has_jq function - Removed fake "Test 4" that didn't actually test fallback All tests passing for both jq and Python paths.
- Add shell_quote() helper for safe shell escaping - Fix enable_project_hooks_in_settings jq branch to use quoted values - Fix enable_project_hooks_in_settings Python branch to use shlex.quote() - Add test cases for project hooks with special characters (space, semicolon, quote)
Return proper exit code when underlying config operations fail
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug Description
This PR fixes a critical bug where
cn offdestroys all user settings insettings.json.The Problem
Before this fix, running
cn offwould:sonnet) toopusExample:
After
cn off(buggy behavior):{ "model": "opus" // Everything else is GONE! }The Fix
Now
cn offonly removes thehookssection while preserving all other settings:Changes
enable_hooks_in_settings()"model": "opus"disable_hooks_in_settings()hookskeydisable_gemini_hooks()Implementation Details
jq(preferred) for JSON manipulationpython3if jq is not availableTesting
Added
tests/test-config-preservation.shwith 4 test cases:enable_hookspreserves existing modeldisable_hookspreserves other settingsRun tests:
Documentation
Added
docs/BUG_FIX_CONFIG_PRESERVATION.mdwith:Files Changed
lib/code-notify/core/config.shtests/test-config-preservation.shdocs/BUG_FIX_CONFIG_PRESERVATION.mdChecklist