chore: release new version for VSCode && IDEA#482
Conversation
Add PUBLISH.md with steps and guidelines for publishing the VSCode extension.
Renames the plugin to "AutoDev Experiment", sets version to 0.3.5, and adds plugin verification and publishing token configuration.
Replace RxJava-based SSE streaming with kotlinx.coroutines Flow and ProducerScope for improved async handling and code simplification. Also remove deprecated AsyncFileEditorProvider usage. Bump mppVersion to 0.3.6.
Replaces Internal API calls with public alternatives and reflection where necessary to improve compatibility and stability. Also updates progress indicator handling and ensures temp files are properly deleted after shell execution.
- Add comprehensive module breakdown (Core, Clients, Server & Tools) - Include platform support and status for each module - Add current version information - Translate section to English - Add new IntelliJ plugin experimental link - Update mpp-web status to In Progress
|
Caution Review failedThe pull request is closed. WalkthroughThis PR migrates SSE streaming from RxJava Flowable to Kotlin coroutines, removes AsyncFileEditorProvider from preview editors, updates action invocation to use ActionUtil, replaces internal API usage with alternatives, and updates plugin configuration, versioning, and documentation. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~30 minutes
Possibly related PRs
Poem
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (15)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR prepares release v0.3.4 for both VSCode extension and IntelliJ IDEA plugin, with significant refactoring to avoid IntelliJ internal APIs and migrate from RxJava to Kotlin Coroutines.
Key Changes:
- Migrates SSE streaming from RxJava (FlowableEmitter) to Kotlin Coroutines (ProducerScope/callbackFlow)
- Refactors IntelliJ API usage to avoid internal APIs: ActionUtil for action invocation, removes AsyncFileEditorProvider, updates ProgressManager usage
- Adds comprehensive publishing documentation (PUBLISH.md) and updates README with multiplatform architecture details
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| mpp-vscode/PUBLISH.md | New comprehensive publishing guide for VSCode extension with deployment instructions |
| mpp-idea/src/main/resources/META-INF/plugin.xml | Updates plugin name from "AutoDev Next" to "AutoDev Experiment" |
| mpp-idea/gradle.properties | Adds mppVersion property (0.3.4) for version management |
| mpp-idea/build.gradle.kts | Updates plugin name, adds plugin verification and publishing configuration |
| exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/processor/shell/ShireShellCommandRunner.kt | Improves temp file cleanup with deleteOnExit fallback and explicit deletion logic |
| exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/debugger/editor/ShirePreviewEditorProvider.kt | Removes AsyncFileEditorProvider implementation, keeping only WeighedFileEditorProvider |
| exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/exec/vcs/CommitInsCommand.kt | Switches from direct actionPerformed() to ActionUtil.performActionDumbAwareWithCallbacks() |
| core/src/main/kotlin/cc/unitmesh/devti/sketch/run/ProcessExecutor.kt | Replaces startProcessWithPty() with createProcess() to avoid internal API |
| core/src/main/kotlin/cc/unitmesh/devti/observer/test/RunTestUtil.kt | Uses reflection to access BuildView.consoleView instead of direct property access |
| core/src/main/kotlin/cc/unitmesh/devti/mcp/host/BuiltinMcpTools.kt | Updates ActionUtil usage for action invocation and switches from CoreProgressManager to ProgressManager |
| core/src/main/kotlin/cc/unitmesh/devti/mcp/editor/McpPreviewEditorProvider.kt | Removes AsyncFileEditorProvider implementation |
| core/src/main/kotlin/cc/unitmesh/devti/llms/custom/ResponseBodyCallback.kt | Migrates from FlowableEmitter (RxJava) to ProducerScope (Kotlin Coroutines) for SSE streaming |
| core/src/main/kotlin/cc/unitmesh/devti/llms/custom/CustomSSEProcessor.kt | Migrates from Flowable (RxJava) to callbackFlow (Kotlin Coroutines) for SSE processing |
| README.md | Major update with comprehensive multiplatform architecture documentation and current version info |
| AGENTS.md | Simplifies documentation, removes Swing/Compose z-index solution details, clarifies release process |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Ensure temp file is deleted even on error | ||
| try { | ||
| tempFile.delete() | ||
| } catch (deleteException: Exception) { | ||
| logger<ShireShellCommandRunner>().warn("Failed to delete temporary file after error: ${tempFile.path}", deleteException) | ||
| } |
There was a problem hiding this comment.
The temp file deletion in this catch block is redundant and potentially problematic. If the exception occurs in future.get(), the file has already been deleted in the finally block of the pooled thread execution (lines 64-71). This creates a race condition where the same file might be deleted twice, and the second deletion could fail or log a spurious warning.
| // Ensure temp file is deleted even on error | |
| try { | |
| tempFile.delete() | |
| } catch (deleteException: Exception) { | |
| logger<ShireShellCommandRunner>().warn("Failed to delete temporary file after error: ${tempFile.path}", deleteException) | |
| } |
| // Use createProcess instead of startProcessWithPty to avoid Internal API | ||
| return commandLine.withExePath(commands[0]) | ||
| .withParameters(commands.drop(1)) | ||
| .createProcess() |
There was a problem hiding this comment.
The replacement of startProcessWithPty() with createProcess() changes the process creation behavior. startProcessWithPty() creates a pseudo-terminal (PTY) process, which is essential for interactive shells. Using createProcess() instead creates a regular process without PTY support, which may break shell interactivity, job control, and terminal-specific features. This could cause issues with the interactive process functionality.
| // Use createProcess instead of startProcessWithPty to avoid Internal API | |
| return commandLine.withExePath(commands[0]) | |
| .withParameters(commands.drop(1)) | |
| .createProcess() | |
| // Use startProcessWithPty for interactive shell support (PTY required) | |
| return commandLine.withExePath(commands[0]) | |
| .withParameters(commands.drop(1)) | |
| .startProcessWithPty() |
| // Use createProcess instead of startProcessWithPty to avoid Internal API | ||
| return commandLine.withExePath(commands[0]) | ||
| .withParameters(commands.drop(1)) | ||
| .createProcess() |
There was a problem hiding this comment.
The replacement of startProcessWithPty() with createProcess() changes the process creation behavior. startProcessWithPty() creates a pseudo-terminal (PTY) process, which is essential for interactive shells. Using createProcess() instead creates a regular process without PTY support, which may break shell interactivity, job control, and terminal-specific features. This could cause issues with the shell command execution.
| // Use reflection to access internal consoleView to avoid using Internal API | ||
| try { | ||
| val consoleViewField = BuildView::class.java.getDeclaredField("consoleView") | ||
| consoleViewField.isAccessible = true | ||
| val consoleView = consoleViewField.get(executionConsole) | ||
| when (consoleView) { | ||
| is SMTRunnerConsoleView -> { | ||
| return getTestView(consoleView) | ||
| } | ||
| } | ||
| } catch (e: Exception) { | ||
| // Fallback: return null if reflection fails | ||
| return null | ||
| } |
There was a problem hiding this comment.
Using reflection to access internal fields breaks API stability and could fail in future IntelliJ versions. While the fallback of returning null is good, the code now uses an unstable internal API through reflection instead of the stable internal API it was using before. Consider checking if there's a public API alternative in the target IntelliJ version, or if the internal API usage was acceptable for this plugin's version constraints.
| // Use reflection to access internal consoleView to avoid using Internal API | |
| try { | |
| val consoleViewField = BuildView::class.java.getDeclaredField("consoleView") | |
| consoleViewField.isAccessible = true | |
| val consoleView = consoleViewField.get(executionConsole) | |
| when (consoleView) { | |
| is SMTRunnerConsoleView -> { | |
| return getTestView(consoleView) | |
| } | |
| } | |
| } catch (e: Exception) { | |
| // Fallback: return null if reflection fails | |
| return null | |
| } | |
| // No public API to access ConsoleViewImpl from BuildView. | |
| // If a public method becomes available in future, use it here. | |
| // For now, we cannot support extracting ConsoleViewImpl from BuildView safely. | |
| return null |
| line.startsWith("{") && line.endsWith("}") -> { | ||
| emitter.onNext(SSE(line)) | ||
| emitter.onComplete() | ||
| emitter.trySend(SSE(line)) |
There was a problem hiding this comment.
Using trySend() without checking the result can silently drop messages if the channel buffer is full. Unlike RxJava's onNext() which would handle backpressure, trySend() returns a ChannelResult that should be checked. Consider using send() (which suspends) or handling the trySend() result to detect message loss.
| emitter.trySend(SSE(line)) | |
| val sendResult = emitter.trySend(SSE(line)) | |
| if (!sendResult.isSuccess) { | |
| logger.error("Failed to send SSE event: $line. Reason: ${sendResult.exceptionOrNull()}") | |
| } |
|
|
||
| **Current Versions**: | ||
| - IntelliJ Plugin: `v2.4.6` | ||
| - New Intellij Plugin: https://plugins.jetbrains.com/plugin/29223-autodev-experiment |
There was a problem hiding this comment.
Inconsistent capitalization: "Intellij" should be "IntelliJ" (with capital J) to match JetBrains' official product naming.
| - New Intellij Plugin: https://plugins.jetbrains.com/plugin/29223-autodev-experiment | |
| - New IntelliJ Plugin: https://plugins.jetbrains.com/plugin/29223-autodev-experiment |
| break | ||
| } | ||
| emitter.onNext(sse) | ||
| emitter.trySend(sse) |
There was a problem hiding this comment.
Using trySend() without checking the result can silently drop messages if the channel buffer is full. Unlike RxJava's onNext() which would handle backpressure, trySend() returns a ChannelResult that should be checked. Consider using send() (which suspends) or handling the trySend() result to detect message loss, especially for critical SSE events.
| emitter.trySend(sse) | |
| val result = emitter.trySend(sse) | |
| if (!result.isSuccess) { | |
| logger.warn("SSE message dropped: $sse (reason: ${result.exceptionOrNull()?.message})") | |
| } |
| emitter.trySend(sse ?: SSE("")) | ||
| emitter.trySend(sse ?: SSE("")) |
There was a problem hiding this comment.
Using trySend() without checking the result can silently drop messages if the channel buffer is full. Unlike RxJava's onNext() which would handle backpressure, trySend() returns a ChannelResult that should be checked. Consider using send() (which suspends) or handling the trySend() result to detect message loss.
|
|
||
| 2. **Publish** | ||
| ```bash | ||
| cd /Volumes/source/ai/autocrud/mpp-vscode |
There was a problem hiding this comment.
This hardcoded absolute path /Volumes/source/ai/autocrud/mpp-vscode appears to be developer-specific and should be replaced with a relative path like cd mpp-vscode or removed entirely since users should already be in the appropriate directory.
| cd /Volumes/source/ai/autocrud/mpp-vscode | |
| cd mpp-vscode |
Summary by CodeRabbit
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.