Skip to content

Add git-ai blame visualization to JetBrains plugin#741

Draft
Krishnachaitanyakc wants to merge 3 commits intogit-ai-project:mainfrom
Krishnachaitanyakc:feat/jetbrains-blame-660
Draft

Add git-ai blame visualization to JetBrains plugin#741
Krishnachaitanyakc wants to merge 3 commits intogit-ai-project:mainfrom
Krishnachaitanyakc:feat/jetbrains-blame-660

Conversation

@Krishnachaitanyakc
Copy link
Contributor

@Krishnachaitanyakc Krishnachaitanyakc commented Mar 17, 2026

Summary

Implements AI blame annotations in the JetBrains IntelliJ plugin, matching the VS Code extension's functionality. Resolves #660.

  • Calls git-ai blame --json --contents - CLI to get per-line AI authorship data
  • Gutter color stripes: 4px colored icons in the gutter for AI-authored lines (40-color palette, same as VS Code)
  • Inline after-text inlays: Shows model name after the line end (e.g. Sonnet 3.5 via Cursor)
  • Status bar widget: Shows AI model or human indicator for the current cursor line; click to toggle mode
  • Toggle action: Cmd+Shift+G / Ctrl+Shift+G cycles through Off → Line → All modes
  • ModelNameParser: Ported from VS Code extension — formats raw model strings into display names
  • 300ms debounced refresh on document edits, LRU cache (20 entries), dirty-file support via stdin piping

Open with Devin

@Krishnachaitanyakc Krishnachaitanyakc marked this pull request as draft March 17, 2026 15:52
devin-ai-integration[bot]

This comment was marked as resolved.

@Krishnachaitanyakc Krishnachaitanyakc force-pushed the feat/jetbrains-blame-660 branch 5 times, most recently from b503fd1 to e11fc9a Compare March 18, 2026 02:14
Implements AI blame annotations in the IntelliJ plugin, matching the
VS Code extension's functionality. Calls `git-ai blame --json --contents -`
to get per-line AI authorship data and renders it via:

- Gutter color stripes (4px colored icons per AI-authored line)
- Inline after-text inlays showing model name (e.g. "Sonnet 3.5 via Cursor")
- Status bar widget showing AI/human indicator for current line
- Toggle action (Cmd+Shift+G) cycling Off/Line/All modes

New files: BlameModels, BlameService, BlameEditorManager,
BlameStatusBarWidgetFactory, BlameToggleAction, BlameStartupActivity,
ModelNameParser (ported from VS Code extension).
@Krishnachaitanyakc Krishnachaitanyakc force-pushed the feat/jetbrains-blame-660 branch from e11fc9a to f9ea024 Compare March 18, 2026 18:36
@Krishnachaitanyakc Krishnachaitanyakc marked this pull request as ready for review March 18, 2026 21:01
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 new potential issues.

View 9 additional findings in Devin Review.

Open in Devin Review

- BlameService: start stdout/stderr readers before stdin write and make
  stdin write async to prevent pipe buffer deadlock on files >64KB
- BlameEditorManager: use getEditors(file) instead of selectedTextEditor
  in fileOpened callback to resolve correct editor in split-editor scenarios
- Add consolidated pre-commit checks section to CLAUDE.md covering
  process I/O patterns, IntelliJ API misuses, Rust formatting, and lint
@Krishnachaitanyakc Krishnachaitanyakc marked this pull request as draft March 19, 2026 16:00
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 11 additional findings in Devin Review.

Open in Devin Review

Comment on lines +339 to +346
override fun dispose() {
scheduler.shutdownNow()
for ((_, state) in editorStates) {
state.clearDecorations()
Disposer.dispose(state)
}
editorStates.clear()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🔴 BlameEditorManager.dispose() calls Disposer.dispose(state) and clearDecorations() without invokeLater, violating mandatory EDT threading rule

The dispose() method at BlameEditorManager.kt:339-346 directly calls state.clearDecorations() and Disposer.dispose(state) without wrapping them in invokeLater. clearDecorations() manipulates editor markup (editor.markupModel.removeHighlighter) and disposes inlays—both require EDT access. When the project service is disposed from a background thread (which IntelliJ does during project closing), this causes threading assertion errors or data corruption.

This violates the mandatory Claude.md rule: "Disposer.dispose() for editor state must be called inside invokeLater to avoid threading races with EDT." The same file correctly follows this pattern in detachFromEditor() (BlameEditorManager.kt:164-165), making the inconsistency clear.

Suggested change
override fun dispose() {
scheduler.shutdownNow()
for ((_, state) in editorStates) {
state.clearDecorations()
Disposer.dispose(state)
}
editorStates.clear()
}
override fun dispose() {
scheduler.shutdownNow()
val states = editorStates.values.toList()
editorStates.clear()
ApplicationManager.getApplication().invokeLater {
for (state in states) {
Disposer.dispose(state)
}
}
}
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

BlameEditorManager.dispose() was calling Disposer.dispose(state) and
clearDecorations() directly without invokeLater, causing EDT threading
violations when the service is disposed from a background thread during
project closing. Now matches the pattern already used in detachFromEditor().
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.

Show git-ai blame (similar to VS Code extension) in Jetbrains

1 participant