Add git-ai blame visualization to JetBrains plugin#741
Add git-ai blame visualization to JetBrains plugin#741Krishnachaitanyakc wants to merge 3 commits intogit-ai-project:mainfrom
Conversation
b503fd1 to
e11fc9a
Compare
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).
e11fc9a to
f9ea024
Compare
agent-support/intellij/src/main/kotlin/org/jetbrains/plugins/template/blame/BlameService.kt
Outdated
Show resolved
Hide resolved
...-support/intellij/src/main/kotlin/org/jetbrains/plugins/template/blame/BlameEditorManager.kt
Show resolved
Hide 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
| override fun dispose() { | ||
| scheduler.shutdownNow() | ||
| for ((_, state) in editorStates) { | ||
| state.clearDecorations() | ||
| Disposer.dispose(state) | ||
| } | ||
| editorStates.clear() | ||
| } |
There was a problem hiding this comment.
🔴 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.
| 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) | |
| } | |
| } | |
| } |
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().
Summary
Implements AI blame annotations in the JetBrains IntelliJ plugin, matching the VS Code extension's functionality. Resolves #660.
git-ai blame --json --contents -CLI to get per-line AI authorship dataSonnet 3.5 via Cursor)Cmd+Shift+G/Ctrl+Shift+Gcycles through Off → Line → All modes