Compare commits
2
Commits
de9f10a8c2
...
a54f7bcb55
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a54f7bcb55 | ||
|
|
c5c3fc57d9 |
@@ -185,6 +185,7 @@ claude-mode preset new <name> [from] copy an existing preset (default: `defaul
|
|||||||
claude-mode preset new <name> --provider <p> [--blank]
|
claude-mode preset new <name> --provider <p> [--blank]
|
||||||
copy that provider's default, or start empty
|
copy that provider's default, or start empty
|
||||||
claude-mode preset rename <name> <new-name> repoints state.json if it is in use
|
claude-mode preset rename <name> <new-name> repoints state.json if it is in use
|
||||||
|
claude-mode preset default [provider] [name|--clear] which preset `claude-mode <provider>` picks
|
||||||
claude-mode preset set <name> <tier> <model-id>
|
claude-mode preset set <name> <tier> <model-id>
|
||||||
claude-mode preset all <name> <model-id> point every tier at one model
|
claude-mode preset all <name> <model-id> point every tier at one model
|
||||||
claude-mode preset rm <name>
|
claude-mode preset rm <name>
|
||||||
@@ -204,8 +205,21 @@ claude-mode sessions --dry-run show what either would do, and do nothing
|
|||||||
claude-mode <mode> --force switch even when preflight says no
|
claude-mode <mode> --force switch even when preflight says no
|
||||||
```
|
```
|
||||||
|
|
||||||
Omitting the preset uses a **fixed** per-provider default, not "most recently
|
Omitting the preset uses a per-provider default, never "most recently used".
|
||||||
used" — so `claude-mode openrouter` always means `default`.
|
Out of the box that is a fixed name — `claude-mode openrouter` means `default`,
|
||||||
|
`zai` means `zai`, `lmstudio` means `lmstudio` — and it can be changed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
claude-mode preset default # what each provider picks, and why
|
||||||
|
claude-mode preset default openrouter cheap # `claude-mode openrouter` now means `cheap`
|
||||||
|
claude-mode preset default openrouter --clear # back to the built-in name
|
||||||
|
```
|
||||||
|
|
||||||
|
The choice lives in `~/.claude-mode/defaults.json`. If the chosen preset is
|
||||||
|
deleted the choice is cleared with it, renaming moves it along, and a choice
|
||||||
|
whose file has gone some other way simply falls back to the built-in name. If
|
||||||
|
that is gone too, the provider's first preset by name is used. The Windows build
|
||||||
|
does not read this file yet, and keeps the built-in names.
|
||||||
|
|
||||||
Editing the active preset re-applies it straight away. For `preset set` and
|
Editing the active preset re-applies it straight away. For `preset set` and
|
||||||
`preset all` that happens **without** asking about running sessions: a switch
|
`preset all` that happens **without** asking about running sessions: a switch
|
||||||
|
|||||||
+79
-5
@@ -18,6 +18,7 @@ CM_BACKUPS="$CM_ROOT/backups"
|
|||||||
CM_STATE="$CM_ROOT/state.json"
|
CM_STATE="$CM_ROOT/state.json"
|
||||||
CM_IGNORED="$CM_ROOT/ignored-sessions.json"
|
CM_IGNORED="$CM_ROOT/ignored-sessions.json"
|
||||||
CM_MODELS_CACHE="$CM_ROOT/models-cache.json"
|
CM_MODELS_CACHE="$CM_ROOT/models-cache.json"
|
||||||
|
CM_DEFAULTS="$CM_ROOT/defaults.json"
|
||||||
CM_SETTINGS_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
|
CM_SETTINGS_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
|
||||||
CM_SETTINGS="$CM_SETTINGS_DIR/settings.json"
|
CM_SETTINGS="$CM_SETTINGS_DIR/settings.json"
|
||||||
CM_HELPER="$CM_BIN/claude-key-helper.sh"
|
CM_HELPER="$CM_BIN/claude-key-helper.sh"
|
||||||
@@ -269,6 +270,8 @@ claude-mode - switch Claude Code between Anthropic, OpenRouter, Z.AI, LM Studio
|
|||||||
claude-mode preset new <name> --provider <p> [--blank]
|
claude-mode preset new <name> --provider <p> [--blank]
|
||||||
copy that provider's default, or start empty
|
copy that provider's default, or start empty
|
||||||
claude-mode preset rename <name> <new-name>
|
claude-mode preset rename <name> <new-name>
|
||||||
|
claude-mode preset default [provider] [name|--clear]
|
||||||
|
which preset 'claude-mode <provider>' picks
|
||||||
claude-mode preset set <name> <tier> <model-id>
|
claude-mode preset set <name> <tier> <model-id>
|
||||||
claude-mode preset all <name> <model-id>
|
claude-mode preset all <name> <model-id>
|
||||||
claude-mode preset url <name> <base-url> point a preset at another server
|
claude-mode preset url <name> <base-url> point a preset at another server
|
||||||
@@ -359,7 +362,12 @@ term_cols() {
|
|||||||
printf '%s' "$c"
|
printf '%s' "$c"
|
||||||
}
|
}
|
||||||
|
|
||||||
default_preset_for() {
|
# The preset `claude-mode <provider>` uses when none is named: the one chosen
|
||||||
|
# with `preset default`, while its file still exists, else the built-in name.
|
||||||
|
# The existence test is what lets a stale choice degrade instead of break.
|
||||||
|
# cm-json.py's BUILTIN_DEFAULT_PRESET and the widget's Modes.DEFAULT_PRESET
|
||||||
|
# mirror the built-in names.
|
||||||
|
builtin_default_preset() {
|
||||||
case "$1" in
|
case "$1" in
|
||||||
openrouter) printf 'default' ;;
|
openrouter) printf 'default' ;;
|
||||||
zai) printf 'zai' ;;
|
zai) printf 'zai' ;;
|
||||||
@@ -367,6 +375,15 @@ default_preset_for() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default_preset_for() {
|
||||||
|
local chosen
|
||||||
|
chosen="$(jget "$CM_DEFAULTS" "$1")"
|
||||||
|
if [ -n "$chosen" ] && valid_preset_name "$chosen" && [ -f "$(preset_path "$chosen")" ]; then
|
||||||
|
printf '%s' "$chosen"; return 0
|
||||||
|
fi
|
||||||
|
builtin_default_preset "$1"
|
||||||
|
}
|
||||||
|
|
||||||
resolve_preset() {
|
resolve_preset() {
|
||||||
local provider="$1" requested="${2:-}" fallback first
|
local provider="$1" requested="${2:-}" fallback first
|
||||||
if [ -n "$requested" ]; then
|
if [ -n "$requested" ]; then
|
||||||
@@ -1571,6 +1588,7 @@ cmd_preset() {
|
|||||||
rm -f "$(preset_path "$name")"; return 1; }
|
rm -f "$(preset_path "$name")"; return 1; }
|
||||||
ok "created blank $provider preset '$name'"
|
ok "created blank $provider preset '$name'"
|
||||||
say 'every tier is empty: set them with claude-mode preset set, or the bar panel'
|
say 'every tier is empty: set them with claude-mode preset set, or the bar panel'
|
||||||
|
write_health "$(state_mode)" "$(state_preset)"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1588,6 +1606,7 @@ cmd_preset() {
|
|||||||
fi
|
fi
|
||||||
cp "$(preset_path "$from")" "$(preset_path "$name")"
|
cp "$(preset_path "$from")" "$(preset_path "$name")"
|
||||||
ok "created $(preset_path "$name") from '$from'"
|
ok "created $(preset_path "$name") from '$from'"
|
||||||
|
write_health "$(state_mode)" "$(state_preset)"
|
||||||
;;
|
;;
|
||||||
rename)
|
rename)
|
||||||
local new="${3:-}" out
|
local new="${3:-}" out
|
||||||
@@ -1596,14 +1615,17 @@ cmd_preset() {
|
|||||||
[ -f "$(preset_path "$name")" ] || { err "preset '$name' not found"; return 1; }
|
[ -f "$(preset_path "$name")" ] || { err "preset '$name' not found"; return 1; }
|
||||||
[ "$name" = "$new" ] && { ok "already called '$new'"; return 0; }
|
[ "$name" = "$new" ] && { ok "already called '$new'"; return 0; }
|
||||||
[ -e "$(preset_path "$new")" ] && { err "preset '$new' already exists"; return 1; }
|
[ -e "$(preset_path "$new")" ] && { err "preset '$new' already exists"; return 1; }
|
||||||
out="$("$PY" "$JSON" preset-rename "$CM_PRESETS" "$name" "$new" "$CM_STATE" 2>&1)" || {
|
out="$("$PY" "$JSON" preset-rename "$CM_PRESETS" "$name" "$new" "$CM_STATE" "$CM_DEFAULTS" 2>&1)" || {
|
||||||
err "$out"; return 1; }
|
err "$out"; return 1; }
|
||||||
ok "renamed '$name' -> '$new'"
|
ok "renamed '$name' -> '$new'"
|
||||||
case "$out" in
|
case "$out" in
|
||||||
*'"active": true'*)
|
*'"active": true'*)
|
||||||
say 'it is the active preset; state.json now names it, and running sessions keep working'
|
say 'it is the active preset; state.json now names it, and running sessions keep working' ;;
|
||||||
write_health "$(state_mode)" "$new" ;;
|
|
||||||
esac
|
esac
|
||||||
|
case "$out" in
|
||||||
|
*'"default": true'*) say 'it was chosen as its provider'"'"'s default, and that follows the new name' ;;
|
||||||
|
esac
|
||||||
|
write_health "$(state_mode)" "$(state_preset)"
|
||||||
;;
|
;;
|
||||||
rm)
|
rm)
|
||||||
[ -n "$name" ] || { err 'usage: claude-mode preset rm <name>'; return 1; }
|
[ -n "$name" ] || { err 'usage: claude-mode preset rm <name>'; return 1; }
|
||||||
@@ -1613,12 +1635,62 @@ cmd_preset() {
|
|||||||
fi
|
fi
|
||||||
local prov; prov="$(jget "$(preset_path "$name")" provider)"; [ -z "$prov" ] && prov=openrouter
|
local prov; prov="$(jget "$(preset_path "$name")" provider)"; [ -z "$prov" ] && prov=openrouter
|
||||||
rm -f "$(preset_path "$name")"; ok "deleted preset '$name'"
|
rm -f "$(preset_path "$name")"; ok "deleted preset '$name'"
|
||||||
|
if [ "$(jget "$CM_DEFAULTS" "$prov")" = "$name" ]; then
|
||||||
|
"$PY" "$JSON" set-default "$CM_DEFAULTS" "$prov" "" >/dev/null
|
||||||
|
say "it was the chosen default for $prov; 'claude-mode $prov' means '$(resolve_preset "$prov" 2>/dev/null || printf 'nothing')' now"
|
||||||
|
fi
|
||||||
# Allowed, but not quietly: with no preset left, `claude-mode <provider>`
|
# Allowed, but not quietly: with no preset left, `claude-mode <provider>`
|
||||||
# has nothing to resolve to.
|
# has nothing to resolve to.
|
||||||
if [ -z "$(presets_for_provider "$prov")" ]; then
|
if [ -z "$(presets_for_provider "$prov")" ]; then
|
||||||
warn "that was the last $prov preset - 'claude-mode $prov' has nothing to switch to now"
|
warn "that was the last $prov preset - 'claude-mode $prov' has nothing to switch to now"
|
||||||
say "create one with: claude-mode preset new <name> --provider $prov [--blank]"
|
say "create one with: claude-mode preset new <name> --provider $prov [--blank]"
|
||||||
fi
|
fi
|
||||||
|
write_health "$(state_mode)" "$(state_preset)"
|
||||||
|
;;
|
||||||
|
default)
|
||||||
|
# Which preset `claude-mode <provider>` means when none is named.
|
||||||
|
local prov="$name" target="${3:-}" p cur got
|
||||||
|
if [ -z "$prov" ]; then
|
||||||
|
head_ 'default preset per provider'
|
||||||
|
for p in openrouter zai lmstudio; do
|
||||||
|
cur="$(jget "$CM_DEFAULTS" "$p")"
|
||||||
|
if [ -n "$cur" ] && [ -f "$(preset_path "$cur")" ]; then
|
||||||
|
printf ' %-11s %s (chosen)\n' "$p" "$cur"
|
||||||
|
else
|
||||||
|
# "built-in" only when it really is the built-in name;
|
||||||
|
# with that preset gone, resolve_preset takes the first.
|
||||||
|
local got_p why
|
||||||
|
got_p="$(resolve_preset "$p" 2>/dev/null)" || got_p=''
|
||||||
|
if [ -z "$got_p" ]; then why='no preset left'
|
||||||
|
elif [ "$got_p" = "$(builtin_default_preset "$p")" ]; then why='built-in'
|
||||||
|
else why='first by name'; fi
|
||||||
|
printf ' %-11s %s (%s%s)\n' "$p" "${got_p:--}" "$why" \
|
||||||
|
"$([ -n "$cur" ] && printf "; chosen '%s' no longer exists" "$cur")"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
printf '\n %sclaude-mode preset default <provider> <name> (or --clear)%s\n' "$C_DIM" "$C_RESET"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
case "$prov" in
|
||||||
|
openrouter|zai|lmstudio) ;;
|
||||||
|
*) err "unknown provider '$prov' - openrouter, zai or lmstudio"; return 1 ;;
|
||||||
|
esac
|
||||||
|
if [ -z "$target" ]; then
|
||||||
|
resolve_preset "$prov" && printf '\n'
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [ "$target" = "--clear" ]; then
|
||||||
|
"$PY" "$JSON" set-default "$CM_DEFAULTS" "$prov" "" >/dev/null || return 1
|
||||||
|
ok "$prov : no longer chosen; 'claude-mode $prov' means '$(resolve_preset "$prov" 2>/dev/null || printf 'nothing - no preset left')'"
|
||||||
|
else
|
||||||
|
valid_preset_name "$target" || { err "invalid preset name '$target'"; return 1; }
|
||||||
|
[ -f "$(preset_path "$target")" ] || { err "preset '$target' not found"; return 1; }
|
||||||
|
got="$(jget "$(preset_path "$target")" provider)"; [ -z "$got" ] && got=openrouter
|
||||||
|
[ "$got" = "$prov" ] || { err "'$target' is for $got, not $prov"; return 1; }
|
||||||
|
"$PY" "$JSON" set-default "$CM_DEFAULTS" "$prov" "$target" >/dev/null || return 1
|
||||||
|
ok "$prov : 'claude-mode $prov' now means '$target'"
|
||||||
|
fi
|
||||||
|
write_health "$(state_mode)" "$(state_preset)"
|
||||||
;;
|
;;
|
||||||
set)
|
set)
|
||||||
local tier="${3:-}" model="${4:-}"
|
local tier="${3:-}" model="${4:-}"
|
||||||
@@ -1913,7 +1985,9 @@ UI_PICKED=''
|
|||||||
ui_pick_preset() {
|
ui_pick_preset() {
|
||||||
local provider="$1" def names name
|
local provider="$1" def names name
|
||||||
UI_PICKED=''
|
UI_PICKED=''
|
||||||
def="$(default_preset_for "$provider")"
|
# resolve_preset, not default_preset_for: the mark should land on whatever
|
||||||
|
# `claude-mode <provider>` would actually pick, fallbacks included.
|
||||||
|
def="$(resolve_preset "$provider" 2>/dev/null)"
|
||||||
names=()
|
names=()
|
||||||
while IFS= read -r name; do names+=("$name"); done < <(presets_for_provider "$provider")
|
while IFS= read -r name; do names+=("$name"); done < <(presets_for_provider "$provider")
|
||||||
[ "${#names[@]}" -gt 0 ] || { err "no presets for '$provider'"; return 1; }
|
[ "${#names[@]}" -gt 0 ] || { err "no presets for '$provider'"; return 1; }
|
||||||
|
|||||||
+69
-4
@@ -17,8 +17,9 @@ Subcommands:
|
|||||||
scan-sessions <projects> [max-age-days] [ignored] broken transcripts, as JSON
|
scan-sessions <projects> [max-age-days] [ignored] broken transcripts, as JSON
|
||||||
ignore-session <ignored> <projects> add|remove|clear|list [id]
|
ignore-session <ignored> <projects> add|remove|clear|list [id]
|
||||||
cache-models <cache> <provider> <1|0> [baseUrl] store a TSV catalogue (stdin)
|
cache-models <cache> <provider> <1|0> [baseUrl] store a TSV catalogue (stdin)
|
||||||
preset-rename <presets-dir> <old> <new> <state> rename, repointing state.json
|
preset-rename <dir> <old> <new> <state> [defaults] rename, repointing state + default
|
||||||
auth-of <preset> "mode<TAB>keyRef"; fails if missing
|
auth-of <preset> "mode<TAB>keyRef"; fails if missing
|
||||||
|
set-default <defaults> <provider> [name] choose (or clear) a provider default
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import glob
|
import glob
|
||||||
@@ -62,6 +63,10 @@ BASE_MANAGED = [
|
|||||||
|
|
||||||
TIERS = ["opus", "sonnet", "haiku", "fable"]
|
TIERS = ["opus", "sonnet", "haiku", "fable"]
|
||||||
|
|
||||||
|
# Mirrors builtin_default_preset() in the CLI: what `claude-mode <provider>`
|
||||||
|
# picks when no preset is named and none has been chosen with `preset default`.
|
||||||
|
BUILTIN_DEFAULT_PRESET = {"openrouter": "default", "zai": "zai", "lmstudio": "lmstudio"}
|
||||||
|
|
||||||
|
|
||||||
def load(path, default=None):
|
def load(path, default=None):
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
@@ -269,15 +274,36 @@ def cmd_auth_of(argv):
|
|||||||
print("%s\t%s" % (auth.get("mode") or "vault", auth.get("keyRef") or "openrouter"))
|
print("%s\t%s" % (auth.get("mode") or "vault", auth.get("keyRef") or "openrouter"))
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_set_default(argv):
|
||||||
|
"""set-default <defaults.json> <provider> [name] - an empty name clears it."""
|
||||||
|
path, prov = argv[0], argv[1]
|
||||||
|
name = argv[2] if len(argv) > 2 else ""
|
||||||
|
try:
|
||||||
|
d = load(path, {})
|
||||||
|
except (OSError, ValueError):
|
||||||
|
d = {}
|
||||||
|
if not isinstance(d, dict):
|
||||||
|
d = {}
|
||||||
|
if name:
|
||||||
|
d[prov] = name
|
||||||
|
else:
|
||||||
|
d.pop(prov, None)
|
||||||
|
save(path, d)
|
||||||
|
print(json.dumps(d))
|
||||||
|
|
||||||
|
|
||||||
def cmd_preset_rename(argv):
|
def cmd_preset_rename(argv):
|
||||||
"""preset-rename <presets-dir> <old> <new> <state.json>
|
"""preset-rename <presets-dir> <old> <new> <state.json> [defaults.json]
|
||||||
|
|
||||||
Every running session's key helper resolves the active preset through
|
Every running session's key helper resolves the active preset through
|
||||||
state.json on each key fetch, so at no instant may state.json name a file
|
state.json on each key fetch, so at no instant may state.json name a file
|
||||||
that is not there. The new name is linked in first, state.json repointed,
|
that is not there. The new name is linked in first, state.json repointed,
|
||||||
and only then does the old name go. Prints {"renamed", "active"}.
|
and only then does the old name go. A provider default chosen with
|
||||||
|
`preset default` follows the rename too. Prints {"renamed", "active",
|
||||||
|
"default"}.
|
||||||
"""
|
"""
|
||||||
d, old, new, state_path = argv[:4]
|
d, old, new, state_path = argv[:4]
|
||||||
|
defaults_path = argv[4] if len(argv) > 4 else ""
|
||||||
src = os.path.join(d, old + ".json")
|
src = os.path.join(d, old + ".json")
|
||||||
dst = os.path.join(d, new + ".json")
|
dst = os.path.join(d, new + ".json")
|
||||||
if not os.path.isfile(src):
|
if not os.path.isfile(src):
|
||||||
@@ -295,8 +321,21 @@ def cmd_preset_rename(argv):
|
|||||||
state["preset"] = new
|
state["preset"] = new
|
||||||
save(state_path, state)
|
save(state_path, state)
|
||||||
|
|
||||||
|
moved = []
|
||||||
|
if defaults_path:
|
||||||
|
try:
|
||||||
|
defaults = load(defaults_path, {})
|
||||||
|
except (OSError, ValueError):
|
||||||
|
defaults = {}
|
||||||
|
if isinstance(defaults, dict):
|
||||||
|
moved = [p for p, n in defaults.items() if n == old]
|
||||||
|
if moved:
|
||||||
|
for p in moved:
|
||||||
|
defaults[p] = new
|
||||||
|
save(defaults_path, defaults)
|
||||||
|
|
||||||
os.unlink(src)
|
os.unlink(src)
|
||||||
print(json.dumps({"renamed": True, "active": active}))
|
print(json.dumps({"renamed": True, "active": active, "default": bool(moved)}))
|
||||||
|
|
||||||
|
|
||||||
def cmd_get(argv):
|
def cmd_get(argv):
|
||||||
@@ -610,6 +649,31 @@ def cmd_health(argv):
|
|||||||
})
|
})
|
||||||
h["presets"] = catalogue
|
h["presets"] = catalogue
|
||||||
|
|
||||||
|
# Which preset `claude-mode <provider>` picks when none is named, in the
|
||||||
|
# CLI's own order (default_preset_for, then resolve_preset): the chosen one
|
||||||
|
# while its file exists, else the built-in name if that exists, else the
|
||||||
|
# first by name. `defaultPresetChosen` holds only the explicit choices, so a
|
||||||
|
# reader can tell a choice it could clear from the built-in fallback.
|
||||||
|
names = {c["name"] for c in catalogue}
|
||||||
|
try:
|
||||||
|
chosen_raw = load(os.path.join(root, "defaults.json"), {})
|
||||||
|
except (OSError, ValueError):
|
||||||
|
chosen_raw = {}
|
||||||
|
if not isinstance(chosen_raw, dict):
|
||||||
|
chosen_raw = {}
|
||||||
|
effective, chosen = {}, {}
|
||||||
|
for prov, builtin in BUILTIN_DEFAULT_PRESET.items():
|
||||||
|
pick = chosen_raw.get(prov)
|
||||||
|
if pick and pick in names:
|
||||||
|
effective[prov] = chosen[prov] = pick
|
||||||
|
elif builtin in names:
|
||||||
|
effective[prov] = builtin
|
||||||
|
else:
|
||||||
|
mine = sorted(c["name"] for c in catalogue if c["provider"] == prov)
|
||||||
|
effective[prov] = mine[0] if mine else ""
|
||||||
|
h["defaultPresetFor"] = effective
|
||||||
|
h["defaultPresetChosen"] = chosen
|
||||||
|
|
||||||
save(os.path.join(root, "health.json"), h)
|
save(os.path.join(root, "health.json"), h)
|
||||||
|
|
||||||
|
|
||||||
@@ -1227,6 +1291,7 @@ COMMANDS = {
|
|||||||
"scaffold": cmd_scaffold,
|
"scaffold": cmd_scaffold,
|
||||||
"preset-rename": cmd_preset_rename,
|
"preset-rename": cmd_preset_rename,
|
||||||
"auth-of": cmd_auth_of,
|
"auth-of": cmd_auth_of,
|
||||||
|
"set-default": cmd_set_default,
|
||||||
"get": cmd_get,
|
"get": cmd_get,
|
||||||
"presets": cmd_presets,
|
"presets": cmd_presets,
|
||||||
"managed": cmd_managed,
|
"managed": cmd_managed,
|
||||||
|
|||||||
@@ -317,7 +317,27 @@ Panel {
|
|||||||
property string editTier: ""
|
property string editTier: ""
|
||||||
property string editModel: ""
|
property string editModel: ""
|
||||||
|
|
||||||
|
// Which preset `claude-mode <provider>` picks when none is named. The CLI
|
||||||
|
// publishes it now that it can be chosen; the built-in names in Modes.js
|
||||||
|
// are only the fallback for a health.json written by an older CLI.
|
||||||
|
readonly property var defaultPresets: {
|
||||||
|
var out = {}
|
||||||
|
var builtin = Modes.DEFAULT_PRESET
|
||||||
|
for (var b in builtin) out[b] = builtin[b]
|
||||||
|
var pub = health && health.defaultPresetFor ? health.defaultPresetFor : null
|
||||||
|
if (pub) for (var p in pub) if (pub[p]) out[p] = pub[p]
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
readonly property var chosenDefaults: health && health.defaultPresetChosen ? health.defaultPresetChosen : ({})
|
||||||
|
|
||||||
readonly property var editEntry: root.editPreset !== "" ? root.presetEntry(root.editPreset) : null
|
readonly property var editEntry: root.editPreset !== "" ? root.presetEntry(root.editPreset) : null
|
||||||
|
readonly property bool editIsDefault: root.editPreset !== "" && root.defaultPresets[root.editProvider] === root.editPreset
|
||||||
|
readonly property bool editIsChosenDefault: root.editPreset !== "" && root.chosenDefaults[root.editProvider] === root.editPreset
|
||||||
|
|
||||||
|
function setDefault(on) {
|
||||||
|
root.runOps("saving", [on ? ["preset", "default", root.editProvider, root.editPreset]
|
||||||
|
: ["preset", "default", root.editProvider, "--clear"]], "preset")
|
||||||
|
}
|
||||||
readonly property string editProvider: editEntry ? String(editEntry.provider) : ""
|
readonly property string editProvider: editEntry ? String(editEntry.provider) : ""
|
||||||
readonly property bool editIsActive: root.mode !== "anthropic" && root.editPreset !== "" && root.editPreset === root.preset
|
readonly property bool editIsActive: root.mode !== "anthropic" && root.editPreset !== "" && root.editPreset === root.preset
|
||||||
|
|
||||||
@@ -847,7 +867,7 @@ Panel {
|
|||||||
readonly property string thisMode: String(modelData)
|
readonly property string thisMode: String(modelData)
|
||||||
readonly property bool isCurrent: thisMode === root.mode
|
readonly property bool isCurrent: thisMode === root.mode
|
||||||
readonly property bool isExpanded: root.expandedMode === thisMode
|
readonly property bool isExpanded: root.expandedMode === thisMode
|
||||||
readonly property var presetList: Modes.presetsFor(root.health, thisMode, Modes.DEFAULT_PRESET)
|
readonly property var presetList: Modes.presetsFor(root.health, thisMode, root.defaultPresets)
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -968,10 +988,24 @@ Panel {
|
|||||||
font.bold: presetRow.isActive
|
font.bold: presetRow.isActive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only worth saying when there is a choice to tell apart.
|
||||||
|
Text {
|
||||||
|
id: defaultTag
|
||||||
|
visible: modeEntry.presetList.length > 1
|
||||||
|
&& String(presetRow.modelData.name) === root.defaultPresets[modeEntry.thisMode]
|
||||||
|
anchors.left: presetName.right
|
||||||
|
anchors.leftMargin: Style.space(6)
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: "default"
|
||||||
|
color: Color.muted
|
||||||
|
font.family: root.bar ? root.bar.fontFamily : Style.font.family
|
||||||
|
font.pixelSize: Style.space(9)
|
||||||
|
}
|
||||||
|
|
||||||
// The opus mapping is the one that tells you what you are
|
// The opus mapping is the one that tells you what you are
|
||||||
// about to be talking to; the rest is in the tooltip.
|
// about to be talking to; the rest is in the tooltip.
|
||||||
Text {
|
Text {
|
||||||
anchors.left: presetName.right
|
anchors.left: defaultTag.visible ? defaultTag.right : presetName.right
|
||||||
anchors.leftMargin: Style.space(8)
|
anchors.leftMargin: Style.space(8)
|
||||||
anchors.right: gearButton.visible ? gearButton.left : parent.right
|
anchors.right: gearButton.visible ? gearButton.left : parent.right
|
||||||
anchors.rightMargin: Style.space(4)
|
anchors.rightMargin: Style.space(4)
|
||||||
@@ -1311,6 +1345,17 @@ Panel {
|
|||||||
font.pixelSize: Style.space(10)
|
font.pixelSize: Style.space(10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
width: parent.width
|
||||||
|
visible: root.editIsDefault
|
||||||
|
text: "claude-mode " + root.editProvider + " picks this one when no preset is named"
|
||||||
|
+ (root.editIsChosenDefault ? "." : " (the built-in choice).")
|
||||||
|
color: Color.muted
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
font.family: root.bar ? root.bar.fontFamily : Style.font.family
|
||||||
|
font.pixelSize: Style.space(10)
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Style.space(1)
|
spacing: Style.space(1)
|
||||||
@@ -1392,6 +1437,8 @@ Panel {
|
|||||||
visible: root.editProvider === "lmstudio"
|
visible: root.editProvider === "lmstudio"
|
||||||
onTriggered: root.openServerSettings(root.editPreset, "preset")
|
onTriggered: root.openServerSettings(root.editPreset, "preset")
|
||||||
}
|
}
|
||||||
|
PillButton { label: "Make default"; visible: !root.editIsDefault; onTriggered: root.setDefault(true) }
|
||||||
|
PillButton { label: "Clear default"; visible: root.editIsChosenDefault; onTriggered: root.setDefault(false) }
|
||||||
PillButton { label: "Duplicate…"; onTriggered: root.openNewPreset(root.editProvider, root.editPreset) }
|
PillButton { label: "Duplicate…"; onTriggered: root.openNewPreset(root.editProvider, root.editPreset) }
|
||||||
PillButton { label: "Rename…"; onTriggered: root.openRename() }
|
PillButton { label: "Rename…"; onTriggered: root.openRename() }
|
||||||
// The CLI refuses to delete the preset in use. A button that always
|
// The CLI refuses to delete the preset in use. A button that always
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"schemaVersion": 1,
|
"schemaVersion": 1,
|
||||||
"id": "smoido.claude-mode",
|
"id": "smoido.claude-mode",
|
||||||
"name": "Claude Mode",
|
"name": "Claude Mode",
|
||||||
"version": "1.10.0",
|
"version": "1.11.0",
|
||||||
"author": "smoido",
|
"author": "smoido",
|
||||||
"description": "Which provider Claude Code is pointed at, and a one-click switch between them",
|
"description": "Which provider Claude Code is pointed at, and a one-click switch between them",
|
||||||
"kinds": ["bar-widget"],
|
"kinds": ["bar-widget"],
|
||||||
|
|||||||
Reference in New Issue
Block a user