Conversation
…ser quota rewards
feat(checkin): add check-in functionality
- Add initialLoaded state to track first data load completion - Set isCollapsed to null initially, determined after data loads - Show loading state on button and description text before data arrives - Remove auto-collapse effect that caused visual flicker - Add i18n translations for loading states (en/fr/ja/ru/vi/zh) Fixes issue where component would collapse/expand after data loads, causing visual flicker when navigating to personal settings page.
…f3d55c3b4d7f3305
…rim_suffix, ensure_prefix, ensure_suffix, trim_space, to_lower, to_upper, replace, and regex_replace
移除gorm:"default:false",避免每次 AutoMigrate时都执行ALTER TABLE `tokens` MODIFY COLUMN `cross_group_retry` boolean DEFAULT false 且bool默认false不影响原有功能
…c1cf2afa2de98c3d
* feat: add support for Doubao /v1/responses
feat: check-in feature integrates Turnstile security check
fix: gemini request -> openai tool call
…#2556) * fix: fix model deployment style issues, lint problems, and i18n gaps. * fix: adjust the key not to be displayed on the frontend, tested via the backend. * fix: adjust the sidebar configuration logic to use the default configuration items if they are not defined.
fix: 修复 gemini 文件类型不支持 image/jpg
…figuration && the AWS calling side did not apply the relay timeout.
fix: fix the proxyURL is empty, not using the default HTTP client configuration && the AWS calling side did not apply the relay timeout.
# Conflicts: # web/src/features/pricing/components/model-row.tsx
…nfig - Add 425+ missing translations across fr, ja, ru, zh, vi locales for subscription management, sidebar navigation, Grok settings, upstream model updates, pricing page, and other UI components - Add 37 missing i18n keys used in t() calls but absent from locale files (pricing filters, display options, audio/cache labels, etc.) - Fix stale tech stack info in CLAUDE.md, AGENTS.md, and project.mdc: React 18 → 19, Vite → Rsbuild, Semi Design → Radix UI + Tailwind - Fix i18n key format description: "Chinese source strings" → English - Deduplicate .cursor/rules/project.mdc to avoid triple-loading the same rules already present in root CLAUDE.md and AGENTS.md - Add i18n-translate Cursor skill for repeatable translation workflow
Replace Card-based dashboard components with a flat, border-driven design system consistent with the pricing page, following the ui-style.mdc conventions. Overview section: - StatCard: replace Card wrapper with flat flex layout, monospace tabular values, uppercase tracking-wider labels, layered opacity hierarchy - PanelWrapper: replace Card/CardHeader/CardContent with rounded-lg border container and border-b header - SummaryCards: merge three stat cards into a single bordered container with divide-x separators; decouple border from stagger animation to prevent border deformation during entrance transitions - ApiInfoPanel/Item: full-width list rows with border-b separators, monospace route names, layered opacity for URLs and descriptions - AnnouncementsPanel: native button rows with hover:bg-muted/40, i18n for "Click for details" hint - FAQPanel: lighter border-border/60 accordion dividers, muted answer text - UptimePanel: uppercase tracking-wider group headers with bg-muted/30 background, monospace uptime percentages, fine-grained border opacity Models section: - LogStatCards: replace Card with rounded-lg border + divide-x grid, fix react-hooks/exhaustive-deps by destructuring props before useEffect - ModelCharts: replace Card+Tabs with bordered container + custom segmented control matching ui-style spec - Suspense fallbacks: match new flat skeleton layout with accurate column structure Animation: - Wrap models section in FadeIn with staggered delay - Keep CardStagger for overview panel grid (each panel has own border) Other: - Add ui-style.mdc cursor rule documenting the design language - Disable react-refresh/only-export-components for src/routes/** in eslint config (TanStack Router route files always export Route objects) - Fix zh.json: "Token-based" translation "基于令牌的" → "按量计费"
Replace the bordered/colored-background StatusBadge and Badge components across the entire frontend with a minimal flat design: a small colored dot followed by colored text, eliminating visual noise from heavy borders, backgrounds, and rounded pill shapes. Key changes: - Redesign StatusBadge to use dot + text instead of bordered pill style, removing cva-based background/border variants in favor of exported dotColorMap and textColorMap lookup tables - Add children prop support to StatusBadge for flexible content rendering alongside the existing label prop - Migrate all Badge usages (except pricing page) to StatusBadge with appropriate variant mappings (default→info, secondary→neutral, outline→neutral, destructive→danger) - Consolidate adjacent multi-badge groups into single-dot layouts with dot separators (·) to reduce visual clutter in: - Channel balance columns (used + remaining) - Channel type column (type + IO.NET indicator) - User invite info column (invited + revenue + inviter) - Usage log stats bar (usage + RPM + TPM) - Usage log time/FRT column (time + FRT + stream status) - Subscription plan counts (active + expired) - Channel affinity scope/regex/key-source columns - Prefill group card headers (type + ID) - Export dotColorMap and textColorMap for direct use in custom inline layouts that need consistent status colors without the full component
Overhaul the public-facing layout, header, and homepage to deliver a polished, animation-rich landing experience inspired by contemporary SaaS design patterns. Header: - Replace sticky header with fixed floating navbar that compacts into a pill-shaped glass-morphism bar on scroll (backdrop-blur + ring) - Add smooth 700ms cubic-bezier transitions for scroll-based shrinking - Build full-screen mobile menu overlay with staggered entry animations - Remove background color from logo container, show logo image directly Homepage sections: - Hero: gradient text title, radial gradient + grid pattern background, interactive terminal demo showcasing API request/response - Terminal demo: auto-cycles through gpt-4o, claude-sonnet-4-20250514, gemini-2.5-pro, deepseek-chat with smooth cross-fade transitions, clickable model badges, dual theme support (light/dark), fixed height - Stats: animated counters driven by IntersectionObserver with cubic-bezier easing, supports integer and decimal modes - Features: Bento grid layout with gap-px border technique, each card includes contextual visuals (model list, security badge, workflow) - How It Works: new three-step process section (Configure → Connect → Monitor) with connecting gradient line and numbered badges - CTA: gradient mesh background with scale-in scroll animation - Footer: streamlined brand column + link columns layout New components: - AnimateInView: IntersectionObserver-based scroll animation component supporting fade-up, fade-in, scale-in, fade-left, fade-right - HeroTerminalDemo: themed terminal with model carousel and live request/response preview CSS: - Add landing page scroll-triggered keyframe animations - Add terminal demo animations (blink cursor, spinner, pulse indicator) - Respect prefers-reduced-motion throughout i18n: - Add 17 new translation keys across all 6 locales (en/zh/fr/ja/ru/vi)
Usage logs - Show Refund (type 6) in detail dialog and hide conversion chain for refunds - Sync filter dialog state from URL for model, token, group, username, and requestId Channels - Support optional stream flag in channel test API, actions, and test dialog - Show upstream model update badges (+added / -removed) on fetchable channel types - Add form fields and drawer toggles for upstream model update check and auto-sync - Persist upstream model update flags in channel settings JSON for fetchable types i18n - Add locale strings for upstream model update UI (en, zh, fr, ja, ru, vi)
…mations Add overflow-y-clip to the shared Table container (data-slot=table-container) alongside overflow-x-auto. Setting overflow-x to auto implicitly pairs with overflow-y: auto in browsers, which made the table shell briefly show a vertical scrollbar during route enter motion (y/blur) and table row stagger. Remove the redundant descendant selector workaround from the model pricing GroupPricingSection; behavior is now covered globally by the Table component.
…le content, and pinned footer Overhaul the authenticated console layout to match the OpenAI dashboard pattern: header and page title bar stay fixed at the top, only the content area scrolls, and table pagination is pinned to the bottom. Layout architecture: - Lock SidebarInset to full viewport height (h-svh) so all inner regions are controlled by flexbox instead of document scroll - Convert Main from a generic div to a semantic <main> flex container with overflow-hidden, removing the legacy `fixed` prop and `data-layout` attribute - Strip scroll-shadow logic and `fixed` prop from Header/AppHeader; the header is now naturally fixed as a shrink-0 flex child - Restructure SectionPageLayout into three flex regions: a shrink-0 title bar, a flex-1 overflow-auto content area, and a shrink-0 footer portal target with empty:hidden - Add min-h-0 to AnimatedOutlet wrappers to prevent flex overflow Footer portal system: - Introduce PageFooterProvider / PageFooterPortal (React Context + createPortal) so deeply nested table components can render their DataTablePagination into the fixed footer without prop drilling - Migrate all 8 data tables (api-keys, channels, users, models, deployments, usage-logs, subscriptions, redemption-codes) to use PageFooterPortal for pagination Page-level fixes: - Profile: wrap content in a scrollable flex child with proper padding - SystemSettings: remove overflow-auto from wrapper to avoid nested scrollbars (sub-pages manage their own scroll) - Playground / Error pages: remove obsolete `fixed` props API keys UX improvement: - Replace inline key show/hide toggle with a Popover-based reveal, removing toggleKeyVisibility and keyVisibility state from the provider context Cleanup: - Remove dead CSS rule for body:has([data-layout='fixed']) - Remove unused `fixed` prop from Header, AppHeader, and Main types - Export PageFooterPortal from layout barrel file
…itions - Standardize primary action buttons (Create, Add, Search) to size="sm" across all pages for visual consistency with channels and models - Redesign NumericSpinnerInput with minimal inline style: plain text by default, hover-revealed +/- buttons, click-to-edit — replacing the clunky bordered input with stacked chevron arrows - Fix vertical scrollbar in channels group column by replacing overflow-x-auto with overflow-hidden (redundant with +N collapse) - Simplify API keys group column: replace colorful StatusBadge pairs with clean typography using opacity hierarchy and dot separators - Move API key copy loading indicator from key text to the copy button itself, eliminating layout shift during key resolution - Reduce page title from text-2xl to text-lg and subtitle to text-sm in SectionPageLayout for a more compact header - Add smooth opacity transition (duration-150) on all 7 server-paginated tables during background data fetches (isFetching && !isLoading), with pointer-events-none to prevent interaction during loading - Constrain usage logs Details column width (size: 200, maxSize: 220)
The console layout refactor in d215046 moved padding ownership from Main onto each route, but SystemSettings was missed — its Outlet wrapper had no padding, so the content area sat flush against the sidebar and top nav. Add `px-4 pt-6 pb-4` to match the vertical rhythm used by SectionPageLayout and the Profile page.
…e pages Unify mobile experience for all data table pages (channels, keys, models, deployments, usage-logs, users, redemption-codes, subscriptions) with a consistent layout pattern and cleaner header area. DataTableToolbar: - Redesign mobile layout: full-width search input + collapsible filter toggle button with active filter count badge - Filters, additional search, and reset button collapse into an expandable section on mobile, keeping the default view compact - Desktop layout remains unchanged SectionPageLayout: - Tighten mobile spacing (padding, gaps) for higher content density - Scale down title (text-base) and description (text-xs) on mobile - Shrink action button gaps on small screens ChannelsPrimaryButtons: - Move Tag Mode and Sort by ID toggles into the "More" dropdown on mobile (via DropdownMenuCheckboxItem), freeing header space - Desktop toggle switches remain visible outside the dropdown MobileCardList (shared component): - Compact list-item layout with title + badge header row and side-by-side key fields, replacing individual card components - Structured (CompactRow) and fallback (FallbackRow) rendering modes driven by column meta (mobileTitle, mobileBadge, mobileHidden) New MobileCardList integration: - Users table: username as title, status as badge; hide id, display_name, invite_info on mobile - Redemptions table: name as title, status as badge; hide id, created_time, expired_time, used_user_id on mobile - Subscriptions table: plan title as title, enabled as badge; hide id, sort_order, reset, payment, total_amount, upgrade_group on mobile Column meta updates: - Add mobileTitle/mobileBadge/mobileHidden meta across all 8 table column definitions for consistent mobile field prioritization Minor fixes: - Hide Subscriptions Stripe/Creem alert on mobile - Disable card hover animations on mobile via CSS media query
Favicon stayed at the hardcoded /logo.png while document.title already followed system_name, leaving tab icon and site branding out of sync. Apply the logo as favicon from localStorage cache on startup, refresh from getStatus(), and re-apply when useSystemConfig finishes preloading. Extract applyFaviconToDom helper into lib/dom-utils with idempotent guard to avoid redundant DOM writes.
… visual editing Port missing features from legacy frontend (b8650b9 merge) to the new React frontend: - Add Codex CLI and Claude CLI channel affinity rule templates with header passthrough presets (pass_headers operations for Originator, Session_id, X-Codex-*, X-Stainless-*, Anthropic-*, etc.) - Introduce "Add Rule" dropdown menu with blank, Codex CLI, and Claude CLI template options in the channel affinity settings page - Add "Fill Templates" button to batch-append both CLI templates with duplicate name resolution and confirmation dialog - Support templateKey prop in RuleEditorDialog to pre-fill form fields from selected template, auto-expanding advanced settings when a param_override_template is present - Add CreateCacheRatio support to the model ratio visual editor, edit dialog, and form — previously only editable in JSON mode, now fully integrated into the visual table column, add/edit dialog fields, and save/delete handlers
- Fix About page URL detection: replace naive `startsWith('https://')`
with proper `new URL()` validation to support both http and https, and
handle untrimmed input that previously caused silent misdetection
- Fix About page HTML detection: remove overly broad `startsWith('<')`
and `endsWith('>')` checks that could misclassify Markdown or XML
content; align with LegalDocument's regex-only `isLikelyHtml` approach
- Fix Home page URL detection: same `startsWith('https://')` bug,
replaced with `new URL()` protocol validation
- Refactor About page to use early-return pattern instead of deeply
nested ternary expressions for better readability
- Replace About loading spinner with Skeleton placeholder consistent
with LegalDocument
- Add `prose prose-neutral dark:prose-invert` typography classes to
About HTML/Markdown rendering for proper dark mode support
- Remove unused `Code` icon import from About page
# Conflicts: # web/bun.lock # web/package.json # web/src/i18n/locales/en.json # web/src/i18n/locales/fr.json # web/src/i18n/locales/ja.json # web/src/i18n/locales/ru.json # web/src/i18n/locales/vi.json
…i18n Backport and enhance several features from the old frontend (web/old) that were missing or incomplete in the new React frontend: - Playground & channel test: parse structured JSON error responses from SSE streams and non-streaming API calls, extract error codes, and display actionable UI for `model_price_error` (admin settings link) - User management: replace local quota manipulation with atomic server-side quota adjustments (add/subtract/override) via dedicated API endpoint, making the quota field read-only in the edit drawer - Subscriptions: display next quota reset time for active subscriptions - Dashboard: limit model ranking chart to top 20 models with an "Other" bucket, add dimension tooltips with sorted values and totals to model call trend and user consumption trend charts - i18n: add 24 new translation keys across all 6 locales (en, zh, fr, ja, ru, vi) for the newly introduced UI elements and messages
…assic)
Introduce runtime frontend theme switching so administrators can switch
between the new frontend (Radix UI + Tailwind) and the classic frontend
(Semi Design) from the settings page without restarting the server.
Directory restructuring:
- Move new frontend from web/ to web/default/
- Move classic frontend from web/old/ to web/classic/
- One-frontend-per-folder layout for extensibility
Backend (injection pattern):
- Add setting/system_setting/theme.go with GlobalConfig.Register("theme")
so the DB key "theme.frontend" is handled automatically by
handleConfigUpdate — no switch-case in updateOptionMap needed
- Use atomic.Value in common.GetTheme()/SetTheme() for lock-free
concurrent reads on the hot path (static file middleware)
- Add themeAwareFileSystem that delegates to the correct embedded FS
based on the current theme at request time
- Embed both frontends into the binary via go:embed
- Add controller validation for theme.frontend values
- Expose theme in GET /api/status response
Frontend settings UI:
- New frontend: add "Frontend Theme" select in System Information section
using Radix UI Select + react-hook-form + Zod validation
- Classic frontend: add "前端主题" select in Personalization section
using Semi Design Form.Select
Build system:
- Update Dockerfile with multi-stage builds for both frontends
- Update Makefile with separate build targets for each frontend
- Update GitHub Actions release workflow for dual frontend builds
i18n:
- New frontend: add translations for all 6 locales (en/zh/fr/ja/ru/vi)
- Classic frontend: add translations for all 7 locales (en/zh-TW/ja/fr/ru/vi)
- Fix zh "AI Proxy Library" → "AI 代理库"
Documentation:
- Update CLAUDE.md, AGENTS.md, .cursor/rules/project.mdc to reflect
the new web/default/ and web/classic/ directory structure
|
Important Review skippedToo many files! This PR contains 292 files, which is 142 over the limit of 150. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (8)
📒 Files selected for processing (292)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR introduces a theme-aware dual-frontend setup (default + classic) with runtime switching, alongside several backend feature additions (theme config sync, OAuth providers, quota pre-consumption return, video task updates) and build/deployment workflow updates.
Changes:
- Add backend-managed frontend theme selection and serve embedded assets for both default/classic themes at runtime.
- Introduce/extend multiple controllers (OIDC/GitHub/Discord/LinuxDO OAuth, video task updater) and supporting model/service utilities.
- Update build tooling and CI to build/embed both frontends; add dev Docker Compose + backend-only dev Dockerfile.
Reviewed changes
Copilot reviewed 96 out of 1336 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| web/classic/src/components/table/models/ModelsDescription.jsx | Adds classic UI header/description for models table with compact toggle. |
| web/classic/src/components/settings/personal/cards/ModelsList.jsx | Adds categorized model list UI with expand/collapse and skeleton/empty states. |
| web/classic/src/components/settings/OtherSetting.jsx | Adds theme.frontend option UI + submit handler in classic settings. |
| web/classic/src/components/playground/index.js | Adds barrel exports for playground components + config storage helpers. |
| web/classic/src/components/common/modals/TwoFactorAuthModal.jsx | Introduces reusable 2FA modal UI. |
| web/classic/src/components/common/examples/ChannelKeyViewExample.jsx | Example integration of SecureVerification flow for viewing channel keys. |
| web/classic/.gitignore | Ignores /dist build output for classic frontend. |
| setting/system_setting/theme.go | Adds theme settings registration and sync to common theme value. |
| service/pre_consume_quota.go | Implements pre-consume quota logic and async return on failure. |
| router/web-router.go | Serves theme-aware embedded static FS; chooses index.html by theme. |
| router/main.go | Updates router wiring to pass ThemeAssets. |
| model/task.go | Adds bulk update by upstream task_id strings. |
| model/option.go | Syncs theme/performance settings after config updates. |
| makefile | Builds both frontends; adds dev targets for API + both web themes. |
| main.go | Embeds both default/classic dist folders; injects analytics into both index pages. |
| docker-compose.dev.yml | Adds backend dev stack (Go build container + Redis + Postgres). |
| controller/task_video.go | Adds video async task updater incl. parsing, redaction, and quota adjustments. |
| controller/option.go | Validates theme.frontend option values (default/classic). |
| controller/oidc.go | Adds OIDC OAuth login/bind flow. |
| controller/misc.go | Exposes current theme in /status payload. |
| controller/linuxdo.go | Adds LinuxDO OAuth login/bind flow. |
| controller/github.go | Adds GitHub OAuth login/bind flow. |
| controller/discord.go | Adds Discord OAuth login/bind flow. |
| common/embed-file-system.go | Adds theme-aware FS wrapper selecting embedded assets by theme at runtime. |
| common/constants.go | Stores theme in atomic.Value with getters/setters. |
| README.en.md | Adds English README documentation. |
| Dockerfile.dev | Adds backend-only dev image build (with embedded frontend placeholders). |
| Dockerfile | Builds and embeds both default/classic frontends into final Go binary image. |
| CLAUDE.md | Updates documented tech stack and frontend/i18n paths. |
| AGENTS.md | Updates documented tech stack and frontend/i18n paths. |
| .github/workflows/release.yml | Builds both frontends during release workflow. |
| .github/workflows/docker-build.yml | Adds Docker build+push workflow. |
| .github/FUNDING.yml | Adds funding configuration. |
| .cursor/skills/vercel-react-best-practices | Adds Cursor skill pointer to repo skills. |
| .cursor/skills/i18n-translate/SKILL.md | Adds i18n translation workflow documentation for default frontend. |
| .cursor/rules/ui-style.mdc | Adds UI style guide rules for Cursor. |
| .cursor/rules/project.mdc | Replaces/updates Cursor project guide to match new frontend setup. |
| .agents/skills/vercel-react-best-practices/** | Adds performance best-practices reference documents. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| t := responseItems.Data | ||
| taskResult.TaskID = t.TaskID | ||
| taskResult.Status = string(t.Status) | ||
| taskResult.Url = t.FailReason |
| var taskData map[string]interface{} | ||
| if err := json.Unmarshal(task.Data, &taskData); err == nil { | ||
| if modelName, ok := taskData["model"].(string); ok && modelName != "" { |
| func redactVideoResponseBody(body []byte) []byte { | ||
| var m map[string]any | ||
| if err := json.Unmarshal(body, &m); err != nil { | ||
| return body | ||
| } | ||
| resp, _ := m["response"].(map[string]any) | ||
| if resp != nil { | ||
| delete(resp, "bytesBase64Encoded") | ||
| if v, ok := resp["video"].(string); ok { | ||
| resp["video"] = truncateBase64(v) | ||
| } | ||
| if vs, ok := resp["videos"].([]any); ok { | ||
| for i := range vs { | ||
| if vm, ok := vs[i].(map[string]any); ok { | ||
| delete(vm, "bytesBase64Encoded") | ||
| } | ||
| } | ||
| } | ||
| } | ||
| b, err := json.Marshal(m) | ||
| if err != nil { | ||
| return body | ||
| } | ||
| return b | ||
| } |
| logger.LogDebug(ctx, fmt.Sprintf("UpdateVideoSingleTask response: %s", string(responseBody))) | ||
|
|
||
| taskResult := &relaycommon.TaskInfo{} | ||
| // try parse as New API response format | ||
| var responseItems dto.TaskResponse[model.Task] | ||
| if err = common.Unmarshal(responseBody, &responseItems); err == nil && responseItems.IsSuccess() { | ||
| logger.LogDebug(ctx, fmt.Sprintf("UpdateVideoSingleTask parsed as new api response format: %+v", responseItems)) | ||
| t := responseItems.Data |
| const savedState = localStorage.getItem('modelsExpanded'); | ||
| return savedState ? JSON.parse(savedState) : false; | ||
| }); | ||
| const [activeModelCategory, setActiveModelCategory] = useState('all'); | ||
| const MODELS_DISPLAY_COUNT = 25; // 默认显示的模型数量 | ||
|
|
||
| // Save models expanded state to localStorage whenever it changes | ||
| useEffect(() => { | ||
| localStorage.setItem('modelsExpanded', JSON.stringify(isModelsExpanded)); |
| const savedState = localStorage.getItem('modelsExpanded'); | ||
| return savedState ? JSON.parse(savedState) : false; | ||
| }); | ||
| const [activeModelCategory, setActiveModelCategory] = useState('all'); | ||
| const MODELS_DISPLAY_COUNT = 25; // 默认显示的模型数量 | ||
|
|
||
| // Save models expanded state to localStorage whenever it changes | ||
| useEffect(() => { | ||
| localStorage.setItem('modelsExpanded', JSON.stringify(isModelsExpanded)); |
| @@ -0,0 +1,35 @@ | |||
| # Backend-only build for frontend development | |||
| # Skips frontend build, uses a placeholder for //go:embed web/dist | |||
…ti-key index and inference_geo scope
- Add `allow_speed` toggle for Anthropic (type 14) channels to control
Claude inference speed mode passthrough, with full form schema,
settings persistence, and UI switch
- Fix `allow_inference_geo` to also apply to Anthropic (type 14) channels,
not just OpenAI (type 1), matching the backend behavior for Claude data
residency region control
- Fix multi-key management dialog to display 1-based key indices instead
of 0-based (#{key.index + 1})
- Fix TypeScript type error in section-registry by adding type assertion
for theme.frontend enum
- Add i18n translations for all new keys across 6 locales (en, zh, fr,
ja, ru, vi)
…lassic as default theme - Add .cursor/ to .gitignore and remove tracked editor config files (.cursor/rules/, .cursor/skills/) from version control - Consolidate .agents/skills/vercel-react-best-practices by keeping only the compiled AGENTS.md and removing redundant SKILL.md and 57 individual rule files under rules/ - Change default frontend theme from "default" to "classic" in both common/constants.go init and setting/system_setting/theme.go
Important
📝 变更描述 / Description
Introduce a completely redesigned default frontend powered by React 19,
TypeScript, Rsbuild, Radix UI, and Tailwind CSS — replacing the legacy
Semi Design stack with a modern, accessible, and performance-first
architecture.
Highlights:
server state, and high-performance data grids
This marks the transition from v0.x to v1.x — a milestone release
that sets the foundation for the next era of the platform.
🚀 变更类型 / Type of change
🔗 关联任务 / Related Issue
✅ 提交前检查项 / Checklist
Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。📸 运行证明 / Proof of Work