Skip to content

feat(amazonq): add diff animation support for chat responses #7492

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 31 commits into
base: feature/code-diff
Choose a base branch
from

Conversation

MarcoWang3
Copy link

@MarcoWang3 MarcoWang3 commented Jun 16, 2025

Problem

Amazon Q chat currently only supports static diff views that are shown after code generation is complete. Users cannot see the real-time changes being made to their files, which creates a disconnect between the AI's explanation and the actual code modifications. This lack of visual feedback makes it difficult to:

  • Follow along with code changes as they happen
  • Understand the step-by-step modifications being made
  • Identify which parts of files are being modified
  • Provide immediate feedback during the code generation process

Solution

Implemented a comprehensive Diff Animation System that provides real-time, Cline-style animated diff views during code generation. This new feature enhances user experience by showing live code changes with visual animations, making the AI coding process more transparent and engaging.

High-Level Diff Animation Workflow

Chat Message Detection → 2. File Change Monitoring → 3. Animation Triggering → 4. Live Diff Rendering → 5. Interactive Review

Detailed Flow:

  1. Chat Processing: System detects file write operations from Amazon Q chat responses
  2. Pre-capture: Original file content is captured before modifications
  3. Change Detection: File system watcher detects actual file writes
  4. Animation Trigger: Diff animation starts automatically when changes are detected
  5. Live Rendering: VS Code diff view opens with line-by-line streaming animation
  6. Interactive Review: Users can interact with the animated diff view and review changes

Architecture & Component Structure

Main Components

DiffAnimationHandler (Main Entry Point - 300 lines)

  • Entry point for all diff animation operations
  • Integrates with Amazon Q chat message processing
  • Manages animation lifecycle from detection to completion
  • Coordinates between all animation components
  • -Uses three sub-components:
    • FileSystemManager (File Operations - ~200 lines)
    • ChatProcessor (Processing Chat Messages - ~200 lines)
    • AnimationQueueManager (Animation Queue Management- ~180 lines)

DiffAnimationController (Animation Engine - 400 lines)

  • Controls real-time animation rendering and timing
  • Creates Cline-style side-by-side diff views
  • Manages line-by-line streaming animations
  • Handles both full file and partial update animations
  • Uses three sub-components:
    • WebviewManager (UI Management - ~250 lines)
    • DiffAnalyzer (Diff Logic - ~220 lines)
    • VSCodeIntegration (VS Code APIs - ~180 lines)

DiffAnimationHandler Supporting Components

FileSystemManager (File Operations - ~200 lines)

  • File watching and change detection
  • Content capture before/after modifications
  • Path resolution and normalization

ChatProcessor (Message Processing - ~150 lines)

  • Amazon Q chat message parsing
  • Tool use detection for file operations
  • File write preparation coordination

AnimationQueueManager (Queue Management - ~180 lines)

  • Concurrent animation coordination
  • Animation state management
  • Performance optimization

DiffAnimationController Sub-Components

WebviewManager (UI Management - ~250 lines)

  • VS Code diff view creation
  • HTML content generation with syntax highlighting
  • Animation timing and effects
  • Message passing between extension and webview

DiffAnalyzer (Diff Logic - ~220 lines)

  • Line-by-line difference calculation
  • Changed region detection
  • Animation scan plan generation
  • Animation timing calculations

VSCodeIntegration (VS Code APIs - ~180 lines)

  • Built-in diff editor integration
  • Editor operations and document management
  • User notifications and status updates

Data Flow

  1. ChatProcessor detects file operations from Amazon Q chat
  2. FileSystemManager captures original content and watches for changes
  3. AnimationQueueManager queues animations when file changes detected
  4. DiffAnimationController creates diff views and manages animations
  5. WebviewManager renders visual diff with streaming effects
  6. DiffAnalyzer calculates line-by-line differences for animation
  7. VSCodeIntegration handles VS Code API interactions and user notifications

New Functionalities

Animation Features

  • 🎬 Real-time Diff Animation: Live line-by-line streaming of code changes
  • 👀 Cline-style Diff View: Side-by-side comparison with original and modified content
  • 🟡 Yellow Scanning Line: Animated yellow line shows current scanning position
  • 🟢 Green Addition Highlighting: New lines highlighted in green after scanning
  • 🔴 Red Deletion Visualization: Clear visualization of removed lines in red
  • 📁 New File Support: Handles creation of new files with empty left panel
  • ⚡ Partial Updates: Animates only changed sections for better performance
  • 🎨 GitHub-style Decorations: Professional diff styling and decorations

Integration Features

  • 💬 Amazon Q Chat Integration: Seamless integration with chat-based code generation
  • 🔍 Auto-detection: Automatic detection of file changes from chat responses
  • 👆 Click-to-View: Users can click file references in chat to view animated diffs
  • 📊 Multi-file Support: Handles concurrent animations across multiple files
  • 🧹 Memory Management: Automatic cleanup prevents memory leaks
  • ⚠️ Error Recovery: Graceful error handling with fallback to static diff

User Experience Enhancements

  • 📱 Status Updates: Real-time status messages during animation process
  • 🔄 Animation History: Maintains history of animated changes for review
  • ⚙️ Performance Optimization: Smart optimization for large files and complex changes

Unit Test Design & Coverage

Comprehensive Test Strategy

Implemented 95%+ code coverage across all new components with systematic edge case testing:

DiffAnimationHandler Tests (15 test categories, 45+ test cases)

  • Initialization: Constructor validation and component integration
  • Chat Integration: Amazon Q ChatResult and ChatMessage processing
  • File Operations: File diff processing with various content types
  • Animation Lifecycle: Start, stop, and cleanup operations
  • Error Handling: Graceful error recovery and fallback mechanisms
  • Memory Management: Cleanup verification and leak prevention
  • Integration Scenarios: End-to-end workflows for different file operations

DiffAnimationController Tests (12 test categories, 40+ test cases)

  • Animation Control: Start, stop, pause, and resume functionality
  • Diff View Management: VS Code diff editor integration
  • Partial Updates: Targeted animations with specific change locations
  • State Management: Animation data persistence and retrieval
  • Performance Testing: Large file handling and optimization
  • Concurrency: Multiple simultaneous animations

Edge Cases Covered

Input Validation & Robustness

  • Null/Undefined Inputs: All public methods handle invalid inputs gracefully
  • Empty Content: Proper handling of empty files and content
  • Invalid Paths: Robust path validation and error recovery
  • Malformed Messages: Amazon Q message parsing with error handling

Performance & Scalability

  • Large Files: Testing with 100K+ character files
  • Concurrent Operations: Multiple simultaneous animations
  • Memory Constraints: Memory usage optimization and cleanup
  • Animation Interruption: Proper cleanup when animations are stopped

Platform Compatibility

  • Path Handling: Cross-platform path resolution and normalization
  • Special Characters: Unicode content and special file path characters
  • File System Errors: Permission issues and file access problems
  • VS Code API Variations: Different VS Code versions and configurations

Mock Strategy & Test Infrastructure

  • Complete VS Code API Mocking: Comprehensive stubbing of all vscode.* APIs
  • File System Simulation: Controlled file operation responses for testing
  • Error Injection: Systematic error simulation for robustness validation
  • State Verification: Animation state persistence and cleanup verification
  • Performance Monitoring: Animation timing and resource usage validation

Benefits of This New Feature

Enhanced User Experience

  • 👁️ Visual Feedback: Users can see exactly what changes are being made in real-time
  • 🎯 Better Understanding: Clear visualization helps users understand AI modifications
  • ⚡ Immediate Review: Users can review changes as they happen, not just after completion
  • 🔍 Detailed Inspection: Line-by-line view shows precise modifications

Improved Development Workflow

  • 🚀 Faster Feedback Loop: Immediate visual feedback during code generation
  • 🛡️ Error Prevention: Users can spot issues during generation, not after
  • 📚 Learning Tool: Helps users understand how AI approaches code modifications
  • 🎨 Professional Experience: Cline-style animations provide polished, professional feel

Technical Advantages

  • 🏗️ Modular Architecture: Clean separation of concerns for maintainability
  • 🧪 Comprehensive Testing: High test coverage ensures reliability
  • ⚡ Performance Optimized: Smart algorithms handle large files efficiently
  • 🔧 Extensible Design: Easy to add new animation types and features

Screenshots

-Create a new file

Create_New_Files.mov

-Edit a single file

Edit_Single_FIle.mov

-Edit multiple files

Edit_Multiple_Files.mov

  • Treat all work as PUBLIC. Private feature/x branches will not be squash-merged at release time.
  • Your code changes must meet the guidelines in CONTRIBUTING.md.
  • License: I confirm that my contribution is made under the terms of the Apache 2.0 license.

@MarcoWang3 MarcoWang3 changed the title Feature/code diff Render Real Time Diff Animation while Generating Codes Jun 16, 2025
@MarcoWang3 MarcoWang3 changed the title Render Real Time Diff Animation while Generating Codes Render Real Time Diff Animation Jun 16, 2025
@MarcoWang3 MarcoWang3 closed this Jun 16, 2025
@MarcoWang3 MarcoWang3 reopened this Jun 16, 2025
@MarcoWang3 MarcoWang3 changed the title Render Real Time Diff Animation feat(amazonq): add diff animation support for chat responses Jun 16, 2025
@MarcoWang3 MarcoWang3 closed this Jun 16, 2025
@MarcoWang3 MarcoWang3 reopened this Jun 16, 2025
Copy link

  • This pull request implements a feat or fix, so it must include a changelog entry (unless the fix is for an unreleased feature). Review the changelog guidelines.
    • Note: beta or "experiment" features that have active users should announce fixes in the changelog.
    • If this is not a feature or fix, use an appropriate type from the title guidelines. For example, telemetry-only changes should use the telemetry type.

@MarcoWang3 MarcoWang3 closed this Jun 16, 2025
@MarcoWang3 MarcoWang3 reopened this Jun 16, 2025
@MarcoWang3 MarcoWang3 closed this Jun 16, 2025
@MarcoWang3 MarcoWang3 reopened this Jun 16, 2025
@MarcoWang3 MarcoWang3 reopened this Jun 16, 2025
@MarcoWang3 MarcoWang3 marked this pull request as ready for review June 16, 2025 23:21
@MarcoWang3 MarcoWang3 requested a review from a team as a code owner June 16, 2025 23:21
@MarcoWang3 MarcoWang3 deleted the branch aws:feature/code-diff July 3, 2025 21:07
@MarcoWang3 MarcoWang3 closed this Jul 3, 2025
@MarcoWang3 MarcoWang3 deleted the feature/code-diff branch July 3, 2025 21:07
@MarcoWang3 MarcoWang3 restored the feature/code-diff branch July 3, 2025 22:14
@MarcoWang3 MarcoWang3 reopened this Jul 3, 2025

## Overview

The `diffAnimation` directory has been refactored from 2 large files (~1700 lines total) into 9 smaller, focused modules following the Single Responsibility Principle. This improves maintainability, testability, and code organization while preserving all existing functionality.
Copy link
Contributor

Choose a reason for hiding this comment

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

This does not add value!

}
}
} catch (error) {
getLogger().error(`[ChatProcessor] ❌ Failed to process chat result: ${error}`)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we show any error to the user in this case? Was that handled somewhere?

const lines = newContent.split('\n')
return {
startLine: 0,
endLine: Math.min(lines.length - 1, 99), // Cap at 100 lines
Copy link
Contributor

@laileni-aws laileni-aws Jul 9, 2025

Choose a reason for hiding this comment

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

Do we need this limit? any reason if yes, please add comment here.

}

// Add context lines (3 before and after)
const contextLines = 3
Copy link
Contributor

Choose a reason for hiding this comment

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

Same question?

return i < arr.length - 1 || l !== ''
})

if (change.removed) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you refactor this function?

scanDelay: number
totalDuration: number
} {
const scanDelay = scanPlanLength > 50 ? 40 : 70
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add comment how we came up with this arbitrary numbers?

})

// Pre-add lines that are before the scan region (context)
for (let i = 0; i < Math.min(changedRegion.startLine, 3); i++) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: use variable naming as index instead of i.


// Pre-add lines that are before the scan region (context)
for (let i = 0; i < Math.min(changedRegion.startLine, 3); i++) {
if (leftLines[i]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit:

const contextLines = Math.min(changedRegion.startLine, 3);

for (let lineIndex = 0; lineIndex < contextLines; lineIndex++) {
    const sides = [
        { side: 'left', lines: leftLines },
        { side: 'right', lines: rightLines }
    ];

    for (const { side, lines } of sides) {
        if (lines[lineIndex]) {
            await this.webviewManager.sendMessageToWebview(filePath, {
                command: 'addLine',
                side,
                line: lines[lineIndex],
                immediately: true
            });
        }
    }
}

/**
* Cancel ongoing animation
*/
private cancelAnimation(filePath: string): void {
Copy link
Contributor

Choose a reason for hiding this comment

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

Its better to have a early return!

private cancelAnimation(filePath: string): void {
    const animation = this.activeAnimations.get(filePath);
    
    // Early return if no animation or if showing static diff
    if (!animation || animation.isShowingStaticDiff) {
        return;
    }

    // Mark animation as cancelled
    animation.animationCancelled = true;
    
    // Clear all timeouts and cleanup
    this.clearAnimationTimeouts(filePath);
}

// Separate method for timeout clearing logic
private clearAnimationTimeouts(filePath: string): void {
    const timeouts = this.animationTimeouts.get(filePath);
    if (!timeouts) {
        return;
    }

    timeouts.forEach(clearTimeout);
    this.animationTimeouts.delete(filePath);
}

*/

/**
* DiffAnimationHandler - Cline-style Diff View Approach
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we remove this comment mentioning our competitor ?

import { PendingFileWrite } from './types'

export class DiffAnimationHandler implements vscode.Disposable {
/**
Copy link
Contributor

@laileni-aws laileni-aws Jul 9, 2025

Choose a reason for hiding this comment

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

nit: This comment can be at L31.

private pendingWrites = new Map<string, PendingFileWrite>()

constructor() {
getLogger().info(`[DiffAnimationHandler] 🚀 Initializing DiffAnimationHandler with Cline-style diff view`)
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment

*/
public async testAnimation(): Promise<void> {
const originalContent = `function hello() {
console.log("Hello World");
Copy link
Contributor

Choose a reason for hiding this comment

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

Please don't use console.log statements instead use Logger.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

}

/**
* Test method to manually trigger animation (for debugging)
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this is not required for prod version. If yes please remove this code!

}`

const newContent = `function hello(name) {
console.log(\`Hello \${name}!\`);
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment

)
getLogger().info(`[DiffAnimationHandler] 🧪 Running test animation for: ${testFilePath}`)

// Run the animation using Cline-style diff view
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above comment

): Promise<void> {
const animationId = `${path.basename(filePath)}_${Date.now()}`

getLogger().info(`[DiffAnimationHandler] 🎬 Starting Cline-style diff animation ${animationId}`)
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here.

Copy link
Contributor

@laileni-aws laileni-aws left a comment

Choose a reason for hiding this comment

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

Please address comments!

└── VSCodeIntegration (VS Code APIs)
```

## Key Benefits
Copy link
Contributor

Choose a reason for hiding this comment

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

I like the section but does not add values for future users, testers.

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.

3 participants