Improve integration project dependency management, conflict detection, and connector handling#2119
Conversation
Previously, the Extracted dir is cleared at the beginning and the .zip files were removed after extraction.
Introduces a new RPC method that clears the currently downloaded integration project dependencies and re-downloads the latest..
Connectors sourced from dependent integration projects do not display a delete button, as they cannot be removed from the referencing project.
…ct dependency Prevents adding a connector that already exists in a dependent integration project and displays an appropriate error to the user.
Prevent adding the dependency if conflicts are detected. Identifies conflicting entries when adding integration project dependencies, show an error message, and removes existing conflicting entries from pom.xml if present.
Update the warning message for conflicting artifacts to prevent UI clutter by truncating overly long strings, thee full detailed error remains accessible in console logs
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts (1)
290-306:⚠️ Potential issue | 🟡 MinorPick the warning from the dependency that actually failed.
This branch still uses
params.newDependencies[0], so a batch update can show the wrong warning when the failed item is not the first one in the request. Use the matched failed dependency instead of the first input item.🛠️ Suggested adjustment
- const newDep = params.newDependencies[0]; - const dependencyString = `${newDep.groupId}-${newDep.artifact}-${newDep.version}`; + const failedDep = dependenciesToRemove[0]; + const dependencyString = failedDep + ? `${failedDep.groupId}-${failedDep.artifact}-${failedDep.version}` + : "";🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts` around lines 290 - 306, The code uses params.newDependencies[0] (newDep) which can be the wrong item for batch updates; instead, find the specific dependency object from params.newDependencies whose groupId-artifact-version matches the dependency key you're checking against (the same string used with connectorsNotDownloaded, connectorsFromIntegrationProjectDeps, unavailableDependencies, missingDescriptorDependencies, versioningMismatchDependencies), assign that matched dependency to newDep and then build dependencyString from it before selecting the warning message.
🧹 Nitpick comments (2)
workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts (2)
854-864: Drop the extra save before formatting.
formatAndSavePomDocument()already applies formatting and saves the file, so the explicitdocument.save()here just adds an extra write cycle.♻️ Suggested cleanup
const document = await workspace.openTextDocument(pomPath); - await document.save(); await formatAndSavePomDocument(pomPath);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts` around lines 854 - 864, The extra explicit save is redundant because formatAndSavePomDocument(pomPath) already formats and saves the file; remove the document.save() call after opening the document. Locate the block that calls workspace.applyEdit(edit), then workspace.openTextDocument(pomPath), and delete the await document.save() line so the flow becomes applyEdit -> openTextDocument -> formatAndSavePomDocument(pomPath), leaving the subsequent MACHINE_VIEW check with getStateMachine(this.projectUri).context() and refreshUI(this.projectUri) unchanged.
433-438: Consider surfacing the combined refetch + reload outcome.This method returns only the raw refetch response, so callers cannot tell whether the follow-up
loadCAppResources()step completed cleanly or hit a conflict/error path. A structured result would make the flow easier to reason about.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts` around lines 433 - 438, The method refetchIntegrationProjectDependencies currently returns only the raw refetch response (res) and hides the outcome of the subsequent loadCAppResources(this.projectUri, langClient) call; change the method to return a structured result (e.g., an object with refetchResult and reloadResult or status fields) and capture errors from loadCAppResources to populate reloadResult (success/failure and optional error message), so callers can inspect both outcomes; update references to MILanguageClient.getInstance, refetchIntegrationProjectDependencies, and loadCAppResources in this function to return and propagate the new structured response instead of just res.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@workspaces/mi/mi-extension/src/visualizer/activate.ts`:
- Around line 571-574: The Range creation incorrectly subtracts 1 from
pomValue.range.start.{line,character} and pomValue.range.end.{line,character},
causing off-by-one shifts; update the Range(...) in activate.ts (the new Range
and Position calls) to use pomValue.range.* values directly (no "- 1") so they
remain in LSP/VS Code zero-based coordinates, and apply the same fix where
textEdit.range is constructed in rpc-manager (rpc-manager.ts) to remove the "-
1" adjustments.
In `@workspaces/mi/mi-visualizer/src/views/Overview/ProjectInformation/index.tsx`:
- Around line 208-210: The reloadDependencies handler fires an async RPC without
awaiting or handling failures; update the reloadDependencies function to await
rpcClient.getMiVisualizerRpcClient().refetchIntegrationProjectDependencies() and
wrap it in a try/catch, logging errors (or showing a user notification) on
failure and optionally returning or rethrowing as appropriate; reference the
reloadDependencies function and the refetchIntegrationProjectDependencies method
on rpcClient.getMiVisualizerRpcClient() when making the change.
---
Outside diff comments:
In `@workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts`:
- Around line 290-306: The code uses params.newDependencies[0] (newDep) which
can be the wrong item for batch updates; instead, find the specific dependency
object from params.newDependencies whose groupId-artifact-version matches the
dependency key you're checking against (the same string used with
connectorsNotDownloaded, connectorsFromIntegrationProjectDeps,
unavailableDependencies, missingDescriptorDependencies,
versioningMismatchDependencies), assign that matched dependency to newDep and
then build dependencyString from it before selecting the warning message.
---
Nitpick comments:
In `@workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts`:
- Around line 854-864: The extra explicit save is redundant because
formatAndSavePomDocument(pomPath) already formats and saves the file; remove the
document.save() call after opening the document. Locate the block that calls
workspace.applyEdit(edit), then workspace.openTextDocument(pomPath), and delete
the await document.save() line so the flow becomes applyEdit -> openTextDocument
-> formatAndSavePomDocument(pomPath), leaving the subsequent MACHINE_VIEW check
with getStateMachine(this.projectUri).context() and refreshUI(this.projectUri)
unchanged.
- Around line 433-438: The method refetchIntegrationProjectDependencies
currently returns only the raw refetch response (res) and hides the outcome of
the subsequent loadCAppResources(this.projectUri, langClient) call; change the
method to return a structured result (e.g., an object with refetchResult and
reloadResult or status fields) and capture errors from loadCAppResources to
populate reloadResult (success/failure and optional error message), so callers
can inspect both outcomes; update references to MILanguageClient.getInstance,
refetchIntegrationProjectDependencies, and loadCAppResources in this function to
return and propagate the new structured response instead of just res.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 325053bf-56fc-490a-966b-61bd8c649c3a
📒 Files selected for processing (12)
workspaces/mi/mi-core/src/rpc-types/mi-visualizer/index.tsworkspaces/mi/mi-core/src/rpc-types/mi-visualizer/rpc-type.tsworkspaces/mi/mi-diagram/src/components/sidePanel/commons/ButtonGroup.tsxworkspaces/mi/mi-diagram/src/components/sidePanel/mediators/List.tsxworkspaces/mi/mi-extension/src/lang-client/ExtendedLanguageClient.tsworkspaces/mi/mi-extension/src/lang-client/activator.tsworkspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-handler.tsworkspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.tsworkspaces/mi/mi-extension/src/util/fileOperations.tsworkspaces/mi/mi-extension/src/visualizer/activate.tsworkspaces/mi/mi-rpc-client/src/rpc-clients/mi-visualizer/rpc-client.tsworkspaces/mi/mi-visualizer/src/views/Overview/ProjectInformation/index.tsx
| const range = new Range( | ||
| new Position(pomValue.range.start.line - 1, pomValue.range.start.character - 1), | ||
| new Position(pomValue.range.end.line - 1, pomValue.range.end.character - 1) | ||
| ); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Inspect range type definitions and related models
rg -n --type=ts -C3 'interface .*Range|type .*Range|range.*start|range.*end|character|line' workspaces/mi/mi-core/src workspaces/mi/mi-extension/src
# 2) Find where dependency ranges are produced/propagated
rg -n --type=ts -C3 'dependencies.*range|conflictingDependencies|getProjectDetails\(' workspaces/mi/mi-core/src workspaces/mi/mi-extension/src
# 3) Compare with other Position constructions in extension code
rg -n --type=ts -C2 'new Position\(' workspaces/mi/mi-extension/srcRepository: wso2/vscode-extensions
Length of output: 50379
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find the function containing lines 571-574
rg -n --type=ts -B 20 "const range = new Range" workspaces/mi/mi-extension/src/visualizer/activate.ts | head -50
# Look for removePomEntries or similar function
rg -n --type=ts "removePomEntries|pomValues" workspaces/mi/mi-extension/src/visualizer/activate.ts | head -20Repository: wso2/vscode-extensions
Length of output: 1171
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find where dependenciesToRemove is defined and used
rg -n --type=ts -B 5 -A 5 "dependenciesToRemove" workspaces/mi/mi-extension/src/visualizer/activate.ts | head -100Repository: wso2/vscode-extensions
Length of output: 963
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find the full context around where allExistingDeps is defined
rg -n --type=ts -B 30 "const dependenciesToRemove" workspaces/mi/mi-extension/src/visualizer/activate.ts | grep -A 30 "allExistingDeps"Repository: wso2/vscode-extensions
Length of output: 545
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find the function containing line 625
rg -n --type=ts -B 50 "const allExistingDeps = \[" workspaces/mi/mi-extension/src/visualizer/activate.ts | head -60Repository: wso2/vscode-extensions
Length of output: 2190
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find getProjectDetails definition
rg -n --type=ts "getProjectDetails\(" workspaces/mi/mi-core/src workspaces/mi/mi-extension/src | head -20Repository: wso2/vscode-extensions
Length of output: 2965
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the getProjectDetails method definition
sed -n '393,420p' workspaces/mi/mi-extension/src/lang-client/ExtendedLanguageClient.tsRepository: wso2/vscode-extensions
Length of output: 1163
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Search for where dependency range is created/assigned on the server side
rg -n --type=ts "range.*start|range.*end|dependencies.*range" workspaces/mi/mi-core/src --max-count=30Repository: wso2/vscode-extensions
Length of output: 48
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check what files are in mi-core/src
find workspaces/mi/mi-core/src -type f -name "*.java" -o -name "*.kt" -o -name "*.scala" | head -10
# Also search for getOverviewPageDetails anywhere
rg -n "getOverviewPageDetails" workspaces/mi/mi-core/src 2>/dev/null | head -20Repository: wso2/vscode-extensions
Length of output: 48
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# List workspaces directory
ls -la workspaces/mi/
# Search across entire repository for where dependency ranges are populated
rg -n "dependencies.*range|range.*line.*character" --type=ts --type=java -i 2>/dev/null | head -30Repository: wso2/vscode-extensions
Length of output: 6386
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check the context around rpc-manager.ts line 849-850
sed -n '840,860p' workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts
# Also check line 5554 context
sed -n '5545,5565p' workspaces/mi/mi-extension/src/rpc-managers/mi-diagram/rpc-manager.tsRepository: wso2/vscode-extensions
Length of output: 1952
Fix off-by-one error in pom.xml edit ranges (lines 572–573).
The pomValue.range values are already zero-based (LSP/VS Code format). Subtracting 1 from both line and character converts them to one-based, targeting incorrect regions.
Remove the - 1 subtractions:
Fix
const range = new Range(
- new Position(pomValue.range.start.line - 1, pomValue.range.start.character - 1),
- new Position(pomValue.range.end.line - 1, pomValue.range.end.character - 1)
+ new Position(pomValue.range.start.line, pomValue.range.start.character),
+ new Position(pomValue.range.end.line, pomValue.range.end.character)
);Note: The same off-by-one error appears in rpc-managers/mi-visualizer/rpc-manager.ts lines 849–850 (textEdit.range).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const range = new Range( | |
| new Position(pomValue.range.start.line - 1, pomValue.range.start.character - 1), | |
| new Position(pomValue.range.end.line - 1, pomValue.range.end.character - 1) | |
| ); | |
| const range = new Range( | |
| new Position(pomValue.range.start.line, pomValue.range.start.character), | |
| new Position(pomValue.range.end.line, pomValue.range.end.character) | |
| ); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@workspaces/mi/mi-extension/src/visualizer/activate.ts` around lines 571 -
574, The Range creation incorrectly subtracts 1 from
pomValue.range.start.{line,character} and pomValue.range.end.{line,character},
causing off-by-one shifts; update the Range(...) in activate.ts (the new Range
and Position calls) to use pomValue.range.* values directly (no "- 1") so they
remain in LSP/VS Code zero-based coordinates, and apply the same fix where
textEdit.range is constructed in rpc-manager (rpc-manager.ts) to remove the "-
1" adjustments.
| const reloadDependencies = () => { | ||
| rpcClient.getMiVisualizerRpcClient().reloadDependencies(); | ||
| rpcClient.getMiVisualizerRpcClient().refetchIntegrationProjectDependencies(); | ||
| } |
There was a problem hiding this comment.
Handle reload RPC errors explicitly.
Line 209 triggers an async RPC without awaiting or catching failures. If the request fails, the action is silent. Please await and handle errors in this handler.
Suggested fix
- const reloadDependencies = () => {
- rpcClient.getMiVisualizerRpcClient().refetchIntegrationProjectDependencies();
- }
+ const reloadDependencies = async () => {
+ try {
+ await rpcClient.getMiVisualizerRpcClient().refetchIntegrationProjectDependencies();
+ } catch (error) {
+ console.error("Failed to refetch integration project dependencies:", error);
+ }
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const reloadDependencies = () => { | |
| rpcClient.getMiVisualizerRpcClient().reloadDependencies(); | |
| rpcClient.getMiVisualizerRpcClient().refetchIntegrationProjectDependencies(); | |
| } | |
| const reloadDependencies = async () => { | |
| try { | |
| await rpcClient.getMiVisualizerRpcClient().refetchIntegrationProjectDependencies(); | |
| } catch (error) { | |
| console.error("Failed to refetch integration project dependencies:", error); | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@workspaces/mi/mi-visualizer/src/views/Overview/ProjectInformation/index.tsx`
around lines 208 - 210, The reloadDependencies handler fires an async RPC
without awaiting or handling failures; update the reloadDependencies function to
await
rpcClient.getMiVisualizerRpcClient().refetchIntegrationProjectDependencies() and
wrap it in a try/catch, logging errors (or showing a user notification) on
failure and optionally returning or rethrowing as appropriate; reference the
reloadDependencies function and the refetchIntegrationProjectDependencies method
on rpcClient.getMiVisualizerRpcClient() when making the change.
There was a problem hiding this comment.
Pull request overview
This PR improves integration project dependency management by adding a dedicated “refetch integration project dependencies” flow, expanding dependent resource loading to detect/remove conflicts, and tightening connector handling in the UI (e.g., only allowing deletion of connectors belonging to the current project).
Changes:
- Introduces a new RPC method to refetch integration project dependencies and wires it through visualizer UI → RPC client → extension handlers → language client.
- Centralizes dependent CApp resource loading (
loadCAppResources) with conflict detection and automatic cleanup of conflicting dependencies inpom.xml. - Updates connector UI behavior so delete actions are only enabled for connectors identified as local to the current project.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| workspaces/mi/mi-visualizer/src/views/Overview/ProjectInformation/index.tsx | Switches overview dependency reload to use the new refetch RPC method. |
| workspaces/mi/mi-rpc-client/src/rpc-clients/mi-visualizer/rpc-client.ts | Adds RPC client method for refetchIntegrationProjectDependencies. |
| workspaces/mi/mi-extension/src/visualizer/activate.ts | Adds loadCAppResources and conflict cleanup logic; adjusts dependency extraction behavior. |
| workspaces/mi/mi-extension/src/util/fileOperations.ts | Adds shared formatAndSavePomDocument helper for formatting/saving pom.xml. |
| workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-manager.ts | Adds manager method for refetch; routes dependent resource loading through loadCAppResources; refactors pom edit+format flow to shared helper. |
| workspaces/mi/mi-extension/src/rpc-managers/mi-visualizer/rpc-handler.ts | Registers the new refetch RPC request handler. |
| workspaces/mi/mi-extension/src/lang-client/activator.ts | Updates initial language-client startup flow to update connectors and load dependent resources via loadCAppResources. |
| workspaces/mi/mi-extension/src/lang-client/ExtendedLanguageClient.ts | Adds refetchIntegrationProjectDependencies request + typed loadDependentCAppResources response model including conflict metadata. |
| workspaces/mi/mi-diagram/src/components/sidePanel/mediators/List.tsx | Enables delete action only for connectors determined to be local to the current project. |
| workspaces/mi/mi-diagram/src/components/sidePanel/commons/ButtonGroup.tsx | Makes delete icon conditional on onDelete being provided. |
| workspaces/mi/mi-core/src/rpc-types/mi-visualizer/rpc-type.ts | Adds the new request type constant for refetch. |
| workspaces/mi/mi-core/src/rpc-types/mi-visualizer/index.ts | Extends MIVisualizerAPI with the new refetch method. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const content = textEdit.newText; | ||
|
|
||
| const range = new Range(new Position(textEdit.range.start.line - 1, textEdit.range.start.character - 1), | ||
| new Position(textEdit.range.end.line - 1, textEdit.range.end.character - 1)); | ||
|
|
There was a problem hiding this comment.
updatePom converts incoming TextEdit.range by subtracting 1 from both line and character. The TextEdit type used here is from vscode-languageclient (LSP), whose positions are 0-based; subtracting 1 will shift edits and can produce negative positions (e.g., edits starting at 0:0). Either treat these ranges as 0-based (remove the - 1 adjustments) or, if the language server intentionally returns 1-based ranges, avoid using the LSP TextEdit type here and introduce a clearly named 1-based range type + conversion at the boundary.
| new Position(pomValue.range.start.line - 1, pomValue.range.start.character - 1), | ||
| new Position(pomValue.range.end.line - 1, pomValue.range.end.character - 1) |
There was a problem hiding this comment.
removePomEntries builds a VS Code Range by subtracting 1 from pomValue.range.start/end line/character. The range values coming from getProjectDetails() are STRange-shaped (line/character) and elsewhere in the extension (e.g., mi-diagram applyEdit) they are treated as already 0-based. This - 1 conversion risks deleting the wrong span in pom.xml or creating negative positions. Consider standardizing range indexing (prefer 0-based) and removing the - 1 adjustments here, or documenting/enforcing 1-based ranges at the type level and clamping at 0 before constructing Positions.
| new Position(pomValue.range.start.line - 1, pomValue.range.start.character - 1), | |
| new Position(pomValue.range.end.line - 1, pomValue.range.end.character - 1) | |
| new Position(pomValue.range.start.line, pomValue.range.start.character), | |
| new Position(pomValue.range.end.line, pomValue.range.end.character) |
Purpose
This PR introduces the following changes:
Related PRs