Move every model choice and native select in the GUI onto the shared select

Open
#42 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Refactor
Clarity
Clearly specified
Activity status
Active
Tech stack
react, typescript

Research direction

Start with the select-base issue and its SearchableSelect.tsx and moved ModelPicker, then review SettingsPrimitives.tsx and the listed GUI component inventory. Migrate model choices, native selects, and SettingsSelect in separate commits while preserving IDs, accessibility labels, test hooks, disabled states, options, defaults, and saved values. Done means the listed search and mobile behaviors apply throughout, the rg check has no unexplained native selects, existing tests pass, and the requested desktop and touch-context phone screenshots are captured; coordinate around dependent issues and overlapping settings files.

Written by the indexing model from the issue text.

Description

enhancement

What feature would you like to see?

After the shared select base and the single model picker exist, most of the GUI still uses the browser's native <select>, the settings-only SettingsSelect, or its own model picker. Lists therefore still look and behave differently from page to page, long lists still have no search, and on a phone they still open as the platform's native picker or a desktop popover instead of a bottom sheet.

Decided
  • Every place where a model is chosen uses the one model picker.
  • Every native <select> and every SettingsSelect moves onto the shared select base (single mode, or multiple where the field is a list).
  • The base's rules apply everywhere: search appears at 8 options or more (LIST_TOOLS_MIN_ITEMS); phones get a bottom sheet.
  • This is a consolidation: no option lists, defaults or saved values change.
Design

Work through the inventory recorded by the select-base issue, directory by directory, in separate commits:

  1. Model choices → the model picker: Composer.tsx (model menu and ExternalModelChoice, :4259), harness/ExecutionSelect.tsx:105, settings/DefaultModelBar.tsx, settings/SessionTitleModelSettings.tsx, settings/SessionsSection.tsx, settings/DecisionSources.tsx, settings/ModelsSection.tsx, settings/profileEditor/fields.tsx (callers of the moved ModelPicker), output-layer/OutputPresetModal.tsx, persona/PersonaEditor.tsx.
  2. Native <select> (42 occurrences in 24 files at the time of the inventory) → the base. The largest groups: usage/export/UsageExportForm.tsx, settings/EngineInstanceForm.tsx, settings/EngineDefaults.tsx, task-board/*, CronTaskEditor.tsx, room/*, media/*.
  3. SettingsSelect (65 uses in 45 files) → make SettingsSelect a thin wrapper over the base so that its 45 callers change no code, then remove the wrapper only if that is a mechanical rename.

For each control keep its id, aria-label, data-* test hooks and disabled states, so existing tests keep their selectors.

Where
  • The inventory and components from the select-base issue (SearchableSelect.tsx, the moved ModelPicker).
  • apps/kiki-gui/src/components/settings/SettingsPrimitives.tsx:210 — SettingsSelect.
  • The files listed under "Design".
Done when
  • rg '<select\b' apps/kiki-gui/src -g '*.tsx' -g '!*.test.tsx' finds nothing, or each remaining hit has a one-line reason in the PR.
  • Every model choice in the GUI renders through the model picker (a test that the composer, Settings → Models default model, the profile editor and the output preset modal mount the same component).
  • Existing GUI tests pass; no saved setting changes value after a round trip through a migrated control.
  • Screenshots at desktop and phone width (light and dark, en and zh) via node apps/kiki-gui/scripts/visual-proof.mjs of: the composer model menu, Settings → Models, one engine settings form, the task board's new-task modal, and the usage export form; phone shots show the bottom sheet. Take phone shots in a touch context (isMobile: true, hasTouch: true, as apps/kiki-gui/scripts/visual-proof-mobile-reading.mjs:294-300 does): phone mode needs (pointer: coarse) (lib/layoutHooks.ts:57), which a width-only viewport does not give.

Additional information

  • Settings work tracked in other issues edits several of the same settings files (the Models section and the general / workspaces / memory / extensions / notifications sections). Do this issue after those land, or coordinate so that only one change is open per file at a time.
  • The composer is also touched by phone work; check open issues that list Composer.tsx before starting step 1.

Order and scope. Paths and line numbers refer to the code after the pending GUI interaction and mobile pull request is merged into kiki.
Depends on: #16, #39, #23, #24, #38.
Main files: apps/kiki-gui/src/components/Composer.tsx, apps/kiki-gui/src/components/harness/ExecutionSelect.tsx, apps/kiki-gui/src/components/settings/**, apps/kiki-gui/src/components/persona/PersonaEditor.tsx, apps/kiki-gui/src/components/output-layer/OutputPresetModal.tsx, apps/kiki-gui/src/components/usage/**, apps/kiki-gui/src/components/UsagePage.tsx, apps/kiki-gui/src/components/task-board/**, apps/kiki-gui/src/components/CronTaskEditor.tsx, apps/kiki-gui/src/components/room/**, apps/kiki-gui/src/components/media/**, apps/kiki-gui/src/components/QueueStrip.tsx and others.

Dominant language
TypeScript
Stars
54
Forks
5
Avg merge
2h 54m
Merged PRs (30d)
2

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from X-T-E-R/kiki

All issues in X-T-E-R/kiki

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.