Problem Statement
The beta8 visual review surfaced broad inconsistency across the app chrome: the top toolbar's action buttons are visibly smaller/lighter than the text next to them (weight imbalance), small triangle glyphs (▹, ▾, an SVG chevron) read as jarring bullets that don't match surrounding size/style/color, page primary buttons are inconsistent in placement and size (HomePage is the lone left-aligned md exception), and refresh entries are missing on some pages while scattered locally on others. One real direction bug was found: the HomePage "update available" check is a plain string-inequality comparison, so it offers an "upgrade" to an older version whenever the installed mise is newer than the latest published one (2026.9.2 installed vs 2026.9.1 latest). Finally, the tools page — the flagship surface of this release — is not self-explanatory on first use: unclear table signals, forms that don't submit on Enter, and comprehension gaps that force reading docs.
Evidence doc (full user quotes, code investigation, finalized decisions): docs/feedback/beta8-feedback-scratch.md.
Solution
Three threads of tickets:
- Chrome / consistency fixes — rebalance top-toolbar action buttons (12px /
--text), remove all caret glyphs from menu triggers (▾, LanguageSwitcher chevron), unify the ▹ separator to → with --flare coloring everywhere, codify and apply "page primaries right-aligned at size sm", and move refresh into a single top-toolbar button fed by a page-registered refresh context (deleting the 7 local refresh buttons).
- Tools-page deep polish — table signal semantics (not-active marker, full
current → latest path in the Latest column, stable version color), keyboard-ization of all forms (Enter submit / Escape revert), datalists, and form comprehension (empty-state copy, link explanation, browse-registry entry, empty version = latest, click-tool-prefills-query, live command preview).
- GUI-layer table affordances per ADR-0007 — replace the 5 percentage columns with fixed px widths, add drag-resize with per-column min widths persisted to localStorage, text filter on tools/env/tasks/settings tables, sortable columns, shared CopyButton, and UI-state persistence (execution panel open/height, sidebar collapsed, per-table pageSize).
User Stories
- As a MiseDeck user, I want the top toolbar's action buttons (全局 / 在终端打开 / 最近) to be the same size and visual weight as the path text beside them, so that the toolbar reads as one balanced line.
- As a MiseDeck user, I want the
▾ caret removed from the 最近 button, so that the toolbar has no jarring mismatched glyphs.
- As a MiseDeck user, I want the LanguageSwitcher to drop its SVG chevron, so that no menu trigger anywhere carries a caret glyph.
- As a MiseDeck user, I want the eyebrow「当前目录」left untouched, so that the design system's single uppercase element stays intact.
- As a MiseDeck user, I want the version-comparison on HomePage to be directional, so that I'm never offered an "upgrade" to a version older than what I have installed.
- As a MiseDeck user, I want
▹ replaced by → everywhere (HomePage / ToolsPage / DoctorPage) with consistent --flare coloring, so that separator glyphs match surrounding text in size, style, and color.
- As a MiseDeck user, I want leftover
▾ glyphs (StyleGuide demo, i18n demo strings) swept out, so that the glyph vocabulary stays clean.
- As a MiseDeck user, I want the "View release notes" link at the right end of the Latest-version row, so that related information sits with the data it describes.
- As a MiseDeck user, I want the self-update button right-aligned at size sm and named 更新版本 / Update, so that it matches every other page's primary button pattern and doesn't read as a raw command.
- As a MiseDeck user, I want the notFound and tooOld states on HomePage to use the same right-aligned sm button, so that all three states are consistent.
- As a MiseDeck user, I want the tools table's 工具 column at a sensible fixed width (~160px, ellipsis + Tooltip for overflow), so that it stops ballooning to half the window.
- As a MiseDeck user, I want all 5 percentage-based table columns replaced by fixed px widths, so that tables stop stretching unevenly with window size.
- As a MiseDeck user, I want to drag table column borders to resize (with per-column minimum widths), so that I can shape tables to my content.
- As a MiseDeck user, I want my adjusted column widths persisted across restarts (localStorage keyed by page+table), so that I don't redo layout work.
- As a MiseDeck user, I want to click a table header to sort (with
↑/↓ data glyphs and numeric segment comparison for versions), so that I can find outliers quickly.
- As a MiseDeck user, I want a text filter on the tools table, so that I can narrow a long tool list.
- As a MiseDeck user, I want the same filter on env / tasks / settings tables via a shared hook, so that filtering works the same everywhere.
- As a MiseDeck user, I want copy buttons for tool name / version / source path (and other copyable values app-wide via a shared CopyButton), so that I can grab values without selecting text.
- As a MiseDeck user, I want the execution panel's open/height, the sidebar's collapsed state, and each table's pageSize remembered, so that the app reopens the way I left it.
- As a MiseDeck user, I want a single refresh button in the top toolbar that refreshes whatever page I'm on, so that refresh exists on every page and lives in one predictable place.
- As a MiseDeck user, I want the 7 local refresh buttons (settings, doctor, overview ×2, tasks, tools, plugins) gone, so that there's exactly one refresh entry.
- As a MiseDeck user, I want the 全部升级 (upgrade-all) button removed, so that the GUI doesn't bundle multiple commands into a new feature the CLI doesn't have.
- As a MiseDeck user, I want the Plugins install button to be primary like the tools page's, so that install actions look identical app-wide.
- As a MiseDeck user, I want 选择其他目录 to be secondary when it sits beside other toolbar buttons (while a lone empty-state way out may stay primary), so that button hierarchy is predictable.
- As a MiseDeck user, I want section eyebrows that merely repeat the page eyebrow removed (overview ×3, doctor ×5, env ×1, lockfile MISE.LOCK), so that each eyebrow appears once per page.
- As a MiseDeck user, I want the mise.lock section hidden entirely when the file is missing, so that I never see a dead placeholder section.
- As a MiseDeck user, I want the overview's global-mode empty state deduped against its section headers, so that the same words don't appear twice.
- As a MiseDeck user, I want inactive tools' rows dimmed with a small「未激活」note, so that I can tell at a glance which version is active.
- As a MiseDeck user, I want the Latest column to render the full
current → latest path (with Tooltip carrying the full path), so that the upgrade story is complete in one cell.
- As a MiseDeck user, I want the current version number's color to stay stable, so that attention goes to the Latest column instead of flickering decoration.
- As a MiseDeck user, I want every form (9 sites: tools ×4, env ×2, tasks ×1, settings ×2) to submit on Enter and revert on Escape via a shared pattern, so that the keyboard works the same everywhere.
- As a MiseDeck user, I want datalists on the switch-version input (installed versions + latest), the query input (known tool names), env var names, and task depends, so that valid values are suggested as I type.
- As a MiseDeck user, I want the tools-page empty state to point me at the install form / Registry, so that I'm guided to act inside the GUI instead of reading docs.
- As a MiseDeck user, I want the link form to explain what
mise link does (in mise's own words) with the picker demoted to secondary, so that I understand the action before running it.
- As a MiseDeck user, I want a "Browse Registry" ghost link in the install form and an explicit "empty version = latest" placeholder, so that I know where to find tools and what leaving the field blank means.
- As a MiseDeck user, I want clicking a tool name to prefill and run an installed-versions query, so that exploring versions takes one click.
- As a MiseDeck user, I want the query section's command preview to update live as I type, so that the GUI teaches me the CLI command I'm building.
- As a MiseDeck user, I want the tasks-page empty state to offer "open config file in editor", so that the page isn't a dead end.
- As a MiseDeck user, I want an uninstall row action on installed plugins (confirm dialog + execution panel running the real
mise plugins uninstall), so that I can complete the plugin lifecycle in the GUI.
- As a MiseDeck user, I want the doctor page's update hint to link to Home ("update on Home"), so that the self-update loop closes.
- As a MiseDeck user, I want Tooltips to never pop on empty / "—" values (one fix in the shared primitive), so that empty cells stop producing pointless hover boxes.
- As a MiseDeck user, I want the settings toolbar count to use a dedicated i18n key with
{{count}} interpolation, so that the sentence is translatable instead of concatenated.
- As a MiseDeck user, I want the 14 hardcoded font-size literals across 6 page CSS files moved onto tokens, so that type sizes stay governed by the design system.
Implementation Decisions
Synthesized from the finalized (定稿) tables in docs/feedback/beta8-feedback-scratch.md:
- Caret removal everywhere: menu/dropdown triggers carry no caret glyph — the hardcoded
▾ on the 最近 button and the LanguageSwitcher SVG chevron are both deleted with no replacement; expandability is conveyed by interaction.
→ replaces ▹: all real uses (HomePage, ToolsPage, DoctorPage) switch to the text glyph → with a shared span class and uniform --flare coloring; visual-language.md and ui-ux-rules.md already codify the swap plus the size/style/color-matching glyph rule (both locales).
- Page primaries right-aligned, size sm: HomePage's three states (updateAvailable / notFound / tooOld) move to right-aligned
sm buttons; zh copy 更新版本, en "Update"; release-notes link moves to the right end of the Latest-version DataRow.
- Unified refresh: refresh is a page-level capability owned by the top toolbar. PageShell gains a refresh-registration context; each page registers "invalidate all my queries" (plugins registers one callback refreshing both Registry and installed list); the 7 local refresh buttons and their CSS are deleted. Rule codified in
ui-ux-rules.md.
- Directional version compare: date versions are split on
. and compared segment-wise numerically in a small frontend function (no Rust changes); upgrade UI shows only when latest > installed.
- Table component gains resize / min-width / localStorage: drag handle on header column borders (visible on hover,
col-resize cursor), per-column declared minimum widths, widths persisted keyed by page+table; implemented once in the Table component so all 6 fixed tables gain it. The 5 percentage columns (tasks ×2, settings, directory preview, tools) become fixed px with content-derived minimums; table min-width becomes the sum of column px values.
- Shared Enter/Esc form pattern: one shared pattern/small wrapper (not nine one-offs) gives
<form onSubmit> + Escape revert to all 9 form sites.
- Tooltip primitive guards empty values: the Tooltip component refuses to pop for empty / "—" values — one fix covers the whole app.
- Shared CopyButton: one component adopted app-wide for copyable values (tool name/version/source path, RAW JSON block, etc.).
- Choose-directory exception: the variant mapping table gains a codified exception — a lone way out in an empty/missing state may be primary; in a multi-button toolbar 选择其他目录 drops to secondary.
- Upgrade-all removed: button, handler, and i18n keys (
tools.actions.upgradeAll, tools.noOutdated) deleted in both locales; mise outdated data still feeds the Latest column.
- Bulk operations OUT: bulk upgrade/uninstall bundles multiple commands into a feature the CLI doesn't have — that crosses the presentation/interaction boundary and is the first application of ADR-0007's boundary. Recorded as precedent.
- Sort indicators:
↑/↓ text glyphs rendered as data (not decoration, exempt from the caret ban); sorted column header gets --text weight.
- References: ADR-0007 (GUI-layer affordances are orthogonal to CLI functionality) and the newly codified
ui-ux-rules.md / visual-language.md rules (glyphs & icons, action-button placement/size, unified refresh, eyebrow dedupe, i18n one-meaning-one-key).
Testing Decisions
- No frontend test harness exists in this repo; acceptance is
npm run ci + cargo check green plus a static self-audit against docs/design/ui-ux-rules.md and visual-language.md.
- Every ticket is marked "not visually verified"; the owner verifies visuals manually.
Out of Scope
- Bulk upgrade / uninstall (CLI-feature territory per ADR-0007).
- Right-click context menus, density toggle, undo.
- P6 column show/hide, P8 focus management, P9 skeleton screens, P10 directory favorites — recorded as candidates in HANDOFF.md.
Priority
The tools page is the top priority of this batch — tickets touching it should be worked first.
Problem Statement
The beta8 visual review surfaced broad inconsistency across the app chrome: the top toolbar's action buttons are visibly smaller/lighter than the text next to them (weight imbalance), small triangle glyphs (
▹,▾, an SVG chevron) read as jarring bullets that don't match surrounding size/style/color, page primary buttons are inconsistent in placement and size (HomePage is the lone left-alignedmdexception), and refresh entries are missing on some pages while scattered locally on others. One real direction bug was found: the HomePage "update available" check is a plain string-inequality comparison, so it offers an "upgrade" to an older version whenever the installed mise is newer than the latest published one (2026.9.2 installed vs 2026.9.1 latest). Finally, the tools page — the flagship surface of this release — is not self-explanatory on first use: unclear table signals, forms that don't submit on Enter, and comprehension gaps that force reading docs.Evidence doc (full user quotes, code investigation, finalized decisions):
docs/feedback/beta8-feedback-scratch.md.Solution
Three threads of tickets:
--text), remove all caret glyphs from menu triggers (▾, LanguageSwitcher chevron), unify the▹separator to→with--flarecoloring everywhere, codify and apply "page primaries right-aligned at size sm", and move refresh into a single top-toolbar button fed by a page-registered refresh context (deleting the 7 local refresh buttons).current → latestpath in the Latest column, stable version color), keyboard-ization of all forms (Enter submit / Escape revert), datalists, and form comprehension (empty-state copy, link explanation, browse-registry entry, empty version = latest, click-tool-prefills-query, live command preview).User Stories
▾caret removed from the 最近 button, so that the toolbar has no jarring mismatched glyphs.▹replaced by→everywhere (HomePage / ToolsPage / DoctorPage) with consistent--flarecoloring, so that separator glyphs match surrounding text in size, style, and color.▾glyphs (StyleGuide demo, i18n demo strings) swept out, so that the glyph vocabulary stays clean.↑/↓data glyphs and numeric segment comparison for versions), so that I can find outliers quickly.current → latestpath (with Tooltip carrying the full path), so that the upgrade story is complete in one cell.mise linkdoes (in mise's own words) with the picker demoted to secondary, so that I understand the action before running it.mise plugins uninstall), so that I can complete the plugin lifecycle in the GUI.{{count}}interpolation, so that the sentence is translatable instead of concatenated.Implementation Decisions
Synthesized from the finalized (定稿) tables in
docs/feedback/beta8-feedback-scratch.md:▾on the 最近 button and the LanguageSwitcher SVG chevron are both deleted with no replacement; expandability is conveyed by interaction.→replaces▹: all real uses (HomePage, ToolsPage, DoctorPage) switch to the text glyph→with a shared span class and uniform--flarecoloring;visual-language.mdandui-ux-rules.mdalready codify the swap plus the size/style/color-matching glyph rule (both locales).smbuttons; zh copy 更新版本, en "Update"; release-notes link moves to the right end of the Latest-version DataRow.ui-ux-rules.md..and compared segment-wise numerically in a small frontend function (no Rust changes); upgrade UI shows only whenlatest > installed.col-resizecursor), per-column declared minimum widths, widths persisted keyed by page+table; implemented once in the Table component so all 6 fixed tables gain it. The 5 percentage columns (tasks ×2, settings, directory preview, tools) become fixed px with content-derived minimums; tablemin-widthbecomes the sum of column px values.<form onSubmit>+ Escape revert to all 9 form sites.tools.actions.upgradeAll,tools.noOutdated) deleted in both locales;mise outdateddata still feeds the Latest column.↑/↓text glyphs rendered as data (not decoration, exempt from the caret ban); sorted column header gets--textweight.ui-ux-rules.md/visual-language.mdrules (glyphs & icons, action-button placement/size, unified refresh, eyebrow dedupe, i18n one-meaning-one-key).Testing Decisions
npm run ci+cargo checkgreen plus a static self-audit againstdocs/design/ui-ux-rules.mdandvisual-language.md.Out of Scope
Priority
The tools page is the top priority of this batch — tickets touching it should be worked first.