Migrates view_users (list dashboard), view_users/user_info_view (user
detail + edit + add-to-team modal), and user_agent_activity (DAU/WAU/
MAU analytics) off Tremor TabGroup/Card/Grid/Text/Title/Metric and off
antd Modal/Form/Select/Tooltip/Button/Skeleton. All three now use
shadcn Tabs + Card + Dialog + react-hook-form (in the add-team modal),
keeping the existing Tremor BarChart (chart exemption) and Tag-chip
multi-select shim. Tests updated to use Radix tab roles and
role='alertdialog' for the DeleteResourceModal selector.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
Migrates user_edit_view, CreateUserButton, BulkEditUsers,
bulk_create_users_button, and DefaultUserSettings off antd Form/Select/
Modal/Input/Typography and off Tremor Card/Text/Title. All five now use
shadcn Dialog + react-hook-form + shadcn Select/Input/Textarea/Badge/
Table, with a local multi-select shim (shadcn Select + badge chips).
The categorical status palette used by the CSV bulk import (red/green/
blue/yellow for invalid/success/pending/warning) and the bulk-edit
amber warning are preserved as raw Tailwind classes and the owning
files are added to the no-raw-tailwind-colors override list and
DEVIATIONS.md per blueprint rule 3.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
- Migrate src/components/mcp_tools/mcp_servers.tsx from Tremor TabGroup/
Tab/TabList/TabPanels + antd Modal/Descriptions/Select/Tooltip/Typography
to shadcn Tabs/AlertDialog/Select/Tooltip/Separator. Delete confirm
uses AlertDialog with a dl/dt/dd Descriptions replacement. The Team /
Access Group filter dropdowns become shadcn Radix Selects with
aria-label. Update mcp_servers.test.tsx to drive the new Radix Select
via getByRole('combobox', { name: 'Team' }) and getAllByRole('option')
instead of .ant-select class selectors.
- Migrate src/components/mcp_tools/mcp_tools.tsx from Tremor Card/Title/
Text + antd Input/Button to shadcn Card/Input/Button. Retains the
loader/selection visual treatment with lucide icons.
- Migrate src/components/mcp_tools/mcp_connect.tsx from antd Card/Alert/
Button/Switch/Form/Collapse + Tremor TabGroup/Tab/Title/Text to
shadcn Card/Alert/Button/Switch/Tabs (Form.Item replaced with a plain
Switch + Label pair — the connect screens have no form submit).
- Migrate src/components/mcp_tools/mcp_discovery.tsx from antd Modal/
Input.Search/Typography to shadcn Dialog + Input with an inline search
icon. Inline styles replaced with Tailwind classes, keeping the custom
2-column server grid and category pills.
- Migrate src/components/mcp_tools/MCPToolsetsTab.tsx from antd Modal/
Form/Input/Typography/message/Spin + Tremor Button/Text/Title to
shadcn Dialog/Input/Label/Button/AlertDialog and MessageManager for
toasts. Form state moves to react-hook-form with register().
- Migrate src/components/mcp_tools/ToolTestPanel.tsx from antd Form.useForm
+ Form.Item + Tremor Button/TextInput to react-hook-form + Controller
with shadcn Input/Textarea/Select/Label/Button. The ref-exposed
boolean-select keeps its title attribute on the trigger so the
existing ToolTestPanel.test.tsx getByTitle('True') assertion still
matches. Categorical green palette retained per BLUEPRINT rule and
added to the eslint overrides list for categorical-palette files
(mcp_connect.tsx, mcp_tools.tsx, ToolTestPanel.tsx).
- Migrate src/components/mcp_tools/mcp_tools.tsx. Categorical palette
overrides recorded in .eslintrc.json.
- MCPPermissionManagement.tsx is already in BLOCKERS.md from commit A as
part of the antd Form cluster; no change required here.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
- Migrate src/components/mcp_tools/mcp_tool_configuration.tsx from
Tremor Card/Title/Text + antd Badge/Spin/Checkbox/Input/Radio to shadcn
Card/Input/Checkbox/Badge/ToggleGroup + lucide icons. Replaces the
Radio.Group view-mode toggle with a shadcn ToggleGroup, and the
antd Spin with a spinning lucide icon. Raw Tailwind colors swapped for
semantic tokens (text-muted-foreground, bg-primary/5, border-primary,
text-destructive).
- Migrate src/components/mcp_tools/MCPToolArgumentsForm.tsx from antd
Form.useForm + Form.Item + antd Input/InputNumber/Select/Tooltip to
react-hook-form with useForm + Controller and shadcn Input/Textarea/
Select/Label/Tooltip. Ref-exposed getSubmitValues() now triggers RHF
validation via trigger() + getValues() and still returns the typed,
JSON-normalised payload expected by playground/chat_ui.
- Record create_mcp_server.tsx / mcp_server_edit.tsx / OAuthFormFields.tsx /
StdioConfiguration.tsx / OpenAPIFormSection.tsx / MCPPermissionManagement.tsx
in BLOCKERS.md. These form a single antd Form cluster (parent +
Form.Item-based children registering into the parent's FormInstance)
whose migration, including rewriting the antd-class-based test helpers
in create_mcp_server.test.tsx / mcp_server_edit.test.tsx, exceeds the
two-attempt budget for this batch.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
Migrate the add-model surface (AddModelForm, add_model_tab,
add_auto_router_tab, advanced_settings, cache_control_settings,
conditional_public_model_name, litellm_model_name,
provider_specific_fields) from antd Form + tremor to shadcn primitives
and react-hook-form.
- Root form state moves from antd FormInstance (Form.useForm) to RHF
UseFormReturn, created in ModelsAndEndpointsView.tsx and threaded
through AddModelTab / AddModelForm. Children use useFormContext /
Controller / useWatch / useFieldArray.
- antd Modal -> shadcn Dialog; antd Tag -> Badge; antd Select -> shadcn
Select; antd Radio.Group -> RadioGroup; antd Accordion (tremor) ->
shadcn Accordion; antd Form.List -> RHF useFieldArray.
- Submit helpers (handle_add_model_submit, handle_add_auto_router_submit)
feature-detect antd.resetFields vs RHF.reset so both paths keep
working through the mixed migration window.
- UploadProps type import migrates from antd/es/upload to a local shim
at add_model/add_model_upload_types.ts (structurally compatible with
the antd shape still used by model_add/AddCredentialModal.tsx and
model_add/EditCredentialModal.tsx).
- cache_control_settings ships both an RHF path (new callers) and a
legacy antd bridge used by model_info_view.tsx so the out-of-scope
detail view keeps working without cascading its migration.
- validateJsonValue added to utils/textUtils.ts to replace the antd
Promise-style formItemValidateJSON for RHF rules.
- Tests repaired: AddModelForm, add_model_tab,
conditional_public_model_name, litellm_model_name,
provider_specific_fields, advanced_settings now wrap with RHF
FormProvider instead of antd Form.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
- add_plugin_form: replace antd Modal/Form/Input/Select and Tremor
Button with shadcn Dialog + react-hook-form + shadcn Input/Textarea/
Select/Button. Validation messages now rendered inline via
formState.errors instead of antd Form.Item's rules. URL preview keeps
the categorical blue palette and is recorded in .eslintrc allowlist.
- MakeSkillPublicForm: drop antd Form wrapper + Steps. Replace with
inline lucide-based Stepper; step state stays plain React useState.
Dialog was already shadcn.
All 60 claude_code_plugins tests pass (AddPluginForm + helpers).
tsc --noEmit clean; eslint clean with categorical-palette
allowlist.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
- MakeAgentPublicForm, MakeMCPPublicForm, MakeModelPublicForm: drop
antd Form + Steps shells. Replace with inline lucide-based Stepper
component; step state stays plain React useState, dialog is already
shadcn Dialog.
- ModelHubTable: replace antd Modal with shadcn Dialog, Tremor
TabGroup/Tab/TabList/TabPanel with shadcn Tabs, Tremor Badge with
shadcn Badge + semantic color helper, Tremor Card/Text/Title/Button
with shadcn primitives + Tailwind, Ant icons with lucide Copy. Keep
categorical palette (blue/green/purple/etc) classes for hub badges;
file remains in .eslintrc allowlist.
- Tests: update mocks to stop stubbing antd (real shadcn Checkbox now
exposes data-state="indeterminate" instead of the old
data-indeterminate prop; tests assert against the Radix attribute).
Split two-click "select/deselect" sequences into separate act()
calls so state updates propagate between clicks.
- All 47 scoped tests pass (MakeAgentPublicForm, MakeMCPPublicForm,
MakeModelPublicForm). ModelHubTable existing 8 tests still pass.
tsc --noEmit clean for migrated files. eslint clean.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
- ProjectsPage: antd Table → shadcn Table + @tanstack/react-table with
TableHeaderSortDropdown for sortable columns.
- ProjectDetailsPage: removed antd Layout/Card/Descriptions/Row/Col/Spin/
Tag/Typography/Empty/Flex/Progress; switched to shadcn Card, Badge,
Progress, Skeleton, Tooltip + a CopyableId molecule mirroring
AccessGroupsDetailsPage.
- ProjectBaseForm: antd Form/Form.Item/Form.List → react-hook-form
FormProvider + Controller + useFieldArray. Dynamic model-limit and
metadata rows use useFieldArray. Guardrails tag input implemented as
a TagsSelect (shadcn Input + Select + Badge chips). Multi-model
selection uses the canonical MultiSelect from AccessGroupBaseForm.
Advanced settings section uses shadcn Collapsible.
- CreateProjectModal / EditProjectModal: share a single FormProvider;
submit via form.handleSubmit instead of form.validateFields; reset
defaults on open.
- ProjectBaseForm.test.tsx: wrap ProjectBaseForm in RHF FormProvider
(mock prop replaced by context). Existing Create/Edit modal tests
updated to include the new emptyProjectFormValues export in their
vi.mock factories.
No antd / @ant-design imports remain in src/components/Projects/. The
ProjectsPage status / ID chip keeps its categorical palette (blue/red/
emerald) via the existing .eslintrc.json override.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
Migrate EditMembership, LoggingSettings, and TeamVirtualKeysTable off
antd / Tremor to shadcn + react-hook-form per BLUEPRINT.md.
- EditMembership: antd Form.useForm / Form.Item → react-hook-form
useForm + Controller + shadcn Input/Label/Select. Multi-select is
rendered as shadcn Select + Badge chip list following the
AccessGroupBaseForm pattern.
- LoggingSettings: antd Select (single + multi) → shadcn Select +
Badge chip list. The multi-select 'Disabled Callbacks' control now
adds selections one at a time and displays selected values as
dismissible chips. The dynamic-params number input switches from
NumericalInput (which coerces through Number) to a raw Input
type=number so string values like '1.0' round-trip verbatim —
fixing a pre-existing test failure where updateCallbackVar received
'1' instead of '1.0'.
- TeamVirtualKeysTable: swap Tremor Table / Button / Badge / Icon /
Text and antd Popover / Tooltip / Skeleton for shadcn equivalents,
mirroring the canonical VirtualKeysTable migration. Sorting,
column resize, tooltips, and 'Last Active' info popover are
preserved; layout classNames are unchanged.
team/TeamInfo.tsx (1724 LoC) is deferred to BLOCKERS.md — its antd
Form uses Form.List with Promise-based custom validators, Form.useWatch,
shouldUpdate, hidden Form.Item registrations, and Select.OptGroup with
tagRender, all of which exceed this batch's budget.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
Scripted pass over all files with @ant-design/icons imports that
only contain icons covered by our mapping table. Each file now
imports lucide icons with 'Outlined' aliases so existing JSX
continues to work unchanged.
Icons mapped:
- Info/Settings/RefreshCcw/Loader2/Search/ArrowLeft/ArrowRight/
ChevronDown/ChevronRight/ChevronUp/ChevronLeft/Plus/PlusCircle/
Minus/MinusCircle/Trash2/Pencil/Copy/Check/CheckCircle2/X/XCircle/
AlertTriangle/AlertCircle/HelpCircle/Wrench/Key/Bot/History/Save/
Globe/Cloud/Server/Database/Upload/Download/Inbox/Link/Ban/EyeOff/
Eye/Code/FileText/File/Clock/User/UserPlus/Users/LayoutGrid/
GitBranch/Zap/Plug/Menu/Filter/MoreHorizontal/Image/Video/Mic/
MapPin/ChevronsUpDown.
Fixups applied after the bulk pass:
- 'spin' prop is antd-specific; replaced with className='animate-spin'
in audit_logs, multi_cost_results, ProjectDetailsPage,
SearchToolTester, EntityUsage, UsagePageView, ai_suggestion_modal.
- agents/add_agent_form: InfoCircleOutlined title/style props (antd)
\u2192 aria-label + Tailwind utilities (lucide React.SVGProps).
After this pass: @ant-design/icons usage drops from 48 \u2192 11 files.
The remaining 11 files import icon names outside the mapping table
and will be migrated individually.
Gates: TS \u2713 | Build \u2713.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
- BaseActionButton.test: PencilAltIcon \u2192 lucide Pencil (aliased).
- Full heroicons count in src/ is now 0. @heroicons/react can be
dropped from package.json in a follow-up cleanup once phase 1
migration is fully closed out.
Gates: TS \u2713 | Build \u2713.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
- prompts/prompt_info: ArrowLeft/Trash/Pencil rewired to lucide.
- mcp_tools/MCPToolsetsTab: Plus/Pencil/Trash rewired.
- organizations: ChevronDown/ChevronRight/Refresh rewired (Refresh \u2192
RefreshCcw).
- Aliases preserved so downstream JSX continues to use the Heroicon
names, unblocking deletion of the @heroicons package without
touching usages in these large files.
Gates: TS \u2713 | Build \u2713.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
- antd Checkbox/Divider/Popover \u2192 shadcn Checkbox/Popover + native
<hr>. antd Slider preserved as AntSlider (shadcn Slider has a
different API).
- Swept bg-white/bg-gray-100/text-gray-700/bg-red-50/text-red-600
to background/muted/foreground + destructive tokens.
- Popover open state now driven by Radix onOpenChange (tracks
outside clicks) instead of the custom hand-rolled toggle.
Gates: TS \u2713 | Build \u2713.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
File already uses shadcn Tooltip + lucide icons and swept to semantic
tokens. Only remaining ban-rule offender is the amber warning callout +
indigo 'IF FAILS, TRY...' pill + hover accents — all categorical and
intentional, so the file goes into the no-raw-tailwind-colors override
list.
Gates: Build \u2713.
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>