Skip to content

Expand AI group actions by default and add toggle switch#98

Open
mbergo wants to merge 4 commits intomatt1398:mainfrom
mbergo:main
Open

Expand AI group actions by default and add toggle switch#98
mbergo wants to merge 4 commits intomatt1398:mainfrom
mbergo:main

Conversation

@mbergo
Copy link

@mbergo mbergo commented Mar 8, 2026

commit 2ac8362

This pull request implements a significant refactor of the per-tab AI group expansion logic in the UI state, introducing a new "expand/collapse all" feature and simplifying how group expansion is managed. The changes replace the old per-group expansion set with a default-expanded flag and a set of manual overrides, making the behavior more intuitive, especially when toggling all groups at once. Additionally, the UI is updated to include a sticky "Expand/Collapse All" button at the top of the chat history panel.

Key changes include:

AI Group Expansion Logic Refactor

  • Replaced the expandedAIGroupIds set in TabUIState with a new aiGroupsExpandedByDefault boolean and a toggledAIGroupIds set, which tracks manual overrides from the default state. This allows for efficient "expand/collapse all" operations and simplifies per-group expansion logic. [1] [2]
  • Updated all expansion/toggle logic and selectors to use the new default/override model, including isAIGroupExpandedForTab, toggleAIGroupExpansionForTab, and expandAIGroupForTab. [1] [2]
  • Added new store methods: getAIGroupsExpandedByDefaultForTab and toggleAIGroupsExpandedByDefaultForTab, enabling toggling the default expansion state and clearing manual overrides when toggling all. [1] [2]

UI Updates for Expand/Collapse All

  • Added an "Expand/Collapse All" button to the sticky header in ChatHistory, allowing users to expand or collapse all AI groups in the current tab with one click. The button updates its icon and tooltip based on the current default state. [1] [2]
  • Updated the sticky header offset and layout to always reserve space for the new button, ensuring proper scrolling behavior.

Hook and Type Updates

  • Updated the useTabUI hook to expose the new aiGroupsExpandedByDefault state and toggleAIGroupsExpandedByDefault method, and to use the new expansion logic. [1] [2] [3] [4] [5]

Testing and Documentation

  • Updated and expanded tests in tabUISlice.test.ts to cover the new default/override logic, ensuring correct per-tab isolation and toggle behavior. [1] [2] [3]
  • Updated developer documentation (CLAUDE.md) to describe the new state model and clarify the role of toggledAIGroupIds.

Miscellaneous

  • Added tar.gz as a build target in package.json.
  • Updated icon imports for new expand/collapse button icons.

These changes improve the usability and maintainability of the per-tab AI group expansion feature, and lay the groundwork for further UI enhancements.

Summary by CodeRabbit

  • New Features

    • Added a persistent sticky header with an Expand All / Collapse All control for AI groups.
    • Per-tab default expand/collapse behavior for AI groups with a toggle to change the default.
  • Chores

    • Linux distributions now include a tar.gz package option.
    • Release workflow now also responds to pushes on main and gates release jobs to tag-based or manual triggers.

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a more intuitive and efficient way to manage the expansion and collapse of AI groups within the UI. By shifting from individual group expansion tracking to a default state with manual overrides, it enables a new 'expand/collapse all' feature, enhancing user control and streamlining the chat history interaction. The changes improve both the underlying state management and the user interface for a smoother experience.

Highlights

  • AI Group Expansion Logic Refactor: The per-tab AI group expansion logic was significantly refactored, replacing the expandedAIGroupIds set with a new aiGroupsExpandedByDefault boolean and a toggledAIGroupIds set. This new model tracks manual overrides from the default state, simplifying 'expand/collapse all' operations and per-group expansion logic. Related selectors and store methods were updated or added to support this new model.
  • UI Updates for Expand/Collapse All: A new 'Expand/Collapse All' button was added to the sticky header in ChatHistory, allowing users to toggle the expansion state of all AI groups in the current tab. The button's icon and tooltip dynamically update based on the current default state, and the sticky header offset was adjusted to accommodate it.
  • Hook and Type Updates: The useTabUI hook was updated to expose the new aiGroupsExpandedByDefault state and toggleAIGroupsExpandedByDefault method, integrating the new expansion logic into the UI layer.
  • Testing and Documentation: Existing tests in tabUISlice.test.ts were updated and expanded to cover the new default/override logic, ensuring correct per-tab isolation and toggle behavior. Developer documentation (CLAUDE.md) was also updated to describe the new state model and the role of toggledAIGroupIds.
  • Miscellaneous Enhancements: The package.json file was updated to include tar.gz as a build target, and new icon imports were added for the expand/collapse button.
Changelog
  • package.json
    • Added "tar.gz" to the build targets array.
  • src/renderer/components/chat/ChatHistory.tsx
    • Imported new Lucide icons for expand/collapse functionality.
    • Integrated new aiGroupsExpandedByDefault state and toggleAIGroupsExpandedByDefault action from useTabUI.
    • Added local state for the expand button's hover effect.
    • Adjusted the STICKY_BUTTON_OFFSET to a fixed value of 44px.
    • Implemented a new "Expand/Collapse All" button in the sticky header, dynamically displaying text and icons based on the expansion state.
    • Modified the marginTop style for the chat content to a fixed value of '-2rem'.
  • src/renderer/hooks/useTabUI.ts
    • Updated the UseTabUIReturn interface to include aiGroupsExpandedByDefault and toggleAIGroupsExpandedByDefault.
    • Modified the useTabUI hook to expose the new aiGroupsExpandedByDefault state and toggleAIGroupsExpandedByDefault method.
    • Rewrote the isAIGroupExpanded callback to use the new aiGroupsExpandedByDefault and toggledAIGroupIds logic.
    • Added aiGroupsExpandedByDefault and toggleAIGroupsExpandedByDefault derivations and callbacks.
  • src/renderer/store/CLAUDE.md
    • Updated the documentation to reflect the change from expandedAIGroupIds to toggledAIGroupIds in the per-tab UI isolation pattern.
  • src/renderer/store/slices/tabUISlice.ts
    • Refactored the TabUIState interface to replace expandedAIGroupIds with aiGroupsExpandedByDefault and toggledAIGroupIds.
    • Updated createDefaultTabUIState to initialize aiGroupsExpandedByDefault to true and toggledAIGroupIds as an empty set.
    • Modified the TabUISlice interface to include getAIGroupsExpandedByDefaultForTab and toggleAIGroupsExpandedByDefaultForTab.
    • Rewrote toggleAIGroupExpansionForTab to update toggledAIGroupIds based on the new default/override logic.
    • Updated isAIGroupExpandedForTab to determine expansion based on aiGroupsExpandedByDefault and toggledAIGroupIds (XOR logic).
    • Modified expandAIGroupForTab to adjust toggledAIGroupIds to achieve an expanded state.
    • Added getAIGroupsExpandedByDefaultForTab to retrieve the default expansion state.
    • Implemented toggleAIGroupsExpandedByDefaultForTab to flip the default expansion state and clear all manual overrides.
  • test/renderer/store/tabUISlice.test.ts
    • Updated initTabUIState tests to assert the initial aiGroupsExpandedByDefault and toggledAIGroupIds states.
    • Modified tests for initTabUIState and toggleAIGroupExpansionForTab to reflect the new default-expanded behavior and how toggling affects it.
    • Adjusted isAIGroupExpandedForTab assertions in isolation tests to match the new default-expanded and override logic.
    • Updated programmatic expansion tests to first collapse a group before expanding to demonstrate the effect.
    • Modified snapshot tests to reflect the new state structure.
    • Updated edge case tests to correctly assert that uninitialized tabs default to expanded.
    • Added a new test suite for AI Groups expanded by default toggle covering default state, toggling, clearing overrides, and isolation between tabs.
Activity
  • No human activity has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@mbergo mbergo changed the title Expand AI group actions by default and add toggle switch [commit 2ac8362d24f6ffa81c7accb12cade814ab4886ae](#diff://2ac8362d24f6ffa81c7accb12cade814ab4886ae) Expand AI group actions by default and add toggle switch Mar 8, 2026
@coderabbitai coderabbitai bot added documentation Improvements or additions to documentation feature request New feature or request labels Mar 8, 2026
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new feature allowing users to control the default expansion state of AI groups in the chat history. The core change involves refactoring the tabUISlice state management to replace expandedAIGroupIds with aiGroupsExpandedByDefault (a boolean) and toggledAIGroupIds (a set for individual overrides). A new 'Expand/Collapse All' button, using new lucide-react icons, has been added to the ChatHistory component's sticky header, enabling users to toggle the global default expansion state for AI groups. Toggling this global setting also clears any previously set individual group overrides. The STICKY_BUTTON_OFFSET in ChatHistory.tsx was adjusted to accommodate the always-present sticky header. Additionally, the package.json file was updated to include tar.gz as a new build target, and corresponding unit tests were updated to reflect the new expansion logic.

@coderabbitai
Copy link

coderabbitai bot commented Mar 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added a Linux tar.gz packaging target and widened release workflow triggers; introduced a per-tab default expand/collapse model for AI groups with toggle support, refactored ChatHistory UI to render a persistent sticky header with global Expand/Collapse control, and updated related store, hook, and tests to match the new model.

Changes

Cohort / File(s) Summary
Build Configuration
package.json
Added "tar.gz" to build.linux.target.
Release Workflow
.github/workflows/release.yml
Workflow now also triggers on pushes to main; release-mac and release-win jobs conditioned to run only for tag triggers starting with v or workflow_dispatch.
Chat UI
src/renderer/components/chat/ChatHistory.tsx
Reworked sticky header to always render; added an Expand All / Collapse All button wired to per-tab default; adjusted layout and STICKY_BUTTON_OFFSET constant.
Tab UI hook
src/renderer/hooks/useTabUI.ts
Added aiGroupsExpandedByDefault: boolean and toggleAIGroupsExpandedByDefault(): void to the hook return; updated isAIGroupExpanded logic to XOR per-tab default with per-group toggles.
Tab UI store slice
src/renderer/store/slices/tabUISlice.ts
Replaced expandedAIGroupIds with aiGroupsExpandedByDefault and toggledAIGroupIds; added toggleAIGroupsExpandedByDefaultForTab action; implemented XOR default/override semantics and updated initialization.
Tests
test/renderer/store/tabUISlice.test.ts
Updated tests to reflect default-expanded behavior, new toggled-ID semantics, and per-tab isolation under the new default/override model.

Possibly related PRs

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/renderer/components/chat/ChatHistory.tsx (1)

233-237: Keep the sticky offset and reclaimed spacing in one place.

Line 236 hard-codes 44, while Line 813 separately hard-codes -2rem to reclaim the same header space. The next button-size tweak can make navigation targets hide under the sticky bar again. Please derive both from one source of truth or measure the sticky container height.

Also applies to: 813-813

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/components/chat/ChatHistory.tsx` around lines 233 - 237, The
hard-coded sticky header size is duplicated (STICKY_BUTTON_OFFSET = 44 and a
separate "-2rem" reclamation) — consolidate into a single source of truth by
deriving the reclaimed spacing from STICKY_BUTTON_OFFSET (or by measuring the
sticky container height at runtime) and use that value wherever you currently
use 44 or "-2rem"; update the ChatHistory component to export/use
STICKY_BUTTON_OFFSET for both the scroll offset and the reclaimed spacing (or
compute stickyHeight via a ref to the sticky container and set both the scroll
offset and the negative-margin/reclaim style from that measured value) so future
button-size changes only require one update.
test/renderer/store/tabUISlice.test.ts (1)

392-449: Add a regression for the auto-expand interaction.

These cases cover the slice transitions in isolation, but they never exercise the sessionDetailSlice loop that auto-expands every AI group. A test that collapses all, runs that path, and asserts the groups stay collapsed would lock down the bug above.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/renderer/store/tabUISlice.test.ts` around lines 392 - 449, Add a
regression test that collapses all AI groups for a tab (use initTabUIState +
toggleAIGroupsExpandedByDefaultForTab to set default collapsed), then invoke the
sessionDetailSlice auto-expand loop (call the function or dispatch the action in
sessionDetailSlice that performs the automatic expansion of AI groups) and
assert that isAIGroupExpandedForTab remains false for each group; this ensures
the sessionDetailSlice auto-expand path respects the collapsed-by-default state
and clears/does not reapply overrides.
src/renderer/hooks/useTabUI.ts (1)

111-117: Avoid duplicating the expansion formula in the hook.

Line 114-116 re-implements the same XOR rule that src/renderer/store/slices/tabUISlice.ts already owns at Line 177-182. The slice tests will not catch a future divergence here, so this should live in one shared helper.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/hooks/useTabUI.ts` around lines 111 - 117, The hook useTabUI.ts
currently re-implements the XOR expansion rule in its isAIGroupExpanded
callback; instead export the single-source helper from the tabUISlice (where the
logic currently lives) and call that helper from useTabUI's isAIGroupExpanded.
Concretely: remove the inline XOR logic in isAIGroupExpanded, add or use an
exported function from src/renderer/store/slices/tabUISlice.ts (e.g., an
exported helper that computes expanded state from aiGroupsExpandedByDefault and
toggledAIGroupIds), import that helper into useTabUI.ts, and delegate the
computation to it so the rule is maintained in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/renderer/store/CLAUDE.md`:
- Around line 36-39: The documentation for tabUISlice omits the
aiGroupsExpandedByDefault flag, making toggledAIGroupIds ambiguous; update the
CLAUDE.md model to document aiGroupsExpandedByDefault alongside
toggledAIGroupIds and explain how the two interact (i.e.,
aiGroupsExpandedByDefault provides the base expansion state per tab and
toggledAIGroupIds contains exceptions relative to that default), and reference
the tabUISlice slice name and both symbols (aiGroupsExpandedByDefault,
toggledAIGroupIds) so readers understand how expansion state is computed.

In `@src/renderer/store/slices/tabUISlice.ts`:
- Around line 185-225: The auto-expand path is repopulating toggledAIGroupIds
even when a tab's aiGroupsExpandedByDefault is false; update the refresh/load
logic in sessionDetailSlice to respect the per-tab default by checking
getAIGroupsExpandedByDefaultForTab(tabId) before calling expandAIGroupForTab
(skip calling expandAIGroupForTab when the default is false), or alternatively
modify expandAIGroupForTab to no-op if getAIGroupsExpandedByDefaultForTab(tabId)
is false; reference expandAIGroupForTab, getAIGroupsExpandedByDefaultForTab, and
toggleAIGroupsExpandedByDefaultForTab when making the change so the collapse-all
state survives refresh.

---

Nitpick comments:
In `@src/renderer/components/chat/ChatHistory.tsx`:
- Around line 233-237: The hard-coded sticky header size is duplicated
(STICKY_BUTTON_OFFSET = 44 and a separate "-2rem" reclamation) — consolidate
into a single source of truth by deriving the reclaimed spacing from
STICKY_BUTTON_OFFSET (or by measuring the sticky container height at runtime)
and use that value wherever you currently use 44 or "-2rem"; update the
ChatHistory component to export/use STICKY_BUTTON_OFFSET for both the scroll
offset and the reclaimed spacing (or compute stickyHeight via a ref to the
sticky container and set both the scroll offset and the negative-margin/reclaim
style from that measured value) so future button-size changes only require one
update.

In `@src/renderer/hooks/useTabUI.ts`:
- Around line 111-117: The hook useTabUI.ts currently re-implements the XOR
expansion rule in its isAIGroupExpanded callback; instead export the
single-source helper from the tabUISlice (where the logic currently lives) and
call that helper from useTabUI's isAIGroupExpanded. Concretely: remove the
inline XOR logic in isAIGroupExpanded, add or use an exported function from
src/renderer/store/slices/tabUISlice.ts (e.g., an exported helper that computes
expanded state from aiGroupsExpandedByDefault and toggledAIGroupIds), import
that helper into useTabUI.ts, and delegate the computation to it so the rule is
maintained in one place.

In `@test/renderer/store/tabUISlice.test.ts`:
- Around line 392-449: Add a regression test that collapses all AI groups for a
tab (use initTabUIState + toggleAIGroupsExpandedByDefaultForTab to set default
collapsed), then invoke the sessionDetailSlice auto-expand loop (call the
function or dispatch the action in sessionDetailSlice that performs the
automatic expansion of AI groups) and assert that isAIGroupExpandedForTab
remains false for each group; this ensures the sessionDetailSlice auto-expand
path respects the collapsed-by-default state and clears/does not reapply
overrides.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7074204d-d633-4a20-8d49-526eade38a89

📥 Commits

Reviewing files that changed from the base of the PR and between 0f58214 and b0031c5.

📒 Files selected for processing (6)
  • package.json
  • src/renderer/components/chat/ChatHistory.tsx
  • src/renderer/hooks/useTabUI.ts
  • src/renderer/store/CLAUDE.md
  • src/renderer/store/slices/tabUISlice.ts
  • test/renderer/store/tabUISlice.test.ts

Comment on lines 36 to 39
## Key Pattern: Per-Tab UI Isolation
`tabUISlice` maintains independent UI state per tab using tabId:
- `expandedAIGroupIds`, `expandedDisplayItemIds`, `expandedSubagentTraceIds`
- `toggledAIGroupIds`, `expandedDisplayItemIds`, `expandedSubagentTraceIds`
- Ensures expanding a group in tab A doesn't affect tab B
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Document aiGroupsExpandedByDefault in this model too.

Line 38 now lists only toggledAIGroupIds, but that set is only interpretable relative to aiGroupsExpandedByDefault. Without the default flag here, the store docs no longer describe how AI-group expansion is actually represented.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/store/CLAUDE.md` around lines 36 - 39, The documentation for
tabUISlice omits the aiGroupsExpandedByDefault flag, making toggledAIGroupIds
ambiguous; update the CLAUDE.md model to document aiGroupsExpandedByDefault
alongside toggledAIGroupIds and explain how the two interact (i.e.,
aiGroupsExpandedByDefault provides the base expansion state per tab and
toggledAIGroupIds contains exceptions relative to that default), and reference
the tabUISlice slice name and both symbols (aiGroupsExpandedByDefault,
toggledAIGroupIds) so readers understand how expansion state is computed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

67-88: Duplicate CI work on push events.

The quality-gate job runs pnpm check (which includes typecheck, lint, test, and build) on every push. However, the validate job already runs typecheck, lint, and build, and the test job already runs tests—both on all events including push. This causes typecheck, lint, and build to run twice on pushes, wasting CI minutes.

Consider one of these approaches:

  1. Remove quality-gate since validate + test already cover all checks
  2. Make quality-gate a summary gate that depends on the other jobs without re-running checks:
    quality-gate:
      if: github.event_name == 'push'
      needs: [validate, test]
      runs-on: ubuntu-latest
      steps:
        - run: echo "All checks passed"
  3. Split by event type: Run validate/test only on PRs and quality-gate only on push
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 67 - 88, The quality-gate job is
duplicating work by re-running pnpm check on push; modify the quality-gate job
(named quality-gate) so it no longer re-runs checks but instead depends on the
existing validate and test jobs: remove the pnpm check step and add a needs:
[validate, test] entry (keep runs-on and a simple step such as echo "All checks
passed" or similar) so validate handles typecheck/lint/build and test handles
tests without double execution.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 67-88: The quality-gate job is duplicating work by re-running pnpm
check on push; modify the quality-gate job (named quality-gate) so it no longer
re-runs checks but instead depends on the existing validate and test jobs:
remove the pnpm check step and add a needs: [validate, test] entry (keep runs-on
and a simple step such as echo "All checks passed" or similar) so validate
handles typecheck/lint/build and test handles tests without double execution.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8fc4b44a-c07b-455e-9ad8-18f4780ce728

📥 Commits

Reviewing files that changed from the base of the PR and between b0031c5 and 65b6eba.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

* Initial plan

* feat: add tar.gz to Linux release build targets

---------
mbergo added 2 commits March 8, 2026 14:03
- Add push trigger for main branch (in addition to version tags)
- Gate mac and Windows release jobs to tag pushes only (require signing secrets)
- Linux job runs on both main branch pushes and version tags
- Add aiGroupsExpandedByDefault flag to TabUIState (default: true)
- Replace expandedAIGroupIds with toggledAIGroupIds for XOR override logic
- Add toggleAIGroupsExpandedByDefaultForTab action to flip default and clear overrides
- Expose aiGroupsExpandedByDefault and toggleAIGroupsExpandedByDefault in useTabUI hook
- Add Collapse All / Expand All button in ChatHistory sticky header (always visible)
- Fix sticky header offset to constant 44px (header always rendered now)
- Update tests to reflect new expand-by-default behavior
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/renderer/components/chat/ChatHistory.tsx (1)

763-772: Add accessibility attributes to the Expand/Collapse All button.

The button lacks aria-label and title attributes, which impacts accessibility and discoverability. The Context button nearby implicitly conveys meaning through its text, but a tooltip would improve UX for the toggle button.

♿ Proposed accessibility improvement
 <button
   onClick={toggleAIGroupsExpandedByDefault}
   className="pointer-events-auto flex items-center gap-1 rounded-md px-2.5 py-1.5 text-xs shadow-lg backdrop-blur-md transition-colors hover:opacity-80"
   style={{
     backgroundColor: 'var(--context-btn-bg)',
     color: 'var(--color-text-secondary)',
   }}
+  title={aiGroupsExpandedByDefault ? 'Collapse all AI groups' : 'Expand all AI groups'}
+  aria-pressed={aiGroupsExpandedByDefault}
 >
   {aiGroupsExpandedByDefault ? 'Collapse All' : 'Expand All'}
 </button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/components/chat/ChatHistory.tsx` around lines 763 - 772, The
Expand/Collapse All button in ChatHistory.tsx (the element using
toggleAIGroupsExpandedByDefault and reading aiGroupsExpandedByDefault) needs
accessibility attributes added: add a dynamic aria-label and a title that
reflect the current state (e.g., "Collapse all AI groups" when
aiGroupsExpandedByDefault is true and "Expand all AI groups" when false) so
screen readers and tooltips convey the action; ensure the attributes are set on
the same <button> element that already calls toggleAIGroupsExpandedByDefault.
test/renderer/store/tabUISlice.test.ts (1)

85-132: Consider adding direct test coverage for toggleAIGroupsExpandedByDefaultForTab.

The test suite thoroughly covers toggleAIGroupExpansionForTab (per-group toggles), but there's no direct test for the new toggleAIGroupsExpandedByDefaultForTab action that flips the default and clears overrides. This is a key behavior change where clicking "Collapse All" should:

  1. Set aiGroupsExpandedByDefault to false
  2. Clear toggledAIGroupIds
💡 Suggested test case
it('should toggle aiGroupsExpandedByDefault and clear overrides', () => {
  store.getState().initTabUIState('tab-1');
  
  // Create some overrides first
  store.getState().toggleAIGroupExpansionForTab('tab-1', 'group-1');
  expect(store.getState().isAIGroupExpandedForTab('tab-1', 'group-1')).toBe(false);
  
  // Toggle the default (Collapse All)
  store.getState().toggleAIGroupsExpandedByDefaultForTab('tab-1');
  
  // Default should now be false, overrides cleared
  const tabState = store.getState().tabUIStates.get('tab-1');
  expect(tabState?.aiGroupsExpandedByDefault).toBe(false);
  expect(tabState?.toggledAIGroupIds.size).toBe(0);
  
  // All groups should now be collapsed by default
  expect(store.getState().isAIGroupExpandedForTab('tab-1', 'group-1')).toBe(false);
  expect(store.getState().isAIGroupExpandedForTab('tab-1', 'group-2')).toBe(false);
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/renderer/store/tabUISlice.test.ts` around lines 85 - 132, Add a unit
test that directly covers toggleAIGroupsExpandedByDefaultForTab: init a tab via
initTabUIState('tab-1'), create an override using
toggleAIGroupExpansionForTab('tab-1','group-1') and assert
isAIGroupExpandedForTab returns false, then call
toggleAIGroupsExpandedByDefaultForTab('tab-1') and assert the tab entry in
tabUIStates has aiGroupsExpandedByDefault === false and toggledAIGroupIds.size
=== 0, and finally assert isAIGroupExpandedForTab('tab-1','group-1') and
isAIGroupExpandedForTab('tab-1','group-2') reflect the new default (both
collapsed).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/renderer/components/chat/ChatHistory.tsx`:
- Around line 763-772: The Expand/Collapse All button in ChatHistory.tsx (the
element using toggleAIGroupsExpandedByDefault and reading
aiGroupsExpandedByDefault) needs accessibility attributes added: add a dynamic
aria-label and a title that reflect the current state (e.g., "Collapse all AI
groups" when aiGroupsExpandedByDefault is true and "Expand all AI groups" when
false) so screen readers and tooltips convey the action; ensure the attributes
are set on the same <button> element that already calls
toggleAIGroupsExpandedByDefault.

In `@test/renderer/store/tabUISlice.test.ts`:
- Around line 85-132: Add a unit test that directly covers
toggleAIGroupsExpandedByDefaultForTab: init a tab via initTabUIState('tab-1'),
create an override using toggleAIGroupExpansionForTab('tab-1','group-1') and
assert isAIGroupExpandedForTab returns false, then call
toggleAIGroupsExpandedByDefaultForTab('tab-1') and assert the tab entry in
tabUIStates has aiGroupsExpandedByDefault === false and toggledAIGroupIds.size
=== 0, and finally assert isAIGroupExpandedForTab('tab-1','group-1') and
isAIGroupExpandedForTab('tab-1','group-2') reflect the new default (both
collapsed).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d68fee4d-b41c-4293-9fcf-833407ab7220

📥 Commits

Reviewing files that changed from the base of the PR and between a119102 and c4fd52e.

📒 Files selected for processing (4)
  • src/renderer/components/chat/ChatHistory.tsx
  • src/renderer/hooks/useTabUI.ts
  • src/renderer/store/slices/tabUISlice.ts
  • test/renderer/store/tabUISlice.test.ts

Use electron-builder with --publish never and upload artifacts
via gh CLI using GITHUB_TOKEN scoped to GITHUB_REPOSITORY.
This avoids electron-builder inferring the upstream repo from
the git remote and trying to publish there instead.
@matt1398
Copy link
Owner

matt1398 commented Mar 9, 2026

Thanks for the PR! Expand/collapse all is a useful feature.

A few things before we can merge:

  • Split this PR. UI features and CI/workflow changes must be separate per the contributing guide. The CI/release changes aren't needed upstream, so please drop those.
  • On the default state: I'd prefer AI groups to start collapsed by default (current behavior), not expanded. The toggle should let users expand all when they want to, not the other way around. Please flip the default.

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

Labels

documentation Improvements or additions to documentation feature request New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants