From 4c791a41b2406454ba70726ee763fdfbeb8eba22 Mon Sep 17 00:00:00 2001 From: "exe.dev user" Date: Wed, 29 Apr 2026 12:01:35 +0000 Subject: [PATCH] feat(setup): cyan highlight on active and submitted choices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Customize `brightSelect`'s render function so the focused option's label paints in brand cyan during selection and the submitted answer paints in dim cyan after the user moves on. Inactive options keep their default rendering — only the cursor and submitted state pick up the color, matching the body-text emphasis added in #2101. Also migrate the one remaining `p.select` call site (the "What next?" prompt after the first chat) to `brightSelect` so every menu in the setup flow goes through the same render path. The shape of the call matches what `brightSelect` already supports — message + options with value/label/hint — so no feature is lost in the swap. Reuses `brandBody` from #2101 for the cyan, so the prompt highlight and the body prose share one definition of the brand body color. --- setup/auto.ts | 2 +- setup/lib/bright-select.ts | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/setup/auto.ts b/setup/auto.ts index c0b5add..024da9f 100644 --- a/setup/auto.ts +++ b/setup/auto.ts @@ -337,7 +337,7 @@ async function main(): Promise { if (ping === 'ok') { phEmit('first_chat_ready'); const next = ensureAnswer( - await p.select({ + await brightSelect<'continue' | 'chat'>({ message: 'What next?', options: [ { diff --git a/setup/lib/bright-select.ts b/setup/lib/bright-select.ts index 94c4838..96c5de4 100644 --- a/setup/lib/bright-select.ts +++ b/setup/lib/bright-select.ts @@ -18,6 +18,8 @@ import { SelectPrompt } from '@clack/core'; import { isCancel } from '@clack/prompts'; import { styleText } from 'node:util'; +import { brandBody } from './theme.js'; + const BULLET_ACTIVE = '●'; const BULLET_INACTIVE = '○'; const BAR = '│'; @@ -95,7 +97,7 @@ export function brightSelect( const shown = st === 'cancel' ? styleText(['strikethrough', 'dim'], selected) - : styleText('dim', selected); + : styleText('dim', brandBody(selected)); lines.push(`${grayBar} ${shown}`); return lines.join('\n'); } @@ -104,11 +106,12 @@ export function brightSelect( options.forEach((opt, idx) => { const label = opt.label ?? String(opt.value); const hint = opt.hint ? ` ${styleText('dim', `(${opt.hint})`)}` : ''; - const marker = - idx === cursor - ? styleText('green', BULLET_ACTIVE) - : styleText('dim', BULLET_INACTIVE); - lines.push(`${bar} ${marker} ${label}${hint}`); + const isActive = idx === cursor; + const marker = isActive + ? styleText('green', BULLET_ACTIVE) + : styleText('dim', BULLET_INACTIVE); + const shownLabel = isActive ? brandBody(label) : label; + lines.push(`${bar} ${marker} ${shownLabel}${hint}`); }); lines.push(styleText(color, CAP_BOT)); return lines.join('\n');