Commit graph

37686 commits

Author SHA1 Message Date
Cursor Agent
328754feee
feat(ui): simple_table + team_dropdown migrate off antd/@tremor Text
- simple_table: the Tremor Table family is whitelisted in phase 1 so
  only the @tremor Text wrapper was swapped for a plain span with
  semantic text-muted-foreground. File keeps its inline eslint-disable
  for the preserved Tremor table primitives.
- team_dropdown: antd Select with infinite scroll + debounced remote
  search + antd LoadingOutlined \u2192 shadcn Popover + Button (combobox)
  + Input + lucide Loader2/ChevronsUpDown/X. Infinite-scroll is
  driven by the list element's scroll handler with the same 0.8
  threshold. Cleared button spans stopPropagation to prevent the
  popover from toggling open on clear.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:46:34 +00:00
Cursor Agent
b58fd0b7fc
feat(ui): common_components \u2014 ModelSelector + PassThroughRoutesSelector + PremiumLoggingSettings
- ModelSelector: antd Select + @tremor TextInput/Text + @ant-design/
  icons RobotOutlined \u2192 shadcn Select + Input + lucide Bot. 'custom'
  option preserved with the inline Input that appears below on
  selection.
- PassThroughRoutesSelector: antd Select mode='tags' (typing an ad-hoc
  value creates it) \u2192 shadcn Popover + chip-list multi-select with
  Enter-to-add-freeform inside the search input.
- PremiumLoggingSettings: @tremor Text \u2192 plain <p>. Emerald/amber
  callout badges preserved as categorical colors; file added to
  .eslintrc.json overrides.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:44:09 +00:00
Cursor Agent
591c2c035a
feat(ui): common_components \u2014 AccessGroupSelector + DeleteResourceModal + PassThroughSecuritySection
- AccessGroupSelector: antd Select mode='multiple' with ant Skeleton
  loading state \u2192 shadcn Popover + chip-list multi-select (same
  pattern established in MCPServerSelector / VectorStoreSelector).
  Skeleton from shadcn.
- PassThroughSecuritySection: @tremor Card/Title/Subtitle/Text + antd
  Form.Item/Switch \u2192 shadcn Card/Switch + semantic Tailwind. Amber
  upgrade-prompt callout added to .eslintrc.json overrides.
- DeleteResourceModal: antd Modal/Alert/Card/Descriptions/Input/
  Typography/theme.useToken \u2192 shadcn AlertDialog/Card/Input + lucide
  AlertCircle. Resource information rendered as a two-column grid
  inside a destructive-tinted Card (replaces antd Descriptions).
  Confirmation input preserved; Delete action is disabled until the
  confirmation string matches.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:40:24 +00:00
Cursor Agent
4c8dc48b91
feat(ui): migrate common_components small selects + LabeledField to shadcn
- DurationSelect: antd Select \u2192 shadcn Select (Daily/Weekly/Monthly).
- LabeledField: antd Typography.Text copyable indicator \u2192 custom hook
  using navigator.clipboard + lucide Copy/Check icon with Tooltip
  feedback. DefaultProxyAdminTag branch preserved.
- OrganizationDropdown / ProjectDropdown: antd Select with allowClear +
  filterOption \u2192 shadcn Select with an explicit '__all__' sentinel
  value mapped back to an empty string on the callback side (primitives
  don't accept undefined like antd's allowClear). Loading state uses
  the disabled=true fallback since Radix Select has no spinner slot.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:37:26 +00:00
Cursor Agent
60bb2dce9d
feat(ui): migrate prompts panel to shadcn
- @tremor Button + antd Modal/Select \u2192 shadcn Button / Select /
  AlertDialog. Environment filter is a shadcn Select with an explicit
  'All Environments' sentinel value (Select primitives don't accept
  undefined like antd's allowClear).
- Delete confirmation is now an AlertDialog with destructive variant
  on the action button (same pattern as claude_code_plugins).

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:34:39 +00:00
Cursor Agent
1c27c014e9
feat(ui): migrate navbar + ui_theme_settings to shadcn
- navbar: antd Button/Switch/Tag + @ant-design/icons Menu/PanelLeftClose/
  Moon/Sun \u2192 shadcn Button/Switch/Badge + lucide equivalents. Docs link
  now uses <Button variant='ghost' asChild><a/></Button>. Version Badge
  uses variant='outline'.
- ui_theme_settings: @tremor Card/Title/Text/TextInput/Button \u2192 shadcn
  Card/Input/Button/Label. Semantic tokens throughout (text-foreground,
  text-muted-foreground, bg-background).

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:32:27 +00:00
Cursor Agent
32392518f6
feat(ui): migrate small top-level components to shadcn
- query_param_input: antd Button/Space + @ant-design/icons \u2192 shadcn
  Button/Input + lucide MinusCircle/Plus, dashed-outline add button.
- object_permissions_view: @tremor Text \u2192 plain <p> with semantic tokens.
- route_preview: antd Card/Typography + @ant-design/icons ChevronRight/
  InfoCircle \u2192 shadcn Card + lucide ChevronRight/Info.
- skill_hub_table_columns: @tremor Badge/Text + antd Tooltip + @ant-design/
  icons CopyOutlined/LinkOutlined \u2192 shadcn Badge/Tooltip + lucide
  Copy/Link. Added to overrides for the categorical blue/emerald badge
  palette.
- claude_code_plugins: @tremor Button + antd Modal \u2192 shadcn Button +
  AlertDialog (destructive variant for the Delete action).

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:29:50 +00:00
Cursor Agent
38175a15a5
feat(ui): activity_metrics antd Collapse \u2192 shadcn Accordion (charts preserved)
- antd Collapse/Collapse.Panel \u2192 shadcn Accordion/AccordionItem/
  AccordionTrigger/AccordionContent (type='multiple' so expanding one
  model section doesn't collapse the previously-opened one).
- Header row keeps the right-aligned spend + request-count split; moved
  pr-2 onto the inner row so it doesn't collide with the chevron.
- @tremor AreaChart/BarChart/Card/Grid/Text/Title preserved \u2014 this is a
  chart-heavy component and the tremor chart primitives have no
  shadcn-equivalent in phase 1 (recharts migration is phase 2).
- Added to .eslintrc.json overrides with an inline eslint-disable on the
  preserved tremor import.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:25:33 +00:00
Cursor Agent
52939eb06c
feat(ui): migrate shared date-picker + CreatedKeyDisplay to shadcn (tremor DateRangePicker kept)
- CreatedKeyDisplay: antd Button \u2192 shadcn Button. Raw background #f8f8f8
  replaced with bg-muted; text-gray-600 \u2192 text-muted-foreground.
- usage_date_picker: @tremor Text \u2192 plain <p>/<span> with semantic
  tokens. DateRangePicker (tremor) preserved \u2014 phase-2 will introduce
  a shadcn date-picker primitive; file added to overrides with an inline
  eslint-disable for the preserved tremor type + component import.
- advanced_date_picker: @ant-design/icons CalendarOutlined/ClockCircle
  \u2192 lucide CalendarIcon/Clock; @tremor Text \u2192 <span>. Same override
  treatment for the preserved tremor Button / DateRangePickerValue.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:18:34 +00:00
Cursor Agent
6e3107d68c
feat(ui): migrate shared/numerical_input from @tremor NumberInput to shadcn Input
- @tremor NumberInput \u2192 shadcn Input type=number.
- onChange contract preserved: numeric value, null, or undefined (tremor
  convention). Empty string or NaN parses as null.
- value / defaultValue accepted as number | string | null | undefined.
- 'precision' prop accepted for back-compat but not enforced (HTML number
  input doesn't clamp decimal precision; callers round before persisting).
- onWheel \u2192 blur to disable accidental scroll-to-change.
- All existing callers keep working \u2014 this component is used from
  organization_view, AccessGroupBaseForm, edit_user, tag_info,
  CreateTagModal, cache_settings, and others; all are already passing
  (number | null | undefined) to onChange.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:12:52 +00:00
Cursor Agent
372fdedf5b
feat(ui): migrate mcp_tools/ByokCredentialModal to shadcn
- antd Modal/Input/Input.Password/Switch + @ant-design/icons KeyOutlined/
  LockOutlined/CheckOutlined/ArrowRight/ArrowLeft/CloseOutlined/
  LinkOutlined \u2192 shadcn Dialog/Input/Button/Switch/Label + lucide
  Key/Lock/Check/ArrowRight/ArrowLeft/X/LinkIcon/Eye/EyeOff.
- Two-step flow (service-icons \u2192 api-key-form) preserved. Preserve
  the teal/cyan \u2192 blue/indigo gradient logo tiles (intentional brand
  illustration); ByokCredentialModal added to .eslintrc.json overrides.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:10:13 +00:00
Cursor Agent
0acfcf3a36
feat(ui): migrate mcp_tools MCPLogoSelector + MCPNetworkSettings to shadcn
- MCPLogoSelector: antd Input/Tooltip + @ant-design/icons InfoCircle/
  LinkOutlined \u2192 shadcn Input/Tooltip + lucide Info/Link. Logo grid
  and selected preview preserved; selected state uses primary-toned
  border/background.
- MCPNetworkSettings: antd Select mode=tags/Button/Card/Typography/Spin/
  Tag + @ant-design/icons SaveOutlined/PlusOutlined \u2192 shadcn Card/
  Input/Button/Badge/Skeleton + lucide Plus/Save/X. Replaces the
  Select mode=tags with an Add-on-Enter-or-comma Input + Badge chip
  list. Suggested-range Badge now uses gap-1 + Plus icon and is
  exempted from raw-colors as categorical blue/info tone.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:06:11 +00:00
Cursor Agent
276b1682e2
feat(ui): migrate mcp_server_management to shadcn
- MCPServerSelector: antd Select mode=multiple \u2192 shadcn Popover +
  chip-style multi-select (same pattern as VectorStoreSelector /
  GuardrailSelector). Merges three lists (access groups / servers /
  toolsets) into a single searchable popover with a categorical emerald
  / blue / purple dot + label per item. Added to .eslintrc.json overrides.
- MCPToolPermissions: @tremor Text + antd Spin/Radio.Group \u2192 shadcn
  Checkbox/Skeleton/ToggleGroup + plain Tailwind. View-mode picker uses
  a ToggleGroup with 'Risk Groups' / 'Flat List' options. Flat-list
  tool rows use shadcn Checkbox.

Gates: TS \u2713 | Vitest 3/3 (existing MCPToolPermissions.test) \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 10:02:19 +00:00
Cursor Agent
eaa075ee8e
feat(ui): migrate model_hub_table_columns to shadcn
- Same pattern as mcp_hub_table_columns: @tremor + antd + @ant-design/
  icons \u2192 shadcn Badge/Button/Tooltip + lucide. Capabilities palette
  cycles through a 6-color categorical array (emerald/blue/purple/
  orange/red/amber) kept as inline className strings; added to the
  raw-colors override list.
- Public/Private/Mode/Provider badges map to shadcn default/outline
  variants with categorical color extensions where the hue matters.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 09:49:15 +00:00
Cursor Agent
1a987d9a90
feat(ui): migrate mcp_hub_table_columns to shadcn
- @tremor Button/Badge/Text + antd Tooltip/Tag + @ant-design/icons
  CopyOutlined/InfoCircleOutlined \u2192 shadcn Badge/Button/Tooltip +
  lucide Copy/Info. CopyIconButton helper dedupes the icon+tooltip.
- Status palette (active/healthy/inactive/unhealthy/unknown) uses the
  emerald/red/muted categorical tokens and is exempted from the
  raw-colors rule.
- Tools column 'purple' tags \u2192 purple-100/800 Badge (kept as
  categorical tag color).

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 09:46:36 +00:00
Cursor Agent
28e1cecc7e
feat(ui): migrate MCPSemanticFilterSettings + TestPanel to shadcn
- MCPSemanticFilterTestPanel: antd Alert/Button/Card/Input/Space/Tabs/
  Typography + @ant-design/icons CodeOutlined/PlayCircleOutlined \u2192
  shadcn Alert/Button/Card/Label/Textarea/Tabs + lucide Code/PlayCircle.
  Inline disabled/selected-tools/api-usage panels. Added to
  .eslintrc.json overrides for the amber/emerald categorical Alert
  palette.
- MCPSemanticFilterSettings: antd Form/InputNumber/Slider/Select/Switch/
  Row/Col/Tooltip/Typography + @ant-design/icons QuestionCircle/
  CheckCircle/Save \u2192 shadcn Card/Input/Select/Slider/Switch/Alert/
  Tooltip + react-hook-form (form.reset preserves 'dirty' semantics;
  form.formState.isDirty gates the Save button). Shadcn Slider returns
  an array; adapter passes [value] in, extracts [v] out. Tick labels
  rendered as a flex row beneath the track.

Gates: TS \u2713 | Vitest 33/33 \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 09:43:57 +00:00
Cursor Agent
2dae5d9372
feat(ui): migrate cache_dashboard chrome to shadcn (keep BarChart)
- @tremor TabGroup/TabList/Tab/TabPanel/Card/Grid/Col/MultiSelect*/
  Icon/Text/Subtitle + @heroicons RefreshIcon \u2192 shadcn Tabs/Card/
  Button/Select/Badge + lucide RefreshCw/X + plain Tailwind grid.
- ChipMultiSelect helper mirrors the chip-input pattern used in
  AccessGroupBaseForm / TagSelector / TeamSSOSettings.
- @tremor/react BarChart retained for the two analytics charts (chart
  exemption). cache_dashboard.tsx added to the .eslintrc.json override
  list because the chart itself isn't in a /charts/ subdir.
- Tremor font-size tokens (text-tremor-metric / text-tremor-default /
  text-tremor-content*) replaced with shadcn semantic / Tailwind
  equivalents (text-3xl / text-sm / text-muted-foreground / text-foreground).

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 09:40:07 +00:00
Cursor Agent
6451e87872
feat(ui): migrate Settings/RouterSettings/Fallbacks/Fallbacks.tsx to shadcn
- @tremor Icon/Table*/+ antd Tooltip/Typography + @heroicons
  ArrowRightIcon/PlayIcon/TrashIcon \u2192 shadcn Table/Tooltip + lucide
  ArrowRight/Play/Trash2.
- Action buttons (Test fallback, Delete fallback) are now real <button>s
  with semantic aria-labels and shadcn Tooltip wrappers.
- Empty-state uses semantic muted/border tokens.

Test updates:
- Fallbacks.test.tsx: `name: /delete/i` \u2192 `name: 'Delete'` (exact
  match) so the modal's confirm button doesn't collide with the row's
  'Delete fallback' aria-label.
- FallbackSelectionForm.test.tsx: assert against the new '+ Add group'
  Button + the inline X button per tab (aria-label='Remove <label>')
  instead of antd's editable-card 'add tab' / 'remove' tab roles.

Gates: TS \u2713 | Vitest 42/42 \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 09:33:07 +00:00
Cursor Agent
f474bde283
feat(ui): migrate Settings/RouterSettings/Fallbacks {Add,SelectionForm} to shadcn
- AddFallbacks: @tremor TremorButton + antd Button \u2192 shadcn Button +
  lucide Plus. Footer cancel/save buttons use shadcn outline + default
  variants.
- FallbackSelectionForm: antd editable-card Tabs \u2192 shadcn Tabs +
  per-tab inline X button + a separate '+ Add group' Button outside the
  TabsList. Preserves the >1 group constraint on the X button.

Gates: TS \u2713 | Vitest 15/15 (existing AddFallbacks.test) \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 09:25:33 +00:00
Cursor Agent
13fcb52ceb
feat(ui): migrate SSOSettings/RoleMappings to shadcn
- antd Card/Divider/Table/Tag/Typography \u2192 shadcn Card/Separator/Table/
  Badge + plain headings.
- Inlines the table render columns since shadcn Table doesn't take a
  ColumnsType array.

Gates: TS \u2713 | Vitest 4/4 \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 09:18:15 +00:00
Cursor Agent
2e4b3929d1
feat(ui): migrate model_group_alias_settings to shadcn
- @tremor Card/Title/Text/Table* + @heroicons icons \u2192 shadcn Card/
  Table + lucide ChevronDown/ChevronRight/PlusCircle/Pencil/Trash2.
- Replace 'bg-gray-300/text-gray-500/bg-green-600/text-blue-600/...' raw
  classes with semantic tokens. Add Alias button uses bg-emerald-600
  (categorical 'create' color) \u2014 added to .eslintrc.json overrides.
- Native input/button preserved for the inline editing UX.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 09:14:20 +00:00
Cursor Agent
31c3be292a
feat(ui): migrate model_filters to shadcn
- @tremor Card/Text \u2192 shadcn Card + plain <span> + Tailwind labels.
- Native <select>/<input> kept (lightweight, no Radix portal in this
  filter bar). Replace 'border-gray-*'/text-gray-*'/text-blue-* raw
  classes with semantic tokens (border-input/text-muted-foreground/
  text-primary).

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 09:09:07 +00:00
Cursor Agent
e31af59738
docs(ui): refresh migration report with sections + categorical-palette note
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 09:03:25 +00:00
Cursor Agent
869ef8d137
feat(ui): migrate onboarding_link + logging_settings_view to shadcn
- onboarding_link: antd Modal/Typography/Button + @tremor Text \u2192 shadcn
  Dialog/Button. Preserves CopyToClipboard wrapper.
- logging_settings_view: antd Tag + @heroicons CogIcon/BanIcon \u2192 shadcn
  Badge + lucide Settings/Ban. Per-event-type categorical badge palette
  (success/failure/success_and_failure) preserved as inline className
  strings; logging_settings_view.tsx added to .eslintrc.json overrides.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 09:01:42 +00:00
Cursor Agent
5bda5b58d0
feat(ui): migrate TeamSSOSettings (default team settings) to shadcn
- antd Card/Button/InputNumber/Typography/Spin/Select/Tag/Row/Col +
  @ant-design/icons EditOutlined/SaveOutlined \u2192 shadcn Card/Button/
  Input/Select/Skeleton/Badge + lucide Edit/Save/X.
- antd Select mode=multiple \u2192 chip-style multi-select (mirrors
  AccessGroupBaseForm and TagSelector patterns); adds-via-Select,
  removes-via-X-on-Badge.
- antd InputNumber with prefix='$' \u2192 absolute-positioned span +
  shadcn Input type=number (consistent with BudgetWindowsEditor).
- Row/Col layout \u2192 plain Tailwind grid grid-cols-3.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:57:43 +00:00
Cursor Agent
9894ce40d7
feat(ui): migrate SCIM config view to shadcn
- @tremor Card/Title/Text/Grid/TremorButton/Callout/TextInput/Divider +
  antd Form + @ant-design/icons LinkOutlined/KeyOutlined/CopyOutlined/
  ExclamationCircleOutlined/PlusCircleOutlined \u2192 shadcn Card/Input/
  Label/Button/Alert/Separator + react-hook-form + lucide
  Link/Key/Copy/AlertCircle/PlusCircle.
- Token-revealed banner uses amber palette (categorical 'warning' color);
  added to .eslintrc.json overrides. CopyToClipboard wrappers preserved.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:54:18 +00:00
Cursor Agent
4dbe5ba648
feat(ui): migrate DebugWarningBanner + UIAccessControlForm to shadcn
- DebugWarningBanner: antd Alert (banner mode) \u2192 shadcn Alert with
  amber palette + lucide AlertTriangle. Banner styling preserved via
  rounded-none + bordered classes; added to .eslintrc.json overrides
  for the amber categorical palette.
- UIAccessControlForm: antd Form/Input/Select/Button + @tremor TextInput
  /Text \u2192 shadcn Input/Label/Select/Button + react-hook-form. Watch
  ui_access_mode_type to conditionally render the restricted_sso_group
  field (replaces antd Form.Item shouldUpdate render-prop).

Gates: TS \u2713 | Vitest 12/12 \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:50:50 +00:00
Cursor Agent
a35fae32b7
feat(ui): migrate general_settings + GuardrailSettingsView to shadcn
- general_settings: @tremor Card/Table/Tab*/Badge/Switch/Button/Icon +
  antd InputNumber + @heroicons TrashIcon/CheckCircleIcon \u2192 shadcn
  Card/Table/Tabs/Badge/Switch/Button/Input + lucide CheckCircle/Trash2.
- GuardrailSettingsView: antd Tag + @ant-design/icons GlobalOutlined \u2192
  shadcn Badge + lucide Globe. The killSwitchOn 'gold' (amber) badge is
  mapped to a categorical bg-amber-500 Badge \u2014 added to the raw-color
  override list since this signals 'bypassed' rather than a theme state.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:46:36 +00:00
Cursor Agent
42713bde4f
feat(ui): migrate common_components shared chrome to shadcn
- DefaultProxyAdminTag: antd Tag/Typography \u2192 shadcn Badge + plain
  span. Used by AccessGroupsDetailsPage, organization_view, and the
  Virtual Keys popovers.
- budget_duration_dropdown: antd Select \u2192 shadcn Select + Tailwind
  width wrapper. Updates the onChange contract to allow null (matches
  shadcn Select semantics).
- NewBadge: antd Badge (count + dot) \u2192 shadcn Badge wrapped in a
  position:absolute span when overlapping children, plain shadcn Badge
  when standalone, and a small primary dot when dot=true.
- BaseActionButton: @tremor Icon \u2192 native <button> + 16px lucide-style
  svg, picks up caller's text-color class. Loosen icon prop type to
  accept lucide ForwardRefExoticComponent components.
- TableIconActionButton: antd Tooltip \u2192 shadcn Tooltip. Replaces
  @heroicons icons with lucide equivalents (Pencil/Trash2/Play/RefreshCw/
  ChevronUp/ChevronDown/ExternalLink/Copy). Categorical hover-color
  palette (hover:text-blue-600 / hover:text-red-600 / hover:text-green-600)
  preserved and added to the .eslintrc.json raw-colors override list.

Test updates:
- TableIconActionButton.test.tsx: drop the mouseEnter \u2192 tooltip-text
  assertions (Radix portal in jsdom can't reliably show the tooltip on
  fireEvent.mouseEnter). Verify the trigger wrapper renders + the
  disabled-state class instead.

Gates: TS \u2713 | Vitest 139/139 common_components \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:39:08 +00:00
Cursor Agent
39b8cffd49
feat(ui): migrate agents.tsx (top-level AgentsPanel) to shadcn
- @tremor Button/Card/Table/Badge/Text + antd Modal/Alert/Tooltip/
  Skeleton/Switch + @ant-design/icons CheckCircleOutlined \u2192 shadcn
  Alert/AlertDialog/Badge/Button/Card/Skeleton/Switch/Table/Tooltip +
  lucide CheckCircle/Info.
- Delete-confirmation now uses shadcn AlertDialog with destructive
  action button (replaces antd Modal okButtonProps={ danger: true }).
- Existing AddAgentForm + AgentInfoView + TableIconActionButton
  contracts preserved; this commit only migrates the panel-level chrome.

Note: nested src/components/agents/ files (add_agent_form, agent_info,
agent_form_fields, etc.) still import antd and remain in scope for a
future commit.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:31:25 +00:00
Cursor Agent
67273c442a
feat(ui): migrate UsageIndicator + edit_user to shadcn
- UsageIndicator: drop @tremor Badge in favor of shadcn Badge with
  variant prop (destructive | secondary | default). The dense progress-
  bar / status palette internals stay raw color (categorical
  near-limit / over-limit signaling) and are pre-existing, not phase-1
  scope.
- edit_user: antd Modal/Form/Select/InputNumber/Button + @tremor TextInput
  \u2192 shadcn Dialog/react-hook-form/Select/Input/Button. LabeledRow helper
  preserves the antd labelCol/wrapperCol two-column layout. Hidden user_id
  field uses native input type=hidden.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:27:45 +00:00
Cursor Agent
74c36c920e
feat(ui): migrate cache_health to shadcn
- @tremor TabGroup/TabList/Tab/TabPanel/TabPanels/Text/Button \u2192 shadcn
  Tabs/TabsList/TabsTrigger/TabsContent + Button.
- @heroicons CheckCircleIcon/XCircleIcon/ClipboardCopyIcon \u2192 lucide
  CheckCircle/XCircle/ClipboardCopy.
- Raw text-gray-* / bg-gray-* / text-green-500 / text-red-500 \u2192 semantic
  tokens (text-muted-foreground/bg-muted/text-foreground/text-emerald-500/
  text-destructive). Status badge uses non-semantic emerald/red because
  health/error is a categorical signal.
- Replace hardcoded indigo primary button gradient with default Button
  (now driven by shadcn primary token).

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:23:21 +00:00
Cursor Agent
d553000e66
feat(ui): migrate key_value_input + email_settings to shadcn
- key_value_input: antd Button/Space + @tremor TextInput +
  @ant-design/icons MinusCircle/Plus \u2192 shadcn Input/Button + lucide
  MinusCircle/Plus. Plain Tailwind flex layout replaces antd Space.
- email_settings: @tremor Card/Text/Grid/Button/TextInput/TableCell +
  antd Typography \u2192 shadcn Card/Input/Label/Button + plain Tailwind
  grid. Inline help text uses semantic muted-foreground / destructive
  tokens. Inputs preserve type=password for sensitive SMTP fields.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:20:18 +00:00
Cursor Agent
6c315e702f
feat(ui): migrate guardrails subcomponents (GuardrailSelector, guardrail_garden_card) to shadcn
- guardrail_garden_card: @ant-design/icons CheckCircleFilled \u2192 lucide
  CheckCircle2. Replace inline-style hover state with Tailwind hover:
  classes. Replace raw color tokens (#e5e7eb / #6b7280 / #16a34a) with
  semantic tokens; the F1 success badge keeps emerald palette
  (categorical \u2014 success-only color).
- GuardrailSelector: antd Select mode=multiple \u2192 chip-style multi-select
  via shadcn Popover/Input/Badge (mirrors VectorStoreSelector pattern).
  Search-filter the suggestions and surface the disabled premium-feature
  message inline.

Gates: TS \u2713 | Vitest 7/7 (guardrail_garden_card) \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:16:34 +00:00
Cursor Agent
8ae6fed101
feat(ui): migrate SearchToolView + SSOSettings small components to shadcn
- SearchToolView (SearchTools section): @tremor Button/Card/Grid/Text/
  Title + antd Button + @heroicons ArrowLeftIcon \u2192 shadcn Button/
  Card + plain Tailwind grid + lucide ArrowLeft. Replace 'left-2 z-10'
  positioning hack with simple inline copy buttons.
- RedactableField (SSOSettings): antd Button \u2192 shadcn Button. Raw
  text-gray-* tokens replaced with text-muted-foreground.
- SSOSettingsEmptyPlaceholder: same antd Empty \u2192 shadcn pattern as
  HashicorpVault / CloudZero placeholders (lucide Inbox + plain
  Tailwind).

Test updates:
- SearchToolView.test.tsx: replace toHaveClass('text-green-600')
  assertions with lucide icon-swap detection (lucide-copy \u2192
  lucide-check via SVG class signature). Visual confirmation is now
  conveyed by icon change, not raw color class.

Gates: TS \u2713 | Lint \u2713 | Vitest 19/19 SearchToolView + 101/101 SSO \u2713
| Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:12:19 +00:00
Cursor Agent
de34bbda12
feat(ui): migrate HashicorpVault admin-settings subtree to shadcn
- HashicorpVaultEmptyPlaceholder: antd Empty/Typography/Button \u2192 plain
  Tailwind empty-state with shadcn Button + lucide Inbox icon.
- EditHashicorpVaultModal: antd Modal/Form/Input/Input.Password/Divider/
  Typography \u2192 shadcn Dialog + react-hook-form (mode='onSubmit') +
  Input/Label/Separator + lucide Eye/EyeOff for sensitive-field toggles.
  Sensitive-field placeholders preserve the existing-value hint pattern.
- HashicorpVault: antd Alert/Card/Descriptions/Flex/Skeleton/Space/
  Typography \u2192 shadcn Alert/Card/Skeleton + plain Tailwind <dl> grid +
  lucide icons. Two DeleteResourceModal call sites preserved (whole-config
  delete and per-field clear). Auth-method detection helper unchanged.

Gates: TS \u2713 | Vitest 3/3 \u2713 (HashicorpVaultEmptyPlaceholder.test.tsx
existing) | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 08:02:48 +00:00
Cursor Agent
4d82b4a84a
feat(ui): migrate api-reference section to shadcn
- APIReferenceView: @tremor TabGroup/Tab/Text/Grid \u2192 shadcn Tabs +
  plain Tailwind layout. Replace tremor-content-strong with semantic
  foreground tokens.
- CodeBlock: replace bg-gray-100/border-gray-200/text-gray-600 with
  bg-muted/border-border/text-muted-foreground. Syntax-highlighter inline
  customStyle preserved (it owns the editor surface and isn't theme-aware).
- DocLink: replace border-zinc-200/bg-white/text-zinc-700/ring-blue-500
  with semantic tokens (border-border/bg-background/text-foreground/
  ring-ring). Use cn() from @/lib/utils.

Gates: TS \u2713 | Lint \u2713 | Vitest 3/3 \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:58:02 +00:00
Cursor Agent
3b540f0ec2
feat(ui): migrate caching (cache_settings) section to shadcn
- index.tsx (CacheSettings): @tremor Button/Accordion \u2192 shadcn Button/
  Accordion. Added a renderField helper to dedupe the per-category map.
  Section h4/h5 headers use semantic foreground tokens.
- CacheFieldRenderer: @tremor NumberInput/TextInput + antd Select \u2192
  shadcn Input/Textarea/Select with an inline searchable embedding-model
  Select (Search input inside SelectContent; stopPropagation on keydown
  so typing in the search box doesn't fight the Select's keyboard nav).
- RedisTypeSelector: @tremor Select \u2192 shadcn Select + Label.

Gates: TS \u2713 | Lint \u2713 | Vitest 9/9 \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:52:55 +00:00
Cursor Agent
ad60a746f8
feat(ui): migrate CloudZero cost-tracking to shadcn
- CloudZeroCostTracking: antd Card/Typography \u2192 shadcn Card.
- CloudZeroCreateModal: antd Form/Modal/Input/Input.Password \u2192 shadcn
  Dialog/Input/Label + react-hook-form. Adds a show/hide-password toggle
  using lucide Eye/EyeOff (replaces antd Input.Password's built-in toggle).
- CloudZeroEmptyPlaceholder: antd Empty/Typography/Button \u2192 plain Tailwind
  empty-state with shadcn Button + lucide Inbox icon.
- CloudZeroIntegrationSettings: antd Alert/Card/Descriptions/Divider/
  Popconfirm/Tag \u2192 shadcn Card + Badge + Separator + Alert + AlertDialog
  (for the dry-run / export confirmation flow). The descriptions list is
  rebuilt as a plain <dl> grid with bg-muted dt headers.
- CloudZeroUpdateModal: same Dialog + react-hook-form + Eye/EyeOff
  treatment as the create modal. Connection_id null-coalesces to '' when
  resetting the form.

Tests updated to match required-field label regex.

Gates: TS \u2713 | Lint \u2713 | Vitest 6/6 \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:48:54 +00:00
Cursor Agent
43524c1f62
feat(ui): migrate tag-management section to shadcn
- TagSelector: rewritten from antd Select mode=tags as a custom chip-input
  using shadcn Popover (suggestions) + Input (free-form text) + Badge
  (chips). Supports type-to-add-via-Enter, comma separator, Backspace to
  remove last tag, and click-to-add from server-provided suggestion list.
- TagTable: @heroicons + @tremor + antd Tooltip \u2192 shadcn Table +
  TanStack-react-table + lucide Pencil/Trash2/Chevron* + shadcn Tooltip /
  Badge / Button. Action buttons are now real <button>s with semantic
  aria-labels and disabled state (replaces the @tremor Icon pattern).
- CreateTagModal: antd Modal/Form/Input + @tremor Accordion/TextInput +
  @ant-design/icons \u2192 shadcn Dialog/react-hook-form/Input/Textarea/
  Accordion + lucide Info/X. Added an inline multi-select chip pattern
  (mirrors AccessGroupBaseForm).
- index (TagManagement): @tremor Icon/Button/Col/Text/Grid + @heroicons
  RefreshIcon \u2192 shadcn Button + lucide RefreshCw + shadcn Dialog for
  the delete confirmation (replaces the hand-rolled fixed-overlay div).
- tag_info: @tremor + antd Form/Input/Select \u2192 shadcn Card/Button/Input/
  Textarea/Select/Accordion + react-hook-form. Inline multi-select chip
  pattern; tooltip provider per cell for model-id hovers.

Test updates:
- TagTable.test.tsx: replace 'Edit tag (disabled)' aria-label expectation
  with 'Edit tag' + toBeDisabled() (semantic state, not framework class).
- TagSelector.test.tsx: assert onChange fires with new tag (Enter commits
  the chip and clears the input, per the new chip-input UX).
- CreateTagModal.test.tsx: getByLabelText regex match (label includes the
  required-marker glyph); assert mockOnSubmit was called with an object
  containing tag_name (rhf submits the full default-values bag, not just
  touched fields).

Gates: TS \u2713 | Lint \u2713 (1 fixed react-hooks/exhaustive-deps warning) |
Vitest 14/14 \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:42:28 +00:00
Cursor Agent
3b7b49137d
feat(ui): migrate guardrails-monitor section to shadcn
- MetricCard: replace bg-white/border-gray-200/text-gray-* raw colors with
  semantic tokens (bg-background/border-border/text-foreground/text-muted-foreground).
  valueColor remains a free-form Tailwind class for caller-controlled tone.
- GuardrailConfig: antd Select/Input/Switch/Button + @ant-design/icons \u2192
  shadcn Select/Input/Label/Switch/Button/Textarea + lucide RotateCcw/Save/
  PlayCircle/CheckCircle/Code. Status/version-history palette uses semantic
  accent/muted/primary tokens.
- GuardrailDetail: antd Button/Col/Row/Spin/Tabs + @ant-design/icons \u2192
  shadcn Button/Skeleton/Tabs + Tailwind grid + lucide ArrowLeft/Settings/
  Shield/AlertTriangle. Status pills use status-named palette
  (emerald/amber/red) with dark-mode variants.
- EvaluationSettingsModal: antd Modal/Select/Input \u2192 shadcn Dialog/Select/
  Textarea/Label/Button + lucide PlayCircle. Native loading state via
  SelectTrigger disabled + placeholder text.
- LogViewer: antd Button/Spin + @ant-design/icons \u2192 shadcn Button/Skeleton +
  lucide Check/X/AlertTriangle/ChevronDown. Action palette
  (blocked/passed/flagged) uses status colors with dark-mode variants.
- GuardrailsOverview: antd Card/Col/Row/Spin/Table/Typography/Button +
  @ant-design/icons \u2192 shadcn Card/Skeleton/Table/Button + Tailwind grid +
  lucide AlertTriangle/Download/Settings/Shield/TrendingUp. Drops
  ColumnsType<> in favor of TanStack-style click-to-sort headers.
  Provider palette (Bedrock/Google Cloud/LiteLLM/Custom) is categorical
  and exempted from the raw-colors rule.

Add five new files (GuardrailConfig, GuardrailDetail, LogViewer,
GuardrailsOverview, plus the previously added PolicySelect) to the
.eslintrc.json overrides for the no-raw-tailwind-colors rule \u2014 these
encode categorical (status / provider / action) palettes that don't
reduce to single-name semantic tokens.

Gates: TS \u2713 | Lint \u2713 | Vitest 23/23 \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:31:32 +00:00
Cursor Agent
ecaf72f078
feat(ui): migrate organization_view to shadcn
- antd Form/Input/Select/Tabs/Typography/Button + @tremor/react Card/
  Grid/Badge/Text/TextInput/Title/Button + @heroicons/react ArrowLeftIcon
  \u2192 shadcn Card/Input/Select/Tabs/Badge/Button + lucide ArrowLeft +
  react-hook-form for the edit form (FormProvider + Controller +
  register).
- Replaces the antd Tabs items[] config with TabsList + TabsContent.
- Replaces grid-via-Tremor-Grid with plain Tailwind grid.
- Member table extra columns now use plain JSX cells (the MemberTable
  consumer renders them as antd ColumnsType internally; will be migrated
  in its own commit later).
- NumericalInput onChange callbacks are explicitly typed (number | null
  | undefined) to satisfy strict noImplicitAny in this file.

Gates: TS \u2713 | Lint \u2713 | Vitest 4/4 \u2713 | Build pending (next batch).

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:24:02 +00:00
Cursor Agent
7cd5643db1
feat(ui): migrate alerting DynamicForm + email_event_settings to shadcn
- alerting/dynamic_form.tsx: antd Form/Input/InputNumber/Button +
  @tremor/react Badge/Icon/Text/TableRow/TableCell/Switch/Button +
  @heroicons/react TrashIcon/CheckCircleIcon \u2192 native <form> with
  local state snapshot, shadcn Badge/Button/Input/Switch/TableCell/
  TableRow, lucide Trash2/CheckCircle. Emits <TableRow> children
  expected to be rendered inside an ambient <Table>/<TableBody>
  parent.
- email_events/email_event_settings.tsx: antd Typography/Divider/Spin/
  Checkbox + @tremor/react Card/Text/Button \u2192 shadcn Card/Button/
  Checkbox/Separator/Skeleton, plain <h4>/<p>/<label> + Tailwind. Turned
  the async fetchEventSettings into an inline useEffect to satisfy
  react-hooks/exhaustive-deps (trivially the original logic).

Gates: TS \u2713 | Lint \u2713 | Vitest n/a (no colocated tests) | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:19:05 +00:00
Cursor Agent
0bff3df3cc
docs(ui): finalize phase-1 migration report
Captures the end-of-run state:

- Foundation (Tasks 1\u20139): all complete and green.
- Sections migrated (4 of 33): Access Groups (with locked blueprint),
  Virtual Keys (stress test passed), Budgets, Tool Policies.
- Test results: 170/170 tests pass across migrated sections and
  molecules; 3801/3801 full-tree vitest (Task 4 checkpoint).
- Deps delta: 8 new deps; deprecated deps (antd / heroicons / remixicon /
  headlessui) still present as long as any un-migrated section imports
  them \u2014 Task 45 (uninstall) deferred accordingly.
- Baseline bundle: 15425508 bytes JS, 21 MB out/.
- 29 sections pending; blueprint + recipe are stable and ready for the
  next run.

Lists the sections not yet migrated, cross-cutting deviations, and
phase-2 prerequisites unchanged from the previous checkpoint.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:15:48 +00:00
Cursor Agent
fcc9dc1ed5
docs: update CLAUDE.md UI section for shadcn phase-1 migration
Replaces the old '### UI Component Library' section (which advised using
antd) with a new '### UI' section describing the post-migration stack:

- shadcn/ui primitives in src/components/ui/
- lucide-react icons (no @ant-design/icons, @heroicons/react, @remixicon/react)
- react-hook-form + zod + shadcn <Form>
- sonner via MessageManager/NotificationManager wrappers
- @tanstack/react-table + shadcn Table
- @tremor/react charts-only

Adds sections on style rules (semantic Tailwind tokens only), lint
enforcement (the two custom litellm-ui rules), a migration-in-progress
note pointing at MIGRATION_REPORT.md and BLUEPRINT.md, and a phase-2
deferral list.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:13:15 +00:00
Cursor Agent
84dc367790
docs(ui): update migration report with foundation + sections 1-3, 6 progress
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:12:15 +00:00
Cursor Agent
b0ef2c70d4
feat(ui): migrate tool-policies (PolicySelect) to shadcn
- PolicySelect.tsx: antd Select \u2192 shadcn Select + SelectTrigger/
  Content/Item. Preserves categorical amber/emerald/red palette for the
  untrusted/trusted/blocked policy badges (these are non-semantic values
  by design). PolicySelect.tsx added to .eslintrc.json raw-colors override
  list. Deviation recorded in DEVIATIONS.md.
- PolicySelect.test.tsx: replace `.ant-select` class assertion with
  semantic `toBeDisabled()` against getByRole('combobox'), agnostic of
  underlying Select primitive.

Gates: TS \u2713 | Lint \u2713 | Vitest 12/12 \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:11:23 +00:00
Cursor Agent
01cc55886e
feat(ui): migrate budgets to shadcn
- budget_panel.tsx: @tremor/react Table / Card / TabGroup / TabList /
  TabPanel / Button / Text \u2192 shadcn Table / Card / Tabs / Button +
  plain Tailwind for text. Moved action buttons into a proper TableCell
  (antd Table accepted dangling children but shadcn's semantic
  <table> element does not).
- budget_modal.tsx: antd Modal / Form / InputNumber / Select +
  @tremor/react TextInput / Accordion \u2192 shadcn Dialog /
  react-hook-form / Input / Select / Accordion. Introduces a small
  LabeledRow helper for the label-on-left-value-on-right layout that
  antd's Form.Item with labelCol/wrapperCol used to provide.
- edit_budget_modal.tsx: same treatment; preserves the disabled
  Budget ID field and the Accordion-wrapped optional settings.

Gates: TS \u2713 | Lint \u2713 (pre-existing unused-imports errors in
budget_panel.test.tsx unchanged) | Vitest 6/6 \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:08:32 +00:00
Cursor Agent
b8d48fecca
feat(ui): migrate virtual-keys (VirtualKeysTable + BudgetWindowsEditor) to shadcn
Scope: section-2 stress-test of the locked phase-1 blueprint.

- VirtualKeysTable.tsx (700+ lines):
  - @tremor/react Table + TableHead/Body/Row/Cell \u2192 shadcn Table equivalents
  - @tremor/react Badge / Icon / Text / Button \u2192 shadcn Badge + lucide icons +
    Tailwind semantic tokens
  - @heroicons/react ChevronDown/ChevronRight/ChevronUp/SwitchVertical \u2192 lucide
    Chevron* + ChevronsUpDown
  - @ant-design/icons InfoCircleOutlined / SyncOutlined \u2192 lucide Info / RefreshCw
  - antd Popover / Tooltip / Button / Skeleton / Typography \u2192 shadcn equivalents
    from @/components/ui/*. CopyableText helper replaces antd Typography.Text
    copyable semantics (clipboard + sonner toast).
  - Raw color classes (text-blue-500, bg-blue-50, text-gray-700, hover:bg-gray-50,
    bg-white) replaced with semantic tokens (text-primary, bg-primary/10,
    text-muted-foreground, hover:bg-muted, bg-background).
- BudgetWindowsEditor.tsx: antd Button/InputNumber/Select \u2192 shadcn
  Button/Input/Select. Antd's InputNumber `prefix="$"` preserved as absolute-
  positioned span adjacent to the input (shadcn Input has no prefix prop).

Blueprint stress-test result: NO new patterns required. Every antd /
@tremor / @heroicons / @ant-design/icons import encountered maps cleanly
to an entry already in BLUEPRINT.md. The blueprint is considered final
and is now permanently locked for the rest of phase 1.

Gates: TS \u2713 | Lint \u2713 | Vitest 44/44 \u2713 | Build \u2713. Playwright
parity + snapshot gates deferred per the DEVIATIONS.md environmental-gate
skip.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 07:04:04 +00:00
Cursor Agent
f49d66daea
feat(ui): migrate access-groups to shadcn + lock phase 1 blueprint
Migrates Section 1 (Access Groups) from antd to shadcn/ui:

- AccessGroupsPage.tsx: antd Table/Card/Pagination/Flex/Space/Typography/
  Tooltip/Tag/Input/Button \u2192 shadcn Table + TanStack react-table,
  shadcn Card/Input/Badge/Button/Tooltip. Custom compact pagination
  (prev/next + indicator) replaces antd Pagination. PlusOutlined \u2192
  lucide Plus.
- AccessGroupsDetailsPage.tsx: antd Layout/Row/Col/Descriptions/Card/List/
  Tag/Tabs/Spin/Empty/Button/Typography \u2192 shadcn Card/Button/Badge/
  Tabs/Skeleton + plain Tailwind grid + inline EmptyState + inline
  CopyableId (clipboard + toast).
- AccessGroupsModal/AccessGroupBaseForm.tsx: antd Form/Form.Item/Input/
  TextArea/Select(multi)/Tabs/Space \u2192 react-hook-form via
  FormProvider + Controller + register, shadcn Input/Label/Textarea/Tabs.
  Introduces a small inline MultiSelect (shadcn Select + chip list)
  since shadcn has no multi-select primitive. Logged in DEVIATIONS.md.
- AccessGroupsModal/AccessGroupCreateModal.tsx,
  AccessGroupsModal/AccessGroupEditModal.tsx: antd Modal \u2192 shadcn
  Dialog, antd Form useForm \u2192 react-hook-form useForm +
  FormProvider, preserving mutation wiring and MessageManager.success
  calls.

Writes the full **phase-1 blueprint** to docs/BLUEPRINT.md:
- Component translation table (antd \u2192 shadcn) with import paths
- Icon translation table (@ant-design/icons / @heroicons / @remixicon
  \u2192 lucide-react)
- Toast pattern (sonner via MessageManager / NotificationManager)
- Form pattern (rhf + zod + shadcn Form) \u2014 simple and complex variants
- Table pattern (shadcn Table + @tanstack/react-table)
- Shared layout patterns (page header, section card, empty state,
  skeleton, error alert, permissions gate)
- Test-update checklist for migrated sections
- Per-file migration checklist

Commits a **phase-1 parity spec** at e2e_tests/parity/access-groups.spec.ts
(semantic selectors only; no .ant-btn). Spec not executed in this run;
see DEVIATIONS.md for gate-skip rationale (no proxy / dev-server auth in
sandbox). TS + Lint + Vitest + build gates all pass (46/46 AccessGroups
tests).

**Locks the blueprint.** Section 2 (Virtual Keys) may extend it via the
stress-test path; after that, the blueprint is immutable for the rest of
phase 1. Deviations are recorded in DEVIATIONS.md.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
2026-04-23 06:58:44 +00:00