Skip to content

Feat/agent group#179

Open
FourWindff wants to merge 8 commits into
johannesjo:mainfrom
FourWindff:feat/agent-group
Open

Feat/agent group#179
FourWindff wants to merge 8 commits into
johannesjo:mainfrom
FourWindff:feat/agent-group

Conversation

@FourWindff

Copy link
Copy Markdown
Contributor

Summary

This branch introduces panel grouping to the tiling layout, grouping task panels by project and agent coordination mode (independent vs coordinator). Each group can be collapsed into a single representative panel, and expanded again on demand. The feature also includes new grouped-panel chrome, updated visual treatments for inactive panels, and persistence for collapsed-group state.

  • Adds panelGroupCollapsed store state keyed by ${projectId}:${groupType} and persists it across sessions.
  • Reworks TilingLayout to compute PanelGroup segments and render grouped panels with a shared background, collapse/expand controls, and adjusted resize handles.
  • Updates styles.css with new .panel-group-wrapper, .panel-group-collapse-btn, .panel-group-expand-btn, and inactive-panel overlay styles.
  • Skips terminal fit when the container has zero size, preventing resize errors for hidden grouped panels.

- Added support for collapsing panel groups, allowing users to manage their workspace more effectively.
- Introduced new state management for collapsed panel groups in the store.
- Updated UI components to reflect the collapsed state and added expand/collapse buttons.
- Enhanced persistence logic to save and restore the collapsed state across sessions.

This feature improves user experience by providing better organization of panels.
…er UI consistency

- Updated styles for inner group resize handles to ensure visibility and proper background blending during hover and dragging states.
- Modified the expand button styling to position it beside the visible panel in collapsed groups, improving layout and usability.
- Added tests to verify the new styles and their behavior in different states.
- Eliminated the box-shadow effect from the active task column to enhance visual clarity.
- Updated tests to verify the absence of accent outlines around collapsed active panel groups.
- Ensured that the active task panel maintains consistent opacity without additional styling interference.
- Changed the background of the expand button to transparent and adjusted its hover filter for better UI coherence.
- Updated related tests to ensure consistent color treatment between collapse and expand controls.
- Removed inline color styling from the expand button for cleaner code and adherence to style guidelines.
…ed project panels

- Added `buildRenderSegments` function to create segments for rendering grouped and single project panels.
- Introduced `buildRenderSegmentsForTest` for testing purposes.
- Updated `TilingLayout` component to utilize the new segment rendering logic.
- Enhanced tests to verify the correct behavior when a single slot becomes a grouped project panel.
- Added state management for panel group collapse in the task store, ensuring proper handling of project group visibility.
- Added `panelCount` to `GroupInfo` to track the number of panels in a group.
- Implemented `isPanelGroupCollapsibleForTest` and `isPanelGroupCollapseControlVisibleForTest` functions to manage collapse behavior based on panel count.
- Updated `TilingLayout` component to utilize new collapse control logic.
- Enhanced tests to verify collapse behavior for single and multiple task panel groups.
- Introduced caching for render segments to prevent unnecessary remounting of unchanged panels.
- Added `hiddenPanelContentStyle` function to manage styles for hidden panels, ensuring proper width preservation.
- Enhanced tests to verify the behavior of cached segments and hidden panel styles, improving performance and UI consistency.
- Introduced a neutral gray overlay for inactive task panels to improve visual distinction.
- Updated styles to remove opacity from inactive panels, ensuring no color tinting occurs.
- Enhanced tests to verify the new overlay behavior and opacity settings for task panels.
@johannesjo

Copy link
Copy Markdown
Owner

First off — thank you for this! 🙏 Panel grouping is a genuinely nice direction for the crowded-strip problem, the store/persistence/security plumbing is careful (project-id validation on load, fail-closed handling of corrupt state), and the test coverage on the pure planning helpers is appreciated. I ran a multi-perspective review (correctness, security, architecture, performance, simplicity, UX). Summary below — overall needs a few changes before merge, but the core is solid.

🔴 Must-fix: collapsing can hide the active panel

setActiveTask / jumpToTask / sidebar clicks (navigation.ts) and togglePanelGroupCollapsed (ui.ts) never touch collapse state — it's only reset on task create/uncollapse. So:

  • Collapse a group, then select a non-first member → it becomes activeTaskId but its wrapper stays width:0; visibility:hidden (TilingLayout.tsx:743-755). Keyboard input goes to an invisible panel and scroll-into-view targets a hidden node, with no visible feedback.
  • Same in reverse: collapsing a group whose active task is a non-first sibling makes the active panel vanish.
  • In focus mode too: wrapperStyle() checks childHidden() before store.focusMode, so a hidden collapsed sibling stays blank even when focused.

Fix: force-expand a group when one of its members becomes active (and/or reassign activeTaskId to the visible first panel when a collapse would hide the current active task).

🟡 High-value cleanups

  • renderSegmentCache is an unbounded module-level Map that's never evicted (TilingLayout.tsx:146-157) — 6 of 7 review passes flagged it. Because the key embeds positional fields (start/end/index/color), it grows monotonically over a session and only returns a stable reference when the exact same layout recurs — so it doesn't actually prevent the reorder remount it looks designed for. Suggest dropping it and letting panelCache (which already stabilizes the real TileChild/DOM) do the work, switching the outer <For> to <Index>.
  • Reorder likely remounts ungrouped panels (terminal disposed → scrollback lost). The outer <For> now keys on single:${id}:${index} objects, so Cmd+←/→ or drag-reorder produces brand-new references → SolidJS recreates the row → TerminalView disposes. Worth confirming by running; fixing the cache the right way resolves it.
  • Two grouping passescomputeTilingSegments already computes group boundaries (isFirst/panelCount), then buildRenderSegments rescans to rediscover them. Unifying into one pass removes the second algorithm + the cache (~60-80 lines).
  • DRY: coordinatorMode || coordinatedBy ? 'coordinator' : 'independent' is duplicated in TilingLayout.tsx and tasks.ts (panelGroupKeyForTask, which also re-implements the key instead of reusing groupKey). One shared getPanelGroupType(task) would help.

🟢 Minor

  • The ~9 *ForTest re-export shims could go away by extracting the pure helpers into a small tilingGroups.ts and exporting them normally (also fixes the file-size growth).
  • groupWrapperPadding ignores its parameter and always returns '0 6px' — make it a const.
  • Dead __collapsed handling (TilingLayout.tsx:164,617) — nothing creates that id anymore.
  • void Object.keys(store.panelGroupCollapsed).join(',') allocates each run; the real subscription is the isPanelGroupCollapsed(...) read below it.
  • styles.test.ts leans on regex-over-CSS and not.toContain('...source...') assertions, which break on harmless restyles without catching real regressions — a rendered-component test would be higher-signal.

💬 On the UX pattern

The grouping + colored background is good. The part I'd reconsider is collapse-to-first-panel: it hides count and identity (you see one arbitrary full-size panel + a faint chevron, with no signal of how many/which tasks are behind it), while reclaiming little space since the representative still renders full-width. Combined with persistence, reopening the app can leave running tasks silently hidden. A couple of directions worth considering:

  • Add a count/identity affordance to the collapsed state (a +N badge / status dots) so hidden panels stay legible — especially on restore.
  • Note we already have focus mode + sidebar collapse; three overlapping "hide panels" mechanisms is a lot of surface. If we can make group-collapse coexist legibly with focus mode (or lean on a tabs-within-group / count-badge-stack representation), that might serve "many parallel agent panels" better than collapse-to-first.

Also minor a11y: the collapse/expand buttons have only title (SVGs are aria-hidden) — an aria-label would help screen readers.

Happy to pair on the active-panel fix or the single-pass/<Index> refactor if useful. Thanks again for tackling this — really like where it's headed!

@FourWindff

Copy link
Copy Markdown
Contributor Author

This PR is still rough — it's mainly meant to explore the grouping interaction. Once the direction is settled, I'll open a fresh PR for the real implementation. Before moving forward, I'd like to discuss a few key questions about the grouping UX:

  1. Besides collapsing a group into the first panel, are there better ways to display grouped task panels?

  2. How should we define which tasks belong to the same group?

    • Same project
    • Tasks created from the same branch
    • In coordinator mode: the coordinator and all its child task panels

    I think grouping by the same project is too broad. Usually I create multiple tasks from a single branch, and they tend to be similar kinds of work — e.g., adjusting UI, or cleaning up different categories of code (dead code, migration, compatibility). The point of grouping is to make it easier to manage related tasks, so grouping by branch or by coordinator mode seems more useful.

  3. How should grouping interact with the sidebar's collapsed mode?
    Should task panels in the same group hide together? For example, show a collapse button only on the first task panel; clicking it hides the entire group. Then clicking any task from that group in the sidebar expands and shows all panels in the group.

  4. When dragging a task panel, should the whole group move together?

Since these are grouped tasks, having them show, hide, and move together seems consistent.

@johannesjo johannesjo requested a review from brooksc June 17, 2026 09:09
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.

2 participants