fix(settings): honor an explicitly saved null in get-effective-settings - #88
Open
JeanBaptisteRenard wants to merge 1 commit into
Open
fix(settings): honor an explicitly saved null in get-effective-settings#88JeanBaptisteRenard wants to merge 1 commit into
JeanBaptisteRenard wants to merge 1 commit into
Conversation
get-effective-settings skipped a saved value when it was `null`, treating it as "never configured". But the settings panel persists permissionMode's "Default (none)" choice as `value || null`, so `null` is a deliberate value there meaning "pass no --permission-mode flag" — not an absent key. Two consequences: - A project that narrowed permissionMode back to "Default" kept inheriting the global mode. Set a global mode, then pick "Default" for one project, and the project still launches with the global mode. The narrower, more restrictive choice silently loses. - Any SETTING_DEFAULTS entry whose value is not null is unreachable at project scope, because a project-level null can never override it. Only `undefined` should fall through to the next-broader scope. Other falsy values (`false`, `0`, `''`) were already handled correctly and stay that way. Extracts the merge loop into resolve-effective-settings.js so the rule can be unit-tested without booting Electron, matching how folder-index-state.js and decodeOsc52Payload are already covered. Happy to inline it back into main.js if you'd rather not have the extra module — the behavioral change is the two dropped `!== null` clauses. 10 tests in test/resolve-effective-settings.test.js. Three of them fail if the `!== null` clauses are put back.
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.
What breaks
get-effective-settingsmerges saved settings overSETTING_DEFAULTS, skipping a scope's value when it isnull:But
nullis not "unset" forpermissionMode.settings-panel.jspersists the "Default (none)" option asvalue || null:So a user who deliberately picks "Default" — meaning prompt for every action, pass no
--permission-modeflag — is stored identically to a user who never opened settings. The DB already distinguishes the two; only the read side collapses them.Two consequences:
1. A project cannot narrow
permissionModeback to "Default". Set a global mode, then choose "Default" for one project, and the project still launches with the global mode. The narrower, more restrictive choice silently loses — which is the wrong direction for a permissions setting.2. Any non-null
SETTING_DEFAULTSvalue is unreachable at project scope, since a project-levelnullcan never override it. That constrains what defaults can be changed to later.Reproduction
Expected: no
--permission-modeflag, Claude prompts for each action.Actual: the session launches with
--permission-mode bypassPermissions. The project's savednullis discarded and the global mode is inherited.The fix
Only
undefined— the key was never saved at that scope — should fall through to the next-broader value. Dropping the two!== nullclauses is the entire behavioral change. Other falsy values (false,0,'') were already handled correctly and are unaffected; there is a test pinning that.I extracted the merge loop into
resolve-effective-settings.jsso the rule can be unit-tested without booting Electron — the same shape asfolder-index-state.jsand thedecodeOsc52Payloadexport, which are already covered that way. If you'd rather not carry the extra module, say so and I'll inline it back intomain.js; the fix itself is two lines.Tests
10 tests in
test/resolve-effective-settings.test.js, covering scope precedence, the explicit-null-wins cases,nullvsundefinednot being conflated, other falsy values surviving, and no input mutation.Verified adversarially: restoring the
!== nullclauses turns exactly three of them red ("a project can narrow permissionMode back to Default over a global mode", "an explicit global null beats a non-null default", "null and undefined are not conflated").npm teston this branch: 33/33 pass (23 before, +10).Found while syncing a fork against v0.0.31. My fork additionally changes
SETTING_DEFAULTS.permissionModeto'auto', which depends on this fix — that part is a local preference and is deliberately not included here.