Files
ccs/ui
Kenneth Wong 02c45e088a fix(extended-context): suffix the Fable tier and default it on 1M launches
The previous commit assumed Claude Code's fable resolver strips [1m] and
therefore never wrote the suffix into ANTHROPIC_DEFAULT_FABLE_MODEL. That
premise only holds when ANTHROPIC_BASE_URL is unset or points at
api.anthropic.com. Behind a proxy (CLIProxy, headroom, ...) Claude Code
2.1.259 does the opposite:

- the fable alias resolver passes the env value through untouched, so a
  saved `claude-fable-5-1[1m]` reaches the model picker as-is;
- the context-window resolver grants 1M unconditionally when the model id
  carries [1m], and otherwise trusts a natively-1M model only when the base
  URL is first-party. Bare `claude-fable-5-1` via 127.0.0.1 is clamped to
  200k even though CLIProxy's /v1/models advertises max_input_tokens 1M.

So the suffix is the only thing that turns the long window on for CCS, and
stripping it from the Fable key is what kept `ccs claude --model fable` at
200k. A headroom settings profile with the suffix saved on that key showed
the 1M window in the same Claude Code build, which is how the inversion was
caught.

Changes:

- Drop the suffix-stripping key guard; ANTHROPIC_DEFAULT_FABLE_MODEL now
  receives and keeps [1m] exactly like the opus/sonnet tiers.
- On a long-context launch (explicit --1m, or a saved [1m] on any Anthropic
  tier key) fill a missing Fable tier with the catalog Fable model plus
  [1m]. The model-neutral claude profile pins no Fable model, so `--model
  fable` used to fall back to Claude Code's bare default and lose the window
  even when every other tier asked for 1M. An explicit mapping always wins,
  --no-1m never fills, and providers without a catalog Fable model are left
  alone.
- Add getDefaultFableTierModel() to the model catalog for that default.

Verified with a stub Claude binary that dumps its environment:

  ccs claude --model fable          -> ANTHROPIC_DEFAULT_FABLE_MODEL=claude-fable-5-1[1m]
  ccs claude --1m                   -> ANTHROPIC_DEFAULT_FABLE_MODEL=claude-fable-5-1[1m]
  ccs claude --no-1m --model fable  -> no Fable tier written, ANTHROPIC_MODEL stripped
2026-09-04 02:48:15 +08:00
..

CCS Dashboard UI

React, TypeScript, and Vite frontend for the local dashboard served by the CCS web server through:

ccs config

Development

From the repository root, build the server and open the integrated dashboard:

bun run dev

Pass a host explicitly when testing network access:

bun run dev -- --host 0.0.0.0
bun run dev -- --host 127.0.0.1

For the frontend-only Vite server:

cd ui
bun run dev

Root and UI scripts are defined in ../package.json and package.json.

Source Ownership

Area Path
Route-level pages src/pages/
Domain and shared components src/components/
Server-state hooks src/hooks/
Cross-page context/providers src/contexts/ and src/providers/
API, localization, catalogs, helpers src/lib/
UI tests tests/ and colocated tests

Follow the owning domain's existing import pattern. Barrel exports are optional, not required at every directory level.

Quality Commands

cd ui
bun run format
bun run typecheck
bun run lint
bun run validate
bun run test:run

bun run validate currently runs typecheck, lint with fixes, and the format check. UI tests run with Vitest; use test, test:run, test:coverage, or test:ui as defined in package.json.

Localization

Dashboard localization uses react-i18next.

Concern Source
Supported locales, normalization, fallback, persistence src/lib/locales.ts
i18next setup and translation resources src/lib/i18n.ts
Language switcher src/components/layout/language-switcher.tsx

English is the fallback. The selected locale is stored in browser local storage under ccs-ui-locale. Treat src/lib/locales.ts as the complete source of truth for supported locale codes. When adding or removing a locale, update the translation resources, switcher, tests, and dashboard i18n guide in the same change.