Skip to content

Conversation

@Aaryan-549
Copy link

Implements optional VS Code integration to preview suggested code changes as side-by-side diffs before approval, providing faster feedback and safer code review.

🎯 Fixes

Closes #448

📝 Summary

This PR adds VS Code diff preview capability to deepagents-cli. When enabled with the --vscode-diff flag, the CLI automatically opens VS Code to show side-by-side diffs of proposed code changes before the approval prompt, allowing developers to review changes in their familiar editor environment with full syntax highlighting and editor features.

🔧 Implementation

Core Components

New Module (vscode_integration.py)

  • is_vscode_available() - Detects if VS Code CLI is installed
  • open_diff_in_vscode() - Opens diff view with temp file management
  • Uses --wait flag to block until VS Code closes (prevents race conditions)
  • Registers atexit handler for cleanup as safety fallback

Configuration (config.py)

  • Added vscode_diff_preview to SessionState
  • Added toggle_vscode_diff_preview() method

CLI Integration (main.py)

  • Added --vscode-diff command-line flag
  • Passes flag to session state initialization

Approval Flow (execution.py)

  • Integrated into prompt_for_tool_approval()
  • Automatically opens diff for write_file and edit_file operations
  • Uses perform_string_replacement to validate edits before showing diff
  • Validates old_string exists and counts occurrences properly
  • Skips diff preview when validation fails (prevents misleading diffs)

Key Features

Automatic Detection: Checks for code command in PATH
Syntax Highlighting: Preserves file extensions for proper highlighting
Reliable Cleanup: Uses --wait + atexit handler to prevent race conditions
Edit Validation: Validates string replacements before showing diff to ensure accuracy
Graceful Fallback: Works without VS Code, prints helpful message
Non-Blocking: Uses wait=False parameter for optional blocking behavior

🧪 Testing

Test Suite (test_vscode_integration.py)

  • 12 comprehensive tests covering all scenarios
  • All tests passing ✅

Test Coverage:

  • VS Code availability detection
  • Diff creation with temp files
  • Command-line argument generation
  • Error handling and fallback behavior
  • File extension preservation
  • Path object handling

⚠️ Windows Compatibility Change

Note to Maintainers: This PR includes a Windows compatibility fix for the execution.py module to resolve import errors on Windows.

The Issue

The original code imported termios and tty unconditionally at the module level. These are Unix-only modules that don't exist on Windows, causing ModuleNotFoundError when running the CLI or tests on Windows.

The Fix

# Unix-only terminal control modules (not available on Windows)
try:
    import termios
    import tty
    HAS_TERMIOS = True
except ImportError:
    HAS_TERMIOS = False

Changes Made:

  • Made termios/tty imports conditional with try-except
  • Added HAS_TERMIOS flag for runtime checks
  • Wrapped Unix-specific terminal code in if HAS_TERMIOS: blocks
  • Provided Windows fallback using standard input() for approval prompts

Impact:

  • ✅ CLI now works on Windows without import errors
  • ✅ Tests run successfully on Windows
  • ✅ No change to Unix/Mac behavior (arrow key navigation still works)
  • ✅ Windows users get text-based approval prompts (A/R/Auto)

Question for Maintainers:
Is this Windows compatibility approach acceptable? The alternative would be to make Windows support explicit in documentation/requirements, but this seemed like a minimal change that enables cross-platform usage.

📚 Documentation

Updated README (libs/deepagents-cli/README.md)

  • Added "VS Code Diff Preview" section
  • Requirements and setup instructions
  • Usage examples and workflow explanation
  • Benefits for developers

🔄 Backward Compatibility

Fully backward compatible - feature is opt-in via --vscode-diff flag
Zero impact when flag is not used
Graceful degradation - works without VS Code installed

📋 Usage Example

# Start CLI with VS Code diff preview
deepagents --vscode-diff

# When agent suggests a file change:
# 1. VS Code opens automatically with side-by-side diff
# 2. Review changes in VS Code (blocks terminal with --wait)
# 3. Close VS Code diff when done reviewing
# 4. Terminal shows approval prompt
# 5. Approve or reject the change
# 6. Temp files cleaned up automatically

🔍 Technical Notes

Temp File Management:

  • Creates temp directory with tempfile.mkdtemp(prefix="deepagents_diff_")
  • Uses --wait flag to block until VS Code closes the diff
  • Immediate cleanup in finally block after VS Code closes
  • atexit handler registered as safety fallback
  • Unregisters atexit handler after successful cleanup

Edit Validation:

  • Uses perform_string_replacement from deepagents.backends.utils for all edit operations
  • Validates that old_string exists in file before creating diff preview
  • Counts occurrences properly, respecting replace_all vs single-replace semantics
  • Returns error message if old_string not found, skipping diff preview
  • Ensures diff preview matches exactly what will be applied by the actual edit operation
  • Prevents showing misleading diffs that would be rejected during execution

Why --wait is Always Used:
The initial implementation had a configurable wait parameter, but we discovered this caused race conditions where temp files were deleted before VS Code could read them. Now --wait is always used to ensure VS Code has finished reading files before cleanup. The wait parameter is deprecated but kept for backwards compatibility.

✅ Checklist

  • Feature implemented and working
  • Comprehensive test suite (12 tests, all passing)
  • Documentation updated
  • Windows compatibility verified
  • Backward compatible (opt-in feature)
  • Code follows project patterns
  • Ready for review

- Implements optional VS Code integration to preview suggested code changes as diffs before approval
- New vscode_integration module with functions to open diffs in VS Code
- Added --vscode-diff CLI flag to enable the feature
- Integrated with existing HITL approval flow in execution.py
- Comprehensive test suite with 12 passing tests
- Updated documentation in README with usage examples
- Fixed Windows compatibility for termios imports

Benefits:
- Visual feedback with syntax highlighting and editor context
- Side-by-side diff comparison in familiar editor environment
- Faster feedback loop for reviewing code changes
- Safer adoption with ability to inspect changes before applying
- Move Path import to module level in execution.py
- Always use --wait flag when opening diffs to prevent race conditions
- Register atexit handler for cleanup as safety fallback
- Update tests to reflect new behavior with --wait always enabled
- Improve comments explaining cleanup flow

This ensures VS Code has finished reading temp files before cleanup,
preventing file access errors and race conditions.
- Capture return value in success variable
- Add comment explaining silent failure is acceptable
- Improves code clarity and error handling transparency
Replace manual string replacement logic in execution.py with proper
validation using perform_string_replacement from deepagents.backends.utils.

Changes:
- Import perform_string_replacement for validated string replacement
- Validate old_string exists before creating diff preview
- Count occurrences properly respecting replace_all semantics
- Skip VS Code diff preview when validation fails (old_string not found)
- Ensures diff preview matches what will actually be applied by the edit operation

This prevents showing misleading diffs when edits will be rejected
due to old_string not being found in the file.

All 61 unit tests pass ✅
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.

Preview suggested code changes as diffs in IDE

1 participant