Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

feat: add collapsible reasoning/tool-call blocks, code copy, and inline diff to TUI messages

Closed
#1,359 2 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

A pull request for this has already been merged.

  • #1361 by @avoidwork — merged

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
12/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Stale
Tech stack
javascript
Domain
cli

Research direction

Start in src/tui/messageBubble.js, where MessageBubbleInner handles reasoning segments (seg.type === "reasoning"), and read the tool-call rendering next to it. The [copy] affordance belongs in the component layer, reusing clipboardy from src/tui/app.js. Tests for the collapse toggles and diff rendering are also needed. This is a multi-feature design task with an open pull request (#1361) and a split recommendation, so confirm scope with the maintainers before starting.

Written by the indexing model from the issue text.

Description

approved feature in progress

Summary

Add four TUI message-rendering enhancements: collapsible reasoning blocks, collapsible tool-call blocks, code-block copy with syntax highlighting, and an inline diff view for file changes.

Motivation

The TUI currently renders reasoning, tool calls, code blocks, and file changes as flat, non-interactive text. This makes long reasoning chains and tool outputs hard to scan, and prevents users from copying code or reviewing file diffs inline. These enhancements make the message stream more navigable and actionable.

Proposed Solution

  1. Reasoning collapse/expand — Add a toggle to collapse a reasoning block to a single '💭 Thinking…' line, expandable on demand. The segment structure in src/tui/messageBubble.js already distinguishes reasoning from message.
  2. Collapsible tool-call blocks — Show tool name + args collapsed, expandable to the full result. Tool-call data already flows through the conversation stream.
  3. Code-block copy + syntax highlighting — Add a [copy] affordance on fenced code blocks using clipboardy (already imported in src/tui/app.js), plus light syntax highlighting in src/tui/markdownText.js.
  4. Inline diff view for file changes — Render file edits as green/red diff lines in a collapsible block, pairing with the existing file/process tooling.

Alternatives Considered

  • Using a full markdown renderer with built-in syntax highlighting — rejected as too heavy for the TUI's lightweight rendering.
  • Rendering diffs as separate panes — rejected in favor of inline collapsible blocks that keep the message stream coherent.

Dependencies

  • clipboardy (already imported in src/tui/app.js) — used for the code-block copy affordance.
  • Syntax highlighting — to be determined during implementation; a lightweight highlighter (e.g., highlight.js or a minimal custom tokenizer) may be added. Unknown — user to confirm for the specific package.

Testing Strategy

  • Unit tests: Verify reasoning/tool-call collapse/expand toggles, code-block copy handler, syntax highlighting output, and diff line rendering.
  • Integration test: Render a message stream with reasoning, tool calls, code blocks, and file changes; verify each renders and toggles correctly.
  • Edge cases: Empty reasoning block, very long tool results, code blocks with no language, diffs with no changes.

Security Considerations

  • Credential storage: No new credentials introduced; clipboardy operates on the local clipboard only.
  • Input validation: Validate rendered content before injecting into the DOM to prevent XSS from model output.
  • OWASP: Sanitize any HTML rendered from markdown/code content; avoid injecting raw model output.

OpenSpec Note

This project uses OpenSpec for feature development. If this request is approved, I will:

  1. Run /opsx:propose to generate a full proposal with specs and tasks
  2. Iterate on the design before any code is written
  3. Follow the task-driven implementation workflow

Split Recommendation

This issue bundles multiple distinct capabilities. Consider splitting into separate issues:

  • Reasoning collapse/expand — Self-contained toggle on existing reasoning segments; lowest dependency.
  • Collapsible tool-call blocks — Independent of reasoning; touches tool-call rendering.
  • Code-block copy + syntax highlighting — Two sub-features (copy + highlighting) that could be split further.
  • Inline diff view for file changes — Depends on file/process tooling; separate rendering concern.

MVP recommendation: Start with reasoning collapse/expand as it has the least dependencies and highest immediate value.

Additional Context

Split out from issue #1339.

Audit Findings (for Issue #1359)

  • src/tui/messageBubble.js — MessageBubbleInner already distinguishes reasoning segments (seg.type === "reasoning", ~line 340) and renders them as gray text with marginLeft: 2. No collapse/expand toggle exists. Tool calls render as flat text via toolCallEl (active), toolDisplayEl (result), and completedToolCallsEl (count map). This is the primary integration point for items 1 and 2 — add useState collapse state and a toggle handler here.
  • src/tui/markdownText.js — Syntax highlighting already exists via cli-highlight (highlightCli) in the code({ text, lang }) renderer method (~line 155). So item 3's highlighting is largely done; only the [copy] affordance is missing. MarkdownText is a pure renderer with no clipboard access — the copy handler must live in the component layer.
  • src/tui/app.js — clipboardy is imported at line 17 and used at line 462 for selection copy. This is the existing copy mechanism to reuse for the [copy] affordance on code blocks.
  • src/tui/conversationArea.js — Reasoning segments are created at lines 668-716. Tool-call data flows through the conversation stream via events (line 650-652), toolCallDisplay, activeToolCall, and completedToolCalls. The events array carries raw stream events including tool calls — the source for collapsible tool-call blocks.
  • src/tui/messageList.js — Passes activeToolCall, toolCallDisplay, completedToolCalls, events, and showToolResults to MessageBubble (~line 592). No changes needed here beyond possibly forwarding new props.
  • Diff view (item 4) — No existing diff rendering. File/process tooling lives in src/tools/process/index.js and src/tools/code/index.js. A new diff segment type or file-change event renderer is needed.

Fix Steps

  1. Reasoning collapse/expand — In src/tui/messageBubble.js, add a useState toggle (e.g., collapsed) to MessageBubbleInner. When seg.type === "reasoning", render a single 💭 Thinking… line when collapsed, and the full gray content when expanded. Add a click/keyboard handler to toggle.
  2. Collapsible tool-call blocks — In src/tui/messageBubble.js, wrap toolCallEl/toolDisplayEl in a collapsible block. Show tool name + args collapsed, expandable to the full result. Source data from events/toolCallDisplay/completedToolCalls flowing from conversationArea.js.
  3. Code-block copy + syntax highlighting — Syntax highlighting already exists via cli-highlight in src/tui/markdownText.js. Add a [copy] affordance on fenced code blocks. Since MarkdownText is a pure renderer, add the copy handler in the component layer (messageBubble.js) or pass a copy callback, reusing clipboardy from src/tui/app.js.
  4. Inline diff view — Add a diff renderer (green/red lines) in a collapsible block. Pair with file/process tooling in src/tools/process/index.js and src/tools/code/index.js. Add a diff segment type or render file-change events.
  5. Write tests — Add unit tests for collapse/expand toggles, the copy handler, and diff rendering.
  6. Verify — Run npm run test, npm run lint, and npm run coverage to confirm no regressions.
Dominant language
JavaScript
Stars
2
Forks
0
Avg merge
1h 15m
Merged PRs (30d)
237

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from avoidwork/madz

All issues in avoidwork/madz

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.