feat(web): generate Claude Code settings for all model tiers#227
Merged
Conversation
Expand the dashboard's Claude Code setup helper from three tiers to four (Fable / Opus / Sonnet / Haiku) and switch the emitted format from shell exports to a JSON `env` fragment for `~/.claude/settings.json`. Fable is Claude Code's new top tier above Opus; missing it left users without a way to route the CLI's Fable slot through Floway. Missing the Opus slot meant the CLI fell back to its built-in default opus id instead of a Floway-catalogued one. Shell exports also don't reach background agents reliably — the supervisor only forwards them when it was started from the same gateway environment and dispatched into the current cwd; @repo / --cwd and the SDK / -p paths drop them. settings.json's `env` block is the only channel that covers every execution context. Emit only the `env` sub-object so users paste it into an existing settings file without clobbering unrelated top-level keys. Also collapse the three ad-hoc tier sort helpers into one distance-to-target factory used for all four buckets, and drop ANTHROPIC_MODEL (redundant with the per-tier defaults).
The Haiku slot's identifiers were still named 'small' from when the picker only distinguished big/sonnet/small. Now that Fable / Opus / Sonnet / Haiku are four peer tiers, the odd-one-out naming is misleading — align on the tier name.
Replace four per-tier `claudeModels{Fable,Opus,Sonnet,Haiku}` computeds,
four `claude{...}Model` refs, four inline watchEffect fallback lines, and
four near-identical `<div>` slots with a `CLAUDE_TIER_KEYS` tuple, a
single `claudeModelsByTier: Record<ClaudeTierKey, string[]>` computed, a
`claudeSelection` reactive record, and one `v-for` template block. This
mirrors the peer `v-for="key in PATH_KEYS"` + bracket-indexed
`Record<PathKey, ...>` shape already in use in
`upstream-edit/CustomConfigPanel.vue` (with its `PATH_KEYS as const`
tuple in `customConfig.ts`). The four `ANTHROPIC_DEFAULT_<TIER>_MODEL`
env keys stay explicit for grep-ability, and Haiku's no-`addCtx`
asymmetry is preserved.
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.
Summary
ANTHROPIC_DEFAULT_FABLE_MODEL/ANTHROPIC_DEFAULT_OPUS_MODELenv vars now have picker slots.{ "env": { ... } }fragment for merging into~/.claude/settings.json(user-scope) or.claude/settings.json(project-scope), instead of the previousexport-style shell block. Claude Code's background-agent supervisor does not reliably inherit shell env —settings.jsonis the only channel that reaches every execution context (SDK,-p, cross-cwd dispatch, background sessions).ANTHROPIC_MODELvar: it duplicated whichever per-tier slot was chosen as the startup default, and the four explicitANTHROPIC_DEFAULT_*_MODELvars now cover the same ground with tier-clear semantics.[1m]context-window suffix on Fable/Opus/Sonnet slots; keep the Haiku slot plain regardless of which model id is picked — Haiku is the background/tool-call tier where 1M-context cost is not warranted.small->haikuto match the tier vocabulary, inline the four single-usesortClaude*comparators, renamecodexModelsList->codexModelsto match the sibling naming convention, and collapse the four parallel Claude tier bindings into a table-drivenCLAUDE_TIER_KEYStuple +Record<TierKey, string>selection.Test plan
vue-tsc --noEmitclean (typecheck)eslint apps/web/src/components/keys/CliSnippet.vueclean{ "env": { ... } }with exactly six keys and noANTHROPIC_MODEL;[1m]suffix appears on Fable/Opus/Sonnet values only.claude-fable-5) keepsANTHROPIC_DEFAULT_HAIKU_MODELplain (no[1m]) while the other three slots retain their[1m]suffixes — confirms the context-suffix asymmetry is per-slot, not per-picked-model.