Skip to content

Instantly share code, notes, and snippets.

@Esonhugh
Last active September 3, 2026 14:42
Show Gist options
  • Select an option

  • Save Esonhugh/544c305b4333acdb1ce39c72c81aac80 to your computer and use it in GitHub Desktop.

Select an option

Save Esonhugh/544c305b4333acdb1ce39c72c81aac80 to your computer and use it in GitHub Desktop.
claude code auto change settings
#!/bin/bash
# Source from zsh or bash:
# source /tmp/1.txt
#
# claude -> base Claude invocation without a settings profile
# claude-abc -> merge settings.base.json + settings.abc.json
# claude-qa-qb-qc -> merge base + settings.qa-qb-qc.json when it exists;
# otherwise merge base + qa + qb + qc
#
# A complete profile name always takes precedence over splitting on `-`.
# `settings.base.json` is automatically prepended unless `base` is requested.
# Profiles are merged from left to right using Object.assign semantics.
# `env` is merged separately so variables from all profiles survive; later
# values win.
# Set NO_DANGER=1 to omit both dangerous-mode flags:
# NO_DANGER=1 claude-base-mjclouds
# Core launcher. $1 = profile (empty for base `claude`); remaining args pass through.
function _claude_launch() {
local profile="$1"
shift
local -a args=()
local settings merged="" exit_status
if [ "${NO_DANGER:-}" != "1" ]; then
args+=(--dangerously-skip-permissions --allow-dangerously-skip-permissions)
fi
if [ -n "$profile" ]; then
local settings_dir="$HOME/.claude"
local exact="$settings_dir/settings.${profile}.json"
local base="$settings_dir/settings.base.json"
local remaining part
local -a settings_files=()
if [ "$profile" != "base" ] && [ -f "$base" ]; then
settings_files+=("$base")
fi
if [ -f "$exact" ]; then
settings_files+=("$exact")
else
case "$profile" in
*-*) ;;
*)
printf 'claude-%s: settings file not found: %s\n' "$profile" "$exact" >&2
return 1
;;
esac
remaining="$profile"
while :; do
part="${remaining%%-*}"
if [ -z "$part" ]; then
printf 'claude-%s: invalid empty profile component\n' "$profile" >&2
return 1
fi
settings="$settings_dir/settings.${part}.json"
if [ ! -f "$settings" ]; then
printf 'claude-%s: settings file not found: %s\n' "$profile" "$settings" >&2
return 1
fi
[ "$settings" = "$base" ] || settings_files+=("$settings")
[ "$remaining" = "$part" ] && break
remaining="${remaining#*-}"
done
fi
if [ "${#settings_files[@]}" -eq 1 ]; then
settings="${settings_files[0]}"
else
if ! command -v jq >/dev/null 2>&1; then
printf 'claude-%s: jq is required to merge settings files\n' "$profile" >&2
return 1
fi
merged="$(mktemp "${TMPDIR:-/tmp}/claude-settings.XXXXXXXX")" || return 1
if ! jq -s '
reduce .[] as $settings (
{};
(.env // {}) as $env |
. + $settings |
.env = ($env + ($settings.env // {}))
)
' "${settings_files[@]}" >"$merged"; then
command rm -f "$merged"
return 1
fi
settings="$merged"
fi
args+=("--settings=$settings" "--setting-sources" "local,project")
fi
command claude "${args[@]}" "$@"
exit_status=$?
[ -z "$merged" ] || command rm -f "$merged"
return "$exit_status"
}
function claude() {
_claude_launch "" "$@"
}
# Define visible functions for discovered profiles so completion and syntax
# highlighters recognize commands such as `claude-abc`.
function _claude_define_profile_function() {
local profile="$1"
local fn="claude-${profile}"
case "$fn" in
*[!A-Za-z0-9_:-]*)
printf 'claude-launcher: skip unsupported function name: %s\n' "$fn" >&2
return 0
;;
esac
if [ -n "$ZSH_VERSION" ]; then
eval "function ${fn}() { _claude_launch ${profile:q} \"\$@\"; }"
else
local quoted_profile
printf -v quoted_profile '%q' "$profile"
eval "${fn}() { _claude_launch ${quoted_profile} \"\$@\"; }"
fi
}
function _claude_define_profile_functions() {
local settings_dir="$HOME/.claude"
local file base profile
[ -d "$settings_dir" ] || return 0
if [ -n "$ZSH_VERSION" ]; then
setopt local_options null_glob
else
shopt -s nullglob
fi
for file in "$settings_dir"/settings.*.json; do
base="${file##*/}"
profile="${base#settings.}"
profile="${profile%.json}"
[ -n "$profile" ] || continue
_claude_define_profile_function "$profile"
done
if [ -n "$BASH_VERSION" ]; then
shopt -u nullglob
fi
}
_claude_define_profile_functions
# Resolve combinations and profiles created after this file was sourced.
if [ -n "$ZSH_VERSION" ]; then
if (( ${+functions[command_not_found_handler]} )) && ! (( ${+functions[_claude_prev_cnf]} )); then
functions[_claude_prev_cnf]=$functions[command_not_found_handler]
fi
command_not_found_handler() {
case "$1" in
claude-*)
local profile="${1#claude-}"
shift
_claude_launch "$profile" "$@"
return $?
;;
esac
if (( ${+functions[_claude_prev_cnf]} )); then
_claude_prev_cnf "$@"
return $?
fi
printf 'zsh: command not found: %s\n' "$1" >&2
return 127
}
elif [ -n "$BASH_VERSION" ]; then
if declare -F command_not_found_handle >/dev/null 2>&1 && ! declare -F _claude_prev_cnf >/dev/null 2>&1; then
eval "$(declare -f command_not_found_handle | sed '1 s/^command_not_found_handle/_claude_prev_cnf/')"
fi
command_not_found_handle() {
case "$1" in
claude-*)
local profile="${1#claude-}"
shift
_claude_launch "$profile" "$@"
return $?
;;
esac
if declare -F _claude_prev_cnf >/dev/null 2>&1; then
_claude_prev_cnf "$@"
return $?
fi
printf 'bash: %s: command not found\n' "$1" >&2
return 127
}
fi
unset -f _claude_define_profile_function _claude_define_profile_functions 2>/dev/null || true
{
"env": {
"ANTHROPIC_API_KEY": "",
"ANTHROPIC_BASE_URL": "",
"ANTHROPIC_SMALL_FAST_MODEL": "", // use to tool result compact or other process
"CLAUDE_CODE_SUBAGENT_MODEL": "", // use to subagents
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "", // real haiku alias
"ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME": "", // in /model name haiku
"ANTHROPIC_DEFAULT_HAIKU_MODEL_DESCRIPTION": "", // in /model description haiku
"ANTHROPIC_DEFAULT_SONNET_MODEL": "", // real sonnet alias
"ANTHROPIC_DEFAULT_SONNET_MODEL_NAME": "", // in /model name sonnet
"ANTHROPIC_DEFAULT_SONNET_MODEL_DESCRIPTION": "", // in /model description sonnet
"ANTHROPIC_DEFAULT_OPUS_MODEL": "", // real opus alias
"ANTHROPIC_DEFAULT_OPUS_MODEL_NAME": "", // in /model name opus
"ANTHROPIC_DEFAULT_OPUS_MODEL_DESCRIPTION": "", // in /model description opus
"ANTHROPIC_DEFAULT_FABLE_MODEL": "", // real fable alias
"ANTHROPIC_DEFAULT_FABLE_MODEL_NAME": "", // in /model name fable
"ANTHROPIC_DEFAULT_FABLE_MODEL_DESCRIPTION": "", // in /model description fable
},
"modelOverrides": {
// "claude-opus-4-6": "arn:aws:bedrock:us-east-1:123456789012:inference-profile/example"
}
}
{
"skipDangerousModePermissionPrompt": true,
"skipWebFetchPreflight": true,
"skipDangerousModePermissionPrompt": true,
"extraKnownMarketplaces": {
"Esonhugh-Marketplace": {
"source": {
"source": "github",
"repo": "Esonhugh/Marketplace"
},
"autoUpdate": true
}
},
"env": {
"CLAUDE_CODE_MAX_OUTPUT_TOKENS": "1000000",
"CLAUDE_CODE_MAX_RETRIES": "100",
"CLAUDE_CODE_ATTRIBUTION_HEADER": "0",
"IS_SANDBOX": "1",
"CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1",
"API_TIMEOUT_MS": "1200000",
"BASH_DEFAULT_TIMEOUT_MS": "300000",
"CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK": "1",
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
},
"permissions": {
"allow": [],
"deny": []
}
}
{
"env": {
"HTTPS_PROXY": "http://127.0.0.1:7890"
}
}
{
"effortLevel": "high"
}
{
"enabledPlugins": {
"finance-market-analysis@Esonhugh-Marketplace": true,
"ibkr-trade-analyzer@Esonhugh-Marketplace": true,
"tradingview@Esonhugh-Marketplace": true
}
}
{
"effortLevel": "low"
}
{
"effortLevel": "max"
}
{
"effortLevel": "medium"
}
{
"enabledPlugins": {}
}
{
"effortLevel": "ultra"
}
{
"effortLevel": "xhigh"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment