Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Aug 28, 2025

This PR implements sorting and pinning functionality for both modes and API profiles in the Roo Code extension.

Summary

Adds the ability to sort and rearrange modes and API profiles under the main input area, with both automatic (alphabetical) and manual sorting options, along with pinning functionality.

Changes

  • ✨ Added global state fields for sorting preferences:

    • modeSortingMode: Controls sorting mode for modes (alphabetical/manual)
    • pinnedModes: Tracks which modes are pinned
    • customModeOrder: Stores custom order for manual mode sorting
    • apiProfileSortingMode: Controls sorting mode for API profiles
    • customApiProfileOrder: Stores custom order for API profile sorting
  • 📌 Implemented pinning functionality for modes (similar to existing API profile pinning)

    • Added pin button to each mode in the selector
    • Pinned modes appear at the top of the list
    • Pin state persists across sessions
  • 🔄 Updated components to respect sorting preferences:

    • ModeSelector: Now supports pinning and respects sorting preferences
    • ApiConfigSelector: Respects manual sorting when enabled
    • Both maintain fuzzy search functionality while preserving sort order
  • 💾 Added proper state persistence through VSCode global state

  • 📝 Added TypeScript type definitions for all new operations

  • ✅ All existing tests pass

What's Next

Future enhancements to consider:

  • Add UI controls in Settings view to toggle between sorting modes
  • Implement drag-and-drop for manual reordering
  • Add visual indicators for current sorting mode

Testing

  • Manually tested pinning/unpinning modes
  • Verified alphabetical sorting works correctly
  • Confirmed pin states persist across sessions
  • Fuzzy search still works with sorting applied
  • All unit tests pass
  • Linting passes

Fixes #7496


Important

This PR adds sorting and pinning functionality for modes and API profiles, updating state management and UI components to support these features.

  • Behavior:
    • Adds sorting and pinning for modes and API profiles in ModeSelector and ApiConfigSelector.
    • Supports alphabetical and manual sorting modes.
    • Pinned items appear at the top and persist across sessions.
  • State Management:
    • Adds modeSortingMode, pinnedModes, customModeOrder, apiProfileSortingMode, and customApiProfileOrder to global state in global-settings.ts.
    • Updates ClineProvider and webviewMessageHandler to handle new state fields.
    • Implements state persistence in ExtensionStateContext.tsx.
  • UI Components:
    • Updates ModeSelector.tsx and ApiConfigSelector.tsx to respect sorting and pinning preferences.
    • Adds pin buttons and sorting logic to UI components.

This description was created by Ellipsis for e4b5d3c. You can customize this summary. It will automatically update as commits are pushed.

- Add global state fields for sorting preferences (modeSortingMode, pinnedModes, customModeOrder, apiProfileSortingMode, customApiProfileOrder)
- Implement pinning functionality for modes similar to existing API profile pinning
- Update ModeSelector component to support pinning and respect sorting preferences
- Update ApiConfigSelector to respect manual sorting when enabled
- Add message handlers for new sorting operations
- Update ExtensionStateContext to include sorting settings and setters
- Modify ClineProvider to pass sorting settings to webview
- Add TypeScript type definitions for all new sorting operations

Implements #7496
@roomote roomote bot requested review from cte, jr and mrubens as code owners August 28, 2025 15:04
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Aug 28, 2025
setHistoryPreviewCollapsed: (value) =>
setState((prevState) => ({ ...prevState, historyPreviewCollapsed: value })),
setHasOpenedModeSelector: (value) => setState((prevState) => ({ ...prevState, hasOpenedModeSelector: value })),
setModeSortingMode: (value) => setState((prevState) => ({ ...prevState, modeSortingMode: value }) as any),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid using as any casts when updating new sorting state fields (e.g. in setModeSortingMode, setPinnedModes, etc.). It would be better to refine the state types so that these fields are typed correctly.

Copy link
Contributor Author

@roomote roomote bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote this code and even I'm not sure why it works.

}

return sorted
}, [modes, modeSortingMode, pinnedModes, customModeOrder])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test coverage for the new sorting and pinning functionality. Could we add tests to verify that:

  • Pinned modes appear at the top
  • Alphabetical sorting works correctly
  • Manual sorting respects the custom order
  • Pin state persists across sessions?

const merged = mergeExtensionState(prevState, newState)
// Handle new sorting settings if present
if ((newState as any).modeSortingMode !== undefined) {
;(merged as any).modeSortingMode = (newState as any).modeSortingMode
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional? Using as any type assertions here bypasses TypeScript's type safety. Could we properly extend the ExtensionState type in packages/types instead?

pinnedApiConfigs: z.record(z.string(), z.boolean()).optional(),

// Mode and API profile sorting preferences
modeSortingMode: z.enum(["alphabetical", "manual"]).optional(),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR mentions future UI controls for toggling between sorting modes, but currently there's no way for users to switch from "alphabetical" to "manual" mode. Should we add a basic toggle in the Settings view, or is this intentionally left for a follow-up PR?

if (modeSortingMode === "manual" && customModeOrder && customModeOrder.length > 0) {
// Sort based on custom order
sorted.sort((a, b) => {
const aIndex = customModeOrder.indexOf(a.slug)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The customModeOrder array is initialized empty and never populated, which means manual sorting won't actually work. Should we implement drag-and-drop or another mechanism to populate this array, or add a TODO comment for the follow-up implementation?


if (apiProfileSortingMode === "manual" && customApiProfileOrder && customApiProfileOrder.length > 0) {
// Sort based on custom order
sorted.sort((a, b) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sorting logic is nearly identical to the one in ModeSelector.tsx. Could we extract it into a shared utility function to reduce duplication?

setHasOpenedModeSelector: (value) => setState((prevState) => ({ ...prevState, hasOpenedModeSelector: value })),
setModeSortingMode: (value) => setState((prevState) => ({ ...prevState, modeSortingMode: value }) as any),
setPinnedModes: (value) => setState((prevState) => ({ ...prevState, pinnedModes: value }) as any),
togglePinnedMode: (modeSlug) =>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new optional props aren't validated before use. Could we add null checks or default values to prevent potential runtime errors?

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Aug 28, 2025
@daniel-lxs daniel-lxs moved this from Triage to PR [Needs Prelim Review] in Roo Code Roadmap Aug 29, 2025
@hannesrudolph hannesrudolph added PR - Needs Preliminary Review and removed Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. labels Aug 29, 2025
@daniel-lxs
Copy link
Member

Closing, see #7496 (comment)

@daniel-lxs daniel-lxs closed this Sep 1, 2025
@github-project-automation github-project-automation bot moved this from PR [Needs Prelim Review] to Done in Roo Code Roadmap Sep 1, 2025
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Sep 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request PR - Needs Preliminary Review size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT] Allow sorting and pinning for Modes and API Profiles under main input

4 participants