- anchor the error status badge to the plugin card icon wrapper
- keep the badge positioned at the icon's bottom-right corner
- add a layout regression test for plugin task items
Added a utility function to generate plugin card icon URLs based on the plugin's source and workspace context. Updated the Card component to utilize this function for determining the correct icon source. Enhanced unit tests to verify the correct URL generation for both marketplace and package icons.
Replace the single `disabled` prop with a pure `deriveTriggerStatus` function
that maps to distinct states (empty, active, credits-exhausted, api-key-unavailable,
incompatible), each with its own badge text and tooltip. Unify non-workflow and
workflow modes into a single split layout, migrate icons to CSS icons, and add
per-status i18n tooltip keys.
- Updated the model provider popup to include loading state for marketplace plugins.
- Improved filtering logic for installed models and marketplace providers.
- Added tests to ensure correct behavior when no models are found and when query parameters are omitted.
- Refactored the handling of model lists to better manage installed and available models.
- Added tests for ModelSelectorTrigger to validate rendering based on credential panel state, including handling of credits exhausted scenarios.
- Updated ModelSelectorTrigger component to utilize useCredentialPanelState for determining status and rendering appropriate UI elements.
- Adjusted related tests to ensure correct behavior when model quota is exceeded and when the selected model is readonly.
- Improved styling for credits exhausted badge in the component.
Problem: Model provider settings page (/plugins?action=showSettings&tab=provider)
was missing plugin update indicators (red dot badge, Update button) that the
/plugins page correctly displayed, because it only fetched installation data
without querying for latest marketplace versions.
Decision: Extract a shared usePluginsWithLatestVersion hook and migrate plugin
API endpoints to oRPC contracts, ensuring both pages use identical data flows.
Model: Both pages now follow the same pattern — fetch installed plugins via
consoleQuery.plugins.checkInstalled, enrich with latest version metadata via
usePluginsWithLatestVersion, then pass complete PluginDetail objects downstream
where useDetailHeaderState computes hasNewVersion for UI indicators.
Impact:
- Update badge red dot and Update button now appear on provider settings page
- Shared hook eliminates 15 lines of duplicate enrichment logic in plugins-panel
- oRPC contracts replace legacy post() calls for plugin endpoints
- Operation dropdown uses auto-width to prevent "View on Marketplace" text wrapping
- Version badge aligned to use Badge component consistently across both pages
- Update button tooltip added with bilingual i18n support
- Deprecated Tooltip migrated to Base UI Tooltip in detail-header
- Migrate PortalToFollowElem to base-ui Popover in model-selector,
model-parameter-modal, and plugin-detail-panel model-selector
- Migrate legacy Tooltip to compound Tooltip in popup-item and trigger
- Unify EmptyTrigger, ModelTrigger, DeprecatedModelTrigger into a
single declarative ModelSelectorTrigger that derives state from props
- Remove showDeprecatedWarnIcon boolean prop anti-pattern; deprecated
state always renders warn icon as part of component's visual contract
- Remove deprecatedClassName prop; component manages disabled styling
- Replace manual triggerRef width measurement with CSS var(--anchor-width)
- Remove tooltip scroll listener (base-ui auto-tracks anchor position)
- Restore conditional placement for workflow mode in plugin-detail-panel
- Prune stale ESLint suppressions for removed deprecated imports
- Updated tests for CredentialItem to improve delete button interaction and check icon rendering.
- Enhanced PopupItem tests by mocking credential panel state for various scenarios, ensuring accurate rendering based on credit status.
- Adjusted Popup tests to include trial credits mock for better coverage of credit management logic.
- Refactored model list item tests to include wrapper for consistent rendering context.
Replace dynamic imports with static imports in marketplace atom tests.
Convert type-only and not-toThrow assertions into proper state-change
verifications. Add comprehensive test suite for model-provider-page
atoms covering all four hooks, cross-hook interaction, selectAtom
granularity, and Provider isolation.
- Replace deprecated Confirm mock with real AlertDialog role-based queries
- Add useInvalidateCheckInstalled mock for QueryClient dependency
- Wrap model-list-item renders in QueryClientProvider
- Migrate PluginVersionPicker from PortalToFollowElem to Popover
- Migrate UpdatePluginModal from Modal to Dialog
- Update version picker offset props (sideOffset/alignOffset)
- Migrate OperationDropdown from legacy portal-to-follow-elem to base UI DropdownMenu primitives
- Add placement, sideOffset, alignOffset, popupClassName props for flexible positioning
- Fix version badge font size: system-2xs-medium-uppercase (10px) → system-xs-medium-uppercase (12px)
- Set provider card dropdown to bottom-start placement with 192px width per Figma spec
- Fix PluginVersionPicker toggle: clicking badge now opens and closes the picker
- Add max-h-[224px] overflow scroll to version list
- Replace Remix icon imports with Tailwind CSS icon classes
- Prune stale eslint suppressions for migrated files