Skip to content

feat(ui): update UI - #121

Merged
tkhwang merged 4 commits into
mainfrom
feat/update-0619-part2
Jun 19, 2026
Merged

feat(ui): update UI#121
tkhwang merged 4 commits into
mainfrom
feat/update-0619-part2

Conversation

@tkhwang

@tkhwang tkhwang commented Jun 19, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for four theme families (Dracula, Nord, Solarized, Gruvbox) with Light and Dark variants.
    • Introduced system theme detection with Light/Dark/System mode selection.
    • Added quit functionality to companion toolbar.
    • Enhanced CLI prompts with better formatting and examples for repository setup.
  • UI Improvements

    • Redesigned Settings panel with visual theme family grid and color swatches.
    • Updated task status indicators for clearer visual feedback.
    • Improved language selection prompts with numbered choices.
    • Changed plan archival default to yes.

tkhwang added 3 commits June 20, 2026 01:55
- Add `preferred_language_choice_label` to display numeric choices for language.
- Update `normalize_preferred_language_choice` to accept 1/2 as valid input.
- Change default for "Mark plan done and archive?" prompt to 'Y/n'.
- Provide an example `pnpm install` for "Repo setup command" prompt.
- Adjust test cases to reflect updated prompt messages.

These changes enhance user experience by making prompts more intuitive and providing helpful defaults or examples, reducing ambiguity and potential for invalid input.
- Change default task expansion to always be true
- Update font family variable from `--ui-font-family` to `--app-font-family`
- Add test to verify app shell font family configuration

The task expansion logic was simplified to always expand tasks,
improving visibility of task details by default. The font family
variable was renamed for better clarity and consistency across the
application. A new test was added to ensure the app shell correctly
applies the configured fixed-width font.
- Update color scheme description to include `Light | Dark | System` mode control and four visible family buttons (`dracula`, `nord`, `solarized`, `gruvbox`).
- Clarify imagery/iconography to use quiet color dots for status and avoid checkmark glyphs in task headers.
- Detail theme select row component to include mode segmented control, family grid, and palette chips.
- Revise token/component ownership to specify individual CSS files for different surface types.
- Expand on the 2026-06-18 refresh to include the expansion of theme presets to four famous families with dark/light variants.

This commit refines the `DESIGN.md` document to provide more precise and updated specifications for the application's visual language, component design, and styling architecture, reflecting recent design decisions.

feat(app): add quit_app command and remove tray menu

- Implement a new `quit_app` Tauri command to allow programmatic application exit.
- Remove the tray icon menu, including "Show Companion" and "Quit" menu items.
- Update the Tauri builder to register the new `quit_app` command.

This change provides a dedicated command for gracefully exiting the application, which can be triggered from the frontend. The removal of the tray menu simplifies the tray icon's interaction model, as the primary UI is expected to be managed through the main window.
@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@tkhwang, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 24 minutes and 44 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ed188bf4-ed3c-46f7-a671-713de2095151

📥 Commits

Reviewing files that changed from the base of the PR and between 282eb42 and ef8f484.

📒 Files selected for processing (11)
  • apps/cli/bin/workbranch
  • apps/cli/src/workbranch/lib/archive.sh
  • apps/cli/tests/cases/plan-archive-triggers.sh
  • apps/cli/tests/run.sh
  • apps/companion/src-tauri/src/tray.rs
  • apps/companion/src/application/preferences.ts
  • apps/companion/src/application/themePreferences.ts
  • apps/companion/src/styles/chrome.css
  • apps/companion/tests/app-shell.test.tsx
  • apps/companion/tests/preferences.test.ts
  • bin/workbranch
📝 Walkthrough

Walkthrough

The companion app's single-theme preference is replaced with a themeFamily + themeMode model supporting four named families (dracula, nord, solarized, gruvbox) with dark/light variants. The monolithic style.css is split into seven CSS modules. A quit_app Tauri command is added and the tray menu is replaced with a ClickAction-based click dispatcher. Separately, CLI prompts for language selection, archive confirmation, and repo setup are refined.

Changes

Companion App: Theme Model, CSS Split, Quit & Tray

Layer / File(s) Summary
Theme vocabulary, types, and preference contract
apps/companion/src/application/themePreferences.ts, apps/companion/src/application/preferences.ts, apps/companion/src/application/systemThemeMode.ts
Defines CompanionTheme/Family/Mode types, option arrays, type guards, legacy converters, and resolvedThemeValue. Migrates CompanionPreferences from theme to themeFamily+themeMode, rewires sanitization with legacy migration, updates persistence read/write, and adds useSystemThemeMode hook.
CSS modularization
apps/companion/src/style.css, apps/companion/src/styles/base.css, apps/companion/src/styles/themes.css, apps/companion/src/styles/chrome.css, apps/companion/src/styles/task-details.css, apps/companion/src/styles/status-groups.css, apps/companion/src/styles/settings.css, apps/companion/src/styles/motion.css
Replaces 813-line monolithic stylesheet with an @import manifest and seven dedicated CSS modules: base variables/layout, eight theme token blocks (4 families × dark/light), chrome/toolbar/nav, task card layout, status badges/project groups, settings panel with mode toggle and swatch grid, and reduced-motion overrides.
Quit command, tray click actions, and AppToolbar
apps/companion/src-tauri/src/lib.rs, apps/companion/src-tauri/src/tray.rs, apps/companion/src/infrastructure/tauriClient.ts, apps/companion/src/ui/AppToolbar.tsx
Adds quit_app Tauri command registered in invoke_handler, adds quitCompanion Tauri client helper, removes tray context menu and introduces ClickAction enum dispatching left-click→toggle/right-click→show, and creates AppToolbar component with refresh and quit buttons.
App.tsx, SettingsPanel, TaskRow wiring
apps/companion/src/App.tsx, apps/companion/src/ui/SettingsPanel.tsx, apps/companion/src/ui/TaskRow.tsx, apps/companion/src/application/state.ts
App.tsx reads systemThemeMode, computes activeTheme, adds handleQuit, and replaces inline toolbar with AppToolbar. SettingsPanel rewrites theme UI to a mode toggle + family button grid with palette swatches. TaskRow replaces icon glyphs with .task-status-dot spans. buildMenuModel sets expanded: true unconditionally.
Companion tests
apps/companion/tests/preferences.test.ts, apps/companion/tests/settings-panel.test.tsx, apps/companion/tests/app-shell.test.tsx, apps/companion/tests/task-row.test.tsx, apps/companion/tests/tauri-client.test.ts, apps/companion/tests/view-nav.test.tsx, apps/companion/tests/acl.test.ts
Updates all companion tests to the themeFamily/themeMode contract; adds legacy migration, resolvedCompanionTheme system/explicit mode coverage, button-grid-based settings interactions, CSS contract assertions for layout and theme tokens, done-state dot rendering, and quitCompanion Tauri invocation verification.
DESIGN.md
DESIGN.md
Updates visual language, component, and CSS ownership sections to reflect the four-family theme model, mode segmented control, and iconography guidance for status dots vs checkmarks.

CLI Prompt UX: Language, Archive, Repo Setup

Layer / File(s) Summary
CLI helpers: language label, archive default, repo-setup prompt
apps/cli/src/workbranch/lib/config.sh, apps/cli/src/workbranch/lib/archive.sh, apps/cli/src/workbranch/commands/config.sh, apps/cli/bin/workbranch, bin/workbranch
Adds preferred_language_choice_label() returning 1: English/2: 한글, updates normalize error message to mention 1/2, changes archive_prompt_current_plan to [Y/n] with empty-as-yes, and updates language/repo-setup prompts to show numbered current choice and pnpm install example when empty.
CLI tests and plan doc
apps/cli/tests/cases/config.sh, apps/cli/tests/cases/interactive-init.sh, apps/cli/tests/cases/plan-archive-triggers.sh, docs/plans/0031-current-only-brief-and-plan-archive-lifecycle.md
Updates test assertions to match [Y/n] archive prompt, pnpm install example in repo-setup prompts, and choose 1 or 2 [1: English]: language prompt wording; updates plan doc archive string.

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant useSystemThemeMode
  participant preferences.ts
  participant themePreferences.ts
  participant SettingsPanel

  App->>useSystemThemeMode: mount
  useSystemThemeMode-->>App: systemThemeMode ("light"|"dark")
  App->>preferences.ts: resolvedCompanionTheme(preferences, systemThemeMode)
  preferences.ts->>themePreferences.ts: resolvedThemeValue(themeFamily, resolvedMode)
  themePreferences.ts-->>App: CompanionTheme ("dracula-dark")
  App->>App: main[data-theme="dracula-dark"]
  App->>SettingsPanel: systemThemeMode prop
  SettingsPanel->>SettingsPanel: filter theme options by resolved mode
  SettingsPanel->>SettingsPanel: render mode toggle + family button grid with swatches
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • tkhwang/workbranch#112: Both PRs update DESIGN.md to shift the companion UI theme specification, including theme language and presentation direction changes.
  • tkhwang/workbranch#69: This PR directly extends the preferred-language CLI flow and normalization to support numbered 1/2 English/Korean options, building on that PR's prompt/normalization groundwork.
  • tkhwang/workbranch#91: This PR adjusts archive_prompt_current_plan default handling ([Y/n] + Enter-as-yes), which modifies the same plan-archiving/done workflow introduced by that PR.

Poem

🐇 Four theme families, dark and light,
The rabbit splits the CSS just right.
A quit button here, a dot not a tick,
[Y/n] by default—Enter does the trick!
From one big stylesheet to seven neat files,
The HUD shines on with developer smiles. ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.87% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'feat(ui): update UI' is too vague and generic—it uses non-descriptive language ('update UI') that doesn't convey what was actually changed across the substantial codebase modifications. Revise the title to specifically describe the main change, such as 'feat(ui): split theme into family and mode with styled components' or similar to reflect the core refactoring.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/update-0619-part2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (1)
apps/companion/src/styles/task-details.css (1)

23-31: ⚡ Quick win

Scope summary styles to the task surface to prevent style bleed.

These selectors are global in a modular CSS setup. Scoping them to task rows avoids accidental overrides if other summary elements are introduced elsewhere.

Suggested diff
-summary {
+.task summary {
 	cursor: default;
 	list-style: none;
 	padding: 9px 10px;
 }
 
-summary::-webkit-details-marker {
+.task summary::-webkit-details-marker {
 	display: none;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/companion/src/styles/task-details.css` around lines 23 - 31, The global
`summary` and `summary::-webkit-details-marker` selectors in the
task-details.css file are too broad and can cause unintended style overrides
elsewhere in the application. Scope these selectors by prefixing them with a
task-specific parent container class (such as a task row or task surface
container class). For example, change `summary` to `.task-container summary` and
`summary::-webkit-details-marker` to `.task-container
summary::-webkit-details-marker` to ensure these styles only apply within the
task component and do not affect other summary elements in the application.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/companion/src-tauri/src/tray.rs`:
- Around line 82-93: The gate acceptance in click_action_from_tray_event happens
before validating whether the button click maps to a real action. Since
middle-click returns None from click_action_for_button, it still updates
last_accepted_click in the gate, causing subsequent real clicks to be
incorrectly suppressed. Move the gate.accept check to occur only after mapping
the button to a ClickAction using click_action_for_button. If the button does
not map to a valid ClickAction (returns None), return None without consuming the
gate. Only accept the gate and return the action when click_action_for_button
returns Some.

In `@apps/companion/src/styles/chrome.css`:
- Around line 91-96: In the `.toolbar-icon` and `.view-nav-icon` CSS rule,
remove the empty line that appears between the `fill: none;` declaration and the
`stroke: currentcolor;` declaration. This empty line violates the stylelint
`declaration-empty-line-before` rule and should be eliminated by placing
`stroke: currentcolor;` directly after `fill: none;` without any blank lines in
between.

In `@apps/companion/src/styles/settings.css`:
- Around line 73-87: The `.settings-row-select select` selector adds a custom
dropdown arrow using the `::after` pseudo-element but does not hide the native
browser select arrow, causing both arrows to display in some browsers. Add the
`appearance: none;` CSS property to the `.settings-row-select select` rule to
disable the default browser dropdown arrow and ensure only the custom caret is
visible.

In `@apps/companion/tests/app-shell.test.tsx`:
- Around line 7-13: The readCssContract function has unbounded recursion that
can hang on circular `@import` chains because it doesn't track which files have
already been processed. Add cycle protection by introducing a visited files
tracking mechanism, either through an optional parameter or a Set of processed
file paths. Before recursively calling readCssContract for each imported file
path in the .map() function, check if the resolved absolute path has already
been visited, and skip processing if it has. This prevents infinite loops when
CSS files have circular import dependencies.

In `@bin/workbranch`:
- Around line 679-684: The preferred_language_choice_label() function has been
edited directly in bin/workbranch, which violates the repo's build contract.
Locate the source file for this function in src/workbranch/**, apply your
changes to that source file instead of the generated bin/workbranch file, and
then rebuild the bin/workbranch artifact from the source. This also applies to
other locations mentioned in the comment (lines 695, 1965-1968, 3260-3261,
3360-3364) - identify all direct edits in bin/workbranch and move them back to
their corresponding src/workbranch/** sources before regenerating the file.

---

Nitpick comments:
In `@apps/companion/src/styles/task-details.css`:
- Around line 23-31: The global `summary` and `summary::-webkit-details-marker`
selectors in the task-details.css file are too broad and can cause unintended
style overrides elsewhere in the application. Scope these selectors by prefixing
them with a task-specific parent container class (such as a task row or task
surface container class). For example, change `summary` to `.task-container
summary` and `summary::-webkit-details-marker` to `.task-container
summary::-webkit-details-marker` to ensure these styles only apply within the
task component and do not affect other summary elements in the application.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e75d756f-6977-4635-86d5-4d31fdcbd13a

📥 Commits

Reviewing files that changed from the base of the PR and between f040f3d and 282eb42.

📒 Files selected for processing (37)
  • DESIGN.md
  • apps/cli/bin/workbranch
  • apps/cli/src/workbranch/commands/config.sh
  • apps/cli/src/workbranch/lib/archive.sh
  • apps/cli/src/workbranch/lib/config.sh
  • apps/cli/tests/cases/config.sh
  • apps/cli/tests/cases/interactive-init.sh
  • apps/cli/tests/cases/plan-archive-triggers.sh
  • apps/companion/src-tauri/src/lib.rs
  • apps/companion/src-tauri/src/tray.rs
  • apps/companion/src-tauri/src/workbranch_bin.rs
  • apps/companion/src/App.tsx
  • apps/companion/src/application/preferences.ts
  • apps/companion/src/application/state.ts
  • apps/companion/src/application/systemThemeMode.ts
  • apps/companion/src/application/themePreferences.ts
  • apps/companion/src/infrastructure/tauriClient.ts
  • apps/companion/src/style.css
  • apps/companion/src/styles/base.css
  • apps/companion/src/styles/chrome.css
  • apps/companion/src/styles/motion.css
  • apps/companion/src/styles/settings.css
  • apps/companion/src/styles/status-groups.css
  • apps/companion/src/styles/task-details.css
  • apps/companion/src/styles/themes.css
  • apps/companion/src/ui/AppToolbar.tsx
  • apps/companion/src/ui/SettingsPanel.tsx
  • apps/companion/src/ui/TaskRow.tsx
  • apps/companion/tests/acl.test.ts
  • apps/companion/tests/app-shell.test.tsx
  • apps/companion/tests/preferences.test.ts
  • apps/companion/tests/settings-panel.test.tsx
  • apps/companion/tests/task-row.test.tsx
  • apps/companion/tests/tauri-client.test.ts
  • apps/companion/tests/view-nav.test.tsx
  • bin/workbranch
  • docs/plans/0031-current-only-brief-and-plan-archive-lifecycle.md

Comment thread apps/companion/src-tauri/src/tray.rs
Comment thread apps/companion/src/styles/chrome.css
Comment thread apps/companion/src/styles/settings.css
Comment thread apps/companion/tests/app-shell.test.tsx Outdated
Comment thread bin/workbranch

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

Copy link
Copy Markdown

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: 282eb42059

ℹ️ 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/companion/src/application/themePreferences.ts
Comment thread apps/cli/src/workbranch/lib/archive.sh
- The `archive_prompt_current_plan` function now correctly handles
  an End-of-File (EOF) input by returning 0, preventing unintended
  behavior when the prompt is closed without user input.
- Added a new test case `test_land_archive_prompt_eof_keeps_brief`
  to verify that an EOF input to the archive prompt results in the
  plan not being archived.

This change ensures that if a user closes the prompt or provides an
EOF, the plan is not automatically archived, maintaining the expected
state.

fix(companion): prevent click gate consumption on middle click

- Modified `click_action_from_tray_event` to only consume the click
  gate if a valid action is determined from the button click.
- Added a new test case `middle_click_does_not_consume_click_gate`
  to ensure that a middle-click event does not consume the tray
  click gate, allowing subsequent clicks to be processed.

This prevents the click gate from being consumed by non-actionable
clicks (like middle-click), ensuring that subsequent actionable
clicks are not suppressed.

refactor(companion): rename legacy theme check

- Renamed `isCompanionTheme` to `isLegacyCompanionTheme` in
  `application/preferences.ts` and `application/themePreferences.ts`.
- Updated references to the renamed function in
  `sanitizeCompanionPreferences`.
- Added `PREVIOUS_COMPANION_THEME_VALUES` to explicitly list
  the old theme values.

This refactoring clarifies the distinction between current and
legacy theme values, improving code readability and maintainability.
@tkhwang
tkhwang merged commit 15f9990 into main Jun 19, 2026
4 checks passed
@tkhwang
tkhwang deleted the feat/update-0619-part2 branch June 19, 2026 18:53
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