Keep in-session /model picks from leaking into the global default#12
Open
payne0420 wants to merge 1 commit into
Open
Keep in-session /model picks from leaking into the global default#12payne0420 wants to merge 1 commit into
payne0420 wants to merge 1 commit into
Conversation
Claude Code v2.1.153+ persists an in-session `/model` pick (Enter in the picker) to the user-global settings file (`~/.claude/settings.json`, the `model` key). Under UltraCode that means picking a proxy-only id (e.g. `claude-composer`, `claude-gpt-5.5-codex`) silently becomes your global default — and a plain `claude` run *outside* the proxy then fails, because the real Anthropic API doesn't recognize that id. Both launchers now snapshot the global `model` key before launch and restore it on exit, so `/model` picks stay session-scoped: - bin/ultracode: snapshot_global_model before start_proxy, restore_global_model inside the stop_proxy EXIT trap. The JSON edit shells out to Python so only the `model` key changes; the rest of settings.json is untouched. - windows/Start-UltraCode.ps1: Save-GlobalModel / Restore-GlobalModel doing the same via Python (avoids ConvertTo-Json mangling single-element arrays in nested blocks like hooks). Ref-count-safe across concurrent sessions: a clean start snapshots, a running session keeps the existing snapshot, and the last session out restores (then removes the saved-state file). Opt out with UC_PRESERVE_GLOBAL_MODEL=0, which restores Claude Code's normal persist-globally behavior. To keep a pick for the current session only without saving, press `s` in the picker instead of Enter. docs/TROUBLESHOOTING.md documents the symptom, the guard, and the escape hatch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Problem
Claude Code v2.1.153+ persists an in-session
/modelpick (pressing Enter in the picker) to the user-global settings file (~/.claude/settings.json, themodelkey). Under UltraCode the picker lists proxy-only ids (e.g.claude-composer,claude-gpt-5.5-codex), so picking one silently makes it your global default — and a plainclauderun outside the proxy then fails, because the real Anthropic API doesn't recognize that id.The launchers set the session model via
--settings+--model(both session-scoped, never persisted), so the launcher itself never pollutes globals — but an interactive/modelEnter-pick does, and there's no Claude Code flag/env to disable that persistence.Fix
Both launchers now snapshot the global
modelkey before launch and restore it on exit, so/modelpicks stay session-scoped:bin/ultracode—snapshot_global_modelbeforestart_proxy;restore_global_modelinside the existingstop_proxyEXIT trap.windows/Start-UltraCode.ps1—Save-GlobalModel/Restore-GlobalModelat the equivalent points.Both do the JSON edit by shelling out to Python (already required by the launchers) rather than re-serializing the whole file, so only the
modelkey is touched and the rest ofsettings.jsonis left intact. (On Windows this also avoidsConvertTo-Jsoncollapsing single-element arrays in nested blocks likehooks.)Behavior
modelkey entirely if there wasn't one before./modelstill applies for the current session; it's just reverted globally on exit.UC_PRESERVE_GLOBAL_MODEL=0restores Claude Code's normal persist-globally behavior.sin the/modelpicker (session-only, never saves) — documented too.Docs
docs/TROUBLESHOOTING.mdgains a section describing the symptom, the guard, and the escape hatch.Testing
model, and removes amodelthe session added when none existed before —permissions/hooks/other keys preserved.bash -n bin/ultracodeclean.python3 test_proxy.py→ ALL TESTS PASSED;python3 scripts/doctor.py→ 17 ok, 0 failures.No changes to
proxy.py; this is launcher-only and independent of other open PRs.🤖 Generated with Claude Code