Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
defa8d2
fix: sort modal menu options alphabetically with prefix matches first
ariane-emory Dec 25, 2025
4cf3839
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 26, 2025
befb257
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 27, 2025
80e8de7
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 27, 2025
f7ddf85
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 27, 2025
9e14562
Merge dev branch into fix/modal-menus-filtered-order
ariane-emory Dec 28, 2025
4a5c4c8
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 28, 2025
6b3fb9e
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 28, 2025
e313b82
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 29, 2025
d8de36b
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 29, 2025
ac4cd09
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 29, 2025
918665b
Merge branch 'fix/modal-menus-filtered-order' of github.com:ariane-em…
ariane-emory Dec 29, 2025
2384cdb
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 29, 2025
f29bf6b
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 29, 2025
77902f0
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 29, 2025
2b0f12f
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 30, 2025
3a72992
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 30, 2025
46d3b99
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 30, 2025
d87d3b0
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 30, 2025
cbad23d
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 30, 2025
667c3ad
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Dec 31, 2025
f6a3c6b
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 1, 2026
a2eae9d
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 1, 2026
e02ad16
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 1, 2026
11f2255
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 2, 2026
27b9958
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 3, 2026
87bee46
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 3, 2026
6567d3b
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 4, 2026
097be11
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 4, 2026
cbcba55
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 4, 2026
09923c7
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 5, 2026
40cb87d
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 5, 2026
64af555
Merge branch 'fix/modal-menus-filtered-order' of github.com:ariane-em…
ariane-emory Jan 5, 2026
7097099
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 5, 2026
a37b7aa
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 5, 2026
579c3bf
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 5, 2026
a415aa1
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 6, 2026
347d7d3
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 6, 2026
6fc5688
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 6, 2026
74e834d
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 6, 2026
46e50ac
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 6, 2026
1d40723
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 7, 2026
aa81b32
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 7, 2026
ec61602
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 7, 2026
b7523e5
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 7, 2026
239fed6
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 8, 2026
e3aa164
Merge latest dev changes, preserving modal menus filtered order feature
ariane-emory Jan 11, 2026
98e7426
Fix syntax error in dialog-model.tsx from merge conflict resolution
ariane-emory Jan 11, 2026
14b7047
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 13, 2026
d1b652c
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 13, 2026
78f077d
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 15, 2026
53df0a8
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 16, 2026
a200957
Merge branch 'dev' into fix/modal-menus-filtered-order
ariane-emory Jan 17, 2026
ebce8b5
Fix OAuth callback test by using available port instead of conflictin…
ariane-emory Jan 17, 2026
b05ef14
Merge dev branch into fix/modal-menus-filtered-order
ariane-emory Jan 17, 2026
d03341b
Resolve merge conflict in OAuth callback test by keeping remote versi…
ariane-emory Jan 17, 2026
f64b9ce
Merge dev into fix/modal-menus-filtered-order
ariane-emory Jan 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,37 @@ export function DialogModel(props: { providerID?: string }) {
)
: []

// Search shows a single merged list (favorites inline)
if (needle) {
const filteredProviders = fuzzysort.go(needle, providerOptions, { keys: ["title", "category"] }).map((x) => x.obj)
const filteredPopular = fuzzysort.go(needle, popularProviders, { keys: ["title"] }).map((x) => x.obj)
return [...filteredProviders, ...filteredPopular]
// Apply fuzzy filtering to each section separately, maintaining section order
// Sort with prefix matches first (alphabetically), then other matches (alphabetically)
// Preserve "Free first" ordering within each group
if (q) {
const needle = q.toLowerCase()
const sortWithPrefixFirst = <T extends { title: string; footer?: string }>(items: T[]): T[] =>
items.sort((a, b) => {
const aTitle = a.title.toLowerCase()
const bTitle = b.title.toLowerCase()
const aIsPrefix = aTitle.startsWith(needle)
const bIsPrefix = bTitle.startsWith(needle)
if (aIsPrefix && !bIsPrefix) return -1
if (!aIsPrefix && bIsPrefix) return 1
// Preserve "Free first" within same prefix group
if (a.footer === "Free" && b.footer !== "Free") return -1
if (a.footer !== "Free" && b.footer === "Free") return 1
return a.title.localeCompare(b.title)
})
const filteredFavorites = sortWithPrefixFirst(
fuzzysort.go(q, favoriteOptions, { keys: ["title"] }).map((x) => x.obj),
)
const filteredRecents = sortWithPrefixFirst(
fuzzysort.go(q, recentOptions, { keys: ["title"] }).map((x) => x.obj).slice(0, 5),
)
const filteredProviders = sortWithPrefixFirst(
fuzzysort.go(q, providerOptions, { keys: ["title", "category"] }).map((x) => x.obj),
)
const filteredPopular = sortWithPrefixFirst(
fuzzysort.go(q, popularProviders, { keys: ["title"] }).map((x) => x.obj),
)
return [...filteredFavorites, ...filteredRecents, ...filteredProviders, ...filteredPopular]
}

return [...favoriteOptions, ...recentOptions, ...providerOptions, ...popularProviders]
Expand Down
15 changes: 13 additions & 2 deletions packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,19 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
const result = pipe(
props.options,
filter((x) => x.disabled !== true),
(x) => (!needle ? x : fuzzysort.go(needle, x, { keys: ["title", "category"] }).map((x) => x.obj)),
(x) => {
if (!needle) return x
const fuzzyResults = fuzzysort.go(needle, x, { keys: ["title", "category"] }).map((x) => x.obj)
return fuzzyResults.sort((a, b) => {
const aTitle = a.title.toLowerCase()
const bTitle = b.title.toLowerCase()
const aIsPrefix = aTitle.startsWith(needle)
const bIsPrefix = bTitle.startsWith(needle)
if (aIsPrefix && !bIsPrefix) return -1
if (!aIsPrefix && bIsPrefix) return 1
return a.title.localeCompare(b.title)
})
},
)
return result
})
Expand All @@ -87,7 +99,6 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
const result = pipe(
filtered(),
groupBy((x) => x.category ?? ""),
// mapValues((x) => x.sort((a, b) => a.title.localeCompare(b.title))),
entries(),
)
return result
Expand Down