- New data-theme-badge axis (default/lg/xl, site default lg) with config
drawer section, cookie persistence, and unlayered CSS overrides; unpin
h-5! on model badge so the setting takes effect
- Right-align and unify type ramp of compound cells inside mobile log
card rows via in-data-[slot=data-table-card-value] variants
- Fix skeleton overflow on narrow screens at call sites (min-w-0,
shrink-0, max-w-full) and mirror real toolbar/stat layouts
- Show theme settings trigger on mobile header
- Replace native datetime-local inputs with a shadcn Calendar range picker:
preset rail (today/7d/this~last week/30d/this~last month), dual-month
desktop view, themed time inputs, fresh-range reselect, no outside days
- Default log time range now covers the whole current day (00:00-23:59:59)
- Fix range highlight invisible inside popovers (muted -> accent) and mark
today by primary text instead of a fill that mimicked selection
- Extract shared calendar locale map (adds zh-TW) for all date pickers
- Generalize disabled-row treatment into status row palettes (error/info/
warning) and apply them to usage-logs desktop rows and mobile cards
- Split "Earned this month" from "This month" i18n key to stop the check-in
card translation leaking into date presets
Show the retry chain as compact grey inline text next to the channel
badge (middle-collapsed beyond three hops, full chain in the tooltip)
instead of hiding it behind a popover icon. Move the model-mapping route
marker inside the badge's trailing icon slot, size the mapping popover
to its content, and make both model names copyable. Group ratio now
hides together with the group name when sensitive info is masked.
Derive --color-identity-* tokens from theme palette variables (chart and
status hues) instead of fixed oklch hues, so group names, channel ids and
model badges re-tint automatically when a color preset overrides the
palette. The monochrome simple-large preset collapses identity tints to
the foreground via --identity-color-mix: 0%.
Also port main's blue default palette (light/dark), preview the default
preset as a rainbow swatch, and show the token group as a tinted
GroupBadge on the usage-logs page.
Rework the earlier dropdown onSelect bridge: keep components/ui pristine
and use Base UI's native closeOnClick={false} + onClick at the nine menu
item call sites instead. Move product policies dropped by the refactor
into the design-system adapters: Button restores nativeButton detection
for render={<Link/>}, Select restores the mobile inline (no portal)
popup and the select-item-text wrapping slot.
Also restore behaviors lost in the refactor: page-size preference falls
back to and mirrors the legacy classic-theme key, background refresh
blocks interaction with stale rows again, pricing table rows are
keyboard accessible, and the pricing card grid resets to page 1 when
filters change.
The design-system consolidation refactor dropped the onSelect-to-onClick
bridge for Base UI menu items, silently breaking menu actions such as
'Delete All Disabled' on the channels page, and removed the 'Internal ID'
translation key still used by the task details dialog.
Persist committed editor drafts to the source model during batch copy so
targets never carry pricing the source would lose, surface loading/error
states for the enabled-models query, and compare saved* props in the
visual editor memo so rows leave the unset list reliably after save.
The task-log and MJ task ID cells used a w-max wrapper, so long IDs
(and the platform/action subtitle) overflowed the column and rendered
under the adjacent Cost column. Constrain the cell to the column width
and let the badge label ellipsize; the copy button still copies the
full ID.
Merge origin/main (48068ce92). The backend billing feature merged
cleanly; the single frontend conflict was a grid ratio tweak to the
old-design mobile log card, which does not exist in our generic
card layout, so our version is kept.
Parse OpenAI's native cache_write_tokens (chat prompt_tokens_details /
responses input_tokens_details), bill it at the cache-creation ratio, and
clamp the uncached prompt remainder at zero since cached + cache-write can
exceed prompt_tokens. Propagate the field through chat/responses/claude
format conversions and tiered expression billing (cc variable).
Merge origin/main (c36418c86, text protocol conversion and advanced
custom routing). Backend and most frontend changes merged cleanly;
conflicts resolved with refactor/ui as the design source of truth:
- advanced-custom-editor-dialog: keep main new routing/conversion
feature body, but use our design-system Button/Input imports and
plain button styling; add the Badge import the new body needs
- details-dialog: adopt main isUsageBillingPathLocal helper for the
billing path row, keep our muted icon styling
- i18n: union-merge of the new protocol-conversion keys across all
locales
* refactor: consolidate relay protocol converters
* refactor relayconvert text converters
* feat: refine relay converters and advanced custom routing
* refactor: enhance logging and add thought signature handling for Gemini requests
* refactor: enhance channel cache and pricing endpoint handling for advanced custom models
* feat: preserve billing usage semantics
* feat: add protocol-aware billing usage
* Delete useless files
* chore: update action versions in workflow files
* chore: update Docker action versions in workflow files
* fix: harden billing usage settlement and hot-path route matching
- estimate Gemini completion tokens locally when billable usageMetadata is
prompt-only but output content was received (e.g. client aborts the stream
before the final chunk), and rebuild the attached billing_usage as estimated
so settlement does not bill zero output tokens
- guard NewClaudeMessagesBillingUsage against all-zero ClaudeUsage, matching
the OpenAI/Gemini constructors, so a zero billing_usage cannot override a
non-zero top-level usage during settlement
- cache compiled advanced-custom route model regexes; they run on the request
hot path and were recompiled per request
- move the effectiveBillingUsage remap to PostTextConsumeQuota only, and
document that calculateTextQuotaSummary expects remapped usage
- document the updatePricingLock -> channelSyncLock lock ordering that
InitChannelCache/CacheUpdateChannel rely on, and the aux-struct pitfall in
GeminiChatResponse.UnmarshalJSON
1250fb2eb adds -ml-1.5 padding compensation to the old-design logs Time
badge; our plain StatusBadge has no horizontal padding so the offset
does not apply. Style follows refactor/ui.
Amends the merge resolution: drop the duplicated copy icon/tooltip block
that main reintroduced in ApiKeyCell (ours already declares it with the
text-success token), and port the functional change from main e40061965
that hides the Delete all stale button entirely when no stale instances
exist instead of rendering it disabled.
Merge origin/main while keeping this branch as the source of truth for
UI/UX. The design-system revert (337169e0a) and StatusBadge padding
revert (1b1b23d1d) from main were absorbed without applying them; only
functional additions were ported and re-styled with our primitives:
- usage-logs: Stream/Timing column split with new TimingMetricsCell and
StreamTpsCell (first-token latency + duration readout, t/s line),
admin All/Only Mine view scope (useLogsViewScope), and a mobile
filter-panel collapse toggle in DataTableFilterPanel
- keys: relative timestamps with absolute-time tooltip and stale-access
highlight via ApiKeyTimestampCell (auto-refreshing now ticker), and
copy button that resolves the real key on demand
- pricing: ModelBillingModeBadge distinguishing dynamic pricing from
token/per-request billing in the Type column
- i18n: First token translations for all locales
Rejected from main: icon-badge tones, overview accent theme colors,
bespoke mobile lists (redemptions/keys), and all other styling that
conflicts with the refactor/ui design language.
Records 337169e0a (revert of the design-system refactor) and 1b1b23d1d
(revert of StatusBadge padding) as merged while keeping the refactor/ui
tree unchanged. This branch is the source of truth for UI/UX design;
functional additions from main are merged separately.
Keep truncated cells single-line across data tables, compact oversized quota figures, and replace loud avatar gradients with identity-tint styling that matches badges.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Replace self-hosted @font-face declarations (font-display: optional) with
direct Fontsource imports (swap), so the UI always settles on bundled
fonts instead of staying on system fonts after first paint
- Add JetBrains Mono (@fontsource-variable/jetbrains-mono) as the built-in
monospace face: it backs --font-mono, .font-mono utilities, and code/pre
- Add a "mono" option to the theme font axis (CSS token, ThemeFont type,
resolver, and config drawer with live preview); default body font stays
Public Sans, Anthropic preset keeps Lora serif
- Lighten --subtle-foreground/--faint-foreground in light mode to 60%/40%
translucent mixes of muted-foreground so secondary metadata (log
sub-labels, placeholders) reads properly grey; declare once since the
var() reference resolves per light/dark mode on <html>
Revert 6869cd94b (perf(web): align table badge spacing).
Restores px padding on status badges so usage-log timing/duration
pills are not flush against the edges.
The custom home page URL iframe only allows allow-forms/allow-popups/
allow-popups-to-escape-sandbox/allow-scripts, without allow-top-navigation*.
As a result, target="_top" nav/menu links inside the (admin-configured,
trusted) embedded page cannot navigate the top-level window on desktop
browsers, while some mobile browsers still allow it via allow-popups —
causing inconsistent behavior rather than an intended restriction.
Add allow-top-navigation-by-user-activation so user-clicked top-level
links work consistently across devices. This token only permits
user-activated top navigation and does NOT grant same-origin access,
so it avoids the security concern of allow-same-origin.
Co-authored-by: 贺. <kuang@M1.local>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace collapsible card details with always-visible label/value rows, add badge-list full display for cards, and polish pricing/channel toolbars and mobile cards.