Skip to content

feat(cli): unify TUI dialog interaction and visuals#363

Merged
liruifengv merged 8 commits into
mainfrom
feat/unify-tui-dialog-ux
Jun 3, 2026
Merged

feat(cli): unify TUI dialog interaction and visuals#363
liruifengv merged 8 commits into
mainfrom
feat/unify-tui-dialog-ux

Conversation

@liruifengv
Copy link
Copy Markdown
Collaborator

@liruifengv liruifengv commented Jun 3, 2026

Related Issue

No prior issue — the problem is described below.

Problem

TUI dialogs and selectors had drifted apart: each picker hardcoded its own selection pointer (> / / ), current-item marker ( / (current)), header layout, and keyboard-hint wording (close / back / exit / dismiss mixed with cancel, ▲▼ vs ↑↓, inconsistent capitalization). /model packed too many controls into one view, and the custom-registry import had an awkward two-field flow with an optional token. There was no single source of truth for how a list dialog should look or behave.

What changed

  • Unified spec. List dialogs follow one layout: a single top border, a (type to search) title suffix on searchable lists, a hint line directly under the title, the shared SELECT_POINTER () and CURRENT_MARK (← current), and a uniform hint vocabulary (capitalized keys, lowercase descriptions, ↑↓/←→, · separator).
  • Consistency fixes across /model, /provider, /plugins, sessions, tasks, help, approval/output viewers, and the queue pane: exit wording standardized to cancel, hardcoded pointers replaced with the shared constant, and ▲▼ replaced with ↑↓.
  • Plugins behavior: drop arrow-key hierarchy navigation (Enter opens a detail, Esc returns), install marketplace plugins on Enter only (Space stays a toggle), reword the inline change badge to require run /new to apply, and stop the editor flash when toggling a plugin.
  • Provider behavior: the provider manager is a plain list (no fuzzy search); delete uses the D key, matching /plugins.
  • Custom-registry import: token is required, with multi-field navigation.
  • Developer docs: introduce the write-tui skill carrying the DESIGN.md interaction/visual spec, and refresh apps/kimi-code/AGENTS.md (plus a root pointer) to match the current TUI architecture.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran `gen-changesets` skill, or this PR needs no changeset.
  • Ran `gen-docs` skill, or this PR needs no doc update.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 3, 2026

🦋 Changeset detected

Latest commit: 51e9a5d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jun 3, 2026

pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@51e9a5d
npx https://pkg.pr.new/@moonshot-ai/kimi-code@51e9a5d

commit: 51e9a5d

Align every list dialog and selector to a single spec: shared selection
pointer and current-item marker, single-border header with a (type to
search) title suffix, consistent search line, and a uniform keyboard-hint
vocabulary. Replace ad-hoc exit wording (close/back/exit/dismiss) with
cancel, hardcoded pointers with the shared constant, and ▲▼ with ↑↓.

Also add fuzzy search to /provider, restyle the /model provider tabs, and
require a token with multi-field navigation in the custom-registry import.

Introduce the write-tui skill (carrying the DESIGN.md spec) and refresh
the apps/kimi-code development guide to match the current TUI architecture.
@liruifengv liruifengv force-pushed the feat/unify-tui-dialog-ux branch from bb88e2e to defea26 Compare June 3, 2026 06:02
The plugins overview and its marketplace/MCP sub-views used Left/Right to
enter and exit details. Remove that hierarchy navigation: Enter opens a
detail, Esc returns, and the arrow keys no longer jump between levels.
Update the sub-view hints from `←/Esc cancel` to `Esc cancel`.
The marketplace install action also fired on Space, which collides with
the Space-toggle convention used elsewhere. Bind install to Enter only and
update the hint to `Enter install/update`.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7d3e34a3f9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +234 to +236
if (tokenValue.length === 0) {
this.hint = 'token-empty';
this.activeField = 'token';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allow empty registry tokens for public imports

When the user imports a public api.json registry that does not require a Bearer token, this validation blocks the TUI flow before fetchCustomRegistry can run. The registry fetcher explicitly supports an empty apiKey by omitting the Authorization header (packages/oauth/src/custom-registry.ts), and the previous dialog submitted an empty token, so /provider can no longer add public custom registries from the TUI even though the backend still supports them.

Useful? React with 👍 / 👎.

The inline badge shown on a changed plugin row read `pending /new`, which
was cryptic. Reword it to `require run /new to apply`. Also switch the
marketplace-install message-flow tests to Enter, matching the Enter-only
install binding.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f5a157d4eb

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/kimi-code/src/tui/components/dialogs/provider-manager.ts Outdated
Each plugin picker's onSelect unconditionally restored the editor before
the handler re-mounted the refreshed picker, so an in-place action like
Space-toggling a plugin flashed: picker → editor → picker. Drop the
pre-restore from the overview/marketplace/MCP onSelect callbacks and let
each handler branch mount its next view; the two branches that close to the
editor (show-list, info) restore it themselves.
Remove the fuzzy filter from the provider manager: no query state, search
line, or type-to-search title suffix, and Esc closes directly. With no
type-to-search to clash with, bind delete to the D key (matching /plugins)
instead of Del/Ctrl+D. Update the write-tui spec to specify D as the
delete shortcut.
The model selector seeded a single thinking draft from the global thinking
flag, so highlighting a thinking-capable model showed Off whenever the
active model had thinking off (e.g. a non-thinking current model). Compute
the draft per model instead: the active model keeps its live state, any
other thinking-capable model defaults to On, and a ←/→ toggle is remembered
per model.
@liruifengv liruifengv merged commit 90879f3 into main Jun 3, 2026
8 checks passed
@liruifengv liruifengv deleted the feat/unify-tui-dialog-ux branch June 3, 2026 11:31
@github-actions github-actions Bot mentioned this pull request Jun 3, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 51e9a5d9ea

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 153 to +155
const totalSegmentWidth = segments.reduce((sum, s) => sum + visibleWidth(s), 0);
if (1 + totalSegmentWidth <= width) {
const hint = chalk.hex(colors.textMuted)('Tab / Shift+Tab provider');
let strip = ' ' + segments.join('');
const available = width - visibleWidth(strip) - 1;
if (available >= visibleWidth(hint) + 1) {
const pad = ' '.repeat(available - visibleWidth(hint));
strip += pad + hint;
}
return strip;
return ' ' + segments.join(' ');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include tab separators in width checks

When there are multiple provider tabs and the terminal width is close to the strip width, this branch decides that all tabs fit using only the sum of the segment widths, but the returned string now inserts spaces between segments with segments.join(' '). For n tabs that adds n - 1 extra columns after the fit check, so the outer render truncates the tab strip and can cut off a visible tab instead of falling back to the scrolling path. Account for the separator widths in both the fit calculation and the scrolling window sizing.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant