Skip to content

Commit 0879ebd

Browse files
fix: restore TUI model selector search box & update AGENTS.md (#932)
* fix: restore TUI model selector search box and add Core Focus docs * fix: update skill priority - compose first, superpowers fallback * docs: add final report for TUI model selector search fix * docs: add PR reference to report
1 parent 0d8a71d commit 0879ebd

3 files changed

Lines changed: 52 additions & 2 deletions

File tree

AGENTS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
- Always use superpowers skill instead of builtin plan mode.
1+
- Use MiMoCode Compose skills when available, otherwise use superpowers skill if installed.
22
- To regenerate the JavaScript SDK, run `./packages/sdk/js/script/build.ts`.
33
- ALWAYS USE PARALLEL TOOLS WHEN APPLICABLE.
44
- The default branch in this repo is `main`.
55
- CI triggers on both `main` and `dev` branches.
66
- Prefer automation: execute requested actions without confirmation unless blocked by missing info or safety/irreversibility.
77

8+
## Core Focus (as of 2025-06-18)
9+
10+
Our core development focus is the **TUI** (terminal UI) implementation in `packages/opencode/src/cli/cmd/tui/`. We do not currently provide support for Web or App interfaces. All operations should default to checking the TUI implementation first.
11+
812
## Style Guide
913

1014
### General Principles
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
feature: tui-model-selector-search
3+
status: delivered
4+
pr: https://github.com/XiaomiMiMo/MiMo-Code/pull/932
5+
branch: fix/model-selector-search-ui
6+
commits: 83ca130..ee30bc0
7+
---
8+
9+
# TUI Model Selector Search — Final Report
10+
11+
## What Was Built
12+
13+
Restored the search input box in the TUI model selector dialog (`/models` command). The search box was hidden due to `skipFilter={true}` being set on the `DialogSelect` component, which suppresses the built-in filter input. Removing this prop re-enables the search UI while preserving the existing custom fuzzysort filtering logic via `onFilter`.
14+
15+
## Architecture
16+
17+
The model selector consists of two layers:
18+
19+
- **`DialogModel`** (`packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx`) — builds the options list (favorites, recents, provider models, "+ Add model" entries) and performs custom fuzzysort filtering via a `query` signal.
20+
- **`DialogSelect`** (`packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx`) — generic selection dialog with built-in search input, keyboard navigation, and scroll. Renders the input when `skipFilter` is not set.
21+
22+
Data flow:
23+
```
24+
User types → DialogSelect <input onInput> → props.onFilter(query)
25+
→ DialogModel setQuery() → options() recomputes with fuzzysort
26+
→ DialogSelect receives new props.options → re-renders filtered list
27+
```
28+
29+
### Design Decisions
30+
31+
- **Custom filtering in DialogModel, not DialogSelect**: DialogModel uses `skipFilter` semantics — it passes pre-filtered `options` to DialogSelect rather than letting DialogSelect do the filtering. This allows model-specific logic (favorites/recents sections disappear on search, fuzzysort with weighted title/category scoring).
32+
- **"+ Add model" entries are searchable**: Each `source === "config"` provider appends a "+ Add model" option. Searching "add" surfaces all of them — this is intentional so users can identify which provider to add to. Normal model searches are unaffected by fuzzysort scoring.
33+
34+
## Usage
35+
36+
Press `/models` in TUI or trigger via keybind. The search input auto-focuses. Type to filter models by name or provider. Press Enter to select, Escape to close.
37+
38+
## Verification
39+
40+
- `bun typecheck` passes (full turbo, 12/12 packages)
41+
- CI: typecheck ✅, lint ✅, 8 test failures are all pre-existing (documented in #911)
42+
- Manual: search box renders and filters correctly in `/models` dialog
43+
44+
## Journey Log
45+
46+
- [lesson] `skipFilter={true}` hides the search input entirely in `DialogSelect` — this prop should only be used when search is genuinely unwanted (e.g. short fixed-option lists like worktree creation)
47+
- [lesson] When a component does its own filtering via `onFilter` callback, it still needs the input rendered — `skipFilter` controls UI visibility, not filtering logic

packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ export function DialogModel(props: { providerID?: string }) {
200200
]}
201201
onFilter={setQuery}
202202
flat={true}
203-
skipFilter={true}
204203
title={title()}
205204
current={local.model.current()}
206205
/>

0 commit comments

Comments
 (0)