Skip to content

Add git-ai blame visualization to JetBrains plugin#741

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

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
devin-ai-integration[bot]

This comment was marked as resolved.

- 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
devin-ai-integration[bot]

This comment was marked as resolved.

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().
@Krishnachaitanyakc Krishnachaitanyakc marked this pull request as ready for review March 22, 2026 19:14
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 13 additional findings in Devin Review.

Open in Devin Review

Comment on lines +133 to +136
if (editorStates.containsKey(editor)) return

val state = EditorBlameState(editor)
editorStates[editor] = state
Copy link
Contributor

Choose a reason for hiding this comment

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

🔴 TOCTOU race in attachToEditor causes leaked state and duplicate editor decorations

attachToEditor uses a non-atomic check-then-act pattern on ConcurrentHashMap at lines 133-136: it calls containsKey(editor) then separately calls editorStates[editor] = state. Since initialize() runs on a background coroutine (via ProjectActivity.execute at BlameStartupActivity.kt:10) and the fileOpened callback fires on EDT (BlameEditorManager.kt:112), two threads can simultaneously pass the containsKey guard for the same editor. The second put overwrites the first state, but the first state's caret and document listeners (registered at lines 139-154 with state as the Disposable parent) remain active on the editor. This orphaned state is never disposed, so its listeners keep firing independently — calling updateLineMode and scheduleBlameRefresh with a state that isn't tracked in the map — producing duplicate gutter icons and inline annotations.

Suggested change
if (editorStates.containsKey(editor)) return
val state = EditorBlameState(editor)
editorStates[editor] = state
val state = EditorBlameState(editor)
if (editorStates.putIfAbsent(editor, state) != null) return
Open in Devin Review

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

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