Skip to content

feat: add inline diff viewer for Edit/Write tool calls#75

Closed
bradfeld wants to merge 2 commits intodanshapiro:mainfrom
bradfeld:feature/FRE-17-add-inline-diff-viewer
Closed

feat: add inline diff viewer for Edit/Write tool calls#75
bradfeld wants to merge 2 commits intodanshapiro:mainfrom
bradfeld:feature/FRE-17-add-inline-diff-viewer

Conversation

@bradfeld
Copy link
Contributor

Summary

  • Extracts diff computation into pure diff-utils.ts with two-level diffing: line-level structure via diffLines + word-level highlighting via diffWords on paired removed→added line runs
  • Enhances DiffView component with word-level highlight spans, compact mode, and maxLines truncation
  • Adds FilePreview component for Write tool full-file preview (all lines shown as added with green styling)
  • Adds ToolDetailPanel with expand/collapse toggle for Edit/Write events in the activity panel sidebar
  • Routes Edit/Write tool.call events to ToolDetailPanel in ToolActivityFeed (other tools remain flat rows)
  • Updates sdk-message-handler to pass full arguments for Edit/Write tool events (others truncated to 200 chars)

Depends on FRE-16 (structured sidebar) — this branch is rebased on feature/FRE-16-structured-sidebar-tool-call-visibility

Test plan

  • npm test passes (3480 pass, 3 pre-existing WSL path failures unrelated)
  • 50 new/enhanced tests: diff-utils (23), DiffView (9), FilePreview (6), ToolDetailPanel (7), ToolActivityFeed (5)
  • Manual: trigger Edit/Write tool calls in Claude session, verify compact→expanded diff rendering
  • Manual: verify non-Edit/Write tools still show flat event rows

🤖 Generated with Claude Code

- Add collapsible sidebar panel alongside terminal panes showing:
  - Tool activity feed with color-coded event types (ring buffer, 200 max)
  - Token usage meter with input/output/cached breakdown
  - Permission request actions with approve/deny buttons
  - Active task list from TaskCreate/TaskUpdate events
- Wire activity panel events through global sdk-message-handler for both
  SDK (claude-chat) and coding CLI (terminal) session types
- Add Redux slice with ring buffer storage and per-session state
- Add toggle button in pane header with event count badge
- Persist panel visibility preference in settings

Fixes empty activity panel bug where codingcli.event messages were only
handled in SessionView (headless sessions) but not for terminal panes.

Refs FRE-16
- Extract diff computation into pure diff-utils.ts with word-level highlighting
- Enhance DiffView with word-level spans, compact mode, and maxLines props
- Add FilePreview component for Write tool full-file preview
- Add ToolDetailPanel with expand/collapse for Edit/Write in activity sidebar
- Route Edit/Write tool.call events to ToolDetailPanel in ToolActivityFeed
- Pass full arguments for Edit/Write in sdk-message-handler (truncate others)
- 50 tests covering diff logic, DiffView, FilePreview, ToolDetailPanel, feed

Refs FRE-17
Copy link

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

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: c5a12cad55

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


const handleApprovePermission = codingCliSessionId
? (requestId: string) => {
ws.send({ type: 'codingcli.approval', sessionId: codingCliSessionId, requestId, approved: true })

Choose a reason for hiding this comment

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

P1 Badge Send a valid WS type for coding CLI approval actions

The new permission buttons emit type: 'codingcli.approval', but that message type is not accepted by the protocol/server, so Approve/Deny from the activity panel will fail at runtime (typically as INVALID_MESSAGE) and leave approvals stuck. I checked shared/ws-protocol.ts (ClientMessageSchema only includes codingcli.create, codingcli.input, and codingcli.kill) and server/ws-handler.ts uses the same discriminated union, so this wire type cannot be processed.

Useful? React with 👍 / 👎.

Comment on lines +124 to +127
toolResult: {
name: block.tool_use_id ?? '',
success: !block.is_error,
output: typeof block.content === 'string' ? block.content.slice(0, 200) : undefined,

Choose a reason for hiding this comment

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

P1 Badge Map SDK tool results into the tool payload

This tool.result event is populated into toolResult with nonstandard fields (name/success) instead of the event.tool shape consumed by the new feed, so SDK tool results render incorrectly: the row label falls back to Result, failures are shown as success, and error output/details are dropped when block.is_error is true. The issue appears whenever an SDK assistant message contains tool_result blocks.

Useful? React with 👍 / 👎.

@danshapiro
Copy link
Owner

Nice work on the diff viewer, @bradfeld — the pure diff-utils.ts with word-level highlighting is clean, and the component separation (DiffView, ToolDetailPanel, FilePreview) is solid.

Since this builds on #72 and shares the same data pipeline question (activity panel only populates via Freshclaude sessions, not terminal-mode), we've consolidated into #83 along with #64 and #67.

Closing in favor of #83 — see the tracking issue for full analysis and questions.

— Claude Code

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