-
Notifications
You must be signed in to change notification settings - Fork 469
feat(mpp-idea): add Compose UI module for IntelliJ IDEA 2025.2+ #470
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
Conversation
- Add mpp-idea module as a composite build (includeBuild) to avoid plugin version conflicts - Use IntelliJ Platform Gradle Plugin 2.10.2 for IDEA 252+ Compose support - Main project continues to use plugin version 2.1.0 for compatibility - Add ToolWindow with Compose UI using Jewel theme - Add ChatApp, ChatViewModel, and CoroutineScopeHolder components - Target IntelliJ IDEA 2025.2.1 (build 252) The composite build approach allows mpp-idea to use a different version of the IntelliJ Platform Gradle Plugin without affecting other modules.
WalkthroughThis PR introduces a new IntelliJ IDEA plugin module ( Changes
Sequence DiagramsequenceDiagram
participant IDE as IntelliJ IDE
participant Factory as ToolWindowFactory
participant Services as CoroutineScopeHolder
participant ViewModel as AutoDevChatViewModel
participant UI as AutoDevChatApp (Compose)
IDE->>Factory: createToolWindowContent(project, toolWindow)
Factory->>Services: project.service(CoroutineScopeHolder)
Services-->>Factory: projectWideCoroutineScope
Factory->>Factory: createScope("AutoDevChat")
Factory->>ViewModel: AutoDevChatViewModel(childScope)
ViewModel-->>Factory: viewModel instance
Factory->>Factory: toolWindow.addComposeTab("Chat")
Factory->>UI: AutoDevChatApp(viewModel)
UI->>ViewModel: collectAsState(chatMessages)
UI->>ViewModel: collectAsState(inputState)
Note over UI,ViewModel: User interactions trigger callbacks
UI->>ViewModel: onInputChanged(text)
UI->>ViewModel: onSendMessage()
ViewModel-->>UI: state updates flow back
UI->>UI: render updated UI
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
|
augmentcode review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatApp.kt (1)
152-208: Consider extracting the send-and-clear logic.The text field clearing logic is duplicated in two places (lines 183 and 200). Consider extracting this into a helper function to improve maintainability.
Apply this refactor:
+ val sendAndClear = { + onSend() + textFieldState.edit { replace(0, length, "") } + } + Row( modifier = Modifier .fillMaxWidth() .padding(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically ) { TextField( state = textFieldState, placeholder = { Text("Type your message...") }, modifier = Modifier .weight(1f) .onPreviewKeyEvent { keyEvent -> if (keyEvent.key == Key.Enter && keyEvent.type == KeyEventType.KeyDown && !isSending) { - onSend() - textFieldState.edit { replace(0, length, "") } + sendAndClear() true } else { false } }, enabled = !isSending ) if (isSending) { DefaultButton(onClick = onAbort) { Text("Stop") } } else { DefaultButton( - onClick = { - onSend() - textFieldState.edit { replace(0, length, "") } - }, + onClick = sendAndClear, enabled = inputState is MessageInputState.Enabled ) { Text("Send") } } }mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevToolWindowFactory.kt (1)
20-22: Consider using DEBUG level for initialization logging.INFO-level logging in the
initblock will emit a message every time the factory is instantiated, which may be noisy in production logs. Consider usingthisLogger().debug(...)instead, or removing this log if it's only useful during development.init { - thisLogger().info("AutoDevToolWindowFactory initialized - Compose UI for IntelliJ IDEA 252+") + thisLogger().debug("AutoDevToolWindowFactory initialized - Compose UI for IntelliJ IDEA 252+") }mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatViewModel.kt (2)
52-53:isLoadingStateFlow is declared but never updated.The
_isLoadingStateFlow is defined but not used anywhere in the current implementation. If it's intended for future AI integration, consider either removing it until needed or adding a TODO comment to clarify its purpose.Either remove the unused state:
- private val _isLoading = MutableStateFlow(false) - val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()Or add a clarifying comment:
+ // TODO: Update isLoading during AI response generation private val _isLoading = MutableStateFlow(false) val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()
96-101: Consider simplifying withifEmpty.Minor readability improvement using Kotlin's
ifEmptyextension.fun onAbortMessage() { - _inputState.value = when (val text = _inputState.value.inputText) { - "" -> MessageInputState.Disabled - else -> MessageInputState.Enabled(text) + val text = _inputState.value.inputText + _inputState.value = text.ifEmpty { null }?.let { MessageInputState.Enabled(it) } + ?: MessageInputState.Disabled } - }Alternatively, keep the current
whenexpression as it's clear and explicit.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
mpp-idea/src/main/resources/icons/autodev-toolwindow.svgis excluded by!**/*.svgmpp-idea/src/main/resources/icons/autodev.svgis excluded by!**/*.svg
📒 Files selected for processing (10)
mpp-idea/build.gradle.kts(1 hunks)mpp-idea/settings.gradle.kts(1 hunks)mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/AutoDevIcons.kt(1 hunks)mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/services/CoroutineScopeHolder.kt(1 hunks)mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatApp.kt(1 hunks)mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatViewModel.kt(1 hunks)mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevToolWindowFactory.kt(1 hunks)mpp-idea/src/main/resources/META-INF/plugin.xml(1 hunks)mpp-idea/src/main/resources/messages/AutoDevIdeaBundle.properties(1 hunks)settings.gradle.kts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{kt,kts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
expect/actualfor platform-specific code in Kotlin Multiplatform (e.g., file I/O on JVM/JS/Wasm)
Files:
mpp-idea/settings.gradle.ktsmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatApp.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/AutoDevIcons.ktsettings.gradle.ktsmpp-idea/build.gradle.ktsmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatViewModel.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/services/CoroutineScopeHolder.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevToolWindowFactory.kt
**/*.{kt,css,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
DO NOT hardcode colors (e.g.,
Color(0xFF...)or#hex). Always use design tokens for consistency across platforms
Files:
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatApp.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/AutoDevIcons.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatViewModel.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/services/CoroutineScopeHolder.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevToolWindowFactory.kt
🧠 Learnings (3)
📚 Learning: 2025-11-29T02:25:03.592Z
Learnt from: CR
Repo: unit-mesh/auto-dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-29T02:25:03.592Z
Learning: Applies to **/{desktopMain,androidMain}/**/*.kt : Compose (Desktop/Android): Use `AutoDevColors` from `cc.unitmesh.devins.ui.compose.theme` or `MaterialTheme.colorScheme`
Applied to files:
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatApp.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/AutoDevIcons.ktmpp-idea/build.gradle.ktsmpp-idea/src/main/resources/META-INF/plugin.xmlmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevToolWindowFactory.kt
📚 Learning: 2025-11-29T02:25:03.592Z
Learnt from: CR
Repo: unit-mesh/auto-dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-29T02:25:03.592Z
Learning: Build MPP Core: `cd /Volumes/source/ai/autocrud && ./gradlew :mpp-core:assembleJsPackage`
Applied to files:
settings.gradle.kts
📚 Learning: 2025-11-29T02:25:03.592Z
Learnt from: CR
Repo: unit-mesh/auto-dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-29T02:25:03.592Z
Learning: Applies to **/*.{kt,kts} : Use `expect`/`actual` for platform-specific code in Kotlin Multiplatform (e.g., file I/O on JVM/JS/Wasm)
Applied to files:
mpp-idea/build.gradle.kts
🧬 Code graph analysis (1)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevToolWindowFactory.kt (1)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatApp.kt (1)
AutoDevChatApp(27-84)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build (241)
- GitHub Check: Build (223)
🔇 Additional comments (14)
settings.gradle.kts (1)
20-20: LGTM! Composite build correctly configured.The
includeBuild("mpp-idea")enables the new mpp-idea module as a composite build, which appropriately isolates its IntelliJ Platform Gradle Plugin version from the main project.mpp-idea/settings.gradle.kts (1)
1-16: LGTM! Standard Gradle settings configuration.The settings file correctly configures repositories for plugin management and dependency resolution.
mpp-idea/build.gradle.kts (1)
1-80: LGTM! Build configuration is well-structured.The build file correctly configures:
- Kotlin 2.2.0 with Compose plugin support
- IntelliJ Platform Plugin 2.10.2 for IDEA 252+ support
- JDK 21 toolchain (required for IDEA 2025.2+)
- All necessary bundled Compose modules
- Appropriate compiler options for experimental Compose APIs
mpp-idea/src/main/resources/messages/AutoDevIdeaBundle.properties (1)
1-17: LGTM! Resource bundle is well-organized.The property keys and values are clearly defined for UI localization.
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatApp.kt (3)
27-84: LGTM! Well-structured Compose UI with proper state management.The main composable correctly:
- Collects state from the ViewModel
- Implements auto-scroll behavior when new messages arrive
- Uses Jewel theme colors (no hardcoded colors - complies with coding guidelines)
- Organizes UI into logical sections (header, messages, input)
86-125: LGTM! Header and empty state are cleanly implemented.Both composables use Jewel theme tokens for consistent styling.
127-150: LGTM! Message bubble styling uses theme tokens correctly.The bubble correctly differentiates user vs. assistant messages using Jewel theme colors, complying with the coding guideline against hardcoded colors.
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/services/CoroutineScopeHolder.kt (1)
14-30: LGTM! Coroutine scope service correctly implemented.The service properly:
- Uses constructor injection for the project-wide scope
- Creates child scopes with proper parent-child lifecycle management
- Documents the cancellation requirements clearly
The
@Suppress("UnstableApiUsage")annotation is appropriate for thechildScopeextension.mpp-idea/src/main/resources/META-INF/plugin.xml (1)
1-30: LGTM! Plugin descriptor is correctly configured.The plugin.xml properly:
- Declares the required Compose module dependency
- Registers the CoroutineScopeHolder project service
- Configures the tool window with correct factory, anchor, and icon references
- Links the resource bundle for localization
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/AutoDevIcons.kt (1)
10-22: Icon resources verified successfully.The icon files referenced in the code exist at the expected paths:
mpp-idea/src/main/resources/icons/autodev-toolwindow.svg✓mpp-idea/src/main/resources/icons/autodev.svg✓The IconLoader.getIcon() calls will resolve correctly to these resources at runtime.
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevToolWindowFactory.kt (1)
30-40: LGTM!The MVVM wiring is well-structured: the coroutine scope is properly scoped via
CoroutineScopeHolder, theviewModelis registered with the tool window's disposable for lifecycle management, and the Compose tab is correctly added via Jewel'saddComposeTab.mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/AutoDevChatViewModel.kt (3)
13-25: LGTM!The
MessageInputStatesealed class is well-designed with clear state variants. Usingdata objectforDisabledis idiomatic Kotlin for singleton-like states.
30-35: LGTM!Clean data class definition with sensible defaults.
111-113: LGTM!Proper cleanup by cancelling the coroutine scope on disposal.
Summary
Add a new
mpp-ideamodule that provides Compose UI support for IntelliJ IDEA 2025.2+ (build 252+).Key Changes
Build Configuration
includeBuild) instead ofincludeto isolate mpp-idea's plugin versionNew Components
addComposeTabfor Compose UITechnical Details
Why Composite Build?
Gradle does not allow the same plugin with different versions in a single build. By using
includeBuild("mpp-idea")instead ofinclude("mpp-idea"), mpp-idea becomes an isolated Gradle project that can use its own plugin versions without affecting the main project.Testing
./gradlew buildPlugin- Main project builds successfully./gradlew :mpp-idea:buildPlugin- mpp-idea module builds successfully./gradlew :core:compileKotlin- Core module compiles without git4idea errorsRelated
Closes the CI failure from PR #469 which was caused by globally upgrading the IntelliJ Platform Gradle Plugin version.
Pull Request opened by Augment Code with guidance from the PR author
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.