Skip to content

feat(desktop): bound expanded tool activity in the conversation #4773

Description

@Colafornia

Problem

A reader expands a tool group to inspect its activity. In a long turn, that action replaces the conversation with several screens of tool rows.

A group with 45 calls remains one continuous part of the transcript. Each row may be short, but the full list pushes the assistant response far below the viewport. Individual output limits do not solve this problem because the height comes from the number of rows.

This issue does not propose a new grouping algorithm. Maka should keep the current chronological grouping of adjacent ordinary tool calls. The change is limited to how an existing group is summarized and displayed after the reader expands it.

The current sticky header also has an unresolved visual defect. Its 8px top offset leaves a strip where the previous row remains partly visible while content scrolls underneath. PR #3375 demonstrated the problem and proposed a flush sticky header, but as of 2026-09-04 that PR remains open and conflicts with current main. The defect is therefore still present.

Visual comparison

Maka current (origin/main) Codex app Astryx official example
Image Image Image

Current experience

The reader expands "45 tool calls"

┌──────────────── conversation viewport ────────────────┐
│ previous content remains visible through an 8px strip │
│ [45 tool calls — sticky header]                        │
│ ✓ Read package.json                              ›     │
│ ✓ Search for ToolTrow                            ›     │
│ ✓ Read tool-activity.tsx                         ›     │
│ ✓ Run tests                                      ›     │
│ ...                                                    │
└────────────────────────────────────────────────────────┘
  37 more rows continue in the transcript
  ↓
  ↓ several screens of scrolling
  ↓
  Assistant response

The reader must choose between keeping the evidence collapsed or letting it displace the response. Expanding one group also adds a permanent chevron to every row, which gives repeated controls the same visual weight as status and result information.

Desired outcome

Expanding a tool group should expose its history without replacing the surrounding conversation.

The reader expands "45 tool calls"

┌──────────────── conversation viewport ────────────────┐
│ 45 tool calls                                          │
│ ┌──────── bounded activity list ─────────────────────┐ │
│ │ ✓ Read package.json                               │ │
│ │ ✓ Search for ToolTrow                             │ │
│ │ ✓ Read tool-activity.tsx                          │ │
│ │ ✓ Run tests                                       │ │
│ │   └─ command and output detail, opened explicitly │ │
│ │ ...                                      scroll ↕ │ │
│ └────────────────────────────────────────────────────┘ │
│                                                        │
│ Assistant response continues near the activity group   │
└────────────────────────────────────────────────────────┘

The information remains available. The difference is navigation cost: readers inspect a bounded evidence region instead of scrolling through several transcript screens before they can continue reading.

Suggested behavior:

  • Keep the current chronological grouping of adjacent ordinary calls. Do not regroup calls by tool type or inferred meaning.
  • Keep multi-call groups collapsed by default.
  • Keep the collapsed summary compact while showing the latest relevant activity, total call count, and a failure signal when needed.
  • Show the total call count and failure count in the expanded group header.
  • Let small expanded groups use their natural height.
  • Bound long groups with a viewport-aware height, such as clamp(160px, 40vh, 360px).
  • Scroll only the tool summary list and contain its scroll chain.
  • Keep the group header outside the internal scroll area.
  • Remove transcript-level sticky behavior from the group header once the group is bounded.
  • Keep an expanded row control reachable while its detail is being read.
  • Keep row details closed until the reader explicitly opens them.
  • Hide completed-row chevrons at rest on pointer devices.
  • Reveal the row affordance on hover and keyboard focus, and keep it visible on touch devices.
  • Keep running and failed states visible without hover.
  • While an expanded group is streaming, follow appended rows only while the reader remains at the list tail. Do not pull the reader away after they scroll upward.
  • Preserve chronological order and existing individual output limits.

Reading advantages

  • Conversation continuity: the assistant response remains close to the work that produced it.
  • Clear hierarchy: the transcript scrolls between conversation units; the inner list scrolls through one unit's evidence.
  • Lower visual noise: status, target, duration, and diff information no longer compete with 45 permanent chevrons.
  • No sticky bleed: the group header no longer needs the sticky behavior that causes the unresolved gap from fix(ui): reading-column polish — balanced density, conversation radius, flush sticky #3375.
  • No information loss: every row and detail remains available through explicit expansion.

Why not only fix the sticky offset?

Changing the sticky offset from 8px to 0 would remove the visible strip reported in #3375, but the expanded group would still occupy several transcript screens.

The sticky header was introduced in #2542 because unbounded activity could push the collapse control out of view. A bounded internal list removes that cause. The group header can then remain outside the list without being sticky.

Row-detail sticky behavior is separate. It can remain within the bounded list so a reader can close an expanded detail without searching for its row header.

Relevant Maka history

Maka has already tested most parts of this interaction:

This proposal keeps the established conclusions: one renderer, collapsed history, visible failures, explicit detail, and no duplicate grouping layer. The new part is bounding the expanded group itself.

Reference research

The direction was compared with several agent products and open-source implementations:

  • OpenCode aggregates low-noise context tools and uses count-based summaries.
  • Reasonix groups related activity and bounds shell previews.
  • AionUI keeps live activity and error counts visible in summaries.
  • Goose uses human-readable action labels and moves raw evidence into nested details.
  • Pi uses explicit expansion and bounded Bash previews.
  • Codex app bounds the expanded group body, scrolls it internally, and avoids a permanent arrow on every ordinary row.

The repeated pattern is:

compact group summary
→ bounded activity overview
→ explicit evidence detail

Alternatives or workarounds

  • Fix only the sticky gap: removes the visual artifact but leaves the transcript-height problem.
  • Keep the current sticky header: preserves the collapse action but lets activity displace the response.
  • Show the first N rows plus "Show all": hides chronology behind another display mode.
  • Virtualize the list: useful for hundreds of rows, but unnecessary for the current scale.
  • Add semantic or per-tool grouping: useful later, but not required to improve the default reading experience.
  • Move details into a side inspector: changes the conversation workflow and desktop layout.

Acceptance criteria

  • Multi-call groups remain collapsed until the reader opens them.
  • Existing chronological group membership remains unchanged; no semantic grouping is introduced.
  • Collapsed and expanded group summaries preserve the call count and a visible failure signal.
  • Small groups expand without an unnecessary scrollbar.
  • A 45-call group stays within a viewport-aware height and scrolls internally.
  • The assistant response remains near the expanded group instead of several screens below it.
  • Scrolling to the end of the group does not unexpectedly scroll the transcript.
  • The group header has no transcript-level sticky behavior or bleed-through gap.
  • An expanded row can still be collapsed while its detail is being read.
  • Completed rows have no permanent chevron on pointer devices.
  • Hover, keyboard focus, and touch retain a clear expansion affordance.
  • Running and failed calls remain identifiable without hover.
  • Row details remain keyboard accessible and closed by default.
  • Streaming rows remain visible while the reader is at the list tail, without overriding a manual upward scroll.
  • Chronological ordering and existing individual output bounds remain unchanged.
  • Browser coverage includes 1, 3, and 45 calls, running/error states, long content, light/dark themes, and a short viewport.

Future direction

This issue defines a better default presentation. It does not make one display policy correct for every tool.

A later change should allow users to configure presentation behavior by tool or tool category. Possible policies include:

  • whether calls join the surrounding tool group or remain standalone;
  • whether they start collapsed, expanded, or summary-only;
  • whether completed calls stay hidden unless they fail;
  • how much information appears in the collapsed summary;
  • whether full result detail is available inline.

For example, search and file-read tools may use compact grouped summaries, while shell, edit, browser, and subagent tools may need different defaults.

The behavior defined in this issue should remain the fallback when no user policy exists. Later configuration should reuse the same group, row, and detail hierarchy instead of adding another renderer.

Out of scope

Per-tool presentation settings, semantic grouping rules, configuration storage and migration, list virtualization, a side inspector, and single-active-detail enforcement are not part of this issue.

Activity

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions